40 if (strcmp(pwd_envar,
"PWD") == 0) {
60 const char *lslash = strrchr(path,
'/');
61 if (!lslash)
return NULp;
63 char *
result = strdup(path);
64 result[lslash-path] = 0;
73 int base_len = strlen(awar_base);
74 bool has_slash = awar_base[base_len-1] ==
'/';
75 char *awar_name =
new char[base_len+30];
78 sprintf(awar_name,
"%s%s", awar_base,
"/directory"+
int(has_slash));
81 sprintf(awar_name,
"%s%s", awar_base,
"/filter" +
int(has_slash));
84 sprintf(awar_name,
"%s%s", awar_base,
"/file_name"+
int(has_slash));
87 #if defined(ASSERTION_USED)
88 bool is_tmp_awar = strncmp(awar_base,
"tmp/", 4) == 0 || strncmp(awar_base,
"/tmp/", 5) == 0;
100 for (
unsigned i = 0; i<dirs.
size(); ++i) {
102 fprintf(stderr,
"Creating directory '%s'\n", dirs[i]);
123 mutable bool aborted;
137 aborted = difftime(now, start) > max_duration;
158 bool leave_wildcards;
159 bool filled_by_wildcard;
170 void bind_callbacks();
171 void execute_browser_command(
const char *browser_command);
172 void fill_recursive(
const char *fulldir,
int skipleft,
const char *mask,
bool recurse,
bool showdir);
174 void format_columns();
184 leave_wildcards(allow_wildcards),
185 filled_by_wildcard(
false),
192 char *multiple_dirs_in_pwd = strchr(pwd,
'^');
193 if (multiple_dirs_in_pwd) {
194 multiple_dirs_in_pwd[0] = 0;
195 pwdx = multiple_dirs_in_pwd+1;
212 sprintf(buffer,
"%sfilter", at_prefix);
218 sprintf(buffer,
"%sfile_name", at_prefix);
224 sprintf(buffer,
"%sbox", at_prefix);
236 unsigned long maxtof = 0;
237 for (
unsigned i = 0; i<dirs.
size(); ++i) {
239 if (tof>maxtof) maxtof = tof;
249 if (!dot)
return NULp;
251 GB_CSTR lslash = strrchr(fullpath,
'/');
252 if (lslash && lslash>dot)
return NULp;
257 static char *
set_suffix(
const char *name,
const char *suffix) {
262 char *path, *fullname;
266 while (suffix[0] ==
'.' || suffix[0] ==
' ') ++suffix;
267 if (!suffix[0]) suffix =
NULp;
275 if (fullname) out.
cat(fullname);
295 inline const char *
valid_path(
const char *path) {
return path[0] ? path :
"."; }
301 void File_selection::execute_browser_command(
const char *browser_command) {
302 if (strcmp(browser_command,
"sort") == 0) {
305 else if (strcmp(browser_command,
"hide") == 0) {
306 show_subdirs =
false;
308 else if (strcmp(browser_command,
"show") == 0) {
311 else if (strcmp(browser_command,
"dot") == 0) {
312 show_hidden = !show_hidden;
314 else if (strcmp(browser_command,
"inctime") == 0) {
323 const char *typechar =
"DFL";
324 for (
int i = 0; typechar[i]; ++i) {
325 if (entry[0] == typechar[i])
return i;
330 void File_selection::format_columns() {
331 const int FORMATTED_TYPES = 3;
333 int maxlen[FORMATTED_TYPES] = { 17, 17, 17 };
335 for (
int pass = 1; pass<=2; ++pass) {
338 const char *disp = entry.get_displayed();
342 const char *q1 = strchr(disp,
'?');
344 const char *q2 = strchr(q1+1,
'?');
348 if (maxlen[type]<len) maxlen[
type] = len;
352 buf.ncat(disp, q1-disp);
354 buf.nput(
' ', maxlen[type]-len);
356 entry.set_displayed(buf.get_data());
366 void File_selection::fill_recursive(
const char *fulldir,
int skipleft,
const char *mask,
bool recurse,
bool showdir) {
367 DIR *dirp = opendir(fulldir);
369 #if defined(TRACE_FILEBOX)
370 printf(
"fill_fileselection_recursive for directory '%s'\n", fulldir);
371 #endif // TRACE_FILEBOX
379 for (dp = readdir(dirp); dp; dp = readdir(dirp)) {
380 const char *entry = dp->d_name;
388 if (!(entry[0] ==
'.' && (!show_hidden || entry[1] == 0 || (entry[1] ==
'.' && entry[2] == 0)))) {
394 fill_recursive(nontruepath, skipleft, mask, recurse, showdir);
401 if ((entry[0] !=
'.' || show_hidden) &&
AW_is_file(fullname)) {
404 stat(fullname, &stt);
407 struct tm *tms = localtime(&stt.st_mtime);
408 strftime(atime, 255,
"%Y/%m/%d %k:%M", tms);
411 char typechar =
AW_is_link(nontruepath) ?
'L' :
'F';
413 const char *sel_entry =
NULp;
414 switch (sort_order) {
416 sel_entry =
GBS_global_string(
"%c ?%s? %7s %s", typechar, nontruepath+skipleft, size, atime);
419 sel_entry =
GBS_global_string(
"%c %s %7s %s", typechar, atime, size, nontruepath+skipleft);
422 sel_entry =
GBS_global_string(
"%c %7s %s %s", typechar, size, atime, nontruepath+skipleft);
427 filelist->
insert(sel_entry, nontruepath);
440 set<string> insertedDirectories;
445 bool not_seen_yet(
const string& dir)
const {
return insertedDirectories.find(dir) == insertedDirectories.end(); }
447 insertedDirectories.insert(dir);
457 if (!expanded_dir) expanded_dir =
GB_getenv(envar);
460 string edir(expanded_dir);
465 filelist->
insert(entry, expanded_dir);
470 inline bool fileOrLink(
const char *d) {
return d[0] ==
'F' || d[0] ==
'L'; }
473 while (d[0] ==
' ') ++d;
474 while (d[0] !=
' ') ++d;
475 while (d[0] ==
' ') ++d;
478 static int cmpBySize(
const char *disp1,
const char *disp2) {
483 if (u1[0] != u2[0]) {
484 static const char *units =
"bkMGTPEZY";
486 const char *p1 = strchr(units, u1[0]);
487 const char *p2 = strchr(units, u2[0]);
507 char *slash = strrchr(name,
'/');
508 name_only = slash ? slash+1 : name;
517 for (
unsigned i = 0; i<cdirs.
size(); ++i) dirs.put(strdup(cdirs[i]));
521 dirs.put(strdup(name));
536 const char *fulldir = dirs[0];
541 if (filled_by_wildcard) {
542 if (leave_wildcards) {
556 if (strcmp(
"/", fulldir)) {
557 filelist->
insert(
"! \'PARENT DIR\' (..)",
"..");
565 char *multiple = strchr(start,
'^');
594 static const char *order_name[
DIR_SORT_ORDERS] = {
"alpha",
"date",
"size" };
598 bool insert_dirs = dirdisp ==
ANY_DIR && show_subdirs;
601 for (
unsigned i = 0; i<dirs.size(); ++i) {
602 const char *fulldir = dirs[i];
603 if (filled_by_wildcard) {
604 if (leave_wildcards) {
605 fill_recursive(fulldir, strlen(fulldir)+1, name_only,
false, insert_dirs);
609 fill_recursive(fulldir, strlen(fulldir)+1, name_only,
true,
false);
613 fill_recursive(fulldir, strlen(fulldir)+1, mask,
false,
false);
621 fill_recursive(fulldir, strlen(fulldir)+1, mask,
false, insert_dirs);
634 filelist->
sort(
false,
false);
640 if (filled_by_wildcard && !leave_wildcards) {
653 const char *qm1 =
NULp;
654 const char *qm2 =
NULp;
666 int cmdlen = qm2-qm1-1;
667 if (cmdlen>=1)
return qm1+1;
677 #if defined(TRACE_FILEBOX)
678 printf(
"fileselection_filename_changed_cb:\n"
679 "- fname ='%s'\n", fname);
680 #endif // TRACE_FILEBOX
684 if (browser_command) {
685 char *browser_command_copy =
ARB_strndup(browser_command, strlen(browser_command)-1);
689 execute_browser_command(browser_command_copy);
693 free(browser_command_copy);
696 char *newName =
NULp;
699 #if defined(TRACE_FILEBOX)
700 printf(
"- dir ='%s'\n", dir);
701 #endif // TRACE_FILEBOX
703 if (fname[0] ==
'/' || fname[0] ==
'~') {
712 char *fulldir =
NULp;
715 else fulldir = strdup(dir);
728 if (newName && strcmp(fname, newName) != 0) {
735 #if defined(TRACE_FILEBOX)
736 printf(
"- newName ='%s'\n", newName);
737 #endif // TRACE_FILEBOX
746 char *lslash = strrchr(newName,
'/');
748 if (lslash == newName) {
764 char *pfilter = strrchr(filter,
'.');
765 pfilter = pfilter ? pfilter+1 : filter;
769 if (!suffix || strcmp(suffix, pfilter) != 0) {
770 if (suffix && post_filter_change_HACK) {
771 if (suffix[-1] ==
'.') suffix[-1] = 0;
773 freeset(newName,
set_suffix(newName, pfilter));
779 if (strcmp(newName, fname) != 0) {
786 if (strchr(fname,
'*')) {
798 if (!avoid_multi_refresh) {
804 if (!avoid_multi_refresh) {
814 if (!avoid_multi_refresh) {
824 void File_selection::bind_callbacks() {
830 #define SELBOX_AUTOREFRESH_FREQUENCY 3000 // refresh every XXX ms
856 if (!autorefresh_info) {
863 install->
acbs = acbs;
867 autorefresh_info = install;
908 if (file[0] !=
'/') {
956 #define TEST_EXPECT_EQUAL_DUPPED(cs1, cs2) \
959 TEST_EXPECT_EQUAL(s1 = (cs1), s2 = (cs2)); \
964 void TEST_detectBrowserCommand() {
975 void TEST_path_unfolding() {
987 TEST_EXPECT_EQUAL_DUPPED(
AW_unfold_path(
"PWD",
"/usr"), strdup(
"/usr"));
989 TEST_EXPECT_EQUAL_DUPPED(
AW_unfold_path(
"ARB_NONEXISTING_ENVAR",
"."), strdup(currDir));
double allowed_duration() const
static int cmpBySize(const char *disp1, const char *disp2)
static bool avoid_multi_refresh
void sort(bool backward, bool case_sensitive)
bool contains_wildcards(const char *name)
static unsigned autorefresh_selboxes(AW_root *)
selbox_autorefresh_info * next
void AW_set_selected_fullname(AW_root *awr, const char *awar_prefix, const char *to_fullname)
return string(buffer, length)
static void dot(double **i, double **j, double **k)
const char * valid_path(const char *path)
void insert_default(const char *displayed, const AW_scalar &value)
bool not_seen_yet(const string &dir) const
GB_ULONG get_newest_dir_modtime() const
bool fileOrLink(const char *d)
int ARB_stricmp(const char *s1, const char *s2)
static void fileselection_filter_changed_cb(AW_root *, File_selection *cbs)
static void selbox_install_autorefresh(AW_root *aw_root, File_selection *acbs)
const char * GBS_global_string(const char *templat,...)
char * AW_get_selected_fullname(AW_root *awr, const char *awar_prefix)
char * GBS_string_eval(const char *insource, const char *icommand)
void cat(const char *from)
void add_timed_callback(int ms, const TimedCallback &tcb)
char * ARB_strpartdup(const char *start, const char *end)
static void show_soft_link(AW_selection_list *filelist, const char *envar, DuplicateLinkFilter &unDup)
NOT4PERL gb_getenv_hook GB_install_getenv_hook(gb_getenv_hook hook)
char buffer[MESSAGE_BUFFERSIZE]
GB_CSTR GB_canonical_path(const char *anypath)
GB_CSTR GB_getenvARBHOME(void)
AW_awar * add_callback(const RootCallback &cb)
static const char * detectBrowserCommand(const char *fname)
void insert(const char *displayed, const AW_scalar &value)
void register_directory(const string &dir)
static HelixNrInfo * start
void filename_changed(bool post_filter_change_HACK)
#define TEST_PUBLISH(testfunction)
const char * read_char_pntr() const
bool finished_in_time() const
unsigned long GB_time_of_file(const char *path)
const char * GBS_readable_size(unsigned long long size, const char *unit_suffix)
static selbox_autorefresh_info * autorefresh_info
static void error(const char *msg)
void AW_create_fileselection_awars(AW_root *awr, const char *awar_base, const char *directories, const char *filter, const char *file_name)
GB_CSTR GB_path_in_ARBHOME(const char *relative_path)
const char *(* gb_getenv_hook)(const char *varname)
bool AW_is_link(const char *path)
char * AW_unfold_path(const char *pwd_envar, const char *path)
static GB_CSTR expand_symbolic_directories(const char *pwd_envar)
char * read_string() const
AW_awar * awar_no_error(const char *awar)
end timer stuff
AW_awar * awar(const char *awar)
int entryType(const char *entry)
static void fileselection_filename_changed_cb(AW_root *, File_selection *cbs)
bool AW_is_dir(const char *path)
static char * set_suffix(const char *name, const char *suffix)
void AW_refresh_fileselection(AW_root *awr, const char *awar_prefix)
File_selection(AW_root *aw_root, const char *awar_prefix, const char *pwd_, DirDisplay disp_dirs, bool allow_wildcards)
void create_gui_elements(AW_window *aws, const char *at_prefix)
GB_CSTR GB_getenv(const char *env)
bool AW_is_file(const char *path)
GB_CSTR GB_concat_full_path(const char *anypath_left, const char *anypath_right)
void create_input_field(const char *awar_name, int columns=0)
#define TEST_EXPECT_NULL(n)
char * ARB_strndup(const char *start, int len)
bool GB_is_directory(const char *path)
const char * name_only(const char *fullpath)
static void fill_fileselection_cb(AW_root *, File_selection *cbs)
AW_selection_list * create_selection_list(const char *awar_name, int columns, int rows)
const char * ARB_strchrnul(const char *str, int chr)
bool at_ifdef(const char *id)
void aw_message(const char *msg)
const char * gotounit(const char *d)
void GB_split_full_path(const char *fullpath, char **res_dir, char **res_fullname, char **res_name_only, char **res_suffix)
bool GB_is_regularfile(const char *path)
void AW_create_fileselection(AW_window *aws, const char *awar_prefix, const char *at_prefix, const char *pwd, DirDisplay disp_dirs, bool allow_wildcards)
GB_ERROR write_string(const char *aw_string)
void GBT_split_string(ConstStrArray &dest, const char *namelist, const char *separator, SplitMode mode)
bool GB_is_link(const char *path)
const char * get_data() const
char * AW_extract_directory(const char *path)
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
static GB_CSTR get_suffix(GB_CSTR fullpath)
bool GBS_string_matches(const char *str, const char *expr, GB_CASE case_sens)
GB_CSTR GB_unfold_path(const char *pwd_envar, const char *path)
#define SELBOX_AUTOREFRESH_FREQUENCY
#define TEST_EXPECT_EQUAL(expr, want)
LimitedTime(double max_duration_seconds)
GB_ERROR GB_create_directory(const char *path)
char * GBS_global_string_copy(const char *templat,...)
void sortCustom(sellist_cmp_fun cmp)