~ubuntu-branches/ubuntu/quantal/kde4libs/quantal

« back to all changes in this revision

Viewing changes to .pc/kubuntu_no_kbookmark_write_error.diff/kio/bookmarks/kbookmarkmanager.cc

  • Committer: Package Import Robot
  • Author(s): Felix Geyer, Philip Muškovac, Jonathan Thomas, Felix Geyer
  • Date: 2011-05-29 17:19:55 UTC
  • mfrom: (1.14.5 upstream) (0.1.19 sid)
  • Revision ID: package-import@ubuntu.com-20110529171955-nodep1593tuwyu6k
Tags: 4:4.6.3-1ubuntu1
[ Philip Muškovac]
* Drop kubuntu_83_fix_solid_network_status.diff
* Update Vcs links as the branch is owned by kubuntu-packagers now

[ Jonathan Thomas ]
* Drop kubuntu_06_user_disk_mounting. We no longer compile the hal
  backend, so this patch is useless.

[ Felix Geyer ]
* Merge from Debian unstable, remaining changes:
  - no build-dep on libaspell-dev
  - no build-dep on libfam-dev
  - kdelibs5-data: don't install kspell_aspell.desktop and
    usr/lib/kde4/kspell_aspell.so
  - kdelibs5-dev: don't install preparetips
  - Pass -DKDESU_USE_SUDO_DEFAULT=true to configure
  - dh_fixperms: exclude /usr/lib/kde4/libexec/fileshareset
  - set export KUBUNTU_DESKTOP_POT=kdelibs
  - don't apply use_dejavu_as_default_font.diff
  - don't apply kconf_update_migrate_from_kde3_icon_theme.diff
    - kdelibs5-data.install: drop usr/share/kde4/apps/kconf_update/kdeui.upd
  - don't build depend on libglu1-mesa-dev, not needed due to
    kubuntu_no_direct_gl_usage.diff
  - Add kdelibs5-data.links: link from /usr/share/doc/kde4 to kde for
    backwards compatible with old docs location
  - Keep the kdelibs5 transitional package
  - kdelibs5-dev.install: install ksambasharedata.h
  - kdelibs5-plugins: recommend ttf-dejavu-core instead of ttf-dejavu to save
    CD space.
* Add Breaks in addition to Replaces for moving files between packages.
* Drop no longer needed Breaks and Replaces.
* Completely drop kubuntu_51_launchpad_integration.diff and
  kubuntu_68_remove_applet_confirmation.diff.
  + Also drop the launchpad and kubuntu icons.
* Remove sequence numbers from kubuntu patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
 
2
// vim: set ts=4 sts=4 sw=4 et:
 
3
/* This file is part of the KDE libraries
 
4
   Copyright (C) 2000 David Faure <faure@kde.org>
 
5
   Copyright (C) 2003 Alexander Kellett <lypanov@kde.org>
 
6
   Copyright (C) 2008 Norbert Frese <nf2@scheinwelt.at>
 
7
 
 
8
   This library is free software; you can redistribute it and/or
 
9
   modify it under the terms of the GNU Library General Public
 
10
   License version 2 as published by the Free Software Foundation.
 
11
 
 
12
   This library is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
   Library General Public License for more details.
 
16
 
 
17
   You should have received a copy of the GNU Library General Public License
 
18
   along with this library; see the file COPYING.LIB.  If not, write to
 
19
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
20
   Boston, MA 02110-1301, USA.
 
21
*/
 
22
 
 
23
#include "kbookmarkmanager.h"
 
24
 
 
25
#include <QtCore/QFile>
 
26
#include <QtCore/QFileInfo>
 
27
#include <QtCore/QProcess>
 
28
#include <QtCore/QRegExp>
 
29
#include <QtCore/QTextStream>
 
30
#include <QtDBus/QtDBus>
 
31
#include <QtGui/QApplication>
 
32
 
 
33
#include <kconfiggroup.h>
 
34
#include <kdebug.h>
 
35
#include <kdirwatch.h>
 
36
#include <klocale.h>
 
37
#include <kmessagebox.h>
 
38
#include <ksavefile.h>
 
39
#include <kstandarddirs.h>
 
40
 
 
41
#include "kbookmarkmenu.h"
 
42
#include "kbookmarkmenu_p.h"
 
