summaryrefslogtreecommitdiff
path: root/app/bin/paramfilesearch_ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/paramfilesearch_ui.c')
-rw-r--r--app/bin/paramfilesearch_ui.c394
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(&currentCat);
+ 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(&currentCat);
+ } 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(&params_path, wGetAppLibDir(), "params", NULL);
- } else {
- params_path = strdup(params_pref);
- }
- return(params_path);
+ if (!params_pref) {
+ MakeFullpath(&params_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);
}