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
28class QWidget;
29class KUrl;
30class 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 */
38class KOODF_EXPORT KoStore
39{
40public:
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 extractFile(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 extractFile(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);
307protected:
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
367protected:
368 KoStorePrivate *d_ptr;
369
370private:
371 Q_DECLARE_PRIVATE(KoStore)
372
373private:
374 KoStore(const KoStore& store); ///< don't copy
375 KoStore& operator=(const KoStore& store); ///< don't assign
376};
377
378#endif
379