~ubuntu-branches/debian/sid/kexi/sid

« back to all changes in this revision

Viewing changes to src/widget/navigator/KexiProjectModel.cpp

  • Committer: Package Import Robot
  • Author(s): Pino Toscano
  • Date: 2017-06-24 20:10:10 UTC
  • Revision ID: package-import@ubuntu.com-20170624201010-5lrzd5r2vwthwifp
Tags: upstream-3.0.1.1
ImportĀ upstreamĀ versionĀ 3.0.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of the KDE project
 
2
   Copyright (C) 2010 Adam Pigg <adam@piggz.co.uk>
 
3
   Copyright (C) 2010-2014 Jarosław Staniek <staniek@kde.org>
 
4
 
 
5
   This library is free software; you can redistribute it and/or
 
6
   modify it under the terms of the GNU Library General Public
 
7
   License version 2 as published by the Free Software Foundation.
 
8
 
 
9
   This library is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
   Library General Public License for more details.
 
13
 
 
14
   You should have received a copy of the GNU Library General Public License
 
15
   along with this library; see the file COPYING.LIB.  If not, write to
 
16
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
17
   Boston, MA 02110-1301, USA.
 
18
*/
 
19
 
 
20
#include "KexiProjectModel.h"
 
21
#include "KexiProjectModelItem.h"
 
22
#include <kexipart.h>
 
23
#include <kexipartinfo.h>
 
24
#include <kexipartitem.h>
 
25
#include <kexiproject.h>
 
26
#include <kexipartmanager.h>
 
27
 
 
28
#include <KDbUtils>
 
29
 
 
30
#include <QDebug>
 
31
 
 
32
class KexiProjectModel::Private {
 
33
public:
 
34
    Private();
 
35
    ~Private();
 
36
 
 
37
    //!Part class to display
 
38
    QString itemsPartClass;
 
39
    KexiProjectModelItem *rootItem;
 
40
    QPersistentModelIndex searchHighlight;
 
41
    QPointer<KexiProject> project;
 
42
    int objectsCount;
 
43
};
 
44
 
 
45
KexiProjectModel::Private::Private() : rootItem(0), objectsCount(0)
 
46
{
 
47
 
 
48
}
 
49
 
 
50
KexiProjectModel::Private::~Private()
 
51
{
 
52
    delete rootItem;
 
53
}
 
54
 
 
55
 
 
56
KexiProjectModel::KexiProjectModel(QObject* parent): QAbstractItemModel(parent) , d(new Private())
 
57
{
 
58
    //qDebug();
 
59
    d->rootItem = new KexiProjectModelItem(QString());
 
60
}
 
61
 
 
62
KexiProject* KexiProjectModel::project() const
 
63
{
 
64
    return d->project;
 
65
}
 
66
 
 
67
void KexiProjectModel::setProject(KexiProject* prj, const QString& itemsPartClass, QString* partManagerErrorMessages)
 
68
{
 
69
    d->project = prj;
 
70
    //qDebug() << itemsPartClass << ".";
 
71
    clear();
 
72
    d->itemsPartClass = itemsPartClass;
 
73
 
 
74
    d->rootItem = new KexiProjectModelItem(prj ? prj->data()->databaseName() : QString());
 
75
 
 
76
    KexiPart::PartInfoList* plist = Kexi::partManager().infoList();
 
77
    if (!plist)
 
78
        return;
 
79
 
 
80
    foreach(KexiPart::Info *info, *plist) {
 
81
        if (!info->isVisibleInNavigator())
 
82
            continue;
 
83
 
 
84
        if (!d->itemsPartClass.isEmpty() && info->pluginId() != d->itemsPartClass)
 
85
            continue;
 
86
 
 
87
        //load part - we need this to have GUI merged with part's actions
 
88
//! @todo FUTURE - don't do that when DESIGN MODE is OFF
 
89
        //qDebug() << info->pluginId() << info->objectName();
 
90
        KexiProjectModelItem *groupItem = 0;
 
91
        if (d->itemsPartClass.isEmpty() /*|| m_itemsPartClass == info->pluginId()*/) {
 
92
            groupItem = addGroup(info, d->rootItem);
 
93
            if (!groupItem) {
 
94
                continue;
 
95
            } else {
 
96
                d->rootItem->appendChild(groupItem);
 
97
            }
 
98
 
 
99
        } else {
 
100
            groupItem = d->rootItem;
 
101
        }
 
102
 
 
103
        //lookup project's objects (part items)
 
104
//! @todo FUTURE - don't do that when DESIGN MODE is OFF
 
105
        KexiPart::ItemDict *item_dict = prj ? prj->items(info) : 0;
 
106
        if (!item_dict) {
 
107
            continue;
 
108
        }
 
109
 
 
110
        foreach(KexiPart::Item *item, *item_dict) {
 
111
            addItem(info, item, groupItem);
 
112
        }
 
113
 
 
114
        groupItem->sortChildren();
 
115
        if (!d->itemsPartClass.isEmpty()) {
 
116
            break; //the only group added, so our work is completed
 
117
        }
 
118
    }
 
119
    if (partManagerErrorMessages && !partManagerErrorMessages->isEmpty())
 
120
        partManagerErrorMessages->append("</ul></p>");
 
121
}
 
