mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-05 20:45:49 +01:00
Mods to saved games dialog: allow to rename the current game; after
renaming or duplicating a game, make that new name the one initially selected in the listbox; remove sorting code relying on OS to sort when CBS_SORT set.
This commit is contained in:
parent
6693565ad5
commit
fb9ea8b64f
4 changed files with 116 additions and 72 deletions
|
@ -1623,23 +1623,26 @@ static void
|
||||||
ceChooseAndOpen( CEAppGlobals* globals )
|
ceChooseAndOpen( CEAppGlobals* globals )
|
||||||
{
|
{
|
||||||
// Save in case we'll be duplicating it
|
// Save in case we'll be duplicating it
|
||||||
|
again:
|
||||||
if ( ceSaveCurGame( globals, XP_FALSE )
|
if ( ceSaveCurGame( globals, XP_FALSE )
|
||||||
|| queryBoxChar( globals, "Do you really want to "
|
|| queryBoxChar( globals, "Do you really want to "
|
||||||
"overwrite the current game?" ) ) {
|
"overwrite the current game?" ) ) {
|
||||||
wchar_t path[256];
|
SavedGamesResult choice;
|
||||||
path[0] = 0;
|
wchar_t newName[256];
|
||||||
|
newName[0] = 0;
|
||||||
|
|
||||||
ceSetTitleFromName( globals ); /* in case we named it above */
|
ceSetTitleFromName( globals ); /* in case we named it above */
|
||||||
|
|
||||||
if ( ceSavedGamesDlg( globals, globals->curGameName,
|
choice = ceSavedGamesDlg( globals, globals->curGameName, newName,
|
||||||
path, VSIZE(path) )) {
|
VSIZE(newName) );
|
||||||
|
if ( CE_SVGAME_CANCEL != choice ) {
|
||||||
XP_UCHAR* name;
|
XP_UCHAR* name;
|
||||||
XP_U16 len;
|
XP_U16 len;
|
||||||
|
|
||||||
len = wcslen(path);
|
len = wcslen(newName);
|
||||||
name = XP_MALLOC( globals->mpool, len + 1 );
|
name = XP_MALLOC( globals->mpool, len + 1 );
|
||||||
|
|
||||||
WideCharToMultiByte( CP_ACP, 0, path, len + 1,
|
WideCharToMultiByte( CP_ACP, 0, newName, len + 1,
|
||||||
name, len + 1, NULL, NULL );
|
name, len + 1, NULL, NULL );
|
||||||
|
|
||||||
if ( globals->curGameName != NULL
|
if ( globals->curGameName != NULL
|
||||||
|
@ -1660,10 +1663,19 @@ ceChooseAndOpen( CEAppGlobals* globals )
|
||||||
globals->curGameName = NULL; /* prevent being destroyed */
|
globals->curGameName = NULL; /* prevent being destroyed */
|
||||||
closeGame( globals );
|
closeGame( globals );
|
||||||
|
|
||||||
|
if ( CE_SVGAME_RENAME == choice ) {
|
||||||
|
XP_U16 len = 1 + XP_STRLEN( oldName );
|
||||||
|
wchar_t widebuf[len];
|
||||||
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, oldName, len,
|
||||||
|
widebuf, len );
|
||||||
|
(void)MoveFile( widebuf, newName );
|
||||||
|
}
|
||||||
|
|
||||||
globals->curGameName = name;
|
globals->curGameName = name;
|
||||||
if ( ceLoadSavedGame( globals ) ) {
|
if ( ceLoadSavedGame( globals ) ) {
|
||||||
XP_FREE( globals->mpool, oldName );
|
XP_FREE( globals->mpool, oldName );
|
||||||
} else {
|
} else {
|
||||||
|
XP_ASSERT( CE_SVGAME_RENAME != choice );
|
||||||
XP_LOGF( "failed to open chosen game" );
|
XP_LOGF( "failed to open chosen game" );
|
||||||
XP_FREE( globals->mpool, globals->curGameName );
|
XP_FREE( globals->mpool, globals->curGameName );
|
||||||
globals->curGameName = oldName;
|
globals->curGameName = oldName;
|
||||||
|
@ -1672,6 +1684,9 @@ ceChooseAndOpen( CEAppGlobals* globals )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ceInitAndStartBoard( globals, XP_FALSE, NULL );
|
ceInitAndStartBoard( globals, XP_FALSE, NULL );
|
||||||
|
if ( CE_SVGAME_RENAME == choice ) {
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XP_LOGF( "GetOpenFileName() failed" );
|
XP_LOGF( "GetOpenFileName() failed" );
|
||||||
|
|
144
wince/cesvdgms.c
144
wince/cesvdgms.c
|
@ -168,17 +168,39 @@ typedef struct CeSavedGamesState {
|
||||||
CeDlgHdr dlgHdr;
|
CeDlgHdr dlgHdr;
|
||||||
wchar_t* buf;
|
wchar_t* buf;
|
||||||
XP_U16 buflen;
|
XP_U16 buflen;
|
||||||
XP_S16 sel;
|
XP_S16 sel; /* index of game name currently selected */
|
||||||
XP_U16 openGameIndex;
|
XP_U16 openGameIndex; /* index of game that's open */
|
||||||
wchar_t curNameW[128];
|
wchar_t openNameW[128];
|
||||||
|
wchar_t newNameW[MAX_PATH];
|
||||||
XP_U16 nItems;
|
XP_U16 nItems;
|
||||||
|
|
||||||
XP_U16 gameListId;
|
XP_U16 gameListId;
|
||||||
XP_Bool opened;
|
|
||||||
XP_Bool inited;
|
XP_Bool inited;
|
||||||
XP_Bool relaunch;
|
XP_Bool relaunch;
|
||||||
|
SavedGamesResult result;
|
||||||
} CeSavedGamesState;
|
} CeSavedGamesState;
|
||||||
|
|
||||||
|
static void
|
||||||
|
ceBasename( wchar_t* buf, const wchar_t* path )
|
||||||
|
{
|
||||||
|
const wchar_t* ptr = path + wcslen(path);
|
||||||
|
const wchar_t* dot = NULL;
|
||||||
|
|
||||||
|
for ( ; ; ) {
|
||||||
|
if ( ptr == path ) {
|
||||||
|
break;
|
||||||
|
} else if ( *ptr == L'\\' ) {
|
||||||
|
++ptr;
|
||||||
|
break;
|
||||||
|
} else if ( !dot && *ptr == L'.' ) {
|
||||||
|
dot = ptr;
|
||||||
|
}
|
||||||
|
--ptr;
|
||||||
|
}
|
||||||
|
lstrcpy( buf, ptr );
|
||||||
|
buf[dot-ptr] = 0; /* nuke extension */
|
||||||
|
} /* ceBasename */
|
||||||
|
|
||||||
/* Probably belongs as a utility */
|
/* Probably belongs as a utility */
|
||||||
static void
|
static void
|
||||||
getComboText( CeSavedGamesState* state, wchar_t* buf, XP_U16* lenp )
|
getComboText( CeSavedGamesState* state, wchar_t* buf, XP_U16* lenp )
|
||||||
|
@ -220,7 +242,7 @@ setButtons( CeSavedGamesState* state )
|
||||||
ceEnOrDisable( hDlg, IDC_SVGM_OPEN, haveItem && !curSelected );
|
ceEnOrDisable( hDlg, IDC_SVGM_OPEN, haveItem && !curSelected );
|
||||||
ceEnOrDisable( hDlg, IDC_SVGM_DUP, haveItem );
|
ceEnOrDisable( hDlg, IDC_SVGM_DUP, haveItem );
|
||||||
ceEnOrDisable( hDlg, IDC_SVGM_DEL, haveItem && !curSelected );
|
ceEnOrDisable( hDlg, IDC_SVGM_DEL, haveItem && !curSelected );
|
||||||
ceEnOrDisable( hDlg, IDC_SVGM_CHANGE, haveItem && !curSelected );
|
ceEnOrDisable( hDlg, IDC_SVGM_CHANGE, haveItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -231,7 +253,7 @@ initSavedGamesData( CeSavedGamesState* state )
|
||||||
CEAppGlobals* globals = state->dlgHdr.globals;
|
CEAppGlobals* globals = state->dlgHdr.globals;
|
||||||
WIN32_FIND_DATA data;
|
WIN32_FIND_DATA data;
|
||||||
wchar_t path[CE_MAX_PATH_LEN];
|
wchar_t path[CE_MAX_PATH_LEN];
|
||||||
XP_S16 curSel = -1;
|
XP_S16 sel;
|
||||||
XP_U16 ii;
|
XP_U16 ii;
|
||||||
XP_U16 nItems = 0;
|
XP_U16 nItems = 0;
|
||||||
|
|
||||||
|
@ -242,40 +264,13 @@ initSavedGamesData( CeSavedGamesState* state )
|
||||||
fileH = FindFirstFile( path, &data );
|
fileH = FindFirstFile( path, &data );
|
||||||
for ( ii = 0; fileH != INVALID_HANDLE_VALUE; ++ii ) {
|
for ( ii = 0; fileH != INVALID_HANDLE_VALUE; ++ii ) {
|
||||||
XP_U16 len = wcslen( data.cFileName );
|
XP_U16 len = wcslen( data.cFileName );
|
||||||
XP_U16 item;
|
|
||||||
XP_Bool isCurGame = 0 == wcscmp( state->curNameW, data.cFileName );
|
|
||||||
|
|
||||||
XP_ASSERT( data.cFileName[len-4] == '.');
|
XP_ASSERT( data.cFileName[len-4] == L'.');
|
||||||
data.cFileName[len-4] = 0;
|
data.cFileName[len-4] = 0;
|
||||||
|
|
||||||
/* Insert in sorted order. This should be fast enough for reasonable
|
|
||||||
numbers of saved games. */
|
|
||||||
/* PENDING: there's supposed to be a field attribute that make sorted
|
|
||||||
order automatic */
|
|
||||||
for ( item = 0; item < nItems; ++item ) {
|
|
||||||
wchar_t buf[256];
|
|
||||||
(void)SendDlgItemMessage( hDlg, state->gameListId,
|
(void)SendDlgItemMessage( hDlg, state->gameListId,
|
||||||
GETLBTEXT(globals), item,
|
ADDSTRING(globals),
|
||||||
(LPARAM)buf );
|
0, (LPARAM)data.cFileName );
|
||||||
/* Does the current item belong above the one we're inserting? */
|
|
||||||
if ( 0 <= wcscmp( buf, data.cFileName ) ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(void)SendDlgItemMessage( hDlg, state->gameListId,
|
|
||||||
INSERTSTRING(globals),
|
|
||||||
item, (LPARAM)data.cFileName );
|
|
||||||
|
|
||||||
/* Remember which entry matches the currently opened game, and adjust
|
|
||||||
if it's changed. We may be incrementing an uninitialized curSel,
|
|
||||||
but that's ok as isCurGame is guaranteed to be true exactly once
|
|
||||||
through. */
|
|
||||||
if ( isCurGame ) {
|
|
||||||
curSel = item;
|
|
||||||
} else if ( curSel >= item ) {
|
|
||||||
++curSel; /* since we've moved it up */
|
|
||||||
}
|
|
||||||
|
|
||||||
++nItems;
|
++nItems;
|
||||||
|
|
||||||
if ( !FindNextFile( fileH, &data ) ) {
|
if ( !FindNextFile( fileH, &data ) ) {
|
||||||
|
@ -283,29 +278,51 @@ initSavedGamesData( CeSavedGamesState* state )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state->nItems = nItems;
|
state->nItems = nItems;
|
||||||
state->openGameIndex = curSel;
|
|
||||||
|
|
||||||
SendDlgItemMessage( hDlg, state->gameListId,
|
/* Now locate the open game and game we should select (which may
|
||||||
SETCURSEL(globals), curSel, 0 );
|
differ) */
|
||||||
state->sel = curSel;
|
sel = SendDlgItemMessage( hDlg, state->gameListId, FINDSTRINGEXACT(globals),
|
||||||
|
-1, (LPARAM)state->openNameW );
|
||||||
|
XP_ASSERT( sel >= 0 ); /* should always have this */
|
||||||
|
state->openGameIndex = sel;
|
||||||
|
|
||||||
|
sel = SendDlgItemMessage( hDlg,state->gameListId, FINDSTRINGEXACT(globals),
|
||||||
|
-1, (LPARAM)state->newNameW );
|
||||||
|
if ( sel < 0 ) {
|
||||||
|
sel = state->openGameIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendDlgItemMessage( hDlg, state->gameListId, SETCURSEL(globals), sel, 0 );
|
||||||
|
state->sel = sel;
|
||||||
|
|
||||||
setButtons( state );
|
setButtons( state );
|
||||||
|
|
||||||
LOG_RETURN_VOID();
|
|
||||||
} /* initSavedGamesData */
|
} /* initSavedGamesData */
|
||||||
|
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
renameSelected( CeSavedGamesState* state )
|
renameSelected( CeSavedGamesState* state )
|
||||||
{
|
{
|
||||||
wchar_t path[MAX_PATH];
|
wchar_t newPath[MAX_PATH];
|
||||||
XP_Bool confirmed = ceConfirmUniqueName( state->dlgHdr.globals, IDS_RENAME,
|
XP_Bool confirmed = ceConfirmUniqueName( state->dlgHdr.globals, IDS_RENAME,
|
||||||
path, VSIZE(path) );
|
newPath, VSIZE(newPath) );
|
||||||
if ( confirmed ) {
|
if ( confirmed ) {
|
||||||
|
/* If we're renaming the current game, we have to exit and let
|
||||||
|
calling code handle it. If we're renaming any other game, we can
|
||||||
|
do it here. */
|
||||||
|
if ( state->openGameIndex == state->sel ) {
|
||||||
|
swprintf( state->buf, L"%s", newPath );
|
||||||
|
state->result = CE_SVGAME_RENAME;
|
||||||
|
} else {
|
||||||
wchar_t curPath[MAX_PATH];
|
wchar_t curPath[MAX_PATH];
|
||||||
getFullSelPath( state, curPath, VSIZE(curPath) );
|
getFullSelPath( state, curPath, VSIZE(curPath) );
|
||||||
confirmed = MoveFile( curPath, path );
|
confirmed = MoveFile( curPath, newPath );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( confirmed ) {
|
||||||
|
ceBasename( state->newNameW, newPath );
|
||||||
|
} else {
|
||||||
|
state->newNameW[0] = 0;
|
||||||
}
|
}
|
||||||
return confirmed;
|
return confirmed;
|
||||||
} /* renameSelected */
|
} /* renameSelected */
|
||||||
|
@ -323,6 +340,13 @@ duplicateSelected( CeSavedGamesState* state )
|
||||||
getFullSelPath( state, curPath, VSIZE(curPath) );
|
getFullSelPath( state, curPath, VSIZE(curPath) );
|
||||||
confirmed = CopyFile( curPath, newPath, TRUE ); /* TRUE is what??? */
|
confirmed = CopyFile( curPath, newPath, TRUE ); /* TRUE is what??? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( confirmed ) {
|
||||||
|
ceBasename( state->newNameW, newPath );
|
||||||
|
} else {
|
||||||
|
state->newNameW[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return confirmed;
|
return confirmed;
|
||||||
} /* duplicateSelected */
|
} /* duplicateSelected */
|
||||||
|
|
||||||
|
@ -415,11 +439,12 @@ SavedGamesDlg( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
|
||||||
wchar_t buf[128];
|
wchar_t buf[128];
|
||||||
XP_U16 len = VSIZE(buf);
|
XP_U16 len = VSIZE(buf);
|
||||||
getComboText( state, buf, &len );
|
getComboText( state, buf, &len );
|
||||||
len = ceGetPath( state->dlgHdr.globals, DEFAULT_DIR_PATH_L,
|
len = ceGetPath( state->dlgHdr.globals,
|
||||||
state->buf, state->buflen );
|
DEFAULT_DIR_PATH_L, state->buf,
|
||||||
|
state->buflen );
|
||||||
swprintf( &state->buf[len], L"%s.xwg", buf );
|
swprintf( &state->buf[len], L"%s.xwg", buf );
|
||||||
XP_LOGW( "returning", state->buf );
|
XP_LOGW( "returning", state->buf );
|
||||||
state->opened = XP_TRUE;
|
state->result = CE_SVGAME_OPEN;
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case IDOK: /* Done button */
|
case IDOK: /* Done button */
|
||||||
|
@ -440,7 +465,7 @@ SavedGamesDlg( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
|
||||||
return result;
|
return result;
|
||||||
} /* SavedGamesDlg */
|
} /* SavedGamesDlg */
|
||||||
|
|
||||||
XP_Bool
|
SavedGamesResult
|
||||||
ceSavedGamesDlg( CEAppGlobals* globals, const XP_UCHAR* curPath,
|
ceSavedGamesDlg( CEAppGlobals* globals, const XP_UCHAR* curPath,
|
||||||
wchar_t* buf, XP_U16 buflen )
|
wchar_t* buf, XP_U16 buflen )
|
||||||
{
|
{
|
||||||
|
@ -455,30 +480,27 @@ ceSavedGamesDlg( CEAppGlobals* globals, const XP_UCHAR* curPath,
|
||||||
state.sel = -1;
|
state.sel = -1;
|
||||||
|
|
||||||
if ( !!curPath ) {
|
if ( !!curPath ) {
|
||||||
wchar_t shortName[128];
|
wchar_t widebuf[MAX_PATH];
|
||||||
XP_U16 len;
|
XP_U16 len;
|
||||||
XP_U16 dirLen;
|
|
||||||
|
|
||||||
dirLen = ceGetPath( globals, DEFAULT_DIR_PATH_L, shortName,
|
|
||||||
VSIZE(shortName) );
|
|
||||||
|
|
||||||
len = (XP_U16)XP_STRLEN( curPath );
|
len = (XP_U16)XP_STRLEN( curPath );
|
||||||
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, curPath, len + 1,
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, curPath, len + 1,
|
||||||
shortName, len + 1 );
|
widebuf, len + 1 );
|
||||||
lstrcpy( state.curNameW, shortName+dirLen );
|
ceBasename( state.openNameW, widebuf );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ; ; ) {
|
for ( ; ; ) {
|
||||||
|
state.relaunch = XP_FALSE;
|
||||||
|
state.result = CE_SVGAME_CANCEL;
|
||||||
|
|
||||||
(void)DialogBoxParam( globals->hInst, (LPCTSTR)IDD_SAVEDGAMESDLG,
|
(void)DialogBoxParam( globals->hInst, (LPCTSTR)IDD_SAVEDGAMESDLG,
|
||||||
globals->hWnd,
|
globals->hWnd,
|
||||||
(DLGPROC)SavedGamesDlg, (long)&state );
|
(DLGPROC)SavedGamesDlg, (long)&state );
|
||||||
|
|
||||||
if ( !state.relaunch ) {
|
if ( !state.relaunch || (state.result == CE_SVGAME_RENAME) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state.relaunch = XP_FALSE;
|
|
||||||
}
|
}
|
||||||
XP_LOGW( __func__, buf );
|
XP_LOGW( __func__, buf );
|
||||||
|
|
||||||
return state.opened;
|
return state.result;
|
||||||
} /* ceSavedGamesDlg */
|
} /* ceSavedGamesDlg */
|
||||||
|
|
|
@ -23,7 +23,14 @@
|
||||||
#include "xptypes.h"
|
#include "xptypes.h"
|
||||||
#include "cemain.h"
|
#include "cemain.h"
|
||||||
|
|
||||||
XP_Bool ceSavedGamesDlg( CEAppGlobals* globals, const XP_UCHAR* curPath,
|
typedef enum {
|
||||||
|
CE_SVGAME_CANCEL
|
||||||
|
,CE_SVGAME_RENAME
|
||||||
|
,CE_SVGAME_OPEN
|
||||||
|
} SavedGamesResult;
|
||||||
|
|
||||||
|
SavedGamesResult ceSavedGamesDlg( CEAppGlobals* globals,
|
||||||
|
const XP_UCHAR* curPath,
|
||||||
wchar_t* buf, XP_U16 buflen );
|
wchar_t* buf, XP_U16 buflen );
|
||||||
XP_Bool ceConfirmUniqueName( CEAppGlobals* globals, XP_U16 strId, wchar_t* buf,
|
XP_Bool ceConfirmUniqueName( CEAppGlobals* globals, XP_U16 strId, wchar_t* buf,
|
||||||
XP_U16 buflen );
|
XP_U16 buflen );
|
||||||
|
|
|
@ -439,7 +439,7 @@ BEGIN
|
||||||
0, 0, 0, 0
|
0, 0, 0, 0
|
||||||
#endif
|
#endif
|
||||||
COMBOBOX IDC_SVGM_GAMELIST_PPC,SVGM_LEFT_COL,SVGM_ROW_2,70,58,
|
COMBOBOX IDC_SVGM_GAMELIST_PPC,SVGM_LEFT_COL,SVGM_ROW_2,70,58,
|
||||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP | CBS_SORT
|
||||||
|
|
||||||
PUSHBUTTON "Open",IDC_SVGM_OPEN,
|
PUSHBUTTON "Open",IDC_SVGM_OPEN,
|
||||||
SVGM_LEFT_COL,SVGM_ROW_3,40,14,WS_DISABLED
|
SVGM_LEFT_COL,SVGM_ROW_3,40,14,WS_DISABLED
|
||||||
|
|
Loading…
Add table
Reference in a new issue