context menus for qick launch bar

svn path=/trunk/; revision=10363
This commit is contained in:
Martin Fuchs 2004-08-02 19:16:18 +00:00
parent efb2135435
commit 62f1a2a671
15 changed files with 247 additions and 139 deletions

View file

@ -81,7 +81,7 @@ DELAYIMPORTS = oleaut32 wsock32
all: precomp.h.gch $(TARGET) all: precomp.h.gch $(TARGET)
precomp.h.gch: precomp.h.gch: *.h utility/*.h shell/*.h desktop/*.h
$(CXX) $(CFLAGS) precomp.h $(CXX) $(CFLAGS) precomp.h
$(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll libexpat.dll $(TARGET): $(OBJECTS) $(PROGRAM)$(RES_SUFFIX) notifyhook.dll libexpat.dll

View file

@ -159,8 +159,10 @@ TaskbarSettingsDlg::TaskbarSettingsDlg(HWND hwnd)
: super(hwnd), : super(hwnd),
_cfg_org(g_Globals._cfg) _cfg_org(g_Globals._cfg)
{ {
CheckDlgButton(hwnd, ID_SHOW_CLOCK, XMLBool(g_Globals.get_cfg("desktopbar"), "options", "show-clock", true)? BST_CHECKED: BST_UNCHECKED); XMLPos options(g_Globals.get_cfg("desktopbar"), "options");
CheckDlgButton(hwnd, ID_HIDE_INACTIVE_ICONS, XMLBool(g_Globals.get_cfg("notify-icons"), "options", "hide-inactive", true)? BST_CHECKED: BST_UNCHECKED);
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) int TaskbarSettingsDlg::Notify(int id, NMHDR* pnmh)
@ -190,13 +192,13 @@ int TaskbarSettingsDlg::Command(int id, int code)
break; break;
case ID_SHOW_CLOCK: 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); SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0);
PropSheet_Changed(GetParent(_hwnd), _hwnd); PropSheet_Changed(GetParent(_hwnd), _hwnd);
break; break;
case ID_HIDE_INACTIVE_ICONS: 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); SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0);
PropSheet_Changed(GetParent(_hwnd), _hwnd); PropSheet_Changed(GetParent(_hwnd), _hwnd);
break; break;

View file

@ -1,6 +1,5 @@
- rewrite autostart code and include all possible autostart locations - rewrite autostart code and include all possible autostart locations
- read "DESCRIPT.ION" files to display file descriptions - read "DESCRIPT.ION" files to display file descriptions
- context menus for quick launch bar
- detect display mode changes and adjust desktop bar size - detect display mode changes and adjust desktop bar size
- handling of full screen applications - handling of full screen applications
- implement additional deskbands - implement additional deskbands

View file

@ -199,6 +199,10 @@ SOURCE=.\Makefile.MinGW
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\Makefile.PCH
# End Source File
# Begin Source File
SOURCE=.\Makefile.Wine SOURCE=.\Makefile.Wine
# End Source File # End Source File
# End Target # End Target

View file

@ -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<HRESULT(WINAPI*)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEMIDLIST*)> 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) HRESULT Entry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut)
{ {
TCHAR path[MAX_PATH]; TCHAR path[MAX_PATH];

View file

@ -105,13 +105,14 @@ public:
void smart_scan(SORT_ORDER sortOrder=SORT_NAME, int scan_flags=SCAN_ALL); void smart_scan(SORT_ORDER sortOrder=SORT_NAME, int scan_flags=SCAN_ALL);
void extract_icon(); void extract_icon();
virtual void read_directory(int scan_flags=SCAN_ALL) {} virtual void read_directory(int scan_flags=SCAN_ALL) {}
virtual const void* get_next_path_component(const void*) const {return NULL;} virtual const void* get_next_path_component(const void*) const {return NULL;}
virtual Entry* find_entry(const void*) {return NULL;} virtual Entry* find_entry(const void*) {return NULL;}
virtual bool get_path(PTSTR path) const = 0; virtual bool get_path(PTSTR path) const = 0;
virtual ShellPath create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;} virtual ShellPath create_absolute_pidl() const {return (LPCITEMIDLIST)NULL;}
virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut); virtual HRESULT GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut);
virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL); virtual BOOL launch_entry(HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL);
virtual HRESULT do_context_menu(HWND hwnd, const POINT& pos);
}; };

View file

@ -496,6 +496,7 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
HWND hpanel = (HWND) wparam; HWND hpanel = (HWND) wparam;
POINTS& pos = MAKEPOINTS(lparam); POINTS& pos = MAKEPOINTS(lparam);
POINT pt; POINTSTOPOINT(pt, pos); POINT pt; POINTSTOPOINT(pt, pos);
POINT pt_screen = pt;
ScreenToClient(hpanel, &pt); ScreenToClient(hpanel, &pt);
SendMessage(hpanel, WM_LBUTTONDOWN, 0, MAKELONG(pt.x, pt.y)); SendMessage(hpanel, WM_LBUTTONDOWN, 0, MAKELONG(pt.x, pt.y));
SendMessage(hpanel, WM_LBUTTONUP, 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) { if (idx != -1) {
Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx); Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx);
ShellPath shell_path = entry->create_absolute_pidl(); CHECKERROR(entry->do_context_menu(_hwnd, pt_screen));
LPCITEMIDLIST pidl_abs = shell_path;
if (pidl_abs) {
IShellFolder* parentFolder;
LPCITEMIDLIST pidlLast;
static DynamicFct<HRESULT(WINAPI*)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEMIDLIST*)> 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));
}
}
} }
break;} break;}

View file

@ -198,32 +198,13 @@ void ShellBrowser::OnTreeItemRClick(int idCtrl, LPNMHDR pnmh)
TreeView_HitTest(_left_hwnd, &tvhti); TreeView_HitTest(_left_hwnd, &tvhti);
if (TVHT_ONITEM & tvhti.flags) { if (TVHT_ONITEM & tvhti.flags) {
ClientToScreen(_left_hwnd, &tvhti.pt); LPARAM itemData = TreeView_GetItemData(_left_hwnd, tvhti.hItem);
Tree_DoItemMenu(_left_hwnd, tvhti.hItem, &tvhti.pt);
}
}
void ShellBrowser::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen) if (itemData) {
{ Entry* entry = (Entry*)itemData;
CONTEXT("ShellBrowser::Tree_DoItemMenu()"); ClientToScreen(_left_hwnd, &tvhti.pt);
LPARAM itemData = TreeView_GetItemData(hwndTreeView, hItem); CHECKERROR(entry->do_context_menu(_hwnd, tvhti.pt));
if (itemData) {
Entry* entry = (Entry*)itemData;
if (entry->_etype == ET_SHELL) {
ShellDirectory* dir = static_cast<ShellDirectory*>(entry->_up);
ShellFolder folder = dir? dir->_folder: GetDesktopFolder();
LPCITEMIDLIST pidl = static_cast<ShellEntry*>(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));
} }
} }
} }

View file

@ -132,7 +132,6 @@ struct ShellBrowser : public IShellBrowserImpl
HRESULT OnDefaultCommand(LPIDA pida); HRESULT OnDefaultCommand(LPIDA pida);
void UpdateFolderView(IShellFolder* folder); void UpdateFolderView(IShellFolder* folder);
void Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPOINT pptScreen);
HTREEITEM select_entry(HTREEITEM hitem, Entry* entry, bool expand=true); HTREEITEM select_entry(HTREEITEM hitem, Entry* entry, bool expand=true);
protected: protected:

View file

@ -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<ShellDirectory*>(_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) HRESULT ShellEntry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut)
{ {
LPCITEMIDLIST pidl = _pidl; LPCITEMIDLIST pidl = _pidl;

View file

@ -32,12 +32,13 @@ struct ShellEntry : public Entry
ShellEntry(Entry* parent, LPITEMIDLIST shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {} 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) {} ShellEntry(Entry* parent, const ShellPath& shell_path) : Entry(parent, ET_SHELL), _pidl(shell_path) {}
virtual bool get_path(PTSTR path) const; virtual bool get_path(PTSTR path) const;
virtual ShellPath create_absolute_pidl() 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 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 ShellPath _pidl; // parent relative PIDL

View file

@ -132,6 +132,7 @@ void QuickLaunchBar::AddShortcuts()
int cy = HIWORD(size); int cy = HIWORD(size);
RECT rect = {0, 0, cx, cy}; RECT rect = {0, 0, cx, cy};
RECT textRect = {0, 0, cx-7, cy-7}; RECT textRect = {0, 0, cx-7, cy-7};
for(int i=0; i<DESKTOP_COUNT; ++i) { for(int i=0; i<DESKTOP_COUNT; ++i) {
HBITMAP hbmp = CreateCompatibleBitmap(canvas, cx, cy); HBITMAP hbmp = CreateCompatibleBitmap(canvas, cx, cy);
HBITMAP hbmp_old = SelectBitmap(hdc, hbmp); HBITMAP hbmp_old = SelectBitmap(hdc, hbmp);
@ -230,7 +231,28 @@ LRESULT QuickLaunchBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
UpdateDesktopButtons(wparam); UpdateDesktopButtons(wparam);
break; break;
default: case WM_CONTEXTMENU: {
TBBUTTON btn;
QuickLaunchMap::iterator it;
Point pt(lparam), clnt_pt=pt;
ScreenToClient(_hwnd, &clnt_pt);
Entry* entry = NULL;
int idx = SendMessage(_hwnd, TB_HITTEST, 0, (LPARAM)&clnt_pt);
if (idx>=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); return super::WndProc(nmsg, wparam, lparam);
} }

View file

@ -216,14 +216,16 @@ void NotifyArea::read_config()
#endif #endif
{ {
if (pos.go_down("desktopbar")) { 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(); pos.back();
} }
} }
if (pos.go_down("notify-icons")) { if (pos.go_down("notify-icons")) {
_hide_inactive = XMLBool(pos, "options", "hide-inactive", true); ///@todo read default setting from registry XMLPos options(pos, "options");
_show_hidden = XMLBool(pos, "options", "show-hidden", false); ///@todo read default setting from registry
_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"); XMLChildrenFilter icons(pos, "icon");
@ -260,13 +262,14 @@ void NotifyArea::write_config()
XMLPos pos = g_Globals.get_cfg(); XMLPos pos = g_Globals.get_cfg();
pos.smart_create("desktopbar"); pos.smart_create("desktopbar");
XMLBoolRef(pos, "options", "show-clock") = _hwndClock!=0; XMLBoolRef(XMLPos(pos,"options"), "show-clock") = _hwndClock!=0;
pos.back(); pos.back();
pos.smart_create("notify-icons"); pos.smart_create("notify-icons");
XMLBoolRef(pos, "options", "hide-inactive") = _hide_inactive; XMLPos options(pos, "options");
XMLBoolRef(pos, "options", "show-hidden") = _show_hidden; XMLBoolRef(options, "hide-inactive") = _hide_inactive;
XMLBoolRef(options, "show-hidden") = _show_hidden;
for(NotifyIconCfgList::iterator it=_cfg.begin(); it!=_cfg.end(); ++it) { for(NotifyIconCfgList::iterator it=_cfg.begin(); it!=_cfg.end(); ++it) {
NotifyIconConfig& cfg = *it; NotifyIconConfig& cfg = *it;
@ -285,6 +288,8 @@ void NotifyArea::write_config()
pos.back(); pos.back();
} }
pos.back(); // smart_create
} }
void NotifyArea::show_clock(bool flag) void NotifyArea::show_clock(bool flag)

View file

@ -81,7 +81,7 @@ HRESULT STDMETHODCALLTYPE IShellBrowserImpl::QueryService(REFGUID guidService, R
return S_OK; 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 return E_FAIL; ///@todo implement IOleCommandTarget
} }

View file

@ -343,7 +343,28 @@ struct XMLNode : public String
#else #else
typedef std::map<String, String> AttributeMap; typedef std::map<String, String> AttributeMap;
#endif #endif
typedef std::list<XMLNode*> Children;
struct Children : public std::list<XMLNode*>
{
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 // access to protected class members for XMLPos and XMLReader
friend struct XMLPos; friend struct XMLPos;
@ -388,24 +409,14 @@ struct XMLNode : public String
_trailing.erase(); _trailing.erase();
_attributes.clear(); _attributes.clear();
_children.clear();
while(!_children.empty()) {
XMLNode* node = _children.back();
_children.pop_back();
node->clear();
delete node;
}
String::erase(); String::erase();
} }
XMLNode& operator=(const XMLNode& other) XMLNode& operator=(const XMLNode& other)
{ {
_children.clear(); _children.assign(other._children);
for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it)
_children.push_back(new XMLNode(**it));
_attributes = other._attributes; _attributes = other._attributes;
@ -424,6 +435,12 @@ struct XMLNode : public String
} }
/// write access to an attribute /// 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) String& operator[](const String& attr_name)
{ {
return _attributes[attr_name]; return _attributes[attr_name];
@ -441,7 +458,7 @@ struct XMLNode : public String
} }
/// convenient value access in children node /// 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); const XMLNode* node = find_first(name);
@ -452,7 +469,7 @@ struct XMLNode : public String
} }
/// convenient storage of distinct values in children node /// 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); XMLNode* node = find_first(name);
@ -466,7 +483,7 @@ struct XMLNode : public String
#ifdef UNICODE #ifdef UNICODE
/// convenient value access in children node /// 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); const XMLNode* node = find_first(name);
@ -477,7 +494,7 @@ struct XMLNode : public String
} }
/// convenient storage of distinct values in children node /// 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); XMLNode* node = find_first(name);
@ -813,7 +830,46 @@ struct XMLPos
{ // don't copy _stack { // 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 /// 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 const XMLNode*() const {return _cur;}
operator XMLNode*() {return _cur;} operator XMLNode*() {return _cur;}
@ -824,6 +880,17 @@ struct XMLPos
XMLNode& operator*() {return *_cur;} XMLNode& operator*() {return *_cur;}
/// attribute access /// 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<typename T> String get(const T& attr_name) const {return (*_cur)[attr_name];} template<typename T> String get(const T& attr_name) const {return (*_cur)[attr_name];}
String& operator[](const String& attr_name) {return (*_cur)[attr_name];} String& operator[](const String& attr_name) {return (*_cur)[attr_name];}
@ -897,7 +964,7 @@ struct XMLPos
if (node) if (node)
go_to(node); go_to(node);
else { else {
XMLNode* node = new XMLNode(name); node = new XMLNode(name);
add_down(node); add_down(node);
(*node)[attr_name] = attr_value; (*node)[attr_name] = attr_value;
} }
@ -982,6 +1049,12 @@ struct const_XMLPos
} }
/// access to current node /// access to current node
const XMLNode& cur() const
{
return *_cur;
}
/// C++ access to current node
operator const XMLNode*() const {return _cur;} operator const XMLNode*() const {return _cur;}
const XMLNode* operator->() const {return _cur;} const XMLNode* operator->() const {return _cur;}
@ -989,6 +1062,12 @@ struct const_XMLPos
const XMLNode& operator*() const {return *_cur;} const XMLNode& operator*() const {return *_cur;}
/// attribute access /// attribute access
String get(const String& attr_name) const
{
return _cur->get(attr_name);
}
/// C++ attribute access
template<typename T> String get(const T& attr_name) const {return _cur->get(attr_name);} template<typename T> String get(const T& attr_name) const {return _cur->get(attr_name);}
/// go back to previous position /// go back to previous position
@ -1069,7 +1148,7 @@ struct XMLBool
XMLBool(LPCTSTR value, bool def=false) XMLBool(LPCTSTR value, bool def=false)
{ {
if (value && *value) if (value && *value)
_value = !_tcsicmp(value, TEXT("TRUE")); _value = !_tcsicmp(value, TEXT("true"));
else else
_value = def; _value = def;
} }
@ -1079,17 +1158,7 @@ struct XMLBool
const String& value = node->get(attr_name); const String& value = node->get(attr_name);
if (!value.empty()) if (!value.empty())
_value = !_tcsicmp(value, TEXT("TRUE")); _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"));
else else
_value = def; _value = def;
} }
@ -1106,7 +1175,7 @@ struct XMLBool
operator LPCTSTR() const operator LPCTSTR() const
{ {
return _value? TEXT("TRUE"): TEXT("FALSE"); return _value? TEXT("true"): TEXT("false");
} }
protected: protected:
@ -1118,8 +1187,8 @@ private:
struct XMLBoolRef struct XMLBoolRef
{ {
XMLBoolRef(XMLNode* node, const String& name, const String& attr_name, bool def=false) XMLBoolRef(XMLNode* node, const String& attr_name, bool def=false)
: _ref(node->value(name, attr_name)) : _ref((*node)[attr_name])
{ {
if (_ref.empty()) if (_ref.empty())
assign(def); assign(def);
@ -1127,12 +1196,12 @@ struct XMLBoolRef
operator bool() const operator bool() const
{ {
return !_tcsicmp(_ref, TEXT("TRUE")); return !_tcsicmp(_ref, TEXT("true"));
} }
bool operator!() const bool operator!() const
{ {
return _tcsicmp(_ref, TEXT("TRUE"))? true: false; return _tcsicmp(_ref, TEXT("true"))? true: false;
} }
XMLBoolRef& operator=(bool value) XMLBoolRef& operator=(bool value)
@ -1144,7 +1213,7 @@ struct XMLBoolRef
void assign(bool value) void assign(bool value)
{ {
_ref.assign(value? TEXT("TRUE"): TEXT("FALSE")); _ref.assign(value? TEXT("true"): TEXT("false"));
} }
void toggle() void toggle()
@ -1182,16 +1251,6 @@ struct XMLInt
_value = def; _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 operator int() const
{ {
return _value; return _value;
@ -1213,8 +1272,8 @@ private:
struct XMLIntRef struct XMLIntRef
{ {
XMLIntRef(XMLNode* node, const String& name, const String& attr_name, int def=0) XMLIntRef(XMLNode* node, const String& attr_name, int def=0)
: _ref(node->value(name, attr_name)) : _ref((*node)[attr_name])
{ {
if (_ref.empty()) if (_ref.empty())
assign(def); assign(def);
@ -1270,16 +1329,6 @@ struct XMLString
_value = def; _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 operator const String&() const
{ {
return _value; return _value;
@ -1299,8 +1348,15 @@ private:
struct XMStringRef struct XMStringRef
{ {
XMStringRef(XMLNode* node, const String& name, const String& attr_name, LPCTSTR def=TEXT("")) XMStringRef(XMLNode* node, const String& attr_name, LPCTSTR def=TEXT(""))
: _ref(node->value(name, attr_name)) : _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()) if (_ref.empty())
assign(def); assign(def);
@ -1351,7 +1407,7 @@ template<>
#pragma warning(disable: 4355) #pragma warning(disable: 4355)
#endif #endif
/// XML file reader /// XML reader base class
struct XMLReaderBase struct XMLReaderBase
{ {
XMLReaderBase(XMLNode* node) XMLReaderBase(XMLNode* node)
@ -1405,6 +1461,7 @@ protected:
}; };
/// XML file reader
struct XMLReader : public XMLReaderBase struct XMLReader : public XMLReaderBase
{ {
XMLReader(XMLNode* node, std::istream& in) 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="") XMLHeader(const std::string& xml_version="1.0", const std::string& encoding="UTF-8", const std::string& doctype="")
: _version(xml_version), : _version(xml_version),
@ -1446,9 +1503,9 @@ struct XMLHeader : public std::string
out << _doctype << '\n'; out << _doctype << '\n';
} }
std::string _version; std::string _version;
std::string _encoding; std::string _encoding;
std::string _doctype; std::string _doctype;
}; };
@ -1548,7 +1605,7 @@ struct XMLDoc : public XMLNode
} }
XML_Error _last_error; XML_Error _last_error;
std::string _last_error_msg; std::string _last_error_msg;
}; };