1 /*****************************************************************************
2 ** File : dirman.c **
3 ** Purpose : Directory Manager **
4 ** Author : Edward Groenendaal **
5 ** Date : 18th Feb 1991 **
6 ** Documentation : Xdtm Design Folder **
7 ** Changes : 28-11-91, Edward Groenendaal **
8 ** Merged Jon's code into V1.8 to make V2.0 **
9 ** 18-04-92, Edward Groenendaal **
10 ** Added #if NeedFunctionPrototypes stuff **
11 ** June 16, 1992, Ramon Santiago **
12 ** Changed all XtCreate calls to XtVaCreate calls. **
13 ** Changed all caddr_t to XtPointer. **
14 ** June 20, 1992, Ramon Santiago **
15 ** removed some lint **
16 *****************************************************************************/
17
18 /* Include the application header file */
19 #include "xdtm.h"
20 #include "menus.h"
21 #include "parse.h"
22
23 /* Include the local header files */
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <dirent.h>
28 #include <sys/stat.h>
29 #include <sys/param.h>
30 #include <limits.h>
31 #include <X11/Xaw/AsciiText.h>
32
33 #include "Xedw/XedwList.h"
34 #include "Xedw/XedwForm.h"
35
36 #define LISTSIZE 128 /* The initial size of the icon_list */
37 #define LISTINCR 64 /* The steps by which it will increase */
38
39 #ifdef TRUE_SYSV
40 #ifndef MAXPATHLEN
41 #define MAXPATHLEN 512 /* jcc */
42 #endif
43 #endif
44
45 /* external and forward functions definitions */
46 #if NeedFunctionPrototypes
47 public void changestate(Boolean);
48 private void DoubleClick(Widget, XButtonEvent*);
49 extern void doubleclick_dialog(String, String);
50 extern void ExecuteIconProgram(Widget, AppProgram *, XtPointer);
51 public String getfilename(String);
52 extern Boolean getIconType(String, String, XdtmList*);
53 private void GoUp(Widget, XButtonEvent*);
54 private int iconcmp(const void *, const void *);
55 extern void PopMenu(Widget, XButtonEvent*);
56 private void Refresh(Widget, XButtonEvent*);
57 private void SelectAll(Widget, XButtonEvent*);
58 public void selection_made(Widget, XtPointer, XtPointer);
59 extern void setCursor(Cursor);
60 extern void setscroll(Widget, float);
61 #else
62 public void changestate();
63 private void DoubleClick();
64 extern void doubleclick_dialog();
65 extern void ExecuteIconProgram();
66 public String getfilename();
67 extern Boolean getIconType();
68 private void GoUp();
69 private int iconcmp();
70 extern void PopMenu();
71 private void Refresh();
72 private void SelectAll();
73 public void selection_made();
74 extern void setCursor();
75 extern void setscroll();
76 #endif
77
78 public Widget directoryManager;
79 public String cwd; /* current working directory */
80 public Cardinal icon_list_size = 0;
81 public Cardinal icon_list_max_size = LISTSIZE;
82 public XdtmList **icon_list; /* List with icons and/or filenames */
83 public String pwd_env_var;
84
85 /* local copies of the menu panes which are to be made insensitive when
86 * no there is no current selection.
87 */
88 private Widget duplicatemenu, infomenu, trashmenu,
89 copymenu, movemenu, mapmenu;
90
91
92 /*****************************************************************************
93 * createDirectoryManagerWidgets *
94 *****************************************************************************/
createDirectoryManagerWidgets(view)95 public void createDirectoryManagerWidgets(view)
96 Widget view;
97 {
98 /* Create the directory manager widget
99 *
100 * - Takes the directoryManager's parent widget
101 */
102
103 extern Icon_mode current_mode;
104 XtTranslations dirManTranslations;
105
106 /* New actions for directoryManager */
107
108 static XtActionsRec actions[] = {
109 {"DoubleClick", (XtActionProc)DoubleClick},
110 {"GoUp", (XtActionProc)GoUp},
111 {"SelectAll", (XtActionProc)SelectAll},
112 {"Refresh", (XtActionProc)Refresh},
113 {"PopMenu", (XtActionProc)PopMenu},
114 {NULL, (XtActionProc)NULL}
115 };
116
117 /* New translations for directoryManager */
118 static char defaultTranslations[] =
119 "<Btn1Up>(2): DoubleClick()\n\
120 <Key>u: GoUp()\n\
121 <Key>a: SelectAll()\n\
122 Ctrl<Key>L: Refresh()\n\
123 <Btn3Down>: Set() PopMenu()\n\
124 <Btn2Down>: Set()";
125 /* on peut peut-etre ajouter Info avec Btn2Up ? */
126
127 /* Set the initial mode depending on the value set in the application
128 * defaults. (current_mode.mode set previously to this value when
129 * creating widgets.
130 */
131
132 directoryManager =
133 XtVaCreateManagedWidget(
134 "directoryManager",
135 xedwListWidgetClass,
136 view,
137 XtNshowIcons, (current_mode.mode == Icons) ? True : False,
138 XtNrowSpacing, (current_mode.mode != Icons) ? 5 : 2,
139 XtNforceColumns, (current_mode.mode == Long) ? True : False,
140 XtNdefaultColumns, (current_mode.mode == Long) ? 1 : 2,
141 XtNfont, app_data.dm_font,
142 XtNmSelections, True,
143 NULL ) ;
144
145 /* Add callbacks and translations */
146 XtAddCallback(directoryManager, XtNcallback,
147 (XtCallbackProc)selection_made, (XtPointer)0);
148 XtAppAddActions(XtWidgetToApplicationContext(view),
149 actions, XtNumber(actions));
150 dirManTranslations = XtParseTranslationTable(defaultTranslations);
151 XtAugmentTranslations(directoryManager, dirManTranslations);
152 }
153
154
155 /*****************************************************************************
156 * splitPath *
157 *****************************************************************************/
158 #if NeedFunctionPrototypes
splitPath(String fullname,String * basename,String * path)159 public void splitPath(String fullname, String *basename, String *path)
160 #else
161 public void splitPath(fullname, basename, path)
162 String fullname;
163 String *basename;
164 String *path;
165 #endif
166 {
167 /* split a fullname description into basename and path.
168 */
169
170 int n, len = strlen(fullname);
171
172 n = len - 1;
173 while ((n >= 0) && (fullname[n] != '/')) n--;
174
175 if (n < 0) /* no slash, it's a basename */
176 {
177 *basename = XtNewString(fullname);
178 *path = XtNewString("");
179 return;
180 }
181 else /* fullname[n] is the last '/' in fullname */
182 {
183 *path = (String)XtMalloc((n + 1) * sizeof(char));
184 strncpy(*path, fullname, n);
185 (*path)[n] = 0;
186 *basename = XtNewString(&fullname[n + 1]);
187 return;
188 }
189 }
190
191
192 /*****************************************************************************
193 * directoryManagerNewDirectory *
194 *****************************************************************************/
directoryManagerNewDirectory(newpath)195 public Boolean directoryManagerNewDirectory(newpath)
196 String newpath;
197 {
198 /* Change the contents of the directoryManager to that of the directory
199 * contained in the string newpath.
200 */
201
202 extern Cursor busy;
203 extern Widget dirSelector;
204 extern Widget directoryManagerView;
205
206 XdtmList temp;
207 DIR *dirp;
208 struct dirent *dp;
209 Cardinal i = 0 ;
210 Boolean result = False; /* Whether the change of directories succeeded */
211
212 /* create a new one */
213 if ((dirp = opendir(newpath)) != NULL && chdir(newpath) == 0) {
214
215 /* set cursor to busy */
216 setCursor(busy);
217
218 /* Emacs likes the env var PWD to find out the current directory */
219 sprintf(pwd_env_var, "PWD=%s", newpath);
220
221 if (putenv(pwd_env_var) != 0) {
222 fprintf(stderr, "xdtm: Can't allocate space for environment\n");
223 exit(2);
224 }
225
226
227 /* In the process of all this we lose our highlighted items, so
228 * let's dim the menu items to reflect this. */
229 changestate(False);
230
231 /* Trash old list */
232 for(i=0; i < icon_list_size; i++) {
233 XtFree((char *)icon_list[i]->string);
234 XtFree((char *)icon_list[i]);
235 }
236
237 /* Get icon type for each file */
238 i = 0;
239 while ((dp = readdir(dirp)) != NULL) {
240
241 String basename = NULL, path = NULL;
242
243 if (i == icon_list_max_size) {
244 icon_list_max_size += LISTINCR;
245 icon_list = (XdtmList**) XtRealloc((char *)icon_list,
246 sizeof(XdtmList*) *
247 icon_list_max_size);
248 }
249
250 if (((strcmp(dp->d_name, ".") == 0) &&
251 (app_data.usedotspec == False)) ||
252 ((strcmp(dp->d_name, "..") == 0) &&
253 (app_data.usedotdotspec == False))) {
254
255 splitPath(newpath, &basename, &path);
256 if (strcmp(dp->d_name, "..") == 0) {
257 String tmppath = path;
258
259 XtFree(basename);
260 splitPath(tmppath, &basename, &path);
261 XtFree(tmppath);
262 }
263 } else {
264 basename = XtNewString(dp->d_name);
265 path = XtNewString(newpath);
266 }
267
268 if (getIconType(basename, path, &temp)) {
269 icon_list[i] = XtNew(XdtmList);
270
271 if (strcmp(dp->d_name, basename) != 0) {
272 /* This is either . or .. without their spec
273 replace basename by dp->d_name in temp.string */
274 int l, lbase = strlen(basename), ltemp = strlen(temp.string);
275 String ptr;
276
277 /* in any case (icons, short or long listing) basename is
278 always last in string, point at it */
279 ptr = temp.string + (ltemp - lbase);
280
281 /* copy dp->d_name at ptr */
282 strcpy(ptr, dp->d_name);
283
284 /* adjust string length */
285 if ((l = strlen(dp->d_name) - lbase) != 0)
286 temp.string = XtRealloc(temp.string, ltemp + l + 1);
287 }
288
289 icon_list[i]->string = temp.string;
290 icon_list[i]->isdir = temp.isdir;
291 icon_list[i]->icon = temp.icon;
292 icon_list[i]->mask = temp.mask;
293 icon_list[i]->user_data = temp.user_data;
294 i++;
295 }
296
297 XtFree(basename);
298 XtFree(path);
299
300 }
301 icon_list[i] = NULL; /* NULL terminated */
302 icon_list_size = i;
303
304 /* Sort the list */
305 qsort((char*)icon_list, icon_list_size, sizeof(icon_list[0]), iconcmp);
306
307 /* Change the contents of the directory Manager */
308 XedwListChange(directoryManager, (XedwList**) icon_list, icon_list_size,
309 0, True);
310
311 if (app_data.scrollonexit == True)
312 /* Set the scrollbar of the viewport to the top */
313 setscroll(directoryManagerView, 0.0);
314
315 closedir(dirp);
316 result = True;
317
318 /* Change entry in the directory selector */
319
320 XtVaSetValues(
321 dirSelector,
322 XtNstring, newpath,
323 NULL ) ;
324
325 /* reset cursor */
326 setCursor((Cursor)NULL);
327 } else
328 alert_dialog("Error: invalid directory!", newpath, NULL);
329
330 return(result);
331 }
332
333 /*****************************************************************************
334 * iconcmp *
335 *****************************************************************************/
336 #if NeedFunctionPrototypes
iconcmp(const void * p1,const void * p2)337 private int iconcmp(const void *p1, const void *p2)
338 #else
339 private int iconcmp(p1, p2)
340 void *p1;
341 void *p2;
342 #endif
343 {
344 XdtmList **ip1 = (XdtmList **)p1;
345 XdtmList **ip2 = (XdtmList **)p2;
346
347 /* compare the strings of 2 XdtmList's
348 * If isdir=True then put in front, otherwise put in order
349 */
350 if (app_data.dirfirst == True)
351 {
352 if ((*ip1)->isdir == True) {
353 if ((*ip2)->isdir == True) {
354 return (strcmp(getfilename((*ip1)->string),
355 getfilename((*ip2)->string)));
356 } else {
357 /* The second element is NOT a directory */
358 return(-1);
359 }
360 } else {
361 /* First element is a file */
362 if ((*ip2)->isdir == True) {
363 /* Second element is a directory */
364 return(1);
365 } else {
366 /* Both elements are files */
367 return (strcmp(getfilename((*ip1)->string),
368 getfilename((*ip2)->string)));
369 }
370 }
371 } else return (strcmp(getfilename((*ip1)->string),
372 getfilename((*ip2)->string)));
373 }
374
375 /*****************************************************************************
376 * initDirectoryManager *
377 *****************************************************************************/
initDirectoryManager()378 public void initDirectoryManager()
379 {
380 /* Get the menubar pane widgets, create the initial icon_list, find
381 * out what the current directory is.
382 */
383
384 extern Boolean buttonSensitive;
385 extern Widget menuBar;
386 char tmpcwd[MAXPATHLEN];
387
388 /* Initialise the icon list */
389 icon_list = (XdtmList**) XtMalloc(sizeof(XdtmList*) * LISTSIZE);
390
391 /* Set the starting directory */
392 #ifdef USE_CWD
393 if (getcwd(tmpcwd, MAXPATHLEN) != NULL)
394 #else
395 if ((char *)getwd(tmpcwd) != (char *)NULL)
396 #endif
397 cwd = XtNewString(tmpcwd);
398 else
399 if ((cwd = (char*) getenv("HOME")) == NULL)
400 cwd = XtNewString("/");
401 else
402 cwd = XtNewString(cwd);
403
404 /* Get the PWD entry from the environment */
405
406 pwd_env_var = XtMalloc(sizeof(char)*255);
407
408 sprintf(pwd_env_var, "PWD=%s", cwd);
409
410 if (putenv(pwd_env_var) != 0) {
411 fprintf(stderr, "xdtm: Can't allocate space for environment\n");
412 exit(2);
413 }
414
415 /* Get the id's of the menu widgets which are to be toggled with the
416 * buttons. Note: This relies on the menus being created first, which
417 * they are.
418 */
419 if ((duplicatemenu =
420 XtNameToWidget(menuBar, "fileMenuButton.fileMenu.duplicate")) == NULL) {
421 fprintf(stderr, "Directorymanager: Can't find duplicate menu widget\n");
422 exit(2);
423 }
424 if ((infomenu =
425 XtNameToWidget(menuBar, "fileMenuButton.fileMenu.info")) == NULL) {
426 fprintf(stderr, "Directorymanager: Can't find info menu widget\n");
427 exit(2);
428 }
429 if ((trashmenu =
430 XtNameToWidget(menuBar, "fileMenuButton.fileMenu.trash")) == NULL) {
431 fprintf(stderr, "Directorymanager: Can't find trash menu widget\n");
432 exit(2);
433 }
434 if ((copymenu =
435 XtNameToWidget(menuBar, "fileMenuButton.fileMenu.copy")) == NULL) {
436 fprintf(stderr, "Directorymanager: Can't find copy menu widget\n");
437 exit(2);
438 }
439 if ((movemenu =
440 XtNameToWidget(menuBar, "fileMenuButton.fileMenu.move")) == NULL) {
441 fprintf(stderr, "Directorymanager: Can't find move menu widget\n");
442 exit(2);
443 }
444 if ((mapmenu =
445 XtNameToWidget(menuBar,
446 "selectionMenuButton.selectionMenu.map")) == NULL) {
447 fprintf(stderr, "Directorymanager: Can't find map menu widget\n");
448 exit(2);
449 }
450
451 /* Add a passive grab to be able to popup spring loaded menu correctly */
452 XGrabButton(XtDisplay(directoryManager), AnyButton, AnyModifier,
453 XtWindow(directoryManager), TRUE,
454 ButtonPressMask|ButtonReleaseMask,
455 GrabModeAsync, GrabModeAsync, None, None );
456
457 (void) directoryManagerNewDirectory(cwd);
458 buttonSensitive = True;
459 changestate(False); /* Insure that menus are insensitive */
460 }
461
462 /*****************************************************************************
463 * selection_made *
464 *****************************************************************************/
465 /*ARGSUSED*/
selection_made(w,client_data,call_data)466 public void selection_made(w, client_data, call_data)
467 Widget w ;
468 XtPointer client_data ;
469 XtPointer call_data ;
470 {
471 /* Someone has either selected or deselected an item.
472 * If there's nothing selected then buttons are changed to
473 * not sensitive.
474 */
475
476 extern Boolean buttonSensitive;
477
478 if (XedwListSelection(w) != buttonSensitive)
479 if (buttonSensitive == False) {
480 changestate(True);
481 } else {
482 changestate(False);
483 }
484 }
485
486 /*****************************************************************************
487 * DoubleClick *
488 *****************************************************************************/
489 /*ARGSUSED*/
DoubleClick(w,event)490 private void DoubleClick(w, event)
491 Widget w;
492 XButtonEvent *event;
493 {
494 /* If the file is a directory, then change to that directory -
495 * if the file has an opt associated with it then run that program
496 * else show the file info.
497 */
498
499 extern Icon_mode current_mode;
500
501 struct stat filestatus;
502 String fullname, filename, temp;
503 XedwListReturnStruct *highlighted;
504 Cardinal index;
505 AppProgram *opt_pgm;
506
507 selection_made(w, (XtPointer)0, (XtPointer)0);
508 highlighted = XedwListShowCurrent(w);
509
510 if (highlighted->xedwList_index != XDTM_LIST_NONE) {
511 index = highlighted->xedwList_index;
512 if ((current_mode.mode == Short) /* No userdefinable ops in Short mode */
513 || (icon_list[index] == NULL) || (icon_list[index]->user_data == NULL))
514 opt_pgm = NULL;
515 else
516 opt_pgm = ((iconOps *)(icon_list[index]->user_data))->cmd;
517 filename = getfilename(highlighted->string);
518 fullname = (String) XtMalloc((strlen(filename)+strlen(cwd)+2) *
519 sizeof(char));
520 strcpy(fullname, cwd);
521 if (strcmp(cwd, "/") != 0)
522 strcat(fullname, "/");
523 strcat(fullname, filename);
524
525 /* Use normal stat.. follows symbolic links.. can use on SYSV */
526 if (stat(fullname, &filestatus) == -1) {
527 alert_dialog("Sorry, that file does", "not really exist!!", "Cancel");
528 } else {
529 if ((filestatus.st_mode & S_IFMT) == S_IFDIR) {
530
531 /* The file is a directory */
532
533 if (strcmp(filename, "..") == 0) {
534 /* Go up one level */
535 strcpy(fullname, cwd);
536 if ((temp = (char*) strrchr(fullname, '/')) == NULL)
537 fprintf(stderr, "xdtm: impossible error (dirman.c)\n");
538 if (temp == fullname)
539 *(temp+1) = '\0';
540 else
541 *temp = '\0';
542 }
543 if (strcmp(filename, ".") == 0) {
544 /* Refresh directory contents */
545 XtFree((char *)fullname);
546 fullname=XtNewString(cwd);
547 }
548 if (directoryManagerNewDirectory(fullname) == True) {
549 /* Normal directory - change to it */
550 XtFree((char *)cwd);
551 cwd=fullname;
552 changestate(False);
553 }
554 } else {
555 if (opt_pgm) {
556 /* There's a program associated with this type of file */
557 ExecuteIconProgram(NULL, opt_pgm, NULL);
558 } else
559 if ((filestatus.st_mode & S_IFMT) == S_IFREG) {
560 /* Display dialog box to ask whether to display file */
561 doubleclick_dialog(filename, cwd);
562 } else alert_dialog("Cannot double click",
563 "on such file!", NULL);
564 XtFree((char *)fullname);
565 }
566 }
567 }
568 XedwListFreeCurrent(highlighted);
569 }
570
571 /*****************************************************************************
572 * GoUp *
573 *****************************************************************************/
574 /*ARGSUSED*/
GoUp(w,event)575 private void GoUp(w, event)
576 Widget w;
577 XButtonEvent *event;
578 {
579 /* Change to the directory immediately above the current one,
580 * does this by highlighting the .. directory, then calling
581 * DoubleClick to change to the highlighted directory.
582 * I used this longwinded approach because it showed on screen
583 * what was actually happening.
584 */
585
586 register int i = 0 ;
587
588 /* Find entry with .. */
589
590 for (; i < icon_list_size &&
591 (strcmp(getfilename(icon_list[i]->string), "..") != 0); i++);
592
593 XedwListUnhighlight(w, XedwAll);
594 XedwListHighlight(w, i); /* Call XedwListHighlight with item number */
595 DoubleClick(w, (XButtonEvent*) NULL); /* Call double click */
596 }
597
598 /*****************************************************************************
599 * SelectAll *
600 *****************************************************************************/
601 /*ARGSUSED*/
SelectAll(w,event)602 private void SelectAll(w, event)
603 Widget w;
604 XButtonEvent *event;
605 {
606 /* Select All the files in the current directory except for . and .. */
607
608 extern Mode mode;
609 extern Cursor busy;
610
611 register int i;
612
613 /* Don't do it if in copy or move mode */
614 if (mode == NormalMode) {
615 setCursor(busy);
616 XedwListHighlight(w, XedwAll);
617
618 /* unhighlight . and .. */
619 for (i=0; i < icon_list_size &&
620 (strcmp(getfilename(icon_list[i]->string), ".") != 0); i++);
621 if (i < icon_list_size) XedwListUnhighlight(w, i);
622 for (i= (i < icon_list_size ? i : 0); i < icon_list_size &&
623 (strcmp(getfilename(icon_list[i]->string), "..") != 0); i++);
624 if (i < icon_list_size) XedwListUnhighlight(w, i);
625 setCursor((Cursor)NULL);
626 } else alert_dialog("Cannot select all", "while trying to Copy/Move", NULL);
627
628
629 /* do buttons */
630 if (icon_list_size > 2) {
631 changestate(True);
632 }
633 }
634
635 /*****************************************************************************
636 * Refresh *
637 *****************************************************************************/
638 /*ARGSUSED*/
Refresh(w,event)639 private void Refresh(w, event)
640 Widget w;
641 XButtonEvent *event;
642 {
643 /* Refresh the current directory contents to the actual contents. */
644
645 directoryManagerNewDirectory(cwd);
646 }
647
648 /*****************************************************************************
649 * changestate *
650 *****************************************************************************/
651 #if NeedFunctionPrototypes
changestate(Boolean new_state)652 public void changestate(Boolean new_state)
653 #else
654 public void changestate(new_state)
655 Boolean new_state;
656 #endif
657 {
658 /* Toggle the sensitivity of all the widgets which may not be used
659 * when no files are highlighted.
660 *
661 * - Takes the new state for widgets.
662 */
663
664 extern Boolean buttonSensitive;
665 extern Widget trashButton, copyButton, moveButton;
666 extern Mode mode;
667
668 if (buttonSensitive == True) {
669 if (mode == MoveMode) {
670 /* Turn off Trash and Copy */
671 XtSetSensitive(copyButton, False);
672 XtSetSensitive(trashButton, False);
673 XtSetSensitive(copymenu, False);
674 XtSetSensitive(trashmenu, False);
675 XtSetSensitive(mapmenu, False);
676 XtSetSensitive(duplicatemenu, False);
677 XtSetSensitive(infomenu, False);
678 buttonSensitive = False;
679 } else if (mode == CopyMode) {
680 /* Turn off Trash and Move */
681 XtSetSensitive(moveButton, False);
682 XtSetSensitive(trashButton, False);
683 XtSetSensitive(movemenu, False);
684 XtSetSensitive(trashmenu, False);
685 XtSetSensitive(mapmenu, False);
686 XtSetSensitive(duplicatemenu, False);
687 XtSetSensitive(infomenu, False);
688 buttonSensitive = False;
689 } else if (new_state == False) {
690 /* Turn off All */
691 XtSetSensitive(moveButton, False);
692 XtSetSensitive(copyButton, False);
693 XtSetSensitive(trashButton, False);
694 XtSetSensitive(copymenu, False);
695 XtSetSensitive(movemenu, False);
696 XtSetSensitive(trashmenu, False);
697 XtSetSensitive(mapmenu, False);
698 XtSetSensitive(duplicatemenu, False);
699 XtSetSensitive(infomenu, False);
700 buttonSensitive = False;
701 }
702 } else {
703 /* buttonSensitive == False */
704
705 /* If in MoveMode or CopyMode, then everything is set anyway */
706 if (mode == NormalMode && new_state == True) {
707 /* Set all to True */
708 XtSetSensitive(trashButton, True);
709 XtSetSensitive(moveButton, True);
710 XtSetSensitive(copyButton, True);
711 XtSetSensitive(trashmenu, True);
712 XtSetSensitive(movemenu, True);
713 XtSetSensitive(copymenu, True);
714 XtSetSensitive(duplicatemenu, True);
715 XtSetSensitive(mapmenu, True);
716 XtSetSensitive(infomenu, True);
717 buttonSensitive = True;
718 }
719 }
720 }
721
722 /*****************************************************************************
723 * getfilename *
724 *****************************************************************************/
getfilename(s)725 public String getfilename(s)
726 String s;
727 {
728 /* If in Long Listing mode this function returns the filename part
729 * of the string used in the directory list. If not in Long Listing
730 * then return the string unmolested.
731 * NOTE that the string returned when in Long Listing mode should not be
732 * freed as it was never allocated.
733 * NOTE also that doing string = getfilename(string) should avoided.
734 */
735 extern Icon_mode current_mode;
736
737 if (current_mode.mode == Long && (strlen(s) > current_mode.length))
738 return (s+current_mode.length);
739 else
740 return (s);
741 }
742