Derive Fl_Zenity_Native_File_Chooser_Driver from Fl_Kdialog_Native_…

Also add Fl::option(OPTION_FNFC_USES_ZENITY)
This commit is contained in:
ManoloFLTK 2022-12-13 18:37:48 +01:00
parent 576271fb04
commit 41f37613ec
16 changed files with 196 additions and 332 deletions

View File

@ -829,15 +829,6 @@ if (OPTION_FILESYSTEM_SUPPORT)
endif (OPTION_FILESYSTEM_SUPPORT)
#######################################################################
#######################################################################
option (OPTION_USE_ZENITY "Fl_Native_File_Chooser may run zenity" ON)
if (OPTION_USE_ZENITY)
set (USE_ZENITY 1)
else ()
set (USE_ZENITY 0)
endif (OPTION_USE_ZENITY)
#######################################################################
#######################################################################
option (OPTION_USE_KDIALOG "Fl_Native_File_Chooser may run kdialog" ON)
if (OPTION_USE_KDIALOG)

View File

@ -272,6 +272,9 @@ public:
/// value.
/// When switched off, no such window gets displayed.
OPTION_SHOW_SCALING,
/// Meaningful for the Wayland/X11 platform only. When switched on (default), the library uses a Zenity-based file dialog.
/// When switched off, the GTK file dialog is used instead.
OPTION_FNFC_USES_ZENITY,
// don't change this, leave it always as the last element
/// For internal use only.
OPTION_LAST

View File

@ -102,15 +102,23 @@ class Fl_Native_File_Chooser_Driver;
to open files with a non-ASCII name).
<B>Platform Specific Caveats</B>
- Under X windows, and if Fl::OPTION_FNFC_USES_GTK has not been switched off,
the widget attempts to use standard GTK file chooser dialogs if they are
available at run-time on the platform, and falls back to use FLTK's Fl_File_Chooser if they are not.
In the first case, calling fl_register_images() adds a "Preview" button to the GTK chooser dialog.
In the latter case, it's best if you call Fl_File_Icon::load_system_icons()
- Under X11/Wayland, what dialog opens is determined as follows:
-# If command \p zenity is available at run-time and if \p Fl::option(OPTION_FNFC_USES_ZENITY) is
not turned off, the \p zenity -based dialog opens. This is expected to be more appropriate
than other dialog forms for sandboxed apps.
-# Else if the app runs under the KDE desktop and if command \p kdialog is available at run-time
and if the library was not built with <tt>cmake -DOPTION_USE_KDIALOG=Off</tt>, the
\p kdialog -based dialog opens.
-# Else if the GTK library is available at run-time on the computer and if \p Fl::option(OPTION_FNFC_USES_GTK) is
not turned off, the GTK-styled dialog opens. Call fl_register_images() to add a "Preview" button to this dialog.
Use the static public attributes of class Fl_File_Chooser to localize the browser.
-# Otherwise, FLTK's own dialog produced by the Fl_File_Chooser class opens.
Call fl_register_images() to add a "Preview" button to it.
It's best if you also call Fl_File_Icon::load_system_icons()
at the start of main(), to enable the nicer looking file browser widgets.
Use the static public attributes of class Fl_File_Chooser to localize
the browser.
Use the static public attributes of class Fl_File_Chooser to localize the browser.
- Some operating systems support certain OS specific options; see
Fl_Native_File_Chooser::options() for a list.

View File

