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 678 of file KisResourceLocator.cpp.

679{
680 if (!resource || !resource->valid()) return false;
681
682 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
684
685 //If we have gotten this far and the resource still doesn't have a filename to save to, we should generate one.
686 if (resource->filename().isEmpty()) {
687 resource->setFilename(resource->name().split(" ").join("_") + resource->defaultFileExtension());
688 }
689
690 if (resource->version() != 0) { // Can happen with cloned resources
691 resource->setVersion(0);
692 }
693
694 // Save the resource to the storage storage
695 if (!storage->addResource(resource)) {
696 qWarning() << "Could not add resource" << resource->filename() << "to the storage" << storageLocation;
697 return false;
698 }
699
700 resource->setStorageLocation(storageLocation);
701 resource->setMD5Sum(storage->resourceMd5(resourceType + "/" + resource->filename()));
702 resource->setDirty(false);
704
705 d->resourceCache[QPair<QString, QString>(storageLocation, resourceType + "/" + resource->filename())] = resource;
706
712 const bool result = KisResourceCacheDb::addResource(storage,
713 storage->timeStampForResource(resourceType, resource->filename()),
714 resource,
715 resourceType);
716 return result;
717}
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 639 of file KisResourceLocator.cpp.

640{
641 // fix filename is missing
642 if (resource->filename().isEmpty()) {
643 resource->setFilename(resource->name().split(" ").join("_") + resource->defaultFileExtension());
644 }
645
646 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!resource->filename().isEmpty(), false);
647
648 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
650
651 const QString fileName = findDeduplicatedFileName(resourceType, resource->filename(), storage);
652 resource->setFilename(fileName);
653 return addResource(resourceType, resource, storageLocation);
654}
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 843 of file KisResourceLocator.cpp.

844{
845 if (d->storages.contains(storageLocation)) {
846 if (!removeStorage(storageLocation)) {
847 qWarning() << "could not remove" << storageLocation;
848 return false;
849 }
850 }
851
852 QVector<std::pair<QString, int>> addedResources;
853 Q_FOREACH(const QString &type, KisResourceLoaderRegistry::instance()->resourceTypes()) {
854 int numAddedResources = 0;
855
856 QSharedPointer<KisResourceStorage::ResourceIterator> it = storage->resources(type);
857 while (it->hasNext()) {
858 it->next();
859 numAddedResources++;
860 }
861
862 if (numAddedResources > 0) {
863 addedResources << std::make_pair(type, numAddedResources);
864 }
865 }
866
867 Q_FOREACH (const auto &typedResources, addedResources) {
868 Q_EMIT beginExternalResourceImport(typedResources.first, typedResources.second);
869 }
870
871 d->storages[storageLocation] = storage;
872 if (!KisResourceCacheDb::addStorage(storage, false)) {
873 d->errorMessages.append(i18n("Could not add %1 to the database", storage->location()));
874 qWarning() << d->errorMessages;
875 return false;
876 }
877
879 d->errorMessages.append(QString("Could not add tags for storage %1 to the cache database").arg(storage->location()));
880 qWarning() << d->errorMessages;
881 return false;
882 }
883
884 Q_FOREACH (const auto &typedResources, addedResources) {
885 Q_EMIT endExternalResourceImport(typedResources.first);
886 }
887
888 Q_EMIT storageAdded(makeStorageLocationRelative(storage->location()));
889 return true;
890}
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 151 of file KisResourceLocator.cpp.

152{
153 return d->errorMessages;
154}

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 668 of file KisResourceLocator.cpp.

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

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 1024 of file KisResourceLocator.cpp.

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

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

◆ findStorages()

void KisResourceLocator::findStorages ( )
private

Definition at line 1093 of file KisResourceLocator.cpp.