122
 
 
123
 
 
124
 
 
125
KexiProjectModel::~KexiProjectModel()
 
126
{
 
127
    delete d;
 
128
}
 
129
 
 
130
QVariant KexiProjectModel::data(const QModelIndex& index, int role) const
 
131
{
 
132
    KexiProjectModelItem *item = static_cast<KexiProjectModelItem*>(index.internalPointer());
 
133
    if (!item)
 
134
        return QVariant();
 
135
    switch (role) {
 
136
    case Qt::DisplayRole:
 
137
    case Qt::WhatsThisRole:
 
138
        return item->data(index.column());
 
139
    case Qt::DecorationRole:
 
140
        return item->icon();
 
141
    default:;
 
142
    }
 
143
 
 
144
    return QVariant();
 
145
}
 
146
 
 
147
int KexiProjectModel::columnCount(const QModelIndex& parent) const
 
148
{
 
149
     if (parent.isValid())
 
150
         return static_cast<KexiProjectModelItem*>(parent.internalPointer())->columnCount();
 
151
     else
 
152
         return d->rootItem->columnCount();
 
153
}
 
154
 
 
155
int KexiProjectModel::rowCount(const QModelIndex& parent) const
 
156
{
 
157
     KexiProjectModelItem *parentItem;
 
158
     if (parent.column() > 0)
 
159
         return 0;
 
160
 
 
161
     if (!parent.isValid())
 
162
         parentItem = d->rootItem;
 
163
     else
 
164
         parentItem = static_cast<KexiProjectModelItem*>(parent.internalPointer());
 
165
 
 
166
     if (parentItem)
 
167
        return parentItem->childCount();
 
168
     else
 
169
         return 0;
 
170
}
 
171
 
 
172
QModelIndex KexiProjectModel::parent(const QModelIndex& index) const
 
173
{
 
174
     if (!index.isValid())
 
175
         return QModelIndex();
 
176
 
 
177
     KexiProjectModelItem *childItem = static_cast<KexiProjectModelItem*>(index.internalPointer());
 
178
     KexiProjectModelItem *parentItem = childItem->parent();
 
179
 
 
180
     if (!parentItem)
 
181
         return QModelIndex();
 
182
 
 
183
     if (parentItem == d->rootItem)
 
184
         return QModelIndex();
 
185
 
 
186
     return createIndex(parentItem->row(), 0, parentItem);
 
187
}
 
188
 
 
189
QModelIndex KexiProjectModel::index(int row, int column, const QModelIndex& parent) const
 
190
{
 
191
    if (!hasIndex(row, column, parent)) {
 
192
        return QModelIndex();
 
193
    }
 
194
 
 
195
    KexiProjectModelItem *parentItem;
 
196
 
 
197
    if (!parent.isValid()) {
 
198
        parentItem = d->rootItem;
 
199
    } else {
 
200
        parentItem = static_cast<KexiProjectModelItem*>(parent.internalPointer());
 
201
    }
 
202
 
 
203
    KexiProjectModelItem *childItem = parentItem->child(row);
 
204
    if (childItem) {
 
205
        return createIndex(row, column, childItem);
 
206
    } else {
 
207
        return QModelIndex();
 
208
    }
 
209
}
 
210
 
 
211
bool KexiProjectModel::hasChildren(const QModelIndex& parent) const
 
212
{
 
213
    return QAbstractItemModel::hasChildren(parent);
 
214
}
 
215
 
 
216
bool KexiProjectModel::renameItem(KexiPart::Item *item, const QString& newName)
 
217
{
 
218
    if (item->name() == newName) { //make sure the new name is different
 
219
        return false;
 
220
    }
 
221
    KexiProjectModelItem *i = modelItemFromItem(*item);
 
222
    if (!i) {
 
223
        return false;
 
224
    }
 
225
    QModelIndex origIndex = indexFromItem(i);
 
226
    bool ok = true;
 
227
    emit renameItem(item, newName, &ok);
 
228
    if (ok) {
 
229
        emit layoutAboutToBeChanged();
 
230
        i->parent()->sortChildren();
 
231
        changePersistentIndex(origIndex, indexFromItem(i));
 
232
        emit layoutChanged();
 
233
    }
 
234
    return ok;
 
235
}
 
