00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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";
00055 }
00056
00057
00058
static QDomElement firstElement(
QDomNode n)
00059 {
00060
while(!n.isNull() && !n.isElement())
00061 n = n.nextSibling();
00062
return n.toElement();
00063 }
00064
00065
00066
static QDomElement lastElement(
QDomNode n)
00067 {
00068
while(!n.isNull() && !n.isElement())
00069 n = n.previousSibling();
00070
return n.toElement();
00071 }
00072
00073 KBookmark
KBookmarkGroup::first()
const
00074
{
00075
return KBookmark( nextKnownTag( firstElement(element.firstChild()),
true ) );
00076 }
00077
00078 KBookmark
KBookmarkGroup::previous(
const KBookmark & current )
const
00079
{
00080
return KBookmark( nextKnownTag( lastElement(current.element.previousSibling()),
false ) );
00081 }
00082
00083 KBookmark
KBookmarkGroup::next(
const KBookmark & current )
const
00084
{
00085
return KBookmark( nextKnownTag( firstElement(current.element.nextSibling()),
true ) );
00086 }
00087
00088
00089
00090
QDomElement KBookmarkGroup::nextKnownTag(
QDomElement start,
bool goNext )
const
00091
{
00092
static const QString & bookmark =
KGlobal::staticQString(
"bookmark");
00093
static const QString & folder =
KGlobal::staticQString(
"folder");
00094
static const QString & separator =
KGlobal::staticQString(
"separator");
00095
00096
for(
QDomNode n = start; !n.isNull(); )
00097 {
00098
QDomElement elem = n.toElement();
00099
QString tag = elem.tagName();
00100
if (tag == folder || tag == bookmark || tag == separator)
00101
return elem;
00102
if (goNext)
00103 n = n.nextSibling();
00104
else
00105 n = n.previousSibling();
00106 }
00107
return QDomElement();
00108 }
00109
00110 KBookmarkGroup KBookmarkGroup::createNewFolder(
KBookmarkManager* mgr,
const QString & text,
bool emitSignal )
00111 {
00112
QString txt( text );
00113
if ( text.isEmpty() )
00114 {
00115
bool ok;
00116
QString caption = parentGroup().fullText().isEmpty() ?
00117 i18n(
"Create New Bookmark Folder" ) :
00118 i18n(
"Create New Bookmark Folder in %1" )
00119 .arg( parentGroup().text() );
00120 txt =
KInputDialog::getText( caption, i18n(
"New folder:" ),
00121 QString::null, &ok );
00122
if ( !ok )
00123
return KBookmarkGroup();
00124 }
00125
00126 Q_ASSERT(!element.isNull());
00127
QDomDocument doc = element.ownerDocument();
00128
QDomElement groupElem = doc.createElement(
"folder" );
00129 element.appendChild( groupElem );
00130
QDomElement textElem = doc.createElement(
"title" );
00131 groupElem.appendChild( textElem );
00132 textElem.appendChild( doc.createTextNode( txt ) );
00133
00134
KBookmarkGroup grp(groupElem);
00135
00136
if (emitSignal)
00137 emit mgr->
notifier().
createdNewFolder(
00138 mgr->
path(), grp.fullText(),
00139 grp.address() );
00140
00141
return grp;
00142
00143 }
00144
00145 KBookmark
KBookmarkGroup::createNewSeparator()
00146 {
00147 Q_ASSERT(!element.isNull());
00148
QDomDocument doc = element.ownerDocument();
00149 Q_ASSERT(!doc.isNull());
00150
QDomElement sepElem = doc.createElement(
"separator" );
00151 element.appendChild( sepElem );
00152
return KBookmark(sepElem);
00153 }
00154
00155 bool KBookmarkGroup::moveItem(
const KBookmark & item,
const KBookmark & after )
00156 {
00157
QDomNode n;
00158
if ( !after.isNull() )
00159 n = element.insertAfter( item.element, after.element );
00160
else
00161 {
00162
if ( element.firstChild().isNull() )
00163 n = element.insertBefore( item.element,
QDomElement() );
00164
00165
00166
QDomElement firstChild = nextKnownTag(element.firstChild().toElement(),
true);
00167
if ( !firstChild.isNull() )
00168 n = element.insertBefore( item.element, firstChild );
00169
else
00170 {
00171
00172 n = element.appendChild( item.element );
00173 }
00174 }
00175
return (!n.isNull());
00176 }
00177
00178 KBookmark
KBookmarkGroup::addBookmark(
KBookmarkManager* mgr,
const QString & text,
const KURL & url,
const QString & icon,
bool emitSignal )
00179 {
00180
00181
QDomDocument doc = element.ownerDocument();
00182
QDomElement elem = doc.createElement(
"bookmark" );
00183 element.appendChild( elem );
00184 elem.setAttribute(
"href", url.
url( 0, 106 ) );
00185
QString _icon = icon;
00186
if ( _icon.isEmpty() )
00187 _icon =
KMimeType::iconForURL( url );
00188 elem.setAttribute(
"icon", _icon );
00189
00190
QDomElement textElem = doc.createElement(
"title" );
00191 elem.appendChild( textElem );
00192 textElem.appendChild( doc.createTextNode( text ) );
00193
00194 KBookmark bk(elem);
00195
00196
if (emitSignal)
00197 emit mgr->
notifier().addedBookmark(
00198 mgr->
path(), url.
url(),
00199 text, bk.address(), icon );
00200
00201
return bk;
00202 }
00203
00204 void KBookmarkGroup::deleteBookmark( KBookmark bk )
00205 {
00206 element.removeChild( bk.element );
00207 }
00208
00209 bool KBookmarkGroup::isToolbarGroup()
const
00210
{
00211
return ( element.attribute(
"toolbar") ==
"yes" );
00212 }
00213
00214
QDomElement KBookmarkGroup::findToolbar()
const
00215
{
00216
if ( element.attribute(
"toolbar") ==
"yes" )
00217
return element;
00218
for (
QDomNode n = element.firstChild(); !n.isNull() ; n = n.nextSibling() )
00219 {
00220
QDomElement e = n.toElement();
00221
00222
if ( e.tagName() ==
"folder" )
00223 {
00224
if ( e.attribute(
"toolbar") ==
"yes" )
00225
return e;
00226
else
00227 {
00228
QDomElement result =
KBookmarkGroup(e).findToolbar();
00229
if (!result.isNull())
00230
return result;
00231 }
00232 }
00233 }
00234
return QDomElement();
00235 }
00236
00237 QValueList<KURL> KBookmarkGroup::groupUrlList()
const
00238
{
00239
QValueList<KURL> urlList;
00240
for ( KBookmark bm =
first(); !bm.isNull(); bm =
next(bm) )
00241 {
00242
if ( bm.isSeparator() || bm.isGroup() )
00243
continue;
00244 urlList << bm.url();
00245 }
00246
return urlList;
00247 }
00248
00250
00251
bool KBookmark::isGroup()
const
00252
{
00253
QString tag = element.tagName();
00254
return ( tag ==
"folder"
00255 || tag ==
"xbel" );
00256 }
00257
00258
bool KBookmark::isSeparator()
const
00259
{
00260
return (element.tagName() ==
"separator");
00261 }
00262
00263
bool KBookmark::hasParent()
const
00264
{
00265
QDomElement parent = element.parentNode().toElement();
00266
return !parent.isNull();
00267 }
00268
00269
QString KBookmark::text()
const
00270
{
00271
return KStringHandler::csqueeze( fullText() );
00272 }
00273
00274
QString KBookmark::fullText()
const
00275
{
00276
if (isSeparator())
00277
return i18n(
"--- separator ---");
00278
00279
return element.namedItem(
"title").toElement().text();
00280 }
00281
00282
KURL KBookmark::url()
const
00283
{
00284
return KURL(element.attribute(
"href"), 106);
00285 }
00286
00287
QString KBookmark::icon()
const
00288
{
00289
QString icon = element.attribute(
"icon");
00290
if ( icon.isEmpty() )
00291
00292
00293
if ( isGroup() )
00294 icon =
"bookmark_folder";
00295
else
00296
if ( isSeparator() )
00297 icon =
"eraser";
00298
else
00299 icon =
KMimeType::iconForURL( url() );
00300
return icon;
00301 }
00302
00303
KBookmarkGroup KBookmark::parentGroup()
const
00304
{
00305
return KBookmarkGroup( element.parentNode().toElement() );
00306 }
00307
00308
KBookmarkGroup KBookmark::toGroup()
const
00309
{
00310 Q_ASSERT( isGroup() );
00311
return KBookmarkGroup(element);
00312 }
00313
00314
QString KBookmark::address()
const
00315
{
00316
if ( element.tagName() ==
"xbel" )
00317
return "";
00318
else
00319 {
00320
00321
if (!hasParent())
00322 {
00323 Q_ASSERT(hasParent());
00324
return "ERROR";
00325 }
00326
KBookmarkGroup group = parentGroup();
00327
QString parentAddress = group.address();
00328 uint counter = 0;
00329
00330
00331
for ( KBookmark bk = group.
first() ; !bk.isNull() ; bk = group.
next(bk), ++counter )
00332 {
00333
if ( bk.element == element )
00334
return parentAddress +
"/" + QString::number(counter);
00335 }
00336
kdWarning() <<
"KBookmark::address : this can't happen! " << parentAddress <<
endl;
00337
return "ERROR";
00338 }
00339 }
00340
00341 KBookmark KBookmark::standaloneBookmark(
const QString & text,
const KURL & url,
const QString & icon )
00342 {
00343
QDomDocument doc(
"xbel");
00344
QDomElement elem = doc.createElement(
"xbel");
00345 doc.appendChild( elem );
00346
KBookmarkGroup grp( elem );
00347 grp.addBookmark( 0L, text, url, icon,
false );
00348
return grp.first();
00349 }
00350
00351
static QDomNode cd_or_create(
QDomNode node,
QString name)
00352 {
00353
QDomNode subnode = node.namedItem(name);
00354
if (subnode.isNull())
00355 {
00356 subnode = node.ownerDocument().createElement(name);
00357 node.appendChild(subnode);
00358 }
00359
return subnode;
00360 }
00361
00362
static QDomText get_or_create_text(
QDomNode node)
00363 {
00364
QDomNode subnode = node.firstChild();
00365
if (subnode.isNull())
00366 {
00367 subnode = node.ownerDocument().createTextNode(
"");
00368 node.appendChild(subnode);
00369 }
00370
return subnode.toText();
00371 }
00372
00373
void KBookmark::updateAccessMetadata()
00374 {
00375
kdDebug(7043) <<
"KBookmark::updateAccessMetadata " << address() <<
" " << url().prettyURL() <<
endl;
00376
00377
QDomNode subnode = cd_or_create(internalElement(),
"info");
00378 subnode = cd_or_create(subnode,
"metadata");
00379
00380 uint timet = QDateTime::currentDateTime().toTime_t();
00381
00382
QDomNode item = cd_or_create(subnode,
"time_added");
00383
QDomText domtext = get_or_create_text(item);
00384
if (domtext.data().isEmpty())
00385 domtext.setData(QString::number(timet));
00386
00387 item = cd_or_create(subnode,
"time_visited");
00388 domtext = get_or_create_text(item);
00389 domtext.setData(QString::number(timet));
00390
00391 item = cd_or_create(subnode,
"visit_count");
00392 domtext = get_or_create_text(item);
00393
QString countStr = domtext.data();
00394
bool ok;
00395
int currentCount = countStr.toInt(&ok);
00396
if (!ok)
00397 currentCount = 0;
00398 currentCount++;
00399 domtext.setData(QString::number(currentCount));
00400
00401
00402 }
00403
00404
void KBookmarkGroupTraverser::traverse(
const KBookmarkGroup &root)
00405 {
00406
00407
QValueStack<KBookmarkGroup> stack;
00408 stack.push(root);
00409 KBookmark bk = stack.top().first();
00410
for (;;) {
00411
if (bk.isNull())
00412 {
00413
if (stack.isEmpty())
00414
return;
00415
if (stack.count() > 1)
00416 visitLeave(stack.top());
00417 bk = stack.pop();
00418 bk = stack.top().next(bk);
00419
if (bk.isNull())
00420
continue;
00421 }
00422
00423
if (bk.isGroup())
00424 {
00425
KBookmarkGroup gp = bk.toGroup();
00426 visitEnter(gp);
00427
if (!gp.
first().isNull())
00428 {
00429 stack.push(gp);
00430 bk = gp.
first();
00431
continue;
00432 }
00433
00434 visitLeave(gp);
00435 }
00436
else
00437 visit(bk);
00438
00439 bk = stack.top().next(bk);
00440 }
00441
00442
00443 }
00444