From ca9dd11bf5e1b3bf5c6c17de34d5d3bf4d3baf38 Mon Sep 17 00:00:00 2001 From: Kurt Hindenburg Date: Sun, 9 Sep 2012 19:03:32 -0400 Subject: [PATCH] Allow option to trim spaces at end of line In the ongoing issue with spaces at the end of lines, this allows for an option to trim the spaces. By default, it is disabled so only people who need this will be affected. Many thanks to David Smid CCBUG: 188528 --- src/EditProfileDialog.cpp | 8 ++++++++ src/EditProfileDialog.h | 1 + src/EditProfileDialog.ui | 10 ++++++++++ src/Profile.cpp | 2 ++ src/Profile.h | 2 ++ src/Screen.cpp | 37 +++++++++++++++++++++++++++---------- src/Screen.h | 20 +++++++++++++------- src/ScreenWindow.cpp | 4 ++-- src/ScreenWindow.h | 3 ++- src/TerminalDisplay.cpp | 5 +++-- src/TerminalDisplay.h | 16 ++++++++++++++++ src/ViewManager.cpp | 1 + 12 files changed, 87 insertions(+), 22 deletions(-) diff --git a/src/EditProfileDialog.cpp b/src/EditProfileDialog.cpp index cc1029f91..8e44df606 100644 --- a/src/EditProfileDialog.cpp +++ b/src/EditProfileDialog.cpp @@ -991,6 +991,10 @@ void EditProfileDialog::setupMousePage(const Profile::Ptr profile) _ui->copyTextToClipboardButton , Profile::AutoCopySelectedText, SLOT(toggleCopyTextToClipboard(bool)) }, + { + _ui->trimTrailingSpacesButton , Profile::TrimTrailingSpacesInSelectedText, + SLOT(toggleTrimTrailingSpacesInSelectedText(bool)) + }, { _ui->openLinksByDirectClickButton , Profile::OpenLinksByDirectClickEnabled, SLOT(toggleOpenLinksByDirectClick(bool)) @@ -1134,6 +1138,10 @@ void EditProfileDialog::toggleCopyTextToClipboard(bool enable) { updateTempProfileProperty(Profile::AutoCopySelectedText, enable); } +void EditProfileDialog::toggleTrimTrailingSpacesInSelectedText(bool enable) +{ + updateTempProfileProperty(Profile::TrimTrailingSpacesInSelectedText, enable); +} void EditProfileDialog::pasteFromX11Selection() { updateTempProfileProperty(Profile::MiddleClickPasteMode, Enum::PasteFromX11Selection); diff --git a/src/EditProfileDialog.h b/src/EditProfileDialog.h index 8d348c469..c85bd11b3 100644 --- a/src/EditProfileDialog.h +++ b/src/EditProfileDialog.h @@ -152,6 +152,7 @@ private slots: void toggleOpenLinksByDirectClick(bool); void toggleCtrlRequiredForDrag(bool); void toggleCopyTextToClipboard(bool); + void toggleTrimTrailingSpacesInSelectedText(bool); void pasteFromX11Selection(); void pasteFromClipboard(); diff --git a/src/EditProfileDialog.ui b/src/EditProfileDialog.ui index b43243497..45eafcc89 100644 --- a/src/EditProfileDialog.ui +++ b/src/EditProfileDialog.ui @@ -784,6 +784,16 @@ + + + + Trim trailing spaces in selected text, useful in some instances + + + Trim trailing spaces + + + diff --git a/src/Profile.cpp b/src/Profile.cpp index 58b753b52..e81433f0a 100644 --- a/src/Profile.cpp +++ b/src/Profile.cpp @@ -107,6 +107,7 @@ const Profile::PropertyInfo Profile::DefaultPropertyNames[] = { , { OpenLinksByDirectClickEnabled , "OpenLinksByDirectClickEnabled" , INTERACTION_GROUP , QVariant::Bool } , { CtrlRequiredForDrag, "CtrlRequiredForDrag" , INTERACTION_GROUP , QVariant::Bool } , { AutoCopySelectedText , "AutoCopySelectedText" , INTERACTION_GROUP , QVariant::Bool } + , { TrimTrailingSpacesInSelectedText , "TrimTrailingSpacesInSelectedText" , INTERACTION_GROUP , QVariant::Bool } , { PasteFromSelectionEnabled , "PasteFromSelectionEnabled" , INTERACTION_GROUP , QVariant::Bool } , { PasteFromClipboardEnabled , "PasteFromClipboardEnabled" , INTERACTION_GROUP , QVariant::Bool } , { MiddleClickPasteMode, "MiddleClickPasteMode" , INTERACTION_GROUP , QVariant::Int } @@ -173,6 +174,7 @@ FallbackProfile::FallbackProfile() setProperty(OpenLinksByDirectClickEnabled, false); setProperty(CtrlRequiredForDrag, true); setProperty(AutoCopySelectedText, false); + setProperty(TrimTrailingSpacesInSelectedText, false); setProperty(PasteFromSelectionEnabled, true); setProperty(PasteFromClipboardEnabled, false); setProperty(MiddleClickPasteMode, Enum::PasteFromX11Selection); diff --git a/src/Profile.h b/src/Profile.h index 4756f900f..f14d3a212 100644 --- a/src/Profile.h +++ b/src/Profile.h @@ -205,6 +205,8 @@ public: CtrlRequiredForDrag, /** (bool) If true, automatically copy selected text into the clipboard */ AutoCopySelectedText, + /** (bool) If true, trailing spaces are trimmed in selected text */ + TrimTrailingSpacesInSelectedText, /** (bool) If true, middle mouse button pastes from X Selection */ PasteFromSelectionEnabled, /** (bool) If true, middle mouse button pastes from Clipboard */ diff --git a/src/Screen.cpp b/src/Screen.cpp index cc29cf6b4..816affe71 100644 --- a/src/Screen.cpp +++ b/src/Screen.cpp @@ -1096,22 +1096,22 @@ bool Screen::isSelected(const int x, const int y) const return pos >= _selTopLeft && pos <= _selBottomRight && columnInSelection; } -QString Screen::selectedText(bool preserveLineBreaks) const +QString Screen::selectedText(bool preserveLineBreaks, bool trimTrailingSpaces) const { if (!isSelectionValid()) return QString(); - return text(_selTopLeft, _selBottomRight, preserveLineBreaks); + return text(_selTopLeft, _selBottomRight, preserveLineBreaks, trimTrailingSpaces); } -QString Screen::text(int startIndex, int endIndex, bool preserveLineBreaks) const +QString Screen::text(int startIndex, int endIndex, bool preserveLineBreaks, bool trimTrailingSpaces) const { QString result; QTextStream stream(&result, QIODevice::ReadWrite); PlainTextDecoder decoder; decoder.begin(&stream); - writeToStream(&decoder, startIndex, endIndex, preserveLineBreaks); + writeToStream(&decoder, startIndex, endIndex, preserveLineBreaks, trimTrailingSpaces); decoder.end(); return result; @@ -1123,16 +1123,18 @@ bool Screen::isSelectionValid() const } void Screen::writeSelectionToStream(TerminalCharacterDecoder* decoder , - bool preserveLineBreaks) const + bool preserveLineBreaks, + bool trimTrailingSpaces) const { if (!isSelectionValid()) return; - writeToStream(decoder, _selTopLeft, _selBottomRight, preserveLineBreaks); + writeToStream(decoder, _selTopLeft, _selBottomRight, preserveLineBreaks, trimTrailingSpaces); } void Screen::writeToStream(TerminalCharacterDecoder* decoder, int startIndex, int endIndex, - bool preserveLineBreaks) const + bool preserveLineBreaks, + bool trimTrailingSpaces) const { const int top = startIndex / _columns; const int left = startIndex % _columns; @@ -1155,7 +1157,8 @@ void Screen::writeToStream(TerminalCharacterDecoder* decoder, count, decoder, appendNewLine, - preserveLineBreaks); + preserveLineBreaks, + trimTrailingSpaces); // if the selection goes beyond the end of the last line then // append a new line character. @@ -1175,7 +1178,8 @@ int Screen::copyLineToStream(int line , int count, TerminalCharacterDecoder* decoder, bool appendNewLine, - bool preserveLineBreaks) const + bool preserveLineBreaks, + bool trimTrailingSpaces) const { //buffer to hold characters for decoding //the buffer is static to avoid initialising every @@ -1222,7 +1226,20 @@ int Screen::copyLineToStream(int line , const int screenLine = line - _history->getLines(); Character* data = _screenLines[screenLine].data(); - const int length = _screenLines[screenLine].count(); + int length = _screenLines[screenLine].count(); + + // Don't remove end spaces in lines that wrap + if (trimTrailingSpaces && !(_lineProperties[screenLine] & LINE_WRAPPED)) + { + // ignore trailing white space at the end of the line + for (int i = length-1; i >= 0; i--) + { + if (data[i].character == ' ') + length--; + else + break; + } + } //retrieve line from screen image for (int i = start; i < qMin(start + count, length); i++) { diff --git a/src/Screen.h b/src/Screen.h index b962dea1e..8520438e8 100644 --- a/src/Screen.h +++ b/src/Screen.h @@ -444,15 +444,19 @@ public: * Convenience method. Returns the currently selected text. * @param preserveLineBreaks Specifies whether new line characters should * be inserted into the returned text at the end of each terminal line. + * @param trimTrailingSpaces Specifies whether trailing spaces should be + * trimmed in the returned text. */ - QString selectedText(bool preserveLineBreaks) const; + QString selectedText(bool preserveLineBreaks, bool trimTrailingSpaces = false) const; /** * Convenience method. Returns the text from @p startIndex to @p endIndex. * @param preserveLineBreaks Specifies whether new line characters should * be inserted into the returned text at the end of each terminal line. + * @param trimTrailingSpaces Specifies whether trailing spaces should be + * trimmed in the returned text. */ - QString text(int startIndex, int endIndex, bool preserveLineBreaks) const; + QString text(int startIndex, int endIndex, bool preserveLineBreaks, bool trimTrailingSpaces = false) const; /** * Copies part of the output to a stream. @@ -470,11 +474,12 @@ public: * @param decoder A decoder which converts terminal characters into text. * PlainTextDecoder is the most commonly used decoder which converts characters * into plain text with no formatting. - * @param preserveLineBreaks Specifies whether new line characters should - * be inserted into the returned text at the end of each terminal line. + * @param trimTrailingSpaces Specifies whether trailing spaces should be + * trimmed in the returned text. */ void writeSelectionToStream(TerminalCharacterDecoder* decoder , bool - preserveLineBreaks = true) const; + preserveLineBreaks = true, + bool trimTrailingSpaces = false) const; /** * Checks if the text between from and to is inside the current @@ -593,7 +598,8 @@ private: int count, TerminalCharacterDecoder* decoder, bool appendNewLine, - bool preserveLineBreaks) const; + bool preserveLineBreaks, + bool trimTrailingSpaces) 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. @@ -625,7 +631,7 @@ private: // 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 = true) const; + int endIndex, bool preserveLineBreaks = true, bool trimTrailingSpaces = false) 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; diff --git a/src/ScreenWindow.cpp b/src/ScreenWindow.cpp index 3c55a297b..bafc6a044 100644 --- a/src/ScreenWindow.cpp +++ b/src/ScreenWindow.cpp @@ -117,9 +117,9 @@ QVector ScreenWindow::getLineProperties() return result; } -QString ScreenWindow::selectedText(bool preserveLineBreaks) const +QString ScreenWindow::selectedText(bool preserveLineBreaks, bool trimTrailingSpaces) const { - return _screen->selectedText(preserveLineBreaks); + return _screen->selectedText(preserveLineBreaks, trimTrailingSpaces); } void ScreenWindow::getSelectionStart(int& column , int& line) diff --git a/src/ScreenWindow.h b/src/ScreenWindow.h index adf6182ac..1aa938a0a 100644 --- a/src/ScreenWindow.h +++ b/src/ScreenWindow.h @@ -222,8 +222,9 @@ public: * Returns the text which is currently selected. * * @param preserveLineBreaks See Screen::selectedText() + * @param trimTrailingSpaces See Screen::selectedText() */ - QString selectedText(bool preserveLineBreaks) const; + QString selectedText(bool preserveLineBreaks, bool trimTrailingSpaces = false) const; public slots: /** diff --git a/src/TerminalDisplay.cpp b/src/TerminalDisplay.cpp index e20bb11fa..d8eac98cb 100644 --- a/src/TerminalDisplay.cpp +++ b/src/TerminalDisplay.cpp @@ -335,6 +335,7 @@ TerminalDisplay::TerminalDisplay(QWidget* parent) , _antialiasText(true) , _printerFriendly(false) , _sessionController(0) + , _trimTrailingSpaces(false) { // terminal applications are not designed with Right-To-Left in mind, // so the layout is forced to Left-To-Right @@ -2590,7 +2591,7 @@ void TerminalDisplay::copyToX11Selection() if (!_screenWindow) return; - QString text = _screenWindow->selectedText(_preserveLineBreaks); + QString text = _screenWindow->selectedText(_preserveLineBreaks, _trimTrailingSpaces); if (text.isEmpty()) return; @@ -2605,7 +2606,7 @@ void TerminalDisplay::copyToClipboard() if (!_screenWindow) return; - QString text = _screenWindow->selectedText(_preserveLineBreaks); + QString text = _screenWindow->selectedText(_preserveLineBreaks, _trimTrailingSpaces); if (text.isEmpty()) return; diff --git a/src/TerminalDisplay.h b/src/TerminalDisplay.h index e1bb91fb4..8e246b84a 100644 --- a/src/TerminalDisplay.h +++ b/src/TerminalDisplay.h @@ -196,6 +196,19 @@ public: return _openLinksByDirectClick; } + /** + * Sets whether trailing spaces should be trimmed in selected text. + */ + void setTrimTrailingSpaces(bool enabled) { + _trimTrailingSpaces = enabled; + } + + /** + * Returns true if trailing spaces should be trimmed in selected text. + */ + bool trimTrailingSpaces() const { + return _trimTrailingSpaces; + } void setLineSpacing(uint); uint lineSpacing() const; @@ -841,6 +854,9 @@ private: static const int DEFAULT_TOP_MARGIN = 1; SessionController* _sessionController; + + bool _trimTrailingSpaces; // trim trailing spaces in selected text + friend class TerminalDisplayAccessible; }; diff --git a/src/ViewManager.cpp b/src/ViewManager.cpp index a2ebe065b..faa139576 100644 --- a/src/ViewManager.cpp +++ b/src/ViewManager.cpp @@ -806,6 +806,7 @@ void ViewManager::applyProfileToView(TerminalDisplay* view , const Profile::Ptr view->setControlDrag(profile->property(Profile::CtrlRequiredForDrag)); view->setBidiEnabled(profile->bidiRenderingEnabled()); view->setLineSpacing(profile->lineSpacing()); + view->setTrimTrailingSpaces(profile->property(Profile::TrimTrailingSpacesInSelectedText)); view->setOpenLinksByDirectClick(profile->property(Profile::OpenLinksByDirectClickEnabled));