From 62f1a2a671c580fdc247a346be9db240ad3f3e5e Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Mon, 2 Aug 2004 19:16:18 +0000 Subject: [PATCH] context menus for qick launch bar svn path=/trunk/; revision=10363 --- reactos/subsys/system/explorer/Makefile.PCH | 2 +- .../system/explorer/dialogs/settings.cpp | 10 +- reactos/subsys/system/explorer/doc/TODO.txt | 1 - .../subsys/system/explorer/make_explorer.dsp | 4 + .../subsys/system/explorer/shell/entries.cpp | 46 +++++ .../subsys/system/explorer/shell/entries.h | 15 +- .../system/explorer/shell/filechild.cpp | 24 +-- .../system/explorer/shell/shellbrowser.cpp | 29 +-- .../system/explorer/shell/shellbrowser.h | 1 - .../subsys/system/explorer/shell/shellfs.cpp | 11 + .../subsys/system/explorer/shell/shellfs.h | 11 +- .../system/explorer/taskbar/quicklaunch.cpp | 24 ++- .../system/explorer/taskbar/traynotify.cpp | 17 +- .../explorer/utility/shellbrowserimpl.cpp | 2 +- .../system/explorer/utility/xmlstorage.h | 189 ++++++++++++------ 15 files changed, 247 insertions(+), 139 deletions(-) diff --git a/reactos/subsys/system/explorer/Makefile.PCH b/reactos/subsys/system/explorer/Makefile.PCH index 51bdc8030c1..2ecc3469554 100644 --- a/reactos/subsys/system/explorer/Makefile.PCH +++ b/reactos/subsys/system/explorer/Makefile.PCH @@ -81,7 +81,7 @@ DELAYIMPORTS = oleaut32 wsock32 all: precomp.h.gch $(TARGET) -precomp.h.gch: +precomp.h.gch: *.h utility/*.h shell/*.h desktop/*.h $(CXX) $(CFLAGS) precomp.h $(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll libexpat.dll diff --git a/reactos/subsys/system/explorer/dialogs/settings.cpp b/reactos/subsys/system/explorer/dialogs/settings.cpp index 3f065d56df4..11cf849d4fd 100644 --- a/reactos/subsys/system/explorer/dialogs/settings.cpp +++ b/reactos/subsys/system/explorer/dialogs/settings.cpp @@ -159,8 +159,10 @@ TaskbarSettingsDlg::TaskbarSettingsDlg(HWND hwnd) : super(hwnd), _cfg_org(g_Globals._cfg) { - CheckDlgButton(hwnd, ID_SHOW_CLOCK, XMLBool(g_Globals.get_cfg("desktopbar"), "options", "show-clock", true)? BST_CHECKED: BST_UNCHECKED); - CheckDlgButton(hwnd, ID_HIDE_INACTIVE_ICONS, XMLBool(g_Globals.get_cfg("notify-icons"), "options", "hide-inactive", true)? BST_CHECKED: BST_UNCHECKED); + XMLPos options(g_Globals.get_cfg("desktopbar"), "options"); + + CheckDlgButton(hwnd, ID_SHOW_CLOCK, XMLBool(options, "show-clock", true)? BST_CHECKED: BST_UNCHECKED); + CheckDlgButton(hwnd, ID_HIDE_INACTIVE_ICONS, XMLBool(options, "hide-inactive", true)? BST_CHECKED: BST_UNCHECKED); } int TaskbarSettingsDlg::Notify(int id, NMHDR* pnmh) @@ -190,13 +192,13 @@ int TaskbarSettingsDlg::Command(int id, int code) break; case ID_SHOW_CLOCK: - XMLBoolRef(g_Globals.get_cfg("desktopbar"), "options", "show-clock", true).toggle(); + XMLBoolRef(XMLPos(g_Globals.get_cfg("desktopbar"),"options"), "show-clock", true).toggle(); SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0); PropSheet_Changed(GetParent(_hwnd), _hwnd); break; case ID_HIDE_INACTIVE_ICONS: - XMLBoolRef(g_Globals.get_cfg("notify-icons"), "options", "hide-inactive", true).toggle(); + XMLBoolRef(XMLPos(g_Globals.get_cfg("notify-icons"),"options"), "hide-inactive", true).toggle(); SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0); PropSheet_Changed(GetParent(_hwnd), _hwnd); break; diff --git a/reactos/subsys/system/explorer/doc/TODO.txt b/reactos/subsys/system/explorer/doc/TODO.txt index 982daa9c2b7..905cbb0b077 100644 --- a/reactos/subsys/system/explorer/doc/TODO.txt +++ b/reactos/subsys/system/explorer/doc/TODO.txt @@ -1,6 +1,5 @@ - rewrite autostart code and include all possible autostart locations - read "DESCRIPT.ION" files to display file descriptions -- context menus for quick launch bar - detect display mode changes and adjust desktop bar size - handling of full screen applications - implement additional deskbands diff --git a/reactos/subsys/system/explorer/make_explorer.dsp b/reactos/subsys/system/explorer/make_explorer.dsp index b53e81968d0..38ed5a94d64 100644 --- a/reactos/subsys/system/explorer/make_explorer.dsp +++ b/reactos/subsys/system/explorer/make_explorer.dsp @@ -199,6 +199,10 @@ SOURCE=.\Makefile.MinGW # End Source File # Begin Source File +SOURCE=.\Makefile.PCH +# End Source File +# Begin Source File + SOURCE=.\Makefile.Wine # End Source File # End Target diff --git a/reactos/subsys/system/explorer/shell/entries.cpp b/reactos/subsys/system/explorer/shell/entries.cpp index e81edbd337b..e849688bed7 100644 --- a/reactos/subsys/system/explorer/shell/entries.cpp +++ b/reactos/subsys/system/explorer/shell/entries.cpp @@ -395,6 +395,52 @@ BOOL Entry::launch_entry(HWND hwnd, UINT nCmdShow) } +HRESULT Entry::do_context_menu(HWND hwnd, const POINT& pos) +{ + ShellPath shell_path = create_absolute_pidl(); + LPCITEMIDLIST pidl_abs = shell_path; + + if (!pidl_abs) + return S_FALSE; // no action for registry entries, etc. + + static DynamicFct SHBindToParent(TEXT("SHELL32"), "SHBindToParent"); + + if (SHBindToParent) { + IShellFolder* parentFolder; + LPCITEMIDLIST pidlLast; + + // get and use the parent folder to display correct context menu in all cases -> correct "Properties" dialog for directories, ... + HRESULT hr = (*SHBindToParent)(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast); + + if (SUCCEEDED(hr)) { + hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y); + + parentFolder->Release(); + } + + return hr; + } else { + /**@todo use parent folder instead of desktop folder + Entry* dir = _up; + + ShellPath parent_path; + + if (dir) + parent_path = dir->create_absolute_pidl(); + else + parent_path = DesktopFolderPath(); + + ShellPath shell_path = create_relative_pidl(parent_path); + LPCITEMIDLIST pidl = shell_path; + + ShellFolder parent_folder = parent_path; + return ShellFolderContextMenu(parent_folder, hwnd, 1, &pidl, pos.x, pos.y); + */ + return ShellFolderContextMenu(GetDesktopFolder(), hwnd, 1, &pidl_abs, pos.x, pos.y); + } +} + + HRESULT Entry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut) { TCHAR path[MAX_PATH]; diff --git a/reactos/subsys/system/explorer/shell/entries.h b/reactos/subsys/system/explorer/shell/entries.h index ed1b9aa8992..a1861ec55c4 100644 --- a/reactos/subsys/system/explorer/shell/entries.h +++ b/reactos/subsys/system/explorer/shell/entries.h @@ -105,13 +105,14 @@ public: void smart_scan(SORT_ORDER sortOrder=SORT_NAME, int scan_flags=SCAN_ALL); void extract_icon(); - virtual void read_directory(int scan_flags=SCAN_ALL) {} - virtual const void* get_next_path_component(const void*) const {return NULL;} - virtual Entry* find_entry(const void*) {return NULL;} - virtual bool get_path(PTSTR path) const = 0; - virtual ShellPath create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;} - virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut); - virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL); + virtual void read_directory(int scan_flags=SCAN_ALL) {} + virtual const void* get_next_path_component(const void*) const {return NULL;} + virtual Entry* find_entry(const void*) {return NULL;} + virtual bool get_path(PTSTR path) const = 0; + virtual ShellPath create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;} + virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut); + virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL); + virtual HRESULT do_context_menu(HWND hwnd, const POINT& pos); }; diff --git a/reactos/subsys/system/explorer/shell/filechild.cpp b/reactos/subsys/system/explorer/shell/filechild.cpp index bf7a8761317..324d1d59cf0 100644 --- a/reactos/subsys/system/explorer/shell/filechild.cpp +++ b/reactos/subsys/system/explorer/shell/filechild.cpp @@ -496,6 +496,7 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) HWND hpanel = (HWND) wparam; POINTS& pos = MAKEPOINTS(lparam); POINT pt; POINTSTOPOINT(pt, pos); + POINT pt_screen = pt; ScreenToClient(hpanel, &pt); SendMessage(hpanel, WM_LBUTTONDOWN, 0, MAKELONG(pt.x, pt.y)); SendMessage(hpanel, WM_LBUTTONUP, 0, MAKELONG(pt.x, pt.y)); @@ -506,28 +507,7 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) if (idx != -1) { Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx); - ShellPath shell_path = entry->create_absolute_pidl(); - LPCITEMIDLIST pidl_abs = shell_path; - - if (pidl_abs) { - IShellFolder* parentFolder; - LPCITEMIDLIST pidlLast; - - static DynamicFct SHBindToParent(TEXT("SHELL32"), "SHBindToParent"); - - if (SHBindToParent) { - // get and use the parent folder to display correct context menu in all cases -> correct "Properties" dialog for directories, ... - if (SUCCEEDED((*SHBindToParent)(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast))) { - HRESULT hr = ShellFolderContextMenu(parentFolder, _hwnd, 1, &pidlLast, pos.x, pos.y); - - parentFolder->Release(); - - CHECKERROR(hr); - } - } else { - CHECKERROR(ShellFolderContextMenu(GetDesktopFolder(), _hwnd, 1, &pidl_abs, pos.x, pos.y)); - } - } + CHECKERROR(entry->do_context_menu(_hwnd, pt_screen)); } break;} diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.cpp b/reactos/subsys/system/explorer/shell/shellbrowser.cpp index fcc22e173ca..3f958eb0b57 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.cpp +++ b/reactos/subsys/system/explorer/shell/shellbrowser.cpp @@ -198,32 +198,13 @@ void ShellBrowser::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh) TreeView_HitTest(_left_hwnd, &tvhti); if (TVHT_ONITEM & tvhti.flags) { - ClientToScreen(_left_hwnd, &tvhti.pt); - Tree_DoItemMenu(_left_hwnd, tvhti.hItem, &tvhti.pt); - } -} + LPARAM itemData = TreeView_GetItemData(_left_hwnd, tvhti.hItem); -void ShellBrowser::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen) -{ - CONTEXT("ShellBrowser::Tree_DoItemMenu()"); + if (itemData) { + Entry* entry = (Entry*)itemData; + ClientToScreen(_left_hwnd, &tvhti.pt); - LPARAM itemData = TreeView_GetItemData(hwndTreeView, hItem); - - if (itemData) { - Entry* entry = (Entry*)itemData; - - if (entry->_etype == ET_SHELL) { - ShellDirectory* dir = static_cast(entry->_up); - ShellFolder folder = dir? dir->_folder: GetDesktopFolder(); - LPCITEMIDLIST pidl = static_cast(entry)->_pidl; - - CHECKERROR(ShellFolderContextMenu(folder, ::GetParent(hwndTreeView), 1, &pidl, pptScreen->x, pptScreen->y)); - } else { - ShellPath shell_path = entry->create_absolute_pidl(); - LPCITEMIDLIST pidl = shell_path; - - ///@todo use parent folder instead of desktop - CHECKERROR(ShellFolderContextMenu(GetDesktopFolder(), _hwnd, 1, &pidl, pptScreen->x, pptScreen->y)); + CHECKERROR(entry->do_context_menu(_hwnd, tvhti.pt)); } } } diff --git a/reactos/subsys/system/explorer/shell/shellbrowser.h b/reactos/subsys/system/explorer/shell/shellbrowser.h index c99e07b573d..18360e9faac 100644 --- a/reactos/subsys/system/explorer/shell/shellbrowser.h +++ b/reactos/subsys/system/explorer/shell/shellbrowser.h @@ -132,7 +132,6 @@ struct ShellBrowser : public IShellBrowserImpl HRESULT OnDefaultCommand(LPIDA pida); void UpdateFolderView(IShellFolder* folder); - void Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen); HTREEITEM select_entry(HTREEITEM hitem, Entry* entry, bool expand=true); protected: diff --git a/reactos/subsys/system/explorer/shell/shellfs.cpp b/reactos/subsys/system/explorer/shell/shellfs.cpp index 1148c9ecb8d..49748a7f60e 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.cpp +++ b/reactos/subsys/system/explorer/shell/shellfs.cpp @@ -202,6 +202,17 @@ BOOL ShellEntry::launch_entry(HWND hwnd, UINT nCmdShow) } +HRESULT ShellEntry::do_context_menu(HWND hwnd, LPPOINT pptScreen) +{ + ShellDirectory* dir = static_cast(_up); + + ShellFolder folder = dir? dir->_folder: GetDesktopFolder(); + LPCITEMIDLIST pidl = _pidl; + + return ShellFolderContextMenu(folder, hwnd, 1, &pidl, pptScreen->x, pptScreen->y); +} + + HRESULT ShellEntry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut) { LPCITEMIDLIST pidl = _pidl; diff --git a/reactos/subsys/system/explorer/shell/shellfs.h b/reactos/subsys/system/explorer/shell/shellfs.h index 7bec8c27679..dd5576fc68d 100644 --- a/reactos/subsys/system/explorer/shell/shellfs.h +++ b/reactos/subsys/system/explorer/shell/shellfs.h @@ -32,12 +32,13 @@ struct ShellEntry : public Entry ShellEntry(Entry* parent, LPITEMIDLIST shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {} ShellEntry(Entry* parent, const ShellPath& shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {} - virtual bool get_path(PTSTR path) const; - virtual ShellPath create_absolute_pidl() const; - virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL); - virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut); + virtual bool get_path(PTSTR path) const; + virtual ShellPath create_absolute_pidl() const; + virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut); + virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL); + virtual HRESULT do_context_menu(HWND hwnd, LPPOINT pptScreen); - IShellFolder* get_parent_folder() const; + IShellFolder* get_parent_folder() const; ShellPath _pidl; // parent relative PIDL diff --git a/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp b/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp index 8e695728324..700ea0b962b 100644 --- a/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp +++ b/reactos/subsys/system/explorer/taskbar/quicklaunch.cpp @@ -132,6 +132,7 @@ void QuickLaunchBar::AddShortcuts() int cy = HIWORD(size); RECT rect = {0, 0, cx, cy}; RECT textRect = {0, 0, cx-7, cy-7}; + for(int i=0; i=0 && + SendMessage(_hwnd, TB_GETBUTTON, idx, (LPARAM)&btn)!=-1 && + (it=_entries.find(btn.idCommand))!=_entries.end()) { + entry = it->second._entry; + } + + if (entry) // entry is NULL for desktop switch buttons + CHECKERROR(entry->do_context_menu(_hwnd, pt)); + else + goto def; + break;} + + default: def: return super::WndProc(nmsg, wparam, lparam); } diff --git a/reactos/subsys/system/explorer/taskbar/traynotify.cpp b/reactos/subsys/system/explorer/taskbar/traynotify.cpp index 650d6796d06..9e830d36c8e 100644 --- a/reactos/subsys/system/explorer/taskbar/traynotify.cpp +++ b/reactos/subsys/system/explorer/taskbar/traynotify.cpp @@ -216,14 +216,16 @@ void NotifyArea::read_config() #endif { if (pos.go_down("desktopbar")) { - clock_visible = XMLBoolRef(pos, "options", "show-clock", !get_hide_clock_from_registry()); + clock_visible = XMLBoolRef(XMLPos(pos,"options"), "show-clock", !get_hide_clock_from_registry()); pos.back(); } } if (pos.go_down("notify-icons")) { - _hide_inactive = XMLBool(pos, "options", "hide-inactive", true); ///@todo read default setting from registry - _show_hidden = XMLBool(pos, "options", "show-hidden", false); ///@todo read default setting from registry + XMLPos options(pos, "options"); + + _hide_inactive = XMLBool(options, "hide-inactive", true); ///@todo read default setting from registry + _show_hidden = XMLBool(options, "show-hidden", false); ///@todo read default setting from registry XMLChildrenFilter icons(pos, "icon"); @@ -260,13 +262,14 @@ void NotifyArea::write_config() XMLPos pos = g_Globals.get_cfg(); pos.smart_create("desktopbar"); - XMLBoolRef(pos, "options", "show-clock") = _hwndClock!=0; + XMLBoolRef(XMLPos(pos,"options"), "show-clock") = _hwndClock!=0; pos.back(); pos.smart_create("notify-icons"); - XMLBoolRef(pos, "options", "hide-inactive") = _hide_inactive; - XMLBoolRef(pos, "options", "show-hidden") = _show_hidden; + XMLPos options(pos, "options"); + XMLBoolRef(options, "hide-inactive") = _hide_inactive; + XMLBoolRef(options, "show-hidden") = _show_hidden; for(NotifyIconCfgList::iterator it=_cfg.begin(); it!=_cfg.end(); ++it) { NotifyIconConfig& cfg = *it; @@ -285,6 +288,8 @@ void NotifyArea::write_config() pos.back(); } + + pos.back(); // smart_create } void NotifyArea::show_clock(bool flag) diff --git a/reactos/subsys/system/explorer/utility/shellbrowserimpl.cpp b/reactos/subsys/system/explorer/utility/shellbrowserimpl.cpp index 6e7c4eccd65..e82ce978d9f 100644 --- a/reactos/subsys/system/explorer/utility/shellbrowserimpl.cpp +++ b/reactos/subsys/system/explorer/utility/shellbrowserimpl.cpp @@ -81,7 +81,7 @@ HRESULT STDMETHODCALLTYPE IShellBrowserImpl::QueryService(REFGUID guidService, R return S_OK; } -HRESULT STDMETHODCALLTYPE IShellBrowserImpl::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText) +HRESULT STDMETHODCALLTYPE IShellBrowserImpl::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText) { return E_FAIL; ///@todo implement IOleCommandTarget } diff --git a/reactos/subsys/system/explorer/utility/xmlstorage.h b/reactos/subsys/system/explorer/utility/xmlstorage.h index f979d8ba2b1..3b788c30c1e 100644 --- a/reactos/subsys/system/explorer/utility/xmlstorage.h +++ b/reactos/subsys/system/explorer/utility/xmlstorage.h @@ -343,7 +343,28 @@ struct XMLNode : public String #else typedef std::map AttributeMap; #endif - typedef std::list Children; + + struct Children : public std::list + { + void assign(const Children& other) + { + clear(); + + for(Children::const_iterator it=other.begin(); it!=other.end(); ++it) + push_back(new XMLNode(**it)); + } + + void clear() + { + while(!empty()) { + XMLNode* node = back(); + pop_back(); + + node->clear(); + delete node; + } + } + }; // access to protected class members for XMLPos and XMLReader friend struct XMLPos; @@ -388,24 +409,14 @@ struct XMLNode : public String _trailing.erase(); _attributes.clear(); - - while(!_children.empty()) { - XMLNode* node = _children.back(); - _children.pop_back(); - - node->clear(); - delete node; - } + _children.clear(); String::erase(); } XMLNode& operator=(const XMLNode& other) { - _children.clear(); - - for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it) - _children.push_back(new XMLNode(**it)); + _children.assign(other._children); _attributes = other._attributes; @@ -424,6 +435,12 @@ struct XMLNode : public String } /// write access to an attribute + void put(const String& attr_name, const String& value) + { + _attributes[attr_name] = value; + } + + /// C++ write access to an attribute String& operator[](const String& attr_name) { return _attributes[attr_name]; @@ -441,7 +458,7 @@ struct XMLNode : public String } /// convenient value access in children node - String value(const String& name, const String& attr_name) const + String subvalue(const String& name, const String& attr_name) const { const XMLNode* node = find_first(name); @@ -452,7 +469,7 @@ struct XMLNode : public String } /// convenient storage of distinct values in children node - String& value(const String& name, const String& attr_name) + String& subvalue(const String& name, const String& attr_name) { XMLNode* node = find_first(name); @@ -466,7 +483,7 @@ struct XMLNode : public String #ifdef UNICODE /// convenient value access in children node - String value(const char* name, const char* attr_name) const + String subvalue(const char* name, const char* attr_name) const { const XMLNode* node = find_first(name); @@ -477,7 +494,7 @@ struct XMLNode : public String } /// convenient storage of distinct values in children node - String& value(const char* name, const String& attr_name) + String& subvalue(const char* name, const String& attr_name) { XMLNode* node = find_first(name); @@ -813,7 +830,46 @@ struct XMLPos { // don't copy _stack } + XMLPos(XMLNode* node, const String& name) + : _root(node), + _cur(node) + { + smart_create(name); + } + + XMLPos(XMLNode* node, const String& name, const String& attr_name, const String& attr_value) + : _root(node), + _cur(node) + { + smart_create(name, attr_name, attr_value); + } + + XMLPos(const XMLPos& other, const String& name) + : _root(other._root), + _cur(other._cur) + { + smart_create(name); + } + + XMLPos(const XMLPos& other, const String& name, const String& attr_name, const String& attr_value) + : _root(other._root), + _cur(other._cur) + { + smart_create(name, attr_name, attr_value); + } + /// access to current node + XMLNode& cur() + { + return *_cur; + } + + const XMLNode& cur() const + { + return *_cur; + } + + /// C++ access to current node operator const XMLNode*() const {return _cur;} operator XMLNode*() {return _cur;} @@ -824,6 +880,17 @@ struct XMLPos XMLNode& operator*() {return *_cur;} /// attribute access + String get(const String& attr_name) const + { + return _cur->get(attr_name); + } + + void put(const String& attr_name, const String& value) + { + _cur->put(attr_name, value); + } + + /// C++ attribute access template String get(const T& attr_name) const {return (*_cur)[attr_name];} String& operator[](const String& attr_name) {return (*_cur)[attr_name];} @@ -897,7 +964,7 @@ struct XMLPos if (node) go_to(node); else { - XMLNode* node = new XMLNode(name); + node = new XMLNode(name); add_down(node); (*node)[attr_name] = attr_value; } @@ -982,6 +1049,12 @@ struct const_XMLPos } /// access to current node + const XMLNode& cur() const + { + return *_cur; + } + + /// C++ access to current node operator const XMLNode*() const {return _cur;} const XMLNode* operator->() const {return _cur;} @@ -989,6 +1062,12 @@ struct const_XMLPos const XMLNode& operator*() const {return *_cur;} /// attribute access + String get(const String& attr_name) const + { + return _cur->get(attr_name); + } + + /// C++ attribute access template String get(const T& attr_name) const {return _cur->get(attr_name);} /// go back to previous position @@ -1069,7 +1148,7 @@ struct XMLBool XMLBool(LPCTSTR value, bool def=false) { if (value && *value) - _value = !_tcsicmp(value, TEXT("TRUE")); + _value = !_tcsicmp(value, TEXT("true")); else _value = def; } @@ -1079,17 +1158,7 @@ struct XMLBool const String& value = node->get(attr_name); if (!value.empty()) - _value = !_tcsicmp(value, TEXT("TRUE")); - else - _value = def; - } - - XMLBool(const XMLNode* node, const String& name, const String& attr_name, bool def=false) - { - const String& value = node->value(name, attr_name); - - if (!value.empty()) - _value = !_tcsicmp(value, TEXT("TRUE")); + _value = !_tcsicmp(value, TEXT("true")); else _value = def; } @@ -1106,7 +1175,7 @@ struct XMLBool operator LPCTSTR() const { - return _value? TEXT("TRUE"): TEXT("FALSE"); + return _value? TEXT("true"): TEXT("false"); } protected: @@ -1118,8 +1187,8 @@ private: struct XMLBoolRef { - XMLBoolRef(XMLNode* node, const String& name, const String& attr_name, bool def=false) - : _ref(node->value(name, attr_name)) + XMLBoolRef(XMLNode* node, const String& attr_name, bool def=false) + : _ref((*node)[attr_name]) { if (_ref.empty()) assign(def); @@ -1127,12 +1196,12 @@ struct XMLBoolRef operator bool() const { - return !_tcsicmp(_ref, TEXT("TRUE")); + return !_tcsicmp(_ref, TEXT("true")); } bool operator!() const { - return _tcsicmp(_ref, TEXT("TRUE"))? true: false; + return _tcsicmp(_ref, TEXT("true"))? true: false; } XMLBoolRef& operator=(bool value) @@ -1144,7 +1213,7 @@ struct XMLBoolRef void assign(bool value) { - _ref.assign(value? TEXT("TRUE"): TEXT("FALSE")); + _ref.assign(value? TEXT("true"): TEXT("false")); } void toggle() @@ -1182,16 +1251,6 @@ struct XMLInt _value = def; } - XMLInt(const XMLNode* node, const String& name, const String& attr_name, int def=0) - { - const String& value = node->value(name, attr_name); - - if (!value.empty()) - _value = _ttoi(value); - else - _value = def; - } - operator int() const { return _value; @@ -1213,8 +1272,8 @@ private: struct XMLIntRef { - XMLIntRef(XMLNode* node, const String& name, const String& attr_name, int def=0) - : _ref(node->value(name, attr_name)) + XMLIntRef(XMLNode* node, const String& attr_name, int def=0) + : _ref((*node)[attr_name]) { if (_ref.empty()) assign(def); @@ -1270,16 +1329,6 @@ struct XMLString _value = def; } - XMLString(const XMLNode* node, const String& name, const String& attr_name, LPCTSTR def=TEXT("")) - { - const String& value = node->value(name, attr_name); - - if (!value.empty()) - _value = value; - else - _value = def; - } - operator const String&() const { return _value; @@ -1299,8 +1348,15 @@ private: struct XMStringRef { - XMStringRef(XMLNode* node, const String& name, const String& attr_name, LPCTSTR def=TEXT("")) - : _ref(node->value(name, attr_name)) + XMStringRef(XMLNode* node, const String& attr_name, LPCTSTR def=TEXT("")) + : _ref((*node)[attr_name]) + { + if (_ref.empty()) + assign(def); + } + + XMStringRef(XMLNode* node, const String& node_name, const String& attr_name, LPCTSTR def=TEXT("")) + : _ref(node->subvalue(node_name, attr_name)) { if (_ref.empty()) assign(def); @@ -1351,7 +1407,7 @@ template<> #pragma warning(disable: 4355) #endif - /// XML file reader + /// XML reader base class struct XMLReaderBase { XMLReaderBase(XMLNode* node) @@ -1405,6 +1461,7 @@ protected: }; + /// XML file reader struct XMLReader : public XMLReaderBase { XMLReader(XMLNode* node, std::istream& in) @@ -1429,7 +1486,7 @@ protected: }; -struct XMLHeader : public std::string +struct XMLHeader { XMLHeader(const std::string& xml_version="1.0", const std::string& encoding="UTF-8", const std::string& doctype="") : _version(xml_version), @@ -1446,9 +1503,9 @@ struct XMLHeader : public std::string out << _doctype << '\n'; } - std::string _version; - std::string _encoding; - std::string _doctype; + std::string _version; + std::string _encoding; + std::string _doctype; }; @@ -1548,7 +1605,7 @@ struct XMLDoc : public XMLNode } XML_Error _last_error; - std::string _last_error_msg; + std::string _last_error_msg; };