xref: /glogg/src/selection.cpp (revision c633ced33b4f2c2cf77c0c80a15fa73a7f13ad9f)
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 
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 
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 
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 
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 
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 
96 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 
109 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 
120 qint64 Selection::selectedLine() const
121 {
122     return selectedLine_;
123 }
124 
125 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.
143 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 
164 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 
183 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