KCoreAddons

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

KDE's Doxygen guidelines are available online.