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