1 /* 2 SPDX-FileCopyrightText: 2008 Volker Krause <vkrause@kde.org> 3 4 SPDX-License-Identifier: LGPL-2.0-or-later 5 */ 6 7 #pragma once 8 9 #include "akonadi-singlefileresource_export.h" 10 #include <Akonadi/ResourceBase> 11 12 #include <QStringList> 13 #include <QUrl> 14 15 namespace KIO 16 { 17 class FileCopyJob; 18 class Job; 19 } 20 21 namespace Akonadi 22 { 23 /** 24 * Base class for single file based resources. 25 * @see SingleFileResource 26 */ 27 class AKONADI_SINGLEFILERESOURCE_EXPORT SingleFileResourceBase : public ResourceBase, public AgentBase::Observer 28 { 29 Q_OBJECT 30 public: 31 explicit SingleFileResourceBase(const QString &id); 32 33 /** 34 * Set the mimetypes supported by this resource and an optional icon for the collection. 35 */ 36 void setSupportedMimetypes(const QStringList &mimeTypes, const QString &icon = QString()); 37 38 void collectionChanged(const Akonadi::Collection &collection) override; 39 40 public Q_SLOTS: 41 void reloadFile(); 42 43 /* 44 * Read the current state from a file. This can happen 45 * from direct callers, or as part of a scheduled task. 46 * @p taskContext specifies whether the method is being 47 * called from within a task or not. 48 */ 49 virtual void readFile(bool taskContext = false) = 0; 50 /* 51 * Writes the current state out to a file. This can happen 52 * from direct callers, or as part of a scheduled task. 53 * @p taskContext specifies whether the method is being 54 * called from within a task or not. 55 */ 56 virtual void writeFile(bool taskContext = false) = 0; 57 58 /* 59 * Same method as above, but uses a QVariant so it can 60 * be called from Akonadi::ResourceScheduler. 61 */ 62 virtual void writeFile(const QVariant &taskContext) = 0; 63 64 protected: 65 /** 66 * Implement in derived classes to do things when the configuration changes 67 * before reload file is called. 68 */ 69 virtual void applyConfigurationChanges(); 70 71 /** 72 * Returns a pointer to the KConfig object which is used to store runtime 73 * information of the resource. 74 */ 75 KSharedConfig::Ptr runtimeConfig() const; 76 77 /** 78 * Handles everything needed when the hash of a file has changed between the 79 * last write and the first read. This stores the new hash in a config file 80 * and notifies implementing resources to handle a hash change if the 81 * previous known hash was not empty. Finally this method clears the cache 82 * and calls synchronize. 83 * Returns true on success, false otherwise. 84 */ 85 bool readLocalFile(const QString &fileName); 86 87 /** 88 * Reimplement to read your data from the given file. 89 * The file is always local, loading from the network is done 90 * automatically if needed. 91 */ 92 virtual bool readFromFile(const QString &fileName) = 0; 93 94 /** 95 * Reimplement to write your data to the given file. 96 * The file is always local, storing back to the network url is done 97 * automatically when needed. 98 */ 99 virtual bool writeToFile(const QString &fileName) = 0; 100 101 /** 102 * It is not always needed to parse the file when a resources is started. 103 * (e.g. When the hash of the file is the same as the last time the resource 104 * has written changes to the file). In this case setActualFileName is 105 * called so that the implementing resource does know which file to read 106 * when it actually needs to read the file. 107 * 108 * The default implementation will just call readFromFile( fileName ), so 109 * implementing resources will have to explicitly reimplement this method to 110 * actually get any profit of this. 111 * 112 * @p fileName This will always be a path to a local file. 113 */ 114 virtual void setLocalFileName(const QString &fileName); 115 116 /** 117 * Generates the full path for the cache file in the case that a remote file 118 * is used. 119 */ 120 QString cacheFile() const; 121 122 /** 123 * Calculates an MD5 hash for given file. If the file does not exists 124 * or the path is empty, this will return an empty QByteArray. 125 */ 126 QByteArray calculateHash(const QString &fileName) const; 127 128 /** 129 * This method is called when the hash of the file has changed between the 130 * last writeFile() and a readFile() call. This means that the file was 131 * changed by another program. 132 * 133 * Note: This method is <em>not</em> called when the last known hash is 134 * empty. In that case it is assumed that the file is loaded for the 135 * first time. 136 */ 137 virtual void handleHashChange(); 138 139 /** 140 * Returns the hash that was stored to a cache file. 141 */ 142 QByteArray loadHash() const; 143 144 /** 145 * Stores the given hash into a cache file. 146 */ 147 void saveHash(const QByteArray &hash) const; 148 149 /** 150 * Returns whether the resource can be written to. 151 */ 152 virtual bool readOnly() const = 0; 153 154 /** 155 * Returns the collection of this resource. 156 */ 157 virtual Collection rootCollection() const = 0; 158 159 protected: 160 QUrl mCurrentUrl; 161 QStringList mSupportedMimetypes; 162 QString mCollectionIcon; 163 KIO::FileCopyJob *mDownloadJob = nullptr; 164 KIO::FileCopyJob *mUploadJob = nullptr; 165 QByteArray mCurrentHash; 166 167 protected Q_SLOTS: 168 void scheduleWrite(); /// Called when changes are added to the ChangeRecorder. 169 void handleProgress(KJob *, unsigned long); 170 void fileChanged(const QString &fileName); 171 void slotDownloadJobResult(KJob *); 172 void slotUploadJobResult(KJob *); 173 }; 174 } 175 176