43
#include "kbookmarkimporter.h"
 
44
#include "kbookmarkdialog.h"
 
45
#include "kbookmarkmanageradaptor_p.h"
 
46
 
 
47
#define BOOKMARK_CHANGE_NOTIFY_INTERFACE "org.kde.KIO.KBookmarkManager"
 
48
 
 
49
class KBookmarkManagerList : public QList<KBookmarkManager *>
 
50
{
 
51
public:
 
52
    ~KBookmarkManagerList() {
 
53
        qDeleteAll( begin() , end() ); // auto-delete functionality
 
54
    }
 
55
 
 
56
    QReadWriteLock lock;
 
57
};
 
58
 
 
59
K_GLOBAL_STATIC(KBookmarkManagerList, s_pSelf)
 
60
 
 
61
class KBookmarkMap : private KBookmarkGroupTraverser {
 
62
public:
 
63
    KBookmarkMap() : m_mapNeedsUpdate(true) {}
 
64
    void setNeedsUpdate() { m_mapNeedsUpdate = true; }
 
65
    void update(KBookmarkManager*);
 
66
    QList<KBookmark> find( const QString &url ) const
 
67
    { return m_bk_map.value(url); }
 
68
private:
 
69
    virtual void visit(const KBookmark &);
 
70
    virtual void visitEnter(const KBookmarkGroup &) { ; }
 
71
    virtual void visitLeave(const KBookmarkGroup &) { ; }
 
72
private:
 
73
    typedef QList<KBookmark> KBookmarkList;
 
74
    QMap<QString, KBookmarkList> m_bk_map;
 
75
    bool m_mapNeedsUpdate;
 
76
};
 
77
 
 
78
void KBookmarkMap::update(KBookmarkManager *manager)
 
79
{
 
80
    if (m_mapNeedsUpdate) {
 
81
        m_mapNeedsUpdate = false;
 
82
 
 
83
        m_bk_map.clear();
 
84
        KBookmarkGroup root = manager->root();
 
85
        traverse(root);
 
86
    }
 
87
}
 
88
 
 
89
void KBookmarkMap::visit(const KBookmark &bk)
 
90
{
 
91
    if (!bk.isSeparator()) {
 
92
        // add bookmark to url map
 
93
        m_bk_map[bk.internalElement().attribute("href")].append(bk);
 
94
    }
 
95
}
 
96
 
 
97
// #########################
 
98
// KBookmarkManager::Private
 
99
class KBookmarkManager::Private
 
100
{
 
101
public:
 
102
    Private(bool bDocIsloaded, const QString &dbusObjectName = QString())
 
103
      : m_doc("xbel")
 
104
      , m_dbusObjectName(dbusObjectName)
 
105
      , m_docIsLoaded(bDocIsloaded)
 
106
      , m_update(false)
 
107
      , m_dialogAllowed(true)
 
108
      , m_dialogParent(0)
 
109
      , m_browserEditor(false)
 
110
      , m_typeExternal(false)
 
111
      , m_kDirWatch(0)
 
112
    {}
 
113
 
 
114
    ~Private() {
 
115
        delete m_kDirWatch;
 
116
    }
 
117
 
 
118
    mutable QDomDocument m_doc;
 
119
    mutable QDomDocument m_toolbarDoc;
 
120
    QString m_bookmarksFile;
 
121
    QString m_dbusObjectName;
 
122
    mutable bool m_docIsLoaded;
 
123
    bool m_update;
 
124
    bool m_dialogAllowed;
 
125
    QWidget *m_dialogParent;
 
126
 
 
127
    bool m_browserEditor;
 
128
    QString m_editorCaption;
 
129
 
 
130
    bool m_typeExternal;
 
131
    KDirWatch * m_kDirWatch;  // for external bookmark files
 
132
 
 
133
    KBookmarkMap m_map;
 
134
};
 
135
 
 
136
// ################
 
137
// KBookmarkManager
 
138
 
 
139
static KBookmarkManager* lookupExisting(const QString& bookmarksFile)
 
140
{
 
141
    for ( KBookmarkManagerList::ConstIterator bmit = s_pSelf->constBegin(), bmend = s_pSelf->constEnd();
 
142
          bmit != bmend; ++bmit ) {
 
143
        if ( (*bmit)->path() == bookmarksFile )
 
144
            return *bmit;
 
145
    }
 
146
    return 0;
 
147
}
 
