Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / konsole / src / ScreenWindow.cpp
blob75ea68982a2fe4e8152c013181a2942edaacfde6
1 /*
2 Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301 USA.
20 // Own
21 #include "ScreenWindow.h"
23 // Qt
24 #include <KDebug>
26 // Konsole
27 #include "Screen.h"
29 using namespace Konsole;
31 ScreenWindow::ScreenWindow(QObject* parent)
32 : QObject(parent)
33 , _windowBuffer(0)
34 , _windowBufferSize(0)
35 , _bufferNeedsUpdate(true)
36 , _windowLines(1)
37 , _currentLine(0)
38 , _trackOutput(true)
39 , _scrollCount(0)
42 ScreenWindow::~ScreenWindow()
44 delete[] _windowBuffer;
46 void ScreenWindow::setScreen(Screen* screen)
48 Q_ASSERT( screen );
50 _screen = screen;
53 Screen* ScreenWindow::screen() const
55 return _screen;
58 Character* ScreenWindow::getImage()
60 // reallocate internal buffer if the window size has changed
61 int size = windowLines() * windowColumns();
62 if (_windowBuffer == 0 || _windowBufferSize != size)
64 delete[] _windowBuffer;
65 _windowBufferSize = size;
66 _windowBuffer = new Character[size];
67 _bufferNeedsUpdate = true;
70 if (!_bufferNeedsUpdate)
71 return _windowBuffer;
73 _screen->getImage(_windowBuffer,size,
74 currentLine(),endWindowLine());
76 // this window may look beyond the end of the screen, in which
77 // case there will be an unused area which needs to be filled
78 // with blank characters
79 fillUnusedArea();
81 _bufferNeedsUpdate = false;
82 return _windowBuffer;
85 void ScreenWindow::fillUnusedArea()
87 int screenEndLine = _screen->getHistLines() + _screen->getLines() - 1;
88 int windowEndLine = currentLine() + windowLines() - 1;
90 int unusedLines = windowEndLine - screenEndLine;
91 int charsToFill = unusedLines * windowColumns();
93 Screen::fillWithDefaultChar(_windowBuffer + _windowBufferSize - charsToFill,charsToFill);
96 // return the index of the line at the end of this window, or if this window
97 // goes beyond the end of the screen, the index of the line at the end
98 // of the screen.
100 // when passing a line number to a Screen method, the line number should
101 // never be more than endWindowLine()
103 int ScreenWindow::endWindowLine() const
105 return qMin(currentLine() + windowLines() - 1,
106 lineCount() - 1);
108 QVector<LineProperty> ScreenWindow::getLineProperties()
110 QVector<LineProperty> result = _screen->getLineProperties(currentLine(),endWindowLine());
112 if (result.count() != windowLines())
113 result.resize(windowLines());
115 return result;
118 QString ScreenWindow::selectedText( bool preserveLineBreaks ) const
120 return _screen->selectedText( preserveLineBreaks );
123 void ScreenWindow::getSelectionStart( int& column , int& line )
125 _screen->getSelectionStart(column,line);
126 line -= currentLine();
128 void ScreenWindow::getSelectionEnd( int& column , int& line )
130 _screen->getSelectionEnd(column,line);
131 line -= currentLine();
133 void ScreenWindow::setSelectionStart( int column , int line , bool columnMode )
135 _screen->setSelectionStart( column , qMin(line + currentLine(),endWindowLine()) , columnMode);
137 _bufferNeedsUpdate = true;
138 emit selectionChanged();
141 void ScreenWindow::setSelectionEnd( int column , int line )
143 _screen->setSelectionEnd( column , qMin(line + currentLine(),endWindowLine()) );
145 _bufferNeedsUpdate = true;
146 emit selectionChanged();
149 bool ScreenWindow::isSelected( int column , int line )
151 return _screen->isSelected( column , qMin(line + currentLine(),endWindowLine()) );
154 void ScreenWindow::clearSelection()
156 _screen->clearSelection();
158 emit selectionChanged();
161 void ScreenWindow::setWindowLines(int lines)
163 Q_ASSERT(lines > 0);
164 _windowLines = lines;
166 int ScreenWindow::windowLines() const
168 return _windowLines;
171 int ScreenWindow::windowColumns() const
173 return _screen->getColumns();
176 int ScreenWindow::lineCount() const
178 return _screen->getHistLines() + _screen->getLines();
181 int ScreenWindow::columnCount() const
183 return _screen->getColumns();
186 QPoint ScreenWindow::cursorPosition() const
188 QPoint position;
190 position.setX( _screen->getCursorX() );
191 position.setY( _screen->getCursorY() );
193 return position;
196 int ScreenWindow::currentLine() const
198 return qBound(0,_currentLine,lineCount()-windowLines());
201 void ScreenWindow::scrollBy( RelativeScrollMode mode , int amount )
203 if ( mode == ScrollLines )
205 scrollTo( currentLine() + amount );
207 else if ( mode == ScrollPages )
209 scrollTo( currentLine() + amount * ( windowLines() / 2 ) );
213 bool ScreenWindow::atEndOfOutput() const
215 return currentLine() == (lineCount()-windowLines());
218 void ScreenWindow::scrollTo( int line )
220 int maxCurrentLineNumber = lineCount() - windowLines();
221 line = qBound(0,line,maxCurrentLineNumber);
223 const int delta = line - _currentLine;
224 _currentLine = line;
226 // keep track of number of lines scrolled by,
227 // this can be reset by calling resetScrollCount()
228 _scrollCount += delta;
230 _bufferNeedsUpdate = true;
232 emit scrolled(_currentLine);
235 void ScreenWindow::setTrackOutput(bool trackOutput)
237 _trackOutput = trackOutput;
240 bool ScreenWindow::trackOutput() const
242 return _trackOutput;
245 int ScreenWindow::scrollCount() const
247 return _scrollCount;
250 void ScreenWindow::resetScrollCount()
252 _scrollCount = 0;
255 QRect ScreenWindow::scrollRegion() const
257 bool equalToScreenSize = windowLines() == _screen->getLines();
259 if ( atEndOfOutput() && equalToScreenSize )
260 return _screen->lastScrolledRegion();
261 else
262 return QRect(0,0,windowColumns(),windowLines());
265 void ScreenWindow::notifyOutputChanged()
267 // move window to the bottom of the screen and update scroll count
268 // if this window is currently tracking the bottom of the screen
269 if ( _trackOutput )
271 _scrollCount -= _screen->scrolledLines();
272 _currentLine = qMax(0,_screen->getHistLines() - (windowLines()-_screen->getLines()));
274 else
276 // if the history is not unlimited then it may
277 // have run out of space and dropped the oldest
278 // lines of output - in this case the screen
279 // window's current line number will need to
280 // be adjusted - otherwise the output will scroll
281 _currentLine = qMax(0,_currentLine -
282 _screen->droppedLines());
284 // ensure that the screen window's current position does
285 // not go beyond the bottom of the screen
286 _currentLine = qMin( _currentLine , _screen->getHistLines() );
289 _bufferNeedsUpdate = true;
291 emit outputChanged();
294 #include "ScreenWindow.moc"