25#include <QtCore/QFile>
26#include <QtCore/QFileInfo>
27#include <QtCore/QProcess>
28#include <QtCore/QRegExp>
29#include <QtCore/QTextStream>
30#include <QtDBus/QtDBus>
31#include <QtGui/QApplication>
47#define BOOKMARK_CHANGE_NOTIFY_INTERFACE "org.kde.KIO.KBookmarkManager"
49class KBookmarkManagerList :
public QList<KBookmarkManager *>
52 ~KBookmarkManagerList() {
53 qDeleteAll( begin() , end() );
63 KBookmarkMap() : m_mapNeedsUpdate(true) {}
64 void setNeedsUpdate() { m_mapNeedsUpdate =
true; }
65 void update(KBookmarkManager*);
66 QList<KBookmark> find(
const QString &url )
const
67 {
return m_bk_map.value(url); }
69 virtual void visit(
const KBookmark &);
70 virtual void visitEnter(
const KBookmarkGroup &) { ; }
71 virtual void visitLeave(
const KBookmarkGroup &) { ; }
73 typedef QList<KBookmark> KBookmarkList;
74 QMap<QString, KBookmarkList> m_bk_map;
75 bool m_mapNeedsUpdate;
80 if (m_mapNeedsUpdate) {
81 m_mapNeedsUpdate =
false;
84 KBookmarkGroup root = manager->
root();
89void KBookmarkMap::visit(
const KBookmark &bk)
99class KBookmarkManager::Private
102 Private(
bool bDocIsloaded,
const QString &dbusObjectName = QString())
104 , m_dbusObjectName(dbusObjectName)
105 , m_docIsLoaded(bDocIsloaded)
107 , m_dialogAllowed(true)
109 , m_browserEditor(false)
110 , m_typeExternal(false)
118 mutable QDomDocument m_doc;
119 mutable QDomDocument m_toolbarDoc;
120 QString m_bookmarksFile;
121 QString m_dbusObjectName;
122 mutable bool m_docIsLoaded;
124 bool m_dialogAllowed;
125 QWidget *m_dialogParent;
127 bool m_browserEditor;
128 QString m_editorCaption;
131 KDirWatch * m_kDirWatch;
141 for ( KBookmarkManagerList::ConstIterator bmit = s_pSelf->constBegin(), bmend = s_pSelf->constEnd();
142 bmit != bmend; ++bmit ) {
143 if ( (*bmit)->path() == bookmarksFile )
152 KBookmarkManager* mgr(0);
154 QReadLocker readLock(&s_pSelf->lock);
161 QWriteLocker writeLock(&s_pSelf->lock);
167 mgr =
new KBookmarkManager( bookmarksFile, dbusObjectName );
168 s_pSelf->append( mgr );
174 KBookmarkManager* mgr(0);
176 QReadLocker readLock(&s_pSelf->lock);
183 QWriteLocker writeLock(&s_pSelf->lock);
189 mgr =
new KBookmarkManager( bookmarksFile );
190 s_pSelf->append( mgr );
198 KBookmarkManager* mgr =
new KBookmarkManager();
199 s_pSelf->append( mgr );
203#define PI_DATA "version=\"1.0\" encoding=\"UTF-8\""
207 QDomElement topLevel = doc.createElement(
"xbel");
208 topLevel.setAttribute(
"xmlns:mime",
"http://www.freedesktop.org/standards/shared-mime-info");
209 topLevel.setAttribute(
"xmlns:bookmark",
"http://www.freedesktop.org/standards/desktop-bookmarks");
210 topLevel.setAttribute(
"xmlns:kdepriv",
"http://www.kde.org/kdepriv");
211 doc.appendChild( topLevel );
212 doc.insertBefore( doc.createProcessingInstruction(
"xml",
PI_DATA), topLevel );
216KBookmarkManager::KBookmarkManager(
const QString & bookmarksFile,
const QString & dbusObjectName)
217 : d(new Private(false, dbusObjectName))
219 if(dbusObjectName.isNull())
220 if ( QFile::exists(d->m_bookmarksFile) )
223 init(
"/KBookmarkManager/"+d->m_dbusObjectName );
227 Q_ASSERT( !bookmarksFile.isEmpty() );
228 d->m_bookmarksFile = bookmarksFile;
230 if ( !QFile::exists(d->m_bookmarksFile) )
233 topLevel.setAttribute(
"dbusName", dbusObjectName);
234 d->m_docIsLoaded =
true;
238KBookmarkManager::KBookmarkManager(
const QString & bookmarksFile)
239 : d(new Private(false))
242 d->m_typeExternal =
true;
245 Q_ASSERT( !bookmarksFile.isEmpty() );
246 d->m_bookmarksFile = bookmarksFile;
248 if ( !QFile::exists(d->m_bookmarksFile) )
256 d->m_docIsLoaded =
true;
260 d->m_kDirWatch->
addFile(d->m_bookmarksFile);
261 QObject::connect( d->m_kDirWatch, SIGNAL(dirty(
const QString&)),
262 this, SLOT(slotFileChanged(
const QString&)));
263 QObject::connect( d->m_kDirWatch, SIGNAL(created(
const QString&)),
264 this, SLOT(slotFileChanged(
const QString&)));
265 QObject::connect( d->m_kDirWatch, SIGNAL(deleted(
const QString&)),
266 this, SLOT(slotFileChanged(
const QString&)));
267 kDebug(7043) <<
"starting KDirWatch for " << d->m_bookmarksFile;
270KBookmarkManager::KBookmarkManager( )
271 : d(new Private(true))
273 init(
"/KBookmarkManager/generated" );
279void KBookmarkManager::init(
const QString& dbusPath )
283 if ( dbusPath !=
"/KBookmarkManager/" && dbusPath !=
"/KBookmarkManager/generated")
285 new KBookmarkManagerAdaptor(
this);
286 QDBusConnection::sessionBus().registerObject( dbusPath,
this );
289 "bookmarksChanged",
this, SLOT(
notifyChanged(QString,QDBusMessage)));
295void KBookmarkManager::slotFileChanged(
const QString& path)
297 if (
path == d->m_bookmarksFile)
299 kDebug(7043) <<
"file changed (KDirWatch) " <<
path ;
310 if (!s_pSelf.isDestroyed()) {
311 s_pSelf->removeAll(
this);
319 return d->m_dialogAllowed;
324 d->m_dialogAllowed = enable;
325 d->m_dialogParent = parent;
330 d->m_update = update;
335 if(!d->m_docIsLoaded)
338 d->m_toolbarDoc.clear();
344void KBookmarkManager::parse()
const
346 d->m_docIsLoaded =
true;
348 QFile file( d->m_bookmarksFile );
349 if ( !file.open( QIODevice::ReadOnly ) )
351 kWarning() <<
"Can't open " << d->m_bookmarksFile;
354 d->m_doc = QDomDocument(
"xbel");
355 d->m_doc.setContent( &file );
357 if ( d->m_doc.documentElement().isNull() )
359 kWarning() <<
"KBookmarkManager::parse : main tag is missing, creating default " << d->m_bookmarksFile;
360 QDomElement element = d->m_doc.createElement(
"xbel");
361 d->m_doc.appendChild(element);
364 QDomElement docElem = d->m_doc.documentElement();
366 QString mainTag = docElem.tagName();
367 if ( mainTag !=
"xbel" )
368 kWarning() <<
"KBookmarkManager::parse : unknown main tag " << mainTag;
370 if(d->m_dbusObjectName.isNull())
372 d->m_dbusObjectName = docElem.attribute(
"dbusName");
374 else if(docElem.attribute(
"dbusName") != d->m_dbusObjectName)
376 docElem.setAttribute(
"dbusName", d->m_dbusObjectName);
380 QDomNode n = d->m_doc.documentElement().previousSibling();
381 if ( n.isProcessingInstruction() )
383 QDomProcessingInstruction pi = n.toProcessingInstruction();
384 pi.parentNode().removeChild(pi);
387 QDomProcessingInstruction pi;
388 pi = d->m_doc.createProcessingInstruction(
"xml",
PI_DATA );
389 d->m_doc.insertBefore( pi, docElem );
393 d->m_map.setNeedsUpdate();
398 return saveAs( d->m_bookmarksFile, toolbarCache );
403 kDebug(7043) <<
"KBookmarkManager::save " << filename;
407 const QString cacheFilename = filename + QLatin1String(
".tbcache");
408 if(toolbarCache && !
root().isToolbarGroup())
411 if ( cacheFile.
open() )
414 QTextStream stream(&str, QIODevice::WriteOnly);
416 const QByteArray cstr = str.toUtf8();
417 cacheFile.write( cstr.data(), cstr.length() );
423 QFile::remove( cacheFilename );
427 QFileInfo info(filename);
428 QDir().mkpath(info.absolutePath());
434 QTextStream stream(&file);
435 stream.setCodec( QTextCodec::codecForName(
"UTF-8" ) );
444 static int hadSaveError =
false;
446 if ( !hadSaveError ) {
447 QString err =
i18n(
"Unable to save bookmarks in %1. Reported error was: %2. "
448 "This error message will only be shown once. The cause "
449 "of the error needs to be fixed as quickly as possible, "
450 "which is most likely a full hard drive.",
453 if (d->m_dialogAllowed && qApp->type() != QApplication::Tty && QThread::currentThread() == qApp->thread())
456 kError() << QString(
"Unable to save bookmarks in %1. File reported the following error-code: %2.").arg(filename).arg(file.
error());
457 emit
const_cast<KBookmarkManager*
>(
this)->
error(err);
465 return d->m_bookmarksFile;
475 kDebug(7043) <<
"KBookmarkManager::toolbar begin";
477 if(!d->m_docIsLoaded)
479 kDebug(7043) <<
"KBookmarkManager::toolbar trying cache";
480 const QString cacheFilename = d->m_bookmarksFile + QLatin1String(
".tbcache");
481 QFileInfo bmInfo(d->m_bookmarksFile);
482 QFileInfo cacheInfo(cacheFilename);
483 if (d->m_toolbarDoc.isNull() &&
484 QFile::exists(cacheFilename) &&
485 bmInfo.lastModified() < cacheInfo.lastModified())
487 kDebug(7043) <<
"KBookmarkManager::toolbar reading file";
488 QFile file( cacheFilename );
490 if ( file.open( QIODevice::ReadOnly ) )
492 d->m_toolbarDoc = QDomDocument(
"cache");
493 d->m_toolbarDoc.setContent( &file );
494 kDebug(7043) <<
"KBookmarkManager::toolbar opened";
497 if (!d->m_toolbarDoc.isNull())
499 kDebug(7043) <<
"KBookmarkManager::toolbar returning element";
500 QDomElement elem = d->m_toolbarDoc.firstChild().toElement();
524 const QStringList addresses = address.split(QRegExp(
"[/+]"),QString::SkipEmptyParts);
526 for ( QStringList::const_iterator it = addresses.begin() ; it != addresses.end() ; )
528 bool append = ((*it) ==
"+");
529 uint number = (*it).toUInt();
533 for ( uint i = 0 ; ( (i<number) || append ) && !bk.
isNull() ; ++i ) {
543 kWarning() <<
"KBookmarkManager::findByAddress: couldn't find item " << address;
578 kDebug(7043) <<
"KBookmarkManager::notifyCompleteChange";
589 kDebug() <<
"reloaded bookmark config!";
597 kDebug() <<
"KBookmarkManager::notifyChanged ( "<<groupAddress<<
")";
603 if (msg.service() != QDBusConnection::sessionBus().baseService())
609 emit
changed( groupAddress, QString() );
614 d->m_editorCaption = caption;
615 d->m_browserEditor = browser;
621 if ( !d->m_editorCaption.isEmpty() )
622 args << QLatin1String(
"--customcaption") << d->m_editorCaption;
623 if ( !d->m_browserEditor )
624 args << QLatin1String(
"--nobrowser");
625 if( !d->m_dbusObjectName.isEmpty() )
626 args << QLatin1String(
"--dbusObjectName") << d->m_dbusObjectName;
627 args << d->m_bookmarksFile;
628 QProcess::startDetached(
"keditbookmarks", args);
634 if ( !d->m_editorCaption.isEmpty() )
635 args << QLatin1String(
"--customcaption") << d->m_editorCaption;
636 if ( !d->m_browserEditor )
637 args << QLatin1String(
"--nobrowser");
638 if( !d->m_dbusObjectName.isEmpty() )
639 args << QLatin1String(
"--dbusObjectName") << d->m_dbusObjectName;
640 args << QLatin1String(
"--address") << address
641 << d->m_bookmarksFile;
642 QProcess::startDetached(
"keditbookmarks", args);
648 d->m_map.update(
this);
650 if ( list.count() == 0 )
654 it != list.end(); ++it )
655 (*it).updateAccessMetadata();
662 d->m_map.update(
this);
665 it != list.end(); ++it )
678 return bookmarkManager;
689 s_self->m_advancedaddbookmark = cg.
readEntry(
"AdvancedAddBookmarkDialog",
false);
726#include "kbookmarkmanager.moc"
This class provides a Dialog for editing properties, adding Bookmarks and creating new folders.
void traverse(const KBookmarkGroup &)
QDomElement findToolbar() const
This class implements the reading/writing of bookmarks in XML.
void configChanged()
Signals that the config changed.
bool autoErrorHandlingEnabled() const
Check whether auto error handling is enabled.
void setAutoErrorHandlingEnabled(bool enable, QWidget *parent)
Enable or disable auto error handling is enabled.
KBookmark findByAddress(const QString &address)
void notifyChanged(const QString &groupAddress, const QDBusMessage &msg)
Emit the changed signal for the group whose address is given.
static KBookmarkManager * managerForFile(const QString &bookmarksFile, const QString &dbusObjectName)
This static function will return an instance of the KBookmarkManager, responsible for the given bookm...
void updateFavicon(const QString &url, const QString &faviconurl)
QDomDocument internalDocument() const
bool updateAccessMetadata(const QString &url)
Update access time stamps for a given url.
KBookmarkGroup toolbar()
This returns the root of the toolbar menu.
void notifyConfigChanged()
void setUpdate(bool update)
Set the update flag.
void bookmarkConfigChanged()
Signal send over DBUS.
static KBookmarkManager * userBookmarksManager()
Returns a pointer to the user's main (konqueror) bookmark collection.
bool save(bool toolbarCache=true) const
Save the bookmarks to an XML file on disk.
QString path() const
This will return the path that this manager is using to read the bookmarks.
void notifyCompleteChange(const QString &caller)
Reparse the whole bookmarks file and notify about the change Doesn't send signal over DBUS to the oth...
KBookmarkGroup root() const
This will return the root bookmark.
static KBookmarkManager * managerForExternalFile(const QString &bookmarksFile)
Returns a KBookmarkManager, which will use KDirWatch for change detection This is important when shar...
friend class KBookmarkGroup
void error(const QString &errorMessage)
Emitted when an error occurs.
bool saveAs(const QString &filename, bool toolbarCache=true) const
Save the bookmarks to the given XML file on disk.
void bookmarksChanged(QString groupAddress)
Signal send over DBUS.
void slotEditBookmarksAtAddress(const QString &address)
~KBookmarkManager()
Destructor.
static KBookmarkManager * createTempManager()
only used for KBookmarkBar
void setEditorOptions(const QString &caption, bool browser)
Set options with which slotEditBookmarks called keditbookmarks this can be used to change the appeara...
void emitChanged()
Saves the bookmark file and notifies everyone.
void changed(const QString &groupAddress, const QString &caller)
Signals that the group (or any of its children) with the address groupAddress (e.g.
virtual bool enableOption(BookmarkOption option) const
Returns true if action should be shown in the menu The default is to show both a add and editBookmark...
virtual KBookmarkDialog * bookmarkDialog(KBookmarkManager *mgr, QWidget *parent)
virtual void openFolderinTabs(const KBookmarkGroup &bm)
Called if the user wants to open every bookmark in this folder in a new tab.
static KBookmarkSettings * s_self
static void readSettings()
static KBookmarkSettings * self()
bool isGroup() const
Whether the bookmark is a group or a normal bookmark.
KBookmarkGroup toGroup() const
Convert this to a group - do this only if isGroup() returns true.
bool isSeparator() const
Whether the bookmark is a separator.
QDomElement internalElement() const
QString readEntry(const char *key, const char *aDefault=0) const
void addFile(const QString &file)
static void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
virtual bool open(OpenMode flags=QIODevice::ReadWrite)
QFile::FileError error() const
QString errorString() const
static bool simpleBackupFile(const QString &filename, const QString &backupDir=QString(), const QString &backupExtension=QLatin1String("~"))
static QString locateLocal(const char *type, const QString &filename, bool createDir, const KComponentData &cData=KGlobal::mainComponent())
#define K_GLOBAL_STATIC(TYPE, NAME)
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
#define BOOKMARK_CHANGE_NOTIFY_INTERFACE
static QDomElement createXbelTopLevelElement(QDomDocument &doc)
static KBookmarkManager * lookupExisting(const QString &bookmarksFile)
QString i18n(const char *text)
QList< Action > parse(QSettings &ini)