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>
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.
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.
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.
20
#include "KexiProjectModel.h"
21
#include "KexiProjectModelItem.h"
23
#include <kexipartinfo.h>
24
#include <kexipartitem.h>
25
#include <kexiproject.h>
26
#include <kexipartmanager.h>
32
class KexiProjectModel::Private {
37
//!Part class to display
38
QString itemsPartClass;
39
KexiProjectModelItem *rootItem;
40
QPersistentModelIndex searchHighlight;
41
QPointer<KexiProject> project;
45
KexiProjectModel::Private::Private() : rootItem(0), objectsCount(0)
50
KexiProjectModel::Private::~Private()
56
KexiProjectModel::KexiProjectModel(QObject* parent): QAbstractItemModel(parent) , d(new Private())
59
d->rootItem = new KexiProjectModelItem(QString());
62
KexiProject* KexiProjectModel::project() const
67
void KexiProjectModel::setProject(KexiProject* prj, const QString& itemsPartClass, QString* partManagerErrorMessages)
70
//qDebug() << itemsPartClass << ".";
72
d->itemsPartClass = itemsPartClass;
74
d->rootItem = new KexiProjectModelItem(prj ? prj->data()->databaseName() : QString());
76
KexiPart::PartInfoList* plist = Kexi::partManager().infoList();
80
foreach(KexiPart::Info *info, *plist) {
81
if (!info->isVisibleInNavigator())
84
if (!d->itemsPartClass.isEmpty() && info->pluginId() != d->itemsPartClass)
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);
96
d->rootItem->appendChild(groupItem);
100
groupItem = d->rootItem;
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;
110
foreach(KexiPart::Item *item, *item_dict) {
111
addItem(info, item, groupItem);
114
groupItem->sortChildren();
115
if (!d->itemsPartClass.isEmpty()) {
116
break; //the only group added, so our work is completed
119
if (partManagerErrorMessages && !partManagerErrorMessages->isEmpty())
120
partManagerErrorMessages->append("</ul></p>");
125
KexiProjectModel::~KexiProjectModel()
130
QVariant KexiProjectModel::data(const QModelIndex& index, int role) const
132
KexiProjectModelItem *item = static_cast<KexiProjectModelItem*>(index.internalPointer());
136
case Qt::DisplayRole:
137
case Qt::WhatsThisRole:
138
return item->data(index.column());
139
case Qt::DecorationRole:
147
int KexiProjectModel::columnCount(const QModelIndex& parent) const
149
if (parent.isValid())
150
return static_cast<KexiProjectModelItem*>(parent.internalPointer())->columnCount();
152
return d->rootItem->columnCount();
155
int KexiProjectModel::rowCount(const QModelIndex& parent) const
157
KexiProjectModelItem *parentItem;
158
if (parent.column() > 0)
161
if (!parent.isValid())
162
parentItem = d->rootItem;
164
parentItem = static_cast<KexiProjectModelItem*>(parent.internalPointer());
167
return parentItem->childCount();
172
QModelIndex KexiProjectModel::parent(const QModelIndex& index) const
174
if (!index.isValid())
175
return QModelIndex();
177
KexiProjectModelItem *childItem = static_cast<KexiProjectModelItem*>(index.internalPointer());
178
KexiProjectModelItem *parentItem = childItem->parent();
181
return QModelIndex();
183
if (parentItem == d->rootItem)
184
return QModelIndex();
186
return createIndex(parentItem->row(), 0, parentItem);
189
QModelIndex KexiProjectModel::index(int row, int column, const QModelIndex& parent) const
191
if (!hasIndex(row, column, parent)) {
192
return QModelIndex();
195
KexiProjectModelItem *parentItem;
197
if (!parent.isValid()) {
198
parentItem = d->rootItem;
200
parentItem = static_cast<KexiProjectModelItem*>(parent.internalPointer());
203
KexiProjectModelItem *childItem = parentItem->child(row);
205
return createIndex(row, column, childItem);
207
return QModelIndex();
211
bool KexiProjectModel::hasChildren(const QModelIndex& parent) const
213
return QAbstractItemModel::hasChildren(parent);
216
bool KexiProjectModel::renameItem(KexiPart::Item *item, const QString& newName)
218
if (item->name() == newName) { //make sure the new name is different
221
KexiProjectModelItem *i = modelItemFromItem(*item);
225
QModelIndex origIndex = indexFromItem(i);
227
emit renameItem(item, newName, &ok);
229
emit layoutAboutToBeChanged();
230
i->parent()->sortChildren();
231
changePersistentIndex(origIndex, indexFromItem(i));
232
emit layoutChanged();
237
bool KexiProjectModel::setItemCaption(KexiPart::Item *item, const QString& newCaption)
239
if (item->caption() == newCaption) { //make sure the new caption is different
243
emit changeItemCaption(item, newCaption, &ok);
247
Qt::ItemFlags KexiProjectModel::flags(const QModelIndex& index) const
249
if (!index.isValid())
250
return QAbstractItemModel::flags(index);
252
KexiProjectModelItem *item = static_cast<KexiProjectModelItem*>(index.internalPointer());
254
return item->flags();
256
return QAbstractItemModel::flags(index);
259
void KexiProjectModel::clear()
267
QString KexiProjectModel::itemsPartClass() const
269
return d->itemsPartClass;
272
KexiProjectModelItem *KexiProjectModel::addGroup(KexiPart::Info *info,
273
KexiProjectModelItem *parent) const
275
if (!info->isVisibleInNavigator())
278
KexiProjectModelItem *item = new KexiProjectModelItem(info, parent);
282
void KexiProjectModel::slotAddItem(KexiPart::Item *item)
284
//qDebug() << item.name();
287
KexiProjectModelItem *parent = modelItemFromName(item->pluginId());
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();
298
//qDebug() << "Unable to find parent item!";
302
KexiProjectModelItem* KexiProjectModel::addItem(KexiPart::Info *info, KexiPart::Item *item,
303
KexiProjectModelItem *parent) const
306
KexiProjectModelItem *i = new KexiProjectModelItem(info, item, parent);
307
parent->appendChild(i);
311
void KexiProjectModel::slotRemoveItem(const KexiPart::Item& item)
314
KexiProjectModelItem *mitm = modelItemFromItem(item);
315
KexiProjectModelItem *parent =0;
318
//qDebug() << "Got model item from item";
319
parent = mitm->parent();
321
//qDebug() << "Unable to get model item from item";
325
idx = indexFromItem(parent);
326
beginRemoveRows(idx, 0,0);
327
parent->removeChild(item);
331
//qDebug() << "Unable to find parent item!";
335
QModelIndex KexiProjectModel::indexFromItem(KexiProjectModelItem* item) const
339
int row = item->parent() ? item->row() : 0;
341
return createIndex(row, 0, (void*)item);
343
return QModelIndex();
346
KexiProjectModelItem* KexiProjectModel::modelItemFromItem(const KexiPart::Item& item) const
348
return d->rootItem->modelItemFromItem(item);
351
KexiProjectModelItem* KexiProjectModel::modelItemFromName(const QString& name) const
354
return d->rootItem->modelItemFromName(name);
357
void KexiProjectModel::updateItemName(KexiPart::Item& item, bool dirty)
360
KexiProjectModelItem *bitem = modelItemFromItem(item);
364
QModelIndex idx = indexFromItem(bitem);
365
bitem->setDirty(dirty);
366
emit dataChanged(idx, idx);
369
QModelIndex KexiProjectModel::firstChildPartItem(const QModelIndex &parentIndex) const
371
int count = rowCount(parentIndex);
372
//qDebug() << "parent:" << data(parentIndex) << parentIndex.isValid() << count;
373
KexiProjectModelItem *it = static_cast<KexiProjectModelItem*>(parentIndex.internalPointer());
375
if (it->partItem()) {
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()) {
387
return QModelIndex();
390
QModelIndex KexiProjectModel::firstPartItem() const
392
return firstChildPartItem(indexFromItem(d->rootItem));
395
// Implemented for KexiSearchableModel:
397
int KexiProjectModel::searchableObjectCount() const
399
const QModelIndex rootIndex = indexFromItem(d->rootItem);
400
const int topLevelCount = rowCount(rootIndex);
402
for (int i = 0; i < topLevelCount; i++) {
403
QModelIndex index = this->index(i, 0, rootIndex);
404
result += rowCount(index);
409
QModelIndex KexiProjectModel::sourceIndexForSearchableObject(int objectIndex) const
411
const QModelIndex rootIndex = indexFromItem(d->rootItem);
412
const int topLevelCount = rowCount(rootIndex);
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);
422
return QModelIndex();
425
QVariant KexiProjectModel::searchableData(const QModelIndex &sourceIndex, int role) const
427
return data(sourceIndex, role);
430
QString KexiProjectModel::pathFromIndex(const QModelIndex &sourceIndex) const
432
KexiProjectModelItem *it = static_cast<KexiProjectModelItem*>(sourceIndex.internalPointer());
433
return it->partItem()->name();
436
QPersistentModelIndex KexiProjectModel::itemWithSearchHighlight() const
438
return d->searchHighlight;
441
bool KexiProjectModel::highlightSearchableObject(const QModelIndex &index)
443
if (d->searchHighlight.isValid() && index != d->searchHighlight) {
444
setData(d->searchHighlight, false, SearchHighlight);
446
setData(index, true, SearchHighlight);
447
emit highlightSearchedItem(index);
448
d->searchHighlight = QPersistentModelIndex(index);
452
bool KexiProjectModel::activateSearchableObject(const QModelIndex &index)
454
if (d->searchHighlight.isValid() && index != d->searchHighlight) {
455
setData(d->searchHighlight, false, SearchHighlight);
457
emit activateSearchedItem(index);
461
int KexiProjectModel::objectsCount() const
463
return d->objectsCount;