// // FLTK native file chooser widget : Zenity version // // Copyright 2021-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this // file is missing or damaged, see the license at: // // https://www.fltk.org/COPYING.php // // Please see the following page on how to report bugs and issues: // // https://www.fltk.org/bugs.php // /** \cond DriverDev \addtogroup DriverDeveloper \{ */ #include #include "Fl_Native_File_Chooser_Zenity.H" #include #include #include // 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_Kdialog_Native_File_Chooser_Driver(val) { } void Fl_Zenity_Native_File_Chooser_Driver::append_filter(char *ret_command, int *pos, int maxlen) { 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 = (int)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]; char *q; for (q = ob+1; q < cb; q++) { strcpy(aux, op+1); int la = (int)strlen(aux); aux[la++] = *q; if (cb < cp-1) { strcpy(aux+la, cb+1); la += (int)strlen(cb+1); } aux[la] = 0; l = (int)strlen(command); snprintf(command+l, lcommand-l, " %s", aux); } strcat(command, "'"); } else { l = (int)strlen(command); snprintf(command+l, lcommand-l, "%s'", op+1); } p = strtok(NULL, "\n"); } free(parsed_filter_copy); // append to ret_command *pos += snprintf(ret_command + *pos, maxlen - *pos, "%s", command); delete [] command; } void Fl_Zenity_Native_File_Chooser_Driver::build_command(char *command, int maxlen) { const char *option; switch (_btype) { 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: 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: option = "--file-selection --multiple --separator='\n'"; break; default: option = "--file-selection"; } // Build preset char preset[FL_PATH_MAX * 2] = ""; if (_preset_file) { char quoted_filename[FL_PATH_MAX]; shell_quote(_preset_file, quoted_filename, sizeof(quoted_filename)); snprintf(preset, sizeof(preset), "--filename=%s", quoted_filename); } else if (_directory) { // This doesn't actually seem to do anything, but supply it anyway. char quoted_dir[FL_PATH_MAX]; shell_quote(_directory, quoted_dir, sizeof(quoted_dir)); snprintf(preset, sizeof(preset), "--filename=%s", quoted_dir); } // Build command int pos = 0; pos += snprintf(command + pos, maxlen - pos, "zenity"); if (_title) { char quoted_title[FL_PATH_MAX]; shell_quote(_title, quoted_title, sizeof(quoted_title)); pos += snprintf(command + pos, maxlen - pos, " --title %s", quoted_title); } pos += snprintf(command + pos, maxlen - pos, " %s", option); if (preset[0]) { pos += snprintf(command + pos, maxlen - pos, " %s", preset); } if (_parsedfilt) append_filter(command, &pos, maxlen); snprintf(command + pos, maxlen - pos, " 2> /dev/null"); //printf("command = %s\n", command); } /** \} \endcond */