summaryrefslogtreecommitdiff
path: root/app/bin/paramfilesearch_ui.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2020-08-22 14:05:41 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2020-08-22 14:05:41 +0200
commitb55285a77da0e0b829e4ce8d7e09debaabc68e15 (patch)
treef622559ef65bbdd3e1c5bdb06098a8f89eec0563 /app/bin/paramfilesearch_ui.c
parentd3897ce090dbeb220ed2c782f095597e417cf3cc (diff)
parentd1ae75703e1ed81d65ea16946dcdb77e7a13adc9 (diff)
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'app/bin/paramfilesearch_ui.c')
-rw-r--r--app/bin/paramfilesearch_ui.c426
1 files changed, 426 insertions, 0 deletions
diff --git a/app/bin/paramfilesearch_ui.c b/app/bin/paramfilesearch_ui.c
new file mode 100644
index 0000000..bf9c47a
--- /dev/null
+++ b/app/bin/paramfilesearch_ui.c
@@ -0,0 +1,426 @@
+/** \file paramfilesearch_ui.c
+ * Parameter File Search Dialog
+ */
+
+/* XTrkCad - Model Railroad CAD
+ * Copyright (C) 2019 Martin Fischer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * 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 "fileio.h"
+#include "directory.h"
+
+#include "bitmaps/magnifier.xpm"
+
+static CatalogEntry *catalogFileBrowse; /**< current search results */
+static TrackLibrary *trackLibrary; /**< Track Library */
+static CatalogEntry *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 SearchUiApply(wWin_p junk);
+static void SearchUiSelectAll(void *junk);
+static void SearchUiDoSearch(void *junk);
+
+static long searchUiMode = 0;
+static paramListData_t searchUiListData = { 10, 370, 0 };
+#define MAXQUERYLENGTH 250
+static char searchUiQuery[MAXQUERYLENGTH];
+static char * searchUiLabels[] = { N_("Show File Names"), NULL };
+
+static paramData_t searchUiPLs[] = {
+#define I_QUERYSTRING (0)
+ { PD_STRING, searchUiQuery, "query", PDO_NOPREF | PDO_STRINGLIMITLENGTH, (void*)(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_LIST, NULL, "inx", PDO_NOPREF | PDO_DLGRESIZE, &searchUiListData, NULL, BL_DUP|BL_SETSTAY|BL_MANY },
+#define I_MODETOGGLE (4)
+ { 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 SEARCHBUTTON ((wButton_p)searchUiPLs[I_SEARCHBUTTON].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)
+
+static paramGroup_t searchUiPG = { "searchgui", 0, searchUiPLs, sizeof searchUiPLs/sizeof searchUiPLs[0] };
+static wWin_p searchUiW;
+
+#define FILESECTION "file"
+#define PARAMDIRECTORY "paramdir"
+
+/**
+ * Reload the listbox showing the current catalog
+ */
+
+static
+void SearchFileListLoad(CatalogEntry *catalog)
+{
+ CatalogEntry *currentEntry = catalog->next;
+ 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]);
+ }
+
+ currentEntry = currentEntry->next;
+ }
+
+ wControlShow((wControl_p)RESULTLIST, TRUE);
+ wControlActive((wControl_p)SELECTALLBUTTON,
+ 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;
+}
+
+
+/**
+ * Reload just the system files into the searchable set
+ */
+
+static void SearchUiDefault(void * junk)
+{
+
+ if (!catalogFileBrowse)
+ catalogFileBrowse = InitCatalog();
+ else {
+ EmptyCatalog(catalogFileBrowse);
+ }
+
+ if (trackLibrary)
+ DeleteLibrary(trackLibrary);
+
+ char * parms_path;
+
+ MakeFullpath(&parms_path, wGetAppLibDir(), "params", NULL);
+
+ trackLibrary = CreateLibrary(parms_path);
+
+ SearchFileListLoad(trackLibrary->catalog); //Start with system files
+
+ free(parms_path);
+
+}
+
+/**
+ * Load the selected items of search results
+ */
+
+void static
+SearchUILoadResults(void)
+{
+ char **fileNames;
+ int files = wListGetSelectedCount(RESULTLIST);
+ int found = 0;
+
+ if (files) {
+ fileNames = malloc(sizeof(char *)*files);
+ if (!fileNames) {
+ AbortProg("Couldn't allocate memory for result list: %s (%d)", __FILE__,
+ __LINE__, NULL);
+ }
+
+ for (int inx = 0; found < files; inx++) {
+ if (wListGetItemSelected(RESULTLIST, inx)) {
+ fileNames[found++] = (char *)wListGetItemContext(RESULTLIST, inx);
+ }
+ }
+
+ LoadParamFile(files, fileNames, NULL);
+ free(fileNames);
+ SearchUiOk((void *) 0);
+ }
+
+}
+
+/**
+ * Update the action buttons.
+ *
+ * If there is at least one selected file, Apply is enabled
+ * If there are entries in the list, Select All is enabled
+ *
+ * \return
+ */
+
+static void UpdateSearchUiButton(void)
+{
+ wIndex_t selCnt = wListGetSelectedCount(RESULTLIST);
+ wIndex_t cnt = wListGetCount(RESULTLIST);
+
+ wControlActive((wControl_p)APPLYBUTTON, selCnt > 0);
+ wControlActive((wControl_p)SELECTALLBUTTON, cnt > 0);
+}
+
+// Return a pointer to the (shifted) 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);
+}
+
+/**
+ * Perform the search. If successful, the results are loaded into the list
+ *
+ * \param ptr INignored
+ */
+
+static void SearchUiDoSearch(void * ptr)
+{
+ unsigned result;
+
+ char * search;
+
+ search = StringTrim(searchUiQuery);
+
+ if (catalogFileBrowse) {
+ EmptyCatalog(catalogFileBrowse);
+ } else
+ catalogFileBrowse = InitCatalog();
+
+ result = SearchLibrary(trackLibrary, search, catalogFileBrowse);
+
+ if (result) {
+ DynString hitsMessage;
+ DynStringMalloc(&hitsMessage, 16);
+ DynStringPrintf(&hitsMessage, _("%d parameter files found."), result);
+ wMessageSetValue(MESSAGETEXT, DynStringToCStr(&hitsMessage));
+ DynStringFree(&hitsMessage);
+
+ SearchFileListLoad(catalogFileBrowse);
+
+ } else {
+
+ wListClear(RESULTLIST);
+ wControlActive((wControl_p)SELECTALLBUTTON, FALSE);
+ wMessageSetValue(MESSAGETEXT, _("No matches found."));
+ }
+}
+
+/**
+ * Select all files in the list
+ *
+ * \param junk IN ignored
+ * \return
+ */
+
+static void SearchUiSelectAll(void *junk)
+{
+ wListSelectAll(RESULTLIST);
+}
+
+/**
+ * Action handler for Done button. Hides the dialog.
+ *
+ * \param [in,out] junk ignored.
+ */
+
+void SearchUiOk(void * junk)
+{
+ if (searchUiW) {
+ wHide(searchUiW);
+ }
+}
+
+/**
+ * Handle the Add button: a list of selected list elements is created and
+ * passed to the parameter file list.
+ *
+ * \param junk IN/OUT ignored
+ */
+
+static void SearchUiApply(wWin_p junk)
+{
+ SearchUILoadResults();
+}
+
+/**
+ * Event handling for the Search dialog. If the 'X' decoration is pressed the
+ * dialog window is closed.
+ *
+ * \param pg IN ignored
+ * \param inx IN ignored
+ * \param valueP IN ignored
+ */
+
+static void SearchUiDlgUpdate(
+ paramGroup_p pg,
+ int inx,
+ void * valueP)
+{
+ switch (inx) {
+ case I_RESULTLIST:
+ UpdateSearchUiButton();
+ break;
+ case I_MODETOGGLE:
+ SearchFileListLoad(currentCat);
+ break;
+ case -1:
+ SearchUiOk(valueP);
+ break;
+ }
+}
+
+/**
+ * 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.
+ *
+ * \return parameter file directory
+ */
+
+static char *
+GetParamsPath()
+{
+ 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);
+}
+/**
+ * Create and open the search dialog.
+ *
+ * \param junk
+ */
+
+void DoSearchParams(void * junk)
+{
+ if (searchUiW == NULL) {
+ catalogFileBrowse = InitCatalog();
+
+ //Make the Find menu bound to the System Library initially
+ char *paramsDir = GetParamsPath();
+ trackLibrary = CreateLibrary(paramsDir);
+ free(paramsDir);
+
+ searchUiPLs[I_SEARCHBUTTON].winLabel = (char *)wIconCreatePixMap(magnifier_xpm);
+
+ ParamRegister(&searchUiPG);
+
+ searchUiW = ParamCreateDialog(&searchUiPG,
+ MakeWindowTitle(_("Choose parameter files")), _("Done"), NULL, wHide,
+ 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);
+ }
+
+ 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
+
+ }
+ wShow(searchUiW);
+}
+
+