1094{
1095 d->storages.clear();
1096 d->resourceCache.clear();
1097
1098 // Add the folder
1100 Q_ASSERT(storage->location() == d->resourceLocation);
1101 d->storages[d->resourceLocation] = storage;
1102
1103 // Add the memory storage
1104 d->storages["memory"] = QSharedPointer<KisResourceStorage>::create("memory");
1105 d->storages["memory"]->setMetaData(KisResourceStorage::s_meta_name, i18n("Temporary Resources"));
1106
1107 // Add font storage
1109 if (fontStorage && fontStorage->valid()) {
1110 d->storages["fontregistry"] = fontStorage;
1111 d->storages["fontregistry"]->setMetaData(KisResourceStorage::s_meta_name, i18n("Font Storage"));
1112 }
1113
1114 // And add bundles and adobe libraries
1115 QStringList filters = QStringList() << "*.bundle" << "*.abr" << "*.asl";
1116 QDirIterator iter(d->resourceLocation, filters, QDir::Files, QDirIterator::Subdirectories);
1117 while (iter.hasNext()) {
1118 iter.next();
1120 if (!storage->valid()) {
1121 // we still add the storage to the list and try to read whatever possible
1122 qWarning() << "KisResourceLocator::findStorages: the storage is invalid" << storage->location();
1123 }
1124 d->storages[storage->location()] = storage;
1125 }
1126
1127 // Add any missing storage types to the resource cache database.
1128 Q_FOREACH(const KisResourceStorage::StorageType &type, KisStoragePluginRegistry::instance()->storageTypes()) {
1130 }
1131}
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 1043 of file KisResourceLocator.cpp.

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

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

References d, and storageByLocation().

◆ fontStorage()

KisResourceStorageSP KisResourceLocator::fontStorage ( ) const
private

Definition at line 1159 of file KisResourceLocator.cpp.

1160{
1161 return storageByLocation("fontregistry");
1162}

References storageByLocation().

◆ getResourceStorage()

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

Definition at line 1164 of file KisResourceLocator.cpp.

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

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 942 of file KisResourceLocator.cpp.

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

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 458 of file KisResourceLocator.cpp.

