1 | /* This file is part of the KDE project |
2 | Copyright (C) 1998, 1999 David Faure <faure@kde.org> |
3 | Copyright (C) 2010 C. Boemann <cbo@boemann.dk> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2 of the License, or (at your option) any later version. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Library General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Library General Public License |
16 | along with this library; see the file COPYING.LIB. If not, write to |
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | * Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | #ifndef __koStore_h_ |
22 | #define __koStore_h_ |
23 | |
24 | #include <QByteArray> |
25 | #include <QIODevice> |
26 | #include "koodf_export.h" |
27 | |
28 | class QWidget; |
29 | class KUrl; |
30 | class KoStorePrivate; |
31 | |
32 | /** |
33 | * Saves and loads Calligra documents using various backends. Currently supported |
34 | * backends are ZIP, tar and directory. |
35 | * We call a "store" the file on the hard disk (the one the users sees) |
36 | * and call a "file" a file inside the store. |
37 | */ |
38 | class KOODF_EXPORT KoStore |
39 | { |
40 | public: |
41 | |
42 | enum Mode { Read, Write }; |
43 | enum Backend { Auto, Tar, Zip, Directory, Encrypted }; |
44 | |
45 | /** |
46 | * Open a store (i.e. the representation on disk of a Calligra document). |
47 | * |
48 | * @param fileName the name of the file to open |
49 | * @param mode if KoStore::Read, open an existing store to read it. |
50 | * if KoStore::Write, create or replace a store. |
51 | * @param backend the backend to use for the data storage. |
52 | * Auto means automatically-determined for reading, |
53 | * and the current format (now Zip) for writing. |
54 | * |
55 | * @param appIdentification the application's mimetype, |
56 | * to be written in the file for "mime-magic" identification. |
57 | * Only meaningful if mode is Write, and if backend!=Directory. |
58 | * |
59 | * @param writeMimetype If true, some backends (notably the Zip |
60 | * store) will write a file called 'mimetype' automatically and |
61 | * fill it with data from the appIdentification. This is only |
62 | * applicable if Mode is set to Write. |
63 | */ |
64 | static KoStore *createStore(const QString &fileName, Mode mode, |
65 | const QByteArray &appIdentification = QByteArray(), |
66 | Backend backend = Auto, bool writeMimetype = true); |
67 | |
68 | /** |
69 | * Create a store for any kind of QIODevice: file, memory buffer... |
70 | * KoStore will take care of opening the QIODevice. |
71 | * This method doesn't support the Directory store! |
72 | */ |
73 | static KoStore *createStore(QIODevice *device, Mode mode, |
74 | const QByteArray &appIdentification = QByteArray(), |
75 | Backend backend = Auto, bool writeMimetype = true); |
76 | |
77 | /** |
78 | * Open a store (i.e. the representation on disk of a Calligra document). |
79 | * |
80 | * @param window associated window (for the progress bar dialog and authentication) |
81 | * @param url URL of the file to open |
82 | * @param mode if KoStore::Read, open an existing store to read it. |
83 | * if KoStore::Write, create or replace a store. |
84 | * @param backend the backend to use for the data storage. |
85 | * Auto means automatically-determined for reading, |
86 | * and the current format (now Zip) for writing. |
87 | * |
88 | * @param appIdentification the application's mimetype, |
89 | * to be written in the file for "mime-magic" identification. |
90 | * Only meaningful if mode is Write, and if backend!=Directory. |
91 | * |
92 | * If the file is remote, the backend Directory cannot be used! |
93 | * |
94 | * @param writeMimetype If true, some backends (notably the Zip |
95 | * store) will write a file called 'mimetype' automatically and |
96 | * fill it with data from the appIdentification. This is only |
97 | * applicable if Mode is set to Write. |
98 | * |
99 | * @bug saving not completely implemented (fixed temporary file) |
100 | */ |
101 | static KoStore *createStore(QWidget *window, const KUrl &url, Mode mode, |
102 | const QByteArray &appIdentification = QByteArray(), Backend backend = Auto, bool writeMimetype = true); |
103 | |
104 | /** |
105 | * Destroys the store (i.e. closes the file on the hard disk) |
106 | */ |
107 | virtual ~KoStore(); |
108 | |
109 | /** |
110 | * Returns the url of the store. It can be a filename or a remote url. |
111 | * it can also be empty, if the store is a bytearray |
112 | * @return the url of the store as supplied in the createStore calls |
113 | */ |
114 | KUrl urlOfStore() const; |
115 | |
116 | /** |
117 | * Open a new file inside the store |
118 | * @param name The filename, internal representation ("root", "tar:/0"... ). |
119 | * If the tar:/ prefix is missing it's assumed to be a relative URI. |
120 | * @return true on success. |
121 | */ |
122 | bool open(const QString &name); |
123 | |
124 | /** |
125 | * Check whether a file inside the store is currently opened with open(), |
126 | * ready to be read or written. |
127 | * @return true if a file is currently opened. |
128 | */ |
129 | bool isOpen() const; |
130 | |
131 | /** |
132 | * Close the file inside the store |
133 | * @return true on success. |
134 | */ |
135 | bool close(); |
136 | |
137 | /** |
138 | * Get a device for reading a file from the store directly |
139 | * (slightly faster than read() calls) |
140 | * You need to call @ref open first, and @ref close afterwards. |
141 | */ |
142 | QIODevice *device() const; |
143 | |
144 | /** |
145 | * Read data from the currently opened file. You can also use the streams |
146 | * for this. |
147 | */ |
148 | QByteArray read(qint64 max); |
149 | |
150 | /** |
151 | * Write data into the currently opened file. You can also use the streams |
152 | * for this. |
153 | */ |
154 | qint64 write(const QByteArray &data); |
155 | |
156 | /** |
157 | * Read data from the currently opened file. You can also use the streams |
158 | * for this. |
159 | * @return size of data read, -1 on error |
160 | */ |
161 | qint64 read(char *buffer, qint64 length); |
162 | |
163 | /** |
164 | * Write data into the currently opened file. You can also use the streams |
165 | * for this. |
166 | */ |
167 | virtual qint64 write(const char* data, qint64 length); |
168 | |
169 | /** |
170 | * @return the size of the currently opened file, -1 on error. |
171 | * Can be used as an argument for the read methods, for instance |
172 | */ |
173 | qint64 size() const; |
174 | |
175 | /** |
176 | * @return true if an error occurred |
177 | */ |
178 | bool bad() const; |
179 | |
180 | /** |
181 | * @return the mode used when opening, read or write |
182 | */ |
183 | Mode mode() const; |
184 | |
185 | /** |
186 | * Enters one or multiple directories. In Read mode this actually |
187 | * checks whether the specified directories exist and returns false |
188 | * if they don't. In Write mode we don't create the directory, we |
189 | * just use the "current directory" to generate the absolute path |
190 | * if you pass a relative path (one not starting with tar:/) when |
191 | * opening a stream. |
192 | * Note: Operates on internal names |
193 | */ |
194 | bool enterDirectory(const QString &directory); |
195 | |
196 | /** |
197 | * Leaves a directory. Equivalent to "cd .." |
198 | * @return true on success, false if we were at the root already to |
199 | * make it possible to "loop to the root" |
200 | */ |
201 | bool leaveDirectory(); |
202 | |
203 | /** |
204 | * Returns the current path including a trailing slash. |
205 | * Note: Returns a path in "internal name" style |
206 | */ |
207 | QString currentPath() const; |
208 | |
209 | /** |
210 | * Stacks the current directory. Restore the current path using |
211 | * @ref popDirectory . |
212 | */ |
213 | void pushDirectory(); |
214 | |
215 | /** |
216 | * Restores the previously pushed directory. No-op if the stack is |
217 | * empty. |
218 | */ |
219 | void popDirectory(); |
220 | |
221 | /** |
222 | * @return true if the given file exists in the current directory, |
223 | * i.e. if open(fileName) will work. |
224 | */ |
225 | bool hasFile(const QString &fileName) const; |
226 | |
227 | /** |
228 | * Imports a local file into a store |
229 | * @param fileName file on hard disk |
230 | * @param destName file in the store |
231 | */ |
232 | bool addLocalFile(const QString &fileName, const QString &destName); |
233 | |
234 | /** |
235 | * Imports data into a store |
236 | * @param buffer data |
237 | * @param destName file in the store |
238 | */ |
239 | bool addDataToFile(QByteArray &buffer, const QString &destName); |
240 | |
241 | /** |
242 | * Extracts a file out of the store |
243 | * @param sourceName file in the store |
244 | * @param fileName file on a disk |
245 | */ |
246 | bool (const QString &sourceName, const QString &fileName); |
247 | |
248 | /** |
249 | * Extracts a file out of the store to a buffer |
250 | * @param sourceName file in the store |
251 | * @param data memory buffer |
252 | */ |
253 | bool (const QString &sourceName, QByteArray &data); |
254 | |
255 | //@{ |
256 | /// See QIODevice |
257 | bool seek(qint64 pos); |
258 | qint64 pos() const; |
259 | bool atEnd() const; |
260 | //@} |
261 | |
262 | /** |
263 | * Call this before destroying the store, to be able to catch errors |
264 | * (e.g. from ksavefile) |
265 | */ |
266 | bool finalize(); |
267 | |
268 | /** |
269 | * Sets the password to be used for decryption or encryption of the store. |
270 | * Use of this function is optional: an encryptable store should make |
271 | * a best effort in obtaining a password if it wasn't supplied. |
272 | * |
273 | * This method only works before opening a file. It might fail when a file |
274 | * has already been opened before calling this method. |
275 | * |
276 | * This method will not function for any store that is not encrypted or |
277 | * can't be encrypted when saving. |
278 | * |
279 | * @param password A non-empty password. |
280 | * |
281 | * @return True if the password was set. |
282 | */ |
283 | virtual bool setPassword(const QString &password); |
284 | |
285 | /** |
286 | * Retrieves the password used to encrypt or decrypt the store. Note that |
287 | * QString() will returned if no password has been given or the store is |
288 | * not encrypted. |
289 | * |
290 | * @return The password this store is encrypted with. |
291 | */ |
292 | virtual QString password(); |
293 | |
294 | /** |
295 | * Returns whether a store opened for reading is encrypted or a store opened |
296 | * for saving will be encrypted. |
297 | * |
298 | * @return True if the store is encrypted. |
299 | */ |
300 | virtual bool isEncrypted(); |
301 | |
302 | /** |
303 | * Allow to enable or disable compression of the files. Only supported by the |
304 | * ZIP backend. |
305 | */ |
306 | virtual void setCompressionEnabled(bool e); |
307 | protected: |
308 | |
309 | KoStore(bool writeMimetype = true); |
310 | |
311 | /** |
312 | * Init store - called by constructor. |
313 | * @return true on success |
314 | */ |
315 | virtual bool init(Mode mode); |
316 | |
317 | /** |
318 | * Finalize store - called by finalize. |
319 | * @return true on success |
320 | */ |
321 | virtual bool doFinalize() { |
322 | return true; |
323 | } |
324 | |
325 | /** |
326 | * Open the file @p name in the store, for writing |
327 | * On success, this method must set m_stream to a stream in which we can write. |
328 | * @param name "absolute path" (in the archive) to the file to open |
329 | * @return true on success |
330 | */ |
331 | virtual bool openWrite(const QString &name) = 0; |
332 | /** |
333 | * Open the file @p name in the store, for reading. |
334 | * On success, this method must set m_stream to a stream from which we can read, |
335 | * as well as setting m_iSize to the size of the file. |
336 | * @param name "absolute path" (in the archive) to the file to open |
337 | * @return true on success |
338 | */ |
339 | virtual bool openRead(const QString &name) = 0; |
340 | |
341 | /** |
342 | * @return true on success |
343 | */ |
344 | virtual bool closeRead() = 0; |
345 | /** |
346 | * @return true on success |
347 | */ |
348 | virtual bool closeWrite() = 0; |
349 | |
350 | /** |
351 | * Enter a subdirectory of the current directory. |
352 | * The directory might not exist yet in Write mode. |
353 | */ |
354 | virtual bool enterRelativeDirectory(const QString &dirName) = 0; |
355 | /** |
356 | * Enter a directory where we've been before. |
357 | * It is guaranteed to always exist. |
358 | */ |
359 | virtual bool enterAbsoluteDirectory(const QString &path) = 0; |
360 | |
361 | /** |
362 | * Check if a file exists inside the store. |
363 | * @param absPath the absolute path inside the store, i.e. not relative to the current directory |
364 | */ |
365 | virtual bool fileExists(const QString &absPath) const = 0; |
366 | |
367 | protected: |
368 | KoStorePrivate *d_ptr; |
369 | |
370 | private: |
371 | Q_DECLARE_PRIVATE(KoStore) |
372 | |
373 | private: |
374 | KoStore(const KoStore& store); ///< don't copy |
375 | KoStore& operator=(const KoStore& store); ///< don't assign |
376 | }; |
377 | |
378 | #endif |
379 | |