Parcourir la source

Fix copy/paste in ctkConsole

In addition to support paste from Ctrl+V, it now supports any paste
(e.g. with middle mouse button).
Also, the behavior is changed to now support Ctrl+V even when
the cursor is in the history area. Pasted text is appended at the end of
the document.

Closes #294
Julien Finet il y a 11 ans
Parent
commit
ad63c20f79
2 fichiers modifiés avec 69 ajouts et 40 suppressions
  1. 58 40
      Libs/Widgets/ctkConsole.cpp
  2. 11 0
      Libs/Widgets/ctkConsole_p.h

+ 58 - 40
Libs/Widgets/ctkConsole.cpp

@@ -157,9 +157,7 @@ void ctkConsolePrivate::keyPressEvent(QKeyEvent* e)
     // Set to true if there's a current selection
     const bool selection = text_cursor.anchor() != text_cursor.position();
     // Set to true if the cursor overlaps the history area
-    const bool history_area =
-      text_cursor.anchor() < this->InteractivePosition
-      || text_cursor.position() < this->InteractivePosition;
+    const bool history_area = this->isCursorInHistoryArea();
 
     // Allow copying anywhere in the console ...
     if(e->key() == Qt::Key_C && e->modifiers() == Qt::ControlModifier)
@@ -185,48 +183,11 @@ void ctkConsolePrivate::keyPressEvent(QKeyEvent* e)
       return;
       }
 
-    // Allow paste only if the selection is in the interactive area ...
-    if(e->key() == Qt::Key_V && e->modifiers() == Qt::ControlModifier)
-      {
-      if(!history_area)
-        {
-        const QMimeData* const clipboard = QApplication::clipboard()->mimeData();
-        const QString text = clipboard->text();
-        if(!text.isNull())
-          {
-          if (this->EditorHints & ctkConsole::SplitCopiedTextByLine)
-            {
-            QStringList lines = text.split(QRegExp("(?:\r\n|\r|\n)"));
-            for(int i=0; i < lines.count(); ++i)
-              {
-              this->switchToUserInputTextColor(&text_cursor);
-              text_cursor.insertText(lines.at(i));
-              this->updateCommandBuffer();
-              if (i < lines.count() - 1)
-                {
-                this->internalExecuteCommand();
-                }
-              }
-            }
-          else
-            {
-            this->switchToUserInputTextColor(&text_cursor);
-            text_cursor.insertText(text);
-            this->updateCommandBuffer();
-            }
-          }
-        }
-
-      e->accept();
-      return;
-      }
-
     // Force the cursor back to the interactive area
     if(history_area && e->key() != Qt::Key_Control)
       {
       text_cursor.setPosition(this->documentEnd());
       this->setTextCursor(text_cursor);
-
       }
 
     switch(e->key())
@@ -650,6 +611,63 @@ void ctkConsolePrivate::onScrollBarValueChanged(int value)
 }
 
 //-----------------------------------------------------------------------------
+bool ctkConsolePrivate::isCursorInHistoryArea()const
+{
+  return this->textCursor().anchor() < this->InteractivePosition
+    || this->textCursor().position() < this->InteractivePosition;
+}
+
+//-----------------------------------------------------------------------------
+void ctkConsolePrivate::insertFromMimeData(const QMimeData* source)
+{
+  if (this->isCursorInHistoryArea())
+    {
+    QTextCursor textCursor = this->textCursor();
+    textCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
+    this->setTextCursor(textCursor);
+    }
+  const QString text = source->text();
+  if (!text.isEmpty())
+    {
+    this->pasteText(text);
+    }
+  else
+    {
+    this->Superclass::insertFromMimeData(source);
+    }
+}
+
+//-----------------------------------------------------------------------------
+void ctkConsolePrivate::pasteText(const QString& text)
+{
+  if(text.isNull())
+    {
+    return;
+    }
+  QTextCursor textCursor = this->textCursor();
+  if (this->EditorHints & ctkConsole::SplitCopiedTextByLine)
+    {
+    QStringList lines = text.split(QRegExp("(?:\r\n|\r|\n)"));
+    for(int i=0; i < lines.count(); ++i)
+      {
+      this->switchToUserInputTextColor(&textCursor);
+      textCursor.insertText(lines.at(i));
+      this->updateCommandBuffer();
+      if (i < lines.count() - 1)
+        {
+        this->internalExecuteCommand();
+        }
+      }
+    }
+  else
+    {
+    this->switchToUserInputTextColor(&textCursor);
+    textCursor.insertText(text);
+    this->updateCommandBuffer();
+    }
+}
+
+//-----------------------------------------------------------------------------
 // ctkConsole methods
 
 //-----------------------------------------------------------------------------

+ 11 - 0
Libs/Widgets/ctkConsole_p.h

@@ -121,6 +121,17 @@ public Q_SLOTS:
   /// Update the value of ScrollbarAtBottom given the current position of the scollbar
   void onScrollBarValueChanged(int value);
 
+protected:
+  /// Return true if the cursor position is in the history area
+  /// false if it is after the InteractivePosition.
+  bool isCursorInHistoryArea()const;
+
+  /// Reimplemented to make sure there is no text added into the
+  /// history logs.
+  virtual void insertFromMimeData(const QMimeData* source);
+
+  /// Paste text at the current text cursor position.
+  void pasteText(const QString& text);
 public:
 
   /// A custom completer