configuration dialog to choose between MDI and SDI mode with persistent storage

svn path=/trunk/; revision=10988
This commit is contained in:
Martin Fuchs 2004-09-22 22:57:00 +00:00
parent 40637ed24b
commit 8e81012956
13 changed files with 356 additions and 155 deletions

View file

@ -229,3 +229,38 @@ int StartmenuSettingsDlg::Command(int id, int code)
*/
return 1;
}
MdiSdiDlg::MdiSdiDlg(HWND hwnd)
: super(hwnd)
{
CenterWindow(hwnd);
XMLPos explorer_options(g_Globals.get_cfg("general"), "explorer");
bool mdi = XMLBool(explorer_options, "mdi", true);
int id = mdi? IDC_MDI: IDC_SDI;
CheckDlgButton(hwnd, id, BST_CHECKED);
SetFocus(GetDlgItem(hwnd, id));
}
int MdiSdiDlg::Command(int id, int code)
{
if (code == BN_CLICKED) {
switch(id) {
case IDOK: {
bool mdi = IsDlgButtonChecked(_hwnd, IDC_MDI)==BST_CHECKED;
XMLPos explorer_options(g_Globals.get_cfg("general"), "explorer");
XMLBoolRef(explorer_options, "mdi") = mdi;
} // fall through
case IDCANCEL:
EndDialog(_hwnd, id);
break;
}
return 0;
}
return 1;
}

View file

@ -85,3 +85,15 @@ struct StartmenuSettingsDlg : public PropSheetPageDlg
virtual int Command(int id, int code);
};
/// configuration dialog to choose between MDI and SDI mode
struct MdiSdiDlg : public ResizeController<Dialog>
{
typedef ResizeController<Dialog> super;
MdiSdiDlg(HWND hwnd);
protected:
virtual int Command(int id, int code);
};

View file

@ -2,6 +2,7 @@
<explorer-cfg>
<general>
<look-and-feel name="classic"/>
<explorer mdi="true"/>
<language name="EN"/>
</general>

View file

@ -39,6 +39,8 @@
#include <fcntl.h> // for _O_RDONLY
#endif
#include "dialogs/settings.h" // for MdiSdiDlg
extern "C" int initialize_gdb_stub(); // start up GDB stub
@ -534,7 +536,13 @@ void explorer_show_frame(int cmdshow, LPTSTR lpCmdLine)
g_Globals._prescan_nodes = false;
bool mdi = true; //@@
XMLPos explorer_options(g_Globals.get_cfg("general"), "explorer");
XS_String mdiStr = XMLString(explorer_options, "mdi");
if (mdiStr.empty())
Dialog::DoModal(IDD_MDI_SDI, WINDOW_CREATOR(MdiSdiDlg), g_Globals._hwndDesktop);
bool mdi = XMLBool(explorer_options, "mdi", true);
// create main window
MainFrameBase::Create(lpCmdLine, mdi, cmdshow);

View file

@ -94,6 +94,7 @@
#define IDB_ICON_ALIGN_2 155
#define IDD_NOTIFYAREA 155
#define IDB_ICON_ALIGN_3 156
#define IDD_MDI_SDI 156
#define IDB_ICON_ALIGN_4 157
#define IDB_ICON_ALIGN_5 158
#define IDB_ICON_ALIGN_6 159
@ -151,6 +152,8 @@
#define IDC_CHECK_ENTRIES 1028
#define IDC_VERSION_TXT 1029
#define IDC_WIN_VERSION 1030
#define IDC_MDI 1030
#define IDC_SDI 1031
#define ID_REFRESH 1704
#define ID_ABOUT_WINEFILE 1705
#define IDS_VERSION_STR 5000
@ -187,6 +190,7 @@
#define ID_CONFIG_TIME 40018
#define ID_VIEW_MDI 40019
#define ID_VIEW_SDI 40020
#define ID_TOOLS_OPTIONS 40021
#define ID_SWITCH_DESKTOP_1 50000
#define ID_WINDOW_NEW 0xE130
#define ID_WINDOW_ARRANGE 0xE131
@ -205,8 +209,8 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 166
#define _APS_NEXT_COMMAND_VALUE 40021
#define _APS_NEXT_CONTROL_VALUE 1030
#define _APS_NEXT_COMMAND_VALUE 40022
#define _APS_NEXT_CONTROL_VALUE 1033
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View file

