From d45460726479931ff7ed75fe0d34da8eea469718 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <qtc-committer@nokia.com>
Date: Wed, 10 Dec 2008 17:21:01 +0100
Subject: [PATCH] Implemented tooltip and lookat for #include directives.

---
 src/libs/cplusplus/CppDocument.cpp       | 10 +++++++---
 src/libs/cplusplus/CppDocument.h         | 23 +++++++++++++++++++++--
 src/libs/cplusplus/pp-client.h           |  3 ++-
 src/libs/cplusplus/pp-engine.cpp         |  4 ++--
 src/plugins/cppeditor/cppeditor.cpp      | 12 +++++++++++-
 src/plugins/cpptools/cpphoverhandler.cpp | 10 ++++++++++
 src/plugins/cpptools/cppmodelmanager.cpp | 10 ++++++----
 7 files changed, 59 insertions(+), 13 deletions(-)

diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index e67214f63b8..d670e7e0018 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -131,12 +131,16 @@ QString Document::fileName() const
 
 QStringList Document::includedFiles() const
 {
-    return _includedFiles;
+    QStringList files;
+    foreach (const Include &i, _includes)
+        files.append(i.fileName());
+    files.removeDuplicates();
+    return files;
 }
 
-void Document::addIncludeFile(const QString &fileName)
+void Document::addIncludeFile(const QString &fileName, unsigned line)
 {
-    _includedFiles.append(fileName);
+    _includes.append(Include(fileName, line));
 }
 
 void Document::appendMacro(const Macro &macro)
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index aaca36c18ee..b31f0d2bc64 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -65,7 +65,7 @@ public:
     QString fileName() const;
 
     QStringList includedFiles() const;
-    void addIncludeFile(const QString &fileName);
+    void addIncludeFile(const QString &fileName, unsigned line);
 
     void appendMacro(const Macro &macro);
     void addMacroUse(const Macro &macro, unsigned offset, unsigned length);
@@ -181,6 +181,22 @@ public:
         { return pos >= _begin && pos < _end; }
     };
 
+    class Include {
+        QString _fileName;
+        unsigned _line;
+
+    public:
+        Include(const QString &fileName, unsigned line)
+            : _fileName(fileName), _line(line)
+        { }
+
+        QString fileName() const
+        { return _fileName; }
+
+        unsigned line() const
+        { return _line; }
+    };
+
     class MacroUse: public Block {
         Macro _macro;
 
@@ -196,6 +212,9 @@ public:
         { return _macro; }
     };
 
+    QList<Include> includes() const
+    { return _includes; }
+
     QList<Block> skippedBlocks() const
     { return _skippedBlocks; }
 
@@ -207,11 +226,11 @@ private:
 
 private:
     QString _fileName;
-    QStringList _includedFiles;
     Control *_control;
     TranslationUnit *_translationUnit;
     Namespace *_globalNamespace;
     QList<DiagnosticMessage> _diagnosticMessages;
+    QList<Include> _includes;
     QList<Macro> _definedMacros;
     QList<Block> _skippedBlocks;
     QList<MacroUse> _macroUses;
diff --git a/src/libs/cplusplus/pp-client.h b/src/libs/cplusplus/pp-client.h
index 2fc781f22f5..eead5bf4600 100644
--- a/src/libs/cplusplus/pp-client.h
+++ b/src/libs/cplusplus/pp-client.h
@@ -63,7 +63,8 @@ public:
   { }
 
   virtual void macroAdded(const Macro &macro) = 0;
