00001 /* 00002 * Copyright 2004, 2006, 2010 Martin Fuchs 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 */ 00018 00019 00020 // 00021 // Explorer and Desktop clone 00022 // 00023 // favorites.cpp 00024 // 00025 // Martin Fuchs, 04.04.2004 00026 // 00027 00028 00029 #include <precomp.h> 00030 00031 #include "startmenu.h" 00032 00033 00034 String DecodeURLString(const char* s) 00035 { 00036 TCHAR buffer[BUFFER_LEN]; 00037 LPTSTR o = buffer; 00038 00039 for(const char* p=s; *p; ++p) 00040 if (*p == '%') { 00041 if (!strncmp(p+1, "20", 2)) { 00042 *o++ = ' '; 00043 p += 2; 00044 } else 00045 *o++ = *p; 00046 } else 00047 *o++ = *p; 00048 00049 return String(buffer, o-buffer); 00050 } 00051 00052 00053 /// read .URL file 00054 bool Bookmark::read_url(LPCTSTR path) 00055 { 00056 char line[BUFFER_LEN]; 00057 00058 tifstream in(path); 00059 00060 while(in.good()) { 00061 in.getline(line, BUFFER_LEN); 00062 00063 const char* p = line; 00064 while(isspace(*p)) 00065 ++p; 00066 00067 const char* keyword = p; 00068 const char* eq = strchr(p, '='); 00069 00070 if (eq) { 00071 const char* cont = eq + 1; 00072 while(isspace(*cont)) 00073 ++cont; 00074 00075 if (!_strnicmp(keyword, "URL", 3)) 00076 _url = DecodeURLString(cont); 00077 else if (!_strnicmp(keyword, "IconFile", 8)) 00078 _icon_path = DecodeURLString(cont); 00079 } 00080 } 00081 00082 return true; 00083 } 00084 00085 /// convert XBEL bookmark node 00086 bool Bookmark::read(const_XMLPos& pos) 00087 { 00088 _url = pos.get("href").c_str(); 00089 00090 if (pos.go_down("title")) { 00091 _name = pos->get_content(); 00092 pos.back(); 00093 } 00094 00095 if (pos.go_down("desc")) { 00096 _description = pos->get_content(); 00097 pos.back(); 00098 } 00099 00100 if (pos.go_down("info")) { 00101 const_XMLChildrenFilter metadata(pos, "metadata"); 00102 00103 for(const_XMLChildrenFilter::const_iterator it=metadata.begin(); it!=metadata.end(); ++it) { 00104 const XMLNode& node = **it; 00105 const_XMLPos sub_pos(&node); 00106 00107 if (node.get("owner") == "ros-explorer") { 00108 if (sub_pos.go_down("icon")) { 00109 _icon_path = sub_pos.get("path").c_str(); 00110 _icon_idx = XS_toi(sub_pos.get("index")); 00111 00112 sub_pos.back(); // </icon> 00113 } 00114 } 00115 } 00116 00117 pos.back(); // </metadata> 00118 pos.back(); // </info> 00119 } 00120 00121 return !_url.empty(); // _url is mandatory. 00122 } 00123 00124 /// write XBEL bookmark node 00125 void Bookmark::write(XMLPos& pos) const 00126 { 00127 pos.create("bookmark"); 00128 00129 pos["href"] = _url.c_str(); 00130 00131 if (!_name.empty()) { 00132 pos.create("title"); 00133 pos->set_content(_name); 00134 pos.back(); 00135 } 00136 00137 if (!_description.empty()) { 00138 pos.create("desc"); 00139 pos->set_content(_description); 00140 pos.back(); 00141 } 00142 00143 if (!_icon_path.empty()) { 00144 pos.create("info"); 00145 pos.create("metadata"); 00146 pos["owner"] = "ros-explorer"; 00147 pos.create("icon"); 00148 pos["path"] = _icon_path.c_str(); 00149 pos["index"].printf(XS_TEXT("%d"), _icon_idx); 00150 pos.back(); // </icon> 00151 pos.back(); // </metadata> 00152 pos.back(); // </info> 00153 } 00154 00155 pos.back(); 00156 } 00157 00158 00159 /// read bookmark folder from XBEL formated XML tree 00160 void BookmarkFolder::read(const_XMLPos& pos) 00161 { 00162 if (pos.go_down("title")) { 00163 _name = pos->get_content(); 00164 pos.back(); 00165 } 00166 00167 if (pos.go_down("desc")) { 00168 _description = pos->get_content(); 00169 pos.back(); 00170 } 00171 00172 _bookmarks.read(pos); 00173 } 00174 00175 /// write bookmark folder content from XBEL formated XML tree 00176 void BookmarkFolder::write(XMLPos& pos) const 00177 { 00178 pos.create("folder"); 00179 00180 if (!_name.empty()) { 00181 pos.create("title"); 00182 pos->set_content(_name); 00183 pos.back(); 00184 } 00185 00186 if (!_description.empty()) { 00187 pos.create("desc"); 00188 pos->set_content(_description); 00189 pos.back(); 00190 } 00191 00192 _bookmarks.write(pos); 00193 } 00194 00195 00196 BookmarkNode::BookmarkNode() 00197 : _type(BMNT_NONE) 00198 { 00199 _pbookmark = NULL; 00200 } 00201 00202 BookmarkNode::BookmarkNode(const Bookmark& bm) 00203 : _type(BMNT_BOOKMARK) 00204 { 00205 _pbookmark = new Bookmark(bm); 00206 } 00207 00208 BookmarkNode::BookmarkNode(const BookmarkFolder& bmf) 00209 : _type(BMNT_FOLDER) 00210 { 00211 _pfolder = new BookmarkFolder(bmf); 00212 } 00213 00214 BookmarkNode::BookmarkNode(const BookmarkNode& other) 00215 : _type(other._type) 00216 { 00217 if (other._type == BMNT_BOOKMARK) 00218 _pbookmark = new Bookmark(*other._pbookmark); 00219 else if (other._type == BMNT_FOLDER) 00220 _pfolder = new BookmarkFolder(*other._pfolder); 00221 else 00222 _pbookmark = NULL; 00223 } 00224 00225 BookmarkNode::~BookmarkNode() 00226 { 00227 if (_type == BMNT_BOOKMARK) 00228 delete _pbookmark; 00229 else if (_type == BMNT_FOLDER) 00230 delete _pfolder; 00231 } 00232 00233 BookmarkNode& BookmarkNode::operator=(const Bookmark& bm) 00234 { 00235 clear(); 00236 00237 _pbookmark = new Bookmark(bm); 00238 00239 return *this; 00240 } 00241 00242 BookmarkNode& BookmarkNode::operator=(const BookmarkFolder& bmf) 00243 { 00244 clear(); 00245 00246 _pfolder = new BookmarkFolder(bmf); 00247 00248 return *this; 00249 } 00250 00251 BookmarkNode& BookmarkNode::operator=(const BookmarkNode& other) 00252 { 00253 clear(); 00254 00255 _type = other._type; 00256 00257 if (other._type == BMNT_BOOKMARK) 00258 _pbookmark = new Bookmark(*other._pbookmark); 00259 else if (other._type == BMNT_FOLDER) 00260 _pfolder = new BookmarkFolder(*other._pfolder); 00261 00262 return *this; 00263 } 00264 00265 void BookmarkNode::clear() 00266 { 00267 if (_type == BMNT_BOOKMARK) { 00268 delete _pbookmark; 00269 _pbookmark = NULL; 00270 } 00271 else if (_type == BMNT_FOLDER) { 00272 delete _pfolder; 00273 _pfolder = NULL; 00274 } 00275 00276 _type = BMNT_NONE; 00277 } 00278 00279 00280 /// read bookmark list from XBEL formated XML tree 00281 void BookmarkList::read(const_XMLPos& pos) 00282 { 00283 const XMLNode::Children& children = pos->get_children(); 00284 00285 for(XMLNode::Children::const_iterator it=children.begin(); it!=children.end(); ++it) { 00286 const XMLNode& node = **it; 00287 const_XMLPos sub_pos(&node); 00288 00289 if (node == "folder") { 00290 BookmarkFolder folder; 00291 00292 folder.read(sub_pos); 00293 00294 push_back(folder); 00295 } else if (node == "bookmark") { 00296 Bookmark bookmark; 00297 00298 if (bookmark.read(sub_pos)) 00299 push_back(bookmark); 00300 } 00301 } 00302 } 00303 00304 /// write bookmark list into XBEL formated XML tree 00305 void BookmarkList::write(XMLPos& pos) const 00306 { 00307 for(const_iterator it=begin(); it!=end(); ++it) { 00308 const BookmarkNode& node = *it; 00309 00310 if (node._type == BookmarkNode::BMNT_FOLDER) { 00311 const BookmarkFolder& folder = *node._pfolder; 00312 00313 folder.write(pos); 00314 00315 pos.back(); 00316 } else if (node._type == BookmarkNode::BMNT_BOOKMARK) { 00317 const Bookmark& bookmark = *node._pbookmark; 00318 00319 if (!bookmark._url.empty()) 00320 bookmark.write(pos); 00321 } 00322 } 00323 } 00324 00325 00326 /// fill treeview control with bookmark tree content 00327 void BookmarkList::fill_tree(HWND hwnd, HTREEITEM parent, HIMAGELIST himagelist, HDC hdc_wnd) const 00328 { 00329 TV_INSERTSTRUCT tvi; 00330 00331 tvi.hParent = parent; 00332 tvi.hInsertAfter = TVI_LAST; 00333 00334 TV_ITEM& tv = tvi.item; 00335 tv.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM; 00336 00337 for(const_iterator it=begin(); it!=end(); ++it) { 00338 const BookmarkNode& node = *it; 00339 00340 tv.lParam = (LPARAM)&node; 00341 00342 if (node._type == BookmarkNode::BMNT_FOLDER) { 00343 const BookmarkFolder& folder = *node._pfolder; 00344 00345 tv.pszText = (LPTSTR)folder._name.c_str(); 00346 tv.iImage = 3; // folder 00347 tv.iSelectedImage = 4; // open folder 00348 HTREEITEM hitem = TreeView_InsertItem(hwnd, &tvi); 00349 00350 folder._bookmarks.fill_tree(hwnd, hitem, himagelist, hdc_wnd); 00351 } else if (node._type == BookmarkNode::BMNT_BOOKMARK) { 00352 const Bookmark& bookmark = *node._pbookmark; 00353 00354 tv.pszText = (LPTSTR)bookmark._name.c_str(); 00355 tv.iImage = 1; // bookmark 00356 tv.iSelectedImage = 2; // selected bookmark 00357 00358 if (!bookmark._icon_path.empty()) { 00359 const Icon& icon = g_Globals._icon_cache.extract(bookmark._icon_path, bookmark._icon_idx); 00360 00361 if ((ICON_ID)icon != ICID_NONE) 00362 tv.iImage = tv.iSelectedImage = icon.add_to_imagelist(himagelist, hdc_wnd); 00363 } 00364 00365 (void)TreeView_InsertItem(hwnd, &tvi); 00366 } 00367 } 00368 } 00369 00370 00371 /// import Internet Explorer bookmarks from Favorites folder into bookmark list 00372 void BookmarkList::import_IE_favorites(ShellDirectory& dir, HWND hwnd) 00373 { 00374 TCHAR path[MAX_PATH], ext[_MAX_EXT]; 00375 00376 dir.smart_scan(SORT_NAME, SCAN_DONT_EXTRACT_ICONS); 00377 00378 for(Entry*entry=dir._down; entry; entry=entry->_next) { 00379 if (entry->_shell_attribs & SFGAO_HIDDEN) // ignore files like "desktop.ini" 00380 continue; 00381 00382 String name; 00383 00384 if (entry->_etype == ET_SHELL) 00385 name = dir._folder.get_name(static_cast<ShellEntry*>(entry)->_pidl); 00386 else 00387 name = entry->_display_name; 00388 00389 if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 00390 BookmarkFolder new_folder; 00391 00392 new_folder._name = DecodeXMLString(name); 00393 00394 if (entry->_etype == ET_SHELL) { 00395 ShellDirectory new_dir(dir._folder, static_cast<ShellEntry*>(entry)->_pidl, hwnd); 00396 new_folder._bookmarks.import_IE_favorites(new_dir, hwnd); 00397 } else { 00398 entry->get_path(path, COUNTOF(path)); 00399 ShellDirectory new_dir(GetDesktopFolder(), path, hwnd); 00400 new_folder._bookmarks.import_IE_favorites(new_dir, hwnd); 00401 } 00402 00403 push_back(new_folder); 00404 } else { 00405 Bookmark bookmark; 00406 00407 bookmark._name = DecodeXMLString(name); 00408 00409 entry->get_path(path, COUNTOF(path)); 00410 _tsplitpath_s(path, NULL, 0, NULL, 0, NULL, 0, ext, COUNTOF(ext)); 00411 00412 if (!_tcsicmp(ext, TEXT(".url"))) { 00413 bookmark.read_url(path); 00414 push_back(bookmark); 00415 } else { 00416 ///@todo read shell links 00417 //assert(0); 00418 } 00419 } 00420 } 00421 } 00422 00423 00424 /// read XBEL bookmark file 00425 bool Favorites::read(LPCTSTR path) 00426 { 00427 XMLDoc xbel; 00428 00429 if (!xbel.read_file(path)) { 00430 if (!xbel._errors.empty()) 00431 MessageBox(g_Globals._hwndDesktop, xbel._errors.str(), 00432 TEXT("ROS Explorer - reading bookmark file"), MB_OK); 00433 } 00434 00435 const_XMLPos pos(&xbel); 00436 00437 if (!pos.go_down("xbel")) 00438 return false; 00439 00440 super::read(pos); 00441 00442 pos.back(); 00443 00444 return true; 00445 } 00446 00447 /// write XBEL bookmark file 00448 void Favorites::write(LPCTSTR path) const 00449 { 00450 XMLDoc xbel; 00451 00452 XMLPos pos(&xbel); 00453 pos.create("xbel"); 00454 super::write(pos); 00455 pos.back(); 00456 00457 xbel._format._doctype._name = "xbel"; 00458 xbel._format._doctype._public = "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"; 00459 xbel._format._doctype._system = "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd"; 00460 00461 xbel.write_file(path); 00462 } 00463 00464 /// import Internet Explorer bookmarks from Favorites folder 00465 bool Favorites::import_IE_favorites(HWND hwnd) 00466 { 00467 WaitCursor wait; 00468 00469 StartMenuShellDirs dirs; 00470 00471 try { 00472 dirs.push_back(ShellDirectory(GetDesktopFolder(), SpecialFolderPath(CSIDL_COMMON_FAVORITES, hwnd), hwnd)); 00473 dirs.push_back(ShellDirectory(GetDesktopFolder(), SpecialFolderPath(CSIDL_FAVORITES, hwnd), hwnd)); 00474 } catch(COMException&) { 00475 } 00476 00477 for(StartMenuShellDirs::iterator it=dirs.begin(); it!=dirs.end(); ++it) { 00478 StartMenuDirectory& smd = *it; 00479 ShellDirectory& dir = smd._dir; 00480 00481 try { 00482 super::import_IE_favorites(dir, hwnd); 00483 } catch(COMException&) { 00484 } 00485 } 00486 00487 return true; 00488 }
ROS Explorer Source Code Documentation
generated on 02.01.2013 by ![]() |