kio Library API Documentation

kbookmark.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., 59 Temple Place - Suite 330, 00019 Boston, MA 02111-1307, USA. 00020 */ 00021 00022 #include "kbookmark.h" 00023 #include <qvaluestack.h> 00024 #include <kdebug.h> 00025 #include <kmimetype.h> 00026 #include <kstringhandler.h> 00027 #include <kinputdialog.h> 00028 #include <kglobal.h> 00029 #include <klocale.h> 00030 #include <assert.h> 00031 #include <kapplication.h> 00032 #include <dcopclient.h> 00033 #include <kbookmarkmanager.h> 00034 00035 KBookmarkGroup::KBookmarkGroup() 00036 : KBookmark( QDomElement() ) 00037 { 00038 } 00039 00040 KBookmarkGroup::KBookmarkGroup( QDomElement elem ) 00041 : KBookmark(elem) 00042 { 00043 } 00044 00045 QString KBookmarkGroup::groupAddress() const 00046 { 00047 if (m_address.isEmpty()) 00048 m_address = address(); 00049 return m_address; 00050 } 00051 00052 bool KBookmarkGroup::isOpen() const 00053 { 00054 return element.attribute("folded") == "no"; // default is: folded 00055 } 00056 00057 KBookmark KBookmarkGroup::first() const 00058 { 00059 return KBookmark( nextKnownTag( element.firstChild().toElement(), true ) ); 00060 } 00061 00062 KBookmark KBookmarkGroup::previous( const KBookmark & current ) const 00063 { 00064 return KBookmark( nextKnownTag( current.element.previousSibling().toElement(), false ) ); 00065 } 00066 00067 KBookmark KBookmarkGroup::next( const KBookmark & current ) const 00068 { 00069 return KBookmark( nextKnownTag( current.element.nextSibling().toElement(), true ) ); 00070 } 00071 00072 QDomElement KBookmarkGroup::nextKnownTag( QDomElement start, bool goNext ) const 00073 { 00074 static const QString & bookmark = KGlobal::staticQString("bookmark"); 00075 static const QString & folder = KGlobal::staticQString("folder"); 00076 static const QString & separator = KGlobal::staticQString("separator"); 00077 QDomElement elem = start; 00078 while ( !elem.isNull() ) 00079 { 00080 QString tag = elem.tagName(); 00081 if (tag == folder || tag == bookmark || tag == separator) 00082 break; 00083 if (goNext) 00084 elem = elem.nextSibling().toElement(); 00085 else 00086 elem = elem.previousSibling().toElement(); 00087 } 00088 return elem; 00089 } 00090 00091 KBookmarkGroup KBookmarkGroup::createNewFolder( KBookmarkManager* mgr, const QString & text, bool emitSignal ) 00092 { 00093 QString txt( text ); 00094 if ( text.isEmpty() ) 00095 { 00096 bool ok; 00097 QString caption = parentGroup().fullText().isEmpty() ? 00098 i18n( "Create New Bookmark Folder" ) : 00099 i18n( "Create New Bookmark Folder in %1" ) 00100 .arg( parentGroup().text() ); 00101 txt = KInputDialog::getText( caption, i18n( "New folder:" ), 00102 QString::null, &ok ); 00103 if ( !ok ) 00104 return KBookmarkGroup(); 00105 } 00106 00107 Q_ASSERT(!element.isNull()); 00108 QDomDocument doc = element.ownerDocument(); 00109 QDomElement groupElem = doc.createElement( "folder" ); 00110 element.appendChild( groupElem ); 00111 QDomElement textElem = doc.createElement( "title" ); 00112 groupElem.appendChild( textElem ); 00113 textElem.appendChild( doc.createTextNode( txt ) ); 00114 00115 KBookmarkGroup grp(groupElem); 00116 00117 if (emitSignal) 00118 emit mgr->notifier().createdNewFolder( 00119 mgr->path(), grp.fullText(), 00120 grp.address() ); 00121 00122 return grp; 00123 00124 } 00125 00126 KBookmark KBookmarkGroup::createNewSeparator() 00127 { 00128 Q_ASSERT(!element.isNull()); 00129 QDomDocument doc = element.ownerDocument(); 00130 Q_ASSERT(!doc.isNull()); 00131 QDomElement sepElem = doc.createElement( "separator" ); 00132 element.appendChild( sepElem ); 00133 return KBookmark(sepElem); 00134 } 00135 00136 bool KBookmarkGroup::moveItem( const KBookmark & item, const KBookmark & after ) 00137 { 00138 QDomNode n; 00139 if ( !after.isNull() ) 00140 n = element.insertAfter( item.element, after.element ); 00141 else // first child 00142 { 00143 if ( element.firstChild().isNull() ) // Empty element -> set as real first child 00144 n = element.insertBefore( item.element, QDomElement() ); 00145 00146 // we have to skip everything up to the first valid child 00147 QDomElement firstChild = nextKnownTag(element.firstChild().toElement(), true); 00148 if ( !firstChild.isNull() ) 00149 n = element.insertBefore( item.element, firstChild ); 00150 else 00151 { 00152 // No real first child -> append after the <title> etc. 00153 n = element.appendChild( item.element ); 00154 } 00155 } 00156 return (!n.isNull()); 00157 } 00158 00159 KBookmark KBookmarkGroup::addBookmark( KBookmarkManager* mgr, const QString & text, const KURL & url, const QString & icon, bool emitSignal ) 00160 { 00161 //kdDebug(7043) << "KBookmarkGroup::addBookmark " << text << " into " << m_address << endl; 00162 QDomDocument doc = element.ownerDocument(); 00163 QDomElement elem = doc.createElement( "bookmark" ); 00164 element.appendChild( elem ); 00165 elem.setAttribute( "href", url.url( 0, 106 ) ); // write utf8 URL (106 is mib enum for utf8) 00166 QString _icon = icon; 00167 if ( _icon.isEmpty() ) 00168 _icon = KMimeType::iconForURL( url ); 00169 elem.setAttribute( "icon", _icon ); 00170 00171 QDomElement textElem = doc.createElement( "title" ); 00172 elem.appendChild( textElem ); 00173 textElem.appendChild( doc.createTextNode( text ) ); 00174 00175 KBookmark bk(elem); 00176 00177 if (emitSignal) 00178 emit mgr->notifier().addedBookmark( 00179 mgr->path(), url.url(), 00180 text, bk.address(), icon ); 00181 00182 return bk; 00183 } 00184 00185 void KBookmarkGroup::deleteBookmark( KBookmark bk ) 00186 { 00187 element.removeChild( bk.element ); 00188 } 00189 00190 bool KBookmarkGroup::isToolbarGroup() const 00191 { 00192 return ( element.attribute("toolbar") == "yes" ); 00193 } 00194 00195 QDomElement KBookmarkGroup::findToolbar() const 00196 { 00197 if ( element.attribute("toolbar") == "yes" ) 00198 return element; 00199 QDomElement e = element.firstChild().toElement(); 00200 for ( ; !e.isNull() ; e = e.nextSibling().toElement() ) 00201 { 00202 // Search among the "folder" children only 00203 if ( e.tagName() == "folder" ) 00204 { 00205 if ( e.attribute("toolbar") == "yes" ) 00206 return e; 00207 else 00208 { 00209 QDomElement result = KBookmarkGroup(e).findToolbar(); 00210 if (!result.isNull()) 00211 return result; 00212 } 00213 } 00214 } 00215 return QDomElement(); 00216 } 00217 00218 QValueList<KURL> KBookmarkGroup::groupUrlList() const 00219 { 00220 QValueList<KURL> urlList; 00221 for ( KBookmark bm = first(); !bm.isNull(); bm = next(bm) ) 00222 { 00223 if ( bm.isSeparator() || bm.isGroup() ) 00224 continue; 00225 urlList << bm.url(); 00226 } 00227 return urlList; 00228 } 00229 00231 00232 bool KBookmark::isGroup() const 00233 { 00234 QString tag = element.tagName(); 00235 return ( tag == "folder" 00236 || tag == "xbel" ); // don't forget the toplevel group 00237 } 00238 00239 bool KBookmark::isSeparator() const 00240 { 00241 return (element.tagName() == "separator"); 00242 } 00243 00244 bool KBookmark::hasParent() const 00245 { 00246 QDomElement parent = element.parentNode().toElement(); 00247 return !parent.isNull(); 00248 } 00249 00250 QString KBookmark::text() const 00251 { 00252 return KStringHandler::csqueeze( fullText() ); 00253 } 00254 00255 QString KBookmark::fullText() const 00256 { 00257 if (isSeparator()) 00258 return i18n("--- separator ---"); 00259 00260 return element.namedItem("title").toElement().text(); 00261 } 00262 00263 KURL KBookmark::url() const 00264 { 00265 return KURL(element.attribute("href"), 106); // Decode it from utf8 (106 is mib enum for utf8) 00266 } 00267 00268 QString KBookmark::icon() const 00269 { 00270 QString icon = element.attribute("icon"); 00271 if ( icon.isEmpty() ) 00272 // Default icon depends on URL for bookmarks, and is default directory 00273 // icon for groups. 00274 if ( isGroup() ) 00275 icon = "bookmark_folder"; 00276 else 00277 if ( isSeparator() ) 00278 icon = "eraser"; // whatever 00279 else 00280 icon = KMimeType::iconForURL( url() ); 00281 return icon; 00282 } 00283 00284 KBookmarkGroup KBookmark::parentGroup() const 00285 { 00286 return KBookmarkGroup( element.parentNode().toElement() ); 00287 } 00288 00289 KBookmarkGroup KBookmark::toGroup() const 00290 { 00291 Q_ASSERT( isGroup() ); 00292 return KBookmarkGroup(element); 00293 } 00294 00295 QString KBookmark::address() const 00296 { 00297 if ( element.tagName() == "xbel" ) 00298 return ""; // not QString::null ! 00299 else 00300 { 00301 // Use keditbookmarks's DEBUG_ADDRESSES flag to debug this code :) 00302 if (!hasParent()) 00303 { 00304 Q_ASSERT(hasParent()); 00305 return "ERROR"; // Avoid an infinite loop 00306 } 00307 KBookmarkGroup group = parentGroup(); 00308 QString parentAddress = group.address(); 00309 uint counter = 0; 00310 // Implementation note: we don't use QDomNode's childNode list because we 00311 // would have to skip "TEXT", which KBookmarkGroup already does for us. 00312 for ( KBookmark bk = group.first() ; !bk.isNull() ; bk = group.next(bk), ++counter ) 00313 { 00314 if ( bk.element == element ) 00315 return parentAddress + "/" + QString::number(counter); 00316 } 00317 kdWarning() << "KBookmark::address : this can't happen! " << parentAddress << endl; 00318 return "ERROR"; 00319 } 00320 } 00321 00322 KBookmark KBookmark::standaloneBookmark( const QString & text, const KURL & url, const QString & icon ) 00323 { 00324 QDomDocument doc("xbel"); 00325 QDomElement elem = doc.createElement("xbel"); 00326 doc.appendChild( elem ); 00327 KBookmarkGroup grp( elem ); 00328 grp.addBookmark( 0L, text, url, icon, false ); 00329 return grp.first(); 00330 } 00331 00332 static QDomNode cd_or_create(QDomNode node, QString name) 00333 { 00334 QDomNode subnode = node.namedItem(name); 00335 if (subnode.isNull()) 00336 { 00337 subnode = node.ownerDocument().createElement(name); 00338 node.appendChild(subnode); 00339 } 00340 return subnode; 00341 } 00342 00343 static QDomText get_or_create_text(QDomNode node) 00344 { 00345 QDomNode subnode = node.firstChild(); 00346 if (subnode.isNull()) 00347 { 00348 subnode = node.ownerDocument().createTextNode(""); 00349 node.appendChild(subnode); 00350 } 00351 return subnode.toText(); 00352 } 00353 00354 void KBookmark::updateAccessMetadata() 00355 { 00356 kdDebug(7043) << "KBookmark::updateAccessMetadata " << address() << " " << url().prettyURL() << endl; 00357 00358 QDomNode subnode = cd_or_create(internalElement(), "info"); 00359 subnode = cd_or_create(subnode, "metadata"); 00360 00361 uint timet = QDateTime::currentDateTime().toTime_t(); 00362 00363 QDomNode item = cd_or_create(subnode, "time_added"); 00364 QDomText domtext = get_or_create_text(item); 00365 if (domtext.data().isEmpty()) 00366 domtext.setData(QString::number(timet)); 00367 00368 item = cd_or_create(subnode, "time_visited"); 00369 domtext = get_or_create_text(item); 00370 domtext.setData(QString::number(timet)); 00371 00372 item = cd_or_create(subnode, "visit_count"); // TODO use spec'ed name 00373 domtext = get_or_create_text(item); 00374 QString countStr = domtext.data(); 00375 bool ok; 00376 int currentCount = countStr.toInt(&ok); 00377 if (!ok) 00378 currentCount = 0; 00379 currentCount++; 00380 domtext.setData(QString::number(currentCount)); 00381 00382 // TODO - for 3.3 - time_modified 00383 } 00384 00385 void KBookmarkGroupTraverser::traverse(const KBookmarkGroup &root) 00386 { 00387 // non-recursive bookmark iterator 00388 QValueStack<KBookmarkGroup> stack; 00389 stack.push(root); 00390 KBookmark bk = stack.top().first(); 00391 for (;;) { 00392 if (bk.isNull()) 00393 { 00394 if (stack.isEmpty()) 00395 return; 00396 if (stack.count() > 1) 00397 visitLeave(stack.top()); 00398 bk = stack.pop(); 00399 bk = stack.top().next(bk); 00400 if (bk.isNull()) 00401 continue; 00402 } 00403 00404 if (bk.isGroup()) 00405 { 00406 KBookmarkGroup gp = bk.toGroup(); 00407 visitEnter(gp); 00408 if (!gp.first().isNull()) 00409 { 00410 stack.push(gp); 00411 bk = gp.first(); 00412 continue; 00413 } 00414 // empty group 00415 visitLeave(gp); 00416 } 00417 else 00418 visit(bk); 00419 00420 bk = stack.top().next(bk); 00421 } 00422 00423 // never reached 00424 } 00425
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 20 09:49:12 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003