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