diff options
Diffstat (limited to 'src/Fl_Native_File_Chooser_Zenity.cxx')
| -rw-r--r-- | src/Fl_Native_File_Chooser_Zenity.cxx | 273 |
1 files changed, 50 insertions, 223 deletions
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; } |
