Commit in reactos/subsys/system/explorer on MAIN
explorer-cfg-template.xml+2-11.2 -> 1.3
explorer.cpp+211.62 -> 1.63
explorer.h+11.17 -> 1.18
explorer_intres.h+3-11.48 -> 1.49
explorer_intres.rc+10-31.66 -> 1.67
globals.h+41.35 -> 1.36
dialogs/settings.cpp+26-31.6 -> 1.7
       /settings.h+31.5 -> 1.6
taskbar/desktopbar.cpp+41.37 -> 1.38
       /quicklaunch.h+1-11.12 -> 1.13
       /traynotify.cpp+97-611.53 -> 1.54
       /traynotify.h+6-11.23 -> 1.24
utility/xmlstorage.h+99-371.5 -> 1.6
+277-108
13 modified files
more configuration options:
- show/hide clock
- disable automatic notification icon hiding

reactos/subsys/system/explorer
explorer-cfg-template.xml 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- explorer-cfg-template.xml	28 Mar 2004 12:00:45 -0000	1.2
+++ explorer-cfg-template.xml	28 Mar 2004 14:55:17 -0000	1.3
@@ -10,6 +10,7 @@
   </desktop>
 
   <desktopbar>
+    <options show-clock="TRUE"/>
     <positions>
 	  <bar name="quicklaunch" left="10" top="2" width="250" height="22"/>
 	  <bar name="taskbar" left="300" top="2" width="400" height="22"/>
@@ -20,7 +21,7 @@
   </taskbar>
 
   <notify-icons>
-    <option show-hidden="FALSE"/>
+    <options hide-inactive="TRUE" show-hidden="FALSE"/>
     <icon name="Volume Control" text="Volume" show="show"/>
   </notify-icons>
 

reactos/subsys/system/explorer
explorer.cpp 1.62 -> 1.63
diff -u -r1.62 -r1.63
--- explorer.cpp	22 Mar 2004 20:58:16 -0000	1.62
+++ explorer.cpp	28 Mar 2004 14:55:17 -0000	1.63
@@ -81,6 +81,7 @@
 	_icon_cache.init();
 }
 
+
 bool ExplorerGlobals::read_cfg()
 {
 	 // read configuration file
@@ -105,6 +106,26 @@
 }
 
 
+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);

reactos/subsys/system/explorer
explorer.h 1.17 -> 1.18
diff -u -r1.17 -r1.18
--- explorer.h	21 Mar 2004 00:31:13 -0000	1.17
+++ explorer.h	28 Mar 2004 14:55:17 -0000	1.18
@@ -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

reactos/subsys/system/explorer
explorer_intres.h 1.48 -> 1.49
diff -u -r1.48 -r1.49
--- explorer_intres.h	21 Mar 2004 00:31:13 -0000	1.48
+++ explorer_intres.h	28 Mar 2004 14:55:17 -0000	1.49
@@ -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

reactos/subsys/system/explorer
explorer_intres.rc 1.66 -> 1.67
diff -u -r1.66 -r1.67
--- explorer_intres.rc	21 Mar 2004 00:31:13 -0000	1.66
+++ explorer_intres.rc	28 Mar 2004 14:55:17 -0000	1.67
@@ -806,6 +806,11 @@
 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 @@
     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 @@
                     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
 
 

reactos/subsys/system/explorer
globals.h 1.35 -> 1.36
diff -u -r1.35 -r1.36
--- globals.h	27 Mar 2004 18:08:42 -0000	1.35
+++ globals.h	28 Mar 2004 14:55:17 -0000	1.36
@@ -227,9 +227,13 @@
 	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;

reactos/subsys/system/explorer/dialogs
settings.cpp 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- settings.cpp	21 Mar 2004 00:31:14 -0000	1.6
+++ settings.cpp	28 Mar 2004 14:55:17 -0000	1.7
@@ -145,8 +145,11 @@
 
 
 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 @@
 	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;
 }
 
 

reactos/subsys/system/explorer/dialogs
settings.h 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- settings.h	21 Mar 2004 00:31:14 -0000	1.5
+++ settings.h	28 Mar 2004 14:55:17 -0000	1.6
@@ -67,6 +67,9 @@
 	TaskbarSettingsDlg(HWND hwnd);
 
 	virtual int	Command(int id, int code);
+
+protected:
+	XMLDoc	_cfg_org;
 };
 
 

reactos/subsys/system/explorer/taskbar
desktopbar.cpp 1.37 -> 1.38
diff -u -r1.37 -r1.38
--- desktopbar.cpp	21 Mar 2004 00:31:14 -0000	1.37
+++ desktopbar.cpp	28 Mar 2004 14:55:18 -0000	1.38
@@ -242,6 +242,10 @@
 			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);

reactos/subsys/system/explorer/taskbar
quicklaunch.h 1.12 -> 1.13
diff -u -r1.12 -r1.13
--- quicklaunch.h	21 Mar 2004 00:31:14 -0000	1.12
+++ quicklaunch.h	28 Mar 2004 14:55:18 -0000	1.13
@@ -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
 

