make all of dialog visible for add_route_dialog
[ardour.git] / gtk2_ardour / export_dialog.cc
index 1153f318f41037a6dea49b7c194bb5554a950aaa..bfe85f69a387972d6118316b1a5f39869c349390 100644 (file)
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
+    $Id$
+
 */
 
 #include <unistd.h>
 #include <utility>
+#include <sys/stat.h>
 
 #include <fstream>
 
 #include <samplerate.h>
 #include <pbd/pthread_utils.h>
 #include <pbd/xml++.h>
+#include <pbd/dirname.h>
 
 #include <gtkmm2ext/utils.h>
 #include <ardour/export.h>
@@ -39,6 +43,7 @@
 #include "ardour_ui.h"
 #include "public_editor.h"
 #include "keyboard.h"
+#include "ardour_message.h"
 
 #include "i18n.h"
 
@@ -60,7 +65,7 @@ static const gchar *sample_rates[] = {
        0
 };
 
-static const gchar *src_qualities[] = {
+static const gchar *src_quality[] = {
        N_("best"),
        N_("fastest"),
        N_("linear"),
@@ -95,18 +100,17 @@ ExportDialog::ExportDialog(PublicEditor& e, AudioRegion* r)
          editor (e),
          format_table (9, 2),
          format_frame (_("FORMAT")),
-         sample_rate_label (_("SAMPLE RATE")),
-         src_quality_label (_("CONVERSION QUALITY")),
-         dither_type_label (_("DITHER TYPE")),
-         cue_file_label (_("CD MARKER FILE TYPE")),
-         channel_count_label (_("CHANNELS")),
-         header_format_label (_("FILE TYPE")),
-         bitdepth_format_label (_("SAMPLE FORMAT")),
-         endian_format_label (_("SAMPLE ENDIANNESS")),
+         cue_file_label (_("CD MARKER FILE TYPE"), 1.0, 0.5),
+         channel_count_label (_("CHANNELS"), 1.0, 0.5),
+         header_format_label (_("FILE TYPE"), 1.0, 0.5),
+         bitdepth_format_label (_("SAMPLE FORMAT"), 1.0, 0.5),
+         endian_format_label (_("SAMPLE ENDIANNESS"), 1.0, 0.5),
+         sample_rate_label (_("SAMPLE RATE"), 1.0, 0.5),
+         src_quality_label (_("CONVERSION QUALITY"), 1.0, 0.5),
+         dither_type_label (_("DITHER TYPE"), 1.0, 0.5),
          cuefile_only_checkbox (_("EXPORT CD MARKER FILE ONLY")),
          file_frame (_("EXPORT TO FILE")),
          file_browse_button (_("Browse")),
-         ok_button (_("Export")),
          track_selector_button (_("Specific tracks ..."))
 {
        guint32 n;
@@ -122,17 +126,9 @@ ExportDialog::ExportDialog(PublicEditor& e, AudioRegion* r)
        set_name ("ExportWindow");
        add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
 
-       add (vpacker);
-
-       vpacker.set_border_width (10);
-       vpacker.set_spacing (10);
-
        file_selector = 0;
        spec.running = false;
 
-       file_entry.signal_focus_in_event().connect (sigc::ptr_fun (ARDOUR_UI::generic_focus_in_event));
-       file_entry.signal_focus_out_event().connect (sigc::ptr_fun (ARDOUR_UI::generic_focus_out_event));
-
        file_entry.set_name ("ExportFileNameEntry");
 
        master_list = ListStore::create (exp_cols);
@@ -175,7 +171,7 @@ ExportDialog::ExportDialog(PublicEditor& e, AudioRegion* r)
        track_scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
        master_scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
 
-       vpacker.pack_start (file_frame, false, false);
+       get_vbox()->pack_start (file_frame, false, false);
 
        hpacker.set_spacing (5);
        hpacker.set_border_width (5);
@@ -199,13 +195,12 @@ ExportDialog::ExportDialog(PublicEditor& e, AudioRegion* r)
                hpacker.pack_start (track_vpacker);
        }
 
-       vpacker.pack_start (hpacker);
+       get_vbox()->pack_start (hpacker);
        
        track_selector_button.set_name ("EditorGTKButton");
        track_selector_button.signal_clicked().connect (mem_fun(*this, &ExportDialog::track_selector_button_click));
 
-       vpacker.pack_start (button_box, false, false);
-       vpacker.pack_start (progress_bar, false, false);
+       get_vbox()->pack_start (progress_bar, false, false);
 
        Gtkmm2ext::set_size_request_to_display_given_text (file_entry, X_("Kg/quite/a/reasonable/size/for/files/i/think"), 5, 8);
 
@@ -219,23 +214,33 @@ ExportDialog::ExportDialog(PublicEditor& e, AudioRegion* r)
        file_frame.set_name (FRAME_NAME);
 
        /* pop_strings needs to be created on the stack because set_popdown_strings()
-        * takes a reference. */
+          takes a reference. 
+       */
+
        vector<string> pop_strings = internationalize(sample_rates);
        Gtkmm2ext::set_popdown_strings (sample_rate_combo, pop_strings);
-       pop_strings = internationalize(sample_rates);
+       sample_rate_combo.set_active_text (pop_strings.front());
+       pop_strings = internationalize(src_quality);
        Gtkmm2ext::set_popdown_strings (src_quality_combo, pop_strings);
+       src_quality_combo.set_active_text (pop_strings.front());
        pop_strings = internationalize(dither_types);
        Gtkmm2ext::set_popdown_strings (dither_type_combo, pop_strings);
+       dither_type_combo.set_active_text (pop_strings.front());
        pop_strings = internationalize(channel_strings);
        Gtkmm2ext::set_popdown_strings (channel_count_combo, pop_strings);
+       channel_count_combo.set_active_text (pop_strings.front());
        pop_strings = internationalize((const char **) sndfile_header_formats_strings);
        Gtkmm2ext::set_popdown_strings (header_format_combo, pop_strings);
+       header_format_combo.set_active_text (pop_strings.front());
        pop_strings = internationalize((const char **) sndfile_bitdepth_formats_strings);
        Gtkmm2ext::set_popdown_strings (bitdepth_format_combo, pop_strings);
+       bitdepth_format_combo.set_active_text (pop_strings.front());
        pop_strings = internationalize((const char **) sndfile_endian_formats_strings);
        Gtkmm2ext::set_popdown_strings (endian_format_combo, pop_strings);
+       endian_format_combo.set_active_text (pop_strings.front());
        pop_strings = internationalize(cue_file_types);
        Gtkmm2ext::set_popdown_strings (cue_file_combo, pop_strings);
+       cue_file_combo.set_active_text (pop_strings.front());
 
        /* this will re-sensitized as soon as a non RIFF/WAV
           header format is chosen.
@@ -279,10 +284,10 @@ ExportDialog::ExportDialog(PublicEditor& e, AudioRegion* r)
        longest_str[0] = 'g';
        longest_str[1] = 'l';
 
-       Gtkmm2ext::set_size_request_to_display_given_text (header_format_combo, longest_str.c_str(), 5+FUDGE, 5);
+       //Gtkmm2ext::set_size_request_to_display_given_text (header_format_combo, longest_str.c_str(), 5+FUDGE, 5);
 
        // TRANSLATORS: "slereg" is "stereo" with ascender and descender substituted
-       Gtkmm2ext::set_size_request_to_display_given_text (channel_count_combo, _("slereg"), 5+FUDGE, 5);
+       //Gtkmm2ext::set_size_request_to_display_given_text (channel_count_combo, _("slereg"), 5+FUDGE, 5);
 
 /*     header_format_combo.set_focus_on_click (true);
        bitdepth_format_combo.set_focus_on_click (true);
@@ -313,54 +318,46 @@ ExportDialog::ExportDialog(PublicEditor& e, AudioRegion* r)
 
        cuefile_only_checkbox.set_name ("ExportCheckbox");
 
-       format_table.set_homogeneous (true);
+       format_table.set_homogeneous (false);
        format_table.set_border_width (5);
        format_table.set_col_spacings (5);
        format_table.set_row_spacings (5);
 
        if (!audio_region) {
                format_table.attach (channel_count_label, 0, 1, 0, 1);
-               format_table.attach (channel_count_combo, 0, 1, 1, 2);
+               format_table.attach (channel_count_combo, 1, 2, 0, 1);
        }
 
-       format_table.attach (header_format_label, 1, 2, 0, 1);
+       format_table.attach (header_format_label, 0, 1, 1, 2);
        format_table.attach (header_format_combo, 1, 2, 1, 2);
 
        format_table.attach (bitdepth_format_label, 0, 1, 2, 3);
-       format_table.attach (bitdepth_format_combo, 0, 1, 3, 4);
+       format_table.attach (bitdepth_format_combo, 1, 2, 2, 3);
 
-       format_table.attach (endian_format_label, 1, 2, 2, 3);
+       format_table.attach (endian_format_label, 0, 1, 3, 4);
        format_table.attach (endian_format_combo, 1, 2, 3, 4);
 
        format_table.attach (sample_rate_label, 0, 1, 4, 5);
-       format_table.attach (sample_rate_combo, 0, 1, 5, 6);
+       format_table.attach (sample_rate_combo, 1, 2, 4, 5);
 
-       format_table.attach (src_quality_label, 1, 2, 4, 5);
+       format_table.attach (src_quality_label, 0, 1, 5, 6);
        format_table.attach (src_quality_combo, 1, 2, 5, 6);
 
        format_table.attach (dither_type_label, 0, 1, 6, 7);
-       format_table.attach (dither_type_combo, 0, 1, 7, 8);
+       format_table.attach (dither_type_combo, 1, 2, 6, 7);
 
-       format_table.attach (cue_file_label, 1, 2, 6, 7);
+       format_table.attach (cue_file_label, 0, 1, 7, 8);
        format_table.attach (cue_file_combo, 1, 2, 7, 8);
-       format_table.attach (cuefile_only_checkbox, 1, 2, 8, 9);
+       format_table.attach (cuefile_only_checkbox, 0, 2, 8, 9);
 
-
-       button_box.set_spacing (10);
-       button_box.set_homogeneous (true);
-
-       cancel_button.add (cancel_label);
-
-       button_box.pack_start (ok_button, false, true);
-       button_box.pack_start (cancel_button, false, true);
-       
-       ok_button.set_name ("EditorGTKButton");
-       cancel_button.set_name ("EditorGTKButton");
        file_entry.set_name ("ExportFileDisplay");
 
        signal_delete_event().connect (mem_fun(*this, &ExportDialog::window_closed));
-       ok_button.signal_clicked().connect (mem_fun(*this, &ExportDialog::do_export));
-       cancel_button.signal_clicked().connect (mem_fun(*this, &ExportDialog::end_dialog));
+
+       ok_button = add_button (Stock::OK, RESPONSE_ACCEPT);
+       ok_button->signal_clicked().connect (mem_fun(*this, &ExportDialog::do_export));
+       cancel_button = add_button (Stock::CANCEL, RESPONSE_CANCEL);
+       cancel_button->signal_clicked().connect (mem_fun(*this, &ExportDialog::end_dialog));
        
        file_browse_button.set_name ("EditorGTKButton");
        file_browse_button.signal_clicked().connect (mem_fun(*this, &ExportDialog::initiate_browse));
@@ -485,14 +482,11 @@ ExportDialog::set_state()
                                if (nchns == 2) {
                                        if (r % 2) {
                                                rows[r][exp_cols.right] = true;
-//                                             master_selector.cell (r, 2).set_pixmap (check_pixmap, check_mask);
                                        } else {
                                                rows[r][exp_cols.left] = true;
-//                                             master_selector.cell (r, 1).set_pixmap (check_pixmap, check_mask);
                                        }
                                } else {
                                        rows[r][exp_cols.left] = true;
-//                                     master_selector.cell (r, 1).set_pixmap (check_pixmap, check_mask);
                                }
                        }
 
@@ -890,9 +884,45 @@ ExportDialog::do_export_cd_markers (const string& path,const string& cuefile_typ
 void
 ExportDialog::do_export ()
 {
-       ok_button.set_sensitive(false);
-       save_state();
-
+       // sanity check file name first
+       string filepath = file_entry.get_text();
+       struct stat statbuf;
+  
+       if (filepath.empty()) {
+               // warning dialog
+               string txt = _("Please enter a valid filename.");
+               MessageDialog msg (*this, txt, false, MESSAGE_ERROR, BUTTONS_OK, true);
+               msg.run();
+               return;
+       }
+       
+       // check if file exists already and warn
+       if (stat (filepath.c_str(), &statbuf) == 0) {
+               if (S_ISDIR (statbuf.st_mode)) {
+                       string txt = _("Please specify a complete filename for the audio file.");
+                       MessageDialog msg (*this, txt, false, MESSAGE_ERROR, BUTTONS_OK, true);
+                       msg.run();
+                       return;
+               }
+               else {
+                       string txt = _("File already exists, do you want to overwrite it?");
+                       MessageDialog msg (*this, txt, false, MESSAGE_QUESTION, BUTTONS_YES_NO, true);
+                       //ArdourMessage msg (this, X_("exportoverwrite"), txt, true, false, Gtk::BUTTONS_YES_NO);
+                       if ((ResponseType) msg.run() == Gtk::RESPONSE_NO) {
+                               return;
+                       }
+               }
+       }
+       
+       // directory needs to exist and be writable
+       string dirpath = PBD::dirname (filepath);
+       if (::access (dirpath.c_str(), W_OK) != 0) {
+               string txt = _("Cannot write file in: ") + dirpath;
+               MessageDialog msg (*this, txt, false, MESSAGE_ERROR, BUTTONS_OK, true);
+               msg.run();
+               return;
+       }
+       
        if (cue_file_combo.get_active_text () != _("None")) {
                do_export_cd_markers (file_entry.get_text(), cue_file_combo.get_active_text ());
        }
@@ -902,9 +932,12 @@ ExportDialog::do_export ()
                return;
        }
 
+       ok_button->set_sensitive(false);
+       save_state();
+
        set_modal (true);
        
-       spec.path = file_entry.get_text();
+       spec.path = filepath;
        spec.progress = 0;
        spec.running = true;
        spec.stop = false;
@@ -1075,7 +1108,7 @@ ExportDialog::end_dialog ()
        }
 
        set_modal (false);
-       ok_button.set_sensitive(true);
+       ok_button->set_sensitive(true);
 }
 
 void
@@ -1097,6 +1130,8 @@ ExportDialog::start_export ()
                if ((last_slash = dir.find_last_of ('/')) != string::npos) {
                        dir = dir.substr (0, last_slash+1);
                }
+
+               dir = dir + "export.wav";
                
                file_entry.set_text (dir);
        }
@@ -1268,19 +1303,11 @@ ExportDialog::initiate_browse ()
 
                file_selector->get_cancel_button()->signal_clicked().connect (bind (mem_fun(*this, &ExportDialog::finish_browse), -1));
                file_selector->get_ok_button()->signal_clicked().connect (bind (mem_fun(*this, &ExportDialog::finish_browse), 1));
-               file_selector->signal_map_event().connect (bind (mem_fun(*this, &ExportDialog::change_focus_policy), true));
-               file_selector->signal_unmap_event().connect (bind (mem_fun(*this, &ExportDialog::change_focus_policy), false));
        }
+       file_selector->set_filename (file_entry.get_text());
        file_selector->show_all ();
 }
 
-gint
-ExportDialog::change_focus_policy (GdkEventAny *ev, bool yn)
-{
-       Keyboard::the_keyboard().allow_focus (yn);
-       return FALSE;
-}
-
 void
 ExportDialog::finish_browse (int status)
 {