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

#include <KisResourceLocator.h>

+ Inheritance diagram for KisResourceLocator:

Classes

class  Private
 
struct  ResourceStorage
 

Public Types

enum class  LocatorError {
  Ok , LocationReadOnly , CannotCreateLocation , CannotInitializeDb ,
  CannotSynchronizeDb
}
 

Signals

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.
 
void endExternalResourceImport (const QString &resourceType)
 Emitted when the locator finished importing the embedded resource.
 
void endExternalResourceRemove (const QString &resourceType)
 Emitted when the locator finished importing the embedded resource.
 
void progressMessage (const QString &)
 
void resourceActiveStateChanged (const QString &resourceType, int resourceId)
 Emitted when a resource changes its active state.
 
void storageAdded (const QString &location)
 Emitted whenever a storage is added.
 
void storageRemoved (const QString &location)
 Emitted whenever a storage is removed.
 
void storageResynchronized (const QString &storage, bool isBulkResynchronization)
 
void storagesBulkSynchronizationFinished ()
 

Public Member Functions

bool addStorage (const QString &storageLocation, KisResourceStorageSP storage)
 addStorage Adds a new resource storage to the database. The storage is will be marked as not pre-installed. If there is already a storage with the given location, it will first be removed.
 
QStringList errorMessages () const
 errorMessages
 
QString filePathForResource (KoResourceSP resource)
 
bool hasStorage (const QString &storageLocation)
 hasStorage can be used to check whether the given storage already exists
 
LocatorError initialize (const QString &installationResourcesLocation)
 initialize Setup the resource locator for use.
 
void purge (const QString &storageLocation, const QVector< int > &removedTagIds)
 purge purges the local resource cache
 
void purgeTag (const QString tagUrl, const QString resourceType)
 
bool removeStorage (const QString &storageLocation)
 removeStorage removes the temporary storage from the database
 
QString resourceLocationBase () const
 resourceLocationBase is the place where all resource storages (folder, bundles etc. are located. This is a writable place.
 
void updateFontStorage ()
 This updates the "fontregistry" storage. Called when the font directories change;.
 
 ~KisResourceLocator ()
 

Static Public Member Functions

static KisResourceLocatorinstance ()
 
static void saveTags ()
 saveTags saves all tags to .tag files in the resource folder
 

Static Public Attributes

static const QString resourceLocationKey {"ResourceDirectory"}
 

Private Types

enum class  InitializationStatus {
  Unknown , Initialized , FirstRun , FirstUpdate ,
  Updating
}
 

Private Member Functions

bool addResource (const QString &resourceType, const KoResourceSP resource, const QString &storageLocation=QString())
 addResource adds the given resource to the database and potentially a storage
 
bool addResourceDeduplicateFileName (const QString &resourceType, const KoResourceSP resource, const QString &storageLocation)
 addResourceDeduplicateFileName imports the resource fith file name deduplication
 
bool exportResource (KoResourceSP resource, QIODevice *device)
 exportResource
 
void findStorages ()
 
LocatorError firstTimeInstallation (InitializationStatus initializationStatus, const QString &installationResourcesLocation)
 
KisResourceStorageSP folderStorage () const
 
KisResourceStorageSP fontStorage () const
 
ResourceStorage getResourceStorage (int resourceId) const
 
KoResourceSP importResource (const QString &resourceType, const QString &fileName, QIODevice *device, const bool allowOverwrite, const QString &storageLocation=QString())
 importResource
 
KoResourceSP importResourceDeduplicateFileName (const QString &resourceType, const QString &proposedFileName, QIODevice *device, const QString &storageLocation=QString())
 importResourceDeduplicateFileName imports the resource fith file name deduplication
 
KoResourceSP importResourceFromFile (const QString &resourceType, const QString &fileName, const bool allowOverwrite, const QString &storageLocation=QString())
 importResourceFromFile
 
bool importWillOverwriteResource (const QString &resourceType, const QString &fileName, const QString &storageLocation=QString()) const
 return whether importing will overwrite some existing resource
 
 KisResourceLocator (const KisResourceLocator &)
 
 KisResourceLocator (QObject *parent)
 
void loadRequiredResources (KoResourceSP resource)
 
QString makeStorageLocationAbsolute (QString storageLocation) const
 
QString makeStorageLocationRelative (QString location) const
 
KisResourceStorageSP memoryStorage () const
 
QMap< QString, QVariant > metaDataForResource (int id) const
 metaDataForResource
 
QMap< QString, QVariant > metaDataForStorage (const QString &storageLocation) const
 metaDataForStorage
 
KisResourceLocator operator= (const KisResourceLocator &)
 
bool reloadResource (const QString &resourceType, const KoResourceSP resource)
 Reloads the resource from its persistent storage.
 
KoResourceSP resource (QString storageLocation, const QString &resourceType, const QString &filename)
 resource finds a physical resource in one of the storages
 
bool resourceCached (QString storageLocation, const QString &resourceType, const QString &filename) const
 
KoResourceSP resourceForId (int resourceId)
 resourceForId returns the resource with the given id, or 0 if no such resource exists. The resource object will have its id set but not its version.
 
bool setMetaDataForResource (int id, QMap< QString, QVariant > map) const
 setMetaDataForResource
 
void setMetaDataForStorage (const QString &storageLocation, QMap< QString, QVariant > map) const
 setMetaDataForStorage
 
bool setResourceActive (int resourceId, bool active)
 setResourceActive
 
KisResourceStorageSP storageByLocation (const QString &location) const
 
QList< KisResourceStorageSPstorages () const
 
bool synchronizeDb ()
 
KisTagSP tagForUrl (const QString &tagUrl, const QString resourceType)
 tagForUrl create a tag from the database
 
bool updateResource (const QString &resourceType, const KoResourceSP resource)
 updateResource
 

Static Private Member Functions

static KisTagSP tagForUrlNoCache (const QString &tagUrl, const QString resourceType)
 tagForUrlNoCache create a tag from the database, don't use cache
 

Private Attributes

QScopedPointer< Privated
 

Friends

class KisAllResourcesModel
 
class KisAllTagResourceModel
 
class KisAllTagsModel
 
class KisBrushTypeMetaDataFixup
 
class KisMyPaintPaintOpPreset
 
class KisResourceCacheDb
 
class KisResourceQueryMapper
 
class KisResourceThumbnailCache
 
class KisResourceUserOperations
 
class KisStorageFilterProxyModel
 
class KisStorageModel
 
class KisTagResourceModel
 
class Resource
 
class TestResourceLocator
 
class TestResourceModel
 

Detailed Description

The KisResourceLocator class locates all resource storages (folders, bundles, various adobe resource libraries) in the resource location.

The resource location is always a writable folder.

There is one resource locator which is owned by the QApplication object.

The resource location is configurable, but there is only one location where Krita will look for resources.

Definition at line 32 of file KisResourceLocator.h.

Member Enumeration Documentation

◆ InitializationStatus

enum class KisResourceLocator::InitializationStatus
strongprivate
Enumerator
Unknown 
Initialized 
FirstRun 
FirstUpdate 
Updating 

Definition at line 360 of file KisResourceLocator.h.

360 {
361 Unknown, // We don't know whether Krita has run on this system for this resource location yet
362 Initialized, // Everything is ready to start synchronizing the database
363 FirstRun, // Krita hasn't run for this resource location yet
364 FirstUpdate, // Krita was installed, but it's a version from before the resource locator existed, only user-defined resources are present
365 Updating // Krita is updating from an older version with resource locator
366 };

◆ LocatorError

Enumerator
Ok 
LocationReadOnly 
CannotCreateLocation 
CannotInitializeDb 
CannotSynchronizeDb 

Definition at line 47 of file KisResourceLocator.h.

Constructor & Destructor Documentation

◆ ~KisResourceLocator()

KisResourceLocator::~KisResourceLocator ( )

Definition at line 90 of file KisResourceLocator.cpp.

91{
92}

◆ KisResourceLocator() [1/2]

KisResourceLocator::KisResourceLocator ( QObject * parent)
private

Definition at line 73 of file KisResourceLocator.cpp.

74 : QObject(parent)
75 , d(new Private())
76{
77}
QScopedPointer< Private > d

◆ KisResourceLocator() [2/2]

KisResourceLocator::KisResourceLocator ( const KisResourceLocator & )
private

Member Function Documentation

◆ addResource()

bool KisResourceLocator::addResource ( const QString & resourceType,
const KoResourceSP resource,
const QString & storageLocation = QString() )
private

addResource adds the given resource to the database and potentially a storage

Parameters
resourceTypethe type of the resource
resourcethe actual resource object
storageLocationthe storage where the resource will be saved. By default this is the default folder storage.
Returns
true if successful

And to the database.

The metadata will be set by KisResourceCacheDb, which is not very consistent with KisResourceLocator::updateResource(), but works :)

Definition at line 677 of file KisResourceLocator.cpp.

