Something went wrong. Try again.
Reactos
Something went wrong. Try again.
11 kB · 488 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489/* * Copyright 2004, 2006 Martin Fuchs * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
// // Explorer and Desktop clone // // favorites.cpp // // Martin Fuchs, 04.04.2004 //
#include <precomp.h>
#include "startmenu.h"
String DecodeURLString(const char* s){ TCHAR buffer[BUFFER_LEN]; LPTSTR o = buffer;
for(const char* p=s; *p; ++p) if (*p == '%') { if (!strncmp(p+1, "20", 2)) { *o++ = ' '; p += 2; } else *o++ = *p; } else *o++ = *p;
return String(buffer, o-buffer);}
/// read .URL filebool Bookmark::read_url(LPCTSTR path){ char line[BUFFER_LEN];
tifstream in(path);
while(in.good()) { in.getline(line, BUFFER_LEN);
const char* p = line; while(isspace(*p)) ++p;
const char* keyword = p; const char* eq = strchr(p, '=');
if (eq) { const char* cont = eq + 1; while(isspace(*cont)) ++cont;
if (!_strnicmp(keyword, "URL", 3)) _url = DecodeURLString(cont); else if (!_strnicmp(keyword, "IconFile", 8)) _icon_path = DecodeURLString(cont); } }
return true;}
/// convert XBEL bookmark nodebool Bookmark::read(const_XMLPos& pos){ _url = pos.get("href").c_str();
if (pos.go_down("title")) { _name = pos->get_content(); pos.back(); }
if (pos.go_down("desc")) { _description = pos->get_content(); pos.back(); }
if (pos.go_down("info")) { const_XMLChildrenFilter metadata(pos, "metadata");
for(const_XMLChildrenFilter::const_iterator it=metadata.begin(); it!=metadata.end(); ++it) { const XMLNode& node = **it; const_XMLPos sub_pos(&node);
if (node.get("owner") == "ros-explorer") { if (sub_pos.go_down("icon")) { _icon_path = sub_pos.get("path").c_str(); _icon_idx = XS_toi(sub_pos.get("index"));
sub_pos.back(); // </icon> } } }
pos.back(); // </metadata> pos.back(); // </info> }
return !_url.empty(); // _url is mandatory.}
/// write XBEL bookmark nodevoid Bookmark::write(XMLPos& pos) const{ pos.create("bookmark");
pos["href"] = _url.c_str();
if (!_name.empty()) { pos.create("title"); pos->set_content(_name); pos.back(); }
if (!_description.empty()) { pos.create("desc"); pos->set_content(_description); pos.back(); }
if (!_icon_path.empty()) { pos.create("info"); pos.create("metadata"); pos["owner"] = "ros-explorer"; pos.create("icon"); pos["path"] = _icon_path.c_str(); pos["index"].printf(XS_TEXT("%d"), _icon_idx); pos.back(); // </icon> pos.back(); // </metadata> pos.back(); // </info> }
pos.back();}
/// read bookmark folder from XBEL formated XML treevoid BookmarkFolder::read(const_XMLPos& pos){ if (pos.go_down("title")) { _name = pos->get_content(); pos.back(); }
if (pos.go_down("desc")) { _description = pos->get_content(); pos.back(); }
_bookmarks.read(pos);}
/// write bookmark folder content from XBEL formated XML treevoid BookmarkFolder::write(XMLPos& pos) const{ pos.create("folder");
if (!_name.empty()) { pos.create("title"); pos->set_content(_name); pos.back(); }
if (!_description.empty()) { pos.create("desc"); pos->set_content(_description); pos.back(); }
_bookmarks.write(pos);}
BookmarkNode::BookmarkNode() : _type(BMNT_NONE){ _pbookmark = NULL;}
BookmarkNode::BookmarkNode(const Bookmark& bm) : _type(BMNT_BOOKMARK){ _pbookmark = new Bookmark(bm);}
BookmarkNode::BookmarkNode(const BookmarkFolder& bmf) : _type(BMNT_FOLDER){ _pfolder = new BookmarkFolder(bmf);}
BookmarkNode::BookmarkNode(const BookmarkNode& other) : _type(other._type){ if (other._type == BMNT_BOOKMARK) _pbookmark = new Bookmark(*other._pbookmark); else if (other._type == BMNT_FOLDER) _pfolder = new BookmarkFolder(*other._pfolder); else _pbookmark = NULL;}
BookmarkNode::~BookmarkNode(){ if (_type == BMNT_BOOKMARK) delete _pbookmark; else if (_type == BMNT_FOLDER) delete _pfolder;}
BookmarkNode& BookmarkNode::operator=(const Bookmark& bm){ clear();
_pbookmark = new Bookmark(bm);
return *this;}
BookmarkNode& BookmarkNode::operator=(const BookmarkFolder& bmf){ clear();
_pfolder = new BookmarkFolder(bmf);
return *this;}
BookmarkNode& BookmarkNode::operator=(const BookmarkNode& other){ clear();
_type = other._type;
if (other._type == BMNT_BOOKMARK) _pbookmark = new Bookmark(*other._pbookmark); else if (other._type == BMNT_FOLDER) _pfolder = new BookmarkFolder(*other._pfolder);
return *this;}
void BookmarkNode::clear(){ if (_type == BMNT_BOOKMARK) { delete _pbookmark; _pbookmark = NULL; } else if (_type == BMNT_FOLDER) { delete _pfolder; _pfolder = NULL; }
_type = BMNT_NONE;}
/// read bookmark list from XBEL formated XML treevoid BookmarkList::read(const_XMLPos& pos){ const XMLNode::Children& children = pos->get_children();
for(XMLNode::Children::const_iterator it=children.begin(); it!=children.end(); ++it) { const XMLNode& node = **it; const_XMLPos sub_pos(&node);
if (node == "folder") { BookmarkFolder folder;
folder.read(sub_pos);
push_back(folder); } else if (node == "bookmark") { Bookmark bookmark;
if (bookmark.read(sub_pos)) push_back(bookmark); } }}
/// write bookmark list into XBEL formated XML treevoid BookmarkList::write(XMLPos& pos) const{ for(const_iterator it=begin(); it!=end(); ++it) { const BookmarkNode& node = *it;
if (node._type == BookmarkNode::BMNT_FOLDER) { const BookmarkFolder& folder = *node._pfolder;
folder.write(pos);
pos.back(); } else if (node._type == BookmarkNode::BMNT_BOOKMARK) { const Bookmark& bookmark = *node._pbookmark;
if (!bookmark._url.empty()) bookmark.write(pos); } }}
/// fill treeview control with bookmark tree contentvoid BookmarkList::fill_tree(HWND hwnd, HTREEITEM parent, HIMAGELIST himagelist, HDC hdc_wnd) const{ TV_INSERTSTRUCT tvi;
tvi.hParent = parent; tvi.hInsertAfter = TVI_LAST;
TV_ITEM& tv = tvi.item; tv.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
for(const_iterator it=begin(); it!=end(); ++it) { const BookmarkNode& node = *it;
tv.lParam = (LPARAM)&node;
if (node._type == BookmarkNode::BMNT_FOLDER) { const BookmarkFolder& folder = *node._pfolder;
tv.pszText = (LPTSTR)folder._name.c_str(); tv.iImage = 3; // folder tv.iSelectedImage = 4; // open folder HTREEITEM hitem = TreeView_InsertItem(hwnd, &tvi);
folder._bookmarks.fill_tree(hwnd, hitem, himagelist, hdc_wnd); } else if (node._type == BookmarkNode::BMNT_BOOKMARK) { const Bookmark& bookmark = *node._pbookmark;
tv.pszText = (LPTSTR)bookmark._name.c_str(); tv.iImage = 1; // bookmark tv.iSelectedImage = 2; // selected bookmark
if (!bookmark._icon_path.empty()) { const Icon& icon = g_Globals._icon_cache.extract(bookmark._icon_path, bookmark._icon_idx);
if ((ICON_ID)icon != ICID_NONE) tv.iImage = tv.iSelectedImage = icon.add_to_imagelist(himagelist, hdc_wnd); }
(void)TreeView_InsertItem(hwnd, &tvi); } }}
/// import Internet Explorer bookmarks from Favorites folder into bookmark listvoid BookmarkList::import_IE_favorites(ShellDirectory& dir, HWND hwnd){ TCHAR path[MAX_PATH], ext[_MAX_EXT];
dir.smart_scan(SORT_NAME, SCAN_DONT_EXTRACT_ICONS);
for(Entry*entry=dir._down; entry; entry=entry->_next) { if (entry->_shell_attribs & SFGAO_HIDDEN) // ignore files like "desktop.ini" continue;
String name;
if (entry->_etype == ET_SHELL) name = dir._folder.get_name(static_cast<ShellEntry*>(entry)->_pidl); else name = entry->_display_name;
if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { BookmarkFolder new_folder;
new_folder._name = DecodeXMLString(name);
if (entry->_etype == ET_SHELL) { ShellDirectory new_dir(dir._folder, static_cast<ShellEntry*>(entry)->_pidl, hwnd); new_folder._bookmarks.import_IE_favorites(new_dir, hwnd); } else { entry->get_path(path, COUNTOF(path)); ShellDirectory new_dir(GetDesktopFolder(), path, hwnd); new_folder._bookmarks.import_IE_favorites(new_dir, hwnd); }
push_back(new_folder); } else { Bookmark bookmark;
bookmark._name = DecodeXMLString(name);
entry->get_path(path, COUNTOF(path)); _tsplitpath_s(path, NULL, 0, NULL, 0, NULL, 0, ext, COUNTOF(ext));
if (!_tcsicmp(ext, TEXT(".url"))) { bookmark.read_url(path); push_back(bookmark); } else { ///@todo read shell links //assert(0); } } }}
/// read XBEL bookmark filebool Favorites::read(LPCTSTR path){ XMLDoc xbel;
if (!xbel.read_file(path)) { if (!xbel._errors.empty()) MessageBox(g_Globals._hwndDesktop, xbel._errors.str(), TEXT("ROS Explorer - reading bookmark file"), MB_OK); }
const_XMLPos pos(&xbel);
if (!pos.go_down("xbel")) return false;
super::read(pos);
pos.back();
return true;}
/// write XBEL bookmark filevoid Favorites::write(LPCTSTR path) const{ XMLDoc xbel;
XMLPos pos(&xbel); pos.create("xbel"); super::write(pos); pos.back();
xbel._format._doctype._name = "xbel"; xbel._format._doctype._public = "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML"; xbel._format._doctype._system = "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd";
xbel.write_file(path);}
/// import Internet Explorer bookmarks from Favorites folderbool Favorites::import_IE_favorites(HWND hwnd){ WaitCursor wait;
StartMenuShellDirs dirs;
try { dirs.push_back(ShellDirectory(GetDesktopFolder(), SpecialFolderPath(CSIDL_COMMON_FAVORITES, hwnd), hwnd)); dirs.push_back(ShellDirectory(GetDesktopFolder(), SpecialFolderPath(CSIDL_FAVORITES, hwnd), hwnd)); } catch(COMException&) { }
for(StartMenuShellDirs::iterator it=dirs.begin(); it!=dirs.end(); ++it) { StartMenuDirectory& smd = *it; ShellDirectory& dir = smd._dir;
try { super::import_IE_favorites(dir, hwnd); } catch(COMException&) { } }
return true;}