148
 
 
149
 
 
150
KBookmarkManager* KBookmarkManager::managerForFile( const QString& bookmarksFile, const QString& dbusObjectName )
 
151
{
 
152
    KBookmarkManager* mgr(0);
 
153
    {
 
154
        QReadLocker readLock(&s_pSelf->lock);
 
155
        mgr = lookupExisting(bookmarksFile);
 
156
        if (mgr) {
 
157
            return mgr;
 
158
        }
 
159
    }
 
160
 
 
161
    QWriteLocker writeLock(&s_pSelf->lock);
 
162
    mgr = lookupExisting(bookmarksFile);
 
163
    if (mgr) {
 
164
        return mgr;
 
165
    }
 
166
 
 
167
    mgr = new KBookmarkManager( bookmarksFile, dbusObjectName );
 
168
    s_pSelf->append( mgr );
 
169
    return mgr;
 
170
}
 
171
 
 
172
KBookmarkManager* KBookmarkManager::managerForExternalFile( const QString& bookmarksFile )
 
173
{
 
174
    KBookmarkManager* mgr(0);
 
175
    {
 
176
        QReadLocker readLock(&s_pSelf->lock);
 
177
        mgr = lookupExisting(bookmarksFile);
 
178
        if (mgr) {
 
179
            return mgr;
 
180
        }
 
181
    }
 
182
 
 
183
    QWriteLocker writeLock(&s_pSelf->lock);
 
184
    mgr = lookupExisting(bookmarksFile);
 
185
    if (mgr) {
 
186
        return mgr;
 
187
    }
 
188
 
 
189
    mgr = new KBookmarkManager( bookmarksFile );
 
190
    s_pSelf->append( mgr );
 
191
    return mgr;
 
192
}
 
193
 
 
194
 
 
195
// principally used for filtered toolbars
 
196
KBookmarkManager* KBookmarkManager::createTempManager()
 
197
{
 
198
    KBookmarkManager* mgr = new KBookmarkManager();
 
199
    s_pSelf->append( mgr );
 
200
    return mgr;
 
201
}
 
202
 
 
203
#define PI_DATA "version=\"1.0\" encoding=\"UTF-8\""
 
204
 
 
205
static QDomElement createXbelTopLevelElement(QDomDocument & doc)
 
206
{
 
207
    QDomElement topLevel = doc.createElement("xbel");
 
208
    topLevel.setAttribute("xmlns:mime", "http://www.freedesktop.org/standards/shared-mime-info");
 
209
    topLevel.setAttribute("xmlns:bookmark", "http://www.freedesktop.org/standards/desktop-bookmarks");
 
210
    topLevel.setAttribute("xmlns:kdepriv", "http://www.kde.org/kdepriv");
 
211
    doc.appendChild( topLevel );
 
212
    doc.insertBefore( doc.createProcessingInstruction( "xml", PI_DATA), topLevel );
 
213
    return topLevel;
 
214
}
 
215
 
 
216
KBookmarkManager::KBookmarkManager( const QString & bookmarksFile, const QString & dbusObjectName)
 
217
 : d(new Private(false, dbusObjectName))
 
218
{
 
219
    if(dbusObjectName.isNull()) // get dbusObjectName from file
 
220
        if ( QFile::exists(d->m_bookmarksFile) )
 
221
            parse(); //sets d->m_dbusObjectName
 
222
 
 
223
    init( "/KBookmarkManager/"+d->m_dbusObjectName );
 
224
 
 
225
    d->m_update = true;
 
226
 
 
227
    Q_ASSERT( !bookmarksFile.isEmpty() );
 
228
    d->m_bookmarksFile = bookmarksFile;
 
229
 
 
230
    if ( !QFile::exists(d->m_bookmarksFile) )
 
231
    {
 
232
        QDomElement topLevel = createXbelTopLevelElement(d->m_doc);
 
233
        topLevel.setAttribute("dbusName", dbusObjectName);
 
234
        d->m_docIsLoaded = true;
 
235
    }
 
236
}
 
237
 
 
238
KBookmarkManager::KBookmarkManager(const QString & bookmarksFile)
 