@ -53,6 +53,10 @@ BEGIN
MENUITEM "Aranjeazã automat", ID_WINDOW_AUTOSORT
MENUITEM "Aranjeazã &Simbolurile", ID_WINDOW_ARRANGE
END
POPUP "&Tools"
BEGIN
MENUITEM "&Options", ID_TOOLS_OPTIONS
END
POPUP "&Ajutor"
BEGIN
MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ
@ -77,6 +81,10 @@ BEGIN
MENUITEM "F&ull Screen\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
MENUITEM "&MDI", ID_VIEW_MDI
END
POPUP "&Tools"
BEGIN
MENUITEM "&Options", ID_TOOLS_OPTIONS
END
POPUP "&Ajutor"
BEGIN
MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ
@ -358,7 +366,7 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "&Aktualisieren\tF5", ID_REFRESH
MENUITEM "&Vollbild\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
MENUITEM "&SDI", ID_VIEW_SDI
MENUITEM "SDI", ID_VIEW_SDI
END
POPUP "&Fenster"
BEGIN
@ -369,6 +377,10 @@ BEGIN
MENUITEM "au&tomatisch anordnen", ID_WINDOW_AUTOSORT
MENUITEM "&Symbole anordnen", ID_WINDOW_ARRANGE
END
POPUP "&Extras"
BEGIN
MENUITEM "&Optionen", ID_TOOLS_OPTIONS
END
POPUP "&Hilfe"
BEGIN
MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ
@ -393,6 +405,10 @@ BEGIN
MENUITEM "&Vollbild\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
MENUITEM "&MDI", ID_VIEW_MDI
END
POPUP "&Extras"
BEGIN
MENUITEM "&Optionen", ID_TOOLS_OPTIONS
END
POPUP "&Hilfe"
BEGIN
MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ
@ -642,12 +658,12 @@ BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOL_BAR
MENUITEM "&Extra Bar", ID_VIEW_EXTRA_BAR
MENUITEM "&Drivebar", ID_VIEW_DRIVE_BAR, CHECKED
MENUITEM "&Side Bar", ID_VIEW_SIDE_BAR
MENUITEM "S&ide Bar", ID_VIEW_SIDE_BAR
MENUITEM "&Status Bar", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Refresh\tF5", ID_REFRESH
MENUITEM "F&ull Screen\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
MENUITEM "&SDI", ID_VIEW_SDI
MENUITEM "SDI", ID_VIEW_SDI
END
POPUP "&Window"
BEGIN
@ -658,29 +674,9 @@ BEGIN
MENUITEM "Arrange Automatically", ID_WINDOW_AUTOSORT
MENUITEM "Arrange &Symbols", ID_WINDOW_ARRANGE
END
POPUP "&Help"
POPUP "&Tools"
BEGIN
MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ
MENUITEM "&About Explorer...", ID_ABOUT_EXPLORER
MENUITEM "About &OS...", ID_ABOUT_WINDOWS
END
END
IDM_SDIFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&View"
BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOL_BAR
MENUITEM "&Side Bar", ID_VIEW_SIDE_BAR, GRAYED
MENUITEM "&Status Bar", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Refresh\tF5", ID_REFRESH
MENUITEM "F&ull Screen\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
MENUITEM "&MDI", ID_VIEW_MDI
MENUITEM "&Options", ID_TOOLS_OPTIONS
END
POPUP "&Help"
BEGIN
@ -832,6 +828,34 @@ BEGIN
END
END
IDM_SDIFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&View"
BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOL_BAR
MENUITEM "S&ide Bar", ID_VIEW_SIDE_BAR, GRAYED
MENUITEM "&Status Bar", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Refresh\tF5", ID_REFRESH
MENUITEM "F&ull Screen\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
MENUITEM "&MDI", ID_VIEW_MDI
END
POPUP "&Tools"
BEGIN
MENUITEM "&Options", ID_TOOLS_OPTIONS
END
POPUP "&Help"
BEGIN
MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ
MENUITEM "&About Explorer...", ID_ABOUT_EXPLORER
MENUITEM "About &OS...", ID_ABOUT_WINDOWS
END
END
/////////////////////////////////////////////////////////////////////////////
//
@ -953,6 +977,25 @@ BEGIN
PUSHBUTTON "&Cancel",IDCANCEL,150,129,50,14
END
IDD_MDI_SDI DIALOGEX 0, 0, 188, 126
STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "Choose MDI / SDI mode"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Please select your prefered explorer user interface:",
IDC_STATIC,7,7,160,8
CONTROL "&MDI (multiple document interface)",IDC_MDI,"Button",
BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,7,30,121,10
CONTROL "&SDI (single document interface)",IDC_SDI,"Button",
BS_AUTORADIOBUTTON,7,53,115,10
LTEXT "This setting will be used as default for all explorer windows in the future.",
IDC_STATIC,7,76,174,22
DEFPUSHBUTTON "&OK",IDOK,29,105,50,14,WS_GROUP
PUSHBUTTON "&Cancel",IDCANCEL,106,105,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
@ -1001,6 +1044,14 @@ BEGIN
TOPMARGIN, 7
BOTTOMMARGIN, 143
END
IDD_MDI_SDI, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 181
TOPMARGIN, 7
BOTTOMMARGIN, 119
END
END
#endif // APSTUDIO_INVOKED
@ -1110,6 +1161,10 @@ BEGIN
MENUITEM "Agrupar Automaticamente", ID_WINDOW_AUTOSORT
MENUITEM "Agrupar &Simbolos", ID_WINDOW_ARRANGE
END
POPUP "&Tools"
BEGIN
MENUITEM "&Options", ID_TOOLS_OPTIONS
END
POPUP "A&yuda"
BEGIN
MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ
@ -1118,30 +1173,6 @@ BEGIN
END
END
IDM_SDIFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&Archivo"
BEGIN
MENUITEM "S&alir", ID_FILE_EXIT
END
POPUP "&Ver"
BEGIN
MENUITEM "&Barra de Herramientas", ID_VIEW_TOOL_BAR
MENUITEM "Barra &Lateral", ID_VIEW_SIDE_BAR, GRAYED
MENUITEM "Barra de &Estado", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Actualizar\tF5", ID_REFRESH
MENUITEM "P&antalla Completa\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
MENUITEM "&MDI", ID_VIEW_MDI
END
POPUP "&Ayuda"
BEGIN
MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ
MENUITEM "&Acerca de Explorer...", ID_ABOUT_EXPLORER
MENUITEM "Acerca de &OS...", ID_ABOUT_WINDOWS
END
END
IDM_WINEFILE MENU FIXED IMPURE
BEGIN
POPUP "&Archivo"
@ -1281,6 +1312,34 @@ BEGIN
END
END
IDM_SDIFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&Archivo"
BEGIN
MENUITEM "S&alir", ID_FILE_EXIT
END
POPUP "&Ver"
BEGIN
MENUITEM "&Barra de Herramientas", ID_VIEW_TOOL_BAR
MENUITEM "Barra &Lateral", ID_VIEW_SIDE_BAR, GRAYED
MENUITEM "Barra de &Estado", ID_VIEW_STATUSBAR
MENUITEM SEPARATOR
MENUITEM "&Actualizar\tF5", ID_REFRESH
MENUITEM "P&antalla Completa\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
MENUITEM "&MDI", ID_VIEW_MDI
END
POPUP "&Tools"
BEGIN
MENUITEM "&Options", ID_TOOLS_OPTIONS
END
POPUP "&Ayuda"
BEGIN
MENUITEM "Explorer &FAQ...", ID_EXPLORER_FAQ
MENUITEM "&Acerca de Explorer...", ID_ABOUT_EXPLORER
MENUITEM "Acerca de &OS...", ID_ABOUT_WINDOWS
END
END
/////////////////////////////////////////////////////////////////////////////
//
@ -1559,6 +1618,10 @@ BEGIN
MENUITEM "Arrange Automatically", ID_WINDOW_AUTOSORT
MENUITEM "Arrange &Symbols", ID_WINDOW_ARRANGE
END
POPUP "&Tools"
BEGIN
MENUITEM "&Options", ID_TOOLS_OPTIONS
END
POPUP "A&ide"
BEGIN
MENUITEM "&FAQ Explorateur...", ID_EXPLORER_FAQ
@ -1583,6 +1646,10 @@ BEGIN
MENUITEM "F&ull Screen\tCtrl+Shift+S", ID_VIEW_FULLSCREEN
MENUITEM "&MDI", ID_VIEW_MDI
END
POPUP "&Tools"
BEGIN
MENUITEM "&Options", ID_TOOLS_OPTIONS
END
POPUP "A&ide"
BEGIN
MENUITEM "&FAQ Explorateur...", ID_EXPLORER_FAQ

