Przeglądaj źródła

Add ctkConsole_p.h header and update ctkPythonConsolePrivate code organization

Jean-Christophe Fillion-Robin 14 lat temu
rodzic
commit
11d77f9ed4

+ 108 - 92
Libs/Scripting/Python/Widgets/ctkPythonConsole.cpp

@@ -143,7 +143,6 @@ public:
   ctkPythonConsole& Parent;
   ctkPythonConsole& Parent;
 };
 };
 
 
-
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 // ctkPythonConsolePrivate
 // ctkPythonConsolePrivate
 
 
@@ -154,121 +153,138 @@ class ctkPythonConsolePrivate
 protected:
 protected:
   ctkPythonConsole* const q_ptr;
   ctkPythonConsole* const q_ptr;
 public:
 public:
-  ctkPythonConsolePrivate(ctkPythonConsole& object, ctkAbstractPythonManager* pythonManager)
-    : q_ptr(&object), Console(&object), PythonManager(pythonManager), MultilineStatement(false),
-    InteractiveConsole(0)
-  {
-  }
+  ctkPythonConsolePrivate(ctkPythonConsole& object, ctkAbstractPythonManager* pythonManager);
+  ~ctkPythonConsolePrivate();
+
+  void initializeInteractiveConsole();
+
+  bool push(const QString& code);
+
+  void resetBuffer();
+
+  void executeCommand(const QString& command);
+
+  void promptForInput(const QString& indent = QString());
+
+  /// Provides a console for gathering user input and displaying Python output
+  ctkConsole Console;
+
+  ctkAbstractPythonManager* PythonManager;
+
+  /// Indicates if the last statement processes was incomplete.
+  bool MultilineStatement;
+
+  PyObject* InteractiveConsole;
+};
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-  ~ctkPythonConsolePrivate()
-  {
-  }
+// ctkPythonConsolePrivate methods
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-  void initializeInteractiveConsole()
-  {
-    // set up the code.InteractiveConsole instance that we'll use.
-    const char* code =
-      "import code\n"
-      "__ctkConsole=code.InteractiveConsole(locals())\n";
-    PyRun_SimpleString(code);
+ctkPythonConsolePrivate::ctkPythonConsolePrivate(
+  ctkPythonConsole& object, ctkAbstractPythonManager* pythonManager)
+  : q_ptr(&object), Console(&object), PythonManager(pythonManager), MultilineStatement(false),
+  InteractiveConsole(0)
+{
+}
 
 
-    // Now get the reference to __ctkConsole and save the pointer.
-    PyObject* main_module = PyImport_AddModule("__main__");
-    PyObject* global_dict = PyModule_GetDict(main_module);
-    this->InteractiveConsole = PyDict_GetItemString(
-      global_dict, "__ctkConsole");
-    if (!this->InteractiveConsole)
-      {
-      qCritical("Failed to locate the InteractiveConsole object.");
-      }
-  }
+//----------------------------------------------------------------------------
+ctkPythonConsolePrivate::~ctkPythonConsolePrivate()
+{
+}
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-  bool push(const QString& code)
-  {
-    bool ret_value = false;
-
-    QString buffer = code;
-    // The embedded python interpreter cannot handle DOS line-endings, see
-    // http://sourceforge.net/tracker/?group_id=5470&atid=105470&func=detail&aid=1167922
-    buffer.remove('\r');
-
-    PyObject *res = PyObject_CallMethod(this->InteractiveConsole,
-                                        const_cast<char*>("push"),
-                                        const_cast<char*>("z"),
-                                        buffer.toAscii().data());
-    if (res)
+void ctkPythonConsolePrivate::initializeInteractiveConsole()
+{
+  // set up the code.InteractiveConsole instance that we'll use.
+  const char* code =
+    "import code\n"
+    "__ctkConsole=code.InteractiveConsole(locals())\n";
+  PyRun_SimpleString(code);
+
+  // Now get the reference to __ctkConsole and save the pointer.
+  PyObject* main_module = PyImport_AddModule("__main__");
+  PyObject* global_dict = PyModule_GetDict(main_module);
+  this->InteractiveConsole = PyDict_GetItemString(
+    global_dict, "__ctkConsole");
+  if (!this->InteractiveConsole)
+    {
+    qCritical("Failed to locate the InteractiveConsole object.");
+    }
+}
+
+//----------------------------------------------------------------------------
+bool ctkPythonConsolePrivate::push(const QString& code)
+{
+  bool ret_value = false;
+
+  QString buffer = code;
+  // The embedded python interpreter cannot handle DOS line-endings, see
+  // http://sourceforge.net/tracker/?group_id=5470&atid=105470&func=detail&aid=1167922
+  buffer.remove('\r');
+
+  PyObject *res = PyObject_CallMethod(this->InteractiveConsole,
+                                      const_cast<char*>("push"),
+                                      const_cast<char*>("z"),
+                                      buffer.toAscii().data());
+  if (res)
+    {
+    int status = 0;
+    if (PyArg_Parse(res, "i", &status))
       {
       {
-      int status = 0;
-      if (PyArg_Parse(res, "i", &status))
-        {
-        ret_value = (status > 0);
-        }
-      Py_DECREF(res);
+      ret_value = (status > 0);
       }
       }
-    return ret_value;
-  }
+    Py_DECREF(res);
+    }
+  return ret_value;
+}
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-  void resetBuffer()
-  {
+void ctkPythonConsolePrivate::resetBuffer()
+{
   if (this->InteractiveConsole)
   if (this->InteractiveConsole)
-    {
+  {
     //this->MakeCurrent();
     //this->MakeCurrent();
     const char* code = "__ctkConsole.resetbuffer()\n";
     const char* code = "__ctkConsole.resetbuffer()\n";
     PyRun_SimpleString(code);
     PyRun_SimpleString(code);
     //this->ReleaseControl();
     //this->ReleaseControl();
-    }
   }
   }
+}
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-  void executeCommand(const QString& command)
-  {
-    this->MultilineStatement = this->push(command);
-//    if (command.length())
-//      {
-//      Q_ASSERT(this->PythonManager);
-//      this->PythonManager->executeString(command);
-//      }
-  }
+void ctkPythonConsolePrivate::executeCommand(const QString& command)
+{
+  this->MultilineStatement = this->push(command);
+//  if (command.length())
+//    {
+//    Q_ASSERT(this->PythonManager);
+//    this->PythonManager->executeString(command);
+//    }
+}
   
   
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-  void promptForInput(const QString& indent=QString())
-  {
-    QTextCharFormat format = this->Console.getFormat();
-    format.setForeground(QColor(0, 0, 0));
-    this->Console.setFormat(format);
+void ctkPythonConsolePrivate::promptForInput(const QString& indent)
+{
+  QTextCharFormat format = this->Console.getFormat();
+  format.setForeground(QColor(0, 0, 0));
+  this->Console.setFormat(format);
 
 
 //     this->Interpreter->MakeCurrent();
 //     this->Interpreter->MakeCurrent();
-    if(!this->MultilineStatement)
-      {
-      this->Console.prompt(">>> ");
-      //this->Console.prompt(
-      //  PyString_AsString(PySys_GetObject(const_cast<char*>("ps1"))));
-      }
-    else
-      {
-      this->Console.prompt("... ");
-      //this->Console.prompt(
-      //  PyString_AsString(PySys_GetObject(const_cast<char*>("ps2"))));
-      }
-    this->Console.printCommand(indent);
+  if(!this->MultilineStatement)
+    {
+    this->Console.prompt(">>> ");
+    //this->Console.prompt(
+    //  PyString_AsString(PySys_GetObject(const_cast<char*>("ps1"))));
+    }
+  else
+    {
+    this->Console.prompt("... ");
+    //this->Console.prompt(
+    //  PyString_AsString(PySys_GetObject(const_cast<char*>("ps2"))));
+    }
+  this->Console.printCommand(indent);
 //     this->Interpreter->ReleaseControl();
 //     this->Interpreter->ReleaseControl();
-  }
-
-  /// Provides a console for gathering user input and displaying 
-  /// Python output
-  ctkConsole Console;
-
-  ctkAbstractPythonManager* PythonManager;
-
-  /// Indicates if the last statement processes was incomplete.
-  bool MultilineStatement;
-
-  PyObject* InteractiveConsole;
-};
+}
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 // ctkPythonConsole methods
 // ctkPythonConsole methods

+ 1 - 0
Libs/Widgets/CMakeLists.txt

@@ -35,6 +35,7 @@ SET(KIT_SRCS
   ctkColorPickerButton.h
   ctkColorPickerButton.h
   ctkConsole.cpp
   ctkConsole.cpp
   ctkConsole.h
   ctkConsole.h
+  ctkConsole_p.h
   ctkConfirmExitDialog.cpp
   ctkConfirmExitDialog.cpp
   ctkConfirmExitDialog.h
   ctkConfirmExitDialog.h
   ctkCoordinatesWidget.cpp
   ctkCoordinatesWidget.cpp

+ 151 - 166
Libs/Widgets/ctkConsole.cpp

@@ -57,50 +57,44 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <QKeyEvent>
 #include <QKeyEvent>
 #include <QPointer>
 #include <QPointer>
 #include <QTextCursor>
 #include <QTextCursor>
-#include <QTextEdit>
 #include <QVBoxLayout>
 #include <QVBoxLayout>
 #include <QScrollBar>
 #include <QScrollBar>
 
 
 // CTK includes
 // CTK includes
 #include "ctkConsole.h"
 #include "ctkConsole.h"
+#include "ctkConsole_p.h"
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-// ctkConsolePrivate
+// ctkConsolePrivate methods
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-class ctkConsolePrivate : public QTextEdit
+ctkConsolePrivate::ctkConsolePrivate(ctkConsole& object) :
+  QTextEdit(&object),
+  q_ptr(&object),
+  InteractivePosition(documentEnd())
 {
 {
-  Q_DECLARE_PUBLIC(ctkConsole);
-protected:
-  ctkConsole* const q_ptr;
-public:
-  ctkConsolePrivate(ctkConsole& object) :
-    QTextEdit(&object),
-    q_ptr(&object),
-    InteractivePosition(documentEnd())
-  {
-    this->setTabChangesFocus(false);
-    this->setAcceptDrops(false);
-    this->setAcceptRichText(false);
-    this->setUndoRedoEnabled(false);
-    
-    QFont f;
-    f.setFamily("Courier");
-    f.setStyleHint(QFont::TypeWriter);
-    f.setFixedPitch(true);
-    
-    QTextCharFormat format;
-    format.setFont(f);
-    format.setForeground(QColor(0, 0, 0));
-    this->setCurrentCharFormat(format);
-    
-    this->CommandHistory.append("");
-    this->CommandPosition = 0;
-  }
-
-  void keyPressEvent(QKeyEvent* e)
-  {
+  this->setTabChangesFocus(false);
+  this->setAcceptDrops(false);
+  this->setAcceptRichText(false);
+  this->setUndoRedoEnabled(false);
+  
+  QFont f;
+  f.setFamily("Courier");
+  f.setStyleHint(QFont::TypeWriter);
+  f.setFixedPitch(true);
+  
+  QTextCharFormat format;
+  format.setFont(f);
+  format.setForeground(QColor(0, 0, 0));
+  this->setCurrentCharFormat(format);
+  
+  this->CommandHistory.append("");
+  this->CommandPosition = 0;
+}
 
 
+//-----------------------------------------------------------------------------
+void ctkConsolePrivate::keyPressEvent(QKeyEvent* e)
+{
   if (this->Completer && this->Completer->popup()->isVisible())
   if (this->Completer && this->Completer->popup()->isVisible())
     {
     {
     // The following keys are forwarded by the completer to the widget
     // The following keys are forwarded by the completer to the widget
@@ -210,7 +204,7 @@ public:
           }
           }
         break;
         break;
         
         
-  
+
       case Qt::Key_Delete:
       case Qt::Key_Delete:
         e->accept();
         e->accept();
         QTextEdit::keyPressEvent(e);
         QTextEdit::keyPressEvent(e);
@@ -257,155 +251,146 @@ public:
         this->updateCompleterIfVisible();
         this->updateCompleterIfVisible();
         break;
         break;
       }
       }
-  }
+}
   
   
-  /// Returns the end of the document
-  /*const*/ int documentEnd()
-  {
-    QTextCursor c(this->document());
-    c.movePosition(QTextCursor::End);
-    return c.position();
-  }
-
-  void focusOutEvent(QFocusEvent *e)
-  {
-    QTextEdit::focusOutEvent(e);
-
-    // For some reason the QCompleter tries to set the focus policy to
-    // NoFocus, set let's make sure we set it back to the default WheelFocus.
-    this->setFocusPolicy(Qt::WheelFocus);
-  }
-
-  void updateCompleterIfVisible()
-  {
-    if (this->Completer && this->Completer->popup()->isVisible())
+//-----------------------------------------------------------------------------
+/*const*/ int ctkConsolePrivate::documentEnd()
+{
+  QTextCursor c(this->document());
+  c.movePosition(QTextCursor::End);
+  return c.position();
+}
+
+//-----------------------------------------------------------------------------
+void ctkConsolePrivate::focusOutEvent(QFocusEvent *e)
+{
+  QTextEdit::focusOutEvent(e);
+
+  // For some reason the QCompleter tries to set the focus policy to
+  // NoFocus, set let's make sure we set it back to the default WheelFocus.
+  this->setFocusPolicy(Qt::WheelFocus);
+}
+
+//-----------------------------------------------------------------------------
+void ctkConsolePrivate::updateCompleterIfVisible()
+{
+  if (this->Completer && this->Completer->popup()->isVisible())
+    {
+    this->updateCompleter();
+    }
+}
+
+//-----------------------------------------------------------------------------
+void ctkConsolePrivate::selectCompletion()
+{
+  Q_Q(ctkConsole);
+  if (this->Completer && this->Completer->completionCount() == 1)
+    {
+    q->insertCompletion(this->Completer->currentCompletion());
+    this->Completer->popup()->hide();
+    }
+}
+
+//-----------------------------------------------------------------------------
+void ctkConsolePrivate::updateCompleter()
+{
+  if (this->Completer)
+    {
+    // Get the text between the current cursor position
+    // and the start of the line
+    QTextCursor text_cursor = this->textCursor();
+    text_cursor.setPosition(this->InteractivePosition, QTextCursor::KeepAnchor);
+    QString commandText = text_cursor.selectedText();
+
+    // Call the completer to update the completion model
+    this->Completer->updateCompletionModel(commandText);
+
+    // Place and show the completer if there are available completions
+    if (this->Completer->completionCount())
       {
       {
-      this->updateCompleter();
+      // Get a QRect for the cursor at the start of the
+      // current word and then translate it down 8 pixels.
+      text_cursor = this->textCursor();
+      text_cursor.movePosition(QTextCursor::StartOfWord);
+      QRect cr = this->cursorRect(text_cursor);
+      cr.translate(0,8);
+      cr.setWidth(this->Completer->popup()->sizeHintForColumn(0)
+        + this->Completer->popup()->verticalScrollBar()->sizeHint().width());
+      this->Completer->complete(cr);
       }
       }
-  }
-
-  /// If there is exactly 1 completion, insert it and hide the completer,
-  /// else do nothing.
-  void selectCompletion()
-  {
-    Q_Q(ctkConsole);
-    if (this->Completer && this->Completer->completionCount() == 1)
+    else
       {
       {
-      q->insertCompletion(this->Completer->currentCompletion());
       this->Completer->popup()->hide();
       this->Completer->popup()->hide();
       }
       }
-  }
-
-  void updateCompleter()
-  {
-    if (this->Completer)
-      {
-      // Get the text between the current cursor position
-      // and the start of the line
-      QTextCursor text_cursor = this->textCursor();
-      text_cursor.setPosition(this->InteractivePosition, QTextCursor::KeepAnchor);
-      QString commandText = text_cursor.selectedText();
-
-      // Call the completer to update the completion model
-      this->Completer->updateCompletionModel(commandText);
-
-      // Place and show the completer if there are available completions
-      if (this->Completer->completionCount())
-        {
-        // Get a QRect for the cursor at the start of the
-        // current word and then translate it down 8 pixels.
-        text_cursor = this->textCursor();
-        text_cursor.movePosition(QTextCursor::StartOfWord);
-        QRect cr = this->cursorRect(text_cursor);
-        cr.translate(0,8);
-        cr.setWidth(this->Completer->popup()->sizeHintForColumn(0)
-          + this->Completer->popup()->verticalScrollBar()->sizeHint().width());
-        this->Completer->complete(cr);
-        }
-      else
-        {
-        this->Completer->popup()->hide();
-        }
-      }
-  }
-  
-  /// Update the contents of the command buffer from the contents of the widget
-  void updateCommandBuffer()
-  {
-    this->commandBuffer() = this->toPlainText().mid(this->InteractivePosition);
-  }
+    }
+}
   
   
-  /// Replace the contents of the command buffer, updating the display
-  void replaceCommandBuffer(const QString& Text)
-  {
-    this->commandBuffer() = Text;
+//-----------------------------------------------------------------------------c
+void ctkConsolePrivate::updateCommandBuffer()
+{
+  this->commandBuffer() = this->toPlainText().mid(this->InteractivePosition);
+}
   
   
-    QTextCursor c(this->document());
-    c.setPosition(this->InteractivePosition);
-    c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
-    c.removeSelectedText();
-    c.insertText(Text);
-  }
+//-----------------------------------------------------------------------------
+void ctkConsolePrivate::replaceCommandBuffer(const QString& Text)
+{
+  this->commandBuffer() = Text;
+
+  QTextCursor c(this->document());
+  c.setPosition(this->InteractivePosition);
+  c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
+  c.removeSelectedText();
+  c.insertText(Text);
+}
   
   
-  /// References the buffer where the current un-executed command is stored
-  QString& commandBuffer()
-  {
-    return this->CommandHistory.back();
-  }
+//-----------------------------------------------------------------------------
+QString& ctkConsolePrivate::commandBuffer()
+{
+  return this->CommandHistory.back();
+}
   
   
-  /// Implements command-execution
-  void internalExecuteCommand()
+//-----------------------------------------------------------------------------
+void ctkConsolePrivate::internalExecuteCommand()
+{
+  Q_Q(ctkConsole);
+
+  // First update the history cache. It's essential to update the
+  // this->CommandPosition before calling internalExecuteCommand() since that
+  // can result in a clearing of the current command (BUG #8765).
+  QString command = this->commandBuffer();
+  if (!command.isEmpty()) // Don't store empty commands in the history
     {
     {
-    Q_Q(ctkConsole);
+    this->CommandHistory.push_back("");
+    this->CommandPosition = this->CommandHistory.size() - 1;
+    }
+  QTextCursor c(this->document());
+  c.movePosition(QTextCursor::End);
+  c.insertText("\n");
 
 
-    // First update the history cache. It's essential to update the
-    // this->CommandPosition before calling internalExecuteCommand() since that
-    // can result in a clearing of the current command (BUG #8765).
-    QString command = this->commandBuffer();
-    if (!command.isEmpty()) // Don't store empty commands in the history
-      {
-      this->CommandHistory.push_back("");
-      this->CommandPosition = this->CommandHistory.size() - 1;
-      }
-    QTextCursor c(this->document());
-    c.movePosition(QTextCursor::End);
-    c.insertText("\n");
+  this->InteractivePosition = this->documentEnd();
+  q->internalExecuteCommand(command);
+}
 
 
-    this->InteractivePosition = this->documentEnd();
-    q->internalExecuteCommand(command);
-    }
+//-----------------------------------------------------------------------------
+void ctkConsolePrivate::setCompleter(ctkConsoleCompleter* completer)
+{
+  Q_Q(ctkConsole);
 
 
-  void setCompleter(ctkConsoleCompleter* completer)
+  if (this->Completer)
     {
     {
-    Q_Q(ctkConsole);
-
-    if (this->Completer)
-      {
-      this->Completer->setWidget(0);
-      QObject::disconnect(this->Completer, SIGNAL(activated(const QString&)),
-                          q, SLOT(insertCompletion(const QString&)));
+    this->Completer->setWidget(0);
+    QObject::disconnect(this->Completer, SIGNAL(activated(const QString&)),
+                        q, SLOT(insertCompletion(const QString&)));
 
 
-      }
-    this->Completer = completer;
-    if (this->Completer)
-      {
-      this->Completer->setWidget(this);
-      QObject::connect(this->Completer, SIGNAL(activated(const QString&)),
-                       q, SLOT(insertCompletion(const QString&)));
-      }
     }
     }
-
-  /// A custom completer
-  QPointer<ctkConsoleCompleter> Completer;
-
-  /** Stores the beginning of the area of interactive input, outside which
-  changes can't be made to the text edit contents */
-  int InteractivePosition;
-  /// Stores command-history, plus the current command buffer
-  QStringList CommandHistory;
-  /// Stores the current position in the command-history
-  int CommandPosition;
-};
+  this->Completer = completer;
+  if (this->Completer)
+    {
+    this->Completer->setWidget(this);
+    QObject::connect(this->Completer, SIGNAL(activated(const QString&)),
+                     q, SLOT(insertCompletion(const QString&)));
+    }
+}
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // ctkConsole methods
 // ctkConsole methods