459{
460 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
461 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(storage, nullptr);
462
463 QByteArray resourceData = device->readAll();
465
466 {
467 QBuffer buf(&resourceData);
468 buf.open(QBuffer::ReadOnly);
469
471
472 if (!loader) {
473 qWarning() << "Could not import" << fileName << ": resource doesn't load.";
474 return nullptr;
475 }
476
477 resource = loader->load(QFileInfo(fileName).fileName(), buf, KisGlobalResourcesInterface::instance());
478 }
479
480 if (!resource || !resource->valid()) {
481 qWarning() << "Could not import" << fileName << ": resource doesn't load.";
482 return nullptr;
483 }
484
485 const QString md5 = KoMD5Generator::generateHash(resourceData);
486 const QString resourceUrl = resourceType + "/" + resource->filename();
487
488 KoResourceSP existingResource = storage->resource(resourceUrl);
489
490 if (existingResource) {
491 const QString existingResourceMd5Sum = storage->resourceMd5(resourceUrl);
492
493 if (!allowOverwrite) {
494 return nullptr;
495 }
496
497 if (existingResourceMd5Sum == md5 &&
498 existingResource->filename() == resource->filename()) {
499
507 int existingResourceId = -1;
508 bool r = KisResourceCacheDb::getResourceIdFromFilename(existingResource->filename(), resourceType, storageLocation, existingResourceId);
509
510 if (r && existingResourceId > 0) {
511 return resourceForId(existingResourceId);
512 }
513 }
514
515 qWarning() << "A resource with the same filename but a different MD5 already exists in the storage" << resourceType << fileName << storageLocation;
516 if (storageLocation == "") {
517 qWarning() << "Proceeding with overwriting the existing resource...";
518 // remove all versions of the resource from the resource folder
519 QStringList versionsLocations;
520
521 // this resource has id -1, we need correct id
522 int existingResourceId = -1;
523 bool r = KisResourceCacheDb::getResourceIdFromVersionedFilename(existingResource->filename(), resourceType, storageLocation, existingResourceId);
524
525 if (r && existingResourceId >= 0) {
526 if (KisResourceCacheDb::getAllVersionsLocations(existingResourceId, versionsLocations)) {
527
528 for (int i = 0; i < versionsLocations.size(); i++) {
529 QFileInfo fi(this->resourceLocationBase() + "/" + resourceType + "/" + versionsLocations[i]);
530 if (fi.exists()) {
531 r = QFile::remove(fi.filePath());
532 if (!r) {
533 qWarning() << "KisResourceLocator::importResourceFromFile: Removal of " << fi.filePath()
534 << "was requested, but it wasn't possible, something went wrong.";
535 }
536 } else {
537 qWarning() << "KisResourceLocator::importResourceFromFile: Removal of " << fi.filePath()
538 << "was requested, but it doesn't exist.";
539 }
540 }
541 } else {
542 qWarning() << "KisResourceLocator::importResourceFromFile: Finding all locations for " << existingResourceId << "was requested, but it failed.";
543 return nullptr;
544 }
545 } else {
546 qWarning() << "KisResourceLocator::importResourceFromFile: there is no resource file found in the location of " << storageLocation << resource->filename() << resourceType;
547 return nullptr;
548 }
549
550 Q_EMIT beginExternalResourceRemove(resourceType, {existingResourceId});
551
552 // remove everything related to this resource from the database (remember about tags and versions!!!)
554
555 {
556 const QString absoluteStorageLocation = makeStorageLocationAbsolute(resource->storageLocation());
557 KisResourceThumbnailCache::instance()->remove(absoluteStorageLocation, resourceType, existingResource->filename());
558 }
559
560 Q_EMIT endExternalResourceRemove(resourceType);
561
562 if (!r) {
563 qWarning() << "KisResourceLocator::importResourceFromFile: Removing resource with id " << existingResourceId << "completely from the database failed.";
564 return nullptr;
565 }
566
567 } else {
568 qWarning() << "KisResourceLocator::importResourceFromFile: Overwriting of the resource was denied, aborting import.";
569 return nullptr;
570 }
571 }
572
573 QBuffer buf(&resourceData);
574 buf.open(QBuffer::ReadOnly);
575
576 if (storage->importResource(resourceUrl, &buf)) {
577 resource = storage->resource(resourceUrl);
578
579 if (!resource) {
580 qWarning() << "Could not retrieve imported resource from the storage" << resourceType << fileName << storageLocation;
581 return nullptr;
582 }
583
584 resource->setStorageLocation(storageLocation);
585 resource->setMD5Sum(storage->resourceMd5(resourceUrl));
586 resource->setVersion(0);
587 resource->setDirty(false);
589
590 Q_EMIT beginExternalResourceImport(resourceType, 1);
591
592 // Insert into the database
593 const bool result = KisResourceCacheDb::addResource(storage,
594 storage->timeStampForResource(resourceType, resource->filename()),
595 resource,
596 resourceType);
597
598 Q_EMIT endExternalResourceImport(resourceType);
599
600 if (!result) {
601 return nullptr;
602 }
603
604 // resourceCaches use absolute locations
605 const QString absoluteStorageLocation = makeStorageLocationAbsolute(resource->storageLocation());
606 const QPair<QString, QString> key = {absoluteStorageLocation, resourceType + "/" + resource->filename()};
607 // Add to the cache
608 d->resourceCache[key] = resource;
610
611 return resource;
612 }
613
614 return nullptr;
615}
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 630 of file KisResourceLocator.cpp.

631{
632 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
633 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(storage, nullptr);
634
635 const QString fileName = findDeduplicatedFileName(resourceType, proposedFileName, storage);
636 return importResource(resourceType, fileName, device, false, storageLocation);
637}
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 447 of file KisResourceLocator.cpp.

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

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 656 of file KisResourceLocator.cpp.

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

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.exists()) {
121 initializationStatus = InitializationStatus::FirstUpdate;
122 }
123 else {
124 fi.open(QFile::ReadOnly);
125 QVersionNumber resource_version = QVersionNumber::fromString(QString::fromUtf8(fi.readAll()));
126 QVersionNumber krita_version = QVersionNumber::fromString(KritaVersionWrapper::versionString());
127 if (krita_version > resource_version) {
128 initializationStatus = InitializationStatus::Updating;
129 }
130 else {
131 initializationStatus = InitializationStatus::Initialized;
132 }
133 }
134 }
135
136 if (initializationStatus != InitializationStatus::Initialized) {
137 KisResourceLocator::LocatorError res = firstTimeInstallation(initializationStatus, installationResourcesLocation);
138 if (res != LocatorError::Ok) {
139 return res;
140 }
141 initializationStatus = InitializationStatus::Initialized;
142 }
143
144 if (!synchronizeDb()) {
146 }
147
148 return LocatorError::Ok;
149}
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 169 of file KisResourceLocator.cpp.

