1 /************************************************************************ 2 ** 3 ** Copyright (C) 2015-2019 Kevin B. Hendricks, Stratford, Ontario Canada 4 ** Copyright (C) 2009-2011 Strahinja Markovic <strahinja.markovic@gmail.com> 5 ** 6 ** This file is part of Sigil. 7 ** 8 ** Sigil is free software: you can redistribute it and/or modify 9 ** it under the terms of the GNU General Public License as published by 10 ** the Free Software Foundation, either version 3 of the License, or 11 ** (at your option) any later version. 12 ** 13 ** Sigil is distributed in the hope that it will be useful, 14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ** GNU General Public License for more details. 17 ** 18 ** You should have received a copy of the GNU General Public License 19 ** along with Sigil. If not, see <http://www.gnu.org/licenses/>. 20 ** 21 *************************************************************************/ 22 23 #pragma once 24 #ifndef RESOURCE_H 25 #define RESOURCE_H 26 27 #include <QtCore/QObject> 28 #include <QtCore/QReadWriteLock> 29 #include <QtCore/QUrl> 30 #include <QtGui/QIcon> 31 32 /** 33 * Represents a resource file on disk. 34 * Stores data caches for improved performance, 35 * enables safe multi-threaded access to the data 36 * and holds all sorts of meta information 37 * on the file. 38 */ 39 class Resource : public QObject 40 { 41 Q_OBJECT 42 43 public: 44 45 /** 46 * Used to inspect a resource's type. 47 * There's a reason why all of these end with *Type. If we just use the 48 * name of the subclass without the suffix, then we get a name clash in 49 * Resource subclasses that use other Resource subclasses. While we can 50 * get around this with a ::, Qt's MOC is not smart enough and sees slots 51 * that refer to, say, ::HTMLResource as having a parameter type of "::HTMLResource". 52 * That is then incompatible with just "HTMLResource". So we use a suffix. 53 */ 54 enum ResourceType { 55 GenericResourceType = 1 << 0, /**< A \em vulgaris resource; used for Misc resources. */ 56 TextResourceType = 1 << 1, /**< Used for Text resources, but \em not HTML files. */ 57 XMLResourceType = 1 << 2, /**< Used for Text resources, but \em not HTML files. */ 58 HTMLResourceType = 1 << 3, /**< Used for pure (X)HTML resources. */ 59 CSSResourceType = 1 << 4, /**< Used for CSS resources (stylesheets). */ 60 ImageResourceType = 1 << 5, /**< Used for image resource, of all types. */ 61 SVGResourceType = 1 << 6, /**< Used for SVG image resources. */ 62 FontResourceType = 1 << 7, /**< Used for font resources, both TTF and OTF. */ 63 OPFResourceType = 1 << 8, /**< Used for the OPF document. */ 64 NCXResourceType = 1 << 9, /**< Used for the NCX table of contents. */ 65 MiscTextResourceType = 1 << 10, /**< Used for editable text resource. */ 66 AudioResourceType = 1 << 11, /**< Used for Audio resources. */ 67 VideoResourceType = 1 << 12 /**< Used for Video resources. */ 68 }; 69 70 /** 71 * Constructor. 72 * 73 * @param fullfilepath The full path to the file that this 74 * resource is representing. 75 * @param parent The object's parent. 76 */ 77 Resource(const QString &mainfolder, const QString &fullfilepath, QObject *parent = NULL); 78 79 /** 80 * The less-than operator overload. By default, compares 81 * the resources by filename (lexical). 82 * 83 * @param other The other Resource object we're comparing with. 84 */ 85 virtual bool operator< (const Resource &other); 86 87 /** 88 * Returns the resource's UUID. 89 * 90 * @return The resource's UUID. 91 */ 92 QString GetIdentifier() const; 93 94 /** 95 * Returns the resource's filename. 96 * 97 * @return The resource's filename. 98 */ 99 QString Filename() const; 100 101 QString GetFolder() const; 102 103 QString GetRelativePath() const; 104 105 QString ShortPathName() const; 106 107 QString GetRelativePathFromResource(const Resource* start_resource) const; 108 109 QString GetRelativePathToResource(const Resource* dest_resource) const; 110 111 /** 112 * Returns the resource's full file path. 113 * We \em really shouldn't be using this, 114 * it kinda breaks encapsulation. 115 * 116 * @return The resource's full file path. 117 */ 118 QString GetFullPath() const; 119 120 /** 121 * Returns the full path to the folder containing 122 * this resource 123 * @return The resource's full path to its containing folder. 124 */ 125 QString GetFullFolderPath() const; 126 127 /** 128 * Returns the URL to the parent folder ("base URL") of this resource. 129 * 130 * @return The base URL. 131 */ 132 QUrl GetBaseUrl() const; 133 134 /** 135 * gets and set the original path relative to the import location 136 */ 137 138 void SetCurrentBookRelPath(const QString& ); 139 140 QString GetCurrentBookRelPath(); 141 142 /** 143 * gets and set the epub version this resource is used in 144 */ 145 146 void SetEpubVersion(const QString& ); 147 148 QString GetEpubVersion() const; 149 150 /** 151 * gets and sets the resources media-type 152 */ 153 154 void SetMediaType(const QString& ); 155 156 QString GetMediaType() const; 157 158 /** 159 * gets and sets the resources Longest Common Path Group 160 */ 161 162 void SetShortPathName(const QString& ); 163 164 QString GetFullPathToBookFolder() const; 165 166 /** 167 * Returns a reference to the resource's ReadWriteLock. 168 * 169 * @return The resource's ReadWriteLock. 170 */ 171 QReadWriteLock &GetLock() const; 172 173 /** 174 * Returns the resource's icon. 175 * 176 * @return The resource's icon. 177 */ 178 QIcon Icon() const; 179 180 /** 181 * Renames the resource. 182 * 183 * @param new_filename The new name. 184 * @return \c true if the operation was successful. 185 */ 186 virtual bool RenameTo(const QString &new_filename); 187 188 189 /** 190 * Moves the resource. 191 * 192 * @param new_bookpath The new bookpath. 193 * @return \c true if the operation was successful. 194 */ 195 virtual bool MoveTo(const QString &new_bookpath); 196 197 /** 198 * Deletes the resource. 199 * 200 * @return \c true if the operation was successful. 201 */ 202 virtual bool Delete(); 203 204 /** 205 * Returns the resource's type. 206 * 207 * @return The resource's type. 208 */ 209 virtual ResourceType Type() const; 210 211 /** 212 * Instructs the resource to save any cached data to disk. 213 * The default implementation does nothing, and assumes 214 * the resource data is not being cached in memory. 215 * 216 * @param book_wide_save If \c false (the default), a ResourceUpdatedOnDisk() 217 * signal will be emitted. 218 */ 219 virtual void SaveToDisk(bool book_wide_save = false); 220 221 /** 222 * Called by FolderKeeper when files get changed on disk. 223 * May trigger a resource internal update if the files were not changed by Sigil. 224 */ 225 void FileChangedOnDisk(); 226 227 signals: 228 229 /** 230 * Emitted whenever the resource changes its name. 231 * 232 * @param resource The resource's that was renamed. 233 */ 234 void Renamed(const Resource *resource, QString old_full_path); 235 236 /** 237 * Emitted whenever the resource changes location. 238 * 239 * @param resource The resource's that was moved. 240 */ 241 void Moved(const Resource *resource, QString old_full_path); 242 243 /** 244 * Emitted when the resource has been scheduled for deletion. 245 * 246 * @param resource The resource's that was deleted. 247 */ 248 void Deleted(const Resource *resource); 249 250 /** 251 * Emitted when the resource has been updated on disk. 252 */ 253 void ResourceUpdatedOnDisk(); 254 255 /** 256 * Emitted after a resource was refreshed from a newer version on disk. 257 * Caused by book files being modified from outside Sigil. 258 */ 259 void ResourceUpdatedFromDisk(Resource *resource); 260 261 /** 262 * Emitted when the resource has been modified. This 263 * modification may or may not be visible on the disk. 264 * (this means that the ResourceUpdatedOnDisk may or may 265 * not have been also emitted). 266 * Note that in the cases where a user of the Resource is 267 * using its low-level interfaces, the resource can be modified 268 * without this signal being emitted. It is then up to the user 269 * to emit this signal. Modifying the resource in such a way 270 * without emitting this signal is an error. 271 */ 272 void Modified(); 273 274 protected: 275 /** 276 * Update the internal resource data from the disk file. 277 */ 278 virtual bool LoadFromDisk(); 279 280 private slots: 281 /** 282 * When ResourceFileChanged detects a modification this slot is activated on 283 * a timer to wait for the file to stop changing. 284 */ 285 void ResourceFileModified(); 286 287 private: 288 289 /** 290 * The resources identifying UUID. 291 */ 292 QString m_Identifier; 293 294 QString m_MainFolder; 295 296 /** 297 * The full path to the resource on disk. 298 */ 299 QString m_FullFilePath; 300 301 /** 302 * Timestamp of when the resource was last saved to disk by Sigil. 303 */ 304 qint64 m_LastSaved; 305 306 /** 307 * Timestamp of when the resource was last written to by an external application. 308 */ 309 qint64 m_LastWrittenTo; 310 311 /** 312 * Size of the resource when last written to by an external application. 313 */ 314 qint64 m_LastWrittenSize; 315 316 /** 317 * The original path to this resource from its imported epub 318 */ 319 QString m_CurrentBookRelPath; 320 321 /** 322 * The version of epub this resource is used in 323 */ 324 QString m_EpubVersion; 325 326 /** 327 * The media type of the resource 328 */ 329 QString m_MediaType; 330 331 332 QString m_ShortName; 333 334 /** 335 * The ReadWriteLock guarding access to the resource's data. 336 */ 337 mutable QReadWriteLock m_ReadWriteLock; 338 }; 339 340 #endif // RESOURCE_H 341