1 //  -*- c-basic-offset:4; indent-tabs-mode:nil -*-
2 /*
3     This file is part of the KDE libraries
4     SPDX-FileCopyrightText: 2000, 2006 David Faure <faure@kde.org>
5 
6     SPDX-License-Identifier: LGPL-2.0-only
7 */
8 #ifndef __kbookmarkmanager_h
9 #define __kbookmarkmanager_h
10 
11 #include <QDomDocument>
12 #include <QObject>
13 #include <QString>
14 
15 #include <memory>
16 
17 class KBookmarkManagerPrivate;
18 
19 #include "kbookmark.h"
20 #if KBOOKMARKS_ENABLE_DEPRECATED_SINCE(5, 79)
21 #include "kbookmarkowner.h" // for SC reasons
22 #endif
23 
24 class KBookmarkGroup;
25 class QDBusMessage;
26 
27 /**
28  * @class KBookmarkManager kbookmarkmanager.h KBookmarkManager
29  *
30  * This class implements the reading/writing of bookmarks in XML.
31  * The bookmarks file is read and written using the XBEL standard
32  * (http://pyxml.sourceforge.net/topics/xbel/)
33  *
34  * A sample file looks like this :
35  * \code
36  * <xbel>
37  *   <bookmark href="http://techbase.kde.org"><title>Developer Web Site</title></bookmark>
38  *   <folder folded="no">
39  *     <title>Title of this folder</title>
40  *     <bookmark icon="kde" href="http://www.kde.org"><title>KDE Web Site</title></bookmark>
41  *     <folder toolbar="yes">
42  *       <title>My own bookmarks</title>
43  *       <bookmark href="http://www.koffice.org"><title>KOffice Web Site</title></bookmark>
44  *       <separator/>
45  *       <bookmark href="http://www.kdevelop.org"><title>KDevelop Web Site</title></bookmark>
46  *     </folder>
47  *   </folder>
48  * </xbel>
49  * \endcode
50  */
51 class KBOOKMARKS_EXPORT KBookmarkManager : public QObject
52 {
53     Q_OBJECT
54 private:
55     /**
56      * Creates a bookmark manager with a path to the bookmarks.  By
57      * default, it will use the KDE standard dirs to find and create the
58      * correct location.  If you are using your own app-specific
59      * bookmarks directory, you must instantiate this class with your
60      * own path <em>before</em> KBookmarkManager::managerForFile() is ever
61      * called.
62      *
63      * @param bookmarksFile full path to the bookmarks file,
64      * Use ~/.kde/share/apps/konqueror/bookmarks.xml for the konqueror bookmarks
65      *
66      * @param dbusObjectName a unique name that represents this bookmark collection,
67      * usually your component (e.g. application) name. This is "konqueror" for the
68      * konqueror bookmarks, "kfile" for KFileDialog bookmarks, etc.
69      * The final D-Bus object path is /KBookmarkManager/dbusObjectName
70      * An empty @p dbusObjectName disables the registration to D-Bus (used for temporary managers)
71      */
72     KBookmarkManager(const QString &bookmarksFile, const QString &dbusObjectName);
73 
74     /**
75      * Creates a bookmark manager for an external file
76      * (Using QFileSystemWatcher for change monitoring)
77      * @since 4.1
78      */
79     KBookmarkManager(const QString &bookmarksFile);
80 
81     /**
82      * Creates a temp bookmark manager
83      */
84     KBookmarkManager();
85 
86 public:
87     /**
88      * Destructor
89      */
90     ~KBookmarkManager() override;
91 
92     /**
93      * Check whether auto error handling is enabled.
94      * If enabled, it will show an error dialog to the user when an
95      * error occurs. It is turned on by default.
96      * @return true if auto error handling is enabled, false otherwise
97      * @note dialogs will only be displayed if the current thread is the gui thread
98      * @since 4.6
99      * @see setAutoErrorHandlingEnabled()
100      */
101     bool autoErrorHandlingEnabled() const;
102 
103     /**
104      * Enable or disable auto error handling is enabled.
105      * If enabled, it will show an error dialog to the user when an
106      * error occurs. It is turned on by default.
107      * If disabled, the application should react on the error() signal.
108      * @param enable true to enable auto error handling, false to disable
109      * @param parent the parent widget for the error dialogs, can be @c nullptr for
110      *               top-level
111      * @since 4.6
112      * @see autoErrorHandlingEnabled()
113      */
114     void setAutoErrorHandlingEnabled(bool enable, QWidget *parent);
115 
116     /**
117      * Set the update flag. Defaults to true.
118      * @param update if true then KBookmarkManager will listen to D-Bus update requests.
119      */
120     void setUpdate(bool update);
121 
122     /**
123      * Save the bookmarks to the given XML file on disk.
124      * @param filename full path to the desired bookmarks file location
125      * @param toolbarCache iff true save a cache of the toolbar folder, too
126      * @return true if saving was successful
127      */
128     // KF6 TODO: Use an enum and not a bool
129     bool saveAs(const QString &filename, bool toolbarCache = true) const;
130 
131     /**
132      * Update access time stamps for a given url.
133      * @param url the viewed url
134      * @return true if any metadata was modified (bookmarks file is not saved automatically)
135      */
136     bool updateAccessMetadata(const QString &url);
137 
138     /*
139      * NB. currently *unimplemented*
140      *
141      * Update favicon url for a given url.
142      * @param url the viewed url
143      * @param faviconurl the favicion url
144      */
145     void updateFavicon(const QString &url, const QString &faviconurl);
146 
147     /**
148      * This will return the path that this manager is using to read
149      * the bookmarks.
150      * @internal
151      * @return the path containing the bookmarks
152      */
153     QString path() const;
154 
155     /**
156      * This will return the root bookmark.  It is used to iterate
157      * through the bookmarks manually.  It is mostly used internally.
158      *
159      * @return the root (top-level) bookmark
160      */
161     KBookmarkGroup root() const;
162 
163     /**
164      * This returns the root of the toolbar menu.
165      * In the XML, this is the group with the attribute toolbar=yes
166      *
167      * @return the toolbar group
168      */
169     KBookmarkGroup toolbar();
170 
171     /**
172      * @return the bookmark designated by @p address
173      * @param address the address belonging to the bookmark you're looking for
174      * @param tolerate when true tries to find the most tolerable bookmark position
175      * @see KBookmark::address
176      */
177     KBookmark findByAddress(const QString &address);
178 
179     /**
180      * Saves the bookmark file and notifies everyone.
181      *
182      **/
183     void emitChanged();
184 
185     /**
186      * Saves the bookmark file and notifies everyone.
187      * @param group the parent of all changed bookmarks
188      */
189     void emitChanged(const KBookmarkGroup &group);
190 
191     /**
192      * Save the bookmarks to an XML file on disk.
193      * You should use emitChanged() instead of this function, it saves
194      * and notifies everyone that the file has changed.
195      * Only use this if you don't want the emitChanged signal.
196      * @param toolbarCache iff true save a cache of the toolbar folder, too
197      * @return true if saving was successful
198      */
199     // KF6 TODO: Use an enum and not a bool
200     bool save(bool toolbarCache = true) const;
201 
202     void emitConfigChanged();
203 
204     /**
205      * Set options with which slotEditBookmarks called keditbookmarks
206      * this can be used to change the appearance of the keditbookmarks
207      * in order to provide a slightly differing outer shell depending
208      * on the bookmarks file / app which calls it.
209      * @param caption the --caption string, for instance "Konsole"
210      * @param browser iff false display no browser specific
211      *            menu items in keditbookmarks :: --nobrowser
212      */
213     // KF6 TODO: Use an enum and not a bool
214     void setEditorOptions(const QString &caption, bool browser);
215 
216     /**
217      * This static function will return an instance of the
218      * KBookmarkManager, responsible for the given @p bookmarksFile.
219      * If you do not instantiate this class either
220      * natively or in a derived class, then it will return an object
221      * with the default behaviors.  If you wish to use different
222      * behaviors, you <em>must</em> derive your own class and
223      * instantiate it before this method is ever called.
224      *
225      * @param bookmarksFile full path to the bookmarks file,
226      * Use ~/.kde/share/apps/konqueror/bookmarks.xml for the konqueror bookmarks
227      *
228      * @param dbusObjectName a unique name that represents this bookmark collection,
229      * usually your component (e.g. application) name. This is "konqueror" for the
230      * konqueror bookmarks, "kfile" for KFileDialog bookmarks, etc.
231      * The final D-Bus object path is /KBookmarkManager/dbusObjectName
232      * An empty @p dbusObjectName disables the registration to D-Bus (used for temporary managers)
233      *
234      */
235     static KBookmarkManager *managerForFile(const QString &bookmarksFile, const QString &dbusObjectName);
236 
237     /**
238      * Returns a KBookmarkManager, which will use QFileSystemWatcher for change detection
239      * This is important when sharing bookmarks with other Desktops.
240      * @param bookmarksFile full path to the bookmarks file
241      * @since 4.1
242      */
243     static KBookmarkManager *managerForExternalFile(const QString &bookmarksFile);
244 
245     /**
246      * only used for KBookmarkBar
247      */
248     static KBookmarkManager *createTempManager();
249 
250     /**
251      * Returns a pointer to the user's main (konqueror) bookmark collection.
252      */
253     static KBookmarkManager *userBookmarksManager();
254 
255     /**
256      * @internal
257      */
258     QDomDocument internalDocument() const;
259 
260 public Q_SLOTS:
261     void slotEditBookmarks();
262     void slotEditBookmarksAtAddress(const QString &address);
263 
264     /**
265      * Reparse the whole bookmarks file and notify about the change
266      * Doesn't send signal over D-Bus to the other Bookmark Managers
267      * You probably want to use emitChanged()
268      *
269      */
270     void notifyCompleteChange(const QString &caller);
271 
272 #ifndef KBOOKMARKS_NO_DBUS
273     /**
274      * Emit the changed signal for the group whose address is given
275      * @see KBookmark::address()
276      * Called by the process that saved the file after
277      * a small change (new bookmark or new folder).
278      * Does not send signal over D-Bus to the other Bookmark Managers
279      * You probably want to call emitChanged()
280      */
281     void notifyChanged(const QString &groupAddress, const QDBusMessage &msg);
282 #endif
283 
284     void notifyConfigChanged();
285 
286 Q_SIGNALS:
287     /**
288      * Signal send over D-Bus
289      */
290     void bookmarkCompleteChange(QString caller);
291 
292     /**
293      * Signal send over D-Bus
294      */
295     void bookmarksChanged(QString groupAddress);
296 
297     /**
298      * Signal send over D-Bus
299      */
300     void bookmarkConfigChanged();
301 
302     /**
303      * Signals that the group (or any of its children) with the address
304      * @p groupAddress (e.g. "/4/5")
305      * has been modified by the caller @p caller.
306      * connect to this
307      */
308     void changed(const QString &groupAddress, const QString &caller);
309 
310     /**
311      * Signals that the config changed
312      */
313     void configChanged();
314 
315     /**
316      * Emitted when an error occurs.
317      * Contains the translated error message.
318      * @since 4.6
319      */
320     void error(const QString &errorMessage);
321 
322 private Q_SLOTS:
323     void slotFileChanged(const QString &path); // external bookmarks
324 
325 private:
326     // consts added to avoid a copy-and-paste of internalDocument
327     void parse() const;
328     void init(const QString &dbusPath);
329 
330     void startKEditBookmarks(const QStringList &args);
331 
332 private:
333     std::unique_ptr<KBookmarkManagerPrivate> const d;
334 
335     friend class KBookmarkGroup;
336 };
337 
338 #endif
339