OSDN Git Service

66117d2fdaa035bcab20acead1b6a080379dd434
[qt-creator-jp/qt-creator-jp.git] / src / plugins / cppeditor / cpptypehierarchy.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "cpptypehierarchy.h"
35 #include "cppeditorconstants.h"
36 #include "cppeditor.h"
37 #include "cppelementevaluator.h"
38 #include "cppplugin.h"
39
40 #include <coreplugin/editormanager/ieditor.h>
41 #include <coreplugin/editormanager/editormanager.h>
42 #include <utils/navigationtreeview.h>
43 #include <utils/annotateditemdelegate.h>
44
45 #include <QtCore/QLatin1Char>
46 #include <QtCore/QLatin1String>
47 #include <QtCore/QModelIndex>
48 #include <QtGui/QVBoxLayout>
49 #include <QtGui/QStandardItemModel>
50 #include <QtGui/QLabel>
51
52 using namespace CppEditor;
53 using namespace Internal;
54 using namespace Utils;
55
56 // CppTypeHierarchyWidget
57 CppTypeHierarchyWidget::CppTypeHierarchyWidget(Core::IEditor *editor) :
58     QWidget(0),
59     m_cppEditor(0),
60     m_treeView(0),
61     m_model(0),
62     m_delegate(0)
63 {
64     QVBoxLayout *layout = new QVBoxLayout;
65     layout->setMargin(0);
66     layout->setSpacing(0);
67
68     if (CPPEditor *cppEditor = qobject_cast<CPPEditor *>(editor)) {
69         m_cppEditor = static_cast<CPPEditorWidget *>(cppEditor->widget());
70
71         m_model = new QStandardItemModel;
72         m_treeView = new Utils::NavigationTreeView;
73         m_delegate = new AnnotatedItemDelegate;
74         m_delegate->setDelimiter(QLatin1String(" "));
75         m_delegate->setAnnotationRole(AnnotationRole);
76         m_treeView->setModel(m_model);
77         m_treeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
78         m_treeView->setItemDelegate(m_delegate);
79         layout->addWidget(m_treeView);
80
81         connect(m_treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(onItemClicked(QModelIndex)));
82         connect(CppPlugin::instance(), SIGNAL(typeHierarchyRequested()), this, SLOT(perform()));
83     } else {
84         QLabel *label = new QLabel(tr("No type hierarchy available"), this);
85         label->setAlignment(Qt::AlignCenter);
86         label->setAutoFillBackground(true);
87         label->setBackgroundRole(QPalette::Base);
88         layout->addWidget(label);
89     }
90     setLayout(layout);
91 }
92
93 CppTypeHierarchyWidget::~CppTypeHierarchyWidget()
94 {
95     delete m_model;
96     delete m_delegate;
97 }
98
99 bool CppTypeHierarchyWidget::handleEditorChange(Core::IEditor *editor)
100 {
101     if (CPPEditor *cppEditor = qobject_cast<CPPEditor *>(editor)) {
102         if (m_cppEditor) {
103             m_cppEditor = static_cast<CPPEditorWidget *>(cppEditor->widget());
104             return true;
105         }
106     } else if (!m_cppEditor) {
107         return true;
108     }
109     return false;
110 }
111
112 void CppTypeHierarchyWidget::perform()
113 {
114     if (!m_cppEditor)
115         return;
116
117     m_model->clear();
118
119     CppElementEvaluator evaluator(m_cppEditor);
120     evaluator.setLookupBaseClasses(true);
121     evaluator.execute();
122     if (evaluator.identifiedCppElement()) {
123         const QSharedPointer<CppElement> &cppElement = evaluator.cppElement();
124         CppElement *element = cppElement.data();
125         if (CppClass *cppClass = dynamic_cast<CppClass *>(element))
126             buildModel(*cppClass, m_model->invisibleRootItem());
127     }
128 }
129
130 void CppTypeHierarchyWidget::buildModel(const CppClass &cppClass, QStandardItem *parent)
131 {
132     QStandardItem *item = new QStandardItem;
133     parent->appendRow(item);
134
135     m_model->setData(m_model->indexFromItem(item), cppClass.name(), Qt::DisplayRole);
136     if (cppClass.name() != cppClass.qualifiedName())
137         m_model->setData(m_model->indexFromItem(item), cppClass.qualifiedName(), AnnotationRole);
138     m_model->setData(m_model->indexFromItem(item), cppClass.icon(), Qt::DecorationRole);
139     QVariant link;
140     link.setValue(CPPEditorWidget::Link(cppClass.link()));
141     m_model->setData(m_model->indexFromItem(item), link, LinkRole);
142
143     foreach (const CppClass &cppBase, cppClass.bases())
144         buildModel(cppBase, item);
145
146     m_treeView->expand(m_model->indexFromItem(item));
147 }
148
149 void CppTypeHierarchyWidget::onItemClicked(const QModelIndex &index)
150 {
151     m_cppEditor->openLink(index.data(LinkRole).value<TextEditor::BaseTextEditorWidget::Link>());
152 }
153
154 // CppTypeHierarchyStackedWidget
155 CppTypeHierarchyStackedWidget::CppTypeHierarchyStackedWidget(QWidget *parent) :
156     QStackedWidget(parent),
157     m_typeHiearchyWidgetInstance(
158         new CppTypeHierarchyWidget(Core::EditorManager::instance()->currentEditor()))
159 {
160     addWidget(m_typeHiearchyWidgetInstance);
161
162     connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)),
163             this, SLOT(editorChanged(Core::IEditor*)));
164 }
165
166 CppTypeHierarchyStackedWidget::~CppTypeHierarchyStackedWidget()
167 {
168     delete m_typeHiearchyWidgetInstance;
169 }
170
171 void CppTypeHierarchyStackedWidget::editorChanged(Core::IEditor *editor)
172 {
173     if (!m_typeHiearchyWidgetInstance->handleEditorChange(editor)) {
174         CppTypeHierarchyWidget *replacement = new CppTypeHierarchyWidget(editor);
175         removeWidget(m_typeHiearchyWidgetInstance);
176         m_typeHiearchyWidgetInstance->deleteLater();
177         m_typeHiearchyWidgetInstance = replacement;
178         addWidget(m_typeHiearchyWidgetInstance);
179     }
180 }
181
182 // CppTypeHierarchyFactory
183 CppTypeHierarchyFactory::CppTypeHierarchyFactory()
184 {}
185
186 CppTypeHierarchyFactory::~CppTypeHierarchyFactory()
187 {}
188
189 QString CppTypeHierarchyFactory::displayName() const
190 {
191     return tr("Type Hierarchy");
192 }
193
194 int CppTypeHierarchyFactory::priority() const
195 {
196     return Constants::TYPE_HIERARCHY_PRIORITY;
197 }
198
199 QString CppTypeHierarchyFactory::id() const
200 {
201     return QLatin1String(Constants::TYPE_HIERARCHY_ID);
202 }
203
204 QKeySequence CppTypeHierarchyFactory::activationSequence() const
205 {
206     return QKeySequence();
207 }
208
209 Core::NavigationView CppTypeHierarchyFactory::createWidget()
210 {
211     CppTypeHierarchyStackedWidget *w = new CppTypeHierarchyStackedWidget;
212     static_cast<CppTypeHierarchyWidget *>(w->currentWidget())->perform();
213     Core::NavigationView navigationView;
214     navigationView.widget = w;
215     return navigationView;
216 }