#include "WINGsP.h" #include #include #include #include #include #include #ifndef PATH_MAX #define PATH_MAX 1024 #endif typedef struct W_FilePanel { WMWindow *win; WMLabel *iconLabel; WMLabel *titleLabel; WMFrame *line; WMLabel *nameLabel; WMBrowser *browser; WMButton *okButton; WMButton *cancelButton; WMButton *homeButton; WMButton *trashcanButton; WMButton *createDirButton; WMButton *disketteButton; WMButton *unmountButton; WMView *accessoryView; WMTextField *fileField; char **fileTypes; struct { unsigned int canExit:1; unsigned int canceled:1; /* clicked on cancel */ unsigned int done:1; unsigned int filtered:1; unsigned int canChooseFiles:1; unsigned int canChooseDirectories:1; unsigned int autoCompletion:1; unsigned int showAllFiles:1; unsigned int canFreeFileTypes:1; unsigned int fileMustExist:1; unsigned int panelType:1; } flags; } W_FilePanel; /* Type of panel */ #define WP_OPEN 0 #define WP_SAVE 1 #define PWIDTH 330 #define PHEIGHT 360 static void listDirectoryOnColumn(WMFilePanel *panel, int column, char *path); static void browserClick(); static void browserDClick(); static void fillColumn(WMBrowserDelegate *self, WMBrowser *bPtr, int column, WMList *list); static void deleteFile(); static void createDir(); static void goHome(); static void goFloppy(); static void goUnmount(); static void buttonClick(); static char *getCurrentFileName(WMFilePanel *panel); static void handleEvents(XEvent *event, void *data); static WMBrowserDelegate browserDelegate = { NULL, /* data */ fillColumn, /* createRowsForColumn */ NULL, /* titleOfColumn */ NULL, /* didScroll */ NULL /* willScroll */ }; static int closestListItem(WMList *list, char *text, Bool exact) { WMListItem *item; WMBag *items = WMGetListItems(list); WMBagIterator i; int len = strlen(text); if (len==0) return -1; WM_ITERATE_BAG(items, item, i) { if (strlen(item->text) >= len && ((exact && strcmp(item->text, text)==0) || (!exact && strncmp(item->text, text, len)==0))) { return WMBagIndexForIterator(items, i); } } return -1; } static void textChangedObserver(void *observerData, WMNotification *notification) { W_FilePanel *panel = (W_FilePanel*)observerData; char *text; WMList *list; int col = WMGetBrowserNumberOfColumns(panel->browser) - 1; int i, textEvent; if (!(list = WMGetBrowserListInColumn(panel->browser, col))) return; text = WMGetTextFieldText(panel->fileField); textEvent = (int)WMGetNotificationClientData(notification); if (panel->flags.autoCompletion && textEvent!=WMDeleteTextEvent) i = closestListItem(list, text, False); else i = closestListItem(list, text, True); WMSelectListItem(list, i); if (i>=0 && panel->flags.autoCompletion) { WMListItem *item = WMGetListItem(list, i); int textLen = strlen(text), itemTextLen = strlen(item->text); int visibleItems = WMWidgetHeight(list)/WMGetListItemHeight(list); WMSetListPosition(list, i - visibleItems/2); if (textEvent!=WMDeleteTextEvent) { WMRange range; WMInsertTextFieldText(panel->fileField, &item->text[textLen], textLen); range.position = textLen; range.count = itemTextLen - textLen; WMSelectTextFieldRange(panel->fileField, range); /*WMSetTextFieldCursorPosition(panel->fileField, itemTextLen);*/ } } wfree(text); } static void textEditedObserver(void *observerData, WMNotification *notification) { W_FilePanel *panel = (W_FilePanel*)observerData; if ((int)WMGetNotificationClientData(notification)==WMReturnTextMovement) { WMPerformButtonClick(panel->okButton); } } static WMFilePanel* makeFilePanel(WMScreen *scrPtr, char *name, char *title) { WMFilePanel *fPtr; WMFont *largeFont; fPtr = wmalloc(sizeof(WMFilePanel)); memset(fPtr, 0, sizeof(WMFilePanel)); fPtr->win = WMCreateWindowWithStyle(scrPtr, name, WMTitledWindowMask |WMResizableWindowMask); WMResizeWidget(fPtr->win, PWIDTH, PHEIGHT); WMSetWindowTitle(fPtr->win, ""); WMCreateEventHandler(WMWidgetView(fPtr->win), StructureNotifyMask, handleEvents, fPtr); WMSetWindowMinSize(fPtr->win, PWIDTH, PHEIGHT); fPtr->iconLabel = WMCreateLabel(fPtr->win); WMResizeWidget(fPtr->iconLabel, 64, 64); WMMoveWidget(fPtr->iconLabel, 0, 0); WMSetLabelImagePosition(fPtr->iconLabel, WIPImageOnly); WMSetLabelImage(fPtr->iconLabel, scrPtr->applicationIcon); fPtr->titleLabel = WMCreateLabel(fPtr->win); WMResizeWidget(fPtr->titleLabel, PWIDTH-64, 64); WMMoveWidget(fPtr->titleLabel, 64, 0); largeFont = WMBoldSystemFontOfSize(scrPtr, 24); WMSetLabelFont(fPtr->titleLabel, largeFont); WMReleaseFont(largeFont); WMSetLabelText(fPtr->titleLabel, title); fPtr->line = WMCreateFrame(fPtr->win); WMMoveWidget(fPtr->line, 0, 64); WMResizeWidget(fPtr->line, PWIDTH, 2); WMSetFrameRelief(fPtr->line, WRGroove); fPtr->browser = WMCreateBrowser(fPtr->win); WMSetBrowserDelegate(fPtr->browser, &browserDelegate); WMSetBrowserAction(fPtr->browser, browserClick, fPtr); WMSetBrowserDoubleAction(fPtr->browser, browserDClick, fPtr); WMMoveWidget(fPtr->browser, 7, 72); WMResizeWidget(fPtr->browser, PWIDTH-14,200); WMHangData(fPtr->browser, fPtr); fPtr->nameLabel = WMCreateLabel(fPtr->win); WMMoveWidget(fPtr->nameLabel, 7, 282); WMResizeWidget(fPtr->nameLabel, 55, 14); WMSetLabelText(fPtr->nameLabel, "Name:"); fPtr->fileField = WMCreateTextField(fPtr->win); WMMoveWidget(fPtr->fileField, 60, 278); WMResizeWidget(fPtr->fileField, PWIDTH-60-10, 24); WMAddNotificationObserver(textEditedObserver, fPtr, WMTextDidEndEditingNotification, fPtr->fileField); WMAddNotificationObserver(textChangedObserver, fPtr, WMTextDidChangeNotification, fPtr->fileField); fPtr->okButton = WMCreateCommandButton(fPtr->win); WMMoveWidget(fPtr->okButton, 245, 325); WMResizeWidget(fPtr->okButton, 75, 28); WMSetButtonText(fPtr->okButton, "OK"); WMSetButtonImage(fPtr->okButton, scrPtr->buttonArrow); WMSetButtonAltImage(fPtr->okButton, scrPtr->pushedButtonArrow); WMSetButtonImagePosition(fPtr->okButton, WIPRight); WMSetButtonAction(fPtr->okButton, buttonClick, fPtr); fPtr->cancelButton = WMCreateCommandButton(fPtr->win); WMMoveWidget(fPtr->cancelButton, 165, 325); WMResizeWidget(fPtr->cancelButton, 75, 28); WMSetButtonText(fPtr->cancelButton, "Cancel"); WMSetButtonAction(fPtr->cancelButton, buttonClick, fPtr); fPtr->trashcanButton = WMCreateCommandButton(fPtr->win); WMMoveWidget(fPtr->trashcanButton, 7, 325); WMResizeWidget(fPtr->trashcanButton, 28, 28); WMSetButtonImagePosition(fPtr->trashcanButton, WIPImageOnly); WMSetButtonImage(fPtr->trashcanButton, scrPtr->trashcanIcon); WMSetButtonAltImage(fPtr->trashcanButton, scrPtr->altTrashcanIcon); WMSetButtonAction(fPtr->trashcanButton, deleteFile, fPtr); fPtr->createDirButton = WMCreateCommandButton(fPtr->win); WMMoveWidget(fPtr->createDirButton, 37, 325); WMResizeWidget(fPtr->createDirButton, 28, 28); WMSetButtonImagePosition(fPtr->createDirButton, WIPImageOnly); WMSetButtonImage(fPtr->createDirButton, scrPtr->createDirIcon); WMSetButtonAltImage(fPtr->createDirButton, scrPtr->altCreateDirIcon); WMSetButtonAction(fPtr->createDirButton, createDir, fPtr); fPtr->homeButton = WMCreateCommandButton(fPtr->win); WMMoveWidget(fPtr->homeButton, 67, 325); WMResizeWidget(fPtr->homeButton, 28, 28); WMSetButtonImagePosition(fPtr->homeButton, WIPImageOnly); WMSetButtonImage(fPtr->homeButton, scrPtr->homeIcon); WMSetButtonAltImage(fPtr->homeButton, scrPtr->altHomeIcon); WMSetButtonAction(fPtr->homeButton, goHome, fPtr); fPtr->disketteButton = WMCreateCommandButton(fPtr->win); WMMoveWidget(fPtr->disketteButton, 97, 325); WMResizeWidget(fPtr->disketteButton, 28, 28); WMSetButtonImagePosition(fPtr->disketteButton, WIPImageOnly); WMSetButtonImage(fPtr->disketteButton, scrPtr->disketteIcon); WMSetButtonAltImage(fPtr->disketteButton, scrPtr->altDisketteIcon); WMSetButtonAction(fPtr->disketteButton, goFloppy, fPtr); fPtr->unmountButton = WMCreateCommandButton(fPtr->win); WMMoveWidget(fPtr->unmountButton, 127, 325); WMResizeWidget(fPtr->unmountButton, 28, 28); WMSetButtonImagePosition(fPtr->unmountButton, WIPImageOnly); WMSetButtonImage(fPtr->unmountButton, scrPtr->unmountIcon); WMSetButtonAltImage(fPtr->unmountButton, scrPtr->altUnmountIcon); WMSetButtonAction(fPtr->unmountButton, goUnmount, fPtr); WMSetButtonEnabled(fPtr->unmountButton, False); WMRealizeWidget(fPtr->win); WMMapSubwidgets(fPtr->win); WMSetFocusToWidget(fPtr->fileField); WMSetTextFieldCursorPosition(fPtr->fileField, 0); WMLoadBrowserColumnZero(fPtr->browser); WMSetWindowInitialPosition(fPtr->win, (scrPtr->rootView->size.width - WMWidgetWidth(fPtr->win))/2, (scrPtr->rootView->size.height - WMWidgetHeight(fPtr->win))/2); fPtr->flags.canChooseFiles = 1; fPtr->flags.canChooseDirectories = 1; fPtr->flags.autoCompletion = 1; return fPtr; } WMOpenPanel* WMGetOpenPanel(WMScreen *scrPtr) { WMFilePanel *panel; if (scrPtr->sharedOpenPanel) return scrPtr->sharedOpenPanel; panel = makeFilePanel(scrPtr, "openFilePanel", "Open"); panel->flags.fileMustExist = 1; panel->flags.panelType = WP_OPEN; scrPtr->sharedOpenPanel = panel; return panel; } WMSavePanel* WMGetSavePanel(WMScreen *scrPtr) { WMFilePanel *panel; if (scrPtr->sharedSavePanel) return scrPtr->sharedSavePanel; panel = makeFilePanel(scrPtr, "saveFilePanel", "Save"); panel->flags.fileMustExist = 0; panel->flags.panelType = WP_SAVE; scrPtr->sharedSavePanel = panel; return panel; } void WMFreeFilePanel(WMFilePanel *panel) { if (panel == WMWidgetScreen(panel->win)->sharedSavePanel) { WMWidgetScreen(panel->win)->sharedSavePanel = NULL; } if (panel == WMWidgetScreen(panel->win)->sharedOpenPanel) { WMWidgetScreen(panel->win)->sharedOpenPanel = NULL; } WMRemoveNotificationObserver(panel); WMUnmapWidget(panel->win); WMDestroyWidget(panel->win); wfree(panel); } int WMRunModalFilePanelForDirectory(WMFilePanel *panel, WMWindow *owner, char *path, char *name, char **fileTypes) { WMScreen *scr = WMWidgetScreen(panel->win); XEvent event; if (name && !owner) { WMSetWindowTitle(panel->win, name); } WMChangePanelOwner(panel->win, owner); WMSetFilePanelDirectory(panel, path); panel->flags.done = 0; switch(panel->flags.panelType) { case WP_OPEN: if (fileTypes) panel->flags.filtered = 1; panel->fileTypes = fileTypes; if (name == NULL) name = "Open"; break; case WP_SAVE: panel->fileTypes = NULL; panel->flags.filtered = 0; if (name == NULL) name = "Save"; break; default: break; } WMSetLabelText(panel->titleLabel, name); scr->modalView = W_VIEW(panel->win); WMMapWidget(panel->win); scr->modal = 1; while (!panel->flags.done) { WMNextEvent(scr->display, &event); WMHandleEvent(&event); } scr->modal = 0; /* Must withdraw window because the next time we map * it, it might have a different transient owner. */ WMCloseWindow(panel->win); return (panel->flags.canceled ? False : True); } void WMSetFilePanelDirectory(WMFilePanel *panel, char *path) { WMList *list; WMListItem *item; int col; char *rest; rest = WMSetBrowserPath(panel->browser, path); if (strcmp(path, "/")==0) rest = NULL; col = WMGetBrowserSelectedColumn(panel->browser); list = WMGetBrowserListInColumn(panel->browser, col); if (list && (item = WMGetListSelectedItem(list))) { if (item->isBranch) { WMSetTextFieldText(panel->fileField, rest); } else { WMSetTextFieldText(panel->fileField, item->text); } } else { WMSetTextFieldText(panel->fileField, rest); } } void WMSetFilePanelCanChooseDirectories(WMFilePanel *panel, Bool flag) { panel->flags.canChooseDirectories = flag; } void WMSetFilePanelCanChooseFiles(WMFilePanel *panel, Bool flag) { panel->flags.canChooseFiles = flag; } void WMSetFilePanelAutoCompletion(WMFilePanel *panel, Bool flag) { panel->flags.autoCompletion = flag; } char* WMGetFilePanelFileName(WMFilePanel *panel) { return getCurrentFileName(panel); } void WMSetFilePanelAccessoryView(WMFilePanel *panel, WMView *view) { WMView *v; panel->accessoryView = view; v = WMWidgetView(panel->win); W_ReparentView(view, v, 0, 0); W_MoveView(view, (v->size.width - v->size.width)/2, 300); } WMView* WMGetFilePanelAccessoryView(WMFilePanel *panel) { return panel->accessoryView; } static char* get_name_from_path(char *path) { int size; assert(path!=NULL); size = strlen(path); /* remove trailing / */ while (size > 0 && path[size-1]=='/') size--; /* directory was root */ if (size == 0) return wstrdup("/"); while (size > 0 && path[size-1] != '/') size--; return wstrdup(&(path[size])); } static int filterFileName(WMFilePanel *panel, char *file, Bool isDirectory) { return True; } #define CAST(item) (*((WMListItem**)item)) static int comparer(const void *a, const void *b) { if (CAST(a)->isBranch == CAST(b)->isBranch) return (strcmp(CAST(a)->text, CAST(b)->text)); if (CAST(a)->isBranch) return (-1); return (1); } #undef CAST static void listDirectoryOnColumn(WMFilePanel *panel, int column, char *path) { WMBrowser *bPtr = panel->browser; struct dirent *dentry; DIR *dir; struct stat stat_buf; char pbuf[PATH_MAX+16]; assert(column >= 0); assert(path != NULL); /* put directory name in the title */ WMSetBrowserColumnTitle(bPtr, column, get_name_from_path(path)); dir = opendir(path); if (!dir) { #ifdef VERBOSE printf("WINGs: could not open directory %s\n", path); #endif return; } /* list contents in the column */ while ((dentry = readdir(dir))) { if (strcmp(dentry->d_name, ".")==0 || strcmp(dentry->d_name, "..")==0) continue; strcpy(pbuf, path); if (strcmp(path, "/")!=0) strcat(pbuf, "/"); strcat(pbuf, dentry->d_name); if (stat(pbuf, &stat_buf)!=0) { #ifdef VERBOSE printf("WINGs: could not stat %s\n", pbuf); #endif continue; } else { int isDirectory; isDirectory = S_ISDIR(stat_buf.st_mode); if (filterFileName(panel, dentry->d_name, isDirectory)) WMInsertBrowserItem(bPtr, column, -1, dentry->d_name, isDirectory); } } WMSortBrowserColumnWithComparer(bPtr, column, comparer); closedir(dir); } static void fillColumn(WMBrowserDelegate *self, WMBrowser *bPtr, int column, WMList *list) { char *path; WMFilePanel *panel; if (column > 0) { path = WMGetBrowserPathToColumn(bPtr, column-1); } else { path = wstrdup("/"); } panel = WMGetHangedData(bPtr); listDirectoryOnColumn(panel, column, path); wfree(path); } static void browserDClick(WMBrowser *bPtr, WMFilePanel *panel) { WMPerformButtonClick(panel->okButton); } static void browserClick(WMBrowser *bPtr, WMFilePanel *panel) { int col = WMGetBrowserSelectedColumn(bPtr); WMListItem *item = WMGetBrowserSelectedItemInColumn(bPtr, col); if (!item || item->isBranch) WMSetTextFieldText(panel->fileField, NULL); else { WMSetTextFieldText(panel->fileField, item->text); } } static void showError(WMScreen *scr, WMWindow *owner, char *s, char *file) { char *errStr; if (file) { errStr = wmalloc(strlen(file)+strlen(s)); sprintf(errStr, s, file); } else { errStr = wstrdup(s); } WMRunAlertPanel(scr, owner, "Error", errStr, "OK", NULL, NULL); wfree(errStr); } static void createDir(WMButton *bPre, WMFilePanel *panel) { char *directory_name; char *directory; char *file; char *s; WMScreen *scr = WMWidgetScreen(panel->win); WMInputPanel *_panel; _panel = WMCreateInputPanel(scr, panel->win, "Create Directory", "Enter directory name", "", "OK", "Cancel"); scr->modalView = W_VIEW(_panel->win); WMMapWidget(_panel->win); scr->modal = 1; while (!_panel->done || WMScreenPending(scr)) { XEvent event; WMNextEvent(scr->display, &event); WMHandleEvent(&event); } scr->modal = 0; if (_panel->result == WAPRDefault) directory_name = WMGetTextFieldText(_panel->text); else { WMDestroyInputPanel(_panel); return; } WMDestroyInputPanel(_panel); directory = getCurrentFileName(panel); { char *s = strrchr(directory,'/'); if (s) s[1] = 0; } if (directory_name[0] == '/') { directory[0] = 0; } else { while ((s = strstr(directory,"//"))) { int i; for (i = 2;s[i] == '/';i++); strcpy(s, &s[i-1]); } if ((s = strrchr(directory, '/')) && !s[1]) s[0] = 0; } while ((s = strstr(directory_name,"//"))) { int i; for (i = 2;s[i] == '/';i++); strcpy(s, &s[i-1]); } if ((s = strrchr(directory_name, '/')) && !s[1]) s[0] = 0; file = wmalloc(strlen(directory_name)+strlen(directory)+1); sprintf(file, "%s/%s", directory, directory_name); while ((s = strstr(file,"//"))) { int i; for (i = 2;s[i] == '/';i++); strcpy(s, &s[i-1]); } if (mkdir(file,0xfff) != 0) { switch (errno) { case EACCES: showError(scr, panel->win, "Permission denied.", NULL); break; case EEXIST: showError(scr, panel->win, "'%s' already existes.", file); break; case ENOENT: showError(scr, panel->win, "Path does not exist.", NULL); } } else WMSetFilePanelDirectory(panel, file); wfree(directory_name); wfree(directory); wfree(file); } static void deleteFile(WMButton *bPre, WMFilePanel *panel) { char *file; char *buffer, *s; struct stat filestat; WMScreen *scr = WMWidgetScreen(panel->win); file = getCurrentFileName(panel); while ((s = strstr(file,"//"))) { int i; for (i = 2;s[i] == '/';i++); strcpy(s, &s[i-1]); } if (strlen(file) > 1 && (s = strrchr(file, '/')) && !s[1]) s[0] = 0; if (stat(file,&filestat)) { switch (errno) { case ENOENT: showError(scr, panel->win, "'%s' does not exist.", file); break; case EACCES: showError(scr, panel->win, "Permission denied.", NULL); break; case ENOMEM: showError(scr, panel->win, "Insufficient memory available.", NULL); break; case EROFS: showError(scr, panel->win, "'%s' is on a read-only filesystem.", file); break; default: showError(scr, panel->win, "Can not delete '%s'.", file); } wfree(file); return; } else if (S_ISDIR(filestat.st_mode)) { buffer = wmalloc(strlen(file)+20); sprintf(buffer,"Delete directory %s ?",file); } else { buffer = wmalloc(strlen(file)+15); sprintf(buffer,"Delete file %s ?",file); } if (!WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win, "Warning", buffer, "OK", "Cancel", NULL)) { if (S_ISDIR(filestat.st_mode)) { if (rmdir(file) != 0) { switch (errno) { case EACCES: showError(scr, panel->win, "Permission denied.", NULL); break; case ENOENT: showError(scr, panel->win, "Directory '%s' does not exist.", file); break; case ENOTEMPTY: showError(scr, panel->win, "Directory '%s' is not empty.", file); break; case EBUSY: showError(scr, panel->win, "Directory '%s' is busy.", file); break; default: showError(scr, panel->win, "Can not delete '%s'.", file); } } else { char *s = strrchr(file,'/'); if (s) s[0] = 0; WMSetFilePanelDirectory(panel, file); } } else if (remove(file) != 0) { switch (errno) { case EISDIR: showError(scr, panel->win, "'%s' is a directory.", file); break; case ENOENT: showError(scr, panel->win, "'%s' does not exist.", file); break; case EACCES: showError(scr, panel->win, "Permission denied.", NULL); break; case ENOMEM: showError(scr, panel->win, "Insufficient memory available.", NULL); break; case EROFS: showError(scr, panel->win, "'%s' is on a read-only filesystem.", file); break; default: showError(scr, panel->win, "Can not delete '%s'.", file); } } else { char *s = strrchr(file,'/'); if (s) s[1] = 0; WMSetFilePanelDirectory(panel, file); } } wfree(buffer); wfree(file); } static void goUnmount(WMButton *bPtr, WMFilePanel *panel) { } static void goFloppy(WMButton *bPtr, WMFilePanel *panel) { struct stat filestat; WMScreen *scr = WMWidgetScreen(panel->win); if (stat(WINGsConfiguration.floppyPath, &filestat)) { showError(scr, panel->win, "An error occured browsing '%s'.", WINGsConfiguration.floppyPath); return; } else if (!S_ISDIR(filestat.st_mode)) { showError(scr, panel->win, "'%s' is not a directory.", WINGsConfiguration.floppyPath); return; } WMSetFilePanelDirectory(panel, WINGsConfiguration.floppyPath); } static void goHome(WMButton *bPtr, WMFilePanel *panel) { char *home; /* home is statically allocated. Don't free it! */ home = wgethomedir(); if (!home) return; WMSetFilePanelDirectory(panel, home); } static void handleEvents(XEvent *event, void *data) { W_FilePanel *pPtr = (W_FilePanel*)data; W_View *view = WMWidgetView(pPtr->win); if (event->type == ConfigureNotify) { if (event->xconfigure.width != view->size.width || event->xconfigure.height != view->size.height) { unsigned int newWidth = event->xconfigure.width; unsigned int newHeight = event->xconfigure.height; int newColumnCount; W_ResizeView(view, newWidth, newHeight); WMResizeWidget(pPtr->line, newWidth, 2); WMResizeWidget(pPtr->browser, newWidth-14, newHeight-(PHEIGHT-200)); WMResizeWidget(pPtr->fileField, newWidth-60-10, 24); WMMoveWidget(pPtr->nameLabel, 7, newHeight-(PHEIGHT-282)); WMMoveWidget(pPtr->fileField, 60, newHeight-(PHEIGHT-278)); WMMoveWidget(pPtr->okButton, newWidth-(PWIDTH-245), newHeight-(PHEIGHT-325)); WMMoveWidget(pPtr->cancelButton, newWidth-(PWIDTH-165), newHeight-(PHEIGHT-325)); WMMoveWidget(pPtr->trashcanButton, 7, newHeight-(PHEIGHT-325)); WMMoveWidget(pPtr->createDirButton, 37, newHeight-(PHEIGHT-325)); WMMoveWidget(pPtr->homeButton, 67, newHeight-(PHEIGHT-325)); WMMoveWidget(pPtr->disketteButton, 97, newHeight-(PHEIGHT-325)); WMMoveWidget(pPtr->unmountButton, 127, newHeight-(PHEIGHT-325)); newColumnCount = (newWidth - 14) / 140; WMSetBrowserMaxVisibleColumns(pPtr->browser, newColumnCount); } } } static char* getCurrentFileName(WMFilePanel *panel) { char *path; char *file; char *tmp; int len; path = WMGetBrowserPath(panel->browser); len = strlen(path); if (path[len-1]=='/') { file = WMGetTextFieldText(panel->fileField); tmp = wmalloc(strlen(path)+strlen(file)+8); if (file[0]!='/') { strcpy(tmp, path); strcat(tmp, file); } else strcpy(tmp, file); wfree(file); wfree(path); return tmp; } else { return path; } } static Bool validOpenFile(WMFilePanel *panel) { WMListItem *item; int col, haveFile = 0; char *file = WMGetTextFieldText(panel->fileField); if (file[0] != '\0') haveFile = 1; wfree(file); col = WMGetBrowserSelectedColumn(panel->browser); item = WMGetBrowserSelectedItemInColumn(panel->browser, col); if (item) { if (item->isBranch && !panel->flags.canChooseDirectories && !haveFile) return False; else if (!item->isBranch && !panel->flags.canChooseFiles) return False; else return True; } else { /* we compute for / here */ if (!panel->flags.canChooseDirectories && !haveFile) return False; else return True; } return True; } static void buttonClick(WMButton *bPtr, WMFilePanel *panel) { WMRange range; if (bPtr == panel->okButton) { if (!validOpenFile(panel)) return; if (panel->flags.fileMustExist) { char *file; file = getCurrentFileName(panel); if (access(file, F_OK)!=0) { WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win, "Error", "File does not exist.", "Ok", NULL, NULL); wfree(file); return; } wfree(file); } panel->flags.canceled = 0; } else panel->flags.canceled = 1; range.count = range.position = 0; WMSelectTextFieldRange(panel->fileField, range); panel->flags.done = 1; }