summaryrefslogtreecommitdiff
path: root/src/Fl_Native_File_Chooser_Zenity.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Fl_Native_File_Chooser_Zenity.cxx')
-rw-r--r--src/Fl_Native_File_Chooser_Zenity.cxx273
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;
}