KFile
kfileplacessharedbookmarks.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project 00002 Copyright (C) 2008 Norbert Frese <nf2@scheinwelt.at> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 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 // compare name and value 00041 if (node1.nodeName() != node2.nodeName() || node1.nodeValue() != node2.nodeValue()) 00042 return false; 00043 00044 // recursively compare children 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 /* 00059 static QString nodeAsString(const QDomNode & node1) 00060 { 00061 QString str; 00062 QTextStream ts( &str, QIODevice::WriteOnly ); 00063 ts << node1; 00064 return str; 00065 } 00066 */ 00067 00068 static bool exactCompareBookmarks(const KBookmark & bookmark1, const KBookmark & bookmark2) 00069 { 00070 //kDebug() << "excat comparing:\n" << nodeAsString(bookmark1.internalElement()) << "\nwith:\n" << nodeAsString(bookmark2.internalElement()); 00071 return deepCompareDomNodes(bookmark1.internalElement(), bookmark2.internalElement()); 00072 } 00073 00074 static void cloneBookmarkContents(const KBookmark & target, const KBookmark & source) 00075 { 00076 const QDomElement targetEl = target.internalElement(); 00077 QDomNode parent = targetEl.parentNode (); 00078 QDomNode clonedNode = source.internalElement().cloneNode(true); 00079 parent.replaceChild (clonedNode , targetEl ); 00080 } 00081 00082 static KBookmark cloneBookmark(const KBookmark & toClone) 00083 { 00084 const QDomNode cloned = toClone.internalElement().cloneNode(true); 00085 return KBookmark(cloned.toElement ()); 00086 } 00087 00088 00089 static void emptyBookmarkGroup(KBookmarkGroup & root) 00090 { 00091 KBookmark bookmark = root.first(); 00092 while (!bookmark.isNull()) { 00093 KBookmark bookmarkToRemove = bookmark; 00094 bookmark = root.next(bookmark); 00095 root.deleteBookmark(bookmarkToRemove); 00096 } 00097 } 00098 00099 static int bookmarkGroupSize(KBookmarkGroup & root) 00100 { 00101 int count=0; 00102 KBookmark bookmark = root.first(); 00103 while (!bookmark.isNull()) { 00104 count++; 00105 bookmark = root.next(bookmark); 00106 } 00107 return count; 00108 } 00109 00111 00112 KFilePlacesSharedBookmarks::KFilePlacesSharedBookmarks(KBookmarkManager * mgr) 00113 { 00114 m_placesBookmarkManager = mgr; 00115 00116 const QString file = KStandardDirs().localxdgdatadir() + "/user-places.xbel"; 00117 m_sharedBookmarkManager = KBookmarkManager::managerForExternalFile(file); 00118 00119 connect(m_sharedBookmarkManager, SIGNAL(changed(const QString&, const QString&)), 00120 this, SLOT(slotSharedBookmarksChanged())); 00121 connect(m_sharedBookmarkManager, SIGNAL(bookmarksChanged(const QString&)), 00122 this, SLOT(slotSharedBookmarksChanged())); 00123 00124 connect(m_placesBookmarkManager, SIGNAL(changed(const QString&, const QString&)), 00125 this, SLOT(slotBookmarksChanged())); 00126 connect(m_placesBookmarkManager, SIGNAL(bookmarksChanged(const QString&)), 00127 this, SLOT(slotBookmarksChanged())); 00128 00129 integrateSharedBookmarks(); 00130 } 00131 00132 bool KFilePlacesSharedBookmarks::integrateSharedBookmarks() 00133 { 00134 KBookmarkGroup root = m_placesBookmarkManager->root(); 00135 KBookmark bookmark = root.first(); 00136 00137 KBookmarkGroup sharedRoot = m_sharedBookmarkManager->root(); 00138 KBookmark sharedBookmark = sharedRoot.first(); 00139 00140 bool dirty = false; 00141 00142 while (!bookmark.isNull()) { 00143 //kDebug() << "importing" << bookmark.text(); 00144 00145 // skip over system items 00146 if (bookmark.metaDataItem("isSystemItem") == "true") { 00147 bookmark = root.next(bookmark); 00148 continue; 00149 } 00150 00151 // do the bookmarks match? 00152 if (!sharedBookmark.isNull() && compareBookmarks(bookmark, sharedBookmark)) { 00153 //kDebug() << "excat comparing: targetbk:\n" << nodeAsString(bookmark.internalElement()) << "\nsourcbk:\n" << nodeAsString(sharedBookmark.internalElement()); 00154 00155 if (!exactCompareBookmarks(bookmark, sharedBookmark)) { 00156 KBookmark cloneTarget=bookmark; 00157 KBookmark cloneSource = sharedBookmark; 00158 00159 sharedBookmark = sharedRoot.next(sharedBookmark); 00160 bookmark = root.next(bookmark); 00161 00162 //kDebug() << "cloning" << cloneSource.text(); 00163 //kDebug() << "cloning: target=\n" << nodeAsString(cloneTarget.internalElement()) << "\n source:\n" << nodeAsString(cloneSource.internalElement()); 00164 00165 cloneBookmarkContents(cloneTarget, cloneSource); 00166 dirty = true; 00167 continue; 00168 } else { 00169 //kDebug() << "keeping" << bookmark.text(); 00170 } 00171 sharedBookmark = sharedRoot.next(sharedBookmark); 00172 bookmark = root.next(bookmark); 00173 continue; 00174 } 00175 00176 // they don't match -> remove 00177 //kDebug() << "removing" << bookmark.text(); 00178 KBookmark bookmarkToRemove = bookmark; 00179 bookmark = root.next(bookmark); 00180 root.deleteBookmark(bookmarkToRemove); 00181 00182 dirty = true; 00183 } 00184 00185 // append the remaining shared bookmarks 00186 while(!sharedBookmark.isNull()) { 00187 root.addBookmark(cloneBookmark(sharedBookmark)); 00188 sharedBookmark = sharedRoot.next(sharedBookmark); 00189 dirty = true; 00190 } 00191 00192 return dirty; 00193 } 00194 00195 bool KFilePlacesSharedBookmarks::exportSharedBookmarks() 00196 { 00197 KBookmarkGroup root = m_placesBookmarkManager->root(); 00198 KBookmark bookmark = root.first(); 00199 00200 KBookmarkGroup sharedRoot = m_sharedBookmarkManager->root(); 00201 KBookmark sharedBookmark = sharedRoot.first(); 00202 00203 bool dirty = false; 00204 00205 // first check if they are the same 00206 int count=0; 00207 while (!bookmark.isNull()) { 00208 //kDebug() << "exporting..." << bookmark.text(); 00209 00210 // skip over system items 00211 if (bookmark.metaDataItem("isSystemItem") == "true") { 00212 bookmark = root.next(bookmark); 00213 continue; 00214 } 00215 count++; 00216 00217 // end of sharedBookmarks? 00218 if (sharedBookmark.isNull()) { 00219 dirty=true; 00220 break; 00221 } 00222 00223 // do the bookmarks match? 00224 if (compareBookmarks(bookmark, sharedBookmark)) { 00225 if (!exactCompareBookmarks(bookmark, sharedBookmark)) { 00226 dirty = true; 00227 break; 00228 } 00229 } else { 00230 dirty=true; 00231 break; 00232 } 00233 sharedBookmark = sharedRoot.next(sharedBookmark); 00234 bookmark = root.next(bookmark); 00235 } 00236 00237 //kDebug() << "dirty=" << dirty << " oldsize=" << bookmarkGroupSize(sharedRoot) << " count=" << count; 00238 00239 if (bookmarkGroupSize(sharedRoot) != count) 00240 dirty=true; 00241 00242 if (dirty) { 00243 emptyBookmarkGroup(sharedRoot); 00244 00245 // append all bookmarks 00246 KBookmark bookmark = root.first(); 00247 00248 while(!bookmark.isNull()) { 00249 00250 if (bookmark.metaDataItem("isSystemItem") == "true") { 00251 bookmark = root.next(bookmark); 00252 continue; 00253 } 00254 00255 sharedRoot.addBookmark(cloneBookmark(bookmark)); 00256 bookmark = root.next(bookmark); 00257 dirty = true; 00258 } 00259 } 00260 00261 return dirty; 00262 00263 } 00264 00265 void KFilePlacesSharedBookmarks::slotSharedBookmarksChanged() 00266 { 00267 //kDebug() << "shared bookmarks changed"; 00268 bool dirty = integrateSharedBookmarks(); 00269 if (dirty) m_placesBookmarkManager->emitChanged(); 00270 } 00271 00272 void KFilePlacesSharedBookmarks::slotBookmarksChanged() 00273 { 00274 //kDebug() << "places bookmarks changed"; 00275 bool dirty = exportSharedBookmarks(); 00276 if (dirty) m_sharedBookmarkManager->emitChanged(); 00277 } 00278 00279 #include "kfileplacessharedbookmarks_p.moc"
KDE 4.6 API Reference