239
    : d(new Private(false))
 
240
{
 
241
    // use KDirWatch to monitor this bookmarks file
 
242
    d->m_typeExternal = true;
 
243
    d->m_update = true;
 
244
 
 
245
    Q_ASSERT( !bookmarksFile.isEmpty() );
 
246
    d->m_bookmarksFile = bookmarksFile;
 
247
 
 
248
    if ( !QFile::exists(d->m_bookmarksFile) )
 
249
    {
 
250
        createXbelTopLevelElement(d->m_doc);
 
251
    }
 
252
    else
 
253
    {
 
254
        parse();
 
255
    }
 
256
    d->m_docIsLoaded = true;
 
257
 
 
258
    // start KDirWatch
 
259
    d->m_kDirWatch = new KDirWatch;
 
260
    d->m_kDirWatch->addFile(d->m_bookmarksFile);
 
261
    QObject::connect( d->m_kDirWatch, SIGNAL(dirty(const QString&)),
 
262
            this, SLOT(slotFileChanged(const QString&)));
 
263
    QObject::connect( d->m_kDirWatch, SIGNAL(created(const QString&)),
 
264
            this, SLOT(slotFileChanged(const QString&)));
 
265
    QObject::connect( d->m_kDirWatch, SIGNAL(deleted(const QString&)),
 
266
            this, SLOT(slotFileChanged(const QString&)));
 
267
    kDebug(7043) << "starting KDirWatch for " << d->m_bookmarksFile;
 
268
}
 
269
 
 
270
KBookmarkManager::KBookmarkManager( )
 
271
    : d(new Private(true))
 
272
{
 
273
    init( "/KBookmarkManager/generated" );
 
274
    d->m_update = false; // TODO - make it read/write
 
275
 
 
276
    createXbelTopLevelElement(d->m_doc);
 
277
}
 
278
 
 
279
void KBookmarkManager::init( const QString& dbusPath )
 
280
{
 
281
    // A KBookmarkManager without a dbus name is a temporary one, like those used by importers;
 
282
    // no need to register them to dbus
 
283
    if ( dbusPath != "/KBookmarkManager/" && dbusPath != "/KBookmarkManager/generated")
 
284
    {
 
285
        new KBookmarkManagerAdaptor(this);
 
286
        QDBusConnection::sessionBus().registerObject( dbusPath, this );
 
287
 
 
288
        QDBusConnection::sessionBus().connect(QString(), dbusPath, BOOKMARK_CHANGE_NOTIFY_INTERFACE,
 
289
                                    "bookmarksChanged", this, SLOT(notifyChanged(QString,QDBusMessage)));
 
290
        QDBusConnection::sessionBus().connect(QString(), dbusPath, BOOKMARK_CHANGE_NOTIFY_INTERFACE,
 
291
                                    "bookmarkConfigChanged", this, SLOT(notifyConfigChanged()));
 
292
    }
 
293
}
 
294
 
 
295
void KBookmarkManager::slotFileChanged(const QString& path)
 
296
{
 
297
    if (path == d->m_bookmarksFile)
 
298
    {
 
299
        kDebug(7043) << "file changed (KDirWatch) " << path ;
 
300
        // Reparse
 
301
        parse();
 
302
        // Tell our GUI
 
303
        // (emit where group is "" to directly mark the root menu as dirty)
 
304
        emit changed( "", QString() );
 
305
    }
 
306
}
 
307
 
 
308
KBookmarkManager::~KBookmarkManager()
 
309
{
 
310
    if (!s_pSelf.isDestroyed()) {
 
311
        s_pSelf->removeAll(this);
 
312
    }
 
313
 
 
314
    delete d;
 
315
}
 
316
 
 
317
bool KBookmarkManager::autoErrorHandlingEnabled() const
 
318
{
 
319
    return d->m_dialogAllowed;
 
320
}
 
321
 
 
322
void KBookmarkManager::setAutoErrorHandlingEnabled( bool enable, QWidget *parent )
 
323
{
 
324
    d->m_dialogAllowed = enable;
 
325
    d->m_dialogParent = parent;
 
326
}
 
327
 
 
328
void KBookmarkManager::setUpdate( bool update )
 
329
{
 
330
    d->m_update = update;
 
331
}
 
