kbookmarkmanager.cc
00001 // -*- c-basic-offset:4; indent-tabs-mode:nil -*- 00002 // vim: set ts=4 sts=4 sw=4 et: 00003 /* This file is part of the KDE libraries 00004 Copyright (C) 2000 David Faure <faure@kde.org> 00005 Copyright (C) 2003 Alexander Kellett <lypanov@kde.org> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License version 2 as published by the Free Software Foundation. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "kbookmarkmanager.h" 00023 #include "kbookmarkmenu.h" 00024 #include "kbookmarkmenu_p.h" 00025 #include "kbookmarkimporter.h" 00026 #include <kdebug.h> 00027 #include <krun.h> 00028 #include <kstandarddirs.h> 00029 #include <ksavefile.h> 00030 #include <dcopref.h> 00031 #include <tqregexp.h> 00032 #include <tdemessagebox.h> 00033 #include <kprocess.h> 00034 #include <tdelocale.h> 00035 #include <tdeapplication.h> 00036 #include <dcopclient.h> 00037 #include <tqfile.h> 00038 #include <tqfileinfo.h> 00039 #include <tqtextstream.h> 00040 #include <kstaticdeleter.h> 00041 #include <tqptrstack.h> 00042 00043 #include "dptrtemplate.h" 00044 00045 class KBookmarkManagerPrivate : public dPtrTemplate<KBookmarkManager, KBookmarkManagerPrivate> { 00046 public: 00047 KBookmarkManagerPrivate() 00048 { m_browserEditor = true; } 00049 TQString m_editorCaption; 00050 bool m_browserEditor; 00051 }; 00052 template<> TQPtrDict<KBookmarkManagerPrivate>* dPtrTemplate<KBookmarkManager, KBookmarkManagerPrivate>::d_ptr = 0; 00053 00054 KBookmarkManagerPrivate* KBookmarkManager::dptr() const { 00055 return KBookmarkManagerPrivate::d( this ); 00056 } 00057 00058 // TODO - clean this stuff up by just using the above dptrtemplate? 00059 TQPtrList<KBookmarkManager>* KBookmarkManager::s_pSelf; 00060 static KStaticDeleter<TQPtrList<KBookmarkManager> > sdbm; 00061 00062 class KBookmarkMap : private KBookmarkGroupTraverser { 00063 public: 00064 KBookmarkMap( KBookmarkManager * ); 00065 void update(); 00066 TQValueList<KBookmark> find( const TQString &url ) const 00067 { return m_bk_map[url]; } 00068 private: 00069 virtual void visit(const KBookmark &); 00070 virtual void visitEnter(const KBookmarkGroup &) { ; } 00071 virtual void visitLeave(const KBookmarkGroup &) { ; } 00072 private: 00073 typedef TQValueList<KBookmark> KBookmarkList; 00074 TQMap<TQString, KBookmarkList> m_bk_map; 00075 KBookmarkManager *m_manager; 00076 }; 00077 00078 static KBookmarkMap *s_bk_map = 0; 00079 00080 KBookmarkMap::KBookmarkMap( KBookmarkManager *manager ) { 00081 m_manager = manager; 00082 } 00083 00084 void KBookmarkMap::update() 00085 { 00086 m_bk_map.clear(); 00087 KBookmarkGroup root = m_manager->root(); 00088 traverse(root); 00089 } 00090 00091 void KBookmarkMap::visit(const KBookmark &bk) 00092 { 00093 if (!bk.isSeparator()) { 00094 // add bookmark to url map 00095 m_bk_map[bk.internalElement().attribute("href")].append(bk); 00096 } 00097 } 00098 00099 00100 KBookmarkManager* KBookmarkManager::managerForFile( const TQString& bookmarksFile, bool bImportDesktopFiles ) 00101 { 00102 if ( !s_pSelf ) { 00103 sdbm.setObject( s_pSelf, new TQPtrList<KBookmarkManager> ); 00104 s_pSelf->setAutoDelete( true ); 00105 } 00106 TQPtrListIterator<KBookmarkManager> it ( *s_pSelf ); 00107 for ( ; it.current() ; ++it ) 00108 if ( it.current()->path() == bookmarksFile ) 00109 return it.current(); 00110 00111 KBookmarkManager* mgr = new KBookmarkManager( bookmarksFile, bImportDesktopFiles ); 00112 s_pSelf->append( mgr ); 00113 return mgr; 00114 } 00115 00116 // principally used for filtered toolbars 00117 KBookmarkManager* KBookmarkManager::createTempManager() 00118 { 00119 if ( !s_pSelf ) { 00120 sdbm.setObject( s_pSelf, new TQPtrList<KBookmarkManager> ); 00121 s_pSelf->setAutoDelete( true ); 00122 } 00123 KBookmarkManager* mgr = new KBookmarkManager(); 00124 s_pSelf->append( mgr ); 00125 return mgr; 00126 } 00127 00128 #define PI_DATA "version=\"1.0\" encoding=\"UTF-8\"" 00129 00130 KBookmarkManager::KBookmarkManager( const TQString & bookmarksFile, bool bImportDesktopFiles ) 00131 : DCOPObject(TQCString("KBookmarkManager-")+bookmarksFile.utf8()), m_doc("xbel"), m_docIsLoaded(false) 00132 { 00133 m_toolbarDoc.clear(); 00134 00135 m_update = true; 00136 m_showNSBookmarks = true; 00137 00138 Q_ASSERT( !bookmarksFile.isEmpty() ); 00139 m_bookmarksFile = bookmarksFile; 00140 00141 if ( !TQFile::exists(m_bookmarksFile) ) 00142 { 00143 TQDomElement topLevel = m_doc.createElement("xbel"); 00144 m_doc.appendChild( topLevel ); 00145 m_doc.insertBefore( m_doc.createProcessingInstruction( "xml", PI_DATA), topLevel ); 00146 if ( bImportDesktopFiles ) 00147 importDesktopFiles(); 00148 m_docIsLoaded = true; 00149 } 00150 00151 connectDCOPSignal(0, objId(), "bookmarksChanged(TQString)", "notifyChanged(TQString)", false); 00152 connectDCOPSignal(0, objId(), "bookmarkConfigChanged()", "notifyConfigChanged()", false); 00153 } 00154 00155 KBookmarkManager::KBookmarkManager( ) 00156 : DCOPObject(TQCString("KBookmarkManager-generated")), m_doc("xbel"), m_docIsLoaded(true) 00157 { 00158 m_toolbarDoc.clear(); // strange ;-) 00159 00160 m_update = false; // TODO - make it read/write 00161 m_showNSBookmarks = true; 00162 00163 m_bookmarksFile = TQString::null; // AK - check all codepaths for this one 00164 00165 TQDomElement topLevel = m_doc.createElement("xbel"); 00166 m_doc.appendChild( topLevel ); 00167 m_doc.insertBefore( m_doc.createProcessingInstruction( "xml", PI_DATA), topLevel ); 00168 00169 // TODO - enable this via some sort of api and fix the above DCOPObject script somehow 00170 #if 0 00171 connectDCOPSignal(0, objId(), "bookmarksChanged(TQString)", "notifyChanged(TQString)", false); 00172 connectDCOPSignal(0, objId(), "bookmarkConfigChanged()", "notifyConfigChanged()", false); 00173 #endif 00174 } 00175 00176 KBookmarkManager::~KBookmarkManager() 00177 { 00178 if ( s_pSelf ) 00179 s_pSelf->removeRef( this ); 00180 } 00181 00182 void KBookmarkManager::setUpdate( bool update ) 00183 { 00184 m_update = update; 00185 } 00186 00187 const TQDomDocument &KBookmarkManager::internalDocument() const 00188 { 00189 if(!m_docIsLoaded) 00190 { 00191 parse(); 00192 m_toolbarDoc.clear(); 00193 } 00194 return m_doc; 00195 } 00196 00197 00198 void KBookmarkManager::parse() const 00199 { 00200 m_docIsLoaded = true; 00201 //kdDebug(7043) << "KBookmarkManager::parse " << m_bookmarksFile << endl; 00202 TQFile file( m_bookmarksFile ); 00203 if ( !file.open( IO_ReadOnly ) ) 00204 { 00205 kdWarning() << "Can't open " << m_bookmarksFile << endl; 00206 return; 00207 } 00208 m_doc = TQDomDocument("xbel"); 00209 m_doc.setContent( &file ); 00210 00211 TQDomElement docElem = m_doc.documentElement(); 00212 if ( docElem.isNull() ) 00213 kdWarning() << "KBookmarkManager::parse : can't parse " << m_bookmarksFile << endl; 00214 else 00215 { 00216 TQString mainTag = docElem.tagName(); 00217 if ( mainTag == "BOOKMARKS" ) 00218 { 00219 kdWarning() << "Old style bookmarks found. Calling convertToXBEL." << endl; 00220 docElem.setTagName("xbel"); 00221 if ( docElem.hasAttribute( "HIDE_NSBK" ) && m_showNSBookmarks ) // non standard either, but we need it 00222 { 00223 docElem.setAttribute( "hide_nsbk", docElem.attribute( "HIDE_NSBK" ) == "1" ? "yes" : "no" ); 00224 docElem.removeAttribute( "HIDE_NSBK" ); 00225 } 00226 00227 convertToXBEL( docElem ); 00228 save(); 00229 } 00230 else if ( mainTag != "xbel" ) 00231 kdWarning() << "KBookmarkManager::parse : unknown main tag " << mainTag << endl; 00232 00233 TQDomNode n = m_doc.documentElement().previousSibling(); 00234 if ( n.isProcessingInstruction() ) 00235 { 00236 TQDomProcessingInstruction pi = n.toProcessingInstruction(); 00237 pi.parentNode().removeChild(pi); 00238 } 00239 00240 TQDomProcessingInstruction pi; 00241 pi = m_doc.createProcessingInstruction( "xml", PI_DATA ); 00242 m_doc.insertBefore( pi, docElem ); 00243 } 00244 00245 file.close(); 00246 if ( !s_bk_map ) 00247 s_bk_map = new KBookmarkMap( const_cast<KBookmarkManager*>( this ) ); 00248 s_bk_map->update(); 00249 } 00250 00251 void KBookmarkManager::convertToXBEL( TQDomElement & group ) 00252 { 00253 TQDomNode n = group.firstChild(); 00254 while( !n.isNull() ) 00255 { 00256 TQDomElement e = n.toElement(); 00257 if ( !e.isNull() ) 00258 { 00259 if ( e.tagName() == "TEXT" ) 00260 { 00261 e.setTagName("title"); 00262 } 00263 else if ( e.tagName() == "SEPARATOR" ) 00264 { 00265 e.setTagName("separator"); // so close... 00266 } 00267 else if ( e.tagName() == "GROUP" ) 00268 { 00269 e.setTagName("folder"); 00270 convertAttribute(e, "ICON","icon"); // non standard, but we need it 00271 if ( e.hasAttribute( "TOOLBAR" ) ) // non standard either, but we need it 00272 { 00273 e.setAttribute( "toolbar", e.attribute( "TOOLBAR" ) == "1" ? "yes" : "no" ); 00274 e.removeAttribute( "TOOLBAR" ); 00275 } 00276 00277 convertAttribute(e, "NETSCAPEINFO","netscapeinfo"); // idem 00278 bool open = (e.attribute("OPEN") == "1"); 00279 e.removeAttribute("OPEN"); 00280 e.setAttribute("folded", open ? "no" : "yes"); 00281 convertToXBEL( e ); 00282 } 00283 else 00284 { 00285 if ( e.tagName() == "BOOKMARK" ) 00286 { 00287 e.setTagName("bookmark"); // so much difference :-) 00288 convertAttribute(e, "ICON","icon"); // non standard, but we need it 00289 convertAttribute(e, "NETSCAPEINFO","netscapeinfo"); // idem 00290 convertAttribute(e, "URL","href"); 00291 TQString text = e.text(); 00292 while ( !e.firstChild().isNull() ) // clean up the old contained text 00293 e.removeChild(e.firstChild()); 00294 TQDomElement titleElem = e.ownerDocument().createElement("title"); 00295 e.appendChild( titleElem ); // should be the only child anyway 00296 titleElem.appendChild( e.ownerDocument().createTextNode( text ) ); 00297 } 00298 else 00299 { 00300 kdWarning(7043) << "Unknown tag " << e.tagName() << endl; 00301 } 00302 } 00303 } 00304 n = n.nextSibling(); 00305 } 00306 } 00307 00308 void KBookmarkManager::convertAttribute( TQDomElement elem, const TQString & oldName, const TQString & newName ) 00309 { 00310 if ( elem.hasAttribute( oldName ) ) 00311 { 00312 elem.setAttribute( newName, elem.attribute( oldName ) ); 00313 elem.removeAttribute( oldName ); 00314 } 00315 } 00316 00317 void KBookmarkManager::importDesktopFiles() 00318 { 00319 KBookmarkImporter importer( const_cast<TQDomDocument *>(&internalDocument()) ); 00320 TQString path(TDEGlobal::dirs()->saveLocation("data", "kfm/bookmarks", true)); 00321 importer.import( path ); 00322 //kdDebug(7043) << internalDocument().toCString() << endl; 00323 00324 save(); 00325 } 00326 00327 bool KBookmarkManager::save( bool toolbarCache ) const 00328 { 00329 return saveAs( m_bookmarksFile, toolbarCache ); 00330 } 00331 00332 bool KBookmarkManager::saveAs( const TQString & filename, bool toolbarCache ) const 00333 { 00334 kdDebug(7043) << "KBookmarkManager::save " << filename << endl; 00335 00336 // Save the bookmark toolbar folder for quick loading 00337 // but only when it will actually make things quicker 00338 const TQString cacheFilename = filename + TQString::fromLatin1(".tbcache"); 00339 if(toolbarCache && !root().isToolbarGroup()) 00340 { 00341 KSaveFile cacheFile( cacheFilename ); 00342 if ( cacheFile.status() == 0 ) 00343 { 00344 TQString str; 00345 TQTextStream stream(&str, IO_WriteOnly); 00346 stream << root().findToolbar(); 00347 TQCString cstr = str.utf8(); 00348 cacheFile.file()->writeBlock( cstr.data(), cstr.length() ); 00349 cacheFile.close(); 00350 } 00351 } 00352 else // remove any (now) stale cache 00353 { 00354 TQFile::remove( cacheFilename ); 00355 } 00356 00357 KSaveFile file( filename ); 00358 if ( file.status() == 0 ) 00359 { 00360 file.backupFile( file.name(), TQString::null, ".bak" ); 00361 TQCString cstr; 00362 cstr = internalDocument().toCString(); // is in UTF8 00363 file.file()->writeBlock( cstr.data(), cstr.length() ); 00364 if ( file.close() ) 00365 return true; 00366 } 00367 00368 static int hadSaveError = false; 00369 file.abort(); 00370 if ( !hadSaveError ) { 00371 TQString error = i18n("Unable to save bookmarks in %1. Reported error was: %2. " 00372 "This error message will only be shown once. The cause " 00373 "of the error needs to be fixed as quickly as possible, " 00374 "which is most likely a full hard drive.") 00375 .arg(filename).arg(TQString::fromLocal8Bit(strerror(file.status()))); 00376 if (tqApp->type() != TQApplication::Tty) 00377 KMessageBox::error( 0L, error ); 00378 else 00379 kdError() << error << endl; 00380 } 00381 hadSaveError = true; 00382 return false; 00383 } 00384 00385 KBookmarkGroup KBookmarkManager::root() const 00386 { 00387 return KBookmarkGroup(internalDocument().documentElement()); 00388 } 00389 00390 KBookmarkGroup KBookmarkManager::toolbar() 00391 { 00392 kdDebug(7043) << "KBookmarkManager::toolbar begin" << endl; 00393 // Only try to read from a toolbar cache if the full document isn't loaded 00394 if(!m_docIsLoaded) 00395 { 00396 kdDebug(7043) << "KBookmarkManager::toolbar trying cache" << endl; 00397 const TQString cacheFilename = m_bookmarksFile + TQString::fromLatin1(".tbcache"); 00398 TQFileInfo bmInfo(m_bookmarksFile); 00399 TQFileInfo cacheInfo(cacheFilename); 00400 if (m_toolbarDoc.isNull() && 00401 TQFile::exists(cacheFilename) && 00402 bmInfo.lastModified() < cacheInfo.lastModified()) 00403 { 00404 kdDebug(7043) << "KBookmarkManager::toolbar reading file" << endl; 00405 TQFile file( cacheFilename ); 00406 00407 if ( file.open( IO_ReadOnly ) ) 00408 { 00409 m_toolbarDoc = TQDomDocument("cache"); 00410 m_toolbarDoc.setContent( &file ); 00411 kdDebug(7043) << "KBookmarkManager::toolbar opened" << endl; 00412 } 00413 } 00414 if (!m_toolbarDoc.isNull()) 00415 { 00416 kdDebug(7043) << "KBookmarkManager::toolbar returning element" << endl; 00417 TQDomElement elem = m_toolbarDoc.firstChild().toElement(); 00418 return KBookmarkGroup(elem); 00419 } 00420 } 00421 00422 // Fallback to the normal way if there is no cache or if the bookmark file 00423 // is already loaded 00424 TQDomElement elem = root().findToolbar(); 00425 if (elem.isNull()) 00426 return root(); // Root is the bookmark toolbar if none has been set. 00427 else 00428 return KBookmarkGroup(root().findToolbar()); 00429 } 00430 00431 KBookmark KBookmarkManager::findByAddress( const TQString & address, bool tolerant ) 00432 { 00433 //kdDebug(7043) << "KBookmarkManager::findByAddress " << address << endl; 00434 KBookmark result = root(); 00435 // The address is something like /5/10/2+ 00436 TQStringList addresses = TQStringList::split(TQRegExp("[/+]"),address); 00437 // kdWarning() << addresses.join(",") << endl; 00438 for ( TQStringList::Iterator it = addresses.begin() ; it != addresses.end() ; ) 00439 { 00440 bool append = ((*it) == "+"); 00441 uint number = (*it).toUInt(); 00442 Q_ASSERT(result.isGroup()); 00443 KBookmarkGroup group = result.toGroup(); 00444 KBookmark bk = group.first(), lbk = bk; // last non-null bookmark 00445 for ( uint i = 0 ; ( (i<number) || append ) && !bk.isNull() ; ++i ) { 00446 lbk = bk; 00447 bk = group.next(bk); 00448 //kdWarning() << i << endl; 00449 } 00450 it++; 00451 int shouldBeGroup = !bk.isGroup() && (it != addresses.end()); 00452 if ( tolerant && ( bk.isNull() || shouldBeGroup ) ) { 00453 if (!lbk.isNull()) result = lbk; 00454 //kdWarning() << "break" << endl; 00455 break; 00456 } 00457 //kdWarning() << "found section" << endl; 00458 result = bk; 00459 } 00460 if (result.isNull()) { 00461 kdWarning() << "KBookmarkManager::findByAddress: couldn't find item " << address << endl; 00462 Q_ASSERT(!tolerant); 00463 } 00464 //kdWarning() << "found " << result.address() << endl; 00465 return result; 00466 } 00467 00468 static TQString pickUnusedTitle( KBookmarkGroup parentBookmark, 00469 const TQString &title, const TQString &url 00470 ) { 00471 // If this title is already used, we'll try to find something unused. 00472 KBookmark ch = parentBookmark.first(); 00473 int count = 1; 00474 TQString uniqueTitle = title; 00475 do 00476 { 00477 while ( !ch.isNull() ) 00478 { 00479 if ( uniqueTitle == ch.text() ) 00480 { 00481 // Title already used ! 00482 if ( url != ch.url().url() ) 00483 { 00484 uniqueTitle = title + TQString(" (%1)").arg(++count); 00485 // New title -> restart search from the beginning 00486 ch = parentBookmark.first(); 00487 break; 00488 } 00489 else 00490 { 00491 // this exact URL already exists 00492 return TQString::null; 00493 } 00494 } 00495 ch = parentBookmark.next( ch ); 00496 } 00497 } while ( !ch.isNull() ); 00498 00499 return uniqueTitle; 00500 } 00501 00502 KBookmarkGroup KBookmarkManager::addBookmarkDialog( 00503 const TQString & _url, const TQString & _title, 00504 const TQString & _parentBookmarkAddress 00505 ) { 00506 TQString url = _url; 00507 TQString title = _title; 00508 TQString parentBookmarkAddress = _parentBookmarkAddress; 00509 00510 if ( url.isEmpty() ) 00511 { 00512 KMessageBox::error( 0L, i18n("Cannot add bookmark with empty URL.")); 00513 return KBookmarkGroup(); 00514 } 00515 00516 if ( title.isEmpty() ) 00517 title = url; 00518 00519 if ( KBookmarkSettings::self()->m_advancedaddbookmark) 00520 { 00521 KBookmarkEditDialog dlg( title, url, this, KBookmarkEditDialog::InsertionMode, parentBookmarkAddress ); 00522 if ( dlg.exec() != KDialogBase::Accepted ) 00523 return KBookmarkGroup(); 00524 title = dlg.finalTitle(); 00525 url = dlg.finalUrl(); 00526 parentBookmarkAddress = dlg.finalAddress(); 00527 } 00528 00529 KBookmarkGroup parentBookmark; 00530 parentBookmark = findByAddress( parentBookmarkAddress ).toGroup(); 00531 Q_ASSERT( !parentBookmark.isNull() ); 00532 00533 TQString uniqueTitle = pickUnusedTitle( parentBookmark, title, url ); 00534 if ( !uniqueTitle.isNull() ) 00535 parentBookmark.addBookmark( this, uniqueTitle, KURL( url )); 00536 00537 return parentBookmark; 00538 } 00539 00540 00541 void KBookmarkManager::emitChanged( /*KDE4 const*/ KBookmarkGroup & group ) 00542 { 00543 save(); 00544 00545 // Tell the other processes too 00546 // kdDebug(7043) << "KBookmarkManager::emitChanged : broadcasting change " << group.address() << endl; 00547 00548 TQByteArray data; 00549 TQDataStream ds( data, IO_WriteOnly ); 00550 ds << group.address(); 00551 00552 emitDCOPSignal("bookmarksChanged(TQString)", data); 00553 00554 // We do get our own broadcast, so no need for this anymore 00555 //emit changed( group ); 00556 } 00557 00558 void KBookmarkManager::emitConfigChanged() 00559 { 00560 emitDCOPSignal("bookmarkConfigChanged()", TQByteArray()); 00561 } 00562 00563 void KBookmarkManager::notifyCompleteChange( TQString caller ) // DCOP call 00564 { 00565 if (!m_update) return; 00566 00567 //kdDebug(7043) << "KBookmarkManager::notifyCompleteChange" << endl; 00568 // The bk editor tells us we should reload everything 00569 // Reparse 00570 parse(); 00571 // Tell our GUI 00572 // (emit where group is "" to directly mark the root menu as dirty) 00573 emit changed( "", caller ); 00574 } 00575 00576 void KBookmarkManager::notifyConfigChanged() // DCOP call 00577 { 00578 kdDebug() << "reloaded bookmark config!" << endl; 00579 KBookmarkSettings::self()->readSettings(); 00580 parse(); // reload, and thusly recreate the menus 00581 } 00582 00583 void KBookmarkManager::notifyChanged( TQString groupAddress ) // DCOP call 00584 { 00585 if (!m_update) return; 00586 00587 // Reparse (the whole file, no other choice) 00588 // if someone else notified us 00589 if (callingDcopClient()->senderId() != DCOPClient::mainClient()->appId()) 00590 parse(); 00591 00592 //kdDebug(7043) << "KBookmarkManager::notifyChanged " << groupAddress << endl; 00593 //KBookmarkGroup group = findByAddress( groupAddress ).toGroup(); 00594 //Q_ASSERT(!group.isNull()); 00595 emit changed( groupAddress, TQString::null ); 00596 } 00597 00598 bool KBookmarkManager::showNSBookmarks() const 00599 { 00600 return KBookmarkMenu::showDynamicBookmarks("netscape").show; 00601 } 00602 00603 void KBookmarkManager::setShowNSBookmarks( bool show ) 00604 { 00605 m_showNSBookmarks = show; 00606 if (this->path() != userBookmarksFile()) 00607 return; 00608 KBookmarkMenu::DynMenuInfo info 00609 = KBookmarkMenu::showDynamicBookmarks("netscape"); 00610 info.show = show; 00611 KBookmarkMenu::setDynamicBookmarks("netscape", info); 00612 } 00613 00614 void KBookmarkManager::setEditorOptions( const TQString& caption, bool browser ) 00615 { 00616 dptr()->m_editorCaption = caption; 00617 dptr()->m_browserEditor = browser; 00618 } 00619 00620 void KBookmarkManager::slotEditBookmarks() 00621 { 00622 TDEProcess proc; 00623 proc << TQString::fromLatin1("keditbookmarks"); 00624 if (!dptr()->m_editorCaption.isNull()) 00625 proc << TQString::fromLatin1("--customcaption") << dptr()->m_editorCaption; 00626 if (!dptr()->m_browserEditor) 00627 proc << TQString::fromLatin1("--nobrowser"); 00628 proc << m_bookmarksFile; 00629 proc.start(TDEProcess::DontCare); 00630 } 00631 00632 void KBookmarkManager::slotEditBookmarksAtAddress( const TQString& address ) 00633 { 00634 TDEProcess proc; 00635 proc << TQString::fromLatin1("keditbookmarks") 00636 << TQString::fromLatin1("--address") << address 00637 << m_bookmarksFile; 00638 proc.start(TDEProcess::DontCare); 00639 } 00640 00642 00643 void KBookmarkOwner::openBookmarkURL( const TQString& url ) 00644 { 00645 (void) new KRun(KURL( url )); 00646 } 00647 00648 void KBookmarkOwner::virtual_hook( int, void* ) 00649 { /*BASE::virtual_hook( id, data );*/ } 00650 00651 bool KBookmarkManager::updateAccessMetadata( const TQString & url, bool emitSignal ) 00652 { 00653 if (!s_bk_map) { 00654 s_bk_map = new KBookmarkMap(this); 00655 s_bk_map->update(); 00656 } 00657 00658 TQValueList<KBookmark> list = s_bk_map->find(url); 00659 if ( list.count() == 0 ) 00660 return false; 00661 00662 for ( TQValueList<KBookmark>::iterator it = list.begin(); 00663 it != list.end(); ++it ) 00664 (*it).updateAccessMetadata(); 00665 00666 if (emitSignal) 00667 emit notifier().updatedAccessMetadata( path(), url ); 00668 00669 return true; 00670 } 00671 00672 void KBookmarkManager::updateFavicon( const TQString &url, const TQString &faviconurl, bool emitSignal ) 00673 { 00674 Q_UNUSED(faviconurl); 00675 00676 if (!s_bk_map) { 00677 s_bk_map = new KBookmarkMap(this); 00678 s_bk_map->update(); 00679 } 00680 00681 TQValueList<KBookmark> list = s_bk_map->find(url); 00682 for ( TQValueList<KBookmark>::iterator it = list.begin(); 00683 it != list.end(); ++it ) 00684 { 00685 // TODO - update favicon data based on faviconurl 00686 // but only when the previously used icon 00687 // isn't a manually set one. 00688 } 00689 00690 if (emitSignal) 00691 { 00692 // TODO 00693 // emit notifier().updatedFavicon( path(), url, faviconurl ); 00694 } 00695 } 00696 00697 TQString KBookmarkManager::userBookmarksFile() 00698 { 00699 return locateLocal("data", TQString::fromLatin1("konqueror/bookmarks.xml")); 00700 } 00701 00702 KBookmarkManager* KBookmarkManager::userBookmarksManager() 00703 { 00704 return KBookmarkManager::managerForFile( userBookmarksFile() ); 00705 } 00706 00707 KBookmarkSettings* KBookmarkSettings::s_self = 0; 00708 00709 void KBookmarkSettings::readSettings() 00710 { 00711 TDEConfig config("kbookmarkrc", false, false); 00712 config.setGroup("Bookmarks"); 00713 00714 // add bookmark dialog usage - no reparse 00715 s_self->m_advancedaddbookmark = config.readBoolEntry("AdvancedAddBookmarkDialog", false); 00716 00717 // these three alter the menu, therefore all need a reparse 00718 s_self->m_contextmenu = config.readBoolEntry("ContextMenuActions", true); 00719 s_self->m_quickactions = config.readBoolEntry("QuickActionSubmenu", false); 00720 s_self->m_filteredtoolbar = config.readBoolEntry("FilteredToolbar", false); 00721 } 00722 00723 KBookmarkSettings *KBookmarkSettings::self() 00724 { 00725 if (!s_self) 00726 { 00727 s_self = new KBookmarkSettings; 00728 readSettings(); 00729 } 00730 return s_self; 00731 } 00732 00733 #include "kbookmarkmanager.moc"