View file

@ -35,6 +35,8 @@ extern HWND create_webchildwindow(const WebChildWndInfo& info);
#include "../explorer_intres.h"
#include "../dialogs/settings.h" // for MdiSdiDlg
HWND MainFrameBase::Create(LPCTSTR path, bool mdi, UINT cmdshow)
{
@ -86,7 +88,7 @@ HWND MainFrameBase::Create(LPCTSTR path, bool mdi, UINT cmdshow)
}
int MainFrameBase::OpenShellFolders(LPIDA pida, HWND hFrameWnd, bool mdi)
int MainFrameBase::OpenShellFolders(LPIDA pida, HWND hFrameWnd)
{
int cnt = 0;
@ -110,6 +112,9 @@ int MainFrameBase::OpenShellFolders(LPIDA pida, HWND hFrameWnd, bool mdi)
} else {
HWND hwnd;
#ifndef _NO_MDI
XMLPos explorer_options(g_Globals.get_cfg("general"), "explorer");
bool mdi = XMLBool(explorer_options, "mdi", true);
if (mdi)
hwnd = MDIMainFrame::Create(pidl_abs, 0);
else
@ -152,7 +157,7 @@ MainFrameBase::MainFrameBase(HWND hwnd)
_himl(ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK|ILC_COLOR24, 2, 0))
{
_hMenuFrame = GetMenu(hwnd);
_hMenuWindow = GetSubMenu(_hMenuFrame, GetMenuItemCount(_hMenuFrame)-2);
_hMenuWindow = GetSubMenu(_hMenuFrame, GetMenuItemCount(_hMenuFrame)-3);
_menu_info._hMenuView = GetSubMenu(_hMenuFrame, 1);
@ -169,13 +174,7 @@ MainFrameBase::MainFrameBase(HWND hwnd)
{10, ID_GO_HOME, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{11, ID_GO_SEARCH, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{12, ID_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{13, ID_STOP, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
/* {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
{0, ID_WINDOW_NEW, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{1, ID_WINDOW_CASCADE, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{2, ID_WINDOW_TILE_HORZ, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{3, ID_WINDOW_TILE_VERT, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
*/
{13, ID_STOP, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0}
};
_htoolbar = CreateToolbarEx(hwnd,
@ -396,6 +395,10 @@ int MainFrameBase::Command(int id, int code)
CheckMenuItem(_menu_info._hMenuView, id, toggle_fullscreen()?MF_CHECKED:0);
break;
case ID_TOOLS_OPTIONS:
Dialog::DoModal(IDD_MDI_SDI, WINDOW_CREATOR(MdiSdiDlg), _hwnd);
break;
case ID_ABOUT_WINDOWS:
ShellAbout(_hwnd, ResString(IDS_TITLE), NULL, 0);
break;
@ -672,6 +675,16 @@ bool MainFrameBase::go_to(LPCTSTR url, bool new_window)
MDIMainFrame::MDIMainFrame(HWND hwnd)
: super(hwnd)
{
TBBUTTON mdiBtns[] = {
{0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
{0, ID_WINDOW_NEW, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{1, ID_WINDOW_CASCADE, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{2, ID_WINDOW_TILE_HORZ, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
{3, ID_WINDOW_TILE_VERT, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0}
};
SendMessage(_htoolbar, TB_ADDBUTTONS, sizeof(mdiBtns)/sizeof(TBBUTTON), (LPARAM)&mdiBtns);
CLIENTCREATESTRUCT ccs;
ccs.hWindowMenu = _hMenuWindow;

View file

@ -39,7 +39,7 @@ struct MainFrameBase : public PreTranslateWindow
~MainFrameBase();
static HWND Create(LPCTSTR path, bool mdi=true, UINT cmdshow=SW_SHOWNORMAL);
static int OpenShellFolders(LPIDA pida, HWND hFrameWnd, bool mdi=true);
static int OpenShellFolders(LPIDA pida, HWND hFrameWnd);
WindowHandle _hwndrebar;

View file

@ -85,15 +85,15 @@ bool Bookmark::read_url(LPCTSTR path)
/// convert XBEL bookmark node
bool Bookmark::read(const_XMLPos& pos)
{
_url = pos.get("href");
_url = pos.get("href").c_str();
if (pos.go_down("title")) {
_name = pos->get_content();
_name = pos->get_content().c_str();
pos.back();
}
if (pos.go_down("desc")) {
_description = pos->get_content();
_description = pos->get_content().c_str();
pos.back();
}
@ -106,8 +106,8 @@ bool Bookmark::read(const_XMLPos& pos)
if (node.get("owner") == "ros-explorer") {
if (sub_pos.go_down("icon")) {
_icon_path = sub_pos.get("path");
_icon_idx = _ttoi(sub_pos.get("index"));
_icon_path = sub_pos.get("path").c_str();
_icon_idx = XS_toi(sub_pos.get("index"));
sub_pos.back(); // </icon>
}
@ -126,7 +126,7 @@ void Bookmark::write(XMLPos& pos) const
{
pos.create("bookmark");
pos["href"] = _url;
pos["href"] = _url.c_str();
if (!_name.empty()) {
pos.create("title");
@ -145,8 +145,8 @@ void Bookmark::write(XMLPos& pos) const
pos.create("metadata");
pos["owner"] = "ros-explorer";
pos.create("icon");
pos["path"] = _icon_path;
pos["index"].printf(TEXT("%d"), _icon_idx);
pos["path"] = _icon_path.c_str();
pos["index"].printf(XS_TEXT("%d"), _icon_idx);
pos.back(); // </icon>
pos.back(); // </metadata>
pos.back(); // </info>
@ -160,12 +160,12 @@ void Bookmark::write(XMLPos& pos) const
void BookmarkFolder::read(const_XMLPos& pos)
{
if (pos.go_down("title")) {
_name = pos->get_content();
_name = pos->get_content().c_str();
pos.back();
}
if (pos.go_down("desc")) {
_description = pos->get_content();
_description = pos->get_content().c_str();
pos.back();
}

View file

@ -234,10 +234,10 @@ void NotifyArea::read_config()
NotifyIconConfig cfg;
cfg._name = node.get("name");
cfg._tipText = node.get("text");
cfg._windowTitle = node.get("window");
cfg._modulePath = node.get("module");
cfg._name = node.get("name").c_str();
cfg._tipText = node.get("text").c_str();
cfg._windowTitle = node.get("window").c_str();
cfg._modulePath = node.get("module").c_str();
const string& mode = node.get("show");
if (mode == "show")
@ -281,11 +281,11 @@ void NotifyArea::write_config()
// refresh unique name
cfg.create_name();
pos["name"] = cfg._name;
pos["text"] = cfg._tipText;
pos["window"] = cfg._windowTitle;
pos["module"] = cfg._modulePath;
pos["show"] = string_from_mode(cfg._mode);
pos["name"] = cfg._name.c_str();
pos["text"] = cfg._tipText.c_str();
pos["window"] = cfg._windowTitle.c_str();
pos["module"] = cfg._modulePath.c_str();
pos["show"] = string_from_mode(cfg._mode).c_str();
pos.back();
}

View file

@ -746,8 +746,10 @@ struct String
#endif
String() {}
String(LPCTSTR s) {if (s) super::assign(s);}
String(LPCTSTR s, int l) : super(s, l) {}
String(const super& other) : super(other) {}
String(const String& other) : super(other) {}

View file

@ -236,12 +236,13 @@ std::string XMLReaderBase::get_error_string() const
}
std::string EncodeXMLString(LPCTSTR s)
std::string EncodeXMLString(const XS_String& str)
{
LPTSTR buffer = (LPTSTR)alloca(5*sizeof(TCHAR)*_tcslen(s)); // worst case. "&amp;"
LPTSTR o = buffer;
LPCXSSTR s = str.c_str();
LPXSSTR buffer = (LPXSSTR)alloca(5*sizeof(XS_CHAR)*XS_len(s)); // worst case. "&amp;"
LPXSSTR o = buffer;
for(LPCTSTR p=s; *p; ++p)
for(LPCXSSTR p=s; *p; ++p)
switch(*p) {
case '&':
*o++ = '&'; *o++ = 'a'; *o++ = 'm'; *o++ = 'p'; *o++ = ';';
@ -259,23 +260,28 @@ std::string EncodeXMLString(LPCTSTR s)
*o++ = *p;
}
#ifdef XS_STRING_UTF8
return XS_String(buffer, o-buffer);
#else
return get_utf8(buffer, o-buffer);
#endif
}
XS_String DecodeXMLString(LPCTSTR s)
XS_String DecodeXMLString(const XS_String& str)
{
LPTSTR buffer = (LPTSTR)alloca(sizeof(TCHAR)*_tcslen(s));
LPTSTR o = buffer;
LPCXSSTR s = str.c_str();
LPXSSTR buffer = (LPXSSTR)alloca(sizeof(XS_CHAR)*XS_len(s));
LPXSSTR o = buffer;
for(LPCTSTR p=s; *p; ++p)
for(LPCXSSTR p=s; *p; ++p)
if (*p == '&') {
if (!_tcsnicmp(p+1, TEXT("amp;"), 4)) {
if (!XS_nicmp(p+1, XS_TEXT("amp;"), 4)) {
*o++ = '&';
p += 4;
} else if (!_tcsnicmp(p+1, TEXT("lt;"), 3)) {
} else if (!XS_nicmp(p+1, XS_TEXT("lt;"), 3)) {
*o++ = '<';
p += 3;
} else if (!_tcsnicmp(p+1, TEXT("gt;"), 3)) {
} else if (!XS_nicmp(p+1, XS_TEXT("gt;"), 3)) {
*o++ = '>';
p += 3;
} else

View file

@ -70,34 +70,67 @@
namespace XMLStorage {
#ifdef _STRING_DEFINED
#ifndef XS_String
#ifdef __GNUC__
#define XS_STRING_UTF8 // The W32API std::wstring implementation of stdlibc++ is unusable, so use UTF8 encoded strings with std::string instead
#endif
#define XS_STRING_UTF8//@@
#ifdef XS_STRING_UTF8
#define XS_CHAR char
#define XS_TEXT(x) x
#define LPXSSTR LPSTR
#define LPCXSSTR LPCSTR
#define XS_icmp stricmp
#define XS_nicmp strnicmp
#define XS_toi atoi
#define XS_len strlen
#define XS_sprintf sprintf
#define XS_vsprintf vsprintf
#else
#define XS_CHAR TCHAR
#define XS_TEXT(x) TEXT(x)
#define LPXSSTR LPTSTR
#define LPCXSSTR LPCTSTR
#define XS_icmp _tcsicmp
#define XS_nicmp _tcsnicmp
#define XS_toi _ttoi
#define XS_len _tcslen
#define XS_sprintf _stprintf
#define XS_vsprintf _vstprintf
#endif
#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
#define XS_String String
#else
#else // _STRING_DEFINED, !XS_STRING_UTF8
/// string class for TCHAR strings
struct XS_String
#ifdef UNICODE
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
: public std::wstring
#else
: public std::string
#endif
{
#ifdef UNICODE
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
typedef std::wstring super;
#else
typedef std::string super;
#endif
XS_String() {}
XS_String(LPCTSTR s) {if (s) super::assign(s);}
XS_String(LPCTSTR s, int l) : super(s, l) {}
XS_String(LPCXSSTR s) {if (s) super::assign(s);}
XS_String(LPCXSSTR s, int l) : super(s, l) {}
XS_String(const super& other) : super(other) {}
XS_String(const XS_String& other) : super(other) {}
#ifdef UNICODE
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
XS_String(LPCSTR s) {assign(s);}
XS_String(LPCSTR s, int l) {assign(s, l);}
XS_String(const std::string& other) {assign(other.c_str());}
@ -109,68 +142,80 @@ struct XS_String
XS_String(LPCWSTR s, int l) {assign(s, l);}
XS_String(const std::wstring& other) {assign(other.c_str());}
XS_String& operator=(LPCWSTR s) {assign(s); return *this;}
#ifdef XS_STRING_UTF8
void assign(const XS_String& s) {assign(s.c_str());}
void assign(LPCWSTR s) {if (s) {int bl=wcslen(s); LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_UTF8, 0, s, bl, b, bl, 0, 0));} else erase();}
void assign(LPCWSTR s, int l) {int bl=l; if (s) {LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_UTF8, 0, s, l, b, bl, 0, 0));} else erase();}
#else // if !UNICODE && !XS_STRING_UTF8
void assign(LPCWSTR s) {if (s) {int bl=wcslen(s); LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, bl, b, bl, 0, 0));} else erase();}
void assign(LPCWSTR s, int l) {int bl=l; if (s) {LPSTR b=(LPSTR)alloca(bl); super::assign(b, WideCharToMultiByte(CP_ACP, 0, s, l, b, bl, 0, 0));} else erase();}
#endif
#endif
XS_String& operator=(LPCTSTR s) {if (s) super::assign(s); else erase(); return *this;}
XS_String& operator=(LPCXSSTR s) {if (s) super::assign(s); else erase(); return *this;}
XS_String& operator=(const super& s) {super::assign(s); return *this;}
void assign(LPCTSTR s) {super::assign(s);}
void assign(LPCTSTR s, int l) {super::assign(s, l);}
void assign(LPCXSSTR s) {super::assign(s);}
void assign(LPCXSSTR s, int l) {super::assign(s, l);}
operator LPCTSTR() const {return c_str();}
operator LPCXSSTR() const {return c_str();}
#ifdef UNICODE
#ifdef XS_STRING_UTF8
operator std::wstring() const {int bl=length(); LPWSTR b=(LPWSTR)alloca(sizeof(WCHAR)*bl); return std::wstring(b, MultiByteToWideChar(CP_UTF8, 0, c_str(), bl, b, bl));}
#elif defined(UNICODE)
operator std::string() const {int bl=length(); LPSTR b=(LPSTR)alloca(bl); return std::string(b, WideCharToMultiByte(CP_ACP, 0, c_str(), bl, b, bl, 0, 0));}
#else
operator std::wstring() const {int bl=length(); LPWSTR b=(LPWSTR)alloca(sizeof(WCHAR)*bl); return std::wstring(b, MultiByteToWideChar(CP_ACP, 0, c_str(), bl, b, bl));}
#endif
XS_String& printf(LPCTSTR fmt, ...)
XS_String& printf(LPCXSSTR fmt, ...)
{
va_list l;
TCHAR b[BUFFER_LEN];
XS_CHAR b[BUFFER_LEN];
va_start(l, fmt);
super::assign(b, _vstprintf(b, fmt, l));
super::assign(b, XS_vsprintf(b, fmt, l));
va_end(l);
return *this;
}
XS_String& vprintf(LPCTSTR fmt, va_list l)
XS_String& vprintf(LPCXSSTR fmt, va_list l)
{
TCHAR b[BUFFER_LEN];
XS_CHAR b[BUFFER_LEN];
super::assign(b, _vstprintf(b, fmt, l));
super::assign(b, XS_vsprintf(b, fmt, l));
return *this;
}
XS_String& appendf(LPCTSTR fmt, ...)
XS_String& appendf(LPCXSSTR fmt, ...)
{
va_list l;
TCHAR b[BUFFER_LEN];
XS_CHAR b[BUFFER_LEN];
va_start(l, fmt);
super::append(b, _vstprintf(b, fmt, l));
super::append(b, XS_vsprintf(b, fmt, l));
va_end(l);
return *this;
}
XS_String& vappendf(LPCTSTR fmt, va_list l)
XS_String& vappendf(LPCXSSTR fmt, va_list l)
{
TCHAR b[BUFFER_LEN];
XS_CHAR b[BUFFER_LEN];
super::append(b, _vstprintf(b, fmt, l));
super::append(b, XS_vsprintf(b, fmt, l));
return *this;
}
};
#endif
#endif // _STRING_DEFINED, !XS_STRING_UTF8
#endif // XS_String
#ifndef XS_STRING_UTF8
inline void assign_utf8(XS_String& s, const char* str)
{
@ -211,8 +256,10 @@ inline std::string get_utf8(const XS_String& s)
return get_utf8(s.c_str(), s.length());
}
extern std::string EncodeXMLString(LPCTSTR s);
extern XS_String DecodeXMLString(LPCTSTR s);
#endif // XS_STRING_UTF8
extern std::string EncodeXMLString(const XS_String& str);
extern XS_String DecodeXMLString(const XS_String& str);
#ifdef __GNUC__
@ -287,6 +334,10 @@ protected:
typedef XS_String String_from_XML_Char;
#elif defined(XS_STRING_UTF8)
typedef XS_String String_from_XML_Char;
#else
struct String_from_XML_Char : public XS_String
@ -300,7 +351,7 @@ struct String_from_XML_Char : public XS_String
#endif
#ifdef UNICODE
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
// optimization for faster UNICODE/ASCII string comparison without temporary A/U conversion
inline bool operator==(const XS_String& s1, const char* s2)
@ -321,7 +372,7 @@ inline bool operator==(const XS_String& s1, const char* s2)
/// in memory representation of an XML node
struct XMLNode : public XS_String
{
#ifdef UNICODE
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
// optimized read access without temporary A/U conversion when using ASCII attribute names
struct AttributeMap : public std::map<XS_String, XS_String>
{
@ -460,7 +511,7 @@ struct XMLNode : public XS_String
if (found != _attributes.end())
return found->second;
else
return TEXT("");
return XS_String();
}
/// convenient value access in children node
@ -471,7 +522,7 @@ struct XMLNode : public XS_String
if (node)
return node->get(attr_name);
else
return TEXT("");
return XS_String();
}
/// convenient storage of distinct values in children node
@ -487,7 +538,7 @@ struct XMLNode : public XS_String
return (*node)[attr_name];
}
#ifdef UNICODE
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
/// convenient value access in children node
XS_String subvalue(const char* name, const char* attr_name) const
{
@ -496,7 +547,7 @@ struct XMLNode : public XS_String
if (node)
return node->get(attr_name);
else
return TEXT("");
return XS_String();
}
/// convenient storage of distinct values in children node
@ -525,16 +576,19 @@ struct XMLNode : public XS_String
XS_String get_content() const
{
#ifdef XS_STRING_UTF8
const XS_String& ret = _content;
#else
XS_String ret;
assign_utf8(ret, _content.c_str());
#endif
return DecodeXMLString(ret);
return DecodeXMLString(ret.c_str());
}
void set_content(const XS_String& s)
{
_content.assign(EncodeXMLString(s));
_content.assign(EncodeXMLString(s.c_str()));
}
enum WRITE_MODE {
@ -600,7 +654,7 @@ protected:
return NULL;
}
#ifdef UNICODE
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
XMLNode* find_first(const char* name) const
{
for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
@ -976,7 +1030,7 @@ struct XMLPos
}
}
#ifdef UNICODE
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
/// search for child and go down
bool go_down(const char* name)
{
@ -1114,7 +1168,7 @@ struct const_XMLPos
/// move X-Path like to position in XML tree
bool go(const char* path);
#ifdef UNICODE
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
/// search for child and go down
bool go_down(const char* name)
{
@ -1151,10 +1205,10 @@ struct XMLBool
{
}
XMLBool(LPCTSTR value, bool def=false)
XMLBool(LPCXSSTR value, bool def=false)
{
if (value && *value)
_value = !_tcsicmp(value, TEXT("true"));
_value = !XS_icmp(value, XS_TEXT("true"));
else
_value = def;
}
@ -1164,7 +1218,7 @@ struct XMLBool
const XS_String& value = node->get(attr_name);
if (!value.empty())
_value = !_tcsicmp(value, TEXT("true"));
_value = !XS_icmp(value.c_str(), XS_TEXT("true"));
else
_value = def;
}
@ -1179,9 +1233,9 @@ struct XMLBool
return !_value;
}
operator LPCTSTR() const
operator LPCXSSTR() const
{
return _value? TEXT("true"): TEXT("false");
return _value? XS_TEXT("true"): XS_TEXT("false");
}
protected:
@ -1202,12 +1256,12 @@ struct XMLBoolRef
operator bool() const
{
return !_tcsicmp(_ref, TEXT("true"));
return !XS_icmp(_ref.c_str(), XS_TEXT("true"));
}
bool operator!() const
{
return _tcsicmp(_ref, TEXT("true"))? true: false;
return XS_icmp(_ref.c_str(), XS_TEXT("true"))? true: false;
}
XMLBoolRef& operator=(bool value)
@ -1219,7 +1273,7 @@ struct XMLBoolRef
void assign(bool value)
{
_ref.assign(value? TEXT("true"): TEXT("false"));
_ref.assign(value? XS_TEXT("true"): XS_TEXT("false"));
}
void toggle()
@ -1239,10 +1293,10 @@ struct XMLInt
{
}
XMLInt(LPCTSTR value, int def=0)
XMLInt(LPCXSSTR value, int def=0)
{
if (value && *value)
_value = _ttoi(value);
_value = XS_toi(value);
else
_value = def;
}
@ -1252,7 +1306,7 @@ struct XMLInt
const XS_String& value = node->get(attr_name);
if (!value.empty())
_value = _ttoi(value);
_value = XS_toi(value.c_str());
else
_value = def;
}
@ -1264,8 +1318,8 @@ struct XMLInt
operator XS_String() const
{
TCHAR buffer[32];
_stprintf(buffer, TEXT("%d"), _value);
XS_CHAR buffer[32];
XS_sprintf(buffer, XS_TEXT("%d"), _value);
return buffer;
}
@ -1294,14 +1348,13 @@ struct XMLIntRef
operator int() const
{
return _ttoi(_ref);
return XS_toi(_ref.c_str());
}
void assign(int value)
{
TCHAR buffer[32];
_stprintf(buffer, TEXT("%d"), value);
XS_CHAR buffer[32];
XS_sprintf(buffer, XS_TEXT("%d"), value);
_ref.assign(buffer);
}
@ -1317,7 +1370,7 @@ struct XMLString
{
}
XMLString(LPCTSTR value, LPCTSTR def=TEXT(""))
XMLString(LPCXSSTR value, LPCXSSTR def=XS_TEXT(""))
{
if (value && *value)
_value = value;
@ -1325,7 +1378,7 @@ struct XMLString
_value = def;
}
XMLString(const XMLNode* node, const XS_String& attr_name, LPCTSTR def=TEXT(""))
XMLString(const XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_TEXT(""))
{
const XS_String& value = node->get(attr_name);
@ -1354,14 +1407,14 @@ private:
struct XMStringRef
{
XMStringRef(XMLNode* node, const XS_String& attr_name, LPCTSTR def=TEXT(""))
XMStringRef(XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_TEXT(""))
: _ref((*node)[attr_name])
{
if (_ref.empty())
assign(def);
}
XMStringRef(XMLNode* node, const XS_String& node_name, const XS_String& attr_name, LPCTSTR def=TEXT(""))
XMStringRef(XMLNode* node, const XS_String& node_name, const XS_String& attr_name, LPCXSSTR def=XS_TEXT(""))
: _ref(node->subvalue(node_name, attr_name))
{
if (_ref.empty())
@ -1391,7 +1444,7 @@ protected:
template<typename T>
inline void read_option(T& var, const_XMLPos& cfg, LPCTSTR key)
inline void read_option(T& var, const_XMLPos& cfg, LPCXSSTR key)
{
const XS_String& val = cfg.get(key);
@ -1400,12 +1453,12 @@ template<typename T>
}
template<>
inline void read_option(int& var, const_XMLPos& cfg, LPCTSTR key)
inline void read_option(int& var, const_XMLPos& cfg, LPCXSSTR key)
{
const XS_String& val = cfg.get(key);
if (!val.empty())
var = _ttoi(val);
var = XS_toi(val.c_str());
}