forked from qt-creator/qt-creator
Create type hierarchy widget; Refactor code from C++ hover into a simple reusable model.
Hierarchy information removed from tooltips now.
This commit is contained in:
@@ -1755,6 +1755,9 @@ void CPPEditor::unCommentSelection()
|
|||||||
|
|
||||||
CPPEditor::Link CPPEditor::linkToSymbol(CPlusPlus::Symbol *symbol)
|
CPPEditor::Link CPPEditor::linkToSymbol(CPlusPlus::Symbol *symbol)
|
||||||
{
|
{
|
||||||
|
if (!symbol)
|
||||||
|
return Link();
|
||||||
|
|
||||||
const QString fileName = QString::fromUtf8(symbol->fileName(),
|
const QString fileName = QString::fromUtf8(symbol->fileName(),
|
||||||
symbol->fileNameLength());
|
symbol->fileNameLength());
|
||||||
unsigned line = symbol->line();
|
unsigned line = symbol->line();
|
||||||
|
@@ -180,6 +180,10 @@ public:
|
|||||||
void setObjCEnabled(bool onoff);
|
void setObjCEnabled(bool onoff);
|
||||||
bool isObjCEnabled() const;
|
bool isObjCEnabled() const;
|
||||||
|
|
||||||
|
bool openLink(const Link &link) { return openCppEditorAt(link); }
|
||||||
|
|
||||||
|
static Link linkToSymbol(CPlusPlus::Symbol *symbol);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void outlineModelIndexChanged(const QModelIndex &index);
|
void outlineModelIndexChanged(const QModelIndex &index);
|
||||||
|
|
||||||
@@ -267,13 +271,10 @@ private:
|
|||||||
void abortRename();
|
void abortRename();
|
||||||
|
|
||||||
Link findLinkAt(const QTextCursor &, bool resolveTarget = true);
|
Link findLinkAt(const QTextCursor &, bool resolveTarget = true);
|
||||||
bool openLink(const Link &link) { return openCppEditorAt(link); }
|
|
||||||
bool openCppEditorAt(const Link &);
|
bool openCppEditorAt(const Link &);
|
||||||
|
|
||||||
QModelIndex indexForPosition(int line, int column, const QModelIndex &rootIndex = QModelIndex()) const;
|
QModelIndex indexForPosition(int line, int column, const QModelIndex &rootIndex = QModelIndex()) const;
|
||||||
|
|
||||||
static Link linkToSymbol(CPlusPlus::Symbol *symbol);
|
|
||||||
|
|
||||||
CppTools::CppModelManagerInterface *m_modelManager;
|
CppTools::CppModelManagerInterface *m_modelManager;
|
||||||
|
|
||||||
QComboBox *m_outlineCombo;
|
QComboBox *m_outlineCombo;
|
||||||
|
@@ -20,8 +20,9 @@ HEADERS += cppplugin.h \
|
|||||||
cppsemanticinfo.h \
|
cppsemanticinfo.h \
|
||||||
cppoutline.h \
|
cppoutline.h \
|
||||||
cppdeclfromdef.h \
|
cppdeclfromdef.h \
|
||||||
cpplocalsymbols.h
|
cpplocalsymbols.h \
|
||||||
|
cpptypehierarchy.h \
|
||||||
|
cppelementevaluator.h
|
||||||
SOURCES += cppplugin.cpp \
|
SOURCES += cppplugin.cpp \
|
||||||
cppeditor.cpp \
|
cppeditor.cpp \
|
||||||
cpphighlighter.cpp \
|
cpphighlighter.cpp \
|
||||||
@@ -35,8 +36,9 @@ SOURCES += cppplugin.cpp \
|
|||||||
cppsemanticinfo.cpp \
|
cppsemanticinfo.cpp \
|
||||||
cppoutline.cpp \
|
cppoutline.cpp \
|
||||||
cppdeclfromdef.cpp \
|
cppdeclfromdef.cpp \
|
||||||
cpplocalsymbols.cpp
|
cpplocalsymbols.cpp \
|
||||||
|
cpptypehierarchy.cpp \
|
||||||
|
cppelementevaluator.cpp
|
||||||
RESOURCES += cppeditor.qrc
|
RESOURCES += cppeditor.qrc
|
||||||
|
OTHER_FILES += CppEditor.pluginspec \
|
||||||
OTHER_FILES += CppEditor.pluginspec CppEditor.mimetypes.xml
|
CppEditor.mimetypes.xml
|
||||||
|
@@ -48,6 +48,9 @@ const char * const FIND_REFERENCES = "CppEditor.FindReferences";
|
|||||||
const char * const JUMP_TO_DEFINITION = "CppEditor.JumpToDefinition";
|
const char * const JUMP_TO_DEFINITION = "CppEditor.JumpToDefinition";
|
||||||
const char * const UPDATE_CODEMODEL = "CppEditor.UpdateCodeModel";
|
const char * const UPDATE_CODEMODEL = "CppEditor.UpdateCodeModel";
|
||||||
|
|
||||||
|
const char * const TYPE_HIERARCHY_ID = "CppEditor.TypeHierarchy";
|
||||||
|
const char * const OPEN_TYPE_HIERARCHY = "CppEditor.OpenTypeHierarchy";
|
||||||
|
|
||||||
const char * const HEADER_FILE_TYPE = "CppHeaderFiles";
|
const char * const HEADER_FILE_TYPE = "CppHeaderFiles";
|
||||||
const char * const SOURCE_FILE_TYPE = "CppSourceFiles";
|
const char * const SOURCE_FILE_TYPE = "CppSourceFiles";
|
||||||
|
|
||||||
|
500
src/plugins/cppeditor/cppelementevaluator.cpp
Normal file
500
src/plugins/cppeditor/cppelementevaluator.cpp
Normal file
@@ -0,0 +1,500 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "cppelementevaluator.h"
|
||||||
|
|
||||||
|
#include <coreplugin/ifile.h>
|
||||||
|
#include <cpptools/cppmodelmanagerinterface.h>
|
||||||
|
|
||||||
|
#include <FullySpecifiedType.h>
|
||||||
|
#include <Names.h>
|
||||||
|
#include <CoreTypes.h>
|
||||||
|
#include <Scope.h>
|
||||||
|
#include <Symbol.h>
|
||||||
|
#include <Symbols.h>
|
||||||
|
#include <cplusplus/ExpressionUnderCursor.h>
|
||||||
|
#include <cplusplus/Overview.h>
|
||||||
|
#include <cplusplus/TypeOfExpression.h>
|
||||||
|
#include <cplusplus/LookupContext.h>
|
||||||
|
#include <cplusplus/LookupItem.h>
|
||||||
|
#include <cplusplus/Icons.h>
|
||||||
|
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QFileInfo>
|
||||||
|
#include <QtCore/QSet>
|
||||||
|
#include <QtCore/QQueue>
|
||||||
|
|
||||||
|
using namespace CppEditor;
|
||||||
|
using namespace Internal;
|
||||||
|
using namespace CPlusPlus;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void moveCursorToEndOfName(QTextCursor *tc) {
|
||||||
|
QTextDocument *doc = tc->document();
|
||||||
|
if (!doc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QChar ch = doc->characterAt(tc->position());
|
||||||
|
while (ch.isLetterOrNumber() || ch == QLatin1Char('_')) {
|
||||||
|
tc->movePosition(QTextCursor::NextCharacter);
|
||||||
|
ch = doc->characterAt(tc->position());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CppElementEvaluator::CppElementEvaluator(CPPEditor *editor) :
|
||||||
|
m_editor(editor),
|
||||||
|
m_modelManager(CppTools::CppModelManagerInterface::instance()),
|
||||||
|
m_tc(editor->textCursor()),
|
||||||
|
m_lookupBaseClasses(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CppElementEvaluator::setTextCursor(const QTextCursor &tc)
|
||||||
|
{ m_tc = tc; }
|
||||||
|
|
||||||
|
void CppElementEvaluator::setLookupBaseClasses(const bool lookup)
|
||||||
|
{ m_lookupBaseClasses = lookup; }
|
||||||
|
|
||||||
|
QSharedPointer<CppElement> CppElementEvaluator::identifyCppElement()
|
||||||
|
{
|
||||||
|
m_element.clear();
|
||||||
|
evaluate();
|
||||||
|
return m_element;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo: Consider refactoring code from CPPEditor::findLinkAt into here.
|
||||||
|
void CppElementEvaluator::evaluate()
|
||||||
|
{
|
||||||
|
if (!m_modelManager)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const Snapshot &snapshot = m_modelManager->snapshot();
|
||||||
|
Document::Ptr doc = snapshot.document(m_editor->file()->fileName());
|
||||||
|
if (!doc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int line = 0;
|
||||||
|
int column = 0;
|
||||||
|
const int pos = m_tc.position();
|
||||||
|
m_editor->convertPosition(pos, &line, &column);
|
||||||
|
|
||||||
|
if (!matchDiagnosticMessage(doc, line)) {
|
||||||
|
if (!matchIncludeFile(doc, line) && !matchMacroInUse(doc, pos)) {
|
||||||
|
moveCursorToEndOfName(&m_tc);
|
||||||
|
|
||||||
|
// Fetch the expression's code
|
||||||
|
ExpressionUnderCursor expressionUnderCursor;
|
||||||
|
const QString &expression = expressionUnderCursor(m_tc);
|
||||||
|
Scope *scope = doc->scopeAt(line, column);
|
||||||
|
|
||||||
|
TypeOfExpression typeOfExpression;
|
||||||
|
typeOfExpression.init(doc, snapshot);
|
||||||
|
const QList<LookupItem> &lookupItems = typeOfExpression(expression, scope);
|
||||||
|
if (lookupItems.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const LookupItem &lookupItem = lookupItems.first(); // ### TODO: select best candidate.
|
||||||
|
handleLookupItemMatch(snapshot, lookupItem, typeOfExpression.context());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CppElementEvaluator::matchDiagnosticMessage(const CPlusPlus::Document::Ptr &document,
|
||||||
|
unsigned line)
|
||||||
|
{
|
||||||
|
foreach (const Document::DiagnosticMessage &m, document->diagnosticMessages()) {
|
||||||
|
if (m.line() == line) {
|
||||||
|
m_element = QSharedPointer<CppElement>(new CppDiagnosis(m));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CppElementEvaluator::matchIncludeFile(const CPlusPlus::Document::Ptr &document, unsigned line)
|
||||||
|
{
|
||||||
|
foreach (const Document::Include &includeFile, document->includes()) {
|
||||||
|
if (includeFile.line() == line) {
|
||||||
|
m_element = QSharedPointer<CppElement>(new CppInclude(includeFile));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CppElementEvaluator::matchMacroInUse(const CPlusPlus::Document::Ptr &document, unsigned pos)
|
||||||
|
{
|
||||||
|
foreach (const Document::MacroUse &use, document->macroUses()) {
|
||||||
|
if (use.contains(pos)) {
|
||||||
|
const unsigned begin = use.begin();
|
||||||
|
const QString &name = use.macro().name();
|
||||||
|
if (pos < begin + name.length()) {
|
||||||
|
m_element = QSharedPointer<CppElement>(new CppMacro(use.macro()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppElementEvaluator::handleLookupItemMatch(const Snapshot &snapshot,
|
||||||
|
const LookupItem &lookupItem,
|
||||||
|
const LookupContext &context)
|
||||||
|
{
|
||||||
|
Symbol *declaration = lookupItem.declaration();
|
||||||
|
if (!declaration) {
|
||||||
|
const QString &type = Overview().prettyType(lookupItem.type(), QString());
|
||||||
|
m_element = QSharedPointer<CppElement>(new Unknown(type));
|
||||||
|
} else {
|
||||||
|
const FullySpecifiedType &type = declaration->type();
|
||||||
|
if (declaration->isNamespace()) {
|
||||||
|
m_element = QSharedPointer<CppElement>(new CppNamespace(declaration));
|
||||||
|
} else if (declaration->isClass() || declaration->isForwardClassDeclaration()) {
|
||||||
|
if (declaration->isForwardClassDeclaration())
|
||||||
|
if (Symbol *classDeclaration = snapshot.findMatchingClassDeclaration(declaration))
|
||||||
|
declaration = classDeclaration;
|
||||||
|
CppClass *cppClass = new CppClass(declaration);
|
||||||
|
if (m_lookupBaseClasses)
|
||||||
|
cppClass->lookupBases(declaration, context);
|
||||||
|
m_element = QSharedPointer<CppElement>(cppClass);
|
||||||
|
} else if (declaration->isEnum() || declaration->scope()->isEnum()) {
|
||||||
|
m_element = QSharedPointer<CppElement>(new CppEnum(declaration));
|
||||||
|
} else if (declaration->isTypedef()) {
|
||||||
|
m_element = QSharedPointer<CppElement>(new CppTypedef(declaration));
|
||||||
|
} else if (declaration->isFunction() || (type.isValid() && type->isFunctionType())) {
|
||||||
|
m_element = QSharedPointer<CppElement>(new CppFunction(declaration));
|
||||||
|
} else if (declaration->isDeclaration() && type.isValid()) {
|
||||||
|
m_element = QSharedPointer<CppElement>(
|
||||||
|
new CppVariable(declaration, context, lookupItem.scope()));
|
||||||
|
} else {
|
||||||
|
m_element = QSharedPointer<CppElement>(new CppDeclarableElement(declaration));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CppElement
|
||||||
|
CppElement::CppElement() : m_helpCategory(CppHoverHandler::HelpCandidate::Unknown)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CppElement::~CppElement()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CppElement::setHelpCategory(const CppHoverHandler::HelpCandidate::Category &cat)
|
||||||
|
{ m_helpCategory = cat; }
|
||||||
|
|
||||||
|
const CppHoverHandler::HelpCandidate::Category &CppElement::helpCategory() const
|
||||||
|
{ return m_helpCategory; }
|
||||||
|
|
||||||
|
void CppElement::setHelpIdCandidates(const QStringList &candidates)
|
||||||
|
{ m_helpIdCandidates = candidates; }
|
||||||
|
|
||||||
|
void CppElement::addHelpIdCandidate(const QString &candidate)
|
||||||
|
{ m_helpIdCandidates.append(candidate); }
|
||||||
|
|
||||||
|
const QStringList &CppElement::helpIdCandidates() const
|
||||||
|
{ return m_helpIdCandidates; }
|
||||||
|
|
||||||
|
void CppElement::setHelpMark(const QString &mark)
|
||||||
|
{ m_helpMark = mark; }
|
||||||
|
|
||||||
|
const QString &CppElement::helpMark() const
|
||||||
|
{ return m_helpMark; }
|
||||||
|
|
||||||
|
void CppElement::setLink(const CPPEditor::Link &link)
|
||||||
|
{ m_link = link; }
|
||||||
|
|
||||||
|
const CPPEditor::Link &CppElement::link() const
|
||||||
|
{ return m_link; }
|
||||||
|
|
||||||
|
void CppElement::setTooltip(const QString &tooltip)
|
||||||
|
{ m_tooltip = tooltip; }
|
||||||
|
|
||||||
|
const QString &CppElement::tooltip() const
|
||||||
|
{ return m_tooltip; }
|
||||||
|
|
||||||
|
|
||||||
|
// Unknown
|
||||||
|
Unknown::Unknown(const QString &type) : CppElement(), m_type(type)
|
||||||
|
{
|
||||||
|
setTooltip(m_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Unknown::~Unknown()
|
||||||
|
{}
|
||||||
|
|
||||||
|
const QString &Unknown::type() const
|
||||||
|
{ return m_type; }
|
||||||
|
|
||||||
|
// CppDiagnosis
|
||||||
|
CppDiagnosis::CppDiagnosis(const Document::DiagnosticMessage &message) :
|
||||||
|
CppElement(), m_text(message.text())
|
||||||
|
{
|
||||||
|
setTooltip(m_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
CppDiagnosis::~CppDiagnosis()
|
||||||
|
{}
|
||||||
|
|
||||||
|
const QString &CppDiagnosis::text() const
|
||||||
|
{ return m_text; }
|
||||||
|
|
||||||
|
// CppInclude
|
||||||
|
CppInclude::~CppInclude()
|
||||||
|
{}
|
||||||
|
|
||||||
|
CppInclude::CppInclude(const Document::Include &includeFile) :
|
||||||
|
CppElement(),
|
||||||
|
m_path(QDir::toNativeSeparators(includeFile.fileName())),
|
||||||
|
m_fileName(QFileInfo(includeFile.fileName()).fileName())
|
||||||
|
{
|
||||||
|
setHelpCategory(CppHoverHandler::HelpCandidate::Brief);
|
||||||
|
setHelpIdCandidates(QStringList(m_fileName));
|
||||||
|
setHelpMark(m_fileName);
|
||||||
|
setLink(CPPEditor::Link(m_path));
|
||||||
|
setTooltip(m_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &CppInclude::path() const
|
||||||
|
{ return m_path; }
|
||||||
|
|
||||||
|
const QString &CppInclude::fileName() const
|
||||||
|
{ return m_fileName; }
|
||||||
|
|
||||||
|
// CppMacro
|
||||||
|
CppMacro::CppMacro(const Macro ¯o) : CppElement()
|
||||||
|
{
|
||||||
|
setHelpCategory(CppHoverHandler::HelpCandidate::Macro);
|
||||||
|
setHelpIdCandidates(QStringList(macro.name()));
|
||||||
|
setHelpMark(macro.name());
|
||||||
|
setLink(CPPEditor::Link(macro.fileName(), macro.line()));
|
||||||
|
setTooltip(macro.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
CppMacro::~CppMacro()
|
||||||
|
{}
|
||||||
|
|
||||||
|
// CppDeclarableElement
|
||||||
|
CppDeclarableElement::CppDeclarableElement(Symbol *declaration) : CppElement()
|
||||||
|
{
|
||||||
|
const FullySpecifiedType &type = declaration->type();
|
||||||
|
|
||||||
|
Overview overview;
|
||||||
|
overview.setShowArgumentNames(true);
|
||||||
|
overview.setShowReturnTypes(true);
|
||||||
|
|
||||||
|
m_icon = Icons().iconForSymbol(declaration);
|
||||||
|
m_name = overview.prettyName(declaration->name());
|
||||||
|
if (declaration->scope()->isClass() ||
|
||||||
|
declaration->scope()->isNamespace() ||
|
||||||
|
declaration->scope()->isEnum()) {
|
||||||
|
m_qualifiedName = overview.prettyName(LookupContext::fullyQualifiedName(declaration));
|
||||||
|
} else {
|
||||||
|
m_qualifiedName = m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration->isClass() ||
|
||||||
|
declaration->isNamespace() ||
|
||||||
|
declaration->isForwardClassDeclaration() ||
|
||||||
|
declaration->isEnum()) {
|
||||||
|
m_type = m_qualifiedName;
|
||||||
|
} else {
|
||||||
|
m_type = overview.prettyType(type, m_qualifiedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTooltip(m_type);
|
||||||
|
setLink(CPPEditor::linkToSymbol(declaration));
|
||||||
|
|
||||||
|
QStringList helpIds;
|
||||||
|
helpIds << m_name << m_qualifiedName;
|
||||||
|
setHelpIdCandidates(helpIds);
|
||||||
|
setHelpMark(m_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
CppDeclarableElement::~CppDeclarableElement()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CppDeclarableElement::setName(const QString &name)
|
||||||
|
{ m_name = name; }
|
||||||
|
|
||||||
|
const QString &CppDeclarableElement::name() const
|
||||||
|
{ return m_name; }
|
||||||
|
|
||||||
|
void CppDeclarableElement::setQualifiedName(const QString &name)
|
||||||
|
{ m_qualifiedName = name; }
|
||||||
|
|
||||||
|
const QString &CppDeclarableElement::qualifiedName() const
|
||||||
|
{ return m_qualifiedName; }
|
||||||
|
|
||||||
|
void CppDeclarableElement::setType(const QString &type)
|
||||||
|
{ m_type = type; }
|
||||||
|
|
||||||
|
const QString &CppDeclarableElement::type() const
|
||||||
|
{ return m_type; }
|
||||||
|
|
||||||
|
void CppDeclarableElement::setIcon(const QIcon &icon)
|
||||||
|
{ m_icon = icon; }
|
||||||
|
|
||||||
|
const QIcon &CppDeclarableElement::icon() const
|
||||||
|
{ return m_icon; }
|
||||||
|
|
||||||
|
// CppNamespace
|
||||||
|
CppNamespace::CppNamespace(Symbol *declaration) : CppDeclarableElement(declaration)
|
||||||
|
{
|
||||||
|
setHelpCategory(CppHoverHandler::HelpCandidate::ClassOrNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
CppNamespace::~CppNamespace()
|
||||||
|
{}
|
||||||
|
|
||||||
|
// CppClass
|
||||||
|
CppClass::CppClass(Symbol *declaration) : CppDeclarableElement(declaration)
|
||||||
|
{
|
||||||
|
setHelpCategory(CppHoverHandler::HelpCandidate::ClassOrNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
CppClass::~CppClass()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CppClass::lookupBases(Symbol *declaration, const CPlusPlus::LookupContext &context)
|
||||||
|
{
|
||||||
|
typedef QPair<ClassOrNamespace *, CppClass *> Data;
|
||||||
|
|
||||||
|
if (ClassOrNamespace *clazz = context.lookupType(declaration)) {
|
||||||
|
QSet<ClassOrNamespace *> visited;
|
||||||
|
|
||||||
|
QQueue<Data> q;
|
||||||
|
q.enqueue(qMakePair(clazz, this));
|
||||||
|
while (!q.isEmpty()) {
|
||||||
|
Data current = q.dequeue();
|
||||||
|
clazz = current.first;
|
||||||
|
visited.insert(clazz);
|
||||||
|
const QList<ClassOrNamespace *> &bases = clazz->usings();
|
||||||
|
foreach (ClassOrNamespace *baseClass, bases) {
|
||||||
|
const QList<Symbol *> &symbols = baseClass->symbols();
|
||||||
|
foreach (Symbol *symbol, symbols) {
|
||||||
|
if (symbol->isClass() && (
|
||||||
|
clazz = context.lookupType(symbol)) &&
|
||||||
|
!visited.contains(clazz)) {
|
||||||
|
CppClass baseCppClass(symbol);
|
||||||
|
CppClass *cppClass = current.second;
|
||||||
|
cppClass->m_bases.append(baseCppClass);
|
||||||
|
q.enqueue(qMakePair(clazz, &cppClass->m_bases.last()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<CppClass> &CppClass::bases() const
|
||||||
|
{ return m_bases; }
|
||||||
|
|
||||||
|
// CppFunction
|
||||||
|
CppFunction::CppFunction(Symbol *declaration) : CppDeclarableElement(declaration)
|
||||||
|
{
|
||||||
|
setHelpCategory(CppHoverHandler::HelpCandidate::Function);
|
||||||
|
|
||||||
|
const FullySpecifiedType &type = declaration->type();
|
||||||
|
|
||||||
|
// Functions marks can be found either by the main overload or signature based
|
||||||
|
// (with no argument names and no return). Help ids have no signature at all.
|
||||||
|
Overview overview;
|
||||||
|
overview.setShowDefaultArguments(false);
|
||||||
|
setHelpMark(overview.prettyType(type, name()));
|
||||||
|
|
||||||
|
overview.setShowFunctionSignatures(false);
|
||||||
|
addHelpIdCandidate(overview.prettyName(declaration->name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
CppFunction::~CppFunction()
|
||||||
|
{}
|
||||||
|
|
||||||
|
// CppEnum
|
||||||
|
CppEnum::CppEnum(Symbol *declaration) : CppDeclarableElement(declaration)
|
||||||
|
{
|
||||||
|
setHelpCategory(CppHoverHandler::HelpCandidate::Enum);
|
||||||
|
|
||||||
|
if (declaration->scope()->isEnum()) {
|
||||||
|
Symbol *enumSymbol = declaration->scope()->asEnum();
|
||||||
|
Overview overview;
|
||||||
|
setHelpMark(overview.prettyName(enumSymbol->name()));
|
||||||
|
setTooltip(overview.prettyName(LookupContext::fullyQualifiedName(enumSymbol)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CppEnum::~CppEnum()
|
||||||
|
{}
|
||||||
|
|
||||||
|
// CppTypedef
|
||||||
|
CppTypedef::CppTypedef(Symbol *declaration) :
|
||||||
|
CppDeclarableElement(declaration)
|
||||||
|
{
|
||||||
|
setHelpCategory(CppHoverHandler::HelpCandidate::Typedef);
|
||||||
|
}
|
||||||
|
|
||||||
|
CppTypedef::~CppTypedef()
|
||||||
|
{}
|
||||||
|
|
||||||
|
// CppVariable
|
||||||
|
CppVariable::CppVariable(Symbol *declaration, const LookupContext &context, Scope *scope) :
|
||||||
|
CppDeclarableElement(declaration)
|
||||||
|
{
|
||||||
|
const FullySpecifiedType &type = declaration->type();
|
||||||
|
|
||||||
|
const Name *typeName = 0;
|
||||||
|
if (type->isNamedType()) {
|
||||||
|
typeName = type->asNamedType()->name();
|
||||||
|
} else if (type->isPointerType() || type->isReferenceType()) {
|
||||||
|
FullySpecifiedType associatedType;
|
||||||
|
if (type->isPointerType())
|
||||||
|
associatedType = type->asPointerType()->elementType();
|
||||||
|
else
|
||||||
|
associatedType = type->asReferenceType()->elementType();
|
||||||
|
if (associatedType->isNamedType())
|
||||||
|
typeName = associatedType->asNamedType()->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeName) {
|
||||||
|
if (ClassOrNamespace *clazz = context.lookupType(typeName, scope)) {
|
||||||
|
if (!clazz->symbols().isEmpty()) {
|
||||||
|
Overview overview;
|
||||||
|
Symbol *symbol = clazz->symbols().at(0);
|
||||||
|
const QString &name =
|
||||||
|
overview.prettyName(LookupContext::fullyQualifiedName(symbol));
|
||||||
|
setTooltip(name);
|
||||||
|
setHelpCategory(CppHoverHandler::HelpCandidate::ClassOrNamespace);
|
||||||
|
setHelpMark(name);
|
||||||
|
setHelpIdCandidates(QStringList(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CppVariable::~CppVariable()
|
||||||
|
{}
|
238
src/plugins/cppeditor/cppelementevaluator.h
Normal file
238
src/plugins/cppeditor/cppelementevaluator.h
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CPPHIGHLEVELMODEL_H
|
||||||
|
#define CPPHIGHLEVELMODEL_H
|
||||||
|
|
||||||
|
#include "cppeditor.h"
|
||||||
|
#include "cpphoverhandler.h"
|
||||||
|
|
||||||
|
#include <cplusplus/CppDocument.h>
|
||||||
|
#include <cplusplus/Overview.h>
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QSharedPointer>
|
||||||
|
#include <QtGui/QTextCursor>
|
||||||
|
#include <QtGui/QIcon>
|
||||||
|
|
||||||
|
namespace CPlusPlus {
|
||||||
|
class LookupItem;
|
||||||
|
class LookupContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CppTools {
|
||||||
|
class CppModelManagerInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CppEditor {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class CPPEditor;
|
||||||
|
class CppElement;
|
||||||
|
|
||||||
|
class CppElementEvaluator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppElementEvaluator(CPPEditor *editor);
|
||||||
|
|
||||||
|
void setTextCursor(const QTextCursor &tc);
|
||||||
|
void setLookupBaseClasses(const bool lookup);
|
||||||
|
|
||||||
|
QSharedPointer<CppElement> identifyCppElement();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void evaluate();
|
||||||
|
bool matchDiagnosticMessage(const CPlusPlus::Document::Ptr &document, unsigned line);
|
||||||
|
bool matchIncludeFile(const CPlusPlus::Document::Ptr &document, unsigned line);
|
||||||
|
bool matchMacroInUse(const CPlusPlus::Document::Ptr &document, unsigned pos);
|
||||||
|
void handleLookupItemMatch(const CPlusPlus::Snapshot &snapshot,
|
||||||
|
const CPlusPlus::LookupItem &lookupItem,
|
||||||
|
const CPlusPlus::LookupContext &lookupContext);
|
||||||
|
|
||||||
|
CPPEditor *m_editor;
|
||||||
|
CppTools::CppModelManagerInterface *m_modelManager;
|
||||||
|
QTextCursor m_tc;
|
||||||
|
bool m_lookupBaseClasses;
|
||||||
|
QSharedPointer<CppElement> m_element;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~CppElement();
|
||||||
|
|
||||||
|
const CppHoverHandler::HelpCandidate::Category &helpCategory() const;
|
||||||
|
const QStringList &helpIdCandidates() const;
|
||||||
|
const QString &helpMark() const;
|
||||||
|
const CPPEditor::Link &link() const;
|
||||||
|
const QString &tooltip() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CppElement();
|
||||||
|
|
||||||
|
void setHelpCategory(const CppHoverHandler::HelpCandidate::Category &category);
|
||||||
|
void setLink(const CPPEditor::Link &link);
|
||||||
|
void setTooltip(const QString &tooltip);
|
||||||
|
void setHelpIdCandidates(const QStringList &candidates);
|
||||||
|
void addHelpIdCandidate(const QString &candidate);
|
||||||
|
void setHelpMark(const QString &mark);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CppHoverHandler::HelpCandidate::Category m_helpCategory;
|
||||||
|
QStringList m_helpIdCandidates;
|
||||||
|
QString m_helpMark;
|
||||||
|
CPPEditor::Link m_link;
|
||||||
|
QString m_tooltip;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Unknown : public CppElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Unknown(const QString &type);
|
||||||
|
virtual ~Unknown();
|
||||||
|
|
||||||
|
const QString &type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppDiagnosis : public CppElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppDiagnosis(const CPlusPlus::Document::DiagnosticMessage &message);
|
||||||
|
virtual ~CppDiagnosis();
|
||||||
|
|
||||||
|
const QString &text() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_text;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppInclude : public CppElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppInclude(const CPlusPlus::Document::Include &includeFile);
|
||||||
|
virtual ~CppInclude();
|
||||||
|
|
||||||
|
const QString &path() const;
|
||||||
|
const QString &fileName() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_path;
|
||||||
|
QString m_fileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppMacro : public CppElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppMacro(const CPlusPlus::Macro ¯o);
|
||||||
|
virtual ~CppMacro();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppDeclarableElement : public CppElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppDeclarableElement(CPlusPlus::Symbol *declaration);
|
||||||
|
virtual ~CppDeclarableElement();
|
||||||
|
|
||||||
|
const QString &name() const;
|
||||||
|
const QString &qualifiedName() const;
|
||||||
|
const QString &type() const;
|
||||||
|
const QIcon &icon() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setName(const QString &name);
|
||||||
|
void setQualifiedName(const QString &name);
|
||||||
|
void setType(const QString &type);
|
||||||
|
void setIcon(const QIcon &icon);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_name;
|
||||||
|
QString m_qualifiedName;
|
||||||
|
QString m_type;
|
||||||
|
QIcon m_icon;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppNamespace : public CppDeclarableElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppNamespace(CPlusPlus::Symbol *declaration);
|
||||||
|
virtual ~CppNamespace();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppClass : public CppDeclarableElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppClass(CPlusPlus::Symbol *declaration);
|
||||||
|
virtual ~CppClass();
|
||||||
|
|
||||||
|
void lookupBases(CPlusPlus::Symbol *declaration, const CPlusPlus::LookupContext &context);
|
||||||
|
|
||||||
|
const QList<CppClass> &bases() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<CppClass> m_bases;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppFunction : public CppDeclarableElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppFunction(CPlusPlus::Symbol *declaration);
|
||||||
|
virtual ~CppFunction();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppEnum : public CppDeclarableElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppEnum(CPlusPlus::Symbol *declaration);
|
||||||
|
virtual ~CppEnum();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppTypedef : public CppDeclarableElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppTypedef(CPlusPlus::Symbol *declaration);
|
||||||
|
virtual ~CppTypedef();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppVariable : public CppDeclarableElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppVariable(CPlusPlus::Symbol *declaration,
|
||||||
|
const CPlusPlus::LookupContext &context,
|
||||||
|
CPlusPlus::Scope *scope);
|
||||||
|
virtual ~CppVariable();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace CppEditor
|
||||||
|
|
||||||
|
#endif // CPPHIGHLEVELMODEL_H
|
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "cpphoverhandler.h"
|
#include "cpphoverhandler.h"
|
||||||
#include "cppeditor.h"
|
#include "cppeditor.h"
|
||||||
|
#include "cppelementevaluator.h"
|
||||||
|
|
||||||
#include <coreplugin/editormanager/ieditor.h>
|
#include <coreplugin/editormanager/ieditor.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
@@ -37,29 +38,9 @@
|
|||||||
#include <texteditor/itexteditor.h>
|
#include <texteditor/itexteditor.h>
|
||||||
#include <texteditor/basetexteditor.h>
|
#include <texteditor/basetexteditor.h>
|
||||||
|
|
||||||
#include <FullySpecifiedType.h>
|
|
||||||
#include <Names.h>
|
|
||||||
#include <CoreTypes.h>
|
|
||||||
#include <Scope.h>
|
|
||||||
#include <Symbol.h>
|
|
||||||
#include <Symbols.h>
|
|
||||||
#include <cplusplus/ExpressionUnderCursor.h>
|
|
||||||
#include <cplusplus/Overview.h>
|
|
||||||
#include <cplusplus/TypeOfExpression.h>
|
|
||||||
#include <cplusplus/LookupContext.h>
|
|
||||||
#include <cplusplus/LookupItem.h>
|
|
||||||
|
|
||||||
#include <QtCore/QSet>
|
|
||||||
#include <QtCore/QDir>
|
|
||||||
#include <QtCore/QFileInfo>
|
|
||||||
#include <QtCore/QtAlgorithms>
|
|
||||||
#include <QtCore/QStringBuilder>
|
|
||||||
#include <QtGui/QTextCursor>
|
#include <QtGui/QTextCursor>
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using namespace CppEditor::Internal;
|
using namespace CppEditor::Internal;
|
||||||
using namespace CPlusPlus;
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -70,73 +51,13 @@ namespace {
|
|||||||
else
|
else
|
||||||
return name.right(name.length() - index - 1);
|
return name.right(name.length() - index - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveCursorToEndOfName(QTextCursor *tc) {
|
|
||||||
QTextDocument *doc = tc->document();
|
|
||||||
if (!doc)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QChar ch = doc->characterAt(tc->position());
|
|
||||||
while (ch.isLetterOrNumber() || ch == QLatin1Char('_')) {
|
|
||||||
tc->movePosition(QTextCursor::NextCharacter);
|
|
||||||
ch = doc->characterAt(tc->position());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void buildClassHierarchyHelper(ClassOrNamespace *classSymbol,
|
|
||||||
const LookupContext &context,
|
|
||||||
const Overview &overview,
|
|
||||||
QList<QStringList> *hierarchy,
|
|
||||||
QSet<ClassOrNamespace *> *visited) {
|
|
||||||
visited->insert(classSymbol);
|
|
||||||
const QList<ClassOrNamespace *> &bases = classSymbol->usings();
|
|
||||||
foreach (ClassOrNamespace *baseClass, bases) {
|
|
||||||
const QList<Symbol *> &symbols = baseClass->symbols();
|
|
||||||
foreach (Symbol *baseSymbol, symbols) {
|
|
||||||
if (baseSymbol->isClass() && (
|
|
||||||
classSymbol = context.lookupType(baseSymbol)) &&
|
|
||||||
!visited->contains(classSymbol)) {
|
|
||||||
const QString &qualifiedName = overview.prettyName(
|
|
||||||
LookupContext::fullyQualifiedName(baseSymbol));
|
|
||||||
if (!qualifiedName.isEmpty()) {
|
|
||||||
hierarchy->back().append(qualifiedName);
|
|
||||||
buildClassHierarchyHelper(classSymbol,
|
|
||||||
context,
|
|
||||||
overview,
|
|
||||||
hierarchy,
|
|
||||||
visited);
|
|
||||||
hierarchy->append(hierarchy->back());
|
|
||||||
hierarchy->back().removeLast();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void buildClassHierarchy(Symbol *symbol,
|
|
||||||
const LookupContext &context,
|
|
||||||
const Overview &overview,
|
|
||||||
QList<QStringList> *hierarchy) {
|
|
||||||
if (ClassOrNamespace *classSymbol = context.lookupType(symbol)) {
|
|
||||||
hierarchy->append(QStringList());
|
|
||||||
QSet<ClassOrNamespace *> visited;
|
|
||||||
buildClassHierarchyHelper(classSymbol, context, overview, hierarchy, &visited);
|
|
||||||
hierarchy->removeLast();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ClassHierarchyComp
|
|
||||||
{
|
|
||||||
bool operator()(const QStringList &a, const QStringList &b)
|
|
||||||
{ return a.size() < b.size(); }
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CppHoverHandler::CppHoverHandler(QObject *parent) : BaseHoverHandler(parent), m_modelManager(0)
|
CppHoverHandler::CppHoverHandler(QObject *parent) : BaseHoverHandler(parent)
|
||||||
{
|
{}
|
||||||
m_modelManager =
|
|
||||||
ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
|
CppHoverHandler::~CppHoverHandler()
|
||||||
}
|
{}
|
||||||
|
|
||||||
bool CppHoverHandler::acceptEditor(IEditor *editor)
|
bool CppHoverHandler::acceptEditor(IEditor *editor)
|
||||||
{
|
{
|
||||||
@@ -148,191 +69,25 @@ bool CppHoverHandler::acceptEditor(IEditor *editor)
|
|||||||
|
|
||||||
void CppHoverHandler::identifyMatch(TextEditor::ITextEditor *editor, int pos)
|
void CppHoverHandler::identifyMatch(TextEditor::ITextEditor *editor, int pos)
|
||||||
{
|
{
|
||||||
if (!m_modelManager)
|
CPPEditor *cppEditor = qobject_cast<CPPEditor *>(editor->widget());
|
||||||
|
if (!cppEditor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Snapshot &snapshot = m_modelManager->snapshot();
|
if (!cppEditor->extraSelectionTooltip(pos).isEmpty()) {
|
||||||
Document::Ptr doc = snapshot.document(editor->file()->fileName());
|
setToolTip(cppEditor->extraSelectionTooltip(pos));
|
||||||
if (!doc)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int line = 0;
|
|
||||||
int column = 0;
|
|
||||||
editor->convertPosition(pos, &line, &column);
|
|
||||||
|
|
||||||
if (!matchDiagnosticMessage(doc, line)) {
|
|
||||||
if (!matchIncludeFile(doc, line) && !matchMacroInUse(doc, pos)) {
|
|
||||||
TextEditor::BaseTextEditor *baseEditor = baseTextEditor(editor);
|
|
||||||
if (!baseEditor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool extraSelectionTooltip = false;
|
|
||||||
if (!baseEditor->extraSelectionTooltip(pos).isEmpty()) {
|
|
||||||
setToolTip(baseEditor->extraSelectionTooltip(pos));
|
|
||||||
extraSelectionTooltip = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextCursor tc(baseEditor->document());
|
|
||||||
tc.setPosition(pos);
|
|
||||||
moveCursorToEndOfName(&tc);
|
|
||||||
|
|
||||||
// Fetch the expression's code
|
|
||||||
ExpressionUnderCursor expressionUnderCursor;
|
|
||||||
const QString &expression = expressionUnderCursor(tc);
|
|
||||||
Scope *scope = doc->scopeAt(line, column);
|
|
||||||
|
|
||||||
TypeOfExpression typeOfExpression;
|
|
||||||
typeOfExpression.init(doc, snapshot);
|
|
||||||
const QList<LookupItem> &lookupItems = typeOfExpression(expression, scope);
|
|
||||||
if (lookupItems.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const LookupItem &lookupItem = lookupItems.first(); // ### TODO: select best candidate.
|
|
||||||
handleLookupItemMatch(lookupItem, typeOfExpression.context(), !extraSelectionTooltip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CppHoverHandler::matchDiagnosticMessage(const CPlusPlus::Document::Ptr &document,
|
|
||||||
unsigned line)
|
|
||||||
{
|
|
||||||
foreach (const Document::DiagnosticMessage &m, document->diagnosticMessages()) {
|
|
||||||
if (m.line() == line) {
|
|
||||||
setToolTip(m.text());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CppHoverHandler::matchIncludeFile(const CPlusPlus::Document::Ptr &document, unsigned line)
|
|
||||||
{
|
|
||||||
foreach (const Document::Include &includeFile, document->includes()) {
|
|
||||||
if (includeFile.line() == line) {
|
|
||||||
setToolTip(QDir::toNativeSeparators(includeFile.fileName()));
|
|
||||||
const QString &fileName = QFileInfo(includeFile.fileName()).fileName();
|
|
||||||
addHelpCandidate(HelpCandidate(fileName, fileName, HelpCandidate::Brief));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CppHoverHandler::matchMacroInUse(const CPlusPlus::Document::Ptr &document, unsigned pos)
|
|
||||||
{
|
|
||||||
foreach (const Document::MacroUse &use, document->macroUses()) {
|
|
||||||
if (use.contains(pos)) {
|
|
||||||
const unsigned begin = use.begin();
|
|
||||||
const QString &name = use.macro().name();
|
|
||||||
if (pos < begin + name.length()) {
|
|
||||||
setToolTip(use.macro().toString());
|
|
||||||
addHelpCandidate(HelpCandidate(name, name, HelpCandidate::Macro));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppHoverHandler::handleLookupItemMatch(const LookupItem &lookupItem,
|
|
||||||
const LookupContext &context,
|
|
||||||
const bool assignTooltip)
|
|
||||||
{
|
|
||||||
Symbol *matchingDeclaration = lookupItem.declaration();
|
|
||||||
FullySpecifiedType matchingType = lookupItem.type();
|
|
||||||
|
|
||||||
Overview overview;
|
|
||||||
overview.setShowArgumentNames(true);
|
|
||||||
overview.setShowReturnTypes(true);
|
|
||||||
|
|
||||||
if (!matchingDeclaration && assignTooltip) {
|
|
||||||
setToolTip(overview.prettyType(matchingType, QString()));
|
|
||||||
} else {
|
} else {
|
||||||
QString name;
|
QTextCursor tc(cppEditor->document());
|
||||||
if (matchingDeclaration->scope()->isClass() ||
|
tc.setPosition(pos);
|
||||||
matchingDeclaration->scope()->isNamespace() ||
|
|
||||||
matchingDeclaration->scope()->isEnum()) {
|
|
||||||
name.append(overview.prettyName(
|
|
||||||
LookupContext::fullyQualifiedName(matchingDeclaration)));
|
|
||||||
|
|
||||||
if (matchingDeclaration->isClass() ||
|
CppElementEvaluator evaluator(cppEditor);
|
||||||
matchingDeclaration->isForwardClassDeclaration()) {
|
evaluator.setTextCursor(tc);
|
||||||
buildClassHierarchy(matchingDeclaration, context, overview, &m_classHierarchy);
|
QSharedPointer<CppElement> cppElement = evaluator.identifyCppElement();
|
||||||
}
|
if (!cppElement.isNull()) {
|
||||||
} else {
|
setToolTip(cppElement->tooltip());
|
||||||
name.append(overview.prettyName(matchingDeclaration->name()));
|
foreach (const QString &helpId, cppElement->helpIdCandidates())
|
||||||
}
|
addHelpCandidate(HelpCandidate(helpId,
|
||||||
|
cppElement->helpMark(),
|
||||||
if (assignTooltip) {
|
cppElement->helpCategory()));
|
||||||
if (matchingDeclaration->isClass() ||
|
|
||||||
matchingDeclaration->isNamespace() ||
|
|
||||||
matchingDeclaration->isForwardClassDeclaration() ||
|
|
||||||
matchingDeclaration->isEnum()) {
|
|
||||||
setToolTip(name);
|
|
||||||
} else {
|
|
||||||
setToolTip(overview.prettyType(matchingType, name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HelpCandidate::Category helpCategory = HelpCandidate::Unknown;
|
|
||||||
if (matchingDeclaration->isNamespace() ||
|
|
||||||
matchingDeclaration->isClass() ||
|
|
||||||
matchingDeclaration->isForwardClassDeclaration()) {
|
|
||||||
helpCategory = HelpCandidate::ClassOrNamespace;
|
|
||||||
} else if (matchingDeclaration->isEnum() ||
|
|
||||||
matchingDeclaration->scope()->isEnum()) {
|
|
||||||
helpCategory = HelpCandidate::Enum;
|
|
||||||
} else if (matchingDeclaration->isTypedef()) {
|
|
||||||
helpCategory = HelpCandidate::Typedef;
|
|
||||||
} else if (matchingDeclaration->isFunction() ||
|
|
||||||
(matchingType.isValid() && matchingType->isFunctionType())){
|
|
||||||
helpCategory = HelpCandidate::Function;
|
|
||||||
} else if (matchingDeclaration->isDeclaration() && matchingType.isValid()) {
|
|
||||||
const Name *typeName = 0;
|
|
||||||
if (matchingType->isNamedType()) {
|
|
||||||
typeName = matchingType->asNamedType()->name();
|
|
||||||
} else if (matchingType->isPointerType() || matchingType->isReferenceType()) {
|
|
||||||
FullySpecifiedType type;
|
|
||||||
if (matchingType->isPointerType())
|
|
||||||
type = matchingType->asPointerType()->elementType();
|
|
||||||
else
|
|
||||||
type = matchingType->asReferenceType()->elementType();
|
|
||||||
if (type->isNamedType())
|
|
||||||
typeName = type->asNamedType()->name();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeName) {
|
|
||||||
if (ClassOrNamespace *clazz = context.lookupType(typeName, lookupItem.scope())) {
|
|
||||||
if (!clazz->symbols().isEmpty()) {
|
|
||||||
Symbol *symbol = clazz->symbols().at(0);
|
|
||||||
matchingDeclaration = symbol;
|
|
||||||
name = overview.prettyName(LookupContext::fullyQualifiedName(symbol));
|
|
||||||
setToolTip(name);
|
|
||||||
buildClassHierarchy(symbol, context, overview, &m_classHierarchy);
|
|
||||||
helpCategory = HelpCandidate::ClassOrNamespace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helpCategory != HelpCandidate::Unknown) {
|
|
||||||
QString docMark = overview.prettyName(matchingDeclaration->name());
|
|
||||||
|
|
||||||
if (matchingType.isValid() && matchingType->isFunctionType()) {
|
|
||||||
// Functions marks can be found either by the main overload or signature based
|
|
||||||
// (with no argument names and no return). Help ids have no signature at all.
|
|
||||||
overview.setShowArgumentNames(false);
|
|
||||||
overview.setShowReturnTypes(false);
|
|
||||||
docMark = overview.prettyType(matchingType, docMark);
|
|
||||||
overview.setShowFunctionSignatures(false);
|
|
||||||
const QString &functionName = overview.prettyName(matchingDeclaration->name());
|
|
||||||
addHelpCandidate(HelpCandidate(functionName, docMark, helpCategory));
|
|
||||||
} else if (matchingDeclaration->scope()->isEnum()) {
|
|
||||||
Symbol *enumSymbol = matchingDeclaration->scope()->asEnum();
|
|
||||||
docMark = overview.prettyName(enumSymbol->name());
|
|
||||||
}
|
|
||||||
|
|
||||||
addHelpCandidate(HelpCandidate(name, docMark, helpCategory));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -357,121 +112,8 @@ void CppHoverHandler::evaluateHelpCandidates()
|
|||||||
|
|
||||||
void CppHoverHandler::decorateToolTip(TextEditor::ITextEditor *editor)
|
void CppHoverHandler::decorateToolTip(TextEditor::ITextEditor *editor)
|
||||||
{
|
{
|
||||||
if (!m_classHierarchy.isEmpty())
|
|
||||||
generateDiagramTooltip(extendToolTips(editor));
|
|
||||||
else
|
|
||||||
generateNormalTooltip(extendToolTips(editor));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppHoverHandler::generateDiagramTooltip(const bool extendTooltips)
|
|
||||||
{
|
|
||||||
QString clazz = toolTip();
|
|
||||||
|
|
||||||
qSort(m_classHierarchy.begin(), m_classHierarchy.end(), ClassHierarchyComp());
|
|
||||||
|
|
||||||
// Remove duplicates (in case there are any).
|
|
||||||
m_classHierarchy.erase(std::unique(m_classHierarchy.begin(), m_classHierarchy.end()),
|
|
||||||
m_classHierarchy.end());
|
|
||||||
|
|
||||||
QStringList directBaseClasses;
|
|
||||||
foreach (const QStringList &hierarchy, m_classHierarchy) {
|
|
||||||
if (hierarchy.size() > 1)
|
|
||||||
break;
|
|
||||||
directBaseClasses.append(hierarchy.at(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString diagram(QLatin1String("<table>"));
|
|
||||||
for (int i = 0; i < directBaseClasses.size(); ++i) {
|
|
||||||
if (i == 0) {
|
|
||||||
diagram.append(QString(
|
|
||||||
"<tr><td>%1</td><td>"
|
|
||||||
"<img src=\":/cppeditor/images/rightarrow.png\"></td>"
|
|
||||||
"<td>%2</td></tr>").arg(toolTip()).arg(directBaseClasses.at(i)));
|
|
||||||
} else {
|
|
||||||
diagram.append(QString(
|
|
||||||
"<tr><td></td><td>"
|
|
||||||
"<img src=\":/cppeditor/images/larrow.png\"></td>"
|
|
||||||
"<td>%1</td></tr>").arg(directBaseClasses.at(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diagram.append(QLatin1String("</table>"));
|
|
||||||
setToolTip(diagram);
|
|
||||||
|
|
||||||
if (matchingHelpCandidate() != -1) {
|
if (matchingHelpCandidate() != -1) {
|
||||||
appendToolTip(getDocContents(extendTooltips));
|
const QString &contents = getDocContents(extendToolTips(editor));
|
||||||
} else {
|
|
||||||
// Look for documented base classes. Diagram the nearest one or the nearest ones (in
|
|
||||||
// the case there are many at the same level).
|
|
||||||
int helpLevel = 0;
|
|
||||||
QList<int> baseClassesWithHelp;
|
|
||||||
for (int i = 0; i < m_classHierarchy.size(); ++i) {
|
|
||||||
const QStringList &hierarchy = m_classHierarchy.at(i);
|
|
||||||
if (helpLevel != 0 && hierarchy.size() != helpLevel)
|
|
||||||
break;
|
|
||||||
|
|
||||||
bool exists = false;
|
|
||||||
QString name = hierarchy.last();
|
|
||||||
if (helpIdExists(name)) {
|
|
||||||
exists = true;
|
|
||||||
} else {
|
|
||||||
name = removeClassNameQualification(name);
|
|
||||||
if (helpIdExists(name)) {
|
|
||||||
exists = true;
|
|
||||||
m_classHierarchy[i].last() = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (exists) {
|
|
||||||
baseClassesWithHelp.append(i);
|
|
||||||
if (helpLevel == 0)
|
|
||||||
helpLevel = hierarchy.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!baseClassesWithHelp.isEmpty()) {
|
|
||||||
// Choose the first one as the help match.
|
|
||||||
QString base = m_classHierarchy.at(baseClassesWithHelp.at(0)).last();
|
|
||||||
HelpCandidate help(base, base, HelpCandidate::ClassOrNamespace);
|
|
||||||
addHelpCandidate(help);
|
|
||||||
setMatchingHelpCandidate(helpCandidates().size() - 1);
|
|
||||||
|
|
||||||
if (baseClassesWithHelp.size() == 1 && helpLevel == 1) {
|
|
||||||
appendToolTip(getDocContents(help, extendTooltips));
|
|
||||||
} else {
|
|
||||||
foreach (int hierarchyIndex, baseClassesWithHelp) {
|
|
||||||
appendToolTip(QLatin1String("<p>"));
|
|
||||||
const QStringList &hierarchy = m_classHierarchy.at(hierarchyIndex);
|
|
||||||
Q_ASSERT(helpLevel <= hierarchy.size());
|
|
||||||
|
|
||||||
// Following contents are inside tables so they are on the exact same
|
|
||||||
// alignment as the top level diagram.
|
|
||||||
diagram = QString(QLatin1String("<table><tr><td>%1</td>")).arg(clazz);
|
|
||||||
for (int i = 0; i < helpLevel; ++i) {
|
|
||||||
diagram.append(
|
|
||||||
QLatin1String("<td><img src=\":/cppeditor/images/rightarrow.png\">"
|
|
||||||
"</td><td>") %
|
|
||||||
hierarchy.at(i) %
|
|
||||||
QLatin1String("</td>"));
|
|
||||||
}
|
|
||||||
diagram.append(QLatin1String("</tr></table>"));
|
|
||||||
|
|
||||||
base = hierarchy.at(helpLevel - 1);
|
|
||||||
const QString &contents =
|
|
||||||
getDocContents(HelpCandidate(base, base, HelpCandidate::Brief), false);
|
|
||||||
if (!contents.isEmpty()) {
|
|
||||||
appendToolTip(diagram % QLatin1String("<table><tr><td>") %
|
|
||||||
contents % QLatin1String("</td></tr></table>"));
|
|
||||||
}
|
|
||||||
appendToolTip(QLatin1String("</p>"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppHoverHandler::generateNormalTooltip(const bool extendTooltips)
|
|
||||||
{
|
|
||||||
if (matchingHelpCandidate() != -1) {
|
|
||||||
const QString &contents = getDocContents(extendTooltips);
|
|
||||||
if (!contents.isEmpty()) {
|
if (!contents.isEmpty()) {
|
||||||
HelpCandidate::Category cat = helpCandidate(matchingHelpCandidate()).m_category;
|
HelpCandidate::Category cat = helpCandidate(matchingHelpCandidate()).m_category;
|
||||||
if (cat == HelpCandidate::ClassOrNamespace)
|
if (cat == HelpCandidate::ClassOrNamespace)
|
||||||
@@ -486,8 +128,3 @@ void CppHoverHandler::generateNormalTooltip(const bool extendTooltips)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppHoverHandler::resetExtras()
|
|
||||||
{
|
|
||||||
m_classHierarchy.clear();
|
|
||||||
}
|
|
||||||
|
@@ -30,26 +30,14 @@
|
|||||||
#ifndef CPPHOVERHANDLER_H
|
#ifndef CPPHOVERHANDLER_H
|
||||||
#define CPPHOVERHANDLER_H
|
#define CPPHOVERHANDLER_H
|
||||||
|
|
||||||
#include <cplusplus/CppDocument.h>
|
|
||||||
#include <texteditor/basehoverhandler.h>
|
#include <texteditor/basehoverhandler.h>
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QList>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
|
|
||||||
namespace CPlusPlus {
|
|
||||||
class LookupItem;
|
|
||||||
class LookupContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class IEditor;
|
class IEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CppTools {
|
|
||||||
class CppModelManagerInterface;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
class ITextEditor;
|
class ITextEditor;
|
||||||
}
|
}
|
||||||
@@ -62,26 +50,13 @@ class CppHoverHandler : public TextEditor::BaseHoverHandler
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
CppHoverHandler(QObject *parent = 0);
|
CppHoverHandler(QObject *parent = 0);
|
||||||
|
virtual ~CppHoverHandler();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool acceptEditor(Core::IEditor *editor);
|
virtual bool acceptEditor(Core::IEditor *editor);
|
||||||
virtual void identifyMatch(TextEditor::ITextEditor *editor, int pos);
|
virtual void identifyMatch(TextEditor::ITextEditor *editor, int pos);
|
||||||
virtual void resetExtras();
|
|
||||||
virtual void evaluateHelpCandidates();
|
virtual void evaluateHelpCandidates();
|
||||||
virtual void decorateToolTip(TextEditor::ITextEditor *editor);
|
virtual void decorateToolTip(TextEditor::ITextEditor *editor);
|
||||||
|
|
||||||
bool matchDiagnosticMessage(const CPlusPlus::Document::Ptr &document, unsigned line);
|
|
||||||
bool matchIncludeFile(const CPlusPlus::Document::Ptr &document, unsigned line);
|
|
||||||
bool matchMacroInUse(const CPlusPlus::Document::Ptr &document, unsigned pos);
|
|
||||||
void handleLookupItemMatch(const CPlusPlus::LookupItem &lookupItem,
|
|
||||||
const CPlusPlus::LookupContext &lookupContext,
|
|
||||||
const bool assignTooltip);
|
|
||||||
|
|
||||||
void generateDiagramTooltip(const bool extendTooltips);
|
|
||||||
void generateNormalTooltip(const bool extendTooltips);
|
|
||||||
|
|
||||||
CppTools::CppModelManagerInterface *m_modelManager;
|
|
||||||
QList<QStringList> m_classHierarchy;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include "cpphoverhandler.h"
|
#include "cpphoverhandler.h"
|
||||||
#include "cppquickfix.h"
|
#include "cppquickfix.h"
|
||||||
#include "cppoutline.h"
|
#include "cppoutline.h"
|
||||||
|
#include "cpptypehierarchy.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
#include <coreplugin/actionmanager/command.h>
|
#include <coreplugin/actionmanager/command.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
|
#include <coreplugin/navigationwidget.h>
|
||||||
#include <texteditor/completionsupport.h>
|
#include <texteditor/completionsupport.h>
|
||||||
#include <texteditor/fontsettings.h>
|
#include <texteditor/fontsettings.h>
|
||||||
#include <texteditor/storagesettings.h>
|
#include <texteditor/storagesettings.h>
|
||||||
@@ -60,6 +62,7 @@
|
|||||||
#include <QtCore/QSettings>
|
#include <QtCore/QSettings>
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
|
||||||
#include <QtGui/QMenu>
|
#include <QtGui/QMenu>
|
||||||
|
|
||||||
@@ -139,8 +142,8 @@ CppPlugin::CppPlugin() :
|
|||||||
m_sortedOutline(false),
|
m_sortedOutline(false),
|
||||||
m_renameSymbolUnderCursorAction(0),
|
m_renameSymbolUnderCursorAction(0),
|
||||||
m_findUsagesAction(0),
|
m_findUsagesAction(0),
|
||||||
m_updateCodeModelAction(0)
|
m_updateCodeModelAction(0),
|
||||||
|
m_openTypeHierarchyAction(0)
|
||||||
{
|
{
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
|
|
||||||
@@ -205,7 +208,7 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess
|
|||||||
addAutoReleasedObject(new CppEditorFactory(this));
|
addAutoReleasedObject(new CppEditorFactory(this));
|
||||||
addAutoReleasedObject(new CppHoverHandler);
|
addAutoReleasedObject(new CppHoverHandler);
|
||||||
addAutoReleasedObject(new CppOutlineWidgetFactory);
|
addAutoReleasedObject(new CppOutlineWidgetFactory);
|
||||||
|
addAutoReleasedObject(new CppTypeHierarchyFactory);
|
||||||
|
|
||||||
m_quickFixCollector = new CppQuickFixCollector;
|
m_quickFixCollector = new CppQuickFixCollector;
|
||||||
addAutoReleasedObject(m_quickFixCollector);
|
addAutoReleasedObject(m_quickFixCollector);
|
||||||
@@ -274,6 +277,13 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess
|
|||||||
contextMenu->addAction(cmd);
|
contextMenu->addAction(cmd);
|
||||||
cppToolsMenu->addAction(cmd);
|
cppToolsMenu->addAction(cmd);
|
||||||
|
|
||||||
|
m_openTypeHierarchyAction = new QAction(tr("Open Type Hierarchy"), this);
|
||||||
|
cmd = am->registerAction(m_openTypeHierarchyAction, Constants::OPEN_TYPE_HIERARCHY, context);
|
||||||
|
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+T")));
|
||||||
|
connect(m_openTypeHierarchyAction, SIGNAL(triggered()), this, SLOT(openTypeHierarchy()));
|
||||||
|
contextMenu->addAction(cmd);
|
||||||
|
cppToolsMenu->addAction(cmd);
|
||||||
|
|
||||||
// Update context in global context
|
// Update context in global context
|
||||||
Core::Context globalContext(Core::Constants::C_GLOBAL);
|
Core::Context globalContext(Core::Constants::C_GLOBAL);
|
||||||
cppToolsMenu->addAction(createSeparator(am, this, globalContext, CppEditor::Constants::SEPARATOR2));
|
cppToolsMenu->addAction(createSeparator(am, this, globalContext, CppEditor::Constants::SEPARATOR2));
|
||||||
@@ -391,6 +401,7 @@ void CppPlugin::onTaskStarted(const QString &type)
|
|||||||
m_renameSymbolUnderCursorAction->setEnabled(false);
|
m_renameSymbolUnderCursorAction->setEnabled(false);
|
||||||
m_findUsagesAction->setEnabled(false);
|
m_findUsagesAction->setEnabled(false);
|
||||||
m_updateCodeModelAction->setEnabled(false);
|
m_updateCodeModelAction->setEnabled(false);
|
||||||
|
m_openTypeHierarchyAction->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,6 +411,7 @@ void CppPlugin::onAllTasksFinished(const QString &type)
|
|||||||
m_renameSymbolUnderCursorAction->setEnabled(true);
|
m_renameSymbolUnderCursorAction->setEnabled(true);
|
||||||
m_findUsagesAction->setEnabled(true);
|
m_findUsagesAction->setEnabled(true);
|
||||||
m_updateCodeModelAction->setEnabled(true);
|
m_updateCodeModelAction->setEnabled(true);
|
||||||
|
m_openTypeHierarchyAction->setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,4 +425,15 @@ void CppPlugin::currentEditorChanged(Core::IEditor *editor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CppPlugin::openTypeHierarchy()
|
||||||
|
{
|
||||||
|
Core::EditorManager *em = Core::EditorManager::instance();
|
||||||
|
CPPEditor *editor = qobject_cast<CPPEditor*>(em->currentEditor()->widget());
|
||||||
|
if (editor) {
|
||||||
|
Core::NavigationWidget *navigation = Core::NavigationWidget::instance();
|
||||||
|
navigation->activateSubWidget(QLatin1String(Constants::TYPE_HIERARCHY_ID));
|
||||||
|
emit typeHierarchyRequested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Q_EXPORT_PLUGIN(CppPlugin)
|
Q_EXPORT_PLUGIN(CppPlugin)
|
||||||
|
@@ -71,6 +71,7 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void outlineSortingChanged(bool sort);
|
void outlineSortingChanged(bool sort);
|
||||||
|
void typeHierarchyRequested();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setSortedOutline(bool sorted);
|
void setSortedOutline(bool sorted);
|
||||||
@@ -85,6 +86,7 @@ private slots:
|
|||||||
void quickFix(TextEditor::ITextEditable *editable);
|
void quickFix(TextEditor::ITextEditable *editable);
|
||||||
void quickFixNow();
|
void quickFixNow();
|
||||||
void currentEditorChanged(Core::IEditor *editor);
|
void currentEditorChanged(Core::IEditor *editor);
|
||||||
|
void openTypeHierarchy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Core::IEditor *createEditor(QWidget *parent);
|
Core::IEditor *createEditor(QWidget *parent);
|
||||||
@@ -98,6 +100,7 @@ private:
|
|||||||
QAction *m_renameSymbolUnderCursorAction;
|
QAction *m_renameSymbolUnderCursorAction;
|
||||||
QAction *m_findUsagesAction;
|
QAction *m_findUsagesAction;
|
||||||
QAction *m_updateCodeModelAction;
|
QAction *m_updateCodeModelAction;
|
||||||
|
QAction *m_openTypeHierarchyAction;
|
||||||
|
|
||||||
CppQuickFixCollector *m_quickFixCollector;
|
CppQuickFixCollector *m_quickFixCollector;
|
||||||
|
|
||||||
|
267
src/plugins/cppeditor/cpptypehierarchy.cpp
Normal file
267
src/plugins/cppeditor/cpptypehierarchy.cpp
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "cpptypehierarchy.h"
|
||||||
|
#include "cppeditorconstants.h"
|
||||||
|
#include "cppeditor.h"
|
||||||
|
#include "cppelementevaluator.h"
|
||||||
|
#include "cppplugin.h"
|
||||||
|
|
||||||
|
#include <coreplugin/editormanager/ieditor.h>
|
||||||
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <coreplugin/coreconstants.h>
|
||||||
|
#include <utils/navigationtreeview.h>
|
||||||
|
|
||||||
|
#include <QtCore/QLatin1Char>
|
||||||
|
#include <QtCore/QLatin1String>
|
||||||
|
#include <QtCore/QModelIndex>
|
||||||
|
#include <QtCore/QSettings>
|
||||||
|
#include <QtGui/QVBoxLayout>
|
||||||
|
#include <QtGui/QStandardItemModel>
|
||||||
|
#include <QtGui/QFontMetrics>
|
||||||
|
#include <QtGui/QApplication>
|
||||||
|
#include <QtGui/QPainter>
|
||||||
|
#include <QtGui/QLabel>
|
||||||
|
|
||||||
|
using namespace CppEditor;
|
||||||
|
using namespace Internal;
|
||||||
|
|
||||||
|
// CppTypeHierarchyItem
|
||||||
|
CppTypeHierarchyItem::CppTypeHierarchyItem(const CppClass &cppClass) :
|
||||||
|
QStandardItem(), m_cppClass(cppClass)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CppTypeHierarchyItem::~CppTypeHierarchyItem()
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CppTypeHierarchyItem::type() const
|
||||||
|
{ return UserType; }
|
||||||
|
|
||||||
|
const CppClass &CppTypeHierarchyItem::cppClass() const
|
||||||
|
{ return m_cppClass; }
|
||||||
|
|
||||||
|
// CppTypeHierarchyDelegate
|
||||||
|
CppTypeHierarchyDelegate::CppTypeHierarchyDelegate(QObject *parent) : QStyledItemDelegate(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CppTypeHierarchyDelegate::~CppTypeHierarchyDelegate()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CppTypeHierarchyDelegate::paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (const QStyleOptionViewItemV3 *v3 =
|
||||||
|
qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option)) {
|
||||||
|
QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, v3, painter, v3->widget);
|
||||||
|
|
||||||
|
QStyleOptionViewItemV4 opt = option;
|
||||||
|
initStyleOption(&opt, index);
|
||||||
|
|
||||||
|
const QStandardItemModel *model = static_cast<const QStandardItemModel *>(index.model());
|
||||||
|
CppTypeHierarchyItem *item =
|
||||||
|
static_cast<CppTypeHierarchyItem *>(model->itemFromIndex(index));
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
const QIcon &icon = item->cppClass().icon();
|
||||||
|
const QSize &iconSize = icon.actualSize(opt.decorationSize);
|
||||||
|
QRect workingRect(opt.rect);
|
||||||
|
QRect decorationRect(workingRect.topLeft(), iconSize);
|
||||||
|
icon.paint(painter, decorationRect, opt.decorationAlignment);
|
||||||
|
workingRect.setX(workingRect.x() + iconSize.width() + 4);
|
||||||
|
|
||||||
|
QRect boundingRect;
|
||||||
|
const QString &name = item->cppClass().name() + QLatin1Char(' ');
|
||||||
|
painter->drawText(workingRect, Qt::AlignLeft, name, &boundingRect);
|
||||||
|
if (item->cppClass().name() != item->cppClass().qualifiedName()) {
|
||||||
|
QFont font(painter->font());
|
||||||
|
if (font.pointSize() > 2)
|
||||||
|
font.setPointSize(font.pointSize() - 2);
|
||||||
|
else if (font.pointSize() > 1)
|
||||||
|
font.setPointSize(font.pointSize() - 1);
|
||||||
|
font.setItalic(true);
|
||||||
|
painter->setFont(font);
|
||||||
|
|
||||||
|
QFontMetrics metrics(font);
|
||||||
|
workingRect.setX(boundingRect.x() + boundingRect.width());
|
||||||
|
workingRect.setY(boundingRect.y() + boundingRect.height() - metrics.height());
|
||||||
|
painter->drawText(workingRect, Qt::AlignLeft, item->cppClass().qualifiedName());
|
||||||
|
}
|
||||||
|
painter->restore();
|
||||||
|
} else {
|
||||||
|
QStyledItemDelegate::paint(painter, option, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize CppTypeHierarchyDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QSize size = QStyledItemDelegate::sizeHint(option, index);
|
||||||
|
size.rwidth() += 5; // Extend a bit because of the font processing.
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CppTypeHierarchyWidget
|
||||||
|
CppTypeHierarchyWidget::CppTypeHierarchyWidget(Core::IEditor *editor) :
|
||||||
|
QWidget(0),
|
||||||
|
m_cppEditor(0),
|
||||||
|
m_treeView(0),
|
||||||
|
m_model(0),
|
||||||
|
m_delegate(0)
|
||||||
|
{
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
layout->setMargin(0);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
|
||||||
|
if (CPPEditorEditable *cppEditable = qobject_cast<CPPEditorEditable *>(editor)) {
|
||||||
|
m_cppEditor = static_cast<CPPEditor *>(cppEditable->widget());
|
||||||
|
|
||||||
|
m_model = new QStandardItemModel;
|
||||||
|
m_treeView = new Utils::NavigationTreeView;
|
||||||
|
m_delegate = new CppTypeHierarchyDelegate;
|
||||||
|
m_treeView->setModel(m_model);
|
||||||
|
m_treeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
m_treeView->setItemDelegate(m_delegate);
|
||||||
|
layout->addWidget(m_treeView);
|
||||||
|
|
||||||
|
connect(m_treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(onItemClicked(QModelIndex)));
|
||||||
|
connect(CppPlugin::instance(), SIGNAL(typeHierarchyRequested()), this, SLOT(perform()));
|
||||||
|
} else {
|
||||||
|
QLabel *label = new QLabel(tr("No type hierarchy available"), this);
|
||||||
|
label->setAlignment(Qt::AlignCenter);
|
||||||
|
label->setAutoFillBackground(true);
|
||||||
|
label->setBackgroundRole(QPalette::Base);
|
||||||
|
layout->addWidget(label);
|
||||||
|
}
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
CppTypeHierarchyWidget::~CppTypeHierarchyWidget()
|
||||||
|
{
|
||||||
|
delete m_model;
|
||||||
|
delete m_delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppTypeHierarchyWidget::perform()
|
||||||
|
{
|
||||||
|
if (!m_cppEditor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_model->clear();
|
||||||
|
|
||||||
|
CppElementEvaluator evaluator(m_cppEditor);
|
||||||
|
evaluator.setLookupBaseClasses(true);
|
||||||
|
QSharedPointer<CppElement> cppElement = evaluator.identifyCppElement();
|
||||||
|
if (!cppElement.isNull()) {
|
||||||
|
CppElement *element = cppElement.data();
|
||||||
|
if (CppClass *cppClass = dynamic_cast<CppClass *>(element))
|
||||||
|
buildModel(*cppClass, m_model->invisibleRootItem());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppTypeHierarchyWidget::buildModel(const CppClass &cppClass, QStandardItem *parent)
|
||||||
|
{
|
||||||
|
CppTypeHierarchyItem *item = new CppTypeHierarchyItem(cppClass);
|
||||||
|
parent->appendRow(item);
|
||||||
|
|
||||||
|
// The delegate retrieves data from the item directly. This is to help size hint.
|
||||||
|
const QString &display = cppClass.name() + cppClass.qualifiedName();
|
||||||
|
m_model->setData(m_model->indexFromItem(item), display, Qt::DisplayRole);
|
||||||
|
m_model->setData(m_model->indexFromItem(item), cppClass.icon(), Qt::DecorationRole);
|
||||||
|
|
||||||
|
foreach (const CppClass &cppBase, cppClass.bases())
|
||||||
|
buildModel(cppBase, item);
|
||||||
|
|
||||||
|
m_treeView->expand(m_model->indexFromItem(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppTypeHierarchyWidget::onItemClicked(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
if (QStandardItem *item = m_model->itemFromIndex(index)) {
|
||||||
|
CppTypeHierarchyItem *cppItem = static_cast<CppTypeHierarchyItem *>(item);
|
||||||
|
m_cppEditor->openLink(cppItem->cppClass().link());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CppTypeHierarchyStackedWidget
|
||||||
|
CppTypeHierarchyStackedWidget::CppTypeHierarchyStackedWidget(QWidget *parent) :
|
||||||
|
QStackedWidget(parent),
|
||||||
|
m_typeHiearchyWidgetInstance(
|
||||||
|
new CppTypeHierarchyWidget(Core::EditorManager::instance()->currentEditor()))
|
||||||
|
{
|
||||||
|
addWidget(m_typeHiearchyWidgetInstance);
|
||||||
|
|
||||||
|
connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)),
|
||||||
|
this, SLOT(editorChanged(Core::IEditor*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CppTypeHierarchyStackedWidget::~CppTypeHierarchyStackedWidget()
|
||||||
|
{
|
||||||
|
delete m_typeHiearchyWidgetInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppTypeHierarchyStackedWidget::editorChanged(Core::IEditor *editor)
|
||||||
|
{
|
||||||
|
CppTypeHierarchyWidget *replacement = new CppTypeHierarchyWidget(editor);
|
||||||
|
removeWidget(m_typeHiearchyWidgetInstance);
|
||||||
|
m_typeHiearchyWidgetInstance->deleteLater();
|
||||||
|
m_typeHiearchyWidgetInstance = replacement;
|
||||||
|
addWidget(m_typeHiearchyWidgetInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CppTypeHierarchyFactory
|
||||||
|
CppTypeHierarchyFactory::CppTypeHierarchyFactory()
|
||||||
|
{}
|
||||||
|
|
||||||
|
CppTypeHierarchyFactory::~CppTypeHierarchyFactory()
|
||||||
|
{}
|
||||||
|
|
||||||
|
QString CppTypeHierarchyFactory::displayName() const
|
||||||
|
{
|
||||||
|
return tr("Type Hierarchy");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CppTypeHierarchyFactory::id() const
|
||||||
|
{
|
||||||
|
return QLatin1String(Constants::TYPE_HIERARCHY_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
QKeySequence CppTypeHierarchyFactory::activationSequence() const
|
||||||
|
{
|
||||||
|
return QKeySequence();
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::NavigationView CppTypeHierarchyFactory::createWidget()
|
||||||
|
{
|
||||||
|
CppTypeHierarchyStackedWidget *w = new CppTypeHierarchyStackedWidget;
|
||||||
|
static_cast<CppTypeHierarchyWidget *>(w->currentWidget())->perform();
|
||||||
|
Core::NavigationView navigationView;
|
||||||
|
navigationView.widget = w;
|
||||||
|
return navigationView;
|
||||||
|
}
|
142
src/plugins/cppeditor/cpptypehierarchy.h
Normal file
142
src/plugins/cppeditor/cpptypehierarchy.h
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CPPTYPEHIERARCHY_H
|
||||||
|
#define CPPTYPEHIERARCHY_H
|
||||||
|
|
||||||
|
#include "cppelementevaluator.h"
|
||||||
|
|
||||||
|
#include <coreplugin/inavigationwidgetfactory.h>
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtGui/QWidget>
|
||||||
|
#include <QtGui/QStackedWidget>
|
||||||
|
#include <QtGui/QStandardItem>
|
||||||
|
#include <QtGui/QStyledItemDelegate>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QStandardItemModel;
|
||||||
|
class QModelIndex;
|
||||||
|
class QPainter;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class IEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Utils {
|
||||||
|
class NavigationTreeView;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CppEditor {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class CPPEditor;
|
||||||
|
|
||||||
|
class CppTypeHierarchyItem : public QStandardItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppTypeHierarchyItem(const CppClass &cppClass);
|
||||||
|
virtual ~CppTypeHierarchyItem();
|
||||||
|
|
||||||
|
virtual int type() const;
|
||||||
|
|
||||||
|
const CppClass &cppClass() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CppClass m_cppClass;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppTypeHierarchyDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CppTypeHierarchyDelegate(QObject *parent = 0);
|
||||||
|
virtual ~CppTypeHierarchyDelegate();
|
||||||
|
|
||||||
|
virtual void paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const;
|
||||||
|
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppTypeHierarchyWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CppTypeHierarchyWidget(Core::IEditor *editor);
|
||||||
|
virtual ~CppTypeHierarchyWidget();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void perform();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onItemClicked(const QModelIndex &index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void buildModel(const CppClass &cppClass, QStandardItem *item);
|
||||||
|
|
||||||
|
CPPEditor *m_cppEditor;
|
||||||
|
Utils::NavigationTreeView *m_treeView;
|
||||||
|
QStandardItemModel *m_model;
|
||||||
|
CppTypeHierarchyDelegate *m_delegate;
|
||||||
|
};
|
||||||
|
|
||||||
|
// @todo: Pretty much the same design as the OutlineWidgetStack. Maybe we can generalize the
|
||||||
|
// outline factory so that it works for different widgets that support the same editor.
|
||||||
|
class CppTypeHierarchyStackedWidget : public QStackedWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CppTypeHierarchyStackedWidget(QWidget *parent = 0);
|
||||||
|
virtual ~CppTypeHierarchyStackedWidget();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void editorChanged(Core::IEditor* editor);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CppTypeHierarchyWidget *m_typeHiearchyWidgetInstance;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CppTypeHierarchyFactory : public Core::INavigationWidgetFactory
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CppTypeHierarchyFactory();
|
||||||
|
virtual ~CppTypeHierarchyFactory();
|
||||||
|
|
||||||
|
virtual QString displayName() const;
|
||||||
|
virtual QString id() const;
|
||||||
|
virtual QKeySequence activationSequence() const;
|
||||||
|
virtual Core::NavigationView createWidget();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace CppEditor
|
||||||
|
|
||||||
|
#endif // CPPTYPEHIERARCHY_H
|
@@ -95,6 +95,10 @@ void BaseHoverHandler::showToolTip(TextEditor::ITextEditor *editor, const QPoint
|
|||||||
|
|
||||||
void BaseHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos)
|
void BaseHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos)
|
||||||
{
|
{
|
||||||
|
BaseTextEditor *baseEditor = baseTextEditor(editor);
|
||||||
|
if (!baseEditor)
|
||||||
|
return;
|
||||||
|
|
||||||
// If the tooltip is visible and there is a help match, this match is used to update
|
// If the tooltip is visible and there is a help match, this match is used to update
|
||||||
// the help id. Otherwise, let the identification process happen.
|
// the help id. Otherwise, let the identification process happen.
|
||||||
if (!ToolTip::instance()->isVisible() || m_matchingHelpCandidate == -1)
|
if (!ToolTip::instance()->isVisible() || m_matchingHelpCandidate == -1)
|
||||||
|
@@ -57,19 +57,6 @@ class TEXTEDITOR_EXPORT BaseHoverHandler : public QObject
|
|||||||
public:
|
public:
|
||||||
BaseHoverHandler(QObject *parent = 0);
|
BaseHoverHandler(QObject *parent = 0);
|
||||||
|
|
||||||
private slots:
|
|
||||||
void editorOpened(Core::IEditor *editor);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void showToolTip(TextEditor::ITextEditor *editor, const QPoint &point, int pos);
|
|
||||||
void updateContextHelpId(TextEditor::ITextEditor *editor, int pos);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void setToolTip(const QString &tooltip);
|
|
||||||
const QString &toolTip() const;
|
|
||||||
void appendToolTip(const QString &extension);
|
|
||||||
void addF1ToToolTip();
|
|
||||||
|
|
||||||
struct HelpCandidate
|
struct HelpCandidate
|
||||||
{
|
{
|
||||||
enum Category {
|
enum Category {
|
||||||
@@ -94,6 +81,19 @@ protected:
|
|||||||
Category m_category;
|
Category m_category;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void editorOpened(Core::IEditor *editor);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void showToolTip(TextEditor::ITextEditor *editor, const QPoint &point, int pos);
|
||||||
|
void updateContextHelpId(TextEditor::ITextEditor *editor, int pos);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setToolTip(const QString &tooltip);
|
||||||
|
const QString &toolTip() const;
|
||||||
|
void appendToolTip(const QString &extension);
|
||||||
|
void addF1ToToolTip();
|
||||||
|
|
||||||
void addHelpCandidate(const HelpCandidate &helpCandidate);
|
void addHelpCandidate(const HelpCandidate &helpCandidate);
|
||||||
void setHelpCandidate(const HelpCandidate &helpCandidate, int index);
|
void setHelpCandidate(const HelpCandidate &helpCandidate, int index);
|
||||||
const QList<HelpCandidate> &helpCandidates() const;
|
const QList<HelpCandidate> &helpCandidates() const;
|
||||||
|
@@ -463,6 +463,7 @@ protected:
|
|||||||
static void countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close,
|
static void countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close,
|
||||||
int *errors, int *stillopen);
|
int *errors, int *stillopen);
|
||||||
|
|
||||||
|
public:
|
||||||
struct Link
|
struct Link
|
||||||
{
|
{
|
||||||
Link(const QString &fileName = QString(),
|
Link(const QString &fileName = QString(),
|
||||||
@@ -489,6 +490,7 @@ protected:
|
|||||||
int column; // Target column
|
int column; // Target column
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
/*!
|
/*!
|
||||||
Reimplement this function to enable code navigation.
|
Reimplement this function to enable code navigation.
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user