File kde4-kdebase-bug-188528-HEAD.patch of Package konsole

diff --git src/EditProfileDialog.cpp src/EditProfileDialog.cpp
index cc1029f..8e44df6 100644
--- src/EditProfileDialog.cpp
+++ src/EditProfileDialog.cpp
@@ -992,6 +992,10 @@ void EditProfileDialog::setupMousePage(const Profile::Ptr profile)
             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 src/EditProfileDialog.h src/EditProfileDialog.h
index 8d348c4..c85bd11 100644
--- src/EditProfileDialog.h
+++ 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 src/EditProfileDialog.ui src/EditProfileDialog.ui
index b432434..d174682 100644
--- src/EditProfileDialog.ui
+++ src/EditProfileDialog.ui
@@ -785,6 +785,16 @@
            </widget>
           </item>
           <item>
+           <widget class="QCheckBox" name="trimTrailingSpacesButton">
+            <property name="toolTip">
+             <string>Trim trailing spaces in selected text, useful in some editors</string>
+            </property>
+            <property name="text">
+             <string>Trim trailing spaces</string>
+            </property>
+           </widget>
+          </item>
+          <item>
            <spacer name="horizontalSpacer_5">
             <property name="orientation">
              <enum>Qt::Horizontal</enum>
diff --git src/Profile.cpp src/Profile.cpp
index 58b753b..e81433f 100644
--- src/Profile.cpp
+++ 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 src/Profile.h src/Profile.h
index 4756f90..f14d3a2 100644
--- src/Profile.h
+++ 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 src/Screen.cpp src/Screen.cpp
index cc29cf6..816affe 100644
--- src/Screen.cpp
+++ 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 src/Screen.h src/Screen.h
index b962dea..8520438 100644
--- src/Screen.h
+++ 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 src/ScreenWindow.cpp src/ScreenWindow.cpp
index 3c55a29..bafc6a0 100644
--- src/ScreenWindow.cpp
+++ src/ScreenWindow.cpp
@@ -117,9 +117,9 @@ QVector<LineProperty> 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 src/ScreenWindow.h src/ScreenWindow.h
index adf6182..1aa938a 100644
--- src/ScreenWindow.h
+++ 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 src/TerminalDisplay.cpp src/TerminalDisplay.cpp
index 4f75a25..6d87a64 100644
--- src/TerminalDisplay.cpp
+++ src/TerminalDisplay.cpp
@@ -328,6 +328,7 @@ TerminalDisplay::TerminalDisplay(QWidget* parent)
     , _cursorShape(Enum::BlockCursor)
     , _antialiasText(true)
     , _sessionController(0)
+    , _trimTrailingSpaces(false)
 {
     // terminal applications are not designed with Right-To-Left in mind,
     // so the layout is forced to Left-To-Right
@@ -2538,7 +2539,7 @@ void TerminalDisplay::copyToX11Selection()
     if (!_screenWindow)
         return;
 
-    QString text = _screenWindow->selectedText(_preserveLineBreaks);
+    QString text = _screenWindow->selectedText(_preserveLineBreaks, _trimTrailingSpaces);
     if (text.isEmpty())
         return;
 
@@ -2553,7 +2554,7 @@ void TerminalDisplay::copyToClipboard()
     if (!_screenWindow)
         return;
 
-    QString text = _screenWindow->selectedText(_preserveLineBreaks);
+    QString text = _screenWindow->selectedText(_preserveLineBreaks, _trimTrailingSpaces);
     if (text.isEmpty())
         return;
 
diff --git src/TerminalDisplay.h src/TerminalDisplay.h
index 5daa019..b606eef 100644
--- src/TerminalDisplay.h
+++ 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;
@@ -827,6 +840,9 @@ private:
     static const int DEFAULT_TOP_MARGIN = 1;
 
     SessionController* _sessionController;
+
+    bool _trimTrailingSpaces;   // trim trailing spaces in selected text
+
     friend class TerminalDisplayAccessible;
 };
 
diff --git src/ViewManager.cpp src/ViewManager.cpp
index 9de6949..62b6842 100644
--- src/ViewManager.cpp
+++ src/ViewManager.cpp
@@ -806,6 +806,7 @@ void ViewManager::applyProfileToView(TerminalDisplay* view , const Profile::Ptr
     view->setControlDrag(profile->property<bool>(Profile::CtrlRequiredForDrag));
     view->setBidiEnabled(profile->bidiRenderingEnabled());
     view->setLineSpacing(profile->lineSpacing());
+    view->setTrimTrailingSpaces(profile->property<bool>(Profile::TrimTrailingSpacesInSelectedText));
 
     view->setOpenLinksByDirectClick(profile->property<bool>(Profile::OpenLinksByDirectClickEnabled));