OverviewModel.cpp 7.07 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2 3 4
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11 12 13 14
** 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.
15
**
16
** GNU Lesser General Public License Usage
17
**
18 19 20 21 22 23
** 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.
24
**
25
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
con's avatar
con committed
29 30 31

#include "OverviewModel.h"
#include "Overview.h"
hjk's avatar
hjk committed
32

con's avatar
con committed
33 34 35 36
#include <Scope.h>
#include <Semantic.h>
#include <Literals.h>
#include <Symbols.h>
hjk's avatar
hjk committed
37

con's avatar
con committed
38 39 40 41 42 43 44 45 46 47 48 49 50
#include <QFile>
#include <QtDebug>

using namespace CPlusPlus;

OverviewModel::OverviewModel(QObject *parent)
    : QAbstractItemModel(parent)
{ }

OverviewModel::~OverviewModel()
{ }

bool OverviewModel::hasDocument() const
hjk's avatar
hjk committed
51 52 53
{
    return _cppDocument;
}
con's avatar
con committed
54 55

Document::Ptr OverviewModel::document() const
hjk's avatar
hjk committed
56 57 58
{
    return _cppDocument;
}
con's avatar
con committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72

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
{
73 74 75 76
    if (!parent.isValid()) {
        if (row == 0) // account for no symbol item
            return createIndex(row, column);
        Symbol *symbol = globalSymbolAt(row-1); // account for no symbol item
con's avatar
con committed
77 78 79
        return createIndex(row, column, symbol);
    } else {
        Symbol *parentSymbol = static_cast<Symbol *>(parent.internalPointer());
80
        Q_ASSERT(parentSymbol);
con's avatar
con committed
81

Roberto Raggi's avatar
Roberto Raggi committed
82 83 84
        Scope *scope = parentSymbol->asScope();
        Q_ASSERT(scope != 0);
        return createIndex(row, 0, scope->memberAt(row));
con's avatar
con committed
85 86 87 88 89 90
    }
}

QModelIndex OverviewModel::parent(const QModelIndex &child) const
{
    Symbol *symbol = static_cast<Symbol *>(child.internalPointer());
91 92
    if (!symbol) // account for no symbol item
        return QModelIndex();
con's avatar
con committed
93 94

    if (Scope *scope = symbol->scope()) {
Roberto Raggi's avatar
Roberto Raggi committed
95
        if (scope->scope()) {
96
            QModelIndex index;
Roberto Raggi's avatar
Roberto Raggi committed
97 98
            if (scope->scope() && scope->scope()->scope()) // the parent doesn't have a parent
                index = createIndex(scope->index(), 0, scope);
99
            else //+1 to account for no symbol item
Roberto Raggi's avatar
Roberto Raggi committed
100
                index = createIndex(scope->index() + 1, 0, scope);
101 102
            return index;
        }
con's avatar
con committed
103 104 105 106 107 108 109 110
    }

    return QModelIndex();
}

int OverviewModel::rowCount(const QModelIndex &parent) const
{
    if (hasDocument()) {
111 112
        if (!parent.isValid()) {
            return globalSymbolCount()+1; // account for no symbol item
con's avatar
con committed
113
        } else {
114 115
            if (!parent.parent().isValid() && parent.row() == 0) // account for no symbol item
                return 0;
con's avatar
con committed
116
            Symbol *parentSymbol = static_cast<Symbol *>(parent.internalPointer());
117
            Q_ASSERT(parentSymbol);
con's avatar
con committed
118

Roberto Raggi's avatar
Roberto Raggi committed
119 120 121
            if (Scope *parentScope = parentSymbol->asScope()) {
                if (!parentScope->isFunction() && !parentScope->isObjCMethod()) {
                    return parentScope->memberCount();
con's avatar
con committed
122 123
                }
            }
124
            return 0;
con's avatar
con committed
125 126
        }
    }
127 128
    if (!parent.isValid())
        return 1; // account for no symbol item
con's avatar
con committed
129 130 131 132
    return 0;
}

int OverviewModel::columnCount(const QModelIndex &) const
hjk's avatar
hjk committed
133 134 135
{
    return 1;
}
con's avatar
con committed
136 137 138

QVariant OverviewModel::data(const QModelIndex &index, int role) const
{
139 140 141 142 143 144 145 146 147 148 149 150 151
    // 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
    }

con's avatar
con committed
152 153 154 155 156 157
    switch (role) {
    case Qt::DisplayRole: {
        Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
        QString name = _overview.prettyName(symbol->name());
        if (name.isEmpty())
            name = QLatin1String("anonymous");
158 159 160 161
        if (symbol->isObjCForwardClassDeclaration())
            name = QLatin1String("@class ") + name;
        if (symbol->isObjCForwardProtocolDeclaration() || symbol->isObjCProtocol())
            name = QLatin1String("@protocol ") + name;
162 163 164 165 166 167 168 169 170 171
        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(')');
        }
172 173
        if (symbol->isObjCPropertyDeclaration())
            name = QLatin1String("@property ") + name;
174 175 176 177 178 179
        if (symbol->isObjCMethod()) {
            ObjCMethod *method = symbol->asObjCMethod();
            if (method->isStatic())
                name = QLatin1Char('+') + name;
            else
                name = QLatin1Char('-') + name;
180
        } else if (! symbol->isScope() || symbol->isFunction()) {
con's avatar
con committed
181 182
            QString type = _overview.prettyType(symbol->type());
            if (! type.isEmpty()) {
183
                if (! symbol->type()->isFunctionType())
con's avatar
con committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
                    name += QLatin1String(": ");
                name += 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);
    } break;

    case FileNameRole: {
        Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
        return QString::fromUtf8(symbol->fileName(), 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
hjk's avatar
hjk committed
220 221 222
{
    return static_cast<Symbol *>(index.internalPointer());
}
con's avatar
con committed
223 224 225 226 227 228

void OverviewModel::rebuild(Document::Ptr doc)
{
    _cppDocument = doc;
    reset();
}