17 typedef struct W_FilePanel
{
29 WMButton
*cancelButton
;
32 WMButton
*trashcanButton
;
33 WMButton
*createDirButton
;
34 WMButton
*disketteButton
;
35 WMButton
*unmountButton
;
37 WMView
*accessoryView
;
39 WMTextField
*fileField
;
44 unsigned int canExit
:1;
45 unsigned int canceled
:1; /* clicked on cancel */
46 unsigned int filtered
:1;
47 unsigned int canChooseFiles
:1;
48 unsigned int canChooseDirectories
:1;
49 unsigned int autoCompletion
:1;
50 unsigned int showAllFiles
:1;
51 unsigned int canFreeFileTypes
:1;
52 unsigned int fileMustExist
:1;
53 unsigned int panelType
:1;
64 static void listDirectoryOnColumn(WMFilePanel
* panel
, int column
, char *path
);
65 static void browserClick();
66 static void browserDClick();
68 static void fillColumn(WMBrowserDelegate
* self
, WMBrowser
* bPtr
, int column
, WMList
* list
);
70 static void deleteFile();
72 static void createDir();
76 static void goFloppy();
78 static void goUnmount();
80 static void buttonClick();
82 static char *getCurrentFileName(WMFilePanel
* panel
);
84 static void handleEvents(XEvent
* event
, void *data
);
86 static WMBrowserDelegate browserDelegate
= {
88 fillColumn
, /* createRowsForColumn */
89 NULL
, /* titleOfColumn */
94 static int closestListItem(WMList
* list
, char *text
, Bool exact
)
97 WMArray
*items
= WMGetListItems(list
);
98 int i
, len
= strlen(text
);
103 for (i
= 0; i
< WMGetArrayItemCount(items
); i
++) {
104 item
= WMGetFromArray(items
, i
);
105 if (strlen(item
->text
) >= len
&&
106 ((exact
&& strcmp(item
->text
, text
) == 0) ||
107 (!exact
&& strncmp(item
->text
, text
, len
) == 0))) {
115 static void textChangedObserver(void *observerData
, WMNotification
* notification
)
117 W_FilePanel
*panel
= (W_FilePanel
*) observerData
;
120 int col
= WMGetBrowserNumberOfColumns(panel
->browser
) - 1;
123 if (!(list
= WMGetBrowserListInColumn(panel
->browser
, col
)))
126 text
= WMGetTextFieldText(panel
->fileField
);
127 textEvent
= (int)(uintptr_t) WMGetNotificationClientData(notification
);
129 if (panel
->flags
.autoCompletion
&& textEvent
!= WMDeleteTextEvent
)
130 i
= closestListItem(list
, text
, False
);
132 i
= closestListItem(list
, text
, True
);
134 WMSelectListItem(list
, i
);
135 if (i
>= 0 && panel
->flags
.autoCompletion
) {
136 WMListItem
*item
= WMGetListItem(list
, i
);
137 int textLen
= strlen(text
), itemTextLen
= strlen(item
->text
);
138 int visibleItems
= WMWidgetHeight(list
) / WMGetListItemHeight(list
);
140 WMSetListPosition(list
, i
- visibleItems
/ 2);
142 if (textEvent
!= WMDeleteTextEvent
) {
145 WMInsertTextFieldText(panel
->fileField
, &item
->text
[textLen
], textLen
);
146 range
.position
= textLen
;
147 range
.count
= itemTextLen
- textLen
;
148 WMSelectTextFieldRange(panel
->fileField
, range
);
149 /*WMSetTextFieldCursorPosition(panel->fileField, itemTextLen); */
156 static void textEditedObserver(void *observerData
, WMNotification
* notification
)
158 W_FilePanel
*panel
= (W_FilePanel
*) observerData
;
160 if ((int)(uintptr_t) WMGetNotificationClientData(notification
) == WMReturnTextMovement
) {
161 WMPerformButtonClick(panel
->okButton
);
165 static WMFilePanel
*makeFilePanel(WMScreen
* scrPtr
, char *name
, char *title
)
171 fPtr
= wmalloc(sizeof(WMFilePanel
));
172 memset(fPtr
, 0, sizeof(WMFilePanel
));
174 fPtr
->win
= WMCreateWindowWithStyle(scrPtr
, name
, WMTitledWindowMask
| WMResizableWindowMask
);
175 WMResizeWidget(fPtr
->win
, PWIDTH
, PHEIGHT
);
176 WMSetWindowTitle(fPtr
->win
, "");
178 WMCreateEventHandler(WMWidgetView(fPtr
->win
), StructureNotifyMask
, handleEvents
, fPtr
);
179 WMSetWindowMinSize(fPtr
->win
, PWIDTH
, PHEIGHT
);
181 fPtr
->iconLabel
= WMCreateLabel(fPtr
->win
);
182 WMResizeWidget(fPtr
->iconLabel
, 64, 64);
183 WMMoveWidget(fPtr
->iconLabel
, 0, 0);
184 WMSetLabelImagePosition(fPtr
->iconLabel
, WIPImageOnly
);
185 icon
= WMCreateApplicationIconBlendedPixmap(scrPtr
, (RColor
*) NULL
);
187 WMSetLabelImage(fPtr
->iconLabel
, icon
);
188 WMReleasePixmap(icon
);
190 WMSetLabelImage(fPtr
->iconLabel
, scrPtr
->applicationIconPixmap
);
193 fPtr
->titleLabel
= WMCreateLabel(fPtr
->win
);
194 WMResizeWidget(fPtr
->titleLabel
, PWIDTH
- 64, 64);
195 WMMoveWidget(fPtr
->titleLabel
, 64, 0);
196 largeFont
= WMBoldSystemFontOfSize(scrPtr
, 24);
197 WMSetLabelFont(fPtr
->titleLabel
, largeFont
);
198 WMReleaseFont(largeFont
);
199 WMSetLabelText(fPtr
->titleLabel
, title
);
201 fPtr
->line
= WMCreateFrame(fPtr
->win
);
202 WMMoveWidget(fPtr
->line
, 0, 64);
203 WMResizeWidget(fPtr
->line
, PWIDTH
, 2);
204 WMSetFrameRelief(fPtr
->line
, WRGroove
);
206 fPtr
->browser
= WMCreateBrowser(fPtr
->win
);
207 WMSetBrowserAllowEmptySelection(fPtr
->browser
, True
);
208 WMSetBrowserDelegate(fPtr
->browser
, &browserDelegate
);
209 WMSetBrowserAction(fPtr
->browser
, browserClick
, fPtr
);
210 WMSetBrowserDoubleAction(fPtr
->browser
, browserDClick
, fPtr
);
211 WMMoveWidget(fPtr
->browser
, 7, 72);
212 WMResizeWidget(fPtr
->browser
, PWIDTH
- 14, 200);
213 WMHangData(fPtr
->browser
, fPtr
);
215 fPtr
->nameLabel
= WMCreateLabel(fPtr
->win
);
216 WMMoveWidget(fPtr
->nameLabel
, 7, 282);
217 WMResizeWidget(fPtr
->nameLabel
, 55, 14);
218 WMSetLabelText(fPtr
->nameLabel
, _("Name:"));
220 fPtr
->fileField
= WMCreateTextField(fPtr
->win
);
221 WMMoveWidget(fPtr
->fileField
, 60, 278);
222 WMResizeWidget(fPtr
->fileField
, PWIDTH
- 60 - 10, 24);
223 WMAddNotificationObserver(textEditedObserver
, fPtr
, WMTextDidEndEditingNotification
, fPtr
->fileField
);
224 WMAddNotificationObserver(textChangedObserver
, fPtr
, WMTextDidChangeNotification
, fPtr
->fileField
);
226 fPtr
->okButton
= WMCreateCommandButton(fPtr
->win
);
227 WMMoveWidget(fPtr
->okButton
, 245, 325);
228 WMResizeWidget(fPtr
->okButton
, 75, 28);
229 WMSetButtonText(fPtr
->okButton
, _("OK"));
230 WMSetButtonImage(fPtr
->okButton
, scrPtr
->buttonArrow
);
231 WMSetButtonAltImage(fPtr
->okButton
, scrPtr
->pushedButtonArrow
);
232 WMSetButtonImagePosition(fPtr
->okButton
, WIPRight
);
233 WMSetButtonAction(fPtr
->okButton
, buttonClick
, fPtr
);
235 fPtr
->cancelButton
= WMCreateCommandButton(fPtr
->win
);
236 WMMoveWidget(fPtr
->cancelButton
, 165, 325);
237 WMResizeWidget(fPtr
->cancelButton
, 75, 28);
238 WMSetButtonText(fPtr
->cancelButton
, _("Cancel"));
239 WMSetButtonAction(fPtr
->cancelButton
, buttonClick
, fPtr
);
241 fPtr
->trashcanButton
= WMCreateCommandButton(fPtr
->win
);
242 WMMoveWidget(fPtr
->trashcanButton
, 7, 325);
243 WMResizeWidget(fPtr
->trashcanButton
, 28, 28);
244 WMSetButtonImagePosition(fPtr
->trashcanButton
, WIPImageOnly
);
245 WMSetButtonImage(fPtr
->trashcanButton
, scrPtr
->trashcanIcon
);
246 WMSetButtonAltImage(fPtr
->trashcanButton
, scrPtr
->altTrashcanIcon
);
247 WMSetButtonAction(fPtr
->trashcanButton
, deleteFile
, fPtr
);
249 fPtr
->createDirButton
= WMCreateCommandButton(fPtr
->win
);
250 WMMoveWidget(fPtr
->createDirButton
, 37, 325);
251 WMResizeWidget(fPtr
->createDirButton
, 28, 28);
252 WMSetButtonImagePosition(fPtr
->createDirButton
, WIPImageOnly
);
253 WMSetButtonImage(fPtr
->createDirButton
, scrPtr
->createDirIcon
);
254 WMSetButtonAltImage(fPtr
->createDirButton
, scrPtr
->altCreateDirIcon
);
255 WMSetButtonAction(fPtr
->createDirButton
, createDir
, fPtr
);
257 fPtr
->homeButton
= WMCreateCommandButton(fPtr
->win
);
258 WMMoveWidget(fPtr
->homeButton
, 67, 325);
259 WMResizeWidget(fPtr
->homeButton
, 28, 28);
260 WMSetButtonImagePosition(fPtr
->homeButton
, WIPImageOnly
);
261 WMSetButtonImage(fPtr
->homeButton
, scrPtr
->homeIcon
);
262 WMSetButtonAltImage(fPtr
->homeButton
, scrPtr
->altHomeIcon
);
263 WMSetButtonAction(fPtr
->homeButton
, goHome
, fPtr
);
265 fPtr
->disketteButton
= WMCreateCommandButton(fPtr
->win
);
266 WMMoveWidget(fPtr
->disketteButton
, 97, 325);
267 WMResizeWidget(fPtr
->disketteButton
, 28, 28);
268 WMSetButtonImagePosition(fPtr
->disketteButton
, WIPImageOnly
);
269 WMSetButtonImage(fPtr
->disketteButton
, scrPtr
->disketteIcon
);
270 WMSetButtonAltImage(fPtr
->disketteButton
, scrPtr
->altDisketteIcon
);
271 WMSetButtonAction(fPtr
->disketteButton
, goFloppy
, fPtr
);
273 fPtr
->unmountButton
= WMCreateCommandButton(fPtr
->win
);
274 WMMoveWidget(fPtr
->unmountButton
, 127, 325);
275 WMResizeWidget(fPtr
->unmountButton
, 28, 28);
276 WMSetButtonImagePosition(fPtr
->unmountButton
, WIPImageOnly
);
277 WMSetButtonImage(fPtr
->unmountButton
, scrPtr
->unmountIcon
);
278 WMSetButtonAltImage(fPtr
->unmountButton
, scrPtr
->altUnmountIcon
);
279 WMSetButtonAction(fPtr
->unmountButton
, goUnmount
, fPtr
);
280 WMSetButtonEnabled(fPtr
->unmountButton
, False
);
282 WMRealizeWidget(fPtr
->win
);
283 WMMapSubwidgets(fPtr
->win
);
285 WMSetFocusToWidget(fPtr
->fileField
);
286 WMSetTextFieldCursorPosition(fPtr
->fileField
, 0);
288 WMLoadBrowserColumnZero(fPtr
->browser
);
290 WMSetWindowInitialPosition(fPtr
->win
,
291 (scrPtr
->rootView
->size
.width
- WMWidgetWidth(fPtr
->win
)) / 2,
292 (scrPtr
->rootView
->size
.height
- WMWidgetHeight(fPtr
->win
)) / 2);
294 fPtr
->flags
.canChooseFiles
= 1;
295 fPtr
->flags
.canChooseDirectories
= 1;
296 fPtr
->flags
.autoCompletion
= 1;
301 WMOpenPanel
*WMGetOpenPanel(WMScreen
* scrPtr
)
305 if (scrPtr
->sharedOpenPanel
)
306 return scrPtr
->sharedOpenPanel
;
308 panel
= makeFilePanel(scrPtr
, "openFilePanel", _("Open"));
309 panel
->flags
.fileMustExist
= 1;
310 panel
->flags
.panelType
= WP_OPEN
;
312 scrPtr
->sharedOpenPanel
= panel
;
317 WMSavePanel
*WMGetSavePanel(WMScreen
* scrPtr
)
321 if (scrPtr
->sharedSavePanel
)
322 return scrPtr
->sharedSavePanel
;
324 panel
= makeFilePanel(scrPtr
, "saveFilePanel", _("Save"));
325 panel
->flags
.fileMustExist
= 0;
326 panel
->flags
.panelType
= WP_SAVE
;
328 scrPtr
->sharedSavePanel
= panel
;
333 void WMFreeFilePanel(WMFilePanel
* panel
)
335 if (panel
== WMWidgetScreen(panel
->win
)->sharedSavePanel
) {
336 WMWidgetScreen(panel
->win
)->sharedSavePanel
= NULL
;
338 if (panel
== WMWidgetScreen(panel
->win
)->sharedOpenPanel
) {
339 WMWidgetScreen(panel
->win
)->sharedOpenPanel
= NULL
;
341 WMRemoveNotificationObserver(panel
);
342 WMUnmapWidget(panel
->win
);
343 WMDestroyWidget(panel
->win
);
348 WMRunModalFilePanelForDirectory(WMFilePanel
* panel
, WMWindow
* owner
, char *path
, char *name
, char **fileTypes
)
350 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
352 if (name
&& !owner
) {
353 WMSetWindowTitle(panel
->win
, name
);
356 WMChangePanelOwner(panel
->win
, owner
);
358 WMSetFilePanelDirectory(panel
, path
);
360 switch (panel
->flags
.panelType
) {
363 panel
->flags
.filtered
= 1;
364 panel
->fileTypes
= fileTypes
;
369 panel
->fileTypes
= NULL
;
370 panel
->flags
.filtered
= 0;
378 WMSetLabelText(panel
->titleLabel
, name
);
380 WMMapWidget(panel
->win
);
382 WMRunModalLoop(scr
, W_VIEW(panel
->win
));
384 /* Must withdraw window because the next time we map
385 * it, it might have a different transient owner.
387 WMCloseWindow(panel
->win
);
389 return (panel
->flags
.canceled
? False
: True
);
392 void WMSetFilePanelDirectory(WMFilePanel
* panel
, char *path
)
399 rest
= WMSetBrowserPath(panel
->browser
, path
);
400 if (strcmp(path
, "/") == 0)
403 col
= WMGetBrowserSelectedColumn(panel
->browser
);
404 list
= WMGetBrowserListInColumn(panel
->browser
, col
);
405 if (list
&& (item
= WMGetListSelectedItem(list
))) {
406 if (item
->isBranch
) {
407 WMSetTextFieldText(panel
->fileField
, rest
);
409 WMSetTextFieldText(panel
->fileField
, item
->text
);
412 WMSetTextFieldText(panel
->fileField
, rest
);
416 void WMSetFilePanelCanChooseDirectories(WMFilePanel
* panel
, Bool flag
)
418 panel
->flags
.canChooseDirectories
= ((flag
== 0) ? 0 : 1);
421 void WMSetFilePanelCanChooseFiles(WMFilePanel
* panel
, Bool flag
)
423 panel
->flags
.canChooseFiles
= ((flag
== 0) ? 0 : 1);
426 void WMSetFilePanelAutoCompletion(WMFilePanel
* panel
, Bool flag
)
428 panel
->flags
.autoCompletion
= ((flag
== 0) ? 0 : 1);
431 char *WMGetFilePanelFileName(WMFilePanel
* panel
)
433 return getCurrentFileName(panel
);
436 void WMSetFilePanelAccessoryView(WMFilePanel
* panel
, WMView
* view
)
440 panel
->accessoryView
= view
;
442 v
= WMWidgetView(panel
->win
);
444 W_ReparentView(view
, v
, 0, 0);
446 W_MoveView(view
, (v
->size
.width
- v
->size
.width
) / 2, 300);
449 WMView
*WMGetFilePanelAccessoryView(WMFilePanel
* panel
)
451 return panel
->accessoryView
;
454 static char *get_name_from_path(char *path
)
458 assert(path
!= NULL
);
462 /* remove trailing / */
463 while (size
> 0 && path
[size
- 1] == '/')
465 /* directory was root */
469 while (size
> 0 && path
[size
- 1] != '/')
472 return wstrdup(&(path
[size
]));
475 static int filterFileName(WMFilePanel
* panel
, char *file
, Bool isDirectory
)
480 #define CAST(item) (*((WMListItem**)item))
481 static int comparer(const void *a
, const void *b
)
483 if (CAST(a
)->isBranch
== CAST(b
)->isBranch
)
484 return (strcmp(CAST(a
)->text
, CAST(b
)->text
));
485 if (CAST(a
)->isBranch
)
492 static void listDirectoryOnColumn(WMFilePanel
* panel
, int column
, char *path
)
494 WMBrowser
*bPtr
= panel
->browser
;
495 struct dirent
*dentry
;
497 struct stat stat_buf
;
498 char pbuf
[PATH_MAX
+ 16];
502 assert(path
!= NULL
);
504 /* put directory name in the title */
505 name
= get_name_from_path(path
);
506 WMSetBrowserColumnTitle(bPtr
, column
, name
);
513 printf(_("WINGs: could not open directory %s\n"), path
);
518 /* list contents in the column */
519 while ((dentry
= readdir(dir
))) {
520 if (strcmp(dentry
->d_name
, ".") == 0 || strcmp(dentry
->d_name
, "..") == 0)
524 if (strcmp(path
, "/") != 0)
526 strcat(pbuf
, dentry
->d_name
);
528 if (stat(pbuf
, &stat_buf
) != 0) {
530 printf(_("WINGs: could not stat %s\n"), pbuf
);
536 isDirectory
= S_ISDIR(stat_buf
.st_mode
);
538 if (filterFileName(panel
, dentry
->d_name
, isDirectory
))
539 WMInsertBrowserItem(bPtr
, column
, -1, dentry
->d_name
, isDirectory
);
542 WMSortBrowserColumnWithComparer(bPtr
, column
, comparer
);
547 static void fillColumn(WMBrowserDelegate
* self
, WMBrowser
* bPtr
, int column
, WMList
* list
)
553 path
= WMGetBrowserPathToColumn(bPtr
, column
- 1);
558 panel
= WMGetHangedData(bPtr
);
559 listDirectoryOnColumn(panel
, column
, path
);
563 static void browserDClick(WMBrowser
* bPtr
, WMFilePanel
* panel
)
565 WMPerformButtonClick(panel
->okButton
);
568 static void browserClick(WMBrowser
* bPtr
, WMFilePanel
* panel
)
570 int col
= WMGetBrowserSelectedColumn(bPtr
);
571 WMListItem
*item
= WMGetBrowserSelectedItemInColumn(bPtr
, col
);
573 if (!item
|| item
->isBranch
)
574 WMSetTextFieldText(panel
->fileField
, NULL
);
576 WMSetTextFieldText(panel
->fileField
, item
->text
);
580 static void showError(WMScreen
* scr
, WMWindow
* owner
, char *s
, char *file
)
585 errStr
= wmalloc(strlen(file
) + strlen(s
));
586 sprintf(errStr
, s
, file
);
590 WMRunAlertPanel(scr
, owner
, _("Error"), errStr
, _("OK"), NULL
, NULL
);
594 static void createDir(WMButton
* bPre
, WMFilePanel
* panel
)
596 char *dirName
, *directory
, *file
, *s
;
597 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
599 dirName
= WMRunInputPanel(scr
, panel
->win
, _("Create Directory"),
600 _("Enter directory name"), "", _("OK"), _("Cancel"));
604 directory
= getCurrentFileName(panel
);
605 s
= strrchr(directory
, '/');
609 if (dirName
[0] == '/') {
612 while ((s
= strstr(directory
, "//"))) {
614 for (i
= 2; s
[i
] == '/'; i
++) ;
615 strcpy(s
, &s
[i
- 1]);
617 if ((s
= strrchr(directory
, '/')) && !s
[1])
620 while ((s
= strstr(dirName
, "//"))) {
622 for (i
= 2; s
[i
] == '/'; i
++) ;
623 strcpy(s
, &s
[i
- 1]);
625 if ((s
= strrchr(dirName
, '/')) && !s
[1])
628 file
= wmalloc(strlen(dirName
) + strlen(directory
) + 4);
629 sprintf(file
, "%s/%s", directory
, dirName
);
630 while ((s
= strstr(file
, "//"))) {
632 for (i
= 2; s
[i
] == '/'; i
++) ;
633 strcpy(s
, &s
[i
- 1]);
636 if (mkdir(file
, 0xfff) != 0) {
639 showError(scr
, panel
->win
, _("Permission denied."), NULL
);
642 showError(scr
, panel
->win
, _("'%s' already exists."), file
);
645 showError(scr
, panel
->win
, _("Path does not exist."), NULL
);
648 WMSetFilePanelDirectory(panel
, file
);
655 static void deleteFile(WMButton
* bPre
, WMFilePanel
* panel
)
659 struct stat filestat
;
660 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
662 file
= getCurrentFileName(panel
);
664 while ((s
= strstr(file
, "//"))) {
666 for (i
= 2; s
[i
] == '/'; i
++) ;
667 strcpy(s
, &s
[i
- 1]);
669 if (strlen(file
) > 1 && (s
= strrchr(file
, '/')) && !s
[1])
672 if (stat(file
, &filestat
)) {
675 showError(scr
, panel
->win
, _("'%s' does not exist."), file
);
678 showError(scr
, panel
->win
, _("Permission denied."), NULL
);
681 showError(scr
, panel
->win
, _("Insufficient memory available."), NULL
);
684 showError(scr
, panel
->win
, _("'%s' is on a read-only filesystem."), file
);
687 showError(scr
, panel
->win
, _("Can not delete '%s'."), file
);
691 } else if (S_ISDIR(filestat
.st_mode
)) {
692 int len
= strlen(file
) + 20;
693 buffer
= wmalloc(len
);
694 snprintf(buffer
, len
, _("Delete directory %s ?"), file
);
696 int len
= strlen(file
) + 15;
697 buffer
= wmalloc(len
);
698 snprintf(buffer
, len
, _("Delete file %s ?"), file
);
701 if (!WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
702 _("Warning"), buffer
, _("OK"), _("Cancel"), NULL
)) {
703 if (S_ISDIR(filestat
.st_mode
)) {
704 if (rmdir(file
) != 0) {
707 showError(scr
, panel
->win
, _("Permission denied."), NULL
);
710 showError(scr
, panel
->win
, _("Directory '%s' does not exist."), file
);
713 showError(scr
, panel
->win
, _("Directory '%s' is not empty."), file
);
716 showError(scr
, panel
->win
, _("Directory '%s' is busy."), file
);
719 showError(scr
, panel
->win
, _("Can not delete '%s'."), file
);
722 char *s
= strrchr(file
, '/');
725 WMSetFilePanelDirectory(panel
, file
);
727 } else if (remove(file
) != 0) {
730 showError(scr
, panel
->win
, _("'%s' is a directory."), file
);
733 showError(scr
, panel
->win
, _("'%s' does not exist."), file
);
736 showError(scr
, panel
->win
, _("Permission denied."), NULL
);
739 showError(scr
, panel
->win
, _("Insufficient memory available."), NULL
);
742 showError(scr
, panel
->win
, _("'%s' is on a read-only filesystem."), file
);
745 showError(scr
, panel
->win
, _("Can not delete '%s'."), file
);
748 char *s
= strrchr(file
, '/');
751 WMSetFilePanelDirectory(panel
, file
);
758 static void goUnmount(WMButton
* bPtr
, WMFilePanel
* panel
)
762 static void goFloppy(WMButton
* bPtr
, WMFilePanel
* panel
)
764 struct stat filestat
;
765 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
767 if (stat(WINGsConfiguration
.floppyPath
, &filestat
)) {
768 showError(scr
, panel
->win
, _("An error occured browsing '%s'."), WINGsConfiguration
.floppyPath
);
770 } else if (!S_ISDIR(filestat
.st_mode
)) {
771 showError(scr
, panel
->win
, _("'%s' is not a directory."), WINGsConfiguration
.floppyPath
);
775 WMSetFilePanelDirectory(panel
, WINGsConfiguration
.floppyPath
);
778 static void goHome(WMButton
* bPtr
, WMFilePanel
* panel
)
782 /* home is statically allocated. Don't free it! */
783 home
= wgethomedir();
787 WMSetFilePanelDirectory(panel
, home
);
790 static void handleEvents(XEvent
* event
, void *data
)
792 W_FilePanel
*pPtr
= (W_FilePanel
*) data
;
793 W_View
*view
= WMWidgetView(pPtr
->win
);
795 if (event
->type
== ConfigureNotify
) {
796 if (event
->xconfigure
.width
!= view
->size
.width
|| event
->xconfigure
.height
!= view
->size
.height
) {
797 unsigned int newWidth
= event
->xconfigure
.width
;
798 unsigned int newHeight
= event
->xconfigure
.height
;
801 W_ResizeView(view
, newWidth
, newHeight
);
802 WMResizeWidget(pPtr
->line
, newWidth
, 2);
803 WMResizeWidget(pPtr
->browser
, newWidth
- 14, newHeight
- (PHEIGHT
- 200));
804 WMResizeWidget(pPtr
->fileField
, newWidth
- 60 - 10, 24);
805 WMMoveWidget(pPtr
->nameLabel
, 7, newHeight
- (PHEIGHT
- 282));
806 WMMoveWidget(pPtr
->fileField
, 60, newHeight
- (PHEIGHT
- 278));
807 WMMoveWidget(pPtr
->okButton
, newWidth
- (PWIDTH
- 245), newHeight
- (PHEIGHT
- 325));
808 WMMoveWidget(pPtr
->cancelButton
, newWidth
- (PWIDTH
- 165), newHeight
- (PHEIGHT
- 325));
810 WMMoveWidget(pPtr
->trashcanButton
, 7, newHeight
- (PHEIGHT
- 325));
811 WMMoveWidget(pPtr
->createDirButton
, 37, newHeight
- (PHEIGHT
- 325));
812 WMMoveWidget(pPtr
->homeButton
, 67, newHeight
- (PHEIGHT
- 325));
813 WMMoveWidget(pPtr
->disketteButton
, 97, newHeight
- (PHEIGHT
- 325));
814 WMMoveWidget(pPtr
->unmountButton
, 127, newHeight
- (PHEIGHT
- 325));
816 newColumnCount
= (newWidth
- 14) / 140;
817 WMSetBrowserMaxVisibleColumns(pPtr
->browser
, newColumnCount
);
822 static char *getCurrentFileName(WMFilePanel
* panel
)
829 path
= WMGetBrowserPath(panel
->browser
);
832 if (path
[len
- 1] == '/') {
833 file
= WMGetTextFieldText(panel
->fileField
);
834 tmp
= wmalloc(strlen(path
) + strlen(file
) + 8);
835 if (file
[0] != '/') {
849 static Bool
validOpenFile(WMFilePanel
* panel
)
852 int col
, haveFile
= 0;
853 char *file
= WMGetTextFieldText(panel
->fileField
);
859 col
= WMGetBrowserSelectedColumn(panel
->browser
);
860 item
= WMGetBrowserSelectedItemInColumn(panel
->browser
, col
);
862 if (item
->isBranch
&& !panel
->flags
.canChooseDirectories
&& !haveFile
)
864 else if (!item
->isBranch
&& !panel
->flags
.canChooseFiles
)
869 /* we compute for / here */
870 if (!panel
->flags
.canChooseDirectories
&& !haveFile
)
878 static void buttonClick(WMButton
* bPtr
, WMFilePanel
* panel
)
882 if (bPtr
== panel
->okButton
) {
883 if (!validOpenFile(panel
))
885 if (panel
->flags
.fileMustExist
) {
888 file
= getCurrentFileName(panel
);
889 if (access(file
, F_OK
) != 0) {
890 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
891 _("Error"), _("File does not exist."), _("OK"), NULL
, NULL
);
897 panel
->flags
.canceled
= 0;
899 panel
->flags
.canceled
= 1;
901 range
.count
= range
.position
= 0;
902 WMSelectTextFieldRange(panel
->fileField
, range
);
903 WMBreakModalLoop(WMWidgetScreen(bPtr
));