332
 
 
333
QDomDocument KBookmarkManager::internalDocument() const
 
334
{
 
335
    if(!d->m_docIsLoaded)
 
336
    {
 
337
        parse();
 
338
        d->m_toolbarDoc.clear();
 
339
    }
 
340
    return d->m_doc;
 
341
}
 
342
 
 
343
 
 
344
void KBookmarkManager::parse() const
 
345
{
 
346
    d->m_docIsLoaded = true;
 
347
    //kDebug(7043) << "KBookmarkManager::parse " << d->m_bookmarksFile;
 
348
    QFile file( d->m_bookmarksFile );
 
349
    if ( !file.open( QIODevice::ReadOnly ) )
 
350
    {
 
351
        kWarning() << "Can't open " << d->m_bookmarksFile;
 
352
        return;
 
353
    }
 
354
    d->m_doc = QDomDocument("xbel");
 
355
    d->m_doc.setContent( &file );
 
356
 
 
357
    if ( d->m_doc.documentElement().isNull() )
 
358
    {
 
359
        kWarning() << "KBookmarkManager::parse : main tag is missing, creating default " << d->m_bookmarksFile;
 
360
        QDomElement element = d->m_doc.createElement("xbel");
 
361
        d->m_doc.appendChild(element);
 
362
    }
 
363
 
 
364
    QDomElement docElem = d->m_doc.documentElement();
 
365
 
 
366
    QString mainTag = docElem.tagName();
 
367
    if ( mainTag != "xbel" )
 
368
        kWarning() << "KBookmarkManager::parse : unknown main tag " << mainTag;
 
369
 
 
370
    if(d->m_dbusObjectName.isNull())
 
371
    {
 
372
        d->m_dbusObjectName = docElem.attribute("dbusName");
 
373
    }
 
374
    else if(docElem.attribute("dbusName") != d->m_dbusObjectName)
 
375
    {
 
376
        docElem.setAttribute("dbusName", d->m_dbusObjectName);
 
377
        save();
 
378
    }
 
379
 
 
380
    QDomNode n = d->m_doc.documentElement().previousSibling();
 
381
    if ( n.isProcessingInstruction() )
 
382
    {
 
383
        QDomProcessingInstruction pi = n.toProcessingInstruction();
 
384
        pi.parentNode().removeChild(pi);
 
385
    }
 
386
 
 
387
    QDomProcessingInstruction pi;
 
388
    pi = d->m_doc.createProcessingInstruction( "xml", PI_DATA );
 
389
    d->m_doc.insertBefore( pi, docElem );
 
390
 
 
391
    file.close();
 
392
 
 
393
    d->m_map.setNeedsUpdate();
 
394
}
 
395
 
 
396
bool KBookmarkManager::save( bool toolbarCache ) const
 
397
{
 
398
    return saveAs( d->m_bookmarksFile, toolbarCache );
 
399
}
 
400
 
 
401
bool KBookmarkManager::saveAs( const QString & filename, bool toolbarCache ) const
 
402
{
 
403
    kDebug(7043) << "KBookmarkManager::save " << filename;
 
404
 
 
405
    // Save the bookmark toolbar folder for quick loading
 
406
    // but only when it will actually make things quicker
 
407
    const QString cacheFilename = filename + QLatin1String(".tbcache");
 
408
    if(toolbarCache && !root().isToolbarGroup())
 
409
    {
 
410
        KSaveFile cacheFile( cacheFilename );
 
411
        if ( cacheFile.open() )
 
412
        {
 
413
            QString str;
 
414
            QTextStream stream(&str, QIODevice::WriteOnly);
 
415
            stream << root().findToolbar();
 
416
            const QByteArray cstr = str.toUtf8();
 
417
            cacheFile.write( cstr.data(), cstr.length() );
 
418
            cacheFile.finalize();
 
419
        }
 
420
    }
 
421
    else // remove any (now) stale cache
 
422
    {
 
423
        QFile::remove( cacheFilename );
 
424
    }
 
425
 
 
426
    KSaveFile file( filename );
 
427
    if ( file.open() )
 
428
    {
 
429
        file.simpleBackupFile( file.fileName(), QString(), ".bak" );
 
430
        QTextStream stream(&file);
 
431
        stream.setCodec( QTextCodec::codecForName( "UTF-8" ) );
 
432
        stream << internalDocument().toString();
 
433
        stream.flush();
 
434
        if ( file.finalize() )
 
435
        {
 
436
            return true;
 
437
        }
 
438
    }
 
439
 
 
440
    static int hadSaveError = false;
 
441
    file.abort();
 
442
    if ( !hadSaveError ) {
 
443
        QString err = i18n("Unable to save bookmarks in %1. Reported error was: %2. "
 
444
                             "This error message will only be shown once. The cause "
 
445
                             "of the error needs to be fixed as quickly as possible, "
 
446
                             "which is most likely a full hard drive.",
 
447
                         filename, file.errorString());
 
448
 
 
449
        if (d->m_dialogAllowed && qApp->type() != QApplication::Tty && QThread::currentThread() == qApp->thread())
 
450
            KMessageBox::error( QApplication::activeWindow(), err );
 
451
 
 
452
        kError() << QString("Unable to save bookmarks in %1. File reported the following error-code: %2.").arg(filename).arg(file.error());
 
453
        emit const_cast<KBookmarkManager*>(this)->error(err);
 
454
    }
 
455
    hadSaveError = true;
 
456
    return false;
 
457
}
 