678{
679 if (!resource || !resource->valid()) return false;
680
681 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
683
684 //If we have gotten this far and the resource still doesn't have a filename to save to, we should generate one.
685 if (resource->filename().isEmpty()) {
686 resource->setFilename(resource->name().split(" ").join("_") + resource->defaultFileExtension());
687 }
688
689 if (resource->version() != 0) { // Can happen with cloned resources
690 resource->setVersion(0);
691 }
692
693 // Save the resource to the storage storage
694 if (!storage->addResource(resource)) {
695 qWarning() << "Could not add resource" << resource->filename() << "to the storage" << storageLocation;
696 return false;
697 }
698
699 resource->setStorageLocation(storageLocation);
700 resource->setMD5Sum(storage->resourceMd5(resourceType + "/" + resource->filename()));
701 resource->setDirty(false);
703
704 d->resourceCache[QPair<QString, QString>(storageLocation, resourceType + "/" + resource->filename())] = resource;
705
711 const bool result = KisResourceCacheDb::addResource(storage,
712 storage->timeStampForResource(resourceType, resource->filename()),
713 resource,
714 resourceType);
715 return result;
716}
static bool addResource(KisResourceStorageSP storage, QDateTime timestamp, KoResourceSP resource, const QString &resourceType)
KoResourceSP resource(QString storageLocation, const QString &resourceType, const QString &filename)
resource finds a physical resource in one of the storages
void loadRequiredResources(KoResourceSP resource)
QString makeStorageLocationAbsolute(QString storageLocation) const
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129

References KisResourceCacheDb::addResource(), d, KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, loadRequiredResources(), makeStorageLocationAbsolute(), and resource().

◆ addResourceDeduplicateFileName()

bool KisResourceLocator::addResourceDeduplicateFileName ( const QString & resourceType,
const KoResourceSP resource,
const QString & storageLocation )
private

addResourceDeduplicateFileName imports the resource fith file name deduplication

When loading embedded resources from another resources, we should make sure they do not overwrite anything and land in the database unconditionally. That is why we might need to rename them on loading. The parent resource will (hopefully) still be able to address them using md5sum.

Parameters
resourceType
deviceQIODevice where the resource should be loaded from
storageLocationoptional, the storage where the resource will be stored. Empty means in the default Folder storage.
Returns
the imported resource, which has been added to the database and the cache

Definition at line 638 of file KisResourceLocator.cpp.

639{
640 // fix filename is missing
641 if (resource->filename().isEmpty()) {
642 resource->setFilename(resource->name().split(" ").join("_") + resource->defaultFileExtension());
643 }
644
645 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!resource->filename().isEmpty(), false);
646
647 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
649
650 const QString fileName = findDeduplicatedFileName(resourceType, resource->filename(), storage);
651 resource->setFilename(fileName);
652 return addResource(resourceType, resource, storageLocation);
653}
bool addResource(const QString &resourceType, const KoResourceSP resource, const QString &storageLocation=QString())
addResource adds the given resource to the database and potentially a storage

References addResource(), d, KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, makeStorageLocationAbsolute(), and resource().

◆ addStorage()

bool KisResourceLocator::addStorage ( const QString & storageLocation,
KisResourceStorageSP storage )

addStorage Adds a new resource storage to the database. The storage is will be marked as not pre-installed. If there is already a storage with the given location, it will first be removed.

Parameters
storageLocationa unique name for the given storage
storagea storage object
Returns
true if the storage has been added successfully

Definition at line 842 of file KisResourceLocator.cpp.

843{
844 if (d->storages.contains(storageLocation)) {
845 if (!removeStorage(storageLocation)) {
846 qWarning() << "could not remove" << storageLocation;
847 return false;
848 }
849 }
850
851 QVector<std::pair<QString, int>> addedResources;
852 Q_FOREACH(const QString &type, KisResourceLoaderRegistry::instance()->resourceTypes()) {
853 int numAddedResources = 0;
854
855 QSharedPointer<KisResourceStorage::ResourceIterator> it = storage->resources(type);
856 while (it->hasNext()) {
857 it->next();
858 numAddedResources++;
859 }
860
861 if (numAddedResources > 0) {
862 addedResources << std::make_pair(type, numAddedResources);
863 }
864 }
865
866 Q_FOREACH (const auto &typedResources, addedResources) {
867 Q_EMIT beginExternalResourceImport(typedResources.first, typedResources.second);
868 }
869
870 d->storages[storageLocation] = storage;
871 if (!KisResourceCacheDb::addStorage(storage, false)) {
872 d->errorMessages.append(i18n("Could not add %1 to the database", storage->location()));
873 qWarning() << d->errorMessages;
874 return false;
875 }
876
878 d->errorMessages.append(QString("Could not add tags for storage %1 to the cache database").arg(storage->location()));
879 qWarning() << d->errorMessages;
880 return false;
881 }
882
883 Q_FOREACH (const auto &typedResources, addedResources) {
884 Q_EMIT endExternalResourceImport(typedResources.first);
885 }
886
887 Q_EMIT storageAdded(makeStorageLocationRelative(storage->location()));
888 return true;
889}
static bool addStorage(KisResourceStorageSP storage, bool preinstalled)
static bool addStorageTags(KisResourceStorageSP storage)
static KisResourceLoaderRegistry * instance()
void storageAdded(const QString &location)
Emitted whenever a storage is added.
bool removeStorage(const QString &storageLocation)
removeStorage removes the temporary storage from the database
void beginExternalResourceImport(const QString &resourceType, int numResources)
Emitted when the locator needs to add an embedded resource.
QString makeStorageLocationRelative(QString location) const
void endExternalResourceImport(const QString &resourceType)
Emitted when the locator finished importing the embedded resource.

References KisResourceCacheDb::addStorage(), KisResourceCacheDb::addStorageTags(), beginExternalResourceImport(), d, endExternalResourceImport(), KisResourceLoaderRegistry::instance(), makeStorageLocationRelative(), removeStorage(), and storageAdded().

◆ beginExternalResourceImport

void KisResourceLocator::beginExternalResourceImport ( const QString & resourceType,
int numResources )
signal

Emitted when the locator needs to add an embedded resource.

◆ beginExternalResourceRemove

void KisResourceLocator::beginExternalResourceRemove ( const QString & resourceType,
const QVector< int > resourceIds )
signal

Emitted when the locator needs to add an embedded resource.

◆ endExternalResourceImport

void KisResourceLocator::endExternalResourceImport ( const QString & resourceType)
signal

Emitted when the locator finished importing the embedded resource.

◆ endExternalResourceRemove

void KisResourceLocator::endExternalResourceRemove ( const QString & resourceType)
signal

Emitted when the locator finished importing the embedded resource.

◆ errorMessages()

QStringList KisResourceLocator::errorMessages ( ) const

errorMessages

Returns

Definition at line 150 of file KisResourceLocator.cpp.

151{
152 return d->errorMessages;
153}

References d.

◆ exportResource()

bool KisResourceLocator::exportResource ( KoResourceSP resource,
QIODevice * device )
private

exportResource

Parameters
resourceresource to be exported
deviceQIODevice where the resource should be loaded to
Returns
true if the resource has been exported successfully

Definition at line 667 of file KisResourceLocator.cpp.

668{
669 if (!resource || !resource->valid() || resource->resourceId() < 0) return false;
670
671 const QString resourceUrl = resource->resourceType().first + "/" + resource->filename();
672 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(resource->storageLocation()));
674 return storage->exportResource(resourceUrl, device);
675}

References d, KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, makeStorageLocationAbsolute(), and resource().

◆ filePathForResource()

QString KisResourceLocator::filePathForResource ( KoResourceSP resource)

Returns the full file path of the resource if it has any separate physical representation on the disk

Definition at line 1023 of file KisResourceLocator.cpp.

1024{
1025 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(resource->storageLocation()));
1026 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(storage, QString());
1027
1028 const QString resourceUrl = resource->resourceType().first + "/" + resource->filename();
1029
1030 return storage->resourceFilePath(resourceUrl);
1031}

References d, KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, makeStorageLocationAbsolute(), and resource().

◆ findStorages()

void KisResourceLocator::findStorages ( )
private

Definition at line 1095 of file KisResourceLocator.cpp.

1096{
1097 d->storages.clear();
1098 d->resourceCache.clear();
1099
1100 // Add the folder
1102 Q_ASSERT(storage->location() == d->resourceLocation);
1103 d->storages[d->resourceLocation] = storage;
1104
1105 // Add the memory storage
1106 d->storages["memory"] = QSharedPointer<KisResourceStorage>::create("memory");
1107 d->storages["memory"]->setMetaData(KisResourceStorage::s_meta_name, i18n("Temporary Resources"));
1108
1109 // Add font storage
1111 if (fontStorage && fontStorage->valid()) {
1112 d->storages["fontregistry"] = fontStorage;
1113 d->storages["fontregistry"]->setMetaData(KisResourceStorage::s_meta_name, i18n("Font Storage"));
1114 }
1115
1116 // And add bundles and adobe libraries
1117 QStringList filters = QStringList() << "*.bundle" << "*.abr" << "*.asl";
1118 QDirIterator iter(d->resourceLocation, filters, QDir::Files, QDirIterator::Subdirectories);
1119 while (iter.hasNext()) {
1120 iter.next();
1122 if (!storage->valid()) {
1123 // we still add the storage to the list and try to read whatever possible
1124 qWarning() << "KisResourceLocator::findStorages: the storage is invalid" << storage->location();
1125 }
1126 d->storages[storage->location()] = storage;
1127 }
1128
1129 // Add any missing storage types to the resource cache database.
1130 Q_FOREACH(const KisResourceStorage::StorageType &type, KisStoragePluginRegistry::instance()->storageTypes()) {
1132 }
1133}
QList< QString > QStringList
static bool registerStorageType(const KisResourceStorage::StorageType storageType)
registerStorageType registers this storage type in the database
KisResourceStorageSP fontStorage() const
static const QString s_meta_name
static KisStoragePluginRegistry * instance()

