Fl_Native_File_Chooser.H 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. //
  2. // "$Id: Fl_Native_File_Chooser.H 10186 2014-06-07 12:01:59Z manolo $"
  3. //
  4. // FLTK native OS file chooser widget
  5. //
  6. // Copyright 1998-2014 by Bill Spitzak and others.
  7. // Copyright 2004 Greg Ercolano.
  8. //
  9. // This library is free software. Distribution and use rights are outlined in
  10. // the file "COPYING" which should have been included with this file. If this
  11. // file is missing or damaged, see the license at:
  12. //
  13. // http://www.fltk.org/COPYING.php
  14. //
  15. // Please report all bugs and problems on the following page:
  16. //
  17. // http://www.fltk.org/str.php
  18. //
  19. /** \file
  20. Fl_Native_File_Chooser widget. */
  21. #ifndef FL_NATIVE_FILE_CHOOSER_H
  22. #define FL_NATIVE_FILE_CHOOSER_H
  23. // Use Windows' chooser
  24. #ifdef WIN32
  25. // #define _WIN32_WINNT 0x0501 // needed for OPENFILENAME's 'FlagsEx'
  26. # include <stdio.h>
  27. # include <stdlib.h> // malloc
  28. # include <windows.h>
  29. # include <commdlg.h> // OPENFILENAME, GetOpenFileName()
  30. # include <shlobj.h> // BROWSEINFO, SHBrowseForFolder()
  31. #endif
  32. // Use Apple's chooser
  33. #ifdef __APPLE__
  34. # define MAXFILTERS 80
  35. #endif
  36. // All else falls back to FLTK's own chooser
  37. #if ! defined(__APPLE__) && !defined(WIN32)
  38. # include <FL/Fl_File_Chooser.H>
  39. # include <unistd.h> // _POSIX_NAME_MAX
  40. #else
  41. # include <FL/filename.H> // FL_EXPORT
  42. #endif
  43. class Fl_FLTK_File_Chooser;
  44. class Fl_GTK_File_Chooser;
  45. /**
  46. This class lets an FLTK application easily and consistently access
  47. the operating system's native file chooser. Some operating systems
  48. have very complex and specific file choosers that many users want
  49. access to specifically, instead of FLTK's default file chooser(s).
  50. In cases where there is no native file browser, FLTK's own file browser
  51. is used instead.
  52. To use this widget, use the following include in your code:
  53. \code
  54. #include <FL/Fl_Native_File_Chooser.H>
  55. \endcode
  56. The following example shows how to pick a single file:
  57. \code
  58. // Create and post the local native file chooser
  59. #include <FL/Fl_Native_File_Chooser.H>
  60. [..]
  61. Fl_Native_File_Chooser fnfc;
  62. fnfc.title("Pick a file");
  63. fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
  64. fnfc.filter("Text\t*.txt\n"
  65. "C Files\t*.{cxx,h,c}");
  66. fnfc.directory("/var/tmp"); // default directory to use
  67. // Show native chooser
  68. switch ( fnfc.show() ) {
  69. case -1: printf("ERROR: %s\n", fnfc.errmsg()); break; // ERROR
  70. case 1: printf("CANCEL\n"); break; // CANCEL
  71. default: printf("PICKED: %s\n", fnfc.filename()); break; // FILE CHOSEN
  72. }
  73. \endcode
  74. The Fl_Native_File_Chooser widget transmits UTF-8 encoded filenames to its user. It is
  75. recommended to open files that may have non-ASCII names with the fl_fopen() or
  76. fl_open() utility functions that handle these names in a cross-platform way
  77. (whereas the standard fopen()/open() functions fail on the MSWindows platform
  78. to open files with a non-ASCII name).
  79. <B>Platform Specific Caveats</B>
  80. - Under X windows, and if Fl::OPTION_FNFC_USES_GTK has not been switched off,
  81. the widget attempts to use standard GTK file chooser dialogs if they are
  82. available at run-time on the platform, and falls back to use FLTK's Fl_File_Chooser if they are not.
  83. In the latter case, it's best if you call Fl_File_Icon::load_system_icons()
  84. at the start of main(), to enable the nicer looking file browser widgets.
  85. Use the static public attributes of class Fl_File_Chooser to localize
  86. the browser.
  87. - Some operating systems support certain OS specific options; see
  88. Fl_Native_File_Chooser::options() for a list.
  89. \image html Fl_Native_File_Chooser.png "The Fl_Native_File_Chooser on different platforms."
  90. \image latex Fl_Native_File_Chooser.png "The Fl_Native_File_Chooser on different platforms" width=14cm
  91. */
  92. class FL_EXPORT Fl_Native_File_Chooser {
  93. public:
  94. enum Type {
  95. BROWSE_FILE = 0, ///< browse files (lets user choose one file)
  96. BROWSE_DIRECTORY, ///< browse directories (lets user choose one directory)
  97. BROWSE_MULTI_FILE, ///< browse files (lets user choose multiple files)
  98. BROWSE_MULTI_DIRECTORY, ///< browse directories (lets user choose multiple directories)
  99. BROWSE_SAVE_FILE, ///< browse to save a file
  100. BROWSE_SAVE_DIRECTORY ///< browse to save a directory
  101. };
  102. enum Option {
  103. NO_OPTIONS = 0x0000, ///< no options enabled
  104. SAVEAS_CONFIRM = 0x0001, ///< Show native 'Save As' overwrite confirm dialog
  105. NEW_FOLDER = 0x0002, ///< Show 'New Folder' icon (if supported)
  106. PREVIEW = 0x0004, ///< enable preview mode (if supported)
  107. USE_FILTER_EXT = 0x0008 ///< Chooser filter pilots the output file extension (if supported)
  108. };
  109. /** Localizable message */
  110. static const char *file_exists_message;
  111. public:
  112. Fl_Native_File_Chooser(int val=BROWSE_FILE);
  113. ~Fl_Native_File_Chooser();
  114. // Public methods
  115. void type(int t);
  116. int type() const ;
  117. void options(int o);
  118. int options() const;
  119. int count() const;
  120. const char *filename() const ;
  121. const char *filename(int i) const ;
  122. void directory(const char *val) ;
  123. const char *directory() const;
  124. void title(const char *t);
  125. const char* title() const;
  126. const char *filter() const ;
  127. void filter(const char *f);
  128. int filters() const ;
  129. void filter_value(int i) ;
  130. int filter_value() const ;
  131. void preset_file(const char*f) ;
  132. const char* preset_file() const;
  133. const char *errmsg() const ;
  134. int show() ;
  135. #ifdef WIN32
  136. private:
  137. int _btype; // kind-of browser to show()
  138. int _options; // general options
  139. OPENFILENAMEW _ofn; // GetOpenFileName() & GetSaveFileName() struct
  140. BROWSEINFOW _binf; // SHBrowseForFolder() struct
  141. char **_pathnames; // array of pathnames
  142. int _tpathnames; // total pathnames
  143. char *_directory; // default pathname to use
  144. char *_title; // title for window
  145. char *_filter; // user-side search filter
  146. char *_parsedfilt; // filter parsed for Windows dialog
  147. int _nfilters; // number of filters parse_filter counted
  148. char *_preset_file; // the file to preselect
  149. char *_errmsg; // error message
  150. // Private methods
  151. void errmsg(const char *msg);
  152. void clear_pathnames();
  153. void set_single_pathname(const char *s);
  154. void add_pathname(const char *s);
  155. void FreePIDL(LPITEMIDLIST pidl);
  156. void ClearOFN();
  157. void ClearBINF();
  158. void Win2Unix(char *s);
  159. void Unix2Win(char *s);
  160. int showfile();
  161. static int CALLBACK Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data);
  162. int showdir();
  163. void parse_filter(const char *);
  164. void clear_filters();
  165. void add_filter(const char *, const char *);
  166. #endif
  167. #ifdef __APPLE__
  168. private:
  169. int _btype; // kind-of browser to show()
  170. int _options; // general options
  171. void *_panel;
  172. char **_pathnames; // array of pathnames
  173. int _tpathnames; // total pathnames
  174. char *_directory; // default pathname to use
  175. char *_title; // title for window
  176. char *_preset_file; // the 'save as' filename
  177. char *_filter; // user-side search filter, eg:
  178. // C Files\t*.[ch]\nText Files\t*.txt"
  179. char *_filt_names; // filter names (tab delimited)
  180. // eg. "C Files\tText Files"
  181. char *_filt_patt[MAXFILTERS];
  182. // array of filter patterns, eg:
  183. // _filt_patt[0]="*.{cxx,h}"
  184. // _filt_patt[1]="*.txt"
  185. int _filt_total; // parse_filter() # of filters loaded
  186. int _filt_value; // index of the selected filter
  187. char *_errmsg; // error message
  188. // Private methods
  189. void errmsg(const char *msg);
  190. void clear_pathnames();
  191. void set_single_pathname(const char *s);
  192. int get_saveas_basename(void);
  193. void clear_filters();
  194. void add_filter(const char *, const char *);
  195. void parse_filter(const char *from);
  196. int post();
  197. int runmodal();
  198. #endif
  199. #if ! defined(__APPLE__) && !defined(WIN32)
  200. private:
  201. #if FLTK_ABI_VERSION <= 10302
  202. int _btype; // kind-of browser to show()
  203. int _options; // general options
  204. int _nfilters;
  205. char *_filter; // user supplied filter
  206. char *_parsedfilt; // parsed filter
  207. int _filtvalue; // selected filter
  208. char *_preset_file;
  209. char *_prevvalue; // Returned filename
  210. char *_directory;
  211. char *_errmsg; // error message
  212. #endif
  213. static int have_looked_for_GTK_libs;
  214. union {
  215. Fl_FLTK_File_Chooser *_x11_file_chooser;
  216. Fl_GTK_File_Chooser *_gtk_file_chooser;
  217. };
  218. #endif
  219. };
  220. #if !defined(__APPLE__) && !defined(WIN32)
  221. class Fl_FLTK_File_Chooser {
  222. friend class Fl_Native_File_Chooser;
  223. protected:
  224. int _btype; // kind-of browser to show()
  225. int _options; // general options
  226. int _nfilters;
  227. char *_filter; // user supplied filter
  228. char *_parsedfilt; // parsed filter
  229. int _filtvalue; // selected filter
  230. char *_preset_file;
  231. char *_prevvalue; // Returned filename
  232. char *_directory;
  233. char *_errmsg; // error message
  234. Fl_FLTK_File_Chooser(int val);
  235. virtual ~Fl_FLTK_File_Chooser();
  236. void errmsg(const char *msg);
  237. int type_fl_file(int);
  238. void parse_filter();
  239. void keeplocation();
  240. int exist_dialog();
  241. Fl_File_Chooser *_file_chooser;
  242. virtual void type(int);
  243. int type() const;
  244. void options(int);
  245. int options() const;
  246. virtual int count() const;
  247. virtual const char *filename() const;
  248. virtual const char *filename(int i) const;
  249. void directory(const char *val);
  250. const char *directory() const;
  251. virtual void title(const char *);
  252. virtual const char* title() const;
  253. const char *filter() const;
  254. void filter(const char *);
  255. int filters() const;
  256. void filter_value(int i);
  257. int filter_value() const;
  258. void preset_file(const char*);
  259. const char* preset_file() const;
  260. const char *errmsg() const;
  261. virtual int show();
  262. };
  263. class Fl_GTK_File_Chooser : public Fl_FLTK_File_Chooser {
  264. friend class Fl_Native_File_Chooser;
  265. private:
  266. typedef struct _GtkWidget GtkWidget;
  267. typedef struct _GtkFileFilterInfo GtkFileFilterInfo;
  268. struct pair {
  269. Fl_GTK_File_Chooser* running; // the running Fl_GTK_File_Chooser
  270. const char *filter; // a filter string of the chooser
  271. pair(Fl_GTK_File_Chooser* c, const char *f) {
  272. running = c;
  273. filter = strdup(f);
  274. };
  275. ~pair() {
  276. free((char*)filter);
  277. };
  278. };
  279. GtkWidget *gtkw_ptr; // used to hold a GtkWidget* without pulling GTK into everything...
  280. void *gtkw_slist; // used to hold a GLib GSList...
  281. unsigned gtkw_count; // number of files read back - if any
  282. mutable char *gtkw_filename; // last name we read back
  283. char *gtkw_title; // the title to be applied to the dialog
  284. const char *previous_filter;
  285. int fl_gtk_chooser_wrapper(); // method that wraps the GTK widget
  286. Fl_GTK_File_Chooser(int val);
  287. virtual ~Fl_GTK_File_Chooser();
  288. static int did_find_GTK_libs;
  289. static void probe_for_GTK_libs(void);
  290. virtual void type(int);
  291. virtual int count() const;
  292. virtual const char *filename() const;
  293. virtual const char *filename(int i) const;
  294. virtual void title(const char *);
  295. virtual const char* title() const;
  296. virtual int show();
  297. void changed_output_type(const char *filter);
  298. static int custom_gtk_filter_function(const GtkFileFilterInfo*, Fl_GTK_File_Chooser::pair*);
  299. static void free_pair(pair *p);
  300. };
  301. #endif // !defined(__APPLE__) && !defined(WIN32)
  302. #endif /*FL_NATIVE_FILE_CHOOSER_H*/
  303. //
  304. // End of "$Id: Fl_Native_File_Chooser.H 10186 2014-06-07 12:01:59Z manolo $".
  305. //