1// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
2// vim: set ts=4 sts=4 sw=4 et:
3/* This file is part of the KDE libraries
4 Copyright (C) 2000, 2006 David Faure <faure@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
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#ifndef __kbookmarkmanager_h
21#define __kbookmarkmanager_h
22
23#include <QtCore/QString>
24#include <QtCore/QStringList>
25#include <QtCore/QObject>
26#include <QtCore/QPair>
27#include <QtXml/QDomDocument>
28#include <QtXml/QDomElement>
29
30#include <kurl.h>
31#include "kbookmark.h"
32
33class KBookmarkGroup;
34class QDBusMessage;
35
36class QTreeWidgetItem;
37class QLabel;
38class QTreeWidget;
39class KLineEdit;
40class KMenu;
41class KBookmarkDialog;
42
43/**
44 * This class implements the reading/writing of bookmarks in XML.
45 * The bookmarks file is read and written using the XBEL standard
46 * (http://pyxml.sourceforge.net/topics/xbel/)
47 *
48 * A sample file looks like this :
49 * \code
50 * <xbel>
51 * <bookmark href="http://techbase.kde.org"><title>Developer Web Site</title></bookmark>
52 * <folder folded="no">
53 * <title>Title of this folder</title>
54 * <bookmark icon="kde" href="http://www.kde.org"><title>KDE Web Site</title></bookmark>
55 * <folder toolbar="yes">
56 * <title>My own bookmarks</title>
57 * <bookmark href="http://www.koffice.org"><title>KOffice Web Site</title></bookmark>
58 * <separator/>
59 * <bookmark href="http://www.kdevelop.org"><title>KDevelop Web Site</title></bookmark>
60 * </folder>
61 * </folder>
62 * </xbel>
63 * \endcode
64 */
65class KIO_EXPORT KBookmarkManager : public QObject
66{
67 Q_OBJECT
68private:
69 /**
70 * Creates a bookmark manager with a path to the bookmarks. By
71 * default, it will use the KDE standard dirs to find and create the
72 * correct location. If you are using your own app-specific
73 * bookmarks directory, you must instantiate this class with your
74 * own path <em>before</em> KBookmarkManager::managerForFile() is ever
75 * called.
76 *
77 * @param bookmarksFile full path to the bookmarks file,
78 * Use ~/.kde/share/apps/konqueror/bookmarks.xml for the konqueror bookmarks
79 *
80 * @param dbusObjectName a unique name that represents this bookmark collection,
81 * usually your kinstance (e.g. kapplication) name. This is "konqueror" for the
82 * konqueror bookmarks, "kfile" for KFileDialog bookmarks, etc.
83 * The final DBus object path is /KBookmarkManager/dbusObjectName
84 * An empty dbusObjectName disables the registration to dbus (used for temporary managers)
85 */
86 KBookmarkManager( const QString & bookmarksFile, const QString& dbusObjectName );
87
88 /**
89 * Creates a bookmark manager for an external file
90 * (Using KDirWatch for change monitoring)
91 * @since 4.1
92 */
93 KBookmarkManager( const QString & bookmarksFile );
94
95 /**
96 * Creates a temp bookmark manager
97 */
98 KBookmarkManager();
99
100public:
101 /**
102 * Destructor
103 */
104 ~KBookmarkManager();
105
106 /**
107 * Check whether auto error handling is enabled.
108 * If enabled, it will show an error dialog to the user when an
109 * error occurs. It is turned on by default.
110 * @return true if auto error handling is enabled, false otherwise
111 * @note dialogs will only be displayed if the current thread is the gui thread
112 * @since 4.6
113 * @see setAutoErrorHandlingEnabled()
114 */
115 bool autoErrorHandlingEnabled() const;
116
117 /**
118 * Enable or disable auto error handling is enabled.
119 * If enabled, it will show an error dialog to the user when an
120 * error occurs. It is turned on by default.
121 * If disabled, the application should react on the error() signal.
122 * @param enable true to enable auto error handling, false to disable
123 * @param parent the parent widget for the error dialogs, can be 0 for
124 * top-level
125 * @since 4.6
126 * @see autoErrorHandlingEnabled()
127 */
128 void setAutoErrorHandlingEnabled( bool enable, QWidget *parent );
129
130 /**
131 * Set the update flag. Defaults to true.
132 * @param update if true then KBookmarkManager will listen to DBUS update requests.
133 */
134 void setUpdate( bool update );
135
136 /**
137 * Save the bookmarks to the given XML file on disk.
138 * @param filename full path to the desired bookmarks file location
139 * @param toolbarCache iff true save a cache of the toolbar folder, too
140 * @return true if saving was successful
141 */
142 // KDE5 TODO: Use an enum and not a bool
143 bool saveAs( const QString & filename, bool toolbarCache = true ) const;
144
145 /**
146 * Update access time stamps for a given url.
147 * @param url the viewed url
148 * @return true if any metadata was modified (bookmarks file is not saved automatically)
149 */
150 bool updateAccessMetadata( const QString &url );
151
152 /*
153 * NB. currently *unimplemented*
154 *
155 * Update favicon url for a given url.
156 * @param url the viewed url
157 * @param faviconurl the favicion url
158 */
159 void updateFavicon( const QString &url, const QString &faviconurl );
160
161 /**
162 * This will return the path that this manager is using to read
163 * the bookmarks.
164 * @internal
165 * @return the path containing the bookmarks
166 */
167 QString path() const;
168
169 /**
170 * This will return the root bookmark. It is used to iterate
171 * through the bookmarks manually. It is mostly used internally.
172 *
173 * @return the root (top-level) bookmark
174 */
175 KBookmarkGroup root() const;
176
177 /**
178 * This returns the root of the toolbar menu.
179 * In the XML, this is the group with the attribute toolbar=yes
180 *
181 * @return the toolbar group
182 */
183 KBookmarkGroup toolbar();
184
185 /**
186 * @return the bookmark designated by @p address
187 * @param address the address belonging to the bookmark you're looking for
188 * @param tolerate when true tries to find the most tolerable bookmark position
189 * @see KBookmark::address
190 */
191 KBookmark findByAddress( const QString & address);
192
193
194 /**
195 * Saves the bookmark file and notifies everyone.
196 *
197 **/
198 void emitChanged();
199
200 /**
201 * Saves the bookmark file and notifies everyone.
202 * @param group the parent of all changed bookmarks
203 */
204 void emitChanged( const KBookmarkGroup & group );
205
206 /**
207 * Save the bookmarks to an XML file on disk.
208 * You should use emitChanged() instead of this function, it saves
209 * and notifies everyone that the file has changed.
210 * Only use this if you don't want the emitChanged signal.
211 * @param toolbarCache iff true save a cache of the toolbar folder, too
212 * @return true if saving was successful
213 */
214 // KDE5 TODO: Use an enum and not a bool
215 bool save( bool toolbarCache = true ) const;
216
217
218 void emitConfigChanged();
219
220 /**
221 * Set options with which slotEditBookmarks called keditbookmarks
222 * this can be used to change the appearance of the keditbookmarks
223 * in order to provide a slightly differing outer shell depending
224 * on the bookmarks file / app which calls it.
225 * @param caption the --caption string, for instance "Konsole"
226 * @param browser iff false display no browser specific
227 * menu items in keditbookmarks :: --nobrowser
228 */
229 // KDE5 TODO: Use an enum and not a bool
230 void setEditorOptions( const QString& caption, bool browser );
231
232 /**
233 * This static function will return an instance of the
234 * KBookmarkManager, responsible for the given @p bookmarksFile.
235 * If you do not instantiate this class either
236 * natively or in a derived class, then it will return an object
237 * with the default behaviors. If you wish to use different
238 * behaviors, you <em>must</em> derive your own class and
239 * instantiate it before this method is ever called.
240 *
241 * @param bookmarksFile full path to the bookmarks file,
242 * Use ~/.kde/share/apps/konqueror/bookmarks.xml for the konqueror bookmarks
243 *
244 * @param dbusObjectName a unique name that represents this bookmark collection,
245 * usually your kinstance (e.g. kapplication) name. This is "konqueror" for the
246 * konqueror bookmarks, "kfile" for KFileDialog bookmarks, etc.
247 * The final DBus object path is /KBookmarkManager/dbusObjectName
248 * An empty dbusObjectName disables the registration to dbus (used for temporary managers)
249 *
250 */
251 static KBookmarkManager* managerForFile( const QString& bookmarksFile,
252 const QString& dbusObjectName );
253
254 /**
255 * Returns a KBookmarkManager, which will use KDirWatch for change detection
256 * This is important when sharing bookmarks with other Desktops.
257 * @param bookmarksFile full path to the bookmarks file
258 * @since 4.1
259 */
260 static KBookmarkManager* managerForExternalFile( const QString& bookmarksFile);
261
262 /**
263 * only used for KBookmarkBar
264 */
265 static KBookmarkManager* createTempManager();
266
267 /**
268 * Returns a pointer to the user's main (konqueror) bookmark collection.
269 */
270 static KBookmarkManager* userBookmarksManager();
271
272 /**
273 * @internal
274 */
275 QDomDocument internalDocument() const;
276
277public Q_SLOTS:
278 void slotEditBookmarks();
279 void slotEditBookmarksAtAddress( const QString& address );
280
281 /**
282 * Reparse the whole bookmarks file and notify about the change
283 * Doesn't send signal over DBUS to the other Bookmark Managers
284 * You probably want to use emitChanged()
285 *
286 */
287 void notifyCompleteChange( const QString &caller );
288
289 /**
290 * Emit the changed signal for the group whose address is given
291 * @see KBookmark::address()
292 * Called by the process that saved the file after
293 * a small change (new bookmark or new folder).
294 * Does not send signal over DBUS to the other Bookmark Managers
295 * You probably want to call emitChanged()
296 */
297 void notifyChanged( const QString &groupAddress, const QDBusMessage &msg );
298
299 void notifyConfigChanged();
300
301Q_SIGNALS:
302 /**
303 * Signal send over DBUS
304 */
305 void bookmarkCompleteChange( QString caller );
306
307 /**
308 * Signal send over DBUS
309 */
310 void bookmarksChanged( QString groupAddress );
311
312 /**
313 * Signal send over DBUS
314 */
315 void bookmarkConfigChanged();
316
317 /**
318 * Signals that the group (or any of its children) with the address
319 * @p groupAddress (e.g. "/4/5")
320 * has been modified by the caller @p caller.
321 * connect to this
322 */
323 void changed( const QString & groupAddress, const QString & caller );
324
325 /**
326 * Signals that the config changed
327 */
328 void configChanged();
329
330 /**
331 * Emitted when an error occurs.
332 * Contains the translated error message.
333 * @since 4.6
334 */
335 void error(const QString &errorMessage);
336
337private Q_SLOTS:
338 void slotFileChanged(const QString& path); // external bookmarks
339
340private:
341 // consts added to avoid a copy-and-paste of internalDocument
342 void parse() const;
343
344 /**
345 * You need to pass a dbusObjectName as the second parameter
346 * In kde 3 managerForFile had the parameters (const QString &, bool)
347 * We want old calls which pass a bool as a second parameter to fail.
348 * Unfortunately C++ can convert a bool to a QString, via QString(char(bool))
349 * This private overloaded method prevents this, as it is a better match,
350 * and thus old calls fail at compile time.
351 */
352 static KBookmarkManager* managerForFile( const QString&, int);
353 void init( const QString& dbusPath );
354
355 class Private;
356 Private * const d;
357
358 friend class KBookmarkGroup;
359};
360
361/**
362 * The KBookmarkMenu and KBookmarkBar classes gives the user
363 * the ability to either edit bookmarks or add their own. In the
364 * first case, the app may want to open the bookmark in a special way.
365 * In the second case, the app <em>must</em> supply the name and the
366 * URL for the bookmark.
367 *
368 * This class gives the app this callback-like ability.
369 *
370 * If your app does not give the user the ability to add bookmarks and
371 * you don't mind using the default bookmark editor to edit your
372 * bookmarks, then you don't need to overload this class at all.
373 * Rather, just use something like:
374 *
375 * <CODE>
376 * bookmarks = new KBookmarkMenu( mgr, 0, menu, actioncollec )
377 * </CODE>
378 *
379 * If you wish to use your own editor or allow the user to add
380 * bookmarks, you must overload this class.
381 */
382class KIO_EXPORT KBookmarkOwner
383{
384public:
385 virtual ~KBookmarkOwner() {}
386
387 /**
388 * This function is called whenever the user wants to add the
389 * current page to the bookmarks list. The title will become the
390 * "name" of the bookmark. You must overload this function if you
391 * wish to give your users the ability to add bookmarks.
392 * The default returns an empty string.
393 *
394 * @return the title of the current page.
395 */
396 virtual QString currentTitle() const { return QString(); }
397
398 /**
399 * This function is called whenever the user wants to add the
400 * current page to the bookmarks list. The URL will become the URL
401 * of the bookmark. You must overload this function if you wish to
402 * give your users the ability to add bookmarks.
403 * The default returns an empty string.
404 *
405 * @return the URL of the current page.
406 */
407 virtual QString currentUrl() const { return QString(); }
408
409
410 /**
411 * This function returns whether the owner supports tabs.
412 * The default returns @c false.
413 */
414 virtual bool supportsTabs() const { return false; }
415
416 /**
417 * Returns a list of title, URL pairs of the open tabs.
418 * The default returns an empty list.
419 */
420 virtual QList<QPair<QString, QString> > currentBookmarkList() const { return QList<QPair<QString, QString> >(); }
421
422 enum BookmarkOption { ShowAddBookmark, ShowEditBookmark };
423
424
425 /** Returns true if \p action should be shown in the menu
426 * The default is to show both a add and editBookmark Entry
427 * //TODO ContextMenuAction? to disable the contextMenu?
428 * Delete and Propeties to disable those in the
429 * context menu?
430 */
431 virtual bool enableOption(BookmarkOption option) const;
432
433 /**
434 * Called if a bookmark is selected. You need to override this.
435 */
436 virtual void openBookmark(const KBookmark & bm, Qt::MouseButtons mb, Qt::KeyboardModifiers km) = 0;
437
438 /**
439 * Called if the user wants to open every bookmark in this folder in a new tab.
440 * The default implementation does nothing.
441 * This is only called if supportsTabs() returns true
442 */
443 virtual void openFolderinTabs(const KBookmarkGroup &bm);
444
445 virtual KBookmarkDialog * bookmarkDialog(KBookmarkManager * mgr, QWidget *parent);
446
447private:
448 class KBookmarkOwnerPrivate;
449 KBookmarkOwnerPrivate *d;
450};
451
452#endif
453
454