]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
PyConsole: fix multi-line pasting.
authorbruneton <bruneton>
Thu, 4 Apr 2013 14:43:53 +0000 (14:43 +0000)
committerbruneton <bruneton>
Thu, 4 Apr 2013 14:43:53 +0000 (14:43 +0000)
Code on several lines can now be pasted properly (including with indentation).

src/PyConsole/PyConsole_Editor.cxx
src/PyConsole/PyConsole_EnhEditor.cxx
src/PyConsole/PyConsole_EnhEditor.h

index aac8a4d4bab870f7b6432aad9e7e8121219fb342..cee79f24547e089d61aab79abfd91954ebe8c7db 100644 (file)
@@ -315,6 +315,8 @@ void PyConsole_Editor::addText( const QString& str,
   \brief Convenient method for executing a Python command,
   as if the user typed it manually.
   \param command python command to be executed
+
+  !!! WARNING: doesn't work properly with multi-line commands. !!!
 */
 void PyConsole_Editor::exec( const QString& command )
 {
@@ -395,6 +397,9 @@ void PyConsole_Editor::execAndWait( const QString& command )
 */
 void PyConsole_Editor::handleReturn()
 {
+  // Position cursor at the end
+  textCursor().movePosition(QTextCursor::End);
+
   // get last line
   QTextBlock par = document()->end().previous();
   if ( !par.isValid() ) return;
index aaec2b1d80d919a07d444cb8c7d553b5f688fb62..de089a8058bdd65f82a01fe42a4cfed5d4095716 100644 (file)
@@ -46,7 +46,9 @@ const std::vector<QString> PyConsole_EnhEditor::SEPARATORS = \
 PyConsole_EnhEditor::PyConsole_EnhEditor(PyConsole_EnhInterp * interp, QWidget * parent) :
      PyConsole_Editor(interp, parent),
      _tab_mode(false),
-     _cursor_pos(-1)
+     _cursor_pos(-1),
+     _multi_line_paste(false),
+     _multi_line_content()
 {
   document()->setUndoRedoEnabled(true);
 }
@@ -318,9 +320,14 @@ void PyConsole_EnhEditor::customEvent( QEvent* event )
       _tab_mode = false;
       _cursor_pos = -1;
       break;
-//    case PyEnhInterp_Event::ES_MULTI_PASTE:
-//      multilinePaste();
-//      break;
+    case PyInterp_Event::ES_OK:
+    case PyInterp_Event::ES_ERROR:
+    case PyInterp_Event::ES_INCOMPLETE:
+      // Before everything else, call super()
+      PyConsole_Editor::customEvent(event);
+      // If we are in multi_paste_mode, process the next item:
+      multiLineProcessNextLine();
+      break;
     default:
       PyConsole_Editor::customEvent( event );
       break;
@@ -388,3 +395,80 @@ QString PyConsole_EnhEditor::formatDocHTML(const QString & doc) const
   rest = rest.replace("\n", " ");
   return templ.arg(fst).arg(rest);
 }
+
+/**
+ * Handle properly multi-line pasting. Qt4 doc recommends overriding this function.
+ * If the pasted text doesn't contain a line return, no special treatment is done.
+ * @param source
+ */
+void PyConsole_EnhEditor::insertFromMimeData(const QMimeData * source)
+{
+  if (_multi_line_paste)
+    return;
+
+  if (source->hasText())
+    {
+      QString s = source->text();
+      if (s.contains("\n"))
+        multilinePaste(s);
+      else
+        PyConsole_Editor::insertFromMimeData(source);
+    }
+  else
+    {
+      PyConsole_Editor::insertFromMimeData(source);
+    }
+}
+
+
+void PyConsole_EnhEditor::multilinePaste(const QString & s)
+{
+  // Turn on multi line pasting mode
+  _multi_line_paste = true;
+
+  // Split the string:
+  QString s2 = s;
+  s2.replace("\r", ""); // Windows string format converted to Unix style
+
+  QStringList lst = s2.split(QChar('\n'), QString::KeepEmptyParts);
+
+  // Perform the proper paste operation for the first line to handle the case where
+  // sth was already there:
+  QMimeData source;
+  source.setText(lst[0]);
+  PyConsole_Editor::insertFromMimeData(&source);
+
+  // Prepare what will have to be executed after the first line:
+  _multi_line_content = std::queue<QString>();
+  for (int i = 1; i < lst.size(); ++i)
+    _multi_line_content.push(lst[i]);
+
+  // Trigger the execution of the first (mixed) line
+  handleReturn();
+
+  // See customEvent() and multiLineProcessNext() for the rest of the handling.
+}
+
+/**
+ * Process the next line in the queue of a multiple copy/paste:
+ */
+void PyConsole_EnhEditor::multiLineProcessNextLine()
+{
+  if (!_multi_line_paste)
+    return;
+
+  QString line(_multi_line_content.front());
+  _multi_line_content.pop();
+  if (!_multi_line_content.size())
+    {
+      // last line in the queue, just paste it
+      addText(line, false, false);
+      _multi_line_paste = false;
+    }
+  else
+    {
+      // paste the line and simulate a <RETURN> key stroke
+      addText(line, false, false);
+      handleReturn();
+    }
+}
index 2500fc9e95faf0a46199ec6e586b8dab60268119..f52dc8256a27dedff51dadcdb1f3dd68ff08f2dc 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "PyConsole_Editor.h"
 #include <QObject>
+#include <queue>
 
 class PyConsole_EnhInterp;
 
@@ -66,13 +67,17 @@ protected:
   /** Cursor position when <TAB> is hit */
   int _cursor_pos;
 
-//  std::stack<QString> _multi_line_content;
+  /** Are we currently pasting several lines */
+  bool _multi_line_paste;
+
+  /** Queue of lines being pasted */
+  std::queue<QString> _multi_line_content;
 
   // Overrides:
   virtual void   keyPressEvent ( QKeyEvent* event);
   virtual void   customEvent( QEvent* event);
   virtual void   mousePressEvent( QMouseEvent* event );
-//  virtual void   insertFromMimeData(const QMimeData * source);
+  virtual void   insertFromMimeData(const QMimeData * source);
 
   virtual PyInterp_Request* createTabRequest( const QString& input );
   virtual void handleTab();
@@ -80,7 +85,9 @@ protected:
   virtual void clearCompletion();
   virtual void formatCompletion(const std::vector<QString> & matches, QString & result) const;
   virtual QString formatDocHTML(const QString & doc) const;
-//  virtual void multilinePaste();
+
+  virtual void multilinePaste(const QString & s);
+  virtual void multiLineProcessNextLine();
 
 private:
   void extractCommon(const std::vector<QString> & matches, QString & result) const;