34 : QAbstractTableModel(parent)
65 if (parent.isValid()) {
76 if (!index.isValid())
return v;
92 if (role != Qt::DisplayRole) {
95 if (orientation == Qt::Horizontal) {
100 return i18n(
"Storage ID");
104 return i18n(
"File Name");
106 return i18n(
"Tooltip");
108 return i18n(
"Image");
110 return i18n(
"Status");
112 return i18n(
"Location");
114 return i18n(
"Resource Type");
116 return i18n(
"Active");
118 return i18n(
"Storage Active");
120 return i18n(
"md5sum");
124 return i18n(
"Large Thumbnail");
126 return i18n(
"Dirty");
128 return i18n(
"Metadata");
130 return i18n(
"Broken Status");
132 return i18n(
"Broken Status Message");
134 return QString::number(section);
142 if (index.isValid() && role == Qt::CheckStateRole &&
143 value.canConvert<
bool>()) {
153 if (!index.isValid()) {
154 return Qt::NoItemFlags;
156 return QAbstractTableModel::flags(index) | Qt::ItemIsEditable | Qt::ItemNeverHasChildren;
161 QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
162 roles[Qt::UserRole +
Id] =
"id";
163 roles[Qt::UserRole +
StorageId] =
"storageId";
164 roles[Qt::UserRole +
Name] =
"name";
165 roles[Qt::UserRole +
Filename] =
"filename";
167 roles[Qt::UserRole +
Thumbnail] =
"thumbnail";
168 roles[Qt::UserRole +
Status] =
"status";
169 roles[Qt::UserRole +
Location] =
"location";
171 roles[Qt::UserRole +
MD5] =
"md5";
172 roles[Qt::UserRole +
Tags] =
"tags";
174 roles[Qt::UserRole +
Dirty] =
"dirty";
175 roles[Qt::UserRole +
MetaData] =
"metadata";
188 if (!index.isValid())
return resource;
189 if (index.row() >
rowCount())
return resource;
211 if (!md5.isEmpty()) {
213 bool r = q.prepare(
"SELECT resources.id AS id\n"
215 "WHERE md5sum = :md5sum");
217 qWarning() <<
"Could not prepare find resourceExists by md5 query" << q.lastError();
220 q.bindValue(
":mdsum", md5);
225 qWarning() <<
"Could not execute resourceExists by md5 query" << q.lastError();
235 if (!filename.isEmpty()) {
237 bool r = q.prepare(
"SELECT resources.id AS id\n"
239 "WHERE filename = :filename");
241 qWarning() <<
"Could not prepare find resourceExists by filename query" << q.lastError();
244 q.bindValue(
":filename", filename);
249 qWarning() <<
"Could not execute resourceExists by filename query" << q.lastError();
259 if (!name.isEmpty()) {
261 bool r = q.prepare(
"SELECT resources.id AS id\n"
263 "WHERE name = :name");
265 qWarning() <<
"Could not prepare find resourceExists by name query" << q.lastError();
268 q.bindValue(
":name", name);
272 qWarning() <<
"Could not execute resourceExists by name query" << q.lastError();
289 if (filename.isEmpty())
return resources;
292 bool r = q.prepare(
"SELECT resources.id AS id\n"
295 "WHERE resources.resource_type_id = resource_types.id\n"
296 "AND resources.filename = :resource_filename\n"
297 "AND resource_types.name = :resource_type\n");
299 qWarning() <<
"Could not prepare KisAllResourcesModel query for resource name" << q.lastError();
301 q.bindValue(
":resource_filename", filename);
306 qWarning() <<
"Could not select" <<
d->
resourceType <<
"resources by filename" << q.lastError() << q.boundValues();
310 int id = q.value(
"id").toInt();
313 resources << resource;
325 if (name.isEmpty())
return resources;
330 bool r = q.prepare(
"SELECT resources.id AS id\n"
333 "WHERE resources.resource_type_id = resource_types.id\n"
334 "AND resources.name = :resource_name\n"
335 "AND resource_types.name = :resource_type\n");
337 qWarning() <<
"Could not prepare KisAllResourcesModel query for resource name" << q.lastError();
341 q.bindValue(
":resource_name", name);
345 qWarning() <<
"Could not select" <<
d->
resourceType <<
"resources by name" << q.lastError() << q.boundValues();
349 int id = q.value(
"id").toInt();
352 resources << resource;
364 if (md5sum.isEmpty())
return resources;
369 bool r = q.prepare(
"SELECT resource_id AS id\n"
370 "FROM versioned_resources\n"
371 "WHERE md5sum = :md5sum");
373 qWarning() <<
"Could not prepare KisAllResourcesModel query for resource md5" << q.lastError();
375 q.bindValue(
":md5sum", md5sum);
379 qWarning() <<
"Could not select" <<
d->
resourceType <<
"resources by md5" << q.lastError() << q.boundValues();
383 int id = q.value(
"id").toInt();
386 resources << resource;
394 if (!resource || !resource->valid() || resource->resourceId() < 0)
return QModelIndex();
403 return QModelIndex();
412 return QModelIndex();
417 if (index.row() >
rowCount())
return false;
420 int resourceId = index.data(Qt::UserRole +
Id).toInt();
422 qWarning() <<
"Failed to change active state of the resource" << resourceId;
434 if (!importedResource) {
435 qWarning() <<
"Failed to import resource" << filename;
439 return importedResource;
446 if (!importedResource) {
447 qWarning() <<
"Failed to import resource" << filename;
451 return importedResource;
463 qWarning() <<
"Failed to export resource" << resource->signature();
470 if (!resource || !resource->valid()) {
471 qWarning() <<
"Cannot add resource. Resource is null or not valid";
478 qWarning() <<
"Failed to add resource" << resource->name();
489 if (!resource || !resource->valid()) {
490 qWarning() <<
"Cannot add resource. Resource is null or not valid";
497 qWarning() <<
"Failed to add resource with name deduplication" << resource->name();
508 if (!resource || !resource->valid()) {
509 qWarning() <<
"Cannot update resource. Resource is null or not valid";
514 qWarning() <<
"Failed to update resource" << resource;
519 Q_EMIT dataChanged(index, index);
525 if (!resource || !resource->valid()) {
526 qWarning() <<
"Cannot reload resource. Resource is null or not valid";
531 qWarning() <<
"Failed to reload resource" << resource;
541 Q_EMIT dataChanged(index, index);
547 if (!resource || !resource->valid() || name.isEmpty()) {
548 qWarning() <<
"Cannot rename resources. Resource is NULL or not valid or name is empty";
551 resource->setName(name);
553 qWarning() <<
"Failed to rename resource" << resource << name;
558 Q_EMIT dataChanged(index, index);
566 Q_ASSERT(resource->resourceId() > -1);
573 "SELECT resources.id\n"
574 ", resources.storage_id\n"
576 ", resources.filename\n"
577 ", resources.tooltip\n"
578 ", resources.status\n"
579 ", resources.md5sum\n"
580 ", storages.location\n"
581 ", resource_types.name as resource_type\n"
582 ", resources.status as resource_active\n"
583 ", storages.active as storage_active\n"
587 "WHERE resources.resource_type_id = resource_types.id\n"
588 "AND resources.storage_id = storages.id\n"
589 "AND resource_types.name = :resource_type\n"
590 "GROUP BY resources.name\n"
591 ", resources.filename\n"
592 ", resources.md5sum\n"
593 "ORDER BY resources.id");
596 qWarning() <<
"Could not prepare KisAllResourcesModel query" <<
d->
resourcesQuery.lastError();
635 r = q.prepare(
"SELECT tags.url\n"
639 "WHERE tags.active > 0\n"
640 "AND tags.id = resource_tags.tag_id\n"
641 "AND resource_tags.resource_id = :resource_id\n"
642 "AND resource_types.id = tags.resource_type_id\n"
643 "AND resource_tags.active = 1\n");
645 qWarning() <<
"Could not prepare TagsForResource query" << q.lastError();
648 q.bindValue(
":resource_id", resourceId);
651 qWarning() <<
"Could not select tags for" << resourceId << q.lastError() << q.boundValues();
657 if (tag && tag->valid()) {
667 if (parent.isValid()) {
680 bool r = q.prepare(
"SELECT COUNT(DISTINCT resources.name || resources.filename || resources.md5sum)\n"
683 "WHERE resources.resource_type_id = resource_types.id\n"
684 "AND resource_types.name = :resource_type\n");
686 qWarning() <<
"Could not prepare all resources rowcount query" << q.lastError();
692 qWarning() <<
"Could not execute all resources rowcount query" << q.lastError() << q.boundValues();
706 if (resourceIds.isEmpty())
return;
710 Q_FOREACH (
int resourceId, resourceIds) {
713 if (index.isValid()) {
724 if (isBulkResynchronization)
return;
759 Q_FOREACH (
int resourceId, resourceIds) {
761 if (index.isValid()) {
762 beginRemoveRows(QModelIndex(), index.row(), index.row());
766 dbgResources <<
"KisAllResourcesModel::beginExternalResourceRemove got invalid index" << index <<
"for resourceId" << resourceId
767 <<
"of type" << resourceType <<
"(possibly the resource was deduplicated via sql query and that's why it doesn't appear in the model)";
789 if (resourceId < 0)
return;
795 if (index.isValid()) {
808 : QSortFilterProxyModel(parent)
845 return source->resourceForIndex(mapToSource(index));
854 return mapFromSource(
source->indexForResource(resource));
856 return QModelIndex();
863 return mapFromSource(
source->indexForResourceId(resourceId));
865 return QModelIndex();
872 return source->setResourceActive(mapToSource(index),
value);
882 res =
source->importResourceFile(filename, allowOverwrite, storageId);
893 res =
source->importResource(filename, device, allowOverwrite, storageId);
902 return source &&
source->importWillOverwriteResource(fileName, storageLocation);
910 res =
source->exportResource(resource, device);
918 bool updateInsteadOfAdd =
false;
925 if (!q.prepare(
"SELECT resources.id\n"
926 ", resources.md5sum\n"
927 ", storages.location\n"
928 ", resource_types.name\n"
932 "WHERE resources.name = :name\n"
933 "AND resources.storage_id = storages.id\n"
934 "AND resources.resource_type_id = resource_types.id\n"
935 "AND resources.status = 0")) {
936 qWarning() <<
"Could not create KisResourceModel::addResource query" << q.lastError();
939 q.bindValue(
":name", resource->name());
942 qWarning() <<
"Could not execute KisResourceModel::addResource query" << q.lastError();
946 int id = q.value(0).toInt();
947 QString md5sum = q.value(1).toString();
948 QString storageLocation = q.value(2).toString();
949 QString resourceType = q.value(3).toString();
954 if (!
q2.prepare(
"SELECT MAX(version)\n"
955 "FROM versioned_resources\n"
956 "WHERE resource_id = :id")) {
957 qWarning() <<
"Could not prepare versioned_resources query" << q.lastError();
960 q2.bindValue(
":id",
id);
963 qWarning() <<
"Could not execute versioned_resources query" << q.lastError();
967 qWarning() <<
"No resource version found with id" << id;
972 int version =
q2.value(0).toInt();
974 if (resourceType == resource->resourceType().first) {
975 resource->setResourceId(
id);
976 resource->setVersion(version);
977 resource->setMD5Sum(md5sum);
978 resource->setActive(
true);
979 resource->setStorageLocation(storageLocation);
981 updateInsteadOfAdd = result;
986 if (!updateInsteadOfAdd) {
987 result =
source->addResource(resource, storageId);
1001 const bool result =
source->addResourceDeduplicateFileName(resource, storageId);
1014 return source->updateResource(resource);
1023 return source->reloadResource(resource);
1032 return source->renameResource(resource, name);
1041 return source->setResourceMetaData(resource, metadata);
1053 QModelIndex idx = sourceModel()->index(source_row, 0, source_parent);
1055 if (idx.isValid()) {
1060 QString queryString = (
"SELECT COUNT(*)\n"
1063 "WHERE resources.id IN (select resource_id FROM resource_tags WHERE active = 1)\n"
1064 "AND storages.id = resources.storage_id\n"
1065 "AND resources.id = :resource_id\n");
1068 queryString.append(
"AND resources.status > 0\n");
1071 queryString.append(
"AND resources.status = 0\n");
1075 queryString.append(
"AND storages.active > 0\n");
1078 queryString.append(
"AND storages.active = 0\n");
1083 if (!q.prepare((queryString))) {
1084 qWarning() <<
"KisResourceModel: Could not prepare resource_tags query" << q.lastError();
1087 q.bindValue(
":resource_id",
id);
1090 qWarning() <<
"KisResourceModel: Could not execute resource_tags query" << q.lastError() << q.boundValues();
1094 if (q.value(0).toInt() > 0) {
1108 return nameLeft.toLower() < nameRight.toLower();
1114 for (
int i = 0; i < rowCount(); ++i) {
1115 QModelIndex idx = index(i, 0);
1116 if (idx.isValid() && data(idx, Qt::UserRole + column).toString() == filter) {
1157 if (idx.isValid()) {
float value(const T *src, size_t ch)
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
Columns
The Columns enum indexes the columns in the model. To get the thumbnail for a particular resource,...
@ Status
Whether the resource is active. Duplicate of ResourceActive.
@ ResourceActive
Whether the current resource is active.
@ Dirty
A dirty resource is one that has been modified locally but not saved.
@ LargeThumbnail
A larger thumbnail for displaying in a tooltip. 200x200 or so.
@ MetaData
MetaData is a map of key, value pairs that is associated with this resource.
@ BrokenStatus
Whether the resource is broken (bool)
@ StorageActive
Whether the current resource's storage is active.
The KisAllresourcesModel class provides access to the cache database for a particular resource type....
KisAllResourcesModel(const QString &resourceType, QObject *parent=0)
void endExternalResourceImport(const QString &resourceType)
bool addResourceDeduplicateFileName(KoResourceSP resource, const QString &storageId=QString("")) override
addResource adds the given resource to the database and storage. If the resource already exists in th...
KoResourceSP importResource(const QString &filename, QIODevice *device, const bool allowOverwrite, const QString &storageId=QString("")) override
importResource imports a resource from a QIODevice
void slotResourceActiveStateChanged(const QString &resourceType, int resourceId)
bool resourceExists(const QString &md5, const QString &filename, const QString &name)
resourceExists checks whether there is a resource with, in order, the given md5, the filename or the ...
QModelIndex indexForResourceId(int resourceId) const override
indexFromResource
bool setResourceActive(const QModelIndex &index, bool value) override
setResourceActive changes 'active' state of the resource
bool importWillOverwriteResource(const QString &fileName, const QString &storageLocation=QString()) const override
importWillOverwriteResource checks is importing a resource with this filename will overwrite anything
bool setData(const QModelIndex &index, const QVariant &value, int role) override
void beginExternalResourceImport(const QString &resourceType, int numResources)
QVector< KoResourceSP > resourcesForName(const QString &name) const
void storagesBulkSynchronizationFinished()
Qt::ItemFlags flags(const QModelIndex &index) const override
~KisAllResourcesModel() override
KoResourceSP resourceForId(int id) const
QVector< KoResourceSP > resourcesForFilename(QString filename) const
QHash< int, QByteArray > roleNames() const override
bool addResource(KoResourceSP resource, const QString &storageId=QString("")) override
addResource adds the given resource to the database and storage. If the resource already exists in th...
void beginExternalResourceRemove(const QString &resourceType, const QVector< int > &resourceId)
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override
QModelIndex indexForResource(KoResourceSP resource) const override
indexFromResource
bool exportResource(KoResourceSP resource, QIODevice *device) override
exportResource exports a resource into a QIODevice
bool renameResource(KoResourceSP resource, const QString &name) override
renameResource name the given resource. The resource will have its name field reset,...
QVector< KoResourceSP > resourcesForMD5(const QString &md5sum) const
void storageResynchronized(const QString &storage, bool isBulkResynchronization)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void endExternalResourceRemove(const QString &resourceType)
bool reloadResource(KoResourceSP resource) override
reloadResource
QVector< KisTagSP > tagsForResource(int resourceId) const
bool setResourceMetaData(KoResourceSP resource, QMap< QString, QVariant > metadata) override
setResourceMetaData
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
KoResourceSP resourceForIndex(QModelIndex index=QModelIndex()) const override
resourceForIndex returns a properly versioned and id'ed resource object
KoResourceSP importResourceFile(const QString &filename, const bool allowOverwrite, const QString &storageId=QString("")) override
importResourceFile
void storageActiveStateChanged(const QString &location)
bool updateResource(KoResourceSP resource) override
updateResource creates a new version of the resource in the storage and in the database....
static QVector< int > resourcesForStorage(const QString &resourceType, const QString &storageLocation)
KisTagSP tagForUrl(const QString &tagUrl, const QString resourceType)
tagForUrl create a tag from the database
KoResourceSP importResource(const QString &resourceType, const QString &fileName, QIODevice *device, const bool allowOverwrite, const QString &storageLocation=QString())
importResource
void endExternalResourceRemove(const QString &resourceType)
Emitted when the locator finished importing the embedded resource.
bool exportResource(KoResourceSP resource, QIODevice *device)
exportResource
void beginExternalResourceImport(const QString &resourceType, int numResources)
Emitted when the locator needs to add an embedded resource.
void beginExternalResourceRemove(const QString &resourceType, const QVector< int > resourceIds)
Emitted when the locator needs to add an embedded resource.
bool importWillOverwriteResource(const QString &resourceType, const QString &fileName, const QString &storageLocation=QString()) const
return whether importing will overwrite some existing resource
bool setMetaDataForResource(int id, QMap< QString, QVariant > map) const
setMetaDataForResource
void endExternalResourceImport(const QString &resourceType)
Emitted when the locator finished importing the embedded resource.
void resourceActiveStateChanged(const QString &resourceType, int resourceId)
Emitted when a resource changes its active state.
KoResourceSP resourceForId(int resourceId)
resourceForId returns the resource with the given id, or 0 if no such resource exists....
static KisResourceLocator * instance()
KoResourceSP importResourceFromFile(const QString &resourceType, const QString &fileName, const bool allowOverwrite, const QString &storageLocation=QString())
importResourceFromFile
static KisAllResourcesModel * resourceModel(const QString &resourceType)
QVector< KoResourceSP > filterByColumn(const QString filter, KisAllResourcesModel::Columns column) const
bool setResourceMetaData(KoResourceSP resource, QMap< QString, QVariant > metadata) override
setResourceMetaData
KoResourceSP resourceForId(int id) const
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override
KoResourceSP importResourceFile(const QString &filename, const bool allowOverwrite, const QString &storageId=QString("")) override
importResourceFile
bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override
bool importWillOverwriteResource(const QString &fileName, const QString &storageLocation=QString()) const override
importWillOverwriteResource checks is importing a resource with this filename will overwrite anything
bool reloadResource(KoResourceSP resource) override
reloadResource
QVector< KisTagSP > tagsForResource(int resourceId) const
bool renameResource(KoResourceSP resource, const QString &name) override
renameResource name the given resource. The resource will have its name field reset,...
KisResourceModel(const QString &type, QObject *parent=0)
bool filterResource(const QModelIndex &idx) const
bool addResourceDeduplicateFileName(KoResourceSP resource, const QString &storageId=QString("")) override
addResource adds the given resource to the database and storage. If the resource already exists in th...
void setStorageFilter(StorageFilter filter) override
bool exportResource(KoResourceSP resource, QIODevice *device) override
exportResource exports a resource into a QIODevice
QVector< KoResourceSP > resourcesForMD5(const QString md5sum) const
bool updateResource(KoResourceSP resource) override
updateResource creates a new version of the resource in the storage and in the database....
QVector< KoResourceSP > resourcesForFilename(QString fileName) const
QVector< KoResourceSP > resourcesForName(QString name) const
bool addResource(KoResourceSP resource, const QString &storageId=QString("")) override
addResource adds the given resource to the database and storage. If the resource already exists in th...
void setResourceFilter(ResourceFilter filter) override
QModelIndex indexForResource(KoResourceSP resource) const override
indexFromResource
void showOnlyUntaggedResources(bool showOnlyUntagged)
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
~KisResourceModel() override
bool setResourceActive(const QModelIndex &index, bool value) override
setResourceActive changes 'active' state of the resource
QModelIndex indexForResourceId(int resourceId) const override
indexFromResource
KoResourceSP importResource(const QString &filename, QIODevice *device, const bool allowOverwrite, const QString &storageId=QString("")) override
importResource imports a resource from a QIODevice
KoResourceSP resourceForIndex(QModelIndex index=QModelIndex()) const override
resourceForIndex returns a properly versioned and id'ed resource object
static QVariant variantFromResourceQuery(const QSqlQuery &query, int column, int role, bool useResourcePrefix)
variantFromResourceQuery returns a QVariant for the given column and or role
static KisStorageModel * instance()
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.
int externalResourcesRemovedCount
StorageFilter storageFilter
bool showOnlyUntaggedResources
ResourceFilter resourceFilter