+ 83 - 0
Libs/Widgets/ctkConsole_p.h

@@ -0,0 +1,83 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkConsole_p_h
+#define __ctkConsole_p_h
+
+// Qt includes
+#include <QTextEdit>
+
+// CTK includes
+#include "ctkConsole.h"
+#include "ctkWidgetsExport.h"
+
+class CTK_WIDGETS_EXPORT ctkConsolePrivate : public QTextEdit
+{
+  Q_DECLARE_PUBLIC(ctkConsole);
+protected:
+  ctkConsole* const q_ptr;
+public:
+
+  ctkConsolePrivate(ctkConsole& object);
+
+  void keyPressEvent(QKeyEvent* e);
+  
+  /// Returns the end of the document
+  /*const*/ int documentEnd();
+
+  void focusOutEvent(QFocusEvent *e);
+
+  void updateCompleterIfVisible();
+
+  /// If there is exactly 1 completion, insert it and hide the completer,
+  /// else do nothing.
+  void selectCompletion();
+
+  void updateCompleter();
+  
+  /// Update the contents of the command buffer from the contents of the widget
+  void updateCommandBuffer();
+  
+  /// Replace the contents of the command buffer, updating the display
+  void replaceCommandBuffer(const QString& Text);
+  
+  /// References the buffer where the current un-executed command is stored
+  QString& commandBuffer();
+  
+  /// Implements command-execution
+  void internalExecuteCommand();
+  
+  void setCompleter(ctkConsoleCompleter* completer);
+
+  /// A custom completer
+  QPointer<ctkConsoleCompleter> Completer;
+
+  /** Stores the beginning of the area of interactive input, outside which
+  changes can't be made to the text edit contents */
+  int InteractivePosition;
+  /// Stores command-history, plus the current command buffer
+  QStringList CommandHistory;
+  /// Stores the current position in the command-history
+  int CommandPosition;
+};
+
+
+#endif
+