[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: Re: [PATCH] KFilePlacesModel : separate storage for custom items
From: nf2 <nf2 () scheinwelt ! at>
Date: 2008-04-13 2:27:58
Message-ID: 48016FAE.4050706 () scheinwelt ! at
[Download RAW message or body]
nf2 wrote:
> Kevin Ottens wrote:
>> Le Thursday 27 March 2008, nf2 a écrit :
>>
>>> That's intentional. They have to be a 1:1copy (otherwise my comparator
>>> won't work and we might run into an endless synchronization ping pong).
>>> According to the xbel spec it's perfectly ok to have such private
>>> metadata (that's the whole point of the owner= attribute):
>>>
>>
>> Hmmm, then I forgot to test something, adding something in the
>> shortcuts.xbel file directly and see how the synchronization cope
>> with that (it won't have an ID for a start).
>>
>>
>
> The missing id should be created in such cases.
>
>>
>>>> Testing your patch I noticed that now the default places have wrong
>>>> icons... Actually after reverting I still see this behavior, so I
>>>> wonder
>>>> if it could be related to your previous changes to KBookmark.
>>>>
>
> Yeah - you were right - a stupid "last minute" change in my KBookmark
> patch caused this problem. I just committed a fix.
>
> So please update, "rm .kde4/share/apps/kfileplaces/bookmarks.xml" and
> try again...
>
>
Here is an updated patch for KFilePlacesModel. As suggested by Emmanuele
Bassi, the file-name of the shared bookmarks is "user-places.xbel" now -
instead of the ambiguous "shortcuts.xbel".
Ok to commit?
Regards,
Norbert
["kfileplaces_fdo_bookmarks_spec4.patch" (text/x-patch)]
Index: kfile/tests/kfileplacesmodeltest.cpp
===================================================================
--- kfile/tests/kfileplacesmodeltest.cpp (revision 795770)
+++ kfile/tests/kfileplacesmodeltest.cpp (working copy)
@@ -82,6 +82,11 @@
const QString file = KStandardDirs::locateLocal("data", \
"kfileplaces/bookmarks.xml"); QFile f(file);
f.remove();
+
+ // Erase the shared bookmarks file also
+ const QString sharedBookmarksFile = KStandardDirs().localxdgdatadir() + \
"/user-places.xbel"; + QFile f2(sharedBookmarksFile);
+ f2.remove();
qRegisterMetaType<QModelIndex>();
setenv("SOLID_FAKEHW", TEST_DATA, 1);
Index: kfile/kfileplacessharedbookmarks.cpp
===================================================================
--- kfile/kfileplacessharedbookmarks.cpp (revision 0)
+++ kfile/kfileplacessharedbookmarks.cpp (revision 0)
@@ -0,0 +1,277 @@
+/* This file is part of the KDE project
+ Copyright (C) 2008 Norbert Frese <nf2 scheinwelt at>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#include <QtCore/QObject>
+#include <QtCore/QTextStream>
+#include <QtCore/QFile>
+#include <kstandarddirs.h>
+#include <kbookmarkmanager.h>
+#include <kbookmark.h>
+#include <kdebug.h>
+
+#include "kfileplacessharedbookmarks_p.h"
+
+//////////////// utility functions
+
+static bool compareBookmarks(const KBookmark & bookmark1, const KBookmark & \
bookmark2) +{
+ return (bookmark1.url() == bookmark2.url() || bookmark1.text() == \
bookmark2.text()); +}
+
+static bool deepCompareDomNodes(const QDomNode & node1, const QDomNode & node2)
+{
+
+ // compare name and value
+ if (node1.nodeName() != node2.nodeName() || node1.nodeValue() != \
node2.nodeValue()) + return false;
+
+ // recursively compare children
+ const QDomNodeList node1Children = node1.childNodes();
+ const QDomNodeList node2Children = node2.childNodes();
+
+ if (node1Children.count () != node2Children.count ())
+ return false;
+
+ for (int i=0; i<node1Children.count ();i++) {
+ if (!deepCompareDomNodes(node1Children.at(i), node2Children.at(i) ))
+ return false;
+ }
+ return true;
+}
+
+static QString nodeAsString(const QDomNode & node1)
+{
+ QString str;
+ QTextStream ts( &str, QIODevice::WriteOnly );
+ ts << node1;
+ return str;
+}
+
+static bool exactCompareBookmarks(const KBookmark & bookmark1, const KBookmark & \
bookmark2) +{
+ //kDebug() << "excat comparing:\n" << nodeAsString(bookmark1.internalElement()) \
<< "\nwith:\n" << nodeAsString(bookmark2.internalElement()); + return \
deepCompareDomNodes(bookmark1.internalElement(), bookmark2.internalElement()); +}
+
+static void cloneBookmarkContents(const KBookmark & target, const KBookmark & \
source) +{
+ const QDomElement targetEl = target.internalElement();
+ QDomNode parent = targetEl.parentNode ();
+ QDomNode clonedNode = source.internalElement().cloneNode(true);
+ parent.replaceChild (clonedNode , targetEl );
+}
+
+static KBookmark cloneBookmark(const KBookmark & toClone)
+{
+ const QDomNode cloned = toClone.internalElement().cloneNode(true);
+ return KBookmark(cloned.toElement ());
+}
+
+
+static void emptyBookmarkGroup(KBookmarkGroup & root)
+{
+ KBookmark bookmark = root.first();
+ while (!bookmark.isNull()) {
+ KBookmark bookmarkToRemove = bookmark;
+ bookmark = root.next(bookmark);
+ root.deleteBookmark(bookmarkToRemove);
+ }
+}
+
+static int bookmarkGroupSize(KBookmarkGroup & root)
+{
+ int count=0;
+ KBookmark bookmark = root.first();
+ while (!bookmark.isNull()) {
+ count++;
+ bookmark = root.next(bookmark);
+ }
+ return count;
+}
+
+//////////////// class KFilePlacesSharedBookmarks
+
+KFilePlacesSharedBookmarks::KFilePlacesSharedBookmarks(KBookmarkManager * mgr)
+{
+ m_placesBookmarkManager = mgr;
+
+ const QString file = KStandardDirs().localxdgdatadir() + "/user-places.xbel";
+ m_sharedBookmarkManager = KBookmarkManager::managerForExternalFile(file);
+
+ connect(m_sharedBookmarkManager, SIGNAL(changed(const QString&, const \
QString&)), + this, SLOT(slotSharedBookmarksChanged()));
+ connect(m_sharedBookmarkManager, SIGNAL(bookmarksChanged(const QString&)),
+ this, SLOT(slotSharedBookmarksChanged()));
+
+ connect(m_placesBookmarkManager, SIGNAL(changed(const QString&, const \
QString&)), + this, SLOT(slotBookmarksChanged()));
+ connect(m_placesBookmarkManager, SIGNAL(bookmarksChanged(const QString&)),
+ this, SLOT(slotBookmarksChanged()));
+
+ integrateSharedBookmarks();
+}
+
+bool KFilePlacesSharedBookmarks::integrateSharedBookmarks()
+{
+ KBookmarkGroup root = m_placesBookmarkManager->root();
+ KBookmark bookmark = root.first();
+
+ KBookmarkGroup sharedRoot = m_sharedBookmarkManager->root();
+ KBookmark sharedBookmark = sharedRoot.first();
+
+ bool dirty = false;
+
+ while (!bookmark.isNull()) {
+ //kDebug() << "importing" << bookmark.text();
+
+ // skip over system items
+ if (bookmark.metaDataItem("isSystemItem") == "true") {
+ bookmark = root.next(bookmark);
+ continue;
+ }
+
+ // do the bookmarks match?
+ if (!sharedBookmark.isNull() && compareBookmarks(bookmark, sharedBookmark)) \
{ + //kDebug() << "excat comparing: targetbk:\n" << \
nodeAsString(bookmark.internalElement()) << "\nsourcbk:\n" << \
nodeAsString(sharedBookmark.internalElement()); +
+ if (!exactCompareBookmarks(bookmark, sharedBookmark)) {
+ KBookmark cloneTarget=bookmark;
+ KBookmark cloneSource = sharedBookmark;
+
+ sharedBookmark = sharedRoot.next(sharedBookmark);
+ bookmark = root.next(bookmark);
+
+ //kDebug() << "cloning" << cloneSource.text();
+ //kDebug() << "cloning: target=\n" << \
nodeAsString(cloneTarget.internalElement()) << "\n source:\n" << \
nodeAsString(cloneSource.internalElement()); +
+ cloneBookmarkContents(cloneTarget, cloneSource);
+ dirty = true;
+ continue;
+ } else {
+ //kDebug() << "keeping" << bookmark.text();
+ }
+ sharedBookmark = sharedRoot.next(sharedBookmark);
+ bookmark = root.next(bookmark);
+ continue;
+ }
+
+ // they don't match -> remove
+ //kDebug() << "removing" << bookmark.text();
+ KBookmark bookmarkToRemove = bookmark;
+ bookmark = root.next(bookmark);
+ root.deleteBookmark(bookmarkToRemove);
+
+ dirty = true;
+ }
+
+ // append the remaining shared bookmarks
+ while(!sharedBookmark.isNull()) {
+ root.addBookmark(cloneBookmark(sharedBookmark));
+ sharedBookmark = sharedRoot.next(sharedBookmark);
+ dirty = true;
+ }
+
+ return dirty;
+}
+
+bool KFilePlacesSharedBookmarks::exportSharedBookmarks()
+{
+ KBookmarkGroup root = m_placesBookmarkManager->root();
+ KBookmark bookmark = root.first();
+
+ KBookmarkGroup sharedRoot = m_sharedBookmarkManager->root();
+ KBookmark sharedBookmark = sharedRoot.first();
+
+ bool dirty = false;
+
+ // first check if they are the same
+ int count=0;
+ while (!bookmark.isNull()) {
+ //kDebug() << "exporting..." << bookmark.text();
+
+ // skip over system items
+ if (bookmark.metaDataItem("isSystemItem") == "true") {
+ bookmark = root.next(bookmark);
+ continue;
+ }
+ count++;
+
+ // end of sharedBookmarks?
+ if (sharedBookmark.isNull()) {
+ dirty=true;
+ break;
+ }
+
+ // do the bookmarks match?
+ if (compareBookmarks(bookmark, sharedBookmark)) {
+ if (!exactCompareBookmarks(bookmark, sharedBookmark)) {
+ dirty = true;
+ break;
+ }
+ } else {
+ dirty=true;
+ break;
+ }
+ sharedBookmark = sharedRoot.next(sharedBookmark);
+ bookmark = root.next(bookmark);
+ }
+
+ //kDebug() << "dirty=" << dirty << " oldsize=" << bookmarkGroupSize(sharedRoot) \
<< " count=" << count; +
+ if (bookmarkGroupSize(sharedRoot) != count)
+ dirty=true;
+
+ if (dirty) {
+ emptyBookmarkGroup(sharedRoot);
+
+ // append all bookmarks
+ KBookmark bookmark = root.first();
+
+ while(!bookmark.isNull()) {
+
+ if (bookmark.metaDataItem("isSystemItem") == "true") {
+ bookmark = root.next(bookmark);
+ continue;
+ }
+
+ sharedRoot.addBookmark(cloneBookmark(bookmark));
+ bookmark = root.next(bookmark);
+ dirty = true;
+ }
+ }
+
+ return dirty;
+
+}
+
+void KFilePlacesSharedBookmarks::slotSharedBookmarksChanged()
+{
+ kDebug() << "shared bookmarks changed";
+ bool dirty = integrateSharedBookmarks();
+ if (dirty) m_placesBookmarkManager->emitChanged();
+}
+
+void KFilePlacesSharedBookmarks::slotBookmarksChanged()
+{
+ kDebug() << "places bookmarks changed";
+ bool dirty = exportSharedBookmarks();
+ if (dirty) m_sharedBookmarkManager->emitChanged();
+}
+
+#include "kfileplacessharedbookmarks_p.moc"
Index: kfile/CMakeLists.txt
===================================================================
--- kfile/CMakeLists.txt (revision 795770)
+++ kfile/CMakeLists.txt (working copy)
@@ -19,6 +19,7 @@
kfilewidget.cpp
kfileplacesitem.cpp
kfileplacesmodel.cpp
+ kfileplacessharedbookmarks.cpp
kfileplacesselector.cpp
kfileplacesview.cpp
kfileplaceeditdialog.cpp
Index: kfile/kfileplacesitem.cpp
===================================================================
--- kfile/kfileplacesitem.cpp (revision 795770)
+++ kfile/kfileplacesitem.cpp (working copy)
@@ -185,13 +185,24 @@
return bookmark;
}
+KBookmark KFilePlacesItem::createSystemBookmark(KBookmarkManager *manager,
+ const QString &label,
+ const KUrl &url,
+ const QString &iconName)
+{
+ KBookmark bookmark = createBookmark(manager, label, url, iconName);
+ bookmark.setMetaDataItem("isSystemItem", "true");
+ return bookmark;
+}
+
+
KBookmark KFilePlacesItem::createDeviceBookmark(KBookmarkManager *manager,
const QString &udi)
{
KBookmarkGroup root = manager->root();
KBookmark bookmark = root.createNewSeparator();
bookmark.setMetaDataItem("UDI", udi);
-
+ bookmark.setMetaDataItem("isSystemItem", "true");
return bookmark;
}
@@ -199,7 +210,11 @@
{
static int count = 0;
- return QString::number(count++);
+// return QString::number(count++);
+
+ return QString::number(QDateTime::currentDateTime().toTime_t())
+ + '/' + QString::number(count++);
+
// return QString::number(QDateTime::currentDateTime().toTime_t())
// + '/' + QString::number(qrand());
Index: kfile/kfileplacesmodel.cpp
===================================================================
--- kfile/kfileplacesmodel.cpp (revision 795770)
+++ kfile/kfileplacesmodel.cpp (working copy)
@@ -19,6 +19,7 @@
*/
#include "kfileplacesmodel.h"
#include "kfileplacesitem_p.h"
+#include "kfileplacessharedbookmarks_p.h"
#include <QtCore/QMimeData>
#include <QtCore/QTimer>
@@ -48,9 +49,9 @@
class KFilePlacesModel::Private
{
public:
- Private(KFilePlacesModel *self) : q(self), bookmarkManager(0) {}
+ Private(KFilePlacesModel *self) : q(self), bookmarkManager(0), \
sharedBookmarks(0) {} + ~Private() { delete sharedBookmarks; }
-
KFilePlacesModel *q;
QList<KFilePlacesItem*> items;
@@ -59,7 +60,8 @@
Solid::Predicate predicate;
KBookmarkManager *bookmarkManager;
-
+ KFilePlacesSharedBookmarks * sharedBookmarks;
+
void reloadAndSignal();
QList<KFilePlacesItem *> loadBookmarkList();
@@ -77,23 +79,24 @@
{
const QString file = KStandardDirs::locateLocal("data", \
"kfileplaces/bookmarks.xml");
d->bookmarkManager = KBookmarkManager::managerForFile(file, "kfilePlaces");
-
+ d->sharedBookmarks = new KFilePlacesSharedBookmarks(d->bookmarkManager);
+
// Let's put some places in there if it's empty
KBookmarkGroup root = d->bookmarkManager->root();
if (root.first().isNull()) {
- KFilePlacesItem::createBookmark(d->bookmarkManager,
+ KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
i18nc("Home Directory", "Home"), \
KUrl(KUser().homeDir()), "user-home");
- KFilePlacesItem::createBookmark(d->bookmarkManager,
+ KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
i18n("Network"), KUrl("remote:/"), \
"network-workgroup"); #ifdef Q_OS_WIN
//C:/ as root for windows...forward slashes are valid too and are used in much/most \
of the KDE code on Windows
- KFilePlacesItem::createBookmark(d->bookmarkManager,
+ KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
i18n("Root"), KUrl("C:/"), "folder-red");
#else
- KFilePlacesItem::createBookmark(d->bookmarkManager,
+ KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
i18n("Root"), KUrl("/"), "folder-red");
#endif
- KFilePlacesItem::createBookmark(d->bookmarkManager,
+ KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
i18n("Trash"), KUrl("trash:/"), \
"user-trash"); }
Index: kfile/kfileplacessharedbookmarks_p.h
===================================================================
--- kfile/kfileplacessharedbookmarks_p.h (revision 0)
+++ kfile/kfileplacessharedbookmarks_p.h (revision 0)
@@ -0,0 +1,56 @@
+/* This file is part of the KDE project
+ Copyright (C) 2008 Norbert Frese <nf2 scheinwelt at>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KFILEPLACESSHARED_P_H_
+#define KFILEPLACESSHARED_P_H_
+
+#include <QtCore/QObject>
+#include <kbookmarkmanager.h>
+
+/**
+ * keeps the KFilePlacesModel bookmarks and the shared bookmark spec
+ * shortcuts in sync
+ */
+class KFilePlacesSharedBookmarks : public QObject
+{
+ Q_OBJECT
+public:
+
+ KFilePlacesSharedBookmarks(KBookmarkManager * mgr);
+ ~KFilePlacesSharedBookmarks() { /* delete m_sharedBookmarkManager; */}
+
+private:
+
+ bool integrateSharedBookmarks();
+ bool exportSharedBookmarks();
+
+ KBookmarkManager *m_placesBookmarkManager;
+ KBookmarkManager *m_sharedBookmarkManager;
+
+private Q_SLOTS:
+
+ void slotSharedBookmarksChanged();
+ void slotBookmarksChanged();
+
+};
+
+
+
+
+#endif /*KFILEPLACESSHARED_P_H_*/
Index: kfile/kfileplacesitem_p.h
===================================================================
--- kfile/kfileplacesitem_p.h (revision 795770)
+++ kfile/kfileplacesitem_p.h (working copy)
@@ -16,6 +16,7 @@
Boston, MA 02110-1301, USA.
*/
+
#ifndef KFILEPLACESITEM_P_H
#define KFILEPLACESITEM_P_H
@@ -48,6 +49,10 @@
const QString &label,
const KUrl &url,
const QString &iconName);
+ static KBookmark createSystemBookmark(KBookmarkManager *manager,
+ const QString &label,
+ const KUrl &url,
+ const QString &iconName);
static KBookmark createDeviceBookmark(KBookmarkManager *manager,
const QString &udi);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic