source: branches/port5/AWT/AWT_file_selection.cxx

Last change on this file was 6287, checked in by westram, 15 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.8 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <time.h>
5#include <string.h>
6// #include <malloc.h>
7#include <memory.h>
8
9#include <arbdb.h>
10#include <arbdbt.h>
11#include <aw_root.hxx>
12#include <aw_device.hxx>
13#include <aw_window.hxx>
14#include <aw_awars.hxx>
15#include "awt.hxx"
16#include "awtlocal.hxx"
17
18#include <dirent.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <sys/param.h>
22
23#include <string>
24#include <set>
25
26#if defined(DEBUG)
27// #define TRACE_FILEBOX
28#endif // DEBUG
29
30using namespace std;
31
32static GB_CSTR awt_get_base_directory(const char *pwd_envar) {
33    GB_CSTR res;
34
35    if (strcmp(pwd_envar, "PWD") == 0) {
36        res = GB_getcwd();
37    }
38    else if (strcmp(pwd_envar, "PT_SERVER_HOME") == 0) {
39        res = GB_path_in_ARBLIB("pts", NULL);
40    }
41    else {
42        res = GB_getenv(pwd_envar);
43        if (!res) res = GB_getcwd(); // fallback to current working dir
44    }
45
46    return res;
47}
48
49
50
51static GB_CSTR get_suffix(GB_CSTR fullpath) { // returns pointer behind '.' of suffix (or NULL if no suffix found)
52    GB_CSTR dot = strrchr(fullpath, '.');
53    if (!dot) return 0;
54
55    GB_CSTR lslash = strrchr(fullpath, '/');
56    if (lslash && lslash>dot) return 0; // no . behind last /
57    return dot+1;
58}
59
60
61static char *set_suffix(const char *name, const char *suffix) {
62    // returns "name.suffix" (name may contain path information)
63    // - eliminates multiple dots
64    // - sets name to 'noname' if no name part is given
65
66    char *path, *fullname;
67    GB_split_full_path(name, &path, &fullname, NULL, NULL);
68
69    // remove dots and spaces from suffix:
70    while (suffix[0] == '.' || suffix[0] == ' ') ++suffix;
71    if (!suffix[0]) suffix = 0;
72
73    GBS_strstruct *out = GBS_stropen(FILENAME_MAX+1);
74    if (path) {
75        GBS_strcat(out, path);
76        GBS_chrcat(out, '/');
77    }
78
79    if (fullname) GBS_strcat(out, fullname);
80
81    if (GB_is_directory(GBS_mempntr(out))) {
82        // if 'out' contains a directory now, 'name' was lacking a filename
83        // (it was only a directory then)
84        GBS_strcat(out, "/noname"); // invent a name
85    }
86
87    if (suffix) {
88        GBS_chrcat(out, '.');
89        GBS_strcat(out, suffix);
90    }
91
92    free(path);
93    free(fullname);
94
95    return GBS_strclose(out);
96}
97
98
99char *AWT_fold_path(char *path, const char *pwd_envar) {
100    char    *unfolded = AWT_unfold_path(path, pwd_envar);
101    GB_CSTR  prefix   = awt_get_base_directory(pwd_envar);
102    int      len      = strlen(prefix);
103
104    if (strncmp(unfolded, prefix, len) == 0) { // unfolded starts with pwd
105        if (unfolded[len] == '/') {
106            strcpy(unfolded, unfolded+len+1);
107        }
108        else if (unfolded[len] == 0) { // unfolded is equal to pwd
109            unfolded[0] = 0;
110        }
111    }
112
113    return unfolded;
114}
115
116/* create a full path */
117
118char *AWT_unfold_path(const char *path, const char *pwd_envar) {
119    if (path[0] == '/' || path[0] == '~') return strdup(GB_get_full_path(path));
120    return strdup(GB_concat_full_path(awt_get_base_directory(pwd_envar), path));
121}
122
123const char *AWT_valid_path(const char *path) {
124    if (strlen(path)) return path;
125    return ".";
126}
127
128int AWT_is_dir(const char *path) { // Warning : returns 1 for symbolic links to directories
129    struct stat stt;
130    if (stat(AWT_valid_path(path), &stt)) return 0;
131    return !!S_ISDIR(stt.st_mode);
132}
133int AWT_is_file(const char *path) { // Warning : returns 1 for symbolic links to files
134    struct stat stt;
135    if (stat(AWT_valid_path(path), &stt)) return 0;
136    return !!S_ISREG(stt.st_mode);
137}
138int AWT_is_link(const char *path) {
139    struct stat stt;
140    if (lstat(AWT_valid_path(path), &stt)) return 0;
141    return !!S_ISLNK(stt.st_mode);
142}
143
144char *AWT_extract_directory(const char *path) {
145    const char *lslash = strrchr(path, '/');
146    if (!lslash) return 0;
147
148    char *result        = strdup(path);
149    result[lslash-path] = 0;
150
151    return result;
152}
153
154#define DIR_SORT_ORDERS 3
155static const char *DIR_sort_order_name[DIR_SORT_ORDERS] = { "alpha", "date", "size" };
156static int DIR_sort_order     = 0; // 0 = alpha; 1 = date; 2 = size;
157static int DIR_subdirs_hidden = 0; // 1 -> hide sub-directories (by user-request)
158static int DIR_show_hidden    = 0; // 1 -> show hidden (i.e. files/directories starting with '.')
159
160static void awt_execute_browser_command(const char *browser_command) {
161    if (strcmp(browser_command, "sort") == 0) {
162        DIR_sort_order = (DIR_sort_order+1)%DIR_SORT_ORDERS;
163    }
164    else if (strcmp(browser_command, "hide") == 0) {
165        DIR_subdirs_hidden = 1;
166    }
167    else if (strcmp(browser_command, "show") == 0) {
168        DIR_subdirs_hidden = 0;
169    }
170    else if (strcmp(browser_command, "dot") == 0) {
171        DIR_show_hidden ^= 1;
172    }
173    else {
174        aw_message(GBS_global_string("Unknown browser command '%s'", browser_command));
175    }
176}
177
178static void awt_fill_selection_box_recursive(const char *fulldir, int skipleft, const char *mask, bool recurse, bool showdir, bool show_dots, AW_window *aws, AW_selection_list *selid) {
179    // see awt_create_selection_box_cb for meaning of 'sort_order'
180
181    DIR *dirp = opendir(fulldir);
182
183#if defined(TRACE_FILEBOX)
184    printf("awt_fill_selection_box_recursive for directory '%s'\n", fulldir);
185#endif // TRACE_FILEBOX
186
187    if (!dirp) {
188        aws->insert_selection(selid, GBS_global_string("x Your directory path is invalid (%s)", fulldir), "?");
189        return;
190    }
191
192    struct dirent *dp;
193    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
194        const char *entry       = dp->d_name;
195        char       *nontruepath = GBS_global_string_copy("%s/%s", fulldir, entry);
196        char       *fullname;
197
198        if (strlen(fulldir)) fullname = strdup(GB_concat_full_path(fulldir, entry));
199        else fullname                 = strdup(GB_get_full_path(entry));
200
201        if (AWT_is_dir(fullname)) {
202            if (!(entry[0] == '.' && (!DIR_show_hidden || entry[1] == 0 || (entry[1] == '.' && entry[2] == 0)))) { // skip "." and ".." and dotdirs if requested
203                if (showdir) {
204                    aws->insert_selection(selid, GBS_global_string("D %-18s(%s)", entry, fullname), fullname);
205                }
206                if (recurse && !AWT_is_link(nontruepath)) { // don't follow links
207                    awt_fill_selection_box_recursive(nontruepath, skipleft, mask, recurse, showdir, show_dots, aws, selid);
208                }
209            }
210        }
211        else {
212            if (GBS_string_matches(entry, mask, GB_IGNORE_CASE)) { // entry matches mask
213                if ((entry[0] != '.' || DIR_show_hidden) && AWT_is_file(fullname)) { // regular existing file
214                    struct stat stt;
215
216                    stat(fullname, &stt);
217
218                    char       atime[256];
219                    struct tm *tms = localtime(&stt.st_mtime);
220                    strftime( atime, 255,"%Y/%m/%d %k:%M",tms);
221
222                    long ksize    = (stt.st_size+512)/1024;
223                    char typechar = AWT_is_link(nontruepath) ? 'L' : 'F';
224
225                    const char *sel_entry = 0;
226                    switch (DIR_sort_order) {
227                        case 0: // alpha
228                            sel_entry = GBS_global_string("%c %-30s  %6lik  %s", typechar, nontruepath+skipleft, ksize, atime);
229                            break;
230                        case 1: // date
231                            sel_entry = GBS_global_string("%c %s  %6lik  %s", typechar, atime, ksize, nontruepath+skipleft);
232                            break;
233                        case 2: // size
234                            sel_entry = GBS_global_string("%c %6lik  %s  %s", typechar, ksize, atime, nontruepath+skipleft);
235                            break;
236                    }
237
238                    aws->insert_selection(selid, sel_entry, nontruepath);
239                }
240            }
241        }
242        free(fullname);
243        free(nontruepath);
244    }
245
246    closedir(dirp);
247}
248
249class DuplicateLinkFilter {
250    set<string> insertedDirectories;
251
252public:
253    DuplicateLinkFilter() {}
254
255    bool not_seen_yet(const string& dir) const { return insertedDirectories.find(dir) == insertedDirectories.end(); }
256    void register_directory(const string& dir) {
257        // printf("register_directory '%s'\n", dir.c_str());
258        insertedDirectories.insert(dir);
259    }
260};
261
262
263static void show_soft_link(AW_window *aws, AW_selection_list *sel_id, const char *envar, DuplicateLinkFilter& unDup) {
264    // adds a soft link (e.g. ARBMACROHOME or ARB_WORKDIR) into file selection box
265    // if content of 'envar' matches 'cwd' nothing is inserted
266
267    const char *expanded_dir = awt_get_base_directory(envar);
268    string      edir(expanded_dir);
269
270    if (unDup.not_seen_yet(edir)) {
271        // printf("New directory '%s' (deduced from '$%s')\n", expanded_dir, envar);
272        unDup.register_directory(edir);
273        const char *entry = GBS_global_string("$ %-18s(%s)", GBS_global_string("'%s'", envar), expanded_dir);
274        aws->insert_selection(sel_id, entry, expanded_dir);
275    }
276    // else {
277        // printf("Skipping directory '%s' (deduced from '$%s')\n", expanded_dir, envar);
278    // }
279}
280
281static void awt_create_selection_box_cb(void *dummy, struct adawcbstruct *cbs) {
282    AW_root             *aw_root = cbs->aws->get_root();
283    AWUSE(dummy);
284    cbs->aws->clear_selection_list(cbs->id);
285
286    char *diru    = aw_root->awar(cbs->def_dir)->read_string();
287    char *fulldir = AWT_unfold_path(diru,cbs->pwd);
288    char *filter  = aw_root->awar(cbs->def_filter)->read_string();
289    char *name    = aw_root->awar(cbs->def_name)->read_string();
290
291#if defined(TRACE_FILEBOX)
292    printf("awt_create_selection_box_cb:\n"
293           "- diru   ='%s'\n"
294           "- fulldir='%s'\n"
295           "- filter ='%s'\n"
296           "- name   ='%s'\n" , diru, fulldir, filter, name);
297#endif // TRACE_FILEBOX
298
299    const char *name_only = 0;
300    {
301        char *slash = strrchr(name, '/');
302        name_only   = slash ? slash+1 : name;
303    }
304
305    if (name[0] == '/' && AWT_is_dir(name)) {
306        freedup(fulldir, name);
307        name_only = "";
308    }
309
310    DuplicateLinkFilter  unDup;
311    unDup.register_directory(fulldir);
312
313    bool is_wildcard = strchr(name_only, '*');
314
315    if (cbs->show_dir) {
316        if (is_wildcard) {
317            if (cbs->leave_wildcards) {
318                cbs->aws->insert_selection( cbs->id, (char *)GBS_global_string("  ALL '%s' in '%s'", name_only, fulldir), name);
319            }
320            else {
321                cbs->aws->insert_selection( cbs->id, (char *)GBS_global_string("  ALL '%s' in+below '%s'", name_only, fulldir), name);
322            }
323        }
324        else {
325            cbs->aws->insert_selection( cbs->id, (char *)GBS_global_string("  CONTENTS OF '%s'",fulldir), fulldir );
326        }
327
328        if (filter[0] && !is_wildcard) {
329            cbs->aws->insert_selection( cbs->id, GBS_global_string("! \' Search for\'     (*%s)", filter), "*" );
330        }
331        if (strcmp("/", fulldir)) {
332            cbs->aws->insert_selection( cbs->id, "! \'PARENT DIR       (..)\'", ".." );
333        }
334        if (DIR_subdirs_hidden == 0) {
335            show_soft_link(cbs->aws, cbs->id, cbs->pwd, unDup);
336
337            if (cbs->pwdx) {        // additional directories
338                char *start = cbs->pwdx;
339                while (start) {
340                    char *multiple = strchr(start, '^');
341                    if (multiple) {
342                        multiple[0] = 0;
343                        show_soft_link(cbs->aws, cbs->id, start, unDup);
344                        multiple[0] = '^';
345                        start       = multiple+1;
346                    }
347                    else {
348                        show_soft_link(cbs->aws, cbs->id, start, unDup);
349                        start = 0;
350                    }
351                }
352            }
353
354            show_soft_link(cbs->aws, cbs->id, "HOME", unDup);
355            show_soft_link(cbs->aws, cbs->id, "PWD", unDup);
356            show_soft_link(cbs->aws, cbs->id, "ARB_WORKDIR", unDup);
357            show_soft_link(cbs->aws, cbs->id, "PT_SERVER_HOME", unDup);
358
359            cbs->aws->insert_selection( cbs->id, "! \' Sub-directories (shown)\'", GBS_global_string("%s?hide?", name));
360        }
361        else {
362            cbs->aws->insert_selection( cbs->id, "! \' Sub-directories (hidden)\'", GBS_global_string("%s?show?", name));
363        }
364    }
365
366    cbs->aws->insert_selection( cbs->id, GBS_global_string("! \' Sort order\'     (%s)", DIR_sort_order_name[DIR_sort_order]),
367                                GBS_global_string("%s?sort?", name));
368
369    cbs->aws->insert_selection( cbs->id,
370                                GBS_global_string("! \' %s%s\'",
371                                                  DIR_show_hidden ? "Hide dot-" : "Show hidden ",
372                                                  cbs->show_dir ? "files/dirs" : "files"),
373                                GBS_global_string("%s?dot?", name));
374
375    if (is_wildcard) {
376        if (cbs->leave_wildcards) {
377            awt_fill_selection_box_recursive(fulldir, strlen(fulldir)+1, name_only, false, cbs->show_dir && !DIR_subdirs_hidden, DIR_show_hidden, cbs->aws, cbs->id);
378        }
379        else {
380            if (cbs->show_dir) { // recursive wildcarded search
381                awt_fill_selection_box_recursive(fulldir, strlen(fulldir)+1, name_only, true, false, DIR_show_hidden, cbs->aws, cbs->id);
382            }
383            else {
384                char *mask = GBS_global_string_copy("%s*%s", name_only, filter);
385                awt_fill_selection_box_recursive(fulldir, strlen(fulldir)+1, mask, false, false, DIR_show_hidden, cbs->aws, cbs->id);
386                free(mask);
387            }
388        }
389    }
390    else {
391        char *mask = GBS_global_string_copy("*%s", filter);
392        awt_fill_selection_box_recursive(fulldir, strlen(fulldir)+1, mask, false, cbs->show_dir && !DIR_subdirs_hidden, DIR_show_hidden, cbs->aws, cbs->id);
393        free(mask);
394    }
395
396    cbs->aws->insert_default_selection( cbs->id, "", "" );
397    cbs->aws->sort_selection_list(cbs->id, 0, 1);
398    cbs->aws->update_selection_list( cbs->id );
399
400    free(name);
401    free(fulldir);
402    free(diru);
403    free(filter);
404}
405
406static bool filter_has_changed = false;
407
408void awt_create_selection_box_changed_filter(void *, struct adawcbstruct *) {
409    filter_has_changed = true;
410#if defined(TRACE_FILEBOX)
411    printf("awt_create_selection_box_changed_filter: marked as changed\n");
412#endif // TRACE_FILEBOX
413}
414
415static void awt_selection_box_changed_filename(void *, struct adawcbstruct *cbs) {
416    AW_root *aw_root = cbs->aws->get_root();
417    char    *fname   = aw_root->awar(cbs->def_name)->read_string();
418
419#if defined(TRACE_FILEBOX)
420    printf("awt_selection_box_changed_filename:\n"
421           "- fname='%s'\n", fname);
422    printf("- cbs->previous_filename='%s'\n", cbs->previous_filename);
423#endif // TRACE_FILEBOX
424
425    if (fname[0]) {
426        char *browser_command = 0;
427        {
428            // internal browser commands (e.g. '?sort?') are simply appended to the filename
429
430            char *lquestion = strrchr(fname, '?');
431            if (lquestion) {
432                lquestion[0] = 0; // remove last '?' + everything behind
433                lquestion    = strrchr(fname, '?');
434                if (lquestion) {
435                    browser_command = lquestion+1;
436                    lquestion[0]    = 0; // completely remove the browser command
437                }
438            }
439        }
440        if (browser_command) {
441            aw_root->awar(cbs->def_name)->write_string(fname); // re-write w/o browser_command
442            awt_execute_browser_command(browser_command);
443            aw_root->awar(cbs->def_dir)->touch(); // force reinit
444        }
445
446        char *newName = 0;
447        char *dir     = aw_root->awar(cbs->def_dir)->read_string();
448
449        if (fname[0] == '/' || fname[0] == '~') {
450            newName = strdup(GB_get_full_path(fname));
451        }
452        else {
453            if (dir[0]) {
454                if (dir[0] == '/') {
455                    newName = strdup(GB_concat_full_path(dir, fname));
456                }
457                else {
458                    char *fulldir = 0;
459
460                    if (dir[0] == '.') fulldir = AWT_unfold_path(dir, cbs->pwd);
461                    else fulldir               = strdup(GB_get_full_path(dir));
462
463                    newName = strdup(GB_concat_full_path(fulldir, fname));
464                    free(fulldir);
465                }
466            }
467            else {
468                newName = strdup(GB_get_full_path(fname));
469            }
470        }
471
472        if (newName) {
473            if (AWT_is_dir(newName)) {
474                aw_root->awar(cbs->def_name)->write_string("");
475                aw_root->awar(cbs->def_dir)->write_string(newName);
476                if (cbs->previous_filename) {
477                    const char *slash              = strrchr(cbs->previous_filename, '/');
478                    const char *name               = slash ? slash+1 : cbs->previous_filename;
479                    const char *with_previous_name = GB_concat_full_path(newName, name);
480
481                    if (!AWT_is_dir(with_previous_name)) { // write as new name if not a directory
482                        aw_root->awar(cbs->def_name)->write_string(with_previous_name);
483                    }
484                    else {
485                        freeset(cbs->previous_filename, 0);
486                        aw_root->awar(cbs->def_name)->write_string(newName);
487                    }
488
489                    freeset(newName, aw_root->awar(cbs->def_name)->read_string());
490                }
491                else {
492                    aw_root->awar(cbs->def_name)->write_string("");
493                }
494            }
495            else {
496                char *lslash = strrchr(newName, '/');
497                if (lslash) {
498                    if (lslash == newName) { // root directory
499                        aw_root->awar(cbs->def_dir)->write_string("/"); // write directory part
500                    }
501                    else {
502                        lslash[0] = 0;
503                        aw_root->awar(cbs->def_dir)->write_string(newName); // write directory part
504                        lslash[0] = '/';
505                    }
506                }
507
508                // now check the correct suffix :
509                {
510                    char *filter = aw_root->awar(cbs->def_filter)->read_string();
511                    if (filter[0]) {
512                        char *pfilter = strrchr(filter,'.');
513                        pfilter       = pfilter ? pfilter+1 : filter;
514
515                        char *suffix = (char*)get_suffix(newName); // cast ok, since get_suffix points into newName
516
517                        if (!suffix || strcmp(suffix, pfilter) != 0) {
518                            if (suffix && filter_has_changed) {
519                                if (suffix[-1] == '.') suffix[-1] = 0;
520                            }
521                            freeset(newName, set_suffix(newName, pfilter));
522                        }
523                    }
524                    free(filter);
525                }
526
527                if (strcmp(newName, fname) != 0) {
528                    aw_root->awar(cbs->def_name)->write_string(newName); // loops back if changed !!!
529                }
530
531                freeset(cbs->previous_filename, newName);
532            }
533        }
534        free(dir);
535
536        if (strchr(fname, '*')) { // wildcard -> search for suffix
537            aw_root->awar(cbs->def_dir)->touch(); // force reinit
538        }
539    }
540
541    filter_has_changed = false;
542
543    free(fname);
544}
545
546#define SELBOX_AUTOREFRESH_FREQUENCY 1000 // refresh once a second
547
548struct selbox_autorefresh_info {
549    unsigned long            modtime;
550    adawcbstruct            *acbs;
551    selbox_autorefresh_info *next;
552};
553static selbox_autorefresh_info *autorefresh_info = 0;
554
555static GB_ULONG get_dir_modtime(adawcbstruct *acbs) {
556    char     *dir   = acbs->awr->awar(acbs->def_dir)->read_string();
557    GB_ULONG  mtime = GB_time_of_file(dir);
558    free(dir);
559    return mtime;
560}
561
562static void autorefresh_selboxes(AW_root *) {
563    selbox_autorefresh_info *check = autorefresh_info;
564
565    while (check) {
566        GB_ULONG mtime = get_dir_modtime(check->acbs);
567        if (mtime != check->modtime) {
568            check->modtime = mtime;
569            check->acbs->awr->awar(check->acbs->def_dir)->touch(); // refresh
570        }
571        check = check->next;
572    }
573
574    // refresh again and again and again..
575    autorefresh_info->acbs->awr->add_timed_callback(SELBOX_AUTOREFRESH_FREQUENCY, autorefresh_selboxes);
576}
577
578static void awt_selbox_install_autorefresh(adawcbstruct *acbs) {
579    if (!autorefresh_info) {    // when installing first selbox
580        acbs->awr->add_timed_callback(SELBOX_AUTOREFRESH_FREQUENCY, autorefresh_selboxes);
581    }
582
583    selbox_autorefresh_info *install = new selbox_autorefresh_info;
584
585    install->acbs    = acbs;
586    install->modtime = get_dir_modtime(acbs);
587   
588    install->next    = autorefresh_info;
589    autorefresh_info = install;
590}
591
592void awt_create_selection_box(AW_window *aws, const char *awar_prefix,const char *at_prefix,const  char *pwd, bool show_dir, bool allow_wildcards)
593{
594    AW_root             *aw_root = aws->get_root();
595    struct adawcbstruct *acbs    = new adawcbstruct;
596    memset(acbs, 0, sizeof(*acbs));
597
598    acbs->aws = (AW_window *)aws;
599    acbs->awr = aw_root;
600    acbs->pwd = strdup(pwd);
601    {
602        char *multiple_dirs_in_pwd = strchr(acbs->pwd, '^');
603        if (multiple_dirs_in_pwd) {
604            multiple_dirs_in_pwd[0] = 0;
605            acbs->pwdx = multiple_dirs_in_pwd+1;
606        }
607        else {
608            acbs->pwdx = 0;
609        }
610    }
611
612    acbs->show_dir          = show_dir;
613    acbs->def_name          = GBS_string_eval(awar_prefix,"*=*/file_name",0);
614    acbs->previous_filename = 0;
615    acbs->leave_wildcards   = allow_wildcards;
616
617    aw_root->awar(acbs->def_name)->add_callback((AW_RCB1)awt_selection_box_changed_filename,(AW_CL)acbs);
618
619    acbs->def_dir = GBS_string_eval(awar_prefix,"*=*/directory",0);
620    aw_root->awar(acbs->def_dir)->add_callback((AW_RCB1)awt_create_selection_box_cb,(AW_CL)acbs);
621
622    acbs->def_filter = GBS_string_eval(awar_prefix,"*=*/filter",0);
623    aw_root->awar(acbs->def_filter)->add_callback((AW_RCB1)awt_create_selection_box_changed_filter,(AW_CL)acbs);
624    aw_root->awar(acbs->def_filter)->add_callback((AW_RCB1)awt_selection_box_changed_filename,(AW_CL)acbs);
625    aw_root->awar(acbs->def_filter)->add_callback((AW_RCB1)awt_create_selection_box_cb,(AW_CL)acbs);
626
627    char buffer[1024];
628    sprintf(buffer,"%sfilter",at_prefix);
629    if (aws->at_ifdef(buffer)){
630        aws->at(buffer);
631        aws->create_input_field(acbs->def_filter,5);
632    }
633
634    sprintf(buffer,"%sfile_name",at_prefix);
635    if (aws->at_ifdef(buffer)){
636        aws->at(buffer);
637        aws->create_input_field(acbs->def_name,20);
638    }
639
640    sprintf(buffer,"%sbox",at_prefix);
641    aws->at(buffer);
642    acbs->id = aws->create_selection_list(acbs->def_name,0,"",2,2);
643   
644    awt_create_selection_box_cb(0,acbs);
645    awt_selection_box_changed_filename(0, acbs);    // this fixes the path name
646
647    awt_selbox_install_autorefresh(acbs);
648}
649
650char *awt_get_selected_fullname(AW_root *awr, const char *awar_prefix) {
651    char *file = awr->awar(GBS_global_string("%s/file_name", awar_prefix))->read_string();
652    if (file[0] != '/') {
653        // if name w/o directory was entered by hand (or by default) then append the directory :
654
655        char    *awar_dir_name = GBS_global_string_copy("%s/directory", awar_prefix);
656        AW_awar *awar_dir      = awr->awar_no_error(awar_dir_name);
657
658        if (!awar_dir) {
659            // file selection box was not active (happens e.g. for print tree)
660            awar_dir = awr->awar_string(awar_dir_name, GB_getcwd());
661        }
662
663        awt_assert(awar_dir);
664
665        char *dir = awar_dir->read_string();
666        if (!dir[0]) {          // empty -> fillin current dir
667            awar_dir->write_string(GB_getcwd());
668            freeset(dir, awar_dir->read_string());
669        }
670
671        char *full = strdup(GB_concat_full_path(dir, file));
672
673        free(dir);
674        free(file);
675       
676        file = full;
677
678        free(awar_dir_name);
679    }
680   
681    return file;
682}
683
684void awt_refresh_selection_box(AW_root *awr, const char *awar_prefix) {
685    awr->awar(GBS_global_string("%s/directory", awar_prefix))->touch();
686}
Note: See TracBrowser for help on using the repository browser.