KFile
kfileplacessharedbookmarks.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kfileplacessharedbookmarks_p.h"
00021
00022 #include <QtCore/QObject>
00023 #include <QtCore/QTextStream>
00024 #include <QtCore/QFile>
00025 #include <kstandarddirs.h>
00026 #include <kbookmarkmanager.h>
00027 #include <kbookmark.h>
00028 #include <kdebug.h>
00029
00031
00032 static bool compareBookmarks(const KBookmark & bookmark1, const KBookmark & bookmark2)
00033 {
00034 return (bookmark1.url() == bookmark2.url() || bookmark1.text() == bookmark2.text());
00035 }
00036
00037 static bool deepCompareDomNodes(const QDomNode & node1, const QDomNode & node2)
00038 {
00039
00040
00041 if (node1.nodeName() != node2.nodeName() || node1.nodeValue() != node2.nodeValue())
00042 return false;
00043
00044
00045 const QDomNodeList node1Children = node1.childNodes();
00046 const QDomNodeList node2Children = node2.childNodes();
00047
00048 if (node1Children.count () != node2Children.count ())
00049 return false;
00050
00051 for (int i=0; i<node1Children.count ();i++) {
00052 if (!deepCompareDomNodes(node1Children.at(i), node2Children.at(i) ))
00053 return false;
00054 }
00055 return true;
00056 }
00057
00058 static QString nodeAsString(const QDomNode & node1)
00059 {
00060 QString str;
00061 QTextStream ts( &str, QIODevice::WriteOnly );
00062 ts << node1;
00063 return str;
00064 }
00065
00066 static bool exactCompareBookmarks(const KBookmark & bookmark1, const KBookmark & bookmark2)
00067 {
00068
00069 return deepCompareDomNodes(bookmark1.internalElement(), bookmark2.internalElement());
00070 }
00071
00072 static void cloneBookmarkContents(const KBookmark & target, const KBookmark & source)
00073 {
00074 const QDomElement targetEl = target.internalElement();
00075 QDomNode parent = targetEl.parentNode ();
00076 QDomNode clonedNode = source.internalElement().cloneNode(true);
00077 parent.replaceChild (clonedNode , targetEl );
00078 }
00079
00080 static KBookmark cloneBookmark(const KBookmark & toClone)
00081 {
00082 const QDomNode cloned = toClone.internalElement().cloneNode(true);
00083 return KBookmark(cloned.toElement ());
00084 }
00085
00086
00087 static void emptyBookmarkGroup(KBookmarkGroup & root)
00088 {
00089 KBookmark bookmark = root.first();
00090 while (!bookmark.isNull()) {
00091 KBookmark bookmarkToRemove = bookmark;
00092 bookmark = root.next(bookmark);
00093 root.deleteBookmark(bookmarkToRemove);
00094 }
00095 }
00096
00097 static int bookmarkGroupSize(KBookmarkGroup & root)
00098 {
00099 int count=0;
00100 KBookmark bookmark = root.first();
00101 while (!bookmark.isNull()) {
00102 count++;
00103 bookmark = root.next(bookmark);
00104 }
00105 return count;
00106 }
00107
00109
00110 KFilePlacesSharedBookmarks::KFilePlacesSharedBookmarks(KBookmarkManager * mgr)
00111 {
00112 m_placesBookmarkManager = mgr;
00113
00114 const QString file = KStandardDirs().localxdgdatadir() + "/user-places.xbel";
00115 m_sharedBookmarkManager = KBookmarkManager::managerForExternalFile(file);
00116
00117 connect(m_sharedBookmarkManager, SIGNAL(changed(const QString&, const QString&)),
00118 this, SLOT(slotSharedBookmarksChanged()));
00119 connect(m_sharedBookmarkManager, SIGNAL(bookmarksChanged(const QString&)),
00120 this, SLOT(slotSharedBookmarksChanged()));
00121
00122 connect(m_placesBookmarkManager, SIGNAL(changed(const QString&, const QString&)),
00123 this, SLOT(slotBookmarksChanged()));
00124 connect(m_placesBookmarkManager, SIGNAL(bookmarksChanged(const QString&)),
00125 this, SLOT(slotBookmarksChanged()));
00126
00127 integrateSharedBookmarks();
00128 }
00129
00130 bool KFilePlacesSharedBookmarks::integrateSharedBookmarks()
00131 {
00132 KBookmarkGroup root = m_placesBookmarkManager->root();
00133 KBookmark bookmark = root.first();
00134
00135 KBookmarkGroup sharedRoot = m_sharedBookmarkManager->root();
00136 KBookmark sharedBookmark = sharedRoot.first();
00137
00138 bool dirty = false;
00139
00140 while (!bookmark.isNull()) {
00141
00142
00143
00144 if (bookmark.metaDataItem("isSystemItem") == "true") {
00145 bookmark = root.next(bookmark);
00146 continue;
00147 }
00148
00149
00150 if (!sharedBookmark.isNull() && compareBookmarks(bookmark, sharedBookmark)) {
00151
00152
00153 if (!exactCompareBookmarks(bookmark, sharedBookmark)) {
00154 KBookmark cloneTarget=bookmark;
00155 KBookmark cloneSource = sharedBookmark;
00156
00157 sharedBookmark = sharedRoot.next(sharedBookmark);
00158 bookmark = root.next(bookmark);
00159
00160
00161
00162
00163 cloneBookmarkContents(cloneTarget, cloneSource);
00164 dirty = true;
00165 continue;
00166 } else {
00167
00168 }
00169 sharedBookmark = sharedRoot.next(sharedBookmark);
00170 bookmark = root.next(bookmark);
00171 continue;
00172 }
00173
00174
00175
00176 KBookmark bookmarkToRemove = bookmark;
00177 bookmark = root.next(bookmark);
00178 root.deleteBookmark(bookmarkToRemove);
00179
00180 dirty = true;
00181 }
00182
00183
00184 while(!sharedBookmark.isNull()) {
00185 root.addBookmark(cloneBookmark(sharedBookmark));
00186 sharedBookmark = sharedRoot.next(sharedBookmark);
00187 dirty = true;
00188 }
00189
00190 return dirty;
00191 }
00192
00193 bool KFilePlacesSharedBookmarks::exportSharedBookmarks()
00194 {
00195 KBookmarkGroup root = m_placesBookmarkManager->root();
00196 KBookmark bookmark = root.first();
00197
00198 KBookmarkGroup sharedRoot = m_sharedBookmarkManager->root();
00199 KBookmark sharedBookmark = sharedRoot.first();
00200
00201 bool dirty = false;
00202
00203
00204 int count=0;
00205 while (!bookmark.isNull()) {
00206
00207
00208
00209 if (bookmark.metaDataItem("isSystemItem") == "true") {
00210 bookmark = root.next(bookmark);
00211 continue;
00212 }
00213 count++;
00214
00215
00216 if (sharedBookmark.isNull()) {
00217 dirty=true;
00218 break;
00219 }
00220
00221
00222 if (compareBookmarks(bookmark, sharedBookmark)) {
00223 if (!exactCompareBookmarks(bookmark, sharedBookmark)) {
00224 dirty = true;
00225 break;
00226 }
00227 } else {
00228 dirty=true;
00229 break;
00230 }
00231 sharedBookmark = sharedRoot.next(sharedBookmark);
00232 bookmark = root.next(bookmark);
00233 }
00234
00235
00236
00237 if (bookmarkGroupSize(sharedRoot) != count)
00238 dirty=true;
00239
00240 if (dirty) {
00241 emptyBookmarkGroup(sharedRoot);
00242
00243
00244 KBookmark bookmark = root.first();
00245
00246 while(!bookmark.isNull()) {
00247
00248 if (bookmark.metaDataItem("isSystemItem") == "true") {
00249 bookmark = root.next(bookmark);
00250 continue;
00251 }
00252
00253 sharedRoot.addBookmark(cloneBookmark(bookmark));
00254 bookmark = root.next(bookmark);
00255 dirty = true;
00256 }
00257 }
00258
00259 return dirty;
00260
00261 }
00262
00263 void KFilePlacesSharedBookmarks::slotSharedBookmarksChanged()
00264 {
00265 kDebug() << "shared bookmarks changed";
00266 bool dirty = integrateSharedBookmarks();
00267 if (dirty) m_placesBookmarkManager->emitChanged();
00268 }
00269
00270 void KFilePlacesSharedBookmarks::slotBookmarksChanged()
00271 {
00272 kDebug() << "places bookmarks changed";
00273 bool dirty = exportSharedBookmarks();
00274 if (dirty) m_sharedBookmarkManager->emitChanged();
00275 }
00276
00277 #include "kfileplacessharedbookmarks_p.moc"