3 * author: Marc van Kempen (wmbfmk@urc.tue.nl)
4 * Desc: File selection routine
6 * Copyright (c) 1995, Marc van Kempen
10 * This software may be used, modified, copied, distributed, and
11 * sold, in both source and binary form provided that the above
12 * copyright and these terms are retained, verbatim, as the first
13 * lines of this file. Under no circumstances is the author
14 * responsible for the proper functioning of this software, nor does
15 * the author assume any responsibility for damages incurred with
22 #include <sys/param.h>
24 #include "ui_objects.h"
26 #include "dialog.priv.h"
32 char *dialog_dfselect(char *dir
, char *fmask
, int is_fselect
);
39 get_directories(DirList
*d
, int n
, char ***names
, int *nd
)
41 * Desc: return the directorienames in <dir> as an array in
42 * <names>, the # of entries in <nd>, memory allocated
43 * to *names should be freed when done with it.
48 /* count the directories, which are in front */
50 while ((*nd
< n
) && (S_ISDIR(d
[*nd
].filestatus
.st_mode
))) (*nd
)++;
51 *names
= (char **) malloc( *nd
* sizeof(char *) );
52 for (i
=0; i
<*nd
; i
++) {
53 (*names
)[i
] = (char *) malloc( strlen(d
[i
].filename
) + 1);
54 strcpy((*names
)[i
], d
[i
].filename
);
58 } /* get_directories() */
61 get_filenames(DirList
*d
, int n
, char ***names
, int *nf
)
63 * Desc: return the filenames in <dir> as an arry in
64 * <names>, the # of entries in <nf>, memory allocated
65 * to *names should be freed when done.
70 /* the # of regular files is the total # of files - # of directories */
71 /* count the # of directories */
73 while ((nd
< n
) && (S_ISDIR(d
[nd
].filestatus
.st_mode
))) nd
++;
75 *names
= (char **) malloc( (n
-nd
) * sizeof(char *) );
77 for (i
=0; i
<*nf
; i
++) {
78 (*names
)[i
] = (char *) malloc( strlen(d
[i
+nd
].filename
) + 1);
79 strcpy((*names
)[i
], d
[i
+nd
].filename
);
83 } /* get_filenames() */
86 FreeNames(char **names
, int n
)
88 * Desc: free the space occupied by names
93 /* free the space occupied by names */
103 dialog_dselect_old(void)
105 * Desc: starting from the current directory,
106 * choose a new current directory
110 char **names
, old_dir
[MAXPATHLEN
];
112 ButtonObj
*okbut
, *cancelbut
;
115 char o_dir
[MAXPATHLEN
];
116 struct ComposeObj
*obj
= NULL
;
117 int n
, nd
, okbutton
, cancelbutton
,
120 ds_win
= newwin(LINES
-8, COLS
-30, 4, 15);
121 if (ds_win
== NULL
) {
122 fprintf(stderr
, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n",
123 LINES
-8, COLS
-30, 4, 15);
126 draw_box(ds_win
, 0, 0, LINES
-8, COLS
-30, dialog_attr
, border_attr
);
127 wattrset(ds_win
, dialog_attr
);
128 mvwaddstr(ds_win
, 0, (COLS
-30)/2 - 9, " Directory Select ");
129 draw_shadow(stdscr
, 4, 15, LINES
-8, COLS
-30);
130 display_helpline(ds_win
, LINES
-9, COLS
-30);
132 /* the Directory string input field */
133 getcwd(o_dir
, MAXPATHLEN
);
134 dir_obj
= NewStringObj(ds_win
, "Directory:", o_dir
, 1, 2, COLS
-34, MAXPATHLEN
-1);
135 AddObj(&obj
, STRINGOBJ
, (void *) dir_obj
);
137 /* the list of directories */
138 get_dir(".", "*", &d
, &n
);
139 get_directories(d
, n
, &names
, &nd
);
140 dirs_obj
= NewListObj(ds_win
, "Directories:", names
, o_dir
, 5, 2,
141 LINES
-15, COLS
-48, nd
);
142 AddObj(&obj
, LISTOBJ
, (void *) dirs_obj
);
146 okbut
= NewButtonObj(ds_win
, "Continue", &okbutton
, 7, COLS
-45);
147 AddObj(&obj
, BUTTONOBJ
, (void *) okbut
);
149 /* the Cancel-button */
150 cancelbutton
= FALSE
;
151 cancelbut
= NewButtonObj(ds_win
, "Return", &cancelbutton
, 11, COLS
-44);
152 AddObj(&obj
, BUTTONOBJ
, (void *) cancelbut
);
156 strcpy(old_dir
, o_dir
);
170 if (strcmp(old_dir
, o_dir
)) {
171 /* the directory was changed, cd into it */
173 dialog_notify("Could not change into directory");
174 strcpy(o_dir
, old_dir
);
176 getcwd(o_dir
, MAXPATHLEN
);
177 strcpy(old_dir
, o_dir
);
179 RefreshStringObj(dir_obj
);
181 get_dir(".", "*", &d
, &n
);
182 FreeNames(names
, nd
);
183 get_directories(d
, n
, &names
, &nd
);
184 UpdateListObj(dirs_obj
, names
, nd
);
185 if (((obj
->prev
)->obj
== (void *) dirs_obj
)) {
199 FreeNames(names
, nd
);
205 } /* dialog_dselect() */
208 dialog_dselect(char *dir
, char *fmask
)
210 * Desc: Choose a directory
213 if (dialog_dfselect(dir
, fmask
, FALSE
)) {
214 return(FALSE
); /* esc or cancel was pressed */
216 return(TRUE
); /* directory was selected */
218 } /* dialog_dselect() */
221 dialog_fselect(char *dir
, char *fmask
)
223 * Desc: Choose a file from a directory
226 return(dialog_dfselect(dir
, fmask
, TRUE
));
227 } /* dialog_fselect() */
230 dialog_dfselect(char *dir
, char *fmask
, int is_fselect
)
232 * Desc: choose a file from the directory <dir>, which
233 * initially display files with the mask <filemask>
234 * pre: <dir> is the initial directory
235 * only files corresponding to the mask <fmask> are displayed
236 * post: returns NULL if no file was selected
237 * else returns pointer to filename, space is allocated, should
238 * be freed after use.
243 char **fnames
, **dnames
, *ret_name
;
246 StringObj
*fm_obj
, *dir_obj
, *sel_obj
;
247 char o_fm
[255], o_dir
[MAXPATHLEN
], o_sel
[MAXPATHLEN
];
248 char old_fmask
[255], old_dir
[MAXPATHLEN
];
249 ListObj
*dirs_obj
, *files_obj
;
250 struct ComposeObj
*obj
= NULL
, *o
;
252 ButtonObj
*okbut_obj
, *canbut_obj
;
253 int ok_button
, cancel_button
;
256 sprintf(msg
, "Could not move into specified directory: %s", dir
);
260 getcwd(o_dir
, MAXPATHLEN
);
262 /* setup the fileselect-window and initialize its components */
263 fs_win
= newwin(LINES
-2, COLS
-20, 1, 10);
264 if (fs_win
== NULL
) {
266 fprintf(stderr
, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n",
267 LINES
-2, COLS
-20, 2, 10);
270 draw_box(fs_win
, 0, 0, LINES
-2, COLS
-20, dialog_attr
, border_attr
);
271 wattrset(fs_win
, dialog_attr
);
273 mvwaddstr(fs_win
, 0, (COLS
-20)/2 - 7, " File Select ");
275 mvwaddstr(fs_win
, 0, (COLS
-20)/2 - 9, " Directory Select ");
277 draw_shadow(stdscr
, 1, 10, LINES
-2, COLS
-20);
278 display_helpline(fs_win
, LINES
-3, COLS
-20);
282 fm_obj
= NewStringObj(fs_win
, "Filemask:", o_fm
, 1, 2, 19, 255);
283 AddObj(&obj
, STRINGOBJ
, (void *) fm_obj
);
285 /* Directory entry */
286 dir_obj
= NewStringObj(fs_win
, "Directory:", o_dir
, 1, 22, COLS
-44, 255);
287 AddObj(&obj
, STRINGOBJ
, (void *) dir_obj
);
290 get_dir(".", fmask
, &d
, &n
); /* read the entire directory */
291 get_directories(d
, n
, &dnames
, &nd
); /* extract the dir-entries */
293 dirs_obj
= NewListObj(fs_win
, "Directories:", dnames
, o_dir
, 5, 2,
294 LINES
-16, (COLS
-20)/2-2, nd
);
296 dirs_obj
= NewListObj(fs_win
, "Directories:", dnames
, o_dir
, 5, 2,
297 LINES
-12, (COLS
-20)/2-2, nd
);
299 AddObj(&obj
, LISTOBJ
, (void *) dirs_obj
);
302 get_filenames(d
, n
, &fnames
, &nf
); /* extract the filenames */
304 files_obj
= NewListObj(fs_win
, "Files:", fnames
, o_sel
, 5, (COLS
-20)/2+1,
305 LINES
-16, (COLS
-20)/2-3, nf
);
307 files_obj
= NewListObj(fs_win
, "Files:", fnames
, o_sel
, 5, (COLS
-20)/2+1,
308 LINES
-12, (COLS
-20)/2-3, nf
);
310 AddObj(&obj
, LISTOBJ
, (void *) files_obj
);
313 /* Selection entry */
315 sel_obj
= NewStringObj(fs_win
, "Selection:", o_sel
, LINES
-10, 2, COLS
-24, 255);
316 AddObj(&obj
, STRINGOBJ
, (void *) sel_obj
);
321 okbut_obj
= NewButtonObj(fs_win
, "Ok", &ok_button
, LINES
-6, 20);
322 AddObj(&obj
, BUTTONOBJ
, (void *) okbut_obj
);
325 cancel_button
= FALSE
;
326 canbut_obj
= NewButtonObj(fs_win
, "Cancel", &cancel_button
, LINES
-6, 30);
327 AddObj(&obj
, BUTTONOBJ
, (void *) canbut_obj
);
329 /* Make sure all objects on the window are drawn */
331 keypad(fs_win
, TRUE
);
333 /* Start the reading */
335 strcpy(old_fmask
, o_fm
);
336 strcpy(old_dir
, o_dir
);
343 if (strcmp(old_fmask
, o_fm
) || strcmp(old_dir
, o_dir
)) {
344 /* reread directory and update the listobjects */
345 if (strcmp(old_dir
, o_dir
)) { /* dir entry was changed */
347 dialog_notify("Could not change into directory");
348 strcpy(o_dir
, old_dir
);
350 getcwd(o_dir
, MAXPATHLEN
);
351 strcpy(old_dir
, o_dir
);
353 RefreshStringObj(dir_obj
);
354 } else { /* fmask entry was changed */
355 strcpy(old_fmask
, o_fm
);
357 get_dir(".", o_fm
, &d
, &n
);
358 FreeNames(dnames
, nd
);
359 get_directories(d
, n
, &dnames
, &nd
);
360 UpdateListObj(dirs_obj
, dnames
, nd
);
361 FreeNames(fnames
, nf
);
362 get_filenames(d
, n
, &fnames
, &nf
);
363 UpdateListObj(files_obj
, fnames
, nf
);
364 if (((o
->prev
)->obj
== (void *) dirs_obj
)) {
370 /* check which button was pressed */
390 FreeNames(dnames
, nd
);
391 FreeNames(fnames
, nf
);
394 if (cancel
|| (strlen(o_sel
) == 0)) {
397 ret_name
= (char *) malloc( strlen(o_sel
) + 1 );
398 strcpy(ret_name
, o_sel
);
401 } /* dialog_fselect() */