-  virtual void sourceNeeded(QString &fileName, IncludeType mode) = 0; // ### FIX the signature.
+  virtual void sourceNeeded(QString &fileName, IncludeType mode,
+                            unsigned line) = 0; // ### FIX the signature.
 
   virtual void startExpandingMacro(unsigned offset,
                                    const Macro &macro,
diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp
index 83386e8079c..c33fc8cb151 100644
--- a/src/libs/cplusplus/pp-engine.cpp
+++ b/src/libs/cplusplus/pp-engine.cpp
@@ -818,7 +818,7 @@ void pp::processInclude(bool skipCurentPath,
         QString fn = QString::fromUtf8(path.constData(), path.length());
 
         if (client)
-            client->sourceNeeded(fn, Client::IncludeGlobal);
+            client->sourceNeeded(fn, Client::IncludeGlobal, firstToken->lineno);
     } else if (tk->is(T_ANGLE_STRING_LITERAL) || tk->is(T_STRING_LITERAL)) {
         const QByteArray spell = tokenSpell(*tk);
         const char *beginOfPath = spell.constBegin();
@@ -831,7 +831,7 @@ void pp::processInclude(bool skipCurentPath,
             QString fn = QString::fromUtf8(path.constData(), path.length());
 
             if (client)
-                client->sourceNeeded(fn, Client::IncludeLocal);
+                client->sourceNeeded(fn, Client::IncludeLocal, firstToken->lineno);
         }
     }
 }
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 8d4a36178ce..f233c0121f8 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -480,13 +480,23 @@ void CPPEditor::jumpToDefinition()
     Document::Ptr doc = m_modelManager->document(file()->fileName());
     if (!doc)
         return;
+
+    QTextCursor tc = textCursor();
+    unsigned lineno = tc.blockNumber() + 1;
+    foreach (const Document::Include &incl, doc->includes()) {
+        if (incl.line() == lineno) {
+            if (TextEditor::BaseTextEditor::openEditorAt(incl.fileName(), 0, 0))
+                return; // done
+            break;
+        }
+    }
+
     Symbol *lastSymbol = doc->findSymbolAt(line, column);
     if (!lastSymbol)
         return;
 
     // Get the expression under the cursor
     const int endOfName = endOfNameUnderCursor();
-    QTextCursor tc = textCursor();
     tc.setPosition(endOfName);
     ExpressionUnderCursor expressionUnderCursor;
     const QString expression = expressionUnderCursor(tc);
diff --git a/src/plugins/cpptools/cpphoverhandler.cpp b/src/plugins/cpptools/cpphoverhandler.cpp
index 338123bc5e6..f3831e5394d 100644
--- a/src/plugins/cpptools/cpphoverhandler.cpp
+++ b/src/plugins/cpptools/cpphoverhandler.cpp
@@ -177,6 +177,16 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
         }
     }
 
+    if (m_toolTip.isEmpty()) {
+        unsigned lineno = tc.blockNumber() + 1;
+        foreach (const Document::Include &incl, doc->includes()) {
+            if (lineno == incl.line()) {
+                m_toolTip = incl.fileName();
+                break;
+            }
+        }
+    }
+
     if (m_toolTip.isEmpty()) {
         // Move to the end of a qualified name
         bool stop = false;
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 40888d99f3f..9adc892713d 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -138,7 +138,8 @@ protected:
     virtual void stopExpandingMacro(unsigned offset, const Macro &macro);
     virtual void startSkippingBlocks(unsigned offset);
     virtual void stopSkippingBlocks(unsigned offset);
-    virtual void sourceNeeded(QString &fileName, IncludeType type);
+    virtual void sourceNeeded(QString &fileName, IncludeType type,
+                              unsigned line);
 
 private:
     QPointer<CppModelManager> m_modelManager;
@@ -176,7 +177,7 @@ void CppPreprocessor::setProjectFiles(const QStringList &files)
 { m_projectFiles = files; }
 
 void CppPreprocessor::run(QString &fileName)
-{ sourceNeeded(fileName, IncludeGlobal); }
+{ sourceNeeded(fileName, IncludeGlobal, /*line = */ 0); }
 
 void CppPreprocessor::operator()(QString &fileName)
 { run(fileName); }
@@ -361,7 +362,8 @@ void CppPreprocessor::stopSkippingBlocks(unsigned offset)
         m_currentDoc->stopSkippingBlocks(offset);
 }
 
-void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type)
+void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type,
+                                   unsigned line)
 {
     if (fileName.isEmpty())
         return;
@@ -369,7 +371,7 @@ void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type)
     QByteArray contents = tryIncludeFile(fileName, type);
 
     if (m_currentDoc) {
-        m_currentDoc->addIncludeFile(fileName);
+        m_currentDoc->addIncludeFile(fileName, line);
         if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
             QString msg;
             msg += fileName;
-- 
GitLab