diff --git a/src/Screen.cpp b/src/Screen.cpp index 2d147821aeed576ee6bfc8b23558354ef01b1ded..62d2ee1dfc341e6f936e7235b31e5aea36cd07a3 100644 --- a/src/Screen.cpp +++ b/src/Screen.cpp @@ -11,6 +11,7 @@ // Qt #include #include +#include // Konsole decoders #include @@ -47,11 +48,13 @@ Screen::Screen(int lines, int columns): _currentTerminalDisplay(nullptr), _lines(lines), _columns(columns), - _screenLines(new ImageLine[_lines + 1]), + _screenLines(_lines + 1), _screenLinesSize(_lines), _scrolledLines(0), _lastScrolledRegion(QRect()), _droppedLines(0), + _oldTotalLines(0), + _isResize(false), _lineProperties(QVarLengthArray()), _history(new HistoryScrollNone()), _cuX(0), @@ -86,7 +89,6 @@ Screen::Screen(int lines, int columns): Screen::~Screen() { - delete[] _screenLines; delete _history; delete _escapeSequenceUrlExtractor; } @@ -367,47 +369,195 @@ void Screen::restoreCursor() updateEffectiveRendition(); } +int Screen::getOldTotalLines() +{ + return _oldTotalLines; +} + +bool Screen::isResize() +{ + if (_isResize) { + _isResize = false; + return true; + } + return _isResize; +} + +// Not to production auxiliar functions to show what is written in screen or history +void toDebug(const Character s[], int count, bool wrapped = false) { + QString out; + for (int i = 0; i < count; i++) { + out += s[i].character; + } + qDebug() << out << (wrapped? " wrapped" : ""); +} +void toDebug(const QVector &s, bool wrapped = false) { + toDebug(s.data(), s.size(), wrapped); +} +///// + +int Screen::getCursorLine() +{ + if (_currentModes[MODE_AppScreen] == 1) { + return _savedState.cursorLine; + } + return _cuY; +} + +void Screen::setCursorLine(int newLine) +{ + if (_currentModes[MODE_AppScreen] == 1) { + _savedState.cursorLine = newLine; + } else { + _cuY = newLine; + } +} + void Screen::resizeImage(int new_lines, int new_columns) { if ((new_lines == _lines) && (new_columns == _columns)) { return; } - if (_cuY > new_lines - 1) { - // attempt to preserve focus and _lines - _bottomMargin = _lines - 1; //FIXME: margin lost - for (int i = 0; i < _cuY - (new_lines - 1); i++) { - addHistLine(); - scrollUp(0, 1); + // Adjust scroll position, and fix glitches + _oldTotalLines = getLines() + getHistLines(); + _isResize = true; + + int cursorLine = getCursorLine(); + const int oldCursorLine = (cursorLine == _lines -1)? new_lines - 1 : cursorLine; + + // First join everything. + int currentPos = 0; + while (currentPos < cursorLine && currentPos < _screenLines.count() - 1) { + // if the line have the 'LINE_WRAPPED' property, concat with the next line and remove it. + if ((_lineProperties[currentPos] & LINE_WRAPPED) != 0) { + _screenLines[currentPos].append(_screenLines[currentPos + 1]); + _screenLines.remove(currentPos + 1); + _lineProperties.remove(currentPos); + cursorLine--; + continue; + } + currentPos++; + } + // Then move the data to lines below. + currentPos = 0; + while (currentPos < cursorLine && currentPos < _screenLines.count()) { + // Ignore whitespaces at the end of the line + int lineSize = _screenLines[currentPos].size(); + while (lineSize > 0 && QChar(_screenLines[currentPos][lineSize - 1].character).isSpace()) { + lineSize--; + } + const bool shouldCopy = lineSize > new_columns; + + // Copy from the current line, to the next one. + if (shouldCopy) { + auto values = _screenLines[currentPos].mid(new_columns); + _screenLines[currentPos].remove(new_columns, values.size()); + _lineProperties.insert(currentPos + 1, _lineProperties[currentPos]); + _screenLines.insert(currentPos + 1, values); + _lineProperties[currentPos] |= LINE_WRAPPED; + cursorLine++; + } + currentPos += 1; + } + // Check if it need to move from _screenLine to _history + while (cursorLine > new_lines - 1) { + fastAddHistLine(); + cursorLine--; + } + _lineProperties.resize(new_lines + 1); + _screenLines.resize(new_lines + 1); + + // Check if _history need to change + if (new_columns != _columns && _history->getLines()) { + // Join next line from _screenLine to _history + while (_history->isWrappedLine(_history->getLines() - 1)) { + fastAddHistLine(); + cursorLine--; + } + currentPos = 0; + // Join everything in _history + while (currentPos < _history->getLines() - 1) { + // if it's true, join the line with next line + if (_history->isWrappedLine(currentPos)) { + int curr_linelen = _history->getLineLen(currentPos); + int next_linelen = _history->getLineLen(currentPos + 1); + auto *new_line = getCharacterBuffer(curr_linelen + next_linelen); + bool new_line_property = _history->isWrappedLine(currentPos + 1); + + // Join the lines + _history->getCells(currentPos, 0, curr_linelen, new_line); + _history->getCells(currentPos + 1, 0, next_linelen, new_line + curr_linelen); + + // save the new_line in history and remove the next line + _history->setCellsAt(currentPos, new_line, curr_linelen + next_linelen); + _history->setLineAt(currentPos, new_line_property); + _history->removeCells(currentPos + 1); + continue; + } + currentPos++; + } + // Now move data to next line if needed + currentPos = 0; + while (currentPos < _history->getLines()) { + int curr_linelen = _history->getLineLen(currentPos); + + // if the current line > new_columns it will need a new line + if (curr_linelen > new_columns) { + bool removeLine = _history->getLines() == _history->getMaxLines(); + auto *curr_line = getCharacterBuffer(curr_linelen); + bool curr_line_property = _history->isWrappedLine(currentPos); + _history->getCells(currentPos, 0, curr_linelen, curr_line); + + _history->setCellsAt(currentPos, curr_line, new_columns); + _history->setLineAt(currentPos, true); + if (currentPos < _history->getMaxLines() - 1) { + _history->insertCells(currentPos + 1, curr_line + new_columns, curr_linelen - new_columns); + _history->setLineAt(currentPos + 1, curr_line_property); + } else { + _history->addCells(curr_line + new_columns, curr_linelen - new_columns); + _history->addLine(curr_line_property); + } + // If _history size > max history size it will drop a line from _history. + // We need to verify if we need to remove a URL. + if (removeLine) { + _escapeSequenceUrlExtractor->historyLinesRemoved(1); + } + } + currentPos++; } } - // create new screen _lines and copy from old to new - - auto newScreenLines = new ImageLine[new_lines + 1]; - for (int i = 0; i < qMin(_lines, new_lines + 1) ; i++) { - newScreenLines[i] = _screenLines[i]; + // Check cursor position and send from _history to _screenLines + ImageLine histLine; + histLine.reserve(1024); + while (cursorLine < oldCursorLine && _history->getLines()) { + int histPos = _history->getLines() - 1; + int histLineLen = _history->getLineLen(histPos); + int isWrapped = _history->isWrappedLine(histPos)? LINE_WRAPPED : LINE_DEFAULT; + histLine.resize(histLineLen); + _history->getCells(histPos, 0, histLineLen, histLine.data()); + _screenLines.insert(0, histLine); + _lineProperties.insert(0, isWrapped); + _history->removeCells(histPos); + cursorLine++; } _lineProperties.resize(new_lines + 1); - for (int i = _lines; (i > 0) && (i < new_lines + 1); i++) { + for (int i = _screenLines.count(); (i > 0) && (i < new_lines + 1); i++) { _lineProperties[i] = LINE_DEFAULT; } + _screenLines.resize(new_lines + 1); - clearSelection(); - - delete[] _screenLines; - _screenLines = newScreenLines; _screenLinesSize = new_lines; - _lines = new_lines; _columns = new_columns; _cuX = qMin(_cuX, _columns - 1); - _cuY = qMin(_cuY, _lines - 1); + cursorLine = qBound(0, cursorLine, _lines - 1); + setCursorLine(cursorLine); // FIXME: try to keep values, evtl. - _topMargin = 0; - _bottomMargin = _lines - 1; + setDefaultMargins(); initTabStops(); clearSelection(); } @@ -1385,7 +1535,7 @@ int Screen::copyLineToStream(int line , screenLine = qMin(screenLine, _screenLinesSize); - Character* data = _screenLines[screenLine].data(); + auto* data = _screenLines[screenLine].data(); int length = _screenLines[screenLine].count(); // Don't remove end spaces in lines that wrap @@ -1457,26 +1607,82 @@ void Screen::writeLinesToStream(TerminalCharacterDecoder* decoder, int fromLine, writeToStream(decoder, loc(0, fromLine), loc(_columns - 1, toLine), PreserveLineBreaks); } +void Screen::fastAddHistLine() +{ + const bool removeLine = _history->getLines() == _history->getMaxLines(); + _history->addCellsVector(_screenLines[0]); + _history->addLine((_lineProperties[0] & LINE_WRAPPED) != 0); + + // If _history size > max history size it will drop a line from _history. + // We need to verify if we need to remove a URL. + if (removeLine) { + _escapeSequenceUrlExtractor->historyLinesRemoved(1); + } + + _screenLines.pop_front(); + _lineProperties.remove(0); +} + void Screen::addHistLine() { // add line to history buffer // we have to take care about scrolling, too... const int oldHistLines = _history->getLines(); + int newHistLines = _history->getLines(); + if (hasScroll()) { + // Check if _history have 'new line' property and join lines before adding a new one to history + if (oldHistLines > 0 && _history->isWrappedLine(oldHistLines - 1)) { + int hist_linelen = _history->getLineLen(oldHistLines - 1); + auto *hist_line = getCharacterBuffer(hist_linelen + _screenLines[0].count()); + _history->getCells(oldHistLines - 1, 0, hist_linelen, hist_line); + + // Join the new line into the old line + for (int i = 0; i < _screenLines[0].count(); i++) { + hist_line[hist_linelen + i] = _screenLines[0][i]; + } + hist_linelen += _screenLines[0].count(); - _history->addCellsVector(_screenLines[0]); - _history->addLine((_lineProperties[0] & LINE_WRAPPED) != 0); + // After join, check if it needs new line in history to show it on scroll + if (hist_linelen > _columns) { + _history->setCellsAt(oldHistLines - 1, hist_line, _columns); + _history->setLineAt(oldHistLines - 1, true); + _history->addCells(hist_line + _columns, hist_linelen - _columns); + _history->addLine((_lineProperties[0] & LINE_WRAPPED) != 0); - const int newHistLines = _history->getLines(); + newHistLines = _history->getLines(); - const bool beginIsTL = (_selBegin == _selTopLeft); + // If the history is full, increment the count + // of dropped _lines + if (newHistLines == oldHistLines) { + _droppedLines++; + + // We removed a line, we need to verify if we need to remove a URL. + _escapeSequenceUrlExtractor->historyLinesRemoved(1); + } + } else { + // Doesn't need a new line + _history->setCellsAt(oldHistLines - 1, hist_line, hist_linelen); + _history->setLineAt(oldHistLines - 1, (_lineProperties[0] & LINE_WRAPPED) != 0); + } + } else { + _history->addCellsVector(_screenLines[0]); + _history->addLine((_lineProperties[0] & LINE_WRAPPED) != 0); + + newHistLines = _history->getLines(); - // If the history is full, increment the count - // of dropped _lines - if (newHistLines == oldHistLines) { - _droppedLines++; + // If the history is full, increment the count + // of dropped _lines + if (newHistLines == oldHistLines) { + _droppedLines++; + + // We removed a line, we need to verify if we need to remove a URL. + _escapeSequenceUrlExtractor->historyLinesRemoved(1); + } } + bool beginIsTL = (_selBegin == _selTopLeft); + // Adjust selection for the new point of reference if (newHistLines > oldHistLines) { if (_selBegin != -1) { @@ -1512,12 +1718,6 @@ void Screen::addHistLine() } } } - - // We removed a line, we need to verify if we need to remove a URL. - const int newHistLines = _history->getLines(); - if (oldHistLines == newHistLines) { - _escapeSequenceUrlExtractor->historyLinesRemoved(1); - } } int Screen::getHistLines() const diff --git a/src/Screen.h b/src/Screen.h index d90ea94f3065e522d477726da456cae68ecb51ca..28af05005dc13decac7b4c29758670403eb45e8d 100644 --- a/src/Screen.h +++ b/src/Screen.h @@ -25,7 +25,8 @@ #define MODE_Screen 3 #define MODE_Cursor 4 #define MODE_NewLine 5 -#define MODES_SCREEN 6 +#define MODE_AppScreen 6 +#define MODES_SCREEN 7 namespace Konsole { class TerminalCharacterDecoder; @@ -588,6 +589,11 @@ public: static const Character DefaultChar; + // Return the total number of lines before resize (fix scroll glitch) + int getOldTotalLines(); + // Return if it was a resize signal (fix scroll glitch) + bool isResize(); + private: //copies a line of text from the screen or history into a stream using a //specified character decoder. Returns the number of lines actually copied, @@ -623,6 +629,8 @@ private: TerminalDisplay *_currentTerminalDisplay; void addHistLine(); + // add lines from _screen to _history and remove from _screen the added lines (used to resize lines and columns) + void fastAddHistLine(); void initTabStops(); @@ -646,6 +654,11 @@ private: // should be as minimal as possible static Character *getCharacterBuffer(const int size); + // Get the cursor line after checking if its app mode or not + int getCursorLine(); + // Set the cursor line after checking if its app mode or not + void setCursorLine (int newLine); + int getLineLength(const int line) const; // screen image ---------------- @@ -653,7 +666,7 @@ private: int _columns; typedef QVector ImageLine; // [0..columns] - ImageLine *_screenLines; // [lines] + QVector _screenLines; // [lines] int _screenLinesSize; // _screenLines.size() int _scrolledLines; @@ -661,6 +674,9 @@ private: int _droppedLines; + int _oldTotalLines; + bool _isResize; + QVarLengthArray _lineProperties; // history buffer --------------- diff --git a/src/ScreenWindow.cpp b/src/ScreenWindow.cpp index 5ff0d245e2e314be3f13817064b1be614b4e78b7..5aa8f1c82868981207afca9135b1c103dad52975 100644 --- a/src/ScreenWindow.cpp +++ b/src/ScreenWindow.cpp @@ -290,10 +290,21 @@ QRect ScreenWindow::scrollRegion() const if (atEndOfOutput() && equalToScreenSize) { return _screen->lastScrolledRegion(); - } + } return {0, 0, windowColumns(), windowLines()}; } +void ScreenWindow::updateCurrentLine() +{ + if (!_screen->isResize()) { + return; + } + if (_currentLine > 0) { + _currentLine -= _screen->getOldTotalLines() - lineCount(); + } + _currentLine = qBound(0, _currentLine, lineCount() - windowLines()); +} + void ScreenWindow::notifyOutputChanged() { // move window to the bottom of the screen and update scroll count diff --git a/src/ScreenWindow.h b/src/ScreenWindow.h index 29ffc3669aca0821eec79330f64e58f23e065c9c..445cd50c600052d74dac7240a0c544272359c5c4 100644 --- a/src/ScreenWindow.h +++ b/src/ScreenWindow.h @@ -218,6 +218,8 @@ public: */ QString selectedText(const Screen::DecodingOptions options) const; + void updateCurrentLine(); + public Q_SLOTS: /** * Notifies the window that the contents of the associated terminal screen have changed. diff --git a/src/Vt102Emulation.cpp b/src/Vt102Emulation.cpp index e048f8ed23ec843baea1afb7cec7cee9dfa4e128..2cdbc6d321cd1b634c600f8edecd90791b0254c3 100644 --- a/src/Vt102Emulation.cpp +++ b/src/Vt102Emulation.cpp @@ -1464,8 +1464,8 @@ void Vt102Emulation::resetMode(int m) setScreen(0); break; } - // FIXME: Currently this has a redundant condition as MODES_SCREEN is 6 - // and MODE_NewLine is 5 + // FIXME: Currently this has a redundant condition as MODES_SCREEN is 7 + // MODE_AppScreen is 6 and MODE_NewLine is 5 if (m < MODES_SCREEN || m == MODE_NewLine) { _screen[0]->resetMode(m); _screen[1]->resetMode(m); diff --git a/src/Vt102Emulation.h b/src/Vt102Emulation.h index ee837752bdd2025cb4bd35e64657b94dfa291bd3..23ac93ec891512120b09eb15ea189c250e186841 100644 --- a/src/Vt102Emulation.h +++ b/src/Vt102Emulation.h @@ -20,22 +20,21 @@ class QTimer; class QKeyEvent; -#define MODE_AppScreen (MODES_SCREEN+0) // Mode #1 -#define MODE_AppCuKeys (MODES_SCREEN+1) // Application cursor keys (DECCKM) -#define MODE_AppKeyPad (MODES_SCREEN+2) // -#define MODE_Mouse1000 (MODES_SCREEN+3) // Send mouse X,Y position on press and release -#define MODE_Mouse1001 (MODES_SCREEN+4) // Use Hilight mouse tracking -#define MODE_Mouse1002 (MODES_SCREEN+5) // Use cell motion mouse tracking -#define MODE_Mouse1003 (MODES_SCREEN+6) // Use all motion mouse tracking -#define MODE_Mouse1005 (MODES_SCREEN+7) // Xterm-style extended coordinates -#define MODE_Mouse1006 (MODES_SCREEN+8) // 2nd Xterm-style extended coordinates -#define MODE_Mouse1007 (MODES_SCREEN+9) // XTerm Alternate Scroll mode; also check AlternateScrolling profile property -#define MODE_Mouse1015 (MODES_SCREEN+10) // Urxvt-style extended coordinates -#define MODE_Ansi (MODES_SCREEN+11) // Use US Ascii for character sets G0-G3 (DECANM) -#define MODE_132Columns (MODES_SCREEN+12) // 80 <-> 132 column mode switch (DECCOLM) -#define MODE_Allow132Columns (MODES_SCREEN+13) // Allow DECCOLM mode -#define MODE_BracketedPaste (MODES_SCREEN+14) // Xterm-style bracketed paste mode -#define MODE_total (MODES_SCREEN+15) +#define MODE_AppCuKeys (MODES_SCREEN+0) // Application cursor keys (DECCKM) +#define MODE_AppKeyPad (MODES_SCREEN+1) // +#define MODE_Mouse1000 (MODES_SCREEN+2) // Send mouse X,Y position on press and release +#define MODE_Mouse1001 (MODES_SCREEN+3) // Use Hilight mouse tracking +#define MODE_Mouse1002 (MODES_SCREEN+4) // Use cell motion mouse tracking +#define MODE_Mouse1003 (MODES_SCREEN+5) // Use all motion mouse tracking +#define MODE_Mouse1005 (MODES_SCREEN+6) // Xterm-style extended coordinates +#define MODE_Mouse1006 (MODES_SCREEN+7) // 2nd Xterm-style extended coordinates +#define MODE_Mouse1007 (MODES_SCREEN+8) // XTerm Alternate Scroll mode; also check AlternateScrolling profile property +#define MODE_Mouse1015 (MODES_SCREEN+9) // Urxvt-style extended coordinates +#define MODE_Ansi (MODES_SCREEN+10) // Use US Ascii for character sets G0-G3 (DECANM) +#define MODE_132Columns (MODES_SCREEN+11) // 80 <-> 132 column mode switch (DECCOLM) +#define MODE_Allow132Columns (MODES_SCREEN+12) // Allow DECCOLM mode +#define MODE_BracketedPaste (MODES_SCREEN+13) // Xterm-style bracketed paste mode +#define MODE_total (MODES_SCREEN+14) namespace Konsole { extern unsigned short vt100_graphics[32]; diff --git a/src/history/HistoryScroll.h b/src/history/HistoryScroll.h index 69285618f04d67c5a87986dccae3cd4e9e28848a..68b274ecd54a1585fb74b1c84956f2e4c81bbe91 100644 --- a/src/history/HistoryScroll.h +++ b/src/history/HistoryScroll.h @@ -32,6 +32,7 @@ public: // access to history virtual int getLines() = 0; + virtual int getMaxLines() = 0; virtual int getLineLen(int lineno) = 0; virtual void getCells(int lineno, int colno, int count, Character res[]) = 0; virtual bool isWrappedLine(int lineNumber) = 0; @@ -47,6 +48,14 @@ public: virtual void addLine(bool previousWrapped = false) = 0; + // modify history + virtual void insertCellsVector(int position, const QVector &cells) = 0; + virtual void insertCells(int position, const Character a[], int count) = 0; + virtual void removeCells(int position) = 0; + virtual void setCellsAt(int position, const Character a[], int count) = 0; + virtual void setCellsVectorAt(int position, const QVector &cells) = 0; + virtual void setLineAt(int position, bool previousWrapped) = 0; + // // FIXME: Passing around constant references to HistoryType instances // is very unsafe, because those references will no longer diff --git a/src/history/HistoryScrollFile.cpp b/src/history/HistoryScrollFile.cpp index ba524162bcc98bb23975e63529064bde81350661..da35cb7c442ede1057d23ef9437b77afc339fe5c 100644 --- a/src/history/HistoryScrollFile.cpp +++ b/src/history/HistoryScrollFile.cpp @@ -33,6 +33,11 @@ int HistoryScrollFile::getLines() return _index.len() / sizeof(qint64); } +int HistoryScrollFile::getMaxLines() +{ + return _index.len() / sizeof(qint64); +} + int HistoryScrollFile::getLineLen(int lineno) { return (startOfLine(lineno + 1) - startOfLine(lineno)) / sizeof(Character); @@ -79,3 +84,27 @@ void HistoryScrollFile::addLine(bool previousWrapped) unsigned char flags = previousWrapped ? 0x01 : 0x00; _lineflags.add(reinterpret_cast(&flags), sizeof(char)); } + +void HistoryScrollFile::insertCells(int , const Character [], int) +{ +} + +void HistoryScrollFile::removeCells(int ) +{ +} + +void HistoryScrollFile::insertCellsVector(int , const QVector &) +{ +} + +void HistoryScrollFile::setCellsAt(int , const Character [], int) +{ +} + +void HistoryScrollFile::setCellsVectorAt(int , const QVector &) +{ +} + +void HistoryScrollFile::setLineAt(int , bool) +{ +} diff --git a/src/history/HistoryScrollFile.h b/src/history/HistoryScrollFile.h index fc22ff92609227908509e4c05580857c860925a8..003f056518a4948db440d6480fa96a681a173219 100644 --- a/src/history/HistoryScrollFile.h +++ b/src/history/HistoryScrollFile.h @@ -27,6 +27,7 @@ public: ~HistoryScrollFile() override; int getLines() override; + int getMaxLines() override; int getLineLen(int lineno) override; void getCells(int lineno, int colno, int count, Character res[]) override; bool isWrappedLine(int lineno) override; @@ -34,6 +35,13 @@ public: void addCells(const Character text[], int count) override; void addLine(bool previousWrapped = false) override; + void insertCellsVector(int position, const QVector &cells) override; + void insertCells(int position, const Character a[], int count) override; + void removeCells(int position) override; + void setCellsAt(int position, const Character a[], int count) override; + void setCellsVectorAt(int position, const QVector &cells) override; + void setLineAt(int position, bool previousWrapped) override; + private: qint64 startOfLine(int lineno); diff --git a/src/history/HistoryScrollNone.cpp b/src/history/HistoryScrollNone.cpp index 0c0721b88097dd837b57aeac36d857e9f1c7d622..4119d691bce1dad37c2101ff2fa45036f782b6f2 100644 --- a/src/history/HistoryScrollNone.cpp +++ b/src/history/HistoryScrollNone.cpp @@ -30,6 +30,11 @@ int HistoryScrollNone::getLines() return 0; } +int HistoryScrollNone::getMaxLines() +{ + return 0; +} + int HistoryScrollNone::getLineLen(int) { return 0; @@ -51,3 +56,27 @@ void HistoryScrollNone::addCells(const Character [], int) void HistoryScrollNone::addLine(bool) { } + +void HistoryScrollNone::insertCells(int , const Character [], int) +{ +} + +void HistoryScrollNone::removeCells(int ) +{ +} + +void HistoryScrollNone::insertCellsVector(int , const QVector &) +{ +} + +void HistoryScrollNone::setCellsAt(int , const Character [], int) +{ +} + +void HistoryScrollNone::setCellsVectorAt(int , const QVector &) +{ +} + +void HistoryScrollNone::setLineAt(int , bool) +{ +} \ No newline at end of file diff --git a/src/history/HistoryScrollNone.h b/src/history/HistoryScrollNone.h index 647d808e19af012cf25b77bc484d2abbbb2da7a8..05cbf765cabf2d307444074bcd9358967b6fa009 100644 --- a/src/history/HistoryScrollNone.h +++ b/src/history/HistoryScrollNone.h @@ -26,12 +26,20 @@ public: bool hasScroll() override; int getLines() override; + int getMaxLines() override; int getLineLen(int lineno) override; void getCells(int lineno, int colno, int count, Character res[]) override; bool isWrappedLine(int lineno) override; void addCells(const Character a[], int count) override; void addLine(bool previousWrapped = false) override; + + void insertCellsVector(int position, const QVector &cells) override; + void insertCells(int position, const Character a[], int count) override; + void removeCells(int position) override; + void setCellsAt(int position, const Character a[], int count) override; + void setCellsVectorAt(int position, const QVector &cells) override; + void setLineAt(int position, bool previousWrapped) override; }; } diff --git a/src/history/compact/CompactHistoryScroll.cpp b/src/history/compact/CompactHistoryScroll.cpp index b0a103352f117099cd9136d1085f71ebe0aa6dc4..9f741f6359e0ae895ab93092222090297b7922d7 100644 --- a/src/history/compact/CompactHistoryScroll.cpp +++ b/src/history/compact/CompactHistoryScroll.cpp @@ -57,6 +57,11 @@ int CompactHistoryScroll::getLines() return _lines.size(); } +int CompactHistoryScroll::getMaxLines() +{ + return static_cast(_maxLineCount); +} + int CompactHistoryScroll::getLineLen(int lineNumber) { if ((lineNumber < 0) || (lineNumber >= _lines.size())) { @@ -91,6 +96,51 @@ void CompactHistoryScroll::setMaxNbLines(unsigned int lineCount) ////qDebug() << "set max lines to: " << _maxLineCount; } +void CompactHistoryScroll::insertCellsVector(int position, const TextLine &cells) +{ + CompactHistoryLine *line = new(_blockList) CompactHistoryLine(cells, _blockList); + + _lines.insert(position, line); + + if (_lines.size() > static_cast(_maxLineCount)) { + delete _lines.takeAt(0); + } +} + +void CompactHistoryScroll::insertCells(int position, const Character a[], int count) +{ + TextLine newLine(count); + std::copy(a, a + count, newLine.begin()); + insertCellsVector(position, newLine); +} + +void CompactHistoryScroll::removeCells(int position) +{ + delete _lines.takeAt(position); +} + +void CompactHistoryScroll::setCellsAt(int position, const Character a[], int count) +{ + TextLine newLine(count); + std::copy(a, a + count, newLine.begin()); + setCellsVectorAt(position, newLine); +} + +void CompactHistoryScroll::setCellsVectorAt(int position, const TextLine &cells) +{ + CompactHistoryLine *line = new(_blockList) CompactHistoryLine(cells, _blockList); + + delete _lines.takeAt(position); + _lines.insert(position, line); +} + +void CompactHistoryScroll::setLineAt(int position, bool previousWrapped) +{ + CompactHistoryLine *line = _lines.at(position); + + line->setWrapped(previousWrapped); +} + bool CompactHistoryScroll::isWrappedLine(int lineNumber) { Q_ASSERT(lineNumber < _lines.size()); diff --git a/src/history/compact/CompactHistoryScroll.h b/src/history/compact/CompactHistoryScroll.h index 74abbbfc30fd711ea07c970f35a2a8c74087988d..5bff5dc3feab134742899baf0ce568ff3bdb05bb 100644 --- a/src/history/compact/CompactHistoryScroll.h +++ b/src/history/compact/CompactHistoryScroll.h @@ -24,6 +24,7 @@ public: ~CompactHistoryScroll() override; int getLines() override; + int getMaxLines() override; int getLineLen(int lineNumber) override; void getCells(int lineNumber, int startColumn, int count, Character buffer[]) override; bool isWrappedLine(int lineNumber) override; @@ -32,7 +33,14 @@ public: void addCellsVector(const TextLine &cells) override; void addLine(bool previousWrapped = false) override; + void insertCellsVector(int position, const TextLine &cells) override; + void insertCells(int position, const Character a[], int count) override; + void removeCells(int position) override; + void setMaxNbLines(unsigned int lineCount); + void setCellsAt(int position, const Character a[], int count) override; + void setCellsVectorAt(int position, const TextLine &cells) override; + void setLineAt(int position, bool previousWrapped) override; private: bool hasDifferentColors(const TextLine &line) const; diff --git a/src/terminalDisplay/TerminalDisplay.cpp b/src/terminalDisplay/TerminalDisplay.cpp index 7381125df17b188c854ee8d7d63db7950ebde4a6..39d1eaa7de9b76b47efd110e4ae0eb3dbbd56e00 100644 --- a/src/terminalDisplay/TerminalDisplay.cpp +++ b/src/terminalDisplay/TerminalDisplay.cpp @@ -497,6 +497,9 @@ void TerminalDisplay::updateImage() return; } + // Better control over screen resizing visual glitches + _screenWindow->updateCurrentLine(); + // optimization - scroll the existing image where possible and // avoid expensive text drawing for parts of the image that // can simply be moved up or down