diff options
| -rw-r--r-- | src/Fl_Native_File_Chooser_Kdialog.H | 4 | ||||
| -rw-r--r-- | src/Fl_Native_File_Chooser_Kdialog.cxx | 55 | ||||
| -rw-r--r-- | src/Fl_Native_File_Chooser_Zenity.H | 3 | ||||
| -rw-r--r-- | src/Fl_Native_File_Chooser_Zenity.cxx | 117 |
4 files changed, 105 insertions, 74 deletions
diff --git a/src/Fl_Native_File_Chooser_Kdialog.H b/src/Fl_Native_File_Chooser_Kdialog.H index f65445fb3..8b50b36fa 100644 --- a/src/Fl_Native_File_Chooser_Kdialog.H +++ b/src/Fl_Native_File_Chooser_Kdialog.H @@ -24,6 +24,7 @@ */ #include <FL/Fl_Native_File_Chooser.H> +#include "Fl_String.H" class Fl_Kdialog_Native_File_Chooser_Driver : public Fl_Native_File_Chooser_FLTK_Driver { friend class Fl_Native_File_Chooser; @@ -45,7 +46,7 @@ class Fl_Kdialog_Native_File_Chooser_Driver : public Fl_Native_File_Chooser_FLTK int count() const FL_OVERRIDE; const char *filename() const FL_OVERRIDE; const char *filename(int i) const FL_OVERRIDE; - virtual char *build_command(); + virtual void build_command(Fl_String& command); int show() FL_OVERRIDE; char *parse_filter(const char *f); const char *filter() const FL_OVERRIDE; @@ -57,6 +58,7 @@ class Fl_Kdialog_Native_File_Chooser_Driver : public Fl_Native_File_Chooser_FLTK const char *directory() const FL_OVERRIDE; void title(const char *val) FL_OVERRIDE; const char *title() const FL_OVERRIDE; + void shell_quote(Fl_String& s); }; /** diff --git a/src/Fl_Native_File_Chooser_Kdialog.cxx b/src/Fl_Native_File_Chooser_Kdialog.cxx index 72bb6ce18..1fa322c98 100644 --- a/src/Fl_Native_File_Chooser_Kdialog.cxx +++ b/src/Fl_Native_File_Chooser_Kdialog.cxx @@ -30,7 +30,6 @@ #include <string.h> #include <unistd.h> - /* Fl_Kdialog_Native_File_Chooser_Driver : file chooser based on the "kdialog" command */ bool Fl_Kdialog_Native_File_Chooser_Driver::did_find_kdialog = false; @@ -73,7 +72,7 @@ static int fnfc_dispatch(int /*event*/, Fl_Window* /*win*/) { } -char *Fl_Kdialog_Native_File_Chooser_Driver::build_command() { +void Fl_Kdialog_Native_File_Chooser_Driver::build_command(Fl_String& command) { const char *option; switch (_btype) { case Fl_Native_File_Chooser::BROWSE_DIRECTORY: @@ -92,25 +91,30 @@ char *Fl_Kdialog_Native_File_Chooser_Driver::build_command() { default: option = "--getopenfilename"; } + + // Build preset const char *preset = "."; - if (_preset_file) preset = _preset_file; + if (_preset_file) preset = _preset_file; else if (_directory) preset = _directory; - const int com_size = strlen(option) + strlen(preset) + - (_title?strlen(_title)+11:0) + (_parsedfilt?strlen(_parsedfilt):0) + 50; - char *command = new char[com_size]; - strcpy(command, "kdialog "); + + // Build command + command = "kdialog"; if (_title) { - snprintf(command+strlen(command), com_size - strlen(command), - " --title '%s'", _title); + Fl_String quoted_title = _title; shell_quote(quoted_title); + command += " --title "; + command += quoted_title; } - snprintf(command+strlen(command), com_size - strlen(command), - " %s %s ", option, preset); + command += " "; + command += option; + command += " "; + command += preset; if (_parsedfilt) { - snprintf(command+strlen(command), com_size - strlen(command), - " \"%s\" ", _parsedfilt); + Fl_String quoted_filt = _parsedfilt; shell_quote(quoted_filt); // NOTE: orig code used double quoting -erco 1/10/24 + command += " "; + command += quoted_filt; } - strcat(command, "2> /dev/null"); // get rid of stderr output - return command; + command += " 2> /dev/null"; // get rid of stderr + //printf("command = %s\n", command.c_str()); } @@ -137,9 +141,10 @@ int Fl_Kdialog_Native_File_Chooser_Driver::show() { return retval; } - char *command = build_command(); -//puts(command); - FILE *pipe = popen(command, "r"); + Fl_String command; + build_command(command); + fprintf(stderr, "DEBUG: POPEN: %s\n", command.c_str()); + FILE *pipe = popen(command.c_str(), "r"); fnfc_pipe_struct data; data.all_files = NULL; if (pipe) { @@ -175,7 +180,6 @@ int Fl_Kdialog_Native_File_Chooser_Driver::show() { } } } - delete[] command; if (!pipe) return -1; return (data.all_files == NULL ? 1 : 0); } @@ -298,6 +302,19 @@ const char *Fl_Kdialog_Native_File_Chooser_Driver::title() const { return _title; } +// Add shell quotes around string 's'. +// Handles quoting embedded quotes. +// +void Fl_Kdialog_Native_File_Chooser_Driver::shell_quote(Fl_String& s) { + Fl_String out = "'"; // leading quote + for (int t=0; t<s.size(); t++) { + if (s[t] == '\'') out += "'\"'\"'"; // quote any quotes + else out += s[t]; + } + out += "'"; // trailing quote + s = out; +} + /** \} \endcond diff --git a/src/Fl_Native_File_Chooser_Zenity.H b/src/Fl_Native_File_Chooser_Zenity.H index 56b12ed29..790180378 100644 --- a/src/Fl_Native_File_Chooser_Zenity.H +++ b/src/Fl_Native_File_Chooser_Zenity.H @@ -30,7 +30,8 @@ class Fl_Zenity_Native_File_Chooser_Driver : public Fl_Kdialog_Native_File_Choos static bool did_find_zenity; static bool have_looked_for_zenity; Fl_Zenity_Native_File_Chooser_Driver(int val); - char *build_command() FL_OVERRIDE; + void append_filter(Fl_String& command); + void build_command(Fl_String& command) FL_OVERRIDE; }; /** diff --git a/src/Fl_Native_File_Chooser_Zenity.cxx b/src/Fl_Native_File_Chooser_Zenity.cxx index aa967bfb0..908e68cda 100644 --- a/src/Fl_Native_File_Chooser_Zenity.cxx +++ b/src/Fl_Native_File_Chooser_Zenity.cxx @@ -36,10 +36,48 @@ bool Fl_Zenity_Native_File_Chooser_Driver::have_looked_for_zenity = false; Fl_Zenity_Native_File_Chooser_Driver::Fl_Zenity_Native_File_Chooser_Driver(int val) : Fl_Kdialog_Native_File_Chooser_Driver(val) { } +void Fl_Zenity_Native_File_Chooser_Driver::append_filter(Fl_String& ret_command) { + // TODO: This could probably be simplified + toughened with Fl_String -erco 1/10/24 + int l; + int lcommand = 10000; + char *command = new char[lcommand]; + command[0] = 0; + char *parsed_filter_copy = strdup(_parsedfilt); // keep _parsedfilt unchanged for re-use + char *p = strtok(parsed_filter_copy, "\n"); + while (p) { + char *op = strchr(p, '('); + l = strlen(command); + snprintf(command+l, lcommand-l, " --file-filter='%s|", p); + char *cp = strchr(p, ')'); + *cp = 0; + char *ob = strchr(op+1, '['); + if (ob) { // process [xyz] patterns + *ob = 0; + char *cb = strchr(ob+1, ']'); + char aux[100]; + for (char *q = ob+1; q < cb; q++) { + strcpy(aux, op+1); + int la = strlen(aux); + aux[la++] = *q; + if (cb < cp-1) { strcpy(aux+la, cb+1); la += strlen(cb+1); } + aux[la] = 0; + l = strlen(command); + snprintf(command+l, lcommand-l, " %s", aux); + } + strcat(command, "'"); + } else { + l = strlen(command); + snprintf(command+l, lcommand-l, "%s'", op+1); + } + p = strtok(NULL, "\n"); + } + free(parsed_filter_copy); + ret_command += command; // append to parent's Fl_String + delete [] command; +} -char *Fl_Zenity_Native_File_Chooser_Driver::build_command() { +void Fl_Zenity_Native_File_Chooser_Driver::build_command(Fl_String& command) { const char *option; - int l; switch (_btype) { case Fl_Native_File_Chooser::BROWSE_DIRECTORY: case Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY: @@ -60,63 +98,36 @@ char *Fl_Zenity_Native_File_Chooser_Driver::build_command() { default: option = "--file-selection"; } - char *preset = NULL; + + // Build preset + Fl_String preset; if (_preset_file) { - l = strlen(_preset_file) + 15; - preset = new char[l]; - snprintf(preset, l, "--filename='%s'", _preset_file); - } - else if (_directory) { + Fl_String quoted_filename = _preset_file; shell_quote(quoted_filename); + preset = "--filename="; + preset += quoted_filename; + } else if (_directory) { // This doesn't actually seem to do anything, but supply it anyway. - l = strlen(_directory) + 15; - preset = new char[l]; - snprintf(preset, l, "--filename '%s'", _directory); + Fl_String quoted_dir = _directory; shell_quote(quoted_dir); + preset = "--filename="; + preset += quoted_dir; } - int lcommand = 10000; - char *command = new char[lcommand]; - strcpy(command, "zenity "); + + // Build command + command = "zenity"; if (_title) { - l = strlen(command); - snprintf(command+l, lcommand-l, " --title '%s'", _title); + Fl_String quoted_title = _title; shell_quote(quoted_title); + command += " --title "; + command += quoted_title; } - l = strlen(command); - snprintf(command+l, lcommand-l, " %s %s ", option, preset ? preset : ""); - delete[] preset; - if (_parsedfilt) { - char *parsed_filter_copy = strdup(_parsedfilt); // keep _parsedfilt unchanged for re-use - char *p = strtok(parsed_filter_copy, "\n"); - while (p) { - char *op = strchr(p, '('); - l = strlen(command); - snprintf(command+l, lcommand-l, " --file-filter='%s|", p); - char *cp = strchr(p, ')'); - *cp = 0; - char *ob = strchr(op+1, '['); - if (ob) { // process [xyz] patterns - *ob = 0; - char *cb = strchr(ob+1, ']'); - char aux[100]; - for (char *q = ob+1; q < cb; q++) { - strcpy(aux, op+1); - int la = strlen(aux); - aux[la++] = *q; - if (cb < cp-1) { strcpy(aux+la, cb+1); la += strlen(cb+1); } - aux[la] = 0; - l = strlen(command); - snprintf(command+l, lcommand-l, " %s", aux); - } - strcat(command, "'"); - } else { - l = strlen(command); - snprintf(command+l, lcommand-l, "%s'", op+1); - } - p = strtok(NULL, "\n"); - } - free(parsed_filter_copy); + command += " "; + command += option; + if (preset != "") { + command += " "; + command += preset; } - strcat(command, " 2> /dev/null"); // get rid of stderr output -//puts(command); - return command; + if (_parsedfilt) append_filter(command); + command += " 2> /dev/null"; // get rid of stderr + //printf("command = %s\n", command.c_str()); } /** |
