Krita Source Code Documentation
Loading...
Searching...
No Matches
KisStorageModel Class Reference

#include <KisStorageModel.h>

+ Inheritance diagram for KisStorageModel:

Classes

struct  Private
 

Public Types

enum  Columns {
  Id = 0 , StorageType , Location , TimeStamp ,
  PreInstalled , Active , Thumbnail , DisplayName ,
  MetaData
}
 
enum  StorageImportOption { None , Overwrite , Rename }
 

Signals

void storageDisabled (const QString &storage)
 
void storageEnabled (const QString &storage)
 
void storageResynchronized (const QString &storage, bool isBulkResynchronization)
 Emitted when an individual storage is initialized.
 
void storagesBulkSynchronizationFinished ()
 Emitted on loading when all the storages are finished initialization.
 

Public Member Functions

bool canImportStorage (const QString &filename) const
 
int columnCount (const QModelIndex &parent=QModelIndex()) const override
 
QVariant data (const QModelIndex &index, int role) const override
 
Qt::ItemFlags flags (const QModelIndex &index) const override
 
QVariant headerData (int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
 
bool importStorage (const QString &filename, StorageImportOption importOption) const
 
bool importStorageData (const QString &filename, StorageImportOption importOption, const QByteArray &data) const
 
 KisStorageModel (QObject *parent=0)
 
int rowCount (const QModelIndex &parent=QModelIndex()) const override
 
bool setData (const QModelIndex &index, const QVariant &value, int role) override
 Enable and disable the storage represented by index.
 
KisResourceStorageSP storageForId (const int storageId) const
 
KisResourceStorageSP storageForIndex (const QModelIndex &index) const
 
 ~KisStorageModel () override
 

Static Public Member Functions

static KisStorageModelinstance ()
 

Private Slots

void addStorage (const QString &location)
 Called whenever a storage is added.
 
void removeStorage (const QString &location)
 This is called when a storage really is deleted both from database and anywhere else.
 
void slotStoragesBulkSynchronizationFinished ()
 called when storages finished synchronization process
 

Private Member Functions

void resetQuery ()
 

Static Private Member Functions

static QImage getThumbnailFromQuery (const QSqlQuery &query)
 
static bool importStorageInternal (const QString &filename, StorageImportOption importOption, bool dryRun, const QByteArray &data)
 

Private Attributes

QScopedPointer< Privated
 

Detailed Description

KisStorageModel provides a model of all registered storages, like the folder storages, the bundle storages or the memory storages. Note that inactive storages are also part of this model.

Definition at line 24 of file KisStorageModel.h.

Member Enumeration Documentation

◆ Columns

Enumerator
Id 
StorageType 
Location 
TimeStamp 
PreInstalled 
Active 
Thumbnail 
DisplayName 
MetaData 

Definition at line 29 of file KisStorageModel.h.

◆ StorageImportOption

Enumerator
None 
Overwrite 
Rename 

Definition at line 41 of file KisStorageModel.h.

Constructor & Destructor Documentation

◆ KisStorageModel()

KisStorageModel::KisStorageModel ( QObject * parent = 0)

Definition at line 34 of file KisStorageModel.cpp.

35 : QAbstractTableModel(parent)
36 , d(new Private())
37{
42
43 resetQuery();
44}
void storageRemoved(const QString &location)
Emitted whenever a storage is removed.
void storageAdded(const QString &location)
Emitted whenever a storage is added.
void storagesBulkSynchronizationFinished()
void storageResynchronized(const QString &storage, bool isBulkResynchronization)
static KisResourceLocator * instance()
void removeStorage(const QString &location)
This is called when a storage really is deleted both from database and anywhere else.
QScopedPointer< Private > d
void addStorage(const QString &location)
Called whenever a storage is added.
void storageResynchronized(const QString &storage, bool isBulkResynchronization)
Emitted when an individual storage is initialized.
void slotStoragesBulkSynchronizationFinished()
called when storages finished synchronization process

References addStorage(), KisResourceLocator::instance(), removeStorage(), resetQuery(), slotStoragesBulkSynchronizationFinished(), KisResourceLocator::storageAdded(), KisResourceLocator::storageRemoved(), KisResourceLocator::storageResynchronized(), storageResynchronized(), and KisResourceLocator::storagesBulkSynchronizationFinished().

◆ ~KisStorageModel()

KisStorageModel::~KisStorageModel ( )
override

Definition at line 51 of file KisStorageModel.cpp.

52{
53}

Member Function Documentation

◆ addStorage

void KisStorageModel::addStorage ( const QString & location)
privateslot

Called whenever a storage is added.

Definition at line 525 of file KisStorageModel.cpp.

526{
527 beginInsertRows(QModelIndex(), rowCount(), rowCount());
528 d->storages.append(location);
529 endInsertRows();
530}
int rowCount(const QModelIndex &parent=QModelIndex()) const override

References d, and rowCount().

◆ canImportStorage()

bool KisStorageModel::canImportStorage ( const QString & filename) const

Definition at line 433 of file KisStorageModel.cpp.

434{
435 return importStorageInternal(filename, None, true, QByteArray());
436}
static bool importStorageInternal(const QString &filename, StorageImportOption importOption, bool dryRun, const QByteArray &data)

References importStorageInternal(), and None.

◆ columnCount()

int KisStorageModel::columnCount ( const QModelIndex & parent = QModelIndex()) const
override

Definition at line 64 of file KisStorageModel.cpp.

65{
66 if (parent.isValid()) {
67 return 0;
68 }
69
70 return (int)MetaData;
71}
ChildIterator< value_type, is_const > parent(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:327

References MetaData.

◆ data()

QVariant KisStorageModel::data ( const QModelIndex & index,
int role ) const
override

Definition at line 117 of file KisStorageModel.cpp.

118{
119 QVariant v;
120
121 if (!index.isValid()) return v;
122 if (index.row() > rowCount()) return v;
123 if (index.column() > (int)MetaData) return v;
124
125 if (role == Qt::FontRole) {
126 return QFont();
127 }
128
129 QString location = d->storages.at(index.row());
130
131 QSqlQuery query;
132
133 bool r = query.prepare(
134 "SELECT storages.id as id\n"
135 ", storage_types.name as storage_type\n"
136 ", location\n"
137 ", timestamp\n"
138 ", pre_installed\n"
139 ", active\n"
140 "FROM storages\n"
141 ", storage_types\n"
142 "WHERE storages.storage_type_id = storage_types.id\n"
143 "AND location = :location");
144
145 if (!r) {
146 qWarning() << "Could not prepare KisStorageModel data query" << query.lastError();
147 return v;
148 }
149
150 query.bindValue(":location", location);
151
152 r = query.exec();
153
154 if (!r) {
155 qWarning() << "Could not execute KisStorageModel data query" << query.lastError() << query.boundValues();
156 return v;
157 }
158
159 if (!query.first()) {
160 qWarning() << "KisStorageModel data query did not return anything";
161 return v;
162 }
163
164 if ((role == Qt::DisplayRole || role == Qt::EditRole) && index.column() == Active) {
165 return query.value("active");
166 } else {
167 switch (role) {
168 case Qt::DisplayRole:
169 {
170 switch(index.column()) {
171 case Id:
172 return query.value("id");
173 case StorageType:
174 return query.value("storage_type");
175 case Location:
176 return query.value("location");
177 case TimeStamp:
178 return QDateTime::fromSecsSinceEpoch(query.value("timestamp").value<int>()).toString();
179 case PreInstalled:
180 return query.value("pre_installed");
181 case Active:
182 return query.value("active");
183 case Thumbnail:
184 {
185 return getThumbnailFromQuery(query);
186 }
187 case DisplayName:
188 {
189 QMap<QString, QVariant> r = KisResourceLocator::instance()->metaDataForStorage(query.value("location").toString());
190 QVariant name = query.value("location");
191 if (r.contains(KisResourceStorage::s_meta_name) && !r[KisResourceStorage::s_meta_name].toString().isNull()) {
193 }
194 else if (r.contains(KisResourceStorage::s_meta_title) && !r[KisResourceStorage::s_meta_title].toString().isNull()) {
196 }
197 return name;
198 }
199 case Qt::UserRole + MetaData:
200 {
201 QMap<QString, QVariant> r = KisResourceLocator::instance()->metaDataForStorage(query.value("location").toString());
202 return r;
203 }
204 default:
205 return v;
206 }
207 }
208 case Qt::CheckStateRole: {
209 switch (index.column()) {
210 case PreInstalled:
211 if (query.value("pre_installed").toInt() == 0) {
212 return Qt::Unchecked;
213 } else {
214 return Qt::Checked;
215 }
216 case Active:
217 if (query.value("active").toInt() == 0) {
218 return Qt::Unchecked;
219 } else {
220 return Qt::Checked;
221 }
222 default:
223 return {};
224 }
225 }
226 case Qt::DecorationRole: {
227 if (index.column() == Thumbnail) {
228 return getThumbnailFromQuery(query);
229 }
230 return {};
231 }
232 case Qt::UserRole + Id:
233 return query.value("id");
234 case Qt::UserRole + DisplayName:
235 {
236 QMap<QString, QVariant> r = KisResourceLocator::instance()->metaDataForStorage(query.value("location").toString());
237 QVariant name = query.value("location");
238 if (r.contains(KisResourceStorage::s_meta_name) && !r[KisResourceStorage::s_meta_name].toString().isNull()) {
240 }
241 else if (r.contains(KisResourceStorage::s_meta_title) && !r[KisResourceStorage::s_meta_title].toString().isNull()) {
243 }
244 return name;
245 }
246 case Qt::UserRole + StorageType:
247 return query.value("storage_type");
248 case Qt::UserRole + Location:
249 return query.value("location");
250 case Qt::UserRole + TimeStamp:
251 return query.value("timestamp");
252 case Qt::UserRole + PreInstalled:
253 return query.value("pre_installed");
254 case Qt::UserRole + Active:
255 return query.value("active");
256 case Qt::UserRole + Thumbnail:
257 return getThumbnailFromQuery(query);
258 case Qt::UserRole + MetaData:
259 {
260 QMap<QString, QVariant> r = KisResourceLocator::instance()->metaDataForStorage(query.value("location").toString());
261 return r;
262 }
263
264 default:
265 ;
266 }
267 }
268
269 return v;
270}
qreal v
QMap< QString, QVariant > metaDataForStorage(const QString &storageLocation) const
metaDataForStorage
static const QString s_meta_title
static const QString s_meta_name
static QImage getThumbnailFromQuery(const QSqlQuery &query)
const char * name(StandardAction id)

References Active, d, DisplayName, getThumbnailFromQuery(), Id, KisResourceLocator::instance(), Location, MetaData, KisResourceLocator::metaDataForStorage(), PreInstalled, rowCount(), KisResourceStorage::s_meta_name, KisResourceStorage::s_meta_title, StorageType, Thumbnail, TimeStamp, and v.

◆ flags()

Qt::ItemFlags KisStorageModel::flags ( const QModelIndex & index) const
override

Definition at line 311 of file KisStorageModel.cpp.

312{
313 if (!index.isValid()) {
314 return Qt::NoItemFlags;
315 }
316 return QAbstractTableModel::flags(index) | Qt::ItemIsEditable | Qt::ItemNeverHasChildren;
317}

◆ getThumbnailFromQuery()

QImage KisStorageModel::getThumbnailFromQuery ( const QSqlQuery & query)
staticprivate

Definition at line 73 of file KisStorageModel.cpp.

74{
75 const QString storageLocation = query.value("location").toString();
76 const QString storageType = query.value("storage_type").toString();
77 const QString storageIdAsString = query.value("id").toString();
78
79 QImage img = KisResourceThumbnailCache::instance()->originalImage(storageLocation, storageType, storageIdAsString);
80 if (!img.isNull()) {
81 return img;
82 } else {
83 const int storageId = query.value("id").toInt();
84 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(storageId >= 0, img);
85
86 bool result = false;
87 QSqlQuery thumbQuery;
88 result = thumbQuery.prepare("SELECT thumbnail FROM storages WHERE id = :id");
89 if (!result) {
90 qWarning() << "Failed to prepare query for thumbnail of" << storageId << thumbQuery.lastError();
91 return img;
92 }
93
94 thumbQuery.bindValue(":id", storageId);
95
96 result = thumbQuery.exec();
97
98 if (!result) {
99 qWarning() << "Failed to execute query for thumbnail of" << storageId << thumbQuery.lastError();
100 return img;
101 }
102
103 if (!thumbQuery.next()) {
104 qWarning() << "Failed to find thumbnail of" << storageId;
105 return img;
106 }
107
108 QByteArray ba = thumbQuery.value("thumbnail").toByteArray();
109 QBuffer buf(&ba);
110 buf.open(QBuffer::ReadOnly);
111 img.load(&buf, "PNG");
112 KisResourceThumbnailCache::instance()->insert(storageLocation, storageType, storageIdAsString, img);
113 return img;
114 }
115}
void insert(const QString &storageLocation, const QString &resourceType, const QString &filename, const QImage &image)
static KisResourceThumbnailCache * instance()
QImage originalImage(const QString &storageLocation, const QString &resourceType, const QString &filename) const
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129

References KisResourceThumbnailCache::insert(), KisResourceThumbnailCache::instance(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, and KisResourceThumbnailCache::originalImage().

◆ headerData()

QVariant KisStorageModel::headerData ( int section,
Qt::Orientation orientation,
int role = Qt::DisplayRole ) const
override

Definition at line 493 of file KisStorageModel.cpp.

494{
495 QVariant v = QVariant();
496 if (role != Qt::DisplayRole) {
497 return v;
498 }
499 if (orientation == Qt::Horizontal) {
500 switch(section) {
501 case Id:
502 return i18n("Id");
503 case StorageType:
504 return i18n("Type");
505 case Location:
506 return i18n("Location");
507 case TimeStamp:
508 return i18n("Creation Date");
509 case PreInstalled:
510 return i18n("Preinstalled");
511 case Active:
512 return i18n("Active");
513 case Thumbnail:
514 return i18n("Thumbnail");
515 case DisplayName:
516 return i18n("Name");
517 default:
518 v = QString::number(section);
519 }
520 return v;
521 }
522 return QAbstractTableModel::headerData(section, orientation, role);
523}

References Active, DisplayName, Id, Location, PreInstalled, StorageType, Thumbnail, TimeStamp, and v.

◆ importStorage()

bool KisStorageModel::importStorage ( const QString & filename,
StorageImportOption importOption ) const

Definition at line 421 of file KisStorageModel.cpp.

422{
423 return importStorageInternal(filename, importOption, false, QByteArray());
424}

References importStorageInternal().

◆ importStorageData()

bool KisStorageModel::importStorageData ( const QString & filename,
StorageImportOption importOption,
const QByteArray & data ) const

Definition at line 426 of file KisStorageModel.cpp.

429{
430 return !data.isEmpty() && importStorageInternal(filename, importOption, false, data);
431}
QVariant data(const QModelIndex &index, int role) const override

References data(), and importStorageInternal().

◆ importStorageInternal()

bool KisStorageModel::importStorageInternal ( const QString & filename,
StorageImportOption importOption,
bool dryRun,
const QByteArray & data )
staticprivate

Definition at line 438 of file KisStorageModel.cpp.

442{
443 // 1. Copy the bundle/storage to the resource folder
444 QFileInfo oldFileInfo(filename);
445 QString newDir = KoResourcePaths::getAppDataLocation();
446 QString newName = oldFileInfo.fileName();
447 QString newLocation = newDir + '/' + newName;
448
449 QFileInfo newFileInfo(newLocation);
450 if (newFileInfo.exists()) {
451 if (importOption == Overwrite) {
452 //QFile::remove(newLocation);
453 return false;
454 } else if (importOption == Rename) {
455 newName = findUnusedName(newDir, newName);
456 newLocation = newDir + '/' + newName;
457 newFileInfo = QFileInfo(newLocation);
458 } else { // importOption == None
459 return false;
460 }
461 }
462
463 // Don't actually import, just check if we could.
464 if (dryRun) {
465 return true;
466 }
467
468 if (data.isEmpty()) {
469 QFile::copy(filename, newLocation);
470 } else {
471 QSaveFile f(newLocation);
472 f.setDirectWriteFallback(false);
473
474 if (!f.open(QIODevice::WriteOnly) || f.write(data) != data.size() || !f.flush()) {
475 qWarning() << "Error writing" << data.size() << "bytes to" << newLocation << "storage:" << f.errorString();
476 return false;
477 }
478
479 f.commit();
480 }
481
482 // 2. Add the bundle as a storage/update database
484 KIS_ASSERT(!storage.isNull());
485 if (storage.isNull()) { return false; }
486 if (!KisResourceLocator::instance()->addStorage(newLocation, storage)) {
487 qWarning() << "Could not add bundle to the storages" << newLocation;
488 return false;
489 }
490 return true;
491}
QString findUnusedName(QString location, QString filename)
static QString getAppDataLocation()
#define KIS_ASSERT(cond)
Definition kis_assert.h:33

References addStorage(), data(), findUnusedName(), KoResourcePaths::getAppDataLocation(), KisResourceLocator::instance(), KIS_ASSERT, Overwrite, and Rename.

◆ instance()

KisStorageModel * KisStorageModel::instance ( )
static

Definition at line 46 of file KisStorageModel.cpp.

47{
48 return s_instance;
49}

◆ removeStorage

void KisStorageModel::removeStorage ( const QString & location)
privateslot

This is called when a storage really is deleted both from database and anywhere else.

Definition at line 532 of file KisStorageModel.cpp.

533{
534 int row = d->storages.indexOf(QFileInfo(location).fileName());
535 beginRemoveRows(QModelIndex(), row, row);
536 d->storages.removeAt(row);
537 endRemoveRows();
538}

References d.

◆ resetQuery()

void KisStorageModel::resetQuery ( )
private

Definition at line 549 of file KisStorageModel.cpp.

550{
551 QSqlQuery query;
552
553 bool r = query.prepare(
554 "SELECT location\n"
555 "FROM storages\n"
556 "ORDER BY id");
557 if (!r) {
558 qWarning() << "Could not prepare KisStorageModel query" << query.lastError();
559 }
560
561 r = query.exec();
562
563 if (!r) {
564 qWarning() << "Could not execute KisStorageModel query" << query.lastError();
565 }
566
567 d->storages.clear();
568 while (query.next()) {
569 d->storages << query.value(0).toString();
570 }
571}

References d.

◆ rowCount()

int KisStorageModel::rowCount ( const QModelIndex & parent = QModelIndex()) const
override

Definition at line 55 of file KisStorageModel.cpp.

56{
57 if (parent.isValid()) {
58 return 0;
59 }
60 return d->storages.size();
61
62}

References d.

◆ setData()

bool KisStorageModel::setData ( const QModelIndex & index,
const QVariant & value,
int role )
override

Enable and disable the storage represented by index.

Definition at line 272 of file KisStorageModel.cpp.

273{
274 if (index.isValid()) {
275
276 if (role == Qt::CheckStateRole) {
277 QSqlQuery query;
278 bool r = query.prepare("UPDATE storages\n"
279 "SET active = :active\n"
280 "WHERE id = :id\n");
281 query.bindValue(":active", value);
282 query.bindValue(":id", index.data(Qt::UserRole + Id));
283
284 if (!r) {
285 qWarning() << "Could not prepare KisStorageModel update query" << query.lastError();
286 return false;
287 }
288
289 r = query.exec();
290
291 if (!r) {
292 qWarning() << "Could not execute KisStorageModel update query" << query.lastError();
293 return false;
294 }
295
296 }
297
298 Q_EMIT dataChanged(index, index, {role});
299
300 if (value.toBool()) {
301 Q_EMIT storageEnabled(data(index, Qt::UserRole + Location).toString());
302 }
303 else {
304 Q_EMIT storageDisabled(data(index, Qt::UserRole + Location).toString());
305 }
306
307 }
308 return true;
309}
float value(const T *src, size_t ch)
void storageDisabled(const QString &storage)
void storageEnabled(const QString &storage)
QString toString(const QString &value)

References data(), Id, Location, storageDisabled(), storageEnabled(), and value().

◆ slotStoragesBulkSynchronizationFinished

void KisStorageModel::slotStoragesBulkSynchronizationFinished ( )
privateslot

called when storages finished synchronization process

Definition at line 540 of file KisStorageModel.cpp.

541{
542 beginResetModel();
543 resetQuery();
544 endResetModel();
545
547}
void storagesBulkSynchronizationFinished()
Emitted on loading when all the storages are finished initialization.

References resetQuery(), and storagesBulkSynchronizationFinished().

◆ storageDisabled

void KisStorageModel::storageDisabled ( const QString & storage)
signal

◆ storageEnabled

void KisStorageModel::storageEnabled ( const QString & storage)
signal

◆ storageForId()

KisResourceStorageSP KisStorageModel::storageForId ( const int storageId) const

Definition at line 331 of file KisStorageModel.cpp.

332{
333 QSqlQuery query;
334
335 bool r = query.prepare("SELECT location\n"
336 "FROM storages\n"
337 "WHERE storages.id = :storageId");
338
339 if (!r) {
340 qWarning() << "Could not prepare KisStorageModel data query" << query.lastError();
341 return 0;
342 }
343
344 query.bindValue(":storageId", storageId);
345
346 r = query.exec();
347
348 if (!r) {
349 qWarning() << "Could not execute KisStorageModel data query" << query.lastError() << query.boundValues();
350 return 0;
351 }
352
353 if (!query.first()) {
354 qWarning() << "KisStorageModel data query did not return anything";
355 return 0;
356 }
357
358 return KisResourceLocator::instance()->storageByLocation(KisResourceLocator::instance()->makeStorageLocationAbsolute(query.value("location").toString()));
359}
KisResourceStorageSP storageByLocation(const QString &location) const

References KisResourceLocator::instance(), and KisResourceLocator::storageByLocation().

◆ storageForIndex()

KisResourceStorageSP KisStorageModel::storageForIndex ( const QModelIndex & index) const

Definition at line 319 of file KisStorageModel.cpp.

320{
321
322 if (!index.isValid()) return 0;
323 if (index.row() > rowCount()) return 0;
324 if (index.column() > (int)MetaData) return 0;
325
326 QString location = d->storages.at(index.row());
327
328 return KisResourceLocator::instance()->storageByLocation(KisResourceLocator::instance()->makeStorageLocationAbsolute(location));
329}

References d, KisResourceLocator::instance(), MetaData, rowCount(), and KisResourceLocator::storageByLocation().

◆ storageResynchronized

void KisStorageModel::storageResynchronized ( const QString & storage,
bool isBulkResynchronization )
signal

Emitted when an individual storage is initialized.

◆ storagesBulkSynchronizationFinished

void KisStorageModel::storagesBulkSynchronizationFinished ( )
signal

Emitted on loading when all the storages are finished initialization.

Member Data Documentation

◆ d

QScopedPointer<Private> KisStorageModel::d
private

Definition at line 102 of file KisStorageModel.h.


The documentation for this class was generated from the following files: