ReactOS  0.4.13-dev-563-g0561610
favorites.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2004, 2006 Martin Fuchs
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 
20  //
21  // Explorer and Desktop clone
22  //
23  // favorites.cpp
24  //
25  // Martin Fuchs, 04.04.2004
26  //
27 
28 
29 #include <precomp.h>
30 
31 #include "startmenu.h"
32 
33 
34 String DecodeURLString(const char* s)
35 {
37  LPTSTR o = buffer;
38 
39  for(const char* p=s; *p; ++p)
40  if (*p == '%') {
41  if (!strncmp(p+1, "20", 2)) {
42  *o++ = ' ';
43  p += 2;
44  } else
45  *o++ = *p;
46  } else
47  *o++ = *p;
48 
49  return String(buffer, o-buffer);
50 }
51 
52 
55 {
56  char line[BUFFER_LEN];
57 
58  tifstream in(path);
59 
60  while(in.good()) {
61  in.getline(line, BUFFER_LEN);
62 
63  const char* p = line;
64  while(isspace(*p))
65  ++p;
66 
67  const char* keyword = p;
68  const char* eq = strchr(p, '=');
69 
70  if (eq) {
71  const char* cont = eq + 1;
72  while(isspace(*cont))
73  ++cont;
74 
75  if (!_strnicmp(keyword, "URL", 3))
76  _url = DecodeURLString(cont);
77  else if (!_strnicmp(keyword, "IconFile", 8))
79  }
80  }
81 
82  return true;
83 }
84 
86 bool Bookmark::read(const_XMLPos& pos)
87 {
88  _url = pos.get("href").c_str();
89 
90  if (pos.go_down("title")) {
91  _name = pos->get_content();
92  pos.back();
93  }
94 
95  if (pos.go_down("desc")) {
96  _description = pos->get_content();
97  pos.back();
98  }
99 
100  if (pos.go_down("info")) {
101  const_XMLChildrenFilter metadata(pos, "metadata");
102 
103  for(const_XMLChildrenFilter::const_iterator it=metadata.begin(); it!=metadata.end(); ++it) {
104  const XMLNode& node = **it;
105  const_XMLPos sub_pos(&node);
106 
107  if (node.get("owner") == "ros-explorer") {
108  if (sub_pos.go_down("icon")) {
109  _icon_path = sub_pos.get("path").c_str();
110  _icon_idx = XS_toi(sub_pos.get("index"));
111 
112  sub_pos.back(); // </icon>
113  }
114  }
115  }
116 
117  pos.back(); // </metadata>
118  pos.back(); // </info>
119  }
120 
121  return !_url.empty(); // _url is mandatory.
122 }
123 
125 void Bookmark::write(XMLPos& pos) const
126 {
127  pos.create("bookmark");
128 
129  pos["href"] = _url.c_str();
130 
131  if (!_name.empty()) {
132  pos.create("title");
133  pos->set_content(_name);
134  pos.back();
135  }
136 
137  if (!_description.empty()) {
138  pos.create("desc");
139  pos->set_content(_description);
140  pos.back();
141  }
142 
143  if (!_icon_path.empty()) {
144  pos.create("info");
145  pos.create("metadata");
146  pos["owner"] = "ros-explorer";
147  pos.create("icon");
148  pos["path"] = _icon_path.c_str();
149  pos["index"].printf(XS_TEXT("%d"), _icon_idx);
150  pos.back(); // </icon>
151  pos.back(); // </metadata>
152  pos.back(); // </info>
153  }
154 
155  pos.back();
156 }
157 
158 
160 void BookmarkFolder::read(const_XMLPos& pos)
161 {
162  if (pos.go_down("title")) {
163  _name = pos->get_content();
164  pos.back();
165  }
166 
167  if (pos.go_down("desc")) {
168  _description = pos->get_content();
169  pos.back();
170  }
171 
173 }
174 
176 void BookmarkFolder::write(XMLPos& pos) const
177 {
178  pos.create("folder");
179 
180  if (!_name.empty()) {
181  pos.create("title");
182  pos->set_content(_name);
183  pos.back();
184  }
185 
186  if (!_description.empty()) {
187  pos.create("desc");
188  pos->set_content(_description);
189  pos.back();
190  }
191 
193 }
194 
195 
197  : _type(BMNT_NONE)
198 {
199  _pbookmark = NULL;
200 }
201 
203  : _type(BMNT_BOOKMARK)
204 {
205  _pbookmark = new Bookmark(bm);
206 }
207 
209  : _type(BMNT_FOLDER)
210 {
211  _pfolder = new BookmarkFolder(bmf);
212 }
213 
215  : _type(other._type)
216 {
217  if (other._type == BMNT_BOOKMARK)
218  _pbookmark = new Bookmark(*other._pbookmark);
219  else if (other._type == BMNT_FOLDER)
220  _pfolder = new BookmarkFolder(*other._pfolder);
221  else
222  _pbookmark = NULL;
223 }
224 
226 {
227  if (_type == BMNT_BOOKMARK)
228  delete _pbookmark;
229  else if (_type == BMNT_FOLDER)
230  delete _pfolder;
231 }
232 
234 {
235  clear();
236 
237  _pbookmark = new Bookmark(bm);
238 
239  return *this;
240 }
241 
243 {
244  clear();
245 
246  _pfolder = new BookmarkFolder(bmf);
247 
248  return *this;
249 }
250 
252 {
253  clear();
254 
255  _type = other._type;
256 
257  if (other._type == BMNT_BOOKMARK)
258  _pbookmark = new Bookmark(*other._pbookmark);
259  else if (other._type == BMNT_FOLDER)
260  _pfolder = new BookmarkFolder(*other._pfolder);
261 
262  return *this;
263 }
264 
266 {
267  if (_type == BMNT_BOOKMARK) {
268  delete _pbookmark;
269  _pbookmark = NULL;
270  }
271  else if (_type == BMNT_FOLDER) {
272  delete _pfolder;
273  _pfolder = NULL;
274  }
275 
276  _type = BMNT_NONE;
277 }
278 
279 
281 void BookmarkList::read(const_XMLPos& pos)
282 {
283  const XMLNode::Children& children = pos->get_children();
284 
285  for(XMLNode::Children::const_iterator it=children.begin(); it!=children.end(); ++it) {
286  const XMLNode& node = **it;
287  const_XMLPos sub_pos(&node);
288 
289  if (node == "folder") {
291 
292  folder.read(sub_pos);
293 
294  push_back(folder);
295  } else if (node == "bookmark") {
296  Bookmark bookmark;
297 
298  if (bookmark.read(sub_pos))
299  push_back(bookmark);
300  }
301  }
302 }
303 
305 void BookmarkList::write(XMLPos& pos) const
306 {
307  for(const_iterator it=begin(); it!=end(); ++it) {
308  const BookmarkNode& node = *it;
309 
310  if (node._type == BookmarkNode::BMNT_FOLDER) {
311  const BookmarkFolder& folder = *node._pfolder;
312 
313  folder.write(pos);
314 
315  pos.back();
316  } else if (node._type == BookmarkNode::BMNT_BOOKMARK) {
317  const Bookmark& bookmark = *node._pbookmark;
318 
319  if (!bookmark._url.empty())
320  bookmark.write(pos);
321  }
322  }
323 }
324 
325 
327 void BookmarkList::fill_tree(HWND hwnd, HTREEITEM parent, HIMAGELIST himagelist, HDC hdc_wnd) const
328 {
329  TV_INSERTSTRUCT tvi;
330 
331  tvi.hParent = parent;
332  tvi.hInsertAfter = TVI_LAST;
333 
334  TV_ITEM& tv = tvi.item;
336 
337  for(const_iterator it=begin(); it!=end(); ++it) {
338  const BookmarkNode& node = *it;
339 
340  tv.lParam = (LPARAM)&node;
341 
342  if (node._type == BookmarkNode::BMNT_FOLDER) {
343  const BookmarkFolder& folder = *node._pfolder;
344 
345  tv.pszText = (LPTSTR)folder._name.c_str();
346  tv.iImage = 3; // folder
347  tv.iSelectedImage = 4; // open folder
348  HTREEITEM hitem = TreeView_InsertItem(hwnd, &tvi);
349 
350  folder._bookmarks.fill_tree(hwnd, hitem, himagelist, hdc_wnd);
351  } else if (node._type == BookmarkNode::BMNT_BOOKMARK) {
352  const Bookmark& bookmark = *node._pbookmark;
353 
354  tv.pszText = (LPTSTR)bookmark._name.c_str();
355  tv.iImage = 1; // bookmark
356  tv.iSelectedImage = 2; // selected bookmark
357 
358  if (!bookmark._icon_path.empty()) {
359  const Icon& icon = g_Globals._icon_cache.extract(bookmark._icon_path, bookmark._icon_idx);
360 
361  if ((ICON_ID)icon != ICID_NONE)
362  tv.iImage = tv.iSelectedImage = icon.add_to_imagelist(himagelist, hdc_wnd);
363  }
364 
365  (void)TreeView_InsertItem(hwnd, &tvi);
366  }
367  }
368 }
369 
370 
373 {
375 
377 
378  for(Entry*entry=dir._down; entry; entry=entry->_next) {
379  if (entry->_shell_attribs & SFGAO_HIDDEN) // ignore files like "desktop.ini"
380  continue;
381 
382  String name;
383 
384  if (entry->_etype == ET_SHELL)
385  name = dir._folder.get_name(static_cast<ShellEntry*>(entry)->_pidl);
386  else
387  name = entry->_display_name;
388 
389  if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
390  BookmarkFolder new_folder;
391 
392  new_folder._name = DecodeXMLString(name);
393 
394  if (entry->_etype == ET_SHELL) {
395  ShellDirectory new_dir(dir._folder, static_cast<ShellEntry*>(entry)->_pidl, hwnd);
397  } else {
398  entry->get_path(path, COUNTOF(path));
401  }
402 
403  push_back(new_folder);
404  } else {
405  Bookmark bookmark;
406 
407  bookmark._name = DecodeXMLString(name);
408 
409  entry->get_path(path, COUNTOF(path));
410  _tsplitpath_s(path, NULL, 0, NULL, 0, NULL, 0, ext, COUNTOF(ext));
411 
412  if (!_tcsicmp(ext, TEXT(".url"))) {
413  bookmark.read_url(path);
414  push_back(bookmark);
415  } else {
417  //assert(0);
418  }
419  }
420  }
421 }
422 
423 
426 {
427  XMLDoc xbel;
428 
429  if (!xbel.read_file(path)) {
430  if (!xbel._errors.empty())
431  MessageBox(g_Globals._hwndDesktop, xbel._errors.str(),
432  TEXT("ROS Explorer - reading bookmark file"), MB_OK);
433  }
434 
435  const_XMLPos pos(&xbel);
436 
437  if (!pos.go_down("xbel"))
438  return false;
439 
440  super::read(pos);
441 
442  pos.back();
443 
444  return true;
445 }
446 
449 {
450  XMLDoc xbel;
451 
452  XMLPos pos(&xbel);
453  pos.create("xbel");
454  super::write(pos);
455  pos.back();
456 
457  xbel._format._doctype._name = "xbel";
458  xbel._format._doctype._public = "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML";
459  xbel._format._doctype._system = "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd";
460 
461  xbel.write_file(path);
462 }
463 
466 {
467  WaitCursor wait;
468 
469  StartMenuShellDirs dirs;
470 
471  try {
474  } catch(COMException&) {
475  }
476 
477  for(StartMenuShellDirs::iterator it=dirs.begin(); it!=dirs.end(); ++it) {
478  StartMenuDirectory& smd = *it;
479  ShellDirectory& dir = smd._dir;
480 
481  try {
483  } catch(COMException&) {
484  }
485  }
486 
487  return true;
488 }
bool read(LPCTSTR path)
read XBEL bookmark file
Definition: favorites.cpp:425
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
void push_back(const_reference __x)
Definition: _list.h:509
void read(const_XMLPos &pos)
read bookmark folder from XBEL formated XML tree
Definition: favorites.cpp:160
#define isspace(c)
Definition: acclib.h:69
iterator begin()
Definition: _list.h:367
#define _tsplitpath_s
Definition: tchar.h:687
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
Definition: fci.c:115
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
BookmarkList _bookmarks
Definition: favorites.h:90
#define _tcsicmp
Definition: xmlstorage.h:205
#define CSIDL_COMMON_FAVORITES
Definition: shlobj.h:2033
ICON_ID
Definition: globals.h:62
Retrieval of special shell folder paths.
Definition: shellclasses.h:981
int other
Definition: msacm.c:1364
int _icon_idx
Definition: favorites.h:40
static HDC
Definition: imagelist.c:92
shell folder entry
Definition: shellfs.h:53
GLuint buffer
Definition: glext.h:5915
static WCHAR String[]
Definition: stringtable.c:55
#define TVIF_SELECTEDIMAGE
Definition: commctrl.h:3243
#define eq(received, expected, label, type)
Definition: locale.c:144
CHAR * LPTSTR
Definition: xmlstorage.h:192
void clear()
Definition: favorites.cpp:265
Exception with context information.
Definition: shellclasses.h:113
bool read_url(LPCTSTR path)
read .URL file
Definition: favorites.cpp:54
#define TreeView_InsertItem(hwnd, lpis)
Definition: commctrl.h:3384
const Icon & extract(LPCTSTR path, ICONCACHE_FLAGS flags=ICF_NORMAL)
Definition: explorer.cpp:416
Bookmark * _pbookmark
Definition: favorites.h:71
void write(LPCTSTR path) const
write XBEL bookmark file
Definition: favorites.cpp:448
#define CSIDL_FAVORITES
Definition: shlobj.h:2009
_Check_return_ _CRTIMP int __cdecl _strnicmp(_In_reads_or_z_(_MaxCount) const char *_Str1, _In_reads_or_z_(_MaxCount) const char *_Str2, _In_ size_t _MaxCount)
smooth NULL
Definition: ftsmooth.c:416
char ext[3]
Definition: mkdosfs.c:358
BookmarkFolder * _pfolder
Definition: favorites.h:72
#define BUFFER_LEN
Definition: utility.h:97
String DecodeURLString(const char *s)
Definition: favorites.cpp:34
LONG_PTR LPARAM
Definition: windef.h:208
Definition: parser.c:48
String _name
Definition: favorites.h:88
void write(XMLPos &pos) const
write bookmark list into XBEL formated XML tree
Definition: favorites.cpp:305
#define TVI_LAST
Definition: commctrl.h:3342
unsigned int dir
Definition: maze.c:112
struct CFFOLDER folder
Definition: fdi.c:110
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
XS_String DecodeXMLString(const std::string &str)
decode XML string literals
Definition: xmlstorage.cpp:478
_STLP_PRIV _List_iterator< BookmarkNode, _Const_traits< BookmarkNode > > const_iterator
Definition: _list.h:276
char TCHAR
Definition: xmlstorage.h:189
BookmarkNode & operator=(const Bookmark &bm)
Definition: favorites.cpp:233
r parent
Definition: btrfs.c:2708
bool read(const_XMLPos &pos)
convert XBEL bookmark node
Definition: favorites.cpp:86
int add_to_imagelist(HIMAGELIST himl, HDC hdc_wnd, COLORREF bk_color=GetSysColor(COLOR_WINDOW), HBRUSH bk_brush=GetSysColorBrush(COLOR_WINDOW)) const
Definition: explorer.cpp:306
String _url
Definition: favorites.h:38
#define MAX_PATH
Definition: compat.h:26
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
String _description
Definition: favorites.h:89
#define SORT_NAME
Definition: xpath.c:441
char line[200]
Definition: main.c:97
void import_IE_favorites(struct ShellDirectory &dir, HWND hwnd)
import Internet Explorer bookmarks from Favorites folder into bookmark list
Definition: favorites.cpp:372
_STLP_PRIV _List_iterator< StartMenuDirectory, _Nonconst_traits< StartMenuDirectory > > iterator
Definition: _list.h:275
uint32_t entry
Definition: isohybrid.c:63
ExplorerGlobals g_Globals
Definition: explorer.cpp:52
GLdouble s
Definition: gl.h:2039
#define MessageBox
Definition: winuser.h:5688
String _description
Definition: favorites.h:37
StartMenuDirectory is used to store the base directory of start menus.
Definition: startmenu.h:52
bool import_IE_favorites(HWND hwnd)
import Internet Explorer bookmarks from Favorites folder
Definition: favorites.cpp:465
void fill_tree(HWND hwnd, HTREEITEM parent, HIMAGELIST, HDC hdc_wnd) const
fill treeview control with bookmark tree content
Definition: favorites.cpp:327
String _name
Definition: favorites.h:36
ShellFolder & GetDesktopFolder()
#define _MAX_EXT
Definition: utility.h:76
BOOKMARKNODE_TYPE _type
Definition: favorites.h:68
#define TV_ITEM
Definition: commctrl.h:3272
#define TEXT(s)
Definition: k32.h:26
GLuint in
Definition: glext.h:9616
#define TVIF_TEXT
Definition: commctrl.h:3238
iterator end()
Definition: _list.h:370
Definition: services.c:325
#define TVIF_IMAGE
Definition: commctrl.h:3239
static void new_dir(void)
Definition: check.c:1099
#define MB_OK
Definition: winuser.h:784
void read(const_XMLPos &pos)
read bookmark list from XBEL formated XML tree
Definition: favorites.cpp:281
ShellDirectory _dir
Definition: startmenu.h:64
char * strchr(const char *String, int ch)
Definition: utclib.c:501
Definition: globals.h:96
Definition: name.c:36
#define XS_TEXT(x)
Definition: xmlstorage.h:237
#define COUNTOF(x)
Definition: utility.h:93
#define TVIF_PARAM
Definition: commctrl.h:3240
GLfloat GLfloat p
Definition: glext.h:8902
#define TV_INSERTSTRUCT
Definition: commctrl.h:3349
struct Bookmark Bookmark
String _icon_path
Definition: favorites.h:39
HWND _hwndDesktop
Definition: globals.h:289
void write(XMLPos &pos) const
write XBEL bookmark node
Definition: favorites.cpp:125
void write(XMLPos &pos) const
write bookmark folder content from XBEL formated XML tree
Definition: favorites.cpp:176
base of all file and directory entries
Definition: entries.h:82
#define XS_toi
Definition: xmlstorage.h:244
Definition: dlist.c:348
IconCache _icon_cache
Definition: globals.h:285
GLuint const GLchar * name
Definition: glext.h:6031