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)
|
||||
{
|
||||
if (!symbol)
|
||||
return Link();
|
||||
|
||||
const QString fileName = QString::fromUtf8(symbol->fileName(),
|
||||
symbol->fileNameLength());
|
||||
unsigned line = symbol->line();
|
||||
|
@@ -180,6 +180,10 @@ public:
|
||||
void setObjCEnabled(bool onoff);
|
||||
bool isObjCEnabled() const;
|
||||
|
||||
bool openLink(const Link &link) { return openCppEditorAt(link); }
|
||||
|
||||
static Link linkToSymbol(CPlusPlus::Symbol *symbol);
|
||||
|
||||
Q_SIGNALS:
|
||||
void outlineModelIndexChanged(const QModelIndex &index);
|
||||
|
||||
@@ -267,13 +271,10 @@ private:
|
||||
void abortRename();
|
||||
|
||||
Link findLinkAt(const QTextCursor &, bool resolveTarget = true);
|
||||
bool openLink(const Link &link) { return openCppEditorAt(link); }
|
||||
bool openCppEditorAt(const Link &);
|
||||
|
||||
QModelIndex indexForPosition(int line, int column, const QModelIndex &rootIndex = QModelIndex()) const;
|
||||
|
||||
static Link linkToSymbol(CPlusPlus::Symbol *symbol);
|
||||
|
||||
CppTools::CppModelManagerInterface *m_modelManager;
|
||||
|
||||
QComboBox *m_outlineCombo;
|
||||
|
@@ -20,8 +20,9 @@ HEADERS += cppplugin.h \
|
||||
cppsemanticinfo.h \
|
||||
cppoutline.h \
|
||||
cppdeclfromdef.h \
|
||||
cpplocalsymbols.h
|
||||
|
||||
cpplocalsymbols.h \
|
||||
cpptypehierarchy.h \
|
||||
cppelementevaluator.h
|
||||
SOURCES += cppplugin.cpp \
|
||||
cppeditor.cpp \
|
||||
cpphighlighter.cpp \
|
||||
@@ -35,8 +36,9 @@ SOURCES += cppplugin.cpp \
|
||||
cppsemanticinfo.cpp \
|
||||
cppoutline.cpp \
|
||||
cppdeclfromdef.cpp \
|
||||
cpplocalsymbols.cpp
|
||||
|
||||
cpplocalsymbols.cpp \
|
||||
cpptypehierarchy.cpp \
|
||||
cppelementevaluator.cpp
|
||||
RESOURCES += cppeditor.qrc
|
||||
|
||||
OTHER_FILES += CppEditor.pluginspec CppEditor.mimetypes.xml
|
||||
OTHER_FILES += CppEditor.pluginspec \
|
||||
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 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 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 "cppeditor.h"
|
||||
#include "cppelementevaluator.h"
|
||||
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
@@ -37,29 +38,9 @@
|
||||
#include <texteditor/itexteditor.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 <algorithm>
|
||||
|
||||
using namespace CppEditor::Internal;
|
||||
using namespace CPlusPlus;
|
||||
using namespace Core;
|
||||
|
||||
namespace {
|
||||
@@ -70,73 +51,13 @@ namespace {
|
||||
else
|
||||
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)
|
||||
{
|
||||
m_modelManager =
|
||||
ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
|
||||
}
|
||||
CppHoverHandler::CppHoverHandler(QObject *parent) : BaseHoverHandler(parent)
|
||||
{}
|
||||
|
||||
CppHoverHandler::~CppHoverHandler()
|
||||
{}
|
||||
|
||||
bool CppHoverHandler::acceptEditor(IEditor *editor)
|
||||
{
|
||||
@@ -148,191 +69,25 @@ bool CppHoverHandler::acceptEditor(IEditor *editor)
|
||||
|
||||
void CppHoverHandler::identifyMatch(TextEditor::ITextEditor *editor, int pos)
|
||||
{
|
||||
if (!m_modelManager)
|
||||
CPPEditor *cppEditor = qobject_cast<CPPEditor *>(editor->widget());
|
||||
if (!cppEditor)
|
||||
return;
|
||||
|
||||
const Snapshot &snapshot = m_modelManager->snapshot();
|
||||
Document::Ptr doc = snapshot.document(editor->file()->fileName());
|
||||
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());
|
||||
if (!cppEditor->extraSelectionTooltip(pos).isEmpty()) {
|
||||
setToolTip(cppEditor->extraSelectionTooltip(pos));
|
||||
} else {
|
||||
QTextCursor tc(cppEditor->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 {
|
||||
QString name;
|
||||
if (matchingDeclaration->scope()->isClass() ||
|
||||
matchingDeclaration->scope()->isNamespace() ||
|
||||
matchingDeclaration->scope()->isEnum()) {
|
||||
name.append(overview.prettyName(
|
||||
LookupContext::fullyQualifiedName(matchingDeclaration)));
|
||||
|
||||
if (matchingDeclaration->isClass() ||
|
||||
matchingDeclaration->isForwardClassDeclaration()) {
|
||||
buildClassHierarchy(matchingDeclaration, context, overview, &m_classHierarchy);
|
||||
}
|
||||
} else {
|
||||
name.append(overview.prettyName(matchingDeclaration->name()));
|
||||
}
|
||||
|
||||
if (assignTooltip) {
|
||||
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));
|
||||
CppElementEvaluator evaluator(cppEditor);
|
||||
evaluator.setTextCursor(tc);
|
||||
QSharedPointer<CppElement> cppElement = evaluator.identifyCppElement();
|
||||
if (!cppElement.isNull()) {
|
||||
setToolTip(cppElement->tooltip());
|
||||
foreach (const QString &helpId, cppElement->helpIdCandidates())
|
||||
addHelpCandidate(HelpCandidate(helpId,
|
||||
cppElement->helpMark(),
|
||||
cppElement->helpCategory()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -357,121 +112,8 @@ void CppHoverHandler::evaluateHelpCandidates()
|
||||
|
||||
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) {
|
||||
appendToolTip(getDocContents(extendTooltips));
|
||||
} 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);
|
||||
const QString &contents = getDocContents(extendToolTips(editor));
|
||||
if (!contents.isEmpty()) {
|
||||
HelpCandidate::Category cat = helpCandidate(matchingHelpCandidate()).m_category;
|
||||
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
|
||||
#define CPPHOVERHANDLER_H
|
||||
|
||||
#include <cplusplus/CppDocument.h>
|
||||
#include <texteditor/basehoverhandler.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
namespace CPlusPlus {
|
||||
class LookupItem;
|
||||
class LookupContext;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
class IEditor;
|
||||
}
|
||||
|
||||
namespace CppTools {
|
||||
class CppModelManagerInterface;
|
||||
}
|
||||
|
||||
namespace TextEditor {
|
||||
class ITextEditor;
|
||||
}
|
||||
@@ -62,26 +50,13 @@ class CppHoverHandler : public TextEditor::BaseHoverHandler
|
||||
Q_OBJECT
|
||||
public:
|
||||
CppHoverHandler(QObject *parent = 0);
|
||||
virtual ~CppHoverHandler();
|
||||
|
||||
private:
|
||||
virtual bool acceptEditor(Core::IEditor *editor);
|
||||
virtual void identifyMatch(TextEditor::ITextEditor *editor, int pos);
|
||||
virtual void resetExtras();
|
||||
virtual void evaluateHelpCandidates();
|
||||
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
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "cpphoverhandler.h"
|
||||
#include "cppquickfix.h"
|
||||
#include "cppoutline.h"
|
||||
#include "cpptypehierarchy.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
@@ -46,6 +47,7 @@
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/progressmanager/progressmanager.h>
|
||||
#include <coreplugin/navigationwidget.h>
|
||||
#include <texteditor/completionsupport.h>
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/storagesettings.h>
|
||||
@@ -60,6 +62,7 @@
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <QtGui/QMenu>
|
||||
|
||||
@@ -139,8 +142,8 @@ CppPlugin::CppPlugin() :
|
||||
m_sortedOutline(false),
|
||||
m_renameSymbolUnderCursorAction(0),
|
||||
m_findUsagesAction(0),
|
||||
m_updateCodeModelAction(0)
|
||||
|
||||
m_updateCodeModelAction(0),
|
||||
m_openTypeHierarchyAction(0)
|
||||
{
|
||||
m_instance = this;
|
||||
|
||||
@@ -205,7 +208,7 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess
|
||||
addAutoReleasedObject(new CppEditorFactory(this));
|
||||
addAutoReleasedObject(new CppHoverHandler);
|
||||
addAutoReleasedObject(new CppOutlineWidgetFactory);
|
||||
|
||||
addAutoReleasedObject(new CppTypeHierarchyFactory);
|
||||
|
||||
m_quickFixCollector = new CppQuickFixCollector;
|
||||
addAutoReleasedObject(m_quickFixCollector);
|
||||
@@ -274,6 +277,13 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess
|
||||
contextMenu->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
|
||||
Core::Context globalContext(Core::Constants::C_GLOBAL);
|
||||
cppToolsMenu->addAction(createSeparator(am, this, globalContext, CppEditor::Constants::SEPARATOR2));
|
||||
@@ -391,6 +401,7 @@ void CppPlugin::onTaskStarted(const QString &type)
|
||||
m_renameSymbolUnderCursorAction->setEnabled(false);
|
||||
m_findUsagesAction->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_findUsagesAction->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)
|
||||
|
@@ -71,6 +71,7 @@ public:
|
||||
|
||||
signals:
|
||||
void outlineSortingChanged(bool sort);
|
||||
void typeHierarchyRequested();
|
||||
|
||||
public slots:
|
||||
void setSortedOutline(bool sorted);
|
||||
@@ -85,6 +86,7 @@ private slots:
|
||||
void quickFix(TextEditor::ITextEditable *editable);
|
||||
void quickFixNow();
|
||||
void currentEditorChanged(Core::IEditor *editor);
|
||||
void openTypeHierarchy();
|
||||
|
||||
private:
|
||||
Core::IEditor *createEditor(QWidget *parent);
|
||||
@@ -98,6 +100,7 @@ private:
|
||||
QAction *m_renameSymbolUnderCursorAction;
|
||||
QAction *m_findUsagesAction;
|
||||
QAction *m_updateCodeModelAction;
|
||||
QAction *m_openTypeHierarchyAction;
|
||||
|
||||
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)
|
||||
{
|
||||
BaseTextEditor *baseEditor = baseTextEditor(editor);
|
||||
if (!baseEditor)
|
||||
return;
|
||||
|
||||
// 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.
|
||||
if (!ToolTip::instance()->isVisible() || m_matchingHelpCandidate == -1)
|
||||
|
@@ -57,19 +57,6 @@ class TEXTEDITOR_EXPORT BaseHoverHandler : public QObject
|
||||
public:
|
||||
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
|
||||
{
|
||||
enum Category {
|
||||
@@ -94,6 +81,19 @@ protected:
|
||||
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 setHelpCandidate(const HelpCandidate &helpCandidate, int index);
|
||||
const QList<HelpCandidate> &helpCandidates() const;
|
||||
|
@@ -463,6 +463,7 @@ protected:
|
||||
static void countBrackets(QTextCursor cursor, int from, int end, QChar open, QChar close,
|
||||
int *errors, int *stillopen);
|
||||
|
||||
public:
|
||||
struct Link
|
||||
{
|
||||
Link(const QString &fileName = QString(),
|
||||
@@ -489,6 +490,7 @@ protected:
|
||||
int column; // Target column
|
||||
};
|
||||
|
||||
protected:
|
||||
/*!
|
||||
Reimplement this function to enable code navigation.
|
||||
|
||||
|
Reference in New Issue
Block a user