Rewrite the Fl_File_Native_Chooser class under the driver model.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11529 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2016-04-05 11:25:35 +00:00
parent 1dfe311998
commit fa67aafa9d
9 changed files with 787 additions and 578 deletions

View File

@ -3,7 +3,7 @@
//
// FLTK native OS file chooser widget
//
// Copyright 1998-2014 by Bill Spitzak and others.
// Copyright 1998-2016 by Bill Spitzak and others.
// Copyright 2004 Greg Ercolano.
//
// This library is free software. Distribution and use rights are outlined in
@ -20,42 +20,41 @@
/** \file
Fl_Native_File_Chooser widget. */
/* Implementation note:
class Fl_Native_File_Chooser <== public API used by applications
class Fl_Native_File_Chooser_Driver <== virtual API that a platform may implement
this API has a do-nothing default implementation
class Fl_Native_File_Chooser_FLTK_Driver <== this API implementation is the default FLTK file chooser
class Fl_Native_File_Chooser_GTK_Driver <== this API implementation runs a GTK file chooser
it is determined at run-time if the GTK dynamic libraries are available
class Fl_Native_File_Chooser_Darwin_Driver <== this API implementation runs a Mac OS X file chooser
class Fl_Native_File_Chooser_WinAPI_Driver <== this API implementation runs a MSWindows file chooser
Each platform must implement the constructor of the Fl_Native_File_Chooser class.
This particular implementation:
Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
platform_fnfc = new Fl_Native_File_Chooser_FLTK_Driver(val);
}
can be used by any platform.
No more code is required. The cross-platform Fl_Native_File_Chooser_FLTK.cxx file must be compiled in libfltk,
and the default FLTK file chooser will be used.
*/
#ifndef FL_NATIVE_FILE_CHOOSER_H
#define FL_NATIVE_FILE_CHOOSER_H
// Use Windows' chooser
#ifdef WIN32
#include <FL/Fl_Export.H>
#include <FL/Fl_File_Chooser.H>
// #define _WIN32_WINNT 0x0501 // needed for OPENFILENAME's 'FlagsEx'
#if defined(FL_LIBRARY)
# include <windows.h>
# include <commdlg.h> // OPENFILENAMEW, GetOpenFileName()
# include <shlobj.h> // BROWSEINFOW, SHBrowseForFolder()
typedef OPENFILENAMEW fl_OPENFILENAMEW;
typedef BROWSEINFOW fl_BROWSEINFOW;
#else
typedef void fl_OPENFILENAMEW;
typedef void fl_BROWSEINFOW;
#endif
# include <FL/filename.H> // FL_EXPORT
// Use Apple's chooser
#elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - native file chooser support
# define MAXFILTERS 80
# include <FL/filename.H> // FL_EXPORT
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: define a file chooser if one is available on your platform"
# include <FL/Fl_File_Chooser.H> // default to FLTK file chooser if none id ported
// All else falls back to FLTK's own chooser
#else
# include <FL/Fl_File_Chooser.H>
#endif
class Fl_FLTK_File_Chooser;
class Fl_GTK_File_Chooser;
class Fl_Native_File_Chooser_Driver;
/**
This class lets an FLTK application easily and consistently access
@ -113,6 +112,8 @@ class Fl_GTK_File_Chooser;
*/
class FL_EXPORT Fl_Native_File_Chooser {
private:
Fl_Native_File_Chooser_Driver *platform_fnfc;
public:
enum Type {
BROWSE_FILE = 0, ///< browse files (lets user choose one file)
@ -129,14 +130,15 @@ public:
PREVIEW = 0x0004, ///< enable preview mode (if supported)
USE_FILTER_EXT = 0x0008 ///< Chooser filter pilots the output file extension (if supported)
};
/** Localizable message */
static const char *file_exists_message;
public:
Fl_Native_File_Chooser(int val=BROWSE_FILE);
/**
The constructor. Internally allocates the native widgets.
Optional \p val presets the type of browser this will be,
which can also be changed with type().
*/
Fl_Native_File_Chooser(int val = BROWSE_FILE); // each platorm implements it
~Fl_Native_File_Chooser();
// Public methods
void type(int t);
int type() const ;
void options(int o);
@ -157,95 +159,46 @@ public:
const char* preset_file() const;
const char *errmsg() const ;
int show() ;
#ifdef WIN32
private:
int _btype; // kind-of browser to show()
int _options; // general options
fl_OPENFILENAMEW *_ofn_ptr; // GetOpenFileName() & GetSaveFileName() struct
fl_BROWSEINFOW *_binf_ptr; // SHBrowseForFolder() struct
char **_pathnames; // array of pathnames
int _tpathnames; // total pathnames
char *_directory; // default pathname to use
char *_title; // title for window
char *_filter; // user-side search filter
char *_parsedfilt; // filter parsed for Windows dialog
int _nfilters; // number of filters parse_filter counted
char *_preset_file; // the file to preselect
char *_errmsg; // error message
// Private methods
void errmsg(const char *msg);
void clear_pathnames();
void set_single_pathname(const char *s);
void add_pathname(const char *s);
void ClearOFN();
void ClearBINF();
void Win2Unix(char *s);
void Unix2Win(char *s);
int showfile();
int showdir();
void parse_filter(const char *);
void clear_filters();
void add_filter(const char *, const char *);
#elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - native file chooser support
private:
int _btype; // kind-of browser to show()
int _options; // general options
void *_panel;
char **_pathnames; // array of pathnames
int _tpathnames; // total pathnames
char *_directory; // default pathname to use
char *_title; // title for window
char *_preset_file; // the 'save as' filename
char *_filter; // user-side search filter, eg:
// C Files\t*.[ch]\nText Files\t*.txt"
char *_filt_names; // filter names (tab delimited)
// eg. "C Files\tText Files"
char *_filt_patt[MAXFILTERS];
// array of filter patterns, eg:
// _filt_patt[0]="*.{cxx,h}"
// _filt_patt[1]="*.txt"
int _filt_total; // parse_filter() # of filters loaded
int _filt_value; // index of the selected filter
char *_errmsg; // error message
// Private methods
void errmsg(const char *msg);
void clear_pathnames();
void set_single_pathname(const char *s);
int get_saveas_basename(void);
void clear_filters();
void parse_filter(const char *from);
int post();
int runmodal();
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: define member variables for file chooser if one is available on your platform"
#else
private:
static int have_looked_for_GTK_libs;
union {
Fl_FLTK_File_Chooser *_x11_file_chooser;
Fl_GTK_File_Chooser *_gtk_file_chooser;
};
#endif
class Fl_Native_File_Chooser_Driver {
protected:
static void chrcat(char *s, char c);
static char *strapp(char *s, const char *val);
static char *strfree(char *val);
static char *strnew(const char *val);
public:
Fl_Native_File_Chooser_Driver(int val) {}
virtual ~Fl_Native_File_Chooser_Driver() {}
virtual void type(int t) {}
virtual int type() const {return 0;}
virtual void options(int o) {}
virtual int options() const {return 0;}
virtual int count() const {return 0;}
virtual const char *filename() const {return 0;}
virtual const char *filename(int i) const {return 0;}
virtual void directory(const char *val) {}
virtual const char *directory() const {return 0;}
virtual void title(const char *t) {}
virtual const char* title() const {return 0;}
virtual const char *filter() const {return 0;}
virtual void filter(const char *f) {}
virtual int filters() const {return 0;}
virtual void filter_value(int i) {}
virtual int filter_value() const {return 0;}
virtual void preset_file(const char*f) {}
virtual const char* preset_file() const {return 0;}
virtual const char *errmsg() const {return 0;}
virtual int show() {return 1;}
};
#if !defined(__APPLE__) && !defined(WIN32) && !defined(FL_PORTING) // PORTME: Fl_Screen_Driver - FLTK file chooser option
class FL_EXPORT Fl_FLTK_File_Chooser {
friend class Fl_Native_File_Chooser;
class Fl_Native_File_Chooser_FLTK_Driver : public Fl_Native_File_Chooser_Driver {
private:
void errmsg(const char *msg);
int type_fl_file(int val);
int exist_dialog();
void parse_filter();
protected:
int _btype; // kind-of browser to show()
int _options; // general options
@ -257,78 +210,33 @@ protected:
char *_prevvalue; // Returned filename
char *_directory;
char *_errmsg; // error message
Fl_FLTK_File_Chooser(int val);
virtual ~Fl_FLTK_File_Chooser();
void errmsg(const char *msg);
int type_fl_file(int);
void parse_filter();
int exist_dialog();
Fl_File_Chooser *_file_chooser;
virtual void type(int);
int type() const;
void options(int);
int options() const;
public:
Fl_Native_File_Chooser_FLTK_Driver(int val);
virtual ~Fl_Native_File_Chooser_FLTK_Driver();
virtual void type(int t);
virtual int type() const ;
virtual void options(int o);
virtual int options() const;
virtual int count() const;
virtual const char *filename() const;
virtual const char *filename(int i) const;
void directory(const char *val);
const char *directory() const;
virtual void title(const char *);
virtual const char *filename() const ;
virtual const char *filename(int i) const ;
virtual void directory(const char *val) ;
virtual const char *directory() const;
virtual void title(const char *t);
virtual const char* title() const;
const char *filter() const;
void filter(const char *);
int filters() const;
void filter_value(int i);
int filter_value() const;
void preset_file(const char*);
const char* preset_file() const;
const char *errmsg() const;
virtual int show();
virtual const char *filter() const ;
virtual void filter(const char *f);
virtual int filters() const ;
virtual void filter_value(int i) ;
virtual int filter_value() const ;
virtual void preset_file(const char*f) ;
virtual const char* preset_file() const;
virtual const char *errmsg() const ;
virtual int show() ;
};
class FL_EXPORT Fl_GTK_File_Chooser : public Fl_FLTK_File_Chooser {
friend class Fl_Native_File_Chooser;
private:
typedef struct _GtkWidget GtkWidget;
typedef struct _GtkFileFilterInfo GtkFileFilterInfo;
struct pair {
Fl_GTK_File_Chooser* running; // the running Fl_GTK_File_Chooser
const char *filter; // a filter string of the chooser
pair(Fl_GTK_File_Chooser* c, const char *f) {
running = c;
filter = strdup(f);
};
~pair() {
free((char*)filter);
};
};
GtkWidget *gtkw_ptr; // used to hold a GtkWidget* without pulling GTK into everything...
void *gtkw_slist; // used to hold a GLib GSList...
unsigned gtkw_count; // number of files read back - if any
mutable char *gtkw_filename; // last name we read back
char *gtkw_title; // the title to be applied to the dialog
const char *previous_filter;
int fl_gtk_chooser_wrapper(); // method that wraps the GTK widget
Fl_GTK_File_Chooser(int val);
virtual ~Fl_GTK_File_Chooser();
static int did_find_GTK_libs;
static void probe_for_GTK_libs(void);
virtual void type(int);
virtual int count() const;
virtual const char *filename() const;
virtual const char *filename(int i) const;
virtual void title(const char *);
virtual const char* title() const;
virtual int show();
void changed_output_type(const char *filter);
static int custom_gtk_filter_function(const GtkFileFilterInfo*, Fl_GTK_File_Chooser::pair*);
static void free_pair(pair *p);
};
#endif // !defined(__APPLE__) && !defined(WIN32) // PORTME: Fl_Screen_Driver - native file chooser option
#endif /*FL_NATIVE_FILE_CHOOSER_H*/
//

View File

@ -185,6 +185,8 @@ if (USE_X11)
drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx
Fl_x.cxx
fl_dnd_x.cxx
Fl_Native_File_Chooser_FLTK.cxx
Fl_Native_File_Chooser_GTK.cxx
)
if (USE_XFT)
set (DRIVER_FILES ${DRIVER_FILES}
@ -280,6 +282,7 @@ else ()
drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx
Fl_win32.cxx
fl_dnd_win32.cxx
Fl_Native_File_Chooser_WIN32.cxx
)
set (DRIVER_HEADER_FILES
drivers/WinAPI/Fl_WinAPI_System_Driver.H
@ -367,12 +370,18 @@ set (CFILES
xutf8/is_right2left.c
xutf8/is_spacing.c
xutf8/case.c
xutf8/utf8Input.c
xutf8/utf8Utils.c
xutf8/utf8Wrap.c
xutf8/keysym2Ucs.c
)
if (USE_X11)
set (CFILES
${CFILES}
xutf8/utf8Input.c
xutf8/utf8Utils.c
xutf8/utf8Wrap.c
xutf8/keysym2Ucs.c
)
endif (USE_X11)
if (APPLE AND (NOT OPTION_APPLE_X11) AND (NOT OPTION_APPLE_SDL))
set (MMFILES
Fl_cocoa.mm

View File

@ -2,7 +2,7 @@
//
// FLTK native OS file chooser widget
//
// Copyright 1998-2010 by Bill Spitzak and others.
// Copyright 1998-2016 by Bill Spitzak and others.
// Copyright 2004 Greg Ercolano.
//
// This library is free software. Distribution and use rights are outlined in
@ -16,25 +16,309 @@
// http://www.fltk.org/str.php
//
// Use Windows' chooser
#ifdef WIN32
#include "Fl_Native_File_Chooser_WIN32.cxx"
// Use Apple's chooser
#elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - native file chooser
#include <FL/Fl_Native_File_Chooser.H>
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: implement the native file chooser interface"
# include "Fl_Native_File_Chooser_FLTK.cxx"
// All else falls back to FLTK's own chooser
#else
#include "Fl_Native_File_Chooser_FLTK.cxx"
#ifdef FL_PORTING
# pragma message "Implement a native file chooser (see Fl_Native_File_Chooser_Driver), or use FLTK's chooser"
Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
platform_fnfc = new Fl_Native_File_Chooser_FLTK_Driver(val);
}
#endif
/** Localizable message */
const char *Fl_Native_File_Chooser::file_exists_message = "File exists. Are you sure you want to overwrite?";
/**
Destructor.
Deallocates any resources allocated to this widget.
*/
Fl_Native_File_Chooser::~Fl_Native_File_Chooser()
{
delete platform_fnfc;
}
/**
Sets the current Fl_Native_File_Chooser::Type of browser.
*/
void Fl_Native_File_Chooser::type(int t)
{
platform_fnfc->type(t);
}
/**
Gets the current Fl_Native_File_Chooser::Type of browser.
*/
int Fl_Native_File_Chooser::type() const
{
return platform_fnfc->type();
}
/**
Sets the platform specific chooser options to \p val.
\p val is expected to be one or more Fl_Native_File_Chooser::Option flags ORed together.
Some platforms have OS-specific functions that can be enabled/disabled via this method.
<P>
\code
Flag Description Win Mac Other
-------------- ----------------------------------------------- ------- ------- -------
NEW_FOLDER Shows the 'New Folder' button. Ignored Used Used
PREVIEW Enables the 'Preview' mode by default. Ignored Ignored Used
SAVEAS_CONFIRM Confirm dialog if BROWSE_SAVE_FILE file exists. Used Used Used
USE_FILTER_EXT Chooser filter pilots the output file extension. Ignored Used Used (GTK)
\endcode
*/
void Fl_Native_File_Chooser::options(int o)
{
platform_fnfc->options(o);
}
/**
Gets the platform specific Fl_Native_File_Chooser::Option flags.
*/
int Fl_Native_File_Chooser::options() const
{
return platform_fnfc->options();
}
/**
Returns the number of filenames (or directory names) the user selected.
<P>
\b Example:
\code
if ( fnfc->show() == 0 ) {
// Print all filenames user selected
for (int n=0; n<fnfc->count(); n++ ) {
printf("%d) '%s'\n", n, fnfc->filename(n));
}
}
\endcode
*/
int Fl_Native_File_Chooser::count() const
{
return platform_fnfc->count();
}
/**
Return the filename the user chose.
Use this if only expecting a single filename.
If more than one filename is expected, use filename(int) instead.
Return value may be "" if no filename was chosen (eg. user cancelled).
*/
const char *Fl_Native_File_Chooser::filename() const
{
return platform_fnfc->filename();
}
/**
Return one of the filenames the user selected.
Use count() to determine how many filenames the user selected.
<P>
\b Example:
\code
if ( fnfc->show() == 0 ) {
// Print all filenames user selected
for (int n=0; n<fnfc->count(); n++ ) {
printf("%d) '%s'\n", n, fnfc->filename(n));
}
}
\endcode
*/
const char *Fl_Native_File_Chooser::filename(int i) const
{
return platform_fnfc->filename(i);
}
/**
Preset the directory the browser will show when opened.
If \p val is NULL, or no directory is specified, the chooser will attempt
to use the last non-cancelled folder.
*/
void Fl_Native_File_Chooser::directory(const char *val)
{
platform_fnfc->directory(val);
}
/**
Returns the current preset directory() value.
*/
const char *Fl_Native_File_Chooser::directory() const
{
return platform_fnfc->directory();
}
/**
Set the title of the file chooser's dialog window.
Can be NULL if no title desired.
The default title varies according to the platform, so you are advised to set the title explicitly.
*/
void Fl_Native_File_Chooser::title(const char *t)
{
platform_fnfc->title(t);
}
/**
Get the title of the file chooser's dialog window.
Return value may be NULL if no title was set.
*/
const char* Fl_Native_File_Chooser::title() const
{
return platform_fnfc->title();
}
/**
Returns the filter string last set.
Can be NULL if no filter was set.
*/
const char *Fl_Native_File_Chooser::filter() const
{
return platform_fnfc->filter();
}
/**
Sets the filename filters used for browsing.
The default is NULL, which browses all files.
<P>
The filter string can be any of:
<P>
- A single wildcard (eg. "*.txt")
- Multiple wildcards (eg. "*.{cxx,h,H}")
- A descriptive name followed by a "\t" and a wildcard (eg. "Text Files\t*.txt")
- A list of separate wildcards with a "\n" between each (eg. "*.{cxx,H}\n*.txt")
- A list of descriptive names and wildcards (eg. "C++ Files\t*.{cxx,H}\nTxt Files\t*.txt")
<P>
The format of each filter is a wildcard, or an optional user description
followed by '\\t' and the wildcard.
<P>
On most platforms, each filter is available to the user via a pulldown menu
in the file chooser. The 'All Files' option is always available to the user.
*/
void Fl_Native_File_Chooser::filter(const char *f)
{
platform_fnfc->filter(f);
}
/**
Gets how many filters were available, not including "All Files"
*/
int Fl_Native_File_Chooser::filters() const
{
return platform_fnfc->filters();
}
/**
Sets which filter will be initially selected.
The first filter is indexed as 0.
If filter_value()==filters(), then "All Files" was chosen.
If filter_value() > filters(), then a custom filter was set.
*/
void Fl_Native_File_Chooser::filter_value(int i)
{
platform_fnfc->filter_value(i);
}
/**
Returns which filter value was last selected by the user.
This is only valid if the chooser returns success.
*/
int Fl_Native_File_Chooser::filter_value() const
{
return platform_fnfc->filters();
}
/**
Sets the default filename for the chooser.
Use directory() to set the default directory.
Mainly used to preset the filename for save dialogs,
and on most platforms can be used for opening files as well.
*/
void Fl_Native_File_Chooser::preset_file(const char*f)
{
platform_fnfc->preset_file(f);
}
/**
Get the preset filename.
*/
const char* Fl_Native_File_Chooser::preset_file() const
{
return platform_fnfc->preset_file();
}
/**
Returns a system dependent error message for the last method that failed.
This message should at least be flagged to the user in a dialog box, or to some kind of error log.
Contents will be valid only for methods that document errmsg() will have info on failures.
*/
const char *Fl_Native_File_Chooser::errmsg() const
{
return platform_fnfc->errmsg();
}
/**
Post the chooser's dialog. Blocks until dialog has been completed or cancelled.
\returns
- 0 -- user picked a file
- 1 -- user cancelled
- -1 -- failed; errmsg() has reason
*/
int Fl_Native_File_Chooser::show()
{
return platform_fnfc->show();
}
// COPY A STRING WITH 'new'
// Value can be NULL
//
char *Fl_Native_File_Chooser_Driver::strnew(const char *val) {
if ( val == NULL ) return(NULL);
char *s = new char[strlen(val)+1];
strcpy(s, val);
return(s);
}
// FREE STRING CREATED WITH strnew(), NULLS OUT STRING
// Value can be NULL
//
char *Fl_Native_File_Chooser_Driver::strfree(char *val) {
if ( val ) delete [] val;
return(NULL);
}
// 'DYNAMICALLY' APPEND ONE STRING TO ANOTHER
// Returns newly allocated string, or NULL
// if s && val == NULL.
// 's' can be NULL; returns a strnew(val).
// 'val' can be NULL; s is returned unmodified.
//
// Usage:
// char *s = strnew("foo"); // s = "foo"
// s = strapp(s, "bar"); // s = "foobar"
//
char *Fl_Native_File_Chooser_Driver::strapp(char *s, const char *val) {
if ( ! val ) {
return(s); // Nothing to append? return s
}
if ( ! s ) {
return(strnew(val)); // New string? return copy of val
}
char *news = new char[strlen(s)+strlen(val)+1];
strcpy(news, s);
strcat(news, val);
delete [] s; // delete old string
return(news); // return new copy
}
// APPEND A CHARACTER TO A STRING
// This does NOT allocate space for the new character.
//
void Fl_Native_File_Chooser_Driver::chrcat(char *s, char c) {
char tmp[2] = { c, '\0' };
strcat(s, tmp);
}
//
// End of "$Id$".
//

View File

@ -16,216 +16,21 @@
// http://www.fltk.org/str.php
//
#include <config.h>
#include <FL/Fl_Native_File_Chooser.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_File_Icon.H>
#define FLTK_CHOOSER_SINGLE Fl_File_Chooser::SINGLE
#define FLTK_CHOOSER_DIRECTORY Fl_File_Chooser::DIRECTORY
#define FLTK_CHOOSER_MULTI Fl_File_Chooser::MULTI
#define FLTK_CHOOSER_CREATE Fl_File_Chooser::CREATE
#include "Fl_Native_File_Chooser_common.cxx"
#include "Fl_Native_File_Chooser_GTK.cxx"
#include <sys/stat.h>
#include <string.h>
#if defined(FL_PORTING)
# pragma message "FL_PORTING: implement Fl_Native_File_Chooser"
int Fl_Native_File_Chooser::show() { return 0; }
void Fl_Native_File_Chooser::type(int t) { }
void Fl_Native_File_Chooser::title(const char *t) { }
void Fl_Native_File_Chooser::filter(const char *f) { }
void Fl_Native_File_Chooser::options(int val) { }
const char *Fl_Native_File_Chooser::filename() const { return 0; }
Fl_Native_File_Chooser::Fl_Native_File_Chooser(int) { }
Fl_Native_File_Chooser::~Fl_Native_File_Chooser() { }
#else
int Fl_Native_File_Chooser::have_looked_for_GTK_libs = 0;
/**
The constructor. Internally allocates the native widgets.
Optional \p val presets the type of browser this will be,
which can also be changed with type().
*/
Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
if (have_looked_for_GTK_libs == 0) {
// First Time here, try to find the GTK libs if they are installed
#if HAVE_DLSYM && HAVE_DLFCN_H
if (Fl::option(Fl::OPTION_FNFC_USES_GTK)) {
Fl_GTK_File_Chooser::probe_for_GTK_libs();
}
#endif
have_looked_for_GTK_libs = -1;
}
// if we found all the GTK functions we need, we will use the GtkFileChooserDialog
if (Fl_GTK_File_Chooser::did_find_GTK_libs) _gtk_file_chooser = new Fl_GTK_File_Chooser(val);
else _x11_file_chooser = new Fl_FLTK_File_Chooser(val);
}
/**
Destructor.
Deallocates any resources allocated to this widget.
*/
Fl_Native_File_Chooser::~Fl_Native_File_Chooser() {
delete _x11_file_chooser;
}
/**
Sets the current Fl_Native_File_Chooser::Type of browser.
*/
void Fl_Native_File_Chooser::type(int t) { return _x11_file_chooser->type(t); }
/**
Gets the current Fl_Native_File_Chooser::Type of browser.
*/
int Fl_Native_File_Chooser::type() const { return _x11_file_chooser->type(); }
/**
Sets the platform specific chooser options to \p val.
\p val is expected to be one or more Fl_Native_File_Chooser::Option flags ORed together.
Some platforms have OS-specific functions that can be enabled/disabled via this method.
<P>
\code
Flag Description Win Mac Other
-------------- ----------------------------------------------- ------- ------- -------
NEW_FOLDER Shows the 'New Folder' button. Ignored Used Used
PREVIEW Enables the 'Preview' mode by default. Ignored Ignored Used
SAVEAS_CONFIRM Confirm dialog if BROWSE_SAVE_FILE file exists. Used Used Used
USE_FILTER_EXT Chooser filter pilots the output file extension. Ignored Used Used (GTK)
\endcode
*/
void Fl_Native_File_Chooser::options(int o) { _x11_file_chooser->options(o); }
/**
Gets the platform specific Fl_Native_File_Chooser::Option flags.
*/
int Fl_Native_File_Chooser::options() const { return _x11_file_chooser->options(); }
/**
Returns the number of filenames (or directory names) the user selected.
<P>
\b Example:
\code
if ( fnfc->show() == 0 ) {
// Print all filenames user selected
for (int n=0; n<fnfc->count(); n++ ) {
printf("%d) '%s'\n", n, fnfc->filename(n));
}
}
\endcode
*/
int Fl_Native_File_Chooser::count() const { return _x11_file_chooser->count(); }
/**
Return the filename the user chose.
Use this if only expecting a single filename.
If more than one filename is expected, use filename(int) instead.
Return value may be "" if no filename was chosen (eg. user cancelled).
*/
const char *Fl_Native_File_Chooser::filename() const { return _x11_file_chooser->filename(); }
/**
Return one of the filenames the user selected.
Use count() to determine how many filenames the user selected.
<P>
\b Example:
\code
if ( fnfc->show() == 0 ) {
// Print all filenames user selected
for (int n=0; n<fnfc->count(); n++ ) {
printf("%d) '%s'\n", n, fnfc->filename(n));
}
}
\endcode
*/
const char *Fl_Native_File_Chooser::filename(int i) const { return _x11_file_chooser->filename(i); }
/**
Preset the directory the browser will show when opened.
If \p val is NULL, or no directory is specified, the chooser will attempt
to use the last non-cancelled folder.
*/
void Fl_Native_File_Chooser::directory(const char *val) { _x11_file_chooser->directory(val); }
/**
Returns the current preset directory() value.
*/
const char *Fl_Native_File_Chooser::directory() const { return _x11_file_chooser->directory(); }
/**
Set the title of the file chooser's dialog window.
Can be NULL if no title desired.
The default title varies according to the platform, so you are advised to set the title explicitly.
*/
void Fl_Native_File_Chooser::title(const char *t) { _x11_file_chooser->title(t); }
/**
Get the title of the file chooser's dialog window.
Return value may be NULL if no title was set.
*/
const char* Fl_Native_File_Chooser::title() const { return _x11_file_chooser->title(); }
/**
Returns the filter string last set.
Can be NULL if no filter was set.
*/
const char *Fl_Native_File_Chooser::filter() const { return _x11_file_chooser->filter(); }
/**
Sets the filename filters used for browsing.
The default is NULL, which browses all files.
<P>
The filter string can be any of:
<P>
- A single wildcard (eg. "*.txt")
- Multiple wildcards (eg. "*.{cxx,h,H}")
- A descriptive name followed by a "\t" and a wildcard (eg. "Text Files\t*.txt")
- A list of separate wildcards with a "\n" between each (eg. "*.{cxx,H}\n*.txt")
- A list of descriptive names and wildcards (eg. "C++ Files\t*.{cxx,H}\nTxt Files\t*.txt")
<P>
The format of each filter is a wildcard, or an optional user description
followed by '\\t' and the wildcard.
<P>
On most platforms, each filter is available to the user via a pulldown menu
in the file chooser. The 'All Files' option is always available to the user.
*/
void Fl_Native_File_Chooser::filter(const char *f) { _x11_file_chooser->filter(f); }
/**
Gets how many filters were available, not including "All Files"
*/
int Fl_Native_File_Chooser::filters() const { return _x11_file_chooser->filters(); }
/**
Sets which filter will be initially selected.
The first filter is indexed as 0.
If filter_value()==filters(), then "All Files" was chosen.
If filter_value() > filters(), then a custom filter was set.
*/
void Fl_Native_File_Chooser::filter_value(int i) { _x11_file_chooser->filter_value(i); }
/**
Returns which filter value was last selected by the user.
This is only valid if the chooser returns success.
*/
int Fl_Native_File_Chooser::filter_value() const { return _x11_file_chooser->filter_value(); }
/**
Sets the default filename for the chooser.
Use directory() to set the default directory.
Mainly used to preset the filename for save dialogs,
and on most platforms can be used for opening files as well.
*/
void Fl_Native_File_Chooser::preset_file(const char* f) { _x11_file_chooser->preset_file(f); }
/**
Get the preset filename.
*/
const char* Fl_Native_File_Chooser::preset_file() const { return _x11_file_chooser->preset_file(); }
/**
Returns a system dependent error message for the last method that failed.
This message should at least be flagged to the user in a dialog box, or to some kind of error log.
Contents will be valid only for methods that document errmsg() will have info on failures.
*/
const char *Fl_Native_File_Chooser::errmsg() const { return _x11_file_chooser->errmsg(); }
/**
Post the chooser's dialog. Blocks until dialog has been completed or cancelled.
\returns
- 0 -- user picked a file
- 1 -- user cancelled
- -1 -- failed; errmsg() has reason
*/
int Fl_Native_File_Chooser::show() { return _x11_file_chooser->show(); }
Fl_FLTK_File_Chooser::Fl_FLTK_File_Chooser(int val) {
Fl_Native_File_Chooser_FLTK_Driver::Fl_Native_File_Chooser_FLTK_Driver(int val) :
Fl_Native_File_Chooser_Driver(val) {
_btype = 0;
_options = 0;
_filter = NULL;
@ -243,7 +48,7 @@ Fl_FLTK_File_Chooser::Fl_FLTK_File_Chooser(int val) {
_nfilters = 0;
}
Fl_FLTK_File_Chooser::~Fl_FLTK_File_Chooser() {
Fl_Native_File_Chooser_FLTK_Driver::~Fl_Native_File_Chooser_FLTK_Driver() {
delete _file_chooser;
_file_chooser = NULL;
_filter = strfree(_filter);
@ -256,13 +61,13 @@ Fl_FLTK_File_Chooser::~Fl_FLTK_File_Chooser() {
// PRIVATE: SET ERROR MESSAGE
void Fl_FLTK_File_Chooser::errmsg(const char *msg) {
void Fl_Native_File_Chooser_FLTK_Driver::errmsg(const char *msg) {
_errmsg = strfree(_errmsg);
_errmsg = strnew(msg);
}
// PRIVATE: translate Native types to Fl_File_Chooser types
int Fl_FLTK_File_Chooser::type_fl_file(int val) {
int Fl_Native_File_Chooser_FLTK_Driver::type_fl_file(int val) {
switch (val) {
case Fl_Native_File_Chooser::BROWSE_FILE:
return(Fl_File_Chooser::SINGLE);
@ -281,24 +86,24 @@ int Fl_FLTK_File_Chooser::type_fl_file(int val) {
}
}
void Fl_FLTK_File_Chooser::type(int val) {
void Fl_Native_File_Chooser_FLTK_Driver::type(int val) {
_btype = val;
_file_chooser->type(type_fl_file(val));
}
int Fl_FLTK_File_Chooser::type() const {
int Fl_Native_File_Chooser_FLTK_Driver::type() const {
return(_btype);
}
void Fl_FLTK_File_Chooser::options(int val) {
void Fl_Native_File_Chooser_FLTK_Driver::options(int val) {
_options = val;
}
int Fl_FLTK_File_Chooser::options() const {
int Fl_Native_File_Chooser_FLTK_Driver::options() const {
return(_options);
}
int Fl_FLTK_File_Chooser::show() {
int Fl_Native_File_Chooser_FLTK_Driver::show() {
// FILTER
if ( _parsedfilt ) {
@ -345,7 +150,7 @@ int Fl_FLTK_File_Chooser::show() {
// HANDLE SHOWING 'SaveAs' CONFIRM
if ( options() & Fl_Native_File_Chooser::SAVEAS_CONFIRM && type() == Fl_Native_File_Chooser::BROWSE_SAVE_FILE ) {
struct stat buf;
if ( stat(_file_chooser->value(), &buf) != -1 ) {
if ( fl_stat(_file_chooser->value(), &buf) != -1 ) {
if ( buf.st_mode & S_IFREG ) { // Regular file + exists?
if ( exist_dialog() == 0 ) {
return(1);
@ -359,63 +164,63 @@ int Fl_FLTK_File_Chooser::show() {
else return(1);
}
const char *Fl_FLTK_File_Chooser::errmsg() const {
const char *Fl_Native_File_Chooser_FLTK_Driver::errmsg() const {
return(_errmsg ? _errmsg : "No error");
}
const char* Fl_FLTK_File_Chooser::filename() const {
const char* Fl_Native_File_Chooser_FLTK_Driver::filename() const {
if ( _file_chooser->count() > 0 ) {
return(_file_chooser->value());
}
return("");
}
const char* Fl_FLTK_File_Chooser::filename(int i) const {
const char* Fl_Native_File_Chooser_FLTK_Driver::filename(int i) const {
if ( i < _file_chooser->count() )
return(_file_chooser->value(i+1)); // convert fltk 1 based to our 0 based
return("");
}
void Fl_FLTK_File_Chooser::title(const char *val) {
void Fl_Native_File_Chooser_FLTK_Driver::title(const char *val) {
_file_chooser->label(val);
}
const char *Fl_FLTK_File_Chooser::title() const {
const char *Fl_Native_File_Chooser_FLTK_Driver::title() const {
return(_file_chooser->label());
}
void Fl_FLTK_File_Chooser::filter(const char *val) {
void Fl_Native_File_Chooser_FLTK_Driver::filter(const char *val) {
_filter = strfree(_filter);
_filter = strnew(val);
parse_filter();
}
const char *Fl_FLTK_File_Chooser::filter() const {
const char *Fl_Native_File_Chooser_FLTK_Driver::filter() const {
return(_filter);
}
int Fl_FLTK_File_Chooser::filters() const {
int Fl_Native_File_Chooser_FLTK_Driver::filters() const {
return(_nfilters);
}
void Fl_FLTK_File_Chooser::filter_value(int val) {
void Fl_Native_File_Chooser_FLTK_Driver::filter_value(int val) {
_filtvalue = val;
}
int Fl_FLTK_File_Chooser::filter_value() const {
int Fl_Native_File_Chooser_FLTK_Driver::filter_value() const {
return _filtvalue;
}
int Fl_FLTK_File_Chooser::count() const {
int Fl_Native_File_Chooser_FLTK_Driver::count() const {
return _file_chooser->count();
}
void Fl_FLTK_File_Chooser::directory(const char *val) {
void Fl_Native_File_Chooser_FLTK_Driver::directory(const char *val) {
_directory = strfree(_directory);
_directory = strnew(val);
}
const char *Fl_FLTK_File_Chooser::directory() const {
const char *Fl_Native_File_Chooser_FLTK_Driver::directory() const {
return _directory;
}
@ -429,7 +234,7 @@ const char *Fl_FLTK_File_Chooser::directory() const {
// Returns a modified version of the filter that the caller is responsible
// for freeing with strfree().
//
void Fl_FLTK_File_Chooser::parse_filter() {
void Fl_Native_File_Chooser_FLTK_Driver::parse_filter() {
_parsedfilt = strfree(_parsedfilt); // clear previous parsed filter (if any)
_nfilters = 0;
char *in = _filter;
@ -492,21 +297,19 @@ void Fl_FLTK_File_Chooser::parse_filter() {
//NOTREACHED
}
void Fl_FLTK_File_Chooser::preset_file(const char* val) {
void Fl_Native_File_Chooser_FLTK_Driver::preset_file(const char* val) {
_preset_file = strfree(_preset_file);
_preset_file = strnew(val);
}
const char* Fl_FLTK_File_Chooser::preset_file() const {
const char* Fl_Native_File_Chooser_FLTK_Driver::preset_file() const {
return _preset_file;
}
int Fl_FLTK_File_Chooser::exist_dialog() {
int Fl_Native_File_Chooser_FLTK_Driver::exist_dialog() {
return fl_choice("%s", fl_cancel, fl_ok, NULL, Fl_Native_File_Chooser::file_exists_message);
}
#endif
//
// End of "$Id$".
//

View File

@ -16,9 +16,11 @@
// http://www.fltk.org/str.php
//
#include <FL/x.H>
#include <config.h>
#ifdef USE_X11
#include <FL/x.H>
#include <FL/Fl_Native_File_Chooser.H>
#if HAVE_DLSYM && HAVE_DLFCN_H
#include <dlfcn.h> // for dlopen et al
@ -93,7 +95,51 @@ typedef void (*GClosureNotify)(gpointer data, GClosure *closure);
/* --------------------- End of Type definitions from GLIB and GTK --------------------- */
int Fl_GTK_File_Chooser::did_find_GTK_libs = 0;
class FL_EXPORT Fl_Native_File_Chooser_GTK_Driver : public Fl_Native_File_Chooser_FLTK_Driver {
friend class Fl_Native_File_Chooser;
private:
static int have_looked_for_GTK_libs;
typedef struct _GtkWidget GtkWidget;
typedef struct _GtkFileFilterInfo GtkFileFilterInfo;
struct pair {
Fl_Native_File_Chooser_GTK_Driver* running; // the running Fl_GTK_File_Chooser
const char *filter; // a filter string of the chooser
pair(Fl_Native_File_Chooser_GTK_Driver* c, const char *f) {
running = c;
filter = strdup(f);
};
~pair() {
free((char*)filter);
};
};
GtkWidget *gtkw_ptr; // used to hold a GtkWidget* without pulling GTK into everything...
void *gtkw_slist; // used to hold a GLib GSList...
unsigned gtkw_count; // number of files read back - if any
mutable char *gtkw_filename; // last name we read back
char *gtkw_title; // the title to be applied to the dialog
const char *previous_filter;
int fl_gtk_chooser_wrapper(); // method that wraps the GTK widget
Fl_Native_File_Chooser_GTK_Driver(int val);
virtual ~Fl_Native_File_Chooser_GTK_Driver();
static int did_find_GTK_libs;
static void probe_for_GTK_libs(void);
virtual void type(int);
virtual int count() const;
virtual const char *filename() const;
virtual const char *filename(int i) const;
virtual void title(const char *);
virtual const char* title() const;
virtual int show();
void changed_output_type(const char *filter);
static int custom_gtk_filter_function(const GtkFileFilterInfo*, Fl_Native_File_Chooser_GTK_Driver::pair*);
static void free_pair(pair *p);
};
int Fl_Native_File_Chooser_GTK_Driver::did_find_GTK_libs = 0;
/* These are the GTK/GLib methods we want to load, but not call by name...! */
@ -245,7 +291,26 @@ typedef void (*XX_gtk_toggle_button_set_active)(GtkToggleButton *, gboolean);
static XX_gtk_toggle_button_set_active fl_gtk_toggle_button_set_active = NULL;
Fl_GTK_File_Chooser::Fl_GTK_File_Chooser(int val) : Fl_FLTK_File_Chooser(-1)
int Fl_Native_File_Chooser_GTK_Driver::have_looked_for_GTK_libs = 0;
Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
if (Fl_Native_File_Chooser_GTK_Driver::have_looked_for_GTK_libs == 0) {
// First Time here, try to find the GTK libs if they are installed
#if HAVE_DLSYM && HAVE_DLFCN_H
if (Fl::option(Fl::OPTION_FNFC_USES_GTK)) {
Fl_Native_File_Chooser_GTK_Driver::probe_for_GTK_libs();
}
#endif
Fl_Native_File_Chooser_GTK_Driver::have_looked_for_GTK_libs = -1;
}
// if we found all the GTK functions we need, we will use the GtkFileChooserDialog
if (Fl_Native_File_Chooser_GTK_Driver::did_find_GTK_libs) platform_fnfc = new Fl_Native_File_Chooser_GTK_Driver(val);
else platform_fnfc = new Fl_Native_File_Chooser_FLTK_Driver(val);
}
Fl_Native_File_Chooser_GTK_Driver::Fl_Native_File_Chooser_GTK_Driver(int val) : Fl_Native_File_Chooser_FLTK_Driver(-1)
{
gtkw_ptr = NULL; // used to hold a GtkWidget*
gtkw_slist = NULL; // will hold the returned file names in a multi-selection...
@ -256,7 +321,7 @@ Fl_GTK_File_Chooser::Fl_GTK_File_Chooser(int val) : Fl_FLTK_File_Chooser(-1)
previous_filter = NULL;
}
Fl_GTK_File_Chooser::~Fl_GTK_File_Chooser()
Fl_Native_File_Chooser_GTK_Driver::~Fl_Native_File_Chooser_GTK_Driver()
{
// Should free up resources taken for...
if(gtkw_ptr) {
@ -280,15 +345,15 @@ Fl_GTK_File_Chooser::~Fl_GTK_File_Chooser()
gtkw_title = strfree(gtkw_title);
}
void Fl_GTK_File_Chooser::type(int val) {
void Fl_Native_File_Chooser_GTK_Driver::type(int val) {
_btype = val;
}
int Fl_GTK_File_Chooser::count() const {
int Fl_Native_File_Chooser_GTK_Driver::count() const {
return gtkw_count;
}
const char *Fl_GTK_File_Chooser::filename() const
const char *Fl_Native_File_Chooser_GTK_Driver::filename() const
{
if(gtkw_ptr) {
if(fl_gtk_file_chooser_get_select_multiple((GtkFileChooser *)gtkw_ptr) == FALSE) {
@ -303,7 +368,7 @@ const char *Fl_GTK_File_Chooser::filename() const
return("");
}
const char *Fl_GTK_File_Chooser::filename(int i) const
const char *Fl_Native_File_Chooser_GTK_Driver::filename(int i) const
{
if(fl_gtk_file_chooser_get_select_multiple((GtkFileChooser *)gtkw_ptr) == FALSE) {
return gtkw_filename;
@ -318,19 +383,19 @@ const char *Fl_GTK_File_Chooser::filename(int i) const
return("");
}
void Fl_GTK_File_Chooser::title(const char *val)
void Fl_Native_File_Chooser_GTK_Driver::title(const char *val)
{
strfree(gtkw_title);
gtkw_title = strnew(val);
}
const char* Fl_GTK_File_Chooser::title() const
const char* Fl_Native_File_Chooser_GTK_Driver::title() const
{
return gtkw_title;
}
/* changes the extension of the outfile in the chooser according to newly selected filter */
void Fl_GTK_File_Chooser::changed_output_type(const char *filter)
void Fl_Native_File_Chooser_GTK_Driver::changed_output_type(const char *filter)
{
if ( !(options()&Fl_Native_File_Chooser::USE_FILTER_EXT) ) return;
if (strchr(filter, '(') || strchr(filter, '{') || strchr(filter+1, '*') || strncmp(filter, "*.", 2)) return;
@ -348,7 +413,7 @@ void Fl_GTK_File_Chooser::changed_output_type(const char *filter)
/* Filters files before display in chooser.
Also used to detect when the filter just changed */
gboolean Fl_GTK_File_Chooser::custom_gtk_filter_function(const GtkFileFilterInfo *info, Fl_GTK_File_Chooser::pair* p)
gboolean Fl_Native_File_Chooser_GTK_Driver::custom_gtk_filter_function(const GtkFileFilterInfo *info, Fl_Native_File_Chooser_GTK_Driver::pair* p)
{
if (p->running->previous_filter != p->filter) {
p->running->changed_output_type(p->filter);
@ -357,7 +422,7 @@ gboolean Fl_GTK_File_Chooser::custom_gtk_filter_function(const GtkFileFilterInfo
return (gboolean)fl_filename_match(fl_filename_name(info->filename), p->filter);
}
void Fl_GTK_File_Chooser::free_pair(Fl_GTK_File_Chooser::pair *p)
void Fl_Native_File_Chooser_GTK_Driver::free_pair(Fl_Native_File_Chooser_GTK_Driver::pair *p)
{
delete p;
}
@ -368,7 +433,7 @@ static void hidden_files_cb(GtkToggleButton *togglebutton, gpointer user_data)
fl_gtk_file_chooser_set_show_hidden((GtkFileChooser*)user_data, state);
}
int Fl_GTK_File_Chooser::show()
int Fl_Native_File_Chooser_GTK_Driver::show()
{
// The point here is that after running a GTK dialog, the calling program's current locale is modified.
// To avoid that, we memorize the calling program's current locale, and the locale as modified
@ -424,7 +489,7 @@ static void run_response_handler(GtkDialog *dialog, gint response_id, gpointer d
}
int Fl_GTK_File_Chooser::fl_gtk_chooser_wrapper()
int Fl_Native_File_Chooser_GTK_Driver::fl_gtk_chooser_wrapper()
{
int result = 1;
static int have_gtk_init = 0;
@ -521,9 +586,9 @@ int Fl_GTK_File_Chooser::fl_gtk_chooser_wrapper()
char *q = strchr(p, ')'); *q = 0;
fl_gtk_file_filter_add_custom(filter_tab[count],
GTK_FILE_FILTER_FILENAME,
(GtkFileFilterFunc)Fl_GTK_File_Chooser::custom_gtk_filter_function,
new Fl_GTK_File_Chooser::pair(this, p),
(GDestroyNotify)Fl_GTK_File_Chooser::free_pair);
(GtkFileFilterFunc)Fl_Native_File_Chooser_GTK_Driver::custom_gtk_filter_function,
new Fl_Native_File_Chooser_GTK_Driver::pair(this, p),
(GDestroyNotify)Fl_Native_File_Chooser_GTK_Driver::free_pair);
fl_gtk_file_chooser_add_filter((GtkFileChooser *)gtkw_ptr, filter_tab[count]);
p = strtok(NULL, "\t");
count++;
@ -642,14 +707,14 @@ static void* fl_dlopen(const char *filename1, const char *filename2)
if (!ptr) ptr = dlopen(filename2, RTLD_LAZY | RTLD_GLOBAL);
return ptr;
}
#endif
#endif // HAVE_DLSYM && HAVE_DLFCN_H
/*
* Use dlopen to see if we can load the gtk dynamic libraries that
* will allow us to create a GtkFileChooserDialog() on the fly,
* without linking to the GTK libs at compile time.
*/
void Fl_GTK_File_Chooser::probe_for_GTK_libs(void) {
void Fl_Native_File_Chooser_GTK_Driver::probe_for_GTK_libs(void) {
#if HAVE_DLSYM && HAVE_DLFCN_H
void *ptr_glib = NULL;
void *ptr_gtk = NULL;
@ -728,10 +793,10 @@ void Fl_GTK_File_Chooser::probe_for_GTK_libs(void) {
GET_SYM(gtk_toggle_button_set_active, ptr_gtk);
did_find_GTK_libs = 1;
#endif
#endif // HAVE_DLSYM && HAVE_DLFCN_H
} // probe_for_GTK_libs
#endif
#endif // USE_X11
//
// End of "$Id$".

View File

@ -23,7 +23,6 @@
#ifdef __APPLE__
#include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat
#include <libgen.h> // dirname(3)
#include <sys/types.h> // stat(2)
#include <sys/stat.h> // stat(2)
@ -34,9 +33,74 @@
#include <FL/Fl_Native_File_Chooser.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/filename.H>
# define MAXFILTERS 80
class Fl_Native_File_Chooser_Darwin_Driver : public Fl_Native_File_Chooser_Driver {
private:
int _btype; // kind-of browser to show()
int _options; // general options
void *_panel;
char **_pathnames; // array of pathnames
int _tpathnames; // total pathnames
char *_directory; // default pathname to use
char *_title; // title for window
char *_preset_file; // the 'save as' filename
char *_filter; // user-side search filter, eg:
// C Files\t*.[ch]\nText Files\t*.txt"
char *_filt_names; // filter names (tab delimited)
// eg. "C Files\tText Files"
char *_filt_patt[MAXFILTERS];
// array of filter patterns, eg:
// _filt_patt[0]="*.{cxx,h}"
// _filt_patt[1]="*.txt"
int _filt_total; // parse_filter() # of filters loaded
int _filt_value; // index of the selected filter
char *_errmsg; // error message
// Private methods
void errmsg(const char *msg);
void clear_pathnames();
void set_single_pathname(const char *s);
int get_saveas_basename(void);
void clear_filters();
void parse_filter(const char *from);
int post();
int runmodal();
public:
Fl_Native_File_Chooser_Darwin_Driver(int val);
~Fl_Native_File_Chooser_Darwin_Driver();
virtual void type(int t);
virtual int type() const ;
virtual void options(int o);
virtual int options() const;
virtual int count() const;
virtual const char *filename() const ;
virtual const char *filename(int i) const ;
virtual void directory(const char *val) ;
virtual const char *directory() const;
virtual void title(const char *t);
virtual const char* title() const;
virtual const char *filter() const ;
virtual void filter(const char *f);
virtual int filters() const ;
virtual void filter_value(int i) ;
virtual int filter_value() const ;
virtual void preset_file(const char*f) ;
virtual const char* preset_file() const;
virtual const char *errmsg() const ;
virtual int show() ;
};
Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
platform_fnfc = new Fl_Native_File_Chooser_Darwin_Driver(val);
}
// FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS
void Fl_Native_File_Chooser::clear_pathnames() {
void Fl_Native_File_Chooser_Darwin_Driver::clear_pathnames() {
if ( _pathnames ) {
while ( --_tpathnames >= 0 ) {
_pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]);
@ -48,7 +112,7 @@ void Fl_Native_File_Chooser::clear_pathnames() {
}
// SET A SINGLE PATHNAME
void Fl_Native_File_Chooser::set_single_pathname(const char *s) {
void Fl_Native_File_Chooser_Darwin_Driver::set_single_pathname(const char *s) {
clear_pathnames();
_pathnames = new char*[1];
_pathnames[0] = strnew(s);
@ -56,10 +120,11 @@ void Fl_Native_File_Chooser::set_single_pathname(const char *s) {
}
// CONSTRUCTOR
Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
Fl_Native_File_Chooser_Darwin_Driver::Fl_Native_File_Chooser_Darwin_Driver(int val) :
Fl_Native_File_Chooser_Driver(val) {
_btype = val;
_panel = NULL;
_options = NO_OPTIONS;
_options = Fl_Native_File_Chooser::NO_OPTIONS;
_pathnames = NULL;
_tpathnames = 0;
_title = NULL;
@ -74,7 +139,7 @@ Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
}
// DESTRUCTOR
Fl_Native_File_Chooser::~Fl_Native_File_Chooser() {
Fl_Native_File_Chooser_Darwin_Driver::~Fl_Native_File_Chooser_Darwin_Driver() {
// _opts // nothing to manage
// _options // nothing to manage
// _keepstate // nothing to manage
@ -93,17 +158,17 @@ Fl_Native_File_Chooser::~Fl_Native_File_Chooser() {
}
// GET TYPE OF BROWSER
int Fl_Native_File_Chooser::type() const {
int Fl_Native_File_Chooser_Darwin_Driver::type() const {
return(_btype);
}
// SET OPTIONS
void Fl_Native_File_Chooser::options(int val) {
void Fl_Native_File_Chooser_Darwin_Driver::options(int val) {
_options = val;
}
// GET OPTIONS
int Fl_Native_File_Chooser::options() const {
int Fl_Native_File_Chooser_Darwin_Driver::options() const {
return(_options);
}
@ -113,7 +178,7 @@ int Fl_Native_File_Chooser::options() const {
// 1 - user cancelled
// -1 - failed; errmsg() has reason
//
int Fl_Native_File_Chooser::show() {
int Fl_Native_File_Chooser_Darwin_Driver::show() {
// Make sure fltk interface updates before posting our dialog
Fl::flush();
@ -127,37 +192,37 @@ int Fl_Native_File_Chooser::show() {
// SET ERROR MESSAGE
// Internal use only.
//
void Fl_Native_File_Chooser::errmsg(const char *msg) {
void Fl_Native_File_Chooser_Darwin_Driver::errmsg(const char *msg) {
_errmsg = strfree(_errmsg);
_errmsg = strnew(msg);
}
// RETURN ERROR MESSAGE
const char *Fl_Native_File_Chooser::errmsg() const {
const char *Fl_Native_File_Chooser_Darwin_Driver::errmsg() const {
return(_errmsg ? _errmsg : "No error");
}
// GET FILENAME
const char* Fl_Native_File_Chooser::filename() const {
const char* Fl_Native_File_Chooser_Darwin_Driver::filename() const {
if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]);
return("");
}
// GET FILENAME FROM LIST OF FILENAMES
const char* Fl_Native_File_Chooser::filename(int i) const {
const char* Fl_Native_File_Chooser_Darwin_Driver::filename(int i) const {
if ( _pathnames && i < _tpathnames ) return(_pathnames[i]);
return("");
}
// GET TOTAL FILENAMES CHOSEN
int Fl_Native_File_Chooser::count() const {
int Fl_Native_File_Chooser_Darwin_Driver::count() const {
return(_tpathnames);
}
// PRESET PATHNAME
// Value can be NULL for none.
//
void Fl_Native_File_Chooser::directory(const char *val) {
void Fl_Native_File_Chooser_Darwin_Driver::directory(const char *val) {
_directory = strfree(_directory);
_directory = strnew(val);
}
@ -165,14 +230,14 @@ void Fl_Native_File_Chooser::directory(const char *val) {
// GET PRESET PATHNAME
// Returned value can be NULL if none set.
//
const char* Fl_Native_File_Chooser::directory() const {
const char* Fl_Native_File_Chooser_Darwin_Driver::directory() const {
return(_directory);
}
// SET TITLE
// Value can be NULL if no title desired.
//
void Fl_Native_File_Chooser::title(const char *val) {
void Fl_Native_File_Chooser_Darwin_Driver::title(const char *val) {
_title = strfree(_title);
_title = strnew(val);
}
@ -180,14 +245,14 @@ void Fl_Native_File_Chooser::title(const char *val) {
// GET TITLE
// Returned value can be NULL if none set.
//
const char *Fl_Native_File_Chooser::title() const {
const char *Fl_Native_File_Chooser_Darwin_Driver::title() const {
return(_title);
}
// SET FILTER
// Can be NULL if no filter needed
//
void Fl_Native_File_Chooser::filter(const char *val) {
void Fl_Native_File_Chooser_Darwin_Driver::filter(const char *val) {
_filter = strfree(_filter);
_filter = strnew(val);
@ -204,14 +269,14 @@ void Fl_Native_File_Chooser::filter(const char *val) {
// GET FILTER
// Returned value can be NULL if none set.
//
const char *Fl_Native_File_Chooser::filter() const {
const char *Fl_Native_File_Chooser_Darwin_Driver::filter() const {
return(_filter);
}
// CLEAR ALL FILTERS
// Internal use only.
//
void Fl_Native_File_Chooser::clear_filters() {
void Fl_Native_File_Chooser_Darwin_Driver::clear_filters() {
_filt_names = strfree(_filt_names);
for (int i=0; i<_filt_total; i++) {
_filt_patt[i] = strfree(_filt_patt[i]);
@ -239,7 +304,7 @@ void Fl_Native_File_Chooser::clear_filters() {
// \_____/ \_______/
// Name Wildcard
//
void Fl_Native_File_Chooser::parse_filter(const char *in) {
void Fl_Native_File_Chooser_Darwin_Driver::parse_filter(const char *in) {
clear_filters();
if ( ! in ) return;
int has_name = strchr(in, '\t') ? 1 : 0;
@ -285,7 +350,7 @@ void Fl_Native_File_Chooser::parse_filter(const char *in) {
// CFStringCreateArrayBySeparatingStrings()
//
if ( _filt_total ) {
_filt_names = strapp(_filt_names, "\t");
_filt_names = strapp(_filt_names, "\t");
}
_filt_names = strapp(_filt_names, name);
@ -303,8 +368,8 @@ void Fl_Native_File_Chooser::parse_filter(const char *in) {
default: // handle all non-special chars
regchar: // handle regular char
switch ( mode ) {
case 'n': chrcat(name, *in); continue;
case 'w': chrcat(wildcard, *in); continue;
case 'n': chrcat(name, *in); continue;
case 'w': chrcat(wildcard, *in); continue;
}
break;
}
@ -315,7 +380,7 @@ void Fl_Native_File_Chooser::parse_filter(const char *in) {
// SET PRESET FILE
// Value can be NULL for none.
//
void Fl_Native_File_Chooser::preset_file(const char* val) {
void Fl_Native_File_Chooser_Darwin_Driver::preset_file(const char* val) {
_preset_file = strfree(_preset_file);
_preset_file = strnew(val);
}
@ -323,28 +388,28 @@ void Fl_Native_File_Chooser::preset_file(const char* val) {
// PRESET FILE
// Returned value can be NULL if none set.
//
const char* Fl_Native_File_Chooser::preset_file() const {
const char* Fl_Native_File_Chooser_Darwin_Driver::preset_file() const {
return(_preset_file);
}
void Fl_Native_File_Chooser::filter_value(int val) {
void Fl_Native_File_Chooser_Darwin_Driver::filter_value(int val) {
_filt_value = val;
}
int Fl_Native_File_Chooser::filter_value() const {
int Fl_Native_File_Chooser_Darwin_Driver::filter_value() const {
return(_filt_value);
}
int Fl_Native_File_Chooser::filters() const {
int Fl_Native_File_Chooser_Darwin_Driver::filters() const {
return(_filt_total);
}
#import <Cocoa/Cocoa.h>
#define UNLIKELYPREFIX "___fl_very_unlikely_prefix_"
int Fl_Native_File_Chooser::get_saveas_basename(void) {
int Fl_Native_File_Chooser_Darwin_Driver::get_saveas_basename(void) {
char *q = strdup( [[[(NSSavePanel*)_panel URL] path] UTF8String] );
if ( !(_options & SAVEAS_CONFIRM) ) {
if ( !(_options & Fl_Native_File_Chooser::SAVEAS_CONFIRM) ) {
const char *d = [[[[(NSSavePanel*)_panel URL] path] stringByDeletingLastPathComponent] UTF8String];
int l = (int)strlen(d) + 1;
if (strcmp(d, "/") == 0) l = 1;
@ -358,7 +423,7 @@ int Fl_Native_File_Chooser::get_saveas_basename(void) {
}
// SET THE TYPE OF BROWSER
void Fl_Native_File_Chooser::type(int val) {
void Fl_Native_File_Chooser_Darwin_Driver::type(int val) {
_btype = val;
}
@ -527,7 +592,7 @@ static NSPopUpButton *createPopupAccessory(NSSavePanel *panel, const char *filte
return popup;
}
int Fl_Native_File_Chooser::runmodal()
int Fl_Native_File_Chooser_Darwin_Driver::runmodal()
{
NSString *dir = nil;
NSString *fname = nil;
@ -563,7 +628,7 @@ int Fl_Native_File_Chooser::runmodal()
// 1 - user cancelled
// -1 - failed; errmsg() has reason
//
int Fl_Native_File_Chooser::post() {
int Fl_Native_File_Chooser_Darwin_Driver::post() {
// INITIALIZE BROWSER
if ( _filt_total == 0 ) { // Make sure they match
_filt_value = 0; // TBD: move to someplace more logical?
@ -571,30 +636,30 @@ int Fl_Native_File_Chooser::post() {
NSAutoreleasePool *localPool;
localPool = [[NSAutoreleasePool alloc] init];
switch (_btype) {
case BROWSE_FILE:
case BROWSE_MULTI_FILE:
case BROWSE_DIRECTORY:
case BROWSE_MULTI_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_FILE:
case Fl_Native_File_Chooser::BROWSE_MULTI_FILE:
case Fl_Native_File_Chooser::BROWSE_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY:
_panel = [NSOpenPanel openPanel];
break;
case BROWSE_SAVE_DIRECTORY:
case BROWSE_SAVE_FILE:
case Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_SAVE_FILE:
_panel = [NSSavePanel savePanel];
break;
}
NSString *nstitle = [NSString stringWithUTF8String: (_title ? _title : "No Title")];
[(NSSavePanel*)_panel setTitle:nstitle];
switch (_btype) {
case BROWSE_MULTI_FILE:
case Fl_Native_File_Chooser::BROWSE_MULTI_FILE:
[(NSOpenPanel*)_panel setAllowsMultipleSelection:YES];
break;
case BROWSE_MULTI_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY:
[(NSOpenPanel*)_panel setAllowsMultipleSelection:YES];
/* FALLTHROUGH */
case BROWSE_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_DIRECTORY:
[(NSOpenPanel*)_panel setCanChooseDirectories:YES];
break;
case BROWSE_SAVE_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY:
[(NSSavePanel*)_panel setCanCreateDirectories:YES];
break;
}
@ -621,13 +686,13 @@ int Fl_Native_File_Chooser::post() {
FLsaveDelegate *saveDelegate = [[[FLsaveDelegate alloc] init] autorelease];
[(NSSavePanel*)_panel setAllowsOtherFileTypes:YES];
[(NSSavePanel*)_panel setDelegate:saveDelegate];
[saveDelegate option:(_options & SAVEAS_CONFIRM)];
[saveDelegate option:(_options & Fl_Native_File_Chooser::SAVEAS_CONFIRM)];
if (_filt_total) {
if (_filt_value >= _filt_total) _filt_value = _filt_total - 1;
char *t = prepareMacFilter(_filt_total, _filter, _filt_patt);
popup = createPopupAccessory((NSSavePanel*)_panel, t, [[(NSSavePanel*)_panel nameFieldLabel] UTF8String], _filt_value);
delete[] t;
if (_options & USE_FILTER_EXT) {
if (_options & Fl_Native_File_Chooser::USE_FILTER_EXT) {
[popup setAction:@selector(changedPopup:)];
[popup setTarget:saveDelegate];
[saveDelegate panel:(NSSavePanel*)_panel];

View File

@ -2,7 +2,7 @@
//
// FLTK native OS file chooser widget
//
// Copyright 1998-2014 by Bill Spitzak and others.
// Copyright 1998-2016 by Bill Spitzak and others.
// Copyright 2004 Greg Ercolano.
// API changes + filter improvements by Nathan Vander Wilt 2005
//
@ -28,15 +28,83 @@
#include <stdio.h> // sprintf
#include <wchar.h>
#include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat
#define FNFC_MAX_PATH 32768 // XXX: MAX_PATH under win32 is 260, too small for modern use
#include <FL/Fl_Native_File_Chooser.H>
# include <windows.h>
# include <commdlg.h> // OPENFILENAMEW, GetOpenFileName()
# include <shlobj.h> // BROWSEINFOW, SHBrowseForFolder()
# include <FL/filename.H> // FL_EXPORT
#include <FL/x.H> // for fl_open_display
class Fl_Native_File_Chooser_WinAPI_Driver : public Fl_Native_File_Chooser_Driver {
private:
int _btype; // kind-of browser to show()
int _options; // general options
OPENFILENAMEW *_ofn_ptr; // GetOpenFileName() & GetSaveFileName() struct
BROWSEINFOW *_binf_ptr; // SHBrowseForFolder() struct
char **_pathnames; // array of pathnames
int _tpathnames; // total pathnames
char *_directory; // default pathname to use
char *_title; // title for window
char *_filter; // user-side search filter
char *_parsedfilt; // filter parsed for Windows dialog
int _nfilters; // number of filters parse_filter counted
char *_preset_file; // the file to preselect
char *_errmsg; // error message
// Private methods
void errmsg(const char *msg);
void clear_pathnames();
void set_single_pathname(const char *s);
void add_pathname(const char *s);
void ClearOFN();
void ClearBINF();
void Win2Unix(char *s);
void Unix2Win(char *s);
int showfile();
int showdir();
void parse_filter(const char *);
void clear_filters();
void add_filter(const char *, const char *);
public:
Fl_Native_File_Chooser_WinAPI_Driver(int val);
~Fl_Native_File_Chooser_WinAPI_Driver();
virtual void type(int t);
virtual int type() const ;
virtual void options(int o);
virtual int options() const;
virtual int count() const;
virtual const char *filename() const ;
virtual const char *filename(int i) const ;
virtual void directory(const char *val) ;
virtual const char *directory() const;
virtual void title(const char *t);
virtual const char* title() const;
virtual const char *filter() const ;
virtual void filter(const char *f);
virtual int filters() const ;
virtual void filter_value(int i) ;
virtual int filter_value() const ;
virtual void preset_file(const char*f) ;
virtual const char* preset_file() const;
virtual const char *errmsg() const ;
virtual int show() ;
};
Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
platform_fnfc = new Fl_Native_File_Chooser_WinAPI_Driver(val);
}
static LPCWSTR utf8towchar(const char *in);
static char *wchartoutf8(LPCWSTR in);
#include <FL/x.H> // for fl_open_display
#define LCURLY_CHR '{'
#define RCURLY_CHR '}'
@ -125,10 +193,11 @@ static void dnullcat(char*&wp, const char *string, int n = -1 ) {
}
// CTOR
Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
Fl_Native_File_Chooser_WinAPI_Driver::Fl_Native_File_Chooser_WinAPI_Driver(int val) :
Fl_Native_File_Chooser_Driver(val) {
_btype = val;
_options = NO_OPTIONS;
_ofn_ptr = new OPENFILENAMEW;
_options = Fl_Native_File_Chooser::NO_OPTIONS;
_ofn_ptr = new OPENFILENAMEW;
_binf_ptr = new BROWSEINFOW;
memset((void*)_ofn_ptr, 0, sizeof(OPENFILENAMEW));
_ofn_ptr->lStructSize = sizeof(OPENFILENAMEW);
@ -146,7 +215,7 @@ Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
}
// DTOR
Fl_Native_File_Chooser::~Fl_Native_File_Chooser() {
Fl_Native_File_Chooser_WinAPI_Driver::~Fl_Native_File_Chooser_WinAPI_Driver() {
//_pathnames // managed by clear_pathnames()
//_tpathnames // managed by clear_pathnames()
_directory = strfree(_directory);
@ -165,33 +234,33 @@ Fl_Native_File_Chooser::~Fl_Native_File_Chooser() {
}
// SET TYPE OF BROWSER
void Fl_Native_File_Chooser::type(int val) {
void Fl_Native_File_Chooser_WinAPI_Driver::type(int val) {
_btype = val;
}
// GET TYPE OF BROWSER
int Fl_Native_File_Chooser::type() const {
int Fl_Native_File_Chooser_WinAPI_Driver::type() const {
return( _btype );
}
// SET OPTIONS
void Fl_Native_File_Chooser::options(int val) {
void Fl_Native_File_Chooser_WinAPI_Driver::options(int val) {
_options = val;
}
// GET OPTIONS
int Fl_Native_File_Chooser::options() const {
int Fl_Native_File_Chooser_WinAPI_Driver::options() const {
return(_options);
}
// PRIVATE: SET ERROR MESSAGE
void Fl_Native_File_Chooser::errmsg(const char *val) {
void Fl_Native_File_Chooser_WinAPI_Driver::errmsg(const char *val) {
_errmsg = strfree(_errmsg);
_errmsg = strnew(val);
}
// FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS
void Fl_Native_File_Chooser::clear_pathnames() {
void Fl_Native_File_Chooser_WinAPI_Driver::clear_pathnames() {
if ( _pathnames ) {
while ( --_tpathnames >= 0 ) {
_pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]);
@ -203,7 +272,7 @@ void Fl_Native_File_Chooser::clear_pathnames() {
}
// SET A SINGLE PATHNAME
void Fl_Native_File_Chooser::set_single_pathname(const char *s) {
void Fl_Native_File_Chooser_WinAPI_Driver::set_single_pathname(const char *s) {
clear_pathnames();
_pathnames = new char*[1];
_pathnames[0] = strnew(s);
@ -211,7 +280,7 @@ void Fl_Native_File_Chooser::set_single_pathname(const char *s) {
}
// ADD PATHNAME TO EXISTING ARRAY
void Fl_Native_File_Chooser::add_pathname(const char *s) {
void Fl_Native_File_Chooser_WinAPI_Driver::add_pathname(const char *s) {
if ( ! _pathnames ) {
// Create first element in array
++_tpathnames;
@ -239,7 +308,7 @@ static void FreePIDL(LPITEMIDLIST pidl) {
}
// CLEAR MICROSOFT OFN (OPEN FILE NAME) CLASS
void Fl_Native_File_Chooser::ClearOFN() {
void Fl_Native_File_Chooser_WinAPI_Driver::ClearOFN() {
// Free any previously allocated lpstrFile before zeroing out _ofn_ptr
if ( _ofn_ptr->lpstrFile ) {
delete[] _ofn_ptr->lpstrFile;
@ -257,7 +326,7 @@ void Fl_Native_File_Chooser::ClearOFN() {
}
// CLEAR MICROSOFT BINF (BROWSER INFO) CLASS
void Fl_Native_File_Chooser::ClearBINF() {
void Fl_Native_File_Chooser_WinAPI_Driver::ClearBINF() {
if ( _binf_ptr->pidlRoot ) {
FreePIDL((ITEMIDLIST*)_binf_ptr->pidlRoot);
_binf_ptr->pidlRoot = NULL;
@ -266,19 +335,19 @@ void Fl_Native_File_Chooser::ClearBINF() {
}
// CONVERT WINDOWS BACKSLASHES TO UNIX FRONTSLASHES
void Fl_Native_File_Chooser::Win2Unix(char *s) {
void Fl_Native_File_Chooser_WinAPI_Driver::Win2Unix(char *s) {
for ( ; *s; s++ )
if ( *s == '\\' ) *s = '/';
}
// CONVERT UNIX FRONTSLASHES TO WINDOWS BACKSLASHES
void Fl_Native_File_Chooser::Unix2Win(char *s) {
void Fl_Native_File_Chooser_WinAPI_Driver::Unix2Win(char *s) {
for ( ; *s; s++ )
if ( *s == '/' ) *s = '\\';
}
// SHOW FILE BROWSER
int Fl_Native_File_Chooser::showfile() {
int Fl_Native_File_Chooser_WinAPI_Driver::showfile() {
ClearOFN();
clear_pathnames();
size_t fsize = FNFC_MAX_PATH;
@ -294,17 +363,17 @@ int Fl_Native_File_Chooser::showfile() {
_ofn_ptr->Flags |= OFN_NOCHANGEDIR; // prevent dialog for messing up the cwd
switch ( _btype ) {
case BROWSE_DIRECTORY:
case BROWSE_MULTI_DIRECTORY:
case BROWSE_SAVE_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY:
abort(); // never happens: handled by showdir()
case BROWSE_FILE:
case Fl_Native_File_Chooser::BROWSE_FILE:
break;
case BROWSE_MULTI_FILE:
case Fl_Native_File_Chooser::BROWSE_MULTI_FILE:
_ofn_ptr->Flags |= OFN_ALLOWMULTISELECT;
break;
case BROWSE_SAVE_FILE:
if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) {
case Fl_Native_File_Chooser::BROWSE_SAVE_FILE:
if ( options() & Fl_Native_File_Chooser::SAVEAS_CONFIRM && type() == Fl_Native_File_Chooser::BROWSE_SAVE_FILE ) {
_ofn_ptr->Flags |= OFN_OVERWRITEPROMPT;
}
break;
@ -376,7 +445,7 @@ int Fl_Native_File_Chooser::showfile() {
}
// OPEN THE DIALOG WINDOW
int err;
if ( _btype == BROWSE_SAVE_FILE ) {
if ( _btype == Fl_Native_File_Chooser::BROWSE_SAVE_FILE ) {
err = GetSaveFileNameW(_ofn_ptr);
} else {
err = GetOpenFileNameW(_ofn_ptr);
@ -399,12 +468,12 @@ int Fl_Native_File_Chooser::showfile() {
}
// PREPARE PATHNAMES FOR RETURN
switch ( _btype ) {
case BROWSE_FILE:
case BROWSE_SAVE_FILE:
case Fl_Native_File_Chooser::BROWSE_FILE:
case Fl_Native_File_Chooser::BROWSE_SAVE_FILE:
set_single_pathname(wchartoutf8(_ofn_ptr->lpstrFile));
// Win2Unix(_pathnames[_tpathnames-1]);
break;
case BROWSE_MULTI_FILE: {
case Fl_Native_File_Chooser::BROWSE_MULTI_FILE: {
// EXTRACT MULTIPLE FILENAMES
const WCHAR *dirname = _ofn_ptr->lpstrFile;
size_t dirlen = wcslen(dirname);
@ -432,9 +501,9 @@ int Fl_Native_File_Chooser::showfile() {
}
break;
}
case BROWSE_DIRECTORY:
case BROWSE_MULTI_DIRECTORY:
case BROWSE_SAVE_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY:
case Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY:
abort(); // never happens: handled by showdir()
}
return(0);
@ -469,7 +538,7 @@ static int CALLBACK Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data) {
}
// SHOW DIRECTORY BROWSER
int Fl_Native_File_Chooser::showdir() {
int Fl_Native_File_Chooser_WinAPI_Driver::showdir() {
// initialize OLE only once
fl_open_display(); // init needed by BIF_USENEWUI
ClearBINF();
@ -506,11 +575,11 @@ int Fl_Native_File_Chooser::showdir() {
// ---
#if defined(BIF_NONEWFOLDERBUTTON) // Version 6.0
if ( _btype == BROWSE_DIRECTORY ) _binf_ptr->ulFlags |= BIF_NONEWFOLDERBUTTON;
if ( _btype == Fl_Native_File_Chooser::BROWSE_DIRECTORY ) _binf_ptr->ulFlags |= BIF_NONEWFOLDERBUTTON;
_binf_ptr->ulFlags |= BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
#elif defined(BIF_USENEWUI) // Version 5.0
if ( _btype == BROWSE_DIRECTORY ) _binf_ptr->ulFlags |= BIF_EDITBOX;
else if ( _btype == BROWSE_SAVE_DIRECTORY ) _binf_ptr->ulFlags |= BIF_USENEWUI;
if ( _btype == Fl_Native_File_Chooser::BROWSE_DIRECTORY ) _binf_ptr->ulFlags |= BIF_EDITBOX;
else if ( _btype == Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY ) _binf_ptr->ulFlags |= BIF_USENEWUI;
_binf_ptr->ulFlags |= BIF_RETURNONLYFSDIRS;
#elif defined(BIF_EDITBOX) // Version 4.71
_binf_ptr->ulFlags |= BIF_RETURNONLYFSDIRS | BIF_EDITBOX;
@ -558,11 +627,11 @@ int Fl_Native_File_Chooser::showdir() {
// 1 - user cancelled
// -1 - failed; errmsg() has reason
//
int Fl_Native_File_Chooser::show() {
int Fl_Native_File_Chooser_WinAPI_Driver::show() {
int retval;
if ( _btype == BROWSE_DIRECTORY ||
_btype == BROWSE_MULTI_DIRECTORY ||
_btype == BROWSE_SAVE_DIRECTORY ) {
if ( _btype == Fl_Native_File_Chooser::BROWSE_DIRECTORY ||
_btype == Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY ||
_btype == Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY ) {
retval = showdir();
} else {
retval = showfile();
@ -577,31 +646,31 @@ int Fl_Native_File_Chooser::show() {
}
// RETURN ERROR MESSAGE
const char *Fl_Native_File_Chooser::errmsg() const {
const char *Fl_Native_File_Chooser_WinAPI_Driver::errmsg() const {
return(_errmsg ? _errmsg : "No error");
}
// GET FILENAME
const char* Fl_Native_File_Chooser::filename() const {
const char* Fl_Native_File_Chooser_WinAPI_Driver::filename() const {
if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]);
return("");
}
// GET FILENAME FROM LIST OF FILENAMES
const char* Fl_Native_File_Chooser::filename(int i) const {
const char* Fl_Native_File_Chooser_WinAPI_Driver::filename(int i) const {
if ( _pathnames && i < _tpathnames ) return(_pathnames[i]);
return("");
}
// GET TOTAL FILENAMES CHOSEN
int Fl_Native_File_Chooser::count() const {
int Fl_Native_File_Chooser_WinAPI_Driver::count() const {
return(_tpathnames);
}
// PRESET PATHNAME
// Can be NULL if no preset is desired.
//
void Fl_Native_File_Chooser::directory(const char *val) {
void Fl_Native_File_Chooser_WinAPI_Driver::directory(const char *val) {
_directory = strfree(_directory);
_directory = strnew(val);
}
@ -609,14 +678,14 @@ void Fl_Native_File_Chooser::directory(const char *val) {
// GET PRESET PATHNAME
// Can return NULL if none set.
//
const char *Fl_Native_File_Chooser::directory() const {
const char *Fl_Native_File_Chooser_WinAPI_Driver::directory() const {
return(_directory);
}
// SET TITLE
// Can be NULL if no title desired.
//
void Fl_Native_File_Chooser::title(const char *val) {
void Fl_Native_File_Chooser_WinAPI_Driver::title(const char *val) {
_title = strfree(_title);
_title = strnew(val);
}
@ -624,14 +693,14 @@ void Fl_Native_File_Chooser::title(const char *val) {
// GET TITLE
// Can return NULL if none set.
//
const char *Fl_Native_File_Chooser::title() const {
const char *Fl_Native_File_Chooser_WinAPI_Driver::title() const {
return(_title);
}
// SET FILTER
// Can be NULL if no filter needed
//
void Fl_Native_File_Chooser::filter(const char *val) {
void Fl_Native_File_Chooser_WinAPI_Driver::filter(const char *val) {
_filter = strfree(_filter);
clear_filters();
if ( val ) {
@ -648,18 +717,18 @@ void Fl_Native_File_Chooser::filter(const char *val) {
// GET FILTER
// Can return NULL if none set.
//
const char *Fl_Native_File_Chooser::filter() const {
const char *Fl_Native_File_Chooser_WinAPI_Driver::filter() const {
return(_filter);
}
// CLEAR FILTERS
void Fl_Native_File_Chooser::clear_filters() {
void Fl_Native_File_Chooser_WinAPI_Driver::clear_filters() {
_nfilters = 0;
_parsedfilt = strfree(_parsedfilt);
}
// ADD A FILTER
void Fl_Native_File_Chooser::add_filter(const char *name_in, // name of filter (optional: can be null)
void Fl_Native_File_Chooser_WinAPI_Driver::add_filter(const char *name_in, // name of filter (optional: can be null)
const char *winfilter) { // windows style filter (eg. "*.cxx;*.h")
// No name? Make one..
char name[1024];
@ -749,7 +818,7 @@ static int count_filters(const char *filter) {
// \_____/ \_______/
// Name Wildcard
//
void Fl_Native_File_Chooser::parse_filter(const char *in) {
void Fl_Native_File_Chooser_WinAPI_Driver::parse_filter(const char *in) {
clear_filters();
if ( ! in ) return;
@ -896,27 +965,27 @@ void Fl_Native_File_Chooser::parse_filter(const char *in) {
}
// SET 'CURRENTLY SELECTED FILTER'
void Fl_Native_File_Chooser::filter_value(int i) {
void Fl_Native_File_Chooser_WinAPI_Driver::filter_value(int i) {
_ofn_ptr->nFilterIndex = i + 1;
}
// RETURN VALUE OF 'CURRENTLY SELECTED FILTER'
int Fl_Native_File_Chooser::filter_value() const {
int Fl_Native_File_Chooser_WinAPI_Driver::filter_value() const {
return(_ofn_ptr->nFilterIndex ? _ofn_ptr->nFilterIndex-1 : _nfilters+1);
}
// PRESET FILENAME FOR 'SAVE AS' CHOOSER
void Fl_Native_File_Chooser::preset_file(const char* val) {
void Fl_Native_File_Chooser_WinAPI_Driver::preset_file(const char* val) {
_preset_file = strfree(_preset_file);
_preset_file = strnew(val);
}
// GET PRESET FILENAME FOR 'SAVE AS' CHOOSER
const char* Fl_Native_File_Chooser::preset_file() const {
const char* Fl_Native_File_Chooser_WinAPI_Driver::preset_file() const {
return(_preset_file);
}
int Fl_Native_File_Chooser::filters() const {
int Fl_Native_File_Chooser_WinAPI_Driver::filters() const {
return(_nfilters);
}

View File

@ -215,11 +215,7 @@ CFILES = fl_call_main.c flstring.c scandir.c numericsort.c vsnprintf.c
UTF8CFILES = \
xutf8/case.c \
xutf8/is_right2left.c \
xutf8/is_spacing.c \
xutf8/keysym2Ucs.c \
xutf8/utf8Input.c \
xutf8/utf8Utils.c \
xutf8/utf8Wrap.c
xutf8/is_spacing.c
QUARTZCPPFILES = \
drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx \
@ -253,7 +249,15 @@ XLIBCPPFILES = \
drivers/Posix/Fl_Posix_System_Driver.cxx \
drivers/Posix/Fl_Posix_Printer_Driver.cxx \
Fl_x.cxx \
fl_dnd_x.cxx
fl_dnd_x.cxx \
Fl_Native_File_Chooser_FLTK.cxx \
Fl_Native_File_Chooser_GTK.cxx
XLIBCFILES = \
xutf8/keysym2Ucs.c \
xutf8/utf8Input.c \
xutf8/utf8Utils.c \
xutf8/utf8Wrap.c
XLIBFONTFILES = \
drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx
@ -277,7 +281,8 @@ GDICPPFILES = \
drivers/WinAPI/Fl_WinAPI_System_Driver.cxx \
drivers/WinAPI/Fl_WinAPI_Printer_Driver.cxx \
Fl_win32.cxx \
fl_dnd_win32.cxx
fl_dnd_win32.cxx \
Fl_Native_File_Chooser_WIN32.cxx
PSCPPFILES = \
drivers/PostScript/Fl_PostScript.cxx \
@ -297,6 +302,7 @@ CPPFILES += $(shell if test $(BUILD_X11) = Yes -a $(BUILD_XFT) != Yes; then echo
CPPFILES += $(shell if test $(BUILD_GDI) = Yes; then echo $(GDICPPFILES); fi)
CFILES += $(shell if test $(BUILD_X11) = Yes; then echo $(XLIBCFILES); fi)
OBJECTS = $(MMFILES:.mm=.o) $(CPPFILES:.cxx=.o) $(CFILES:.c=.o) $(UTF8CFILES:.c=.o)
GLOBJECTS = $(GLCPPFILES:.cxx=.o)
@ -565,9 +571,9 @@ clean:
libfltk_gl.dylib libfltk_images.dylib \
cmap core
depend: $(CPPFILES) $(MMFILES) $(FLCPPFILES) $(GLCPPFILES) $(IMGCPPFILES) $(CFILES) $(UTF8CFILES)
depend: $(CPPFILES) $(MMFILES) $(FLCPPFILES) $(GLCPPFILES) $(IMGCPPFILES) $(CFILES) $(UTF8CFILES) $(XLIBCFILES)
makedepend -Y -I.. -f makedepend $(CPPFILES) $(MMFILES) $(FLCPPFILES) \
$(GLCPPFILES) $(IMGCPPFILES) $(CFILES) $(UTF8CFILES)
$(GLCPPFILES) $(IMGCPPFILES) $(CFILES) $(UTF8CFILES) $(XLIBCFILES)
# Automatically generated dependencies... generated on a Linux/Unix host !
include makedepend
@ -577,12 +583,15 @@ include makedepend
# Please add only non-Linux/Unix files or such that are optional
# (like "*xft*") here:
Fl_get_key.o: Fl_get_key_mac.cxx Fl_get_key_win32.cxx
Fl_Native_File_Chooser.o : Fl_Native_File_Chooser_WIN32.cxx
Fl_Native_File_Chooser_WIN32.o : Fl_Native_File_Chooser_WIN32.cxx
Fl_Native_File_Chooser_MAC.o: Fl_Native_File_Chooser_MAC.mm
Fl_Native_File_Chooser_FLTK.o: Fl_Native_File_Chooser_FLTK.cxx
Fl_Native_File_Chooser_GTK.o: Fl_Native_File_Chooser_GTK.cxx
Fl_win32.o: Fl_win32.cxx
Fl_cocoa.o: Fl_cocoa.mm
fl_color.o:
fl_dnd.o: fl_dnd_win32.cxx fl_dnd_x.cxx
fl_dnd_win32.o: fl_dnd_win32.cxx
fl_dnd_x.o: fl_dnd_x.cxx
Fl_Printer.o: ../src/drivers/PostScript/Fl_PostScript.cxx
Fl_Quartz_Printer.o: Fl_Quartz_Printer.mm
fl_arci.o: ../FL/mac.H ../FL/win32.H
@ -591,8 +600,6 @@ fl_ask.o: ../FL/mac.H ../FL/win32.H
Fl_Bitmap.o: ../FL/mac.H ../FL/win32.H
fl_color.o: ../FL/mac.H ../FL/win32.H
fl_cursor.o: ../FL/mac.H ../FL/win32.H
fl_dnd.o: ../FL/mac.H ../FL/win32.H
Fl.o: ../FL/mac.H ../FL/win32.H
Fl_Double_Window.o: ../FL/mac.H ../FL/win32.H
fl_draw_image.o: ../FL/mac.H ../FL/win32.H
fl_draw_pixmap.o: ../FL/mac.H ../FL/win32.H

View File

@ -380,7 +380,6 @@ Fl_Native_File_Chooser.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H
Fl_Native_File_Chooser.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H
Fl_Native_File_Chooser.o: ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H
Fl_Native_File_Chooser.o: ../FL/fl_ask.H ../FL/Fl_File_Icon.H
Fl_Native_File_Chooser.o: Fl_Native_File_Chooser_common.cxx
Fl_Native_File_Chooser.o: ../FL/Enumerations.H Fl_Native_File_Chooser_GTK.cxx
Fl_Native_File_Chooser.o: ../FL/x.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
Fl_Native_File_Chooser.o: ../FL/Fl_Preferences.H