References d, fontStorage(), KisStoragePluginRegistry::instance(), KisResourceCacheDb::registerStorageType(), and KisResourceStorage::s_meta_name.

◆ firstTimeInstallation()

KisResourceLocator::LocatorError KisResourceLocator::firstTimeInstallation ( InitializationStatus initializationStatus,
const QString & installationResourcesLocation )
private

Definition at line 1042 of file KisResourceLocator.cpp.

1043{
1044 Q_EMIT progressMessage(i18n("Krita is running for the first time. Initialization will take some time."));
1045 Q_UNUSED(initializationStatus);
1046
1047 Q_FOREACH(const QString &folder, KisResourceLoaderRegistry::instance()->resourceTypes()) {
1048 QDir dir(d->resourceLocation + '/' + folder + '/');
1049 if (!dir.exists()) {
1050 if (!QDir().mkpath(d->resourceLocation + '/' + folder + '/')) {
1051 d->errorMessages << i18n("3. Could not create the resource location at %1.", dir.path());
1053 }
1054 }
1055 }
1056
1057 Q_FOREACH(const QString &folder, KisResourceLoaderRegistry::instance()->resourceTypes()) {
1058 QDir dir(installationResourcesLocation + '/' + folder + '/');
1059 if (dir.exists()) {
1060 Q_FOREACH(const QString &entry, dir.entryList(QDir::Files | QDir::Readable)) {
1061 QFile f(dir.canonicalPath() + '/'+ entry);
1062 if (!QFileInfo(d->resourceLocation + '/' + folder + '/' + entry).exists()) {
1063 if (!f.copy(d->resourceLocation + '/' + folder + '/' + entry)) {
1064 d->errorMessages << i18n("Could not copy resource %1 to %2", f.fileName(), d->resourceLocation + '/' + folder + '/' + entry);
1065 }
1066 }
1067 }
1068 }
1069 }
1070
1071 // And add bundles and adobe libraries
1072 QStringList filters = QStringList() << "*.bundle" << "*.abr" << "*.asl";
1073 QDirIterator iter(installationResourcesLocation, filters, QDir::Files, QDirIterator::Subdirectories);
1074 while (iter.hasNext()) {
1075 iter.next();
1076 Q_EMIT progressMessage(i18n("Installing the resources from bundle %1.", iter.filePath()));
1077 QFile f(iter.filePath());
1078 Q_ASSERT(f.exists());
1079 if (!f.copy(d->resourceLocation + '/' + iter.fileName())) {
1080 d->errorMessages << i18n("Could not copy resource %1 to %2", f.fileName(), d->resourceLocation);
1081 }
1082 }
1083
1084 QFile f(d->resourceLocation + '/' + "KRITA_RESOURCE_VERSION");
1085 if (f.open(QFile::WriteOnly)) {
1086 f.write(KritaVersionWrapper::versionString().toUtf8());
1087 f.close();
1088 } else {
1089 qWarning() << "Could not open" << f.fileName() << "for writing:" << f.errorString();
1090 }
1091
1092 return LocatorError::Ok;
1093}
void progressMessage(const QString &)
KRITAVERSION_EXPORT QString versionString(bool checkGit=false)

References CannotCreateLocation, d, KisResourceLoaderRegistry::instance(), Ok, progressMessage(), and KritaVersionWrapper::versionString().

◆ folderStorage()

KisResourceStorageSP KisResourceLocator::folderStorage ( ) const
private

Definition at line 1151 of file KisResourceLocator.cpp.

1152{
1153 return storageByLocation(d->resourceLocation);
1154}
KisResourceStorageSP storageByLocation(const QString &location) const

References d, and storageByLocation().

◆ fontStorage()

KisResourceStorageSP KisResourceLocator::fontStorage ( ) const
private

Definition at line 1161 of file KisResourceLocator.cpp.

1162{
1163 return storageByLocation("fontregistry");
1164}

References storageByLocation().

◆ getResourceStorage()

KisResourceLocator::ResourceStorage KisResourceLocator::getResourceStorage ( int resourceId) const
private

Definition at line 1166 of file KisResourceLocator.cpp.

1167{
1168 ResourceStorage rs;
1169
1170 QSqlQuery q;
1171 bool r = q.prepare("SELECT storages.location\n"
1172 ", resource_types.name as resource_type\n"
1173 ", resources.filename\n"
1174 "FROM resources\n"
1175 ", storages\n"
1176 ", resource_types\n"
1177 "WHERE resources.id = :resource_id\n"
1178 "AND resources.storage_id = storages.id\n"
1179 "AND resource_types.id = resources.resource_type_id");
1180 if (!r) {
1181 qWarning() << "KisResourceLocator::removeResource: could not prepare query." << q.lastError();
1182 return rs;
1183 }
1184
1185
1186 q.bindValue(":resource_id", resourceId);
1187
1188 r = q.exec();
1189 if (!r) {
1190 qWarning() << "KisResourceLocator::removeResource: could not execute query." << q.lastError();
1191 return rs;
1192 }
1193
1194 q.first();
1195
1196 QString storageLocation = q.value("location").toString();
1197 QString resourceType= q.value("resource_type").toString();
1198 QString resourceFilename = q.value("filename").toString();
1199
1200 rs.storageLocation = makeStorageLocationAbsolute(storageLocation);
1201 rs.resourceType = resourceType;
1202 rs.resourceFileName = resourceFilename;
1203
1204 return rs;
1205}

References makeStorageLocationAbsolute(), KisResourceLocator::ResourceStorage::resourceFileName, KisResourceLocator::ResourceStorage::resourceType, and KisResourceLocator::ResourceStorage::storageLocation.

◆ hasStorage()

bool KisResourceLocator::hasStorage ( const QString & storageLocation)

hasStorage can be used to check whether the given storage already exists

Parameters
storageLocationthe name of the storage
Returns
true if the storage is known

Definition at line 941 of file KisResourceLocator.cpp.

942{
943 return d->storages.contains(document);
944}

References d.

◆ importResource()

KoResourceSP KisResourceLocator::importResource ( const QString & resourceType,
const QString & fileName,
QIODevice * device,
const bool allowOverwrite,
const QString & storageLocation = QString() )
private

importResource

Parameters
resourceType
fileNamefilename that should be assigned to the resource
deviceQIODevice where the resource should be loaded from
storageLocationoptional, the storage where the resource will be stored. Empty means in the default Folder storage.
Returns
the imported resource, which has been added to the database and the cache

Make sure that this resource is the latest version of the resource. Also, we cannot just return existingResource, because it has uninitialized fields. It should go through the initialization by the locator's caching system.

Definition at line 457 of file KisResourceLocator.cpp.

