ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

favorites.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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 
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 
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 
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 
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 
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 
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 
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 
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 
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 {
00417                 //assert(0);
00418             }
00419         }
00420     }
00421 }
00422 
00423 
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 
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 
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 }

Generated on Sat May 26 2012 04:17:33 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.