ceLocateNDicts now takes a callback. Use that to build menu of dicts

rather than call OpenFile, which doesn't let you browse much of the
file system on CE.  Heading for installing dicts in Program Files so
users never have to worry about them.
This commit is contained in:
ehouse 2006-04-19 04:56:00 +00:00
parent ddb21c3cfc
commit 5a8c1ef2af
7 changed files with 111 additions and 117 deletions

View file

@ -415,59 +415,6 @@ ce_dict_getShortName( DictionaryCtxt* dict )
return bname( name );
} /* ce_dict_getShortName */
XP_Bool
ce_pickDictFile( CEAppGlobals* globals, XP_UCHAR* buf, XP_U16 bufLen )
{
XP_Bool result = XP_FALSE;
wchar_t nameBuf[256];
OPENFILENAME openFileStruct;
XP_MEMSET( &openFileStruct, 0, sizeof(openFileStruct) );
XP_MEMSET( nameBuf, 0, sizeof(nameBuf) );
openFileStruct.lStructSize = sizeof(openFileStruct);
openFileStruct.hwndOwner = globals->hWnd;
openFileStruct.lpstrFilter = L"Crosswords dictionaries" L"\0"
L"*.xwd" L"\0\0";
openFileStruct.Flags = OFN_FILEMUSTEXIST
| OFN_HIDEREADONLY
| OFN_PATHMUSTEXIST;
openFileStruct.lpstrFile = nameBuf;
openFileStruct.nMaxFile = sizeof(nameBuf)/sizeof(nameBuf[0]);
while ( GetOpenFileName( &openFileStruct ) ) {
XP_U16 len;
XP_UCHAR multiBuf[256];
if ( !checkIfDictAndLegal( MPPARM(globals->mpool) nameBuf,
openFileStruct.nFileOffset,
nameBuf + openFileStruct.nFileOffset ) ) {
wchar_t errBuf[128];
(void)swprintf( errBuf,
L"\"%s\" is not a valid Crosswords dictionary.",
nameBuf + openFileStruct.nFileOffset );
MessageBox( globals->hWnd, errBuf, NULL, MB_OK );
continue;
}
len = WideCharToMultiByte( CP_ACP, 0, nameBuf, wcslen(nameBuf),
multiBuf,
sizeof(multiBuf), NULL, NULL );
if ( len > 0 && len < bufLen ) {
multiBuf[len] = '\0';
len = (XP_U16)XP_STRLEN( multiBuf );
XP_MEMCPY( buf, multiBuf, len );
buf[len] = '\0';
result = XP_TRUE;
break;
}
}
return result;
} /* ce_pickDictFile */
static XP_U8*
openMappedFile( MPFORMAL const wchar_t* name, HANDLE* mappedFileP,
HANDLE* hFileP, XP_U32* sizep )
@ -571,7 +518,7 @@ checkIfDictAndLegal( MPFORMAL wchar_t* path, XP_U16 pathLen,
XP_U16 flags;
HANDLE mappedFile, hFile;
XP_U8* base;
wchar_t pathBuf[257];
wchar_t pathBuf[CE_MAX_PATH_LEN+1];
wcscpy( pathBuf, path );
pathBuf[pathLen] = 0;
@ -579,7 +526,7 @@ checkIfDictAndLegal( MPFORMAL wchar_t* path, XP_U16 pathLen,
#ifdef DEBUG
{
char narrowName[257];
char narrowName[CE_MAX_PATH_LEN+1];
int len = wcslen( pathBuf );
len = WideCharToMultiByte( CP_ACP, 0, pathBuf, len + 1,
narrowName, len + 1, NULL, NULL );
@ -608,7 +555,7 @@ checkIfDictAndLegal( MPFORMAL wchar_t* path, XP_U16 pathLen,
} /* checkIfDictAndLegal */
static void
locateOneDir( MPFORMAL wchar_t* path, XP_UCHAR** bufs, XP_U16 nSought,
locateOneDir( MPFORMAL wchar_t* path, OnePathCB cb, void* ctxt, XP_U16 nSought,
XP_U16* nFoundP )
{
WIN32_FIND_DATA data;
@ -639,28 +586,33 @@ locateOneDir( MPFORMAL wchar_t* path, XP_UCHAR** bufs, XP_U16 nSought,
#if defined TARGET_OS_WINCE
/* We don't do recursive search on Win32!!! */
lstrcpy( path+startLen, data.cFileName );
locateOneDir( MPPARM(mpool) path, bufs, nSought, nFoundP );
locateOneDir( MPPARM(mpool) path, cb, ctxt, nSought, nFoundP );
if ( *nFoundP == nSought ) {
break;
}
path[startLen] = 0;
#endif
} else if ( checkIfDictAndLegal( MPPARM(mpool) path, startLen,
data.cFileName ) ) {
XP_U16 len;
XP_UCHAR* str;
XP_UCHAR buf[CE_MAX_PATH_LEN+1];
XP_ASSERT( *nFoundP < nSought );
len = startLen + wcslen( data.cFileName ) + 1;
str = XP_MALLOC( mpool, len );
WideCharToMultiByte( CP_ACP, 0, path, startLen,
str, startLen, NULL, NULL );
WideCharToMultiByte( CP_ACP, 0, data.cFileName, -1,
str + startLen, len - startLen,
NULL, NULL );
XP_LOGF( "%s: got %s at end\n", __FUNCTION__, str );
lstrcpy( path+startLen, data.cFileName );
if ( !(*cb)( path, (*nFoundP)++, ctxt ) ) {
break;
}
/* len = startLen + wcslen( data.cFileName ) + 1; */
/* WideCharToMultiByte( CP_ACP, 0, path, startLen, */
/* buf, startLen, NULL, NULL ); */
/* WideCharToMultiByte( CP_ACP, 0, data.cFileName, -1, */
/* buf + startLen, len - startLen, */
/* NULL, NULL ); */
/* if ( !(*cb)( buf, (*nFoundP)++, ctxt ) ) { */
/* break; */
/* } */
bufs[(*nFoundP)++] = str;
if ( *nFoundP == nSought ) {
break;
}
@ -670,6 +622,7 @@ locateOneDir( MPFORMAL wchar_t* path, XP_UCHAR** bufs, XP_U16 nSought,
XP_ASSERT( GetLastError() == ERROR_NO_MORE_FILES );
break;
}
path[startLen] = 0;
}
(void)FindClose( fileH );
@ -677,14 +630,14 @@ locateOneDir( MPFORMAL wchar_t* path, XP_UCHAR** bufs, XP_U16 nSought,
} /* locateOneDir */
XP_U16
ceLocateNDicts( MPFORMAL XP_UCHAR** bufs, XP_U16 nSought )
ceLocateNDicts( MPFORMAL XP_U16 nSought, OnePathCB cb, void* ctxt )
{
XP_U16 nFound = 0;
wchar_t pathBuf[257];
wchar_t pathBuf[CE_MAX_PATH_LEN+1];
pathBuf[0] = 0;
locateOneDir( MPPARM(mpool) pathBuf, bufs, nSought, &nFound );
locateOneDir( MPPARM(mpool) pathBuf, cb, ctxt, nSought, &nFound );
return nFound;
} /* ceLocateNthDict */

View file

@ -1,6 +1,6 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/* Copyright 1999-2001 by Eric House (xwords@eehouse.org). All rights reserved.
/* Copyright 1999-2006 by Eric House (xwords@eehouse.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -22,6 +22,8 @@
#include "cemain.h"
#define CE_MAX_PATH_LEN 256
typedef struct CEBitmapInfo {
XP_U8* bits;
XP_U16 nCols;
@ -31,13 +33,12 @@ typedef struct CEBitmapInfo {
DictionaryCtxt* ce_dictionary_make(CEAppGlobals* globals, XP_UCHAR* name);
DictionaryCtxt* ce_dictionary_make_empty( CEAppGlobals* globals );
XP_Bool ce_pickDictFile( CEAppGlobals* globals, XP_UCHAR* buf, XP_U16 len );
/* ceLocateNDicts: Allocate and store in bufs ptrs to up to nSought paths to
* dict files. Return the number actually found. Caller is responsible for
* making sure bufs contains nSought slots.
*/
XP_U16 ceLocateNDicts( MPFORMAL XP_UCHAR** bufs, XP_U16 nSought );
typedef XP_Bool (*OnePathCB)( const wchar_t* wPath, XP_U16 index, void* ctxt );
XP_U16 ceLocateNDicts( MPFORMAL XP_U16 nSought, OnePathCB cb, void* ctxt );
XP_UCHAR* bname( XP_UCHAR* in );

View file

@ -43,6 +43,31 @@ ceCountLocalIn( HWND hDlg, XP_U16 nPlayers )
} /* ceCountLocalIn */
#endif
static XP_Bool
addDictToMenu( const wchar_t* wPath, XP_U16 index, void* ctxt )
{
GameInfoState* giState = (GameInfoState*)ctxt;
XP_LOGF( "%s called %dth time", __FUNCTION__, index );
SendDlgItemMessage( giState->hDlg, IDC_DICTCOMBO, CB_ADDSTRING, 0,
(long)wPath );
if ( giState->newDictName[0] != 0 && !giState->curSelSet ) {
XP_UCHAR buf[CE_MAX_PATH_LEN+1];
WideCharToMultiByte( CP_ACP, 0, wPath, -1, buf, sizeof(buf),
NULL, NULL );
XP_LOGF( "%s: comparing %s, %s", __FUNCTION__, buf, giState->newDictName );
if ( 0 == XP_STRCMP( buf, giState->newDictName ) ) {
XP_LOGF( "%s: they're the same; setting to %d", __FUNCTION__, index );
giState->curSelSet = XP_TRUE;
SendDlgItemMessage( giState->hDlg, IDC_DICTCOMBO, CB_SETCURSEL,
index, 0L );
}
}
return XP_TRUE;
}
static void
loadFromGameInfo( HWND hDlg, CEAppGlobals* globals, GameInfoState* giState )
{
@ -101,40 +126,28 @@ loadFromGameInfo( HWND hDlg, CEAppGlobals* globals, GameInfoState* giState )
giState->curServerHilite, 0L );
#endif
/* set the dictionary name */
if ( 0 ) {
#ifndef STUBBED_DICT
} else if ( !!gi->dictName ) {
str = bname( gi->dictName );
XP_MEMCPY( giState->newDictName, gi->dictName,
if ( !!gi->dictName ) {
XP_LOGF( "%s: copying %s to giState->newDictName",
__FUNCTION__, gi->dictName );
XP_MEMCPY( giState->newDictName, gi->dictName,
(XP_U16)XP_STRLEN(gi->dictName)+1 );
} else if ( 1 == ceLocateNDicts( MPPARM(globals->mpool) &str, 1 ) ) {
XP_MEMCPY( giState->newDictName, str, (XP_U16)XP_STRLEN(str)+1 );
XP_FREE( globals->mpool, str );
str = bname( giState->newDictName );
#endif
} else {
#ifdef STUBBED_DICT
/* assumption is there's no dict on the device */
str = "(Stub dict)";
#else
str = "--pick--";
#endif
}
ceSetDlgItemFileName( hDlg, IDC_DICTBUTTON, str );
if ( giState->isNewGame ) {
(void)ceLocateNDicts( MPPARM(globals->mpool) 32, addDictToMenu,
giState );
}
#endif
if ( !giState->isNewGame ) {
XP_U16 disableIDs[] = { IDC_NPLAYERSCOMBO,
IDC_ROLECOMBO,
IDC_DICTBUTTON};
IDC_DICTCOMBO};
XP_U16 i;
for( i = 0; i < sizeof(disableIDs)/sizeof(disableIDs[0]); ++i ) {
ceEnOrDisable( hDlg, disableIDs[i], XP_FALSE );
}
}
} /* loadFromGameInfo */
static void
@ -340,7 +353,21 @@ stateToGameInfo( HWND hDlg, CEAppGlobals* globals, GameInfoState* giState )
getStringAndReplace( globals, hDlg, id, &lp->name );
}
/* dictionary */
/* dictionary */ {
XP_LOGF( "%s: sending CB_GETCURSEL", __FUNCTION__ );
int sel = SendDlgItemMessage( hDlg, IDC_DICTCOMBO, CB_GETCURSEL, 0, 0L );
XP_LOGF( "%s: sel came back %d", __FUNCTION__, sel );
if ( sel >= 0 ) {
wchar_t widebuf[CE_MAX_PATH_LEN+1];
int len;
(void)SendDlgItemMessage( hDlg, IDC_DICTCOMBO, CB_GETLBTEXT, sel,
(long)widebuf );
WideCharToMultiByte( CP_ACP, 0, widebuf, -1, giState->newDictName,
sizeof(giState->newDictName), NULL, NULL );
XP_LOGF( "%s: text is %s", __FUNCTION__, giState->newDictName );
}
}
replaceStringIfDifferent( MPPARM(globals->mpool) &gi->dictName,
giState->newDictName );
@ -363,6 +390,7 @@ stateToGameInfo( HWND hDlg, CEAppGlobals* globals, GameInfoState* giState )
&giState->prefsPrefs );
}
LOG_RETURN_VOID();
} /* stateToGameInfo */
static void
@ -446,6 +474,7 @@ GameInfo(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
SetWindowLong( hDlg, GWL_USERDATA, lParam );
giState = (GameInfoState*)lParam;
giState->hDlg = hDlg;
globals = giState->globals;
loadFromGameInfo( hDlg, globals, giState );
@ -526,20 +555,6 @@ GameInfo(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
}
break;
#endif
#ifndef STUBBED_DICT
case IDC_DICTBUTTON:
if ( giState->isNewGame ) { /* ignore if in info mode */
giState->newDictName[0] = 0;
if ( ce_pickDictFile( globals, giState->newDictName,
sizeof(giState->newDictName) )) {
XP_UCHAR* basename = bname(giState->newDictName);
ceSetDlgItemFileName( hDlg, id, basename );
}
}
break;
#endif
case OPTIONS_BUTTON:
handleOptionsButton( hDlg, globals, giState );
break;

View file

@ -23,10 +23,12 @@
#include "stdafx.h"
#include "cemain.h"
#include "ceprefs.h"
#include "cedict.h"
typedef struct GameInfoState {
CEAppGlobals* globals;
XP_UCHAR newDictName[256];
HWND hDlg;
XP_UCHAR newDictName[CE_MAX_PATH_LEN];
XP_Bool isNewGame; /* newGame or GameInfo */
XP_Bool userCancelled; /* OUT param */
@ -34,6 +36,7 @@ typedef struct GameInfoState {
XP_Bool prefsChanged;
XP_Bool colorsChanged;
XP_Bool addrChanged;
XP_Bool curSelSet;
Connectedness curServerHilite;
CePrefsPrefs prefsPrefs;
} GameInfoState;

View file

@ -149,6 +149,8 @@ static XP_Bool ceSaveCurGame( CEAppGlobals* globals, XP_Bool autoSave );
static void updateForColors( CEAppGlobals* globals );
static XWStreamCtxt* make_generic_stream( CEAppGlobals* globals );
static void ce_send_on_close( XWStreamCtxt* stream, void* closure );
static XP_Bool ceSetDictName( const wchar_t* wPath, XP_U16 index, void* ctxt );
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass (HINSTANCE, LPTSTR);
@ -967,7 +969,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow)
/* choose one. If none found it's an error. */
#ifndef STUBBED_DICT
result = 1 == ceLocateNDicts(MPPARM(mpool) &globals->gameInfo.dictName, 1);
result = 1 == ceLocateNDicts(MPPARM(mpool) 1, ceSetDictName, globals );
/* result = 1 == ceLocateNDicts(MPPARM(mpool) &globals->gameInfo.dictName, 1); */
if ( !result ) {
messageBoxChar( globals, "Please install at least one Crosswords "
"dictionary.", L"Fatal error" );
@ -1016,6 +1019,24 @@ InitInstance(HINSTANCE hInstance, int nCmdShow)
return result;
} /* InitInstance */
static XP_Bool
ceSetDictName( const wchar_t* wPath, XP_U16 index, void* ctxt )
{
CEAppGlobals* globals = (CEAppGlobals*)ctxt;
XP_UCHAR* str;
XP_UCHAR buf[CE_MAX_PATH_LEN];
XP_ASSERT( index == 0 ); /* we said one only! */
WideCharToMultiByte( CP_ACP, 0, wPath, -1,
buf, sizeof(buf)-1, NULL, NULL );
XP_LOGF( "%s: got path \"%s\"", __FUNCTION__, buf );
str = copyString( MPPARM(globals->mpool) buf );
XP_ASSERT( NULL == globals->gameInfo.dictName );
globals->gameInfo.dictName = str;
return NULL != str;
} /* ceSetDictName */
static XP_Bool
ceHandleHintRequest( CEAppGlobals* globals )
{

View file

@ -60,7 +60,7 @@
#define TIMER_CHECK 1024
#define NAME_EDIT5 1025
#define TIMER_EDIT 1026
#define IDC_DICTBUTTON 1027
#define IDC_DICTCOMBO 1027
#define IDC_COMBO3 1028
#define BLANKFACE_COMBO 1029
#define PHONIES_COMBO 1030

View file

@ -250,8 +250,9 @@ BEGIN
ES_PASSWORD | ES_AUTOHSCROLL
LTEXT "Dictionary:",IDC_STATIC,LEFT_COL,DICTPICK_ROW,36,8,SS_NOPREFIX
PUSHBUTTON "Dictionary picker",IDC_DICTBUTTON,43,DICTPICK_ROW,
85, ROW_SPACE
COMBOBOX IDC_DICTCOMBO,43,DICTPICK_ROW,85,ROW_SPACE,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,29,BUTTONS_ROW,31,BUTTON_HT
DEFPUSHBUTTON "Cancel",IDCANCEL,70,BUTTONS_ROW,31,BUTTON_HT
END