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
21 #include "ScreenWindow.h"
29 using namespace Konsole
;
31 ScreenWindow::ScreenWindow(QObject
* parent
)
34 , _windowBufferSize(0)
35 , _bufferNeedsUpdate(true)
42 ScreenWindow::~ScreenWindow()
44 delete[] _windowBuffer
;
46 void ScreenWindow::setScreen(Screen
* screen
)
53 Screen
* ScreenWindow::screen() const
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
)
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
81 _bufferNeedsUpdate
= false;
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
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,
108 QVector
<LineProperty
> ScreenWindow::getLineProperties()
110 QVector
<LineProperty
> result
= _screen
->getLineProperties(currentLine(),endWindowLine());
112 if (result
.count() != windowLines())
113 result
.resize(windowLines());
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
)
164 _windowLines
= lines
;
166 int ScreenWindow::windowLines() const
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
190 position
.setX( _screen
->getCursorX() );
191 position
.setY( _screen
->getCursorY() );
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
;
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
245 int ScreenWindow::scrollCount() const
250 void ScreenWindow::resetScrollCount()
255 QRect
ScreenWindow::scrollRegion() const
257 bool equalToScreenSize
= windowLines() == _screen
->getLines();
259 if ( atEndOfOutput() && equalToScreenSize
)
260 return _screen
->lastScrolledRegion();
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
271 _scrollCount
-= _screen
->scrolledLines();
272 _currentLine
= qMax(0,_screen
->getHistLines() - (windowLines()-_screen
->getLines()));
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"