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