summaryrefslogtreecommitdiffstats
path: root/kio/bookmarks/kbookmarkmanager.cc
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kio/bookmarks/kbookmarkmanager.cc
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kio/bookmarks/kbookmarkmanager.cc')
-rw-r--r--kio/bookmarks/kbookmarkmanager.cc727
1 files changed, 727 insertions, 0 deletions
diff --git a/kio/bookmarks/kbookmarkmanager.cc b/kio/bookmarks/kbookmarkmanager.cc
new file mode 100644
index 000000000..d101c1f7f
--- /dev/null
+++ b/kio/bookmarks/kbookmarkmanager.cc
@@ -0,0 +1,727 @@
+// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
+// vim: set ts=4 sts=4 sw=4 et:
+/* This file is part of the KDE libraries
+ Copyright (C) 2000 David Faure <[email protected]>
+ Copyright (C) 2003 Alexander Kellett <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kbookmarkmanager.h"
+#include "kbookmarkmenu.h"
+#include "kbookmarkmenu_p.h"
+#include "kbookmarkimporter.h"
+#include <kdebug.h>
+#include <krun.h>
+#include <kstandarddirs.h>
+#include <ksavefile.h>
+#include <dcopref.h>
+#include <qregexp.h>
+#include <kmessagebox.h>
+#include <kprocess.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#include <kstaticdeleter.h>
+#include <qptrstack.h>
+
+#include "dptrtemplate.h"
+
+class KBookmarkManagerPrivate : public dPtrTemplate<KBookmarkManager, KBookmarkManagerPrivate> {
+public:
+ KBookmarkManagerPrivate()
+ { m_browserEditor = true; }
+ QString m_editorCaption;
+ bool m_browserEditor;
+};
+template<> QPtrDict<KBookmarkManagerPrivate>* dPtrTemplate<KBookmarkManager, KBookmarkManagerPrivate>::d_ptr = 0;
+
+KBookmarkManagerPrivate* KBookmarkManager::dptr() const {
+ return KBookmarkManagerPrivate::d( this );
+}
+
+// TODO - clean this stuff up by just using the above dptrtemplate?
+QPtrList<KBookmarkManager>* KBookmarkManager::s_pSelf;
+static KStaticDeleter<QPtrList<KBookmarkManager> > sdbm;
+
+class KBookmarkMap : private KBookmarkGroupTraverser {
+public:
+ KBookmarkMap( KBookmarkManager * );
+ void update();
+ QValueList<KBookmark> find( const QString &url ) const
+ { return m_bk_map[url]; }
+private:
+ virtual void visit(const KBookmark &);
+ virtual void visitEnter(const KBookmarkGroup &) { ; }
+ virtual void visitLeave(const KBookmarkGroup &) { ; }
+private:
+ typedef QValueList<KBookmark> KBookmarkList;
+ QMap<QString, KBookmarkList> m_bk_map;
+ KBookmarkManager *m_manager;
+};
+
+static KBookmarkMap *s_bk_map = 0;
+
+KBookmarkMap::KBookmarkMap( KBookmarkManager *manager ) {
+ m_manager = manager;
+}
+
+void KBookmarkMap::update()
+{
+ m_bk_map.clear();
+ KBookmarkGroup root = m_manager->root();
+ traverse(root);
+}
+
+void KBookmarkMap::visit(const KBookmark &bk)
+{
+ if (!bk.isSeparator()) {
+ // add bookmark to url map
+ m_bk_map[bk.internalElement().attribute("href")].append(bk);
+ }
+}
+
+
+KBookmarkManager* KBookmarkManager::managerForFile( const QString& bookmarksFile, bool bImportDesktopFiles )
+{
+ if ( !s_pSelf ) {
+ sdbm.setObject( s_pSelf, new QPtrList<KBookmarkManager> );
+ s_pSelf->setAutoDelete( true );
+ }
+ QPtrListIterator<KBookmarkManager> it ( *s_pSelf );
+ for ( ; it.current() ; ++it )
+ if ( it.current()->path() == bookmarksFile )
+ return it.current();
+
+ KBookmarkManager* mgr = new KBookmarkManager( bookmarksFile, bImportDesktopFiles );
+ s_pSelf->append( mgr );
+ return mgr;
+}
+
+// principally used for filtered toolbars
+KBookmarkManager* KBookmarkManager::createTempManager()
+{
+ if ( !s_pSelf ) {
+ sdbm.setObject( s_pSelf, new QPtrList<KBookmarkManager> );
+ s_pSelf->setAutoDelete( true );
+ }
+ KBookmarkManager* mgr = new KBookmarkManager();
+ s_pSelf->append( mgr );
+ return mgr;
+}
+
+#define PI_DATA "version=\"1.0\" encoding=\"UTF-8\""
+
+KBookmarkManager::KBookmarkManager( const QString & bookmarksFile, bool bImportDesktopFiles )
+ : DCOPObject(QCString("KBookmarkManager-")+bookmarksFile.utf8()), m_doc("xbel"), m_docIsLoaded(false)
+{
+ m_toolbarDoc.clear();
+
+ m_update = true;
+ m_showNSBookmarks = true;
+
+ Q_ASSERT( !bookmarksFile.isEmpty() );
+ m_bookmarksFile = bookmarksFile;
+
+ if ( !QFile::exists(m_bookmarksFile) )
+ {
+ QDomElement topLevel = m_doc.createElement("xbel");
+ m_doc.appendChild( topLevel );
+ m_doc.insertBefore( m_doc.createProcessingInstruction( "xml", PI_DATA), topLevel );
+ if ( bImportDesktopFiles )
+ importDesktopFiles();
+ m_docIsLoaded = true;
+ }
+
+ connectDCOPSignal(0, objId(), "bookmarksChanged(QString)", "notifyChanged(QString)", false);
+ connectDCOPSignal(0, objId(), "bookmarkConfigChanged()", "notifyConfigChanged()", false);
+}
+
+KBookmarkManager::KBookmarkManager( )
+ : DCOPObject(QCString("KBookmarkManager-generated")), m_doc("xbel"), m_docIsLoaded(true)
+{
+ m_toolbarDoc.clear(); // strange ;-)
+
+ m_update = false; // TODO - make it read/write
+ m_showNSBookmarks = true;
+
+ m_bookmarksFile = QString::null; // AK - check all codepaths for this one
+
+ QDomElement topLevel = m_doc.createElement("xbel");
+ m_doc.appendChild( topLevel );
+ m_doc.insertBefore( m_doc.createProcessingInstruction( "xml", PI_DATA), topLevel );
+
+ // TODO - enable this via some sort of api and fix the above DCOPObject script somehow
+#if 0
+ connectDCOPSignal(0, objId(), "bookmarksChanged(QString)", "notifyChanged(QString)", false);
+ connectDCOPSignal(0, objId(), "bookmarkConfigChanged()", "notifyConfigChanged()", false);
+#endif
+}
+
+KBookmarkManager::~KBookmarkManager()
+{
+ if ( s_pSelf )
+ s_pSelf->removeRef( this );
+}
+
+void KBookmarkManager::setUpdate( bool update )
+{
+ m_update = update;
+}
+
+const QDomDocument &KBookmarkManager::internalDocument() const
+{
+ if(!m_docIsLoaded)
+ {
+ parse();
+ m_toolbarDoc.clear();
+ }
+ return m_doc;
+}
+
+
+void KBookmarkManager::parse() const
+{
+ m_docIsLoaded = true;
+ //kdDebug(7043) << "KBookmarkManager::parse " << m_bookmarksFile << endl;
+ QFile file( m_bookmarksFile );
+ if ( !file.open( IO_ReadOnly ) )
+ {
+ kdWarning() << "Can't open " << m_bookmarksFile << endl;
+ return;
+ }
+ m_doc = QDomDocument("xbel");
+ m_doc.setContent( &file );
+
+ QDomElement docElem = m_doc.documentElement();
+ if ( docElem.isNull() )
+ kdWarning() << "KBookmarkManager::parse : can't parse " << m_bookmarksFile << endl;
+ else
+ {
+ QString mainTag = docElem.tagName();
+ if ( mainTag == "BOOKMARKS" )
+ {
+ kdWarning() << "Old style bookmarks found. Calling convertToXBEL." << endl;
+ docElem.setTagName("xbel");
+ if ( docElem.hasAttribute( "HIDE_NSBK" ) && m_showNSBookmarks ) // non standard either, but we need it
+ {
+ docElem.setAttribute( "hide_nsbk", docElem.attribute( "HIDE_NSBK" ) == "1" ? "yes" : "no" );
+ docElem.removeAttribute( "HIDE_NSBK" );
+ }
+
+ convertToXBEL( docElem );
+ save();
+ }
+ else if ( mainTag != "xbel" )
+ kdWarning() << "KBookmarkManager::parse : unknown main tag " << mainTag << endl;
+
+ QDomNode n = m_doc.documentElement().previousSibling();
+ if ( n.isProcessingInstruction() )
+ {
+ QDomProcessingInstruction pi = n.toProcessingInstruction();
+ pi.parentNode().removeChild(pi);
+ }
+
+ QDomProcessingInstruction pi;
+ pi = m_doc.createProcessingInstruction( "xml", PI_DATA );
+ m_doc.insertBefore( pi, docElem );
+ }
+
+ file.close();
+ if ( !s_bk_map )
+ s_bk_map = new KBookmarkMap( const_cast<KBookmarkManager*>( this ) );
+ s_bk_map->update();
+}
+
+void KBookmarkManager::convertToXBEL( QDomElement & group )
+{
+ QDomNode n = group.firstChild();
+ while( !n.isNull() )
+ {
+ QDomElement e = n.toElement();
+ if ( !e.isNull() )
+ if ( e.tagName() == "TEXT" )
+ {
+ e.setTagName("title");
+ }
+ else if ( e.tagName() == "SEPARATOR" )
+ {
+ e.setTagName("separator"); // so close...
+ }
+ else if ( e.tagName() == "GROUP" )
+ {
+ e.setTagName("folder");
+ convertAttribute(e, "ICON","icon"); // non standard, but we need it
+ if ( e.hasAttribute( "TOOLBAR" ) ) // non standard either, but we need it
+ {
+ e.setAttribute( "toolbar", e.attribute( "TOOLBAR" ) == "1" ? "yes" : "no" );
+ e.removeAttribute( "TOOLBAR" );
+ }
+
+ convertAttribute(e, "NETSCAPEINFO","netscapeinfo"); // idem
+ bool open = (e.attribute("OPEN") == "1");
+ e.removeAttribute("OPEN");
+ e.setAttribute("folded", open ? "no" : "yes");
+ convertToXBEL( e );
+ }
+ else
+ if ( e.tagName() == "BOOKMARK" )
+ {
+ e.setTagName("bookmark"); // so much difference :-)
+ convertAttribute(e, "ICON","icon"); // non standard, but we need it
+ convertAttribute(e, "NETSCAPEINFO","netscapeinfo"); // idem
+ convertAttribute(e, "URL","href");
+ QString text = e.text();
+ while ( !e.firstChild().isNull() ) // clean up the old contained text
+ e.removeChild(e.firstChild());
+ QDomElement titleElem = e.ownerDocument().createElement("title");
+ e.appendChild( titleElem ); // should be the only child anyway
+ titleElem.appendChild( e.ownerDocument().createTextNode( text ) );
+ }
+ else
+ kdWarning(7043) << "Unknown tag " << e.tagName() << endl;
+ n = n.nextSibling();
+ }
+}
+
+void KBookmarkManager::convertAttribute( QDomElement elem, const QString & oldName, const QString & newName )
+{
+ if ( elem.hasAttribute( oldName ) )
+ {
+ elem.setAttribute( newName, elem.attribute( oldName ) );
+ elem.removeAttribute( oldName );
+ }
+}
+
+void KBookmarkManager::importDesktopFiles()
+{
+ KBookmarkImporter importer( const_cast<QDomDocument *>(&internalDocument()) );
+ QString path(KGlobal::dirs()->saveLocation("data", "kfm/bookmarks", true));
+ importer.import( path );
+ //kdDebug(7043) << internalDocument().toCString() << endl;
+
+ save();
+}
+
+bool KBookmarkManager::save( bool toolbarCache ) const
+{
+ return saveAs( m_bookmarksFile, toolbarCache );
+}
+
+bool KBookmarkManager::saveAs( const QString & filename, bool toolbarCache ) const
+{
+ kdDebug(7043) << "KBookmarkManager::save " << filename << endl;
+
+ // Save the bookmark toolbar folder for quick loading
+ // but only when it will actually make things quicker
+ const QString cacheFilename = filename + QString::fromLatin1(".tbcache");
+ if(toolbarCache && !root().isToolbarGroup())
+ {
+ KSaveFile cacheFile( cacheFilename );
+ if ( cacheFile.status() == 0 )
+ {
+ QString str;
+ QTextStream stream(&str, IO_WriteOnly);
+ stream << root().findToolbar();
+ QCString cstr = str.utf8();
+ cacheFile.file()->writeBlock( cstr.data(), cstr.length() );
+ cacheFile.close();
+ }
+ }
+ else // remove any (now) stale cache
+ {
+ QFile::remove( cacheFilename );
+ }
+
+ KSaveFile file( filename );
+ if ( file.status() == 0 )
+ {
+ file.backupFile( file.name(), QString::null, ".bak" );
+ QCString cstr;
+ cstr = internalDocument().toCString(); // is in UTF8
+ file.file()->writeBlock( cstr.data(), cstr.length() );
+ if ( file.close() )
+ return true;
+ }
+
+ static int hadSaveError = false;
+ file.abort();
+ if ( !hadSaveError ) {
+ QString error = i18n("Unable to save bookmarks in %1. Reported error was: %2. "
+ "This error message will only be shown once. The cause "
+ "of the error needs to be fixed as quickly as possible, "
+ "which is most likely a full hard drive.")
+ .arg(filename).arg(QString::fromLocal8Bit(strerror(file.status())));
+ if (qApp->type() != QApplication::Tty)
+ KMessageBox::error( 0L, error );
+ else
+ kdError() << error << endl;
+ }
+ hadSaveError = true;
+ return false;
+}
+
+KBookmarkGroup KBookmarkManager::root() const
+{
+ return KBookmarkGroup(internalDocument().documentElement());
+}
+
+KBookmarkGroup KBookmarkManager::toolbar()
+{
+ kdDebug(7043) << "KBookmarkManager::toolbar begin" << endl;
+ // Only try to read from a toolbar cache if the full document isn't loaded
+ if(!m_docIsLoaded)
+ {
+ kdDebug(7043) << "KBookmarkManager::toolbar trying cache" << endl;
+ const QString cacheFilename = m_bookmarksFile + QString::fromLatin1(".tbcache");
+ QFileInfo bmInfo(m_bookmarksFile);
+ QFileInfo cacheInfo(cacheFilename);
+ if (m_toolbarDoc.isNull() &&
+ QFile::exists(cacheFilename) &&
+ bmInfo.lastModified() < cacheInfo.lastModified())
+ {
+ kdDebug(7043) << "KBookmarkManager::toolbar reading file" << endl;
+ QFile file( cacheFilename );
+
+ if ( file.open( IO_ReadOnly ) )
+ {
+ m_toolbarDoc = QDomDocument("cache");
+ m_toolbarDoc.setContent( &file );
+ kdDebug(7043) << "KBookmarkManager::toolbar opened" << endl;
+ }
+ }
+ if (!m_toolbarDoc.isNull())
+ {
+ kdDebug(7043) << "KBookmarkManager::toolbar returning element" << endl;
+ QDomElement elem = m_toolbarDoc.firstChild().toElement();
+ return KBookmarkGroup(elem);
+ }
+ }
+
+ // Fallback to the normal way if there is no cache or if the bookmark file
+ // is already loaded
+ QDomElement elem = root().findToolbar();
+ if (elem.isNull())
+ return root(); // Root is the bookmark toolbar if none has been set.
+ else
+ return KBookmarkGroup(root().findToolbar());
+}
+
+KBookmark KBookmarkManager::findByAddress( const QString & address, bool tolerant )
+{
+ //kdDebug(7043) << "KBookmarkManager::findByAddress " << address << endl;
+ KBookmark result = root();
+ // The address is something like /5/10/2+
+ QStringList addresses = QStringList::split(QRegExp("[/+]"),address);
+ // kdWarning() << addresses.join(",") << endl;
+ for ( QStringList::Iterator it = addresses.begin() ; it != addresses.end() ; )
+ {
+ bool append = ((*it) == "+");
+ uint number = (*it).toUInt();
+ Q_ASSERT(result.isGroup());
+ KBookmarkGroup group = result.toGroup();
+ KBookmark bk = group.first(), lbk = bk; // last non-null bookmark
+ for ( uint i = 0 ; ( (i<number) || append ) && !bk.isNull() ; ++i ) {
+ lbk = bk;
+ bk = group.next(bk);
+ //kdWarning() << i << endl;
+ }
+ it++;
+ int shouldBeGroup = !bk.isGroup() && (it != addresses.end());
+ if ( tolerant && ( bk.isNull() || shouldBeGroup ) ) {
+ if (!lbk.isNull()) result = lbk;
+ //kdWarning() << "break" << endl;
+ break;
+ }
+ //kdWarning() << "found section" << endl;
+ result = bk;
+ }
+ if (result.isNull()) {
+ kdWarning() << "KBookmarkManager::findByAddress: couldn't find item " << address << endl;
+ Q_ASSERT(!tolerant);
+ }
+ //kdWarning() << "found " << result.address() << endl;
+ return result;
+ }
+
+static QString pickUnusedTitle( KBookmarkGroup parentBookmark,
+ const QString &title, const QString &url
+) {
+ // If this title is already used, we'll try to find something unused.
+ KBookmark ch = parentBookmark.first();
+ int count = 1;
+ QString uniqueTitle = title;
+ do
+ {
+ while ( !ch.isNull() )
+ {
+ if ( uniqueTitle == ch.text() )
+ {
+ // Title already used !
+ if ( url != ch.url().url() )
+ {
+ uniqueTitle = title + QString(" (%1)").arg(++count);
+ // New title -> restart search from the beginning
+ ch = parentBookmark.first();
+ break;
+ }
+ else
+ {
+ // this exact URL already exists
+ return QString::null;
+ }
+ }
+ ch = parentBookmark.next( ch );
+ }
+ } while ( !ch.isNull() );
+
+ return uniqueTitle;
+}
+
+KBookmarkGroup KBookmarkManager::addBookmarkDialog(
+ const QString & _url, const QString & _title,
+ const QString & _parentBookmarkAddress
+) {
+ QString url = _url;
+ QString title = _title;
+ QString parentBookmarkAddress = _parentBookmarkAddress;
+
+ if ( url.isEmpty() )
+ {
+ KMessageBox::error( 0L, i18n("Cannot add bookmark with empty URL."));
+ return KBookmarkGroup();
+ }
+
+ if ( title.isEmpty() )
+ title = url;
+
+ if ( KBookmarkSettings::self()->m_advancedaddbookmark)
+ {
+ KBookmarkEditDialog dlg( title, url, this, KBookmarkEditDialog::InsertionMode, parentBookmarkAddress );
+ if ( dlg.exec() != KDialogBase::Accepted )
+ return KBookmarkGroup();
+ title = dlg.finalTitle();
+ url = dlg.finalUrl();
+ parentBookmarkAddress = dlg.finalAddress();
+ }
+
+ KBookmarkGroup parentBookmark;
+ parentBookmark = findByAddress( parentBookmarkAddress ).toGroup();
+ Q_ASSERT( !parentBookmark.isNull() );
+
+ QString uniqueTitle = pickUnusedTitle( parentBookmark, title, url );
+ if ( !uniqueTitle.isNull() )
+ parentBookmark.addBookmark( this, uniqueTitle, KURL( url ));
+
+ return parentBookmark;
+}
+
+
+void KBookmarkManager::emitChanged( /*KDE4 const*/ KBookmarkGroup & group )
+{
+ save();
+
+ // Tell the other processes too
+ // kdDebug(7043) << "KBookmarkManager::emitChanged : broadcasting change " << group.address() << endl;
+
+ QByteArray data;
+ QDataStream ds( data, IO_WriteOnly );
+ ds << group.address();
+
+ emitDCOPSignal("bookmarksChanged(QString)", data);
+
+ // We do get our own broadcast, so no need for this anymore
+ //emit changed( group );
+}
+
+void KBookmarkManager::emitConfigChanged()
+{
+ emitDCOPSignal("bookmarkConfigChanged()", QByteArray());
+}
+
+void KBookmarkManager::notifyCompleteChange( QString caller ) // DCOP call
+{
+ if (!m_update) return;
+
+ //kdDebug(7043) << "KBookmarkManager::notifyCompleteChange" << endl;
+ // The bk editor tells us we should reload everything
+ // Reparse
+ parse();
+ // Tell our GUI
+ // (emit where group is "" to directly mark the root menu as dirty)
+ emit changed( "", caller );
+}
+
+void KBookmarkManager::notifyConfigChanged() // DCOP call
+{
+ kdDebug() << "reloaded bookmark config!" << endl;
+ KBookmarkSettings::self()->readSettings();
+ parse(); // reload, and thusly recreate the menus
+}
+
+void KBookmarkManager::notifyChanged( QString groupAddress ) // DCOP call
+{
+ if (!m_update) return;
+
+ // Reparse (the whole file, no other choice)
+ // if someone else notified us
+ if (callingDcopClient()->senderId() != DCOPClient::mainClient()->appId())
+ parse();
+
+ //kdDebug(7043) << "KBookmarkManager::notifyChanged " << groupAddress << endl;
+ //KBookmarkGroup group = findByAddress( groupAddress ).toGroup();
+ //Q_ASSERT(!group.isNull());
+ emit changed( groupAddress, QString::null );
+}
+
+bool KBookmarkManager::showNSBookmarks() const
+{
+ return KBookmarkMenu::showDynamicBookmarks("netscape").show;
+}
+
+void KBookmarkManager::setShowNSBookmarks( bool show )
+{
+ m_showNSBookmarks = show;
+ if (this->path() != userBookmarksFile())
+ return;
+ KBookmarkMenu::DynMenuInfo info
+ = KBookmarkMenu::showDynamicBookmarks("netscape");
+ info.show = show;
+ KBookmarkMenu::setDynamicBookmarks("netscape", info);
+}
+
+void KBookmarkManager::setEditorOptions( const QString& caption, bool browser )
+{
+ dptr()->m_editorCaption = caption;
+ dptr()->m_browserEditor = browser;
+}
+
+void KBookmarkManager::slotEditBookmarks()
+{
+ KProcess proc;
+ proc << QString::fromLatin1("keditbookmarks");
+ if (!dptr()->m_editorCaption.isNull())
+ proc << QString::fromLatin1("--customcaption") << dptr()->m_editorCaption;
+ if (!dptr()->m_browserEditor)
+ proc << QString::fromLatin1("--nobrowser");
+ proc << m_bookmarksFile;
+ proc.start(KProcess::DontCare);
+}
+
+void KBookmarkManager::slotEditBookmarksAtAddress( const QString& address )
+{
+ KProcess proc;
+ proc << QString::fromLatin1("keditbookmarks")
+ << QString::fromLatin1("--address") << address
+ << m_bookmarksFile;
+ proc.start(KProcess::DontCare);
+}
+
+///////
+
+void KBookmarkOwner::openBookmarkURL( const QString& url )
+{
+ (void) new KRun(KURL( url ));
+}
+
+void KBookmarkOwner::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+
+bool KBookmarkManager::updateAccessMetadata( const QString & url, bool emitSignal )
+{
+ if (!s_bk_map) {
+ s_bk_map = new KBookmarkMap(this);
+ s_bk_map->update();
+ }
+
+ QValueList<KBookmark> list = s_bk_map->find(url);
+ if ( list.count() == 0 )
+ return false;
+
+ for ( QValueList<KBookmark>::iterator it = list.begin();
+ it != list.end(); ++it )
+ (*it).updateAccessMetadata();
+
+ if (emitSignal)
+ emit notifier().updatedAccessMetadata( path(), url );
+
+ return true;
+}
+
+void KBookmarkManager::updateFavicon( const QString &url, const QString &faviconurl, bool emitSignal )
+{
+ Q_UNUSED(faviconurl);
+
+ if (!s_bk_map) {
+ s_bk_map = new KBookmarkMap(this);
+ s_bk_map->update();
+ }
+
+ QValueList<KBookmark> list = s_bk_map->find(url);
+ for ( QValueList<KBookmark>::iterator it = list.begin();
+ it != list.end(); ++it )
+ {
+ // TODO - update favicon data based on faviconurl
+ // but only when the previously used icon
+ // isn't a manually set one.
+ }
+
+ if (emitSignal)
+ {
+ // TODO
+ // emit notifier().updatedFavicon( path(), url, faviconurl );
+ }
+}
+
+QString KBookmarkManager::userBookmarksFile()
+{
+ return locateLocal("data", QString::fromLatin1("konqueror/bookmarks.xml"));
+}
+
+KBookmarkManager* KBookmarkManager::userBookmarksManager()
+{
+ return KBookmarkManager::managerForFile( userBookmarksFile() );
+}
+
+KBookmarkSettings* KBookmarkSettings::s_self = 0;
+
+void KBookmarkSettings::readSettings()
+{
+ KConfig config("kbookmarkrc", false, false);
+ config.setGroup("Bookmarks");
+
+ // add bookmark dialog usage - no reparse
+ s_self->m_advancedaddbookmark = config.readBoolEntry("AdvancedAddBookmarkDialog", false);
+
+ // these three alter the menu, therefore all need a reparse
+ s_self->m_contextmenu = config.readBoolEntry("ContextMenuActions", true);
+ s_self->m_quickactions = config.readBoolEntry("QuickActionSubmenu", false);
+ s_self->m_filteredtoolbar = config.readBoolEntry("FilteredToolbar", false);
+}
+
+KBookmarkSettings *KBookmarkSettings::self()
+{
+ if (!s_self)
+ {
+ s_self = new KBookmarkSettings;
+ readSettings();
+ }
+ return s_self;
+}
+
+#include "kbookmarkmanager.moc"