Changeset View
Changeset View
Standalone View
Standalone View
src/TerminalDisplay.cpp
Show First 20 Lines • Show All 390 Lines • ▼ Show 20 Line(s) | 362 | TerminalDisplay::TerminalDisplay(QWidget* parent) | |||
---|---|---|---|---|---|
391 | , _wordSelectionMode(false) | 391 | , _wordSelectionMode(false) | ||
392 | , _lineSelectionMode(false) | 392 | , _lineSelectionMode(false) | ||
393 | , _preserveLineBreaks(true) | 393 | , _preserveLineBreaks(true) | ||
394 | , _columnSelectionMode(false) | 394 | , _columnSelectionMode(false) | ||
395 | , _autoCopySelectedText(false) | 395 | , _autoCopySelectedText(false) | ||
396 | , _copyTextAsHTML(true) | 396 | , _copyTextAsHTML(true) | ||
397 | , _middleClickPasteMode(Enum::PasteFromX11Selection) | 397 | , _middleClickPasteMode(Enum::PasteFromX11Selection) | ||
398 | , _scrollBar(nullptr) | 398 | , _scrollBar(nullptr) | ||
399 | , _scrollbarLocation(Enum::ScrollBarRight) | | |||
400 | , _scrollFullPage(false) | 399 | , _scrollFullPage(false) | ||
401 | , _wordCharacters(QStringLiteral(":@-./_~")) | 400 | , _wordCharacters(QStringLiteral(":@-./_~")) | ||
402 | , _bellMode(Enum::NotifyBell) | 401 | , _bellMode(Enum::NotifyBell) | ||
403 | , _allowBlinkingText(true) | 402 | , _allowBlinkingText(true) | ||
404 | , _allowBlinkingCursor(false) | 403 | , _allowBlinkingCursor(false) | ||
405 | , _textBlinking(false) | 404 | , _textBlinking(false) | ||
406 | , _cursorBlinking(false) | 405 | , _cursorBlinking(false) | ||
407 | , _hasTextBlinker(false) | 406 | , _hasTextBlinker(false) | ||
Show All 33 Lines | |||||
441 | { | 440 | { | ||
442 | // terminal applications are not designed with Right-To-Left in mind, | 441 | // terminal applications are not designed with Right-To-Left in mind, | ||
443 | // so the layout is forced to Left-To-Right | 442 | // so the layout is forced to Left-To-Right | ||
444 | setLayoutDirection(Qt::LeftToRight); | 443 | setLayoutDirection(Qt::LeftToRight); | ||
445 | 444 | | |||
446 | _contentRect = QRect(_margin, _margin, 1, 1); | 445 | _contentRect = QRect(_margin, _margin, 1, 1); | ||
447 | 446 | | |||
448 | // create scroll bar for scrolling output up and down | 447 | // create scroll bar for scrolling output up and down | ||
449 | _scrollBar = new QScrollBar(this); | 448 | _scrollBar = new TerminalScrollBar(this); | ||
450 | // set the scroll bar's slider to occupy the whole area of the scroll bar initially | 449 | // set the scroll bar's slider to occupy the whole area of the scroll bar initially | ||
451 | setScroll(0, 0); | 450 | _scrollBar->setScroll(0, 0); | ||
452 | _scrollBar->setCursor(Qt::ArrowCursor); | 451 | connect(_scrollBar, &QScrollBar::valueChanged, this, &Konsole::TerminalDisplay::scrollBarValueChanged); | ||
453 | connect(_scrollBar, &QScrollBar::valueChanged, this, &Konsole::TerminalDisplay::scrollBarPositionChanged); | | |||
454 | connect(_scrollBar, &QScrollBar::sliderMoved, this, &Konsole::TerminalDisplay::viewScrolledByUser); | 452 | connect(_scrollBar, &QScrollBar::sliderMoved, this, &Konsole::TerminalDisplay::viewScrolledByUser); | ||
455 | 453 | connect(_scrollBar, &TerminalScrollBar::positionChanged, this, &Konsole::TerminalDisplay::scrollBarPositionChanged); | |||
456 | // setup timers for blinking text | 454 | // setup timers for blinking text | ||
457 | _blinkTextTimer = new QTimer(this); | 455 | _blinkTextTimer = new QTimer(this); | ||
458 | _blinkTextTimer->setInterval(TEXT_BLINK_DELAY); | 456 | _blinkTextTimer->setInterval(TEXT_BLINK_DELAY); | ||
459 | connect(_blinkTextTimer, &QTimer::timeout, this, &Konsole::TerminalDisplay::blinkTextEvent); | 457 | connect(_blinkTextTimer, &QTimer::timeout, this, &Konsole::TerminalDisplay::blinkTextEvent); | ||
460 | 458 | | |||
461 | // setup timers for blinking cursor | 459 | // setup timers for blinking cursor | ||
462 | _blinkCursorTimer = new QTimer(this); | 460 | _blinkCursorTimer = new QTimer(this); | ||
463 | _blinkCursorTimer->setInterval(QApplication::cursorFlashTime() / 2); | 461 | _blinkCursorTimer->setInterval(QApplication::cursorFlashTime() / 2); | ||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Line(s) | 508 | { | |||
515 | delete _outputSuspendedMessageWidget; | 513 | delete _outputSuspendedMessageWidget; | ||
516 | delete[] _image; | 514 | delete[] _image; | ||
517 | delete _filterChain; | 515 | delete _filterChain; | ||
518 | 516 | | |||
519 | _readOnlyMessageWidget = nullptr; | 517 | _readOnlyMessageWidget = nullptr; | ||
520 | _outputSuspendedMessageWidget = nullptr; | 518 | _outputSuspendedMessageWidget = nullptr; | ||
521 | } | 519 | } | ||
522 | 520 | | |||
521 | TerminalScrollBar *TerminalDisplay::scrollBar() const | ||||
522 | { | ||||
523 | return _scrollBar; | ||||
524 | } | ||||
525 | | ||||
523 | /* ------------------------------------------------------------------------- */ | 526 | /* ------------------------------------------------------------------------- */ | ||
524 | /* */ | 527 | /* */ | ||
525 | /* Display Operations */ | 528 | /* Display Operations */ | ||
526 | /* */ | 529 | /* */ | ||
527 | /* ------------------------------------------------------------------------- */ | 530 | /* ------------------------------------------------------------------------- */ | ||
528 | 531 | | |||
529 | /** | 532 | /** | ||
530 | A table for emulating the simple (single width) unicode drawing chars. | 533 | A table for emulating the simple (single width) unicode drawing chars. | ||
▲ Show 20 Lines • Show All 567 Lines • ▼ Show 20 Line(s) | 1063 | { | |||
1098 | // | 1101 | // | ||
1099 | // The right edge must be before the left edge of the scroll bar to | 1102 | // The right edge must be before the left edge of the scroll bar to | ||
1100 | // avoid triggering a repaint of the entire widget, the distance is | 1103 | // avoid triggering a repaint of the entire widget, the distance is | ||
1101 | // given by SCROLLBAR_CONTENT_GAP | 1104 | // given by SCROLLBAR_CONTENT_GAP | ||
1102 | // | 1105 | // | ||
1103 | // Set the QT_FLUSH_PAINT environment variable to '1' before starting the | 1106 | // Set the QT_FLUSH_PAINT environment variable to '1' before starting the | ||
1104 | // application to monitor repainting. | 1107 | // application to monitor repainting. | ||
1105 | // | 1108 | // | ||
1109 | const int scrollBarWidth = _scrollBar->isHidden() ? 0 : _scrollBar->themeAwareWidth(); | ||||
1110 | const int SCROLLBAR_CONTENT_GAP = 1; | ||||
1106 | QRect scrollRect; | 1111 | QRect scrollRect; | ||
1107 | scrollRect.setLeft(0); | 1112 | if (_scrollBar->position() == TerminalScrollBar::Position::Left) { | ||
1113 | scrollRect.setLeft(scrollBarWidth + SCROLLBAR_CONTENT_GAP); | ||||
1108 | scrollRect.setRight(width()); | 1114 | scrollRect.setRight(width()); | ||
1109 | 1115 | } else { | |||
1116 | scrollRect.setLeft(0); | ||||
1117 | scrollRect.setRight(width() - scrollBarWidth - SCROLLBAR_CONTENT_GAP); | ||||
1118 | } | ||||
1110 | void* firstCharPos = &_image[ region.top() * _columns ]; | 1119 | void* firstCharPos = &_image[ region.top() * _columns ]; | ||
1111 | void* lastCharPos = &_image[(region.top() + abs(lines)) * _columns ]; | 1120 | void* lastCharPos = &_image[(region.top() + abs(lines)) * _columns ]; | ||
1112 | 1121 | | |||
1113 | const int top = _contentRect.top() + (region.top() * _fontHeight); | 1122 | const int top = _contentRect.top() + (region.top() * _fontHeight); | ||
1114 | const int linesToMove = region.height() - abs(lines); | 1123 | const int linesToMove = region.height() - abs(lines); | ||
1115 | const int bytesToMove = linesToMove * _columns * sizeof(Character); | 1124 | const int bytesToMove = linesToMove * _columns * sizeof(Character); | ||
1116 | 1125 | | |||
1117 | Q_ASSERT(linesToMove > 0); | 1126 | Q_ASSERT(linesToMove > 0); | ||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Line(s) | 1240 | if (_image == nullptr) { | |||
1233 | // The emitted changedContentSizeSignal also leads to getImage being recreated, so do this first. | 1242 | // The emitted changedContentSizeSignal also leads to getImage being recreated, so do this first. | ||
1234 | updateImageSize(); | 1243 | updateImageSize(); | ||
1235 | } | 1244 | } | ||
1236 | 1245 | | |||
1237 | Character* const newimg = _screenWindow->getImage(); | 1246 | Character* const newimg = _screenWindow->getImage(); | ||
1238 | const int lines = _screenWindow->windowLines(); | 1247 | const int lines = _screenWindow->windowLines(); | ||
1239 | const int columns = _screenWindow->windowColumns(); | 1248 | const int columns = _screenWindow->windowColumns(); | ||
1240 | 1249 | | |||
1241 | setScroll(_screenWindow->currentLine() , _screenWindow->lineCount()); | 1250 | _scrollBar->setScroll(_screenWindow->currentLine() , _screenWindow->lineCount()); | ||
1242 | 1251 | | |||
1243 | Q_ASSERT(_usedLines <= _lines); | 1252 | Q_ASSERT(_usedLines <= _lines); | ||
1244 | Q_ASSERT(_usedColumns <= _columns); | 1253 | Q_ASSERT(_usedColumns <= _columns); | ||
1245 | 1254 | | |||
1246 | int y, x, len; | 1255 | int y, x, len; | ||
1247 | 1256 | | |||
1248 | const QPoint tL = contentsRect().topLeft(); | 1257 | const QPoint tL = contentsRect().topLeft(); | ||
1249 | const int tLx = tL.x(); | 1258 | const int tLx = tL.x(); | ||
▲ Show 20 Lines • Show All 773 Lines • ▼ Show 20 Line(s) | |||||
2023 | { | 2032 | { | ||
2024 | for (int i = 0; i < _imageSize; ++i) { | 2033 | for (int i = 0; i < _imageSize; ++i) { | ||
2025 | _image[i] = Screen::DefaultChar; | 2034 | _image[i] = Screen::DefaultChar; | ||
2026 | } | 2035 | } | ||
2027 | } | 2036 | } | ||
2028 | 2037 | | |||
2029 | void TerminalDisplay::calcGeometry() | 2038 | void TerminalDisplay::calcGeometry() | ||
2030 | { | 2039 | { | ||
2031 | _scrollBar->resize(_scrollBar->sizeHint().width(), contentsRect().height()); | | |||
2032 | _contentRect = contentsRect().adjusted(_margin, _margin, -_margin, -_margin); | 2040 | _contentRect = contentsRect().adjusted(_margin, _margin, -_margin, -_margin); | ||
2033 | 2041 | | |||
2034 | switch (_scrollbarLocation) { | 2042 | _scrollBar->fixGeometry(); | ||
2035 | case Enum::ScrollBarHidden : | 2043 | | ||
2044 | switch (_scrollBar->position()) { | ||||
2045 | case TerminalScrollBar::Position::Hidden: | ||||
2036 | break; | 2046 | break; | ||
2037 | case Enum::ScrollBarLeft : | 2047 | case TerminalScrollBar::Position::Left : | ||
2038 | _scrollBar->move(contentsRect().topLeft()); | 2048 | _contentRect.setLeft(_contentRect.left() + _scrollBar->themeAwareWidth()); | ||
2039 | break; | 2049 | break; | ||
2040 | case Enum::ScrollBarRight: | 2050 | case TerminalScrollBar::Position::Right: | ||
2041 | _scrollBar->move(contentsRect().topRight() - QPoint(_scrollBar->width() - 1, 0)); | 2051 | _contentRect.setRight(_contentRect.right() - _scrollBar->themeAwareWidth()); | ||
2042 | break; | 2052 | break; | ||
2043 | } | 2053 | } | ||
2044 | 2054 | | |||
2045 | // ensure that display is always at least one column wide | 2055 | // ensure that display is always at least one column wide | ||
2046 | _columns = qMax(1, _contentRect.width() / _fontWidth); | 2056 | _columns = qMax(1, _contentRect.width() / _fontWidth); | ||
2047 | _usedColumns = qMin(_usedColumns, _columns); | 2057 | _usedColumns = qMin(_usedColumns, _columns); | ||
2048 | 2058 | | |||
2049 | // ensure that display is always at least one line high | 2059 | // ensure that display is always at least one line high | ||
2050 | _lines = qMax(1, _contentRect.height() / _fontHeight); | 2060 | _lines = qMax(1, _contentRect.height() / _fontHeight); | ||
2051 | _usedLines = qMin(_usedLines, _lines); | 2061 | _usedLines = qMin(_usedLines, _lines); | ||
2052 | 2062 | | |||
2063 | scrollBar()->setLines(_lines); | ||||
2064 | | ||||
2053 | if(_centerContents) { | 2065 | if(_centerContents) { | ||
2054 | QSize unusedPixels = _contentRect.size() - QSize(_columns * _fontWidth, _lines * _fontHeight); | 2066 | QSize unusedPixels = _contentRect.size() - QSize(_columns * _fontWidth, _lines * _fontHeight); | ||
2055 | _contentRect.adjust(unusedPixels.width() / 2, unusedPixels.height() / 2, 0, 0); | 2067 | _contentRect.adjust(unusedPixels.width() / 2, unusedPixels.height() / 2, 0, 0); | ||
2056 | } | 2068 | } | ||
2057 | } | 2069 | } | ||
2058 | 2070 | | |||
2059 | // calculate the needed size, this must be synced with calcGeometry() | 2071 | // calculate the needed size, this must be synced with calcGeometry() | ||
2060 | void TerminalDisplay::setSize(int columns, int lines) | 2072 | void TerminalDisplay::setSize(int columns, int lines) | ||
2061 | { | 2073 | { | ||
2074 | const int scrollBarWidth = _scrollBar->isHidden() ? 0 : _scrollBar->themeAwareWidth(); | ||||
2062 | const int horizontalMargin = _margin * 2; | 2075 | const int horizontalMargin = _margin * 2; | ||
2063 | const int verticalMargin = _margin * 2; | 2076 | const int verticalMargin = _margin * 2; | ||
2064 | 2077 | | |||
2065 | QSize newSize = QSize(horizontalMargin + (columns * _fontWidth) , | 2078 | QSize newSize = QSize(horizontalMargin + scrollBarWidth + (columns * _fontWidth) , | ||
2066 | verticalMargin + (lines * _fontHeight)); | 2079 | verticalMargin + (lines * _fontHeight)); | ||
2067 | 2080 | | |||
2068 | if (newSize != size()) { | 2081 | if (newSize != size()) { | ||
2069 | _size = newSize; | 2082 | _size = newSize; | ||
2070 | updateGeometry(); | 2083 | updateGeometry(); | ||
2071 | } | 2084 | } | ||
2072 | } | 2085 | } | ||
2073 | 2086 | | |||
Show All 33 Lines | |||||
2107 | } | 2120 | } | ||
2108 | 2121 | | |||
2109 | /* ------------------------------------------------------------------------- */ | 2122 | /* ------------------------------------------------------------------------- */ | ||
2110 | /* */ | 2123 | /* */ | ||
2111 | /* Scrollbar */ | 2124 | /* Scrollbar */ | ||
2112 | /* */ | 2125 | /* */ | ||
2113 | /* ------------------------------------------------------------------------- */ | 2126 | /* ------------------------------------------------------------------------- */ | ||
2114 | 2127 | | |||
2115 | void TerminalDisplay::setScrollBarPosition(Enum::ScrollBarPositionEnum position) | 2128 | void TerminalDisplay::scrollBarPositionChanged(TerminalScrollBar::Position position) | ||
2116 | { | 2129 | { | ||
2117 | if (_scrollbarLocation == position) { | 2130 | Q_UNUSED(position); | ||
2118 | return; | | |||
2119 | } | | |||
2120 | | ||||
2121 | if (position == Enum::ScrollBarHidden) { | | |||
2122 | _scrollBar->hide(); | | |||
2123 | } else if (_scrollBar->maximum() != 0) { | | |||
2124 | _scrollBar->show(); | | |||
2125 | } | | |||
2126 | | ||||
2127 | _scrollbarLocation = position; | | |||
2128 | | ||||
2129 | propagateSize(); | 2131 | propagateSize(); | ||
2130 | update(); | 2132 | update(); | ||
2131 | } | 2133 | } | ||
2132 | 2134 | | |||
2133 | void TerminalDisplay::scrollBarPositionChanged(int) | 2135 | void TerminalDisplay::scrollBarValueChanged(int) | ||
2134 | { | 2136 | { | ||
2135 | if (_screenWindow.isNull()) { | 2137 | if (_screenWindow.isNull()) { | ||
2136 | return; | 2138 | return; | ||
2137 | } | 2139 | } | ||
2138 | 2140 | | |||
2139 | _screenWindow->scrollTo(_scrollBar->value()); | 2141 | _screenWindow->scrollTo(_scrollBar->value()); | ||
2140 | 2142 | | |||
2141 | // if the thumb has been moved to the bottom of the _scrollBar then set | 2143 | // if the thumb has been moved to the bottom of the _scrollBar then set | ||
2142 | // the display to automatically track new output, | 2144 | // the display to automatically track new output, | ||
2143 | // that is, scroll down automatically | 2145 | // that is, scroll down automatically | ||
2144 | // to how new _lines as they are added | 2146 | // to how new _lines as they are added | ||
2145 | const bool atEndOfOutput = (_scrollBar->value() == _scrollBar->maximum()); | 2147 | const bool atEndOfOutput = (_scrollBar->value() == _scrollBar->maximum()); | ||
2146 | _screenWindow->setTrackOutput(atEndOfOutput); | 2148 | _screenWindow->setTrackOutput(atEndOfOutput); | ||
2147 | 2149 | | |||
2148 | updateImage(); | 2150 | updateImage(); | ||
2149 | } | 2151 | } | ||
2150 | 2152 | | |||
2151 | void TerminalDisplay::setScroll(int cursor, int slines) | | |||
2152 | { | | |||
2153 | // update _scrollBar if the range or value has changed, | | |||
2154 | // otherwise return | | |||
2155 | // | | |||
2156 | // setting the range or value of a _scrollBar will always trigger | | |||
2157 | // a repaint, so it should be avoided if it is not necessary | | |||
2158 | | ||||
2159 | if (_scrollBar->maximum() == 0 && _scrollBar->value() == cursor) { | | |||
2160 | // hide the scrollbar if it's not needed | | |||
2161 | _scrollBar->hide(); | | |||
2162 | return; | | |||
2163 | | ||||
2164 | } else if (_scrollbarLocation != Enum::ScrollBarHidden){ | | |||
2165 | _scrollBar->show(); | | |||
2166 | } | | |||
2167 | | ||||
2168 | disconnect(_scrollBar, &QScrollBar::valueChanged, this, &Konsole::TerminalDisplay::scrollBarPositionChanged); | | |||
2169 | _scrollBar->setRange(0, slines - _lines); | | |||
2170 | _scrollBar->setSingleStep(1); | | |||
2171 | _scrollBar->setPageStep(_lines); | | |||
2172 | _scrollBar->setValue(cursor); | | |||
2173 | connect(_scrollBar, &QScrollBar::valueChanged, this, &Konsole::TerminalDisplay::scrollBarPositionChanged); | | |||
2174 | } | | |||
2175 | | ||||
2176 | void TerminalDisplay::setScrollFullPage(bool fullPage) | 2153 | void TerminalDisplay::setScrollFullPage(bool fullPage) | ||
2177 | { | 2154 | { | ||
2178 | _scrollFullPage = fullPage; | 2155 | _scrollFullPage = fullPage; | ||
2179 | } | 2156 | } | ||
2180 | 2157 | | |||
2181 | bool TerminalDisplay::scrollFullPage() const | 2158 | bool TerminalDisplay::scrollFullPage() const | ||
2182 | { | 2159 | { | ||
2183 | return _scrollFullPage; | 2160 | return _scrollFullPage; | ||
▲ Show 20 Lines • Show All 1748 Lines • Show Last 20 Lines |