458
 
 
459
QString KBookmarkManager::path() const
 
460
{
 
461
    return d->m_bookmarksFile;
 
462
}
 
463
 
 
464
KBookmarkGroup KBookmarkManager::root() const
 
465
{
 
466
    return KBookmarkGroup(internalDocument().documentElement());
 
467
}
 
468
 
 
469
KBookmarkGroup KBookmarkManager::toolbar()
 
470
{
 
471
    kDebug(7043) << "KBookmarkManager::toolbar begin";
 
472
    // Only try to read from a toolbar cache if the full document isn't loaded
 
473
    if(!d->m_docIsLoaded)
 
474
    {
 
475
        kDebug(7043) << "KBookmarkManager::toolbar trying cache";
 
476
        const QString cacheFilename = d->m_bookmarksFile + QLatin1String(".tbcache");
 
477
        QFileInfo bmInfo(d->m_bookmarksFile);
 
478
        QFileInfo cacheInfo(cacheFilename);
 
479
        if (d->m_toolbarDoc.isNull() &&
 
480
            QFile::exists(cacheFilename) &&
 
481
            bmInfo.lastModified() < cacheInfo.lastModified())
 
482
        {
 
483
            kDebug(7043) << "KBookmarkManager::toolbar reading file";
 
484
            QFile file( cacheFilename );
 
485
 
 
486
            if ( file.open( QIODevice::ReadOnly ) )
 
487
            {
 
488
                d->m_toolbarDoc = QDomDocument("cache");
 
489
                d->m_toolbarDoc.setContent( &file );
 
490
                kDebug(7043) << "KBookmarkManager::toolbar opened";
 
491
            }
 
492
        }
 
493
        if (!d->m_toolbarDoc.isNull())
 
494
        {
 
495
            kDebug(7043) << "KBookmarkManager::toolbar returning element";
 
496
            QDomElement elem = d->m_toolbarDoc.firstChild().toElement();
 
497
            return KBookmarkGroup(elem);
 
498
        }
 
499
    }
 
500
 
 
501
    // Fallback to the normal way if there is no cache or if the bookmark file
 
502
    // is already loaded
 
503
    QDomElement elem = root().findToolbar();
 
504
    if (elem.isNull())
 
505
        return root(); // Root is the bookmark toolbar if none has been set.
 
506
    else
 
507
        return KBookmarkGroup(root().findToolbar());
 
508
}
 
509
 
 
510
KBookmark KBookmarkManager::findByAddress( const QString & address )
 
