From aec36eec7c70defd178fc6dc76d3db1b6807454f Mon Sep 17 00:00:00 2001
From: Erik Verbruggen <erik.verbruggen@nokia.com>
Date: Tue, 27 Jul 2010 17:02:12 +0200
Subject: [PATCH] Use the new InsertionPointLocator for declarations.

Still need to change it to use RefactoringChanges, and to do better definition
generation.
---
 src/libs/cplusplus/InsertionPointLocator.cpp  |  6 +-
 src/plugins/designer/qtcreatorintegration.cpp | 83 +++++++++----------
 2 files changed, 42 insertions(+), 47 deletions(-)

diff --git a/src/libs/cplusplus/InsertionPointLocator.cpp b/src/libs/cplusplus/InsertionPointLocator.cpp
index 3f34f06da69..9db5278e244 100644
--- a/src/libs/cplusplus/InsertionPointLocator.cpp
+++ b/src/libs/cplusplus/InsertionPointLocator.cpp
@@ -57,7 +57,7 @@ static QString generate(InsertionPointLocator::AccessSpec xsSpec)
         return QLatin1String("protected slots:\n");
 
     case InsertionPointLocator::PrivateSlot:
-        return QLatin1String("private slot:\n");
+        return QLatin1String("private slots:\n");
 
     case InsertionPointLocator::Signals:
         return QLatin1String("signals:\n");
@@ -158,8 +158,8 @@ protected:
         }
 
         // try to find a fitting access spec to insert in front of:
-        AccessRange best = ranges.first();
-        for (int i = ranges.size() - 1; i > 0; --i) {
+        AccessRange best = ranges.last();
+        for (int i = ranges.size() - 2; i > 0; --i) {
             const AccessRange &range = ranges.at(i);
             if (distance(range.xsSpec, xsSpec) < distance(best.xsSpec, xsSpec))
                 best = range;
diff --git a/src/plugins/designer/qtcreatorintegration.cpp b/src/plugins/designer/qtcreatorintegration.cpp
index 9957ba05363..ff40fd0c1a4 100644
--- a/src/plugins/designer/qtcreatorintegration.cpp
+++ b/src/plugins/designer/qtcreatorintegration.cpp
@@ -36,6 +36,7 @@
 #include <widgethost.h>
 
 #include <cpptools/cppmodelmanagerinterface.h>
+#include <cplusplus/InsertionPointLocator.h>
 #include <cplusplus/Symbols.h>
 #include <cplusplus/Overview.h>
 #include <cplusplus/CoreTypes.h>
@@ -324,49 +325,23 @@ static void addDeclaration(Document::Ptr doc, const Class *cl, const QString &fu
     declaration += functionName;
     declaration += QLatin1String(";\n");
 
-    // functionName comes already with argument names (if designer managed to
-    // do that).  First, let's try to find any method which is a private slot
-    // (then we don't need to add "private slots:" statement)
-    const unsigned mCount = cl->memberCount();
-    for (unsigned j = 0; j < mCount; j++) { // go through all members
-        if (const Declaration *decl = cl->memberAt(j)->asDeclaration())
-            if (const Function *fun = decl->type()->asFunctionType())  {
-                // we are only interested in declarations of methods.
-                if (fun->isSlot() && fun->isPrivate()) {
-
-                    //
-                    // ### FIXME: change this to use the Refactoring changes and the AST to find the correct insertion position
-                    //
-
-                    const int line = fun->line(); // this is the beginning of function name: "void ^foo(...)"
-                    const int column = 0;
-                    if (ITextEditable *editable = editableAt(docFileName, line, column)) {
-                        BaseTextEditor *editor = qobject_cast<BaseTextEditor *>(editable->widget());
-                        if (editor) {
-                            QTextCursor tc = editor->textCursor();
-                            int pos = tc.position();
-                            tc.beginEditBlock();
-                            tc.insertText(declaration);
-                            tc.setPosition(pos, QTextCursor::KeepAnchor);
-                            editor->indentInsertedText(tc);
-                            tc.endEditBlock();
-                        }
-                    }
-                    return;
-                }
-            }
-    }
-
-    // We didn't find any method under "private slots:", let's add "private slots:". Below code
-    // adds "private slots:" by the end of the class definition.
-
-    if (ITextEditable *editable = editableAt(docFileName, cl->line(), cl->column())) {
-        int classEndPosition = findClassEndPosition(editable->contents(), editable->position());
-        if (classEndPosition >= 0) {
-            int line, column;
-            editable->convertPosition(classEndPosition, &line, &column); // converts back position into a line and column
-            editable->gotoLine(line, column);  // go to position (we should be just before closing } of the class)
-            editable->insert(QLatin1String("\nprivate slots:\n    ") + declaration);
+    InsertionPointLocator find(doc);
+    const InsertionLocation loc = find.methodDeclarationInClass(cl, InsertionPointLocator::PrivateSlot);
+
+    //
+    // ### FIXME: change this to use the Refactoring changes!
+    //
+
+    if (ITextEditable *editable = editableAt(docFileName, loc.line(), loc.column() - 1)) {
+        BaseTextEditor *editor = qobject_cast<BaseTextEditor *>(editable->widget());
+        if (editor) {
+            QTextCursor tc = editor->textCursor();
+            int pos = tc.position();
+            tc.beginEditBlock();
+            tc.insertText(loc.prefix() + declaration);
+            tc.setPosition(pos, QTextCursor::KeepAnchor);
+            editor->indentInsertedText(tc);
+            tc.endEditBlock();
         }
     }
 }
@@ -486,6 +461,24 @@ static inline QString uiClassName(QString formObjectName)
     return formObjectName;
 }
 
+static Document::Ptr getParsedDocument(const QString &fileName, CppTools::CppModelManagerInterface::WorkingCopy &workingCopy, Snapshot &snapshot)
+{
+    QString src;
+    if (workingCopy.contains(fileName)) {
+        src = workingCopy.source(fileName);
+    } else {
+        QFile file(fileName);
+        if (file.open(QFile::ReadOnly))
+            src = QTextStream(&file).readAll(); // ### FIXME
+    }
+
+    QByteArray source = snapshot.preprocessedCode(src, fileName);
+
+    Document::Ptr doc = snapshot.documentFromSource(source, fileName);
+    doc->check();
+    return doc;
+}
+
 // Goto slot invoked by the designer context menu. Either navigates
 // to an existing slot function or create a new one.
 
@@ -583,7 +576,9 @@ bool QtCreatorIntegration::navigateToSlot(const QString &objectName,
         }
     } else {
         // add function declaration to cl
-        addDeclaration(doc, cl, functionNameWithParameterNames);
+        CppTools::CppModelManagerInterface::WorkingCopy workingCopy = cppModelManagerInstance()->workingCopy();
+        Document::Ptr tmpDoc = getParsedDocument(doc->fileName(), workingCopy, docTable);
+        addDeclaration(tmpDoc, cl, functionNameWithParameterNames);
 
         // add function definition to cpp file
         sourceDoc = addDefinition(docTable, doc->fileName(), className, functionNameWithParameterNames, &line);
-- 
GitLab