diff options
Diffstat (limited to 'src/plugins')
23 files changed, 346 insertions, 56 deletions
diff --git a/src/plugins/cpptools/abstracteditorsupport.cpp b/src/plugins/cpptools/abstracteditorsupport.cpp new file mode 100644 index 0000000000..c8e04b7eeb --- /dev/null +++ b/src/plugins/cpptools/abstracteditorsupport.cpp @@ -0,0 +1,74 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "cppmodelmanagerinterface.h" + +#include <cplusplus/Overview.h> +#include <cplusplus/CppDocument.h> +#include <cplusplus/ExpressionUnderCursor.h> +#include <CoreTypes.h> +#include <Names.h> +#include <Symbols.h> +#include <Scope.h> + +namespace CppTools { + +AbstractEditorSupport::AbstractEditorSupport(CppModelManagerInterface *modelmanager) : + m_modelmanager(modelmanager) +{ +} + +AbstractEditorSupport::~AbstractEditorSupport() +{ +} + +void AbstractEditorSupport::updateDocument() +{ + m_modelmanager->updateSourceFiles(QStringList(fileName())); +} + +QString AbstractEditorSupport::functionAt(const CppModelManagerInterface *modelManager, + const QString &fileName, + int line, int column) +{ + const CPlusPlus::Snapshot snapshot = modelManager->snapshot(); + const CPlusPlus::Document::Ptr document = snapshot.value(fileName); + if (!document) + return QString(); + if (const CPlusPlus::Symbol *symbol = document->findSymbolAt(line, column)) + if (const CPlusPlus::Scope *scope = symbol->scope()) + if (const CPlusPlus::Scope *functionScope = scope->enclosingFunctionScope()) + if (const CPlusPlus::Symbol *function = functionScope->owner()) { + const CPlusPlus::Overview o; + return o.prettyName(function->name()); + } + return QString(); +} + +} diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h index bb926905d0..375ad0d4c8 100644 --- a/src/plugins/cpptools/cppmodelmanagerinterface.h +++ b/src/plugins/cpptools/cppmodelmanagerinterface.h @@ -97,14 +97,18 @@ public: class CPPTOOLS_EXPORT AbstractEditorSupport { public: - AbstractEditorSupport(CppModelManagerInterface *modelmanager) - : m_modelmanager(modelmanager) {} - virtual ~AbstractEditorSupport() {} + explicit AbstractEditorSupport(CppModelManagerInterface *modelmanager); + virtual ~AbstractEditorSupport(); + virtual QByteArray contents() const = 0; virtual QString fileName() const = 0; - void updateDocument() - { m_modelmanager->updateSourceFiles(QStringList() << fileName()); } + void updateDocument(); + + // TODO: find a better place for common utility functions + static QString functionAt(const CppModelManagerInterface *mm, + const QString &fileName, + int line, int column); private: CppModelManagerInterface *m_modelmanager; diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro index d6d24e0f83..8a943ff4b7 100644 --- a/src/plugins/cpptools/cpptools.pro +++ b/src/plugins/cpptools/cpptools.pro @@ -33,7 +33,8 @@ SOURCES += completionsettingspage.cpp \ cpptoolsplugin.cpp \ searchsymbols.cpp \ cppdoxygen.cpp \ - cppfilesettingspage.cpp + cppfilesettingspage.cpp \ + abstracteditorsupport.cpp FORMS += completionsettingspage.ui \ cppfilesettingspage.ui diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index 789936f3ea..6559c964d0 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.cpp +++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp @@ -52,6 +52,7 @@ #include <utils/qtcassert.h> #include <utils/winutils.h> #include <utils/consoleprocess.h> +#include <texteditor/itexteditor.h> #include <QtCore/QDebug> #include <QtCore/QTimer> @@ -63,6 +64,7 @@ #include <QtGui/QMessageBox> #include <QtGui/QMainWindow> #include <QtGui/QApplication> +#include <QtGui/QToolTip> #define DBGHELP_TRANSLATE_TCHAR #include <inc/Dbghelp.h> @@ -380,6 +382,7 @@ void CdbDebugEnginePrivate::clearForRun() m_breakEventMode = BreakEventHandle; m_firstActivatedFrame = false; cleanStackTrace(); + m_editorToolTipCache.clear(); } void CdbDebugEnginePrivate::cleanStackTrace() @@ -438,10 +441,66 @@ void CdbDebugEngine::shutdown() exitDebugger(); } -void CdbDebugEngine::setToolTipExpression(const QPoint & pos, const QString & exp) +QString CdbDebugEngine::editorToolTip(const QString &exp, const QString &function) { + // Figure the editor tooltip. Ask the frame context of the + // function if it is a local variable it knows. If that is not + // the case, try to evaluate via debugger + QString errorMessage; + QString rc; + // Find the frame of the function if there is any + CdbStackFrameContext *frame = 0; + if (m_d->m_currentStackTrace && !function.isEmpty()) { + const int frameIndex = m_d->m_currentStackTrace->indexOf(function); + if (frameIndex != -1) + frame = m_d->m_currentStackTrace->frameContextAt(frameIndex, &errorMessage); + } + if (frame && frame->editorToolTip(QLatin1String("local.") + exp, &rc, &errorMessage)) + return rc; + // No function/symbol context found, try to evaluate in current context. + // Do not append type as this will mostly be 'long long' for integers, etc. + QString type; + if (!evaluateExpression(exp, &rc, &type, &errorMessage)) + return QString(); + return rc; +} + +void CdbDebugEngine::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos) +{ + typedef CdbDebugEnginePrivate::EditorToolTipCache EditorToolTipCache; if (debugCDB) - qDebug() << Q_FUNC_INFO << '\n' << pos << exp; + qDebug() << Q_FUNC_INFO << '\n' << cursorPos; + // Need a stopped debuggee and a cpp file + if (!m_d->m_hDebuggeeProcess || m_d->isDebuggeeRunning()) + return; + if (!isCppEditor(editor)) + return; + // Determine expression and function + QString toolTip; + do { + int line; + int column; + QString function; + const QString exp = cppExpressionAt(editor, cursorPos, &line, &column, &function); + if (function.isEmpty() || exp.isEmpty()) + break; + // Check cache (key containing function) or try to figure out expression + QString cacheKey = function; + cacheKey += QLatin1Char('@'); + cacheKey += exp; + const EditorToolTipCache::const_iterator cit = m_d->m_editorToolTipCache.constFind(cacheKey); + if (cit != m_d->m_editorToolTipCache.constEnd()) { + toolTip = cit.value(); + } else { + toolTip = editorToolTip(exp, function); + if (!toolTip.isEmpty()) + m_d->m_editorToolTipCache.insert(cacheKey, toolTip); + } + } while (false); + // Display + QToolTip::hideText(); + if (!toolTip.isEmpty()) + QToolTip::showText(mousePos, toolTip); } void CdbDebugEnginePrivate::clearDisplay() diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h index 33640b9992..8dd0fa601f 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.h +++ b/src/plugins/debugger/cdb/cdbdebugengine.h @@ -60,7 +60,7 @@ public: QString *errorMessage); virtual void shutdown(); - virtual void setToolTipExpression(const QPoint &pos, const QString &exp); + virtual void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); virtual bool startDebugger(); virtual void exitDebugger(); virtual void detachDebugger(); @@ -118,6 +118,7 @@ private: bool evaluateExpression(const QString &expression, QString *value, QString *type, QString *errorMessage); void evaluateWatcher(WatchData *wd); void filterEvaluateWatchers(QList<WatchData> *wd, WatchHandler *wh); + QString editorToolTip(const QString &exp, const QString &function); CdbDebugEnginePrivate *m_d; diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h index 746d1993f6..d9d568c0d8 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine_p.h +++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h @@ -39,6 +39,7 @@ #include <utils/consoleprocess.h> #include <QtCore/QSharedPointer> +#include <QtCore/QMap> namespace Debugger { namespace Internal { @@ -94,7 +95,9 @@ struct CdbComInterfaces }; struct CdbDebugEnginePrivate -{ +{ + typedef QMap<QString, QString> EditorToolTipCache; + enum HandleBreakEventMode { // Special modes for break event handler. BreakEventHandle, BreakEventIgnoreOnce, @@ -160,6 +163,8 @@ struct CdbDebugEnginePrivate DebuggerManager *m_debuggerManager; IDebuggerManagerAccessForEngines *m_debuggerManagerAccess; CdbStackTraceContext *m_currentStackTrace; + EditorToolTipCache m_editorToolTipCache; + bool m_firstActivatedFrame; DebuggerStartMode m_mode; diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.cpp b/src/plugins/debugger/cdb/cdbstackframecontext.cpp index 48072bf2c2..3fddffd1de 100644 --- a/src/plugins/debugger/cdb/cdbstackframecontext.cpp +++ b/src/plugins/debugger/cdb/cdbstackframecontext.cpp @@ -186,5 +186,32 @@ CdbStackFrameContext::~CdbStackFrameContext() delete m_symbolContext; } +bool CdbStackFrameContext::editorToolTip(const QString &iname, + QString *value, + QString *errorMessage) +{ + value->clear(); + unsigned long index; + if (!m_symbolContext->lookupPrefix(iname, &index)) { + *errorMessage = QString::fromLatin1("%1 not found.").arg(iname); + return false; + } + const WatchData wd = m_symbolContext->symbolAt(index); + // Check dumpers. Should actually be just one item. + if (m_useDumpers && m_dumper->state() != CdbDumperHelper::Disabled) { + QList<WatchData> result; + if (CdbDumperHelper::DumpOk == m_dumper->dumpType(wd, false, OwnerDumper, &result, errorMessage)) { + foreach (const WatchData &dwd, result) { + if (!value->isEmpty()) + value->append(QLatin1Char('\n')); + value->append(dwd.toToolTip()); + } + return true; + } // Dumped ok + } // has Dumpers + *value = wd.toToolTip(); + return true; +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.h b/src/plugins/debugger/cdb/cdbstackframecontext.h index caf84dde97..020a0e31bb 100644 --- a/src/plugins/debugger/cdb/cdbstackframecontext.h +++ b/src/plugins/debugger/cdb/cdbstackframecontext.h @@ -51,10 +51,11 @@ class CdbStackFrameContext public: explicit CdbStackFrameContext(const QSharedPointer<CdbDumperHelper> &dumper, CdbSymbolGroupContext *symbolContext); - ~CdbStackFrameContext(); + ~CdbStackFrameContext(); bool assignValue(const QString &iname, const QString &value, QString *newValue /* = 0 */, QString *errorMessage); + bool editorToolTip(const QString &iname, QString *value, QString *errorMessage); bool populateModelInitially(WatchHandler *wh, QString *errorMessage); diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp index 3b39976355..3f72f268f8 100644 --- a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp +++ b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp @@ -118,6 +118,27 @@ bool CdbStackTraceContext::init(unsigned long frameCount, QString * /*errorMessa return true; } +int CdbStackTraceContext::indexOf(const QString &function) const +{ + + const QChar exclamationMark = QLatin1Char('!'); + const int count = m_frames.size(); + // Module contained ('module!foo'). Exact match + if (function.contains(exclamationMark)) { + + for (int i = 0; i < count; i++) + if (m_frames.at(i).function == function) + return i; + return -1; + } + // No module, fuzzy match + QString pattern = exclamationMark + function; + for (int i = 0; i < count; i++) + if (m_frames.at(i).function.endsWith(pattern)) + return i; + return -1; +} + CdbStackFrameContext *CdbStackTraceContext::frameContextAt(int index, QString *errorMessage) { // Create a frame on demand diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.h b/src/plugins/debugger/cdb/cdbstacktracecontext.h index b5e041d2c2..0a285c5a88 100644 --- a/src/plugins/debugger/cdb/cdbstacktracecontext.h +++ b/src/plugins/debugger/cdb/cdbstacktracecontext.h @@ -69,6 +69,8 @@ public: QList<StackFrame> frames() const { return m_frames; } inline int frameCount() const { return m_frames.size(); } + // Search for function. Should ideally contain the module as 'module!foo'. + int indexOf(const QString &function) const; // Top-Level instruction offset for disassembler ULONG64 instructionOffset() const { return m_instructionOffset; } diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h index bfd5ecd3b9..ef8f939c71 100644 --- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h +++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h @@ -89,6 +89,9 @@ public: template <class OutputIterator> bool getChildSymbols(const QString &prefix, OutputIterator it, QString *errorMessage); + WatchData symbolAt(unsigned long index) const; + bool lookupPrefix(const QString &prefix, unsigned long *index) const; + enum SymbolState { LeafSymbol, ExpandedSymbol, CollapsedSymbol }; SymbolState symbolState(unsigned long index) const; SymbolState symbolState(const QString &prefix) const; @@ -116,10 +119,8 @@ private: unsigned long *parentId, QString *errorMessage); bool expandSymbol(const QString &prefix, unsigned long index, QString *errorMessage); - void populateINameIndexMap(const QString &prefix, unsigned long parentId, unsigned long start, unsigned long count); - WatchData symbolAt(unsigned long index) const; - QString symbolINameAt(unsigned long index) const; - bool lookupPrefix(const QString &prefix, unsigned long *index) const; + void populateINameIndexMap(const QString &prefix, unsigned long parentId, unsigned long start, unsigned long count); + QString symbolINameAt(unsigned long index) const; int getDisplayableChildCount(unsigned long index) const; inline DEBUG_SYMBOL_PARAMETERS *symbolParameters() { return &(*m_symbolParameters.begin()); } diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 9f29c1c83c..303884b0fa 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -719,10 +719,10 @@ void DebuggerManager::attemptBreakpointSynchronization() m_engine->attemptBreakpointSynchronization(); } -void DebuggerManager::setToolTipExpression(const QPoint &pos, const QString &exp) +void DebuggerManager::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos) { if (m_engine) - m_engine->setToolTipExpression(pos, exp); + m_engine->setToolTipExpression(mousePos, editor, cursorPos); } void DebuggerManager::updateWatchModel() diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index 53b252e6c9..3db8271a24 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -50,6 +50,10 @@ namespace Core { class IOptionsPage; } // namespace Core +namespace TextEditor { + class ITextEditor; +} + namespace Debugger { namespace Internal { @@ -379,7 +383,7 @@ private: void toggleBreakpoint(const QString &fileName, int lineNumber); void toggleBreakpointEnabled(const QString &fileName, int lineNumber); BreakpointData *findBreakpoint(const QString &fileName, int lineNumber); - void setToolTipExpression(const QPoint &pos, const QString &exp0); + void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); DebuggerRunControl *m_runControl; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 262fd38912..f7081d8997 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -948,28 +948,10 @@ void DebuggerPlugin::requestMark(TextEditor::ITextEditor *editor, int lineNumber void DebuggerPlugin::showToolTip(TextEditor::ITextEditor *editor, const QPoint &point, int pos) { - if (!theDebuggerBoolSetting(UseToolTips)) + if (!theDebuggerBoolSetting(UseToolTips) || m_manager->status() == DebuggerProcessNotReady) return; - QPlainTextEdit *plaintext = qobject_cast<QPlainTextEdit*>(editor->widget()); - if (!plaintext) - return; - - QString expr = plaintext->textCursor().selectedText(); - if (expr.isEmpty()) { - QTextCursor tc(plaintext->document()); - tc.setPosition(pos); - - const QChar ch = editor->characterAt(pos); - if (ch.isLetterOrNumber() || ch == QLatin1Char('_')) - tc.movePosition(QTextCursor::EndOfWord); - - // Fetch the expression's code. - CPlusPlus::ExpressionUnderCursor expressionUnderCursor; - expr = expressionUnderCursor(tc); - } - //qDebug() << " TOOLTIP EXPR " << expr; - m_manager->setToolTipExpression(point, expr); + m_manager->setToolTipExpression(point, editor, pos); } void DebuggerPlugin::setSessionValue(const QString &name, const QVariant &value) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 6cd9d9bc20..c2849210e8 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -50,6 +50,7 @@ #include "debuggerdialogs.h" #include <utils/qtcassert.h> +#include <texteditor/itexteditor.h> #include <coreplugin/icore.h> #include <QtCore/QDebug> @@ -2605,11 +2606,10 @@ static QString m_toolTipExpression; static QPoint m_toolTipPos; static QMap<QString, WatchData> m_toolTipCache; -void GdbEngine::setToolTipExpression(const QPoint &pos, const QString &exp0) +void GdbEngine::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos) { - //qDebug() << "SET TOOLTIP EXP" << pos << exp0; - if (q->status() != DebuggerInferiorStopped) { - //qDebug() << "SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED"; + if (q->status() != DebuggerInferiorStopped || !isCppEditor(editor)) { + //qDebug() << "SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED/Non Cpp editor"; return; } @@ -2618,9 +2618,10 @@ void GdbEngine::setToolTipExpression(const QPoint &pos, const QString &exp0) return; } - m_toolTipPos = pos; - m_toolTipExpression = exp0; - QString exp = exp0; + m_toolTipPos = mousePos; + int line, column; + m_toolTipExpression = cppExpressionAt(editor, cursorPos, &line, &column); + QString exp = m_toolTipExpression; /* if (m_toolTip.isTypePending()) { qDebug() << "suppressing duplicated tooltip creation"; diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h index 8feef5dc32..ef5c0a34d6 100644 --- a/src/plugins/debugger/gdbengine.h +++ b/src/plugins/debugger/gdbengine.h @@ -96,7 +96,7 @@ private: void nextIExec(); void shutdown(); - void setToolTipExpression(const QPoint &pos, const QString &exp); + void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); bool startDebugger(); void exitDebugger(); void detachDebugger(); diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h index 9d85ebace1..6c0fdda97e 100644 --- a/src/plugins/debugger/idebuggerengine.h +++ b/src/plugins/debugger/idebuggerengine.h @@ -38,6 +38,10 @@ class QPoint; class QString; QT_END_NAMESPACE +namespace TextEditor { + class ITextEditor; +} + namespace Debugger { namespace Internal { @@ -49,7 +53,7 @@ public: IDebuggerEngine(QObject *parent = 0) : QObject(parent) {} virtual void shutdown() = 0; - virtual void setToolTipExpression(const QPoint &pos, const QString &exp) = 0; + virtual void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos) = 0; virtual bool startDebugger() = 0; virtual void exitDebugger() = 0; virtual void detachDebugger() {} diff --git a/src/plugins/debugger/scriptengine.cpp b/src/plugins/debugger/scriptengine.cpp index 76451774c7..c8efb92ca9 100644 --- a/src/plugins/debugger/scriptengine.cpp +++ b/src/plugins/debugger/scriptengine.cpp @@ -43,6 +43,11 @@ #include <utils/qtcassert.h> +#include <qtscripteditor/qtscripteditorconstants.h> + +#include <texteditor/itexteditor.h> +#include <coreplugin/ifile.h> + #include <QtCore/QDateTime> #include <QtCore/QDebug> #include <QtCore/QDir> @@ -423,18 +428,24 @@ static WatchData m_toolTip; static QPoint m_toolTipPos; static QHash<QString, WatchData> m_toolTipCache; -void ScriptEngine::setToolTipExpression(const QPoint &pos, const QString &exp0) +void ScriptEngine::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos) { - Q_UNUSED(pos); - Q_UNUSED(exp0); + Q_UNUSED(mousePos); + Q_UNUSED(editor); + Q_UNUSED(cursorPos); if (q->status() != DebuggerInferiorStopped) { //SDEBUG("SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED"); return; } + // Check mime type and get expression (borrowing some C++ - functions) + const QString javaScriptMimeType = QLatin1String(QtScriptEditor::Constants::C_QTSCRIPTEDITOR_MIMETYPE); + if (!editor->file() || editor->file()->mimeType() != javaScriptMimeType) + return; - //m_toolTipPos = pos; - QString exp = exp0; + int line; + int column; + QString exp = cppExpressionAt(editor, cursorPos, &line, &column); /* if (m_toolTipCache.contains(exp)) { diff --git a/src/plugins/debugger/scriptengine.h b/src/plugins/debugger/scriptengine.h index 5c55b04d0d..ce4f6cb588 100644 --- a/src/plugins/debugger/scriptengine.h +++ b/src/plugins/debugger/scriptengine.h @@ -75,7 +75,7 @@ private: void nextIExec(); void shutdown(); - void setToolTipExpression(const QPoint &pos, const QString &exp); + void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); bool startDebugger(); void exitDebugger(); diff --git a/src/plugins/debugger/tcfengine.cpp b/src/plugins/debugger/tcfengine.cpp index 32f2d96bb0..f3bb046881 100644 --- a/src/plugins/debugger/tcfengine.cpp +++ b/src/plugins/debugger/tcfengine.cpp @@ -429,11 +429,13 @@ static WatchData m_toolTip; static QPoint m_toolTipPos; static QHash<QString, WatchData> m_toolTipCache; -void TcfEngine::setToolTipExpression(const QPoint &pos, const QString &exp0) +void TcfEngine::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos) { + Q_UNUSED(mousePos) + Q_UNUSED(editor) + Q_UNUSED(cursorPos) } - ////////////////////////////////////////////////////////////////////// // // Watch specific stuff diff --git a/src/plugins/debugger/tcfengine.h b/src/plugins/debugger/tcfengine.h index eb965d1bc7..d069989427 100644 --- a/src/plugins/debugger/tcfengine.h +++ b/src/plugins/debugger/tcfengine.h @@ -85,7 +85,7 @@ private: void nextIExec(); void shutdown(); - void setToolTipExpression(const QPoint &pos, const QString &exp); + void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); bool startDebugger(); void exitDebugger(); diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index a665bd774e..f074ee2ddc 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -31,12 +31,27 @@ #include "watchhandler.h" #include <utils/qtcassert.h> +#include <texteditor/basetexteditor.h> +#include <texteditor/basetextmark.h> +#include <texteditor/itexteditor.h> +#include <texteditor/texteditorconstants.h> + +#include <cpptools/cppmodelmanagerinterface.h> +#include <cpptools/cpptoolsconstants.h> + +#include <cplusplus/ExpressionUnderCursor.h> + +#include <extensionsystem/pluginmanager.h> + #include <QtCore/QDebug> #include <QtCore/QTime> #include <QtCore/QStringList> #include <QtCore/QCoreApplication> #include <QtCore/QTextStream> +#include <QtGui/QTextCursor> +#include <QtGui/QPlainTextEdit> + #include <string.h> #include <ctype.h> @@ -365,6 +380,68 @@ QString decodeData(const QByteArray &ba, int encoding) return QCoreApplication::translate("Debugger", "<Encoding error>"); } +// Editor tooltip support +bool isCppEditor(Core::IEditor *editor) +{ + static QStringList cppMimeTypes; + if (cppMimeTypes.empty()) { + cppMimeTypes << QLatin1String(CppTools::Constants::C_SOURCE_MIMETYPE) + << QLatin1String(CppTools::Constants::CPP_SOURCE_MIMETYPE) + << QLatin1String(CppTools::Constants::CPP_HEADER_MIMETYPE) + << QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE); + } + if (const Core::IFile *file = editor->file()) + return cppMimeTypes.contains(file->mimeType()); + return false; +} + +// Find the function the cursor is in to use a scope. + + + + + +// Return the Cpp expression, and, if desired, the function +QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos, + int *line, int *column, QString *function /* = 0 */) +{ + + *line = *column = 0; + if (function) + function->clear(); + + const QPlainTextEdit *plaintext = qobject_cast<QPlainTextEdit*>(editor->widget()); + if (!plaintext) + return QString(); + + QString expr = plaintext->textCursor().selectedText(); + if (expr.isEmpty()) { + QTextCursor tc(plaintext->document()); + tc.setPosition(pos); + + const QChar ch = editor->characterAt(pos); + if (ch.isLetterOrNumber() || ch == QLatin1Char('_')) + tc.movePosition(QTextCursor::EndOfWord); + + // Fetch the expression's code. + CPlusPlus::ExpressionUnderCursor expressionUnderCursor; + expr = expressionUnderCursor(tc); + *column = tc.columnNumber(); + *line = tc.blockNumber(); + } else { + const QTextCursor tc = plaintext->textCursor(); + *column = tc.columnNumber(); + *line = tc.blockNumber(); + } + + if (function && !expr.isEmpty()) + if (const Core::IFile *file = editor->file()) + if (CppTools::CppModelManagerInterface *modelManager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>()) + *function = CppTools::AbstractEditorSupport::functionAt(modelManager, file->fileName(), *line, *column); + + return expr; +} + // --------------- QtDumperResult QtDumperResult::Child::Child() : diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h index e9d8ab7910..e87b3cd822 100644 --- a/src/plugins/debugger/watchutils.h +++ b/src/plugins/debugger/watchutils.h @@ -37,6 +37,14 @@ QT_BEGIN_NAMESPACE class QDebug; QT_END_NAMESPACE +namespace TextEditor { + class ITextEditor; +} + +namespace Core { + class IEditor; +} + namespace Debugger { namespace Internal { @@ -67,6 +75,11 @@ bool isIntOrFloatType(const QString &type); QString sizeofTypeExpression(const QString &type); QString quoteUnprintableLatin1(const QByteArray &ba); +// Editor tooltip support +bool isCppEditor(Core::IEditor *editor); +QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos, + int *line, int *column, QString *function = 0); + // Decode string data as returned by the dumper helpers. QString decodeData(const QByteArray &baIn, int encoding); |