diff options
Diffstat (limited to 'app/bin/paramfilesearch_ui.c')
-rw-r--r-- | app/bin/paramfilesearch_ui.c | 394 |
1 files changed, 235 insertions, 159 deletions
diff --git a/app/bin/paramfilesearch_ui.c b/app/bin/paramfilesearch_ui.c index bf9c47a..15498f8 100644 --- a/app/bin/paramfilesearch_ui.c +++ b/app/bin/paramfilesearch_ui.c @@ -2,7 +2,7 @@ * Parameter File Search Dialog */ -/* XTrkCad - Model Railroad CAD +/* XTrackCAD - Model Railroad CAD * Copyright (C) 2019 Martin Fischer * * This program is free software; you can redistribute it and/or modify @@ -20,106 +20,151 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <assert.h> -#include <ctype.h> -#include <stdbool.h> -#include <stdint.h> -#include <string.h> - #include "custom.h" #include "dynstring.h" -#include "i18n.h" -#include "messages.h" #include "param.h" #include "include/partcatalog.h" #include "paths.h" #include "include/paramfilelist.h" +#include "include/paramfile.h" #include "fileio.h" #include "directory.h" +#include "misc2.h" +#include "layout.h" -#include "bitmaps/magnifier.xpm" - -static CatalogEntry *catalogFileBrowse; /**< current search results */ -static TrackLibrary *trackLibrary; /**< Track Library */ -static CatalogEntry *currentCat; /**< catalog being shown */ +static ParameterLib *trackLibrary; /**< Track Library */ +static Catalog currentCat; /**< catalog being shown */ /* define the search / browse dialog */ -static struct wFilSel_t *searchUi_fs; /**< searchdialog for parameter files */ - -static void SearchUiBrowse(void *junk); -static void SearchUiDefault(void * junk); +static void SearchUiDefault(void); static void SearchUiApply(wWin_p junk); static void SearchUiSelectAll(void *junk); static void SearchUiDoSearch(void *junk); +static void SearchUiClearFilter(void *ptr); static long searchUiMode = 0; +static long searchFitMode = 0; static paramListData_t searchUiListData = { 10, 370, 0 }; #define MAXQUERYLENGTH 250 static char searchUiQuery[MAXQUERYLENGTH]; static char * searchUiLabels[] = { N_("Show File Names"), NULL }; +// Note these are defined in the same order as FIT_ANY, FIT_COMPATIBLE, FIT_EXACT +static char * searchFitLabels[] = { N_("Fit Any"), N_("Fit Compatible"), N_("Fit Exact"), NULL}; + + +#define QUERYPROMPTSTRING "Enter at least one search word" static paramData_t searchUiPLs[] = { #define I_QUERYSTRING (0) - { PD_STRING, searchUiQuery, "query", PDO_NOPREF | PDO_STRINGLIMITLENGTH, (void*)(340), "", 0, 0, MAXQUERYLENGTH-1 }, + { PD_STRING, searchUiQuery, "query", PDO_ENTER | PDO_NOPREF | PDO_STRINGLIMITLENGTH | PDO_DLGRESIZE, I2VP(340), "", 0, 0, MAXQUERYLENGTH-1 }, #define I_SEARCHBUTTON (1) - { PD_BUTTON, (void*)SearchUiDoSearch, "find", PDO_DLGHORZ, 0, NULL, BO_ICON, (void *)NULL }, -#define I_MESSAGE (2) - { PD_MESSAGE, N_("Enter at least one search word"), NULL, PDO_DLGBOXEND, (void *)370 }, -#define I_RESULTLIST (3) + { PD_BUTTON, SearchUiDoSearch, "find", PDO_DLGHORZ, 0, NULL, BO_ICON, NULL }, +#define I_CLEARBUTTON (2) + { PD_BUTTON, SearchUiClearFilter, "clearfilter", PDO_DLGHORZ, 0, NULL, BO_ICON, NULL }, +#define I_FITRADIO (3) + { PD_RADIO, &searchFitMode, "fit", PDO_NOPREF | PDO_DLGBOXEND, searchFitLabels, NULL, BC_HORZ|BC_NOBORDER }, +#define I_MESSAGE (4) + { PD_MESSAGE, N_(QUERYPROMPTSTRING), NULL, 0, I2VP(370) }, +#define I_STATISTICS (5) + { PD_MESSAGE, "", NULL, PDO_DLGBOXEND, I2VP(370) }, +#define I_RESULTLIST (6) { PD_LIST, NULL, "inx", PDO_NOPREF | PDO_DLGRESIZE, &searchUiListData, NULL, BL_DUP|BL_SETSTAY|BL_MANY }, -#define I_MODETOGGLE (4) +#define I_MODETOGGLE (7) { PD_TOGGLE, &searchUiMode, "mode", PDO_DLGBOXEND, searchUiLabels, NULL, BC_HORZ|BC_NOBORDER }, -#define I_APPLYBUTTON (5) - { PD_BUTTON, (void *)SearchUiApply, "apply", PDO_DLGCMDBUTTON, NULL, N_("Add") }, -#define I_SELECTALLBUTTON (6) - { PD_BUTTON, (void*)SearchUiSelectAll, "selectall", PDO_DLGCMDBUTTON, NULL, N_("Select all") }, - { PD_BUTTON, (void*)SearchUiDefault, "default", 0, NULL, N_("Reload Library") }, +#define I_APPLYBUTTON (8) + { PD_BUTTON, SearchUiApply, "apply", PDO_DLGCMDBUTTON, NULL, N_("Add") }, +#define I_SELECTALLBUTTON (9) + { PD_BUTTON, SearchUiSelectAll, "selectall", PDO_DLGCMDBUTTON, NULL, N_("Select all") }, }; #define SEARCHBUTTON ((wButton_p)searchUiPLs[I_SEARCHBUTTON].control) +#define CLEARBUTTON ((wButton_p)searchUiPLs[I_CLEARBUTTON].control) #define RESULTLIST ((wList_p)searchUiPLs[I_RESULTLIST].control) #define APPLYBUTTON ((wButton_p)searchUiPLs[I_APPLYBUTTON].control) #define SELECTALLBUTTON ((wButton_p)searchUiPLs[I_SELECTALLBUTTON].control) #define MESSAGETEXT ((wMessage_p)searchUiPLs[I_MESSAGE].control) #define QUERYSTRING ((wString_p)searchUiPLs[I_QUERYSTRING].control) +#define SEARCHSTAT ((wMessage_p)searchUiPLs[I_STATISTICS].control) +#define FITRADIO ((wChoice_p)searchUiPLs[I_FITRADIO].control) -static paramGroup_t searchUiPG = { "searchgui", 0, searchUiPLs, sizeof searchUiPLs/sizeof searchUiPLs[0] }; +static paramGroup_t searchUiPG = { "searchgui", 0, searchUiPLs, COUNT( searchUiPLs ) }; static wWin_p searchUiW; #define FILESECTION "file" #define PARAMDIRECTORY "paramdir" + +/** + * Clears the current catalog + */ + +void +ClearCurrentCatalog(void) +{ + if (currentCat.head) { + DestroyCatalog(¤tCat); + currentCat.head = NULL; + } +} + /** - * Reload the listbox showing the current catalog + * Reload the listbox showing the current catalog. The catalog is either the system + * default library catalog or a search result + * + * \param [in] catalog the current catalog. */ static -void SearchFileListLoad(CatalogEntry *catalog) +int SearchFileListLoad(Catalog *catalog) + { - CatalogEntry *currentEntry = catalog->next; + CatalogEntry *head = catalog->head; + CatalogEntry *catalogEntry; + DynString description; DynStringMalloc(&description, STR_SHORT_SIZE); wControlShow((wControl_p)RESULTLIST, FALSE); wListClear(RESULTLIST); - while (currentEntry != currentEntry->next) { - for (unsigned int i=0;i<currentEntry->files;i++) { - DynStringClear(&description); - DynStringCatCStr(&description, - ((!searchUiMode) && currentEntry->contents) ? - currentEntry->contents : - currentEntry->fullFileName[i]); - - wListAddValue(RESULTLIST, - DynStringToCStr(&description), - NULL, - // indicatorIcons[paramFileInfo.favorite][paramFileInfo.trackState], - (void*)currentEntry->fullFileName[i]); + DL_FOREACH(head, catalogEntry) { + for (unsigned int i=0; i<catalogEntry->files; i++) { + if (catalogEntry->tag && searchFitMode != 0) { + char * type_copy = MyStrdup(catalogEntry->tag); + char * cp = type_copy; + char * type = strtok(cp, " \t"); + SCALE_FIT_TYPE_T fit_type; + if (strcmp(type,TURNOUTCOMMAND) == 0) + fit_type = FIT_TURNOUT; + else if (strcmp(type,STRUCTURECOMMAND)==0) + fit_type = FIT_STRUCTURE; + else if ((strcmp(type,CARCOMMAND)==0) || (strcmp(type,CARPROTOCOMMAND)==0)) + fit_type = FIT_CAR; + char * scale = strtok(NULL, " \t\n"); + if (scale) { + SCALEINX_T scale1 = LookupScale(scale); + SCALEINX_T scale2 = GetLayoutCurScale(); + if (searchFitMode == FIT_COMPATIBLE) { + if (CompatibleScale(fit_type,scale1,scale2)<FIT_COMPATIBLE) continue; + } else { + if (CompatibleScale(fit_type,scale1,scale2)<FIT_EXACT) continue; + } + + } + MyFree(type_copy); + } + DynStringClear(&description); + DynStringCatCStr(&description, + ((!searchUiMode) && catalogEntry->contents) ? + catalogEntry->contents : + catalogEntry->fullFileName[i]); + + wListAddValue(RESULTLIST, + DynStringToCStr(&description), + NULL, + catalogEntry->fullFileName[i]); } - - currentEntry = currentEntry->next; } wControlShow((wControl_p)RESULTLIST, TRUE); @@ -127,55 +172,27 @@ void SearchFileListLoad(CatalogEntry *catalog) wListGetCount(RESULTLIST)); DynStringFree(&description); - - currentCat = catalog; -} - -/** - * Find parameter files using the file selector - * - * \param junk - */ - -static void SearchUiBrowse(void * junk) -{ - - //EmptyCatalog(catalogFileBrowse); - - wFilSelect(searchUi_fs, GetParamFileDir()); - - //SearchFileListLoad(catalogFileBrowse); - - return; + return wListGetCount(RESULTLIST); } - /** * Reload just the system files into the searchable set */ -static void SearchUiDefault(void * junk) +static void SearchUiDefault(void) { + DynString dsSummary; - if (!catalogFileBrowse) - catalogFileBrowse = InitCatalog(); - else { - EmptyCatalog(catalogFileBrowse); - } - - if (trackLibrary) - DeleteLibrary(trackLibrary); - - char * parms_path; + int matches = SearchFileListLoad(trackLibrary->catalog); //Start with system files + wStringSetValue(QUERYSTRING, ""); - MakeFullpath(&parms_path, wGetAppLibDir(), "params", NULL); - - trackLibrary = CreateLibrary(parms_path); - - SearchFileListLoad(trackLibrary->catalog); //Start with system files - - free(parms_path); + wMessageSetValue(MESSAGETEXT, _(QUERYPROMPTSTRING)); + DynStringMalloc(&dsSummary, 16); + DynStringPrintf(&dsSummary, _("%u parameter files in library. %d Fit Scale."), CountCatalogEntries(trackLibrary->catalog), matches); + wMessageSetValue(SEARCHSTAT, DynStringToCStr(&dsSummary)); + DynStringFree(&dsSummary); + wControlActive((wControl_p)CLEARBUTTON, FALSE); } /** @@ -185,12 +202,12 @@ static void SearchUiDefault(void * junk) void static SearchUILoadResults(void) { - char **fileNames; int files = wListGetSelectedCount(RESULTLIST); - int found = 0; if (files) { - fileNames = malloc(sizeof(char *)*files); + char **fileNames; + int found = 0; + fileNames = MyMalloc(sizeof(char *)*files); if (!fileNames) { AbortProg("Couldn't allocate memory for result list: %s (%d)", __FILE__, __LINE__, NULL); @@ -198,13 +215,13 @@ SearchUILoadResults(void) for (int inx = 0; found < files; inx++) { if (wListGetItemSelected(RESULTLIST, inx)) { - fileNames[found++] = (char *)wListGetItemContext(RESULTLIST, inx); + fileNames[found++] = (char *)wListGetItemContext(RESULTLIST, inx); } } LoadParamFile(files, fileNames, NULL); - free(fileNames); - SearchUiOk((void *) 0); + MyFree(fileNames); + SearchUiOk(NULL); } } @@ -227,62 +244,95 @@ static void UpdateSearchUiButton(void) wControlActive((wControl_p)SELECTALLBUTTON, cnt > 0); } -// Return a pointer to the (shifted) trimmed string +/** + * Return a pointer to the (shifted) trimmed string + * + * \param [in,out] s If non-null, a char to process. + * + * \returns pointer to the trimmed string + */ + char * StringTrim(char *s) { - char *original = s; - size_t len = 0; - - while (isspace((unsigned char) *s)) { - s++; - } - if (*s) { - char *p = s; - while (*p) p++; - while (isspace((unsigned char) *(--p))); - p[1] = '\0'; - len = (size_t) (p - s + 1); - } - - return (s == original) ? s : memmove(original, s, len + 1); + char *original = s; + size_t len = 0; + + while (isspace((unsigned char) *s)) { + s++; + } + if (*s) { + char *p = s; + while (*p) { + p++; + } + while (isspace((unsigned char) *(--p))); + p[1] = '\0'; + len = (size_t)(p - s + 1); + } + + return (s == original) ? s : memmove(original, s, len + 1); } /** * Perform the search. If successful, the results are loaded into the list * - * \param ptr INignored + * \param [in,out] ptr ignored. */ static void SearchUiDoSearch(void * ptr) { unsigned result; - + SearchResult *currentResults = MyMalloc(sizeof(SearchResult)); char * search; + ClearCurrentCatalog(); + + strcpy(searchUiQuery, wStringGetValue((wString_p)searchUiPG.paramPtr[I_QUERYSTRING].control)); search = StringTrim(searchUiQuery); - if (catalogFileBrowse) { - EmptyCatalog(catalogFileBrowse); - } else - catalogFileBrowse = InitCatalog(); + if (search[0]) { + result = SearchLibrary(trackLibrary, search, currentResults); - result = SearchLibrary(trackLibrary, search, catalogFileBrowse); + if (result) { - if (result) { - DynString hitsMessage; - DynStringMalloc(&hitsMessage, 16); - DynStringPrintf(&hitsMessage, _("%d parameter files found."), result); - wMessageSetValue(MESSAGETEXT, DynStringToCStr(&hitsMessage)); - DynStringFree(&hitsMessage); + char *statistics; - SearchFileListLoad(catalogFileBrowse); + statistics = SearchStatistics(currentResults); + wMessageSetValue(SEARCHSTAT, statistics); + MyFree(statistics); - } else { + int matches = SearchFileListLoad(&(currentResults->subCatalog)); - wListClear(RESULTLIST); - wControlActive((wControl_p)SELECTALLBUTTON, FALSE); - wMessageSetValue(MESSAGETEXT, _("No matches found.")); - } + DynString hitsMessage; + DynStringMalloc(&hitsMessage, 16); + DynStringPrintf(&hitsMessage, _("%d parameter files found. %d Fit Scale"), result, matches); + wMessageSetValue(MESSAGETEXT, DynStringToCStr(&hitsMessage)); + DynStringFree(&hitsMessage); + + currentCat = currentResults->subCatalog; + wControlActive((wControl_p)CLEARBUTTON, TRUE); + } else { + wListClear(RESULTLIST); + wControlActive((wControl_p)SELECTALLBUTTON, FALSE); + wMessageSetValue(MESSAGETEXT, _("No matches found.")); + } + } else { + SearchUiDefault(); + } + MyFree(currentResults); //Because SearchFileList also caches the currentResults->subCatalog address as currentCatalog for reuse. +} + +/** + * Clear the current filter + * + * \param [in,out] ptr ignored + */ + +static void +SearchUiClearFilter(void *ptr) +{ + ClearCurrentCatalog(); + SearchUiDefault(); } /** @@ -323,7 +373,7 @@ static void SearchUiApply(wWin_p junk) } /** - * Event handling for the Search dialog. If the 'X' decoration is pressed the + * Event handling for the Search dialog. If the 'X' decoration is pressed the * dialog window is closed. * * \param pg IN ignored @@ -337,20 +387,41 @@ static void SearchUiDlgUpdate( void * valueP) { switch (inx) { + case I_QUERYSTRING: + if (pg->paramPtr[inx].enter_pressed) { + strcpy( searchUiQuery, wStringGetValue((wString_p)pg->paramPtr[inx].control) ); + SearchUiDoSearch(NULL); + } + break; case I_RESULTLIST: UpdateSearchUiButton(); break; + case I_FITRADIO: + strcpy( searchUiQuery, wStringGetValue((wString_p)pg->paramPtr[I_QUERYSTRING].control) ); + SearchUiDoSearch(NULL); + break; case I_MODETOGGLE: - SearchFileListLoad(currentCat); + if (currentCat.head) { + SearchFileListLoad(¤tCat); + } else { + SearchFileListLoad(trackLibrary->catalog); + } + break; + case -1: + SearchUiOk(valueP); break; - case -1: - SearchUiOk(valueP); - break; } } +void +SearchUiCancel(wWin_p window) +{ + ClearCurrentCatalog(); + wHide(window); +} + /** - * Get the system default directory for parameter files. First step is to + * Get the system default directory for parameter files. First step is to * check the configuration file for a user specific setting. If that is not * found, the diretory is based derived from the installation directory. * The returned string has to be free'd() when no longer needed. @@ -361,17 +432,21 @@ static void SearchUiDlgUpdate( static char * GetParamsPath() { - char * params_path; - char *params_pref; - params_pref = wPrefGetString(FILESECTION, PARAMDIRECTORY); + char * params_path; + char *params_pref; + params_pref = wPrefGetString(FILESECTION, PARAMDIRECTORY); - if (!params_pref) { - MakeFullpath(¶ms_path, wGetAppLibDir(), "params", NULL); - } else { - params_path = strdup(params_pref); - } - return(params_path); + if (!params_pref) { + MakeFullpath(¶ms_path, wGetAppLibDir(), "params", NULL); + } else { + params_path = strdup(params_pref); + } + return (params_path); } + +#include "bitmaps/funnel.xpm" +#include "bitmaps/funnelclear.xpm" + /** * Create and open the search dialog. * @@ -381,45 +456,46 @@ GetParamsPath() void DoSearchParams(void * junk) { if (searchUiW == NULL) { - catalogFileBrowse = InitCatalog(); //Make the Find menu bound to the System Library initially - char *paramsDir = GetParamsPath(); + char *paramsDir = GetParamsPath(); trackLibrary = CreateLibrary(paramsDir); - free(paramsDir); + free(paramsDir); - searchUiPLs[I_SEARCHBUTTON].winLabel = (char *)wIconCreatePixMap(magnifier_xpm); + searchUiPLs[I_SEARCHBUTTON].winLabel = (char *)wIconCreatePixMap(funnel_xpm); + searchUiPLs[I_CLEARBUTTON].winLabel = (char *)wIconCreatePixMap( + funnelclear_xpm); + + searchFitMode = FIT_COMPATIBLE; //Default to "Any" after startup ParamRegister(&searchUiPG); + + searchUiW = ParamCreateDialog(&searchUiPG, - MakeWindowTitle(_("Choose parameter files")), _("Done"), NULL, wHide, + MakeWindowTitle(_("Choose parameter files")), _("Done"), NULL, SearchUiCancel, TRUE, NULL, F_RESIZE | F_RECALLSIZE, SearchUiDlgUpdate); - if (trackLibrary) { - SearchFileListLoad(trackLibrary->catalog); //Start with system files - } + + wControlActive((wControl_p)APPLYBUTTON, FALSE); wControlActive((wControl_p)SELECTALLBUTTON, FALSE); - - searchUi_fs = wFilSelCreate(searchUiW, FS_LOAD, FS_MULTIPLEFILES, - _("Load Parameters"), _("Parameter files (*.xtp)|*.xtp"), GetParameterFileInfo, - (void *)catalogFileBrowse); } + wControlActive((wControl_p)FITRADIO, TRUE); + ParamLoadControls(&searchUiPG); ParamGroupRecord(&searchUiPG); + if (!trackLibrary) { wControlActive((wControl_p)SEARCHBUTTON, FALSE); wControlActive((wControl_p)QUERYSTRING, FALSE); wMessageSetValue(MESSAGETEXT, _("No system parameter files found, search is disabled.")); } else { - wStringSetValue(QUERYSTRING, ""); - - SearchFileListLoad(trackLibrary->catalog); //Start with system files - + SearchUiDefault(); } + wShow(searchUiW); } |