170{
171 auto loadResourcesGroup =
172 [this, parentResource = resource] (QList<KoResourceLoadResult> resources,
173 const QString &resourceGroup) {
174
175 Q_FOREACH (KoResourceLoadResult res, resources) {
176 switch (res.type())
177 {
179 KIS_SAFE_ASSERT_RECOVER_NOOP(res.resource()->resourceId() >= 0);
180 break;
183 QByteArray data = res.embeddedResource().data();
184 QBuffer buffer(&data);
185 buffer.open(QBuffer::ReadOnly);
186 importResourceDeduplicateFileName(sig.type, sig.filename, &buffer, "memory");
187 break;
188 }
190 qWarning() << "Failed to load" << resourceGroup << "resource:" << res.signature();
191 break;
192 }
193 }
194 };
195
200 loadResourcesGroup(resource->takeSideLoadedResources(KisGlobalResourcesInterface::instance()), "side-loaded");
201
205 loadResourcesGroup(resource->requiredResources(KisGlobalResourcesInterface::instance()), "linked");
206}
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 1205 of file KisResourceLocator.cpp.

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

References resourceLocationBase().

◆ makeStorageLocationRelative()

QString KisResourceLocator::makeStorageLocationRelative ( QString location) const
private

Definition at line 1298 of file KisResourceLocator.cpp.

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

References resourceLocationBase().

◆ memoryStorage()

KisResourceStorageSP KisResourceLocator::memoryStorage ( ) const
private

Definition at line 1154 of file KisResourceLocator.cpp.

1155{
1156 return storageByLocation("memory");
1157}

References storageByLocation().

◆ metaDataForResource()

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

metaDataForResource

Parameters
id
Returns

Definition at line 792 of file KisResourceLocator.cpp.

793{
794 return KisResourceCacheDb::metaDataForId(id, "resources");
795}
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 802 of file KisResourceLocator.cpp.

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

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 825 of file KisResourceLocator.cpp.

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

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 1019 of file KisResourceLocator.cpp.

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

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 767 of file KisResourceLocator.cpp.

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

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 892 of file KisResourceLocator.cpp.

893{
894 // Cloned documents have a document storage, but that isn't in the locator.
895 if (!d->storages.contains(storageLocation)) {
896 return true;
897 }
898
900
901 Q_FOREACH(const QString &type, KisResourceLoaderRegistry::instance()->resourceTypes()) {
902 const QVector<int> resources = KisResourceCacheDb::resourcesForStorage(type, storageLocation);
903 if (!resources.isEmpty()) {
904 removedResources << std::make_pair(type, resources);
905 }
906 }
907
909 QVector<int> allRemovedTagIds;
910 Q_FOREACH(const QString &type, KisResourceLoaderRegistry::instance()->resourceTypes()) {
911 auto [uniqueTags, sharedTags] = KisResourceCacheDb::tagsForStorage(type, storageLocation);
912 removedTags << std::make_pair(type, uniqueTags);
913 allRemovedTagIds << uniqueTags;
914 }
915
916 Q_FOREACH (const auto &typedResources, removedResources) {
917 Q_EMIT beginExternalResourceRemove(typedResources.first, typedResources.second);
918 }
919
920 // TODO: add model notification about removed tags
921 Q_UNUSED(removedTags);
922
923 purge(storageLocation, allRemovedTagIds);
924
925 KisResourceStorageSP storage = d->storages.take(storageLocation);
926
927 if (!KisResourceCacheDb::deleteStorage(storage)) {
928 d->errorMessages.append(i18n("Could not remove storage %1 from the database", storage->location()));
929 qWarning() << d->errorMessages;
930 return false;
931 }
932
933 Q_FOREACH (const auto &typedResources, removedResources) {
934 Q_EMIT endExternalResourceRemove(typedResources.first);
935 }
936
937 Q_EMIT storageRemoved(makeStorageLocationRelative(storage->location()));
938
939 return true;
940}
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 332 of file KisResourceLocator.cpp.

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

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 161 of file KisResourceLocator.cpp.

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

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 422 of file KisResourceLocator.cpp.

