dingstudio / rpms / konsole

Forked from rpms/konsole a year ago
Clone

Blame SOURCES/konsole-avoid-pasting-control-characters.patch

57d43c
diff --git a/src/Emulation.cpp b/src/Emulation.cpp
57d43c
index 02ed4be..80d93ba 100644
57d43c
--- a/src/Emulation.cpp
57d43c
+++ b/src/Emulation.cpp
57d43c
@@ -39,6 +39,7 @@ Emulation::Emulation() :
57d43c
     _decoder(0),
57d43c
     _keyTranslator(0),
57d43c
     _usesMouse(false),
57d43c
+    _bracketedPasteMode(false),
57d43c
     _imageSizeInitialized(false)
57d43c
 {
57d43c
     // create screens with a default size
57d43c
@@ -52,6 +53,8 @@ Emulation::Emulation() :
57d43c
     // listen for mouse status changes
57d43c
     connect(this , SIGNAL(programUsesMouseChanged(bool)) ,
57d43c
             SLOT(usesMouseChanged(bool)));
57d43c
+    connect(this , SIGNAL(programBracketedPasteModeChanged(bool)) ,
57d43c
+            SLOT(bracketedPasteModeChanged(bool)));
57d43c
 }
57d43c
 
57d43c
 bool Emulation::programUsesMouse() const
57d43c
@@ -64,6 +67,16 @@ void Emulation::usesMouseChanged(bool usesMouse)
57d43c
     _usesMouse = usesMouse;
57d43c
 }
57d43c
 
57d43c
+bool Emulation::programBracketedPasteMode() const
57d43c
+{
57d43c
+    return _bracketedPasteMode;
57d43c
+}
57d43c
+
57d43c
+void Emulation::bracketedPasteModeChanged(bool bracketedPasteMode)
57d43c
+{
57d43c
+    _bracketedPasteMode = bracketedPasteMode;
57d43c
+}
57d43c
+
57d43c
 ScreenWindow* Emulation::createWindow()