511
{
 
512
    //kDebug(7043) << "KBookmarkManager::findByAddress " << address;
 
513
    KBookmark result = root();
 
514
    // The address is something like /5/10/2+
 
515
    const QStringList addresses = address.split(QRegExp("[/+]"),QString::SkipEmptyParts);
 
516
    // kWarning() << addresses.join(",");
 
517
    for ( QStringList::const_iterator it = addresses.begin() ; it != addresses.end() ; )
 
518
    {
 
519
       bool append = ((*it) == "+");
 
520
       uint number = (*it).toUInt();
 
521
       Q_ASSERT(result.isGroup());
 
522
       KBookmarkGroup group = result.toGroup();
 
523
       KBookmark bk = group.first(), lbk = bk; // last non-null bookmark
 
524
       for ( uint i = 0 ; ( (i<number) || append ) && !bk.isNull() ; ++i ) {
 
525
           lbk = bk;
 
526
           bk = group.next(bk);
 
527
         //kWarning() << i;
 
528
       }
 
529
       it++;
 
530
       //kWarning() << "found section";
 
531
       result = bk;
 
532
    }
 
533
    if (result.isNull()) {
 
534
       kWarning() << "KBookmarkManager::findByAddress: couldn't find item " << address;
 
535
    }
 
536
    //kWarning() << "found " << result.address();
 
537
    return result;
 
538
 }
 
539
 
 
540
void KBookmarkManager::emitChanged()
 
541
{
 
542
    emitChanged(root());
 
543
}
 
544
 
 
545
 
 
546
void KBookmarkManager::emitChanged( const KBookmarkGroup & group )
 
547
{
 
548
    (void) save(); // KDE5 TODO: emitChanged should return a bool? Maybe rename it to saveAndEmitChanged?
 
549
 
 
550
    // Tell the other processes too
 
551
    // kDebug(7043) << "KBookmarkManager::emitChanged : broadcasting change " << group.address();
 
552
 
 
553
    emit bookmarksChanged(group.address());
 
554
 
 
555
    // We do get our own broadcast, so no need for this anymore
 
556
    //emit changed( group );
 
557
}
 
558
 
 
559
void KBookmarkManager::emitConfigChanged()
 
560
{
 
561
    emit bookmarkConfigChanged();
 
562
}
 
563
 
 
564
void KBookmarkManager::notifyCompleteChange( const QString &caller ) // DBUS call
 
565
{
 
566
    if (!d->m_update)
 
567
        return;
 
568
 
 
569
    kDebug(7043) << "KBookmarkManager::notifyCompleteChange";
 
570
    // The bk editor tells us we should reload everything
 
571
    // Reparse
 
572
    parse();
 
573
    // Tell our GUI
 
574
    // (emit where group is "" to directly mark the root menu as dirty)
 
575
    emit changed( "", caller );
 
576
}
 
577
 
 
578
void KBookmarkManager::notifyConfigChanged() // DBUS call
 
579
{
 
580
    kDebug() << "reloaded bookmark config!";
 
581
    KBookmarkSettings::self()->readSettings();
 
582
    parse(); // reload, and thusly recreate the menus
 
583
    emit configChanged();
 
584
}
 
585
 
 
586
void KBookmarkManager::notifyChanged( const QString &groupAddress, const QDBusMessage &msg ) // DBUS call
 
587
{
 
588
    kDebug() << "KBookmarkManager::notifyChanged ( "<<groupAddress<<")";
 
589
    if (!d->m_update)
 
590
        return;
 
591
 
 
592
    // Reparse (the whole file, no other choice)
 
593
    // if someone else notified us
 
594
    if (msg.service() != QDBusConnection::sessionBus().baseService())
 
595
       parse();
 
596
 
 
597
    //kDebug(7043) << "KBookmarkManager::notifyChanged " << groupAddress;
 
598
    //KBookmarkGroup group = findByAddress( groupAddress ).toGroup();
 
599
    //Q_ASSERT(!group.isNull());
 
600
    emit changed( groupAddress, QString() );
 
601
}
 
602
 
 
603
void KBookmarkManager::setEditorOptions( const QString& caption, bool browser )
 
604
{
 
605
    d->m_editorCaption = caption;
 
606
    d->m_browserEditor = browser;
 
607
}
 
608
 
 
609
void KBookmarkManager::slotEditBookmarks()
 
610
{
 
611
    QStringList args;
 
612
    if ( !d->m_editorCaption.isEmpty() )
 
613
       args << QLatin1String("--customcaption") << d->m_editorCaption;
 
614
    if ( !d->m_browserEditor )
 
615
       args << QLatin1String("--nobrowser");
 
616
    if( !d->m_dbusObjectName.isEmpty() )
 
617
      args << QLatin1String("--dbusObjectName") << d->m_dbusObjectName;
 
618
    args << d->m_bookmarksFile;
 
619
    QProcess::startDetached("keditbookmarks", args);
 
620
}
 
