From 1b447272b2759059f48ef8272094248da6fd877a Mon Sep 17 00:00:00 2001 From: ehouse Date: Mon, 24 Apr 2006 04:34:42 +0000 Subject: [PATCH] Replace generic "no dictionaries found" warning with list of directories searched and URL from which to download. --- xwords4/wince/cedict.c | 128 ++++++++++++++++++++++++++++++++++++++- xwords4/wince/cedict.h | 2 +- xwords4/wince/cemain.c | 14 ++++- xwords4/wince/xwords4.rc | 6 +- 4 files changed, 143 insertions(+), 7 deletions(-) diff --git a/xwords4/wince/cedict.c b/xwords4/wince/cedict.c index ebd435c6f..a6677db4f 100755 --- a/xwords4/wince/cedict.c +++ b/xwords4/wince/cedict.c @@ -619,6 +619,106 @@ locateOneDir( MPFORMAL wchar_t* path, OnePathCB cb, void* ctxt, XP_U16 nSought, } } /* locateOneDir */ +#define USE_FOREACH /* FOREACH avoids code duplication, but may not be worth + the extra complexity. Size is the same. */ +#ifdef USE_FOREACH +typedef XP_Bool (*ForEachCB)( wchar_t* dir, void* ctxt ); + +static void +forEachDictDir( HINSTANCE hInstance, ForEachCB cb, void* ctxt ) +{ + UINT id; + for ( id = IDS_DICTDIRS; ; ++id ) { + wchar_t pathBuf[CE_MAX_PATH_LEN+1]; + if ( 0 >= LoadString( hInstance, id, pathBuf, + sizeof(pathBuf)/sizeof(pathBuf[0]) ) ) { + break; + } + + if ( !(*cb)( pathBuf, ctxt ) ) { + break; + } + } +} /* forEachDictDir */ + +typedef struct LocateOneData { + XP_U16 nFound; + XP_U16 nSought; + OnePathCB cb; + void* ctxt; + + MPSLOT +} LocateOneData; + +static XP_Bool +locateOneDirCB( wchar_t* dir, void* ctxt ) +{ + LocateOneData* datap = (LocateOneData*)ctxt; + + locateOneDir( MPPARM(datap->mpool) dir, datap->cb, + datap->ctxt, datap->nSought, &datap->nFound ); + + if ( datap->nFound >= datap->nSought ) { + return XP_FALSE; + } + return XP_TRUE; +} /* locateOneDirCB */ + +XP_U16 +ceLocateNDicts( MPFORMAL HINSTANCE hInstance, XP_U16 nSought, + OnePathCB cb, void* ctxt ) +{ + LocateOneData data; + + data.nFound = 0; + data.nSought = nSought; + data.cb = cb; + data.ctxt = ctxt; +#ifdef MEM_DEBUG + data.mpool = mpool; +#endif + + forEachDictDir( hInstance, locateOneDirCB, &data ); + return data.nFound; +} + +typedef struct FormatDirsData { + XWStreamCtxt* stream; + XP_Bool firstPassDone; +} FormatDirsData; + +static XP_Bool +formatDirsCB( wchar_t* dir, void* ctxt ) +{ + FormatDirsData* datap = (FormatDirsData*)ctxt; + XP_UCHAR narrow[CE_MAX_PATH_LEN+1]; + int len; + + if ( datap->firstPassDone ) { + stream_putBytes( datap->stream, ", ", 2 ); + } else { + datap->firstPassDone = XP_TRUE; + } + + len = WideCharToMultiByte( CP_ACP, 0, dir, -1, + narrow, sizeof(narrow)/sizeof(narrow[0]), + NULL, NULL ); + stream_putBytes( datap->stream, narrow, len-1 ); /* skip null */ + return XP_TRUE; +} /* formatDirsCB */ + +void +ceFormatDictDirs( XWStreamCtxt* stream, HINSTANCE hInstance ) +{ + FormatDirsData data; + data.stream = stream; + data.firstPassDone = XP_FALSE; + + forEachDictDir( hInstance, formatDirsCB, &data ); +} + +#else + XP_U16 ceLocateNDicts( MPFORMAL HINSTANCE hInstance, XP_U16 nSought, OnePathCB cb, void* ctxt ) @@ -641,7 +741,33 @@ ceLocateNDicts( MPFORMAL HINSTANCE hInstance, XP_U16 nSought, } return nFound; -} /* ceLocateNthDict */ +} /* ceLocateNDicts */ + +void +ceFormatDictDirs( XWStreamCtxt* stream, HINSTANCE hInstance ) +{ + UINT id; + + for ( id = IDS_DICTDIRS; ; ++id ) { + wchar_t wide[CE_MAX_PATH_LEN+1]; + XP_UCHAR narrow[CE_MAX_PATH_LEN+1]; + XP_U16 len; + + if ( 0 >= LoadString( hInstance, id, wide, + sizeof(wide)/sizeof(wide[0]) ) ) { + break; + } + + if ( id != IDS_DICTDIRS ) { + stream_putBytes( stream, ", ", 2 ); + } + len = WideCharToMultiByte( CP_ACP, 0, wide, -1, + narrow, sizeof(narrow)/sizeof(narrow[0]), + NULL, NULL ); + stream_putBytes( stream, narrow, len-1 ); /* skip null */ + } +} +#endif /* USE_FOREACH */ static XP_U32 n_ptr_tohl( XP_U8** inp ) diff --git a/xwords4/wince/cedict.h b/xwords4/wince/cedict.h index cad996f1d..82987d7ba 100755 --- a/xwords4/wince/cedict.h +++ b/xwords4/wince/cedict.h @@ -40,7 +40,7 @@ DictionaryCtxt* ce_dictionary_make_empty( CEAppGlobals* globals ); typedef XP_Bool (*OnePathCB)( const wchar_t* wPath, XP_U16 index, void* ctxt ); XP_U16 ceLocateNDicts( MPFORMAL HINSTANCE hInstance, XP_U16 nSought, OnePathCB cb, void* ctxt ); - +void ceFormatDictDirs( XWStreamCtxt* stream, HINSTANCE hInstance ); XP_UCHAR* bname( XP_UCHAR* in ); #endif diff --git a/xwords4/wince/cemain.c b/xwords4/wince/cemain.c index 80cc239e2..529fc3c4c 100755 --- a/xwords4/wince/cemain.c +++ b/xwords4/wince/cemain.c @@ -150,6 +150,8 @@ 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 ); +static void messageBoxStream( CEAppGlobals* globals, XWStreamCtxt* stream, + wchar_t* title ); // Forward declarations of functions included in this code module: @@ -972,8 +974,16 @@ InitInstance(HINSTANCE hInstance, int nCmdShow) result = 1 == ceLocateNDicts( MPPARM(mpool) hInstance, 1, ceSetDictName, globals ); if ( !result ) { - messageBoxChar( globals, "Please install at least one Crosswords " - "dictionary.", L"Fatal error" ); + XWStreamCtxt* stream = make_generic_stream( globals ); + char* str = "Please install a Crosswords dictionary " + "in one of these directories: "; + stream_putBytes( stream, str, XP_STRLEN(str) ); + ceFormatDictDirs( stream, hInstance ); + str = ". Download dictionaries from http://xwords.sf.net."; + stream_putBytes( stream, str, XP_STRLEN(str) ); + + messageBoxStream( globals, stream, L"Dictionary Not Found" ); + stream_destroy( stream ); return FALSE; } #endif diff --git a/xwords4/wince/xwords4.rc b/xwords4/wince/xwords4.rc index a198b9ed5..197fcc85a 100755 --- a/xwords4/wince/xwords4.rc +++ b/xwords4/wince/xwords4.rc @@ -663,11 +663,11 @@ BEGIN IDS_FILE "File" IDS_GAME "Game" IDS_MOVE "Move" -#ifdef _WIN32 - IDS_DICTDIRS "." -#else +#ifdef _WIN32_WCE IDS_DICTDIRS "\\Program Files\\Crosswords" IDS_DICTDIRS+1 "\\SD Card\\Crosswords" +#else + IDS_DICTDIRS "." #endif END