458{
459 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
460 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(storage, nullptr);
461
462 QByteArray resourceData = device->readAll();
464
465 {
466 QBuffer buf(&resourceData);
467 buf.open(QBuffer::ReadOnly);
468
470
471 if (!loader) {
472 qWarning() << "Could not import" << fileName << ": resource doesn't load.";
473 return nullptr;
474 }
475
476 resource = loader->load(QFileInfo(fileName).fileName(), buf, KisGlobalResourcesInterface::instance());
477 }
478
479 if (!resource || !resource->valid()) {
480 qWarning() << "Could not import" << fileName << ": resource doesn't load.";
481 return nullptr;
482 }
483
484 const QString md5 = KoMD5Generator::generateHash(resourceData);
485 const QString resourceUrl = resourceType + "/" + resource->filename();
486
487 KoResourceSP existingResource = storage->resource(resourceUrl);
488
489 if (existingResource) {
490 const QString existingResourceMd5Sum = storage->resourceMd5(resourceUrl);
491
492 if (!allowOverwrite) {
493 return nullptr;
494 }
495
496 if (existingResourceMd5Sum == md5 &&
497 existingResource->filename() == resource->filename()) {
498
506 int existingResourceId = -1;
507 bool r = KisResourceCacheDb::getResourceIdFromFilename(existingResource->filename(), resourceType, storageLocation, existingResourceId);
508
509 if (r && existingResourceId > 0) {
510 return resourceForId(existingResourceId);
511 }
512 }
513
514 qWarning() << "A resource with the same filename but a different MD5 already exists in the storage" << resourceType << fileName << storageLocation;
515 if (storageLocation == "") {
516 qWarning() << "Proceeding with overwriting the existing resource...";
517 // remove all versions of the resource from the resource folder
518 QStringList versionsLocations;
519
520 // this resource has id -1, we need correct id
521 int existingResourceId = -1;
522 bool r = KisResourceCacheDb::getResourceIdFromVersionedFilename(existingResource->filename(), resourceType, storageLocation, existingResourceId);
523
524 if (r && existingResourceId >= 0) {
525 if (KisResourceCacheDb::getAllVersionsLocations(existingResourceId, versionsLocations)) {
526
527 for (int i = 0; i < versionsLocations.size(); i++) {
528 QFileInfo fi(this->resourceLocationBase() + "/" + resourceType + "/" + versionsLocations[i]);
529 if (fi.exists()) {
530 r = QFile::remove(fi.filePath());
531 if (!r) {
532 qWarning() << "KisResourceLocator::importResourceFromFile: Removal of " << fi.filePath()
533 << "was requested, but it wasn't possible, something went wrong.";
534 }
535 } else {
536 qWarning() << "KisResourceLocator::importResourceFromFile: Removal of " << fi.filePath()
537 << "was requested, but it doesn't exist.";
538 }
539 }
540 } else {
541 qWarning() << "KisResourceLocator::importResourceFromFile: Finding all locations for " << existingResourceId << "was requested, but it failed.";
542 return nullptr;
543 }
544 } else {
545 qWarning() << "KisResourceLocator::importResourceFromFile: there is no resource file found in the location of " << storageLocation << resource->filename() << resourceType;
546 return nullptr;
547 }
548
549 Q_EMIT beginExternalResourceRemove(resourceType, {existingResourceId});
550
551 // remove everything related to this resource from the database (remember about tags and versions!!!)
553
554 {
555 const QString absoluteStorageLocation = makeStorageLocationAbsolute(resource->storageLocation());
556 KisResourceThumbnailCache::instance()->remove(absoluteStorageLocation, resourceType, existingResource->filename());
557 }
558
559 Q_EMIT endExternalResourceRemove(resourceType);
560
561 if (!r) {
562 qWarning() << "KisResourceLocator::importResourceFromFile: Removing resource with id " << existingResourceId << "completely from the database failed.";
563 return nullptr;
564 }
565
566 } else {
567 qWarning() << "KisResourceLocator::importResourceFromFile: Overwriting of the resource was denied, aborting import.";
568 return nullptr;
569 }
570 }
571
572 QBuffer buf(&resourceData);
573 buf.open(QBuffer::ReadOnly);
574
575 if (storage->importResource(resourceUrl, &buf)) {
576 resource = storage->resource(resourceUrl);
577
578 if (!resource) {
579 qWarning() << "Could not retrieve imported resource from the storage" << resourceType << fileName << storageLocation;
580 return nullptr;
581 }
582
583 resource->setStorageLocation(storageLocation);
584 resource->setMD5Sum(storage->resourceMd5(resourceUrl));
585 resource->setVersion(0);
586 resource->setDirty(false);
588
589 Q_EMIT beginExternalResourceImport(resourceType, 1);
590
591 // Insert into the database
592 const bool result = KisResourceCacheDb::addResource(storage,
593 storage->timeStampForResource(resourceType, resource->filename()),
594 resource,
595 resourceType);
596
597 Q_EMIT endExternalResourceImport(resourceType);
598
599 if (!result) {
600 return nullptr;
601 }
602
603 // resourceCaches use absolute locations
604 const QString absoluteStorageLocation = makeStorageLocationAbsolute(resource->storageLocation());
605 const QPair<QString, QString> key = {absoluteStorageLocation, resourceType + "/" + resource->filename()};
606 // Add to the cache
607 d->resourceCache[key] = resource;
609
610 return resource;
611 }
612
613 return nullptr;
614}
static KisResourcesInterfaceSP instance()
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
static bool getAllVersionsLocations(int resourceId, QStringList &outVersionsLocationsList)
static bool getResourceIdFromFilename(QString filename, QString resourceType, QString storageLocation, int &outResourceId)
The function will find the resource only if it is the latest version.
static bool removeResourceCompletely(int resourceId)
static bool getResourceIdFromVersionedFilename(QString filename, QString resourceType, QString storageLocation, int &outResourceId)
Note that here you can put even the original filename - any filename from the versioned_resources - a...
The KisResourceLoader class is an abstract interface class that must be implemented by actual resourc...
bool load(KoResourceSP resource, QIODevice &dev, KisResourcesInterfaceSP resourcesInterface)
KisResourceLoaderBase * loader(const QString &resourceType, const QString &mimetype) const
void endExternalResourceRemove(const QString &resourceType)
Emitted when the locator finished importing the embedded resource.
QString resourceLocationBase() const
resourceLocationBase is the place where all resource storages (folder, bundles etc....
void beginExternalResourceRemove(const QString &resourceType, const QVector< int > resourceIds)
Emitted when the locator needs to add an embedded resource.
KoResourceSP resourceForId(int resourceId)
resourceForId returns the resource with the given id, or 0 if no such resource exists....
void insert(const QString &storageLocation, const QString &resourceType, const QString &filename, const QImage &image)
static KisResourceThumbnailCache * instance()
void remove(const QString &storageLocation, const QString &resourceType, const QString &filename)
static QString generateHash(const QString &filename)
generateHash reads the given file and generates a hex-encoded md5sum for the file.

References KisResourceCacheDb::addResource(), beginExternalResourceImport(), beginExternalResourceRemove(), d, endExternalResourceImport(), endExternalResourceRemove(), KoMD5Generator::generateHash(), KisResourceCacheDb::getAllVersionsLocations(), KisResourceCacheDb::getResourceIdFromFilename(), KisResourceCacheDb::getResourceIdFromVersionedFilename(), KisResourceThumbnailCache::insert(), KisGlobalResourcesInterface::instance(), KisResourceLoaderRegistry::instance(), KisResourceThumbnailCache::instance(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, KisResourceLoaderBase::load(), KisResourceLoaderRegistry::loader(), loadRequiredResources(), makeStorageLocationAbsolute(), KisMimeDatabase::mimeTypeForFile(), KisResourceThumbnailCache::remove(), KisResourceCacheDb::removeResourceCompletely(), resource(), resourceForId(), and resourceLocationBase().

◆ importResourceDeduplicateFileName()

KoResourceSP KisResourceLocator::importResourceDeduplicateFileName ( const QString & resourceType,
const QString & proposedFileName,
QIODevice * device,
const QString & storageLocation = QString() )
private

importResourceDeduplicateFileName imports the resource fith file name deduplication

When loading embedded resources from another resources, we should make sure they do not overwrite anything and land in the database unconditionally. That is why we might need to rename them on loading. The parent resource will (hopefully) still be able to address them using md5sum.

Parameters
resourceType
proposedFileNamefilename that should be assigned to the resource (will possibly be changed)
deviceQIODevice where the resource should be loaded from
storageLocationoptional, the storage where the resource will be stored. Empty means in the default Folder storage.
Returns
the imported resource, which has been added to the database and the cache

Definition at line 629 of file KisResourceLocator.cpp.

630{
631 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
632 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(storage, nullptr);
633
634 const QString fileName = findDeduplicatedFileName(resourceType, proposedFileName, storage);
635 return importResource(resourceType, fileName, device, false, storageLocation);
636}
KoResourceSP importResource(const QString &resourceType, const QString &fileName, QIODevice *device, const bool allowOverwrite, const QString &storageLocation=QString())
importResource

References d, importResource(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, and makeStorageLocationAbsolute().

◆ importResourceFromFile()

KoResourceSP KisResourceLocator::importResourceFromFile ( const QString & resourceType,
const QString & fileName,
const bool allowOverwrite,
const QString & storageLocation = QString() )
private

importResourceFromFile

Parameters
resourceType
fileName
storageLocationoptional, the storage where the resource will be stored. Empty means in the default Folder storage.
Returns
the imported resource, which has been added to the database and the cache

Definition at line 446 of file KisResourceLocator.cpp.

447{
448 QFile f(fileName);
449 if (!f.open(QFile::ReadOnly)) {
450 qWarning() << "Could not open" << fileName << "for loading";
451 return nullptr;
452 }
453
454 return importResource(resourceType, fileName, &f, allowOverwrite, storageLocation);
455}

References importResource().

◆ importWillOverwriteResource()

bool KisResourceLocator::importWillOverwriteResource ( const QString & resourceType,
const QString & fileName,
const QString & storageLocation = QString() ) const
private

return whether importing will overwrite some existing resource

Parameters
resourceType
fileNamefilename that should be assigned to the resource
storageLocationoptional, the storage where the resource will be stored. Empty means in the default Folder storage.

Definition at line 655 of file KisResourceLocator.cpp.

656{
657 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
659
660 const QString resourceUrl = resourceType + "/" + QFileInfo(fileName).fileName();
661
662 KoResourceSP existingResource = storage->resource(resourceUrl);
663
664 return !existingResource.isNull();
665}

References d, KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, and makeStorageLocationAbsolute().

◆ initialize()

KisResourceLocator::LocatorError KisResourceLocator::initialize ( const QString & installationResourcesLocation)

initialize Setup the resource locator for use.

Parameters
installationResourcesLocationthe place where the resources that come packaged with Krita reside.

Definition at line 94 of file KisResourceLocator.cpp.

95{
97
98 d->resourceLocation = KoResourcePaths::getAppDataLocation();
99
100 if (!d->resourceLocation.endsWith('/')) d->resourceLocation += '/';
101
102 QFileInfo fi(d->resourceLocation);
103
104 if (!fi.exists()) {
105 if (!QDir().mkpath(d->resourceLocation)) {
106 d->errorMessages << i18n("1. Could not create the resource location at %1.", d->resourceLocation);
108 }
109 initializationStatus = InitializationStatus::FirstRun;
110 }
111
112 if (!fi.isWritable()) {
113 d->errorMessages << i18n("2. The resource location at %1 is not writable.", d->resourceLocation);
115 }
116
117 // Check whether we're updating from an older version
118 if (initializationStatus != InitializationStatus::FirstRun) {
119 QFile fi(d->resourceLocation + '/' + "KRITA_RESOURCE_VERSION");
120 if (!fi.open(QFile::ReadOnly)) {
121 initializationStatus = InitializationStatus::FirstUpdate;
122 }
123 else {
124 QVersionNumber resource_version = QVersionNumber::fromString(QString::fromUtf8(fi.readAll()));
125 QVersionNumber krita_version = QVersionNumber::fromString(KritaVersionWrapper::versionString());
126 if (krita_version > resource_version) {
127 initializationStatus = InitializationStatus::Updating;
128 }
129 else {
130 initializationStatus = InitializationStatus::Initialized;
131 }
132 }
133 }
134
135 if (initializationStatus != InitializationStatus::Initialized) {
136 KisResourceLocator::LocatorError res = firstTimeInstallation(initializationStatus, installationResourcesLocation);
137 if (res != LocatorError::Ok) {
138 return res;
139 }
140 initializationStatus = InitializationStatus::Initialized;
141 }
142
143 if (!synchronizeDb()) {
145 }
146
147 return LocatorError::Ok;
148}
LocatorError firstTimeInstallation(InitializationStatus initializationStatus, const QString &installationResourcesLocation)
static QString getAppDataLocation()

References CannotCreateLocation, CannotSynchronizeDb, d, FirstRun, firstTimeInstallation(), FirstUpdate, KoResourcePaths::getAppDataLocation(), Initialized, LocationReadOnly, Ok, synchronizeDb(), Unknown, Updating, and KritaVersionWrapper::versionString().

◆ instance()

KisResourceLocator * KisResourceLocator::instance ( )
static

Definition at line 79 of file KisResourceLocator.cpp.

80{
81 // Not a regular Q_GLOBAL_STATIC, because we want this deleted as
82 // part of the app destructor.
83 KisResourceLocator *locator = qApp->findChild<KisResourceLocator *>(QString());
84 if (!locator) {
85 locator = new KisResourceLocator(qApp);
86 }
87 return locator;
88}
KisResourceLocator(QObject *parent)

References KisResourceLocator().

◆ loadRequiredResources()

void KisResourceLocator::loadRequiredResources ( KoResourceSP resource)
private

Loads all the resources required by resource into the cache

loadRequiredResources() also loads embedded resources and adds them into the database.

First load the side-loaded resources, since they may be linked by the linked resources.

Now load the linked resources

Definition at line 168 of file KisResourceLocator.cpp.

169{
170 auto loadResourcesGroup =
171 [this, parentResource = resource] (QList<KoResourceLoadResult> resources,
172 const QString &resourceGroup) {
173
174 Q_FOREACH (KoResourceLoadResult res, resources) {
175 switch (res.type())
176 {
178 KIS_SAFE_ASSERT_RECOVER_NOOP(res.resource()->resourceId() >= 0);
179 break;
182 QByteArray data = res.embeddedResource().data();
183 QBuffer buffer(&data);
184 buffer.open(QBuffer::ReadOnly);
185 importResourceDeduplicateFileName(sig.type, sig.filename, &buffer, "memory");
186 break;
187 }
189 qWarning() << "Failed to load" << resourceGroup << "resource:" << res.signature();
190 break;
191 }
192 }
193 };
194
199 loadResourcesGroup(resource->takeSideLoadedResources(KisGlobalResourcesInterface::instance()), "side-loaded");
200
204 loadResourcesGroup(resource->requiredResources(KisGlobalResourcesInterface::instance()), "linked");
205}
KoResourceSP importResourceDeduplicateFileName(const QString &resourceType, const QString &proposedFileName, QIODevice *device, const QString &storageLocation=QString())
importResourceDeduplicateFileName imports the resource fith file name deduplication
const KoResourceSignature & signature() const
QByteArray data() const
KoResourceSP resource() const noexcept
KoEmbeddedResource embeddedResource() const noexcept
KoResourceSignature signature() const
A simple wrapper object for the main information about the resource.
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130

References KoEmbeddedResource::data(), KoResourceLoadResult::EmbeddedResource, KoResourceLoadResult::embeddedResource(), KoResourceLoadResult::ExistingResource, KoResourceLoadResult::FailedLink, KoResourceSignature::filename, importResourceDeduplicateFileName(), KisGlobalResourcesInterface::instance(), KIS_SAFE_ASSERT_RECOVER_NOOP, KoResourceLoadResult::resource(), resource(), KoEmbeddedResource::signature(), KoResourceLoadResult::signature(), KoResourceLoadResult::type(), and KoResourceSignature::type.

◆ makeStorageLocationAbsolute()

QString KisResourceLocator::makeStorageLocationAbsolute ( QString storageLocation) const
private

Definition at line 1207 of file KisResourceLocator.cpp.

1208{
1209// debugResource << "makeStorageLocationAbsolute" << storageLocation;
1210
1211 if (storageLocation.isEmpty()) {
1212 return resourceLocationBase();
1213 }
1214
1215 if (QFileInfo(storageLocation).isRelative() && (storageLocation.endsWith(".bundle", Qt::CaseInsensitive)
1216 || storageLocation.endsWith(".asl", Qt::CaseInsensitive)
1217 || storageLocation.endsWith(".abr", Qt::CaseInsensitive))) {
1218 if (resourceLocationBase().endsWith('/') || resourceLocationBase().endsWith("\\")) {
1219 storageLocation = resourceLocationBase() + storageLocation;
1220 }
1221 else {
1222 storageLocation = resourceLocationBase() + '/' + storageLocation;
1223 }
1224 }
1225
1226// debugResource << "\t" << storageLocation;
1227 return storageLocation;
1228}

References resourceLocationBase().

◆ makeStorageLocationRelative()

QString KisResourceLocator::makeStorageLocationRelative ( QString location) const
private

Definition at line 1300 of file KisResourceLocator.cpp.

1301{
1302// debugResource << "makeStorageLocationRelative" << location << "locationbase" << resourceLocationBase();
1303 return location.remove(resourceLocationBase());
1304}

References resourceLocationBase().

◆ memoryStorage()

KisResourceStorageSP KisResourceLocator::memoryStorage ( ) const
private

Definition at line 1156 of file KisResourceLocator.cpp.

1157{
1158 return storageByLocation("memory");
1159}

References storageByLocation().

◆ metaDataForResource()

QMap< QString, QVariant > KisResourceLocator::metaDataForResource ( int id) const
private

metaDataForResource

Parameters
id
Returns

Definition at line 791 of file KisResourceLocator.cpp.

792{
793 return KisResourceCacheDb::metaDataForId(id, "resources");
794}
static QMap< QString, QVariant > metaDataForId(int id, const QString &tableName)
metaDataForId

References KisResourceCacheDb::metaDataForId().

◆ metaDataForStorage()

QMap< QString, QVariant > KisResourceLocator::metaDataForStorage ( const QString & storageLocation) const
private

metaDataForStorage

Parameters
storage
Returns

Definition at line 801 of file KisResourceLocator.cpp.

802{
803 QMap<QString, QVariant> metadata;
804
805 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
806 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(storage, metadata);
807
808 Q_FOREACH(const QString key, storage->metaDataKeys()) {
809 metadata[key] = storage->metaData(key);
810 }
811 return metadata;
812}

References d, KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, and makeStorageLocationAbsolute().

◆ operator=()

KisResourceLocator KisResourceLocator::operator= ( const KisResourceLocator & )
private

◆ progressMessage

void KisResourceLocator::progressMessage ( const QString & )
signal

◆ purge()

void KisResourceLocator::purge ( const QString & storageLocation,
const QVector< int > & removedTagIds )

purge purges the local resource cache

Definition at line 824 of file KisResourceLocator.cpp.

825{
826 Q_FOREACH(const auto key, d->resourceCache.keys()) {
827 if (key.first == storageLocation) {
828 d->resourceCache.remove(key);
830 }
831 }
832
833 for (auto it = d->tagCache.begin(); it != d->tagCache.end();) {
834 if (removedTagIds.contains(it.value()->id())) {
835 it = d->tagCache.erase(it);
836 } else {
837 ++it;
838 }
839 }
840}

References d, KisResourceThumbnailCache::instance(), and KisResourceThumbnailCache::remove().

◆ purgeTag()

void KisResourceLocator::purgeTag ( const QString tagUrl,
const QString resourceType )

Remove the given tag from the cache

Definition at line 1018 of file KisResourceLocator.cpp.

1019{
1020 d->tagCache.remove(QPair<QString, QString>(resourceType, tagUrl));
1021}

References d.

◆ reloadResource()

bool KisResourceLocator::reloadResource ( const QString & resourceType,
const KoResourceSP resource )
private

Reloads the resource from its persistent storage.

Parameters
resourceTypethe type of the resource
resourcethe actual resource object
Returns
true if reloading was successful. When returned false, resource is kept unchanged

Definition at line 766 of file KisResourceLocator.cpp.

767{
768 // This resource isn't in the database yet, so we cannot reload it
769 if (resource->resourceId() < 0) return false;
770
771 QString storageLocation = makeStorageLocationAbsolute(resource->storageLocation());
772 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
774
775 if (!storage->loadVersionedResource(resource)) {
776 qWarning() << "Failed to reload the resource" << resource->name() << "from storage" << storageLocation;
777 return false;
778 }
779
780 resource->setMD5Sum(storage->resourceMd5(resourceType + "/" + resource->filename()));
781 resource->setDirty(false);
783
784 // We haven't changed the version of the resource, so the cache must be still valid
785 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType + "/" + resource->filename());
786 Q_ASSERT(d->resourceCache[key] == resource);
787
788 return true;
789}

References d, KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, loadRequiredResources(), makeStorageLocationAbsolute(), and resource().

◆ removeStorage()

bool KisResourceLocator::removeStorage ( const QString & storageLocation)

removeStorage removes the temporary storage from the database

Parameters
storageLocationthe unique name of the storage
Returns
true is successful.

Definition at line 891 of file KisResourceLocator.cpp.

892{
893 // Cloned documents have a document storage, but that isn't in the locator.
894 if (!d->storages.contains(storageLocation)) {
895 return true;
896 }
897
899
900 Q_FOREACH(const QString &type, KisResourceLoaderRegistry::instance()->resourceTypes()) {
901 const QVector<int> resources = KisResourceCacheDb::resourcesForStorage(type, storageLocation);
902 if (!resources.isEmpty()) {
903 removedResources << std::make_pair(type, resources);
904 }
905 }
906
908 QVector<int> allRemovedTagIds;
909 Q_FOREACH(const QString &type, KisResourceLoaderRegistry::instance()->resourceTypes()) {
910 auto [uniqueTags, sharedTags] = KisResourceCacheDb::tagsForStorage(type, storageLocation);
911 removedTags << std::make_pair(type, uniqueTags);
912 allRemovedTagIds << uniqueTags;
913 }
914
915 Q_FOREACH (const auto &typedResources, removedResources) {
916 Q_EMIT beginExternalResourceRemove(typedResources.first, typedResources.second);
917 }
918
919 // TODO: add model notification about removed tags
920 Q_UNUSED(removedTags);
921
922 purge(storageLocation, allRemovedTagIds);
923
924 KisResourceStorageSP storage = d->storages.take(storageLocation);
925
926 if (!KisResourceCacheDb::deleteStorage(storage)) {
927 d->errorMessages.append(i18n("Could not remove storage %1 from the database", storage->location()));
928 qWarning() << d->errorMessages;
929 return false;
930 }
931
932 Q_FOREACH (const auto &typedResources, removedResources) {
933 Q_EMIT endExternalResourceRemove(typedResources.first);
934 }
935
936 Q_EMIT storageRemoved(makeStorageLocationRelative(storage->location()));
937
938 return true;
939}
static QVector< int > resourcesForStorage(const QString &resourceType, const QString &storageLocation)
static bool deleteStorage(KisResourceStorageSP storage)
Actually delete the storage and all its resources from the database (i.e., nothing is set to inactive...
static std::pair< QVector< int >, QVector< int > > tagsForStorage(const QString &resourceType, const QString &storageLocation)
void storageRemoved(const QString &location)
Emitted whenever a storage is removed.
void purge(const QString &storageLocation, const QVector< int > &removedTagIds)
purge purges the local resource cache

References beginExternalResourceRemove(), d, KisResourceCacheDb::deleteStorage(), endExternalResourceRemove(), KisResourceLoaderRegistry::instance(), makeStorageLocationRelative(), purge(), KisResourceCacheDb::resourcesForStorage(), storageRemoved(), and KisResourceCacheDb::tagsForStorage().

◆ resource()

KoResourceSP KisResourceLocator::resource ( QString storageLocation,
const QString & resourceType,
const QString & filename )
private

resource finds a physical resource in one of the storages

Parameters
storageLocationthe storage containing the resource. If empty, this is the folder storage.

Note that the resource does not have the version or id field set, so this cannot be used directly, but only through KisResourceModel.

Parameters
resourceTypethe type of the resource
filenamethe filename of the resource including extension, but without any paths
Returns
A resource if found, or 0

Definition at line 331 of file KisResourceLocator.cpp.

332{
333 storageLocation = makeStorageLocationAbsolute(storageLocation);
334
335 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType + "/" + filename);
336
338 if (d->resourceCache.contains(key)) {
339 resource = d->resourceCache[key];
340 }
341 else {
342 KisResourceStorageSP storage = d->safeGetStorage(storageLocation);
343 if (!storage) {
344 return 0;
345 }
346
347 resource = storage->resource(resourceType + "/" + filename);
348
349 if (resource) {
350 d->resourceCache[key] = resource;
351 // load all the embedded resources into temporary "memory" storage
353 }
354 }
355
356 if (!resource) {
357 qWarning() << "KoResourceSP KisResourceLocator::resource" << storageLocation << resourceType << filename << "was not found";
358 return 0;
359 }
360
361 resource->setStorageLocation(storageLocation);
362 Q_ASSERT(!resource->storageLocation().isEmpty());
363
364 if (resource->resourceId() < 0 || resource->version() < 0) {
365 QSqlQuery q;
366 if (!q.prepare("SELECT resources.id\n"
367 ", versioned_resources.version as version\n"
368 ", versioned_resources.md5sum as md5sum\n"
369 ", resources.name\n"
370 ", resources.status\n"
371 "FROM resources\n"
372 ", storages\n"
373 ", resource_types\n"
374 ", versioned_resources\n"
375 "WHERE storages.id = resources.storage_id\n"
376 "AND storages.location = :storage_location\n"
377 "AND resource_types.id = resources.resource_type_id\n"
378 "AND resource_types.name = :resource_type\n"
379 "AND resources.filename = :filename\n"
380 "AND versioned_resources.resource_id = resources.id\n"
381 "AND versioned_resources.version = (SELECT MAX(version) FROM versioned_resources WHERE versioned_resources.resource_id = resources.id)")) {
382 qWarning() << "Could not prepare id/version query" << q.lastError();
383
384 }
385
386 q.bindValue(":storage_location", makeStorageLocationRelative(storageLocation));
387 q.bindValue(":resource_type", resourceType);
388 q.bindValue(":filename", filename);
389
390 if (!q.exec()) {
391 qWarning() << "Could not execute id/version query" << q.lastError() << q.boundValues();
392 }
393
394 if (!q.first()) {
395 qWarning() << "Could not find the resource in the database" << storageLocation << resourceType << filename;
396 }
397
398 resource->setResourceId(q.value(0).toInt());
399 Q_ASSERT(resource->resourceId() >= 0);
400
401 resource->setVersion(q.value(1).toInt());
402 Q_ASSERT(resource->version() >= 0);
403
404 resource->setMD5Sum(q.value(2).toString());
405 Q_ASSERT(!resource->md5Sum().isEmpty());
406
407 resource->setActive(q.value(4).toBool());
408
409 // To override resources that use the filename for the name, which is versioned, and we don't want the version number in the name
410 resource->setName(q.value(3).toString());;
411 }
412
413 if (!resource) {
414 qWarning() << "Could not find resource" << resourceType + "/" + filename;
415 return 0;
416 }
417
418 return resource;
419}

References d, loadRequiredResources(), makeStorageLocationAbsolute(), makeStorageLocationRelative(), and resource().

◆ resourceActiveStateChanged

void KisResourceLocator::resourceActiveStateChanged ( const QString & resourceType,
int resourceId )
signal

Emitted when a resource changes its active state.

◆ resourceCached()

bool KisResourceLocator::resourceCached ( QString storageLocation,
const QString & resourceType,
const QString & filename ) const
private
Returns
true if the resource is present in the cache, false if it hasn't been loaded

Definition at line 160 of file KisResourceLocator.cpp.

161{
162 storageLocation = makeStorageLocationAbsolute(storageLocation);
163 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType + "/" + filename);
164
165 return d->resourceCache.contains(key);
166}

