1 /*
2 * Copyright (C) 2010, 2013 Nicolas Bonnefon and other contributors
3 *
4 * This file is part of glogg.
5 *
6 * glogg is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * glogg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with glogg. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 // This file implements Selection.
21 // This class implements the selection handling. No check is made on
22 // the validity of the selection, it must be handled by the caller.
23 // There are three types of selection, only one type might be active
24 // at any time.
25
26 #include "selection.h"
27
28 #include "data/abstractlogdata.h"
29
Selection()30 Selection::Selection()
31 {
32 selectedLine_ = -1;
33
34 selectedPartial_.line = -1;
35 selectedPartial_.startColumn = 0;
36 selectedPartial_.endColumn = 0;
37
38 selectedRange_.startLine = -1;
39 selectedRange_.endLine = 0;
40 }
41
selectPortion(int line,int start_column,int end_column)42 void Selection::selectPortion( int line, int start_column, int end_column )
43 {
44 // First unselect any whole line or range
45 selectedLine_ = -1;
46 selectedRange_.startLine = -1;
47
48 selectedPartial_.line = line;
49 selectedPartial_.startColumn = qMin ( start_column, end_column );
50 selectedPartial_.endColumn = qMax ( start_column, end_column );
51 }
52
selectRange(int start_line,int end_line)53 void Selection::selectRange( int start_line, int end_line )
54 {
55 // First unselect any whole line and portion
56 selectedLine_ = -1;
57 selectedPartial_.line = -1;
58
59 selectedRange_.startLine = qMin ( start_line, end_line );
60 selectedRange_.endLine = qMax ( start_line, end_line );
61
62 selectedRange_.firstLine = start_line;
63 }
64
selectRangeFromPrevious(int line)65 void Selection::selectRangeFromPrevious( int line )
66 {
67 int previous_line;
68
69 if ( selectedLine_ >= 0 )
70 previous_line = selectedLine_;
71 else if ( selectedRange_.startLine >= 0 )
72 previous_line = selectedRange_.firstLine;
73 else if ( selectedPartial_.line >= 0 )
74 previous_line = selectedPartial_.line;
75 else
76 previous_line = 0;
77
78 selectRange( previous_line, line );
79 }
80
crop(int last_line)81 void Selection::crop( int last_line )
82 {
83 if ( selectedLine_ > last_line )
84 selectedLine_ = -1;
85
86 if ( selectedPartial_.line > last_line )
87 selectedPartial_.line = -1;
88
89 if ( selectedRange_.endLine > last_line )
90 selectedRange_.endLine = last_line;
91
92 if ( selectedRange_.startLine > last_line )
93 selectedRange_.startLine = last_line;
94 };
95
getPortionForLine(int line,int * start_column,int * end_column) const96 bool Selection::getPortionForLine( int line, int* start_column, int* end_column ) const
97 {
98 if ( selectedPartial_.line == line ) {
99 *start_column = selectedPartial_.startColumn;
100 *end_column = selectedPartial_.endColumn;
101
102 return true;
103 }
104 else {
105 return false;
106 }
107 }
108
isLineSelected(int line) const109 bool Selection::isLineSelected( int line ) const
110 {
111 if ( line == selectedLine_ )
112 return true;
113 else if ( selectedRange_.startLine >= 0 )
114 return ( ( line >= selectedRange_.startLine )
115 && ( line <= selectedRange_.endLine ) );
116 else
117 return false;
118 }
119
selectedLine() const120 qint64 Selection::selectedLine() const
121 {
122 return selectedLine_;
123 }
124
getLines() const125 QList<int> Selection::getLines() const
126 {
127 QList<int> selection;
128
129 if ( selectedLine_ >= 0 )
130 selection.append( selectedLine_ );
131 else if ( selectedPartial_.line >= 0 )
132 selection.append( selectedPartial_.line );
133 else if ( selectedRange_.startLine >= 0 )
134 for ( int i = selectedRange_.startLine;
135 i <= selectedRange_.endLine; i++ )
136 selection.append( i );
137
138 return selection;
139 }
140
141 // The tab behaviour is a bit odd at the moment, full lines are not expanded
142 // but partials (part of line) are, they probably should not ideally.
getSelectedText(const AbstractLogData * logData) const143 QString Selection::getSelectedText( const AbstractLogData* logData ) const
144 {
145 QString text;
146
147 if ( selectedLine_ >= 0 ) {
148 text = logData->getLineString( selectedLine_ );
149 }
150 else if ( selectedPartial_.line >= 0 ) {
151 text = logData->getExpandedLineString( selectedPartial_.line ).
152 mid( selectedPartial_.startColumn, ( selectedPartial_.endColumn -
153 selectedPartial_.startColumn ) + 1 );
154 }
155 else if ( selectedRange_.startLine >= 0 ) {
156 QStringList list = logData->getLines( selectedRange_.startLine,
157 selectedRange_.endLine - selectedRange_.startLine + 1 );
158 text = list.join( "\n" );
159 }
160
161 return text;
162 }
163
getNextPosition() const164 FilePosition Selection::getNextPosition() const
165 {
166 qint64 line = 0;
167 int column = 0;
168
169 if ( selectedLine_ >= 0 ) {
170 line = selectedLine_ + 1;
171 }
172 else if ( selectedRange_.startLine >= 0 ) {
173 line = selectedRange_.endLine + 1;
174 }
175 else if ( selectedPartial_.line >= 0 ) {
176 line = selectedPartial_.line;
177 column = selectedPartial_.endColumn + 1;
178 }
179
180 return FilePosition( line, column );
181 }
182
getPreviousPosition() const183 FilePosition Selection::getPreviousPosition() const
184 {
185 qint64 line = 0;
186 int column = 0;
187
188 if ( selectedLine_ >= 0 ) {
189 line = selectedLine_;
190 }
191 else if ( selectedRange_.startLine >= 0 ) {
192 line = selectedRange_.startLine;
193 }
194 else if ( selectedPartial_.line >= 0 ) {
195 line = selectedPartial_.line;
196 column = qMax( selectedPartial_.startColumn - 1, 0 );
197 }
198
199 return FilePosition( line, column );
200 }
201