MauiKit Terminal

ScreenWindow.cpp
1/*
2 SPDX-FileCopyrightText: 2007 Robert Knight <robertknight@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5
6 This program is distributed in the hope that it will be useful,
7 but WITHOUT ANY WARRANTY; without even the implied warranty of
8 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 GNU General Public License for more details.
10
11 You should have received a copy of the GNU General Public License
12 along with this program; if not, write to the Free Software
13 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
14 02110-1301 USA.
15*/
16
17// Own
18#include "ScreenWindow.h"
19
20// Qt
21#include <QtDebug>
22
23// Konsole
24#include "Screen.h"
25
26using namespace Konsole;
27
29 : QObject(parent)
30 , _screen(nullptr)
31 , _windowBufferSize(0)
32 , _bufferNeedsUpdate(true)
33 , _windowLines(1)
34 , _currentLine(0)
35 , _trackOutput(true)
36 , _scrollCount(0)
37{
38}
39ScreenWindow::~ScreenWindow() = default;
40
42{
43 Q_ASSERT(screen);
44
45 _screen = screen;
46}
47
49{
50 return _screen;
51}
52
53std::span<Character> ScreenWindow::getImage()
54{
55 // reallocate internal buffer if the window size has changed
56 int size = windowLines() * windowColumns();
57 if (_windowBuffer.empty() || _windowBufferSize != size) {
58 _windowBufferSize = size;
59 _windowBuffer = std::vector<Character>(size);
60 _bufferNeedsUpdate = true;
61 }
62
63 if (!_bufferNeedsUpdate)
64 return _windowBuffer;
65
66 _screen->getImage(_windowBuffer, size, currentLine(), endWindowLine());
67
68 // this window may look beyond the end of the screen, in which
69 // case there will be an unused area which needs to be filled
70 // with blank characters
71 fillUnusedArea();
72
73 _bufferNeedsUpdate = false;
74 return _windowBuffer;
75}
76
77void ScreenWindow::fillUnusedArea()
78{
79 int screenEndLine = _screen->getHistLines() + _screen->getLines() - 1;
80 int windowEndLine = currentLine() + windowLines() - 1;
81
82 int unusedLines = windowEndLine - screenEndLine;
83
84 // stop when unusedLines is negative; there is an issue w/ charsToFill
85 // being greater than an int can hold
86 if (unusedLines <= 0) {
87 return;
88 }
89
90 int charsToFill = unusedLines * windowColumns();
91
92 Screen::fillWithDefaultChar(std::span(_windowBuffer).subspan(_windowBufferSize - charsToFill), charsToFill);
93}
94
95// return the index of the line at the end of this window, or if this window
96// goes beyond the end of the screen, the index of the line at the end
97// of the screen.
98//
99// when passing a line number to a Screen method, the line number should
100// never be more than endWindowLine()
101//
102int ScreenWindow::endWindowLine() const
103{
104 return qMin(currentLine() + windowLines() - 1, lineCount() - 1);
105}
107{
108 QVector<LineProperty> result = _screen->getLineProperties(currentLine(), endWindowLine());
109
110 if (result.size() != windowLines())
111 result.resize(windowLines());
112
113 return result;
114}
115
116QString ScreenWindow::selectedText(bool preserveLineBreaks) const
117{
118 return _screen->selectedText(preserveLineBreaks);
119}
120
121void ScreenWindow::getSelectionStart(int &column, int &line)
122{
123 _screen->getSelectionStart(column, line);
124 line -= currentLine();
125}
126void ScreenWindow::getSelectionEnd(int &column, int &line)
127{
128 _screen->getSelectionEnd(column, line);
129 line -= currentLine();
130}
131void ScreenWindow::setSelectionStart(int column, int line, bool columnMode)
132{
133 _screen->setSelectionStart(column, qMin(line + currentLine(), endWindowLine()), columnMode);
134
135 _bufferNeedsUpdate = true;
137}
138
139void ScreenWindow::setSelectionEnd(int column, int line)
140{
141 _screen->setSelectionEnd(column, qMin(line + currentLine(), endWindowLine()));
142
143 _bufferNeedsUpdate = true;
145}
146
147bool ScreenWindow::isSelected(int column, int line)
148{
149 return _screen->isSelected(column, qMin(line + currentLine(), endWindowLine()));
150}
151
153{
154 _screen->clearSelection();
155
157}
158
160{
161 Q_ASSERT(lines > 0);
162 _windowLines = lines;
163}
165{
166 return _windowLines;
167}
168
170{
171 return _screen->getColumns();
172}
173
175{
176 return _screen->getHistLines() + _screen->getLines();
177}
178
180{
181 return _screen->getColumns();
182}
183
185{
186 QPoint position;
187
188 position.setX(_screen->getCursorX());
189 position.setY(_screen->getCursorY());
190
191 return position;
192}
193
195{
196 return qBound(0, _currentLine, lineCount() - windowLines());
197}
198
200{
201 if (mode == ScrollLines) {
202 scrollTo(currentLine() + amount);
203 } else if (mode == ScrollPages) {
204 scrollTo(currentLine() + amount * (windowLines() / 2));
205 }
206}
207
209{
210 return currentLine() == (lineCount() - windowLines());
211}
212
214{
215 int maxCurrentLineNumber = lineCount() - windowLines();
216 line = qBound(0, line, maxCurrentLineNumber);
217
218 const int delta = line - _currentLine;
219 _currentLine = line;
220
221 // keep track of number of lines scrolled by,
222 // this can be reset by calling resetScrollCount()
223 _scrollCount += delta;
224
225 _bufferNeedsUpdate = true;
226
227 Q_EMIT scrolled(_currentLine);
228}
229
230void ScreenWindow::setTrackOutput(bool trackOutput)
231{
232 _trackOutput = trackOutput;
233}
234
236{
237 return _trackOutput;
238}
239
241{
242 return _scrollCount;
243}
244
246{
247 _scrollCount = 0;
248}
249
251{
252 bool equalToScreenSize = windowLines() == _screen->getLines();
253
254 if (atEndOfOutput() && equalToScreenSize)
255 return _screen->lastScrolledRegion();
256 else
257 return {0, 0, windowColumns(), windowLines()};
258}
259
261{
262 // move window to the bottom of the screen and update scroll count
263 // if this window is currently tracking the bottom of the screen
264 if (_trackOutput) {
265 _scrollCount -= _screen->scrolledLines();
266 _currentLine = qMax(0, _screen->getHistLines() - (windowLines() - _screen->getLines()));
267 } else {
268 // if the history is not unlimited then it may
269 // have run out of space and dropped the oldest
270 // lines of output - in this case the screen
271 // window's current line number will need to
272 // be adjusted - otherwise the output will scroll
273 _currentLine = qMax(0, _currentLine - _screen->droppedLines());
274
275 // ensure that the screen window's current position does
276 // not go beyond the bottom of the screen
277 _currentLine = qMin(_currentLine, _screen->getHistLines());
278 }
279
280 _bufferNeedsUpdate = true;
281
283}
284
285void ScreenWindow::handleCommandFromKeyboard(KeyboardTranslator::Command command)
286{
287 // Keyboard-based navigation
288 bool update = false;
289
290 // EraseCommand is handled in Vt102Emulation
293 update = true;
294 }
297 update = true;
298 }
301 update = true;
302 }
305 update = true;
306 }
308 Q_EMIT scrollToEnd();
309 update = true;
310 }
312 scrollTo(0);
313 update = true;
314 }
315 // TODO: KeyboardTranslator::ScrollLockCommand
316 // TODO: KeyboardTranslator::SendCommand
317
318 if (update) {
320
322 }
323}
324
325// #include "ScreenWindow.moc"
Command
This enum describes commands which are associated with particular key sequences.
@ ScrollPageDownCommand
Scroll the terminal display down one page.
@ ScrollDownToBottomCommand
Scroll the terminal display down to the end of history.
@ ScrollUpToTopCommand
Scroll the terminal display up to the start of history.
@ ScrollLineUpCommand
Scroll the terminal display up one line.
@ ScrollPageUpCommand
Scroll the terminal display up one page.
@ ScrollLineDownCommand
Scroll the terminal display down one line.
void setSelectionStart(int column, int line, bool columnMode)
Sets the start of the selection to the given line and column within the window.
void setSelectionEnd(int column, int line)
Sets the end of the selection to the given line and column within the window.
void getSelectionEnd(int &column, int &line)
Retrieves the end of the selection within the window.
RelativeScrollMode
Describes the units which scrollBy() moves the window by.
@ ScrollLines
Scroll the window down by a given number of lines.
@ ScrollPages
Scroll the window down by a given number of pages, where one page is windowLines() lines.
void setTrackOutput(bool trackOutput)
Specifies whether the window should automatically move to the bottom of the screen when new output is...
QRect scrollRegion() const
Returns the area of the window which was last scrolled, this is usually the whole window area.
int windowLines() const
Returns the number of lines in the window.
int currentLine() const
Returns the index of the line which is currently at the top of this window.
bool atEndOfOutput() const
Convenience method.
bool isSelected(int column, int line)
Returns true if the character at line , column is part of the selection.
int lineCount() const
Returns the total number of lines in the screen.
void getSelectionStart(int &column, int &line)
Retrieves the start of the selection within the window.
int columnCount() const
Returns the total number of columns in the screen.
void clearSelection()
Clears the current selection.
QString selectedText(bool preserveLineBreaks) const
Returns the text which is currently selected.
int windowColumns() const
Returns the number of columns in the window.
void selectionChanged()
Emitted when the selection is changed.
bool trackOutput() const
Returns whether the window automatically moves to the bottom of the screen as new output is added.
ScreenWindow(QObject *parent=nullptr)
Constructs a new screen window with the given parent.
void setScreen(Screen *screen)
Sets the screen which this window looks onto.
void notifyOutputChanged()
Notifies the window that the contents of the associated terminal screen have changed.
QPoint cursorPosition() const
Returns the position of the cursor within the window.
void scrollBy(RelativeScrollMode mode, int amount)
Scrolls the window relative to its current position on the screen.
int scrollCount() const
Returns the number of lines which the region of the window specified by scrollRegion() has been scrol...
void scrolled(int line)
Emitted when the screen window is scrolled to a different position.
void scrollTo(int line)
Scrolls the window so that line is at the top of the window.
void resetScrollCount()
Resets the count of scrolled lines returned by scrollCount()
std::span< Character > getImage()
Returns the image of characters which are currently visible through this window onto the screen.
Screen * screen() const
Returns the screen which this window looks onto.
QVector< LineProperty > getLineProperties()
Returns the line attributes associated with the lines of characters which are currently visible throu...
void outputChanged()
Emitted when the contents of the associated terminal screen (see screen()) changes.
void setWindowLines(int lines)
Sets the number of lines in the window.
An image of characters with associated attributes.
Definition Screen.h:70
int getCursorY() const
Returns the line which the cursor is positioned on.
Definition Screen.cpp:828
void getImage(std::span< Character > dest, int size, int startLine, int endLine) const
Returns the current screen image.
Definition Screen.cpp:475
void setSelectionEnd(const int column, const int line)
Sets the end of the current selection.
Definition Screen.cpp:1061
static void fillWithDefaultChar(std::span< Character > dest, int count)
Fills the buffer dest with count instances of the default (ie.
Definition Screen.cpp:1329
void getSelectionStart(int &column, int &line) const
Retrieves the start of the selection or the cursor position if there is no selection.
Definition Screen.cpp:1029
int getHistLines() const
Return the number of lines in the history buffer.
Definition Screen.cpp:1295
void getSelectionEnd(int &column, int &line) const
Retrieves the end of the selection or the cursor position if there is no selection.
Definition Screen.cpp:1039
int getCursorX() const
Returns the column which the cursor is positioned at.
Definition Screen.cpp:823
QRect lastScrolledRegion() const
Returns the region of the image which was last scrolled.
Definition Screen.cpp:746
int getLines() const
Return the number of lines.
Definition Screen.h:385
int scrolledLines() const
Returns the number of lines that the image has been scrolled up or down by, since the last call to re...
Definition Screen.cpp:720
void clearSelection()
Clears the current selection.
Definition Screen.cpp:1022
void setSelectionStart(const int column, const int line, const bool blockSelectionMode)
Sets the start of the selection.
Definition Screen.cpp:1049
bool isSelected(const int column, const int line) const
Returns true if the character at (column, line) is part of the current selection.
Definition Screen.cpp:1092
QVector< LineProperty > getLineProperties(int startLine, int endLine) const
Returns the additional attributes associated with lines in the image.
Definition Screen.cpp:508
int getColumns() const
Return the number of columns.
Definition Screen.h:390
int droppedLines() const
Returns the number of lines of output which have been dropped from the history since the last call to...
Definition Screen.cpp:724
QString selectedText(bool preserveLineBreaks) const
Convenience method.
Definition Screen.cpp:1103
void update(Part *part, const QByteArray &data, qint64 dataSize)
void resize(qsizetype size)
qsizetype size() const const
Q_EMITQ_EMIT
void setX(int x)
void setY(int y)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Aug 30 2024 11:51:42 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.