summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools/cppoverviewmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/cpptools/cppoverviewmodel.cpp')
-rw-r--r--src/plugins/cpptools/cppoverviewmodel.cpp253
1 files changed, 253 insertions, 0 deletions
diff --git a/src/plugins/cpptools/cppoverviewmodel.cpp b/src/plugins/cpptools/cppoverviewmodel.cpp
new file mode 100644
index 0000000000..7fe118f68c
--- /dev/null
+++ b/src/plugins/cpptools/cppoverviewmodel.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "cppoverviewmodel.h"
+
+#include <cplusplus/Icons.h>
+#include <cplusplus/Literals.h>
+#include <cplusplus/Overview.h>
+#include <cplusplus/Scope.h>
+#include <cplusplus/Symbols.h>
+
+#include <utils/dropsupport.h>
+
+using namespace CPlusPlus;
+namespace CppTools {
+
+OverviewModel::OverviewModel(QObject *parent)
+ : AbstractOverviewModel(parent)
+{ }
+
+OverviewModel::~OverviewModel()
+{ }
+
+bool OverviewModel::hasDocument() const
+{
+ return _cppDocument;
+}
+
+Document::Ptr OverviewModel::document() const
+{
+ return _cppDocument;
+}
+
+unsigned OverviewModel::globalSymbolCount() const
+{
+ unsigned count = 0;
+ if (_cppDocument)
+ count += _cppDocument->globalSymbolCount();
+ return count;
+}
+
+Symbol *OverviewModel::globalSymbolAt(unsigned index) const
+{ return _cppDocument->globalSymbolAt(index); }
+
+QModelIndex OverviewModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if (!parent.isValid()) {
+ if (row == 0) // account for no symbol item
+ return createIndex(row, column);
+ Symbol *symbol = globalSymbolAt(static_cast<unsigned>(row-1)); // account for no symbol item
+ return createIndex(row, column, symbol);
+ } else {
+ Symbol *parentSymbol = static_cast<Symbol *>(
+ parent.internalPointer());
+ Q_ASSERT(parentSymbol);
+
+ if (Template *t = parentSymbol->asTemplate())
+ if (Symbol *templateParentSymbol = t->declaration())
+ parentSymbol = templateParentSymbol;
+
+ Scope *scope = parentSymbol->asScope();
+ Q_ASSERT(scope != nullptr);
+ return createIndex(row, 0, scope->memberAt(static_cast<unsigned>(row)));
+ }
+}
+
+QModelIndex OverviewModel::parent(const QModelIndex &child) const
+{
+ Symbol *symbol = static_cast<Symbol *>(child.internalPointer());
+ if (!symbol) // account for no symbol item
+ return QModelIndex();
+
+ if (Scope *scope = symbol->enclosingScope()) {
+ if (scope->isTemplate() && scope->enclosingScope())
+ scope = scope->enclosingScope();
+ if (scope->enclosingScope()) {
+ QModelIndex index;
+ if (scope->enclosingScope() && scope->enclosingScope()->enclosingScope()) // the parent doesn't have a parent
+ index = createIndex(static_cast<int>(scope->index()), 0, scope);
+ else //+1 to account for no symbol item
+ index = createIndex(static_cast<int>(scope->index() + 1), 0, scope);
+ return index;
+ }
+ }
+
+ return QModelIndex();
+}
+
+int OverviewModel::rowCount(const QModelIndex &parent) const
+{
+ if (hasDocument()) {
+ if (!parent.isValid()) {
+ return static_cast<int>(globalSymbolCount() + 1); // account for no symbol item
+ } else {
+ if (!parent.parent().isValid() && parent.row() == 0) // account for no symbol item
+ return 0;
+ Symbol *parentSymbol = static_cast<Symbol *>(
+ parent.internalPointer());
+ Q_ASSERT(parentSymbol);
+
+ if (Template *t = parentSymbol->asTemplate())
+ if (Symbol *templateParentSymbol = t->declaration())
+ parentSymbol = templateParentSymbol;
+
+ if (Scope *parentScope = parentSymbol->asScope()) {
+ if (!parentScope->isFunction() && !parentScope->isObjCMethod())
+ return static_cast<int>(parentScope->memberCount());
+ }
+ return 0;
+ }
+ }
+ if (!parent.isValid())
+ return 1; // account for no symbol item
+ return 0;
+}
+
+int OverviewModel::columnCount(const QModelIndex &) const
+{
+ return 1;
+}
+
+QVariant OverviewModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ // account for no symbol item
+ if (!index.parent().isValid() && index.row() == 0) {
+ switch (role) {
+ case Qt::DisplayRole:
+ if (rowCount() > 1)
+ return tr("<Select Symbol>");
+ else
+ return tr("<No Symbols>");
+ default:
+ return QVariant();
+ } //switch
+ }
+
+ switch (role) {
+ case Qt::DisplayRole: {
+ Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
+ QString name = _overview.prettyName(symbol->name());
+ if (name.isEmpty())
+ name = QLatin1String("anonymous");
+ if (symbol->isObjCForwardClassDeclaration())
+ name = QLatin1String("@class ") + name;
+ if (symbol->isObjCForwardProtocolDeclaration() || symbol->isObjCProtocol())
+ name = QLatin1String("@protocol ") + name;
+ if (symbol->isObjCClass()) {
+ ObjCClass *clazz = symbol->asObjCClass();
+ if (clazz->isInterface())
+ name = QLatin1String("@interface ") + name;
+ else
+ name = QLatin1String("@implementation ") + name;
+
+ if (clazz->isCategory()) {
+ name += QLatin1String(" (") + _overview.prettyName(clazz->categoryName())
+ + QLatin1Char(')');
+ }
+ }
+ if (symbol->isObjCPropertyDeclaration())
+ name = QLatin1String("@property ") + name;
+ if (Template *t = symbol->asTemplate())
+ if (Symbol *templateDeclaration = t->declaration()) {
+ QStringList parameters;
+ parameters.reserve(static_cast<int>(t->templateParameterCount()));
+ for (unsigned i = 0; i < t->templateParameterCount(); ++i)
+ parameters.append(_overview.prettyName(t->templateParameterAt(i)->name()));
+ name += QLatin1Char('<') + parameters.join(QLatin1String(", ")) + QLatin1Char('>');
+ symbol = templateDeclaration;
+ }
+ if (symbol->isObjCMethod()) {
+ ObjCMethod *method = symbol->asObjCMethod();
+ if (method->isStatic())
+ name = QLatin1Char('+') + name;
+ else
+ name = QLatin1Char('-') + name;
+ } else if (! symbol->isScope() || symbol->isFunction()) {
+ QString type = _overview.prettyType(symbol->type());
+ if (Function *f = symbol->type()->asFunctionType()) {
+ name += type;
+ type = _overview.prettyType(f->returnType());
+ }
+ if (! type.isEmpty())
+ name += QLatin1String(": ") + type;
+ }
+ return name;
+ }
+
+ case Qt::EditRole: {
+ Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
+ QString name = _overview.prettyName(symbol->name());
+ if (name.isEmpty())
+ name = QLatin1String("anonymous");
+ return name;
+ }
+
+ case Qt::DecorationRole: {
+ Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
+ return Icons::iconForSymbol(symbol);
+ }
+
+ case FileNameRole: {
+ Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
+ return QString::fromUtf8(symbol->fileName(), static_cast<int>(symbol->fileNameLength()));
+ }
+
+ case LineNumberRole: {
+ Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
+ return symbol->line();
+ }
+
+ default:
+ return QVariant();
+ } // switch
+}
+
+Symbol *OverviewModel::symbolFromIndex(const QModelIndex &index) const
+{
+ return static_cast<Symbol *>(index.internalPointer());
+}
+
+void OverviewModel::rebuild(Document::Ptr doc)
+{
+ beginResetModel();
+ _cppDocument = doc;
+ endResetModel();
+}
+
+} // namespace CppTools