diff --git a/reactos/subsys/system/explorer/dialogs/settings.cpp b/reactos/subsys/system/explorer/dialogs/settings.cpp index 0a6eddd37ec..1d6f80179e0 100644 --- a/reactos/subsys/system/explorer/dialogs/settings.cpp +++ b/reactos/subsys/system/explorer/dialogs/settings.cpp @@ -145,8 +145,11 @@ int DesktopSettingsDlg::Command(int id, int code) TaskbarSettingsDlg::TaskbarSettingsDlg(HWND hwnd) - : super(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); } int TaskbarSettingsDlg::Command(int id, int code) @@ -154,10 +157,30 @@ int TaskbarSettingsDlg::Command(int id, int code) switch(id) { case ID_CONFIG_NOTIFYAREA: Dialog::DoModal(IDD_NOTIFYAREA, WINDOW_CREATOR(TrayNotifyDlg), _hwnd); - return 0; + break; + + case ID_SHOW_CLOCK: + XMLBoolRef(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(); + SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0); + PropSheet_Changed(GetParent(_hwnd), _hwnd); + break; + + case PSN_RESET: + g_Globals._cfg = _cfg_org; + SendMessage(g_Globals._hwndDesktopBar, PM_REFRESH_CONFIG, 0, 0); + break; + + default: + return 1; } - return 1; + return 0; } diff --git a/reactos/subsys/system/explorer/dialogs/settings.h b/reactos/subsys/system/explorer/dialogs/settings.h index 88bcd4e4567..e555194fd4f 100644 --- a/reactos/subsys/system/explorer/dialogs/settings.h +++ b/reactos/subsys/system/explorer/dialogs/settings.h @@ -67,6 +67,9 @@ struct TaskbarSettingsDlg : public PropSheetPageDlg TaskbarSettingsDlg(HWND hwnd); virtual int Command(int id, int code); + +protected: + XMLDoc _cfg_org; }; diff --git a/reactos/subsys/system/explorer/explorer-cfg-template.xml b/reactos/subsys/system/explorer/explorer-cfg-template.xml index 98feb73007b..82a29c14976 100644 --- a/reactos/subsys/system/explorer/explorer-cfg-template.xml +++ b/reactos/subsys/system/explorer/explorer-cfg-template.xml @@ -10,6 +10,7 @@ + @@ -20,7 +21,7 @@ - diff --git a/reactos/subsys/system/explorer/explorer.cpp b/reactos/subsys/system/explorer/explorer.cpp index e390d7119a9..17ecf23f1b7 100644 --- a/reactos/subsys/system/explorer/explorer.cpp +++ b/reactos/subsys/system/explorer/explorer.cpp @@ -81,6 +81,7 @@ void ExplorerGlobals::init(HINSTANCE hInstance) _icon_cache.init(); } + bool ExplorerGlobals::read_cfg() { // read configuration file @@ -105,6 +106,26 @@ void ExplorerGlobals::write_cfg() } +XMLPos ExplorerGlobals::get_cfg() +{ + XMLPos pos(&_cfg); + + pos.create("explorer-cfg"); + + return pos; +} + +XMLPos ExplorerGlobals::get_cfg(const String& name) +{ + XMLPos pos(&_cfg); + + pos.create("explorer-cfg"); + pos.create(name); + + return pos; +} + + void _log_(LPCTSTR txt) { FmtString msg(TEXT("%s\n"), txt); diff --git a/reactos/subsys/system/explorer/explorer.h b/reactos/subsys/system/explorer/explorer.h index 31c341e7ab4..f2343425eff 100644 --- a/reactos/subsys/system/explorer/explorer.h +++ b/reactos/subsys/system/explorer/explorer.h @@ -55,6 +55,7 @@ #define PM_GET_WIDTH (WM_APP+0x18) #define PM_REFRESH (WM_APP+0x1B) +#define PM_REFRESH_CONFIG (WM_APP+0x1C) #define CLASSNAME_FRAME TEXT("CabinetWClass") // same class name for frame window as in MS Explorer diff --git a/reactos/subsys/system/explorer/explorer_intres.h b/reactos/subsys/system/explorer/explorer_intres.h index f58d5577221..29fee0ad3a4 100644 --- a/reactos/subsys/system/explorer/explorer_intres.h +++ b/reactos/subsys/system/explorer/explorer_intres.h @@ -140,6 +140,8 @@ #define IDC_NOTIFY_HIDE 1021 #define IDC_NOTIFY_AUTOHIDE 1022 #define IDC_LABEL4 1023 +#define ID_HIDE_INACTIVE_ICONS 1025 +#define ID_SHOW_CLOCK 1026 #define ID_REFRESH 1704 #define ID_ABOUT_WINEFILE 1705 #define IDC_FILETREE 10001 @@ -191,7 +193,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 166 #define _APS_NEXT_COMMAND_VALUE 40019 -#define _APS_NEXT_CONTROL_VALUE 1024 +#define _APS_NEXT_CONTROL_VALUE 1026 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/reactos/subsys/system/explorer/explorer_intres.rc b/reactos/subsys/system/explorer/explorer_intres.rc index e1685e8d92e..a3f3eb07ba7 100644 --- a/reactos/subsys/system/explorer/explorer_intres.rc +++ b/reactos/subsys/system/explorer/explorer_intres.rc @@ -806,6 +806,11 @@ STYLE WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Taskbar Properties" FONT 8, "MS Sans Serif" BEGIN + CONTROL "show &clock",ID_SHOW_CLOCK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,113,52,10 + CONTROL "&hide inactive notification icons", + ID_HIDE_INACTIVE_ICONS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,135,111,10 PUSHBUTTON "&Notifications...",ID_CONFIG_NOTIFYAREA,153,133,50,14 END @@ -821,13 +826,13 @@ STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME EXSTYLE WS_EX_APPWINDOW CAPTION "Configure Notification Icons" -FONT 8, "MS Sans Serif", 0, 0, 0x1 +FONT 8, "MS Sans Serif" BEGIN CONTROL "Tree1",IDC_NOTIFY_ICONS,"SysTreeView32",TVS_HASLINES | TVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,193,31 LTEXT "&Tooltip Text:",IDC_LABEL1,7,44,40,8 EDITTEXT IDC_NOTIFY_TOOLTIP,55,42,145,14,ES_AUTOHSCROLL - LTEXT "&Window Title:",IDC_LABEL2,7,63,44,8 + LTEXT "W&indow Title:",IDC_LABEL2,7,63,44,8 EDITTEXT IDC_NOTIFY_TITLE,55,60,145,14,ES_AUTOHSCROLL LTEXT "&Module Path:",IDC_LABEL3,7,81,43,8 EDITTEXT IDC_NOTIFY_MODULE,55,78,145,14,ES_AUTOHSCROLL @@ -838,9 +843,11 @@ BEGIN 107,29,10 CONTROL "a&utohide",IDC_NOTIFY_AUTOHIDE,"Button", BS_AUTORADIOBUTTON,112,107,43,10 + ICON "",IDC_PICTURE,173,100,20,20 + CONTROL "sho&w hidden",ID_SHOW_HIDDEN_ICONS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,131,56,10 DEFPUSHBUTTON "&OK",IDOK,91,129,50,14,WS_GROUP PUSHBUTTON "&Cancel",IDCANCEL,150,129,50,14 - ICON "",IDC_PICTURE,173,100,20,20 END diff --git a/reactos/subsys/system/explorer/globals.h b/reactos/subsys/system/explorer/globals.h index 2712e3fe5a4..b42152755fd 100644 --- a/reactos/subsys/system/explorer/globals.h +++ b/reactos/subsys/system/explorer/globals.h @@ -227,9 +227,13 @@ extern struct ExplorerGlobals ExplorerGlobals(); void init(HINSTANCE hInstance); + bool read_cfg(); void write_cfg(); + XMLPos get_cfg(); + XMLPos get_cfg(const String& name); + HINSTANCE _hInstance; ATOM _hframeClass; UINT _cfStrFName; diff --git a/reactos/subsys/system/explorer/taskbar/desktopbar.cpp b/reactos/subsys/system/explorer/taskbar/desktopbar.cpp index 088331a7c7d..59e003a25b4 100644 --- a/reactos/subsys/system/explorer/taskbar/desktopbar.cpp +++ b/reactos/subsys/system/explorer/taskbar/desktopbar.cpp @@ -242,6 +242,10 @@ LRESULT DesktopBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) return SendMessage(_hwndTaskBar, nmsg, wparam, lparam); break; + case PM_REFRESH_CONFIG: ///@todo read desktop bar settings + SendMessage(_hwndNotify, PM_REFRESH_CONFIG, 0, 0); + break; + case WM_TIMER: if (wparam == ID_TRAY_VOLUME) { KillTimer(_hwnd, wparam); diff --git a/reactos/subsys/system/explorer/taskbar/quicklaunch.h b/reactos/subsys/system/explorer/taskbar/quicklaunch.h index 3f269a4f72d..ff1230ca567 100644 --- a/reactos/subsys/system/explorer/taskbar/quicklaunch.h +++ b/reactos/subsys/system/explorer/taskbar/quicklaunch.h @@ -31,7 +31,7 @@ #define IDW_QUICKLAUNCHBAR 101 -#define PM_UPDATE_DESKTOP (WM_APP+0x1C) +#define PM_UPDATE_DESKTOP (WM_APP+0x23) #define IDC_FIRST_QUICK_ID 0x4000 diff --git a/reactos/subsys/system/explorer/taskbar/traynotify.cpp b/reactos/subsys/system/explorer/taskbar/traynotify.cpp index d964514e8f4..9ad323c0cce 100644 --- a/reactos/subsys/system/explorer/taskbar/traynotify.cpp +++ b/reactos/subsys/system/explorer/taskbar/traynotify.cpp @@ -177,8 +177,7 @@ NotifyArea::NotifyArea(HWND hwnd) _clock_width = 0; _last_icon_count = 0; _show_hidden = false; - - read_config(); + _hide_inactive = true; } NotifyArea::~NotifyArea() @@ -188,40 +187,68 @@ NotifyArea::~NotifyArea() write_config(); } +static bool get_hide_clock_from_registry() +{ + HKEY hkeyStuckRects = 0; + DWORD buffer[10]; + DWORD len = sizeof(buffer); + + bool hide_clock = false; + + // check if the clock should be hidden + if (!RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects2"), &hkeyStuckRects) && + !RegQueryValueEx(hkeyStuckRects, TEXT("Settings"), 0, NULL, (LPBYTE)buffer, &len) && + len==sizeof(buffer) && buffer[0]==sizeof(buffer)) + hide_clock = buffer[2] & 0x08? true: false; + + if (hkeyStuckRects) + RegCloseKey(hkeyStuckRects); + + return hide_clock; +} + void NotifyArea::read_config() { // read notification icon settings from XML configuration - XMLPos pos(&g_Globals._cfg); - - if (pos.go_down("explorer-cfg")) { - if (pos.go_down("notify-icons")) { - _show_hidden = XMLBool(pos, "option", "show-hidden"); - - XMLChildrenFilter icons(pos, "icon"); - - for(XMLChildrenFilter::iterator it=icons.begin(); it!=icons.end(); ++it) { - const XMLNode& node = **it; - - NotifyIconConfig cfg; - - cfg._name = node["name"]; - cfg._tipText = node["text"]; - cfg._windowTitle = node["window"]; - cfg._modulePath = node["module"]; - const string& mode = node["show"]; - - if (mode == "show") - cfg._mode = NIM_SHOW; - else if (mode == "hide") - cfg._mode = NIM_HIDE; - else //if (mode == "auto") - cfg._mode = NIM_HIDE; - - _cfg.push_back(cfg); - } + XMLPos pos = g_Globals.get_cfg(); +#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) + if (!g_Globals._SHRestricted || !SHRestricted(REST_HIDECLOCK)) +#endif + { + if (pos.go_down("desktopbar")) { + bool show = XMLBoolRef(pos, "options", "show-clock", !get_hide_clock_from_registry()); + show_clock(show); 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 + + XMLChildrenFilter icons(pos, "icon"); + + for(XMLChildrenFilter::iterator it=icons.begin(); it!=icons.end(); ++it) { + const XMLNode& node = **it; + + NotifyIconConfig cfg; + + cfg._name = node["name"]; + cfg._tipText = node["text"]; + cfg._windowTitle = node["window"]; + cfg._modulePath = node["module"]; + const string& mode = node["show"]; + + if (mode == "show") + cfg._mode = NIM_SHOW; + else if (mode == "hide") + cfg._mode = NIM_HIDE; + else //if (mode == "auto") + cfg._mode = NIM_HIDE; + + _cfg.push_back(cfg); + } pos.back(); } @@ -230,12 +257,16 @@ void NotifyArea::read_config() void NotifyArea::write_config() { // write notification icon settings to XML configuration file - XMLPos pos(&g_Globals._cfg); + XMLPos pos = g_Globals.get_cfg(); + + pos.create("desktopbar"); + XMLBoolRef(pos, "options", "show-clock") = _hwndClock!=0; + pos.back(); - pos.create("explorer-cfg"); pos.create("notify-icons"); - XMLBoolRef(pos, "option", "show-hidden") = _show_hidden; + XMLBoolRef(pos, "options", "hide-inactive") = _hide_inactive; + XMLBoolRef(pos, "options", "show-hidden") = _show_hidden; for(NotifyIconCfgList::iterator it=_cfg.begin(); it!=_cfg.end(); ++it) { NotifyIconConfig& cfg = *it; @@ -243,7 +274,7 @@ void NotifyArea::write_config() // search for the corresponding node using the original name pos.create("icon", "name", cfg._name); - // refresh name + // refresh unique name cfg.create_name(); pos["name"] = cfg._name; @@ -254,33 +285,14 @@ void NotifyArea::write_config() pos.back(); } - - pos.back(); - pos.back(); } -LRESULT NotifyArea::Init(LPCREATESTRUCT pcs) +void NotifyArea::show_clock(bool flag) { - if (super::Init(pcs)) - return 1; + bool vis = _hwndClock!=0; -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) - if (!g_Globals._SHRestricted || !SHRestricted(REST_HIDECLOCK)) -#endif - { - HKEY hkeyStuckRects = 0; - DWORD buffer[10]; - DWORD len = sizeof(buffer); - - bool hide_clock = false; - - // check if the clock should be hidden - if (!RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects2"), &hkeyStuckRects) && - !RegQueryValueEx(hkeyStuckRects, TEXT("Settings"), 0, NULL, (LPBYTE)buffer, &len) && - len==sizeof(buffer) && buffer[0]==sizeof(buffer)) - hide_clock = buffer[2] & 0x08? true: false; - - if (!hide_clock) { + if (vis != flag) { + if (flag) { // create clock window _hwndClock = ClockWindow::Create(_hwnd); @@ -288,11 +300,22 @@ LRESULT NotifyArea::Init(LPCREATESTRUCT pcs) ClientRect clock_size(_hwndClock); _clock_width = clock_size.right; } + } else { + DestroyWindow(_hwndClock); + _hwndClock = 0; + _clock_width = 0; } - if (hkeyStuckRects) - RegCloseKey(hkeyStuckRects); + SendMessage(GetParent(_hwnd), PM_RESIZE_CHILDREN, 0, 0); } +} + +LRESULT NotifyArea::Init(LPCREATESTRUCT pcs) +{ + if (super::Init(pcs)) + return 1; + + read_config(); SetTimer(_hwnd, 0, 1000, NULL); @@ -344,6 +367,10 @@ LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) case PM_GET_WIDTH: return _sorted_icons.size()*NOTIFYICON_DIST + NOTIFYAREA_SPACE + _clock_width; + case PM_REFRESH_CONFIG: + read_config(); + break; + case WM_CONTEXTMENU: { Point pt(lparam); ScreenToClient(_hwnd, &pt); @@ -629,11 +656,12 @@ void NotifyArea::Refresh(bool update) case NIM_AUTO: // automatically hide icons after long periods of inactivity - if (!(entry._dwState & NIS_HIDDEN)) - if (now-entry._lastChange > ICON_AUTOHIDE_SECONDS*1000) { - entry._dwState |= NIS_HIDDEN; - ++update; - } + if (_hide_inactive) + if (!(entry._dwState & NIS_HIDDEN)) + if (now-entry._lastChange > ICON_AUTOHIDE_SECONDS*1000) { + entry._dwState |= NIS_HIDDEN; + ++update; + } break; } } @@ -746,6 +774,7 @@ TrayNotifyDlg::TrayNotifyDlg(HWND hwnd) _icon_states_org[it->first] = IconStatePair(it->second._mode, it->second._dwState); _cfg_org = _pNotifyArea->_cfg; + _show_hidden_org = _pNotifyArea->_show_hidden; } SetWindowIcon(hwnd, IDI_REACTOS/*IDI_SEARCH*/); @@ -777,6 +806,7 @@ TrayNotifyDlg::TrayNotifyDlg(HWND hwnd) _resize_mgr.Add(IDC_NOTIFY_AUTOHIDE,MOVE_Y); _resize_mgr.Add(IDC_PICTURE, MOVE); + _resize_mgr.Add(ID_SHOW_HIDDEN_ICONS,MOVE_Y); _resize_mgr.Add(IDOK, MOVE); _resize_mgr.Add(IDCANCEL, MOVE); @@ -871,7 +901,7 @@ void TrayNotifyDlg::Refresh() DestroyIcon(hicon); } - // insert new configuration entry + CheckDlgButton(_hwnd, ID_SHOW_HIDDEN_ICONS, _pNotifyArea->_show_hidden? BST_CHECKED: BST_UNCHECKED); } TreeView_Expand(_tree_ctrl, _hitemCurrent_visible, TVE_EXPAND); @@ -956,6 +986,11 @@ int TrayNotifyDlg::Command(int id, int code) SetIconMode(NIM_AUTO); break; + case ID_SHOW_HIDDEN_ICONS: + if (_pNotifyArea) + SendMessage(*_pNotifyArea, WM_COMMAND, MAKEWPARAM(id,code), 0); + break; + case IDOK: EndDialog(_hwnd, id); break; @@ -965,6 +1000,7 @@ int TrayNotifyDlg::Command(int id, int code) if (_pNotifyArea) { // restore original icon states and configuration data _pNotifyArea->_cfg = _cfg_org; + _pNotifyArea->_show_hidden = _show_hidden_org; for(IconStateMap::const_iterator it=_icon_states_org.begin(); it!=_icon_states_org.end(); ++it) { NotifyInfo& info = _pNotifyArea->_icon_map[it->first]; diff --git a/reactos/subsys/system/explorer/taskbar/traynotify.h b/reactos/subsys/system/explorer/taskbar/traynotify.h index acfcf76a31f..df37640635e 100644 --- a/reactos/subsys/system/explorer/taskbar/traynotify.h +++ b/reactos/subsys/system/explorer/taskbar/traynotify.h @@ -143,6 +143,7 @@ protected: NotifyHook _hook; bool _show_hidden; + bool _hide_inactive; LRESULT Init(LPCREATESTRUCT pcs); LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam); @@ -160,7 +161,8 @@ protected: void read_config(); void write_config(); -public: // for TrayNotifyDlg + friend struct TrayNotifyDlg; + NotifyIconCfgList _cfg; map _window_modules; @@ -169,6 +171,8 @@ public: // for TrayNotifyDlg NotifyIconSet _sorted_icons; int _next_idx; size_t _last_icon_count; + + void show_clock(bool flag); }; @@ -191,6 +195,7 @@ protected: NotifyIconCfgList _cfg_org; IconStateMap _icon_states_org; + bool _show_hidden_org; HTREEITEM _hitemCurrent; HTREEITEM _hitemCurrent_visible; diff --git a/reactos/subsys/system/explorer/utility/xmlstorage.h b/reactos/subsys/system/explorer/utility/xmlstorage.h index 41378e149a1..7b58322b5b1 100644 --- a/reactos/subsys/system/explorer/utility/xmlstorage.h +++ b/reactos/subsys/system/explorer/utility/xmlstorage.h @@ -241,6 +241,15 @@ struct XMLNode : public String { } + XMLNode(const XMLNode& other) + : _content(other._content), + _trailing(other._trailing), + _attributes(other._attributes) + { + for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it) + _children.push_back(new XMLNode(**it)); + } + ~XMLNode() { while(!_children.empty()) { @@ -272,6 +281,30 @@ struct XMLNode : public String return ""; } + /// convenient value access in children node + String value(const String& name, const String& attr_name) const + { + XMLNode* node = find_first(name); + + if (node) + return (*node)[attr_name]; + else + return ""; + } + + /// convenient storage of distinct values in children node + String& value(const String& name, const String& attr_name) + { + XMLNode* node = find_first(name); + + if (!node) { + node = new XMLNode(name); + add_child(node); + } + + return (*node)[attr_name]; + } + const Children& get_children() const { return _children; @@ -470,6 +503,12 @@ struct XMLPos : _root(root), _cur(root) { + } + + XMLPos(const XMLPos& other) + : _root(other._root), + _cur(other._cur) + { // don't copy _stack } /// access to current node @@ -556,28 +595,6 @@ struct XMLPos } } - String& value(const String& name, const String& attr_name) - { - XMLNode* node = _cur->find_first(name); - - if (!node) { - node = new XMLNode(name); - _cur->add_child(node); - } - - return (*node)[attr_name]; - } - - String value(const String& name, const String& attr_name) const - { - XMLNode* node = _cur->find_first(name); - - if (node) - return (*node)[attr_name]; - else - return ""; - } - protected: XMLNode* _root; XMLNode* _cur; @@ -599,14 +616,22 @@ struct XMLBool { } - XMLBool(LPCTSTR value) + XMLBool(LPCTSTR value, bool def=false) { - _value = !_tcsicmp(value, TEXT("TRUE")); + if (value && *value) + _value = !_tcsicmp(value, TEXT("TRUE")); + else + _value = def; } - XMLBool(XMLPos& pos, const String& name, const String& attr_name) + XMLBool(XMLNode* node, const String& name, const String& attr_name, bool def=false) { - _value = !_tcsicmp(pos.value(name, attr_name), TEXT("TRUE")); + const String& value = node->value(name, attr_name); + + if (!value.empty()) + _value = !_tcsicmp(value, TEXT("TRUE")); + else + _value = def; } operator bool() const @@ -628,18 +653,35 @@ private: struct XMLBoolRef { - XMLBoolRef(XMLPos& pos, const String& name, const String& attr_name) - : _ref(pos.value(name, attr_name)) + XMLBoolRef(XMLNode* node, const String& name, const String& attr_name, bool def=false) + : _ref(node->value(name, attr_name)) { + if (_ref.empty()) + assign(def); + } + + operator bool() const + { + return !_tcsicmp(_ref, TEXT("TRUE")); } XMLBoolRef& operator=(bool value) { - _ref.assign(value? TEXT("TRUE"): TEXT("FALSE")); + assign(value); return *this; } + void assign(bool value) + { + _ref.assign(value? TEXT("TRUE"): TEXT("FALSE")); + } + + void toggle() + { + assign(!operator bool()); + } + protected: String& _ref; }; @@ -652,14 +694,22 @@ struct XMLNumber { } - XMLNumber(LPCTSTR value) + XMLNumber(LPCTSTR value, int def=0) { - _value = _ttoi(value); + if (value && *value) + _value = _ttoi(value); + else + _value = def; } - XMLNumber(XMLPos& pos, const String& name, const String& attr_name) + XMLNumber(XMLNode* node, const String& name, const String& attr_name, int def=0) { - _value = _ttoi(pos.value(name, attr_name)); + const String& value = node->value(name, attr_name); + + if (!value.empty()) + _value = _ttoi(node->value(name, attr_name)); + else + _value = def; } operator int() const @@ -683,19 +733,31 @@ private: struct XMLNumberRef { - XMLNumberRef(XMLPos& pos, const String& name, const String& attr_name) - : _ref(pos.value(name, attr_name)) + XMLNumberRef(XMLNode* node, const String& name, const String& attr_name, int def=0) + : _ref(node->value(name, attr_name)) { + if (_ref.empty()) + assign(def); } XMLNumberRef& operator=(int value) + { + assign(value); + + return *this; + } + + operator int() const + { + return _ttoi(_ref); + } + + void assign(int value) { TCHAR buffer[32]; _stprintf(buffer, TEXT("%d"), value); _ref.assign(buffer); - - return *this; } protected: