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