diff --git a/src/Makefile.am b/src/Makefile.am index 2ef1503..0676bc5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -268,7 +268,6 @@ flmsg_SOURCES += \ widgets/Fl_Text_Buffer_mod.cxx \ widgets/Fl_Text_Editor_mod.cxx \ widgets/Fl_Text_Display_mod.cxx \ - widgets/Fl_Native_File_Chooser.cxx \ widgets/FTextView.cxx \ widgets/icons.cxx \ widgets/pixmaps.cxx \ @@ -295,9 +294,6 @@ EXTRA_DIST += \ config.h \ utils/mingw.c \ widgets/flnfc_common.cxx \ - widgets/Fl_Native_File_Chooser_FLTK.cxx \ - widgets/Fl_Native_File_Chooser_MAC.cxx \ - widgets/Fl_Native_File_Chooser_WIN32.cxx \ include/arl_msgs.h \ include/arq.h \ include/flmsg_arq.h \ @@ -362,10 +358,6 @@ EXTRA_DIST += \ include/Fl_Text_Editor_mod_1_1.H \ include/Fl_Text_Editor_mod_1_3.H \ include/FTextView.h \ - include/FL/Fl_Native_File_Chooser_FLTK.H \ - include/FL/Fl_Native_File_Chooser_MAC.H \ - include/FL/Fl_Native_File_Chooser.H \ - include/FL/Fl_Native_File_Chooser_WIN32.H \ include/blank.h \ include/csv.h \ include/missing_strings.h \ diff --git a/src/include/FL/Fl_Native_File_Chooser.H b/src/include/FL/Fl_Native_File_Chooser.H deleted file mode 100644 index f55c7e3..0000000 --- a/src/include/FL/Fl_Native_File_Chooser.H +++ /dev/null @@ -1,42 +0,0 @@ -// -// Fl_Native_File_Chooser.H -- FLTK native OS file chooser widget -// -// Copyright 2004 by Greg Ercolano. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// -// Free Software Foundation, Inc. -// 51 Franklin Street, Fifth Floor -// Boston, MA 02110-1301 USA. -// - -#ifndef FL_NATIVE_FILE_CHOOSER_H -#define FL_NATIVE_FILE_CHOOSER_H - -// Use Windows' chooser -#if defined(_WIN32) || defined(__CYGWIN__) -#include -#endif - -// Use Apple's chooser -#ifdef __APPLE__ -#include -#endif - -// All else falls back to FLTK's own chooser -#if ! defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) -#include -#endif - -#endif /*FL_NATIVE_FILE_CHOOSER_H*/ diff --git a/src/include/FL/Fl_Native_File_Chooser_FLTK.H b/src/include/FL/Fl_Native_File_Chooser_FLTK.H deleted file mode 100644 index f1cf637..0000000 --- a/src/include/FL/Fl_Native_File_Chooser_FLTK.H +++ /dev/null @@ -1,103 +0,0 @@ -// -// Fl_Native_File_Chooser_DEFAULT.H -- FLTK native OS file chooser widget -// -// Copyright 2005 by Nathan Vander Wilt. -// March 2005 - wrapper around Fl_File_Chooser -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// -// Free Software Foundation, Inc. -// 51 Franklin Street, Fifth Floor -// Boston, MA 02110-1301 USA. -// - -#include -#include - -#include -#include "icons.h" -#include "gettext.h" - -class Fl_Native_File_Chooser { -public: - enum Type { - BROWSE_FILE = 0, - BROWSE_DIRECTORY, - BROWSE_MULTI_FILE, - BROWSE_MULTI_DIRECTORY, - BROWSE_SAVE_FILE, - BROWSE_SAVE_DIRECTORY - }; - enum Option { - NO_OPTIONS = 0x0000, // no options enabled - SAVEAS_CONFIRM = 0x0001, // Show native 'Save As' overwrite - // confirm dialog (if supported) - NEW_FOLDER = 0x0002, // Show 'New Folder' icon - // (if supported) - PREVIEW = 0x0004 // enable preview mode - }; -private: - int _btype; // kind-of browser to show() - int _options; // general options - char *_filter; // user supplied filter - char *_parsedfilt; // parsed filter - int _filtvalue; // selected filter - char *_preset_file; - char *_prevvalue; // Returned filename - char *_directory; - char *_errmsg; // error message - Fl_File_Chooser *file_chooser; - - int exist_dialog() { - return(fl_choice2(_("File exists. Are you sure you want to overwrite?"), - _("Cancel"), _("OK"), NULL)); - } - void load_system_icons() { - Fl_File_Icon::load_system_icons(); - } - - int _nfilters; - - // Private methods - void errmsg(const char *msg); - int type_fl_file(int); - void parse_filter(); - void keeplocation(); - -public: - Fl_Native_File_Chooser(int val=BROWSE_FILE); - ~Fl_Native_File_Chooser(); - - // Public methods - void type(int); - int type() const; - void options(int); - int options() const; - int count() const; - const char *filename() const; - const char *filename(int i) const; - void directory(const char *val); - const char *directory() const; - void title(const char *); - const char* title() const; - const char *filter() const; - void filter(const char *); - int filters() const { return(_nfilters); } - void filter_value(int i); - int filter_value() const; - void preset_file(const char*); - const char* preset_file() const; - const char *errmsg() const; - int show(); -}; diff --git a/src/include/FL/Fl_Native_File_Chooser_MAC.H b/src/include/FL/Fl_Native_File_Chooser_MAC.H deleted file mode 100644 index 67a3be3..0000000 --- a/src/include/FL/Fl_Native_File_Chooser_MAC.H +++ /dev/null @@ -1,140 +0,0 @@ -// -// Fl_Native_File_Chooser_MAC.H -- FLTK native OS file chooser widget -// -// Copyright 2004 by Greg Ercolano. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// -// Free Software Foundation, Inc. -// 51 Franklin Street, Fifth Floor -// Boston, MA 02110-1301 USA. -// -// 10 20 30 40 50 60 70 -// | | | | | | | -// 4567890123456789012345678901234567890123456789012345678901234567890123456789 - -// OSX-SPECIFIC NATIVE BROWSER -#ifdef __APPLE_CC__ -#include -#else -#include -#endif - -#include -#define MAXFILTERS 80 - -class Fl_Native_File_Chooser { -public: - enum Type { - BROWSE_FILE = 0, - BROWSE_DIRECTORY, - BROWSE_MULTI_FILE, - BROWSE_MULTI_DIRECTORY, - BROWSE_SAVE_FILE, - BROWSE_SAVE_DIRECTORY - }; - enum Option { - NO_OPTIONS = 0x0000, // no options enabled - SAVEAS_CONFIRM = 0x0001, // Show native 'Save As' overwrite - // confirm dialog (if supported) - NEW_FOLDER = 0x0002, // Show 'New Folder' icon - // (if supported) - PREVIEW = 0x0004, // enable preview mode - }; -protected: - NavDialogCreationOptions _opts; // file navigation options -private: - int _btype; // kind-of browser to show() - int _options; // general options - NavDialogRef _ref; // file navigation reference - NavActionState _keepstate; // holds button permissions - NavMenuItemSpec _tempitem; // Popup menu selection - 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 CLASS TO HANDLE NAVIGATION DIALOG REPLY STRUCT - // Class-ified, mainly to ensure proper cleanup. - // - class NavReply { - int _valid_reply; - NavReplyRecord _reply; - public: - NavReply(); - ~NavReply(); - int get_reply(NavDialogRef& ref); - int get_saveas_basename(char *s, int slen); - int get_dirname(char *s, int slen); - int get_pathnames(char **&pathnames, int& tpathnames); - }; - - // Private methods - void errmsg(const char *msg); - void clear_pathnames(); - void set_single_pathname(const char *s); - int get_saveas_basename(NavDialogRef& ref); - int get_pathnames(NavDialogRef& ref); - static void event_handler(NavEventCallbackMessage callBackSelector, - NavCBRecPtr cbparm, void *data); - - void clear_filters(); - void add_filter(const char *, const char *); - void parse_filter(const char *from); - static Boolean filter_proc_cb(AEDesc *, void *, void *, NavFilterModes); - Boolean filter_proc_cb2(AEDesc*, void*, void*, NavFilterModes); - int post(); - -public: - Fl_Native_File_Chooser(int val = BROWSE_FILE); - ~Fl_Native_File_Chooser(); - - // Public methods - void type(int); - int type() const; - void options(int); - int options() const; - int count() const; - const char *filename() const; - const char *filename(int i) const; - void directory(const char *); - const char *directory() const; - void title(const char *); - const char *title() const; - const char *filter() const; - void filter(const char *); - void filter_value(int i) { _filt_value = i; } - int filter_value() { return(_filt_value); } - int filters() { return(_filt_total); } - void preset_file(const char *); - const char *preset_file(); - const char *errmsg() const; - int show(); -}; diff --git a/src/include/FL/Fl_Native_File_Chooser_WIN32.H b/src/include/FL/Fl_Native_File_Chooser_WIN32.H deleted file mode 100644 index 12868d6..0000000 --- a/src/include/FL/Fl_Native_File_Chooser_WIN32.H +++ /dev/null @@ -1,110 +0,0 @@ -// -// Fl_Native_File_Chooser_WINDOWS.H -- FLTK native OS file chooser widget -// -// Copyright 2004 by Greg Ercolano. -// April 2005 - API changes, improved filter processing by Nathan Vander Wilt -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// -// Free Software Foundation, Inc. -// 51 Franklin Street, Fifth Floor -// Boston, MA 02110-1301 USA. -// - -// #define _WIN32_WINNT 0x0501 // needed for OPENFILENAME's 'FlagsEx' -#include -#include // malloc -#include -#include // OPENFILENAME, GetOpenFileName() -#include // BROWSEINFO, SHBrowseForFolder() - -class Fl_Native_File_Chooser { -public: - enum Type { - BROWSE_FILE = 0, - BROWSE_DIRECTORY, - BROWSE_MULTI_FILE, - BROWSE_MULTI_DIRECTORY, - BROWSE_SAVE_FILE, - BROWSE_SAVE_DIRECTORY - }; - enum Option { - NO_OPTIONS = 0x0000, // no options enabled - SAVEAS_CONFIRM = 0x0001, // Show native 'Save As' overwrite - // confirm dialog (if supported) - NEW_FOLDER = 0x0002, // Show 'New Folder' icon - // (if supported) - PREVIEW = 0x0004, // enable preview mode - }; -private: - int _btype; // kind-of browser to show() - int _options; // general options - OPENFILENAME _ofn; // GetOpenFileName() & GetSaveFileName() struct - BROWSEINFO _binf; // 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 FreePIDL(ITEMIDLIST *pidl); - void ClearOFN(); - void ClearBINF(); - void Win2Unix(char *s); - void Unix2Win(char *s); - int showfile(); - static int CALLBACK Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data); - int showdir(); - - void parse_filter(const char *); - void clear_filters(); - void add_filter(const char *, const char *); - -public: - Fl_Native_File_Chooser(int val = BROWSE_FILE); - ~Fl_Native_File_Chooser(); - - // Public methods - void type(int val); - int type() const; - void options(int); - int options() const; - int count() const; - const char *filename() const; - const char *filename(int i) const; - void directory(const char *val); - const char *directory() const; - void title(const char *val); - const char *title() const; - const char *filter() const; - void filter(const char *val); - int filters() const { return _nfilters; } - void filter_value(int i); - int filter_value() const; - void preset_file(const char *); - const char *preset_file() const; - const char *errmsg() const; - int show(); -}; diff --git a/src/widgets/Fl_Native_File_Chooser.cxx b/src/widgets/Fl_Native_File_Chooser.cxx deleted file mode 100644 index 5d19e20..0000000 --- a/src/widgets/Fl_Native_File_Chooser.cxx +++ /dev/null @@ -1,50 +0,0 @@ -// -// Fl_Native_File_Chooser.cxx -- FLTK native OS file chooser widget -// -// Copyright 2004 by Greg Ercolano. -// -// ---------------------------------------------------------------------------- -// Copyright (C) 2014 -// David Freese, W1HKJ -// -// This file is part of flmsg -// -// flrig is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// flrig is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ---------------------------------------------------------------------------- - -#include - -#if FLMSG_FLTK_API_MAJOR == 1 && FLMSG_FLTK_API_MINOR < 3 - -// Use Windows' chooser -# if defined(__WIN32__) || defined(__CYGWIN__) -# include "Fl_Native_File_Chooser_WIN32.cxx" -# endif - -// Use Apple's chooser -# ifdef __APPLE__ -# include "Fl_Native_File_Chooser_MAC.cxx" -# endif - -// All else falls back to FLTK's own chooser -# if ! defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) -# include "Fl_Native_File_Chooser_FLTK.cxx" -# endif - -#else -# ifdef __WIN32__ -# include "Fl_Native_File_Chooser_WIN32.cxx" -# endif - -#endif diff --git a/src/widgets/Fl_Native_File_Chooser_FLTK.cxx b/src/widgets/Fl_Native_File_Chooser_FLTK.cxx deleted file mode 100644 index 49696b8..0000000 --- a/src/widgets/Fl_Native_File_Chooser_FLTK.cxx +++ /dev/null @@ -1,373 +0,0 @@ -// -// Fl_Native_File_Chooser_FLTK.cxx -- FLTK native OS file chooser widget -// -// Copyright 2004 by Greg Ercolano. -// API changes + filter improvements by Nathan Vander Wilt 2005 -// ---------------------------------------------------------------------------- -// Copyright (C) 2014 -// David Freese, W1HKJ -// -// This file is part of flmsg -// -// flrig is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// flrig is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ---------------------------------------------------------------------------- - -#define FLTK1 - -#ifdef FLTK1 -// -// FLTK1 -// -#include -#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_DIRECTORY Fl_File_Chooser::DIRECTORY -#define FLTK_CHOOSER_MULTI Fl_File_Chooser::MULTI -#define FLTK_CHOOSER_CREATE Fl_File_Chooser::CREATE -#else -// -// FLTK2 -// -#include -#include -#define FNFC_CTOR NativeFileChooser -#define FNFC_CLASS fltk::FNFC_CTOR -#define FLTK_CHOOSER_SINGLE fltk::FileChooser::SINGLE -#define FLTK_CHOOSER_DIRECTORY fltk::FileChooser::DIRECTORY -#define FLTK_CHOOSER_MULTI fltk::FileChooser::MULTI -#define FLTK_CHOOSER_CREATE fltk::FileChooser::CREATE -#endif - -#include "flnfc_common.cxx" -#include - -// CTOR -FNFC_CLASS::FNFC_CTOR(int val) { - static int init = 0; // 'first time' initialize flag - if ( init == 0 ) { - // Initialize when instanced for first time - load_system_icons(); - init = 1; - } - _btype = val; - _options = NO_OPTIONS; - _filter = NULL; - _filtvalue = 0; - _parsedfilt = NULL; - _preset_file = NULL; - _prevvalue = NULL; - _directory = NULL; - _errmsg = NULL; -#ifdef FLTK1 - file_chooser = new Fl_File_Chooser(NULL, NULL, 0, NULL); -#else - file_chooser = new fltk::FileChooser(NULL, NULL, 0, NULL); -#endif - type(val); // do this after file_chooser created - _nfilters = 0; -} - -// DTOR -FNFC_CLASS::~FNFC_CTOR() { - delete file_chooser; - _filter = strfree(_filter); - _parsedfilt = strfree(_parsedfilt); - _preset_file = strfree(_preset_file); - _prevvalue = strfree(_prevvalue); - _directory = strfree(_directory); - _errmsg = strfree(_errmsg); -} - -// PRIVATE: SET ERROR MESSAGE -void FNFC_CLASS::errmsg(const char *msg) { - _errmsg = strfree(_errmsg); - _errmsg = strnew(msg); -} - -// PRIVATE: translate Native types to Fl_File_Chooser types -int FNFC_CLASS::type_fl_file(int val) { - switch (val) { - case BROWSE_FILE: - return(FLTK_CHOOSER_SINGLE); - case BROWSE_DIRECTORY: - return(FLTK_CHOOSER_SINGLE | FLTK_CHOOSER_DIRECTORY); - case BROWSE_MULTI_FILE: - return(FLTK_CHOOSER_MULTI); - case BROWSE_MULTI_DIRECTORY: - return(FLTK_CHOOSER_DIRECTORY | FLTK_CHOOSER_MULTI); - case BROWSE_SAVE_FILE: - return(FLTK_CHOOSER_SINGLE | FLTK_CHOOSER_CREATE); - case BROWSE_SAVE_DIRECTORY: - return(FLTK_CHOOSER_DIRECTORY | FLTK_CHOOSER_MULTI | FLTK_CHOOSER_CREATE); - default: - return(FLTK_CHOOSER_SINGLE); - } -} - -void FNFC_CLASS::type(int val) { - _btype = val; - file_chooser->type(type_fl_file(val)); -} - -int FNFC_CLASS::type() const { - return(_btype); -} - -// SET OPTIONS -void FNFC_CLASS::options(int val) { - _options = val; -} - -// GET OPTIONS -int FNFC_CLASS::options() const { - return(_options); -} - -// Show chooser, blocks until done. -// RETURNS: -// 0 - user picked a file -// 1 - user cancelled -// -1 - failed; errmsg() has reason -// -int FNFC_CLASS::show() { - // FILTER - if ( _parsedfilt ) { - file_chooser->filter(_parsedfilt); - } - - // FILTER VALUE - // Set this /after/ setting the filter - // - file_chooser->filter_value(_filtvalue); - - // DIRECTORY - if ( _directory && _directory[0] ) { - file_chooser->directory(_directory); - } else { - file_chooser->directory(_prevvalue); - } - - // PRESET FILE - if ( _preset_file ) { - file_chooser->value(_preset_file); - } - - // OPTIONS: PREVIEW - file_chooser->preview( (options() & PREVIEW) ? 1 : 0); - - // OPTIONS: NEW FOLDER - if ( options() & NEW_FOLDER ) - file_chooser->type(file_chooser->type() | - FLTK_CHOOSER_CREATE); // on - - // SHOW - file_chooser->show(); - -#ifdef FLTK1 - // FLTK1: BLOCK WHILE BROWSER SHOWN - while ( file_chooser->shown() ) { - Fl::wait(); - } -#else - // FLTK2: BLOCK WHILE BROWSER SHOWN - while ( file_chooser->visible() ) { - fltk::wait(); - } -#endif - - if ( file_chooser->value() && file_chooser->value()[0] ) { - _prevvalue = strfree(_prevvalue); - _prevvalue = strnew(file_chooser->value()); - _filtvalue = file_chooser->filter_value(); // update filter value - - // HANDLE SHOWING 'SaveAs' CONFIRM - if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) { - struct stat buf; - if ( stat(file_chooser->value(), &buf) != -1 ) { - if ( buf.st_mode & S_IFREG ) { // Regular file + exists? - if ( exist_dialog() == 0 ) { - return(1); - } - } - } - } - } - - if ( file_chooser->count() ) return(0); - else return(1); -} - -// RETURN ERROR MESSAGE -const char *FNFC_CLASS::errmsg() const { - return(_errmsg ? _errmsg : "No error"); -} - -// GET FILENAME -const char* FNFC_CLASS::filename() const { - if ( file_chooser->count() > 0 ) return(file_chooser->value()); - return(""); -} - -// GET FILENAME FROM LIST OF FILENAMES -const char* FNFC_CLASS::filename(int i) const { - if ( i < file_chooser->count() ) - return(file_chooser->value(i+1)); // convert fltk 1 based to our 0 based - return(""); -} - -// SET TITLE -// Can be NULL if no title desired. -// -void FNFC_CLASS::title(const char *val) { - file_chooser->label(val); -} - -// GET TITLE -// Can return NULL if none set. -// -const char *FNFC_CLASS::title() const { - return(file_chooser->label()); -} - -// SET FILTER -// Can be NULL if no filter needed -// -void FNFC_CLASS::filter(const char *val) { - _filter = strfree(_filter); - _filter = strnew(val); - parse_filter(); -} - -// GET FILTER -const char *FNFC_CLASS::filter() const { - return(_filter); -} - -// SET SELECTED FILTER -void FNFC_CLASS::filter_value(int val) { - _filtvalue = val; -} - -// RETURN SELECTED FILTER -int FNFC_CLASS::filter_value() const { - return(_filtvalue); -} - -// GET TOTAL FILENAMES CHOSEN -int FNFC_CLASS::count() const { - return(file_chooser->count()); -} - -// PRESET PATHNAME -// Can be NULL if no preset is desired. -// -void FNFC_CLASS::directory(const char *val) { - _directory = strfree(_directory); - _directory = strnew(val); -} - -// GET PRESET PATHNAME -// Can return NULL if none set. -// -const char *FNFC_CLASS::directory() const { - return(_directory); -} - -// Convert our filter format to fltk's chooser format -// FROM TO (FLTK) -// ------------------------- -------------------------- -// "*.cxx" "*.cxx Files(*.cxx)" -// "C Files\t*.{cxx,h}" "C Files(*.{cxx,h})" -// "C Files\t*.{cxx,h}\nText Files\t*.txt" "C Files(*.{cxx,h})\tText Files(*.txt)" -// -// Returns a modified version of the filter that the caller is responsible -// for freeing with strfree(). -// -void FNFC_CLASS::parse_filter() { - _parsedfilt = strfree(_parsedfilt); // clear previous parsed filter (if any) - _nfilters = 0; - char *in = _filter; - if ( !in ) return; - - int has_name = strchr(in, '\t') ? 1 : 0; - - char mode = has_name ? 'n' : 'w'; // parse mode: n=title, w=wildcard - char wildcard[1024] = ""; // parsed wildcard - char name[1024] = ""; - - // Parse filter user specified - for ( ; 1; in++ ) { - - /*** DEBUG - printf("WORKING ON '%c': mode=<%c> name=<%s> wildcard=<%s>\n", - *in, mode, name, wildcard); - ***/ - - switch (*in) { - // FINISHED PARSING NAME? - case '\t': - if ( mode != 'n' ) goto regchar; - mode = 'w'; - break; - - // ESCAPE NEXT CHAR - case '\\': - ++in; - goto regchar; - - // FINISHED PARSING ONE OF POSSIBLY SEVERAL FILTERS? - case '\r': - case '\n': - case '\0': - // APPEND NEW FILTER TO LIST - if ( wildcard[0] ) { - // OUT: "name(wild)\tname(wild)" - char comp[2048]; - snprintf(comp, sizeof(comp), "%s%.511s(%.511s)", ((_parsedfilt)?"\t":""), - name, wildcard); - _parsedfilt = strapp(_parsedfilt, comp); - _nfilters++; - //DEBUG printf("DEBUG: PARSED FILT NOW <%s>\n", _parsedfilt); - } - // RESET - wildcard[0] = name[0] = '\0'; - mode = strchr(in, '\t') ? 'n' : 'w'; - // DONE? - if ( *in == '\0' ) return; // done - else continue; // not done yet, more filters - - // Parse all other chars - default: // handle all non-special chars - regchar: // handle regular char - switch ( mode ) { - case 'n': chrcat(name, *in); continue; - case 'w': chrcat(wildcard, *in); continue; - } - break; - } - } - //NOTREACHED -} - -// SET PRESET FILENAME -void FNFC_CLASS::preset_file(const char* val) { - _preset_file = strfree(_preset_file); - _preset_file = strnew(val); -} - -// GET PRESET FILENAME -const char* FNFC_CLASS::preset_file() const { - return(_preset_file); -} diff --git a/src/widgets/Fl_Native_File_Chooser_MAC.cxx b/src/widgets/Fl_Native_File_Chooser_MAC.cxx deleted file mode 100644 index ab3755a..0000000 --- a/src/widgets/Fl_Native_File_Chooser_MAC.cxx +++ /dev/null @@ -1,859 +0,0 @@ -// -// Fl_Native_File_Chooser_MAC.cxx -- FLTK native OS file chooser widget -// -// Copyright 2004 by Greg Ercolano. -// FLTK2/MAC port by Greg Ercolano 2007. -// ---------------------------------------------------------------------------- -// Copyright (C) 2014 -// David Freese, W1HKJ -// -// This file is part of flmsg -// -// flrig is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// flrig is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ---------------------------------------------------------------------------- - -#include "flnfc_common.cxx" // strnew/strfree/strapp/chrcat - -#define FLTK1 - -#ifdef FLTK1 -// -// FLTK1 -// -#include -#include -#include -#define FNFC_CLASS Fl_Native_File_Chooser -#define FNFC_CTOR Fl_Native_File_Chooser -#else -// -// FLTK2 -// -#include -#include -#include -#define FNFC_CTOR NativeFileChooser -#define FNFC_CLASS fltk::FNFC_CTOR -#define fl_filename_match filename_match // fltk1 name -> fltk2 name -#define fl_filename_isdir filename_isdir // fltk1 name -> fltk2 name -#endif - -// TRY TO CONVERT AN AEDesc TO AN FSSpec -// As per Apple Technical Q&A QA1274 -// eg: http://developer.apple.com/qa/qa2001/qa1274.html -// Returns 'noErr' if OK, -// or an 'OSX result code' on error. -// -static int AEDescToFSSpec(const AEDesc* desc, FSSpec* fsspec) { - OSStatus err = noErr; - AEDesc coerceDesc; - // If AEDesc isn't already an FSSpec, convert it to one - if ( desc->descriptorType != typeFSS ) { - if ( ( err = AECoerceDesc(desc, typeFSS, &coerceDesc) ) == noErr ) { - // Get FSSpec out of AEDesc - err = AEGetDescData(&coerceDesc, fsspec, sizeof(FSSpec)); - AEDisposeDesc(&coerceDesc); - } - } else { - err = AEGetDescData(desc, fsspec, sizeof(FSSpec)); - } - return( err ); -} - -// CONVERT AN FSSpec TO A PATHNAME -static void FSSpecToPath(const FSSpec &spec, char *buff, int bufflen) { - FSRef fsRef; - FSpMakeFSRef(&spec, &fsRef); - FSRefMakePath(&fsRef, (UInt8*)buff, bufflen); -} - -// CONVERT REGULAR PATH -> FSSpec -// If file does not exist, expect fnfErr. -// Returns 'noErr' if OK, -// or an 'OSX result code' on error. -// -static OSStatus PathToFSSpec(const char *path, FSSpec &spec) { - OSStatus err; - FSRef ref; - if ((err = FSPathMakeRef((const UInt8*)path, &ref, NULL)) != noErr) { - return(err); - } - // FSRef -> FSSpec - if ((err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, &spec, - NULL)) != noErr) { - return(err); - } - return(noErr); -} - -// NAVREPLY: CTOR -FNFC_CLASS::NavReply::NavReply() { - _valid_reply = 0; -} - -// NAVREPLY: DTOR -FNFC_CLASS::NavReply::~NavReply() { - if ( _valid_reply ) { - NavDisposeReply(&_reply); - } -} - -// GET REPLY FROM THE NAV* DIALOG -int FNFC_CLASS::NavReply::get_reply(NavDialogRef& ref) { - if ( _valid_reply ) { - NavDisposeReply(&_reply); // dispose of previous - _valid_reply = 0; - } - if ( ref == NULL || NavDialogGetReply(ref, &_reply) != noErr ) { - return(-1); - } - _valid_reply = 1; - return(0); -} - -// RETURN THE BASENAME USER WANTS TO 'Save As' -int FNFC_CLASS::NavReply::get_saveas_basename(char *s, int slen) { - if (CFStringGetCString(_reply.saveFileName, s, slen-1, - kCFStringEncodingUTF8) == false) { - s[0] = '\0'; - return(-1); - } - return(0); -} - -// RETURN THE DIRECTORY NAME -// Returns 0 on success, -1 on error. -// -int FNFC_CLASS::NavReply::get_dirname(char *s, int slen) { - FSSpec fsspec; - if ( AEDescToFSSpec(&_reply.selection, &fsspec) != noErr ) { - // Conversion failed? Return empty name - s[0] = 0; - return(-1); - } - FSSpecToPath(fsspec, s, slen); - return(0); -} - -// RETURN MULTIPLE DIRECTORIES -// Returns: 0 on success with pathnames[] containing pathnames selected, -// -1 on error -// -int FNFC_CLASS::NavReply::get_pathnames(char **&pathnames, - int& tpathnames) { - // How many items selected? - long count = 0; - if ( AECountItems(&_reply.selection, &count) != noErr ) - { return(-1); } - - // Allocate space for that many pathnames - pathnames = new char*[count]; - memset((void*)pathnames, 0, count*sizeof(char*)); - tpathnames = count; - - // Walk list of pathnames selected - for (short index=1; index<=count; index++) { - AEKeyword keyWord; - AEDesc desc; - if (AEGetNthDesc(&_reply.selection, index, typeFSS, &keyWord, - &desc) != noErr) { - pathnames[index-1] = strnew(""); - continue; - } - FSSpec fsspec; - if (AEGetDescData(&desc, &fsspec, sizeof(FSSpec)) != noErr ) { - pathnames[index-1] = strnew(""); - continue; - } - char s[4096]; - FSSpecToPath(fsspec, s, sizeof(s)-1); - pathnames[index-1] = strnew(s); - AEDisposeDesc(&desc); - } - return(0); -} - -// FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS -void FNFC_CLASS::clear_pathnames() { - if ( _pathnames ) { - while ( --_tpathnames >= 0 ) { - _pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]); - } - delete [] _pathnames; - _pathnames = NULL; - } - _tpathnames = 0; -} - -// SET A SINGLE PATHNAME -void FNFC_CLASS::set_single_pathname(const char *s) { - clear_pathnames(); - _pathnames = new char*[1]; - _pathnames[0] = strnew(s); - _tpathnames = 1; -} - -// GET THE 'Save As' FILENAME -// Returns -1 on error, errmsg() has reason, filename == "". -// 0 if OK, filename() has filename chosen. -// -int FNFC_CLASS::get_saveas_basename(NavDialogRef& ref) { - if ( ref == NULL ) { - errmsg("get_saveas_basename: ref is NULL"); - return(-1); - } - NavReply reply; - OSStatus err; - if ((err = reply.get_reply(ref)) != noErr ) { - errmsg("NavReply::get_reply() failed"); - clear_pathnames(); - return(-1); - } - - char pathname[4096] = ""; - // Directory name.. - // -2 leaves room to append '/' - // - if ( reply.get_dirname(pathname, sizeof(pathname)-2) < 0 ) { - clear_pathnames(); - errmsg("NavReply::get_dirname() failed"); - return(-1); - } - // Append '/' - int len = strlen(pathname); - pathname[len++] = '/'; - pathname[len] = '\0'; - // Basename.. - if ( reply.get_saveas_basename(pathname+len, sizeof(pathname)-len) < 0 ) { - clear_pathnames(); - errmsg("NavReply::get_saveas_basename() failed"); - return(-1); - } - set_single_pathname(pathname); - return(0); -} - -// GET (POTENTIALLY) MULTIPLE FILENAMES -// Returns: -// -1 -- error, errmsg() has reason, filename == "" -// 0 -- OK, pathnames()/filename() has pathname(s) chosen -// -int FNFC_CLASS::get_pathnames(NavDialogRef& ref) { - if ( ref == NULL ) { - errmsg("get_saveas_basename: ref is NULL"); - return(-1); - } - NavReply reply; - OSStatus err; - if ((err = reply.get_reply(ref)) != noErr ) { - errmsg("NavReply::get_reply() failed"); - clear_pathnames(); - return(-1); - } - // First, clear pathnames array of any previous contents - clear_pathnames(); - if ( reply.get_pathnames(_pathnames, _tpathnames) < 0 ) { - clear_pathnames(); - errmsg("NavReply::get_dirname() failed"); - return(-1); - } - return(0); -} - -// NAV CALLBACK EVENT HANDLER -void FNFC_CLASS::event_handler( - NavEventCallbackMessage callBackSelector, - NavCBRecPtr cbparm, - void *data) { - OSStatus err; - FNFC_CLASS *nfb = (FNFC_CLASS*)data; - switch (callBackSelector) { - case kNavCBStart: - if ( nfb->directory() || nfb->preset_file() ) { - const char *pathname = nfb->directory() - ? nfb->directory() - : nfb->preset_file(); - FSSpec spec; - if ( ( err = PathToFSSpec(pathname, spec) ) != noErr ) { - fprintf(stderr, "PathToFSSpec(%s) failed: err=%d\n", - pathname, (int)err); - break; - } - AEDesc desc; - if ((err = AECreateDesc(typeFSS, &spec, sizeof(FSSpec), - &desc)) != noErr) { - fprintf(stderr, "AECreateDesc() failed: err=%d\n", - (int)err); - } - if ((err = NavCustomControl(cbparm->context, - kNavCtlSetLocation, - &desc)) != noErr) { - fprintf(stderr, "NavCustomControl() failed: err=%d\n", - (int)err); - } - AEDisposeDesc(&desc); - } - if ( nfb->_btype == BROWSE_SAVE_FILE && nfb->preset_file() ) { - CFStringRef namestr = - CFStringCreateWithCString(NULL, - nfb->preset_file(), - kCFStringEncodingASCII); - NavDialogSetSaveFileName(cbparm->context, namestr); - CFRelease(namestr); - } - NavCustomControl(cbparm->context, - kNavCtlSetActionState, - &nfb->_keepstate ); - - // Select the right filter in pop-up menu - if ( nfb->_filt_value == nfb->_filt_total ) { - // Select All Documents - NavPopupMenuItem kAll = kNavAllFiles; - NavCustomControl(cbparm->context, kNavCtlSelectAllType, &kAll); - } else if (nfb->_filt_value < nfb->_filt_total) { - // Select custom filter - nfb->_tempitem.version = kNavMenuItemSpecVersion; - nfb->_tempitem.menuCreator = 'extn'; - nfb->_tempitem.menuType = nfb->_filt_value; - *nfb->_tempitem.menuItemName = '\0'; // needed on 10.3+ - NavCustomControl(cbparm->context, - kNavCtlSelectCustomType, - &(nfb->_tempitem)); - } - break; - - case kNavCBPopupMenuSelect: - NavMenuItemSpecPtr ptr; - // they really buried this one! - ptr = (NavMenuItemSpecPtr)cbparm->eventData.eventDataParms.param; - if ( ptr->menuCreator ) { - // Gets index to filter ( menuCreator = 'extn' ) - nfb->_filt_value = ptr->menuType; - } else { - // All docs filter selected ( menuCreator = '\0\0\0\0' ) - nfb->_filt_value = nfb->_filt_total; - } - break; - - case kNavCBSelectEntry: - NavActionState astate; - switch ( nfb->_btype ) { - // these don't need selection override - case BROWSE_MULTI_FILE: - case BROWSE_MULTI_DIRECTORY: - case BROWSE_SAVE_FILE: - break; - - // These need to allow only one item, so disable - // Open button if user tries to select multiple files - case BROWSE_SAVE_DIRECTORY: - case BROWSE_DIRECTORY: - case BROWSE_FILE: - SInt32 selectcount; - AECountItems((AEDescList*)cbparm-> - eventData.eventDataParms.param, - &selectcount); - if ( selectcount > 1 ) { - NavCustomControl(cbparm->context, - kNavCtlSetSelection, - NULL); - astate = nfb->_keepstate | - kNavDontOpenState | - kNavDontChooseState; - NavCustomControl(cbparm->context, - kNavCtlSetActionState, - &astate ); - } - else { - astate= nfb->_keepstate | kNavNormalState; - NavCustomControl(cbparm->context, - kNavCtlSetActionState, - &astate ); - } - break; - } - break; - } -} - -// CONSTRUCTOR -FNFC_CLASS::FNFC_CTOR(int val) { - _btype = val; - NavGetDefaultDialogCreationOptions(&_opts); - _opts.optionFlags |= kNavDontConfirmReplacement; // no confirms for "save as" - _options = NO_OPTIONS; - _ref = NULL; - memset(&_tempitem, 0, sizeof(_tempitem)); - _pathnames = NULL; - _tpathnames = 0; - _title = NULL; - _filter = NULL; - _filt_names = NULL; - memset(_filt_patt, 0, sizeof(char*) * MAXFILTERS); - _filt_total = 0; - _filt_value = 0; - _directory = NULL; - _preset_file = NULL; - _errmsg = NULL; - _keepstate = kNavNormalState; -} - -// DESTRUCTOR -FNFC_CLASS::~FNFC_CTOR() { - // _opts // nothing to manage - if (_ref) { NavDialogDispose(_ref); _ref = NULL; } - // _options // nothing to manage - // _keepstate // nothing to manage - // _tempitem // nothing to manage - clear_pathnames(); - _directory = strfree(_directory); - _title = strfree(_title); - _preset_file = strfree(_preset_file); - _filter = strfree(_filter); - //_filt_names // managed by clear_filters() - //_filt_patt[i] // managed by clear_filters() - //_filt_total // managed by clear_filters() - clear_filters(); - //_filt_value // nothing to manage - _errmsg = strfree(_errmsg); -} - -// SET THE TYPE OF BROWSER -void FNFC_CLASS::type(int val) { - _btype = val; -} - -// GET TYPE OF BROWSER -int FNFC_CLASS::type() const { - return(_btype); -} - -// SET OPTIONS -void FNFC_CLASS::options(int val) { - _options = val; -} - -// GET OPTIONS -int FNFC_CLASS::options() const { - return(_options); -} - -// SHOW THE BROWSER WINDOW -// Returns: -// 0 - user picked a file -// 1 - user cancelled -// -1 - failed; errmsg() has reason -// -int FNFC_CLASS::show() { - - // Make sure fltk interface updates before posting our dialog -#ifdef FLTK1 - Fl::flush(); -#else - fltk::flush(); -#endif - - // BROWSER TITLE - CFStringRef cfs_title; - cfs_title = CFStringCreateWithCString(NULL, - _title ? _title : "No Title", - kCFStringEncodingASCII); - _opts.windowTitle = cfs_title; - - _keepstate = kNavNormalState; - - // BROWSER FILTERS - CFArrayRef filter_array = NULL; - { - // One or more filters specified? - if ( _filt_total ) { - // NAMES -> CFArrayRef - CFStringRef tab = CFSTR("\t"); - CFStringRef tmp_cfs; - tmp_cfs = CFStringCreateWithCString(NULL, _filt_names, - kCFStringEncodingASCII); - filter_array = CFStringCreateArrayBySeparatingStrings( - NULL, tmp_cfs, tab); - CFRelease(tmp_cfs); - CFRelease(tab); - _opts.popupExtension = filter_array; - _opts.optionFlags |= kNavAllFilesInPopup; - } else { - filter_array = NULL; - _opts.popupExtension = NULL; - _opts.optionFlags |= kNavAllFilesInPopup; - } - } - - // HANDLE OPTIONS WE SUPPORT - if ( _options & SAVEAS_CONFIRM ) { - _opts.optionFlags &= ~kNavDontConfirmReplacement; // enables confirm - } else { - _opts.optionFlags |= kNavDontConfirmReplacement; // disables confirm - } - - // POST BROWSER - int err = post(); - - // RELEASE _FILT_ARR - if ( filter_array ) CFRelease(filter_array); - filter_array = NULL; - _opts.popupExtension = NULL; - _filt_total = 0; - - // RELEASE TITLE - if ( cfs_title ) CFRelease(cfs_title); - cfs_title = NULL; - - return(err); -} - -// POST BROWSER -// Internal use only. -// Assumes '_opts' has been initialized. -// -// Returns: -// 0 - user picked a file -// 1 - user cancelled -// -1 - failed; errmsg() has reason -// -int FNFC_CLASS::post() { - - // INITIALIZE BROWSER - OSStatus err; - if ( _filt_total == 0 ) { // Make sure they match - _filt_value = 0; // TBD: move to someplace more logical? - } - - switch (_btype) { - case BROWSE_FILE: - case BROWSE_MULTI_FILE: - //_keepstate = kNavDontNewFolderState; - // Prompt user for one or more files - if ((err = NavCreateGetFileDialog( - &_opts, // options - 0, // file types - event_handler, // event handler - 0, // preview callback - filter_proc_cb, // filter callback - (void*)this, // callback data - &_ref)) != noErr ) { // dialog ref - errmsg("NavCreateGetFileDialog: failed"); - return(-1); - } - break; - - case BROWSE_DIRECTORY: - case BROWSE_MULTI_DIRECTORY: - _keepstate = kNavDontNewFolderState; - //FALLTHROUGH - - case BROWSE_SAVE_DIRECTORY: - // Prompts user for one or more files or folders - if ((err = NavCreateChooseFolderDialog( - &_opts, // options - event_handler, // event callback - 0, // filter callback - (void*)this, // callback data - &_ref)) != noErr ) { // dialog ref - errmsg("NavCreateChooseFolderDialog: failed"); - return(-1); - } - break; - - case BROWSE_SAVE_FILE: - // Prompt user for filename to 'save as' - if ((err = NavCreatePutFileDialog( - &_opts, // options - 0, // file types - 0, // file creator - event_handler, // event handler - (void*)this, // callback data - &_ref)) != noErr ) { // dialog ref - errmsg("NavCreatePutFileDialog: failed"); - return(-1); - } - break; - } - - // SHOW THE DIALOG - if ( ( err = NavDialogRun(_ref) ) != 0 ) { - char msg[80]; - sprintf(msg, "NavDialogRun: failed (err=%d)", (int)err); - errmsg(msg); - return(-1); - } - - // WHAT ACTION DID USER CHOOSE? - NavUserAction act = NavDialogGetUserAction(_ref); - if ( act == kNavUserActionNone ) { - errmsg("Nothing happened yet (dialog still open)"); - return(-1); - } - else if ( act == kNavUserActionCancel ) { // user chose 'cancel' - return(1); - } - else if ( act == kNavUserActionSaveAs ) { // user chose 'save as' - return(get_saveas_basename(_ref)); - } - - // TOO MANY FILES CHOSEN? - int ret = get_pathnames(_ref); - if ( _btype == BROWSE_FILE && ret == 0 && _tpathnames != 1 ) { - char msg[80]; - sprintf(msg, "Expected only one file to be chosen.. you chose %d.", - (int)_tpathnames); - errmsg(msg); - return(-1); - } - return(err); -} - -// SET ERROR MESSAGE -// Internal use only. -// -void FNFC_CLASS::errmsg(const char *msg) { - _errmsg = strfree(_errmsg); - _errmsg = strnew(msg); -} - -// RETURN ERROR MESSAGE -const char *FNFC_CLASS::errmsg() const { - return(_errmsg ? _errmsg : "No error"); -} - -// GET FILENAME -const char* FNFC_CLASS::filename() const { - if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]); - return(""); -} - -// GET FILENAME FROM LIST OF FILENAMES -const char* FNFC_CLASS::filename(int i) const { - if ( _pathnames && i < _tpathnames ) return(_pathnames[i]); - return(""); -} - -// GET TOTAL FILENAMES CHOSEN -int FNFC_CLASS::count() const { - return(_tpathnames); -} - -// PRESET PATHNAME -// Value can be NULL for none. -// -void FNFC_CLASS::directory(const char *val) { - _directory = strfree(_directory); - _directory = strnew(val); -} - -// GET PRESET PATHNAME -// Returned value can be NULL if none set. -// -const char* FNFC_CLASS::directory() const { - return(_directory); -} - -// SET TITLE -// Value can be NULL if no title desired. -// -void FNFC_CLASS::title(const char *val) { - _title = strfree(_title); - _title = strnew(val); -} - -// GET TITLE -// Returned value can be NULL if none set. -// -const char *FNFC_CLASS::title() const { - return(_title); -} - -// SET FILTER -// Can be NULL if no filter needed -// -void FNFC_CLASS::filter(const char *val) { - _filter = strfree(_filter); - _filter = strnew(val); - - // Parse filter user specified - // IN: _filter = "C Files\t*.{cxx,h}\nText Files\t*.txt" - // OUT: _filt_names = "C Files\tText Files" - // _filt_patt[0] = "*.{cxx,h}" - // _filt_patt[1] = "*.txt" - // _filt_total = 2 - // - parse_filter(_filter); -} - -// GET FILTER -// Returned value can be NULL if none set. -// -const char *FNFC_CLASS::filter() const { - return(_filter); -} - -// CLEAR ALL FILTERS -// Internal use only. -// -void FNFC_CLASS::clear_filters() { - _filt_names = strfree(_filt_names); - for (int i=0; i<_filt_total; i++) { - _filt_patt[i] = strfree(_filt_patt[i]); - } - _filt_total = 0; -} - -// PARSE USER'S FILTER SPEC -// Parses user specified filter ('in'), -// breaks out into _filt_patt[], _filt_names, and _filt_total. -// -// Handles: -// IN: OUT:_filt_names OUT: _filt_patt -// ------------------------------------ ------------------ --------------- -// "*.{ma,mb}" "*.{ma,mb} Files" "*.{ma,mb}" -// "*.[abc]" "*.[abc] Files" "*.[abc]" -// "*.txt" "*.txt Files" "*.c" -// "C Files\t*.[ch]" "C Files" "*.[ch]" -// "C Files\t*.[ch]\nText Files\t*.cxx" "C Files" "*.[ch]" -// -// Parsing Mode: -// IN:"C Files\t*.{cxx,h}" -// ||||||| ||||||||| -// mode: nnnnnnn wwwwwwwww -// \_____/ \_______/ -// Name Wildcard -// -void FNFC_CLASS::parse_filter(const char *in) { - clear_filters(); - if ( ! in ) return; - int has_name = strchr(in, '\t') ? 1 : 0; - - char mode = has_name ? 'n' : 'w'; // parse mode: n=title, w=wildcard - char wildcard[1024] = ""; // parsed wildcard - char name[1024] = ""; - - // Parse filter user specified - for ( ; 1; in++ ) { - - //// DEBUG - //// printf("WORKING ON '%c': mode=<%c> name=<%s> wildcard=<%s>\n", - //// *in, mode, name, wildcard); - - switch (*in) { - // FINISHED PARSING NAME? - case '\t': - if ( mode != 'n' ) goto regchar; - mode = 'w'; - break; - - // ESCAPE NEXT CHAR - case '\\': - ++in; - goto regchar; - - // FINISHED PARSING ONE OF POSSIBLY SEVERAL FILTERS? - case '\r': - case '\n': - case '\0': - // TITLE - // If user didn't specify a name, make one - // - if ( name[0] == '\0' ) { - sprintf(name, "%.*s Files", (int)sizeof(name)-10, wildcard); - } - // APPEND NEW FILTER TO LIST - if ( wildcard[0] ) { - // Add to filtername list - // Tab delimit if more than one. We later break - // tab delimited string into CFArray with - // CFStringCreateArrayBySeparatingStrings() - // - if ( _filt_total ) { - _filt_names = strapp(_filt_names, "\t"); - } - _filt_names = strapp(_filt_names, name); - - // Add filter to the pattern array - _filt_patt[_filt_total++] = strnew(wildcard); - } - // RESET - wildcard[0] = name[0] = '\0'; - mode = strchr(in, '\t') ? 'n' : 'w'; - // DONE? - if ( *in == '\0' ) return; // done - else continue; // not done yet, more filters - - // Parse all other chars - default: // handle all non-special chars - regchar: // handle regular char - switch ( mode ) { - case 'n': chrcat(name, *in); continue; - case 'w': chrcat(wildcard, *in); continue; - } - break; - } - } - //NOTREACHED -} - -// STATIC: FILTER CALLBACK -Boolean FNFC_CLASS::filter_proc_cb(AEDesc *theItem, - void *info, - void *callBackUD, - NavFilterModes filterMode) { - return((FNFC_CLASS*)callBackUD)->filter_proc_cb2( - theItem, info, callBackUD, filterMode); -} - -// FILTER CALLBACK -// Return true if match, -// false if no match. -// -Boolean FNFC_CLASS::filter_proc_cb2(AEDesc *theItem, - void *info, - void *callBackUD, - NavFilterModes filterMode) { - // All files chosen or no filters - if ( _filt_value == _filt_total ) return(true); - - FSSpec fsspec; - char pathname[4096]; - - // On fail, filter should return true by default - if ( AEDescToFSSpec(theItem, &fsspec) != noErr ) { - return(true); - } - FSSpecToPath(fsspec, pathname, sizeof(pathname)-1); - - if ( fl_filename_isdir(pathname) ) return(true); - if ( fl_filename_match(pathname, _filt_patt[_filt_value]) ) return(true); - else return(false); -} - -// SET PRESET FILE -// Value can be NULL for none. -// -void FNFC_CLASS::preset_file(const char* val) { - _preset_file = strfree(_preset_file); - _preset_file = strnew(val); -} - -// PRESET FILE -// Returned value can be NULL if none set. -// -const char* FNFC_CLASS::preset_file() { - return(_preset_file); -} - diff --git a/src/widgets/Fl_Native_File_Chooser_WIN32.cxx b/src/widgets/Fl_Native_File_Chooser_WIN32.cxx deleted file mode 100644 index ee181a4..0000000 --- a/src/widgets/Fl_Native_File_Chooser_WIN32.cxx +++ /dev/null @@ -1,797 +0,0 @@ -// Fl_Native_File_Chooser_WIN32.cxx -- FLTK native OS file chooser widget -// -// Copyright 2004 by Greg Ercolano. -// API changes + filter improvements by Nathan Vander Wilt 2005 -// FLTK2/WIN32 port by Greg Ercolano -// ---------------------------------------------------------------------------- -// Copyright (C) 2014 -// David Freese, W1HKJ -// -// This file is part of flmsg -// -// flrig is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// flrig is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ---------------------------------------------------------------------------- - -#include // debugging -#include "flnfc_common.cxx" // strnew/strfree/strapp/chrcat - -#define FLTK1 - -#ifdef FLTK1 -// -// FLTK1 -// -#include -#define FNFC_CLASS Fl_Native_File_Chooser -#define FNFC_CTOR Fl_Native_File_Chooser -#else -// -// FLTK2 -// -#include -#include -#define FNFC_CTOR NativeFileChooser -#define FNFC_CLASS fltk::FNFC_CTOR -#endif - -#define LCURLY_CHR '{' -#define RCURLY_CHR '}' -#define LBRACKET_CHR '[' -#define RBRACKET_CHR ']' -#define MAXFILTERS 80 - -#if 0 -// STATIC: PRINT WINDOWS 'DOUBLE NULL' STRING (DEBUG) -static void dnullprint(char *wp) { - if ( ! wp ) return; - for ( int t=0; true; t++ ) { - if ( wp[t] == '\0' && wp[t+1] == '\0' ) { - printf("\\0\\0"); - fflush(stdout); - return; - } else if ( wp[t] == '\0' ) { - printf("\\0"); - } else { - printf("%c",wp[t]); - } - } -} -#endif - -// RETURN LENGTH OF DOUBLENULL STRING -// Includes single nulls in count, excludes trailing doublenull. -// -// 1234 567 -// |||/\||| -// IN: "one\0two\0\0" -// OUT: 7 -// -static int dnulllen(const char *wp) { - int len = 0; - while ( ! ( *(wp+0) == 0 && *(wp+1) == 0 ) ) - { ++wp; ++len; } - return(len); -} - -// STATIC: Append a string to another, leaving terminated with DOUBLE NULL. -// Automatically handles extending length of string. -// wp can be NULL (a new wp will be allocated and initialized). -// string must be NULL terminated. -// The pointer wp may be modified on return. -// -static void dnullcat(char*&wp, const char *string, int n = -1 ) { - //DEBUG printf("DEBUG: dnullcat IN: <"); dnullprint(wp); printf(">\n"); - int inlen = ( n < 0 ) ? strlen(string) : n; - if ( ! wp ) { - wp = new char[inlen + 4]; - *(wp+0) = '\0'; - *(wp+1) = '\0'; - } else { - int wplen = dnulllen(wp); - // Make copy of wp into larger buffer - char *tmp = new char[wplen + inlen + 4]; - memcpy(tmp, wp, wplen+2); // copy of wp plus doublenull - delete [] wp; // delete old wp - wp = tmp; // use new copy - //DEBUG printf("DEBUG: dnullcat COPY: <"); dnullprint(wp); printf("> (wplen=%d)\n", wplen); - } - - // Find end of double null string - // *wp2 is left pointing at second null. - // - char *wp2 = wp; - if ( *(wp2+0) != '\0' && *(wp2+1) != '\0' ) { - for ( ; 1; wp2++ ) - if ( *(wp2+0) == '\0' && *(wp2+1) == '\0' ) - { wp2++; break; } - } - - if ( n == -1 ) n = strlen(string); - strncpy(wp2, string, n); - - // Leave string double-null terminated - *(wp2+n+0) = '\0'; - *(wp2+n+1) = '\0'; - //DEBUG printf("DEBUG: dnullcat OUT: <"); dnullprint(wp); printf(">\n\n"); -} - -// CTOR -FNFC_CLASS::FNFC_CTOR(int val) { - _btype = val; - _options = NO_OPTIONS; - memset((void*)&_ofn, 0, sizeof(OPENFILENAME)); - _ofn.lStructSize = sizeof(OPENFILENAME); - _ofn.hwndOwner = NULL; - memset((void*)&_binf, 0, sizeof(BROWSEINFO)); - _pathnames = NULL; - _tpathnames = 0; - _directory = NULL; - _title = NULL; - _filter = NULL; - _parsedfilt = NULL; - _nfilters = 0; - _preset_file = NULL; - _errmsg = NULL; -} - -// DTOR -FNFC_CLASS::~FNFC_CTOR() { - //_pathnames // managed by clear_pathnames() - //_tpathnames // managed by clear_pathnames() - _directory = strfree(_directory); - _title = strfree(_title); - _filter = strfree(_filter); - //_parsedfilt // managed by clear_filters() - //_nfilters // managed by clear_filters() - _preset_file = strfree(_preset_file); - _errmsg = strfree(_errmsg); - clear_filters(); - clear_pathnames(); - ClearOFN(); - ClearBINF(); -} - -// SET TYPE OF BROWSER -void FNFC_CLASS::type(int val) { - _btype = val; -} - -// GET TYPE OF BROWSER -int FNFC_CLASS::type() const { - return( _btype ); -} - -// SET OPTIONS -void FNFC_CLASS::options(int val) { - _options = val; -} - -// GET OPTIONS -int FNFC_CLASS::options() const { - return(_options); -} - -// PRIVATE: SET ERROR MESSAGE -void FNFC_CLASS::errmsg(const char *val) { - _errmsg = strfree(_errmsg); - _errmsg = strnew(val); -} - -// FREE PATHNAMES ARRAY, IF IT HAS ANY CONTENTS -void FNFC_CLASS::clear_pathnames() { - if ( _pathnames ) { - while ( --_tpathnames >= 0 ) { - _pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]); - } - delete [] _pathnames; - _pathnames = NULL; - } - _tpathnames = 0; -} - -// SET A SINGLE PATHNAME -void FNFC_CLASS::set_single_pathname(const char *s) { - clear_pathnames(); - _pathnames = new char*[1]; - _pathnames[0] = strnew(s); - _tpathnames = 1; -} - -// ADD PATHNAME TO EXISTING ARRAY -void FNFC_CLASS::add_pathname(const char *s) { - if ( ! _pathnames ) { - // Create first element in array - ++_tpathnames; - _pathnames = new char*[_tpathnames]; - } else { - // Grow array by 1 - char **tmp = new char*[_tpathnames+1]; // create new buffer - memcpy((void*)tmp, (void*)_pathnames, - sizeof(char*)*_tpathnames); // copy old - delete [] _pathnames; // delete old - _pathnames = tmp; // use new - ++_tpathnames; - } - _pathnames[_tpathnames-1] = strnew(s); -} - -// FREE A PIDL (Pointer to IDentity List) -void FNFC_CLASS::FreePIDL(ITEMIDLIST *pidl) { - IMalloc *imalloc = NULL; - if ( SUCCEEDED(SHGetMalloc(&imalloc)) ) - { imalloc->Free(pidl); imalloc->Release(); imalloc = NULL; } -} - -// CLEAR MICROSOFT OFN (OPEN FILE NAME) CLASS -void FNFC_CLASS::ClearOFN() { - // Free any previously allocated lpstrFile before zeroing out _ofn - if ( _ofn.lpstrFile ) { - _ofn.lpstrFile = strfree((char*)_ofn.lpstrFile); - } - if ( _ofn.lpstrInitialDir ) { - _ofn.lpstrInitialDir = (LPCSTR)strfree((char*)_ofn.lpstrInitialDir); - } - _ofn.lpstrFilter = NULL; // (deleted elsewhere) - int temp = _ofn.nFilterIndex; // keep the filter_value - memset((void*)&_ofn, 0, sizeof(_ofn)); - _ofn.lStructSize = sizeof(OPENFILENAME); - _ofn.nFilterIndex = temp; -} - -// CLEAR MICROSOFT BINF (BROWSER INFO) CLASS -void FNFC_CLASS::ClearBINF() { - if ( _binf.pidlRoot ) { - FreePIDL((ITEMIDLIST*)_binf.pidlRoot); - _binf.pidlRoot = NULL; - } - memset((void*)&_binf, 0, sizeof(_binf)); -} - -// CONVERT WINDOWS BACKSLASHES TO UNIX FRONTSLASHES -void FNFC_CLASS::Win2Unix(char *s) { - for ( ; *s; s++ ) - if ( *s == '\\' ) *s = '/'; -} - -// CONVERT UNIX FRONTSLASHES TO WINDOWS BACKSLASHES -void FNFC_CLASS::Unix2Win(char *s) { - for ( ; *s; s++ ) - if ( *s == '/' ) *s = '\\'; -} - -// SHOW FILE BROWSER -int FNFC_CLASS::showfile() { - ClearOFN(); - clear_pathnames(); - size_t fsize = 2048; - _ofn.Flags |= OFN_NOVALIDATE; // prevent disabling of front slashes - _ofn.Flags |= OFN_HIDEREADONLY; // hide goofy readonly flag - // USE NEW BROWSER - _ofn.Flags |= OFN_EXPLORER; // use newer explorer windows - _ofn.Flags |= OFN_ENABLESIZING; // allow window to be resized (hey, why not?) - - // XXX: The docs for OFN_NOCHANGEDIR says the flag is 'ineffective' on XP/2K/NT! - // But let's set it anyway.. - // - _ofn.Flags |= OFN_NOCHANGEDIR; // prevent dialog for messing up the cwd - - switch ( _btype ) { - case BROWSE_DIRECTORY: - case BROWSE_MULTI_DIRECTORY: - case BROWSE_SAVE_DIRECTORY: - abort(); // never happens: handled by showdir() - case BROWSE_FILE: - fsize = 65536; // XXX: there must be a better way - break; - case BROWSE_MULTI_FILE: - _ofn.Flags |= OFN_ALLOWMULTISELECT; - fsize = 65536; // XXX: there must be a better way - break; - case BROWSE_SAVE_FILE: - if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) { - _ofn.Flags |= OFN_OVERWRITEPROMPT; - } - break; - } - // SPACE FOR RETURNED FILENAME - _ofn.lpstrFile = new char[fsize]; - _ofn.nMaxFile = fsize-1; - _ofn.lpstrFile[0] = '\0'; - _ofn.lpstrFile[1] = '\0'; // dnull - // PARENT WINDOW - _ofn.hwndOwner = GetForegroundWindow(); - // DIALOG TITLE - _ofn.lpstrTitle = _title ? _title : NULL; - // FILTER - _ofn.lpstrFilter = _parsedfilt ? _parsedfilt : NULL; - // PRESET FILE - // If set, supercedes _directory. See KB Q86920 for details - // - if ( _preset_file ) { - size_t len = strlen(_preset_file); - if ( len >= _ofn.nMaxFile ) { - char msg[80]; - sprintf(msg, "preset_file() filename is too long: %ld is >=%ld", - (long)len, (long)fsize); - return(-1); - } - strncpy(_ofn.lpstrFile, _preset_file, _ofn.nMaxFile); - Unix2Win(_ofn.lpstrFile); - _ofn.lpstrFile[len+0] = 0; // multiselect needs dnull - _ofn.lpstrFile[len+1] = 0; - } - if ( _directory ) { - // PRESET DIR - // XXX: See KB Q86920 for doc bug: - // http://support.microsoft.com/default.aspx?scid=kb;en-us;86920 - // - _ofn.lpstrInitialDir = strnew(_directory); - Unix2Win((char*)_ofn.lpstrInitialDir); - } - // SAVE THE CURRENT DIRECTORY - // XXX: Save the cwd because GetOpenFileName() is probably going to - // change it, in spite of the OFN_NOCHANGEDIR flag, due to its docs - // saying the flag is 'ineffective'. %^( - // - char oldcwd[MAX_PATH]; - GetCurrentDirectory(MAX_PATH, oldcwd); - oldcwd[MAX_PATH-1] = '\0'; - // OPEN THE DIALOG WINDOW - int err; - if ( _btype == BROWSE_SAVE_FILE ) { - err = GetSaveFileName(&_ofn); - } else { - err = GetOpenFileName(&_ofn); - } - if ( err == 0 ) { - // EXTENDED ERROR CHECK - int err = CommDlgExtendedError(); - // CANCEL? - if ( err == 0 ) - return(1); // user hit 'cancel' - // AN ERROR OCCURRED - char msg[80]; - sprintf(msg, "CommDlgExtendedError() code=%d", err); - errmsg(msg); - // XXX: RESTORE CWD - if ( oldcwd[0] ) SetCurrentDirectory(oldcwd); - return(-1); - } - // XXX: RESTORE CWD - if ( oldcwd[0] ) { - SetCurrentDirectory(oldcwd); - } - // PREPARE PATHNAMES FOR RETURN - switch ( _btype ) { - case BROWSE_FILE: - case BROWSE_SAVE_FILE: - set_single_pathname(_ofn.lpstrFile); - Win2Unix(_pathnames[_tpathnames-1]); - break; - case BROWSE_MULTI_FILE: { - // EXTRACT MULTIPLE FILENAMES - const char *dirname = _ofn.lpstrFile; - int dirlen = strlen(dirname); - if ( dirlen > 0 ) { - // WALK STRING SEARCHING FOR 'DOUBLE-NULL' - // eg. "/dir/name\0foo1\0foo2\0foo3\0\0" - // - char pathname[2048]; - for ( const char *s = _ofn.lpstrFile + dirlen + 1; - *s; s+= (strlen(s)+1)) { - strcpy(pathname, dirname); - strcat(pathname, "\\"); - strcat(pathname, s); - add_pathname(pathname); - Win2Unix(_pathnames[_tpathnames-1]); - } - } - // XXX - // Work around problem where pasted forward-slash pathname - // into the file browser causes new "Explorer" interface - // not to grok forward slashes, passing back as a 'filename'..! - // - if ( _tpathnames == 0 ) { - add_pathname(dirname); - Win2Unix(_pathnames[_tpathnames-1]); - } - break; - } - case BROWSE_DIRECTORY: - case BROWSE_MULTI_DIRECTORY: - case BROWSE_SAVE_DIRECTORY: - abort(); // never happens: handled by showdir() - } - return(0); -} - -// Used by SHBrowseForFolder(), sets initial selected dir. -// Ref: Usenet: microsoft.public.vc.mfc, Dec 8 2000, 1:38p David Lowndes -// Subject: How to specify to select an initial folder .." -// -int CALLBACK FNFC_CLASS::Dir_CB(HWND win, UINT msg, - LPARAM param, LPARAM data) { - switch (msg) { - case BFFM_INITIALIZED: - if (data) ::SendMessage(win, BFFM_SETSELECTION, TRUE, data); - break; - case BFFM_SELCHANGED: - TCHAR path[MAX_PATH]; - if ( SHGetPathFromIDList((ITEMIDLIST*)param, path) ) { - ::SendMessage(win, BFFM_ENABLEOK, 0, 1); - } else { - //disable ok button if not a path - ::SendMessage(win, BFFM_ENABLEOK, 0, 0); - } - break; - case BFFM_VALIDATEFAILED: - // we could pop up an annoying message here. - // also needs set ulFlags |= BIF_VALIDATE - break; - default: - break; - } - return(0); -} - -// SHOW DIRECTORY BROWSER -int FNFC_CLASS::showdir() { - OleInitialize(NULL); // init needed by BIF_USENEWUI - ClearBINF(); - clear_pathnames(); - // PARENT WINDOW - _binf.hwndOwner = GetForegroundWindow(); - // DIALOG TITLE - _binf.lpszTitle = _title ? _title : NULL; - // FLAGS - _binf.ulFlags = 0; // initialize - - // TBD: make sure matches to runtime system, if need be. - //( what if _WIN32_IE doesn't match system? does the program not run? ) - // TBD: match all 3 types of directories - -#if defined(BIF_NONEWFOLDERBUTTON) // Version 6.0 - if ( _btype == BROWSE_DIRECTORY ) _binf.ulFlags |= BIF_NONEWFOLDERBUTTON; - _binf.ulFlags |= BIF_USENEWUI | BIF_SHAREABLE | BIF_RETURNONLYFSDIRS; -#elif defined(BIF_USENEWUI) // Version 5.0 - if ( _btype == BROWSE_DIRECTORY ) _binf.ulFlags |= BIF_EDITBOX; - else if ( _btype == BROWSE_SAVE_DIRECTORY ) _binf.ulFlags |= BIF_USENEWUI; - _binf.ulFlags |= BIF_SHAREABLE | BIF_RETURNONLYFSDIRS; -#elif defined(BIF_EDITBOX) // Version 4.71 - _binf.ulFlags |= BIF_RETURNONLYFSDIRS | BIF_EDITBOX; -#else // Version Old - _binf.ulFlags |= BIF_RETURNONLYFSDIRS; -#endif - - // BUFFER - char displayname[MAX_PATH]; - _binf.pszDisplayName = displayname; - // PRESET DIR - char presetname[MAX_PATH]; - if ( _directory ) { - strcpy(presetname, _directory); - Unix2Win(presetname); - _binf.lParam = (LPARAM)presetname; - } - else _binf.lParam = 0; - _binf.lpfn = Dir_CB; - // OPEN BROWSER - ITEMIDLIST *pidl = SHBrowseForFolder(&_binf); - // CANCEL? - if ( pidl == NULL ) return(1); - - // GET THE PATHNAME(S) THE USER SELECTED - // TBD: expand NetHood shortcuts from this PIDL?? - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shbrowseforfolder.asp - - TCHAR path[MAX_PATH]; - if ( SHGetPathFromIDList(pidl, path) ) { - Win2Unix(path); - add_pathname(path); - } - FreePIDL(pidl); - if ( !strlen(path) ) return(1); // don't return empty pathnames - return(0); -} - -// RETURNS: -// 0 - user picked a file -// 1 - user cancelled -// -1 - failed; errmsg() has reason -// -int FNFC_CLASS::show() { - if ( _btype == BROWSE_DIRECTORY || - _btype == BROWSE_MULTI_DIRECTORY || - _btype == BROWSE_SAVE_DIRECTORY ) { - return(showdir()); - } else { - return(showfile()); - } -} - -// RETURN ERROR MESSAGE -const char *FNFC_CLASS::errmsg() const { - return(_errmsg ? _errmsg : "No error"); -} - -// GET FILENAME -const char* FNFC_CLASS::filename() const { - if ( _pathnames && _tpathnames > 0 ) return(_pathnames[0]); - return(""); -} - -// GET FILENAME FROM LIST OF FILENAMES -const char* FNFC_CLASS::filename(int i) const { - if ( _pathnames && i < _tpathnames ) return(_pathnames[i]); - return(""); -} - -// GET TOTAL FILENAMES CHOSEN -int FNFC_CLASS::count() const { - return(_tpathnames); -} - -// PRESET PATHNAME -// Can be NULL if no preset is desired. -// -void FNFC_CLASS::directory(const char *val) { - _directory = strfree(_directory); - _directory = strnew(val); -} - -// GET PRESET PATHNAME -// Can return NULL if none set. -// -const char *FNFC_CLASS::directory() const { - return(_directory); -} - -// SET TITLE -// Can be NULL if no title desired. -// -void FNFC_CLASS::title(const char *val) { - _title = strfree(_title); - _title = strnew(val); -} - -// GET TITLE -// Can return NULL if none set. -// -const char *FNFC_CLASS::title() const { - return(_title); -} - -// SET FILTER -// Can be NULL if no filter needed -// -void FNFC_CLASS::filter(const char *val) { - _filter = strfree(_filter); - clear_filters(); - if ( val ) { - _filter = strnew(val); - parse_filter(_filter); - } - add_filter("All Files", "*.*"); // always include 'all files' option - -#ifdef DEBUG - nullprint(_parsedfilt); -#endif /*DEBUG*/ -} - -// GET FILTER -// Can return NULL if none set. -// -const char *FNFC_CLASS::filter() const { - return(_filter); -} - -// CLEAR FILTERS -void FNFC_CLASS::clear_filters() { - _nfilters = 0; - _parsedfilt = strfree(_parsedfilt); -} - -// ADD A FILTER -void FNFC_CLASS::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]; - if ( !name_in || name_in[0] == '\0' ) { - sprintf(name, "%.*s Files", sizeof(name)-10, winfilter); - } else { - sprintf(name, "%.*s", sizeof(name)-10, name_in); - } - dnullcat(_parsedfilt, name); - dnullcat(_parsedfilt, winfilter); - _nfilters++; - //DEBUG printf("DEBUG: ADD FILTER name=<%s> winfilter=<%s>\n", name, winfilter); -} - -// CONVERT FLTK STYLE PATTERN MATCHES TO WINDOWS 'DOUBLENULL' PATTERN -// Handles: -// IN OUT -// ----------- ----------------------------- -// *.{ma,mb} "*.{ma,mb} Files\0*.ma;*.mb\0\0" -// *.[abc] "*.[abc] Files\0*.a;*.b;*.c\0\0" -// *.txt "*.txt Files\0*.txt\0\0" -// C Files\t*.[ch] "C Files\0*.c;*.h\0\0" -// -// Example: -// IN: "*.{ma,mb}" -// OUT: "*.ma;*.mb Files\0*.ma;*.mb\0All Files\0*.*\0\0" -// --------------- --------- --------- --- -// | | | | -// Title Wildcards Title Wildcards -// -// Parsing Mode: -// IN:"C Files\t*.{cxx,h}" -// ||||||| ||||||||| -// mode: nnnnnnn ww{{{{{{{ -// \_____/ \_______/ -// Name Wildcard -// -void FNFC_CLASS::parse_filter(const char *in) { - clear_filters(); - if ( ! in ) return; - - int has_name = strchr(in, '\t') ? 1 : 0; - - char mode = has_name ? 'n' : 'w'; // parse mode: n=name, w=wildcard - int nwildcards = 0; - char wildcards[MAXFILTERS][1024]; // parsed wildcards (can be several) - char wildprefix[512] = ""; - char name[512] = ""; - - // Init - int t; - for ( t=0; t name=<%s> wildprefix=<%s> nwildcards=%d wildcards[n]=<%s>\n", - //// *in, mode, name, wildprefix, nwildcards, wildcards[nwildcards]); - - switch (*in) { - case ',': - case '|': - if ( mode == LCURLY_CHR ) { - // create new wildcard, copy in prefix - strcat(wildcards[nwildcards++], wildprefix); - continue; - } else { - goto regchar; - } - continue; - - // FINISHED PARSING A NAME? - case '\t': - if ( mode != 'n' ) goto regchar; - // finish parsing name? switch to wildcard mode - mode = 'w'; - break; - - // ESCAPE NEXT CHAR - case '\\': - ++in; - goto regchar; - - // FINISHED PARSING ONE OF POSSIBLY SEVERAL FILTERS? - case '\r': - case '\n': - case '\0': - { - if ( mode == 'w' ) { // finished parsing wildcard? - if ( nwildcards == 0 ) { - strcpy(wildcards[nwildcards++], wildprefix); - } - // Append wildcards in Microsoft's "*.one;*.two" format - char comp[4096] = ""; - for ( t=0; t 0 ) { - chrcat(wildcards[nwildcards-1], *in); - } - continue; - - case 'n': - chrcat(name, *in); - continue; - - case 'w': - chrcat(wildprefix, *in); - for ( t=0; t #include -#include #include "config.h" -#include "fileselect.h" +#include "fileselect.h" #include "debug.h" /** @@ -106,6 +105,8 @@ The filter type must be terminated with a '\n' on OS X or the application crashe */ +bool trx_inhibit = false; + using namespace std; namespace FSEL { @@ -117,6 +118,7 @@ string filename, stitle, sfilter, sdef, sdirectory; char dirbuf[FL_PATH_MAX + 1] = ""; char msg[400]; +// use this function for testing on garbage OS, aka Windows /* void pfile (const char *dir, const char *fname, const char *filt) { char fn[FL_PATH_MAX+1]; @@ -126,7 +128,7 @@ void pfile (const char *dir, const char *fname, const char *filt) { fl_filename_expand(fn, sizeof(fn) -1, "$HOME/"); #endif strcat(fn, "pfile.txt"); - FILE *f = fopen(fn, "a"); + FILE *f = fl_fopen(fn, "a"); fprintf(f,"\ dir: %s\n\ file: %s\n\ @@ -164,7 +166,11 @@ const char* select(const char* title, const char* filter, const char* def, int* if (def) { sdef.assign(def); - sdirectory.assign(def); + if (!sdef.empty()) { + p = sdef.length() - 1; + if ((sdef[p] == '/') || (sdef[p] == '\\')) sdef.append("fname"); + } + sdirectory.assign(sdef); p = sdirectory.rfind(fl_filename_name(sdef.c_str())); sdirectory.erase(p); } @@ -194,11 +200,14 @@ const char* select(const char* title, const char* filter, const char* def, int* // pfile(sdirectory.c_str(), sdef.c_str(), sfilter.c_str()); filename.clear(); + + trx_inhibit = true; + switch ( native.show() ) { - case -1: + case -1: // ERROR LOG_ERROR("ERROR: %s\n", native.errmsg()); // Error fall through - case 1: - return 0; + case 1: // CANCEL + filename = ""; break; default: if ( native.filename() ) { @@ -209,6 +218,8 @@ const char* select(const char* title, const char* filter, const char* def, int* break; } + trx_inhibit = false; + if (fsel) *fsel = native.filter_value(); @@ -238,7 +249,11 @@ const char* saveas(const char* title, const char* filter, const char* def, int* if (def) { sdef.assign(def); - sdirectory.assign(def); + if (!sdef.empty()) { + p = sdef.length() - 1; + if ((sdef[p] == '/') || (sdef[p] == '\\')) sdef.append("fname"); + } + sdirectory.assign(sdef); p = sdirectory.rfind(fl_filename_name(sdef.c_str())); sdirectory.erase(p); } @@ -267,9 +282,16 @@ const char* saveas(const char* title, const char* filter, const char* def, int* // pfile(sdirectory.c_str(), sdef.c_str(), sfilter.c_str()); filename.clear(); + + trx_inhibit = true; + switch ( native.show() ) { - case -1: LOG_ERROR("ERROR: %s\n", native.errmsg()); break; // ERROR - case 1: break; // CANCEL + case -1: // ERROR + LOG_ERROR("ERROR: %s\n", native.errmsg()); + break; + case 1: // CANCEL + filename = ""; + break; default: if ( native.filename() ) { filename = native.filename(); @@ -279,6 +301,8 @@ const char* saveas(const char* title, const char* filter, const char* def, int* break; } + trx_inhibit = false; + if (fsel) *fsel = native.filter_value(); @@ -312,9 +336,16 @@ const char* dir_select(const char* title, const char* filter, const char* def) sdirectory.clear(); filename.clear(); + + trx_inhibit = true; + switch ( native.show() ) { - case -1: LOG_ERROR("ERROR: %s\n", native.errmsg()); break; // ERROR - case 1: break; // CANCEL + case -1: // ERROR + LOG_ERROR("ERROR: %s\n", native.errmsg()); + break; + case 1: // CANCEL + filename = ""; + break; default: if ( native.filename() ) { filename = native.filename(); @@ -324,6 +355,8 @@ const char* dir_select(const char* title, const char* filter, const char* def) break; } + trx_inhibit = false; + return filename.c_str(); } diff --git a/src/xmlrpcpp/XmlRpcBase64.h b/src/xmlrpcpp/XmlRpcBase64.h index 3c71f23..f930741 100644 --- a/src/xmlrpcpp/XmlRpcBase64.h +++ b/src/xmlrpcpp/XmlRpcBase64.h @@ -1,7 +1,7 @@ // ---------------------------------------------------------------------------- // // flxmlrpc Copyright (c) 2015 by W1HKJ, Dave Freese -// +// // XmlRpc++ Copyright (c) 2002-2008 by Chris Morley // // This file is part of fldigi @@ -18,6 +18,8 @@ #if !defined(__BASE64_H_INCLUDED__) #define __BASE64_H_INCLUDED__ 1 +#include // Corrects forward declarations issue c++11 +#include // Corrects forward declarations issue c++11 #include static @@ -52,7 +54,7 @@ public: typedef unsigned char byte_t; typedef _E char_type; - typedef _Tr traits_type; + typedef _Tr traits_type; // xmlrpc_base64 requires max line length <= 72 characters // you can fill end of line @@ -231,7 +233,7 @@ public: _3to4.zero(); // -- 0 -- - // Search next valid char... + // Search next valid char... while((_Char = _getCharType(*_First)) < 0 && _Char == _UNKNOWN_CHAR) { if(++_First == _Last) @@ -242,49 +244,49 @@ public: if(_Char == _EQUAL_CHAR){ // Error! First character in octet can't be '=' - _St |= _IOS_FAILBIT; - return _First; + _St |= _IOS_FAILBIT; + return _First; } else _3to4.b64_0(_Char); // -- 1 -- - // Search next valid char... + // Search next valid char... while(++_First != _Last) if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR) break; if(_First == _Last) { - _St |= _IOS_FAILBIT|_IOS_EOFBIT; // unexpected EOF + _St |= _IOS_FAILBIT|_IOS_EOFBIT; // unexpected EOF return _First; } if(_Char == _EQUAL_CHAR){ // Error! Second character in octet can't be '=' - _St |= _IOS_FAILBIT; - return _First; + _St |= _IOS_FAILBIT; + return _First; } else _3to4.b64_1(_Char); // -- 2 -- - // Search next valid char... + // Search next valid char... while(++_First != _Last) if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR) break; if(_First == _Last) { // Error! Unexpected EOF. Must be '=' or xmlrpc_base64 character - _St |= _IOS_FAILBIT|_IOS_EOFBIT; - return _First; + _St |= _IOS_FAILBIT|_IOS_EOFBIT; + return _First; } if(_Char == _EQUAL_CHAR){ // OK! - _3to4.b64_2(0); - _3to4.b64_3(0); + _3to4.b64_2(0); + _3to4.b64_3(0); // chek for EOF if(++_First == _Last) @@ -293,7 +295,7 @@ public: //_St |= _IOS_BADBIT|_IOS_EOFBIT; _St |= _IOS_EOFBIT; } - else + else if(_getCharType(*_First) != _EQUAL_CHAR) { // Error! Must be '='. Ignore it. @@ -311,23 +313,23 @@ public: // -- 3 -- - // Search next valid char... + // Search next valid char... while(++_First != _Last) if((_Char = _getCharType(*_First)) != _UNKNOWN_CHAR) break; if(_First == _Last) { // Unexpected EOF. It's error. But ignore it. - //_St |= _IOS_FAILBIT|_IOS_EOFBIT; - _St |= _IOS_EOFBIT; - - return _First; + //_St |= _IOS_FAILBIT|_IOS_EOFBIT; + _St |= _IOS_EOFBIT; + + return _First; } if(_Char == _EQUAL_CHAR) { // OK! - _3to4.b64_3(0); + _3to4.b64_3(0); // write to output 2 bytes *_To = (byte_t) _3to4.get_0(); @@ -347,7 +349,7 @@ public: *_To = (byte_t) _3to4.get_2(); ++_First; - + } // while(_First != _Last) @@ -355,7 +357,7 @@ public: } protected: - + int _getCharType(int _Ch) const { if(_xmlrpc_base64Chars[62] == _Ch) diff --git a/src/xmlrpcpp/XmlRpcDispatch.cpp b/src/xmlrpcpp/XmlRpcDispatch.cpp index adc8a78..c7fd3d9 100644 --- a/src/xmlrpcpp/XmlRpcDispatch.cpp +++ b/src/xmlrpcpp/XmlRpcDispatch.cpp @@ -33,6 +33,7 @@ #endif // __FreeBSD__ #if defined(_WINDOWS) +#undef _WINSOCKAPI_ # include # define USE_FTIME diff --git a/src/xmlrpcpp/XmlRpcSocket.cpp b/src/xmlrpcpp/XmlRpcSocket.cpp index 26e4cf9..31221c0 100644 --- a/src/xmlrpcpp/XmlRpcSocket.cpp +++ b/src/xmlrpcpp/XmlRpcSocket.cpp @@ -1,7 +1,7 @@ // ---------------------------------------------------------------------------- // // flxmlrpc Copyright (c) 2015 by W1HKJ, Dave Freese -// +// // XmlRpc++ Copyright (c) 2002-2008 by Chris Morley // // This file is part of fldigi @@ -22,13 +22,22 @@ #if defined(_WINDOWS) +#undef _WINSOCKAPI_ # include # include //# pragma lib(WS2_32.lib) -# define EINPROGRESS WSAEINPROGRESS -# define EWOULDBLOCK WSAEWOULDBLOCK -# define ETIMEDOUT WSAETIMEDOUT +// Updates to MXE require conditional test before assignment to +// prevent duplicate defines. + +#undef EINPROGRESS +#define EINPROGRESS WSAEINPROGRESS + +#undef EWOULDBLOCK +#define EWOULDBLOCK WSAEWOULDBLOCK + +#undef ETIMEDOUT +#define ETIMEDOUT WSAETIMEDOUT typedef int socklen_t; @@ -62,7 +71,7 @@ static void initialize() WORD wVersionRequested = MAKEWORD( 2, 0 ); WSADATA wsaData; WSAStartup(wVersionRequested, &wsaData); - atexit((void(*)(void)) WSACleanup); + atexit((void(*)(void)) WSACleanup); } #else { diff --git a/src/xmlrpcpp/XmlRpcSource.cpp b/src/xmlrpcpp/XmlRpcSource.cpp index 97edfff..27467e9 100644 --- a/src/xmlrpcpp/XmlRpcSource.cpp +++ b/src/xmlrpcpp/XmlRpcSource.cpp @@ -21,6 +21,7 @@ #include "XmlRpcUtil.h" #if defined(_WINDOWS) +#undef _WINSOCKAPI_ # include # include #else