diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/Fl.cxx | 4 | ||||
| -rw-r--r-- | src/Fl_Native_File_Chooser_GTK.cxx | 8 | ||||
| -rw-r--r-- | src/Fl_Native_File_Chooser_Kdialog.H | 2 | ||||
| -rw-r--r-- | src/Fl_Native_File_Chooser_Kdialog.cxx | 54 | ||||
| -rw-r--r-- | src/Fl_Native_File_Chooser_Zenity.H | 30 | ||||
| -rw-r--r-- | src/Fl_Native_File_Chooser_Zenity.cxx | 273 | ||||
| -rw-r--r-- | src/Makefile | 2 |
8 files changed, 95 insertions, 284 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f316d11de..43baa24d1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -212,13 +212,10 @@ if (FLTK_USE_X11 AND NOT OPTION_USE_WAYLAND) fl_dnd_x.cxx Fl_Native_File_Chooser_FLTK.cxx Fl_Native_File_Chooser_GTK.cxx + Fl_Native_File_Chooser_Zenity.cxx Fl_get_key.cxx ) - if (OPTION_USE_ZENITY) - set (DRIVER_FILES ${DRIVER_FILES} Fl_Native_File_Chooser_Zenity.cxx) - endif (OPTION_USE_ZENITY) - if (OPTION_USE_KDIALOG) set (DRIVER_FILES ${DRIVER_FILES} Fl_Native_File_Chooser_Kdialog.cxx) endif (OPTION_USE_KDIALOG) @@ -291,6 +288,7 @@ elseif (OPTION_USE_WAYLAND) Fl_Native_File_Chooser_FLTK.cxx Fl_Native_File_Chooser_GTK.cxx Fl_Native_File_Chooser_Kdialog.cxx + Fl_Native_File_Chooser_Zenity.cxx ) if (FLTK_USE_X11) list (APPEND DRIVER_FILES diff --git a/src/Fl.cxx b/src/Fl.cxx index 15eee143e..ee16805d9 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -1920,6 +1920,8 @@ bool Fl::option(Fl_Option opt) opt_prefs.get("ShowZoomFactor", tmp, 1); // default: on options_[OPTION_SHOW_SCALING] = tmp; + opt_prefs.get("UseZenity", tmp, 1); // default: on + options_[OPTION_FNFC_USES_ZENITY] = tmp; } { // next, check the user preferences // override system options only, if the option is set ( >= 0 ) @@ -1944,6 +1946,8 @@ bool Fl::option(Fl_Option opt) opt_prefs.get("ShowZoomFactor", tmp, -1); if (tmp >= 0) options_[OPTION_SHOW_SCALING] = tmp; + opt_prefs.get("UseZenity", tmp, -1); + if (tmp >= 0) options_[OPTION_FNFC_USES_ZENITY] = tmp; } { // now, if the developer has registered this app, we could ask for per-application preferences } diff --git a/src/Fl_Native_File_Chooser_GTK.cxx b/src/Fl_Native_File_Chooser_GTK.cxx index e41c4230f..98dbb5567 100644 --- a/src/Fl_Native_File_Chooser_GTK.cxx +++ b/src/Fl_Native_File_Chooser_GTK.cxx @@ -17,9 +17,7 @@ #include <config.h> #include <FL/Fl_Native_File_Chooser.H> -#if USE_ZENITY -# include "Fl_Native_File_Chooser_Zenity.H" -#endif +#include "Fl_Native_File_Chooser_Zenity.H" #if USE_KDIALOG # include "Fl_Native_File_Chooser_Kdialog.H" #endif @@ -934,8 +932,7 @@ Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) { platform_fnfc = NULL; fl_open_display(); if (Fl::option(Fl::OPTION_FNFC_USES_GTK)) { -#if USE_ZENITY - if (val != BROWSE_MULTI_DIRECTORY) { + if (Fl::option(Fl::OPTION_FNFC_USES_ZENITY)&& val != BROWSE_MULTI_DIRECTORY) { if (!Fl_Zenity_Native_File_Chooser_Driver::have_looked_for_zenity) { // First Time here, try to find zenity FILE *pipe = popen("zenity --version 2> /dev/null", "r"); @@ -950,7 +947,6 @@ Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) { // if we found zenity, we will use the Fl_Zenity_Native_File_Chooser_Driver if (Fl_Zenity_Native_File_Chooser_Driver::did_find_zenity) platform_fnfc = new Fl_Zenity_Native_File_Chooser_Driver(val); } -#endif // USE_ZENITY #if USE_KDIALOG const char *desktop = getenv("XDG_CURRENT_DESKTOP"); if (!platform_fnfc && desktop && strcmp(desktop, "KDE") == 0 && val != BROWSE_MULTI_DIRECTORY) { diff --git a/src/Fl_Native_File_Chooser_Kdialog.H b/src/Fl_Native_File_Chooser_Kdialog.H index 0463c9d58..c4f824b76 100644 --- a/src/Fl_Native_File_Chooser_Kdialog.H +++ b/src/Fl_Native_File_Chooser_Kdialog.H @@ -21,6 +21,7 @@ class Fl_Kdialog_Native_File_Chooser_Driver : public Fl_Native_File_Chooser_FLTK_Driver { friend class Fl_Native_File_Chooser; + friend class Fl_Zenity_Native_File_Chooser_Driver; struct fnfc_pipe_struct { char *all_files; int fd; @@ -38,6 +39,7 @@ class Fl_Kdialog_Native_File_Chooser_Driver : public Fl_Native_File_Chooser_FLTK int count() const; const char *filename() const; const char *filename(int i) const; + virtual char *build_command(); int show(); char *parse_filter(const char *f); const char *filter() const; diff --git a/src/Fl_Native_File_Chooser_Kdialog.cxx b/src/Fl_Native_File_Chooser_Kdialog.cxx index 3e86b021e..b61bed43e 100644 --- a/src/Fl_Native_File_Chooser_Kdialog.cxx +++ b/src/Fl_Native_File_Chooser_Kdialog.cxx @@ -67,31 +67,9 @@ static int fnfc_dispatch(int /*event*/, Fl_Window* /*win*/) { } -int Fl_Kdialog_Native_File_Chooser_Driver::show() { +char *Fl_Kdialog_Native_File_Chooser_Driver::build_command() { const char *option; switch (_btype) { - case Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY: { - // BROWSE_MULTI_DIRECTORY is not supported by kdialog, run GTK chooser instead - Fl_Native_File_Chooser fnfc(Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY); - fnfc.title( title() ); - fnfc.directory(directory()); - fnfc.preset_file(preset_file()); - fnfc.filter(filter()); - fnfc.options(options()); - int retval = fnfc.show(); - for (int i = 0; i < _tpathnames; i++) delete[] _pathnames[i]; - delete[] _pathnames; _pathnames = NULL; - _tpathnames = fnfc.count(); - if (_tpathnames && retval == 0) { - _pathnames = new char*[_tpathnames]; - for (int i = 0; i < _tpathnames; i++) { - _pathnames[i] = new char[strlen(fnfc.filename(i))+1]; - strcpy(_pathnames[i], fnfc.filename(i)); - } - } - return retval; - } - break; case Fl_Native_File_Chooser::BROWSE_DIRECTORY: option = "--getexistingdirectory"; break; @@ -126,6 +104,34 @@ int Fl_Kdialog_Native_File_Chooser_Driver::show() { " \"%s\" ", _parsedfilt); } strcat(command, "2> /dev/null"); // get rid of stderr output + return command; +} + + +int Fl_Kdialog_Native_File_Chooser_Driver::show() { + if (_btype == Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY) { + // BROWSE_MULTI_DIRECTORY is not supported by kdialog, run GTK chooser instead + Fl_Native_File_Chooser fnfc(Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY); + fnfc.title( title() ); + fnfc.directory(directory()); + fnfc.preset_file(preset_file()); + fnfc.filter(filter()); + fnfc.options(options()); + int retval = fnfc.show(); + for (int i = 0; i < _tpathnames; i++) delete[] _pathnames[i]; + delete[] _pathnames; _pathnames = NULL; + _tpathnames = fnfc.count(); + if (_tpathnames && retval == 0) { + _pathnames = new char*[_tpathnames]; + for (int i = 0; i < _tpathnames; i++) { + _pathnames[i] = new char[strlen(fnfc.filename(i))+1]; + strcpy(_pathnames[i], fnfc.filename(i)); + } + } + return retval; + } + + char *command = build_command(); //puts(command); FILE *pipe = popen(command, "r"); fnfc_pipe_struct data; @@ -243,7 +249,7 @@ void Fl_Kdialog_Native_File_Chooser_Driver::filter(const char *f) { while (part) { char *p = parse_filter(part); _parsedfilt = strapp(_parsedfilt, p); - _parsedfilt = strapp(_parsedfilt, "\\n"); + _parsedfilt = strapp(_parsedfilt, "\n"); delete[] p; _nfilters++; part = strtok_r(NULL, "\n", &ptr); diff --git a/src/Fl_Native_File_Chooser_Zenity.H b/src/Fl_Native_File_Chooser_Zenity.H index 90614bb4f..bdaa5ba20 100644 --- a/src/Fl_Native_File_Chooser_Zenity.H +++ b/src/Fl_Native_File_Chooser_Zenity.H @@ -17,38 +17,14 @@ #ifndef FL_ZENITY_NATIVE_FILE_CHOOSER_H #define FL_ZENITY_NATIVE_FILE_CHOOSER_H 1 -#include <FL/Fl_Native_File_Chooser.H> +#include "Fl_Native_File_Chooser_Kdialog.H" -class FL_EXPORT Fl_Zenity_Native_File_Chooser_Driver : public Fl_Native_File_Chooser_FLTK_Driver { +class Fl_Zenity_Native_File_Chooser_Driver : public Fl_Kdialog_Native_File_Chooser_Driver { friend class Fl_Native_File_Chooser; - struct fnfc_pipe_struct { - char *all_files; - int fd; - }; - static void fnfc_fd_cb(int fd, fnfc_pipe_struct *data); - char **_pathnames; - int _tpathnames; - char *_directory; - char *_preset_file; - char *_title; static bool did_find_zenity; static bool have_looked_for_zenity; Fl_Zenity_Native_File_Chooser_Driver(int val); - ~Fl_Zenity_Native_File_Chooser_Driver(); - int count() const; - const char *filename() const; - const char *filename(int i) const; - int show(); - char *parse_filter(const char *f); - const char *filter() const; - virtual void filter(const char *f); - int filters() const; - void preset_file(const char *val); - const char *preset_file() const; - void directory(const char *val); - const char *directory() const; - void title(const char *val); - const char *title() const; + virtual char *build_command(); }; #endif // FL_ZENITY_NATIVE_FILE_CHOOSER_H diff --git a/src/Fl_Native_File_Chooser_Zenity.cxx b/src/Fl_Native_File_Chooser_Zenity.cxx index 2699d2b27..9d79e628c 100644 --- a/src/Fl_Native_File_Chooser_Zenity.cxx +++ b/src/Fl_Native_File_Chooser_Zenity.cxx @@ -15,90 +15,36 @@ // #include <config.h> -#include <FL/Fl_Native_File_Chooser.H> #include "Fl_Native_File_Chooser_Zenity.H" -#include "Fl_Window_Driver.H" -#include "drivers/Unix/Fl_Unix_System_Driver.H" #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> -/* Fl_Zenity_Native_File_Chooser_Driver : file chooser based on the "zenity" command */ +// Fl_Zenity_Native_File_Chooser_Driver : file chooser based on the "zenity" command bool Fl_Zenity_Native_File_Chooser_Driver::did_find_zenity = false; 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_Native_File_Chooser_FLTK_Driver(val) { - _tpathnames = 0; - _pathnames = NULL; - _directory = NULL; - _preset_file = NULL; - _title = NULL; +Fl_Zenity_Native_File_Chooser_Driver::Fl_Zenity_Native_File_Chooser_Driver(int val) : Fl_Kdialog_Native_File_Chooser_Driver(val) { } -Fl_Zenity_Native_File_Chooser_Driver::~Fl_Zenity_Native_File_Chooser_Driver() { - for (int i = 0; i < _tpathnames; i++) delete[] _pathnames[i]; - delete[] _pathnames; - if (_preset_file) free(_preset_file); - if (_directory) free(_directory); - if (_title) free(_title); -} - - -void Fl_Zenity_Native_File_Chooser_Driver::fnfc_fd_cb(int fd, - Fl_Zenity_Native_File_Chooser_Driver::fnfc_pipe_struct *data) { - char tmp[FL_PATH_MAX]; - int l = read(fd, tmp, sizeof(tmp)-1); - if (l > 0) { - tmp[l] = 0; - data->all_files = Fl_Native_File_Chooser_Driver::strapp(data->all_files, tmp); - } else { - data->fd = -1; - } -} - - -static int fnfc_dispatch(int /*event*/, Fl_Window* /*win*/) { - return 0; -} - - -int Fl_Zenity_Native_File_Chooser_Driver::show() { +char *Fl_Zenity_Native_File_Chooser_Driver::build_command() { const char *option; + int l; switch (_btype) { - case Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY: { - // BROWSE_MULTI_DIRECTORY is not supported by zenity, run other chooser instead - Fl_Native_File_Chooser fnfc(Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY); - fnfc.title( title() ); - fnfc.directory(directory()); - fnfc.preset_file(preset_file()); - fnfc.filter(filter()); - fnfc.options(options()); - int retval = fnfc.show(); - for (int i = 0; i < _tpathnames; i++) delete[] _pathnames[i]; - delete[] _pathnames; _pathnames = NULL; - _tpathnames = fnfc.count(); - if (_tpathnames && retval == 0) { - _pathnames = new char*[_tpathnames]; - for (int i = 0; i < _tpathnames; i++) { - _pathnames[i] = new char[strlen(fnfc.filename(i))+1]; - strcpy(_pathnames[i], fnfc.filename(i)); - } - } - return retval; - } - break; case Fl_Native_File_Chooser::BROWSE_DIRECTORY: case Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY: option = "--file-selection --directory"; break; case Fl_Native_File_Chooser::BROWSE_SAVE_FILE: - option = "--file-selection --save"; + if (options() & Fl_Native_File_Chooser::SAVEAS_CONFIRM) + option = "--file-selection --save --confirm-overwrite"; + else + option = "--file-selection --save"; break; case Fl_Native_File_Chooser::BROWSE_MULTI_FILE: @@ -110,176 +56,57 @@ int Fl_Zenity_Native_File_Chooser_Driver::show() { } char *preset = NULL; if (_preset_file) { - preset = new char[strlen(_preset_file) + 15]; - sprintf(preset, "--filename '%s'", _preset_file); + l = strlen(_preset_file) + 15; + preset = new char[l]; + snprintf(preset, l, "--filename='%s'", _preset_file); } else if (_directory) { // This doesn't actually seem to do anything, but supply it anyway. - preset = new char[strlen(_directory) + 15]; - sprintf(preset, "--filename '%s'", _directory); + l = strlen(_directory) + 15; + preset = new char[l]; + snprintf(preset, l, "--filename '%s'", _directory); } - char *command = new char[strlen(option) + strlen(preset) + (_title?strlen(_title)+11:0) + - (_parsedfilt?strlen(_parsedfilt):0) + 50]; + int lcommand = 1000; + char *command = new char[lcommand]; strcpy(command, "zenity "); if (_title) { - sprintf(command+strlen(command), " --title '%s'", _title); + l = strlen(command); + snprintf(command+l, lcommand-l, " --title '%s'", _title); } - sprintf(command+strlen(command), " %s %s ", option, preset ? preset : ""); + l = strlen(command); + snprintf(command+l, lcommand-l, " %s %s ", option, preset ? preset : ""); delete[] preset; - if (_parsedfilt) sprintf(command+strlen(command), " \"%s\" ", _parsedfilt); - strcat(command, "2> /dev/null"); // get rid of stderr output -//puts(command); - FILE *pipe = popen(command, "r"); - fnfc_pipe_struct data; - data.all_files = NULL; - if (pipe) { - data.fd = fileno(pipe); - Fl::add_fd(data.fd, FL_READ, (Fl_FD_Handler)fnfc_fd_cb, &data); - Fl_Event_Dispatch old_dispatch = Fl::event_dispatch(); - // prevent FLTK from processing any event - Fl::event_dispatch(fnfc_dispatch); - void *control = ((Fl_Unix_System_Driver*)Fl::system_driver())->control_maximize_button(NULL); - // run event loop until pipe finishes - while (data.fd >= 0) Fl::wait(); - Fl::remove_fd(fileno(pipe)); - pclose(pipe); - // return to previous event processing by FLTK - Fl::event_dispatch(old_dispatch); - if (control) ((Fl_Unix_System_Driver*)Fl::system_driver())->control_maximize_button(control); - if (data.all_files) { - // process text received from pipe - if (data.all_files[strlen(data.all_files)-1] == '\n') data.all_files[strlen(data.all_files)-1] = 0; - for (int i = 0; i < _tpathnames; i++) delete[] _pathnames[i]; - delete[] _pathnames; - char *p = data.all_files; - int count = 1; - while ((p = strchr(p+1, ' '))) count++; - _pathnames = new char*[count]; - _tpathnames = 0; - char *q = strtok(data.all_files, " "); - while (q) { - _pathnames[_tpathnames] = new char[strlen(q)+1]; - strcpy(_pathnames[_tpathnames], q); - _tpathnames++; - q = strtok(NULL, " "); + if (_parsedfilt) { + char *p = strtok(_parsedfilt, "\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"); } } - delete[] command; - if (_title) { free(_title); _title = NULL; } - if (!pipe) return -1; - return (data.all_files == NULL ? 1 : 0); -} - - -const char *Fl_Zenity_Native_File_Chooser_Driver::filename() const { - return _tpathnames >= 1 ? _pathnames[0] : NULL; -} - -const char *Fl_Zenity_Native_File_Chooser_Driver::filename (int i) const { - return _tpathnames > i ? _pathnames[i] : NULL; -} - -const char *Fl_Zenity_Native_File_Chooser_Driver::filter() const { - return _filter; -} - -int Fl_Zenity_Native_File_Chooser_Driver::filters() const { - return (_nfilters ? _nfilters - 1 : 0); -} - -int Fl_Zenity_Native_File_Chooser_Driver::count() const { - return _tpathnames; -} - -char *Fl_Zenity_Native_File_Chooser_Driver::parse_filter(const char *f) { - //In: "*.H\n" or "*.H" Out: "(*.H)" - //In: "Headers\t*.H\n" Out: "Headers (*.H)" - //In: "Headers\t*.{H,h}\n" Out: "Headers (*.H *.h)" - const char *p = strchr(f, '\t'); - if (!p) p = f - 1; - const char *q = strchr(f, '\n'); if (!q) q = f + strlen(f); - const char *r = strchr(f, '{'); - char *developed = NULL; - if (r) { // with {} - char *lead = new char[r-p]; - memcpy(lead, p+1, (r-p)-1); lead[(r-p)-1] = 0; - const char *r2 = strchr(r, '}'); - char *ends = new char[r2-r]; - memcpy(ends, r+1, (r2-r)-1); ends[(r2-r)-1] = 0; - char *ptr; - char *part = strtok_r(ends, ",", &ptr); - while (part) { - developed = strapp(developed, lead); - developed = strapp(developed, part); - developed = strapp(developed, " "); - part = strtok_r(NULL, ",", &ptr); - } - if (developed[strlen(developed)-1] == ' ') developed[strlen(developed)-1] = 0; - delete[] lead; - delete[] ends; - } - int lout = (p>f?p-f:0) + 2 + (r?strlen(developed):((q-p)-1)) + 2; - char *out = new char[lout]; *out = 0; - if (p > f) {memcpy(out, f, p-f); out[p-f] = 0; } - strcat(out, " ("); - if (r) { - strcpy(out+strlen(out), developed); - strfree(developed); - } - else memcpy(out+strlen(out), p+1, (q-p)); - strcat(out, ")"); -//puts(out); - return out; -} - - -void Fl_Zenity_Native_File_Chooser_Driver::filter(const char *f) { - _parsedfilt = strfree(_parsedfilt); // clear previous parsed filter (if any) - _nfilters = 0; - if (!f) return; - _filter = strdup(f); - char *f2 = strdup(f); - char *ptr; - char *part = strtok_r(f2, "\n", &ptr); - while (part) { - char *p = parse_filter(part); - _parsedfilt = strapp(_parsedfilt, p); - _parsedfilt = strapp(_parsedfilt, "\\n"); - delete[] p; - _nfilters++; - part = strtok_r(NULL, "\n", &ptr); - } - free(f2); - _parsedfilt = strapp(_parsedfilt, "All files (*)"); - _nfilters++; -//puts(_parsedfilt); -} - -void Fl_Zenity_Native_File_Chooser_Driver::preset_file(const char *val) { - if (_preset_file) free(_preset_file); - _preset_file = strdup(val); -} - -const char *Fl_Zenity_Native_File_Chooser_Driver::preset_file() const { - return _preset_file; -} - -void Fl_Zenity_Native_File_Chooser_Driver::directory(const char *val) { - if (_directory) free(_directory); - _directory = strdup(val); -} - -const char *Fl_Zenity_Native_File_Chooser_Driver::directory() const { - return _directory; -} - -void Fl_Zenity_Native_File_Chooser_Driver::title(const char *val) -{ - if (_title) free(_title); - _title = strdup(val); -} - -const char *Fl_Zenity_Native_File_Chooser_Driver::title() const { - return _title; + strcat(command, " 2> /dev/null"); // get rid of stderr output +//puts(command); + return command; } diff --git a/src/Makefile b/src/Makefile index d8640f2b5..819cd7b9b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -277,6 +277,7 @@ XLIBCPPFILES = \ Fl_Native_File_Chooser_FLTK.cxx \ Fl_Native_File_Chooser_GTK.cxx\ Fl_Native_File_Chooser_Kdialog.cxx \ + Fl_Native_File_Chooser_Zenity.cxx \ Fl_get_key.cxx # These graphics driver files are used under condition: BUILD_CAIRO @@ -299,6 +300,7 @@ WLCPPFILES = \ Fl_Native_File_Chooser_FLTK.cxx \ Fl_Native_File_Chooser_GTK.cxx \ Fl_Native_File_Chooser_Kdialog.cxx \ + Fl_Native_File_Chooser_Zenity.cxx \ drivers/Posix/Fl_Posix_System_Driver.cxx \ drivers/Unix/Fl_Unix_System_Driver.cxx \ drivers/Unix/Fl_Unix_Screen_Driver.cxx \ |