References d, and makeStorageLocationAbsolute().

◆ resourceForId()

KoResourceSP KisResourceLocator::resourceForId ( int resourceId)
private

resourceForId returns the resource with the given id, or 0 if no such resource exists. The resource object will have its id set but not its version.

Parameters
resourceIdthe id

Definition at line 421 of file KisResourceLocator.cpp.

422{
423 ResourceStorage rs = getResourceStorage(resourceId);
424 KoResourceSP r = resource(rs.storageLocation, rs.resourceType, rs.resourceFileName);
425 return r;
426}
ResourceStorage getResourceStorage(int resourceId) const

References getResourceStorage(), resource(), KisResourceLocator::ResourceStorage::resourceFileName, KisResourceLocator::ResourceStorage::resourceType, and KisResourceLocator::ResourceStorage::storageLocation.

◆ resourceLocationBase()

QString KisResourceLocator::resourceLocationBase ( ) const

resourceLocationBase is the place where all resource storages (folder, bundles etc. are located. This is a writable place.

Returns
the base location for all storages.

Definition at line 155 of file KisResourceLocator.cpp.

156{
157 return d->resourceLocation;
158}

References d.

◆ saveTags()

void KisResourceLocator::saveTags ( )
static

saveTags saves all tags to .tag files in the resource folder

Definition at line 946 of file KisResourceLocator.cpp.

947{
948 QSqlQuery query;
949
950 if (!query.prepare("SELECT tags.url \n"
951 ", resource_types.name \n"
952 "FROM tags\n"
953 ", resource_types\n"
954 "WHERE tags.resource_type_id = resource_types.id\n"))
955 {
956 qWarning() << "Could not prepare save tags query" << query.lastError();
957 return;
958 }
959
960 if (!query.exec()) {
961 qWarning() << "Could not execute save tags query" << query.lastError();
962 return;
963 }
964
965 // this needs to use ResourcePaths because it is sometimes called during initialization
966 // (when the database versions don't match up and tags need to be saved)
967 QString resourceLocation = KoResourcePaths::getAppDataLocation() + "/";
968
969 while (query.next()) {
970 // Save tag...
971 KisTagSP tag = tagForUrlNoCache(query.value("tags.url").toString(),
972 query.value("resource_types.name").toString());
973
974 if (!tag || !tag->valid()) {
975 continue;
976 }
977
978
979 QString filename = tag->filename();
980 if (filename.isEmpty() || QFileInfo(filename).suffix().isEmpty()) {
981 filename = tag->url() + ".tag";
982 }
983
984
985 if (QFileInfo(filename).suffix() != "tag" && QFileInfo(filename).suffix() != "TAG") {
986 // it's either .abr file, or maybe a .bundle
987 // or something else, but not a tag file
988 dbgResources << "Skipping saving tag " << tag->name(false) << filename << tag->resourceType();
989 continue;
990 }
991
992 filename.remove(resourceLocation);
993
994 QFile f(resourceLocation + "/" + tag->resourceType() + '/' + filename);
995
996 if (!f.open(QFile::WriteOnly)) {
997 qWarning () << "Could not open tag file for writing" << f.fileName();
998 continue;
999 }
1000
1001 QBuffer buf;
1002 buf.open(QIODevice::WriteOnly);;
1003
1004 if (!tag->save(buf)) {
1005 qWarning() << "Could not save tag to" << f.fileName();
1006 buf.close();
1007 f.close();
1008 continue;
1009 }
1010
1011 f.write(buf.data());
1012 f.flush();
1013
1014 f.close();
1015 }
1016}
static KisTagSP tagForUrlNoCache(const QString &tagUrl, const QString resourceType)
tagForUrlNoCache create a tag from the database, don't use cache
#define dbgResources
Definition kis_debug.h:43

References dbgResources, KoResourcePaths::getAppDataLocation(), and tagForUrlNoCache().

◆ setMetaDataForResource()

bool KisResourceLocator::setMetaDataForResource ( int id,
QMap< QString, QVariant > map ) const
private

setMetaDataForResource

Parameters
id
map
Returns

Definition at line 796 of file KisResourceLocator.cpp.

797{
798 return KisResourceCacheDb::updateMetaDataForId(map, id, "resources");
799}
static bool updateMetaDataForId(const QMap< QString, QVariant > map, int id, const QString &tableName)
setMetaDataForId removes all metadata for the given id and table name, and inserts the metadata in th...

References KisResourceCacheDb::updateMetaDataForId().

◆ setMetaDataForStorage()

void KisResourceLocator::setMetaDataForStorage ( const QString & storageLocation,
QMap< QString, QVariant > map ) const
private

setMetaDataForStorage

Parameters
storage
map

Definition at line 814 of file KisResourceLocator.cpp.

815{
816 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
818
819 Q_FOREACH(const QString &key, map.keys()) {
820 storage->setMetaData(key, map[key]);
821 }
822}
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128

References d, KIS_SAFE_ASSERT_RECOVER_RETURN, and makeStorageLocationAbsolute().

◆ setResourceActive()

bool KisResourceLocator::setResourceActive ( int resourceId,
bool active )
private

setResourceActive

Parameters
resourceId
activeshows if the resource should be set as active or not
Returns

Definition at line 428 of file KisResourceLocator.cpp.

429{
430 // First remove the resource from the cache
431 ResourceStorage rs = getResourceStorage(resourceId);
432 QPair<QString, QString> key = QPair<QString, QString> (rs.storageLocation, rs.resourceType + "/" + rs.resourceFileName);
433
434 d->resourceCache.remove(key);
435 if (!active) {
437 }
438
439 bool result = KisResourceCacheDb::setResourceActive(resourceId, active);
440
441 Q_EMIT resourceActiveStateChanged(rs.resourceType, resourceId);
442
443 return result;
444}
static bool setResourceActive(int resourceId, bool active=false)
Make this resource active or inactive; this does not remove the resource from disk or from the databa...
void resourceActiveStateChanged(const QString &resourceType, int resourceId)
Emitted when a resource changes its active state.

References d, getResourceStorage(), KisResourceThumbnailCache::instance(), KisResourceThumbnailCache::remove(), resourceActiveStateChanged(), KisResourceLocator::ResourceStorage::resourceFileName, KisResourceLocator::ResourceStorage::resourceType, KisResourceCacheDb::setResourceActive(), and KisResourceLocator::ResourceStorage::storageLocation.

◆ storageAdded

void KisResourceLocator::storageAdded ( const QString & location)
signal

Emitted whenever a storage is added.

◆ storageByLocation()

KisResourceStorageSP KisResourceLocator::storageByLocation ( const QString & location) const
private

Definition at line 1140 of file KisResourceLocator.cpp.

1141{
1142 KisResourceStorageSP storage = d->safeGetStorage(location);
1143 if (!storage || !storage->valid()) {
1144 qWarning() << "Could not retrieve the" << location << "storage object or the object is not valid";
1145 return 0;
1146 }
1147
1148 return storage;
1149}

References d.

◆ storageRemoved

void KisResourceLocator::storageRemoved ( const QString & location)
signal

Emitted whenever a storage is removed.

◆ storageResynchronized

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

Emitted when a storage is resynchronized using KisresourceCacheDb::synchronizeStorage()

if isBulkResynchronization then this resynchronization happened as a part of bulk resynchronization at the start of Krita. At the end of this bulk action storagesBulkSynchronizationFinished() will be emitted as well.

◆ storages()

QList< KisResourceStorageSP > KisResourceLocator::storages ( ) const
private

Definition at line 1135 of file KisResourceLocator.cpp.

1136{
1137 return d->storages.values();
1138}

References d.

◆ storagesBulkSynchronizationFinished

void KisResourceLocator::storagesBulkSynchronizationFinished ( )
signal

Emitted when bulk-synchronization of all the storages has been finished

See also
storageResynchronized

◆ synchronizeDb()

bool KisResourceLocator::synchronizeDb ( )
private

In the current layout of the database we cannot set FOREIGN KEY for the metadata table (since it links to both, resources and storages), hence we should manually track the orphaned data.

Theoretically, these should be none, if our code is correct, but who knows anything about our code...

Definition at line 1230 of file KisResourceLocator.cpp.

1231{
1232 Q_EMIT progressMessage(i18n("Synchronizing the resources."));
1233
1234 d->errorMessages.clear();
1235
1236 // Add resource types that have been added since first-time installation.
1237 Q_FOREACH(auto loader, KisResourceLoaderRegistry::instance()->values()) {
1238 KisResourceCacheDb::registerResourceType(loader->resourceType());
1239 }
1240
1241
1242 findStorages();
1243 Q_FOREACH(const KisResourceStorageSP storage, d->storages) {
1245 d->errorMessages.append(i18n("Could not synchronize %1 with the database", storage->location()));
1246 } else {
1247 Q_EMIT storageResynchronized(storage->location(), true);
1248 }
1249 }
1250
1251 Q_FOREACH(const KisResourceStorageSP storage, d->storages) {
1252 if (!KisResourceCacheDb::addStorageTags(storage)) {
1253 d->errorMessages.append(i18n("Could not synchronize %1 with the database", storage->location()));
1254 }
1255 }
1256
1258
1268
1269 // now remove the storages that no longer exists
1270 KisStorageModel model;
1271
1272 QList<QString> storagesToRemove;
1273 for (int i = 0; i < model.rowCount(); i++) {
1274 QModelIndex idx = model.index(i, 0);
1275 QString location = model.data(idx, Qt::UserRole + KisStorageModel::Location).toString();
1276 storagesToRemove << location;
1277 }
1278
1279 for (int i = 0; i < storagesToRemove.size(); i++) {
1280 QString location = storagesToRemove[i];
1281 if (!d->storages.contains(this->makeStorageLocationAbsolute(location))) {
1282 if (!KisResourceCacheDb::deleteStorage(location)) {
1283 d->errorMessages.append(i18n("Could not remove storage %1 from the database", this->makeStorageLocationAbsolute(location)));
1284 qWarning() << d->errorMessages;
1285 return false;
1286 }
1287 Q_EMIT storageRemoved(this->makeStorageLocationAbsolute(location));
1288 }
1289 }
1290
1291
1292 d->errorMessages <<
1294
1295 d->resourceCache.clear();
1296 return d->errorMessages.isEmpty();
1297}
static bool removeOrphanedMetaData()
removeOrphanedMetaData Previous versions of Krita never removed metadata, so this function doublechec...
static bool registerResourceType(const QString &resourceType)
registerResourceType registers this resource type in the database
static bool synchronizeStorage(KisResourceStorageSP storage)
void storagesBulkSynchronizationFinished()
void storageResynchronized(const QString &storage, bool isBulkResynchronization)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override

