cpptypehierarchy.cpp 6.78 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/**************************************************************************
**
** 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 <utils/navigationtreeview.h>
39
#include <utils/annotateditemdelegate.h>
40 41 42 43 44 45 46 47 48 49

#include <QtCore/QLatin1Char>
#include <QtCore/QLatin1String>
#include <QtCore/QModelIndex>
#include <QtGui/QVBoxLayout>
#include <QtGui/QStandardItemModel>
#include <QtGui/QLabel>

using namespace CppEditor;
using namespace Internal;
50
using namespace Utils;
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

// 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;
69 70 71
        m_delegate = new AnnotatedItemDelegate;
        m_delegate->setDelimiter(QLatin1String(" "));
        m_delegate->setAnnotationRole(AnnotationRole);
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
        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;
}

Leandro Melo's avatar
Leandro Melo committed
95
bool CppTypeHierarchyWidget::handleEditorChange(Core::IEditor *editor)
96 97 98 99 100 101 102 103 104 105 106 107
{
    if (CPPEditorEditable *cppEditable = qobject_cast<CPPEditorEditable *>(editor)) {
        if (m_cppEditor) {
            m_cppEditor = static_cast<CPPEditor *>(cppEditable->widget());
            return true;
        }
    } else if (!m_cppEditor) {
        return true;
    }
    return false;
}

108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
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)
{
127
    QStandardItem *item = new QStandardItem;
128 129
    parent->appendRow(item);

130 131 132
    m_model->setData(m_model->indexFromItem(item), cppClass.name(), Qt::DisplayRole);
    if (cppClass.name() != cppClass.qualifiedName())
        m_model->setData(m_model->indexFromItem(item), cppClass.qualifiedName(), AnnotationRole);
133
    m_model->setData(m_model->indexFromItem(item), cppClass.icon(), Qt::DecorationRole);
134 135 136
    QVariant link;
    link.setValue(CPPEditor::Link(cppClass.link()));
    m_model->setData(m_model->indexFromItem(item), link, LinkRole);
137 138 139 140 141 142 143 144 145

    foreach (const CppClass &cppBase, cppClass.bases())
        buildModel(cppBase, item);

    m_treeView->expand(m_model->indexFromItem(item));
}

void CppTypeHierarchyWidget::onItemClicked(const QModelIndex &index)
{
146
    m_cppEditor->openLink(index.data(LinkRole).value<CPPEditor::Link>());
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
}

// 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)
{
Leandro Melo's avatar
Leandro Melo committed
168
    if (!m_typeHiearchyWidgetInstance->handleEditorChange(editor)) {
169 170 171 172 173 174
        CppTypeHierarchyWidget *replacement = new CppTypeHierarchyWidget(editor);
        removeWidget(m_typeHiearchyWidgetInstance);
        m_typeHiearchyWidgetInstance->deleteLater();
        m_typeHiearchyWidgetInstance = replacement;
        addWidget(m_typeHiearchyWidgetInstance);
    }
175 176 177 178 179 180 181 182 183 184 185 186 187 188
}

// CppTypeHierarchyFactory
CppTypeHierarchyFactory::CppTypeHierarchyFactory()
{}

CppTypeHierarchyFactory::~CppTypeHierarchyFactory()
{}

QString CppTypeHierarchyFactory::displayName() const
{
    return tr("Type Hierarchy");
}

189 190 191 192 193
int CppTypeHierarchyFactory::priority() const
{
    return Constants::TYPE_HIERARCHY_PRIORITY;
}

194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
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;
}