summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools/cppoverviewmodel.cpp
diff options
context:
space:
mode:
authorChristian Stenger <christian.stenger@qt.io>2018-02-27 12:25:05 +0100
committerChristian Stenger <christian.stenger@qt.io>2018-03-02 09:05:21 +0000
commit33f2c240490b02ecae00a296022cdb8061a69a3d (patch)
tree98ad1a4762940d163b0ee93dfed11421d04fef65 /src/plugins/cpptools/cppoverviewmodel.cpp
parent4523e579436c484d8ce5bd643729477f4214d9f7 (diff)
downloadqt-creator-33f2c240490b02ecae00a296022cdb8061a69a3d.tar.gz
CppTools: Fix builtin overview model
5e872c0fcd2 changed the base class to TreeModel which needs to have TreeItem inserted to fully work as intended. This patch makes the overview model work without running into countless soft asserts when using the builtin code model. Change-Id: I875529bef03ea2cd9a226b05410fd05e247eded1 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Nikita Baryshnikov <nib952051@gmail.com>
Diffstat (limited to 'src/plugins/cpptools/cppoverviewmodel.cpp')
-rw-r--r--src/plugins/cpptools/cppoverviewmodel.cpp223
1 files changed, 90 insertions, 133 deletions
diff --git a/src/plugins/cpptools/cppoverviewmodel.cpp b/src/plugins/cpptools/cppoverviewmodel.cpp
index 1cf10b4b9f..eaa4b2a8aa 100644
--- a/src/plugins/cpptools/cppoverviewmodel.cpp
+++ b/src/plugins/cpptools/cppoverviewmodel.cpp
@@ -37,121 +37,26 @@
using namespace CPlusPlus;
namespace CppTools {
-bool OverviewModel::hasDocument() 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
+QVariant SymbolItem::data(int /*column*/, int role) 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) {
+ if (!symbol && parent()) { // account for no symbol item
switch (role) {
case Qt::DisplayRole:
- if (rowCount() > 1)
- return tr("<Select Symbol>");
- else
- return tr("<No Symbols>");
+ if (parent()->childCount() > 1)
+ return QString(QT_TRANSLATE_NOOP("CppTools::OverviewModel", "<Select Symbol>"));
+ return QString(QT_TRANSLATE_NOOP("CppTools::OverviewModel", "<No Symbols>"));
default:
return QVariant();
- } //switch
+ }
}
+ OverviewModel *overviewModel = qobject_cast<OverviewModel *>(model());
+ if (!overviewModel)
+ return QVariant();
+
switch (role) {
case Qt::DisplayRole: {
- Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
- QString name = _overview.prettyName(symbol->name());
+ QString name = overviewModel->_overview.prettyName(symbol->name());
if (name.isEmpty())
name = QLatin1String("anonymous");
if (symbol->isObjCForwardClassDeclaration())
@@ -166,32 +71,36 @@ QVariant OverviewModel::data(const QModelIndex &index, int role) const
name = QLatin1String("@implementation ") + name;
if (clazz->isCategory()) {
- name += QLatin1String(" (") + _overview.prettyName(clazz->categoryName())
- + QLatin1Char(')');
+ name += QString(" (%1)").arg(overviewModel->_overview.prettyName(
+ clazz->categoryName()));
}
}
if (symbol->isObjCPropertyDeclaration())
name = QLatin1String("@property ") + name;
- if (Template *t = symbol->asTemplate())
+ // if symbol is a template we might change it now - so, use a copy instead as we're const
+ Symbol *symbl = symbol;
+ if (Template *t = symbl->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;
+ for (unsigned i = 0; i < t->templateParameterCount(); ++i) {
+ parameters.append(overviewModel->_overview.prettyName(
+ t->templateParameterAt(i)->name()));
+ }
+ name += QString("<%1>").arg(parameters.join(QLatin1String(", ")));
+ symbl = templateDeclaration;
}
- if (symbol->isObjCMethod()) {
- ObjCMethod *method = symbol->asObjCMethod();
+ if (symbl->isObjCMethod()) {
+ ObjCMethod *method = symbl->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()) {
+ } else if (! symbl->isScope() || symbl->isFunction()) {
+ QString type = overviewModel->_overview.prettyType(symbl->type());
+ if (Function *f = symbl->type()->asFunctionType()) {
name += type;
- type = _overview.prettyType(f->returnType());
+ type = overviewModel->_overview.prettyType(f->returnType());
}
if (! type.isEmpty())
name += QLatin1String(": ") + type;
@@ -200,42 +109,58 @@ QVariant OverviewModel::data(const QModelIndex &index, int role) const
}
case Qt::EditRole: {
- Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
- QString name = _overview.prettyName(symbol->name());
+ QString name = overviewModel->_overview.prettyName(symbol->name());
if (name.isEmpty())
name = QLatin1String("anonymous");
return name;
}
- case Qt::DecorationRole: {
- Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
+ case Qt::DecorationRole:
return Icons::iconForSymbol(symbol);
- }
- case FileNameRole: {
- Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
- return QString::fromUtf8(symbol->fileName(), static_cast<int>(symbol->fileNameLength()));
- }
+ case AbstractOverviewModel::FileNameRole:
+ return QString::fromUtf8(symbol->fileName(), static_cast<int>(symbol->fileNameLength()));
- case LineNumberRole: {
- Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
- return symbol->line();
- }
+ case AbstractOverviewModel::LineNumberRole:
+ return symbol->line();
default:
return QVariant();
} // switch
}
+
+bool OverviewModel::hasDocument() 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); }
+
Symbol *OverviewModel::symbolFromIndex(const QModelIndex &index) const
{
- return static_cast<Symbol *>(index.internalPointer());
+ if (!index.isValid())
+ return nullptr;
+ SymbolItem *item = static_cast<SymbolItem *>(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