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>
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"