• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeio/bookmarks
 

tdeio/bookmarks

  • tdeio
  • bookmarks
kbookmark.cpp
1 /* This file is part of the KDE libraries
2  Copyright (C) 2000 David Faure <faure@kde.org>
3  Copyright (C) 2003 Alexander Kellett <lypanov@kde.org>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "kbookmark.h"
21 #include <tqvaluestack.h>
22 #include <kdebug.h>
23 #include <kmimetype.h>
24 #include <kstringhandler.h>
25 #include <kinputdialog.h>
26 #include <tdeglobal.h>
27 #include <tdelocale.h>
28 #include <assert.h>
29 #include <tdeapplication.h>
30 #include <dcopclient.h>
31 #include <kbookmarkmanager.h>
32 
33 KBookmarkGroup::KBookmarkGroup()
34  : KBookmark( TQDomElement() )
35 {
36 }
37 
38 KBookmarkGroup::KBookmarkGroup( TQDomElement elem )
39  : KBookmark(elem)
40 {
41 }
42 
43 TQString KBookmarkGroup::groupAddress() const
44 {
45  if (m_address.isEmpty())
46  m_address = address();
47  return m_address;
48 }
49 
50 bool KBookmarkGroup::isOpen() const
51 {
52  return element.attribute("folded") == "no"; // default is: folded
53 }
54 
55 // Returns first element node equal to or after node n
56 static TQDomElement firstElement(TQDomNode n)
57 {
58  while(!n.isNull() && !n.isElement())
59  n = n.nextSibling();
60  return n.toElement();
61 }
62 
63 // Returns first element node equal to or before node n
64 static TQDomElement lastElement(TQDomNode n)
65 {
66  while(!n.isNull() && !n.isElement())
67  n = n.previousSibling();
68  return n.toElement();
69 }
70 
71 KBookmark KBookmarkGroup::first() const
72 {
73  return KBookmark( nextKnownTag( firstElement(element.firstChild()), true ) );
74 }
75 
76 KBookmark KBookmarkGroup::previous( const KBookmark & current ) const
77 {
78  return KBookmark( nextKnownTag( lastElement(current.element.previousSibling()), false ) );
79 }
80 
81 KBookmark KBookmarkGroup::next( const KBookmark & current ) const
82 {
83  return KBookmark( nextKnownTag( firstElement(current.element.nextSibling()), true ) );
84 }
85 
86 // KDE4: Change TQDomElement to TQDomNode so that we can get rid of
87 // firstElement() and lastElement()
88 TQDomElement KBookmarkGroup::nextKnownTag( TQDomElement start, bool goNext ) const
89 {
90  static const TQString & bookmark = TDEGlobal::staticQString("bookmark");
91  static const TQString & folder = TDEGlobal::staticQString("folder");
92  static const TQString & separator = TDEGlobal::staticQString("separator");
93 
94  for( TQDomNode n = start; !n.isNull(); )
95  {
96  TQDomElement elem = n.toElement();
97  TQString tag = elem.tagName();
98  if (tag == folder || tag == bookmark || tag == separator)
99  return elem;
100  if (goNext)
101  n = n.nextSibling();
102  else
103  n = n.previousSibling();
104  }
105  return TQDomElement();
106 }
107 
108 KBookmarkGroup KBookmarkGroup::createNewFolder( KBookmarkManager* mgr, const TQString & text, bool emitSignal )
109 {
110  TQString txt( text );
111  if ( text.isEmpty() )
112  {
113  bool ok;
114  TQString caption = parentGroup().fullText().isEmpty() ?
115  i18n( "Create New Bookmark Folder" ) :
116  i18n( "Create New Bookmark Folder in %1" )
117  .arg( parentGroup().text() );
118  txt = KInputDialog::getText( caption, i18n( "New folder:" ),
119  TQString::null, &ok );
120  if ( !ok )
121  return KBookmarkGroup();
122  }
123 
124  Q_ASSERT(!element.isNull());
125  TQDomDocument doc = element.ownerDocument();
126  TQDomElement groupElem = doc.createElement( "folder" );
127  element.appendChild( groupElem );
128  TQDomElement textElem = doc.createElement( "title" );
129  groupElem.appendChild( textElem );
130  textElem.appendChild( doc.createTextNode( txt ) );
131 
132  KBookmarkGroup grp(groupElem);
133 
134  if (emitSignal)
135  emit mgr->notifier().createdNewFolder(
136  mgr->path(), grp.fullText(),
137  grp.address() );
138 
139  return grp;
140 
141 }
142 
143 KBookmark KBookmarkGroup::createNewSeparator()
144 {
145  Q_ASSERT(!element.isNull());
146  TQDomDocument doc = element.ownerDocument();
147  Q_ASSERT(!doc.isNull());
148  TQDomElement sepElem = doc.createElement( "separator" );
149  element.appendChild( sepElem );
150  return KBookmark(sepElem);
151 }
152 
153 bool KBookmarkGroup::moveItem( const KBookmark & item, const KBookmark & after )
154 {
155  TQDomNode n;
156  if ( !after.isNull() )
157  n = element.insertAfter( item.element, after.element );
158  else // first child
159  {
160  if ( element.firstChild().isNull() ) // Empty element -> set as real first child
161  n = element.insertBefore( item.element, TQDomElement() );
162 
163  // we have to skip everything up to the first valid child
164  TQDomElement firstChild = nextKnownTag(element.firstChild().toElement(), true);
165  if ( !firstChild.isNull() )
166  n = element.insertBefore( item.element, firstChild );
167  else
168  {
169  // No real first child -> append after the <title> etc.
170  n = element.appendChild( item.element );
171  }
172  }
173  return (!n.isNull());
174 }
175 
176 KBookmark KBookmarkGroup::addBookmark( KBookmarkManager* mgr, const KBookmark &bm, bool emitSignal )
177 {
178  element.appendChild( bm.internalElement() );
179 
180  if (emitSignal) {
181  if ( bm.hasMetaData() ) {
182  mgr->notifyCompleteChange( "" );
183  } else {
184  emit mgr->notifier().addedBookmark(
185  mgr->path(), bm.url().url(),
186  bm.fullText(), bm.address(), bm.icon() );
187  }
188  }
189 
190  return bm;
191 }
192 
193 KBookmark KBookmarkGroup::addBookmark( KBookmarkManager* mgr, const TQString & text, const KURL & url, const TQString & icon, bool emitSignal )
194 {
195  //kdDebug(7043) << "KBookmarkGroup::addBookmark " << text << " into " << m_address << endl;
196  TQDomDocument doc = element.ownerDocument();
197  TQDomElement elem = doc.createElement( "bookmark" );
198  elem.setAttribute( "href", url.url( 0, 106 ) ); // write utf8 URL (106 is mib enum for utf8)
199  TQString _icon = icon;
200  if ( _icon.isEmpty() )
201  _icon = KMimeType::iconForURL( url );
202  elem.setAttribute( "icon", _icon );
203 
204  TQDomElement textElem = doc.createElement( "title" );
205  elem.appendChild( textElem );
206  textElem.appendChild( doc.createTextNode( text ) );
207 
208  return addBookmark( mgr, KBookmark( elem ), emitSignal );
209 }
210 
211 void KBookmarkGroup::deleteBookmark( KBookmark bk )
212 {
213  element.removeChild( bk.element );
214 }
215 
216 bool KBookmarkGroup::isToolbarGroup() const
217 {
218  return ( element.attribute("toolbar") == "yes" );
219 }
220 
221 TQDomElement KBookmarkGroup::findToolbar() const
222 {
223  if ( element.attribute("toolbar") == "yes" )
224  return element;
225  for (TQDomNode n = element.firstChild(); !n.isNull() ; n = n.nextSibling() )
226  {
227  TQDomElement e = n.toElement();
228  // Search among the "folder" children only
229  if ( e.tagName() == "folder" )
230  {
231  if ( e.attribute("toolbar") == "yes" )
232  return e;
233  else
234  {
235  TQDomElement result = KBookmarkGroup(e).findToolbar();
236  if (!result.isNull())
237  return result;
238  }
239  }
240  }
241  return TQDomElement();
242 }
243 
244 TQValueList<KURL> KBookmarkGroup::groupUrlList() const
245 {
246  TQValueList<KURL> urlList;
247  for ( KBookmark bm = first(); !bm.isNull(); bm = next(bm) )
248  {
249  if ( bm.isSeparator() || bm.isGroup() )
250  continue;
251  urlList << bm.url();
252  }
253  return urlList;
254 }
255 
257 
258 bool KBookmark::isGroup() const
259 {
260  TQString tag = element.tagName();
261  return ( tag == "folder"
262  || tag == "xbel" ); // don't forget the toplevel group
263 }
264 
265 bool KBookmark::isSeparator() const
266 {
267  return (element.tagName() == "separator");
268 }
269 
270 bool KBookmark::hasParent() const
271 {
272  TQDomElement parent = element.parentNode().toElement();
273  return !parent.isNull();
274 }
275 
276 TQString KBookmark::text() const
277 {
278  return KStringHandler::csqueeze( fullText() );
279 }
280 
281 TQString KBookmark::fullText() const
282 {
283  if (isSeparator())
284  return i18n("--- separator ---");
285 
286  return element.namedItem("title").toElement().text();
287 }
288 
289 KURL KBookmark::url() const
290 {
291  return KURL(element.attribute("href"), 106); // Decode it from utf8 (106 is mib enum for utf8)
292 }
293 
294 TQString KBookmark::icon() const
295 {
296  TQString icon = element.attribute("icon");
297  if ( icon.isEmpty() ) {
298  // Default icon depends on URL for bookmarks, and is default directory
299  // icon for groups.
300  if ( isGroup() ) {
301  icon = "bookmark_folder";
302  }
303  else {
304  if ( isSeparator() ) {
305  icon = "eraser"; // whatever
306  }
307  else {
308  icon = KMimeType::iconForURL( url() );
309  }
310  }
311  }
312  return icon;
313 }
314 
315 KBookmarkGroup KBookmark::parentGroup() const
316 {
317  return KBookmarkGroup( element.parentNode().toElement() );
318 }
319 
320 KBookmarkGroup KBookmark::toGroup() const
321 {
322  Q_ASSERT( isGroup() );
323  return KBookmarkGroup(element);
324 }
325 
326 TQString KBookmark::address() const
327 {
328  if ( element.tagName() == "xbel" )
329  return ""; // not TQString::null !
330  else
331  {
332  // Use keditbookmarks's DEBUG_ADDRESSES flag to debug this code :)
333  if (!hasParent())
334  {
335  Q_ASSERT(hasParent());
336  return "ERROR"; // Avoid an infinite loop
337  }
338  KBookmarkGroup group = parentGroup();
339  TQString parentAddress = group.address();
340  uint counter = 0;
341  // Implementation note: we don't use QDomNode's childNode list because we
342  // would have to skip "TEXT", which KBookmarkGroup already does for us.
343  for ( KBookmark bk = group.first() ; !bk.isNull() ; bk = group.next(bk), ++counter )
344  {
345  if ( bk.element == element )
346  return parentAddress + "/" + TQString::number(counter);
347  }
348  kdWarning() << "KBookmark::address : this can't happen! " << parentAddress << endl;
349  return "ERROR";
350  }
351 }
352 
353 KBookmark KBookmark::standaloneBookmark( const TQString & text, const KURL & url, const TQString & icon )
354 {
355  TQDomDocument doc("xbel");
356  TQDomElement elem = doc.createElement("xbel");
357  doc.appendChild( elem );
358  KBookmarkGroup grp( elem );
359  grp.addBookmark( 0L, text, url, icon, false );
360  return grp.first();
361 }
362 
363 // For some strange reason TQString("").left(0) returns TQString::null;
364 // That breaks commonParent()
365 TQString KBookmark::left(const TQString & str, uint len)
366 {
367  //kdDebug()<<"********"<<TQString("").left(0).isNull()<<endl;
368  if(len == 0)
369  return TQString("");
370  else
371  return str.left(len);
372 }
373 
374 TQString KBookmark::commonParent(TQString A, TQString B)
375 {
376  TQString error("ERROR");
377  if(A == error || B == error)
378  return error;
379 
380  A += "/";
381  B += "/";
382 
383  uint lastCommonSlash = 0;
384  uint lastPos = A.length() < B.length() ? A.length() : B.length();
385  for(uint i=0; i < lastPos; ++i)
386  {
387  if(A[i] != B[i])
388  return left(A, lastCommonSlash);
389  if(A[i] == '/')
390  lastCommonSlash = i;
391  }
392  return left(A, lastCommonSlash);
393 }
394 
395 static TQDomNode cd_or_create(TQDomNode node, TQString name)
396 {
397  TQDomNode subnode = node.namedItem(name);
398  if (subnode.isNull())
399  {
400  subnode = node.ownerDocument().createElement(name);
401  node.appendChild(subnode);
402  }
403  return subnode;
404 }
405 
406 static TQDomText get_or_create_text(TQDomNode node)
407 {
408  TQDomNode subnode = node.firstChild();
409  if (subnode.isNull())
410  {
411  subnode = node.ownerDocument().createTextNode("");
412  node.appendChild(subnode);
413  }
414  return subnode.toText();
415 }
416 
417 // Look for a metadata with owner="http://www.kde.org" or without any owner (for compatibility)
418 static TQDomNode findOrCreateMetadata( TQDomNode& parent )
419 {
420  static const char kdeOwner[] = "http://www.kde.org";
421  TQDomElement metadataElement;
422  for ( TQDomNode _node = parent.firstChild(); !_node.isNull(); _node = _node.nextSibling() ) {
423  TQDomElement elem = _node.toElement();
424  if ( !elem.isNull() && elem.tagName() == "metadata" ) {
425  const TQString owner = elem.attribute( "owner" );
426  if ( owner == kdeOwner )
427  return elem;
428  if ( owner.isEmpty() )
429  metadataElement = elem;
430  }
431  }
432  if ( metadataElement.isNull() ) {
433  metadataElement = parent.ownerDocument().createElement( "metadata" );
434  parent.appendChild(metadataElement);
435  }
436  metadataElement.setAttribute( "owner", kdeOwner );
437  return metadataElement;
438 }
439 
440 bool KBookmark::hasMetaData() const
441 {
442  // ### NOTE: this code creates <info> and <metadata>, despite its name and the const.
443  // It doesn't matter much in practice since it's only called for newly-created bookmarks,
444  // which will get metadata soon after anyway.
445  TQDomNode n = cd_or_create( internalElement(), "info" );
446  return findOrCreateMetadata( n ).hasChildNodes();
447 }
448 
449 void KBookmark::updateAccessMetadata()
450 {
451  kdDebug(7043) << "KBookmark::updateAccessMetadata " << address() << " " << url().prettyURL() << endl;
452 
453  const uint timet = TQDateTime::currentDateTime().toTime_t();
454  setMetaDataItem( "time_added", TQString::number( timet ), DontOverwriteMetaData );
455  setMetaDataItem( "time_visited", TQString::number( timet ) );
456 
457  TQString countStr = metaDataItem( "visit_count" ); // TODO use spec'ed name
458  bool ok;
459  int currentCount = countStr.toInt(&ok);
460  if (!ok)
461  currentCount = 0;
462  currentCount++;
463  setMetaDataItem( "visit_count", TQString::number( currentCount ) );
464 
465  // TODO - for 4.0 - time_modified
466 }
467 
468 TQString KBookmark::metaDataItem( const TQString &key ) const
469 {
470  TQDomNode infoNode = cd_or_create( internalElement(), "info" );
471  infoNode = findOrCreateMetadata( infoNode );
472  for ( TQDomNode n = infoNode.firstChild(); !n.isNull(); n = n.nextSibling() ) {
473  if ( !n.isElement() ) {
474  continue;
475  }
476  const TQDomElement e = n.toElement();
477  if ( e.tagName() == key ) {
478  return e.text();
479  }
480  }
481  return TQString::null;
482 }
483 
484 void KBookmark::setMetaDataItem( const TQString &key, const TQString &value, MetaDataOverwriteMode mode )
485 {
486  TQDomNode infoNode = cd_or_create( internalElement(), "info" );
487  infoNode = findOrCreateMetadata( infoNode );
488 
489  TQDomNode item = cd_or_create( infoNode, key );
490  TQDomText text = get_or_create_text( item );
491  if ( mode == DontOverwriteMetaData && !text.data().isEmpty() ) {
492  return;
493  }
494 
495  text.setData( value );
496 }
497 
498 void KBookmarkGroupTraverser::traverse(const KBookmarkGroup &root)
499 {
500  // non-recursive bookmark iterator
501  TQValueStack<KBookmarkGroup> stack;
502  stack.push(root);
503  KBookmark bk = stack.top().first();
504  for (;;) {
505  if (bk.isNull())
506  {
507  if (stack.isEmpty())
508  return;
509  if (stack.count() > 1)
510  visitLeave(stack.top());
511  bk = stack.pop();
512  bk = stack.top().next(bk);
513  if (bk.isNull())
514  continue;
515  }
516 
517  if (bk.isGroup())
518  {
519  KBookmarkGroup gp = bk.toGroup();
520  visitEnter(gp);
521  if (!gp.first().isNull())
522  {
523  stack.push(gp);
524  bk = gp.first();
525  continue;
526  }
527  // empty group
528  visitLeave(gp);
529  }
530  else
531  visit(bk);
532 
533  bk = stack.top().next(bk);
534  }
535 
536  // never reached
537 }
538 
KBookmarkGroup::previous
KBookmark previous(const KBookmark &current) const
Return the prevous sibling of a child bookmark of this group.
Definition: kbookmark.cpp:76
KBookmarkManager::notifier
KBookmarkNotifier & notifier()
Access to bookmark notifier, for emitting signals.
Definition: kbookmarkmanager.h:235
KBookmarkGroup::isToolbarGroup
bool isToolbarGroup() const
Definition: kbookmark.cpp:216
KBookmarkGroup::createNewSeparator
KBookmark createNewSeparator()
Create a new bookmark separator Don't forget to use KBookmarkManager::self()->emitChanged( parentBook...
Definition: kbookmark.cpp:143
KBookmarkGroup::createNewFolder
KBookmarkGroup createNewFolder(KBookmarkManager *mgr, const TQString &text=TQString::null, bool emitSignal=true)
Create a new bookmark folder, as the last child of this group.
Definition: kbookmark.cpp:108
KBookmarkGroup::addBookmark
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()->...
Definition: kbookmark.cpp:176
KBookmarkManager
This class implements the reading/writing of bookmarks in XML.
Definition: kbookmarkmanager.h:51
KBookmarkGroup::groupUrlList
TQValueList< KURL > groupUrlList() const
Definition: kbookmark.cpp:244
KBookmarkGroup::groupAddress
TQString groupAddress() const
Much like KBookmark::address, but caches the address into m_address.
Definition: kbookmark.cpp:43
KBookmarkGroup::KBookmarkGroup
KBookmarkGroup()
Create an invalid group.
Definition: kbookmark.cpp:33
KBookmarkManager::notifyCompleteChange
ASYNC notifyCompleteChange(TQString caller)
Reparse the whole bookmarks file and notify about the change (Called by the bookmark editor) ...
Definition: kbookmarkmanager.cpp:561
KBookmarkGroup
A group of bookmarks.
Definition: kbookmark.h:197
KBookmarkManager::path
TQString path()
This will return the path that this manager is using to read the bookmarks.
Definition: kbookmarkmanager.h:132
KBookmarkGroup::isOpen
bool isOpen() const
Definition: kbookmark.cpp:50
KBookmarkGroup::deleteBookmark
void deleteBookmark(KBookmark bk)
Delete a bookmark - it has to be one of our children ! Don't forget to use KBookmarkManager::self()->...
Definition: kbookmark.cpp:211
KBookmarkGroup::moveItem
bool moveItem(const KBookmark &item, const KBookmark &after)
Moves item after after (which should be a child of ours).
Definition: kbookmark.cpp:153
KBookmarkGroup::next
KBookmark next(const KBookmark &current) const
Return the next sibling of a child bookmark of this group.
Definition: kbookmark.cpp:81
KBookmarkGroup::first
KBookmark first() const
Return the first child bookmark of this group.
Definition: kbookmark.cpp:71

tdeio/bookmarks

Skip menu "tdeio/bookmarks"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

tdeio/bookmarks

Skip menu "tdeio/bookmarks"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/bookmarks by doxygen 1.8.8
This website is maintained by Timothy Pearson.