621
 
 
622
void KBookmarkManager::slotEditBookmarksAtAddress( const QString& address )
 
623
{
 
624
    QStringList args;
 
625
    if ( !d->m_editorCaption.isEmpty() )
 
626
       args << QLatin1String("--customcaption") << d->m_editorCaption;
 
627
    if ( !d->m_browserEditor )
 
628
       args << QLatin1String("--nobrowser");
 
629
    if( !d->m_dbusObjectName.isEmpty() )
 
630
      args << QLatin1String("--dbusObjectName") << d->m_dbusObjectName;
 
631
    args << QLatin1String("--address") << address
 
632
         << d->m_bookmarksFile;
 
633
    QProcess::startDetached("keditbookmarks", args);
 
634
}
 
635
 
 
636
///////
 
637
bool KBookmarkManager::updateAccessMetadata( const QString & url )
 
638
{
 
639
    d->m_map.update(this);
 
640
    QList<KBookmark> list = d->m_map.find(url);
 
641
    if ( list.count() == 0 )
 
642
        return false;
 
643
 
 
644
    for ( QList<KBookmark>::iterator it = list.begin();
 
645
          it != list.end(); ++it )
 
646
        (*it).updateAccessMetadata();
 
647
 
 
648
    return true;
 
649
}
 
650
 
 
651
void KBookmarkManager::updateFavicon( const QString &url, const QString &faviconurl )
 
652
{
 
653
    d->m_map.update(this);
 
654
    QList<KBookmark> list = d->m_map.find(url);
 
655
    for ( QList<KBookmark>::iterator it = list.begin();
 
656
          it != list.end(); ++it )
 
657
    {
 
658
        // TODO - update favicon data based on faviconurl
 
659
        //        but only when the previously used icon
 
660
        //        isn't a manually set one.
 
661
    }
 
662
}
 
663
 
 
664
KBookmarkManager* KBookmarkManager::userBookmarksManager()
 
665
{
 
666
     const QString bookmarksFile = KStandardDirs::locateLocal("data", QString::fromLatin1("konqueror/bookmarks.xml"));
 
667
     KBookmarkManager* bookmarkManager = KBookmarkManager::managerForFile( bookmarksFile, "konqueror" );
 
668
     bookmarkManager->setEditorOptions(KGlobal::caption(), true);
 
669
     return bookmarkManager;
 
670
}
 
671
 
 
672
KBookmarkSettings* KBookmarkSettings::s_self = 0;
 
673
 
 
674
void KBookmarkSettings::readSettings()
 
675
{
 
676
   KConfig config("kbookmarkrc", KConfig::NoGlobals);
 
677
   KConfigGroup cg(&config, "Bookmarks");
 
678
 
 
679
   // add bookmark dialog usage - no reparse
 
680
   s_self->m_advancedaddbookmark = cg.readEntry("AdvancedAddBookmarkDialog", false);
 
681
 
 
682
   // this one alters the menu, therefore it needs a reparse
 
683
   s_self->m_contextmenu = cg.readEntry("ContextMenuActions", true);
 
684
}
 
685
 
 
686
KBookmarkSettings *KBookmarkSettings::self()
 
687
{
 
688
   if (!s_self)
 
689
   {
 
690
      s_self = new KBookmarkSettings;
 
691
      readSettings();
 
692
   }
 
693
   return s_self;
 
694
}
 
695
 
 
696
/////////// KBookmarkOwner
 
697
 
 
698
bool KBookmarkOwner::enableOption(BookmarkOption action) const
 
699
{
 
700
    if(action == ShowAddBookmark)
 
701
        return true;
 
702
    if(action == ShowEditBookmark)
 
703
        return true;
 
704
    return false;
 
705
}
 
706
 
 
707
KBookmarkDialog * KBookmarkOwner::bookmarkDialog(KBookmarkManager * mgr, QWidget * parent)
 
708
{
 
709
    return new KBookmarkDialog(mgr, parent);
 
710
}
 
711
 
 
712
void KBookmarkOwner::openFolderinTabs(const KBookmarkGroup &)
 
713
{
 
714
 
 
715
}
 
716
 
 
717
#include "kbookmarkmanager.moc"