References KisResourceCacheDb::addStorageTags(), d, KisStorageModel::data(), KisResourceCacheDb::deleteStorage(), KisResourceLoaderRegistry::executeAllFixups(), findStorages(), KisResourceLoaderRegistry::instance(), KisStorageModel::Location, makeStorageLocationAbsolute(), progressMessage(), KisResourceCacheDb::registerResourceType(), KisResourceCacheDb::removeOrphanedMetaData(), KisStorageModel::rowCount(), storageRemoved(), storageResynchronized(), storagesBulkSynchronizationFinished(), and KisResourceCacheDb::synchronizeStorage().

◆ tagForUrl()

KisTagSP KisResourceLocator::tagForUrl ( const QString & tagUrl,
const QString resourceType )
private

tagForUrl create a tag from the database

Parameters
tagUrlthe url
Returns
a complete tag with all translated names and comments.

Definition at line 207 of file KisResourceLocator.cpp.

208{
209 if (d->tagCache.contains(QPair<QString, QString>(resourceType, tagUrl))) {
210 return d->tagCache[QPair<QString, QString>(resourceType, tagUrl)];
211 }
212
213 KisTagSP tag = tagForUrlNoCache(tagUrl, resourceType);
214
215 if (tag && tag->valid()) {
216 d->tagCache[QPair<QString, QString>(resourceType, tagUrl)] = tag;
217 }
218
219 return tag;
220}

