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));