File indexing completed on 2024-05-19 04:27:38
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 friend class KisResourceThumbnailCache; 0163 0164 /// @return true if the resource is present in the cache, false if it hasn't been loaded 0165 bool resourceCached(QString storageLocation, const QString &resourceType, const QString &filename) const; 0166 0167 /** 0168 * @brief resource finds a physical resource in one of the storages 0169 * @param storageLocation the storage containing the resource. If empty, 0170 * this is the folder storage. 0171 * 0172 * Note that the resource does not have the version or id field set, so this cannot be used directly, 0173 * but only through KisResourceModel. 0174 * 0175 * @param resourceType the type of the resource 0176 * @param filename the filename of the resource including extension, but without 0177 * any paths 0178 * @return A resource if found, or 0 0179 */ 0180 KoResourceSP resource(QString storageLocation, const QString &resourceType, const QString &filename); 0181 0182 /** 0183 * @brief resourceForId returns the resource with the given id, or 0 if no such resource exists. 0184 * The resource object will have its id set but not its version. 0185 * @param resourceId the id 0186 */ 0187 KoResourceSP resourceForId(int resourceId); 0188 0189 /** 0190 * @brief setResourceActive 0191 * @param resourceId 0192 * @param active shows if the resource should be set as active or not 0193 * @return 0194 */ 0195 bool setResourceActive(int resourceId, bool active); 0196 0197 /** 0198 * @brief importResourceFromFile 0199 * @param resourceType 0200 * @param fileName 0201 * @param storageLocation: optional, the storage where the resource will be stored. Empty means in the default Folder storage. 0202 * @return the imported resource, which has been added to the database and the cache 0203 */ 0204 KoResourceSP importResourceFromFile(const QString &resourceType, const QString &fileName, const bool allowOverwrite, const QString &storageLocation = QString()); 0205 0206 /** 0207 * @brief importResource 0208 * @param resourceType 0209 * @param fileName: filename that should be assigned to the resource 0210 * @param device: QIODevice where the resource should be loaded from 0211 * @param storageLocation: optional, the storage where the resource will be stored. Empty means in the default Folder storage. 0212 * @return the imported resource, which has been added to the database and the cache 0213 */ 0214 KoResourceSP importResource(const QString &resourceType, const QString &fileName, QIODevice *device, const bool allowOverwrite, const QString &storageLocation = QString()); 0215 0216 /** 0217 * @brief return whether importing will overwrite some existing resource 0218 * @param resourceType 0219 * @param fileName: filename that should be assigned to the resource 0220 * @param storageLocation: optional, the storage where the resource will be stored. Empty means in the default Folder storage. 0221 */ 0222 bool importWillOverwriteResource(const QString &resourceType, const QString &fileName, const QString &storageLocation = QString()) const; 0223 0224 /** 0225 * @brief exportResource 0226 * @param resource resource to be exported 0227 * @param device: QIODevice where the resource should be loaded to 0228 * @return true if the resource has been exported successfully 0229 */ 0230 bool exportResource(KoResourceSP resource, QIODevice *device); 0231 0232 /** 0233 * @brief addResource adds the given resource to the database and potentially a storage 0234 * @param resourceType the type of the resource 0235 * @param resource the actual resource object 0236 * @param storageLocation the storage where the resource will be saved. By default this is the default folder storage. 0237 * @return true if successful 0238 */ 0239 bool addResource(const QString &resourceType, const KoResourceSP resource, const QString &storageLocation = QString()); 0240 0241 /** 0242 * @brief updateResource 0243 * @param resourceType 0244 * @param resource 0245 * @return 0246 */ 0247 bool updateResource(const QString &resourceType, const KoResourceSP resource); 0248 0249 /** 0250 * @brief Reloads the resource from its persistent storage 0251 * @param resourceType the type of the resource 0252 * @param resource the actual resource object 0253 * @return true if reloading was successful. When returned false, 0254 * \p resource is kept unchanged 0255 */ 0256 bool reloadResource(const QString &resourceType, const KoResourceSP resource); 0257 0258 /** 0259 * @brief metaDataForResource 0260 * @param id 0261 * @return 0262 */ 0263 QMap<QString, QVariant> metaDataForResource(int id) const; 0264 0265 /** 0266 * @brief setMetaDataForResource 0267 * @param id 0268 * @param map 0269 * @return 0270 */ 0271 bool setMetaDataForResource(int id, QMap<QString, QVariant> map) const; 0272 0273 /** 0274 * @brief metaDataForStorage 0275 * @param storage 0276 * @return 0277 */ 0278 QMap<QString, QVariant> metaDataForStorage(const QString &storageLocation) const; 0279 0280 /** 0281 * @brief setMetaDataForStorage 0282 * @param storage 0283 * @param map 0284 */ 0285 void setMetaDataForStorage(const QString &storageLocation, QMap<QString, QVariant> map) const; 0286 0287 /** 0288 * Loads all the resources required by \p resource into the cache 0289 * 0290 * loadRequiredResources() also loads embedded resources and adds them 0291 * into the database. 0292 */ 0293 void loadRequiredResources(KoResourceSP resource); 0294 0295 /** 0296 * @brief tagForUrl create a tag from the database 0297 * @param tagUrl the url 0298 * @return a complete tag with all translated names and comments. 0299 */ 0300 KisTagSP tagForUrl(const QString &tagUrl, const QString resourceType); 0301 0302 /** 0303 * @brief tagForUrlNoCache create a tag from the database, don't use cache 0304 * @param tagUrl url of the tag 0305 * @param resourceType resource type of the tag 0306 * @return 0307 */ 0308 static KisTagSP tagForUrlNoCache(const QString &tagUrl, const QString resourceType); 0309 0310 KisResourceLocator(QObject *parent); 0311 KisResourceLocator(const KisResourceLocator&); 0312 KisResourceLocator operator=(const KisResourceLocator&); 0313 0314 enum class InitializationStatus { 0315 Unknown, // We don't know whether Krita has run on this system for this resource location yet 0316 Initialized, // Everything is ready to start synchronizing the database 0317 FirstRun, // Krita hasn't run for this resource location yet 0318 FirstUpdate, // Krita was installed, but it's a version from before the resource locator existed, only user-defined resources are present 0319 Updating // Krita is updating from an older version with resource locator 0320 }; 0321 0322 LocatorError firstTimeInstallation(InitializationStatus initializationStatus, const QString &installationResourcesLocation); 0323 0324 // First time installation 0325 bool initializeDb(); 0326 0327 // Synchronize on restarting Krita to see whether the user has added any storages or resources to the resources location 0328 bool synchronizeDb(); 0329 0330 void findStorages(); 0331 QList<KisResourceStorageSP> storages() const; 0332 0333 KisResourceStorageSP storageByLocation(const QString &location) const; 0334 KisResourceStorageSP folderStorage() const; 0335 KisResourceStorageSP memoryStorage() const; 0336 0337 struct ResourceStorage { 0338 QString storageLocation; 0339 QString resourceType; 0340 QString resourceFileName; 0341 }; 0342 0343 friend class KisMyPaintPaintOpPreset; 0344 0345 ResourceStorage getResourceStorage(int resourceId) const; 0346 QString makeStorageLocationAbsolute(QString storageLocation) const; 0347 QString makeStorageLocationRelative(QString location) const; 0348 0349 class Private; 0350 QScopedPointer<Private> d; 0351 }; 0352 0353 #endif // KISRESOURCELOCATOR_H