References d, and tagForUrlNoCache().

◆ tagForUrlNoCache()

KisTagSP KisResourceLocator::tagForUrlNoCache ( const QString & tagUrl,
const QString resourceType )
staticprivate

tagForUrlNoCache create a tag from the database, don't use cache

Parameters
tagUrlurl of the tag
resourceTyperesource type of the tag
Returns

Definition at line 222 of file KisResourceLocator.cpp.

223{
224 QSqlQuery query;
225 bool r = query.prepare("SELECT tags.id\n"
226 ", tags.url\n"
227 ", tags.active\n"
228 ", tags.name\n"
229 ", tags.comment\n"
230 ", tags.filename\n"
231 ", resource_types.name as resource_type\n"
232 ", resource_types.id\n"
233 "FROM tags\n"
234 ", resource_types\n"
235 "WHERE tags.resource_type_id = resource_types.id\n"
236 "AND resource_types.name = :resource_type\n"
237 "AND tags.url = :tag_url\n");
238
239 if (!r) {
240 qWarning() << "Could not prepare KisResourceLocator::tagForUrl query" << query.lastError();
241 return KisTagSP();
242 }
243
244 query.bindValue(":resource_type", resourceType);
245 query.bindValue(":tag_url", tagUrl);
246
247 r = query.exec();
248 if (!r) {
249 qWarning() << "Could not execute KisResourceLocator::tagForUrl query" << query.lastError() << query.boundValues();
250 return KisTagSP();
251 }
252
253 r = query.first();
254 if (!r) {
255 return KisTagSP();
256 }
257
258 KisTagSP tag(new KisTag());
259
260 int tagId = query.value("tags.id").toInt();
261 int resourceTypeId = query.value("resource_types.id").toInt();
262
263 tag->setUrl(query.value("url").toString());
264 tag->setResourceType(resourceType);
265 tag->setId(query.value("id").toInt());
266 tag->setActive(query.value("active").toBool());
267 tag->setName(query.value("name").toString());
268 tag->setComment(query.value("comment").toString());
269 tag->setFilename(query.value("filename").toString());
270 tag->setValid(true);
271
272
273 QMap<QString, QString> names;
274 QMap<QString, QString> comments;
275
276 r = query.prepare("SELECT language\n"
277 ", name\n"
278 ", comment\n"
279 "FROM tag_translations\n"
280 "WHERE tag_id = :id");
281
282 if (!r) {
283 qWarning() << "Could not prepare KisResourceLocator::tagForUrl translation query" << query.lastError();
284 }
285
286 query.bindValue(":id", tag->id());
287
288 if (!query.exec()) {
289 qWarning() << "Could not execute KisResourceLocator::tagForUrl translation query" << query.lastError();
290 }
291
292 while (query.next()) {
293 names[query.value(0).toString()] = query.value(1).toString();
294 comments[query.value(0).toString()] = query.value(2).toString();
295 }
296
297 tag->setNames(names);
298 tag->setComments(comments);
299
300 QSqlQuery defaultResourcesQuery;
301
302 if (!defaultResourcesQuery.prepare("SELECT resources.filename\n"
303 "FROM resources\n"
304 ", resource_tags\n"
305 "WHERE resource_tags.tag_id = :tag_id\n"
306 "AND resources.resource_type_id = :type_id\n"
307 "AND resource_tags.resource_id = resources.id\n"
308 "AND resource_tags.active = 1\n")) {
309 qWarning() << "Could not prepare resource/tag query" << defaultResourcesQuery.lastError();
310 }
311
312 defaultResourcesQuery.bindValue(":tag_id", tagId);
313 defaultResourcesQuery.bindValue(":type_id", resourceTypeId);
314
315 if (!defaultResourcesQuery.exec()) {
316 qWarning() << "Could not execute resource/tag query" << defaultResourcesQuery.lastError();
317 }
318
319 QStringList resourceFileNames;
320
321 while (defaultResourcesQuery.next()) {
322 resourceFileNames << defaultResourcesQuery.value("resources.filename").toString();
323 }
324
325 tag->setDefaultResources(resourceFileNames);
326
327 return tag;
328}
QSharedPointer< KisTag > KisTagSP
Definition KisTag.h:20
The KisTag loads a tag from a .tag file. A .tag file is a .desktop file. The following fields are imp...
Definition KisTag.h:34

