root/sweep/trunk/src/file_dialogs.c

Revision 691, 21.9 kB (checked in by erikd, 2 years ago)

Remove needless #defines of buffer lengths.

Code had many instances of:

#undef BUF_LEN
#define BUF_LEN 64
char buf[BUF_LEN];
snprintf (buf, BUF_LEN, ....);

which can be replaced with:

char buf[64];
snprintf (buf, sizeof (buf), ....);

which is far cleaner and more difficult to get wrong.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Sweep, a sound wave editor.
3  *
4  * Copyright (C) 2000 Conrad Parker
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <errno.h>
32
33 #include <gdk/gdkkeysyms.h>
34 #include <gtk/gtk.h>
35
36 #include <sndfile.h>
37
38 #include <sweep/sweep_types.h>
39 #include <sweep/sweep_sample.h>
40 #include <sweep/sweep_i18n.h>
41
42 #include "sweep_app.h"
43 #include "file_sndfile.h"
44 #include "sample.h"
45 #include "interface.h"
46 #include "sample-display.h"
47 #include "question_dialogs.h"
48 #include "preferences.h"
49
50 #define LAST_LOAD_KEY "Last_Load"
51 #define LAST_SAVE_KEY "Last_Save"
52
53 #ifdef HAVE_OGGVORBIS
54 extern sw_sample * vorbis_sample_reload (sw_sample * sample);
55 extern sw_sample * vorbis_sample_load (char * pathname);
56 extern int vorbis_save_options_dialog (sw_sample * sample, char * pathname);
57 #endif
58
59 #ifdef HAVE_SPEEX
60 extern sw_sample * speex_sample_reload (sw_sample * sample);
61 extern sw_sample * speex_sample_load (char * pathname);
62 extern int speex_save_options_dialog (sw_sample * sample, char * pathname);
63 #endif
64
65 #ifdef HAVE_MAD
66 extern sw_sample * mad_sample_reload (sw_sample * sample);
67 extern sw_sample * mad_sample_load (char * pathname);
68 #endif
69
70 void
71 mp3_unsupported_dialog (void)
72 {
73   info_dialog_new (_("MP3 export unsupported"), NULL,
74                    _("Export to MP3 format cannot legally be supported "
75                      "in free software\n"
76                      "due to patent licensing restrictions.\n\n"
77                      "Please use Ogg Vorbis format instead, which\n"
78                      "provides better quality and is free."));
79 }
80
81 /* This source code can compile against both version 0 and version 1
82 ** of libsndfile.
83 */
84
85 typedef struct {
86   sw_file_format_t file_format;
87   gchar * name;
88   gchar * exts; /* comma separated extensions */
89 } sw_file_format_desc;
90
91 void
92 file_guess_method (sw_sample * sample, char * pathname);
93
94 #if ! (defined (SNDFILE_1))
95
96 static sw_file_format_desc file_formats [] = {
97   {
98     SWEEP_FILE_FORMAT_RAW,
99     N_("Raw PCM (headerless)"),
100     "raw",
101   },
102   {
103     SWEEP_FILE_FORMAT_AIFF,
104     "Apple/SGI AIFF,AIFF-C",
105     "aiff,aifc"
106   },
107   {
108     SWEEP_FILE_FORMAT_AU,
109     "Sun/NeXT AU",
110     "au",
111   },
112   {
113     SWEEP_FILE_FORMAT_SVX,
114     "Amiga IFF,SVX8,SVX16",
115     "svx",
116   },
117   {
118     SWEEP_FILE_FORMAT_PAF,
119     "Ensoniq PARIS",
120     "paf",
121   },
122   {
123     SWEEP_FILE_FORMAT_IRCAM,
124     "IRCAM/Berkeley/CARL SF",
125     "sf",
126   },
127   {
128     SWEEP_FILE_FORMAT_VOC,
129     "Creative Labs VOC",
130     "voc",
131   },
132   {
133     SWEEP_FILE_FORMAT_WAV,
134     "Microsoft WAV",
135     "wav,riff",
136   },
137 };
138
139 #endif
140
141 static gboolean
142 sweep_dir_exists (char * pathname)
143 {
144   struct stat statbuf;
145   char buf[512];
146
147   gchar * dirname;
148
149   dirname = g_dirname (pathname);
150
151   if (dirname && strcmp (dirname, "") && stat (dirname, &statbuf) == -1) {
152     switch (errno) {
153     case ENOENT:
154       snprintf (buf, sizeof (buf), _("%s does not exist."), dirname);
155       info_dialog_new (_("Directory does not exist"), NULL, buf);
156       g_free (dirname);
157       return FALSE;
158       break;
159     default:
160       break;
161     }
162   }
163
164   /* dirname is either NULL, "" or an existing directory */
165
166   return TRUE;
167 }
168
169 #ifdef HAVE_MAD
170 static gboolean
171 file_guess_mp3 (char * pathname)
172 {
173   gchar * ext;
174
175   ext = strrchr (pathname, '.');
176
177   if (ext != NULL) {
178     ext++;
179     if (!g_strncasecmp (ext, "mp3", 4)) return TRUE;
180     if (!g_strncasecmp (ext, "mp2", 4)) return TRUE;
181   }
182
183   return FALSE;
184 }
185 #endif
186
187 sw_sample *
188 sample_reload (sw_sample * sample)
189 {
190   sw_sample * new_sample = NULL;
191
192 #ifdef HAVE_OGGVORBIS
193   new_sample = vorbis_sample_reload (sample);
194 #endif
195
196   if (new_sample == NULL)
197     new_sample = sndfile_sample_reload (sample, FALSE);
198
199 #ifdef HAVE_SPEEX
200   if (new_sample == NULL)
201     new_sample = speex_sample_reload (sample);
202 #endif
203
204 #ifdef HAVE_MAD
205   if (new_sample == NULL && file_guess_mp3 (sample->pathname))
206     new_sample = mad_sample_reload (sample);
207 #endif
208
209   if (new_sample == NULL)
210     new_sample = sndfile_sample_reload (sample, TRUE);
211
212   return new_sample;
213 }
214
215 static sw_sample *
216 try_sample_load (char * pathname)
217 {
218   sw_sample * sample = NULL;
219
220 #ifdef HAVE_OGGVORBIS
221   sample = vorbis_sample_load (pathname);
222 #endif
223
224   if (sample == NULL)
225     sample = sndfile_sample_load (pathname, FALSE);
226
227 #ifdef HAVE_SPEEX
228   if (sample == NULL)
229     sample = speex_sample_load (pathname);
230 #endif
231
232 #ifdef HAVE_MAD
233   if (sample == NULL && file_guess_mp3 (pathname))
234     sample = mad_sample_load (pathname);
235 #endif
236
237   if (sample == NULL)
238     sample = sndfile_sample_load (pathname, TRUE); 
239  
240   if (sample != NULL)
241         recent_manager_add_item (pathname);
242        
243   return sample;
244 }
245
246 sw_sample *
247 sample_load (char * pathname)
248 {
249   if (sweep_dir_exists (pathname)) {
250     if (strcmp (pathname, "-") == 0) {
251       try_sample_load (pathname);
252     } else if (access(pathname, R_OK) == -1) {
253       switch (errno) {
254       case ENOENT:
255         create_sample_new_dialog_defaults (pathname);
256         /*sweep_perror (errno, pathname);*/
257         break;
258       default:
259         sweep_perror (errno, _("Unable to read\n%s"), pathname);
260         break;
261       }
262     } else {
263       prefs_set_string (LAST_LOAD_KEY, pathname);
264      
265       return try_sample_load (pathname);
266     }
267   }
268
269   return NULL;
270 }
271
272 void
273 sample_load_cb(GtkWidget * widget, gpointer data)
274 {
275
276   GtkWidget *dialog;
277   gchar *load_current_file;
278   gint win_width, win_height;
279   GSList *filenames, *list;
280  
281   filenames = list = NULL;
282    
283   win_width = gdk_screen_width () / 2;
284   win_height = gdk_screen_height () / 2;
285
286   dialog = gtk_file_chooser_dialog_new (_("Sweep: Open Files"),
287                                       data,
288                                       GTK_FILE_CHOOSER_ACTION_OPEN,
289                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
290                                       GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
291                                       NULL);
292    
293   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
294   gtk_widget_set_size_request (dialog, win_width, win_height);
295   gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
296  
297   sweep_set_window_icon (GTK_WINDOW(dialog));
298   attach_window_close_accel(GTK_WINDOW(dialog));
299    
300   load_current_file = prefs_get_string (LAST_LOAD_KEY);
301  
302   if (load_current_file) {
303       gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(dialog), load_current_file);
304      
305       g_free(load_current_file);
306   }
307    
308   if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
309      
310    filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER(dialog));     
311    
312    for (list = filenames; list; list = list->next) {
313
314      if (list->data) {
315        sample_load ((gchar *)list->data);
316        g_free (list->data);
317      }   
318   }
319      
320   if (filenames)
321     g_slist_free(filenames);
322      
323   } else {
324     /* do nothing so exit */
325      sample_bank_remove(NULL);
326   }
327    
328   gtk_widget_destroy (dialog);
329 }
330
331 gboolean
332 sample_mtime_changed (sw_sample * sample)
333 {
334   struct stat statbuf;
335
336   /* a last_mtime of 0 indicates that the file is not from disk */
337   if (sample->last_mtime == 0) return FALSE;
338
339   if (stat (sample->pathname, &statbuf) == -1) {
340     sweep_perror (errno, sample->pathname);
341     return FALSE;
342   }
343
344   return (sample->last_mtime != statbuf.st_mtime);
345 }
346
347 void
348 sample_revert_ok_cb (GtkWidget * widget, gpointer data)
349 {
350   sw_sample * sample = (sw_sample *)data;
351
352   sample_reload (sample);
353 }
354
355 void
356 sample_revert_cb (GtkWidget * widget, gpointer data)
357 {
358   sw_view * view = (sw_view *)data;
359   sw_sample * sample;
360   char buf[512];
361    
362   sample = view->sample;
363
364   snprintf (buf, sizeof (buf),
365             _("Are you sure you want to revert %s to\n%s?\n\n"
366               "All changes and undo information will be lost."),
367             g_basename (sample->pathname), sample->pathname);
368
369   question_dialog_new (sample, _("Revert file"), buf,
370                        _("Revert"), _("Don't revert"),
371                        G_CALLBACK (sample_revert_ok_cb), sample, NULL, NULL,
372                        SWEEP_EDIT_MODE_ALLOC);
373 }
374
375 void
376 sample_store_and_free_pathname (sw_sample * sample, gchar * pathname)
377 {
378   prefs_set_string (LAST_SAVE_KEY, pathname);
379
380   sample_set_pathname (sample, pathname);
381
382 #ifdef DEVEL_CODE
383   g_free (pathname);
384 #endif
385 }
386
387 void
388 file_guess_method (sw_sample * sample, char * pathname)
389 {
390   int i;
391   gchar * ext;
392
393 #if defined (SNDFILE_1)
394   SF_FORMAT_INFO  info ;
395   int   count ;
396 #else
397   gchar ** exts, **e;
398   sw_file_format_desc * desc;
399 #endif
400
401   g_assert (sample->file_method == SWEEP_FILE_METHOD_BY_EXTENSION);
402
403   if (pathname == NULL) goto guess_raw;
404
405   ext = strrchr (pathname, '.');
406
407   if (ext != NULL) {
408     ext++;
409
410 #ifdef HAVE_OGGVORBIS
411     if (!g_strncasecmp (ext, "ogg", SW_DIR_LEN)) {
412       sample->file_method = SWEEP_FILE_METHOD_OGGVORBIS;
413       sample->file_format = 0;
414       return;
415     }
416 #endif
417
418 #ifdef HAVE_SPEEX
419     if (!g_strncasecmp (ext, "spx", SW_DIR_LEN)) {
420       sample->file_method = SWEEP_FILE_METHOD_SPEEX;
421       sample->file_format = 0;
422       return;
423     }
424 #endif
425
426     /* MP3 has dummy annoying dialog support */
427     if (!g_strncasecmp (ext, "mp3", SW_DIR_LEN)) {
428       sample->file_method = SWEEP_FILE_METHOD_MP3;
429       sample->file_format = 0;
430       return;
431     }
432
433 #if defined (SNDFILE_1)
434
435     sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int)) ;
436
437     for (i = 0; i <  count ; i++) {
438       info.format = i ;
439       sf_command (NULL, SFC_GET_FORMAT_MAJOR, &info, sizeof (info)) ;
440                
441       if (!g_strncasecmp (ext, info.extension, SW_DIR_LEN)) {
442         sample->file_method = SWEEP_FILE_METHOD_LIBSNDFILE;
443         sample->file_format = info.format;
444         break; /* NB. this break is essential to ensure that eg. a file
445                 * ending in ".wav" is guessed as RIFF/WAV not Sphere/NIST,
446                 * which also may use the ending ".wav"; assuming RIFF/WAV is
447                 * more common we prefer to use this format when guessing.
448                 */
449       }
450     }
451
452     /* Catch some common conventions not offered by libsndfile */
453     if (sample->file_method == SWEEP_FILE_METHOD_BY_EXTENSION) {
454       if (!g_strncasecmp(ext, "aifc", SW_DIR_LEN) ||
455           !g_strncasecmp(ext, "aif", SW_DIR_LEN)) {
456         sample->file_method = SWEEP_FILE_METHOD_LIBSNDFILE;
457         sample->file_format = SF_FORMAT_AIFF;
458       }
459     }
460
461 #else
462
463     for (i = 0; i <  sizeof(file_formats)/sizeof(sw_file_format_desc); i++) {
464       desc = &file_formats[i];
465       exts = g_strsplit (desc->exts, ",", 16);
466       for (e = exts; *e; e++) {
467         if (!g_strncasecmp (*e, ext, SW_DIR_LEN)) {
468           sample->file_method = SWEEP_FILE_METHOD_LIBSNDFILE;
469           sample->file_format = desc->file_format;
470         }
471       }
472       g_strfreev (exts);
473     }
474
475 #endif
476
477   }
478
479  guess_raw:
480  
481   if (sample->file_method == SWEEP_FILE_METHOD_BY_EXTENSION) {
482     sample->file_method = SWEEP_FILE_METHOD_LIBSNDFILE;
483 #if defined (SNDFILE_1)
484     sample->file_format = SF_FORMAT_RAW;
485 #else
486     sample->file_format = SWEEP_FILE_FORMAT_RAW;
487 #endif
488   }
489
490   return;
491 }   
492
493 typedef struct {
494   sw_sample * sample;
495   char * pathname;
496 } save_as_data;
497
498 static void
499 overwrite_ok_cb (GtkWidget * widget, gpointer data)
500 {
501   save_as_data * sd = (save_as_data *)data;
502   sw_sample * sample = sd->sample;
503   char * pathname = sd->pathname;
504
505   if (sample->file_method == SWEEP_FILE_METHOD_BY_EXTENSION) {
506     file_guess_method (sample, pathname);
507   }
508
509   switch (sample->file_method) {
510   case SWEEP_FILE_METHOD_LIBSNDFILE:
511     sndfile_save_options_dialog (sample, pathname);
512     break;
513 #ifdef HAVE_OGGVORBIS
514   case SWEEP_FILE_METHOD_OGGVORBIS:
515     vorbis_save_options_dialog (sample, pathname);
516     break;
517 #endif
518 #ifdef HAVE_SPEEX
519   case SWEEP_FILE_METHOD_SPEEX:
520     speex_save_options_dialog (sample, pathname);
521     break;
522 #endif
523   case SWEEP_FILE_METHOD_MP3:
524     mp3_unsupported_dialog ();
525     break;
526   default:
527     g_assert_not_reached ();
528     break;
529   }
530
531   g_free (sd);
532 }
533
534 static void
535 overwrite_cancel_cb (GtkWidget * widget, gpointer data)
536 {
537   save_as_data * sd = (save_as_data *)data;
538   gchar * msg;
539
540   msg = g_strdup_printf (_("Save as %s cancelled"), g_basename (sd->pathname));
541   sample_set_tmp_message (sd->sample, msg);
542   g_free (msg);
543
544   g_free (sd);
545 }
546
547 static void
548 file_set_format_cb (GtkWidget * widget, gpointer data)
549 {
550   sw_sample * sample = (sw_sample *)data;
551
552   sample->file_method = (sw_file_method_t)
553      GPOINTER_TO_INT(g_object_get_data (G_OBJECT(widget), "method"));
554
555   sample->file_format =
556      GPOINTER_TO_INT(g_object_get_data (G_OBJECT(widget), "format"));
557 }
558
559 static GtkWidget *
560 create_save_menu (sw_sample * sample)
561 {
562   GtkWidget * menu;
563   GtkWidget * menuitem;
564   int i;
565
566 #if defined (SNDFILE_1)
567   SF_FORMAT_INFO  info ;
568   int   count ;
569 #else
570   sw_file_format_desc * desc;
571 #endif
572
573   menu = gtk_menu_new ();
574
575   sample->file_method = SWEEP_FILE_METHOD_BY_EXTENSION;
576
577   menuitem = gtk_menu_item_new_with_label (_("By extension"));
578   gtk_menu_append (GTK_MENU(menu), menuitem);
579   gtk_object_set_data (GTK_OBJECT(menuitem), "method",
580                        SWEEP_FILE_METHOD_BY_EXTENSION);
581   gtk_object_set_data (GTK_OBJECT(menuitem), "format", 0);
582   gtk_signal_connect (GTK_OBJECT(menuitem), "activate",
583                       GTK_SIGNAL_FUNC(file_set_format_cb), sample);
584   gtk_widget_show (menuitem);
585
586   menuitem = gtk_menu_item_new (); /* Separator */
587   gtk_menu_append (GTK_MENU(menu), menuitem);
588   gtk_widget_show (menuitem);
589
590   /* libsndfile formats */
591
592 #if defined (SNDFILE_1)
593
594   sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int)) ;
595
596   for (i = 0; i < count ; i++) {
597     info.format = i ;
598     sf_command (NULL, SFC_GET_FORMAT_MAJOR, &info, sizeof (info)) ;
599
600     menuitem = gtk_menu_item_new_with_label (info.name);
601     gtk_menu_append (GTK_MENU(menu), menuitem);
602     gtk_object_set_data (GTK_OBJECT(menuitem), "method",
603                          GINT_TO_POINTER(SWEEP_FILE_METHOD_LIBSNDFILE));
604     gtk_object_set_data (GTK_OBJECT(menuitem), "format",
605                          GINT_TO_POINTER(info.format));
606     gtk_signal_connect (GTK_OBJECT(menuitem), "activate",
607                         GTK_SIGNAL_FUNC(file_set_format_cb), sample);
608     gtk_widget_show (menuitem);
609   }
610
611 #else
612
613   for (i = 0; i < sizeof(file_formats)/sizeof(sw_file_format_desc); i++) {
614     desc = &file_formats[i];
615     menuitem = gtk_menu_item_new_with_label (_(desc->name));
616     gtk_menu_append (GTK_MENU(menu), menuitem);
617     gtk_object_set_data (GTK_OBJECT(menuitem), "method",
618                          GINT_TO_POINTER(SWEEP_FILE_METHOD_LIBSNDFILE));
619     gtk_object_set_data (GTK_OBJECT(menuitem), "format",
620                          GINT_TO_POINTER(desc->file_format));
621     gtk_signal_connect (GTK_OBJECT(menuitem), "activate",
622                         GTK_SIGNAL_FUNC(file_set_format_cb), sample);
623     gtk_widget_show (menuitem);
624   }
625
626 #endif
627
628   menuitem = gtk_menu_item_new (); /* Separator */
629   gtk_menu_append (GTK_MENU(menu), menuitem);
630   gtk_widget_show (menuitem);
631
632   /* MP3 (encoding not supported due to patent restrictions) */
633
634   menuitem = gtk_menu_item_new_with_label (_("MP3 (Use Ogg Vorbis instead)"));
635   gtk_widget_set_sensitive (menuitem, FALSE);
636   gtk_menu_append (GTK_MENU(menu), menuitem);
637   gtk_widget_show (menuitem);
638
639 #ifdef HAVE_OGGVORBIS
640   /* Ogg Vorbis */
641
642   menuitem = gtk_menu_item_new_with_label ("Ogg Vorbis (Xiph.org)");
643   gtk_menu_append (GTK_MENU(menu), menuitem);
644   gtk_object_set_data (GTK_OBJECT(menuitem), "method",
645                        GINT_TO_POINTER(SWEEP_FILE_METHOD_OGGVORBIS));
646   gtk_object_set_data (GTK_OBJECT(menuitem), "format",
647                        GINT_TO_POINTER(0));
648   gtk_signal_connect (GTK_OBJECT(menuitem), "activate",
649                       GTK_SIGNAL_FUNC(file_set_format_cb), sample);
650   gtk_widget_show (menuitem);
651 #endif
652
653 #ifdef HAVE_SPEEX
654   /* Speex */
655
656   menuitem = gtk_menu_item_new_with_label ("Speex (Xiph.org)");
657   gtk_menu_append (GTK_MENU(menu), menuitem);
658   gtk_object_set_data (GTK_OBJECT(menuitem), "method",
659                        GINT_TO_POINTER(SWEEP_FILE_METHOD_SPEEX));
660   gtk_object_set_data (GTK_OBJECT(menuitem), "format",
661                        GINT_TO_POINTER(0));
662   gtk_signal_connect (GTK_OBJECT(menuitem), "activate",
663                       GTK_SIGNAL_FUNC(file_set_format_cb), sample);
664   gtk_widget_show (menuitem);
665 #endif
666
667   return menu;
668 }
669
670 void
671 sample_save_as_cb(GtkWidget * widget, gpointer data)
672 {
673   GtkWidget *dialog;
674   gint win_width, win_height;
675   sw_view * view = (sw_view *)data;
676   sw_sample * sample;
677   GtkWidget * save_options;
678   GtkWidget * frame;
679   GtkWidget * hbox;
680   GtkWidget * label;
681   GtkWidget * option_menu;
682   GtkWidget * save_menu;
683   struct stat statbuf;
684   gchar *filename;
685   gint retval;
686
687   save_as_data * sd;
688
689   char buf[512];
690   char * last_save;
691
692   win_width = gdk_screen_width () / 2;
693   win_height = gdk_screen_height () / 2;
694    
695   sample = view->sample;
696
697   dialog = gtk_file_chooser_dialog_new (_("Sweep: Save file"),
698                                       GTK_WINDOW(view->window),
699                                       GTK_FILE_CHOOSER_ACTION_SAVE,
700                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
701                                       GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
702                                       NULL);
703          
704    
705   //gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
706   attach_window_close_accel(GTK_WINDOW(dialog));
707   sweep_set_window_icon (GTK_WINDOW(dialog));
708    
709   save_options = gtk_hbox_new (TRUE, 1);
710
711   frame = gtk_frame_new (_("Save Options"));
712   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
713   gtk_box_pack_start (GTK_BOX (save_options), frame, TRUE, TRUE, 4);
714  
715   hbox = gtk_hbox_new (FALSE, 4);
716   gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
717   gtk_container_add (GTK_CONTAINER (frame), hbox);
718   gtk_widget_show (hbox);
719  
720   label = gtk_label_new (_("Determine File Type:"));
721   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
722   gtk_widget_show (label);
723  
724   option_menu = gtk_option_menu_new ();
725   gtk_box_pack_start (GTK_BOX (hbox), option_menu, TRUE, TRUE, 0);
726   gtk_widget_show (option_menu);
727  
728   save_menu = create_save_menu (sample);
729   gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), save_menu);
730  
731   gtk_widget_show (frame);
732
733   /* pack the containing save_options hbox into the save-dialog */
734   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
735                     save_options, FALSE, FALSE, 0);
736
737   gtk_widget_show (save_options);
738    
739   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
740   gtk_widget_set_size_request (dialog, win_width, win_height);
741    
742   if (strcmp (g_path_get_dirname(sample->pathname), ".") == 0) {
743
744     last_save = prefs_get_string (LAST_SAVE_KEY);
745
746     if (last_save != NULL) {
747       gchar * last_save_dir = g_dirname (last_save);
748            
749           gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(dialog),
750                                       last_save_dir);                         
751       gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(dialog),
752                                       sample->pathname);
753
754       g_free (last_save_dir);
755       g_free (last_save);
756
757     }
758   } else {
759      retval =  gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(dialog),
760                                     sample->pathname);
761         /* FIXME: bug (local only?) causes gtk_file_chooser_set_filename
762            to fail silently in some cases*/
763         filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
764         //printf("filename pre: %s\n", filename);
765         //printf("sample->pathname: %s\n", sample->pathname);
766
767   }
768  
769   retval = gtk_dialog_run (GTK_DIALOG (dialog));
770                            
771   filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
772   //printf("filename post: %s\n", filename);
773   sample = view->sample;
774   sd = g_malloc (sizeof (save_as_data));
775   sd->sample = sample;
776   sd->pathname = filename;
777
778   if (retval == GTK_RESPONSE_ACCEPT) {
779    
780     if (!sweep_dir_exists (filename)) {
781       g_free (sd); 
782       g_free (filename);
783       return;
784     }
785
786     if (stat (filename, &statbuf) == -1) {
787       switch (errno) {
788       case ENOENT:
789         /* If it doesn't exist, it's ok to save as */
790         overwrite_ok_cb (NULL, sd);
791         break;
792       default:
793         sweep_perror (errno, filename);
794         break;
795       }
796     } else {
797       /* file exists */
798        
799       if (access(filename, W_OK) == -1) {
800         sweep_perror (errno, _("You are not allowed to write to\n%s"), filename);
801       } else {
802         snprintf (buf, sizeof (buf), _("%s exists. Overwrite?"), filename);
803
804         question_dialog_new (sample, _("File exists"), buf,
805                            _("Overwrite"), _("Don't overwrite"),
806                              G_CALLBACK (overwrite_ok_cb), sd, G_CALLBACK (overwrite_cancel_cb), sd,
807                              SWEEP_EDIT_MODE_META);
808       }
809     }
810     /* FIXME: wrapped this due to the above gtk_file_chooser_set_filename problem */
811     } else if (sd->pathname != NULL) {
812       gchar * msg;
813
814       msg = g_strdup_printf (_("Save as %s cancelled"), g_basename (sd->pathname));
815       sample_set_tmp_message (sd->sample, msg);
816       g_free (msg);
817      
818     } else {
819  
820     g_free (sd);
821     g_free (filename);
822     }
823   gtk_widget_destroy (dialog);
824    
825    
826 }
827
828 static void
829 sample_save_ok_cb(GtkWidget * widget, gpointer data)
830 {
831   sw_view * view = (sw_view *)data;
832   sw_sample * sample = view->sample;
833
834   switch (sample->file_method) {
835   case SWEEP_FILE_METHOD_LIBSNDFILE:
836     sndfile_sample_save (sample, sample->pathname);
837     break;
838 #ifdef HAVE_OGGVORBIS
839   case SWEEP_FILE_METHOD_OGGVORBIS:
840     vorbis_save_options_dialog (sample, sample->pathname);
841     break;
842 #endif
843 #ifdef HAVE_SPEEX
844   case SWEEP_FILE_METHOD_SPEEX:
845     speex_save_options_dialog (sample, sample->pathname);
846     break;
847 #endif
848   case SWEEP_FILE_METHOD_MP3:
849     mp3_unsupported_dialog ();
850     break;
851   default:
852     sample_save_as_cb (widget, data);
853     break;
854   }
855 }
856
857 void
858 sample_save_cb (GtkWidget * widget, gpointer data)
859 {
860   sw_view * view = (sw_view *)data;
861   sw_sample * sample;
862   char buf[512];
863    
864   sample = view->sample;
865
866   if (sample->last_mtime == 0 ||
867       sample->file_method == SWEEP_FILE_METHOD_MP3) {
868     sample_save_as_cb (widget, data);
869   } else if (sample_mtime_changed (sample)) {
870     snprintf (buf, sizeof (buf),
871               _("%s\n has changed on disk.\n\n"
872                 "Are you sure you want to save?"),
873               sample->pathname);
874    
875     question_dialog_new (sample, _("File modified"), buf,
876                          _("Save"), _("Don't save"),
877                           G_CALLBACK (sample_save_ok_cb), view, NULL, NULL,
878                          SWEEP_EDIT_MODE_ALLOC);
879   } else {
880     sample_save_ok_cb (widget, view);
881   }
882 }
Note: See TracBrowser for help on using the browser.