2
* FChooser.c : A widget for choosing a file
4
* George Ferguson, ferguson@cs.rochester.edu, 21 Jan 1993.
6
* This code is derived from the FileSelector widget by Brian Totty,
7
* hence the following copyright applies:
9
* Copyright 1990,1991,1992 Brian Totty
11
* Permission to use, copy, modify, distribute, and sell this software
12
* and its documentation for any purpose is hereby granted without fee,
13
* provided that the above copyright notice appears in all copies and that
14
* both that copyright notice and this permission notice appear in
15
* supporting documentation, and that the name of Brian Totty or
16
* University of Illinois not be used in advertising or publicity
17
* pertaining to distribution of the software without specific, written
18
* prior permission. Brian Totty and University of Illinois make no
19
* representations about the suitability of this software for any
20
* purpose. It is provided "as is" without express or implied warranty.
22
* Brian Totty and University of Illinois disclaim all warranties with
23
* regard to this software, including all implied warranties of
24
* merchantability and fitness, in no event shall Brian Totty or
25
* University of Illinois be liable for any special, indirect or
26
* consequential damages or any damages whatsoever resulting from loss of
27
* use, data or profits, whether in an action of contract, negligence or
28
* other tortious action, arising out of or in connection with the use or
29
* performance of this software.
33
* Department of Computer Science
34
* University Of Illinois at Urbana-Champaign
35
* 1304 West Springfield Avenue
44
#include <X11/IntrinsicP.h>
45
#include <X11/Intrinsic.h>
46
#include <X11/StringDefs.h>
47
#include <X11/cursorfont.h>
48
#include <X11/CompositeP.h>
49
#include <X11/Composite.h>
51
#include <X11/Xaw3d/MenuButton.h>
52
#include <X11/Xaw3d/SimpleMenu.h>
53
#include <X11/Xaw3d/SmeBSB.h>
54
#include <X11/Xaw3d/Viewport.h>
55
#include <X11/Xaw3d/List.h>
57
#include <X11/Xaw/MenuButton.h>
58
#include <X11/Xaw/SimpleMenu.h>
59
#include <X11/Xaw/SmeBSB.h>
60
#include <X11/Xaw/Viewport.h>
61
#include <X11/Xaw/List.h>
65
#include "FChooserP.h"
68
/*---------------------------------------------------------------------------*
70
I N T E R N A L R O U T I N E S
72
*---------------------------------------------------------------------------*/
74
#if (!NeedFunctionPrototypes)
76
static void Initialize();
77
static void Realize();
78
static void Destroy();
80
static Boolean SetValues();
81
static XtGeometryResult GeometryManager();
82
static void ChildrenCreate();
83
static void ChildrenRealize();
84
static void ChildrenUpdate();
85
static void DirectoryCallback();
86
static void FileCallback();
87
static void SelectFileByIndex();
88
static Boolean SelectFileByName();
89
static void UnselectAll();
91
static void GotoDeepestLegalDirectory();
92
static void UpdateLists();
97
static void Initialize(Widget request, Widget new);
98
static void Realize(Widget w, XtValueMask *valueMask,
99
XSetWindowAttributes *attrs);
100
static void Destroy(XfwfFileChooserWidget fcw);
101
static void Resize(Widget w);
102
static Boolean SetValues(Widget current, Widget request, Widget new);
103
static XtGeometryResult GeometryManager(Widget w,
104
XtWidgetGeometry *request,
105
XtWidgetGeometry *reply);
106
static void ChildrenCreate(XfwfFileChooserWidget fcw);
107
static void ChildrenRealize(XfwfFileChooserWidget fcw);
108
static void ChildrenUpdate(XfwfFileChooserWidget fcw);
109
static void DirectoryCallback(Widget w, XtPointer client_data,
110
XtPointer call_data);
111
static void FileCallback(Widget w, XtPointer client_data,
112
XtPointer call_data);
113
static void SelectFileByIndex(XfwfFileChooserWidget fcw, int index);
114
static Boolean SelectFileByName(XfwfFileChooserWidget fcw, char *name);
115
static void UnselectAll(XfwfFileChooserWidget fcw);
116
static void Notify(XfwfFileChooserWidget fcw);
117
static void GotoDeepestLegalDirectory(XfwfFileChooserWidget fcw);
118
static void UpdateLists(XfwfFileChooserWidget fcw);
119
static void Chdir(XfwfFileChooserWidget fcw);
123
/*---------------------------------------------------------------------------*
125
R E S O U R C E I N I T I A L I Z A T I O N
127
*---------------------------------------------------------------------------*/
129
#define FCFieldOffset(FIELD) XtOffset(XfwfFileChooserWidget,fileChooser.FIELD)
130
#define CoreFieldOffset(FIELD) XtOffset(Widget,core.FIELD)
132
static XtResource resources[] = {
133
{ XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
134
CoreFieldOffset(width), XtRString, "500" },
135
{ XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
136
CoreFieldOffset(height), XtRString, "250" },
137
{ XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
138
CoreFieldOffset(background_pixel), XtRString, "white" },
139
{ XtNcurrentDirectory, XtCPathname, XtRString, sizeof(String),
140
FCFieldOffset(current_dir), XtRString, NULL },
141
{ XtNcurrentFile, XtCFilename, XtRString, sizeof(String),
142
FCFieldOffset(current_file), XtRString, NULL },
143
{ XtNcallback, XtCCallback, XtRCallback,
144
sizeof(XtCallbackList), FCFieldOffset(callbacks), XtRCallback, NULL},
145
{XtNsortMode, XtCValue, XtRInt, sizeof(int),
146
FCFieldOffset(sort_mode), XtRString, "2"},
147
{XtNpattern, XtCFile, XtRString, sizeof(String),
148
FCFieldOffset(pattern), XtRString, NULL},
152
#undef CoreFieldOffset
154
/*---------------------------------------------------------------------------*
156
C L A S S A L L O C A T I O N
158
*---------------------------------------------------------------------------*/
160
XfwfFileChooserClassRec xfwfFileChooserClassRec = {
162
/* superclass */ (WidgetClass)&compositeClassRec,
163
/* class_name */ "XfwfFileChooser",
164
/* widget_size */ sizeof(XfwfFileChooserRec),
165
/* class_initialize */ NULL,
166
/* class_part_initialize*/ NULL,
167
/* class_inited */ FALSE,
168
/* initialize */ (XtInitProc)Initialize,
169
/* initialize_hook */ NULL,
170
/* realize */ (XtRealizeProc)Realize,
173
/* resources */ resources,
174
/* resource_count */ XtNumber(resources),
175
/* xrm_class */ NULLQUARK,
176
/* compress_motion */ TRUE,
177
/* compress_exposure */ TRUE,
178
/* compress_enterleave */ TRUE,
179
/* visible_interest */ FALSE,
180
/* destroy */ (XtWidgetProc)Destroy,
181
/* resize */ (XtWidgetProc)Resize,
182
/* expose */ XtInheritExpose,
183
/* set_values */ (XtSetValuesFunc)SetValues,
184
/* set_values_hook */ NULL,
185
/* set_values_almost */ XtInheritSetValuesAlmost,
186
/* get_values_hook */ NULL,
187
/* accept_focus */ NULL,
188
/* version */ XtVersion,
189
/* callback_private */ NULL,
191
/* query_geometry */ XtInheritQueryGeometry,
192
/* display_accelerator */ XtInheritDisplayAccelerator,
196
/* geometry_manager */ GeometryManager,
197
/* change_managed */ XtInheritChangeManaged,
198
/* insert_child */ XtInheritInsertChild,
199
/* delete_child */ XtInheritDeleteChild,
201
}, /* Composite Part */
203
/* no extra class data */ 0
204
} /* FileSelector Part */
207
WidgetClass xfwfFileChooserWidgetClass =
208
(WidgetClass)&xfwfFileChooserClassRec;
210
/*---------------------------------------------------------------------------*
212
E X P O R T E D M E T H O D S
214
*---------------------------------------------------------------------------*/
217
/*---------------------------------------------------------------------------*
221
This procedure is called by the X toolkit to initialize
222
the FileChooser widget instance. The hook to this routine is in the
223
initialize part of the core part of the class.
225
*---------------------------------------------------------------------------*/
229
Initialize(request,new)
232
XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)new;
233
char *str,*initial_file,path[MAXPATHLEN + 2];
234
static char *star = "*";
236
FCBusyCursor(fcw) = XCreateFontCursor(XtDisplay(fcw),XC_watch);
237
FCDirMenu(fcw) = NULL;
238
FCDirMenuButton(fcw) = NULL;
239
FCFileList(fcw) = NULL;
240
FCDirMgr(fcw) = NULL;
241
FCFileNames(fcw) = NULL;
242
FCNumFileNames(fcw) = 0;
243
FCDirNames(fcw) = NULL;
244
FCNumDirNames(fcw) = 0;
246
str = (char *)XtCalloc((MAXPATHLEN + 2),sizeof(char));
247
if (FCCurrentDirectory(fcw) != NULL) { /* User Specified Path */
248
strcpy(str,FCCurrentDirectory(fcw));
253
FCCurrentDirectory(fcw) = str;
255
str = (char *)XtCalloc((MAXPATHLEN + 2),sizeof(char));
256
initial_file = FCCurrentFile(fcw);
257
FCCurrentFile(fcw) = str;
259
if (FCCorePart(request)->width <= 0)
260
FCCorePart(new)->width = 500;
261
if (FCCorePart(request)->height <= 0)
262
FCCorePart(new)->height = 200;
264
if (FCPattern(fcw) == NULL)
265
FCPattern(fcw) = star;
266
FCPattern(fcw) = XtNewString(FCPattern(fcw));
269
GotoDeepestLegalDirectory(fcw);
271
SelectFileByName(fcw,initial_file);
272
} /* End Initialize */
274
/*---------------------------------------------------------------------------*
278
This function is called to realize a FileChooser widget.
280
*---------------------------------------------------------------------------*/
282
static void Realize(w,valueMask,attrs)
284
XtValueMask *valueMask;
285
XSetWindowAttributes *attrs;
287
XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)w;
289
XtCreateWindow(w,InputOutput,(Visual *)CopyFromParent,*valueMask,attrs);
290
ChildrenRealize(fcw);
296
/*---------------------------------------------------------------------------*
300
This function is called to destroy a FileChooser widget.
302
*---------------------------------------------------------------------------*/
306
XfwfFileChooserWidget fcw;
310
XtFree(FCCurrentDirectory(fcw));
311
XtFree(FCCurrentFile(fcw));
312
XtFree(FCPattern(fcw));
313
if (FCFileNames(fcw) != NULL) {
314
for (i=0; i < FCNumFileNames(fcw); i++)
315
XtFree(FCFileNames(fcw)[i]);
316
XtFree(FCFileNames(fcw));
318
if (FCDirNames(fcw) != NULL) {
319
for (i=0; i < FCNumDirNames(fcw); i++)
320
XtFree(FCDirNames(fcw)[i]);
321
XtFree(FCDirNames(fcw));
325
/*---------------------------------------------------------------------------*
329
This function is called to resize a FileChooser widget.
331
*---------------------------------------------------------------------------*/
337
XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)w;
342
/*---------------------------------------------------------------------------*
346
This function is the external interface for setting resources.
348
*---------------------------------------------------------------------------*/
352
SetValues(current,request,new)
353
Widget current,request,new;
355
XfwfFileChooserWidget fcw_current = (XfwfFileChooserWidget)current;
356
XfwfFileChooserWidget fcw_new = (XfwfFileChooserWidget)new;
357
XfwfFileChooserWidget fcw_request = (XfwfFileChooserWidget)request;
359
if (FCCurrentDirectory(fcw_current) != FCCurrentDirectory(fcw_new)){
360
/* strcpy(FCCurrentDirectory(fcw_current),FCCurrentDirectory(fcw_new));
361
FCCurrentDirectory(fcw_new) = FCCurrentDirectory(fcw_current); */
362
/* didn't understand why to copy the new string into old space and
363
use this for the new widget ?! - ACZ */
366
if (FCCurrentFile(fcw_current) != FCCurrentFile(fcw_new)) {
369
new_name = FCCurrentFile(fcw_new);
370
FCCurrentFile(fcw_new) = FCCurrentFile(fcw_current);
371
SelectFileByName(fcw_new,new_name);
373
if (FCPattern(fcw_current) != FCPattern(fcw_new)) {
374
/* XtFree(FCPattern(fcw_current));
375
FCPattern(fcw_new) = XtNewString(FCPattern(fcw_request)); */
376
/* above was XtNewString(FCPattern(fcw_current)) - ACZ */
379
if (FCSortMode(fcw_current) != FCSortMode(fcw_new)) {
383
} /* End SetValues() */
385
/*---------------------------------------------------------------------------*
387
GeometryManager(w,request,reply)
389
This routine acts as the geometry_manager method for the
390
FileChooser widget. It is called when a child wants to
391
resize/reposition itself.
393
Currently, we allow all requests.
395
*---------------------------------------------------------------------------*/
398
static XtGeometryResult
399
GeometryManager(w,request,reply)
401
XtWidgetGeometry *request;
402
XtWidgetGeometry *reply;
404
return(XtGeometryYes);
405
} /* End GeometryManager */
407
/*---------------------------------------------------------------------------*
409
L O C A L R O U T I N E S
411
*---------------------------------------------------------------------------*/
413
/*---------------------------------------------------------------------------*
417
This routine creates the initial child widgets for the
418
file selector widget and places them in the widget fcw.
419
No placement or resizing is done. That is done by
422
*---------------------------------------------------------------------------*/
426
XfwfFileChooserWidget fcw;
428
static char *str = NULL;
430
FCDirMenuButton(fcw) =
431
XtVaCreateManagedWidget(FC_DIR_MENU_BUTTON_NAME,menuButtonWidgetClass,
433
XtNmenuName, FC_DIR_MENU_NAME,
436
FCFileViewport(fcw) =
437
XtVaCreateManagedWidget(FC_FILE_VIEWPORT_NAME,viewportWidgetClass,
444
FCFileList(fcw) = XtVaCreateManagedWidget(FC_FILE_LIST_NAME,listWidgetClass,
447
XtNdefaultColumns, 1,
448
XtNforceColumns, True,
449
XtNverticalList, True,
450
/* XtNborderWidth, 0, */
453
XtAddCallback(FCFileList(fcw),XtNcallback,
454
(XtCallbackProc)FileCallback,(XtPointer)fcw);
455
} /* End ChildrenCreate */
457
/*---------------------------------------------------------------------------*
461
This routine realizes the child widgets. The widgets must
462
already have been created and initialized. Their coordinates
463
should already have been set.
465
*---------------------------------------------------------------------------*/
469
XfwfFileChooserWidget fcw;
471
XtRealizeWidget(FCDirMenuButton(fcw));
472
XtRealizeWidget(FCFileViewport(fcw));
473
XtRealizeWidget(FCFileList(fcw));
474
} /* End ChildrenRealize */
476
/*---------------------------------------------------------------------------*
480
This routine takes a FileChooser widget fcw and updates
481
the child widgets by recalculating their coordinates based
482
on the current size of the FileChooser, and setting the
483
appropriate resources.
485
We go to some trouble to get something useful displayed in the
486
FCDirMenuButton(fcw) if the current directory name is too long
487
to fit in the button. It would be nice if the "justify" resource
488
of the MenuButton widget did this, but...
490
*---------------------------------------------------------------------------*/
494
XfwfFileChooserWidget fcw;
498
Dimension menuButtonW,menuButtonH,fileListW,fileListH;
499
Position menuButtonX,menuButtonY,fileListX,fileListY;
500
XtWidgetGeometry parent_idea,child_idea;
505
if (!XtIsRealized((Widget)fcw)) {
514
XtVaGetValues(FCDirMenuButton(fcw), XtNfont, &fs, NULL);
515
/* Get The Child Widgets Current Widths And Heights */
516
/* (although we don't actually use the existing values... */
517
menuButtonW = CoreWidth(FCDirMenuButton(fcw));
518
menuButtonH = CoreHeight(FCDirMenuButton(fcw));
524
/* Adjust menu button label if too small */
525
/* It would be nice if the "justify" resource of MenuButton did this... */
526
label = FCCurrentDirectory(fcw);
527
if (XTextWidth(fs,label,strlen(label)) > menuButtonW-intw) {
528
char newLabel[MAXPATHLEN];
529
/* cut away chars from left side until it fits into the button */
530
while (*label && XTextWidth(fs,label,strlen(label))>menuButtonW-intw) {
535
strcpy(newLabel,""); /* was "<" - ACZ */
536
strcat(newLabel,label);
537
XtVaSetValues(FCDirMenuButton(fcw), XtNlabel, newLabel, NULL);
539
XtVaSetValues(FCDirMenuButton(fcw), XtNlabel, label, NULL);
542
fileListH = h - menuButtonH - gap;
543
/* Listen To Child Height Request For List */
545
parent_idea.request_mode = CWWidth | CWHeight;
546
parent_idea.width = fileListW;
547
parent_idea.height = fileListH;
548
XtQueryGeometry(FCFileList(fcw),&parent_idea,&child_idea);
549
if ((child_idea.request_mode & CWHeight) &&
550
(child_idea.height < parent_idea.height)) {
551
fileListH = child_idea.height;
554
/* Vertical Positions */
556
fileListY = menuButtonH + gap;
557
/* Horizontal Positions */
562
XtMoveWidget(FCDirMenuButton(fcw),menuButtonX,menuButtonY);
563
XtMoveWidget(FCFileViewport(fcw),fileListX,fileListY);
565
XtResizeWidget(FCDirMenuButton(fcw),menuButtonW,menuButtonH,
566
CoreBorderWidth(FCDirMenuButton(fcw)));
567
XtResizeWidget(FCFileViewport(fcw),fileListW,fileListH,
568
CoreBorderWidth(FCFileViewport(fcw)));
569
} /* End ChildrenUpdate */
571
/*---------------------------------------------------------------------------*
573
I N T E R N A L C A L L B A C K S
575
*---------------------------------------------------------------------------*/
577
/*---------------------------------------------------------------------------*
579
DirectoryCallback(w,client_data,call_data)
581
This is called when the user selects an ancestor directory from
582
the menu. The argument "w" is the selected object (hence the two
583
calls to XtParent()) and "client_data" is it's index in the menu.
585
*---------------------------------------------------------------------------*/
589
DirectoryCallback(w,client_data,call_data)
591
XtPointer client_data; /* index */
592
XtPointer call_data; /* not used */
594
int index = (int)client_data;
595
XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)XtParent(XtParent(w));
598
strcpy(FCCurrentDirectory(fcw),"/");
599
for (i = 1; i <= index; i++) {
600
strcat(FCCurrentDirectory(fcw),FCDirNames(fcw)[i]);
601
strcat(FCCurrentDirectory(fcw),"/");
604
} /* End DirectoryCallback */
606
/*---------------------------------------------------------------------------*
608
FileCallback(w,client_data,call_data)
610
This is called when the user selects a file in the fileList.
611
The argument "client_data" is the FileChooser widget, "call_data"
612
is a pointer to the standard List widget callback information.
614
*---------------------------------------------------------------------------*/
618
FileCallback(w,client_data,call_data)
620
XtPointer client_data; /* fcw */
621
XtPointer call_data; /* return struct */
623
XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)client_data;
624
XawListReturnStruct *ret = (XawListReturnStruct *)call_data;
626
if (ret->list_index == -1) {
627
UnselectAll(fcw); /* Click On Blank Space */
630
SelectFileByIndex(fcw,ret->list_index);
632
} /* End FileCallback */
634
/*---------------------------------------------------------------------------*
636
I N T E R N A L S U P P O R T R O U T I N E S
638
*---------------------------------------------------------------------------*/
641
SelectFileByIndex(fcw,index)
642
XfwfFileChooserWidget fcw;
647
DirectoryMgrGotoItem(FCDirMgr(fcw),index);
648
if ((dir_entry=DirectoryMgrCurrentEntry(FCDirMgr(fcw))) == NULL) {
649
fprintf(stderr,"SelectFileByIndex: Entry %d invalid\n",index);
652
if (DirEntryIsDir(dir_entry) || DirEntryIsDirectoryLink(dir_entry)) {
653
strcat(FCCurrentDirectory(fcw),DirEntryFileName(dir_entry));
655
} else if (!DirEntryIsBrokenLink(dir_entry)) { /* File */
656
strcpy(FCCurrentFile(fcw),DirEntryFileName(dir_entry));
657
XawListHighlight(FCFileList(fcw),index);
659
} else { /* Broken Link */
660
XBell(XtDisplay(fcw),0);
663
} /* End SelectFileByIndex */
666
SelectFileByName(fcw,name)
667
XfwfFileChooserWidget fcw;
670
if (DirectoryMgrGotoNamedItem(FCDirMgr(fcw),name) == FALSE) {
673
SelectFileByIndex(fcw,DirectoryMgrCurrentIndex(FCDirMgr(fcw)));
675
} /* End SelectFileByName */
679
XfwfFileChooserWidget fcw;
681
Boolean selected = FCCurrentFile(fcw)[0] != '\0';
683
FCCurrentFile(fcw)[0] = '\0';
684
XawListUnhighlight(FCFileList(fcw));
687
} /* End UnselectAll */
691
XfwfFileChooserWidget fcw;
693
XfwfFileChooserReturnStruct ret;
695
if (FCCurrentFile(fcw)[0] != '\0') {
696
ret.directory = FCCurrentDirectory(fcw);
697
ret.file = FCCurrentFile(fcw);
699
ret.directory = NULL;
702
XtCallCallbacks((Widget)fcw,XtNcallback,(XtPointer)&ret);
705
/*---------------------------------------------------------------------------*
707
GotoDeepestLegalDirectory(fcw)
709
This function takes a FileChooser widget <fcw> and modifies the
710
directory string in FCCurrentDirectory(fcw) to be the deepest
711
legal directory above the string. Partial or incorrect directory
712
names are stripped starting at the end.
714
It then calls UpdateLists() to reset the information dislayed in
717
*---------------------------------------------------------------------------*/
720
GotoDeepestLegalDirectory(fcw)
721
XfwfFileChooserWidget fcw;
724
char temp[MAXPATHLEN + 2];
726
dir = FCCurrentDirectory(fcw);
727
for (end=dir; *end != '\0'; ++end)
730
if (DirectoryPathExpand(dir,temp) == NULL) {
731
while (*end != '/' && end != dir) {
736
strcpy(FCCurrentDirectory(fcw),temp);
742
} /* End GotoDeepestLegalDirectory */
744
/*---------------------------------------------------------------------------*
748
This routine resets the information displayed in a FileChooser
749
widget by doing the following:
750
1. It changes the cursor to the value of the "busyCursor" resource.
751
2. The old directory manager (FCDirMgr(fcw)) is closed and a
752
new one opened based on the value of FCCurrentDirectory(fcw).
753
3. Any old string arrays are freed, and any existing directory
755
4. A new array of strings (FCFileNames(fcw)) is allocated and filled
756
with the names of the files in the directory, then this array
757
is used to set what is displayed in the FCFileList(fcw) widget.
758
5. A new array of strings (FCDirNames(fcw)) is allocated and filled
759
with the names of the ancestor directories. These are also used
760
to create a new FCDirMenu(fcw), and the label FCDirMenuButton(fcw)
761
is set to the name of the directory.
762
6. Finally, the cursor is restored.
764
*---------------------------------------------------------------------------*/
768
XfwfFileChooserWidget fcw;
773
char temp[MAXPATHLEN + 2];
776
if (XtIsRealized((Widget)fcw)) {
777
/* This is puke-ola. */
778
XDefineCursor(XtDisplay(fcw),XtWindow(fcw),FCBusyCursor(fcw));
779
XDefineCursor(XtDisplay(fcw),XtWindow(FCFileList(fcw)),
781
XDefineCursor(XtDisplay(fcw),XtWindow(FCDirMenuButton(fcw)),
783
XFlush(XtDisplay(fcw));
786
DirectoryMgrClose(FCDirMgr(fcw));
787
FCDirMgr(fcw) = DirectoryMgrSimpleOpen(FCCurrentDirectory(fcw),
788
FCSortMode(fcw),FCPattern(fcw));
790
/* Throw away old info */
791
if (FCFileNames(fcw) != NULL) {
792
for (i = 0; i < FCNumFileNames(fcw); i++)
793
XtFree(FCFileNames(fcw)[i]);
794
XtFree((char *)FCFileNames(fcw));
796
if (FCDirNames(fcw) != NULL) {
797
for (i = 0; i < FCNumDirNames(fcw); i++)
798
XtFree(FCDirNames(fcw)[i]);
799
XtFree((char *)FCDirNames(fcw));
801
if (FCDirMenu(fcw) != NULL)
802
XtDestroyWidget(FCDirMenu(fcw));
804
/* Count how many files and dirs we have now */
805
FCNumFileNames(fcw) = DirectoryMgrFilteredCount(FCDirMgr(fcw));
806
FCNumDirNames(fcw) = 1;
807
for (dir=FCCurrentDirectory(fcw)+1; *dir != '\0'; dir++) {
809
FCNumDirNames(fcw) += 1;
812
/* Make the array of filenames and set the fileList widget */
813
FCFileNames(fcw) = (char **)XtCalloc(FCNumFileNames(fcw)+1,sizeof(char *));
814
for (i=0; i < FCNumFileNames(fcw); i++) {
815
dir_entry = DirectoryMgrNextEntry(FCDirMgr(fcw));
816
if (dir_entry == NULL)
817
XtError("Inconsistent Directory");
818
strcpy(temp,DirEntryFileName(dir_entry));
819
if (DirEntryIsDir(dir_entry))
821
else if (DirEntryIsBrokenLink(dir_entry))
823
else if (DirEntryIsDirectoryLink(dir_entry))
825
else if (DirEntryIsSymLink(dir_entry))
827
FCFileNames(fcw)[i] = XtNewString(temp);
829
FCFileNames(fcw)[i] = NULL;
830
XawListChange(FCFileList(fcw),FCFileNames(fcw),0,0,True);
832
/* Make the array of dirnames and build a new dirMenu widget */
833
FCDirNames(fcw) = (char **)XtCalloc(FCNumDirNames(fcw)+1,sizeof(char *));
834
FCDirNames(fcw)[0] = XtNewString("/");
835
FCDirMenu(fcw) = XtCreatePopupShell(FC_DIR_MENU_NAME,simpleMenuWidgetClass,
837
menuItem = XtCreateManagedWidget("/",smeBSBObjectClass,FCDirMenu(fcw),
839
XtAddCallback(menuItem,XtNcallback,DirectoryCallback,(XtPointer)0);
840
start = FCCurrentDirectory(fcw);
841
for (i = 1; i < FCNumDirNames(fcw); i++) {
842
while (*start != '\0' && *start == '/')
845
while (*start != '\0' && *start != '/')
846
temp[count++] = *start++;
848
FCDirNames(fcw)[i] = XtNewString(temp);
849
menuItem = XtVaCreateManagedWidget("dirMenuItem",smeBSBObjectClass,
853
XtAddCallback(menuItem,XtNcallback,DirectoryCallback,(XtPointer)i);
855
XtVaSetValues(FCDirMenuButton(fcw), XtNlabel,FCCurrentDirectory(fcw), NULL);
856
if (XtIsRealized((Widget)fcw)) {
857
XUndefineCursor(XtDisplay(fcw),XtWindow(fcw));
858
XUndefineCursor(XtDisplay(fcw),XtWindow(FCFileList(fcw)));
859
XUndefineCursor(XtDisplay(fcw),XtWindow(FCDirMenuButton(fcw)));
861
} /* End UpdateLists */
864
static void Chdir(fcw)
865
XfwfFileChooserWidget fcw;
867
GotoDeepestLegalDirectory(fcw);
871
/*---------------------------------------------------------------------------*
873
E X T E R N A L R O U T I N E S
875
*---------------------------------------------------------------------------*/
878
XfwfFileChooserChangeDirectory(fcw,dir)
879
XfwfFileChooserWidget fcw;
882
strcpy(FCCurrentDirectory(fcw),dir);
884
} /* End XfwfFileChooserChangeDirectory */
887
XfwfFileChooserRefresh(fcw)
888
XfwfFileChooserWidget fcw;
890
XfwfFileChooserChangeDirectory(fcw,".");
891
} /* End XfwfFileChooserRefresh */
894
XfwfFileChooserCurrentDirectory(fcw)
895
XfwfFileChooserWidget fcw;
897
return(FCCurrentDirectory(fcw));
898
} /* End XfwfFileChooserCurrentDirectory */
901
XfwfFileChooserCurrentFile(fcw)
902
XfwfFileChooserWidget fcw;
904
return(FCCurrentFile(fcw));
905
} /* End XfwfFileChooserCurrentFile */