236
 
 
237
bool KexiProjectModel::setItemCaption(KexiPart::Item *item, const QString& newCaption)
 
238
{
 
239
    if (item->caption() == newCaption) { //make sure the new caption is different
 
240
        return false;
 
241
    }
 
242
    bool ok = true;
 
243
    emit changeItemCaption(item, newCaption, &ok);
 
244
    return ok;
 
245
}
 
246
 
 
247
Qt::ItemFlags KexiProjectModel::flags(const QModelIndex& index) const
 
248
{
 
249
    if (!index.isValid())
 
250
         return QAbstractItemModel::flags(index);
 
251
 
 
252
    KexiProjectModelItem *item = static_cast<KexiProjectModelItem*>(index.internalPointer());
 
253
    if (item) {
 
254
        return item->flags();
 
255
    }
 
256
    return QAbstractItemModel::flags(index);
 
257
}
 
258
 
 
259
void KexiProjectModel::clear()
 
260
{
 
261
    beginResetModel();
 
262
    delete(d->rootItem);
 
263
    d->rootItem = 0;
 
264
    endResetModel();
 
265
}
 
266
 
 
267
QString KexiProjectModel::itemsPartClass() const
 
268
{
 
269
    return d->itemsPartClass;
 
270
}
 
271
 
 
272
KexiProjectModelItem *KexiProjectModel::addGroup(KexiPart::Info *info,
 
273
                                                 KexiProjectModelItem *parent) const
 
274
{
 
275
    if (!info->isVisibleInNavigator())
 
276
        return 0;
 
277
 
 
278
    KexiProjectModelItem *item = new KexiProjectModelItem(info, parent);
 
279
    return item;
 
280
}
 
281
 
 
282
void KexiProjectModel::slotAddItem(KexiPart::Item *item)
 
283
{
 
284
    //qDebug() << item.name();
 
285
    QModelIndex idx;
 
286
 
 
287
    KexiProjectModelItem *parent = modelItemFromName(item->pluginId());
 
288
 
 
289
    if (parent) {
 
290
        //qDebug() << "Got Parent" << parent->data(0);
 
291
        idx = indexFromItem(parent);
 
292
        beginInsertRows(idx, 0,0);
 
293
        addItem(parent->partInfo(), item, parent);
 
294
        parent->sortChildren();
 
295
        endInsertRows();
 
296
    }
 
297
    else {
 
298
        //qDebug() << "Unable to find parent item!";
 
299
    }
 
300
}
 
301
 
 
302
KexiProjectModelItem* KexiProjectModel::addItem(KexiPart::Info *info, KexiPart::Item *item,
 
303
                                                KexiProjectModelItem *parent) const
 
304
{
 
305
    d->objectsCount++;
 
306
    KexiProjectModelItem *i = new KexiProjectModelItem(info, item, parent);
 
307
    parent->appendChild(i);
 
308
    return i;
 
309
}
 
310
 
 
311
void KexiProjectModel::slotRemoveItem(const KexiPart::Item& item)
 
312
{
 
313
    QModelIndex idx;
 
314
    KexiProjectModelItem *mitm = modelItemFromItem(item);
 
315
    KexiProjectModelItem *parent =0;
 
316
 
 
317
    if (mitm) {
 
318
        //qDebug() << "Got model item from item";
 
319
        parent = mitm->parent();
 
320
    } else {
 
321
        //qDebug() << "Unable to get model item from item";
 
322
    }
 
323
 
 
324
    if (parent) {
 
325
        idx = indexFromItem(parent);
 
326
        beginRemoveRows(idx, 0,0);
 
327
        parent->removeChild(item);
 
328
        d->objectsCount--;
 
329
        endRemoveRows();
 
330
    } else {
 
331
        //qDebug() << "Unable to find parent item!";
 
332
    }
 
333
}
 
334
 
 
335
QModelIndex KexiProjectModel::indexFromItem(KexiProjectModelItem* item) const
 
336
{
 
337
    //qDebug();
 
338
    if (item) {
 
339
        int row = item->parent() ? item->row() : 0;
 
340
        //qDebug() << row;
 
341
        return createIndex(row, 0, (void*)item);
 
342
    }
 
343
    return QModelIndex();
 
344
}
 
345
 
 
346
KexiProjectModelItem* KexiProjectModel::modelItemFromItem(const KexiPart::Item& item) const
 
347
{
 
348
    return d->rootItem->modelItemFromItem(item);
 
349
}
 
350
 
 
351
KexiProjectModelItem* KexiProjectModel::modelItemFromName(const QString& name) const
 
