diff --git a/src/Emulation.cpp b/src/Emulation.cpp --- a/src/Emulation.cpp +++ b/src/Emulation.cpp @@ -100,7 +100,7 @@ void Emulation::checkSelectedText() { - QString text = _currentScreen->selectedText(true, false, false, false); + QString text = _currentScreen->selectedText(Screen::PreserveLineBreaks); emit selectionChanged(text); } diff --git a/src/Screen.h b/src/Screen.h --- a/src/Screen.h +++ b/src/Screen.h @@ -73,6 +73,15 @@ class Screen { public: + enum DecodingOption { + PlainText = 0x0, + ConvertToHtml = 0x1, + PreserveLineBreaks = 0x2, + TrimLeadingWhitespace = 0x4, + TrimTrailingWhitespace = 0x8 + }; + Q_DECLARE_FLAGS(DecodingOptions, DecodingOption) + /** Construct a new screen image of size @p lines by @p columns. */ Screen(int lines, int columns); ~Screen(); @@ -447,9 +456,7 @@ * trimmed in the returned text. * @param html Specifies if returned text should have HTML tags. */ - QString selectedText(bool preserveLineBreaks, - bool trimTrailingSpaces, bool trimLeadingSpaces, - bool html) const; + QString selectedText(const DecodingOptions options) const; /** * Convenience method. Returns the text between two indices. @@ -463,9 +470,7 @@ * trimmed in the returned text. * @param html Specifies if returned text should have HTML tags. */ - QString text(int startIndex, int endIndex, bool preserveLineBreaks, - bool trimTrailingSpaces, bool trimLeadingSpaces, - bool html) const; + QString text(int startIndex, int endIndex, const DecodingOptions options) const; /** * Copies part of the output to a stream. @@ -490,9 +495,7 @@ * @param trimLeadingSpaces Specifies whether leading spaces should be * trimmed in the returned text. */ - void writeSelectionToStream(TerminalCharacterDecoder *decoder, bool - preserveLineBreaks, - bool trimTrailingSpaces, bool trimLeadingSpaces) const; + void writeSelectionToStream(TerminalCharacterDecoder *decoder, const Konsole::Screen::DecodingOptions options) const; /** * Checks if the text between from and to is inside the current @@ -610,8 +613,7 @@ //decoder - a decoder which converts terminal characters (an Character array) into text //appendNewLine - if true a new line character (\n) is appended to the end of the line int copyLineToStream(int line, int start, int count, TerminalCharacterDecoder *decoder, - bool appendNewLine, bool preserveLineBreaks, - bool trimTrailingSpaces, bool trimLeadingSpaces) const; + bool appendNewLine, const Konsole::Screen::DecodingOptions options) const; //fills a section of the screen image with the character 'c' //the parameters are specified as offsets from the start of the screen image. @@ -643,7 +645,7 @@ // copies text from 'startIndex' to 'endIndex' to a stream // startIndex and endIndex are positions generated using the loc(x,y) macro void writeToStream(TerminalCharacterDecoder *decoder, int startIndex, int endIndex, - bool preserveLineBreaks, bool trimTrailingSpaces, bool trimLeadingSpaces) const; + const Konsole::Screen::DecodingOptions options) const; // copies 'count' lines from the screen buffer into 'dest', // starting from 'startLine', where 0 is the first line in the screen buffer void copyFromScreen(Character *dest, int startLine, int count) const; @@ -724,6 +726,10 @@ // last position where we added a character int _lastPos; }; + } +Q_DECLARE_OPERATORS_FOR_FLAGS(Konsole::Screen::DecodingOptions) + + #endif // SCREEN_H diff --git a/src/Screen.cpp b/src/Screen.cpp --- a/src/Screen.cpp +++ b/src/Screen.cpp @@ -1087,15 +1087,15 @@ return pos >= _selTopLeft && pos <= _selBottomRight && columnInSelection; } -QString Screen::selectedText(bool preserveLineBreaks, bool trimTrailingSpaces, bool trimLeadingSpaces, bool html) const +QString Screen::selectedText(const DecodingOptions options) const { if (!isSelectionValid()) return QString(); - return text(_selTopLeft, _selBottomRight, preserveLineBreaks, trimTrailingSpaces, trimLeadingSpaces, html); + return text(_selTopLeft, _selBottomRight, options); } -QString Screen::text(int startIndex, int endIndex, bool preserveLineBreaks, bool trimTrailingSpaces, bool trimLeadingSpaces, bool html) const +QString Screen::text(int startIndex, int endIndex, const DecodingOptions options) const { QString result; QTextStream stream(&result, QIODevice::ReadWrite); @@ -1104,7 +1104,7 @@ PlainTextDecoder plainTextDecoder; TerminalCharacterDecoder *decoder; - if(html) + if(options & ConvertToHtml) { decoder = &htmlDecoder; } @@ -1114,7 +1114,7 @@ } decoder->begin(&stream); - writeToStream(decoder, startIndex, endIndex, preserveLineBreaks, trimTrailingSpaces, trimLeadingSpaces); + writeToStream(decoder, startIndex, endIndex, options); decoder->end(); return result; @@ -1126,18 +1126,16 @@ } void Screen::writeSelectionToStream(TerminalCharacterDecoder* decoder , - bool preserveLineBreaks, - bool trimTrailingSpaces, bool trimLeadingSpaces) const + const DecodingOptions options) const { if (!isSelectionValid()) return; - writeToStream(decoder, _selTopLeft, _selBottomRight, preserveLineBreaks, trimTrailingSpaces, trimLeadingSpaces); + writeToStream(decoder, _selTopLeft, _selBottomRight, options); } void Screen::writeToStream(TerminalCharacterDecoder* decoder, int startIndex, int endIndex, - bool preserveLineBreaks, - bool trimTrailingSpaces, bool trimLeadingSpaces) const + const DecodingOptions options) const { const int top = startIndex / _columns; const int left = startIndex % _columns; @@ -1160,9 +1158,7 @@ count, decoder, appendNewLine, - preserveLineBreaks, - trimTrailingSpaces, - trimLeadingSpaces); + options); // if the selection goes beyond the end of the last line then // append a new line character. @@ -1171,7 +1167,7 @@ // the text on a line. if (y == bottom && copied < count && - !trimTrailingSpaces) { + !options.testFlag(TrimTrailingWhitespace)) { Character newLineChar('\n'); decoder->decodeLine(&newLineChar, 1, 0); } @@ -1183,9 +1179,7 @@ int count, TerminalCharacterDecoder* decoder, bool appendNewLine, - bool preserveLineBreaks, - bool trimTrailingSpaces, - bool trimLeadingSpaces) const + const DecodingOptions options) const { //buffer to hold characters for decoding //the buffer is static to avoid initializing every @@ -1241,7 +1235,7 @@ int length = _screenLines[screenLine].count(); // Don't remove end spaces in lines that wrap - if (trimTrailingSpaces && ((_lineProperties[screenLine] & LINE_WRAPPED) == 0)) + if (options.testFlag(TrimTrailingWhitespace) && ((_lineProperties[screenLine] & LINE_WRAPPED) == 0)) { // ignore trailing white space at the end of the line for (int i = length-1; i >= 0; i--) @@ -1272,12 +1266,12 @@ // When users ask not to preserve the linebreaks, they usually mean: // `treat LINEBREAK as SPACE, thus joining multiple _lines into // single line in the same way as 'J' does in VIM.` - characterBuffer[count] = preserveLineBreaks ? Character('\n') : Character(' '); + characterBuffer[count] = options.testFlag(PreserveLineBreaks) ? Character('\n') : Character(' '); count++; } } - if (trimLeadingSpaces) { + if (options & TrimLeadingWhitespace) { int spacesCount = 0; for (spacesCount = 0; spacesCount < count; spacesCount++) { if (!QChar(characterBuffer[spacesCount].character).isSpace()) { @@ -1305,7 +1299,7 @@ void Screen::writeLinesToStream(TerminalCharacterDecoder* decoder, int fromLine, int toLine) const { - writeToStream(decoder, loc(0, fromLine), loc(_columns - 1, toLine), true, false, false); + writeToStream(decoder, loc(0, fromLine), loc(_columns - 1, toLine), PreserveLineBreaks); } void Screen::addHistLine() diff --git a/src/ScreenWindow.h b/src/ScreenWindow.h --- a/src/ScreenWindow.h +++ b/src/ScreenWindow.h @@ -27,9 +27,9 @@ // Konsole #include "Character.h" +#include "Screen.h" namespace Konsole { -class Screen; /** * Provides a window onto a section of a terminal screen. A terminal widget can then render @@ -232,9 +232,7 @@ * @param trimLeadingSpaces See Screen::selectedText() * @param html Specifies if returned text should have HTML tags. */ - QString selectedText(bool preserveLineBreaks, - bool trimTrailingSpaces, bool trimLeadingSpaces, - bool html) const; + QString selectedText(const Konsole::Screen::DecodingOptions options) const; public Q_SLOTS: /** diff --git a/src/ScreenWindow.cpp b/src/ScreenWindow.cpp --- a/src/ScreenWindow.cpp +++ b/src/ScreenWindow.cpp @@ -125,11 +125,9 @@ return result; } -QString ScreenWindow::selectedText(bool preserveLineBreaks, - bool trimTrailingSpaces, bool trimLeadingSpaces, - bool html) const +QString ScreenWindow::selectedText(const Screen::DecodingOptions options) const { - return _screen->selectedText(preserveLineBreaks, trimTrailingSpaces, trimLeadingSpaces, html); + return _screen->selectedText(options); } void ScreenWindow::getSelectionStart(int &column, int &line) diff --git a/src/SessionController.cpp b/src/SessionController.cpp --- a/src/SessionController.cpp +++ b/src/SessionController.cpp @@ -1148,7 +1148,7 @@ void SessionController::searchBarEvent() { - QString selectedText = _view->screenWindow()->selectedText(true, true, true, false); + QString selectedText = _view->screenWindow()->selectedText(Screen::PreserveLineBreaks | Screen::TrimLeadingWhitespace | Screen::TrimTrailingWhitespace); if (!selectedText.isEmpty()) _searchBar->setSearchText(selectedText); diff --git a/src/TerminalDisplay.h b/src/TerminalDisplay.h --- a/src/TerminalDisplay.h +++ b/src/TerminalDisplay.h @@ -857,6 +857,9 @@ QPoint findWordStart(const QPoint &pnt); QPoint findWordEnd(const QPoint &pnt); + // Uses the current settings for trimming whitespace and preserving linebreaks to create a proper flag value for Screen + Screen::DecodingOptions currentDecodingOptions(); + // the window onto the terminal screen which this display // is currently showing. QPointer _screenWindow; diff --git a/src/TerminalDisplay.cpp b/src/TerminalDisplay.cpp --- a/src/TerminalDisplay.cpp +++ b/src/TerminalDisplay.cpp @@ -2731,6 +2731,22 @@ return QPoint(x, y); } +Screen::DecodingOptions TerminalDisplay::currentDecodingOptions() +{ + Screen::DecodingOptions decodingOptions; + if (_preserveLineBreaks) { + decodingOptions |= Screen::PreserveLineBreaks; + } + if (_trimLeadingSpaces) { + decodingOptions |= Screen::TrimLeadingWhitespace; + } + if (_trimTrailingSpaces) { + decodingOptions |= Screen::TrimTrailingWhitespace; + } + + return decodingOptions; +} + void TerminalDisplay::mouseTripleClickEvent(QMouseEvent* ev) { if (_screenWindow == nullptr) return; @@ -2894,10 +2910,11 @@ if (_screenWindow == nullptr) return; - QString text = _screenWindow->selectedText(_preserveLineBreaks, _trimTrailingSpaces, _trimLeadingSpaces, false); + + QString text = _screenWindow->selectedText(currentDecodingOptions()); if (text.isEmpty()) return; - QString html = _screenWindow->selectedText(_preserveLineBreaks, _trimTrailingSpaces, _trimLeadingSpaces, true); + QString html = _screenWindow->selectedText(currentDecodingOptions() | Screen::ConvertToHtml); auto mimeData = new QMimeData; mimeData->setText(text); @@ -2916,10 +2933,10 @@ if (_screenWindow == nullptr) return; - QString text = _screenWindow->selectedText(_preserveLineBreaks, _trimTrailingSpaces, _trimLeadingSpaces, false); + QString text = _screenWindow->selectedText(currentDecodingOptions()); if (text.isEmpty()) return; - QString html = _screenWindow->selectedText(_preserveLineBreaks, _trimTrailingSpaces, _trimLeadingSpaces, true); + QString html = _screenWindow->selectedText(currentDecodingOptions() | Screen::ConvertToHtml); auto mimeData = new QMimeData; mimeData->setText(text); diff --git a/src/TerminalDisplayAccessible.cpp b/src/TerminalDisplayAccessible.cpp --- a/src/TerminalDisplayAccessible.cpp +++ b/src/TerminalDisplayAccessible.cpp @@ -98,8 +98,7 @@ return QString(); } - return display->screenWindow()->screen()->text(0, display->_usedColumns * display->_usedLines, - true, false, false, false); + return display->screenWindow()->screen()->text(0, display->_usedColumns * display->_usedLines, Screen::PreserveLineBreaks); } void TerminalDisplayAccessible::addSelection(int startOffset, int endOffset) @@ -186,7 +185,7 @@ return QString(); } - return display()->screenWindow()->screen()->text(startOffset, endOffset, true, false, false, false); + return display()->screenWindow()->screen()->text(startOffset, endOffset, Screen::PreserveLineBreaks); } TerminalDisplay *TerminalDisplayAccessible::display() const