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