◆ updateFontStorage()

void KisResourceLocator::updateFontStorage ( )

This updates the "fontregistry" storage. Called when the font directories change;.

Definition at line 1033 of file KisResourceLocator.cpp.

1034{
1036 qWarning() << i18n("Could not synchronize updated font registry with the database");
1037 } else {
1038 Q_EMIT storageResynchronized(fontStorage()->location(), false);
1039 }
1040}

References fontStorage(), storageResynchronized(), and KisResourceCacheDb::synchronizeStorage().

◆ updateResource()

bool KisResourceLocator::updateResource ( const QString & resourceType,
const KoResourceSP resource )
private

updateResource

Parameters
resourceType
resource
Returns

Definition at line 718 of file KisResourceLocator.cpp.

719{
720 QString storageLocation = makeStorageLocationAbsolute(resource->storageLocation());
721
722 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
724
725 if (resource->resourceId() < 0) {
726 return addResource(resourceType, resource);
727 }
728
729 if (!storage->supportsVersioning()) return false;
730
731 // remove older version
732 KisResourceThumbnailCache::instance()->remove(storageLocation, resourceType, resource->filename());
733
734 resource->updateThumbnail();
735 resource->setVersion(resource->version() + 1);
736 resource->setActive(true);
737
738 if (!storage->saveAsNewVersion(resource)) {
739 qWarning() << "Failed to save the new version of " << resource->name() << "to storage" << storageLocation;
740 return false;
741 }
742
743 resource->setMD5Sum(storage->resourceMd5(resourceType + "/" + resource->filename()));
744 resource->setDirty(false);
746
747 // The version needs already to have been incremented
748 if (!KisResourceCacheDb::addResourceVersion(resource->resourceId(), QDateTime::currentDateTime(), storage, resource)) {
749 qWarning() << "Failed to add a new version of the resource to the database" << resource->name();
750 return false;
751 }
752
753 if (!setMetaDataForResource(resource->resourceId(), resource->metadata())) {
754 qWarning() << "Failed to update resource metadata" << resource;
755 return false;
756 }
757
758 // Update the resource in the cache
759 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType + "/" + resource->filename());
760 d->resourceCache[key] = resource;
762
763 return true;
764}
static bool addResourceVersion(int resourceId, QDateTime timestamp, KisResourceStorageSP storage, KoResourceSP resource)
addResourceVersion adds a new version of the resource to the database. The resource itself already sh...
bool setMetaDataForResource(int id, QMap< QString, QVariant > map) const
setMetaDataForResource

References addResource(), KisResourceCacheDb::addResourceVersion(), d, KisResourceThumbnailCache::insert(), KisResourceThumbnailCache::instance(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, loadRequiredResources(), makeStorageLocationAbsolute(), KisResourceThumbnailCache::remove(), resource(), and setMetaDataForResource().

Friends And Related Symbol Documentation

◆ KisAllResourcesModel

friend class KisAllResourcesModel
friend

Definition at line 166 of file KisResourceLocator.h.

◆ KisAllTagResourceModel

friend class KisAllTagResourceModel
friend

Definition at line 167 of file KisResourceLocator.h.

◆ KisAllTagsModel

friend class KisAllTagsModel
friend

Definition at line 164 of file KisResourceLocator.h.

◆ KisBrushTypeMetaDataFixup

friend class KisBrushTypeMetaDataFixup
friend

Definition at line 176 of file KisResourceLocator.h.

◆ KisMyPaintPaintOpPreset

friend class KisMyPaintPaintOpPreset
friend

Definition at line 387 of file KisResourceLocator.h.

◆ KisResourceCacheDb

friend class KisResourceCacheDb
friend

Definition at line 172 of file KisResourceLocator.h.

◆ KisResourceQueryMapper

friend class KisResourceQueryMapper
friend

Definition at line 174 of file KisResourceLocator.h.

◆ KisResourceThumbnailCache

friend class KisResourceThumbnailCache
friend

Definition at line 177 of file KisResourceLocator.h.

◆ KisResourceUserOperations

friend class KisResourceUserOperations
friend

Definition at line 175 of file KisResourceLocator.h.

◆ KisStorageFilterProxyModel

friend class KisStorageFilterProxyModel
friend

Definition at line 173 of file KisResourceLocator.h.

◆ KisStorageModel

friend class KisStorageModel
friend

Definition at line 168 of file KisResourceLocator.h.

◆ KisTagResourceModel

friend class KisTagResourceModel
friend

Definition at line 165 of file KisResourceLocator.h.

◆ Resource

friend class Resource
friend

Definition at line 171 of file KisResourceLocator.h.

◆ TestResourceLocator

friend class TestResourceLocator
friend

Definition at line 169 of file KisResourceLocator.h.

◆ TestResourceModel

friend class TestResourceModel
friend

Definition at line 170 of file KisResourceLocator.h.

Member Data Documentation

◆ d

QScopedPointer<Private> KisResourceLocator::d
private

Definition at line 394 of file KisResourceLocator.h.

◆ resourceLocationKey

const QString KisResourceLocator::resourceLocationKey {"ResourceDirectory"}
static

Definition at line 47 of file KisResourceLocator.h.

47{

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