@ -342,12 +342,6 @@
#cmakedefine FL_CFG_NO_FILESYSTEM_SUPPORT 1
/*
* Do we want class Fl_Native_File_Chooser to run zenity when available?
*/
#cmakedefine01 USE_ZENITY
/*
* Do we want class Fl_Native_File_Chooser to run kdialog when zenity is
* unavailable and desktop is KDE?

View File

@ -342,12 +342,6 @@
#undef FL_CFG_NO_FILESYSTEM_SUPPORT
/*
* Do we want class Fl_Native_File_Chooser to run zenity if available?
*/
#define USE_ZENITY 1
/*
* Do we want class Fl_Native_File_Chooser to run kdialog when zenity is
* unavailable and desktop is KDE?

View File

@ -633,6 +633,7 @@ static void refreshUI() {
wGTKText->value(opt[Fl::OPTION_FNFC_USES_GTK][mode]);
wPrintGTKText->value(opt[Fl::OPTION_PRINTER_USES_GTK][mode]);
wShowZoomFactor->value(opt[Fl::OPTION_SHOW_SCALING][mode]);
wUseZenity->value(opt[Fl::OPTION_FNFC_USES_ZENITY][mode]);
}
/**
@ -650,6 +651,7 @@ static void readPrefs() {
opt_prefs.get("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK ][1], 2);
opt_prefs.get("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK ][1], 2);
opt_prefs.get("ShowZoomFactor", opt[Fl::OPTION_SHOW_SCALING ][1], 2);
opt_prefs.get("UseZenity", opt[Fl::OPTION_FNFC_USES_ZENITY ][1], 2);
}
{
Fl_Preferences prefs(Fl_Preferences::USER_L, "fltk.org", "fltk");
@ -661,6 +663,7 @@ static void readPrefs() {
opt_prefs.get("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK ][0], 2);
opt_prefs.get("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK ][0], 2);
opt_prefs.get("ShowZoomFactor", opt[Fl::OPTION_SHOW_SCALING ][0], 2);
opt_prefs.get("UseZenity", opt[Fl::OPTION_FNFC_USES_ZENITY ][0], 2);
}
refreshUI();
}
@ -687,6 +690,8 @@ static void writePrefs() {
else opt_prefs.set("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK][1]);
if (opt[Fl::OPTION_SHOW_SCALING][1]==2) opt_prefs.deleteEntry("ShowZoomFactor");
else opt_prefs.set("ShowZoomFactor", opt[Fl::OPTION_SHOW_SCALING][1]);
if (opt[Fl::OPTION_FNFC_USES_ZENITY][1]==2) opt_prefs.deleteEntry("UseZenity");
else opt_prefs.set("UseZenity", opt[Fl::OPTION_FNFC_USES_ZENITY][1]);
}
{
Fl_Preferences prefs(Fl_Preferences::USER_L, "fltk.org", "fltk");
@ -705,6 +710,8 @@ static void writePrefs() {
else opt_prefs.set("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK][0]);
if (opt[Fl::OPTION_SHOW_SCALING][0]==2) opt_prefs.deleteEntry("ShowZoomFactor");
else opt_prefs.set("ShowZoomFactor", opt[Fl::OPTION_SHOW_SCALING][0]);
if (opt[Fl::OPTION_FNFC_USES_ZENITY][0]==2) opt_prefs.deleteEntry("UseZenity");
else opt_prefs.set("UseZenity", opt[Fl::OPTION_FNFC_USES_ZENITY][0]);
}
}
@ -795,6 +802,20 @@ Fl_Menu_Item menu_wGTKText[] = {
{0,0,0,0,0,0,0,0,0}
};
Fl_Choice *wUseZenity=(Fl_Choice *)0;
static void cb_wUseZenity(Fl_Choice*, void*) {
int mode = wUserOrSystem->value();
opt[Fl::OPTION_FNFC_USES_ZENITY ][mode] = wUseZenity->value();
}
Fl_Menu_Item menu_wUseZenity[] = {
{"off", 0, 0, (void*)(0), 0, (uchar)FL_NORMAL_LABEL, 0, 14, 0},
{"on", 0, 0, (void*)(1), 128, (uchar)FL_NORMAL_LABEL, 0, 14, 0},
{"default", 0, 0, (void*)(2), 0, (uchar)FL_NORMAL_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0}
};
Fl_Choice *wPrintGTKText=(Fl_Choice *)0;
static void cb_wPrintGTKText(Fl_Choice*, void*) {
@ -845,7 +866,7 @@ static void cb_OK(Fl_Button*, void*) {
}
Fl_Double_Window* make_global_settings_window() {
{ global_settings_window = new Fl_Double_Window(400, 531, "FLTK Preferences");
{ global_settings_window = new Fl_Double_Window(400, 572, "FLTK Preferences");
global_settings_window->color(FL_LIGHT1);
{ Fl_Group* o = new Fl_Group(10, 10, 380, 100, "Keyboard Focus Options");
o->box(FL_GTK_DOWN_BOX);
@ -900,7 +921,7 @@ dropping text from other applications still works.\n\nDefault is on.");
} // Fl_Choice* wDNDText
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(10, 269, 380, 66, "Native File Chooser Options");
{ Fl_Group* o = new Fl_Group(10, 269, 380, 104, "Native File Chooser Options");
o->box(FL_GTK_DOWN_BOX);
o->labelfont(2);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
@ -914,13 +935,22 @@ ble.\n\nDefault is on.");
wGTKText->callback((Fl_Callback*)cb_wGTKText);
wGTKText->menu(menu_wGTKText);
} // Fl_Choice* wGTKText
{ wUseZenity = new Fl_Choice(245, 334, 100, 26, "Native File Chooser uses Zenity:");
wUseZenity->tooltip("OPTION_FNFC_USES_ZENITY\n\nIf \'Native File Chooser uses Zenity\' is enabled,\
the library uses a Zenity-based file dialog to open/save files when possible.\
If disabled, the GTK-based dialog is used. Default is on. Meaningful only wit\
h Wayland/X11 platforms.");
wUseZenity->down_box(FL_BORDER_BOX);
wUseZenity->callback((Fl_Callback*)cb_wUseZenity);
wUseZenity->menu(menu_wUseZenity);
} // Fl_Choice* wUseZenity
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(10, 345, 380, 66, "Print dialog Options");
{ Fl_Group* o = new Fl_Group(10, 384, 380, 66, "Print dialog Options");
o->box(FL_GTK_DOWN_BOX);
o->labelfont(2);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
{ wPrintGTKText = new Fl_Choice(245, 366, 100, 25, "Print dialog uses GTK:");
{ wPrintGTKText = new Fl_Choice(245, 405, 100, 25, "Print dialog uses GTK:");
wPrintGTKText->tooltip("OPTION_PRINTER_USES_GTK\n\nIf \'Print dialog uses GTK\' is enabled, the Fl_Pr\
inter class\ncalls the GTK print dialog when it\'s available on the platfom. I\
f disabled, the Fl_Printer class\nalways uses FLTK\'s own print dialog even if\
@ -931,11 +961,11 @@ f disabled, the Fl_Printer class\nalways uses FLTK\'s own print dialog even if\
} // Fl_Choice* wPrintGTKText
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(10, 421, 380, 66, "Scaling Factor Options");
{ Fl_Group* o = new Fl_Group(10, 459, 380, 66, "Scaling Factor Options");
o->box(FL_GTK_DOWN_BOX);
o->labelfont(2);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
{ wShowZoomFactor = new Fl_Choice(245, 442, 100, 25, "Transiently show scaling factor:");
{ wShowZoomFactor = new Fl_Choice(245, 483, 100, 25, "Transiently show scaling factor:");
wShowZoomFactor->tooltip("OPTION_SHOW_SCALING\n\nIf \'Transiently show scaling factor\' is enabled, the\
library shows in a transient yellow window the display\nscaling factor value \
when it is changed. If disabled, no such transient window is used.\n\nDefault \
@ -946,7 +976,7 @@ is on.");
} // Fl_Choice* wShowZoomFactor
o->end();
} // Fl_Group* o
{ wUserOrSystem = new Fl_Choice(10, 496, 141, 25);
{ wUserOrSystem = new Fl_Choice(10, 535, 141, 25);
wUserOrSystem->tooltip("Change settings for the current user, or default values for all users of this\
computer. Individual users can override system options, if they set their opt\
ions to specific values (not \'default\').");
@ -954,10 +984,10 @@ ions to specific values (not \'default\').");
wUserOrSystem->callback((Fl_Callback*)cb_wUserOrSystem);
wUserOrSystem->menu(menu_wUserOrSystem);
} // Fl_Choice* wUserOrSystem
{ Fl_Button* o = new Fl_Button(230, 496, 75, 25, "Cancel");
{ Fl_Button* o = new Fl_Button(230, 535, 75, 25, "Cancel");
o->callback((Fl_Callback*)cb_Cancel1);
} // Fl_Button* o
{ Fl_Button* o = new Fl_Button(315, 496, 75, 25, "OK");
{ Fl_Button* o = new Fl_Button(315, 535, 75, 25, "OK");
o->callback((Fl_Callback*)cb_OK);
} // Fl_Button* o
global_settings_window->end();

View File

@ -524,7 +524,8 @@ wShowTooltips->value(opt[Fl::OPTION_SHOW_TOOLTIPS][mode]);
wDNDText->value(opt[Fl::OPTION_DND_TEXT][mode]);
wGTKText->value(opt[Fl::OPTION_FNFC_USES_GTK][mode]);
wPrintGTKText->value(opt[Fl::OPTION_PRINTER_USES_GTK][mode]);
wShowZoomFactor->value(opt[Fl::OPTION_SHOW_SCALING][mode]);} {}
wShowZoomFactor->value(opt[Fl::OPTION_SHOW_SCALING][mode]);
wUseZenity->value(opt[Fl::OPTION_FNFC_USES_ZENITY][mode]);} {}
}
Function {readPrefs()} {
@ -541,6 +542,7 @@ Function {readPrefs()} {
opt_prefs.get("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK ][1], 2);
opt_prefs.get("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK ][1], 2);
opt_prefs.get("ShowZoomFactor", opt[Fl::OPTION_SHOW_SCALING ][1], 2);
opt_prefs.get("UseZenity", opt[Fl::OPTION_FNFC_USES_ZENITY ][1], 2);
}
{
Fl_Preferences prefs(Fl_Preferences::USER_L, "fltk.org", "fltk");
@ -552,6 +554,7 @@ Function {readPrefs()} {
opt_prefs.get("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK ][0], 2);
opt_prefs.get("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK ][0], 2);
opt_prefs.get("ShowZoomFactor", opt[Fl::OPTION_SHOW_SCALING ][0], 2);
opt_prefs.get("UseZenity", opt[Fl::OPTION_FNFC_USES_ZENITY ][0], 2);
}
refreshUI();} {}
}
@ -577,6 +580,8 @@ Function {writePrefs()} {
else opt_prefs.set("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK][1]);
if (opt[Fl::OPTION_SHOW_SCALING][1]==2) opt_prefs.deleteEntry("ShowZoomFactor");
else opt_prefs.set("ShowZoomFactor", opt[Fl::OPTION_SHOW_SCALING][1]);
if (opt[Fl::OPTION_FNFC_USES_ZENITY][1]==2) opt_prefs.deleteEntry("UseZenity");
else opt_prefs.set("UseZenity", opt[Fl::OPTION_FNFC_USES_ZENITY][1]);
}
{
Fl_Preferences prefs(Fl_Preferences::USER_L, "fltk.org", "fltk");
@ -595,6 +600,8 @@ Function {writePrefs()} {
else opt_prefs.set("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK][0]);
if (opt[Fl::OPTION_SHOW_SCALING][0]==2) opt_prefs.deleteEntry("ShowZoomFactor");
else opt_prefs.set("ShowZoomFactor", opt[Fl::OPTION_SHOW_SCALING][0]);
if (opt[Fl::OPTION_FNFC_USES_ZENITY][0]==2) opt_prefs.deleteEntry("UseZenity");
else opt_prefs.set("UseZenity", opt[Fl::OPTION_FNFC_USES_ZENITY][0]);
}} {}
}
@ -617,7 +624,7 @@ global_settings_window->show();} {}
Function {make_global_settings_window()} {} {
Fl_Window global_settings_window {
label {FLTK Preferences} open
xywh {715 96 400 531} type Double color 50 hide
xywh {817 110 400 572} type Double color 50 hide
} {
Fl_Group {} {
label {Keyboard Focus Options} open
@ -740,7 +747,7 @@ Default is on.} xywh {245 225 100 25} down_box BORDER_BOX
}
Fl_Group {} {
label {Native File Chooser Options} open
xywh {10 269 380 66} box GTK_DOWN_BOX labelfont 2 align 21
xywh {10 269 380 104} box GTK_DOWN_BOX labelfont 2 align 21
} {
Fl_Choice wGTKText {
label {Native File Chooser uses GTK:}
@ -770,10 +777,34 @@ Default is on.} xywh {245 300 100 25} down_box BORDER_BOX
xywh {30 30 31 20}
}
}
Fl_Choice wUseZenity {
label {Native File Chooser uses Zenity:}
callback {int mode = wUserOrSystem->value();
opt[Fl::OPTION_FNFC_USES_ZENITY ][mode] = wUseZenity->value();}
tooltip {OPTION_FNFC_USES_ZENITY
If 'Native File Chooser uses Zenity' is enabled, the library uses a Zenity-based file dialog to open/save files when possible. If disabled, the GTK-based dialog is used. Default is on. Meaningful only with Wayland/X11 platforms.} xywh {245 334 100 26} down_box BORDER_BOX
} {
MenuItem {} {
label off
user_data 0 user_data_type long
xywh {545 545 31 20}
}
MenuItem {} {
label on
user_data 1 user_data_type long
xywh {545 545 31 20} divider
}
MenuItem {} {
label default
user_data 2 user_data_type long
xywh {545 545 31 20}
}
}
}
Fl_Group {} {
label {Print dialog Options} open
xywh {10 345 380 66} box GTK_DOWN_BOX labelfont 2 align 21
xywh {10 384 380 66} box GTK_DOWN_BOX labelfont 2 align 21
} {
Fl_Choice wPrintGTKText {
label {Print dialog uses GTK:}
@ -785,7 +816,7 @@ If 'Print dialog uses GTK' is enabled, the Fl_Printer class
calls the GTK print dialog when it's available on the platfom. If disabled, the Fl_Printer class
always uses FLTK's own print dialog even if GTK is available.
Default is on.} xywh {245 366 100 25} down_box BORDER_BOX
Default is on.} xywh {245 405 100 25} down_box BORDER_BOX
} {
MenuItem {} {
label off
@ -806,7 +837,7 @@ Default is on.} xywh {245 366 100 25} down_box BORDER_BOX
}
Fl_Group {} {
label {Scaling Factor Options} open
xywh {10 421 380 66} box GTK_DOWN_BOX labelfont 2 align 21
xywh {10 459 380 66} box GTK_DOWN_BOX labelfont 2 align 21
} {
Fl_Choice wShowZoomFactor {
label {Transiently show scaling factor:}
@ -817,7 +848,7 @@ opt[Fl::OPTION_SHOW_SCALING ][mode] = wShowZoomFactor->value();} open
If 'Transiently show scaling factor' is enabled, the library shows in a transient yellow window the display
scaling factor value when it is changed. If disabled, no such transient window is used.
Default is on.} xywh {245 442 100 25} down_box BORDER_BOX
Default is on.} xywh {245 483 100 25} down_box BORDER_BOX
} {
MenuItem {} {
label off
@ -838,7 +869,7 @@ Default is on.} xywh {245 442 100 25} down_box BORDER_BOX
}
Fl_Choice wUserOrSystem {
callback {refreshUI();} open
tooltip {Change settings for the current user, or default values for all users of this computer. Individual users can override system options, if they set their options to specific values (not 'default').} xywh {10 496 141 25} down_box BORDER_BOX
tooltip {Change settings for the current user, or default values for all users of this computer. Individual users can override system options, if they set their options to specific values (not 'default').} xywh {10 535 141 25} down_box BORDER_BOX
} {
MenuItem {} {
label {User Settings}
@ -854,13 +885,13 @@ Default is on.} xywh {245 442 100 25} down_box BORDER_BOX
Fl_Button {} {
label Cancel
callback {global_settings_window->hide();}
xywh {230 496 75 25}
xywh {230 535 75 25}
}
Fl_Button {} {
label OK
callback {writePrefs();
global_settings_window->hide();}
xywh {315 496 75 25}
xywh {315 535 75 25}
}
}
code {readPrefs();

View File

@ -108,6 +108,7 @@ extern Fl_Choice *wArrowFocus;
extern Fl_Choice *wShowTooltips;
extern Fl_Choice *wDNDText;
extern Fl_Choice *wGTKText;
extern Fl_Choice *wUseZenity;
extern Fl_Choice *wPrintGTKText;
extern Fl_Choice *wShowZoomFactor;
extern Fl_Choice *wUserOrSystem;
@ -117,6 +118,7 @@ extern Fl_Menu_Item menu_wArrowFocus[];
extern Fl_Menu_Item menu_wShowTooltips[];
extern Fl_Menu_Item menu_wDNDText[];
extern Fl_Menu_Item menu_wGTKText[];
extern Fl_Menu_Item menu_wUseZenity[];
extern Fl_Menu_Item menu_wPrintGTKText[];
extern Fl_Menu_Item menu_wShowZoomFactor[];
extern Fl_Menu_Item menu_wUserOrSystem[];

View File

@ -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

View File

@ -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
}

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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 \