20 #include "kbookmarkmanager.h"
21 #include "kbookmarkmenu.h"
22 #include "kbookmarkmenu_p.h"
23 #include "kbookmarkimporter.h"
26 #include <kstandarddirs.h>
27 #include <ksavefile.h>
30 #include <tdemessagebox.h>
31 #include <tdeprocess.h>
32 #include <tdelocale.h>
33 #include <tdeapplication.h>
34 #include <dcopclient.h>
36 #include <tqfileinfo.h>
37 #include <tqtextstream.h>
38 #include <kstaticdeleter.h>
39 #include <tqptrstack.h>
41 #include "dptrtemplate.h"
43 class KBookmarkManagerPrivate :
public dPtrTemplate<KBookmarkManager, KBookmarkManagerPrivate> {
45 KBookmarkManagerPrivate()
46 { m_browserEditor =
true; }
47 TQString m_editorCaption;
50 template<> TQPtrDict<KBookmarkManagerPrivate>* dPtrTemplate<KBookmarkManager, KBookmarkManagerPrivate>::d_ptr = 0;
52 KBookmarkManagerPrivate* KBookmarkManager::dptr()
const {
53 return KBookmarkManagerPrivate::d(
this );
57 TQPtrList<KBookmarkManager>* KBookmarkManager::s_pSelf;
58 static KStaticDeleter<TQPtrList<KBookmarkManager> > sdbm;
64 TQValueList<KBookmark> find(
const TQString &url )
const
65 {
return m_bk_map[url]; }
67 virtual void visit(
const KBookmark &);
71 typedef TQValueList<KBookmark> KBookmarkList;
72 TQMap<TQString, KBookmarkList> m_bk_map;
76 static KBookmarkMap *s_bk_map = 0;
82 void KBookmarkMap::update()
89 void KBookmarkMap::visit(
const KBookmark &bk)
91 if (!bk.isSeparator()) {
93 m_bk_map[bk.internalElement().attribute(
"href")].append(bk);
101 sdbm.setObject( s_pSelf,
new TQPtrList<KBookmarkManager> );
102 s_pSelf->setAutoDelete(
true );
104 TQPtrListIterator<KBookmarkManager> it ( *s_pSelf );
105 for ( ; it.current() ; ++it )
106 if ( it.current()->path() == bookmarksFile )
110 s_pSelf->append( mgr );
118 sdbm.setObject( s_pSelf,
new TQPtrList<KBookmarkManager> );
119 s_pSelf->setAutoDelete(
true );
122 s_pSelf->append( mgr );
126 #define PI_DATA "version=\"1.0\" encoding=\"UTF-8\""
129 : DCOPObject(TQCString(
"KBookmarkManager-")+bookmarksFile.utf8()), m_doc(
"xbel"), m_docIsLoaded(false)
131 m_toolbarDoc.clear();
134 m_showNSBookmarks =
true;
136 Q_ASSERT( !bookmarksFile.isEmpty() );
137 m_bookmarksFile = bookmarksFile;
139 if ( !TQFile::exists(m_bookmarksFile) )
141 TQDomElement topLevel = m_doc.createElement(
"xbel");
142 m_doc.appendChild( topLevel );
143 m_doc.insertBefore( m_doc.createProcessingInstruction(
"xml", PI_DATA), topLevel );
144 if ( bImportDesktopFiles )
145 importDesktopFiles();
146 m_docIsLoaded =
true;
149 connectDCOPSignal(0, objId(),
"bookmarksChanged(TQString)",
"notifyChanged(TQString)",
false);
150 connectDCOPSignal(0, objId(),
"bookmarkConfigChanged()",
"notifyConfigChanged()",
false);
154 : DCOPObject(TQCString(
"KBookmarkManager-generated")), m_doc(
"xbel"), m_docIsLoaded(true)
156 m_toolbarDoc.clear();
159 m_showNSBookmarks =
true;
161 m_bookmarksFile = TQString::null;
163 TQDomElement topLevel = m_doc.createElement(
"xbel");
164 m_doc.appendChild( topLevel );
165 m_doc.insertBefore( m_doc.createProcessingInstruction(
"xml", PI_DATA), topLevel );
169 connectDCOPSignal(0, objId(),
"bookmarksChanged(TQString)",
"notifyChanged(TQString)",
false);
170 connectDCOPSignal(0, objId(),
"bookmarkConfigChanged()",
"notifyConfigChanged()",
false);
177 s_pSelf->removeRef(
this );
185 const TQDomDocument &KBookmarkManager::internalDocument()
const
190 m_toolbarDoc.clear();
196 void KBookmarkManager::parse()
const
198 m_docIsLoaded =
true;
200 TQFile file( m_bookmarksFile );
201 if ( !file.open( IO_ReadOnly ) )
203 kdWarning() <<
"Can't open " << m_bookmarksFile << endl;
206 m_doc = TQDomDocument(
"xbel");
207 m_doc.setContent( &file );
209 TQDomElement docElem = m_doc.documentElement();
210 if ( docElem.isNull() )
211 kdWarning() <<
"KBookmarkManager::parse : can't parse " << m_bookmarksFile << endl;
214 TQString mainTag = docElem.tagName();
215 if ( mainTag ==
"BOOKMARKS" )
217 kdWarning() <<
"Old style bookmarks found. Calling convertToXBEL." << endl;
218 docElem.setTagName(
"xbel");
219 if ( docElem.hasAttribute(
"HIDE_NSBK" ) && m_showNSBookmarks )
221 docElem.setAttribute(
"hide_nsbk", docElem.attribute(
"HIDE_NSBK" ) ==
"1" ?
"yes" :
"no" );
222 docElem.removeAttribute(
"HIDE_NSBK" );
225 convertToXBEL( docElem );
228 else if ( mainTag !=
"xbel" )
229 kdWarning() <<
"KBookmarkManager::parse : unknown main tag " << mainTag << endl;
231 TQDomNode n = m_doc.documentElement().previousSibling();
232 if ( n.isProcessingInstruction() )
234 TQDomProcessingInstruction pi = n.toProcessingInstruction();
235 pi.parentNode().removeChild(pi);
238 TQDomProcessingInstruction pi;
239 pi = m_doc.createProcessingInstruction(
"xml", PI_DATA );
240 m_doc.insertBefore( pi, docElem );
249 void KBookmarkManager::convertToXBEL( TQDomElement & group )
251 TQDomNode n = group.firstChild();
254 TQDomElement e = n.toElement();
257 if ( e.tagName() ==
"TEXT" )
259 e.setTagName(
"title");
261 else if ( e.tagName() ==
"SEPARATOR" )
263 e.setTagName(
"separator");
265 else if ( e.tagName() ==
"GROUP" )
267 e.setTagName(
"folder");
268 convertAttribute(e,
"ICON",
"icon");
269 if ( e.hasAttribute(
"TOOLBAR" ) )
271 e.setAttribute(
"toolbar", e.attribute(
"TOOLBAR" ) ==
"1" ?
"yes" :
"no" );
272 e.removeAttribute(
"TOOLBAR" );
275 convertAttribute(e,
"NETSCAPEINFO",
"netscapeinfo");
276 bool open = (e.attribute(
"OPEN") ==
"1");
277 e.removeAttribute(
"OPEN");
278 e.setAttribute(
"folded", open ?
"no" :
"yes");
283 if ( e.tagName() ==
"BOOKMARK" )
285 e.setTagName(
"bookmark");
286 convertAttribute(e,
"ICON",
"icon");
287 convertAttribute(e,
"NETSCAPEINFO",
"netscapeinfo");
288 convertAttribute(e,
"URL",
"href");
289 TQString text = e.text();
290 while ( !e.firstChild().isNull() )
291 e.removeChild(e.firstChild());
292 TQDomElement titleElem = e.ownerDocument().createElement(
"title");
293 e.appendChild( titleElem );
294 titleElem.appendChild( e.ownerDocument().createTextNode( text ) );
298 kdWarning(7043) <<
"Unknown tag " << e.tagName() << endl;
306 void KBookmarkManager::convertAttribute( TQDomElement elem,
const TQString & oldName,
const TQString & newName )
308 if ( elem.hasAttribute( oldName ) )
310 elem.setAttribute( newName, elem.attribute( oldName ) );
311 elem.removeAttribute( oldName );
315 void KBookmarkManager::importDesktopFiles()
318 TQString
path(TDEGlobal::dirs()->saveLocation(
"data",
"kfm/bookmarks",
true));
319 importer.import(
path );
327 return saveAs( m_bookmarksFile, toolbarCache );
332 kdDebug(7043) <<
"KBookmarkManager::save " << filename << endl;
336 const TQString cacheFilename = filename + TQString::fromLatin1(
".tbcache");
337 if(toolbarCache && !
root().isToolbarGroup())
339 KSaveFile cacheFile( cacheFilename );
340 if ( cacheFile.status() == 0 )
343 TQTextStream stream(&str, IO_WriteOnly);
344 stream <<
root().findToolbar();
345 TQCString cstr = str.utf8();
346 cacheFile.file()->writeBlock( cstr.data(), cstr.length() );
352 TQFile::remove( cacheFilename );
355 KSaveFile file( filename );
356 if ( file.status() == 0 )
358 file.backupFile( file.name(), TQString::null,
".bak" );
360 cstr = internalDocument().toCString();
361 file.file()->writeBlock( cstr.data(), cstr.length() );
366 static int hadSaveError =
false;
368 if ( !hadSaveError ) {
369 TQString error = i18n(
"Unable to save bookmarks in %1. Reported error was: %2. "
370 "This error message will only be shown once. The cause "
371 "of the error needs to be fixed as quickly as possible, "
372 "which is most likely a full hard drive.")
373 .arg(filename).arg(TQString::fromLocal8Bit(strerror(file.status())));
374 if (tqApp->type() != TQApplication::Tty)
375 KMessageBox::error( 0L, error );
377 kdError() << error << endl;
390 kdDebug(7043) <<
"KBookmarkManager::toolbar begin" << endl;
394 kdDebug(7043) <<
"KBookmarkManager::toolbar trying cache" << endl;
395 const TQString cacheFilename = m_bookmarksFile + TQString::fromLatin1(
".tbcache");
396 TQFileInfo bmInfo(m_bookmarksFile);
397 TQFileInfo cacheInfo(cacheFilename);
398 if (m_toolbarDoc.isNull() &&
399 TQFile::exists(cacheFilename) &&
400 bmInfo.lastModified() < cacheInfo.lastModified())
402 kdDebug(7043) <<
"KBookmarkManager::toolbar reading file" << endl;
403 TQFile file( cacheFilename );
405 if ( file.open( IO_ReadOnly ) )
407 m_toolbarDoc = TQDomDocument(
"cache");
408 m_toolbarDoc.setContent( &file );
409 kdDebug(7043) <<
"KBookmarkManager::toolbar opened" << endl;
412 if (!m_toolbarDoc.isNull())
414 kdDebug(7043) <<
"KBookmarkManager::toolbar returning element" << endl;
415 TQDomElement elem = m_toolbarDoc.firstChild().toElement();
422 TQDomElement elem =
root().findToolbar();
432 KBookmark result =
root();
434 TQStringList addresses = TQStringList::split(TQRegExp(
"[/+]"),address);
436 for ( TQStringList::Iterator it = addresses.begin() ; it != addresses.end() ; )
438 bool append = ((*it) ==
"+");
439 uint number = (*it).toUInt();
440 Q_ASSERT(result.isGroup());
442 KBookmark bk = group.
first(), lbk = bk;
443 for ( uint i = 0 ; ( (i<number) || append ) && !bk.isNull() ; ++i ) {
449 int shouldBeGroup = !bk.isGroup() && (it != addresses.end());
450 if ( tolerant && ( bk.isNull() || shouldBeGroup ) ) {
451 if (!lbk.isNull()) result = lbk;
458 if (result.isNull()) {
459 kdWarning() <<
"KBookmarkManager::findByAddress: couldn't find item " << address << endl;
467 const TQString &title,
const TQString &url
470 KBookmark ch = parentBookmark.
first();
472 TQString uniqueTitle = title;
475 while ( !ch.isNull() )
477 if ( uniqueTitle == ch.text() )
480 if ( url != ch.url().url() )
482 uniqueTitle = title + TQString(
" (%1)").arg(++count);
484 ch = parentBookmark.
first();
490 return TQString::null;
493 ch = parentBookmark.
next( ch );
495 }
while ( !ch.isNull() );
501 const TQString & _url,
const TQString & _title,
502 const TQString & _parentBookmarkAddress
505 TQString title = _title;
506 TQString parentBookmarkAddress = _parentBookmarkAddress;
510 KMessageBox::error( 0L, i18n(
"Cannot add bookmark with empty URL."));
514 if ( title.isEmpty() )
517 if ( KBookmarkSettings::self()->m_advancedaddbookmark)
519 KBookmarkEditDialog dlg( title, url,
this, KBookmarkEditDialog::InsertionMode, parentBookmarkAddress );
520 if ( dlg.exec() != KDialogBase::Accepted )
522 title = dlg.finalTitle();
523 url = dlg.finalUrl();
524 parentBookmarkAddress = dlg.finalAddress();
528 parentBookmark =
findByAddress( parentBookmarkAddress ).toGroup();
529 Q_ASSERT( !parentBookmark.isNull() );
531 TQString uniqueTitle = pickUnusedTitle( parentBookmark, title, url );
532 if ( !uniqueTitle.isNull() )
533 parentBookmark.
addBookmark(
this, uniqueTitle, KURL( url ));
535 return parentBookmark;
547 TQDataStream ds( data, IO_WriteOnly );
548 ds << group.address();
550 emitDCOPSignal(
"bookmarksChanged(TQString)", data);
556 void KBookmarkManager::emitConfigChanged()
558 emitDCOPSignal(
"bookmarkConfigChanged()", TQByteArray());
563 if (!m_update)
return;
574 void KBookmarkManager::notifyConfigChanged()
576 kdDebug() <<
"reloaded bookmark config!" << endl;
577 KBookmarkSettings::self()->readSettings();
583 if (!m_update)
return;
587 if (callingDcopClient()->senderId() != DCOPClient::mainClient()->appId())
593 emit
changed( groupAddress, TQString::null );
603 m_showNSBookmarks = show;
614 dptr()->m_editorCaption = caption;
615 dptr()->m_browserEditor = browser;
618 void KBookmarkManager::slotEditBookmarks()
621 proc << TQString::fromLatin1(
"keditbookmarks");
622 if (!dptr()->m_editorCaption.isNull())
623 proc << TQString::fromLatin1(
"--customcaption") << dptr()->m_editorCaption;
624 if (!dptr()->m_browserEditor)
625 proc << TQString::fromLatin1(
"--nobrowser");
626 proc << m_bookmarksFile;
627 proc.start(TDEProcess::DontCare);
630 void KBookmarkManager::slotEditBookmarksAtAddress(
const TQString& address )
633 proc << TQString::fromLatin1(
"keditbookmarks")
634 << TQString::fromLatin1(
"--address") << address
636 proc.start(TDEProcess::DontCare);
643 (void)
new KRun(KURL( url ));
646 void KBookmarkOwner::virtual_hook(
int,
void* )
652 s_bk_map =
new KBookmarkMap(
this);
656 TQValueList<KBookmark> list = s_bk_map->find(url);
657 if ( list.count() == 0 )
660 for ( TQValueList<KBookmark>::iterator it = list.begin();
661 it != list.end(); ++it )
662 (*it).updateAccessMetadata();
670 void KBookmarkManager::updateFavicon(
const TQString &url,
const TQString &faviconurl,
bool emitSignal )
672 Q_UNUSED(faviconurl);
675 s_bk_map =
new KBookmarkMap(
this);
679 TQValueList<KBookmark> list = s_bk_map->find(url);
680 for ( TQValueList<KBookmark>::iterator it = list.begin();
681 it != list.end(); ++it )
697 return locateLocal(
"data", TQString::fromLatin1(
"konqueror/bookmarks.xml"));
705 KBookmarkSettings* KBookmarkSettings::s_self = 0;
707 void KBookmarkSettings::readSettings()
709 TDEConfig config(
"kbookmarkrc",
false,
false);
710 config.setGroup(
"Bookmarks");
713 s_self->m_advancedaddbookmark = config.readBoolEntry(
"AdvancedAddBookmarkDialog",
false);
716 s_self->m_contextmenu = config.readBoolEntry(
"ContextMenuActions",
true);
717 s_self->m_quickactions = config.readBoolEntry(
"QuickActionSubmenu",
false);
718 s_self->m_filteredtoolbar = config.readBoolEntry(
"FilteredToolbar",
false);
721 KBookmarkSettings *KBookmarkSettings::self()
725 s_self =
new KBookmarkSettings;
731 #include "kbookmarkmanager.moc"
KBookmark next(const KBookmark ¤t) const
Return the next sibling of a child bookmark of this group.
KBookmark first() const
Return the first child bookmark of this group.
KBookmark addBookmark(KBookmarkManager *mgr, const KBookmark &bm, bool emitSignal=true)
Create a new bookmark, as the last child of this group Don't forget to use KBookmarkManager::self()->...
A class for importing the previous bookmarks (desktop files) Separated from KBookmarkManager to save ...
This class implements the reading/writing of bookmarks in XML.
void emitChanged(KBookmarkGroup &group)
Saves the bookmark file and notifies everyone.
TQString path()
This will return the path that this manager is using to read the bookmarks.
KBookmark findByAddress(const TQString &address, bool tolerate=false)
ASYNC notifyChanged(TQString groupAddress)
Emit the changed signal for the group whose address is given.
KBookmarkGroup toolbar()
This returns the root of the toolbar menu.
bool saveAs(const TQString &filename, bool toolbarCache=true) const
Save the bookmarks to the given XML file on disk.
void setEditorOptions(const TQString &caption, bool browser)
Set options with which slotEditBookmarks called keditbookmarks this can be used to change the appeara...
void setUpdate(bool update)
Set the update flag.
KBookmarkNotifier & notifier()
Access to bookmark notifier, for emitting signals.
KBookmarkGroup addBookmarkDialog(const TQString &_url, const TQString &_title, const TQString &_parentBookmarkAddress=TQString::null)
static KBookmarkManager * userBookmarksManager()
Returns a pointer to the users main bookmark collection.
bool save(bool toolbarCache=true) const
Save the bookmarks to the default konqueror XML file on disk.
KBookmarkGroup root() const
This will return the root bookmark.
bool showNSBookmarks() const
void changed(const TQString &groupAddress, const TQString &caller)
Signals that the group (or any of its children) with the address groupAddress (e.g.
~KBookmarkManager()
Destructor.
ASYNC notifyCompleteChange(TQString caller)
Reparse the whole bookmarks file and notify about the change (Called by the bookmark editor)
static KBookmarkManager * managerForFile(const TQString &bookmarksFile, bool bImportDesktopFiles=true)
This static function will return an instance of the KBookmarkManager, responsible for the given bookm...
static TQString userBookmarksFile()
Returns the path to the user's main bookmark collection file.
void setShowNSBookmarks(bool show)
Shows an extra menu for NS bookmarks.
bool updateAccessMetadata(const TQString &url, bool emitSignal=true)
Update access time stamps for a given url.
virtual void openBookmarkURL(const TQString &_url)
This function is called if the user selects a bookmark.