1 /********************************************************************
2 This file is part of the abs 0.907 distribution. abs is a spreadsheet
3 with graphical user interface.
4
5 Copyright (C) 1998-2001 Andr� Bertin (Andre.Bertin@ping.be)
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version if in the same spirit as version 2.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 Concact: abs@pi.be
22 http://home.pi.be/bertin/abs.shtml
23
24 *********************************************************************/
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 #include <stdio.h>
54 #include <sys/types.h>
55 #include <sys/stat.h>
56
57 #ifndef _HPUX_SOURCE
58 #include <dirent.h>
59 #define DIRSTRUCT struct dirent
60 #endif
61
62 #ifdef _HPUX_SOURCE
63 #define DIRSTRUCT struct direct
64 #include <sys/dir.h>
65 #ifndef S_IFDIR
66 #define S_IFDIR 0040000
67 #endif
68 #endif
69
70 #include <unistd.h>
71
72
73 #include "param.h"
74 #include "file_selector.h"
75 #include "memory.h"
76
77 #include "gr_interf.h"
78 #include "entrypop.h"
79 #include "info_dialog.h"
80
81 static Widget promptShell = NULL;
82 static Widget promptDialog;
83 static Widget valueWidget;
84 static Widget dirvalueWidget;
85
86 static Widget list;
87 static Widget dirlist;
88
89 static Entry_Pop *filter;
90
91
92
93 static char dialogTranslation[] = "\
94 <Key>Return: Accept()\n\
95 ";
96
97 static XtActionsRec dialogactionsTable[] =
98 {
99 {"Accept", AcceptAction},
100 };
101
102
103 static void (*promptfunction) ();
104
105 extern Widget gettop ();
106
107 static char curdir[512];
108
109 static char **labels = NULL;
110 static char **dirlabels = NULL;
111
112 void
set_filename(Widget w,XtPointer closure,XtPointer call_data)113 set_filename (Widget w, XtPointer closure, XtPointer call_data)
114 {
115 Arg arglist[1];
116 XawListReturnStruct *item = (XawListReturnStruct *) call_data;
117 XtSetArg (arglist[0], XtNstring, item->string);
118 XtSetValues (valueWidget, arglist, 1);
119
120 }
121
122 void
MakeFullPath(char * root,char * filename,char * pathname)123 MakeFullPath (char *root, char *filename, char *pathname)
124 {
125 strcpy (pathname, root);
126 strcat (pathname, "/");
127 strcat (pathname, filename);
128 }
129
130 void
change_dir(Widget w,XtPointer closure,XtPointer call_data)131 change_dir (Widget w, XtPointer closure, XtPointer call_data)
132 {
133 char backupdir[512];
134 int len = strlen (curdir);
135 int backuplen = len;
136 DIR *dir;
137
138 XawListReturnStruct *item = (XawListReturnStruct *) call_data;
139
140 strncpy (backupdir, curdir, 511);
141
142 if (strcmp (item->string, "..") == 0)
143 {
144 if (len <= 1)
145 return;
146
147 while (len > 1 && curdir[len - 1] == '/')
148 len--;
149
150 while (len > 1 && curdir[len - 1] != '/')
151 len--;
152
153 if (len > 1)
154 {
155 curdir[len] = '\0';
156 }
157 else
158 {
159 sprintf (curdir, "/");
160 }
161
162 }
163 else
164 {
165 if (strcmp (item->string, ".") != 0)
166 {
167 if (len > 1 && curdir[len - 1] != '/')
168 strcat (curdir, "/");
169 strcat (curdir, item->string);
170 }
171 }
172
173 dir = opendir (curdir);
174 if (dir == NULL)
175 {
176 char message[600];
177 sprintf (message, "impossible to open dir (%s)", curdir);
178 Inform (message, NULL);
179 strncpy (curdir, backupdir, backuplen);
180 curdir[backuplen] = '\0';
181 return;
182 }
183
184 freelist ();
185 remake_list ();
186 w_n = 0;
187 XtSetArg (w_args[w_n], XtNstring, curdir);
188 w_n++;
189 XtSetValues (dirvalueWidget, w_args, w_n);
190
191 }
192
193
194 void
cb_Cancel(Widget w,XtPointer client_data,XtPointer call_data)195 cb_Cancel (Widget w, XtPointer client_data, XtPointer call_data)
196 {
197 if (promptShell)
198 {
199 freelist ();
200 XtPopdown (promptShell);
201 }
202 reactivate_zoom ();
203 }
204
205 void
CancelAction(Widget w,XEvent * event,String * params,Cardinal * num_params)206 CancelAction (Widget w, XEvent * event, String * params, Cardinal * num_params)
207 {
208 cb_Cancel (w, NULL, NULL);
209 }
210
211 void
cb_Rescan(Widget w,XtPointer client_data,XtPointer call_data)212 cb_Rescan (Widget w, XtPointer client_data, XtPointer call_data)
213 {
214 char *str;
215 Arg arglist[1];
216 XtSetArg (arglist[0], XtNstring, &str);
217
218
219 freelist ();
220 remake_list ();
221 }
222
223 void
RescanAction(Widget w,XEvent * event,String * params,Cardinal * num_params)224 RescanAction (Widget w, XEvent * event, String * params, Cardinal * num_params)
225 {
226 cb_Rescan (w, NULL, NULL);
227 }
228
229 void
cb_Accept(Widget w,XtPointer client_data,XtPointer call_data)230 cb_Accept (Widget w, XtPointer client_data, XtPointer call_data)
231 {
232 char *filename;
233 char *str;
234 Arg arglist[1];
235 int len = 2;
236 XtSetArg (arglist[0], XtNstring, &str);
237 XtGetValues (valueWidget, arglist, 1);
238 if (curdir != NULL)
239 len += strlen (curdir);
240 if (str != NULL)
241 len += strlen (str);
242 filename = (char *) absmalloc (sizeof (char) * len, "AcceptAction:filename");
243 sprintf (filename, "%s/%s", curdir, str);
244
245 cb_Cancel (w, client_data, call_data);
246 (*promptfunction) (filename);
247 absfree (filename, "AcceptAction:filename");
248 }
249
250 void
AcceptAction(Widget w,XEvent * event,String * params,Cardinal * num_params)251 AcceptAction (Widget w, XEvent * event, String * params, Cardinal * num_params)
252 {
253 cb_Accept (w, NULL, NULL);
254 }
255
256 int
MakePrompt(Widget centerw,char * prompt,void (* func)(),char * def)257 MakePrompt (Widget centerw, char *prompt, void (*func) (), char *def)
258 {
259
260 Arg centerArgs[2];
261 Arg args[20];
262 int n;
263 Position source_x, source_y;
264 Position dest_x, dest_y;
265 Dimension center_width, center_height;
266 Dimension prompt_width, prompt_height;
267
268 XtTranslations dialog_trans_table;
269
270 Widget cancel, ok, rescan, filterlabel, filename, dirname, viewport1,
271 viewport2, box;
272 Widget vsrl;
273
274
275
276 desactivate_zoom ();
277
278 if (promptShell == NULL)
279 {
280 n = 0;
281 XtSetArg (args[n], XtNinput, True);
282 n++;
283 XtSetArg (args[n], XtNwidth, 540);
284 n++;
285 XtSetArg (args[n], XtNheight, 350);
286 n++;
287 promptShell = XtCreatePopupShell
288 ("promptShell", transientShellWidgetClass, gettop (), args, 3);
289
290
291
292 n = 0;
293 XtSetArg (args[n], XtNwidth, 540);
294 n++;
295 XtSetArg (args[n], XtNheight, 350);
296 n++;
297 promptDialog = XtCreateManagedWidget ("promptDialog", formWidgetClass,
298 promptShell, args, n);
299 n = 0;
300 XtSetArg (args[n], XtNwidth, 540);
301 n++;
302 XtSetArg (args[n], XtNheight, 1);
303 n++;
304 XtSetArg (args[n], XtNborderWidth, 0);
305 n++;
306 box = XtCreateManagedWidget ("promptDialog", formWidgetClass,
307 promptDialog, args, n);
308 n = 0;
309 XtSetArg (args[n], XtNwidth, 1);
310 n++;
311 XtSetArg (args[n], XtNheight, 350);
312 n++;
313 XtSetArg (args[n], XtNborderWidth, 0);
314 n++;
315 box = XtCreateManagedWidget ("promptDialog", formWidgetClass,
316 promptDialog, args, n);
317
318 w_n = 0;
319 w_dim (200, 20);
320 w_rel (NULL, 9, 5);
321 w_bord (0);
322 XtSetArg (w_args[w_n], XtNlabel, "File name:");
323 w_n++;
324 XtSetArg (w_args[w_n], XtNjustify, XtJustifyLeft);
325 w_n++;
326 filename = XtCreateManagedWidget
327 ("Filename", labelWidgetClass, promptDialog, w_args, w_n);
328
329
330 w_n = 0;
331 w_dim (130, 20);
332 w_rel (filename, 20, -20);
333 XtSetArg (w_args[w_n], XtNborderWidth, 0);
334 w_n++;
335 XtSetArg (w_args[w_n], XtNlabel, "Directory:");
336 w_n++;
337 XtSetArg (w_args[w_n], XtNjustify, XtJustifyLeft);
338 w_n++;
339 dirname = XtCreateManagedWidget
340 ("Dirname", labelWidgetClass, promptDialog, w_args, w_n);
341
342 w_n = 0;
343 w_dim (200, 20);
344 w_bord (0);
345 w_rel (filename, -200, 2);
346 XtSetArg (w_args[w_n], XtNstring, "");
347 w_n++;
348 XtSetArg (w_args[w_n], XtNeditType, XawtextEdit);
349 w_n++;
350 w_bONw ();
351 valueWidget = XtCreateManagedWidget
352 ("text", asciiTextWidgetClass, promptDialog, w_args, w_n);
353 addshadow (valueWidget, 3);
354
355 w_n = 0;
356 w_dim (290, 20);
357 w_rel (dirname, -130, 2);
358 w_bord (0);
359 XtSetArg (w_args[w_n], XtNlabel, "");
360 w_n++;
361 XtSetArg (w_args[w_n], XtNborderWidth, 0);
362 w_n++;
363 XtSetArg (w_args[w_n], XtNjustify, XtJustifyLeft);
364 w_n++;
365 w_bONw ();
366 dirvalueWidget = XtCreateManagedWidget
367 ("dirtext", labelWidgetClass, promptDialog, w_args, w_n);
368
369
370 w_n = 0;
371 w_bord (0);
372 w_dim (200, 240);
373 w_rel (valueWidget, -200, 9);
374 XtSetArg (w_args[w_n], XtNuseRight, True);
375 w_n++;
376 XtSetArg (w_args[w_n], XtNallowVert, True);
377 w_n++;
378 XtSetArg (w_args[w_n], XtNforceBars, True);
379 w_n++;
380
381 viewport1 = XtCreateManagedWidget ("viewport1",
382 viewportWidgetClass, promptDialog, w_args, w_n);
383 vsrl = XtNameToWidget (viewport1, "vertical");
384 if (vsrl != (Widget) NULL)
385 {
386 modscroll (vsrl);
387 }
388
389 addshadow (viewport1, 6);
390
391 w_n = 0;
392 w_bord (0);
393 XtSetArg (w_args[w_n], XtNdefaultColumns, 1);
394 w_n++;
395 XtSetArg (w_args[w_n], XtNforceColumns, True);
396 w_n++;
397 w_bONw ();
398 list = XtCreateManagedWidget ("list", listWidgetClass,
399 viewport1, w_args, w_n);
400 XtAddCallback (list, XtNcallback, set_filename, NULL);
401 addshadow (list, 6);
402
403
404 w_n = 0;
405 w_bord (0);
406 w_dim (200, 240);
407 w_rel (dirvalueWidget, -290, 9);
408 w_bord (0);
409 XtSetArg (w_args[w_n], XtNuseRight, True);
410 w_n++;
411 XtSetArg (w_args[w_n], XtNallowVert, True);
412 w_n++;
413 XtSetArg (w_args[w_n], XtNforceBars, True);
414 w_n++;
415 viewport2 = XtCreateManagedWidget ("viewport2",
416 viewportWidgetClass, promptDialog, w_args, w_n);
417 vsrl = XtNameToWidget (viewport2, "vertical");
418 if (vsrl != (Widget) NULL)
419 {
420 modscroll (vsrl);
421 }
422 addshadow (viewport2, 6);
423
424 w_n = 0;
425 w_bord (0);
426 XtSetArg (w_args[w_n], XtNdefaultColumns, 1);
427 w_n++;
428 XtSetArg (w_args[w_n], XtNforceColumns, True);
429 w_n++;
430 w_bONw ();
431 dirlist = XtCreateManagedWidget ("dirlist", listWidgetClass,
432 viewport2, w_args, w_n);
433 XtAddCallback (dirlist, XtNcallback, change_dir, NULL);
434 addshadow (dirlist, 5);
435
436 w_n = 0;
437 w_dim (200, 20);
438 w_rel (viewport1, -200, 9);
439 w_bord (0);
440 XtSetArg (w_args[w_n], XtNlabel, "Filter:");
441 w_n++;
442 XtSetArg (w_args[w_n], XtNjustify, XtJustifyLeft);
443 w_n++;
444 filterlabel = XtCreateManagedWidget
445 ("Filter", labelWidgetClass, promptDialog, w_args, w_n);
446
447 filter = newentrypop (promptDialog, "printerpop", popdown, 200, 20);
448 entrypop_add_item (filter, "*.abs");
449 entrypop_add_item (filter, "*.txt");
450 entrypop_add_item (filter, "*.*");
451 entrypop_add_item (filter, "*");
452 entrypop_init_val (filter, "*.abs");
453 entrypop_callback (filter, cb_Rescan);
454 w_n = 0;
455 w_rel (filterlabel, -200, 0);
456 w_set (filter->baseform);
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477 w_n = 0;
478 w_dim (85, 20);
479 w_rel (NULL, 435, 80);
480 ok = XtCreateManagedWidget
481 ("Ok", commandWidgetClass, promptDialog, w_args, w_n);
482 XtAddCallback (ok, XtNcallback, cb_Accept, (XtPointer) NULL);
483
484 w_n = 0;
485 w_dim (85, 20);
486 w_rel (NULL, 435, 115);
487 rescan = XtCreateManagedWidget
488 ("Rescan", commandWidgetClass, promptDialog, w_args, w_n);
489 XtAddCallback (rescan, XtNcallback, cb_Rescan, (XtPointer) NULL);
490
491 w_n = 0;
492 w_dim (85, 20);
493 w_rel (NULL, 435, 150);
494 cancel = XtCreateManagedWidget
495 ("Cancel", commandWidgetClass, promptDialog, w_args, w_n);
496 XtAddCallback (cancel, XtNcallback, cb_Cancel, (XtPointer) NULL);
497
498
499
500 XtAppAddActions (XtWidgetToApplicationContext (gettop ()),
501 dialogactionsTable, XtNumber (dialogactionsTable));
502
503 dialog_trans_table = XtParseTranslationTable (dialogTranslation);
504 XtOverrideTranslations (promptDialog, dialog_trans_table);
505 XtOverrideTranslations (valueWidget, dialog_trans_table);
506
507 XtRealizeWidget (promptShell);
508 if (getcwd (curdir, 511) == NULL)
509 sprintf (curdir, ".");
510 }
511
512
513
514 XtSetArg (centerArgs[0], XtNwidth, ¢er_width);
515 XtSetArg (centerArgs[1], XtNheight, ¢er_height);
516 XtGetValues (centerw, centerArgs, 2);
517 XtSetArg (centerArgs[0], XtNwidth, &prompt_width);
518 XtSetArg (centerArgs[1], XtNheight, &prompt_height);
519 XtGetValues (promptShell, centerArgs, 2);
520 source_x = (int) (center_width - prompt_width) / 2;
521 source_y = (int) (center_height - prompt_height) / 3;
522 XtTranslateCoords (centerw, source_x, source_y, &dest_x, &dest_y);
523 XtSetArg (centerArgs[0], XtNx, dest_x);
524 XtSetArg (centerArgs[1], XtNy, dest_y);
525 XtSetValues (promptShell, centerArgs, 2);
526
527
528
529
530
531
532 XtPopup (promptShell, XtGrabNone);
533
534 promptfunction = func;
535 remake_list ();
536 return 0;
537 }
538
539
540
541
542
543
544
545
546
547 Boolean
IsDirectory(char * root,char * path)548 IsDirectory (char *root, char *path)
549 {
550 char fullpath[512];
551 struct stat statbuf;
552
553 if (path == NULL)
554 return (False);
555 MakeFullPath (root, path, fullpath);
556 if (stat (fullpath, &statbuf))
557 return (False);
558
559 if (statbuf.st_mode & S_IFDIR)
560 return (True);
561 else
562 return (False);
563 }
564
565
566 int
pass_filter(char * file,char * mask)567 pass_filter (char *file, char *mask)
568 {
569 int masklen, filelen;
570 int m = 0;
571 int f = 0;
572 int tm;
573 int matched = 0;
574 char tomatch = '\0';
575 int allok = 0;
576
577 if (file == NULL)
578 return 0;
579 if (mask == NULL)
580 return 1;
581
582 filelen = strlen (file);
583 masklen = strlen (mask);
584
585 while (m < masklen && f < filelen)
586 {
587 allok = 0;
588 while (mask[m] == '*' && m < masklen)
589 {
590 allok = 1;
591 m++;
592 }
593
594 if (m < masklen)
595 {
596 tomatch = mask[m];
597 tm = 1;
598 }
599 else
600 {
601 tm = 0;
602 }
603
604 if (allok)
605 {
606 if (tm)
607 {
608 matched = 0;
609 while (f < filelen && !matched)
610 {
611 if (file[f] == tomatch)
612 matched = 1;
613 else
614 f++;
615 }
616 if (!matched)
617 return 0;
618 }
619 else
620 {
621 return 1;
622 }
623 }
624 else
625 {
626 if (file[f] == mask[m])
627 {
628 m++;
629 f++;
630 }
631 else
632 {
633 return 0;
634 }
635 }
636 }
637
638 if (f < filelen)
639 return 0;
640 return 1;
641 }
642
643
644 void
remake_list()645 remake_list ()
646 {
647 int n;
648 int len;
649
650 DIR *dir;
651 DIRSTRUCT *entry;
652 int i, diri;
653 int j, k;
654 char *tmp;
655 char *mask;
656
657 w_n = 0;
658 XtSetArg (w_args[w_n], XtNlabel, curdir);
659 w_n++;
660 XtSetValues (dirvalueWidget, w_args, w_n);
661
662 mask = entrypop_gettext (filter);
663
664 dir = opendir (curdir);
665 if (dir == NULL)
666 {
667 fprintf (stderr, "impossible to open dir (%s)\n", curdir);
668 return;
669 }
670
671 n = 0;
672 while (readdir (dir) != NULL)
673 n++;
674
675 rewinddir (dir);
676
677 labels = (char **) absmalloc ((n + 3) * sizeof (char *), "remake_list:labels ");
678 dirlabels = (char **) absmalloc ((n + 3) * sizeof (char *), "remake_list:dirlabels ");
679
680 i = 0;
681 diri = 0;
682 while ((entry = readdir (dir)) != NULL)
683 {
684
685
686 len = 256;
687
688 if (IsDirectory (curdir, entry->d_name) && diri < n + 2)
689 {
690 len = strlen (entry->d_name);
691
692 dirlabels[diri] = (char *) absmalloc (sizeof (char) * (len + 1), "remake_list:dirlabels[diri] ");
693 strcpy (dirlabels[diri], entry->d_name);
694 diri++;
695 }
696 else
697 {
698 if (strncmp (entry->d_name, ".", 1) && i < n + 2)
699 {
700
701 if (pass_filter (entry->d_name, mask))
702 {
703 len = strlen (entry->d_name);
704
705 labels[i] = (char *) absmalloc (sizeof (char) * (len + 1), "remake_list:labels[i] ");
706 strcpy (labels[i], entry->d_name);
707 i++;
708 }
709 }
710 }
711 }
712 closedir (dir);
713
714 labels[i] = NULL;
715 dirlabels[diri] = NULL;
716
717 if (i < 500)
718 for (j = 0; j < i; j++)
719 for (k = j + 1; k < i; k++)
720 if (strcmp (labels[j], labels[k]) > 0)
721 {
722 tmp = labels[j];
723 labels[j] = labels[k];
724 labels[k] = tmp;
725 }
726
727 if (diri < 500)
728 for (j = 0; j < diri; j++)
729 for (k = j + 1; k < diri; k++)
730 if (strcmp (dirlabels[j], dirlabels[k]) > 0)
731 {
732 tmp = dirlabels[j];
733 dirlabels[j] = dirlabels[k];
734 dirlabels[k] = tmp;
735 }
736
737
738
739
740 XawListChange (list, labels, 0, 0, True);
741 XawListChange (dirlist, dirlabels, 0, 0, True);
742
743 return;
744
745 }
746
747 void
freelist()748 freelist ()
749 {
750 int i;
751
752 if (labels != NULL)
753 {
754 i = 0;
755 while (labels[i] != NULL)
756 {
757
758 absfree (labels[i], "freelist:labels[i] ");
759 i++;
760 }
761 absfree (labels, "freelist:labels ");
762 labels = NULL;
763 }
764 if (dirlabels != NULL)
765 {
766 i = 0;
767 while (dirlabels[i] != NULL)
768 {
769
770 absfree (dirlabels[i], "freelist:dirlabels[i] ");
771 i++;
772 }
773 absfree (dirlabels, "freelist:dirlabels ");
774 dirlabels = NULL;
775 }
776 }
777