1 /*
2  * Motif
3  *
4  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * HISTORY
25  */
26 
27 #ifdef REV_INFO
28 #ifndef lint
29 static char *rcsid = "$TOG: actions.c /main/7 1997/05/02 10:01:40 dbl $";
30 #endif
31 #endif
32 
33 #include <stdlib.h>
34 #include <ctype.h>
35 #include <X11/Intrinsic.h>
36 #include <X11/StringDefs.h>
37 #include <Xm/Xm.h>
38 #include <Xm/SelectioB.h>
39 #include <Xm/Notebook.h>
40 #include <Xm/Form.h>
41 #include <Xm/LabelG.h>
42 #include <Xm/PushBG.h>
43 #include <Xm/PushB.h>
44 #include <Xm/BulletinB.h>
45 #include <Xm/RowColumn.h>
46 #include <Xm/MessageB.h>
47 #include <Xm/TextF.h>
48 #include <Xm/Text.h>
49 #include <Exm/TabB.h>
50 
51 #include "page.h"
52 
53 extern Page pages[];
54 Widget editDialog = 0, deleteDialog = 0;
55 
56 void SetPage(int);
57 void AdjustPages(int, int);
58 void FixPages();
59 void PageChange(Widget w, XtPointer i, XmNotebookCallbackStruct *cs);
60 Page AllocPage();
61 char* Trim(char*);
62 extern void SaveDB(char*);
63 
64 extern Widget shell, textw, labelw, notebook;
65 extern int maxpages, currentPage, modified;
66 
67 void
NewPage(Widget w,XtPointer i,XmPushButtonCallbackStruct * cs)68 NewPage(Widget w, XtPointer i, XmPushButtonCallbackStruct *cs)
69 {
70   Arg args[2];
71 
72   if (modified && pages[currentPage] != NULL) {
73     if (pages[currentPage] -> page != NULL)
74       XtFree(pages[currentPage] -> page);
75      pages[currentPage] -> page = XmTextGetString(textw);
76   }
77   AdjustPages(currentPage, 1);
78   pages[currentPage] = AllocPage();
79   FixPages();
80   XtSetArg(args[0], XmNcurrentPageNumber, (currentPage + 1));
81   XtSetArg(args[1], XmNlastPageNumber, (maxpages + 1));
82   XtSetValues(notebook, args, 2);
83   SetPage(currentPage);
84 }
85 
86 void
DoDeletePage(Widget w,XtPointer i,XmPushButtonCallbackStruct * cs)87 DoDeletePage(Widget w, XtPointer i, XmPushButtonCallbackStruct *cs)
88 {
89   Arg args[2];
90 
91   if (pages[currentPage] != NULL) {
92     if (pages[currentPage] -> page != NULL) XtFree(pages[currentPage] -> page);
93     if (pages[currentPage] -> minorPB != (Widget) 0)
94       XtDestroyWidget(pages[currentPage] -> minorPB);
95     if (pages[currentPage] -> majorPB != (Widget) 0)
96       XtDestroyWidget(pages[currentPage] -> majorPB);
97     XtFree((XtPointer) pages[currentPage]);
98   }
99   pages[currentPage] = NULL;
100   AdjustPages(currentPage, -1);
101 
102   /* If there are no more pages left,  then create a blank one */
103   if (maxpages < 0) {
104     pages[0] = AllocPage();
105     pages[0] -> page = XtMalloc(2);
106     pages[0] -> page[0] = 0;
107     maxpages = 0;
108   }
109 
110   FixPages();
111   XtSetArg(args[0], XmNcurrentPageNumber, (currentPage + 1));
112   XtSetArg(args[1], XmNlastPageNumber, (maxpages + 1));
113   XtSetValues(notebook, args, 2);
114   SetPage(currentPage);
115 }
116 
117 void
DeletePage(Widget w,XtPointer i,XmPushButtonCallbackStruct * cs)118 DeletePage(Widget w, XtPointer i, XmPushButtonCallbackStruct *cs)
119 {
120   if (deleteDialog == 0) {
121     Arg args[10];
122     XmString okLabel, promptText, dialogTitle;
123 
124     dialogTitle = XmStringCreateLocalized("Page Delete Dialog");
125     okLabel = XmStringCreateLocalized("Delete");
126     promptText = XmStringCreateLocalized("Really delete this page?");
127     XtSetArg(args[0], XmNokLabelString, okLabel);
128     XtSetArg(args[1], XmNmessageString, promptText);
129     XtSetArg(args[2], XmNdialogTitle, dialogTitle);
130     XtSetArg(args[3], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL);
131     deleteDialog = XmCreateMessageDialog(shell, "DeletePage",
132 					args, 4);
133     XtAddCallback(deleteDialog, XmNokCallback,
134 		  (XtCallbackProc) DoDeletePage, NULL);
135     XmStringFree(dialogTitle);
136     XmStringFree(okLabel);
137     XmStringFree(promptText);
138   }
139 
140   XtManageChild(deleteDialog);
141 }
142 
143 Widget labelEditW, majorTabW, minorTabW;
144 
145 void
DoEditPage(Widget w,XtPointer ig,XmPushButtonCallbackStruct * cs)146 DoEditPage(Widget w, XtPointer ig, XmPushButtonCallbackStruct *cs)
147 {
148   char *temp;
149   XmString tstr;
150   Arg args[5];
151   int i;
152 
153   pages[currentPage] -> label = XmTextFieldGetString(labelEditW);
154 
155   if (pages[currentPage] -> minorTab != NULL)
156     XtFree(pages[currentPage] -> minorTab);
157   temp = XmTextGetString(minorTabW);
158   temp = Trim(temp);
159   if (strlen(temp) > 0)
160     pages[currentPage] -> minorTab = temp;
161   else {
162     XtFree(temp);
163     pages[currentPage] -> minorTab = NULL;
164     if (pages[currentPage] -> minorPB)
165       XtUnmanageChild(pages[currentPage] -> minorPB);
166   }
167 
168   if (pages[currentPage] -> majorTab != NULL)
169     XtFree(pages[currentPage] -> majorTab);
170   temp = XmTextGetString(majorTabW);
171   temp = Trim(temp);
172   if (strlen(temp) > 0)
173     pages[currentPage] -> majorTab = temp;
174   else {
175     XtFree(temp);
176     pages[currentPage] -> majorTab = NULL;
177     if (pages[currentPage] -> majorPB)
178       XtUnmanageChild(pages[currentPage] -> majorPB);
179   }
180 
181   if (pages[currentPage] -> majorTab != NULL) {
182     if (pages[currentPage] -> majorPB == (Widget) 0) {
183       i = 0;
184       XtSetArg(args[i], XmNpageNumber, currentPage + 1); i++;
185       XtSetArg(args[i], XmNnotebookChildType, XmMAJOR_TAB); i++;
186       XtSetArg(args[i], XmNshadowThickness, 1); i++;
187       pages[currentPage] -> majorPB =
188 	ExmCreateTabButton(notebook, "atab", args, i);
189     }
190     tstr = XmStringGenerate(pages[currentPage] -> majorTab, NULL,
191 			    XmCHARSET_TEXT, NULL);
192     XtSetArg(args[0], ExmNcompoundString, tstr);
193     XtSetValues(pages[currentPage] -> majorPB, args, 1);
194     XtManageChild(pages[currentPage] -> majorPB);
195   }
196 
197   if (pages[currentPage] -> minorTab != NULL) {
198     if (pages[currentPage] -> minorPB == (Widget) 0) {
199       i = 0;
200       XtSetArg(args[i], XmNpageNumber, currentPage + 1); i++;
201       XtSetArg(args[i], XmNnotebookChildType, XmMINOR_TAB); i++;
202       XtSetArg(args[i], XmNshadowThickness, 1); i++;
203       pages[currentPage] -> minorPB =
204 	ExmCreateTabButton(notebook, "atab", args, i);
205     }
206     tstr = XmStringGenerate(pages[currentPage] -> minorTab, NULL,
207 			    XmCHARSET_TEXT, NULL);
208     XtSetArg(args[0], ExmNcompoundString, tstr);
209     XtSetValues(pages[currentPage] -> minorPB, args, 1);
210     XtManageChild(pages[currentPage] -> minorPB);
211   }
212 
213   /* Get contents before update */
214   XtFree(pages[currentPage] -> page);
215   pages[currentPage] -> page = XmTextGetString(textw);
216 
217   SetPage(currentPage);
218 }
219 
220 void
EditPage(Widget w,XtPointer i,XmPushButtonCallbackStruct * cs)221 EditPage(Widget w, XtPointer i, XmPushButtonCallbackStruct *cs)
222 {
223   if (pages[currentPage] == NULL) return;
224 
225   if (editDialog == 0) {
226     Arg args[10];
227     XmString promptText, dialogTitle, temp;
228     XmString okLabel, cancelLabel;
229     Widget label, rc1, rc2;
230 
231     dialogTitle = XmStringCreateLocalized("Page Edit Dialog");
232     promptText = XmStringCreateLocalized("Really edit this page?");
233     okLabel = XmStringCreateLocalized("OK");
234     cancelLabel = XmStringCreateLocalized("Cancel");
235     XtSetArg(args[0], XmNselectionLabelString, promptText);
236     XtSetArg(args[1], XmNdialogTitle, dialogTitle);
237     XtSetArg(args[2], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL);
238     XtSetArg(args[3], XmNokLabelString, okLabel);
239     XtSetArg(args[4], XmNcancelLabelString, cancelLabel);
240     editDialog = XmCreateTemplateDialog(shell, "EditPage",
241 					args, 5);
242     XtAddCallback(editDialog, XmNokCallback,
243 		  (XtCallbackProc) DoEditPage, NULL);
244 
245     XmStringFree(dialogTitle);
246     XmStringFree(promptText);
247     XmStringFree(okLabel);
248     XmStringFree(cancelLabel);
249 
250     XtSetArg(args[0], XmNorientation, XmVERTICAL);
251     rc1 = XmCreateRowColumn(editDialog, "rc", args, 1);
252     XtManageChild(rc1);
253 
254     XtSetArg(args[0], XmNorientation, XmHORIZONTAL);
255     rc2 = XmCreateRowColumn(rc1, "rc2", args, 1);
256     temp = XmStringCreateLocalized("Label:");
257     XtSetArg(args[0], XmNwidth, 100);
258     XtSetArg(args[1], XmNlabelString, temp);
259     label = XmCreateLabelGadget(rc2, "label", args, 2);
260     XtManageChild(label);
261     XmStringFree(temp);
262     XtManageChild(rc2);
263 
264     labelEditW = XmCreateTextField(rc2, "editTF", NULL, 0);
265     XtManageChild(labelEditW);
266 
267     XtSetArg(args[0], XmNorientation, XmHORIZONTAL);
268     rc2 = XmCreateRowColumn(rc1, "rc2", args, 1);
269     temp = XmStringCreateLocalized("Major Tab:");
270     XtSetArg(args[0], XmNwidth, 100);
271     XtSetArg(args[1], XmNlabelString, temp);
272     label = XmCreateLabelGadget(rc2, "label", args, 2);
273     XtManageChild(label);
274     XmStringFree(temp);
275 
276     majorTabW = XmCreateTextField(rc2, "majorTF", NULL, 0);
277     XtManageChild(majorTabW);
278     XtManageChild(rc2);
279 
280     XtSetArg(args[0], XmNorientation, XmHORIZONTAL);
281     rc2 = XmCreateRowColumn(rc1, "rc2", args, 1);
282     temp = XmStringCreateLocalized("Minor Tab:");
283     XtSetArg(args[0], XmNwidth, 100);
284     XtSetArg(args[1], XmNlabelString, temp);
285     label = XmCreateLabelGadget(rc2, "label", args, 2);
286     XtManageChild(label);
287     XmStringFree(temp);
288 
289     minorTabW = XmCreateTextField(rc2, "minorTF", NULL, 0);
290     XtManageChild(minorTabW);
291     XtManageChild(rc2);
292   }
293 
294   if (pages[currentPage] -> label != NULL)
295     XmTextFieldSetString(labelEditW, pages[currentPage] -> label);
296   else
297     XmTextFieldSetString(labelEditW, "");
298 
299   if (pages[currentPage] -> majorTab != NULL)
300     XmTextSetString(majorTabW, pages[currentPage] -> majorTab);
301   else
302     XmTextSetString(majorTabW, "");
303 
304   if (pages[currentPage] -> minorTab != NULL)
305     XmTextSetString(minorTabW, pages[currentPage] -> minorTab);
306   else
307     XmTextSetString(minorTabW, "");
308 
309   XtManageChild(editDialog);
310 }
311 
312 void
SaveIt(Widget w,char * i,XmPushButtonCallbackStruct * e)313 SaveIt(Widget w, char *i, XmPushButtonCallbackStruct *e)
314 {
315   SaveDB(options.todoFile);
316 }
317 
318 void
SetPage(int pageNumber)319 SetPage(int pageNumber)
320 {
321   XmString tmp;
322   char buf[80];
323   Arg args[5];
324 
325   currentPage = pageNumber;
326   if (pageNumber <= maxpages) {
327     XtSetArg(args[0], XmNpageNumber, (pageNumber + 1));
328     XtSetValues(XtParent(textw), args, 1);
329   }
330   if (pages[pageNumber] != NULL) {
331     if (pages[pageNumber] -> page != NULL)
332       XtSetArg(args[0], XmNvalue, pages[pageNumber] -> page);
333     else
334       XtSetArg(args[0], XmNvalue, "");
335     XtSetValues(textw, args, 1);
336 
337     if (pages[pageNumber] -> label != NULL)
338       tmp = XmStringCreateLocalized(pages[pageNumber] -> label);
339     else {
340       sprintf(buf, "Page %d", pageNumber + 1);
341       tmp = XmStringCreateLocalized(buf);
342     }
343   }
344   else {
345     XtSetArg(args[0], XmNvalue, "");
346     XtSetValues(textw, args, 1);
347     sprintf(buf, "Page %d (Bad Page)", pageNumber + 1);
348     tmp = XmStringCreateLocalized(buf);
349   }
350 
351   XmTextSetTopCharacter(textw, pages[pageNumber] -> lasttoppos);
352   XmTextSetInsertionPosition(textw, pages[pageNumber] -> lastcursorpos);
353 
354   XtSetArg(args[0], XmNpageNumber, (pageNumber + 1));
355   XtSetArg(args[1], XmNlabelString, tmp);
356   XtSetValues(labelw, args, 2);
357   XmStringFree(tmp);
358 }
359 
360 void
PageChange(Widget w,XtPointer i,XmNotebookCallbackStruct * cs)361 PageChange(Widget w, XtPointer i, XmNotebookCallbackStruct *cs)
362 {
363   if (modified && pages[currentPage] != NULL) {
364     if (pages[currentPage] -> page != NULL)
365       XtFree(pages[currentPage] -> page);
366     pages[currentPage] -> page = XmTextGetString(textw);
367     pages[currentPage] -> lasttoppos = XmTextGetTopCharacter(textw);
368     pages[currentPage] -> lastcursorpos = XmTextGetInsertionPosition(textw);
369   }
370 
371   SetPage(cs -> page_number - 1);
372 }
373 
374 void
AdjustPages(int startpage,int ins)375 AdjustPages(int startpage, int ins)
376 {
377   int i;
378 
379   /* ins is either +1 or -1 for insert or delete a page */
380 
381   if (ins > 0) {
382     for(i = maxpages; i >= startpage; i--)
383       pages[i + 1] = pages[i];
384     maxpages += 1;
385   } else {
386     for(i = startpage; i <= maxpages; i++)
387       pages[i] = pages[i + 1];
388     maxpages -= 1;
389   }
390 }
391 
FixPages()392 void FixPages() {
393   int i;
394   Arg args[2];
395 
396   /* Now scan the pages and fix the tabs */
397   for (i = 0; i <= maxpages; i++) {
398     XtSetArg(args[0], XmNpageNumber, (i + 1));
399     if (pages[i] -> majorPB != (Widget) 0)
400       XtSetValues(pages[i] -> majorPB, args, 1);
401     if (pages[i] -> minorPB != (Widget) 0)
402       XtSetValues(pages[i] -> minorPB, args, 1);
403   }
404 }
405 
406 /* This function removes leading and trailing whitespace.  It
407    deallocates the original string and returns a brand new string */
408 
409 char*
Trim(char * str)410 Trim(char* str)
411 {
412   char *new;
413   int first, last;
414   int length;
415 
416   if (str == NULL) return(XtNewString(""));
417 
418   length = strlen(str);
419 
420   for(first = 0; first < length && isspace(str[first]); first++);
421   for(last = length - 1; last > first && isspace(str[last]); last--);
422 
423   if (! isspace(str[last])) last++; /* Last needs to be adjusted */
424 
425   if (first == last) /* Empty */
426     {
427       free(str);
428       return(strdup(""));
429     }
430   else
431     {
432       new = XtMalloc(last - first + 1); /* Don't forget last 0 */
433       strncpy(new, &str[first], last - first);
434       new[last - first] = 0;
435       free(str);
436       return(new);
437     }
438 }
439