1 | /* This file is part of the KDE libraries |
2 | Copyright (c) 2006 Jacob R Rideout <kde@jacobrideout.net> |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2 of the License, or (at your option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #ifndef KAUTOSAVEFILE_H |
21 | #define KAUTOSAVEFILE_H |
22 | |
23 | #include <kdecore_export.h> |
24 | #include "kurl.h" |
25 | |
26 | #include <QtCore/QFile> |
27 | #include <QtCore/QList> |
28 | |
29 | class KAutoSaveFilePrivate; |
30 | /** |
31 | * \class KAutoSaveFile kautosavefile.h <KAutoSaveFile> |
32 | * |
33 | * @brief Creates and manages a temporary "auto-save" file. |
34 | * Autosave files are temporary files that applications use to store |
35 | * the unsaved data in a file they have open for |
36 | * editing. KAutoSaveFile allows you to easily create and manage such |
37 | * files, as well as to recover the unsaved data left over by a |
38 | * crashed or otherwise gone process. |
39 | * |
40 | * Each KAutoSaveFile object is associated with one specific file that |
41 | * the application holds open. KAutoSaveFile is also a QObject, so it |
42 | * can be reparented to the actual opened file object, so as to manage |
43 | * the lifetime of the temporary file. |
44 | * |
45 | * Typical use consists of: |
46 | * - verifying whether stale autosave files exist for the opened file |
47 | * - deciding whether to recover the old, autosaved data |
48 | * - if not recovering, creating a KAutoSaveFile object for the opened file |
49 | * - during normal execution of the program, periodically save unsaved |
50 | * data into the KAutoSaveFile file. |
51 | * |
52 | * KAutoSaveFile holds a lock on the autosave file, so it's safe to |
53 | * delete the file and recreate it later. Because of that, disposing |
54 | * of stale autosave files should be done with releaseLock(). No lock is |
55 | * held on the managed file. |
56 | * |
57 | * Examples: |
58 | * Opening a new file: |
59 | * @code |
60 | * void Document::open(const KUrl &url) |
61 | * { |
62 | * // check whether autosave files exist: |
63 | * QList<KAutoSaveFile *> staleFiles = KAutoSaveFile::staleFiles(url); |
64 | * if (!staleFiles.isEmpty()) { |
65 | * if (KMessageBox::questionYesNo(parent, |
66 | * "Auto-saved files exist. Do you want to recover them now?", |
67 | * "File Recovery", |
68 | * "Recover", "Don't recover") == KMessage::Yes) { |
69 | * recoverFiles(staleFiles); |
70 | * return; |
71 | * } else { |
72 | * // remove the stale files |
73 | * foreach (KAutoSaveFile *stale, staleFiles) { |
74 | * stale->open(QIODevice::ReadWrite); |
75 | * delete stale; |
76 | * } |
77 | * } |
78 | * } |
79 | * |
80 | * // create new autosave object |
81 | * m_autosave = new KAutoSaveFile(url, this); |
82 | * |
83 | * // continue the process of opening file 'url' |
84 | * ... |
85 | * } |
86 | * @endcode |
87 | * |
88 | * The function recoverFiles could loop over the list of files and do this: |
89 | * @code |
90 | * foreach (KAutoSaveFile *stale, staleFiles) { |
91 | * if (!stale->open(QIODevice::ReadWrite)) { |
92 | * // show an error message; we could not steal the lockfile |
93 | * // maybe another application got to the file before us? |
94 | * delete stale; |
95 | * continue; |
96 | * } |
97 | * Document *doc = new Document; |
98 | * doc->m_autosave = stale; |
99 | * stale->setParent(doc); // reparent |
100 | * |
101 | * doc->setUrl(stale->managedFile()); |
102 | * doc->setContents(stale->readAll()); |
103 | * doc->setState(Document::Modified); // mark it as modified and unsaved |
104 | * |
105 | * documentManager->addDocument(doc); |
106 | * } |
107 | * @endcode |
108 | * |
109 | * If the file is unsaved, periodically write the contents to the save file: |
110 | * @code |
111 | * if (!m_autosave->isOpen() && !m_autosave->open(QIODevice::ReadWrite)) { |
112 | * // show error: could not open the autosave file |
113 | * } |
114 | * m_autosave->write(contents()); |
115 | * @endcode |
116 | * |
117 | * When the user saves the file, the autosaved file is no longer |
118 | * necessary and can be removed or emptied. |
119 | * @code |
120 | * m_autosave->resize(0); // leaves the file open |
121 | * @endcode |
122 | * |
123 | * @code |
124 | * m_autosave->remove(); // closes the file |
125 | * @endcode |
126 | * |
127 | * @author Jacob R Rideout <kde@jacobrideout.net> |
128 | */ |
129 | class KDECORE_EXPORT KAutoSaveFile : public QFile |
130 | { |
131 | Q_OBJECT |
132 | public: |
133 | /** |
134 | * Constructs a KAutoSaveFile for file @p filename. The temporary |
135 | * file is not opened or created until actually needed. The file |
136 | * @p filename does not have to exist for KAutoSaveFile to be |
137 | * constructed (if it exists, it will not be touched). |
138 | * |
139 | * @param filename the filename that this KAutoSaveFile refers to |
140 | * @param parent the parent object |
141 | */ |
142 | explicit KAutoSaveFile(const KUrl &filename, QObject *parent = 0); |
143 | |
144 | /** |
145 | * @overload |
146 | * Constructs a KAutoSaveFile object. Note that you need to call |
147 | * setManagedFile() before calling open(). |
148 | * |
149 | * @param parent the parent object |
150 | */ |
151 | explicit KAutoSaveFile(QObject *parent = 0); |
152 | |
153 | /** |
154 | * Destroys the KAutoSaveFile object, removes the autosave |
155 | * file and drops the lock being held (if any). |
156 | */ |
157 | ~KAutoSaveFile(); |
158 | |
159 | /** |
160 | * Retrieves the URL of the file managed by KAutoSaveFile. This |
161 | * is the same URL that was given to setManagedFile() or the |
162 | * KAutoSaveFile constructor. |
163 | * |
164 | * This is the name of the real file being edited by the |
165 | * application. To get the name of the temporary file where data |
166 | * can be saved, use fileName() (after you have called open()). |
167 | */ |
168 | KUrl managedFile() const; |
169 | |
170 | /** |
171 | * Sets the URL of the file managed by KAutoSaveFile. This should |
172 | * be the name of the real file being edited by the application. |
173 | * If the file was previously set, this function calls releaseLock(). |
174 | * |
175 | * @param filename the filename that this KAutoSaveFile refers to |
176 | */ |
177 | void setManagedFile(const KUrl &filename); |
178 | |
179 | /** |
180 | * Closes the autosave file resource and removes the lock |
181 | * file. The file name returned by fileName() will no longer be |
182 | * protected and can be overwritten by another application at any |
183 | * time. To obtain a new lock, call open() again. |
184 | * |
185 | * This function calls remove(), so the autosave temporary file |
186 | * will be removed too. |
187 | */ |
188 | virtual void releaseLock(); |
189 | |
190 | /** |
191 | * Opens the autosave file and locks it if it wasn't already |
192 | * locked. The name of the temporary file where data can be saved |
193 | * to will be set by this function and can be retrieved with |
194 | * fileName(). It will not change unless releaseLock() is called. No |
195 | * other application will attempt to edit such a file either while |
196 | * the lock is held. |
197 | * |
198 | * @param openmode the mode that should be used to open the file, |
199 | * probably QIODevice::ReadWrite |
200 | * @returns true if the file could be opened (= locked and |
201 | * created), false if the operation failed |
202 | */ |
203 | virtual bool open(OpenMode openmode); |
204 | |
205 | /** |
206 | * Checks for stale autosave files for @p filename. Returns a list |
207 | * of autosave files that contain autosaved data left behind by |
208 | * other instances of the application, due to crashing or |
209 | * otherwise uncleanly exiting. |
210 | * |
211 | * It is the application's job to determine what to do with such |
212 | * unsaved data. Generally, this is done by asking the user if he |
213 | * wants to see the recovered data, and then allowing the user to |
214 | * save if he wants to. |
215 | * |
216 | * If not given, the application name is obtained from |
217 | * QCoreApplication, so be sure to have set it correctly before |
218 | * calling this function. |
219 | * |
220 | * This function returns a list of unopened KAutoSaveFile |
221 | * objects. By calling open() on them, the application will steal |
222 | * the lock. Subsequent releaseLock() or deleting of the object will |
223 | * then erase the stale autosave file. |
224 | */ |
225 | static QList<KAutoSaveFile *> staleFiles(const KUrl &filename, |
226 | const QString &applicationName = |
227 | QString()); |
228 | |
229 | /** |
230 | * Returns all stale autosave files left behind by crashed or |
231 | * otherwise gone instances of this application. |
232 | * |
233 | * If not given, the application name is obtained from |
234 | * QCoreApplication, so be sure to have set it correctly before |
235 | * calling this function. |
236 | * |
237 | * See staleFiles() for information on the returned objects. |
238 | */ |
239 | static QList<KAutoSaveFile *> allStaleFiles(const QString &applicationName = |
240 | QString()); |
241 | |
242 | private: |
243 | Q_DISABLE_COPY(KAutoSaveFile) |
244 | friend class KAutoSaveFilePrivate; |
245 | KAutoSaveFilePrivate* const d; |
246 | }; |
247 | |
248 | #endif // KAUTOSAVEFILE_H |
249 | |