Pārlūkot izejas kodu

ENH: ctkPythonConsole: Offset cursor for function in user-defined classes

This commit is based on commit d4d8c7e originally associated with
topic python-autocomplete-parameter-detection from Christopher
Mullins.

It fixes issues reported in http://na-mic.org/Mantis/view.php?id=1227

Co-authored-by: Mayeul Chassagnard <mayeul.chassagnard@kitware.com>
Co-authored-by: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com>
Christopher Mullins 9 gadi atpakaļ
vecāks
revīzija
ea557e2790
1 mainītis faili ar 34 papildinājumiem un 0 dzēšanām
  1. 34 0
      Libs/Scripting/Python/Widgets/ctkPythonConsole.cpp

+ 34 - 0
Libs/Scripting/Python/Widgets/ctkPythonConsole.cpp

@@ -88,8 +88,10 @@ public:
   virtual void updateCompletionModel(const QString& completion);
 
 protected:
+  bool isInUserDefinedClass(const QString &pythonFunctionPath);
   bool isUserDefinedFunction(const QString &pythonFunctionName);
   bool isBuiltInFunction(const QString &pythonFunctionName);
+  int parameterCountUserDefinedClassFunction(const QString &pythonFunctionName);
   int parameterCountBuiltInFunction(const QString& pythonFunctionName);
   int parameterCountUserDefinedFunction(const QString& pythonFunctionName);
   int parameterCountFromDocumentation(const QString& pythonFunctionPath);
@@ -139,6 +141,10 @@ int ctkPythonConsoleCompleter::cursorOffset(const QString& completion)
       {
       parameterCount = this->parameterCountUserDefinedFunction(QStringList(userDefinedFunctionPath+lineSplit).join("."));
       }
+    else if (this->isInUserDefinedClass(currentCompletionText))
+      {
+      parameterCount = this->parameterCountUserDefinedClassFunction(QStringList(userDefinedFunctionPath+lineSplit).join("."));
+      }
     else
       {
       QStringList variableNameAndFunctionList = userDefinedFunctionPath + lineSplit;
@@ -155,6 +161,12 @@ int ctkPythonConsoleCompleter::cursorOffset(const QString& completion)
 
 
 //---------------------------------------------------------------------------
+bool ctkPythonConsoleCompleter::isInUserDefinedClass(const QString &pythonFunctionPath)
+{
+  return this->PythonManager.pythonAttributes(pythonFunctionPath).contains("__func__");
+}
+
+//---------------------------------------------------------------------------
 bool ctkPythonConsoleCompleter::isUserDefinedFunction(const QString &pythonFunctionName)
 {
   return this->PythonManager.pythonAttributes(pythonFunctionName).contains("__call__");
@@ -207,6 +219,28 @@ int ctkPythonConsoleCompleter::parameterCountUserDefinedFunction(const QString&
 }
 
 //----------------------------------------------------------------------------
+int ctkPythonConsoleCompleter::parameterCountUserDefinedClassFunction(const QString& pythonFunctionName)
+{
+  int parameterCount = 0;
+  PyObject* pFunction = this->PythonManager.pythonObject(pythonFunctionName);
+  if (PyCallable_Check(pFunction))
+    {
+    PyObject* fc = PyObject_GetAttrString(pFunction, "func_code");
+    if (fc)
+      {
+      PyObject* ac = PyObject_GetAttrString(fc, "co_argcount");
+      if (ac)
+        {
+        parameterCount = PyInt_AsLong(ac);
+        Py_DECREF(ac);
+        }
+      Py_DECREF(fc);
+      }
+    }
+  return parameterCount;
+}
+
+//----------------------------------------------------------------------------
 int ctkPythonConsoleCompleter::parameterCountFromDocumentation(const QString& pythonFunctionPath)
 {
   int parameterCount = 0;