352
{
 
353
    //qDebug() << name;
 
354
    return d->rootItem->modelItemFromName(name);
 
355
}
 
356
 
 
357
void KexiProjectModel::updateItemName(KexiPart::Item& item, bool dirty)
 
358
{
 
359
    //qDebug();
 
360
    KexiProjectModelItem *bitem = modelItemFromItem(item);
 
361
    if (!bitem)
 
362
        return;
 
363
 
 
364
    QModelIndex idx = indexFromItem(bitem);
 
365
    bitem->setDirty(dirty);
 
366
    emit dataChanged(idx, idx);
 
367
}
 
368
 
 
369
QModelIndex KexiProjectModel::firstChildPartItem(const QModelIndex &parentIndex) const
 
370
{
 
371
    int count = rowCount(parentIndex);
 
372
    //qDebug() << "parent:" << data(parentIndex) << parentIndex.isValid() << count;
 
373
    KexiProjectModelItem *it = static_cast<KexiProjectModelItem*>(parentIndex.internalPointer());
 
374
    if (it) {
 
375
        if (it->partItem()) {
 
376
            return parentIndex;
 
377
        }
 
378
    }
 
379
    for (int i = 0; i < count; i++) {
 
380
        QModelIndex index = parentIndex.child(i, 0);
 
381
        //qDebug() << data(index);
 
382
        index = firstChildPartItem(index);
 
383
        if (index.isValid()) {
 
384
            return index;
 
385
        }
 
386
    }
 
387
    return QModelIndex();
 
388
}
 
389
 
 
390
QModelIndex KexiProjectModel::firstPartItem() const
 
391
{
 
392
    return firstChildPartItem(indexFromItem(d->rootItem));
 
393
}
 
394
 
 
395
// Implemented for KexiSearchableModel:
 
396
 
 
397
int KexiProjectModel::searchableObjectCount() const
 
398
{
 
399
    const QModelIndex rootIndex = indexFromItem(d->rootItem);
 
400
    const int topLevelCount = rowCount(rootIndex);
 
401
    int result = 0;
 
402
    for (int i = 0; i < topLevelCount; i++) {
 
403
        QModelIndex index = this->index(i, 0, rootIndex);
 
404
        result += rowCount(index);
 
405
    }
 
406
    return result;
 
407
}
 
408
 
 
409
QModelIndex KexiProjectModel::sourceIndexForSearchableObject(int objectIndex) const
 
410
{
 
411
    const QModelIndex rootIndex = indexFromItem(d->rootItem);
 
412
    const int topLevelCount = rowCount(rootIndex);
 
413
    int j = objectIndex;
 
414
    for (int i = 0; i < topLevelCount; i++) {
 
415
        QModelIndex index = this->index(i, 0, rootIndex);
 
416
        const int childCount = rowCount(index);
 
417
        if (j < childCount) {
 
418
            return this->index(j, 0, index);
 
419
        }
 
420
        j -= childCount;
 
421
    }
 
422
    return QModelIndex();
 
423
}
 
424
 
 
425
QVariant KexiProjectModel::searchableData(const QModelIndex &sourceIndex, int role) const
 
426
{
 
427
    return data(sourceIndex, role);
 
428
}
 
429
 
 
430
QString KexiProjectModel::pathFromIndex(const QModelIndex &sourceIndex) const
 
431
{
 
432
    KexiProjectModelItem *it = static_cast<KexiProjectModelItem*>(sourceIndex.internalPointer());
 
433
    return it->partItem()->name();
 
434
}
 
435
 
 
436
QPersistentModelIndex KexiProjectModel::itemWithSearchHighlight() const
 
437
{
 
438
    return d->searchHighlight;
 
439
}
 
440
 
 
441
bool KexiProjectModel::highlightSearchableObject(const QModelIndex &index)
 
442
{
 
443
    if (d->searchHighlight.isValid() && index != d->searchHighlight) {
 
444
        setData(d->searchHighlight, false, SearchHighlight);
 
445
    }
 
446
    setData(index, true, SearchHighlight);
 
447
    emit highlightSearchedItem(index);
 
448
    d->searchHighlight = QPersistentModelIndex(index);
 
449
    return true;
 
450
}
 
451
 
 
452
bool KexiProjectModel::activateSearchableObject(const QModelIndex &index)
 
453
{
 
454
    if (d->searchHighlight.isValid() && index != d->searchHighlight) {
 
455
        setData(d->searchHighlight, false, SearchHighlight);
 
456
    }
 
457
    emit activateSearchedItem(index);
 
458
    return true;
 
459
}
 
460
 
 
461
int KexiProjectModel::objectsCount() const
 
462
{
 
463
    return d->objectsCount;
 
464
}