OverviewModel.cpp 6.76 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 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
26
** contact the sales department at http://www.qtsoftware.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
82

        ScopedSymbol *scopedSymbol = parentSymbol->asScopedSymbol();
83
        Q_ASSERT(scopedSymbol);
con's avatar
con committed
84
85

        Scope *scope = scopedSymbol->members();
86
        Q_ASSERT(scope);
con's avatar
con committed
87
88
89
90
91
92
93
94

        return createIndex(row, 0, scope->symbolAt(row));
    }
}

QModelIndex OverviewModel::parent(const QModelIndex &child) const
{
    Symbol *symbol = static_cast<Symbol *>(child.internalPointer());
95
96
    if (!symbol) // account for no symbol item
        return QModelIndex();
con's avatar
con committed
97
98
99

    if (Scope *scope = symbol->scope()) {
        Symbol *parentSymbol = scope->owner();
100
101
102
103
104
105
106
107
108
        if (parentSymbol && parentSymbol->scope()) {
            QModelIndex index;
            if (parentSymbol->scope() && parentSymbol->scope()->owner()
                    && parentSymbol->scope()->owner()->scope()) // the parent doesn't have a parent
                index = createIndex(parentSymbol->index(), 0, parentSymbol);
            else //+1 to account for no symbol item
                index = createIndex(parentSymbol->index() + 1, 0, parentSymbol);
            return index;
        }
con's avatar
con committed
109
110
111
112
113
114
115
116
    }

    return QModelIndex();
}

int OverviewModel::rowCount(const QModelIndex &parent) const
{
    if (hasDocument()) {
117
118
        if (!parent.isValid()) {
            return globalSymbolCount()+1; // account for no symbol item
con's avatar
con committed
119
        } else {
120
121
            if (!parent.parent().isValid() && parent.row() == 0) // account for no symbol item
                return 0;
con's avatar
con committed
122
            Symbol *parentSymbol = static_cast<Symbol *>(parent.internalPointer());
123
            Q_ASSERT(parentSymbol);
con's avatar
con committed
124
125

            if (ScopedSymbol *scopedSymbol = parentSymbol->asScopedSymbol()) {
126
                if (!scopedSymbol->isFunction()) {
con's avatar
con committed
127
                    Scope *parentScope = scopedSymbol->members();
128
                    Q_ASSERT(parentScope);
con's avatar
con committed
129
130
131
132

                    return parentScope->symbolCount();
                }
            }
133
            return 0;
con's avatar
con committed
134
135
        }
    }
136
137
    if (!parent.isValid())
        return 1; // account for no symbol item
con's avatar
con committed
138
139
140
141
    return 0;
}

int OverviewModel::columnCount(const QModelIndex &) const
hjk's avatar
hjk committed
142
143
144
{
    return 1;
}
con's avatar
con committed
145
146
147

QVariant OverviewModel::data(const QModelIndex &index, int role) const
{
148
149
150
151
152
153
154
155
156
157
158
159
160
    // 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
161
162
163
164
165
166
    switch (role) {
    case Qt::DisplayRole: {
        Symbol *symbol = static_cast<Symbol *>(index.internalPointer());
        QString name = _overview.prettyName(symbol->name());
        if (name.isEmpty())
            name = QLatin1String("anonymous");
167
168
169
170
171
172
        if (symbol->isObjCForwardClassDeclaration())
            name = QLatin1String("@class ") + name;
        if (symbol->isObjCForwardProtocolDeclaration() || symbol->isObjCProtocol())
            name = QLatin1String("@protocol ") + name;
        if (symbol->isObjCClass())
            name = QLatin1String("@interface ") + name;
con's avatar
con committed
173
174
175
        if (! symbol->isScopedSymbol() || symbol->isFunction()) {
            QString type = _overview.prettyType(symbol->type());
            if (! type.isEmpty()) {
176
                if (! symbol->type()->isFunctionType())
con's avatar
con committed
177
178
179
180
181
182
183
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
                    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
213
214
215
{
    return static_cast<Symbol *>(index.internalPointer());
}
con's avatar
con committed
216
217
218
219
220
221

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