18 typedef struct W_FilePanel
{
30 WMButton
*cancelButton
;
33 WMButton
*trashcanButton
;
34 WMButton
*createDirButton
;
35 WMButton
*disketteButton
;
36 WMButton
*unmountButton
;
38 WMView
*accessoryView
;
40 WMTextField
*fileField
;
45 unsigned int canExit
:1;
46 unsigned int canceled
:1; /* clicked on cancel */
47 unsigned int filtered
:1;
48 unsigned int canChooseFiles
:1;
49 unsigned int canChooseDirectories
:1;
50 unsigned int autoCompletion
:1;
51 unsigned int showAllFiles
:1;
52 unsigned int canFreeFileTypes
:1;
53 unsigned int fileMustExist
:1;
54 unsigned int panelType
:1;
65 static void listDirectoryOnColumn(WMFilePanel
* panel
, int column
, const char *path
);
66 static void browserClick(WMWidget
*widget
, void *p_panel
);
67 static void browserDClick(WMWidget
*widget
, void *p_panel
);
69 static void fillColumn(WMBrowserDelegate
* self
, WMBrowser
* bPtr
, int column
, WMList
* list
);
71 static void normalizePath(char *s
);
73 static void deleteFile(WMWidget
*widget
, void *p_panel
);
74 static void createDir(WMWidget
*widget
, void *p_panel
);
75 static void goHome(WMWidget
*widget
, void *p_panel
);
76 static void goFloppy(WMWidget
*widget
, void *p_panel
);
77 static void goUnmount(WMWidget
*widget
, void *p_panel
);
78 static void buttonClick(WMWidget
*widget
, void *p_panel
);
80 static char *getCurrentFileName(WMFilePanel
* panel
);
82 static void handleEvents(XEvent
* event
, void *data
);
84 static WMBrowserDelegate browserDelegate
= {
86 fillColumn
, /* createRowsForColumn */
87 NULL
, /* titleOfColumn */
92 static int closestListItem(WMList
* list
, const char *text
, Bool exact
)
95 WMArray
*items
= WMGetListItems(list
);
96 int i
, nb_item
, len
= strlen(text
);
101 nb_item
= WMGetArrayItemCount(items
);
102 for (i
= 0; i
< nb_item
; i
++) {
103 item
= WMGetFromArray(items
, i
);
104 if ((exact
&& strcmp(item
->text
, text
) == 0) ||
105 (!exact
&& strncmp(item
->text
, text
, len
) == 0)) {
113 static void textChangedObserver(void *observerData
, WMNotification
* notification
)
115 W_FilePanel
*panel
= (W_FilePanel
*) observerData
;
118 int col
= WMGetBrowserNumberOfColumns(panel
->browser
) - 1;
122 if (!(list
= WMGetBrowserListInColumn(panel
->browser
, col
)))
125 text
= WMGetTextFieldText(panel
->fileField
);
126 textEvent
= (uintptr_t)WMGetNotificationClientData(notification
);
128 if (panel
->flags
.autoCompletion
&& textEvent
!= WMDeleteTextEvent
)
129 i
= closestListItem(list
, text
, False
);
131 i
= closestListItem(list
, text
, True
);
133 WMSelectListItem(list
, i
);
134 if (i
>= 0 && panel
->flags
.autoCompletion
) {
135 WMListItem
*item
= WMGetListItem(list
, i
);
136 int textLen
= strlen(text
), itemTextLen
= strlen(item
->text
);
137 int visibleItems
= WMWidgetHeight(list
) / WMGetListItemHeight(list
);
139 WMSetListPosition(list
, i
- visibleItems
/ 2);
141 if (textEvent
!= WMDeleteTextEvent
) {
144 WMInsertTextFieldText(panel
->fileField
, &item
->text
[textLen
], textLen
);
145 range
.position
= textLen
;
146 range
.count
= itemTextLen
- textLen
;
147 WMSelectTextFieldRange(panel
->fileField
, range
);
148 /*WMSetTextFieldCursorPosition(panel->fileField, itemTextLen); */
155 static void textEditedObserver(void *observerData
, WMNotification
* notification
)
157 W_FilePanel
*panel
= (W_FilePanel
*) observerData
;
159 if ((uintptr_t)WMGetNotificationClientData(notification
) == WMReturnTextMovement
) {
160 WMPerformButtonClick(panel
->okButton
);
164 static WMFilePanel
*makeFilePanel(WMScreen
* scrPtr
, const char *name
, const char *title
)
170 fPtr
= wmalloc(sizeof(WMFilePanel
));
172 fPtr
->win
= WMCreateWindowWithStyle(scrPtr
, name
, WMTitledWindowMask
| WMResizableWindowMask
);
173 WMResizeWidget(fPtr
->win
, PWIDTH
, PHEIGHT
);
174 WMSetWindowTitle(fPtr
->win
, "");
176 WMCreateEventHandler(WMWidgetView(fPtr
->win
), StructureNotifyMask
, handleEvents
, fPtr
);
177 WMSetWindowMinSize(fPtr
->win
, PWIDTH
, PHEIGHT
);
179 fPtr
->iconLabel
= WMCreateLabel(fPtr
->win
);
180 WMResizeWidget(fPtr
->iconLabel
, 64, 64);
181 WMMoveWidget(fPtr
->iconLabel
, 0, 0);
182 WMSetLabelImagePosition(fPtr
->iconLabel
, WIPImageOnly
);
183 icon
= WMCreateApplicationIconBlendedPixmap(scrPtr
, (RColor
*) NULL
);
185 WMSetLabelImage(fPtr
->iconLabel
, icon
);
186 WMReleasePixmap(icon
);
188 WMSetLabelImage(fPtr
->iconLabel
, scrPtr
->applicationIconPixmap
);
191 fPtr
->titleLabel
= WMCreateLabel(fPtr
->win
);
192 WMResizeWidget(fPtr
->titleLabel
, PWIDTH
- 64, 64);
193 WMMoveWidget(fPtr
->titleLabel
, 64, 0);
194 largeFont
= WMBoldSystemFontOfSize(scrPtr
, 24);
195 WMSetLabelFont(fPtr
->titleLabel
, largeFont
);
196 WMReleaseFont(largeFont
);
197 WMSetLabelText(fPtr
->titleLabel
, title
);
199 fPtr
->line
= WMCreateFrame(fPtr
->win
);
200 WMMoveWidget(fPtr
->line
, 0, 64);
201 WMResizeWidget(fPtr
->line
, PWIDTH
, 2);
202 WMSetFrameRelief(fPtr
->line
, WRGroove
);
204 fPtr
->browser
= WMCreateBrowser(fPtr
->win
);
205 WMSetBrowserAllowEmptySelection(fPtr
->browser
, True
);
206 WMSetBrowserDelegate(fPtr
->browser
, &browserDelegate
);
207 WMSetBrowserAction(fPtr
->browser
, browserClick
, fPtr
);
208 WMSetBrowserDoubleAction(fPtr
->browser
, browserDClick
, fPtr
);
209 WMMoveWidget(fPtr
->browser
, 7, 72);
210 WMResizeWidget(fPtr
->browser
, PWIDTH
- 14, 200);
211 WMHangData(fPtr
->browser
, fPtr
);
213 fPtr
->nameLabel
= WMCreateLabel(fPtr
->win
);
214 WMMoveWidget(fPtr
->nameLabel
, 7, 282);
215 WMResizeWidget(fPtr
->nameLabel
, 55, 14);
216 WMSetLabelText(fPtr
->nameLabel
, _("Name:"));
218 fPtr
->fileField
= WMCreateTextField(fPtr
->win
);
219 WMMoveWidget(fPtr
->fileField
, 60, 278);
220 WMResizeWidget(fPtr
->fileField
, PWIDTH
- 60 - 10, 24);
221 WMAddNotificationObserver(textEditedObserver
, fPtr
, WMTextDidEndEditingNotification
, fPtr
->fileField
);
222 WMAddNotificationObserver(textChangedObserver
, fPtr
, WMTextDidChangeNotification
, fPtr
->fileField
);
224 fPtr
->okButton
= WMCreateCommandButton(fPtr
->win
);
225 WMMoveWidget(fPtr
->okButton
, 245, 325);
226 WMResizeWidget(fPtr
->okButton
, 75, 28);
227 WMSetButtonText(fPtr
->okButton
, _("OK"));
228 WMSetButtonImage(fPtr
->okButton
, scrPtr
->buttonArrow
);
229 WMSetButtonAltImage(fPtr
->okButton
, scrPtr
->pushedButtonArrow
);
230 WMSetButtonImagePosition(fPtr
->okButton
, WIPRight
);
231 WMSetButtonAction(fPtr
->okButton
, buttonClick
, fPtr
);
233 fPtr
->cancelButton
= WMCreateCommandButton(fPtr
->win
);
234 WMMoveWidget(fPtr
->cancelButton
, 165, 325);
235 WMResizeWidget(fPtr
->cancelButton
, 75, 28);
236 WMSetButtonText(fPtr
->cancelButton
, _("Cancel"));
237 WMSetButtonAction(fPtr
->cancelButton
, buttonClick
, fPtr
);
239 fPtr
->trashcanButton
= WMCreateCommandButton(fPtr
->win
);
240 WMMoveWidget(fPtr
->trashcanButton
, 7, 325);
241 WMResizeWidget(fPtr
->trashcanButton
, 28, 28);
242 WMSetButtonImagePosition(fPtr
->trashcanButton
, WIPImageOnly
);
243 WMSetButtonImage(fPtr
->trashcanButton
, scrPtr
->trashcanIcon
);
244 WMSetButtonAltImage(fPtr
->trashcanButton
, scrPtr
->altTrashcanIcon
);
245 WMSetButtonAction(fPtr
->trashcanButton
, deleteFile
, fPtr
);
247 fPtr
->createDirButton
= WMCreateCommandButton(fPtr
->win
);
248 WMMoveWidget(fPtr
->createDirButton
, 37, 325);
249 WMResizeWidget(fPtr
->createDirButton
, 28, 28);
250 WMSetButtonImagePosition(fPtr
->createDirButton
, WIPImageOnly
);
251 WMSetButtonImage(fPtr
->createDirButton
, scrPtr
->createDirIcon
);
252 WMSetButtonAltImage(fPtr
->createDirButton
, scrPtr
->altCreateDirIcon
);
253 WMSetButtonAction(fPtr
->createDirButton
, createDir
, fPtr
);
255 fPtr
->homeButton
= WMCreateCommandButton(fPtr
->win
);
256 WMMoveWidget(fPtr
->homeButton
, 67, 325);
257 WMResizeWidget(fPtr
->homeButton
, 28, 28);
258 WMSetButtonImagePosition(fPtr
->homeButton
, WIPImageOnly
);
259 WMSetButtonImage(fPtr
->homeButton
, scrPtr
->homeIcon
);
260 WMSetButtonAltImage(fPtr
->homeButton
, scrPtr
->altHomeIcon
);
261 WMSetButtonAction(fPtr
->homeButton
, goHome
, fPtr
);
263 fPtr
->disketteButton
= WMCreateCommandButton(fPtr
->win
);
264 WMMoveWidget(fPtr
->disketteButton
, 97, 325);
265 WMResizeWidget(fPtr
->disketteButton
, 28, 28);
266 WMSetButtonImagePosition(fPtr
->disketteButton
, WIPImageOnly
);
267 WMSetButtonImage(fPtr
->disketteButton
, scrPtr
->disketteIcon
);
268 WMSetButtonAltImage(fPtr
->disketteButton
, scrPtr
->altDisketteIcon
);
269 WMSetButtonAction(fPtr
->disketteButton
, goFloppy
, fPtr
);
271 fPtr
->unmountButton
= WMCreateCommandButton(fPtr
->win
);
272 WMMoveWidget(fPtr
->unmountButton
, 127, 325);
273 WMResizeWidget(fPtr
->unmountButton
, 28, 28);
274 WMSetButtonImagePosition(fPtr
->unmountButton
, WIPImageOnly
);
275 WMSetButtonImage(fPtr
->unmountButton
, scrPtr
->unmountIcon
);
276 WMSetButtonAltImage(fPtr
->unmountButton
, scrPtr
->altUnmountIcon
);
277 WMSetButtonAction(fPtr
->unmountButton
, goUnmount
, fPtr
);
278 WMSetButtonEnabled(fPtr
->unmountButton
, False
);
280 WMRealizeWidget(fPtr
->win
);
281 WMMapSubwidgets(fPtr
->win
);
283 WMSetFocusToWidget(fPtr
->fileField
);
284 WMSetTextFieldCursorPosition(fPtr
->fileField
, 0);
286 WMLoadBrowserColumnZero(fPtr
->browser
);
288 WMSetWindowInitialPosition(fPtr
->win
,
289 (scrPtr
->rootView
->size
.width
- WMWidgetWidth(fPtr
->win
)) / 2,
290 (scrPtr
->rootView
->size
.height
- WMWidgetHeight(fPtr
->win
)) / 2);
292 fPtr
->flags
.canChooseFiles
= 1;
293 fPtr
->flags
.canChooseDirectories
= 1;
294 fPtr
->flags
.autoCompletion
= 1;
299 WMOpenPanel
*WMGetOpenPanel(WMScreen
* scrPtr
)
303 if (scrPtr
->sharedOpenPanel
)
304 return scrPtr
->sharedOpenPanel
;
306 panel
= makeFilePanel(scrPtr
, "openFilePanel", _("Open"));
307 panel
->flags
.fileMustExist
= 1;
308 panel
->flags
.panelType
= WP_OPEN
;
310 scrPtr
->sharedOpenPanel
= panel
;
315 WMSavePanel
*WMGetSavePanel(WMScreen
* scrPtr
)
319 if (scrPtr
->sharedSavePanel
)
320 return scrPtr
->sharedSavePanel
;
322 panel
= makeFilePanel(scrPtr
, "saveFilePanel", _("Save"));
323 panel
->flags
.fileMustExist
= 0;
324 panel
->flags
.panelType
= WP_SAVE
;
326 scrPtr
->sharedSavePanel
= panel
;
331 void WMFreeFilePanel(WMFilePanel
* panel
)
333 if (panel
== WMWidgetScreen(panel
->win
)->sharedSavePanel
) {
334 WMWidgetScreen(panel
->win
)->sharedSavePanel
= NULL
;
336 if (panel
== WMWidgetScreen(panel
->win
)->sharedOpenPanel
) {
337 WMWidgetScreen(panel
->win
)->sharedOpenPanel
= NULL
;
339 WMRemoveNotificationObserver(panel
);
340 WMUnmapWidget(panel
->win
);
341 WMDestroyWidget(panel
->win
);
346 WMRunModalFilePanelForDirectory(WMFilePanel
* panel
, WMWindow
* owner
, char *path
, const char *name
, char **fileTypes
)
348 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
350 if (name
&& !owner
) {
351 WMSetWindowTitle(panel
->win
, name
);
354 WMChangePanelOwner(panel
->win
, owner
);
356 WMSetFilePanelDirectory(panel
, path
);
358 switch (panel
->flags
.panelType
) {
361 panel
->flags
.filtered
= 1;
362 panel
->fileTypes
= fileTypes
;
367 panel
->fileTypes
= NULL
;
368 panel
->flags
.filtered
= 0;
376 WMSetLabelText(panel
->titleLabel
, name
);
378 WMMapWidget(panel
->win
);
380 WMRunModalLoop(scr
, W_VIEW(panel
->win
));
382 /* Must withdraw window because the next time we map
383 * it, it might have a different transient owner.
385 WMCloseWindow(panel
->win
);
387 return (panel
->flags
.canceled
? False
: True
);
390 void WMSetFilePanelDirectory(WMFilePanel
* panel
, char *path
)
397 rest
= WMSetBrowserPath(panel
->browser
, path
);
398 if (strcmp(path
, "/") == 0)
401 col
= WMGetBrowserSelectedColumn(panel
->browser
);
402 list
= WMGetBrowserListInColumn(panel
->browser
, col
);
403 if (list
&& (item
= WMGetListSelectedItem(list
))) {
404 if (item
->isBranch
) {
405 WMSetTextFieldText(panel
->fileField
, rest
);
407 WMSetTextFieldText(panel
->fileField
, item
->text
);
410 WMSetTextFieldText(panel
->fileField
, rest
);
414 void WMSetFilePanelCanChooseDirectories(WMFilePanel
* panel
, Bool flag
)
416 panel
->flags
.canChooseDirectories
= ((flag
== 0) ? 0 : 1);
419 void WMSetFilePanelCanChooseFiles(WMFilePanel
* panel
, Bool flag
)
421 panel
->flags
.canChooseFiles
= ((flag
== 0) ? 0 : 1);
424 void WMSetFilePanelAutoCompletion(WMFilePanel
* panel
, Bool flag
)
426 panel
->flags
.autoCompletion
= ((flag
== 0) ? 0 : 1);
429 char *WMGetFilePanelFileName(WMFilePanel
* panel
)
431 return getCurrentFileName(panel
);
434 void WMSetFilePanelAccessoryView(WMFilePanel
* panel
, WMView
* view
)
438 panel
->accessoryView
= view
;
440 v
= WMWidgetView(panel
->win
);
442 W_ReparentView(view
, v
, 0, 0);
444 W_MoveView(view
, (v
->size
.width
- v
->size
.width
) / 2, 300);
447 WMView
*WMGetFilePanelAccessoryView(WMFilePanel
* panel
)
449 return panel
->accessoryView
;
452 static char *get_name_from_path(const char *path
)
456 assert(path
!= NULL
);
460 /* remove trailing / */
461 while (size
> 0 && path
[size
- 1] == '/')
463 /* directory was root */
467 while (size
> 0 && path
[size
- 1] != '/')
470 return wstrdup(&(path
[size
]));
473 #define CAST(item) (*((WMListItem**)item))
474 static int comparer(const void *a
, const void *b
)
476 if (CAST(a
)->isBranch
== CAST(b
)->isBranch
)
477 return (strcmp(CAST(a
)->text
, CAST(b
)->text
));
478 if (CAST(a
)->isBranch
)
485 static void listDirectoryOnColumn(WMFilePanel
* panel
, int column
, const char *path
)
487 WMBrowser
*bPtr
= panel
->browser
;
488 struct dirent
*dentry
;
490 struct stat stat_buf
;
491 char pbuf
[PATH_MAX
+ 16];
495 assert(path
!= NULL
);
497 /* put directory name in the title */
498 name
= get_name_from_path(path
);
499 WMSetBrowserColumnTitle(bPtr
, column
, name
);
506 printf(_("WINGs: could not open directory %s\n"), path
);
511 /* list contents in the column */
512 while ((dentry
= readdir(dir
))) {
513 if (strcmp(dentry
->d_name
, ".") == 0 || strcmp(dentry
->d_name
, "..") == 0)
516 if (wstrlcpy(pbuf
, path
, sizeof(pbuf
)) >= sizeof(pbuf
))
518 if (strcmp(path
, "/") != 0 &&
519 wstrlcat(pbuf
, "/", sizeof(pbuf
)) >= sizeof(pbuf
))
521 if (wstrlcat(pbuf
, dentry
->d_name
, sizeof(pbuf
)) >= sizeof(pbuf
))
524 if (stat(pbuf
, &stat_buf
) != 0) {
526 printf(_("WINGs: could not stat %s\n"), pbuf
);
532 isDirectory
= S_ISDIR(stat_buf
.st_mode
);
533 WMInsertBrowserItem(bPtr
, column
, -1, dentry
->d_name
, isDirectory
);
536 WMSortBrowserColumnWithComparer(bPtr
, column
, comparer
);
542 static void fillColumn(WMBrowserDelegate
* self
, WMBrowser
* bPtr
, int column
, WMList
* list
)
547 /* Parameter not used, but tell the compiler that it is ok */
552 path
= WMGetBrowserPathToColumn(bPtr
, column
- 1);
557 panel
= WMGetHangedData(bPtr
);
558 listDirectoryOnColumn(panel
, column
, path
);
562 static void browserDClick(WMWidget
*widget
, void *p_panel
)
564 WMFilePanel
*panel
= p_panel
;
566 /* Parameter not used, but tell the compiler that it is ok */
569 WMPerformButtonClick(panel
->okButton
);
572 static void browserClick(WMWidget
*widget
, void *p_panel
)
574 WMBrowser
*bPtr
= (WMBrowser
*) widget
;
575 WMFilePanel
*panel
= p_panel
;
576 int col
= WMGetBrowserSelectedColumn(bPtr
);
577 WMListItem
*item
= WMGetBrowserSelectedItemInColumn(bPtr
, col
);
579 if (!item
|| item
->isBranch
)
580 WMSetTextFieldText(panel
->fileField
, NULL
);
582 WMSetTextFieldText(panel
->fileField
, item
->text
);
586 static void showError(WMScreen
* scr
, WMWindow
* owner
, const char *s
, const char *file
)
591 errStr
= wmalloc(strlen(file
) + strlen(s
) + 1);
592 sprintf(errStr
, s
, file
);
596 WMRunAlertPanel(scr
, owner
, _("Error"), errStr
, _("OK"), NULL
, NULL
);
600 static void createDir(WMWidget
*widget
, void *p_panel
)
602 WMFilePanel
*panel
= p_panel
;
603 char *dirName
, *directory
, *file
;
605 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
607 /* Parameter not used, but tell the compiler that it is ok */
610 dirName
= WMRunInputPanel(scr
, panel
->win
, _("Create Directory"),
611 _("Enter directory name"), "", _("OK"), _("Cancel"));
615 /* if `dirName' is an absolute path, don't mind `directory'.
616 * normalize as needed (possibly not needed at all?) */
617 normalizePath(dirName
);
618 if (*dirName
!= '/') {
619 directory
= getCurrentFileName(panel
);
620 normalizePath(directory
);
625 slen
= strlen(dirName
) + (directory
? strlen(directory
) + 1 /* "/" */ : 0) + 1 /* NULL */;
626 file
= wmalloc(slen
);
629 (wstrlcat(file
, directory
, slen
) >= slen
||
630 wstrlcat(file
, "/", slen
) >= slen
))
633 if (wstrlcat(file
, dirName
, slen
) >= slen
)
636 if (mkdir(file
, 00777) != 0) {
637 #define __msgbufsize__ 512
638 char *buffer
= wmalloc(__msgbufsize__
);
639 snprintf(buffer
, __msgbufsize__
, _("Can not create %s: %s"), file
, strerror(errno
));
640 showError(scr
, panel
->win
, buffer
, NULL
);
642 #undef __msgbufsize__
644 WMSetFilePanelDirectory(panel
, file
);
657 *----------------------------------------------------------------------
659 * Remove multiple consecutive and any trailing slashes from
661 *----------------------------------------------------------------------
663 static void normalizePath(char *s
)
668 for (i
= 0; s
[i
]; (void)(!found
&& i
++)) {
670 if (s
[i
] == '/' && s
[i
+1] == '/') {
674 while (s
[i
+nslash
] == '/')
676 for (j
= 0; s
[i
+j
+nslash
]; j
++)
677 s
[i
+j
] = s
[i
+j
+nslash
];
681 if (i
> 1 && s
[--i
] == '/')
686 static void deleteFile(WMWidget
*widget
, void *p_panel
)
688 WMFilePanel
*panel
= p_panel
;
691 struct stat filestat
;
692 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
694 /* Parameter not used, but tell the compiler that it is ok */
697 file
= getCurrentFileName(panel
);
703 if (stat(file
, &filestat
) == -1) {
704 snprintf(buffer
, sizeof(buffer
),
705 _("Can not find %s: %s"),
706 file
, strerror(errno
));
707 showError(scr
, panel
->win
, buffer
, NULL
);
711 snprintf(buffer
, sizeof(buffer
), _("Delete %s %s?"),
712 S_ISDIR(filestat
.st_mode
) ? _("directory") : _("file"), file
);
714 if (!WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
715 _("Warning"), buffer
, _("OK"), _("Cancel"), NULL
)) {
717 if (remove(file
) == -1) {
718 snprintf(buffer
, sizeof(buffer
),
719 _("Removing %s failed: %s"),
720 file
, strerror(errno
));
721 showError(scr
, panel
->win
, buffer
, NULL
);
723 char *s
= strrchr(file
, '/');
726 WMSetFilePanelDirectory(panel
, file
);
734 static void goUnmount(WMWidget
*widget
, void *p_panel
)
736 /* Not implemented yet */
741 static void goFloppy(WMWidget
*widget
, void *p_panel
)
743 WMFilePanel
*panel
= p_panel
;
744 struct stat filestat
;
745 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
747 /* Parameter not used, but tell the compiler that it is ok */
750 if (stat(WINGsConfiguration
.floppyPath
, &filestat
)) {
751 showError(scr
, panel
->win
, _("An error occured browsing '%s'."), WINGsConfiguration
.floppyPath
);
753 } else if (!S_ISDIR(filestat
.st_mode
)) {
754 showError(scr
, panel
->win
, _("'%s' is not a directory."), WINGsConfiguration
.floppyPath
);
758 WMSetFilePanelDirectory(panel
, WINGsConfiguration
.floppyPath
);
761 static void goHome(WMWidget
*widget
, void *p_panel
)
763 WMFilePanel
*panel
= p_panel
;
766 /* Parameter not used, but tell the compiler that it is ok */
769 /* home is statically allocated. Don't free it! */
770 home
= wgethomedir();
774 WMSetFilePanelDirectory(panel
, home
);
777 static void handleEvents(XEvent
* event
, void *data
)
779 W_FilePanel
*pPtr
= (W_FilePanel
*) data
;
780 W_View
*view
= WMWidgetView(pPtr
->win
);
782 if (event
->type
== ConfigureNotify
) {
783 if (event
->xconfigure
.width
!= view
->size
.width
|| event
->xconfigure
.height
!= view
->size
.height
) {
784 unsigned int newWidth
= event
->xconfigure
.width
;
785 unsigned int newHeight
= event
->xconfigure
.height
;
788 W_ResizeView(view
, newWidth
, newHeight
);
789 WMResizeWidget(pPtr
->line
, newWidth
, 2);
790 WMResizeWidget(pPtr
->browser
, newWidth
- 14, newHeight
- (PHEIGHT
- 200));
791 WMResizeWidget(pPtr
->fileField
, newWidth
- 60 - 10, 24);
792 WMMoveWidget(pPtr
->nameLabel
, 7, newHeight
- (PHEIGHT
- 282));
793 WMMoveWidget(pPtr
->fileField
, 60, newHeight
- (PHEIGHT
- 278));
794 WMMoveWidget(pPtr
->okButton
, newWidth
- (PWIDTH
- 245), newHeight
- (PHEIGHT
- 325));
795 WMMoveWidget(pPtr
->cancelButton
, newWidth
- (PWIDTH
- 165), newHeight
- (PHEIGHT
- 325));
797 WMMoveWidget(pPtr
->trashcanButton
, 7, newHeight
- (PHEIGHT
- 325));
798 WMMoveWidget(pPtr
->createDirButton
, 37, newHeight
- (PHEIGHT
- 325));
799 WMMoveWidget(pPtr
->homeButton
, 67, newHeight
- (PHEIGHT
- 325));
800 WMMoveWidget(pPtr
->disketteButton
, 97, newHeight
- (PHEIGHT
- 325));
801 WMMoveWidget(pPtr
->unmountButton
, 127, newHeight
- (PHEIGHT
- 325));
803 newColumnCount
= (newWidth
- 14) / 140;
804 WMSetBrowserMaxVisibleColumns(pPtr
->browser
, newColumnCount
);
809 static char *getCurrentFileName(WMFilePanel
* panel
)
816 path
= WMGetBrowserPath(panel
->browser
);
821 if (path
[strlen(path
) -1] != '/')
824 file
= WMGetTextFieldText(panel
->fileField
);
825 slen
= strlen(path
) + strlen(file
) + 1;
839 static Bool
validOpenFile(WMFilePanel
* panel
)
842 int col
, haveFile
= 0;
843 char *file
= WMGetTextFieldText(panel
->fileField
);
849 col
= WMGetBrowserSelectedColumn(panel
->browser
);
850 item
= WMGetBrowserSelectedItemInColumn(panel
->browser
, col
);
852 if (item
->isBranch
&& !panel
->flags
.canChooseDirectories
&& !haveFile
)
854 else if (!item
->isBranch
&& !panel
->flags
.canChooseFiles
)
859 /* we compute for / here */
860 if (!panel
->flags
.canChooseDirectories
&& !haveFile
)
868 static void buttonClick(WMWidget
*widget
, void *p_panel
)
870 WMButton
*bPtr
= (WMButton
*) widget
;
871 WMFilePanel
*panel
= p_panel
;
874 if (bPtr
== panel
->okButton
) {
875 if (!validOpenFile(panel
))
877 if (panel
->flags
.fileMustExist
) {
880 file
= getCurrentFileName(panel
);
881 if (access(file
, F_OK
) != 0) {
882 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
883 _("Error"), _("File does not exist."), _("OK"), NULL
, NULL
);
889 panel
->flags
.canceled
= 0;
891 panel
->flags
.canceled
= 1;
893 range
.count
= range
.position
= 0;
894 WMSelectTextFieldRange(panel
->fileField
, range
);
895 WMBreakModalLoop(WMWidgetScreen(bPtr
));