Fl_Native_File_Chooser follow up maintenance.

* doxygen docs added
	* Changed all FNFC_XXX macros to full Fl_Native_File_Chooser names for doxygen
	* Added missing svn $Id tags
	* Small mods to Manolo's old_dir[] in Fl_Native_File_Chooser_FLTK to use a dynamic string instead of old_dir[300]



git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7003 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Greg Ercolano 2010-01-14 20:47:59 +00:00
parent 209e1bfea1
commit f910c1c181
7 changed files with 375 additions and 220 deletions

View File

@ -30,7 +30,7 @@
#define FL_NATIVE_FILE_CHOOSER_H #define FL_NATIVE_FILE_CHOOSER_H
// Use Windows' chooser // Use Windows' chooser
#ifdef _WIN32 #ifdef WIN32
#include <FL/Fl_Native_File_Chooser_WIN32.H> #include <FL/Fl_Native_File_Chooser_WIN32.H>
#endif #endif
@ -40,7 +40,7 @@
#endif #endif
// All else falls back to FLTK's own chooser // All else falls back to FLTK's own chooser
#if ! defined(__APPLE__) && !defined(_WIN32) #if ! defined(__APPLE__) && !defined(WIN32)
#include <FL/Fl_Native_File_Chooser_FLTK.H> #include <FL/Fl_Native_File_Chooser_FLTK.H>
#endif #endif
@ -49,4 +49,3 @@
// //
// End of "$Id$". // End of "$Id$".
// //

View File

@ -26,28 +26,66 @@
// http://www.fltk.org/str.php // http://www.fltk.org/str.php
// //
#include <FL/Fl_File_Chooser.H> /* \file
#include <string.h> Fl_Native_File_Chooser widget. */
#include <FL/Fl_File_Chooser.H>
#include <unistd.h> // _POSIX_NAME_MAX
/**
This class lets an FLTK application easily and consistently access
the operating system's native file chooser. Some operating systems
have very complex and specific file choosers that many users want
access to specifically, instead of FLTK's default file chooser(s).
<P>
In cases where there is no native file browser, FLTK's own file browser
is used instead.
<P>
\code
// Create and post the local native file chooser
#include <FL/Fl_Native_File_Chooser.H>
[..]
Fl_Native_File_Chooser fnfc;
fnfc.title("Pick a file");
fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
fnfc.filter("Text\t*.txt\n"
"C Files\t*.{cxx,h,c}");
fnfc.directory("/var/tmp");
// Show native chooser
switch ( fnfc.show() ) {
case -1: printf("ERROR: %s\n", fnfc.errmsg()); break; // ERROR
case 1: printf("CANCEL\n"); break; // CANCEL
default: printf("PICKED: %s\n", fnfc.filename()); break; // FILE CHOSEN
}
\endcode
<P>
<B>Platform Specific Caveats</B>
<P>
- Under X windows, it's best if you call Fl_File_Icon::load_system_icons()
at the start of main(), to enable the nicer looking file browser widgets.
- Some operating systems support certain OS specific options; see
Fl_Native_File_Chooser::options() for a list.
*/
class Fl_Native_File_Chooser { class Fl_Native_File_Chooser {
public: public:
enum Type { enum Type {
BROWSE_FILE = 0, BROWSE_FILE = 0, ///< browse files (lets user choose one file)
BROWSE_DIRECTORY, BROWSE_DIRECTORY, ///< browse directories (lets user choose one directory)
BROWSE_MULTI_FILE, BROWSE_MULTI_FILE, ///< browse files (lets user choose multiple files)
BROWSE_MULTI_DIRECTORY, BROWSE_MULTI_DIRECTORY, ///< browse directories (lets user choose multiple directories)
BROWSE_SAVE_FILE, BROWSE_SAVE_FILE, ///< browse to save a file
BROWSE_SAVE_DIRECTORY BROWSE_SAVE_DIRECTORY ///< browse to save a directory
}; };
enum Option { enum Option {
NO_OPTIONS = 0x0000, // no options enabled NO_OPTIONS = 0x0000, ///< no options enabled
SAVEAS_CONFIRM = 0x0001, // Show native 'Save As' overwrite confirm dialog (if supported) SAVEAS_CONFIRM = 0x0001, ///< Show native 'Save As' overwrite confirm dialog (if supported)
NEW_FOLDER = 0x0002, // Show 'New Folder' icon (if supported) NEW_FOLDER = 0x0002, ///< Show 'New Folder' icon (if supported)
PREVIEW = 0x0004 // enable preview mode PREVIEW = 0x0004, ///< enable preview mode
}; };
private: private:
int _btype; // kind-of browser to show() int _btype; // kind-of browser to show()
int _options; // general options int _options; // general options
int _nfilters;
char *_filter; // user supplied filter char *_filter; // user supplied filter
char *_parsedfilt; // parsed filter char *_parsedfilt; // parsed filter
int _filtvalue; // selected filter int _filtvalue; // selected filter
@ -55,22 +93,12 @@ private:
char *_prevvalue; // Returned filename char *_prevvalue; // Returned filename
char *_directory; char *_directory;
char *_errmsg; // error message char *_errmsg; // error message
Fl_File_Chooser *file_chooser; char *_old_dir;
Fl_File_Chooser *_file_chooser;
int exist_dialog() { // added by MG
return(fl_choice("File exists. Are you sure you want to overwrite?",
"Cancel", " OK ", NULL));
}
void load_system_icons() {
Fl_File_Icon::load_system_icons();
}
int _nfilters;
//added by MG
Fl_File_Browser *my_fileList; Fl_File_Browser *my_fileList;
Fl_Check_Button *show_hidden; Fl_Check_Button *show_hidden;
char old_dir[300];
int prev_filtervalue; int prev_filtervalue;
static void show_hidden_cb(Fl_Check_Button *o, void *data); static void show_hidden_cb(Fl_Check_Button *o, void *data);
static void remove_hidden_files(Fl_File_Browser *my_fileList); static void remove_hidden_files(Fl_File_Browser *my_fileList);
@ -80,6 +108,7 @@ private:
int type_fl_file(int); int type_fl_file(int);
void parse_filter(); void parse_filter();
void keeplocation(); void keeplocation();
int exist_dialog();
public: public:
Fl_Native_File_Chooser(int val=BROWSE_FILE); Fl_Native_File_Chooser(int val=BROWSE_FILE);
@ -99,7 +128,7 @@ public:
const char* title() const; const char* title() const;
const char *filter() const; const char *filter() const;
void filter(const char *); void filter(const char *);
int filters() const { return(_nfilters); } int filters() const;
void filter_value(int i); void filter_value(int i);
int filter_value() const; int filter_value() const;
void preset_file(const char*); void preset_file(const char*);
@ -113,4 +142,3 @@ public:
// //
// End of "$Id$". // End of "$Id$".
// //

View File

@ -1,6 +1,9 @@
// //
// Fl_Native_File_Chooser_WINDOWS.H -- FLTK native OS file chooser widget // "$Id$"
// //
// FLTK native OS file chooser widget
//
// Copyright 1998-2005 by Bill Spitzak and others.
// Copyright 2004 by Greg Ercolano. // Copyright 2004 by Greg Ercolano.
// April 2005 - API changes, improved filter processing by Nathan Vander Wilt // April 2005 - API changes, improved filter processing by Nathan Vander Wilt
// //
@ -19,6 +22,12 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA. // USA.
// //
// Please report all bugs and problems to:
//
// http://www.fltk.org/str.php
//
#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE
// #define _WIN32_WINNT 0x0501 // needed for OPENFILENAME's 'FlagsEx' // #define _WIN32_WINNT 0x0501 // needed for OPENFILENAME's 'FlagsEx'
#include <stdio.h> #include <stdio.h>
@ -104,8 +113,8 @@ public:
const char *errmsg() const; const char *errmsg() const;
int show(); int show();
}; };
#endif /*!FL_DOXYGEN*/
// //
// End of "$Id$". // End of "$Id$".
// //