423{
424 ResourceStorage rs = getResourceStorage(resourceId);
425 KoResourceSP r = resource(rs.storageLocation, rs.resourceType, rs.resourceFileName);
426 return r;
427}
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 156 of file KisResourceLocator.cpp.

157{
158 return d->resourceLocation;
159}

References d.

◆ saveTags()

void KisResourceLocator::saveTags ( )
static

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

Definition at line 947 of file KisResourceLocator.cpp.

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

798{
799 return KisResourceCacheDb::updateMetaDataForId(map, id, "resources");
800}
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 815 of file KisResourceLocator.cpp.

816{
817 KisResourceStorageSP storage = d->safeGetStorage(makeStorageLocationAbsolute(storageLocation));
819
820 Q_FOREACH(const QString &key, map.keys()) {
821 storage->setMetaData(key, map[key]);
822 }
823}
#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 429 of file KisResourceLocator.cpp.

430{
431 // First remove the resource from the cache
432 ResourceStorage rs = getResourceStorage(resourceId);
433 QPair<QString, QString> key = QPair<QString, QString> (rs.storageLocation, rs.resourceType + "/" + rs.resourceFileName);
434
435 d->resourceCache.remove(key);
436 if (!active) {
438 }
439
440 bool result = KisResourceCacheDb::setResourceActive(resourceId, active);
441
442 Q_EMIT resourceActiveStateChanged(rs.resourceType, resourceId);
443
444 return result;
445}
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 1138 of file KisResourceLocator.cpp.

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

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 1133 of file KisResourceLocator.cpp.

1134{
1135 return d->storages.values();
1136}

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 1228 of file KisResourceLocator.cpp.

1229{
1230 Q_EMIT progressMessage(i18n("Synchronizing the resources."));
1231
1232 d->errorMessages.clear();
1233
1234 // Add resource types that have been added since first-time installation.
1235 Q_FOREACH(auto loader, KisResourceLoaderRegistry::instance()->values()) {
1236 KisResourceCacheDb::registerResourceType(loader->resourceType());
1237 }
1238
1239
1240 findStorages();
1241 Q_FOREACH(const KisResourceStorageSP storage, d->storages) {
1243 d->errorMessages.append(i18n("Could not synchronize %1 with the database", storage->location()));
1244 } else {
1245 Q_EMIT storageResynchronized(storage->location(), true);
1246 }
1247 }
1248
1249 Q_FOREACH(const KisResourceStorageSP storage, d->storages) {
1250 if (!KisResourceCacheDb::addStorageTags(storage)) {
1251 d->errorMessages.append(i18n("Could not synchronize %1 with the database", storage->location()));
1252 }
1253 }
1254
1256
1266
1267 // now remove the storages that no longer exists
1268 KisStorageModel model;
1269
1270 QList<QString> storagesToRemove;
1271 for (int i = 0; i < model.rowCount(); i++) {
1272 QModelIndex idx = model.index(i, 0);
1273 QString location = model.data(idx, Qt::UserRole + KisStorageModel::Location).toString();
1274 storagesToRemove << location;
1275 }
1276
1277 for (int i = 0; i < storagesToRemove.size(); i++) {
1278 QString location = storagesToRemove[i];
1279 if (!d->storages.contains(this->makeStorageLocationAbsolute(location))) {
1280 if (!KisResourceCacheDb::deleteStorage(location)) {
1281 d->errorMessages.append(i18n("Could not remove storage %1 from the database", this->makeStorageLocationAbsolute(location)));
1282 qWarning() << d->errorMessages;
1283 return false;
1284 }
1285 Q_EMIT storageRemoved(this->makeStorageLocationAbsolute(location));
1286 }
1287 }
1288
1289
1290 d->errorMessages <<
1292
1293 d->resourceCache.clear();
1294 return d->errorMessages.isEmpty();
1295}
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 208 of file KisResourceLocator.cpp.

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

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 223 of file KisResourceLocator.cpp.

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

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

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 719 of file KisResourceLocator.cpp.

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