1 /* $Id: cdktemplate.c,v 1.14 2016/12/04 15:22:16 tom Exp $ */
2 
3 #include <cdk_test.h>
4 
5 #ifdef XCURSES
6 char *XCursesProgramName = "cdktemplate";
7 #endif
8 
9 /*
10  * Declare file local prototypes.
11  */
12 static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
13 
14 /*
15  * Define file local variables.
16  */
17 static const char *FPUsage = "-p Plate [-o Overlay] [-P Mix Plate] [-d Default Answer] [-m Minimum Length] [-T Title] [-L Label] [-B Buttons] [-O Output file] [-X X Position] [-Y Y Position] [-N] [-S]";
18 
19 /*
20  *
21  */
main(int argc,char ** argv)22 int main (int argc, char **argv)
23 {
24    /* *INDENT-EQLS* */
25    CDKSCREEN *cdkScreen         = 0;
26    CDKTEMPLATE *widget          = 0;
27    CDKBUTTONBOX *buttonWidget   = 0;
28    char *answer                 = 0;
29    char *tmp                    = 0;
30    char *CDK_WIDGET_COLOR       = 0;
31    char *temp                   = 0;
32    chtype *holder               = 0;
33    int buttonCount              = 0;
34    int selection                = 0;
35    int shadowHeight             = 0;
36    FILE *fp                     = stderr;
37    char **buttonList            = 0;
38    int j1, j2;
39 
40    CDK_PARAMS params;
41    boolean boxWidget;
42    boolean mixPlate;
43    boolean shadowWidget;
44    char *buttons;
45    char *defaultAnswer;
46    char *label;
47    char *my_overlay;
48    char *outputFile;
49    char *plate;
50    char *title;
51    int minimum;
52    int xpos;
53    int ypos;
54 
55    CDKparseParams (argc, argv, &params, "d:m:o:p:B:L:O:P:T:" CDK_MIN_PARAMS);
56 
57    /* *INDENT-EQLS* */
58    xpos            = CDKparamValue (&params, 'X', CENTER);
59    ypos            = CDKparamValue (&params, 'Y', CENTER);
60    boxWidget       = CDKparamValue (&params, 'N', TRUE);
61    shadowWidget    = CDKparamValue (&params, 'S', FALSE);
62    minimum         = CDKparamValue (&params, 'm', 0);
63    mixPlate        = CDKparamValue (&params, 'P', FALSE);
64    defaultAnswer   = CDKparamString (&params, 'd');
65    my_overlay      = CDKparamString (&params, 'o');
66    plate           = CDKparamString (&params, 'p');
67    buttons         = CDKparamString (&params, 'B');
68    label           = CDKparamString (&params, 'L');
69    outputFile      = CDKparamString (&params, 'O');
70    title           = CDKparamString (&params, 'T');
71 
72    /* Make sure all the command line parameters were provided. */
73    if (plate == 0)
74    {
75       fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
76       ExitProgram (CLI_ERROR);
77    }
78 
79    /* If the user asked for an output file, try to open it. */
80    if (outputFile != 0)
81    {
82       if ((fp = fopen (outputFile, "w")) == 0)
83       {
84 	 fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
85 	 ExitProgram (CLI_ERROR);
86       }
87    }
88 
89    cdkScreen = initCDKScreen (NULL);
90 
91    /* Start color. */
92    initCDKColor ();
93 
94    /* Check if the user wants to set the background of the main screen. */
95    if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
96    {
97       holder = char2Chtype (temp, &j1, &j2);
98       wbkgd (cdkScreen->window, holder[0]);
99       wrefresh (cdkScreen->window);
100       freeChtype (holder);
101    }
102 
103    /* Get the widget color background color. */
104    if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
105    {
106       CDK_WIDGET_COLOR = 0;
107    }
108 
109    /* Create the template widget. */
110    widget = newCDKTemplate (cdkScreen, xpos, ypos,
111 			    title, label,
112 			    plate, my_overlay,
113 			    boxWidget, shadowWidget);
114 
115    /* Check to make sure we created the widget. */
116    if (widget == 0)
117    {
118       /* Shut down curses and CDK. */
119       destroyCDKScreen (cdkScreen);
120       endCDK ();
121 
122       fprintf (stderr,
123 	       "Error: Could not create the template field. "
124 	       "Is the window too small?\n");
125 
126       ExitProgram (CLI_ERROR);
127    }
128 
129    /* Split the buttons if they supplied some. */
130    if (buttons != 0)
131    {
132       /* Split the button list up. */
133       buttonList = CDKsplitString (buttons, '\n');
134       buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
135 
136       /* We need to create a buttonbox widget. */
137       buttonWidget = newCDKButtonbox (cdkScreen,
138 				      getbegx (widget->win),
139 				      (getbegy (widget->win)
140 				       + widget->boxHeight - 1),
141 				      1, widget->boxWidth - 1,
142 				      0, 1, buttonCount,
143 				      (CDK_CSTRING2) buttonList, buttonCount,
144 				      A_REVERSE, boxWidget, FALSE);
145       setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
146       setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
147 
148       /*
149        * We need to set the lower left and right
150        * characters of the widget.
151        */
152       setCDKTemplateLLChar (widget, ACS_LTEE);
153       setCDKTemplateLRChar (widget, ACS_RTEE);
154 
155       /*
156        * Bind the Tab key in the widget to send a
157        * Tab key to the button box widget.
158        */
159       bindCDKObject (vTEMPLATE, widget, KEY_TAB, widgetCB, buttonWidget);
160       bindCDKObject (vTEMPLATE, widget, CDK_NEXT, widgetCB, buttonWidget);
161       bindCDKObject (vTEMPLATE, widget, CDK_PREV, widgetCB, buttonWidget);
162 
163       /* Check if the user wants to set the background of the widget. */
164       setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
165 
166       /* Draw the button widget. */
167       drawCDKButtonbox (buttonWidget, boxWidget);
168    }
169 
170    /*
171     * If the user asked for a shadow, we need to create one.  Do this instead
172     * of using the shadow parameter because the button widget is not part of
173     * the main widget and if the user asks for both buttons and a shadow, we
174     * need to create a shadow big enough for both widgets.  Create the shadow
175     * window using the widgets shadowWin element, so screen refreshes will draw
176     * them as well.
177     */
178    if (shadowWidget == TRUE)
179    {
180       /* Determine the height of the shadow window. */
181       shadowHeight = (buttonWidget == 0 ?
182 		      widget->boxHeight :
183 		      widget->boxHeight + buttonWidget->boxHeight - 1);
184 
185       /* Create the shadow window. */
186       widget->shadowWin = newwin (shadowHeight,
187 				  widget->boxWidth,
188 				  getbegy (widget->win) + 1,
189 				  getbegx (widget->win) + 1);
190 
191       /* Make sure we could have created the shadow window. */
192       if (widget->shadowWin != 0)
193       {
194 	 widget->shadow = TRUE;
195 
196 	 /*
197 	  * We force the widget and buttonWidget to be drawn so the
198 	  * buttonbox widget will be drawn when the widget is activated.
199 	  * Otherwise the shadow window will draw over the button widget.
200 	  */
201 	 drawCDKTemplate (widget, ObjOf (widget)->box);
202 	 eraseCDKButtonbox (buttonWidget);
203 	 drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
204       }
205    }
206 
207    /* Check if the user wants to set the background of the widget. */
208    setCDKTemplateBackgroundColor (widget, CDK_WIDGET_COLOR);
209 
210    /* If a default answer were proivded, set it in the widget. */
211    if (defaultAnswer != 0)
212    {
213       setCDKTemplateValue (widget, defaultAnswer);
214    }
215 
216    /* If the user asked for a minimum value, set it. */
217    setCDKTemplateMin (widget, minimum);
218 
219    /* Activate the widget. */
220    tmp = activateCDKTemplate (widget, 0);
221 
222    /* If the user asked for plate mixing, give it to them. */
223    if (mixPlate == TRUE)
224    {
225       answer = mixCDKTemplate (widget);
226    }
227    else
228    {
229       answer = copyChar (tmp);
230    }
231 
232    /* If there were buttons, get the button selected. */
233    if (buttonWidget != 0)
234    {
235       selection = buttonWidget->currentButton;
236       destroyCDKButtonbox (buttonWidget);
237    }
238 
239    /* End CDK. */
240    destroyCDKTemplate (widget);
241    destroyCDKScreen (cdkScreen);
242    endCDK ();
243 
244    /* Print the value from the widget. */
245    if (answer != 0)
246    {
247       fprintf (fp, "%s\n", answer);
248       freeChar (answer);
249    }
250    fclose (fp);
251 
252    /* Exit with the button number picked. */
253    ExitProgram (selection);
254 }
255 
widgetCB(EObjectType cdktype GCC_UNUSED,void * object GCC_UNUSED,void * clientData,chtype key)256 static int widgetCB (EObjectType cdktype GCC_UNUSED,
257 		     void *object GCC_UNUSED,
258 		     void *clientData,
259 		     chtype key)
260 {
261    CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
262    (void) injectCDKButtonbox (buttonbox, key);
263    return (TRUE);
264 }
265