reactos/subsys/system/explorer/taskbar
traynotify.cpp 1.53 -> 1.54
diff -u -r1.53 -r1.54
--- traynotify.cpp	28 Mar 2004 12:00:45 -0000	1.53
+++ traynotify.cpp	28 Mar 2004 14:55:18 -0000	1.54
@@ -177,8 +177,7 @@
 	_clock_width = 0;
 	_last_icon_count = 0;
 	_show_hidden = false;
-
-	read_config();
+	_hide_inactive = true;
 }
 
 NotifyArea::~NotifyArea()
@@ -188,39 +187,67 @@
 	write_config();
 }
 
-void NotifyArea::read_config()
+static bool get_hide_clock_from_registry()
 {
-	 // read notification icon settings from XML configuration
-	XMLPos pos(&g_Globals._cfg);
+	HKEY hkeyStuckRects = 0;
+	DWORD buffer[10];
+	DWORD len = sizeof(buffer);
 
-	if (pos.go_down("explorer-cfg")) {
-		if (pos.go_down("notify-icons")) {
-			_show_hidden = XMLBool(pos, "option", "show-hidden");
+	bool hide_clock = false;
 
-			XMLChildrenFilter icons(pos, "icon");
+	 // 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;
 
-			for(XMLChildrenFilter::iterator it=icons.begin(); it!=icons.end(); ++it) {
-				const XMLNode& node = **it;
+	if (hkeyStuckRects)
+		RegCloseKey(hkeyStuckRects);
 
-				NotifyIconConfig cfg;
+	return hide_clock;
+}
 
-				cfg._name = node["name"];
-				cfg._tipText = node["text"];
-				cfg._windowTitle = node["window"];
-				cfg._modulePath = node["module"];
-				const string& mode = node["show"];
+void NotifyArea::read_config()
+{
+	 // read notification icon settings from XML configuration
+	XMLPos pos = g_Globals.get_cfg();
 
-				if (mode == "show")
-					cfg._mode = NIM_SHOW;
-				else if (mode == "hide")
-					cfg._mode = NIM_HIDE;
-				else //if (mode == "auto")
-					cfg._mode = NIM_HIDE;
+#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();
+		}
+	}
 
-				_cfg.push_back(cfg);
-			}
+	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;
 
-			pos.back();
+			_cfg.push_back(cfg);
 		}
 
 		pos.back();
@@ -230,12 +257,16 @@
 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 @@
 		 // 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 @@
 
 		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 @@
 				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 @@
 	  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 @@
 
 		  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 @@
 			_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 @@
 	_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 @@
 				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 @@
 			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 @@
 			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];

reactos/subsys/system/explorer/taskbar
traynotify.h 1.23 -> 1.24
diff -u -r1.23 -r1.24
--- traynotify.h	27 Mar 2004 14:02:28 -0000	1.23
+++ traynotify.h	28 Mar 2004 14:55:18 -0000	1.24
@@ -143,6 +143,7 @@
 	NotifyHook _hook;
 
 	bool	_show_hidden;
+	bool	_hide_inactive;
 
 	LRESULT Init(LPCREATESTRUCT pcs);
 	LRESULT	WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
@@ -160,7 +161,8 @@
 	void	read_config();
 	void	write_config();
 
-public:	// for TrayNotifyDlg
+	friend struct TrayNotifyDlg;
+
 	NotifyIconCfgList _cfg;
 
 	map<HWND, String> _window_modules;
@@ -169,6 +171,8 @@
 	NotifyIconSet _sorted_icons;
 	int		_next_idx;
 	size_t	_last_icon_count;
+
+	void	show_clock(bool flag);
 };
 
 
@@ -191,6 +195,7 @@
 
 	NotifyIconCfgList _cfg_org;
 	IconStateMap _icon_states_org;
+	bool	_show_hidden_org;
 
 	HTREEITEM _hitemCurrent;
 	HTREEITEM _hitemCurrent_visible;

reactos/subsys/system/explorer/utility
xmlstorage.h 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- xmlstorage.h	28 Mar 2004 12:00:46 -0000	1.5
+++ xmlstorage.h	28 Mar 2004 14:55:18 -0000	1.6
@@ -241,6 +241,15 @@
 	{
 	}
 
+	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 @@
 			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;
@@ -472,6 +505,12 @@
 	{
 	}
 
+	XMLPos(const XMLPos& other)
+	 :	_root(other._root),
+		_cur(other._cur)
+	{	// don't copy _stack
+	}
+
 	 /// access to current node
 	operator XMLNode*() {return _cur;}
 	operator const XMLNode*() const {return _cur;}
@@ -556,28 +595,6 @@
 		}
 	}
 
-	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 @@
 	{
 	}
 
-	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 @@
 
 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 @@
 	{
 	}
 
-	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 @@
 
 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:
CVSspam 0.2.8