diff --git a/src/plugins/cpptools/cppoverviewmodel.cpp b/src/plugins/cpptools/cppoverviewmodel.cpp index 1cf10b4b9fd..eaa4b2a8aab 100644 --- a/src/plugins/cpptools/cppoverviewmodel.cpp +++ b/src/plugins/cpptools/cppoverviewmodel.cpp @@ -37,6 +37,99 @@ using namespace CPlusPlus; namespace CppTools { +QVariant SymbolItem::data(int /*column*/, int role) const +{ + if (!symbol && parent()) { // account for no symbol item + switch (role) { + case Qt::DisplayRole: + if (parent()->childCount() > 1) + return QString(QT_TRANSLATE_NOOP("CppTools::OverviewModel", ""); - else - return tr(""); - default: - return QVariant(); - } //switch - } - - switch (role) { - case Qt::DisplayRole: { - Symbol *symbol = static_cast(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(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(index.internalPointer()); - QString name = _overview.prettyName(symbol->name()); - if (name.isEmpty()) - name = QLatin1String("anonymous"); - return name; - } - - case Qt::DecorationRole: { - Symbol *symbol = static_cast(index.internalPointer()); - return Icons::iconForSymbol(symbol); - } - - case FileNameRole: { - Symbol *symbol = static_cast(index.internalPointer()); - return QString::fromUtf8(symbol->fileName(), static_cast(symbol->fileNameLength())); - } - - case LineNumberRole: { - Symbol *symbol = static_cast(index.internalPointer()); - return symbol->line(); - } - - default: - return QVariant(); - } // switch -} - Symbol *OverviewModel::symbolFromIndex(const QModelIndex &index) const { - return static_cast(index.internalPointer()); + if (!index.isValid()) + return nullptr; + SymbolItem *item = static_cast(itemForIndex(index)); + return item ? item->symbol : nullptr; } void OverviewModel::rebuild(Document::Ptr doc) { beginResetModel(); _cppDocument = doc; + auto root = new SymbolItem; + buildTree(root, true); + setRootItem(root); endResetModel(); } @@ -265,4 +190,36 @@ Utils::LineColumn OverviewModel::lineColumnFromIndex(const QModelIndex &sourceIn return lineColumn; } +void OverviewModel::buildTree(SymbolItem *root, bool isRoot) +{ + if (!root) + return; + + if (isRoot) { + unsigned rows = globalSymbolCount(); + for (unsigned row = 0; row < rows; ++row) { + Symbol *symbol = globalSymbolAt(row); + auto currentItem = new SymbolItem(symbol); + buildTree(currentItem, false); + root->appendChild(currentItem); + } + root->prependChild(new SymbolItem); // account for no symbol item + } else { + Symbol *symbol = root->symbol; + if (Scope *scope = symbol->asScope()) { + Scope::iterator it = scope->memberBegin(); + Scope::iterator end = scope->memberEnd(); + for ( ; it != end; ++it) { + if (!((*it)->name())) + continue; + if ((*it)->asArgument()) + continue; + auto currentItem = new SymbolItem(*it); + buildTree(currentItem, false); + root->appendChild(currentItem); + } + } + } +} + } // namespace CppTools diff --git a/src/plugins/cpptools/cppoverviewmodel.h b/src/plugins/cpptools/cppoverviewmodel.h index 42832552a56..cae53470227 100644 --- a/src/plugins/cpptools/cppoverviewmodel.h +++ b/src/plugins/cpptools/cppoverviewmodel.h @@ -32,18 +32,22 @@ namespace CppTools { +struct SymbolItem : public Utils::TreeItem +{ + SymbolItem() = default; + SymbolItem(CPlusPlus::Symbol *symbol) : symbol(symbol) {} + + QVariant data(int column, int role) const override; + + CPlusPlus::Symbol *symbol = nullptr; // not owned +}; + + class CPPTOOLS_EXPORT OverviewModel : public AbstractOverviewModel { Q_OBJECT public: - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &child) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - void rebuild(CPlusPlus::Document::Ptr doc) override; bool isGenerated(const QModelIndex &sourceIndex) const override; @@ -55,10 +59,12 @@ private: bool hasDocument() const; unsigned globalSymbolCount() const; CPlusPlus::Symbol *globalSymbolAt(unsigned index) const; + void buildTree(SymbolItem *root, bool isRoot); private: CPlusPlus::Document::Ptr _cppDocument; CPlusPlus::Overview _overview; + friend class SymbolItem; }; } // namespace CppTools