View File

@ -26,7 +26,7 @@
// //
// Use Windows' chooser // Use Windows' chooser
#ifdef _WIN32 #ifdef WIN32
#include "Fl_Native_File_Chooser_WIN32.cxx" #include "Fl_Native_File_Chooser_WIN32.cxx"
#endif #endif
@ -36,7 +36,7 @@
#endif #endif
// All else falls back to FLTK's own chooser // All else falls back to FLTK's own chooser
#if ! defined(__APPLE__) && !defined(_WIN32) #if ! defined(__APPLE__) && !defined(WIN32)
#include "Fl_Native_File_Chooser_FLTK.cxx" #include "Fl_Native_File_Chooser_FLTK.cxx"
#endif #endif

View File

@ -28,8 +28,6 @@
#include <FL/Fl_Native_File_Chooser.H> #include <FL/Fl_Native_File_Chooser.H>
#include <FL/Fl_File_Icon.H> #include <FL/Fl_File_Icon.H>
#define FNFC_CLASS Fl_Native_File_Chooser
#define FNFC_CTOR Fl_Native_File_Chooser
#define FLTK_CHOOSER_SINGLE Fl_File_Chooser::SINGLE #define FLTK_CHOOSER_SINGLE Fl_File_Chooser::SINGLE
#define FLTK_CHOOSER_DIRECTORY Fl_File_Chooser::DIRECTORY #define FLTK_CHOOSER_DIRECTORY Fl_File_Chooser::DIRECTORY
#define FLTK_CHOOSER_MULTI Fl_File_Chooser::MULTI #define FLTK_CHOOSER_MULTI Fl_File_Chooser::MULTI
@ -37,11 +35,16 @@
#include "Fl_Native_File_Chooser_common.cxx" #include "Fl_Native_File_Chooser_common.cxx"
#include <sys/stat.h> #include <sys/stat.h>
#include <string.h>
// CTOR /**
FNFC_CLASS::FNFC_CTOR(int val) { 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) {
//// CANT USE THIS -- MESSES UP LINKING/CREATES DEPENDENCY ON fltk_images. //// CANT USE THIS -- MESSES UP LINKING/CREATES DEPENDENCY ON fltk_images.
//// Have user call this from app instead. //// Have app call this from main() instead.
//// ////
//// static int init = 0; // 'first time' initialize flag //// static int init = 0; // 'first time' initialize flag
//// if ( init == 0 ) { //// if ( init == 0 ) {
@ -58,47 +61,51 @@ FNFC_CLASS::FNFC_CTOR(int val) {
_prevvalue = NULL; _prevvalue = NULL;
_directory = NULL; _directory = NULL;
_errmsg = NULL; _errmsg = NULL;
file_chooser = new Fl_File_Chooser(NULL, NULL, 0, NULL); _file_chooser = new Fl_File_Chooser(NULL, NULL, 0, NULL);
type(val); // do this after file_chooser created type(val); // do this after _file_chooser created
_nfilters = 0; _nfilters = 0;
// Added by MG // Added by MG
Fl_Button *b = file_chooser->previewButton; Fl_Button *b = _file_chooser->previewButton;
Fl_Window *w = b->window(); Fl_Window *w = b->window();
Fl_Group::current(w); // adds a "Show hidden files" check button in file_chooser's window Fl_Group::current(w); // adds a "Show hidden files" check button in _file_chooser's window
show_hidden = new Fl_Check_Button(b->x() + b->w() + 10, b->y(), 145, b->h(), "Show hidden files"); show_hidden = new Fl_Check_Button(b->x() + b->w() + 10, b->y(), 145, b->h(), "Show hidden files");
show_hidden->callback((Fl_Callback*)show_hidden_cb, this); show_hidden->callback((Fl_Callback*)show_hidden_cb, this);
// This is a hack to bypass the fact that fileList is a private member of file_chooser. // This is a hack to bypass the fact that fileList is a private member of _file_chooser.
// Find it as 1st child of 2nd child of file_chooser's window. // Find it as 1st child of 2nd child of _file_chooser's window.
Fl_Group *g = (Fl_Group *)w->array()[1]; Fl_Group *g = (Fl_Group *)w->array()[1];
my_fileList = (Fl_File_Browser *)g->array()[0]; my_fileList = (Fl_File_Browser *)g->array()[0];
old_dir[0] = 0; // to detect directory changes _old_dir = 0; // to detect directory changes
prev_filtervalue = file_chooser->filter_value(); // to detect filter changes prev_filtervalue = _file_chooser->filter_value(); // to detect filter changes
// Hack to get file_chooser's showChoice widget. // Hack to get _file_chooser's showChoice widget.
// Find it as 1st child of 1st child of file_chooser's window. // Find it as 1st child of 1st child of _file_chooser's window.
g = (Fl_Group *)w->array()[0]; g = (Fl_Group *)w->array()[0];
showChoice = (Fl_Choice *)g->array()[0]; showChoice = (Fl_Choice *)g->array()[0];
} }
// DTOR /**
FNFC_CLASS::~FNFC_CTOR() { Destructor.
delete file_chooser; Deallocates any resources allocated to this widget.
*/
Fl_Native_File_Chooser::~Fl_Native_File_Chooser() {
delete _file_chooser;
_filter = strfree(_filter); _filter = strfree(_filter);
_parsedfilt = strfree(_parsedfilt); _parsedfilt = strfree(_parsedfilt);
_preset_file = strfree(_preset_file); _preset_file = strfree(_preset_file);
_prevvalue = strfree(_prevvalue); _prevvalue = strfree(_prevvalue);
_directory = strfree(_directory); _directory = strfree(_directory);
_errmsg = strfree(_errmsg); _errmsg = strfree(_errmsg);
_old_dir = strfree(_old_dir);
} }
// PRIVATE: SET ERROR MESSAGE // PRIVATE: SET ERROR MESSAGE
void FNFC_CLASS::errmsg(const char *msg) { void Fl_Native_File_Chooser::errmsg(const char *msg) {
_errmsg = strfree(_errmsg); _errmsg = strfree(_errmsg);
_errmsg = strnew(msg); _errmsg = strnew(msg);
} }
// PRIVATE: translate Native types to Fl_File_Chooser types // PRIVATE: translate Native types to Fl_File_Chooser types
int FNFC_CLASS::type_fl_file(int val) { int Fl_Native_File_Chooser::type_fl_file(int val) {
switch (val) { switch (val) {
case BROWSE_FILE: case BROWSE_FILE:
return(FLTK_CHOOSER_SINGLE); return(FLTK_CHOOSER_SINGLE);
@ -117,85 +124,107 @@ int FNFC_CLASS::type_fl_file(int val) {
} }
} }
void FNFC_CLASS::type(int val) { /**
Sets the current Fl_Native_File_Chooser::Type of browser.
*/
void Fl_Native_File_Chooser::type(int val) {
_btype = val; _btype = val;
file_chooser->type(type_fl_file(val)); _file_chooser->type(type_fl_file(val));
} }
int FNFC_CLASS::type() const { /**
Gets the current Fl_Native_File_Chooser::Type of browser.
*/
int Fl_Native_File_Chooser::type() const {
return(_btype); return(_btype);
} }
// SET OPTIONS /**
void FNFC_CLASS::options(int val) { 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. Ignored Used Ignored
\endcode
*/
void Fl_Native_File_Chooser::options(int val) {
_options = val; _options = val;
} }
// GET OPTIONS /**
int FNFC_CLASS::options() const { Gets the platform specific Fl_Native_File_Chooser::Option flags.
*/
int Fl_Native_File_Chooser::options() const {
return(_options); return(_options);
} }
// Show chooser, blocks until done. /**
// RETURNS: Post the chooser's dialog. Blocks until dialog has been completed or cancelled.
// 0 - user picked a file \returns
// 1 - user cancelled - 0 -- user picked a file
// -1 - failed; errmsg() has reason - 1 -- user cancelled
// - -1 -- failed; errmsg() has reason
int FNFC_CLASS::show() { */
int Fl_Native_File_Chooser::show() {
// FILTER // FILTER
if ( _parsedfilt ) { if ( _parsedfilt ) {
file_chooser->filter(_parsedfilt); _file_chooser->filter(_parsedfilt);
} }
// FILTER VALUE // FILTER VALUE
// Set this /after/ setting the filter // Set this /after/ setting the filter
// //
file_chooser->filter_value(_filtvalue); _file_chooser->filter_value(_filtvalue);
// DIRECTORY // DIRECTORY
if ( _directory && _directory[0] ) { if ( _directory && _directory[0] ) {
file_chooser->directory(_directory); _file_chooser->directory(_directory);
} else { } else {
file_chooser->directory(_prevvalue); _file_chooser->directory(_prevvalue);
} }
// PRESET FILE // PRESET FILE
if ( _preset_file ) { if ( _preset_file ) {
file_chooser->value(_preset_file); _file_chooser->value(_preset_file);
} }
// OPTIONS: PREVIEW // OPTIONS: PREVIEW
file_chooser->preview( (options() & PREVIEW) ? 1 : 0); _file_chooser->preview( (options() & PREVIEW) ? 1 : 0);
// OPTIONS: NEW FOLDER // OPTIONS: NEW FOLDER
if ( options() & NEW_FOLDER ) if ( options() & NEW_FOLDER )
file_chooser->type(file_chooser->type() | FLTK_CHOOSER_CREATE); // on _file_chooser->type(_file_chooser->type() | FLTK_CHOOSER_CREATE); // on
// SHOW // SHOW
file_chooser->show(); _file_chooser->show();
// BLOCK WHILE BROWSER SHOWN // BLOCK WHILE BROWSER SHOWN
while ( file_chooser->shown() ) { while ( _file_chooser->shown() ) {
if(strcmp(old_dir, file_chooser->directory()) != 0) { if (_old_dir==0 || strcmp(_old_dir, _file_chooser->directory()) != 0) {
strcpy(old_dir, file_chooser->directory()); _old_dir = strfree(_old_dir);
if(!show_hidden->value()) remove_hidden_files(my_fileList); _old_dir = strnew(_file_chooser->directory());
} else if(prev_filtervalue != file_chooser->filter_value() ) { if (!show_hidden->value()) remove_hidden_files(my_fileList);
prev_filtervalue = file_chooser->filter_value(); } else if (prev_filtervalue != _file_chooser->filter_value() ) {
if(!show_hidden->value() ) remove_hidden_files(my_fileList); prev_filtervalue = _file_chooser->filter_value();
if (!show_hidden->value() ) remove_hidden_files(my_fileList);
} }
Fl::wait(); Fl::wait();
} }
if ( file_chooser->value() && file_chooser->value()[0] ) { if ( _file_chooser->value() && _file_chooser->value()[0] ) {
_prevvalue = strfree(_prevvalue); _prevvalue = strfree(_prevvalue);
_prevvalue = strnew(file_chooser->value()); _prevvalue = strnew(_file_chooser->value());
_filtvalue = file_chooser->filter_value(); // update filter value _filtvalue = _file_chooser->filter_value(); // update filter value
// HANDLE SHOWING 'SaveAs' CONFIRM // HANDLE SHOWING 'SaveAs' CONFIRM
if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) { if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) {
struct stat buf; struct stat buf;
if ( stat(file_chooser->value(), &buf) != -1 ) { if ( stat(_file_chooser->value(), &buf) != -1 ) {
if ( buf.st_mode & S_IFREG ) { // Regular file + exists? if ( buf.st_mode & S_IFREG ) { // Regular file + exists?
if ( exist_dialog() == 0 ) { if ( exist_dialog() == 0 ) {
return(1); return(1);
@ -205,87 +234,160 @@ int FNFC_CLASS::show() {
} }
} }
if ( file_chooser->count() ) return(0); if ( _file_chooser->count() ) return(0);
else return(1); else return(1);
} }
// RETURN ERROR MESSAGE /**
const char *FNFC_CLASS::errmsg() const { 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(_errmsg ? _errmsg : "No error"); return(_errmsg ? _errmsg : "No error");
} }
// GET FILENAME /**
const char* FNFC_CLASS::filename() const { Return the filename the user choose.
if ( file_chooser->count() > 0 ) return(file_chooser->value()); 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 {
if ( _file_chooser->count() > 0 ) return(_file_chooser->value());
return(""); return("");
} }
// GET FILENAME FROM LIST OF FILENAMES /**
const char* FNFC_CLASS::filename(int i) const { Return one of the filenames the user selected.
if ( i < file_chooser->count() ) Use count() to determine how many filenames the user selected.
return(file_chooser->value(i+1)); // convert fltk 1 based to our 0 based <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 {
if ( i < _file_chooser->count() )
return(_file_chooser->value(i+1)); // convert fltk 1 based to our 0 based
return(""); return("");
} }
// SET TITLE /**
// Can be NULL if no title desired. Set the title of the file chooser's dialog window.
// Can be NULL if no title desired.
void FNFC_CLASS::title(const char *val) { The default title varies according to the platform, so you are advised to set the title explicitly.
file_chooser->label(val); */
void Fl_Native_File_Chooser::title(const char *val) {
_file_chooser->label(val);
} }
// GET TITLE /**
// Can return NULL if none set. Get the title of the file chooser's dialog window.
// Return value may be NULL if no title was set.
const char *FNFC_CLASS::title() const { */
return(file_chooser->label()); const char *Fl_Native_File_Chooser::title() const {
return(_file_chooser->label());
} }
// SET FILTER /**
// Can be NULL if no filter needed Sets the filename filters used for browsing.
// The default is NULL, which browses all files.
void FNFC_CLASS::filter(const char *val) { <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 *val) {
_filter = strfree(_filter); _filter = strfree(_filter);
_filter = strnew(val); _filter = strnew(val);
parse_filter(); parse_filter();
} }
// GET FILTER /**
const char *FNFC_CLASS::filter() const { Returns the filter string last set.
Can be NULL if no filter was set.
*/
const char *Fl_Native_File_Chooser::filter() const {
return(_filter); return(_filter);
} }
// SET SELECTED FILTER /**
void FNFC_CLASS::filter_value(int val) { Gets how many filters were available, not including "All Files"
*/
int Fl_Native_File_Chooser::filters() const {
return(_nfilters);
}
/**
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 val) {
_filtvalue = val; _filtvalue = val;
} }
// RETURN SELECTED FILTER /**
int FNFC_CLASS::filter_value() const { 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(_filtvalue); return(_filtvalue);
} }
// GET TOTAL FILENAMES CHOSEN /**
int FNFC_CLASS::count() const { Returns the number of filenames (or directory names) the user selected.
return(file_chooser->count()); <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(_file_chooser->count());
} }
// PRESET PATHNAME /**
// Can be NULL if no preset is desired. Preset the directory the browser will show when opened.
// If \p val is NULL, or no directory is specified, the chooser will attempt
void FNFC_CLASS::directory(const char *val) { to use the last non-cancelled folder.
*/
void Fl_Native_File_Chooser::directory(const char *val) {
_directory = strfree(_directory); _directory = strfree(_directory);
_directory = strnew(val); _directory = strnew(val);
} }
// GET PRESET PATHNAME /**
// Can return NULL if none set. Returns the current preset directory() value.
// */
const char *FNFC_CLASS::directory() const { const char *Fl_Native_File_Chooser::directory() const {
return(_directory); return(_directory);
} }
// Convert our filter format to fltk's chooser format // PRIVATE: Convert our filter format to fltk's chooser format
// FROM TO (FLTK) // FROM TO (FLTK)
// ------------------------- -------------------------- // ------------------------- --------------------------
// "*.cxx" "*.cxx Files(*.cxx)" // "*.cxx" "*.cxx Files(*.cxx)"
@ -295,7 +397,7 @@ const char *FNFC_CLASS::directory() const {
// Returns a modified version of the filter that the caller is responsible // Returns a modified version of the filter that the caller is responsible
// for freeing with strfree(). // for freeing with strfree().
// //
void FNFC_CLASS::parse_filter() { void Fl_Native_File_Chooser::parse_filter() {
_parsedfilt = strfree(_parsedfilt); // clear previous parsed filter (if any) _parsedfilt = strfree(_parsedfilt); // clear previous parsed filter (if any)
_nfilters = 0; _nfilters = 0;
char *in = _filter; char *in = _filter;
@ -358,38 +460,52 @@ void FNFC_CLASS::parse_filter() {
//NOTREACHED //NOTREACHED
} }
// SET PRESET FILENAME /**
void FNFC_CLASS::preset_file(const char* val) { 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* val) {
_preset_file = strfree(_preset_file); _preset_file = strfree(_preset_file);
_preset_file = strnew(val); _preset_file = strnew(val);
} }
// GET PRESET FILENAME /**
const char* FNFC_CLASS::preset_file() const { Get the preset filename.
*/
const char* Fl_Native_File_Chooser::preset_file() const {
return(_preset_file); return(_preset_file);
} }
void FNFC_CLASS::show_hidden_cb(Fl_Check_Button *o, void *data) void Fl_Native_File_Chooser::show_hidden_cb(Fl_Check_Button *o, void *data)
{ {
Fl_Native_File_Chooser *mychooser = (Fl_Native_File_Chooser *)data; Fl_Native_File_Chooser *mychooser = (Fl_Native_File_Chooser *)data;
if(o->value()) { if (o->value()) {
mychooser->my_fileList->load(mychooser->file_chooser->directory()); mychooser->my_fileList->load(mychooser->_file_chooser->directory());
} else { } else {
remove_hidden_files(mychooser->my_fileList); remove_hidden_files(mychooser->my_fileList);
mychooser->my_fileList->redraw(); mychooser->my_fileList->redraw();
} }
} }
void FNFC_CLASS::remove_hidden_files(Fl_File_Browser *my_fileList) // PRIVATE: Don't show hidden files
void Fl_Native_File_Chooser::remove_hidden_files(Fl_File_Browser *my_fileList)
{ {
int count = my_fileList->size(); int count = my_fileList->size();
for(int num = count; num >= 1; num--) { for(int num = count; num >= 1; num--) {
const char *p = my_fileList->text(num); const char *p = my_fileList->text(num);
if(*p == '.' && strcmp(p, "../") != 0) my_fileList->remove(num); if (*p == '.' && strcmp(p, "../") != 0) my_fileList->remove(num);
} }
my_fileList->topline(1); my_fileList->topline(1);
} }
// PRIVATE: Don't show hidden files
int Fl_Native_File_Chooser::exist_dialog() {
return(fl_choice("File exists. Are you sure you want to overwrite?",
"Cancel", " OK ", NULL));
}
// //
// End of "$Id$". // End of "$Id$".
// //

View File

@ -30,6 +30,8 @@
// Possibly 'preset_file' could be used to select the filename. // Possibly 'preset_file' could be used to select the filename.
// //
#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE
#include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat #include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat
#include <libgen.h> // dirname(3) #include <libgen.h> // dirname(3)
#include <sys/types.h> // stat(2) #include <sys/types.h> // stat(2)
@ -39,8 +41,6 @@
#include <FL/Fl.H> #include <FL/Fl.H>
#include <FL/Fl_Native_File_Chooser.H> #include <FL/Fl_Native_File_Chooser.H>
#include <FL/filename.H> #include <FL/filename.H>
#define FNFC_CLASS Fl_Native_File_Chooser
#define FNFC_CTOR Fl_Native_File_Chooser
#ifndef __APPLE_COCOA__ #ifndef __APPLE_COCOA__
// TRY TO CONVERT AN AEDesc TO AN FSRef // TRY TO CONVERT AN AEDesc TO AN FSRef
@ -65,19 +65,19 @@ static int AEDescToFSRef(const AEDesc* desc, FSRef* fsref) {
} }
// NAVREPLY: CTOR // NAVREPLY: CTOR
FNFC_CLASS::NavReply::NavReply() { Fl_Native_File_Chooser::NavReply::NavReply() {
_valid_reply = 0; _valid_reply = 0;
} }
// NAVREPLY: DTOR // NAVREPLY: DTOR
FNFC_CLASS::NavReply::~NavReply() { Fl_Native_File_Chooser::NavReply::~NavReply() {
if ( _valid_reply ) { if ( _valid_reply ) {
NavDisposeReply(&_reply); NavDisposeReply(&_reply);
} }
} }
// GET REPLY FROM THE NAV* DIALOG // GET REPLY FROM THE NAV* DIALOG
int FNFC_CLASS::NavReply::get_reply(NavDialogRef& ref) { int Fl_Native_File_Chooser::NavReply::get_reply(NavDialogRef& ref) {
if ( _valid_reply ) { if ( _valid_reply ) {
NavDisposeReply(&_reply); // dispose of previous NavDisposeReply(&_reply); // dispose of previous
_valid_reply = 0; _valid_reply = 0;
@ -90,7 +90,7 @@ int FNFC_CLASS::NavReply::get_reply(NavDialogRef& ref) {
} }
// RETURN THE BASENAME USER WANTS TO 'Save As' // RETURN THE BASENAME USER WANTS TO 'Save As'
int FNFC_CLASS::NavReply::get_saveas_basename(char *s, int slen) { int Fl_Native_File_Chooser::NavReply::get_saveas_basename(char *s, int slen) {
if (CFStringGetCString(_reply.saveFileName, s, slen-1, kCFStringEncodingUTF8) == false) { if (CFStringGetCString(_reply.saveFileName, s, slen-1, kCFStringEncodingUTF8) == false) {
s[0] = '\0'; s[0] = '\0';
return(-1); return(-1);
@ -101,7 +101,7 @@ int FNFC_CLASS::NavReply::get_saveas_basename(char *s, int slen) {
// RETURN THE DIRECTORY NAME // RETURN THE DIRECTORY NAME
// Returns 0 on success, -1 on error. // Returns 0 on success, -1 on error.
// //
int FNFC_CLASS::NavReply::get_dirname(char *s, int slen) { int Fl_Native_File_Chooser::NavReply::get_dirname(char *s, int slen) {
FSRef fsref; FSRef fsref;
if ( AEDescToFSRef(&_reply.selection, &fsref) != noErr ) { if ( AEDescToFSRef(&_reply.selection, &fsref) != noErr ) {
// Conversion failed? Return empty name // Conversion failed? Return empty name
@ -116,7 +116,7 @@ int FNFC_CLASS::NavReply::get_dirname(char *s, int slen) {
// Returns: 0 on success with pathnames[] containing pathnames selected, // Returns: 0 on success with pathnames[] containing pathnames selected,
// -1 on error // -1 on error
// //
int FNFC_CLASS::NavReply::get_pathnames(char **&pathnames, int& tpathnames) { int Fl_Native_File_Chooser::NavReply::get_pathnames(char **&pathnames, int& tpathnames) {
// How many items selected? // How many items selected?
long count = 0; long count = 0;
if ( AECountItems(&_reply.selection, &count) != noErr ) { if ( AECountItems(&_reply.selection, &count) != noErr ) {
@ -151,7 +151,7 @@ int FNFC_CLASS::NavReply::get_pathnames(char **&pathnames, int& tpathnames) {
#endif /* !__APPLE_COCOA__ */ #endif /* !__APPLE_COCOA__ */
// FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS // FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS
void FNFC_CLASS::clear_pathnames() { void Fl_Native_File_Chooser::clear_pathnames() {
if ( _pathnames ) { if ( _pathnames ) {
while ( --_tpathnames >= 0 ) { while ( --_tpathnames >= 0 ) {
_pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]); _pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]);
@ -163,7 +163,7 @@ void FNFC_CLASS::clear_pathnames() {
} }
// SET A SINGLE PATHNAME // SET A SINGLE PATHNAME
void FNFC_CLASS::set_single_pathname(const char *s) { void Fl_Native_File_Chooser::set_single_pathname(const char *s) {
clear_pathnames(); clear_pathnames();
_pathnames = new char*[1]; _pathnames = new char*[1];
_pathnames[0] = strnew(s); _pathnames[0] = strnew(s);
@ -175,7 +175,7 @@ void FNFC_CLASS::set_single_pathname(const char *s) {
// Returns -1 on error, errmsg() has reason, filename == "". // Returns -1 on error, errmsg() has reason, filename == "".
// 0 if OK, filename() has filename chosen. // 0 if OK, filename() has filename chosen.
// //
int FNFC_CLASS::get_saveas_basename(NavDialogRef& ref) { int Fl_Native_File_Chooser::get_saveas_basename(NavDialogRef& ref) {
if ( ref == NULL ) { if ( ref == NULL ) {
errmsg("get_saveas_basename: ref is NULL"); errmsg("get_saveas_basename: ref is NULL");
return(-1); return(-1);
@ -216,7 +216,7 @@ int FNFC_CLASS::get_saveas_basename(NavDialogRef& ref) {
// -1 -- error, errmsg() has reason, filename == "" // -1 -- error, errmsg() has reason, filename == ""
// 0 -- OK, pathnames()/filename() has pathname(s) chosen // 0 -- OK, pathnames()/filename() has pathname(s) chosen
// //
int FNFC_CLASS::get_pathnames(NavDialogRef& ref) { int Fl_Native_File_Chooser::get_pathnames(NavDialogRef& ref) {
if ( ref == NULL ) { if ( ref == NULL ) {
errmsg("get_saveas_basename: ref is NULL"); errmsg("get_saveas_basename: ref is NULL");
return(-1); return(-1);
@ -278,10 +278,10 @@ static void PreselectPathname(NavCBRecPtr cbparm, const char *path) {
} }
// NAV CALLBACK EVENT HANDLER // NAV CALLBACK EVENT HANDLER
void FNFC_CLASS::event_handler(NavEventCallbackMessage callBackSelector, void Fl_Native_File_Chooser::event_handler(NavEventCallbackMessage callBackSelector,
NavCBRecPtr cbparm, NavCBRecPtr cbparm,
void *data) { void *data) {
FNFC_CLASS *nfb = (FNFC_CLASS*)data; Fl_Native_File_Chooser *nfb = (Fl_Native_File_Chooser*)data;
switch (callBackSelector) { switch (callBackSelector) {
case kNavCBStart: case kNavCBStart:
{ {
@ -381,7 +381,7 @@ void FNFC_CLASS::event_handler(NavEventCallbackMessage callBackSelector,
#endif /* !__APPLE_COCOA__ */ #endif /* !__APPLE_COCOA__ */
// CONSTRUCTOR // CONSTRUCTOR
FNFC_CLASS::FNFC_CTOR(int val) { Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
_btype = val; _btype = val;
#ifdef __APPLE_COCOA__ #ifdef __APPLE_COCOA__
_panel = NULL; _panel = NULL;
@ -407,7 +407,7 @@ FNFC_CLASS::FNFC_CTOR(int val) {
} }
// DESTRUCTOR // DESTRUCTOR
FNFC_CLASS::~FNFC_CTOR() { Fl_Native_File_Chooser::~Fl_Native_File_Chooser() {
// _opts // nothing to manage // _opts // nothing to manage
#ifndef __APPLE_COCOA__ #ifndef __APPLE_COCOA__
if (_ref) { NavDialogDispose(_ref); _ref = NULL; } if (_ref) { NavDialogDispose(_ref); _ref = NULL; }
@ -430,23 +430,23 @@ FNFC_CLASS::~FNFC_CTOR() {
#ifndef __APPLE_COCOA__ #ifndef __APPLE_COCOA__
// SET THE TYPE OF BROWSER // SET THE TYPE OF BROWSER
void FNFC_CLASS::type(int val) { void Fl_Native_File_Chooser::type(int val) {
_btype = val; _btype = val;
} }
#endif /* !__APPLE_COCOA__ */ #endif /* !__APPLE_COCOA__ */
// GET TYPE OF BROWSER // GET TYPE OF BROWSER
int FNFC_CLASS::type() const { int Fl_Native_File_Chooser::type() const {
return(_btype); return(_btype);
} }
// SET OPTIONS // SET OPTIONS
void FNFC_CLASS::options(int val) { void Fl_Native_File_Chooser::options(int val) {
_options = val; _options = val;
} }
// GET OPTIONS // GET OPTIONS
int FNFC_CLASS::options() const { int Fl_Native_File_Chooser::options() const {
return(_options); return(_options);
} }
@ -456,7 +456,7 @@ int FNFC_CLASS::options() const {
// 1 - user cancelled // 1 - user cancelled
// -1 - failed; errmsg() has reason // -1 - failed; errmsg() has reason
// //
int FNFC_CLASS::show() { int Fl_Native_File_Chooser::show() {
// Make sure fltk interface updates before posting our dialog // Make sure fltk interface updates before posting our dialog
Fl::flush(); Fl::flush();
@ -520,7 +520,7 @@ int FNFC_CLASS::show() {
} }
#ifndef __APPLE_COCOA__ #ifndef __APPLE_COCOA__
int FNFC_CLASS::post() { int Fl_Native_File_Chooser::post() {
// INITIALIZE BROWSER // INITIALIZE BROWSER
OSStatus err; OSStatus err;
@ -612,37 +612,37 @@ int FNFC_CLASS::post() {
// SET ERROR MESSAGE // SET ERROR MESSAGE
// Internal use only. // Internal use only.
// //
void FNFC_CLASS::errmsg(const char *msg) { void Fl_Native_File_Chooser::errmsg(const char *msg) {
_errmsg = strfree(_errmsg); _errmsg = strfree(_errmsg);
_errmsg = strnew(msg); _errmsg = strnew(msg);
} }
// RETURN ERROR MESSAGE // RETURN ERROR MESSAGE
const char *FNFC_CLASS::errmsg() const { const char *Fl_Native_File_Chooser::errmsg() const {
return(_errmsg ? _errmsg : "No error"); return(_errmsg ? _errmsg : "No error");
} }
// GET FILENAME // GET FILENAME
const char* FNFC_CLASS::filename() const { const char* Fl_Native_File_Chooser::filename() const {
if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]); if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]);
return(""); return("");
} }
// GET FILENAME FROM LIST OF FILENAMES // GET FILENAME FROM LIST OF FILENAMES
const char* FNFC_CLASS::filename(int i) const { const char* Fl_Native_File_Chooser::filename(int i) const {
if ( _pathnames && i < _tpathnames ) return(_pathnames[i]); if ( _pathnames && i < _tpathnames ) return(_pathnames[i]);
return(""); return("");
} }
// GET TOTAL FILENAMES CHOSEN // GET TOTAL FILENAMES CHOSEN
int FNFC_CLASS::count() const { int Fl_Native_File_Chooser::count() const {
return(_tpathnames); return(_tpathnames);
} }
// PRESET PATHNAME // PRESET PATHNAME
// Value can be NULL for none. // Value can be NULL for none.
// //
void FNFC_CLASS::directory(const char *val) { void Fl_Native_File_Chooser::directory(const char *val) {
_directory = strfree(_directory); _directory = strfree(_directory);
_directory = strnew(val); _directory = strnew(val);
} }
@ -650,14 +650,14 @@ void FNFC_CLASS::directory(const char *val) {
// GET PRESET PATHNAME // GET PRESET PATHNAME
// Returned value can be NULL if none set. // Returned value can be NULL if none set.
// //
const char* FNFC_CLASS::directory() const { const char* Fl_Native_File_Chooser::directory() const {
return(_directory); return(_directory);
} }
// SET TITLE // SET TITLE
// Value can be NULL if no title desired. // Value can be NULL if no title desired.
// //
void FNFC_CLASS::title(const char *val) { void Fl_Native_File_Chooser::title(const char *val) {
_title = strfree(_title); _title = strfree(_title);
_title = strnew(val); _title = strnew(val);
} }
@ -665,14 +665,14 @@ void FNFC_CLASS::title(const char *val) {
// GET TITLE // GET TITLE
// Returned value can be NULL if none set. // Returned value can be NULL if none set.
// //
const char *FNFC_CLASS::title() const { const char *Fl_Native_File_Chooser::title() const {
return(_title); return(_title);
} }
// SET FILTER // SET FILTER
// Can be NULL if no filter needed // Can be NULL if no filter needed
// //
void FNFC_CLASS::filter(const char *val) { void Fl_Native_File_Chooser::filter(const char *val) {
_filter = strfree(_filter); _filter = strfree(_filter);
_filter = strnew(val); _filter = strnew(val);
@ -689,14 +689,14 @@ void FNFC_CLASS::filter(const char *val) {
// GET FILTER // GET FILTER
// Returned value can be NULL if none set. // Returned value can be NULL if none set.
// //
const char *FNFC_CLASS::filter() const { const char *Fl_Native_File_Chooser::filter() const {
return(_filter); return(_filter);
} }
// CLEAR ALL FILTERS // CLEAR ALL FILTERS
// Internal use only. // Internal use only.
// //
void FNFC_CLASS::clear_filters() { void Fl_Native_File_Chooser::clear_filters() {
_filt_names = strfree(_filt_names); _filt_names = strfree(_filt_names);
for (int i=0; i<_filt_total; i++) { for (int i=0; i<_filt_total; i++) {
_filt_patt[i] = strfree(_filt_patt[i]); _filt_patt[i] = strfree(_filt_patt[i]);
@ -724,7 +724,7 @@ void FNFC_CLASS::clear_filters() {
// \_____/ \_______/ // \_____/ \_______/
// Name Wildcard // Name Wildcard
// //
void FNFC_CLASS::parse_filter(const char *in) { void Fl_Native_File_Chooser::parse_filter(const char *in) {
clear_filters(); clear_filters();
if ( ! in ) return; if ( ! in ) return;
int has_name = strchr(in, '\t') ? 1 : 0; int has_name = strchr(in, '\t') ? 1 : 0;
@ -799,11 +799,11 @@ void FNFC_CLASS::parse_filter(const char *in) {
#ifndef __APPLE_COCOA__ #ifndef __APPLE_COCOA__
// STATIC: FILTER CALLBACK // STATIC: FILTER CALLBACK
Boolean FNFC_CLASS::filter_proc_cb(AEDesc *theItem, Boolean Fl_Native_File_Chooser::filter_proc_cb(AEDesc *theItem,
void *info, void *info,
void *callBackUD, void *callBackUD,
NavFilterModes filterMode) { NavFilterModes filterMode) {
return((FNFC_CLASS*)callBackUD)->filter_proc_cb2(theItem, return((Fl_Native_File_Chooser*)callBackUD)->filter_proc_cb2(theItem,
info, info,
callBackUD, callBackUD,
filterMode); filterMode);
@ -813,7 +813,7 @@ Boolean FNFC_CLASS::filter_proc_cb(AEDesc *theItem,
// Return true if match, // Return true if match,
// false if no match. // false if no match.
// //
Boolean FNFC_CLASS::filter_proc_cb2(AEDesc *theItem, Boolean Fl_Native_File_Chooser::filter_proc_cb2(AEDesc *theItem,
void *info, void *info,
void *callBackUD, void *callBackUD,
NavFilterModes filterMode) { NavFilterModes filterMode) {
@ -838,7 +838,7 @@ Boolean FNFC_CLASS::filter_proc_cb2(AEDesc *theItem,
// SET PRESET FILE // SET PRESET FILE
// Value can be NULL for none. // Value can be NULL for none.
// //
void FNFC_CLASS::preset_file(const char* val) { void Fl_Native_File_Chooser::preset_file(const char* val) {
_preset_file = strfree(_preset_file); _preset_file = strfree(_preset_file);
_preset_file = strnew(val); _preset_file = strnew(val);
} }
@ -846,7 +846,7 @@ void FNFC_CLASS::preset_file(const char* val) {
// PRESET FILE // PRESET FILE
// Returned value can be NULL if none set. // Returned value can be NULL if none set.
// //
const char* FNFC_CLASS::preset_file() { const char* Fl_Native_File_Chooser::preset_file() {
return(_preset_file); return(_preset_file);
} }
@ -854,7 +854,7 @@ const char* FNFC_CLASS::preset_file() {
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#define UNLIKELYPREFIX "___fl_very_unlikely_prefix_" #define UNLIKELYPREFIX "___fl_very_unlikely_prefix_"
int FNFC_CLASS::get_saveas_basename(void) { int Fl_Native_File_Chooser::get_saveas_basename(void) {
char *q = strdup( [[(NSSavePanel*)_panel filename] fileSystemRepresentation] ); char *q = strdup( [[(NSSavePanel*)_panel filename] fileSystemRepresentation] );
id delegate = [(NSSavePanel*)_panel delegate]; id delegate = [(NSSavePanel*)_panel delegate];
if(delegate != nil) { if(delegate != nil) {
@ -870,7 +870,7 @@ int FNFC_CLASS::get_saveas_basename(void) {
} }
// SET THE TYPE OF BROWSER // SET THE TYPE OF BROWSER
void FNFC_CLASS::type(int val) { void Fl_Native_File_Chooser::type(int val) {
_btype = val; _btype = val;
switch (_btype) { switch (_btype) {
case BROWSE_FILE: case BROWSE_FILE:
@ -966,7 +966,7 @@ static NSPopUpButton *createPopupAccessory(NSSavePanel *panel, const char *filte
// 1 - user cancelled // 1 - user cancelled
// -1 - failed; errmsg() has reason // -1 - failed; errmsg() has reason
// //
int FNFC_CLASS::post() { int Fl_Native_File_Chooser::post() {
// INITIALIZE BROWSER // INITIALIZE BROWSER
if ( _filt_total == 0 ) { // Make sure they match if ( _filt_total == 0 ) { // Make sure they match
_filt_value = 0; // TBD: move to someplace more logical? _filt_value = 0; // TBD: move to someplace more logical?
@ -1081,6 +1081,7 @@ int FNFC_CLASS::post() {
} }
#endif //__APPLE_COCOA__ #endif //__APPLE_COCOA__
#endif /*!FL_DOXYGEN*/
// //
// End of "$Id$". // End of "$Id$".

View File

@ -30,6 +30,8 @@
// http://www.codeproject.com/dialog/selectfolder.asp // http://www.codeproject.com/dialog/selectfolder.asp
// //
#ifndef FL_DOXYGEN // PREVENT DOXYGEN'S USE OF THIS FILE
#include <stdio.h> // debugging #include <stdio.h> // debugging
#include <wchar.h> //MG #include <wchar.h> //MG
#include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat #include "Fl_Native_File_Chooser_common.cxx" // strnew/strfree/strapp/chrcat
@ -38,8 +40,6 @@ LPCWSTR utf8towchar(const char *in); //MG
char *wchartoutf8(LPCWSTR in); //MG char *wchartoutf8(LPCWSTR in); //MG
#include <FL/Fl_Native_File_Chooser.H> #include <FL/Fl_Native_File_Chooser.H>
#define FNFC_CLASS Fl_Native_File_Chooser
#define FNFC_CTOR Fl_Native_File_Chooser
#define LCURLY_CHR '{' #define LCURLY_CHR '{'
#define RCURLY_CHR '}' #define RCURLY_CHR '}'
@ -125,7 +125,7 @@ static void dnullcat(char*&wp, const char *string, int n = -1 ) {
} }
// CTOR // CTOR
FNFC_CLASS::FNFC_CTOR(int val) { Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
_btype = val; _btype = val;
_options = NO_OPTIONS; _options = NO_OPTIONS;
memset((void*)&_ofn, 0, sizeof(OPENFILENAMEW)); memset((void*)&_ofn, 0, sizeof(OPENFILENAMEW));
@ -144,7 +144,7 @@ FNFC_CLASS::FNFC_CTOR(int val) {
} }
// DTOR // DTOR
FNFC_CLASS::~FNFC_CTOR() { Fl_Native_File_Chooser::~Fl_Native_File_Chooser() {
//_pathnames // managed by clear_pathnames() //_pathnames // managed by clear_pathnames()
//_tpathnames // managed by clear_pathnames() //_tpathnames // managed by clear_pathnames()
_directory = strfree(_directory); _directory = strfree(_directory);
@ -161,33 +161,33 @@ FNFC_CLASS::~FNFC_CTOR() {
} }
// SET TYPE OF BROWSER // SET TYPE OF BROWSER
void FNFC_CLASS::type(int val) { void Fl_Native_File_Chooser::type(int val) {
_btype = val; _btype = val;
} }
// GET TYPE OF BROWSER // GET TYPE OF BROWSER
int FNFC_CLASS::type() const { int Fl_Native_File_Chooser::type() const {
return( _btype ); return( _btype );
} }
// SET OPTIONS // SET OPTIONS
void FNFC_CLASS::options(int val) { void Fl_Native_File_Chooser::options(int val) {
_options = val; _options = val;
} }
// GET OPTIONS // GET OPTIONS
int FNFC_CLASS::options() const { int Fl_Native_File_Chooser::options() const {
return(_options); return(_options);
} }
// PRIVATE: SET ERROR MESSAGE // PRIVATE: SET ERROR MESSAGE
void FNFC_CLASS::errmsg(const char *val) { void Fl_Native_File_Chooser::errmsg(const char *val) {
_errmsg = strfree(_errmsg); _errmsg = strfree(_errmsg);
_errmsg = strnew(val); _errmsg = strnew(val);
} }
// FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS // FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS
void FNFC_CLASS::clear_pathnames() { void Fl_Native_File_Chooser::clear_pathnames() {
if ( _pathnames ) { if ( _pathnames ) {
while ( --_tpathnames >= 0 ) { while ( --_tpathnames >= 0 ) {
_pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]); _pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]);
@ -199,7 +199,7 @@ void FNFC_CLASS::clear_pathnames() {
} }
// SET A SINGLE PATHNAME // SET A SINGLE PATHNAME
void FNFC_CLASS::set_single_pathname(const char *s) { void Fl_Native_File_Chooser::set_single_pathname(const char *s) {
clear_pathnames(); clear_pathnames();
_pathnames = new char*[1]; _pathnames = new char*[1];
_pathnames[0] = strnew(s); _pathnames[0] = strnew(s);
@ -207,7 +207,7 @@ void FNFC_CLASS::set_single_pathname(const char *s) {
} }
// ADD PATHNAME TO EXISTING ARRAY // ADD PATHNAME TO EXISTING ARRAY
void FNFC_CLASS::add_pathname(const char *s) { void Fl_Native_File_Chooser::add_pathname(const char *s) {
if ( ! _pathnames ) { if ( ! _pathnames ) {
// Create first element in array // Create first element in array
++_tpathnames; ++_tpathnames;
@ -225,7 +225,7 @@ void FNFC_CLASS::add_pathname(const char *s) {
} }
// FREE A PIDL (Pointer to IDentity List) // FREE A PIDL (Pointer to IDentity List)
void FNFC_CLASS::FreePIDL(ITEMIDLIST *pidl) { void Fl_Native_File_Chooser::FreePIDL(ITEMIDLIST *pidl) {
IMalloc *imalloc = NULL; IMalloc *imalloc = NULL;
if ( SUCCEEDED(SHGetMalloc(&imalloc)) ) { if ( SUCCEEDED(SHGetMalloc(&imalloc)) ) {
imalloc->Free(pidl); imalloc->Free(pidl);
@ -235,7 +235,7 @@ void FNFC_CLASS::FreePIDL(ITEMIDLIST *pidl) {
} }
// CLEAR MICROSOFT OFN (OPEN FILE NAME) CLASS // CLEAR MICROSOFT OFN (OPEN FILE NAME) CLASS
void FNFC_CLASS::ClearOFN() { void Fl_Native_File_Chooser::ClearOFN() {
// Free any previously allocated lpstrFile before zeroing out _ofn // Free any previously allocated lpstrFile before zeroing out _ofn
if ( _ofn.lpstrFile ) { if ( _ofn.lpstrFile ) {
delete [] _ofn.lpstrFile; delete [] _ofn.lpstrFile;
@ -253,7 +253,7 @@ void FNFC_CLASS::ClearOFN() {
} }
// CLEAR MICROSOFT BINF (BROWSER INFO) CLASS // CLEAR MICROSOFT BINF (BROWSER INFO) CLASS
void FNFC_CLASS::ClearBINF() { void Fl_Native_File_Chooser::ClearBINF() {
if ( _binf.pidlRoot ) { if ( _binf.pidlRoot ) {
FreePIDL((ITEMIDLIST*)_binf.pidlRoot); FreePIDL((ITEMIDLIST*)_binf.pidlRoot);
_binf.pidlRoot = NULL; _binf.pidlRoot = NULL;
@ -262,19 +262,19 @@ void FNFC_CLASS::ClearBINF() {
} }
// CONVERT WINDOWS BACKSLASHES TO UNIX FRONTSLASHES // CONVERT WINDOWS BACKSLASHES TO UNIX FRONTSLASHES
void FNFC_CLASS::Win2Unix(char *s) { void Fl_Native_File_Chooser::Win2Unix(char *s) {
for ( ; *s; s++ ) for ( ; *s; s++ )
if ( *s == '\\' ) *s = '/'; if ( *s == '\\' ) *s = '/';
} }
// CONVERT UNIX FRONTSLASHES TO WINDOWS BACKSLASHES // CONVERT UNIX FRONTSLASHES TO WINDOWS BACKSLASHES
void FNFC_CLASS::Unix2Win(char *s) { void Fl_Native_File_Chooser::Unix2Win(char *s) {
for ( ; *s; s++ ) for ( ; *s; s++ )
if ( *s == '/' ) *s = '\\'; if ( *s == '/' ) *s = '\\';
} }
// SHOW FILE BROWSER // SHOW FILE BROWSER
int FNFC_CLASS::showfile() { int Fl_Native_File_Chooser::showfile() {
ClearOFN(); ClearOFN();
clear_pathnames(); clear_pathnames();
size_t fsize = MAX_PATH; size_t fsize = MAX_PATH;
@ -437,7 +437,7 @@ int FNFC_CLASS::showfile() {
// Ref: Usenet: microsoft.public.vc.mfc, Dec 8 2000, 1:38p David Lowndes // Ref: Usenet: microsoft.public.vc.mfc, Dec 8 2000, 1:38p David Lowndes
// Subject: How to specify to select an initial folder .." // Subject: How to specify to select an initial folder .."
// //
int CALLBACK FNFC_CLASS::Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data) { int CALLBACK Fl_Native_File_Chooser::Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data) {
switch (msg) { switch (msg) {
case BFFM_INITIALIZED: case BFFM_INITIALIZED:
if (data) ::SendMessage(win, BFFM_SETSELECTION, TRUE, data); if (data) ::SendMessage(win, BFFM_SETSELECTION, TRUE, data);
@ -462,7 +462,7 @@ int CALLBACK FNFC_CLASS::Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data) {
} }
// SHOW DIRECTORY BROWSER // SHOW DIRECTORY BROWSER
int FNFC_CLASS::showdir() { int Fl_Native_File_Chooser::showdir() {
OleInitialize(NULL); // init needed by BIF_USENEWUI OleInitialize(NULL); // init needed by BIF_USENEWUI
ClearBINF(); ClearBINF();
clear_pathnames(); clear_pathnames();
@ -531,7 +531,7 @@ int FNFC_CLASS::showdir() {
// 1 - user cancelled // 1 - user cancelled
// -1 - failed; errmsg() has reason // -1 - failed; errmsg() has reason
// //
int FNFC_CLASS::show() { int Fl_Native_File_Chooser::show() {
if ( _btype == BROWSE_DIRECTORY || if ( _btype == BROWSE_DIRECTORY ||
_btype == BROWSE_MULTI_DIRECTORY || _btype == BROWSE_MULTI_DIRECTORY ||
_btype == BROWSE_SAVE_DIRECTORY ) { _btype == BROWSE_SAVE_DIRECTORY ) {
@ -542,31 +542,31 @@ int FNFC_CLASS::show() {
} }
// RETURN ERROR MESSAGE // RETURN ERROR MESSAGE
const char *FNFC_CLASS::errmsg() const { const char *Fl_Native_File_Chooser::errmsg() const {
return(_errmsg ? _errmsg : "No error"); return(_errmsg ? _errmsg : "No error");
} }
// GET FILENAME // GET FILENAME
const char* FNFC_CLASS::filename() const { const char* Fl_Native_File_Chooser::filename() const {
if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]); if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]);
return(""); return("");
} }
// GET FILENAME FROM LIST OF FILENAMES // GET FILENAME FROM LIST OF FILENAMES
const char* FNFC_CLASS::filename(int i) const { const char* Fl_Native_File_Chooser::filename(int i) const {
if ( _pathnames && i < _tpathnames ) return(_pathnames[i]); if ( _pathnames && i < _tpathnames ) return(_pathnames[i]);
return(""); return("");
} }
// GET TOTAL FILENAMES CHOSEN // GET TOTAL FILENAMES CHOSEN
int FNFC_CLASS::count() const { int Fl_Native_File_Chooser::count() const {
return(_tpathnames); return(_tpathnames);
} }
// PRESET PATHNAME // PRESET PATHNAME
// Can be NULL if no preset is desired. // Can be NULL if no preset is desired.
// //
void FNFC_CLASS::directory(const char *val) { void Fl_Native_File_Chooser::directory(const char *val) {
_directory = strfree(_directory); _directory = strfree(_directory);
_directory = strnew(val); _directory = strnew(val);
} }
@ -574,14 +574,14 @@ void FNFC_CLASS::directory(const char *val) {
// GET PRESET PATHNAME // GET PRESET PATHNAME
// Can return NULL if none set. // Can return NULL if none set.
// //
const char *FNFC_CLASS::directory() const { const char *Fl_Native_File_Chooser::directory() const {
return(_directory); return(_directory);
} }
// SET TITLE // SET TITLE
// Can be NULL if no title desired. // Can be NULL if no title desired.
// //
void FNFC_CLASS::title(const char *val) { void Fl_Native_File_Chooser::title(const char *val) {
_title = strfree(_title); _title = strfree(_title);
_title = strnew(val); _title = strnew(val);
} }
@ -589,14 +589,14 @@ void FNFC_CLASS::title(const char *val) {
// GET TITLE // GET TITLE
// Can return NULL if none set. // Can return NULL if none set.
// //
const char *FNFC_CLASS::title() const { const char *Fl_Native_File_Chooser::title() const {
return(_title); return(_title);
} }
// SET FILTER // SET FILTER
// Can be NULL if no filter needed // Can be NULL if no filter needed
// //
void FNFC_CLASS::filter(const char *val) { void Fl_Native_File_Chooser::filter(const char *val) {
_filter = strfree(_filter); _filter = strfree(_filter);
clear_filters(); clear_filters();
if ( val ) { if ( val ) {
@ -613,18 +613,18 @@ void FNFC_CLASS::filter(const char *val) {
// GET FILTER // GET FILTER
// Can return NULL if none set. // Can return NULL if none set.
// //
const char *FNFC_CLASS::filter() const { const char *Fl_Native_File_Chooser::filter() const {
return(_filter); return(_filter);
} }
// CLEAR FILTERS // CLEAR FILTERS
void FNFC_CLASS::clear_filters() { void Fl_Native_File_Chooser::clear_filters() {
_nfilters = 0; _nfilters = 0;
_parsedfilt = strfree(_parsedfilt); _parsedfilt = strfree(_parsedfilt);
} }
// ADD A FILTER // ADD A FILTER
void FNFC_CLASS::add_filter(const char *name_in, // name of filter (optional: can be null) void Fl_Native_File_Chooser::add_filter(const char *name_in, // name of filter (optional: can be null)
const char *winfilter) { // windows style filter (eg. "*.cxx;*.h") const char *winfilter) { // windows style filter (eg. "*.cxx;*.h")
// No name? Make one.. // No name? Make one..
char name[1024]; char name[1024];
@ -662,7 +662,7 @@ void FNFC_CLASS::add_filter(const char *name_in, // name of filter (optional: ca
// \_____/ \_______/ // \_____/ \_______/
// Name Wildcard // Name Wildcard
// //
void FNFC_CLASS::parse_filter(const char *in) { void Fl_Native_File_Chooser::parse_filter(const char *in) {
clear_filters(); clear_filters();
if ( ! in ) return; if ( ! in ) return;
@ -795,23 +795,23 @@ void FNFC_CLASS::parse_filter(const char *in) {
} }
// SET 'CURRENTLY SELECTED FILTER' // SET 'CURRENTLY SELECTED FILTER'
void FNFC_CLASS::filter_value(int i) { void Fl_Native_File_Chooser::filter_value(int i) {
_ofn.nFilterIndex = i + 1; _ofn.nFilterIndex = i + 1;
} }
// RETURN VALUE OF 'CURRENTLY SELECTED FILTER' // RETURN VALUE OF 'CURRENTLY SELECTED FILTER'
int FNFC_CLASS::filter_value() const { int Fl_Native_File_Chooser::filter_value() const {
return(_ofn.nFilterIndex ? _ofn.nFilterIndex-1 : _nfilters+1); return(_ofn.nFilterIndex ? _ofn.nFilterIndex-1 : _nfilters+1);
} }
// PRESET FILENAME FOR 'SAVE AS' CHOOSER // PRESET FILENAME FOR 'SAVE AS' CHOOSER
void FNFC_CLASS::preset_file(const char* val) { void Fl_Native_File_Chooser::preset_file(const char* val) {
_preset_file = strfree(_preset_file); _preset_file = strfree(_preset_file);
_preset_file = strnew(val); _preset_file = strnew(val);
} }
// GET PRESET FILENAME FOR 'SAVE AS' CHOOSER // GET PRESET FILENAME FOR 'SAVE AS' CHOOSER
const char* FNFC_CLASS::preset_file() const { const char* Fl_Native_File_Chooser::preset_file() const {
return(_preset_file); return(_preset_file);
} }
@ -843,6 +843,8 @@ LPCWSTR utf8towchar(const char *in)
return wout; return wout;
} }
#endif /*!FL_DOXYGEN*/
// //
// End of "$Id$". // End of "$Id$".
// //