13#include <QDirIterator>
16#include <QVersionNumber>
22#include <kconfiggroup.h>
23#include <ksharedconfig.h>
24#include <klocalizedstring.h>
84 if (!
d->resourceLocation.endsWith(
'/'))
d->resourceLocation +=
'/';
86 QFileInfo fi(
d->resourceLocation);
89 if (!QDir().mkpath(
d->resourceLocation)) {
90 d->errorMessages << i18n(
"1. Could not create the resource location at %1.",
d->resourceLocation);
96 if (!fi.isWritable()) {
97 d->errorMessages << i18n(
"2. The resource location at %1 is not writable.",
d->resourceLocation);
103 QFile fi(
d->resourceLocation +
'/' +
"KRITA_RESOURCE_VERSION");
108 fi.open(QFile::ReadOnly);
109 QVersionNumber resource_version = QVersionNumber::fromString(QString::fromUtf8(fi.readAll()));
111 if (krita_version > resource_version) {
137 return d->errorMessages;
142 return d->resourceLocation;
148 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType +
"/" + filename);
150 return d->resourceCache.contains(key);
155 auto loadResourcesGroup =
157 const QString &resourceGroup) {
168 QBuffer buffer(&data);
169 buffer.open(QBuffer::ReadOnly);
175 qWarning() <<
"Failed to load" << resourceGroup <<
"resource:" << res.
signature();
195 if (
d->tagCache.contains(QPair<QString, QString>(resourceType, tagUrl))) {
196 return d->tagCache[QPair<QString, QString>(resourceType, tagUrl)];
201 if (tag && tag->valid()) {
202 d->tagCache[QPair<QString, QString>(resourceType, tagUrl)] = tag;
211 bool r = query.prepare(
"SELECT tags.id\n"
217 ", resource_types.name as resource_type\n"
218 ", resource_types.id\n"
221 "WHERE tags.resource_type_id = resource_types.id\n"
222 "AND resource_types.name = :resource_type\n"
223 "AND tags.url = :tag_url\n");
226 qWarning() <<
"Could not prepare KisResourceLocator::tagForUrl query" << query.lastError();
230 query.bindValue(
":resource_type", resourceType);
231 query.bindValue(
":tag_url", tagUrl);
235 qWarning() <<
"Could not execute KisResourceLocator::tagForUrl query" << query.lastError() << query.boundValues();
246 int tagId = query.value(
"tags.id").toInt();
247 int resourceTypeId = query.value(
"resource_types.id").toInt();
249 tag->setUrl(query.value(
"url").toString());
250 tag->setResourceType(resourceType);
251 tag->setId(query.value(
"id").toInt());
252 tag->setActive(query.value(
"active").toBool());
253 tag->setName(query.value(
"name").toString());
254 tag->setComment(query.value(
"comment").toString());
255 tag->setFilename(query.value(
"filename").toString());
259 QMap<QString, QString> names;
260 QMap<QString, QString> comments;
262 r = query.prepare(
"SELECT language\n"
265 "FROM tag_translations\n"
266 "WHERE tag_id = :id");
269 qWarning() <<
"Could not prepare KisResourceLocator::tagForUrl translation query" << query.lastError();
272 query.bindValue(
":id", tag->id());
275 qWarning() <<
"Could not execute KisResourceLocator::tagForUrl translation query" << query.lastError();
278 while (query.next()) {
279 names[query.value(0).toString()] = query.value(1).toString();
280 comments[query.value(0).toString()] = query.value(2).toString();
283 tag->setNames(names);
284 tag->setComments(comments);
286 QSqlQuery defaultResourcesQuery;
288 if (!defaultResourcesQuery.prepare(
"SELECT resources.filename\n"
291 "WHERE resource_tags.tag_id = :tag_id\n"
292 "AND resources.resource_type_id = :type_id\n"
293 "AND resource_tags.resource_id = resources.id\n"
294 "AND resource_tags.active = 1\n")) {
295 qWarning() <<
"Could not prepare resource/tag query" << defaultResourcesQuery.lastError();
298 defaultResourcesQuery.bindValue(
":tag_id", tagId);
299 defaultResourcesQuery.bindValue(
":type_id", resourceTypeId);
301 if (!defaultResourcesQuery.exec()) {
302 qWarning() <<
"Could not execute resource/tag query" << defaultResourcesQuery.lastError();
307 while (defaultResourcesQuery.next()) {
308 resourceFileNames << defaultResourcesQuery.value(
"resources.filename").toString();
311 tag->setDefaultResources(resourceFileNames);
321 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType +
"/" + filename);
324 if (
d->resourceCache.contains(key)) {
330 qWarning() <<
"Could not find storage" << storageLocation;
334 resource = storage->resource(resourceType +
"/" + filename);
344 qWarning() <<
"KoResourceSP KisResourceLocator::resource" << storageLocation << resourceType << filename <<
"was not found";
348 resource->setStorageLocation(storageLocation);
349 Q_ASSERT(!
resource->storageLocation().isEmpty());
353 if (!q.prepare(
"SELECT resources.id\n"
354 ", versioned_resources.version as version\n"
355 ", versioned_resources.md5sum as md5sum\n"
357 ", resources.status\n"
361 ", versioned_resources\n"
362 "WHERE storages.id = resources.storage_id\n"
363 "AND storages.location = :storage_location\n"
364 "AND resource_types.id = resources.resource_type_id\n"
365 "AND resource_types.name = :resource_type\n"
366 "AND resources.filename = :filename\n"
367 "AND versioned_resources.resource_id = resources.id\n"
368 "AND versioned_resources.version = (SELECT MAX(version) FROM versioned_resources WHERE versioned_resources.resource_id = resources.id)")) {
369 qWarning() <<
"Could not prepare id/version query" << q.lastError();
374 q.bindValue(
":resource_type", resourceType);
375 q.bindValue(
":filename", filename);
378 qWarning() <<
"Could not execute id/version query" << q.lastError() << q.boundValues();
382 qWarning() <<
"Could not find the resource in the database" << storageLocation << resourceType << filename;
385 resource->setResourceId(q.value(0).toInt());
386 Q_ASSERT(
resource->resourceId() >= 0);
388 resource->setVersion(q.value(1).toInt());
391 resource->setMD5Sum(q.value(2).toString());
392 Q_ASSERT(!
resource->md5Sum().isEmpty());
394 resource->setActive(q.value(4).toBool());
397 resource->setName(q.value(3).toString());;
401 qWarning() <<
"Could not find resource" << resourceType +
"/" + filename;
421 d->resourceCache.remove(key);
436 if (!f.open(QFile::ReadOnly)) {
437 qWarning() <<
"Could not open" << fileName <<
"for loading";
441 return importResource(resourceType, fileName, &f, allowOverwrite, storageLocation);
448 QByteArray resourceData = device->readAll();
452 QBuffer buf(&resourceData);
453 buf.open(QBuffer::ReadOnly);
458 qWarning() <<
"Could not import" << fileName <<
": resource doesn't load.";
466 qWarning() <<
"Could not import" << fileName <<
": resource doesn't load.";
471 const QString resourceUrl = resourceType +
"/" +
resource->filename();
473 const KoResourceSP existingResource = storage->resource(resourceUrl);
475 if (existingResource) {
476 const QString existingResourceMd5Sum = storage->resourceMd5(resourceUrl);
478 if (!allowOverwrite) {
482 if (existingResourceMd5Sum == md5 &&
483 existingResource->filename() ==
resource->filename()) {
492 int existingResourceId = -1;
495 if (r && existingResourceId > 0) {
500 qWarning() <<
"A resource with the same filename but a different MD5 already exists in the storage" << resourceType << fileName << storageLocation;
501 if (storageLocation ==
"") {
502 qWarning() <<
"Proceeding with overwriting the existing resource...";
507 int existingResourceId = -1;
510 if (r && existingResourceId >= 0) {
513 for (
int i = 0; i < versionsLocations.size(); i++) {
516 r = QFile::remove(fi.filePath());
518 qWarning() <<
"KisResourceLocator::importResourceFromFile: Removal of " << fi.filePath()
519 <<
"was requested, but it wasn't possible, something went wrong.";
522 qWarning() <<
"KisResourceLocator::importResourceFromFile: Removal of " << fi.filePath()
523 <<
"was requested, but it doesn't exist.";
527 qWarning() <<
"KisResourceLocator::importResourceFromFile: Finding all locations for " << existingResourceId <<
"was requested, but it failed.";
531 qWarning() <<
"KisResourceLocator::importResourceFromFile: there is no resource file found in the location of " << storageLocation <<
resource->filename() << resourceType;
548 qWarning() <<
"KisResourceLocator::importResourceFromFile: Removing resource with id " << existingResourceId <<
"completely from the database failed.";
553 qWarning() <<
"KisResourceLocator::importResourceFromFile: Overwriting of the resource was denied, aborting import.";
558 QBuffer buf(&resourceData);
559 buf.open(QBuffer::ReadOnly);
561 if (storage->importResource(resourceUrl, &buf)) {
562 resource = storage->resource(resourceUrl);
565 qWarning() <<
"Could not retrieve imported resource from the storage" << resourceType << fileName << storageLocation;
569 resource->setStorageLocation(storageLocation);
570 resource->setMD5Sum(storage->resourceMd5(resourceUrl));
579 storage->timeStampForResource(resourceType,
resource->filename()),
591 const QPair<QString, QString> key = {absoluteStorageLocation, resourceType +
"/" +
resource->filename()};
606 const QString resourceUrl = resourceType +
"/" + QFileInfo(fileName).fileName();
608 const KoResourceSP existingResource = storage->resource(resourceUrl);
610 return !existingResource.isNull();
617 const QString resourceUrl =
resource->resourceType().first +
"/" +
resource->filename();
619 return storage->exportResource(resourceUrl, device);
630 if (
resource->filename().isEmpty()) {
639 if (!storage->addResource(
resource)) {
640 qWarning() <<
"Could not add resource" <<
resource->filename() <<
"to the storage" << storageLocation;
644 resource->setStorageLocation(storageLocation);
645 resource->setMD5Sum(storage->resourceMd5(resourceType +
"/" +
resource->filename()));
649 d->resourceCache[QPair<QString, QString>(storageLocation, resourceType +
"/" +
resource->filename())] =
resource;
657 storage->timeStampForResource(resourceType,
resource->filename()),
667 Q_ASSERT(
d->storages.contains(storageLocation));
675 if (!storage->supportsVersioning())
return false;
684 if (!storage->saveAsNewVersion(
resource)) {
685 qWarning() <<
"Failed to save the new version of " <<
resource->name() <<
"to storage" << storageLocation;
689 resource->setMD5Sum(storage->resourceMd5(resourceType +
"/" +
resource->filename()));
695 qWarning() <<
"Failed to add a new version of the resource to the database" <<
resource->name();
700 qWarning() <<
"Failed to update resource metadata" <<
resource;
705 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType +
"/" +
resource->filename());
715 if (
resource->resourceId() < 0)
return false;
718 Q_ASSERT(
d->storages.contains(storageLocation));
722 if (!storage->loadVersionedResource(
resource)) {
723 qWarning() <<
"Failed to reload the resource" <<
resource->name() <<
"from storage" << storageLocation;
727 resource->setMD5Sum(storage->resourceMd5(resourceType +
"/" +
resource->filename()));
732 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType +
"/" +
resource->filename());
733 Q_ASSERT(
d->resourceCache[key] ==
resource);
750 QMap<QString, QVariant> metadata;
752 qWarning() << storageLocation <<
"not in" <<
d->storages.keys();
762 Q_FOREACH(
const QString key, st->metaDataKeys()) {
763 metadata[key] = st->metaData(key);
770 Q_ASSERT(
d->storages.contains(storageLocation));
771 Q_FOREACH(
const QString &key, map.keys()) {
772 d->storages[storageLocation]->setMetaData(key, map[key]);
778 Q_FOREACH(
const auto key,
d->resourceCache.keys()) {
779 if (key.first == storageLocation) {
780 d->resourceCache.remove(key);
788 if (
d->storages.contains(storageLocation)) {
790 qWarning() <<
"could not remove" << storageLocation;
797 int numAddedResources = 0;
800 while (it->hasNext()) {
805 if (numAddedResources > 0) {
806 addedResources << std::make_pair(type, numAddedResources);
810 Q_FOREACH (
const auto &typedResources, addedResources) {
814 d->storages[storageLocation] = storage;
816 d->errorMessages.append(i18n(
"Could not add %1 to the database", storage->location()));
817 qWarning() <<
d->errorMessages;
822 d->errorMessages.append(QString(
"Could not add tags for storage %1 to the cache database").arg(storage->location()));
823 qWarning() <<
d->errorMessages;
827 Q_FOREACH (
const auto &typedResources, addedResources) {
838 if (!
d->storages.contains(storageLocation)) {
846 if (!resources.isEmpty()) {
847 removedResources << std::make_pair(type, resources);
851 Q_FOREACH (
const auto &typedResources, removedResources) {
855 purge(storageLocation);
860 d->errorMessages.append(i18n(
"Could not remove storage %1 from the database", storage->location()));
861 qWarning() <<
d->errorMessages;
865 Q_FOREACH (
const auto &typedResources, removedResources) {
876 return d->storages.contains(document);
883 if (!query.prepare(
"SELECT tags.url \n"
884 ", resource_types.name \n"
887 "WHERE tags.resource_type_id = resource_types.id\n"))
889 qWarning() <<
"Could not prepare save tags query" << query.lastError();
894 qWarning() <<
"Could not execute save tags query" << query.lastError();
902 while (query.next()) {
905 query.value(
"resource_types.name").toString());
907 if (!tag || !tag->valid()) {
912 QString filename = tag->filename();
913 if (filename.isEmpty() || QFileInfo(filename).suffix().isEmpty()) {
914 filename = tag->url() +
".tag";
918 if (QFileInfo(filename).suffix() !=
"tag" && QFileInfo(filename).suffix() !=
"TAG") {
921 dbgResources <<
"Skipping saving tag " << tag->name(
false) << filename << tag->resourceType();
925 filename.remove(resourceLocation);
927 QFile f(resourceLocation +
"/" + tag->resourceType() +
'/' + filename);
929 if (!f.open(QFile::WriteOnly)) {
930 qWarning () <<
"Could not open tag file for writing" << f.fileName();
935 buf.open(QIODevice::WriteOnly);;
937 if (!tag->save(buf)) {
938 qWarning() <<
"Could not save tag to" << f.fileName();
953 d->tagCache.remove(QPair<QString, QString>(resourceType, tagUrl));
961 qWarning() <<
"Could not find storage" << storageLocation;
965 const QString resourceUrl =
resource->resourceType().first +
"/" +
resource->filename();
967 return storage->resourceFilePath(resourceUrl);
973 qWarning() << i18n(
"Could not synchronize updated font registry with the database");
981 Q_EMIT
progressMessage(i18n(
"Krita is running for the first time. Initialization will take some time."));
982 Q_UNUSED(initializationStatus);
985 QDir dir(
d->resourceLocation +
'/' + folder +
'/');
987 if (!QDir().mkpath(
d->resourceLocation +
'/' + folder +
'/')) {
988 d->errorMessages << i18n(
"3. Could not create the resource location at %1.", dir.path());
995 QDir dir(installationResourcesLocation +
'/' + folder +
'/');
997 Q_FOREACH(
const QString &entry, dir.entryList(QDir::Files | QDir::Readable)) {
998 QFile f(dir.canonicalPath() +
'/'+ entry);
999 if (!QFileInfo(
d->resourceLocation +
'/' + folder +
'/' + entry).exists()) {
1000 if (!f.copy(
d->resourceLocation +
'/' + folder +
'/' + entry)) {
1001 d->errorMessages << i18n(
"Could not copy resource %1 to %2", f.fileName(),
d->resourceLocation +
'/' + folder +
'/' + entry);
1010 QDirIterator iter(installationResourcesLocation, filters, QDir::Files, QDirIterator::Subdirectories);
1011 while (iter.hasNext()) {
1013 Q_EMIT
progressMessage(i18n(
"Installing the resources from bundle %1.", iter.filePath()));
1014 QFile f(iter.filePath());
1015 Q_ASSERT(f.exists());
1016 if (!f.copy(
d->resourceLocation +
'/' + iter.fileName())) {
1017 d->errorMessages << i18n(
"Could not copy resource %1 to %2", f.fileName(),
d->resourceLocation);
1021 QFile f(
d->resourceLocation +
'/' +
"KRITA_RESOURCE_VERSION");
1022 f.open(QFile::WriteOnly);
1031 d->storages.clear();
1032 d->resourceCache.clear();
1036 Q_ASSERT(storage->location() ==
d->resourceLocation);
1037 d->storages[
d->resourceLocation] = storage;
1052 QDirIterator iter(
d->resourceLocation, filters, QDir::Files, QDirIterator::Subdirectories);
1053 while (iter.hasNext()) {
1056 if (!storage->valid()) {
1058 qWarning() <<
"KisResourceLocator::findStorages: the storage is invalid" << storage->location();
1060 d->storages[storage->location()] = storage;
1071 return d->storages.values();
1076 if (!
d->storages.contains(location)) {
1077 qWarning() <<
"No" << location <<
"storage defined:" <<
d->storages.keys();
1081 if (!storage || !storage->valid()) {
1082 qWarning() <<
"Could not retrieve the" << location <<
"storage object or the object is not valid";
1109 bool r = q.prepare(
"SELECT storages.location\n"
1110 ", resource_types.name as resource_type\n"
1111 ", resources.filename\n"
1114 ", resource_types\n"
1115 "WHERE resources.id = :resource_id\n"
1116 "AND resources.storage_id = storages.id\n"
1117 "AND resource_types.id = resources.resource_type_id");
1119 qWarning() <<
"KisResourceLocator::removeResource: could not prepare query." << q.lastError();
1124 q.bindValue(
":resource_id", resourceId);
1128 qWarning() <<
"KisResourceLocator::removeResource: could not execute query." << q.lastError();
1134 QString storageLocation = q.value(
"location").toString();
1135 QString resourceType= q.value(
"resource_type").toString();
1136 QString resourceFilename = q.value(
"filename").toString();
1149 if (storageLocation.isEmpty()) {
1153 if (QFileInfo(storageLocation).isRelative() && (storageLocation.endsWith(
".bundle", Qt::CaseInsensitive)
1154 || storageLocation.endsWith(
".asl", Qt::CaseInsensitive)
1155 || storageLocation.endsWith(
".abr", Qt::CaseInsensitive))) {
1165 return storageLocation;
1172 d->errorMessages.clear();
1183 d->errorMessages.append(i18n(
"Could not synchronize %1 with the database", storage->location()));
1191 d->errorMessages.append(i18n(
"Could not synchronize %1 with the database", storage->location()));
1211 for (
int i = 0; i < model.
rowCount(); i++) {
1212 QModelIndex idx = model.index(i, 0);
1214 storagesToRemove << location;
1217 for (
int i = 0; i < storagesToRemove.size(); i++) {
1218 QString location = storagesToRemove[i];
1219 if (!
d->storages.contains(this->makeStorageLocationAbsolute(location))) {
1222 qWarning() <<
d->errorMessages;
1233 d->resourceCache.clear();
1234 return d->errorMessages.isEmpty();
QList< QString > QStringList
QSharedPointer< KisTag > KisTagSP
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 addStorage(KisResourceStorageSP storage, bool preinstalled)
static bool addResource(KisResourceStorageSP storage, QDateTime timestamp, KoResourceSP resource, const QString &resourceType)
static bool getAllVersionsLocations(int resourceId, QStringList &outVersionsLocationsList)
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...
static bool removeOrphanedMetaData()
removeOrphanedMetaData Previous versions of Krita never removed metadata, so this function doublechec...
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...
static QMap< QString, QVariant > metaDataForId(int id, const QString &tableName)
metaDataForId
static QVector< int > resourcesForStorage(const QString &resourceType, const QString &storageLocation)
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 deleteStorage(KisResourceStorageSP storage)
Actually delete the storage and all its resources from the database (i.e., nothing is set to inactive...
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...
static bool removeResourceCompletely(int resourceId)
static bool addStorageTags(KisResourceStorageSP storage)
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...
static bool registerResourceType(const QString &resourceType)
registerResourceType registers this resource type in the database
static bool synchronizeStorage(KisResourceStorageSP storage)
static bool registerStorageType(const KisResourceStorage::StorageType storageType)
registerStorageType registers this storage type in the database
The KisResourceLoader class is an abstract interface class that must be implemented by actual resourc...
bool load(KoResourceSP resource, QIODevice &dev, KisResourcesInterfaceSP resourcesInterface)
QStringList executeAllFixups()
static KisResourceLoaderRegistry * instance()
KisResourceLoaderBase * loader(const QString &resourceType, const QString &mimetype) const
QHash< QPair< QString, QString >, KoResourceSP > resourceCache
QMap< QString, KisResourceStorageSP > storages
QMap< QPair< QString, QString >, KisTagSP > tagCache
QStringList errorMessages
KisResourceStorageSP folderStorage() const
QMap< QString, QVariant > metaDataForStorage(const QString &storageLocation) const
metaDataForStorage
void progressMessage(const QString &)
LocatorError initialize(const QString &installationResourcesLocation)
initialize Setup the resource locator for use.
QScopedPointer< Private > d
KisTagSP tagForUrl(const QString &tagUrl, const QString resourceType)
tagForUrl create a tag from the database
bool resourceCached(QString storageLocation, const QString &resourceType, const QString &filename) const
KoResourceSP resource(QString storageLocation, const QString &resourceType, const QString &filename)
resource finds a physical resource in one of the storages
KoResourceSP importResource(const QString &resourceType, const QString &fileName, QIODevice *device, const bool allowOverwrite, const QString &storageLocation=QString())
importResource
bool addResource(const QString &resourceType, const KoResourceSP resource, const QString &storageLocation=QString())
addResource adds the given resource to the database and potentially a storage
static const QString resourceLocationKey
void updateFontStorage()
This updates the "fontregistry" storage. Called when the font directories change;.
KisResourceStorageSP fontStorage() const
void endExternalResourceRemove(const QString &resourceType)
Emitted when the locator finished importing the embedded resource.
KisResourceStorageSP storageByLocation(const QString &location) const
void storageRemoved(const QString &location)
Emitted whenever a storage is removed.
bool exportResource(KoResourceSP resource, QIODevice *device)
exportResource
void purge(const QString &storageLocation)
purge purges the local resource cache
QStringList errorMessages() const
errorMessages
QList< KisResourceStorageSP > storages() const
ResourceStorage getResourceStorage(int resourceId) const
bool updateResource(const QString &resourceType, const KoResourceSP resource)
updateResource
void storageAdded(const QString &location)
Emitted whenever a storage is added.
QString resourceLocationBase() const
resourceLocationBase is the place where all resource storages (folder, bundles etc....
bool removeStorage(const QString &storageLocation)
removeStorage removes the temporary storage from the database
KisResourceStorageSP memoryStorage() const
void storagesBulkSynchronizationFinished()
void beginExternalResourceImport(const QString &resourceType, int numResources)
Emitted when the locator needs to add an embedded resource.
bool hasStorage(const QString &storageLocation)
hasStorage can be used to check whether the given storage already exists
void beginExternalResourceRemove(const QString &resourceType, const QVector< int > resourceIds)
Emitted when the locator needs to add an embedded resource.
void loadRequiredResources(KoResourceSP resource)
QString makeStorageLocationRelative(QString location) const
bool reloadResource(const QString &resourceType, const KoResourceSP resource)
Reloads the resource from its persistent storage.
QString makeStorageLocationAbsolute(QString storageLocation) const
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-inst...
static void saveTags()
saveTags saves all tags to .tag files in the resource folder
QMap< QString, QVariant > metaDataForResource(int id) const
metaDataForResource
QString filePathForResource(KoResourceSP resource)
bool importWillOverwriteResource(const QString &resourceType, const QString &fileName, const QString &storageLocation=QString()) const
return whether importing will overwrite some existing resource
void setMetaDataForStorage(const QString &storageLocation, QMap< QString, QVariant > map) const
setMetaDataForStorage
bool setMetaDataForResource(int id, QMap< QString, QVariant > map) const
setMetaDataForResource
void endExternalResourceImport(const QString &resourceType)
Emitted when the locator finished importing the embedded resource.
bool setResourceActive(int resourceId, bool active)
setResourceActive
KisResourceLocator(QObject *parent)
static KisTagSP tagForUrlNoCache(const QString &tagUrl, const QString resourceType)
tagForUrlNoCache create a tag from the database, don't use cache
void purgeTag(const QString tagUrl, const QString resourceType)
void storageResynchronized(const QString &storage, bool isBulkResynchronization)
LocatorError firstTimeInstallation(InitializationStatus initializationStatus, const QString &installationResourcesLocation)
void resourceActiveStateChanged(const QString &resourceType, int resourceId)
Emitted when a resource changes its active state.
KoResourceSP resourceForId(int resourceId)
resourceForId returns the resource with the given id, or 0 if no such resource exists....
static KisResourceLocator * instance()
KoResourceSP importResourceFromFile(const QString &resourceType, const QString &fileName, const bool allowOverwrite, const QString &storageLocation=QString())
importResourceFromFile
static const QString s_meta_name
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)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override
static KisStoragePluginRegistry * instance()
The KisTag loads a tag from a .tag file. A .tag file is a .desktop file. The following fields are imp...
const KoResourceSignature & signature() const
static QString generateHash(const QString &filename)
generateHash reads the given file and generates a hex-encoded md5sum for the file.
KoResourceSP resource() const noexcept
KoEmbeddedResource embeddedResource() const noexcept
KoResourceSignature signature() const
static QString getAppDataLocation()
A simple wrapper object for the main information about the resource.
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
KRITAVERSION_EXPORT QString versionString(bool checkGit=false)