File indexing completed on 2024-05-12 15:59:50
0001 /* 0002 * SPDX-FileCopyrightText: 2018 Boudewijn Rempt <boud@valdyas.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KISRESOURCELOCATOR_H 0008 #define KISRESOURCELOCATOR_H 0009 0010 #include <QObject> 0011 #include <QScopedPointer> 0012 #include <QStringList> 0013 #include <QString> 0014 0015 #include "kritaresources_export.h" 0016 0017 #include <KisResourceStorage.h> 0018 0019 0020 /** 0021 * The KisResourceLocator class locates all resource storages (folders, 0022 * bundles, various adobe resource libraries) in the resource location. 0023 * 0024 * The resource location is always a writable folder. 0025 * 0026 * There is one resource locator which is owned by the QApplication 0027 * object. 0028 * 0029 * The resource location is configurable, but there is only one location 0030 * where Krita will look for resources. 0031 */ 0032 class KRITARESOURCES_EXPORT KisResourceLocator : public QObject 0033 { 0034 Q_OBJECT 0035 public: 0036 0037 // The configuration key that holds the resource location 0038 // for this installation of Krita. The location is 0039 // QStandardPaths::AppDataLocation by default, but that 0040 // can be changed. 0041 static const QString resourceLocationKey; 0042 0043 static KisResourceLocator *instance(); 0044 0045 ~KisResourceLocator(); 0046 0047 enum class LocatorError { 0048 Ok, 0049 LocationReadOnly, 0050 CannotCreateLocation, 0051 CannotInitializeDb, 0052 CannotSynchronizeDb 0053 }; 0054 0055 /** 0056 * @brief initialize Setup the resource locator for use. 0057 * 0058 * @param installationResourcesLocation the place where the resources 0059 * that come packaged with Krita reside. 0060 */ 0061 LocatorError initialize(const QString &installationResourcesLocation); 0062 0063 /** 0064 * @brief errorMessages 0065 * @return 0066 */ 0067 QStringList errorMessages() const; 0068 0069 /** 0070 * @brief resourceLocationBase is the place where all resource storages (folder, 0071 * bundles etc. are located. This is a writable place. 0072 * @return the base location for all storages. 0073 */ 0074 QString resourceLocationBase() const; 0075 0076 /** 0077 * @brief purge purges the local resource cache 0078 */ 0079 void purge(const QString &storageLocation); 0080 0081 /** 0082 * @brief addStorage Adds a new resource storage to the database. The storage is 0083 * will be marked as not pre-installed. If there is already a storage with the 0084 * given location, it will first be removed. 0085 * @param storageLocation a unique name for the given storage 0086 * @param storage a storage object 0087 * @return true if the storage has been added successfully 0088 */ 0089 bool addStorage(const QString &storageLocation, KisResourceStorageSP storage); 0090 0091 /** 0092 * @brief removeStorage removes the temporary storage from the database 0093 * @param storageLocation the unique name of the storage 0094 * @return true is successful. 0095 */ 0096 bool removeStorage(const QString &storageLocation); 0097 0098 /** 0099 * @brief hasStorage can be used to check whether the given storage already exists 0100 * @param storageLocation the name of the storage 0101 * @return true if the storage is known 0102 */ 0103 bool hasStorage(const QString &storageLocation); 0104 0105 0106 /** 0107 * @brief saveTags saves all tags to .tag files in the resource folder 0108 */ 0109 static void saveTags(); 0110 0111 /** 0112 * Remove the given tag from the cache 0113 */ 0114 void purgeTag(const QString tagUrl, const QString resourceType); 0115 0116 /** 0117 * Returns the full file path of the resource if it has any 0118 * separate physical representation on the disk 0119 */ 0120 QString filePathForResource(KoResourceSP resource); 0121 0122 Q_SIGNALS: 0123 0124 void progressMessage(const QString&); 0125 0126 /// Emitted whenever a storage is added 0127 void storageAdded(const QString &location); 0128 0129 /// Emitted whenever a storage is removed 0130 void storageRemoved(const QString &location); 0131 0132 /// Emitted when the locator needs to add an embedded resource 0133 void beginExternalResourceImport(const QString &resourceType, int numResources); 0134 0135 /// Emitted when the locator finished importing the embedded resource 0136 void endExternalResourceImport(const QString &resourceType); 0137 0138 /// Emitted when the locator needs to add an embedded resource 0139 void beginExternalResourceRemove(const QString &resourceType, const QVector<int> resourceIds); 0140 0141 /// Emitted when the locator finished importing the embedded resource 0142 void endExternalResourceRemove(const QString &resourceType); 0143 0144 /// Emitted when a resource changes its active state 0145 void resourceActiveStateChanged(const QString &resourceType, int resourceId); 0146 0147 private: 0148 0149 friend class KisAllTagsModel; 0150 friend class KisTagResourceModel; 0151 friend class KisAllResourcesModel; 0152 friend class KisAllTagResourceModel; 0153 friend class KisStorageModel; 0154 friend class TestResourceLocator; 0155 friend class TestResourceModel; 0156 friend class Resource; 0157 friend class KisResourceCacheDb; 0158 friend class KisStorageFilterProxyModel; 0159 friend class KisResourceQueryMapper; 0160 friend class KisResourceUserOperations; 0161 friend class KisBrushTypeMetaDataFixup; 0162 0163 /// @return true if the resource is present in the cache, false if it hasn't been loaded 0164 bool resourceCached(QString storageLocation, const QString &resourceType, const QString &filename) const; 0165 0166 /// add the thumbnail associated with resouceId to cache 0167 void cacheThumbnail(QString storageLocation, const QString &resourceType, const QString &filename, const QImage &img); 0168 0169 /// @return a valid image if the thumbnail is present in the cache, an invalid image otherwise 0170 QImage thumbnailCached(QString storageLocation, const QString &resourceType, const QString &filename); 0171 0172 /** 0173 * @brief resource finds a physical resource in one of the storages 0174 * @param storageLocation the storage containing the resource. If empty, 0175 * this is the folder storage. 0176 * 0177 * Note that the resource does not have the version or id field set, so this cannot be used directly, 0178 * but only through KisResourceModel. 0179 * 0180 * @param resourceType the type of the resource 0181 * @param filename the filename of the resource including extension, but without 0182 * any paths 0183 * @return A resource if found, or 0 0184 */ 0185 KoResourceSP resource(QString storageLocation, const QString &resourceType, const QString &filename); 0186 0187 /** 0188 * @brief resourceForId returns the resource with the given id, or 0 if no such resource exists. 0189 * The resource object will have its id set but not its version. 0190 * @param resourceId the id 0191 */ 0192 KoResourceSP resourceForId(int resourceId); 0193 0194 /** 0195 * @brief setResourceActive 0196 * @param resourceId 0197 * @param active shows if the resource should be set as active or not 0198 * @return 0199 */ 0200 bool setResourceActive(int resourceId, bool active); 0201 0202 /** 0203 * @brief importResourceFromFile 0204 * @param resourceType 0205 * @param fileName 0206 * @param storageLocation: optional, the storage where the resource will be stored. Empty means in the default Folder storage. 0207 * @return the imported resource, which has been added to the database and the cache 0208 */ 0209 KoResourceSP importResourceFromFile(const QString &resourceType, const QString &fileName, const bool allowOverwrite, const QString &storageLocation = QString()); 0210 0211 /** 0212 * @brief importResource 0213 * @param resourceType 0214 * @param fileName: filename that should be assigned to the resource 0215 * @param device: QIODevice where the resource should be loaded from 0216 * @param storageLocation: optional, the storage where the resource will be stored. Empty means in the default Folder storage. 0217 * @return the imported resource, which has been added to the database and the cache 0218 */ 0219 KoResourceSP importResource(const QString &resourceType, const QString &fileName, QIODevice *device, const bool allowOverwrite, const QString &storageLocation = QString()); 0220 0221 /** 0222 * @brief return whether importing will overwrite some existing resource 0223 * @param resourceType 0224 * @param fileName: filename that should be assigned to the resource 0225 * @param storageLocation: optional, the storage where the resource will be stored. Empty means in the default Folder storage. 0226 */ 0227 bool importWillOverwriteResource(const QString &resourceType, const QString &fileName, const QString &storageLocation = QString()) const; 0228 0229 /** 0230 * @brief exportResource 0231 * @param resource resource to be exported 0232 * @param device: QIODevice where the resource should be loaded to 0233 * @return true if the resource has been exported successfully 0234 */ 0235 bool exportResource(KoResourceSP resource, QIODevice *device); 0236 0237 /** 0238 * @brief addResource adds the given resource to the database and potentially a storage 0239 * @param resourceType the type of the resource 0240 * @param resource the actual resource object 0241 * @param storageLocation the storage where the resource will be saved. By default this is the the default folder storage. 0242 * @return true if successful 0243 */ 0244 bool addResource(const QString &resourceType, const KoResourceSP resource, const QString &storageLocation = QString()); 0245 0246 /** 0247 * @brief updateResource 0248 * @param resourceType 0249 * @param resource 0250 * @return 0251 */ 0252 bool updateResource(const QString &resourceType, const KoResourceSP resource); 0253 0254 /** 0255 * @brief Reloads the resource from its persistent storage 0256 * @param resourceType the type of the resource 0257 * @param resource the actual resource object 0258 * @return true if reloading was successful. When returned false, 0259 * \p resource is kept unchanged 0260 */ 0261 bool reloadResource(const QString &resourceType, const KoResourceSP resource); 0262 0263 /** 0264 * @brief metaDataForResource 0265 * @param id 0266 * @return 0267 */ 0268 QMap<QString, QVariant> metaDataForResource(int id) const; 0269 0270 /** 0271 * @brief setMetaDataForResource 0272 * @param id 0273 * @param map 0274 * @return 0275 */ 0276 bool setMetaDataForResource(int id, QMap<QString, QVariant> map) const; 0277 0278 /** 0279 * @brief metaDataForStorage 0280 * @param storage 0281 * @return 0282 */ 0283 QMap<QString, QVariant> metaDataForStorage(const QString &storageLocation) const; 0284 0285 /** 0286 * @brief setMetaDataForStorage 0287 * @param storage 0288 * @param map 0289 */ 0290 void setMetaDataForStorage(const QString &storageLocation, QMap<QString, QVariant> map) const; 0291 0292 /** 0293 * Loads all the resources required by \p resource into the cache 0294 * 0295 * loadRequiredResources() also loads embedded resources and adds them 0296 * into the database. 0297 */ 0298 void loadRequiredResources(KoResourceSP resource); 0299 0300 /** 0301 * @brief tagForUrl create a tag from the database 0302 * @param tagUrl the url 0303 * @return a complete tag with all translated names and comments. 0304 */ 0305 KisTagSP tagForUrl(const QString &tagUrl, const QString resourceType); 0306 0307 /** 0308 * @brief tagForUrlNoCache create a tag from the database, don't use cache 0309 * @param tagUrl url of the tag 0310 * @param resourceType resource type of the tag 0311 * @return 0312 */ 0313 static KisTagSP tagForUrlNoCache(const QString &tagUrl, const QString resourceType); 0314 0315 KisResourceLocator(QObject *parent); 0316 KisResourceLocator(const KisResourceLocator&); 0317 KisResourceLocator operator=(const KisResourceLocator&); 0318 0319 enum class InitializationStatus { 0320 Unknown, // We don't know whether Krita has run on this system for this resource location yet 0321 Initialized, // Everything is ready to start synchronizing the database 0322 FirstRun, // Krita hasn't run for this resource location yet 0323 FirstUpdate, // Krita was installed, but it's a version from before the resource locator existed, only user-defined resources are present 0324 Updating // Krita is updating from an older version with resource locator 0325 }; 0326 0327 LocatorError firstTimeInstallation(InitializationStatus initializationStatus, const QString &installationResourcesLocation); 0328 0329 // First time installation 0330 bool initializeDb(); 0331 0332 // Synchronize on restarting Krita to see whether the user has added any storages or resources to the resources location 0333 bool synchronizeDb(); 0334 0335 void findStorages(); 0336 QList<KisResourceStorageSP> storages() const; 0337 0338 KisResourceStorageSP storageByLocation(const QString &location) const; 0339 KisResourceStorageSP folderStorage() const; 0340 KisResourceStorageSP memoryStorage() const; 0341 0342 struct ResourceStorage { 0343 QString storageLocation; 0344 QString resourceType; 0345 QString resourceFileName; 0346 }; 0347 0348 friend class KisMyPaintPaintOpPreset; 0349 0350 ResourceStorage getResourceStorage(int resourceId) const; 0351 QString makeStorageLocationAbsolute(QString storageLocation) const; 0352 QString makeStorageLocationRelative(QString location) const; 0353 0354 class Private; 0355 QScopedPointer<Private> d; 0356 }; 0357 0358 #endif // KISRESOURCELOCATOR_H