13#include <QDirIterator>
16#include <QVersionNumber>
22#include <kconfiggroup.h>
23#include <ksharedconfig.h>
24#include <klocalizedstring.h>
64 if (!
storages.contains(storageLocation)) {
65 qWarning() <<
"WARNING: KisResourceLocator: failed to find a storage with location" << storageLocation;
100 if (!
d->resourceLocation.endsWith(
'/'))
d->resourceLocation +=
'/';
102 QFileInfo fi(
d->resourceLocation);
105 if (!QDir().mkpath(
d->resourceLocation)) {
106 d->errorMessages << i18n(
"1. Could not create the resource location at %1.",
d->resourceLocation);
112 if (!fi.isWritable()) {
113 d->errorMessages << i18n(
"2. The resource location at %1 is not writable.",
d->resourceLocation);
119 QFile fi(
d->resourceLocation +
'/' +
"KRITA_RESOURCE_VERSION");
120 if (!fi.open(QFile::ReadOnly)) {
124 QVersionNumber resource_version = QVersionNumber::fromString(QString::fromUtf8(fi.readAll()));
126 if (krita_version > resource_version) {
152 return d->errorMessages;
157 return d->resourceLocation;
163 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType +
"/" + filename);
165 return d->resourceCache.contains(key);
170 auto loadResourcesGroup =
172 const QString &resourceGroup) {
183 QBuffer buffer(&data);
184 buffer.open(QBuffer::ReadOnly);
189 qWarning() <<
"Failed to load" << resourceGroup <<
"resource:" << res.
signature();
209 if (
d->tagCache.contains(QPair<QString, QString>(resourceType, tagUrl))) {
210 return d->tagCache[QPair<QString, QString>(resourceType, tagUrl)];
215 if (tag && tag->valid()) {
216 d->tagCache[QPair<QString, QString>(resourceType, tagUrl)] = tag;
225 bool r = query.prepare(
"SELECT tags.id\n"
231 ", resource_types.name as resource_type\n"
232 ", resource_types.id\n"
235 "WHERE tags.resource_type_id = resource_types.id\n"
236 "AND resource_types.name = :resource_type\n"
237 "AND tags.url = :tag_url\n");
240 qWarning() <<
"Could not prepare KisResourceLocator::tagForUrl query" << query.lastError();
244 query.bindValue(
":resource_type", resourceType);
245 query.bindValue(
":tag_url", tagUrl);
249 qWarning() <<
"Could not execute KisResourceLocator::tagForUrl query" << query.lastError() << query.boundValues();
260 int tagId = query.value(
"tags.id").toInt();
261 int resourceTypeId = query.value(
"resource_types.id").toInt();
263 tag->setUrl(query.value(
"url").toString());
264 tag->setResourceType(resourceType);
265 tag->setId(query.value(
"id").toInt());
266 tag->setActive(query.value(
"active").toBool());
267 tag->setName(query.value(
"name").toString());
268 tag->setComment(query.value(
"comment").toString());
269 tag->setFilename(query.value(
"filename").toString());
273 QMap<QString, QString> names;
274 QMap<QString, QString> comments;
276 r = query.prepare(
"SELECT language\n"
279 "FROM tag_translations\n"
280 "WHERE tag_id = :id");
283 qWarning() <<
"Could not prepare KisResourceLocator::tagForUrl translation query" << query.lastError();
286 query.bindValue(
":id", tag->id());
289 qWarning() <<
"Could not execute KisResourceLocator::tagForUrl translation query" << query.lastError();
292 while (query.next()) {
293 names[query.value(0).toString()] = query.value(1).toString();
294 comments[query.value(0).toString()] = query.value(2).toString();
297 tag->setNames(names);
298 tag->setComments(comments);
300 QSqlQuery defaultResourcesQuery;
302 if (!defaultResourcesQuery.prepare(
"SELECT resources.filename\n"
305 "WHERE resource_tags.tag_id = :tag_id\n"
306 "AND resources.resource_type_id = :type_id\n"
307 "AND resource_tags.resource_id = resources.id\n"
308 "AND resource_tags.active = 1\n")) {
309 qWarning() <<
"Could not prepare resource/tag query" << defaultResourcesQuery.lastError();
312 defaultResourcesQuery.bindValue(
":tag_id", tagId);
313 defaultResourcesQuery.bindValue(
":type_id", resourceTypeId);
315 if (!defaultResourcesQuery.exec()) {
316 qWarning() <<
"Could not execute resource/tag query" << defaultResourcesQuery.lastError();
321 while (defaultResourcesQuery.next()) {
322 resourceFileNames << defaultResourcesQuery.value(
"resources.filename").toString();
325 tag->setDefaultResources(resourceFileNames);
335 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType +
"/" + filename);
338 if (
d->resourceCache.contains(key)) {
347 resource = storage->resource(resourceType +
"/" + filename);
357 qWarning() <<
"KoResourceSP KisResourceLocator::resource" << storageLocation << resourceType << filename <<
"was not found";
361 resource->setStorageLocation(storageLocation);
362 Q_ASSERT(!
resource->storageLocation().isEmpty());
366 if (!q.prepare(
"SELECT resources.id\n"
367 ", versioned_resources.version as version\n"
368 ", versioned_resources.md5sum as md5sum\n"
370 ", resources.status\n"
374 ", versioned_resources\n"
375 "WHERE storages.id = resources.storage_id\n"
376 "AND storages.location = :storage_location\n"
377 "AND resource_types.id = resources.resource_type_id\n"
378 "AND resource_types.name = :resource_type\n"
379 "AND resources.filename = :filename\n"
380 "AND versioned_resources.resource_id = resources.id\n"
381 "AND versioned_resources.version = (SELECT MAX(version) FROM versioned_resources WHERE versioned_resources.resource_id = resources.id)")) {
382 qWarning() <<
"Could not prepare id/version query" << q.lastError();
387 q.bindValue(
":resource_type", resourceType);
388 q.bindValue(
":filename", filename);
391 qWarning() <<
"Could not execute id/version query" << q.lastError() << q.boundValues();
395 qWarning() <<
"Could not find the resource in the database" << storageLocation << resourceType << filename;
398 resource->setResourceId(q.value(0).toInt());
399 Q_ASSERT(
resource->resourceId() >= 0);
401 resource->setVersion(q.value(1).toInt());
404 resource->setMD5Sum(q.value(2).toString());
405 Q_ASSERT(!
resource->md5Sum().isEmpty());
407 resource->setActive(q.value(4).toBool());
410 resource->setName(q.value(3).toString());;
414 qWarning() <<
"Could not find resource" << resourceType +
"/" + filename;
434 d->resourceCache.remove(key);
449 if (!f.open(QFile::ReadOnly)) {
450 qWarning() <<
"Could not open" << fileName <<
"for loading";
454 return importResource(resourceType, fileName, &f, allowOverwrite, storageLocation);
462 QByteArray resourceData = device->readAll();
466 QBuffer buf(&resourceData);
467 buf.open(QBuffer::ReadOnly);
472 qWarning() <<
"Could not import" << fileName <<
": resource doesn't load.";
480 qWarning() <<
"Could not import" << fileName <<
": resource doesn't load.";
485 const QString resourceUrl = resourceType +
"/" +
resource->filename();
487 KoResourceSP existingResource = storage->resource(resourceUrl);
489 if (existingResource) {
490 const QString existingResourceMd5Sum = storage->resourceMd5(resourceUrl);
492 if (!allowOverwrite) {
496 if (existingResourceMd5Sum == md5 &&
497 existingResource->filename() ==
resource->filename()) {
506 int existingResourceId = -1;
509 if (r && existingResourceId > 0) {
514 qWarning() <<
"A resource with the same filename but a different MD5 already exists in the storage" << resourceType << fileName << storageLocation;
515 if (storageLocation ==
"") {
516 qWarning() <<
"Proceeding with overwriting the existing resource...";
521 int existingResourceId = -1;
524 if (r && existingResourceId >= 0) {
527 for (
int i = 0; i < versionsLocations.size(); i++) {
530 r = QFile::remove(fi.filePath());
532 qWarning() <<
"KisResourceLocator::importResourceFromFile: Removal of " << fi.filePath()
533 <<
"was requested, but it wasn't possible, something went wrong.";
536 qWarning() <<
"KisResourceLocator::importResourceFromFile: Removal of " << fi.filePath()
537 <<
"was requested, but it doesn't exist.";
541 qWarning() <<
"KisResourceLocator::importResourceFromFile: Finding all locations for " << existingResourceId <<
"was requested, but it failed.";
545 qWarning() <<
"KisResourceLocator::importResourceFromFile: there is no resource file found in the location of " << storageLocation <<
resource->filename() << resourceType;
562 qWarning() <<
"KisResourceLocator::importResourceFromFile: Removing resource with id " << existingResourceId <<
"completely from the database failed.";
567 qWarning() <<
"KisResourceLocator::importResourceFromFile: Overwriting of the resource was denied, aborting import.";
572 QBuffer buf(&resourceData);
573 buf.open(QBuffer::ReadOnly);
575 if (storage->importResource(resourceUrl, &buf)) {
576 resource = storage->resource(resourceUrl);
579 qWarning() <<
"Could not retrieve imported resource from the storage" << resourceType << fileName << storageLocation;
583 resource->setStorageLocation(storageLocation);
584 resource->setMD5Sum(storage->resourceMd5(resourceUrl));
593 storage->timeStampForResource(resourceType,
resource->filename()),
605 const QPair<QString, QString> key = {absoluteStorageLocation, resourceType +
"/" +
resource->filename()};
617QString findDeduplicatedFileName(
const QString &resourceType,
const QString &proposedFileName,
KisResourceStorageSP storage)
620 auto fileAllowedCallback = [resourceType, storage] (
const QString &fileName) {
621 QString resourceUrl = resourceType +
"/" + fileName;
622 return !storage->resource(resourceUrl);
634 const QString fileName = findDeduplicatedFileName(resourceType, proposedFileName, storage);
635 return importResource(resourceType, fileName, device,
false, storageLocation);
641 if (
resource->filename().isEmpty()) {
650 const QString fileName = findDeduplicatedFileName(resourceType,
resource->filename(), storage);
660 const QString resourceUrl = resourceType +
"/" + QFileInfo(fileName).fileName();
662 KoResourceSP existingResource = storage->resource(resourceUrl);
664 return !existingResource.isNull();
671 const QString resourceUrl =
resource->resourceType().first +
"/" +
resource->filename();
674 return storage->exportResource(resourceUrl, device);
685 if (
resource->filename().isEmpty()) {
694 if (!storage->addResource(
resource)) {
695 qWarning() <<
"Could not add resource" <<
resource->filename() <<
"to the storage" << storageLocation;
699 resource->setStorageLocation(storageLocation);
700 resource->setMD5Sum(storage->resourceMd5(resourceType +
"/" +
resource->filename()));
704 d->resourceCache[QPair<QString, QString>(storageLocation, resourceType +
"/" +
resource->filename())] =
resource;
712 storage->timeStampForResource(resourceType,
resource->filename()),
729 if (!storage->supportsVersioning())
return false;
738 if (!storage->saveAsNewVersion(
resource)) {
739 qWarning() <<
"Failed to save the new version of " <<
resource->name() <<
"to storage" << storageLocation;
743 resource->setMD5Sum(storage->resourceMd5(resourceType +
"/" +
resource->filename()));
749 qWarning() <<
"Failed to add a new version of the resource to the database" <<
resource->name();
754 qWarning() <<
"Failed to update resource metadata" <<
resource;
759 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType +
"/" +
resource->filename());
769 if (
resource->resourceId() < 0)
return false;
775 if (!storage->loadVersionedResource(
resource)) {
776 qWarning() <<
"Failed to reload the resource" <<
resource->name() <<
"from storage" << storageLocation;
780 resource->setMD5Sum(storage->resourceMd5(resourceType +
"/" +
resource->filename()));
785 QPair<QString, QString> key = QPair<QString, QString> (storageLocation, resourceType +
"/" +
resource->filename());
786 Q_ASSERT(
d->resourceCache[key] ==
resource);
803 QMap<QString, QVariant> metadata;
808 Q_FOREACH(
const QString key, storage->metaDataKeys()) {
809 metadata[key] = storage->metaData(key);
819 Q_FOREACH(
const QString &key, map.keys()) {
820 storage->setMetaData(key, map[key]);
826 Q_FOREACH(
const auto key,
d->resourceCache.keys()) {
827 if (key.first == storageLocation) {
828 d->resourceCache.remove(key);
833 for (
auto it =
d->tagCache.begin(); it !=
d->tagCache.end();) {
834 if (removedTagIds.contains(it.value()->id())) {
835 it =
d->tagCache.erase(it);
844 if (
d->storages.contains(storageLocation)) {
846 qWarning() <<
"could not remove" << storageLocation;
853 int numAddedResources = 0;
856 while (it->hasNext()) {
861 if (numAddedResources > 0) {
862 addedResources << std::make_pair(type, numAddedResources);
866 Q_FOREACH (
const auto &typedResources, addedResources) {
870 d->storages[storageLocation] = storage;
872 d->errorMessages.append(i18n(
"Could not add %1 to the database", storage->location()));
873 qWarning() <<
d->errorMessages;
878 d->errorMessages.append(QString(
"Could not add tags for storage %1 to the cache database").arg(storage->location()));
879 qWarning() <<
d->errorMessages;
883 Q_FOREACH (
const auto &typedResources, addedResources) {
894 if (!
d->storages.contains(storageLocation)) {
902 if (!resources.isEmpty()) {
903 removedResources << std::make_pair(type, resources);
911 removedTags << std::make_pair(type, uniqueTags);
912 allRemovedTagIds << uniqueTags;
915 Q_FOREACH (
const auto &typedResources, removedResources) {
920 Q_UNUSED(removedTags);
922 purge(storageLocation, allRemovedTagIds);
927 d->errorMessages.append(i18n(
"Could not remove storage %1 from the database", storage->location()));
928 qWarning() <<
d->errorMessages;
932 Q_FOREACH (
const auto &typedResources, removedResources) {
943 return d->storages.contains(document);
950 if (!query.prepare(
"SELECT tags.url \n"
951 ", resource_types.name \n"
954 "WHERE tags.resource_type_id = resource_types.id\n"))
956 qWarning() <<
"Could not prepare save tags query" << query.lastError();
961 qWarning() <<
"Could not execute save tags query" << query.lastError();
969 while (query.next()) {
972 query.value(
"resource_types.name").toString());
974 if (!tag || !tag->valid()) {
979 QString filename = tag->filename();
980 if (filename.isEmpty() || QFileInfo(filename).suffix().isEmpty()) {
981 filename = tag->url() +
".tag";
985 if (QFileInfo(filename).suffix() !=
"tag" && QFileInfo(filename).suffix() !=
"TAG") {
988 dbgResources <<
"Skipping saving tag " << tag->name(
false) << filename << tag->resourceType();
992 filename.remove(resourceLocation);
994 QFile f(resourceLocation +
"/" + tag->resourceType() +
'/' + filename);
996 if (!f.open(QFile::WriteOnly)) {
997 qWarning () <<
"Could not open tag file for writing" << f.fileName();
1002 buf.open(QIODevice::WriteOnly);;
1004 if (!tag->save(buf)) {
1005 qWarning() <<
"Could not save tag to" << f.fileName();
1011 f.write(buf.data());
1020 d->tagCache.remove(QPair<QString, QString>(resourceType, tagUrl));
1028 const QString resourceUrl =
resource->resourceType().first +
"/" +
resource->filename();
1030 return storage->resourceFilePath(resourceUrl);
1036 qWarning() << i18n(
"Could not synchronize updated font registry with the database");
1044 Q_EMIT
progressMessage(i18n(
"Krita is running for the first time. Initialization will take some time."));
1045 Q_UNUSED(initializationStatus);
1048 QDir dir(
d->resourceLocation +
'/' + folder +
'/');
1049 if (!dir.exists()) {
1050 if (!QDir().mkpath(
d->resourceLocation +
'/' + folder +
'/')) {
1051 d->errorMessages << i18n(
"3. Could not create the resource location at %1.", dir.path());
1058 QDir dir(installationResourcesLocation +
'/' + folder +
'/');
1060 Q_FOREACH(
const QString &entry, dir.entryList(QDir::Files | QDir::Readable)) {
1061 QFile f(dir.canonicalPath() +
'/'+ entry);
1062 if (!QFileInfo(
d->resourceLocation +
'/' + folder +
'/' + entry).exists()) {
1063 if (!f.copy(
d->resourceLocation +
'/' + folder +
'/' + entry)) {
1064 d->errorMessages << i18n(
"Could not copy resource %1 to %2", f.fileName(),
d->resourceLocation +
'/' + folder +
'/' + entry);
1073 QDirIterator iter(installationResourcesLocation, filters, QDir::Files, QDirIterator::Subdirectories);
1074 while (iter.hasNext()) {
1076 Q_EMIT
progressMessage(i18n(
"Installing the resources from bundle %1.", iter.filePath()));
1077 QFile f(iter.filePath());
1078 Q_ASSERT(f.exists());
1079 if (!f.copy(
d->resourceLocation +
'/' + iter.fileName())) {
1080 d->errorMessages << i18n(
"Could not copy resource %1 to %2", f.fileName(),
d->resourceLocation);
1084 QFile f(
d->resourceLocation +
'/' +
"KRITA_RESOURCE_VERSION");
1085 if (f.open(QFile::WriteOnly)) {
1089 qWarning() <<
"Could not open" << f.fileName() <<
"for writing:" << f.errorString();
1097 d->storages.clear();
1098 d->resourceCache.clear();
1102 Q_ASSERT(storage->location() ==
d->resourceLocation);
1103 d->storages[
d->resourceLocation] = storage;
1118 QDirIterator iter(
d->resourceLocation, filters, QDir::Files, QDirIterator::Subdirectories);
1119 while (iter.hasNext()) {
1122 if (!storage->valid()) {
1124 qWarning() <<
"KisResourceLocator::findStorages: the storage is invalid" << storage->location();
1126 d->storages[storage->location()] = storage;
1137 return d->storages.values();
1143 if (!storage || !storage->valid()) {
1144 qWarning() <<
"Could not retrieve the" << location <<
"storage object or the object is not valid";
1171 bool r = q.prepare(
"SELECT storages.location\n"
1172 ", resource_types.name as resource_type\n"
1173 ", resources.filename\n"
1176 ", resource_types\n"
1177 "WHERE resources.id = :resource_id\n"
1178 "AND resources.storage_id = storages.id\n"
1179 "AND resource_types.id = resources.resource_type_id");
1181 qWarning() <<
"KisResourceLocator::removeResource: could not prepare query." << q.lastError();
1186 q.bindValue(
":resource_id", resourceId);
1190 qWarning() <<
"KisResourceLocator::removeResource: could not execute query." << q.lastError();
1196 QString storageLocation = q.value(
"location").toString();
1197 QString resourceType= q.value(
"resource_type").toString();
1198 QString resourceFilename = q.value(
"filename").toString();
1211 if (storageLocation.isEmpty()) {
1215 if (QFileInfo(storageLocation).isRelative() && (storageLocation.endsWith(
".bundle", Qt::CaseInsensitive)
1216 || storageLocation.endsWith(
".asl", Qt::CaseInsensitive)
1217 || storageLocation.endsWith(
".abr", Qt::CaseInsensitive))) {
1227 return storageLocation;
1234 d->errorMessages.clear();
1245 d->errorMessages.append(i18n(
"Could not synchronize %1 with the database", storage->location()));
1253 d->errorMessages.append(i18n(
"Could not synchronize %1 with the database", storage->location()));
1273 for (
int i = 0; i < model.
rowCount(); i++) {
1274 QModelIndex idx = model.index(i, 0);
1276 storagesToRemove << location;
1279 for (
int i = 0; i < storagesToRemove.size(); i++) {
1280 QString location = storagesToRemove[i];
1281 if (!
d->storages.contains(this->makeStorageLocationAbsolute(location))) {
1284 qWarning() <<
d->errorMessages;
1295 d->resourceCache.clear();
1296 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 std::pair< QVector< int >, QVector< int > > tagsForStorage(const QString &resourceType, const QString &storageLocation)
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
KisResourceStorageSP safeGetStorage(const QString &storageLocation)
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
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.
KoResourceSP importResourceDeduplicateFileName(const QString &resourceType, const QString &proposedFileName, QIODevice *device, const QString &storageLocation=QString())
importResourceDeduplicateFileName imports the resource fith file name deduplication
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 purge(const QString &storageLocation, const QVector< int > &removedTagIds)
purge purges the local resource cache
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)
bool addResourceDeduplicateFileName(const QString &resourceType, const KoResourceSP resource, const QString &storageLocation)
addResourceDeduplicateFileName imports the resource fith file name deduplication
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_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
QString deduplicateFileName(const QString &fileName, const QString &separator, std::function< bool(QString)> fileAllowedCallback)
KRITAVERSION_EXPORT QString versionString(bool checkGit=false)