1 /*
2   DF-SHOW: An interactive directory/file browser written for Unix-like systems.
3   Based on the applications from the PC-DOS DF-EDIT suite by Larry Kroeker.
4   Copyright (C) 2018-2021  Robert Ian Hawdon
5 
6   This program is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10 
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15 
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #define _GNU_SOURCE
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <ncurses.h>
24 #include <string.h>
25 #include <libconfig.h>
26 #include <wchar.h>
27 #include <math.h>
28 #include "menu.h"
29 #include "settings.h"
30 #include "colors.h"
31 #include "input.h"
32 
33 menuDef *settingsMenu;
34 int settingsMenuSize = 0;
35 wchar_t *settingsMenuLabel;
36 
37 int settingsPos = 0;
38 int settingsBinPos = -1;
39 int settingsFreePos = -1;
40 
updateSetting(settingIndex ** settings,int index,int type,int intSetting)41 void updateSetting(settingIndex **settings, int index, int type, int intSetting)
42 {
43   // To-Do, do a verification on the type
44 
45   (*settings)[index].intSetting = intSetting;
46 }
47 
addT1CharValue(t1CharValues ** values,int * totalItems,int * maxItem,char * refLabel,char * value)48 void addT1CharValue(t1CharValues **values, int *totalItems, int *maxItem, char *refLabel, char *value)
49 {
50   t1CharValues *tmp;
51   int i = *totalItems, j, k;
52 
53   if (i == 0){
54     tmp = malloc(sizeof(t1CharValues) * 2);
55     j = -1;
56   } else {
57     tmp = realloc(*values, (i + 1) * (sizeof(t1CharValues) + 1));
58   }
59 
60   if (tmp){
61     *values = tmp;
62   }
63 
64   for (k = 0; k < i; k++){
65     if (strcmp((*values)[k].refLabel, refLabel)){
66       j = -1;
67     } else {
68       j = (*values)[k].index;
69     }
70   }
71 
72   j++;
73   (*values)[i].index = j;
74   sprintf((*values)[i].refLabel, "%s", refLabel);
75   sprintf((*values)[i].value, "%s", value);
76 
77   ++*totalItems;
78   ++*maxItem;
79 
80 }
81 
addT2BinValue(t2BinValues ** values,int * totalItems,int * maxItem,char * refLabel,char * settingLabel,int reset)82 void addT2BinValue(t2BinValues **values, int *totalItems, int *maxItem, char *refLabel, char *settingLabel, int reset)
83 {
84   t2BinValues *tmp;
85   int value;
86   int i = *totalItems, j;
87 
88   if (i == 0){
89     tmp = malloc(sizeof(t2BinValues) * 2);
90     j = -1;
91   } else {
92     tmp = realloc(*values, (i + 1) * (sizeof(t2BinValues) + 1));
93   }
94 
95   if (tmp){
96     *values = tmp;
97   }
98 
99   if (reset == 1){
100     j = -1;
101   } else {
102     j = ((*values))[i - 1].index;
103   }
104 
105   value = pow(2, *maxItem);
106 
107   j++;
108   ((*values))[i].index = j;
109   sprintf((*values)[i].refLabel, "%s", refLabel);
110   sprintf((*values)[i].settingLabel, "%s", settingLabel);
111   ((*values))[i].value = value;
112   ((*values))[i].boolVal = 0;
113 
114   ++*totalItems;
115   ++*maxItem;
116 
117 }
118 
importSetting(settingIndex ** settings,int * items,char * refLabel,wchar_t * textLabel,int type,char * charSetting,int intSetting,int maxValue,int invert)119 void importSetting(settingIndex **settings, int *items, char *refLabel, wchar_t *textLabel, int type, char *charSetting, int intSetting, int maxValue, int invert)
120 {
121   settingIndex *tmp;
122   int currentItem = *items;
123 
124   if (*items == 0){
125     tmp = malloc(sizeof(settingIndex) * 2);
126   } else {
127     tmp = realloc(*settings, (currentItem + 1) * (sizeof(settingIndex) + 1));
128   }
129 
130   if (tmp){
131     *settings = tmp;
132   }
133 
134   (*settings)[currentItem].type = type;
135   sprintf((*settings)[currentItem].refLabel, "%s", refLabel);
136   swprintf((*settings)[currentItem].textLabel, 32, L"%ls", textLabel);
137   (*settings)[currentItem].intSetting = intSetting;
138   (*settings)[currentItem].maxValue = maxValue;
139   (*settings)[currentItem].invert = invert;
140 
141   if (charSetting){
142     (*settings)[currentItem].charSetting = malloc(sizeof(char) * (strlen(charSetting) + 1));
143     sprintf((*settings)[currentItem].charSetting, "%s", charSetting);
144   }
145 
146   ++*items;
147 }
148 
intSettingValue(int * setting,int newValue)149 int intSettingValue(int *setting, int newValue){
150   if (newValue > -1){
151     *setting = newValue;
152   }
153   return *setting;
154 }
155 
populateBool(t2BinValues ** values,char * refLabel,int setting,int maxValue)156 void populateBool(t2BinValues **values, char *refLabel, int setting, int maxValue)
157 {
158   int i;
159 
160   for (i = maxValue - 1; i > -1 ; i--){
161     if (!strcmp((*values)[i].refLabel, refLabel)){
162       if (setting - ((*values))[i].value > - 1){
163         ((*values))[i].boolVal = 1;
164         setting = setting - ((*values))[i].value;
165       }
166     }
167   }
168 }
169 
adjustBinSetting(settingIndex ** settings,t2BinValues ** values,char * refLabel,int * setting,int maxValue)170 void adjustBinSetting(settingIndex **settings, t2BinValues **values, char *refLabel, int *setting, int maxValue)
171 {
172   int i;
173 
174   for (i = 0; i < maxValue + 1; i++){
175     if (!strcmp((*values)[i].refLabel, refLabel) && ((*values)[i].index == settingsBinPos)){
176       if ((*values)[i].boolVal > 0){
177         (*settings)[settingsPos].intSetting = (*settings)[settingsPos].intSetting - (*values)[i].value;
178         (*values)[i].boolVal = 0;
179       } else {
180         (*settings)[settingsPos].intSetting = (*settings)[settingsPos].intSetting + (*values)[i].value;
181         (*values)[i].boolVal = 1;
182       }
183     }
184   }
185 }
186 
printSetting(int line,int col,settingIndex ** settings,t1CharValues ** values,t2BinValues ** bins,int index,int charIndex,int binIndex,int type,int invert)187 void printSetting(int line, int col, settingIndex **settings, t1CharValues **values, t2BinValues **bins, int index, int charIndex, int binIndex, int type, int invert)
188 {
189 
190   int settingWork, b, c, i, v;
191   int labelLen = 0, valueLen = 0, itemAdjust = 0;
192   char refLabel[16];
193 
194   labelLen = wcslen((*settings)[index].textLabel) + 2;
195   sprintf(refLabel, "%s", (*settings)[index].refLabel);
196 
197   for (i = 0; i < charIndex; i++){
198     if (!strcmp((*values)[i].refLabel, refLabel) && ((*values)[i].index) == 0){
199       v = i;
200     }
201   }
202 
203   for (c = 0; c < binIndex; c++){
204     if (!strcmp((*bins)[c].refLabel, refLabel) && ((*bins)[c].index) == 0){
205       b = c;
206     }
207   }
208 
209   if (type == 0 ){
210     if (invert == 1){
211       if ((*settings)[index].intSetting > 0){
212         settingWork = 0;
213       } else {
214         settingWork = 1;
215       }
216     } else {
217       settingWork = (*settings)[index].intSetting;
218     }
219     setColors(HILITE_PAIR);
220     mvprintw(line, col, "[");
221     if (settingsPos == index){
222       attron(A_REVERSE);
223     }
224     if (settingWork == 0){
225       mvprintw(line, col + 1, " ");
226     } else {
227       mvprintw(line, col + 1, "*");
228     }
229     attroff(A_REVERSE);
230     mvprintw(line, col + 2, "]");
231     setColors(COMMAND_PAIR);
232     mvprintw(line, col + 4, "%ls", (*settings)[index].textLabel);
233   } else if (type == 1){
234     setColors(HILITE_PAIR);
235     mvprintw(line, col, "<");
236     if (settingsPos == index){
237       attron(A_REVERSE);
238     }
239     if ((*settings)[index].maxValue > 0) {
240       mvprintw(line, col + 1, "-");
241     } else {
242       mvprintw(line, col + 1, "?");
243     }
244     attroff(A_REVERSE);
245     mvprintw(line, col + 2, ">");
246     setColors(COMMAND_PAIR);
247     mvprintw(line, col + 4, "%ls:", (*settings)[index].textLabel);
248     for(i = 0; i < ((*settings)[index].maxValue); i++){
249       //Temp Test
250       valueLen = strlen((*values)[i + v].value) + 3;
251       if (i == (*settings)[index].intSetting){
252         setColors(HILITE_PAIR);
253       } else {
254         setColors(COMMAND_PAIR);
255       }
256       mvprintw(line, (col + 4 + labelLen + itemAdjust), "<%s>", (*values)[i + v].value);
257       itemAdjust = itemAdjust + valueLen;
258     }
259   } else if (type == 2){
260     setColors(HILITE_PAIR);
261     mvprintw(line, col, "<");
262     if (settingsPos == index && settingsBinPos < 0){
263       attron(A_REVERSE);
264     }
265     if ((*settings)[index].maxValue > 0) {
266       mvprintw(line, col + 1, " ");
267     } else {
268       mvprintw(line, col + 1, "?");
269     }
270     attroff(A_REVERSE);
271     mvprintw(line, col + 2, ">");
272     setColors(COMMAND_PAIR);
273     mvprintw(line, col + 4, "%ls:", (*settings)[index].textLabel);
274     for(i = 0; i < ((*settings)[index].maxValue); i++){
275       valueLen = strlen((*bins)[i + b].settingLabel) + 3;
276       if ((*bins)[i + b].boolVal == 1){
277         setColors(HILITE_PAIR);
278       }
279       if (settingsBinPos == (i + b) ){
280         attron(A_REVERSE);
281       }
282       mvprintw(line, (col + 4 + labelLen + itemAdjust), "<%s>", (*bins)[i + b].settingLabel);
283       attroff(A_REVERSE);
284       setColors(COMMAND_PAIR);
285       itemAdjust = itemAdjust + valueLen;
286     }
287   } else if (type == 3){
288     // To Do: Add Free Text logic
289     setColors(HILITE_PAIR);
290     mvprintw(line, col, " ");
291     if (settingsPos == index && settingsFreePos < 0){
292       attron(A_REVERSE);
293     }
294     mvprintw(line, col + 1, "-");
295     attroff(A_REVERSE);
296     mvprintw(line, col + 2, ">");
297     setColors(COMMAND_PAIR);
298     mvprintw(line, col + 4, "%ls:", (*settings)[index].textLabel);
299     setColors(HILITE_PAIR);
300     move(line, (col + 4 + labelLen + itemAdjust));
301     mvprintw(line, (col + 4 + labelLen + itemAdjust), "%s", (*settings)[index].charSetting); // To Do
302     setColors(COMMAND_PAIR);
303   }
304 }
305 
textValueLookup(t1CharValues ** values,int * items,char * refLabel,char * value)306 int textValueLookup(t1CharValues **values, int *items, char *refLabel, char *value)
307 {
308   int i;
309 
310   for (i = 0; i < *items; i++){
311     if (!strcmp((*values)[i].value, value) && !strcmp((*values)[i].refLabel, refLabel)){
312       return (*values)[i].index;
313     }
314   }
315 
316   return -1;
317 }
318