57d43c
 {
57d43c
     ScreenWindow* window = new ScreenWindow();
57d43c
diff --git a/src/Emulation.h b/src/Emulation.h
57d43c
index aa24d69..966b423 100644
57d43c
--- a/src/Emulation.h
57d43c
+++ b/src/Emulation.h
57d43c
@@ -215,6 +215,8 @@ public:
57d43c
      */
57d43c
     bool programUsesMouse() const;
57d43c
 
57d43c
+    bool programBracketedPasteMode() const;
57d43c
+
57d43c
 public slots:
57d43c
 
57d43c
     /** Change the size of the emulation's image */
57d43c
@@ -314,6 +316,8 @@ signals:
57d43c
      */
57d43c
     void programUsesMouseChanged(bool usesMouse);
57d43c
 
57d43c
+    void programBracketedPasteModeChanged(bool bracketedPasteMode);
57d43c
+
57d43c
     /**
57d43c
      * Emitted when the contents of the screen image change.
57d43c
      * The emulation buffers the updates from successive image changes,
57d43c
@@ -474,8 +478,11 @@ private slots:
57d43c
 
57d43c
     void usesMouseChanged(bool usesMouse);
57d43c
 
57d43c
+    void bracketedPasteModeChanged(bool bracketedPasteMode);
57d43c
+
57d43c
 private:
57d43c
     bool _usesMouse;
57d43c
+    bool _bracketedPasteMode;
57d43c
     QTimer _bulkTimer1;
57d43c
     QTimer _bulkTimer2;
57d43c
     bool _imageSizeInitialized;
57d43c
diff --git a/src/Session.cpp b/src/Session.cpp
57d43c
index 2d8ca89..68e8ef7 100644
57d43c
--- a/src/Session.cpp
57d43c
+++ b/src/Session.cpp
57d43c
@@ -326,6 +326,11 @@ void Session::addView(TerminalDisplay* widget)
57d43c
 
57d43c
     widget->setUsesMouse(_emulation->programUsesMouse());
57d43c
 
57d43c
+    connect(_emulation, SIGNAL(programBracketedPasteModeChanged(bool)),
57d43c
+            widget, SLOT(setBracketedPasteMode(bool)));
57d43c
+
57d43c
+    widget->setBracketedPasteMode(_emulation->programBracketedPasteMode());
57d43c
+
57d43c
     widget->setScreenWindow(_emulation->createWindow());
57d43c
 
57d43c
     //connect view signals and slots
57d43c
diff --git a/src/TerminalDisplay.cpp b/src/TerminalDisplay.cpp
57d43c
index 871dc9f..be80e7c 100644
57d43c
--- a/src/TerminalDisplay.cpp
57d43c
+++ b/src/TerminalDisplay.cpp
57d43c
@@ -51,6 +51,7 @@
57d43c
 #include <KIO/NetAccess>
57d43c
 #include <konq_operations.h>
57d43c
 #include <KFileItem>
57d43c
+#include <KMessageBox>
57d43c
 
57d43c
 // Konsole
57d43c
 #include "Filter.h"
57d43c
@@ -367,6 +368,7 @@ TerminalDisplay::TerminalDisplay(QWidget* parent)
57d43c
     setMouseTracking(true);
57d43c
 
57d43c
     setUsesMouse(true);
57d43c
+    setBracketedPasteMode(false);
57d43c
 
57d43c
     setColorTable(ColorScheme::defaultTable);
57d43c
 
57d43c
@@ -2554,6 +2556,15 @@ bool TerminalDisplay::usesMouse() const
57d43c
     return _mouseMarks;
57d43c
 }
57d43c
 
57d43c
+void TerminalDisplay::setBracketedPasteMode(bool on)
57d43c
+{
57d43c
+    _bracketedPasteMode = on;
57d43c
+}
57d43c
+bool TerminalDisplay::bracketedPasteMode() const
57d43c
+{
57d43c
+    return _bracketedPasteMode;
57d43c
+}
57d43c
+
57d43c
 /* ------------------------------------------------------------------------- */
57d43c
 /*                                                                           */
57d43c
 /*                               Clipboard                                   */
57d43c
@@ -2568,8 +2579,84 @@ void TerminalDisplay::doPaste(QString text, bool appendReturn)
57d43c
     if (appendReturn)
57d43c
         text.append("\r");
57d43c
 
57d43c
+    QStringList unsafeCharacters;
57d43c
+    Q_FOREACH (const QChar &c, text) {
57d43c
+        if (!c.isPrint() && c != QLatin1Char('\t') && c != QLatin1Char('\n')) {
57d43c
+            QString description;
57d43c
+            switch(c.unicode()) {
57d43c
+            case '\x03':
57d43c
+                description = i18n("^C Interrupt: May abort the current process");
57d43c
+                break;
57d43c
+            case '\x04':
57d43c
+                description = i18n("^D End of transmission: May exit the current process");
57d43c
+                break;
57d43c
+            case '\x07':
57d43c
+                description = i18n("^G Bell: Will try to emit an audible warning");
57d43c
+                break;
57d43c
+            case '\x08':
57d43c
+                description = i18n("^H Backspace");
57d43c
+                break;
57d43c
+            case '\x13':
57d43c
+                description = i18n("^S Scroll lock: Locks terminal output");
57d43c
+                break;
57d43c
+            case '\x1a':
57d43c
+                description = i18n("^Z Suspend: Stops current process");
57d43c
+                break;
57d43c
+            case '\x1b':
57d43c
+                description = i18n("ESC: Used for special commands to the current process");
57d43c
+                break;
57d43c
+            default:
57d43c
+                description = i18n("Other unprintable character (\\x%1)").arg(QString::number(c.unicode(), 16));
57d43c
+                break;
57d43c
+            }
57d43c
+            unsafeCharacters.append(description);
57d43c
+        }
57d43c
+    }
57d43c
+    unsafeCharacters.removeDuplicates();
57d43c
+
57d43c
+    if (!unsafeCharacters.isEmpty()) {
57d43c
+        int result = KMessageBox::warningYesNoCancelList(window(),
57d43c
+                i18n("The text you're trying to paste contains hidden unprintable characters, "
57d43c
+                    "do you want to filter them out?"),
57d43c
+                unsafeCharacters,
57d43c
+                i18nc("@title", "Filter"),
57d43c
+                KGuiItem(i18nc("@action:button",
57d43c
+                    "&Remove unprintable"),
57d43c
+                    QLatin1String("filter-symbolic")),
57d43c
+                KGuiItem(i18nc("@action:button",
57d43c
+                    "Confirm &paste"),
57d43c
+                    QLatin1String("edit-paste")),
57d43c
+                KGuiItem(i18nc("@action:button",
57d43c
+                    "&Cancel paste"),
57d43c
+                    QLatin1String("dialog-cancel")),
57d43c
+                QLatin1String("ShowPasteUnprintableWarning")
57d43c
+            );
57d43c
+        switch(result){
57d43c
+        case KMessageBox::Cancel:
57d43c
+            return;
57d43c
+        case KMessageBox::Yes: {
57d43c
+            QString sanitized;
57d43c
+            Q_FOREACH (const QChar &c, text) {
57d43c
+                if (c.isPrint() || c == QLatin1Char('\t') || c == QLatin1Char('\n')) {
57d43c
+                    sanitized.append(c);
57d43c
+                }
57d43c
+            }
57d43c
+            text = sanitized;
57d43c
+        }
57d43c
+        case KMessageBox::No:
57d43c
+            break;
57d43c
+        default:
57d43c
+            break;
57d43c
+        }
57d43c
+    }
57d43c
+
57d43c
     if (!text.isEmpty()) {
57d43c
         text.replace('\n', '\r');
57d43c
+        if (bracketedPasteMode()) {
57d43c
+            text.remove(QLatin1String("\033"));
57d43c
+            text.prepend("\033[200~");
57d43c
+            text.append("\033[201~");
57d43c
+        }
57d43c
         // perform paste by simulating keypress events
57d43c
         QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text);
57d43c
         emit keyPressedSignal(&e);
57d43c
diff --git a/src/TerminalDisplay.h b/src/TerminalDisplay.h
57d43c
index 8e246b8..23913d1 100644
57d43c
--- a/src/TerminalDisplay.h
57d43c
+++ b/src/TerminalDisplay.h
57d43c
@@ -512,6 +512,9 @@ public slots:
57d43c
     /** See setUsesMouse() */
57d43c
     bool usesMouse() const;
57d43c
 
57d43c
+    void setBracketedPasteMode(bool bracketedPasteMode);
57d43c
+    bool bracketedPasteMode() const;
57d43c
+
57d43c
     /**
57d43c
      * Shows a notification that a bell event has occurred in the terminal.
57d43c
      * TODO: More documentation here
57d43c
@@ -770,6 +773,7 @@ private:
57d43c
     bool _showTerminalSizeHint;
57d43c
     bool _bidiEnabled;
57d43c
     bool _mouseMarks;
57d43c
+    bool _bracketedPasteMode;
57d43c
 
57d43c
     QPoint  _iPntSel; // initial selection point
57d43c
     QPoint  _pntSel; // current selection point
57d43c
diff --git a/src/Vt102Emulation.cpp b/src/Vt102Emulation.cpp
57d43c
index 7f663f2..76b3ac5 100644
57d43c
--- a/src/Vt102Emulation.cpp
57d43c
+++ b/src/Vt102Emulation.cpp
57d43c
@@ -787,6 +787,11 @@ void Vt102Emulation::processToken(int token, int p, int q)
57d43c
     case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM
57d43c
     case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM
57d43c
 
57d43c
+    case TY_CSI_PR('h', 2004) :          setMode      (MODE_BracketedPaste); break; //XTERM
57d43c
+    case TY_CSI_PR('l', 2004) :        resetMode      (MODE_BracketedPaste); break; //XTERM
57d43c
+    case TY_CSI_PR('s', 2004) :         saveMode      (MODE_BracketedPaste); break; //XTERM
57d43c
+    case TY_CSI_PR('r', 2004) :      restoreMode      (MODE_BracketedPaste); break; //XTERM
57d43c
+
57d43c
     //FIXME: weird DEC reset sequence
57d43c
     case TY_CSI_PE('p'      ) : /* IGNORED: reset         (        ) */ break;
57d43c
 
57d43c
@@ -1194,6 +1199,7 @@ void Vt102Emulation::resetModes()
57d43c
     resetMode(MODE_Mouse1005);  saveMode(MODE_Mouse1005);
57d43c
     resetMode(MODE_Mouse1006);  saveMode(MODE_Mouse1006);
57d43c
     resetMode(MODE_Mouse1015);  saveMode(MODE_Mouse1015);
57d43c
+    resetMode(MODE_BracketedPaste);  saveMode(MODE_BracketedPaste);
57d43c
 
57d43c
     resetMode(MODE_AppScreen);  saveMode(MODE_AppScreen);
57d43c
     resetMode(MODE_AppCuKeys);  saveMode(MODE_AppCuKeys);
57d43c
@@ -1219,6 +1225,10 @@ void Vt102Emulation::setMode(int m)
57d43c
         emit programUsesMouseChanged(false);
57d43c
         break;
57d43c
 
57d43c
+    case MODE_BracketedPaste:
57d43c
+        emit programBracketedPasteModeChanged(true);
57d43c
+        break;
57d43c
+
57d43c
     case MODE_AppScreen :
57d43c
         _screen[1]->clearSelection();
57d43c
         setScreen(1);
57d43c
@@ -1245,6 +1255,10 @@ void Vt102Emulation::resetMode(int m)
57d43c
         emit programUsesMouseChanged(true);
57d43c
         break;
57d43c
 
57d43c
+    case MODE_BracketedPaste:
57d43c
+        emit programBracketedPasteModeChanged(false);
57d43c
+        break;
57d43c
+
57d43c
     case MODE_AppScreen :
57d43c
         _screen[0]->clearSelection();
57d43c
         setScreen(0);
57d43c
diff --git a/src/Vt102Emulation.h b/src/Vt102Emulation.h
57d43c
index c15f6ea..8d678e0 100644
57d43c
--- a/src/Vt102Emulation.h
57d43c
+++ b/src/Vt102Emulation.h
57d43c
@@ -46,7 +46,8 @@ class QKeyEvent;
57d43c
 #define MODE_Ansi            (MODES_SCREEN+10)   // Use US Ascii for character sets G0-G3 (DECANM)
57d43c
 #define MODE_132Columns      (MODES_SCREEN+11)  // 80 <-> 132 column mode switch (DECCOLM)
57d43c
 #define MODE_Allow132Columns (MODES_SCREEN+12)  // Allow DECCOLM mode
57d43c
-#define MODE_total           (MODES_SCREEN+13)
57d43c
+#define MODE_BracketedPaste  (MODES_SCREEN+13)  // Xterm-style bracketed paste mode
57d43c
+#define MODE_total           (MODES_SCREEN+14)
57d43c
 
57d43c
 namespace Konsole
57d43c
 {