1 /* fileselector.c: GTK fileselector routines
2    Copyright (c) 2000-2007 Philip Kendall
3    Copyright (c) 2015-2016 Sergio Baldoví
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License along
16    with this program; if not, write to the Free Software Foundation, Inc.,
17    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 
19    Author contact information:
20 
21    E-mail: philip-fuse@shadowmagic.org.uk
22 
23 */
24 
25 #include <config.h>
26 
27 #include <gtk/gtk.h>
28 
29 #include "gtkinternals.h"
30 #include "ui/ui.h"
31 
32 static gchar *current_folder;
33 
34 static void add_filter_defaults( GtkWidget *file_chooser );
35 static void add_filter_auxiliary_files( GtkFileFilter *filter );
36 static void add_filter_disk_files( GtkFileFilter *filter );
37 static void add_filter_dock_files( GtkFileFilter *filter );
38 static void add_filter_harddisk_files( GtkFileFilter *filter );
39 static void add_filter_microdrive_files( GtkFileFilter *filter );
40 static void add_filter_movie_files( GtkFileFilter *filter );
41 static void add_filter_recording_files( GtkFileFilter *filter );
42 static void add_filter_snapshot_files( GtkFileFilter *filter );
43 static void add_filter_tape_files( GtkFileFilter *filter );
44 
45 #if defined LIBSPECTRUM_SUPPORTS_BZ2_COMPRESSION || \
46     defined LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION
47 static void add_filter_compressed_files( GtkFileFilter *filter );
48 #endif
49 
50 static char*
run_dialog(const char * title,GtkFileChooserAction action)51 run_dialog( const char *title, GtkFileChooserAction action )
52 {
53   GtkWidget *dialog;
54   char *filename = NULL;
55   const char *button;
56 
57   if( action == GTK_FILE_CHOOSER_ACTION_SAVE ) {
58     button = "_Save";
59   } else {
60     button = "_Open";
61   }
62 
63   dialog =
64     gtk_file_chooser_dialog_new( title, GTK_WINDOW( gtkui_window ),
65                                  action, "_Cancel", GTK_RESPONSE_CANCEL,
66                                  button, GTK_RESPONSE_ACCEPT,
67                                  NULL );
68 
69   gtk_dialog_set_default_response( GTK_DIALOG( dialog ), GTK_RESPONSE_ACCEPT );
70 
71   /* TODO: select filter based on UI operation (snapshot, recording, screenshot) */
72   /* TODO: custom filter based file action (open, save) */
73   add_filter_defaults( dialog );
74 
75   if( current_folder )
76     gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( dialog ), current_folder );
77 
78   if( gtk_dialog_run( GTK_DIALOG( dialog ) ) == GTK_RESPONSE_ACCEPT ) {
79     gchar *new_folder = gtk_file_chooser_get_current_folder( GTK_FILE_CHOOSER( dialog ) );
80     if( new_folder ) {
81       g_free( current_folder );
82       current_folder = new_folder;
83     }
84     filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( dialog ) );
85   }
86 
87   gtk_widget_destroy( dialog );
88 
89   return filename;
90 }
91 
92 
93 char*
ui_get_open_filename(const char * title)94 ui_get_open_filename( const char *title )
95 {
96   return run_dialog( title, GTK_FILE_CHOOSER_ACTION_OPEN );
97 }
98 
99 char*
ui_get_save_filename(const char * title)100 ui_get_save_filename( const char *title )
101 {
102   return run_dialog( title, GTK_FILE_CHOOSER_ACTION_SAVE );
103 }
104 
105 static void
add_filter_defaults(GtkWidget * file_chooser)106 add_filter_defaults( GtkWidget *file_chooser )
107 {
108   GtkFileFilter *filter;
109 
110   /* TODO: poll libspectrum for supported file extensions and avoid duplication
111      between UIs */
112   filter = gtk_file_filter_new();
113   gtk_file_filter_set_name( filter, "Supported Files" );
114   add_filter_auxiliary_files( filter );
115 #if defined LIBSPECTRUM_SUPPORTS_BZ2_COMPRESSION || \
116     defined LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION
117   add_filter_compressed_files( filter );
118 #endif
119   add_filter_disk_files( filter );
120   add_filter_dock_files( filter );
121   add_filter_harddisk_files( filter );
122   add_filter_microdrive_files( filter );
123   add_filter_movie_files( filter );
124   add_filter_recording_files( filter );
125   add_filter_snapshot_files( filter );
126   add_filter_tape_files( filter );
127   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
128 
129   filter = gtk_file_filter_new();
130   gtk_file_filter_set_name( filter, "All Files" );
131   gtk_file_filter_add_pattern( filter, "*" );
132   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
133 
134   filter = gtk_file_filter_new();
135   gtk_file_filter_set_name( filter, "Auxiliary Files" );
136   add_filter_auxiliary_files( filter );
137   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
138 
139   filter = gtk_file_filter_new();
140   gtk_file_filter_set_name( filter, "Cartridge Files" );
141   add_filter_dock_files( filter );
142   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
143 
144 #if defined LIBSPECTRUM_SUPPORTS_BZ2_COMPRESSION || \
145     defined LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION
146   filter = gtk_file_filter_new();
147   gtk_file_filter_set_name( filter, "Compressed Files" );
148   add_filter_compressed_files( filter );
149   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
150 #endif
151 
152   filter = gtk_file_filter_new();
153   gtk_file_filter_set_name( filter, "Disk Files" );
154   add_filter_disk_files( filter );
155   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
156 
157   filter = gtk_file_filter_new();
158   gtk_file_filter_set_name( filter, "Harddisk Files" );
159   add_filter_harddisk_files( filter );
160   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
161 
162   filter = gtk_file_filter_new();
163   gtk_file_filter_set_name( filter, "Microdrive Files" );
164   add_filter_microdrive_files( filter );
165   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
166 
167   filter = gtk_file_filter_new();
168   gtk_file_filter_set_name( filter, "Movie Files" );
169   add_filter_movie_files( filter );
170   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
171 
172   filter = gtk_file_filter_new();
173   gtk_file_filter_set_name( filter, "Recording Files" );
174   add_filter_recording_files( filter );
175   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
176 
177   filter = gtk_file_filter_new();
178   gtk_file_filter_set_name( filter, "Snapshot Files" );
179   add_filter_snapshot_files( filter );
180   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
181 
182   filter = gtk_file_filter_new();
183   gtk_file_filter_set_name( filter, "Tape Files" );
184   add_filter_tape_files( filter );
185   gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( file_chooser ), filter );
186 
187 }
188 
189 static void
add_filter_auxiliary_files(GtkFileFilter * filter)190 add_filter_auxiliary_files( GtkFileFilter *filter )
191 {
192   gtk_file_filter_add_pattern( filter, "*.bin" );
193   gtk_file_filter_add_pattern( filter, "*.log" );
194   gtk_file_filter_add_pattern( filter, "*.pok" );
195   gtk_file_filter_add_pattern( filter, "*.scr" );
196   gtk_file_filter_add_pattern( filter, "*.mlt" );
197 
198   gtk_file_filter_add_pattern( filter, "*.BIN" );
199   gtk_file_filter_add_pattern( filter, "*.LOG" );
200   gtk_file_filter_add_pattern( filter, "*.POK" );
201   gtk_file_filter_add_pattern( filter, "*.SCR" );
202   gtk_file_filter_add_pattern( filter, "*.MLT" );
203 
204 #ifdef USE_LIBPNG
205   gtk_file_filter_add_pattern( filter, "*.png" );
206   gtk_file_filter_add_pattern( filter, "*.PNG" );
207 #endif
208 
209 #ifdef HAVE_LIB_XML2
210   gtk_file_filter_add_pattern( filter, "*.svg" );
211   gtk_file_filter_add_pattern( filter, "*.SVG" );
212 #endif
213 }
214 
215 
216 #if defined LIBSPECTRUM_SUPPORTS_BZ2_COMPRESSION || \
217     defined LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION
218 
219 static void
add_filter_compressed_files(GtkFileFilter * filter)220 add_filter_compressed_files( GtkFileFilter *filter )
221 {
222 #ifdef LIBSPECTRUM_SUPPORTS_ZLIB_COMPRESSION
223   gtk_file_filter_add_pattern( filter, "*.gz" );
224   gtk_file_filter_add_pattern( filter, "*.GZ" );
225   gtk_file_filter_add_pattern( filter, "*.zip" );
226   gtk_file_filter_add_pattern( filter, "*.ZIP" );
227 #endif
228 
229 #ifdef LIBSPECTRUM_SUPPORTS_BZ2_COMPRESSION
230   gtk_file_filter_add_pattern( filter, "*.bz2" );
231   gtk_file_filter_add_pattern( filter, "*.BZ2" );
232 #endif
233 }
234 
235 #endif
236 
237 static void
add_filter_disk_files(GtkFileFilter * filter)238 add_filter_disk_files( GtkFileFilter *filter )
239 {
240   gtk_file_filter_add_pattern( filter, "*.d40" );
241   gtk_file_filter_add_pattern( filter, "*.d80" );
242   gtk_file_filter_add_pattern( filter, "*.dsk" );
243   gtk_file_filter_add_pattern( filter, "*.fdi" );
244   gtk_file_filter_add_pattern( filter, "*.img" );
245   gtk_file_filter_add_pattern( filter, "*.mgt" );
246   gtk_file_filter_add_pattern( filter, "*.opd" );
247   gtk_file_filter_add_pattern( filter, "*.opu" );
248   gtk_file_filter_add_pattern( filter, "*.sad" );
249   gtk_file_filter_add_pattern( filter, "*.scl" );
250   gtk_file_filter_add_pattern( filter, "*.td0" );
251   gtk_file_filter_add_pattern( filter, "*.trd" );
252   gtk_file_filter_add_pattern( filter, "*.udi" );
253 
254   gtk_file_filter_add_pattern( filter, "*.D40" );
255   gtk_file_filter_add_pattern( filter, "*.D80" );
256   gtk_file_filter_add_pattern( filter, "*.DSK" );
257   gtk_file_filter_add_pattern( filter, "*.FDI" );
258   gtk_file_filter_add_pattern( filter, "*.IMG" );
259   gtk_file_filter_add_pattern( filter, "*.MGT" );
260   gtk_file_filter_add_pattern( filter, "*.OPD" );
261   gtk_file_filter_add_pattern( filter, "*.OPU" );
262   gtk_file_filter_add_pattern( filter, "*.SAD" );
263   gtk_file_filter_add_pattern( filter, "*.SCL" );
264   gtk_file_filter_add_pattern( filter, "*.TD0" );
265   gtk_file_filter_add_pattern( filter, "*.TRD" );
266   gtk_file_filter_add_pattern( filter, "*.UDI" );
267 }
268 
269 static void
add_filter_dock_files(GtkFileFilter * filter)270 add_filter_dock_files( GtkFileFilter *filter )
271 {
272   gtk_file_filter_add_pattern( filter, "*.dck" );
273   gtk_file_filter_add_pattern( filter, "*.rom" );
274 
275   gtk_file_filter_add_pattern( filter, "*.DCK" );
276   gtk_file_filter_add_pattern( filter, "*.ROM" );
277 }
278 
279 static void
add_filter_harddisk_files(GtkFileFilter * filter)280 add_filter_harddisk_files( GtkFileFilter *filter )
281 {
282   gtk_file_filter_add_pattern( filter, "*.hdf" );
283 
284   gtk_file_filter_add_pattern( filter, "*.HDF" );
285 }
286 
287 static void
add_filter_microdrive_files(GtkFileFilter * filter)288 add_filter_microdrive_files( GtkFileFilter *filter )
289 {
290   gtk_file_filter_add_pattern( filter, "*.mdr" );
291 
292   gtk_file_filter_add_pattern( filter, "*.MDR" );
293 }
294 
295 static void
add_filter_movie_files(GtkFileFilter * filter)296 add_filter_movie_files( GtkFileFilter *filter )
297 {
298   gtk_file_filter_add_pattern( filter, "*.fmf" );
299 
300   gtk_file_filter_add_pattern( filter, "*.FMF" );
301 }
302 
303 static void
add_filter_recording_files(GtkFileFilter * filter)304 add_filter_recording_files( GtkFileFilter *filter )
305 {
306   gtk_file_filter_add_pattern( filter, "*.rzx" );
307 
308   gtk_file_filter_add_pattern( filter, "*.RZX" );
309 }
310 
311 static void
add_filter_snapshot_files(GtkFileFilter * filter)312 add_filter_snapshot_files( GtkFileFilter *filter )
313 {
314   gtk_file_filter_add_pattern( filter, "*.mgtsnp" );
315   gtk_file_filter_add_pattern( filter, "*.slt" );
316   gtk_file_filter_add_pattern( filter, "*.sna" );
317   gtk_file_filter_add_pattern( filter, "*.snapshot" );
318   gtk_file_filter_add_pattern( filter, "*.snp" );
319   gtk_file_filter_add_pattern( filter, "*.sp" );
320   gtk_file_filter_add_pattern( filter, "*.szx" );
321   gtk_file_filter_add_pattern( filter, "*.z80" );
322   gtk_file_filter_add_pattern( filter, "*.zx-state" );
323 
324   gtk_file_filter_add_pattern( filter, "*.MGTSNP" );
325   gtk_file_filter_add_pattern( filter, "*.SLT" );
326   gtk_file_filter_add_pattern( filter, "*.SNA" );
327   gtk_file_filter_add_pattern( filter, "*.SNAPSHOT" );
328   gtk_file_filter_add_pattern( filter, "*.SNP" );
329   gtk_file_filter_add_pattern( filter, "*.SP" );
330   gtk_file_filter_add_pattern( filter, "*.SZX" );
331   gtk_file_filter_add_pattern( filter, "*.Z80" );
332   gtk_file_filter_add_pattern( filter, "*.ZX-STATE" );
333 }
334 
335 static void
add_filter_tape_files(GtkFileFilter * filter)336 add_filter_tape_files( GtkFileFilter *filter )
337 {
338   gtk_file_filter_add_pattern( filter, "*.csw" );
339   gtk_file_filter_add_pattern( filter, "*.ltp" );
340   gtk_file_filter_add_pattern( filter, "*.pzx" );
341   gtk_file_filter_add_pattern( filter, "*.raw" );
342   gtk_file_filter_add_pattern( filter, "*.spc" );
343   gtk_file_filter_add_pattern( filter, "*.sta" );
344   gtk_file_filter_add_pattern( filter, "*.tzx" );
345   gtk_file_filter_add_pattern( filter, "*.tap" );
346   gtk_file_filter_add_pattern( filter, "*.wav" );
347 
348   gtk_file_filter_add_pattern( filter, "*.CSW" );
349   gtk_file_filter_add_pattern( filter, "*.LTP" );
350   gtk_file_filter_add_pattern( filter, "*.PZX" );
351   gtk_file_filter_add_pattern( filter, "*.RAW" );
352   gtk_file_filter_add_pattern( filter, "*.SPC" );
353   gtk_file_filter_add_pattern( filter, "*.STA" );
354   gtk_file_filter_add_pattern( filter, "*.TZX" );
355   gtk_file_filter_add_pattern( filter, "*.TAP" );
356   gtk_file_filter_add_pattern( filter, "*.WAV" );
357 }
358