source: ogBrowser-Git/qtermwidget/lib/ScreenWindow.cpp @ 9004d96

jenkinsmain
Last change on this file since 9004d96 was 64efc22, checked in by Vadim Troshchinskiy <vtroshchinskiy@…>, 19 months ago

Update qtermwidget to modern version

  • Property mode set to 100644
File size: 8.5 KB
Line 
1/*
2    Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
3
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.
8
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.
13
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.
18*/
19
20// Own
21#include "ScreenWindow.h"
22
23// Qt
24#include <QtDebug>
25
26// Konsole
27#include "Screen.h"
28
29using namespace Konsole;
30
31ScreenWindow::ScreenWindow(QObject* parent)
32    : QObject(parent)
33    , _screen(nullptr)
34    , _windowBuffer(nullptr)
35    , _windowBufferSize(0)
36    , _bufferNeedsUpdate(true)
37    , _windowLines(1)
38    , _currentLine(0)
39    , _trackOutput(true)
40    , _scrollCount(0)
41{
42}
43ScreenWindow::~ScreenWindow()
44{
45    delete[] _windowBuffer;
46}
47void ScreenWindow::setScreen(Screen* screen)
48{
49    Q_ASSERT( screen );
50
51    _screen = screen;
52}
53
54Screen* ScreenWindow::screen() const
55{
56    return _screen;
57}
58
59Character* ScreenWindow::getImage()
60{
61    // reallocate internal buffer if the window size has changed
62    int size = windowLines() * windowColumns();
63    if (_windowBuffer == nullptr || _windowBufferSize != size)
64    {
65        delete[] _windowBuffer;
66        _windowBufferSize = size;
67        _windowBuffer = new Character[size];
68        _bufferNeedsUpdate = true;
69    }
70
71     if (!_bufferNeedsUpdate)
72        return _windowBuffer;
73
74    _screen->getImage(_windowBuffer,size,
75                      currentLine(),endWindowLine());
76
77    // this window may look beyond the end of the screen, in which
78    // case there will be an unused area which needs to be filled
79    // with blank characters
80    fillUnusedArea();
81
82    _bufferNeedsUpdate = false;
83    return _windowBuffer;
84}
85
86void ScreenWindow::fillUnusedArea()
87{
88    int screenEndLine = _screen->getHistLines() + _screen->getLines() - 1;
89    int windowEndLine = currentLine() + windowLines() - 1;
90
91    int unusedLines = windowEndLine - screenEndLine;
92    int charsToFill = unusedLines * windowColumns();
93
94    Screen::fillWithDefaultChar(_windowBuffer + _windowBufferSize - charsToFill,charsToFill);
95}
96
97// return the index of the line at the end of this window, or if this window
98// goes beyond the end of the screen, the index of the line at the end
99// of the screen.
100//
101// when passing a line number to a Screen method, the line number should
102// never be more than endWindowLine()
103//
104int ScreenWindow::endWindowLine() const
105{
106    return qMin(currentLine() + windowLines() - 1,
107                lineCount() - 1);
108}
109QVector<LineProperty> ScreenWindow::getLineProperties()
110{
111    QVector<LineProperty> result = _screen->getLineProperties(currentLine(),endWindowLine());
112
113    if (result.count() != windowLines())
114        result.resize(windowLines());
115
116    return result;
117}
118
119QString ScreenWindow::selectedText( bool preserveLineBreaks ) const
120{
121    return _screen->selectedText( preserveLineBreaks );
122}
123
124void ScreenWindow::getSelectionStart( int& column , int& line )
125{
126    _screen->getSelectionStart(column,line);
127    line -= currentLine();
128}
129void ScreenWindow::getSelectionEnd( int& column , int& line )
130{
131    _screen->getSelectionEnd(column,line);
132    line -= currentLine();
133}
134void ScreenWindow::setSelectionStart( int column , int line , bool columnMode )
135{
136    _screen->setSelectionStart( column , qMin(line + currentLine(),endWindowLine())  , columnMode);
137
138    _bufferNeedsUpdate = true;
139    emit selectionChanged();
140}
141
142void ScreenWindow::setSelectionEnd( int column , int line )
143{
144    _screen->setSelectionEnd( column , qMin(line + currentLine(),endWindowLine()) );
145
146    _bufferNeedsUpdate = true;
147    emit selectionChanged();
148}
149
150bool ScreenWindow::isSelected( int column , int line )
151{
152    return _screen->isSelected( column , qMin(line + currentLine(),endWindowLine()) );
153}
154
155void ScreenWindow::clearSelection()
156{
157    _screen->clearSelection();
158
159    emit selectionChanged();
160}
161
162void ScreenWindow::setWindowLines(int lines)
163{
164    Q_ASSERT(lines > 0);
165    _windowLines = lines;
166}
167int ScreenWindow::windowLines() const
168{
169    return _windowLines;
170}
171
172int ScreenWindow::windowColumns() const
173{
174    return _screen->getColumns();
175}
176
177int ScreenWindow::lineCount() const
178{
179    return _screen->getHistLines() + _screen->getLines();
180}
181
182int ScreenWindow::columnCount() const
183{
184    return _screen->getColumns();
185}
186
187QPoint ScreenWindow::cursorPosition() const
188{
189    QPoint position;
190
191    position.setX( _screen->getCursorX() );
192    position.setY( _screen->getCursorY() );
193
194    return position;
195}
196
197int ScreenWindow::currentLine() const
198{
199    return qBound(0,_currentLine,lineCount()-windowLines());
200}
201
202void ScreenWindow::scrollBy( RelativeScrollMode mode , int amount )
203{
204    if ( mode == ScrollLines )
205    {
206        scrollTo( currentLine() + amount );
207    }
208    else if ( mode == ScrollPages )
209    {
210        scrollTo( currentLine() + amount * ( windowLines() / 2 ) );
211    }
212}
213
214bool ScreenWindow::atEndOfOutput() const
215{
216    return currentLine() == (lineCount()-windowLines());
217}
218
219void ScreenWindow::scrollTo( int line )
220{
221    int maxCurrentLineNumber = lineCount() - windowLines();
222    line = qBound(0,line,maxCurrentLineNumber);
223
224    const int delta = line - _currentLine;
225    _currentLine = line;
226
227    // keep track of number of lines scrolled by,
228    // this can be reset by calling resetScrollCount()
229    _scrollCount += delta;
230
231    _bufferNeedsUpdate = true;
232
233    emit scrolled(_currentLine);
234}
235
236void ScreenWindow::setTrackOutput(bool trackOutput)
237{
238    _trackOutput = trackOutput;
239}
240
241bool ScreenWindow::trackOutput() const
242{
243    return _trackOutput;
244}
245
246int ScreenWindow::scrollCount() const
247{
248    return _scrollCount;
249}
250
251void ScreenWindow::resetScrollCount()
252{
253    _scrollCount = 0;
254}
255
256QRect ScreenWindow::scrollRegion() const
257{
258    bool equalToScreenSize = windowLines() == _screen->getLines();
259
260    if ( atEndOfOutput() && equalToScreenSize )
261        return _screen->lastScrolledRegion();
262    else
263        return {0,0,windowColumns(),windowLines()};
264}
265
266void ScreenWindow::notifyOutputChanged()
267{
268    // move window to the bottom of the screen and update scroll count
269    // if this window is currently tracking the bottom of the screen
270    if ( _trackOutput )
271    {
272        _scrollCount -= _screen->scrolledLines();
273        _currentLine = qMax(0,_screen->getHistLines() - (windowLines()-_screen->getLines()));
274    }
275    else
276    {
277        // if the history is not unlimited then it may
278        // have run out of space and dropped the oldest
279        // lines of output - in this case the screen
280        // window's current line number will need to
281        // be adjusted - otherwise the output will scroll
282        _currentLine = qMax(0,_currentLine -
283                              _screen->droppedLines());
284
285        // ensure that the screen window's current position does
286        // not go beyond the bottom of the screen
287        _currentLine = qMin( _currentLine , _screen->getHistLines() );
288    }
289
290    _bufferNeedsUpdate = true;
291
292    emit outputChanged();
293}
294
295void ScreenWindow::handleCommandFromKeyboard(KeyboardTranslator::Command command)
296{
297    // Keyboard-based navigation
298    bool update = false;
299
300    // EraseCommand is handled in Vt102Emulation
301    if ( command & KeyboardTranslator::ScrollPageUpCommand )
302    {
303        scrollBy( ScreenWindow::ScrollPages , -1 );
304        update = true;
305    }
306    if ( command & KeyboardTranslator::ScrollPageDownCommand )
307    {
308        scrollBy( ScreenWindow::ScrollPages , 1 );
309        update = true;
310    }
311    if ( command & KeyboardTranslator::ScrollLineUpCommand )
312    {
313        scrollBy( ScreenWindow::ScrollLines , -1 );
314        update = true;
315    }
316    if ( command & KeyboardTranslator::ScrollLineDownCommand )
317    {
318        scrollBy( ScreenWindow::ScrollLines , 1 );
319        update = true;
320    }
321    if ( command & KeyboardTranslator::ScrollDownToBottomCommand )
322    {
323        Q_EMIT scrollToEnd();
324        update = true;
325    }
326    if ( command & KeyboardTranslator::ScrollUpToTopCommand)
327    {
328        scrollTo(0);
329        update = true;
330    }
331    // TODO: KeyboardTranslator::ScrollLockCommand
332    // TODO: KeyboardTranslator::SendCommand
333
334    if ( update )
335    {
336        setTrackOutput( atEndOfOutput() );
337
338        Q_EMIT outputChanged();
339    }
340}
341
342//#include "ScreenWindow.moc"
Note: See TracBrowser for help on using the repository browser.