* Fixed const correctness error in Location
authorSakari Bergen <sakari.bergen@beatwaves.net>
Mon, 29 Sep 2008 17:01:52 +0000 (17:01 +0000)
committerSakari Bergen <sakari.bergen@beatwaves.net>
Mon, 29 Sep 2008 17:01:52 +0000 (17:01 +0000)
* Reworked ExportMainDialog in preparation for the creation of CD and region export dialogs:
  * Separated ExportPresetSelector and ExportFileNotebook from ExportMainDialog
  * Made ExportTimespanSelector polymorphic regarding single/multiple timespan mode
  * renamed ExportMainDialog to ExportDialog and made it easily customizable
  * created ExportRangeDialog and ExportSelectionDialog, these can be later customized more if necessary

git-svn-id: svn://localhost/ardour2/branches/3.0@3834 d708f5d6-7413-0410-9779-e7cbd77b26cf

13 files changed:
gtk2_ardour/SConscript
gtk2_ardour/editor_export_audio.cc
gtk2_ardour/export_dialog.cc [new file with mode: 0644]
gtk2_ardour/export_dialog.h [new file with mode: 0644]
gtk2_ardour/export_file_notebook.cc [new file with mode: 0644]
gtk2_ardour/export_file_notebook.h [new file with mode: 0644]
gtk2_ardour/export_main_dialog.cc [deleted file]
gtk2_ardour/export_main_dialog.h [deleted file]
gtk2_ardour/export_preset_selector.cc [new file with mode: 0644]
gtk2_ardour/export_preset_selector.h [new file with mode: 0644]
gtk2_ardour/export_timespan_selector.cc
gtk2_ardour/export_timespan_selector.h
libs/ardour/ardour/location.h

index 0388910ebd3839b3b2d4ac0944390e482e106f50..818b0fa15c05aba7f482f73ea9da9c246dbd172b 100644 (file)
@@ -172,10 +172,12 @@ editor_timefx.cc
 engine_dialog.cc
 enums.cc
 export_channel_selector.cc
+export_dialog.cc
 export_filename_selector.cc
+export_file_notebook.cc
 export_format_dialog.cc
 export_format_selector.cc
-export_main_dialog.cc
+export_preset_selector.cc
 export_timespan_selector.cc
 gain_meter.cc
 generic_pluginui.cc
index ac68f6d907cacb0d6226f4fd301211d6bfb47c2b..b382200d384b1a16e642ac72c5191e9b35ca5d0f 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <gtkmm/messagedialog.h>
 
-#include "export_main_dialog.h"
+#include "export_dialog.h"
 #include "editor.h"
 #include "public_editor.h"
 #include "selection.h"
@@ -54,7 +54,7 @@ using namespace Gtk;
 void
 Editor::export_audio ()
 {
-       ExportMainDialog dialog (*this);
+       ExportDialog dialog (*this);
        dialog.set_session (session);
        dialog.run();
 }
@@ -62,9 +62,8 @@ Editor::export_audio ()
 void
 Editor::export_selection ()
 {
-       ExportMainDialog dialog (*this);
+       ExportSelectionDialog dialog (*this);
        dialog.set_session (session);
-       dialog.select_timespan (X_("selection"));
        dialog.run();
 }
 
@@ -82,9 +81,8 @@ Editor::export_range ()
        bool is_start;
 
        if (((l = find_location_from_marker (marker, is_start)) != 0) && (l->end() > l->start())) {
-               ExportMainDialog dialog (*this);
+               ExportRangeDialog dialog (*this, l->id().to_s());
                dialog.set_session (session);
-               dialog.select_timespan (l->id().to_s());
                dialog.run();
        }
 }
diff --git a/gtk2_ardour/export_dialog.cc b/gtk2_ardour/export_dialog.cc
new file mode 100644 (file)
index 0000000..7ae81a0
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+    Copyright (C) 2008 Paul Davis
+    Author: Sakari Bergen
+
+    This program 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 2 of the License, or
+    (at your option) any later version.
+
+    This program 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, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "export_dialog.h"
+
+#include <sigc++/signal.h>
+
+#include <pbd/filesystem.h>
+
+#include <ardour/export_status.h>
+#include <ardour/export_handler.h>
+
+using namespace ARDOUR;
+using namespace PBD;
+
+ExportDialog::ExportDialog (PublicEditor & editor, Glib::ustring title) :
+  ArdourDialog (title),
+  editor (editor),
+
+  warn_label ("", Gtk::ALIGN_LEFT),
+  list_files_label (_("<span color=\"#ffa755\">Some already existing files will be overwritten.</span>"), Gtk::ALIGN_RIGHT),
+  list_files_button (_("List files"))
+{ }
+
+ExportDialog::~ExportDialog ()
+{ }
+
+void
+ExportDialog::set_session (ARDOUR::Session* s)
+{
+       init ();
+
+       session = s;
+       
+       /* Init handler and profile manager */
+       
+       handler = session->get_export_handler ();
+       status = session->get_export_status ();
+       profile_manager.reset (new ExportProfileManager (*session));
+       
+       preset_selector->set_manager (profile_manager);
+       file_notebook->set_session_and_manager (session, profile_manager);
+       
+       /* Hand on selection range to profile manager  */
+       
+       TimeSelection const & time (editor.get_selection().time);
+       if (!time.empty()) {
+               profile_manager->set_selection_range (time.front().start, time.front().end);
+       } else {
+               profile_manager->set_selection_range ();
+       }
+       
+       /* Load states */
+       
+       profile_manager->load_profile ();
+       sync_with_manager ();
+       
+       /* Warnings */
+       
+       preset_selector->CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportDialog::sync_with_manager));
+       timespan_selector->CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportDialog::update_warnings));
+       channel_selector->CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportDialog::update_warnings));
+       file_notebook->CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportDialog::update_warnings));
+       status->Aborting.connect (sigc::mem_fun (*this, &ExportDialog::notify_errors));
+       
+       update_warnings ();
+}
+
+void
+ExportDialog::init ()
+{
+       init_components ();
+       init_gui ();
+
+       /* warnings */
+       
+       warning_widget.pack_start (warn_hbox, true, true, 6);
+       warning_widget.pack_end (list_files_hbox, false, false, 0);
+       
+       warn_hbox.pack_start (warn_label, true, true, 16);
+       warn_label.set_use_markup (true);
+       
+       list_files_hbox.pack_end (list_files_button, false, false, 6);
+       list_files_hbox.pack_end (list_files_label, false, false, 6);
+       list_files_label.set_use_markup (true);
+       
+       list_files_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportDialog::show_conflicting_files));
+       
+       /* Progress indicators */
+       
+       progress_widget.pack_start (progress_label, false, false, 6);
+       progress_widget.pack_start (progress_bar, false, false, 6);
+       
+       /* Buttons */
+       
+       cancel_button = add_button (Gtk::Stock::CANCEL, RESPONSE_CANCEL);
+       rt_export_button = add_button (_("Realtime export"), RESPONSE_RT);
+       fast_export_button = add_button (_("Fast Export"), RESPONSE_FAST);
+       
+       cancel_button->signal_clicked().connect (sigc::mem_fun (*this, &ExportDialog::close_dialog));
+       rt_export_button->signal_clicked().connect (sigc::mem_fun (*this, &ExportDialog::export_rt));
+       fast_export_button->signal_clicked().connect (sigc::mem_fun (*this, &ExportDialog::export_fw));
+       
+       /* Done! */
+       
+       show_all_children ();
+       progress_widget.hide_all();
+}
+
+void
+ExportDialog::init_gui ()
+{
+       Gtk::Alignment * preset_align = Gtk::manage (new Gtk::Alignment());
+       preset_align->add (*preset_selector);
+       preset_align->set_padding (0, 12, 0, 0);
+       get_vbox()->pack_start (*preset_align, false, false, 0);
+       
+       Gtk::Alignment * timespan_align = Gtk::manage (new Gtk::Alignment());
+       Gtk::Label * timespan_label = Gtk::manage (new Gtk::Label (_("Time Span"), Gtk::ALIGN_LEFT));
+       timespan_align->add (*timespan_selector);
+       timespan_align->set_padding (0, 12, 18, 0);
+       get_vbox()->pack_start (*timespan_label, false, false, 0);
+       get_vbox()->pack_start (*timespan_align, false, false, 0);
+       
+       Gtk::Alignment * channels_align = Gtk::manage (new Gtk::Alignment());
+       Gtk::Label * channels_label = Gtk::manage (new Gtk::Label (_("Channels"), Gtk::ALIGN_LEFT));
+       channels_align->add (*channel_selector);
+       channels_align->set_padding (0, 12, 18, 0);
+       get_vbox()->pack_start (*channels_label, false, false, 0);
+       get_vbox()->pack_start (*channels_align, false, false, 0);
+       
+       get_vbox()->pack_start (*file_notebook, false, false, 0);
+       get_vbox()->pack_start (warning_widget, true, true, 0);
+       get_vbox()->pack_start (progress_widget, true, true, 0);
+       
+       Pango::AttrList bold;
+       Pango::Attribute b = Pango::Attribute::create_attr_weight (Pango::WEIGHT_BOLD);
+       bold.insert (b);
+       
+       timespan_label->set_attributes (bold);
+       channels_label->set_attributes (bold);
+}
+
+void
+ExportDialog::init_components ()
+{
+       preset_selector.reset (new ExportPresetSelector ());
+       timespan_selector.reset (new ExportTimespanSelectorMultiple ());
+       channel_selector.reset (new ExportChannelSelector ());
+       file_notebook.reset (new ExportFileNotebook ());
+}
+
+void
+ExportDialog::notify_errors ()
+{
+       if (status->errors()) {
+               Glib::ustring txt = _("Export has been aborted due to an error!\nSee the Log for details.");
+               Gtk::MessageDialog msg (txt, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
+               msg.run();
+       }
+}
+
+void
+ExportDialog::close_dialog ()
+{
+       if (status->running) {
+               status->abort();
+       }
+       
+       hide_all ();
+       set_modal (false);
+       
+}
+
+void
+ExportDialog::sync_with_manager ()
+{
+       timespan_selector->set_state (profile_manager->get_timespans().front(), session);
+       channel_selector->set_state (profile_manager->get_channel_configs().front(), session);
+       file_notebook->sync_with_manager ();
+
+       update_warnings ();
+}
+
+void
+ExportDialog::update_warnings ()
+{
+       /* Reset state */
+
+       warn_string = "";
+       warn_label.set_markup (warn_string);
+
+       list_files_hbox.hide ();
+       list_files_string = "";
+       
+       fast_export_button->set_sensitive (true);
+       rt_export_button->set_sensitive (true);
+
+       /* Add new warnings */
+
+       boost::shared_ptr<ExportProfileManager::Warnings> warnings = profile_manager->get_warnings();
+
+       for (std::list<Glib::ustring>::iterator it = warnings->errors.begin(); it != warnings->errors.end(); ++it) {
+               add_error (*it);
+       }
+
+       for (std::list<Glib::ustring>::iterator it = warnings->warnings.begin(); it != warnings->warnings.end(); ++it) {
+               add_warning (*it);
+       }
+
+       if (!warnings->conflicting_filenames.empty()) {
+               list_files_hbox.show ();
+               for (std::list<Glib::ustring>::iterator it = warnings->conflicting_filenames.begin(); it != warnings->conflicting_filenames.end(); ++it) {
+                       ustring::size_type pos = it->find_last_of ("/");
+                       list_files_string += "\n" + it->substr (0, pos + 1) + "<b>" + it->substr (pos + 1) + "</b>";
+               }
+       }
+}
+
+void
+ExportDialog::show_conflicting_files ()
+{
+       ArdourDialog dialog (_("Files that will be overwritten"), true);
+       
+       Gtk::Label label ("", Gtk::ALIGN_LEFT);
+       label.set_use_markup (true);
+       label.set_markup (list_files_string);
+       
+       dialog.get_vbox()->pack_start (label);
+       dialog.add_button (Gtk::Stock::OK, 0);
+       dialog.show_all_children ();
+       
+       dialog.run();
+}
+
+void
+ExportDialog::export_rt ()
+{
+       profile_manager->prepare_for_export ();
+       handler->do_export (true);
+       show_progress ();
+}
+
+void
+ExportDialog::export_fw ()
+{
+       profile_manager->prepare_for_export ();
+       handler->do_export (false);
+       show_progress ();
+}
+
+void
+ExportDialog::show_progress ()
+{
+       status->running = true;
+
+       cancel_button->set_label (_("Stop Export"));
+       rt_export_button->set_sensitive (false);
+       fast_export_button->set_sensitive (false);
+
+       progress_bar.set_fraction (0.0);
+       warning_widget.hide_all();
+       progress_widget.show ();
+       progress_widget.show_all_children ();
+       progress_connection = Glib::signal_timeout().connect (mem_fun(*this, &ExportDialog::progress_timeout), 100);
+       
+       gtk_main_iteration ();
+       while (status->running) {
+               if (gtk_events_pending()) {
+                       gtk_main_iteration ();
+               } else {
+                       usleep (10000);
+               }
+       }
+}
+
+gint
+ExportDialog::progress_timeout ()
+{
+       switch (status->stage) {
+         case export_None:
+               progress_label.set_text ("");
+               break;
+         case export_ReadTimespan:
+               progress_label.set_text (string_compose (_("Reading timespan %1 of %2"), status->timespan, status->total_timespans));
+               break;
+         case export_PostProcess:
+               progress_label.set_text (string_compose (_("Processing file %2 of %3 (%1) from timespan %4 of %5"),
+                                                        file_notebook->get_nth_format_name (status->format),
+                                                        status->format, status->total_formats,
+                                                        status->timespan, status->total_timespans));
+               break;
+         case export_Write:
+               progress_label.set_text (string_compose (_("Encoding file %2 of %3 (%1) from timespan %4 of %5"),
+                                                        file_notebook->get_nth_format_name (status->format),
+                                                        status->format, status->total_formats,
+                                                        status->timespan, status->total_timespans));
+               break;
+       }
+
+       progress_bar.set_fraction (status->progress);
+       return TRUE;
+}
+
+void
+ExportDialog::add_error (Glib::ustring const & text)
+{
+       fast_export_button->set_sensitive (false);
+       rt_export_button->set_sensitive (false);
+       
+       if (warn_string.empty()) {
+               warn_string = _("<span color=\"#ffa755\">Error: ") + text + "</span>";
+       } else {
+               warn_string = _("<span color=\"#ffa755\">Error: ") + text + "</span>\n" + warn_string;
+       }
+       
+       warn_label.set_markup (warn_string);
+}
+
+void
+ExportDialog::add_warning (Glib::ustring const & text)
+{
+       if (warn_string.empty()) {
+               warn_string = _("<span color=\"#ffa755\">Warning: ") + text + "</span>";
+       } else {
+               warn_string = warn_string + _("\n<span color=\"#ffa755\">Warning: ") + text + "</span>";
+       }
+       
+       warn_label.set_markup (warn_string);
+}
+
+/*** Dialog specializations ***/
+
+ExportRangeDialog::ExportRangeDialog (PublicEditor & editor, Glib::ustring range_id) :
+  ExportDialog (editor, _("Export Range")),
+  range_id (range_id)
+{}
+
+void
+ExportRangeDialog::init_components ()
+{
+       preset_selector.reset (new ExportPresetSelector ());
+       timespan_selector.reset (new ExportTimespanSelectorSingle (range_id));
+       channel_selector.reset (new ExportChannelSelector ());
+       file_notebook.reset (new ExportFileNotebook ());
+}
+
+ExportSelectionDialog::ExportSelectionDialog (PublicEditor & editor) :
+  ExportDialog (editor, _("Export Selection"))
+{}
+
+void
+ExportSelectionDialog::init_components ()
+{
+       preset_selector.reset (new ExportPresetSelector ());
+       timespan_selector.reset (new ExportTimespanSelectorSingle (X_("selection")));
+       channel_selector.reset (new ExportChannelSelector ());
+       file_notebook.reset (new ExportFileNotebook ());
+}
diff --git a/gtk2_ardour/export_dialog.h b/gtk2_ardour/export_dialog.h
new file mode 100644 (file)
index 0000000..c0c5a24
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+    Copyright (C) 2008 Paul Davis
+    Author: Sakari Bergen
+
+    This program 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 2 of the License, or
+    (at your option) any later version.
+
+    This program 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, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __export_dialog_h__
+#define __export_dialog_h__
+
+#include <boost/shared_ptr.hpp>
+
+#include <ardour/export_handler.h>
+#include <ardour/export_profile_manager.h>
+
+#include "public_editor.h"
+#include "export_timespan_selector.h"
+#include "export_channel_selector.h"
+#include "export_file_notebook.h"
+#include "export_preset_selector.h"
+#include "ardour_dialog.h"
+
+#include <gtkmm.h>
+
+#include "i18n.h"
+
+namespace ARDOUR {
+       class ExportStatus;
+}
+
+class ExportTimespanSelector;
+class ExportChannelSelector;
+
+class ExportDialog : public ArdourDialog {
+
+  public:
+
+       explicit ExportDialog (PublicEditor & editor, Glib::ustring title = _("Export"));
+       ~ExportDialog ();
+       
+       void set_session (ARDOUR::Session* s);
+       
+       /* Responses */
+
+       enum Responses {
+               RESPONSE_RT,
+               RESPONSE_FAST,
+               RESPONSE_CANCEL
+       };
+
+  protected:
+
+       // initializes GUI layout
+       virtual void init_gui ();
+
+       // Must initialize all the shared_ptrs below
+       virtual void init_components ();
+
+       boost::shared_ptr<ExportPresetSelector>   preset_selector;
+       boost::shared_ptr<ExportTimespanSelector> timespan_selector;
+       boost::shared_ptr<ExportChannelSelector>  channel_selector;
+       boost::shared_ptr<ExportFileNotebook>     file_notebook;
+       
+       Gtk::VBox                                 warning_widget;
+       Gtk::VBox                                 progress_widget;
+
+  private:
+
+       void init ();
+
+       void notify_errors ();
+       void close_dialog ();
+       
+       void sync_with_manager ();
+       void update_warnings ();
+       void show_conflicting_files ();
+
+       void export_rt ();
+       void export_fw ();
+       
+       void show_progress ();
+       gint progress_timeout ();
+       
+       typedef boost::shared_ptr<ARDOUR::ExportHandler> HandlerPtr;
+       typedef boost::shared_ptr<ARDOUR::ExportProfileManager> ManagerPtr;
+       typedef boost::shared_ptr<ARDOUR::ExportStatus> StatusPtr;
+       
+       PublicEditor &  editor;
+       HandlerPtr      handler;
+       ManagerPtr      profile_manager;
+       StatusPtr       status;
+       
+       /*** GUI components ***/
+       
+       /* Warning area */
+       
+       Gtk::HBox           warn_hbox;
+       Gtk::Label          warn_label;
+       Glib::ustring       warn_string;
+       
+       Gtk::HBox           list_files_hbox;
+       Gtk::Label          list_files_label;
+       Gtk::Button         list_files_button;
+       Glib::ustring       list_files_string;
+       
+       void add_error (Glib::ustring const & text);
+       void add_warning (Glib::ustring const & text);
+       
+       /* Progress bar */
+       
+       Gtk::Label              progress_label;
+       Gtk::ProgressBar        progress_bar;
+       sigc::connection        progress_connection;
+       
+       /* Buttons */
+       
+       Gtk::Button *           cancel_button;
+       Gtk::Button *           rt_export_button;
+       Gtk::Button *           fast_export_button;
+
+};
+
+class ExportRangeDialog : public ExportDialog
+{
+  public:
+       ExportRangeDialog (PublicEditor & editor, Glib::ustring range_id);
+
+  private:
+       void init_components ();
+       
+       Glib::ustring range_id;
+};
+
+class ExportSelectionDialog : public ExportDialog
+{
+  public:
+       ExportSelectionDialog (PublicEditor & editor);
+
+  private:
+       void init_components ();
+};
+
+#endif /* __ardour_export_dialog_h__ */
diff --git a/gtk2_ardour/export_file_notebook.cc b/gtk2_ardour/export_file_notebook.cc
new file mode 100644 (file)
index 0000000..001b180
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+    Copyright (C) 2008 Paul Davis
+    Author: Sakari Bergen
+
+    This program 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 2 of the License, or
+    (at your option) any later version.
+
+    This program 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, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "export_file_notebook.h"
+
+#include <ardour/export_format_specification.h>
+
+#include "utils.h"
+#include "i18n.h"
+
+using namespace ARDOUR;
+
+ExportFileNotebook::ExportFileNotebook () :
+  page_counter (1)
+{
+       /* Last page */
+       
+       new_file_button.add (*Gtk::manage (new Gtk::Image (::get_icon("add"))));
+       new_file_button.set_alignment (0, 0.5);
+       new_file_button.set_relief (Gtk::RELIEF_NONE);
+       
+       new_file_hbox.pack_start (new_file_button, true, true);
+       append_page (new_file_dummy, new_file_hbox);
+       set_tab_label_packing (new_file_dummy, true, true, Gtk::PACK_START);
+       new_file_hbox.show_all_children ();
+       
+       page_change_connection = signal_switch_page().connect (sigc::mem_fun (*this, &ExportFileNotebook::handle_page_change));
+       new_file_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportFileNotebook::add_new_file_page));
+}
+
+void
+ExportFileNotebook::set_session_and_manager (ARDOUR::Session * s, boost::shared_ptr<ARDOUR::ExportProfileManager> manager)
+{
+       session = s;
+       profile_manager = manager;
+       
+       sync_with_manager ();
+}
+
+void
+ExportFileNotebook::sync_with_manager ()
+{
+       /* Clear pages from notebook
+          The page switch handling has to be disabled during removing all pages due to a gtk bug
+        */
+
+       page_change_connection.block();
+       while (get_n_pages() > 1) {
+               remove_page (0);
+       }
+       page_change_connection.block(false);
+       
+       page_counter = 1;
+       last_visible_page = 0;
+
+       /* File notebook */
+
+       ExportProfileManager::FormatStateList const & formats = profile_manager->get_formats ();
+       ExportProfileManager::FormatStateList::const_iterator format_it;
+       ExportProfileManager::FilenameStateList const & filenames = profile_manager->get_filenames ();
+       ExportProfileManager::FilenameStateList::const_iterator filename_it;
+       for (format_it = formats.begin(), filename_it = filenames.begin();
+            format_it != formats.end() && filename_it != filenames.end();
+            ++format_it, ++filename_it) {
+               add_file_page (*format_it, *filename_it);
+       }
+       
+       set_current_page (0);
+       CriticalSelectionChanged ();
+}
+
+Glib::ustring
+ExportFileNotebook::get_nth_format_name (uint32_t n)
+{
+       FilePage * page;
+       if ((page = dynamic_cast<FilePage *> (get_nth_page (n - 1)))) {
+               return page->get_format_name();
+       }
+       return "";
+}
+
+void
+ExportFileNotebook::add_new_file_page ()
+{
+       FilePage * page;
+       if ((page = dynamic_cast<FilePage *> (get_nth_page (get_current_page())))) {
+               add_file_page (profile_manager->duplicate_format_state (page->get_format_state()),
+                              profile_manager->duplicate_filename_state (page->get_filename_state()));
+       }
+}
+
+void
+ExportFileNotebook::add_file_page (ARDOUR::ExportProfileManager::FormatStatePtr format_state, ARDOUR::ExportProfileManager::FilenameStatePtr filename_state)
+{
+       FilePage * page = Gtk::manage (new FilePage (session, profile_manager, this, page_counter, format_state, filename_state));
+       page->CriticalSelectionChanged.connect (CriticalSelectionChanged.make_slot());
+       insert_page (*page, page->get_tab_widget(), get_n_pages() - 1);
+
+       update_remove_file_page_sensitivity ();
+       show_all_children();
+       ++page_counter;
+       
+       CriticalSelectionChanged ();
+}
+
+void
+ExportFileNotebook::remove_file_page (FilePage * page)
+{
+       profile_manager->remove_format_state (page->get_format_state());
+       profile_manager->remove_filename_state (page->get_filename_state());
+
+       remove_page (*page);
+       update_remove_file_page_sensitivity ();
+       
+       CriticalSelectionChanged ();
+}
+
+void
+ExportFileNotebook::update_remove_file_page_sensitivity ()
+{
+       FilePage * page;
+       if ((page = dynamic_cast<FilePage *> (get_nth_page (0)))) {
+               if (get_n_pages() > 2) {
+                       page->set_remove_sensitive (true);
+               } else {
+                       page->set_remove_sensitive (false);
+               }
+       }
+}
+
+void
+ExportFileNotebook::handle_page_change (GtkNotebookPage*, uint32_t page)
+{
+       if (page + 1 == (uint32_t) get_n_pages()) {
+               set_current_page (last_visible_page);
+       } else {
+               last_visible_page = page;
+       }
+}
+
+ExportFileNotebook::FilePage::FilePage (Session * s, ManagerPtr profile_manager, ExportFileNotebook * parent, uint32_t number,
+                                        ExportProfileManager::FormatStatePtr format_state,
+                                        ExportProfileManager::FilenameStatePtr filename_state) :
+  format_state (format_state),
+  filename_state (filename_state),
+  profile_manager (profile_manager),
+
+  format_label (_("Format"), Gtk::ALIGN_LEFT),
+  filename_label (_("Location"), Gtk::ALIGN_LEFT),
+  tab_number (number)
+{
+       set_border_width (12);
+
+       pack_start (format_label, false, false, 0);
+       pack_start (format_align, false, false, 0);
+       pack_start (filename_label, false, false, 0);
+       pack_start (filename_align, false, false, 0);
+       
+       format_align.add (format_selector);
+       format_align.set_padding (6, 12, 18, 0);
+       
+       filename_align.add (filename_selector);
+       filename_align.set_padding (0, 12, 18, 0);
+       
+       Pango::AttrList bold;
+       Pango::Attribute b = Pango::Attribute::create_attr_weight (Pango::WEIGHT_BOLD);
+       bold.insert (b);
+       
+       format_label.set_attributes (bold);
+       filename_label.set_attributes (bold);
+       tab_label.set_attributes (bold);
+       
+       /* Set states */
+       format_selector.set_state (format_state, s);
+       filename_selector.set_state (filename_state, s);
+       
+       /* Signals */
+       
+       tab_close_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*parent, &ExportFileNotebook::remove_file_page), this));
+       
+       profile_manager->FormatListChanged.connect (sigc::mem_fun (format_selector, &ExportFormatSelector::update_format_list));
+       
+       format_selector.FormatEdited.connect (sigc::mem_fun (*this, &ExportFileNotebook::FilePage::save_format_to_manager));
+       format_selector.FormatRemoved.connect (sigc::mem_fun (*profile_manager, &ExportProfileManager::remove_format_profile));
+       format_selector.NewFormat.connect (sigc::mem_fun (*profile_manager, &ExportProfileManager::get_new_format));
+       
+       format_selector.CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportFileNotebook::FilePage::update_tab_label));
+       filename_selector.CriticalSelectionChanged.connect (CriticalSelectionChanged.make_slot());
+       
+       /* Tab widget */
+       
+       tab_close_button.add (*Gtk::manage (new Gtk::Image (::get_icon("close"))));
+       tab_close_alignment.add (tab_close_button);
+       tab_close_alignment.set (0.5, 0.5, 0, 0);
+       
+       tab_widget.pack_start (tab_label, false, false, 3);
+       tab_widget.pack_end (tab_close_alignment, false, false, 0);
+       tab_widget.show_all_children ();
+       update_tab_label ();
+       
+       /* Done */
+       
+       show_all_children ();
+}
+
+ExportFileNotebook::FilePage::~FilePage ()
+{
+}
+
+void
+ExportFileNotebook::FilePage::set_remove_sensitive (bool value)
+{
+       tab_close_button.set_sensitive (value);
+}
+
+Glib::ustring
+ExportFileNotebook::FilePage::get_format_name () const
+{
+       if (format_state && format_state->format) {
+               return format_state->format->name();
+       }
+       return "No format!";
+}
+
+void
+ExportFileNotebook::FilePage::save_format_to_manager (FormatPtr format)
+{
+       profile_manager->save_format_to_disk (format);
+}
+
+void
+ExportFileNotebook::FilePage::update_tab_label ()
+{
+       tab_label.set_text (string_compose ("%1 %2", tab_number, get_format_name()));
+       CriticalSelectionChanged();
+}
diff --git a/gtk2_ardour/export_file_notebook.h b/gtk2_ardour/export_file_notebook.h
new file mode 100644 (file)
index 0000000..aed9a0f
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+    Copyright (C) 2008 Paul Davis
+    Author: Sakari Bergen
+
+    This program 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 2 of the License, or
+    (at your option) any later version.
+
+    This program 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, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __export_file_notebook_h__
+#define __export_file_notebook_h__
+
+#include <sigc++/signal.h>
+#include <gtkmm.h>
+
+#include <ardour/export_profile_manager.h>
+
+#include "export_format_selector.h"
+#include "export_filename_selector.h"
+
+namespace ARDOUR {
+       class Session;
+}
+
+
+class ExportFileNotebook : public Gtk::Notebook
+{
+  public:
+       
+       ExportFileNotebook ();
+       
+       void set_session_and_manager (ARDOUR::Session * s, boost::shared_ptr<ARDOUR::ExportProfileManager> manager);
+       void sync_with_manager ();
+       
+       Glib::ustring get_nth_format_name (uint32_t n);
+       
+       sigc::signal<void> CriticalSelectionChanged;
+       
+  private:
+
+       typedef boost::shared_ptr<ARDOUR::ExportProfileManager> ManagerPtr;
+       typedef boost::shared_ptr<ARDOUR::ExportFormatSpecification> FormatPtr;
+       typedef boost::shared_ptr<ARDOUR::ExportFilename> FilenamePtr;
+       class FilePage;
+       
+       ManagerPtr        profile_manager;
+       ARDOUR::Session * session;
+
+       void add_new_file_page ();
+       void add_file_page (ARDOUR::ExportProfileManager::FormatStatePtr format_state, ARDOUR::ExportProfileManager::FilenameStatePtr filename_state);
+       void remove_file_page (FilePage * page);
+       void update_remove_file_page_sensitivity ();
+       
+       sigc::connection page_change_connection;
+       void handle_page_change (GtkNotebookPage*, uint32_t page);
+       
+       Gtk::HBox    new_file_hbox;
+       Gtk::Button  new_file_button;
+       Gtk::VBox    new_file_dummy;
+       
+       uint32_t     last_visible_page;
+       uint32_t     page_counter;
+
+       class FilePage : public Gtk::VBox {
+         public:
+               FilePage (ARDOUR::Session * s, ManagerPtr profile_manager, ExportFileNotebook * parent, uint32_t number, 
+                         ARDOUR::ExportProfileManager::FormatStatePtr format_state,
+                         ARDOUR::ExportProfileManager::FilenameStatePtr filename_state);
+               
+               virtual ~FilePage ();
+               
+               Gtk::Widget & get_tab_widget () { return tab_widget; }
+               void set_remove_sensitive (bool value);
+               Glib::ustring get_format_name () const;
+               
+               ARDOUR::ExportProfileManager::FormatStatePtr   get_format_state () const { return format_state; }
+               ARDOUR::ExportProfileManager::FilenameStatePtr get_filename_state () const { return filename_state; }
+               
+               sigc::signal<void> CriticalSelectionChanged;
+               
+         private:
+               void save_format_to_manager (FormatPtr format);
+               void update_tab_label ();
+               
+               ARDOUR::ExportProfileManager::FormatStatePtr   format_state;
+               ARDOUR::ExportProfileManager::FilenameStatePtr filename_state;
+               ManagerPtr                                     profile_manager;
+       
+               /* GUI components */
+       
+               Gtk::Label              format_label;
+               Gtk::Alignment          format_align;
+               ExportFormatSelector    format_selector;
+       
+               Gtk::Label              filename_label;
+               Gtk::Alignment          filename_align;
+               ExportFilenameSelector  filename_selector;
+       
+               Gtk::HBox               tab_widget;
+               Gtk::Label              tab_label;
+               Gtk::Alignment          tab_close_alignment;
+               Gtk::Button             tab_close_button;
+               uint32_t                tab_number;
+       };
+};
+
+#endif
diff --git a/gtk2_ardour/export_main_dialog.cc b/gtk2_ardour/export_main_dialog.cc
deleted file mode 100644 (file)
index e653a48..0000000
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
-    Copyright (C) 2008 Paul Davis
-    Author: Sakari Bergen
-
-    This program 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 2 of the License, or
-    (at your option) any later version.
-
-    This program 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, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "export_main_dialog.h"
-
-#include <sigc++/signal.h>
-
-#include <pbd/filesystem.h>
-
-#include "utils.h"
-
-#include <ardour/export_handler.h>
-#include <ardour/export_filename.h>
-#include <ardour/export_format_specification.h>
-#include <ardour/export_channel_configuration.h>
-#include <ardour/export_preset.h>
-
-#include "i18n.h"
-
-using namespace ARDOUR;
-using namespace PBD;
-
-ExportMainDialog::ExportMainDialog (PublicEditor & editor) :
-  ArdourDialog (_("Export")),
-  editor (editor),
-
-  preset_label (_("Preset:"), Gtk::ALIGN_LEFT),
-  preset_save_button (Gtk::Stock::SAVE),
-  preset_remove_button (Gtk::Stock::REMOVE),
-  preset_new_button (Gtk::Stock::NEW),
-
-  page_counter (1),
-
-  warn_label ("", Gtk::ALIGN_LEFT),
-  list_files_label (_("<span color=\"#ffa755\">Some already existing files will be overwritten.</span>"), Gtk::ALIGN_RIGHT),
-  list_files_button (_("List files")),
-
-  timespan_label (_("Time Span"), Gtk::ALIGN_LEFT),
-
-  channels_label (_("Channels"), Gtk::ALIGN_LEFT)
-{
-       /* Main packing */
-
-       get_vbox()->pack_start (preset_align, false, false, 0);
-       get_vbox()->pack_start (timespan_label, false, false, 0);
-       get_vbox()->pack_start (timespan_align, false, false, 0);
-       get_vbox()->pack_start (channels_label, false, false, 0);
-       get_vbox()->pack_start (channels_align, false, false, 0);
-       get_vbox()->pack_start (file_notebook, false, false, 0);
-       get_vbox()->pack_start (warn_container, true, true, 0);
-       get_vbox()->pack_start (progress_container, true, true, 0);
-       
-       timespan_align.add (timespan_selector);
-       timespan_align.set_padding (0, 12, 18, 0);
-       
-       channels_align.add (channel_selector);
-       channels_align.set_padding (0, 12, 18, 0);
-       
-       /* Preset manipulation */
-       
-       preset_list = Gtk::ListStore::create (preset_cols);
-       preset_entry.set_model (preset_list);
-       preset_entry.set_text_column (preset_cols.label);
-       
-       preset_align.add (preset_hbox);
-       preset_align.set_padding (0, 12, 0, 0);
-       
-       preset_hbox.pack_start (preset_label, false, false, 0);
-       preset_hbox.pack_start (preset_entry, true, true, 6);
-       preset_hbox.pack_start (preset_save_button, false, false, 0);
-       preset_hbox.pack_start (preset_remove_button, false, false, 6);
-       preset_hbox.pack_start (preset_new_button, false, false, 0);
-       
-       preset_save_button.set_sensitive (false);
-       preset_remove_button.set_sensitive (false);
-       preset_new_button.set_sensitive (false);
-       
-       preset_select_connection = preset_entry.signal_changed().connect (sigc::mem_fun (*this, &ExportMainDialog::select_preset));
-       preset_save_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportMainDialog::save_current_preset));
-       preset_new_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportMainDialog::save_current_preset));
-       preset_remove_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportMainDialog::remove_current_preset));
-       
-       /* warnings */
-       
-       warn_container.pack_start (warn_hbox, true, true, 6);
-       warn_container.pack_end (list_files_hbox, false, false, 0);
-       
-       warn_hbox.pack_start (warn_label, true, true, 16);
-       warn_label.set_use_markup (true);
-       
-       list_files_hbox.pack_end (list_files_button, false, false, 6);
-       list_files_hbox.pack_end (list_files_label, false, false, 6);
-       list_files_label.set_use_markup (true);
-       
-       list_files_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportMainDialog::show_conflicting_files));
-       
-       /* Progress indicators */
-       
-       progress_container.pack_start (progress_label, false, false, 6);
-       progress_container.pack_start (progress_bar, false, false, 6);
-       
-       /* Buttons */
-       
-       cancel_button = add_button (Gtk::Stock::CANCEL, RESPONSE_CANCEL);
-       rt_export_button = add_button (_("Realtime export"), RESPONSE_RT);
-       fast_export_button = add_button (_("Fast Export"), RESPONSE_FAST);
-       
-       cancel_button->signal_clicked().connect (sigc::mem_fun (*this, &ExportMainDialog::close_dialog));
-       rt_export_button->signal_clicked().connect (sigc::mem_fun (*this, &ExportMainDialog::export_rt));
-       fast_export_button->signal_clicked().connect (sigc::mem_fun (*this, &ExportMainDialog::export_fw));
-       
-       /* Bolding for labels */
-       
-       Pango::AttrList bold;
-       Pango::Attribute b = Pango::Attribute::create_attr_weight (Pango::WEIGHT_BOLD);
-       bold.insert (b);
-       
-       timespan_label.set_attributes (bold);
-       channels_label.set_attributes (bold);
-       
-       /* Done! */
-       
-       show_all_children ();
-       progress_container.hide_all();
-}
-
-ExportMainDialog::~ExportMainDialog ()
-{
-}
-
-void
-ExportMainDialog::set_session (ARDOUR::Session* s)
-{
-       session = s;
-       
-       /* Init handler and profile manager */
-       
-       handler = session->get_export_handler ();
-       status = session->get_export_status ();
-       profile_manager.reset (new ExportProfileManager (*session));
-       
-       /* Selection range  */
-       
-       TimeSelection const & time (editor.get_selection().time);
-       if (!time.empty()) {
-               profile_manager->set_selection_range (time.front().start, time.front().end);
-       } else {
-               profile_manager->set_selection_range ();
-       }
-       
-       /* Last notebook page */
-       
-       new_file_button.add (*Gtk::manage (new Gtk::Image (::get_icon("add"))));
-       new_file_button.set_alignment (0, 0.5);
-       new_file_button.set_relief (Gtk::RELIEF_NONE);
-       
-       new_file_hbox.pack_start (new_file_button, true, true);
-       file_notebook.append_page (new_file_dummy, new_file_hbox);
-       file_notebook.set_tab_label_packing (new_file_dummy, true, true, Gtk::PACK_START);
-       new_file_hbox.show_all_children ();
-       
-       page_change_connection = file_notebook.signal_switch_page().connect (sigc::mem_fun (*this, &ExportMainDialog::handle_page_change));
-       new_file_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportMainDialog::add_new_file_page));
-       
-       /* Load states */
-       
-       profile_manager->load_profile ();
-       sync_with_manager ();
-       
-       /* Warnings */
-       
-       timespan_selector.CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportMainDialog::update_warnings));
-       channel_selector.CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportMainDialog::update_warnings));
-       status->Aborting.connect (sigc::mem_fun (*this, &ExportMainDialog::notify_errors));
-       
-       update_warnings ();
-}
-
-void
-ExportMainDialog::select_timespan (Glib::ustring id)
-{
-       set_title ("Export Range");
-       timespan_selector.select_one_range (id);
-}
-
-void
-ExportMainDialog::notify_errors ()
-{
-       if (status->errors()) {
-               Glib::ustring txt = _("Export has been aborted due to an error!\nSee the Log for details.");
-               Gtk::MessageDialog msg (txt, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
-               msg.run();
-       }
-}
-
-void
-ExportMainDialog::close_dialog ()
-{
-       if (status->running) {
-               status->abort();
-       }
-       
-       hide_all ();
-       set_modal (false);
-       
-}
-
-void
-ExportMainDialog::sync_with_manager ()
-{
-       /* Clear pages from notebook
-          The page switch handling has to be disabled during removing all pages due to a gtk bug
-        */
-
-       page_change_connection.block();
-       while (file_notebook.get_n_pages() > 1) {
-               file_notebook.remove_page (0);
-       }
-       page_change_connection.block(false);
-       
-       page_counter = 1;
-       last_visible_page = 0;
-
-       /* Preset list */
-       
-       preset_list->clear();
-       
-       PresetList const & presets = profile_manager->get_presets();
-       Gtk::ListStore::iterator tree_it;
-       
-       for (PresetList::const_iterator it = presets.begin(); it != presets.end(); ++it) {
-               tree_it = preset_list->append();
-               tree_it->set_value (preset_cols.preset, *it);
-               tree_it->set_value (preset_cols.label, Glib::ustring ((*it)->name()));
-               
-               if (*it == current_preset) {
-                       preset_select_connection.block (true);
-                       preset_entry.set_active (tree_it);
-                       preset_select_connection.block (false);
-               }
-       }       
-
-       /* Timespan and channel config */
-
-       timespan_selector.set_state (profile_manager->get_timespans().front(), session);
-       channel_selector.set_state (profile_manager->get_channel_configs().front(), session);
-
-       /* File notebook */
-
-       ExportProfileManager::FormatStateList const & formats = profile_manager->get_formats ();
-       ExportProfileManager::FormatStateList::const_iterator format_it;
-       ExportProfileManager::FilenameStateList const & filenames = profile_manager->get_filenames ();
-       ExportProfileManager::FilenameStateList::const_iterator filename_it;
-       for (format_it = formats.begin(), filename_it = filenames.begin();
-            format_it != formats.end() && filename_it != filenames.end();
-            ++format_it, ++filename_it) {
-               add_file_page (*format_it, *filename_it);
-       }
-       
-       file_notebook.set_current_page (0);
-       update_warnings ();
-}
-
-void
-ExportMainDialog::update_warnings ()
-{
-       /* Reset state */
-
-       warn_string = "";
-       warn_label.set_markup (warn_string);
-
-       list_files_hbox.hide ();
-       list_files_string = "";
-       
-       fast_export_button->set_sensitive (true);
-       rt_export_button->set_sensitive (true);
-
-       /* Add new warnings */
-
-       boost::shared_ptr<ExportProfileManager::Warnings> warnings = profile_manager->get_warnings();
-
-       for (std::list<Glib::ustring>::iterator it = warnings->errors.begin(); it != warnings->errors.end(); ++it) {
-               add_error (*it);
-       }
-
-       for (std::list<Glib::ustring>::iterator it = warnings->warnings.begin(); it != warnings->warnings.end(); ++it) {
-               add_warning (*it);
-       }
-
-       if (!warnings->conflicting_filenames.empty()) {
-               list_files_hbox.show ();
-               for (std::list<Glib::ustring>::iterator it = warnings->conflicting_filenames.begin(); it != warnings->conflicting_filenames.end(); ++it) {
-                       ustring::size_type pos = it->find_last_of ("/");
-                       list_files_string += "\n" + it->substr (0, pos + 1) + "<b>" + it->substr (pos + 1) + "</b>";
-               }
-       }
-}
-
-void
-ExportMainDialog::show_conflicting_files ()
-{
-       ArdourDialog dialog (_("Files that will be overwritten"), true);
-       
-       Gtk::Label label ("", Gtk::ALIGN_LEFT);
-       label.set_use_markup (true);
-       label.set_markup (list_files_string);
-       
-       dialog.get_vbox()->pack_start (label);
-       dialog.add_button (Gtk::Stock::OK, 0);
-       dialog.show_all_children ();
-       
-       dialog.run();
-}
-
-void
-ExportMainDialog::export_rt ()
-{
-       profile_manager->prepare_for_export ();
-       handler->do_export (true);
-       show_progress ();
-}
-
-void
-ExportMainDialog::export_fw ()
-{
-       profile_manager->prepare_for_export ();
-       handler->do_export (false);
-       show_progress ();
-}
-
-void
-ExportMainDialog::show_progress ()
-{
-       status->running = true;
-
-       cancel_button->set_label (_("Stop Export"));
-       rt_export_button->set_sensitive (false);
-       fast_export_button->set_sensitive (false);
-
-       progress_bar.set_fraction (0.0);
-       warn_container.hide_all();
-       progress_container.show ();
-       progress_container.show_all_children ();
-       progress_connection = Glib::signal_timeout().connect (mem_fun(*this, &ExportMainDialog::progress_timeout), 100);
-       
-       gtk_main_iteration ();
-       while (status->running) {
-               if (gtk_events_pending()) {
-                       gtk_main_iteration ();
-               } else {
-                       usleep (10000);
-               }
-       }
-}
-
-Glib::ustring
-ExportMainDialog::get_nth_format_name (uint32_t n)
-{
-       FilePage * page;
-       if ((page = dynamic_cast<FilePage *> (file_notebook.get_nth_page (n - 1)))) {
-               return page->get_format_name();
-       }
-       return "";
-}
-
-gint
-ExportMainDialog::progress_timeout ()
-{
-       switch (status->stage) {
-         case export_None:
-               progress_label.set_text ("");
-               break;
-         case export_ReadTimespan:
-               progress_label.set_text (string_compose (_("Reading timespan %1 of %2"), status->timespan, status->total_timespans));
-               break;
-         case export_PostProcess:
-               progress_label.set_text (string_compose (_("Processing file %2 of %3 (%1) from timespan %4 of %5"),
-                                                        get_nth_format_name (status->format),
-                                                        status->format, status->total_formats,
-                                                        status->timespan, status->total_timespans));
-               break;
-         case export_Write:
-               progress_label.set_text (string_compose (_("Encoding file %2 of %3 (%1) from timespan %4 of %5"),
-                                                        get_nth_format_name (status->format),
-                                                        status->format, status->total_formats,
-                                                        status->timespan, status->total_timespans));
-               break;
-       }
-
-       progress_bar.set_fraction (status->progress);
-       return TRUE;
-}
-
-void
-ExportMainDialog::select_preset ()
-{
-       Gtk::ListStore::iterator it = preset_entry.get_active ();
-       Glib::ustring text = preset_entry.get_entry()->get_text();
-       bool preset_name_exists = false;
-       
-       for (PresetList::const_iterator it = profile_manager->get_presets().begin(); it != profile_manager->get_presets().end(); ++it) {
-               if (!(*it)->name().compare (text)) { preset_name_exists = true; }
-       }
-       
-       if (preset_list->iter_is_valid (it)) {
-       
-               previous_preset = current_preset = it->get_value (preset_cols.preset);
-               if (!profile_manager->load_preset (current_preset)) {
-                       Gtk::MessageDialog dialog (_("The selected preset did not load successfully!\nPerhaps it references a format that has been removed?"),
-                                                  false, Gtk::MESSAGE_WARNING);
-                       dialog.run ();
-               }
-               sync_with_manager ();
-               
-               /* Make an edit, so that signal changed will be emitted on re-selection */
-               
-               preset_select_connection.block (true);
-               preset_entry.get_entry()->set_text ("");
-               preset_entry.get_entry()->set_text (text);
-               preset_select_connection.block (false);
-       
-       } else { // Text has been edited 
-               if (previous_preset && !text.compare (previous_preset->name())) {
-                       
-                       current_preset = previous_preset;
-                       
-               } else {
-                       current_preset.reset ();
-                       profile_manager->load_preset (current_preset);
-               }
-       }
-       
-       preset_save_button.set_sensitive (current_preset);
-       preset_remove_button.set_sensitive (current_preset);
-       preset_new_button.set_sensitive (!current_preset && !text.empty() && !preset_name_exists);
-}
-
-void
-ExportMainDialog::save_current_preset ()
-{
-       if (!profile_manager) { return; }
-       
-       previous_preset = current_preset = profile_manager->save_preset (preset_entry.get_entry()->get_text());
-       sync_with_manager ();
-       select_preset (); // Update preset widget states
-}
-
-void
-ExportMainDialog::remove_current_preset ()
-{
-       if (!profile_manager) { return; }
-       
-       profile_manager->remove_preset();
-       preset_entry.get_entry()->set_text ("");
-       sync_with_manager ();
-}
-
-ExportMainDialog::FilePage::FilePage (Session * s, ManagerPtr profile_manager, ExportMainDialog * parent, uint32_t number,
-                                      ExportProfileManager::FormatStatePtr format_state,
-                                      ExportProfileManager::FilenameStatePtr filename_state) :
-  format_state (format_state),
-  filename_state (filename_state),
-  profile_manager (profile_manager),
-
-  format_label (_("Format"), Gtk::ALIGN_LEFT),
-  filename_label (_("Location"), Gtk::ALIGN_LEFT),
-  tab_number (number)
-{
-       set_border_width (12);
-
-       pack_start (format_label, false, false, 0);
-       pack_start (format_align, false, false, 0);
-       pack_start (filename_label, false, false, 0);
-       pack_start (filename_align, false, false, 0);
-       
-       format_align.add (format_selector);
-       format_align.set_padding (6, 12, 18, 0);
-       
-       filename_align.add (filename_selector);
-       filename_align.set_padding (0, 12, 18, 0);
-       
-       Pango::AttrList bold;
-       Pango::Attribute b = Pango::Attribute::create_attr_weight (Pango::WEIGHT_BOLD);
-       bold.insert (b);
-       
-       format_label.set_attributes (bold);
-       filename_label.set_attributes (bold);
-       tab_label.set_attributes (bold);
-       
-       /* Set states */
-       format_selector.set_state (format_state, s);
-       filename_selector.set_state (filename_state, s);
-       
-       /* Signals */
-       
-       tab_close_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*parent, &ExportMainDialog::remove_file_page), this));
-       
-       profile_manager->FormatListChanged.connect (sigc::mem_fun (format_selector, &ExportFormatSelector::update_format_list));
-       
-       format_selector.FormatEdited.connect (sigc::mem_fun (*this, &ExportMainDialog::FilePage::save_format_to_manager));
-       format_selector.FormatRemoved.connect (sigc::mem_fun (*profile_manager, &ExportProfileManager::remove_format_profile));
-       format_selector.NewFormat.connect (sigc::mem_fun (*profile_manager, &ExportProfileManager::get_new_format));
-       
-       format_selector.CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportMainDialog::FilePage::update_tab_label));
-       filename_selector.CriticalSelectionChanged.connect (CriticalSelectionChanged.make_slot());
-       
-       /* Tab widget */
-       
-       tab_close_button.add (*Gtk::manage (new Gtk::Image (::get_icon("close"))));
-       tab_close_alignment.add (tab_close_button);
-       tab_close_alignment.set (0.5, 0.5, 0, 0);
-       
-       tab_widget.pack_start (tab_label, false, false, 3);
-       tab_widget.pack_end (tab_close_alignment, false, false, 0);
-       tab_widget.show_all_children ();
-       update_tab_label ();
-       
-       /* Done */
-       
-       show_all_children ();
-}
-
-ExportMainDialog::FilePage::~FilePage ()
-{
-}
-
-void
-ExportMainDialog::FilePage::set_remove_sensitive (bool value)
-{
-       tab_close_button.set_sensitive (value);
-}
-
-Glib::ustring
-ExportMainDialog::FilePage::get_format_name () const
-{
-       if (format_state && format_state->format) {
-               return format_state->format->name();
-       }
-       return "No format!";
-}
-
-void
-ExportMainDialog::FilePage::save_format_to_manager (FormatPtr format)
-{
-       profile_manager->save_format_to_disk (format);
-}
-
-void
-ExportMainDialog::FilePage::update_tab_label ()
-{
-       tab_label.set_text (string_compose ("%1 %2", tab_number, get_format_name()));
-       CriticalSelectionChanged();
-}
-
-void
-ExportMainDialog::add_new_file_page ()
-{
-       FilePage * page;
-       if ((page = dynamic_cast<FilePage *> (file_notebook.get_nth_page (file_notebook.get_current_page())))) {
-               add_file_page (profile_manager->duplicate_format_state (page->get_format_state()),
-                              profile_manager->duplicate_filename_state (page->get_filename_state()));
-       }
-}
-
-void
-ExportMainDialog::add_file_page (ExportProfileManager::FormatStatePtr format_state, ExportProfileManager::FilenameStatePtr filename_state)
-{
-       FilePage * page = Gtk::manage (new FilePage (session, profile_manager, this, page_counter, format_state, filename_state));
-       page->CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportMainDialog::update_warnings));
-       file_notebook.insert_page (*page, page->get_tab_widget(), file_notebook.get_n_pages() - 1);
-
-       update_remove_file_page_sensitivity ();
-       file_notebook.show_all_children();
-       ++page_counter;
-       
-       update_warnings ();
-}
-
-void
-ExportMainDialog::remove_file_page (FilePage * page)
-{
-       profile_manager->remove_format_state (page->get_format_state());
-       profile_manager->remove_filename_state (page->get_filename_state());
-
-       file_notebook.remove_page (*page);
-       update_remove_file_page_sensitivity ();
-       
-       update_warnings ();
-}
-
-void
-ExportMainDialog::update_remove_file_page_sensitivity ()
-{
-       FilePage * page;
-       if ((page = dynamic_cast<FilePage *> (file_notebook.get_nth_page (0)))) {
-               if (file_notebook.get_n_pages() > 2) {
-                       page->set_remove_sensitive (true);
-               } else {
-                       page->set_remove_sensitive (false);
-               }
-       }
-}
-
-void
-ExportMainDialog::handle_page_change (GtkNotebookPage*, uint page)
-{
-       if (page + 1 == (uint32_t) file_notebook.get_n_pages()) {
-               file_notebook.set_current_page (last_visible_page);
-       } else {
-               last_visible_page = page;
-       }
-}
-
-void
-ExportMainDialog::add_error (Glib::ustring const & text)
-{
-       fast_export_button->set_sensitive (false);
-       rt_export_button->set_sensitive (false);
-       
-       if (warn_string.empty()) {
-               warn_string = _("<span color=\"#ffa755\">Error: ") + text + "</span>";
-       } else {
-               warn_string = _("<span color=\"#ffa755\">Error: ") + text + "</span>\n" + warn_string;
-       }
-       
-       warn_label.set_markup (warn_string);
-}
-
-void
-ExportMainDialog::add_warning (Glib::ustring const & text)
-{
-       if (warn_string.empty()) {
-               warn_string = _("<span color=\"#ffa755\">Warning: ") + text + "</span>";
-       } else {
-               warn_string = warn_string + _("\n<span color=\"#ffa755\">Warning: ") + text + "</span>";
-       }
-       
-       warn_label.set_markup (warn_string);
-}
diff --git a/gtk2_ardour/export_main_dialog.h b/gtk2_ardour/export_main_dialog.h
deleted file mode 100644 (file)
index e578833..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
-    Copyright (C) 2008 Paul Davis
-    Author: Sakari Bergen
-
-    This program 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 2 of the License, or
-    (at your option) any later version.
-
-    This program 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, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef __export_main_dialog_h__
-#define __export_main_dialog_h__
-
-#include <boost/shared_ptr.hpp>
-
-#include <ardour/export_handler.h>
-#include <ardour/export_profile_manager.h>
-
-#include "public_editor.h"
-#include "export_timespan_selector.h"
-#include "export_channel_selector.h"
-#include "export_format_selector.h"
-#include "export_filename_selector.h"
-#include "ardour_dialog.h"
-
-#include <gtkmm.h>
-
-namespace ARDOUR {
-       class ExportFilename;
-       class ExportFormatSpecification;
-       class ExportChannelConfiguration;
-       class ExportStatus;
-}
-
-class ExportTimespanSelector;
-class ExportChannelSelector;
-class ExportFormatSelector;
-class ExportFilenameSelector;
-
-class ExportMainDialog : public ArdourDialog {
-
-  public:
-
-       explicit ExportMainDialog (PublicEditor & editor);
-       ~ExportMainDialog ();
-       
-       void set_session (ARDOUR::Session* s);
-       
-       void select_timespan (Glib::ustring id);
-       
-       /* Responses */
-
-       enum Responses {
-               RESPONSE_RT,
-               RESPONSE_FAST,
-               RESPONSE_CANCEL
-       };
-
-  private:
-
-       void notify_errors ();
-       void close_dialog ();
-       
-       void sync_with_manager ();
-       void update_warnings ();
-       void show_conflicting_files ();
-       
-       typedef boost::shared_ptr<ARDOUR::ExportTimespan> TimespanPtr;
-       typedef boost::shared_ptr<std::list<TimespanPtr> > TimespanList;
-       
-       typedef boost::shared_ptr<ARDOUR::ExportChannelConfiguration> ChannelConfigPtr;
-       typedef std::list<ChannelConfigPtr> ChannelConfigList;
-       
-       typedef boost::shared_ptr<ARDOUR::ExportFilename> FilenamePtr;
-       
-       typedef boost::shared_ptr<ARDOUR::ExportHandler> HandlerPtr;
-       typedef boost::shared_ptr<ARDOUR::ExportFormatSpecification> FormatPtr;
-       typedef boost::shared_ptr<ARDOUR::ExportProfileManager> ManagerPtr;
-       typedef boost::shared_ptr<ARDOUR::ExportStatus> StatusPtr;
-
-       void export_rt ();
-       void export_fw ();
-       
-       void show_progress ();
-       Glib::ustring get_nth_format_name (uint32_t n);
-       gint progress_timeout ();
-       
-       /* Other stuff */
-       
-       PublicEditor &  editor;
-       HandlerPtr      handler;
-       ManagerPtr      profile_manager;
-       StatusPtr       status;
-       
-       /*** GUI components ***/
-       
-       Gtk::Table          main_table;
-       
-       /* Presets */
-       
-       typedef ARDOUR::ExportProfileManager::PresetPtr PresetPtr;
-       typedef ARDOUR::ExportProfileManager::PresetList PresetList;
-       
-       sigc::connection preset_select_connection;
-       
-       void select_preset ();
-       void save_current_preset ();
-       void remove_current_preset ();
-       
-       struct PresetCols : public Gtk::TreeModelColumnRecord
-       {
-         public:
-               Gtk::TreeModelColumn<PresetPtr>      preset;
-               Gtk::TreeModelColumn<Glib::ustring>  label;
-       
-               PresetCols () { add (preset); add (label); }
-       };
-       PresetCols                   preset_cols;
-       Glib::RefPtr<Gtk::ListStore> preset_list;
-       PresetPtr                    current_preset;
-       PresetPtr                    previous_preset;
-       
-       Gtk::Alignment      preset_align;
-       Gtk::HBox           preset_hbox;
-       Gtk::Label          preset_label;
-       Gtk::ComboBoxEntry  preset_entry;
-       
-       Gtk::Button         preset_save_button;
-       Gtk::Button         preset_remove_button;
-       Gtk::Button         preset_new_button;
-       
-       /* File Notebook */
-       
-       class FilePage : public Gtk::VBox {
-         public:
-               FilePage (ARDOUR::Session * s, ManagerPtr profile_manager, ExportMainDialog * parent, uint32_t number, 
-                         ARDOUR::ExportProfileManager::FormatStatePtr format_state,
-                         ARDOUR::ExportProfileManager::FilenameStatePtr filename_state);
-               
-               virtual ~FilePage ();
-               
-               Gtk::Widget & get_tab_widget () { return tab_widget; }
-               void set_remove_sensitive (bool value);
-               Glib::ustring get_format_name () const;
-               
-               ARDOUR::ExportProfileManager::FormatStatePtr   get_format_state () const { return format_state; }
-               ARDOUR::ExportProfileManager::FilenameStatePtr get_filename_state () const { return filename_state; }
-               
-               sigc::signal<void> CriticalSelectionChanged;
-               
-         private:
-               void save_format_to_manager (FormatPtr format);
-               void update_tab_label ();
-               
-               ARDOUR::ExportProfileManager::FormatStatePtr   format_state;
-               ARDOUR::ExportProfileManager::FilenameStatePtr filename_state;
-               ManagerPtr                                     profile_manager;
-       
-               /* GUI components */
-       
-               Gtk::Label              format_label;
-               Gtk::Alignment          format_align;
-               ExportFormatSelector    format_selector;
-       
-               Gtk::Label              filename_label;
-               Gtk::Alignment          filename_align;
-               ExportFilenameSelector  filename_selector;
-       
-               Gtk::HBox               tab_widget;
-               Gtk::Label              tab_label;
-               Gtk::Alignment          tab_close_alignment;
-               Gtk::Button             tab_close_button;
-               uint32_t                tab_number;
-       };
-       
-       void add_new_file_page ();
-       void add_file_page (ARDOUR::ExportProfileManager::FormatStatePtr format_state, ARDOUR::ExportProfileManager::FilenameStatePtr filename_state);
-       void remove_file_page (FilePage * page);
-       void update_remove_file_page_sensitivity ();
-       
-       sigc::connection page_change_connection;
-       void handle_page_change (GtkNotebookPage*, uint32_t page);
-       
-       uint32_t last_visible_page;
-       uint32_t page_counter;
-       
-       /* Warning area */
-       
-       Gtk::VBox           warn_container;
-       
-       Gtk::HBox           warn_hbox;
-       Gtk::Label          warn_label;
-       Glib::ustring       warn_string;
-       
-       Gtk::HBox           list_files_hbox;
-       Gtk::Label          list_files_label;
-       Gtk::Button         list_files_button;
-       Glib::ustring       list_files_string;
-       
-       void add_error (Glib::ustring const & text);
-       void add_warning (Glib::ustring const & text);
-       
-       /* Progress bar */
-       
-       Gtk::VBox               progress_container;
-       Gtk::Label              progress_label;
-       Gtk::ProgressBar        progress_bar;
-       sigc::connection        progress_connection;
-       
-       /* Everything else */
-
-       Gtk::Label              timespan_label;
-       Gtk::Alignment          timespan_align;
-       ExportTimespanSelector  timespan_selector;
-       
-       Gtk::Label              channels_label;
-       Gtk::Alignment          channels_align;
-       ExportChannelSelector   channel_selector;
-       
-       Gtk::Notebook           file_notebook;
-       
-       Gtk::HBox               new_file_hbox;
-       Gtk::Button             new_file_button;
-       Gtk::VBox               new_file_dummy;
-       
-       Gtk::Button *           cancel_button;
-       Gtk::Button *           rt_export_button;
-       Gtk::Button *           fast_export_button;
-
-};
-
-#endif /* __ardour_export_main_dialog_h__ */
diff --git a/gtk2_ardour/export_preset_selector.cc b/gtk2_ardour/export_preset_selector.cc
new file mode 100644 (file)
index 0000000..bfbb6a8
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+    Copyright (C) 2008 Paul Davis
+    Author: Sakari Bergen
+
+    This program 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 2 of the License, or
+    (at your option) any later version.
+
+    This program 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, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "export_preset_selector.h"
+
+#include <ardour/export_preset.h>
+
+#include "i18n.h"
+
+ExportPresetSelector::ExportPresetSelector () :
+  label (_("Preset"), Gtk::ALIGN_LEFT),
+  save_button (Gtk::Stock::SAVE),
+  remove_button (Gtk::Stock::REMOVE),
+  new_button (Gtk::Stock::NEW)
+{
+       list = Gtk::ListStore::create (cols);
+       entry.set_model (list);
+       entry.set_text_column (cols.label);
+       
+       pack_start (label, false, false, 0);
+       pack_start (entry, true, true, 6);
+       pack_start (save_button, false, false, 0);
+       pack_start (remove_button, false, false, 6);
+       pack_start (new_button, false, false, 0);
+       
+       save_button.set_sensitive (false);
+       remove_button.set_sensitive (false);
+       new_button.set_sensitive (false);
+       
+       select_connection = entry.signal_changed().connect (sigc::mem_fun (*this, &ExportPresetSelector::update_selection));
+       save_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportPresetSelector::save_current));
+       new_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportPresetSelector::save_current));
+       remove_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportPresetSelector::remove_current));
+       
+       show_all_children ();
+}
+
+void
+ExportPresetSelector::set_manager (boost::shared_ptr<ARDOUR::ExportProfileManager> manager)
+{
+       profile_manager = manager;
+       sync_with_manager ();
+}
+
+void
+ExportPresetSelector::sync_with_manager ()
+{
+       list->clear();
+       
+       PresetList const & presets = profile_manager->get_presets();
+       Gtk::ListStore::iterator tree_it;
+       
+       for (PresetList::const_iterator it = presets.begin(); it != presets.end(); ++it) {
+               tree_it = list->append();
+               tree_it->set_value (cols.preset, *it);
+               tree_it->set_value (cols.label, Glib::ustring ((*it)->name()));
+               
+               if (*it == current) {
+                       select_connection.block (true);
+                       entry.set_active (tree_it);
+                       select_connection.block (false);
+               }
+       }
+}
+
+void
+ExportPresetSelector::update_selection ()
+{
+       Gtk::ListStore::iterator it = entry.get_active ();
+       Glib::ustring text = entry.get_entry()->get_text();
+       bool preset_name_exists = false;
+       
+       for (PresetList::const_iterator it = profile_manager->get_presets().begin(); it != profile_manager->get_presets().end(); ++it) {
+               if (!(*it)->name().compare (text)) { preset_name_exists = true; }
+       }
+       
+       if (list->iter_is_valid (it)) {
+       
+               previous = current = it->get_value (cols.preset);
+               if (!profile_manager->load_preset (current)) {
+                       Gtk::MessageDialog dialog (_("The selected preset did not load successfully!\nPerhaps it references a format that has been removed?"),
+                                                  false, Gtk::MESSAGE_WARNING);
+                       dialog.run ();
+               }
+               sync_with_manager ();
+               CriticalSelectionChanged();
+               
+               /* Make an edit, so that signal changed will be emitted on re-selection */
+               
+               select_connection.block (true);
+               entry.get_entry()->set_text ("");
+               entry.get_entry()->set_text (text);
+               select_connection.block (false);
+       
+       } else { // Text has been edited 
+               if (previous && !text.compare (previous->name())) {
+                       
+                       current = previous;
+                       
+               } else {
+                       current.reset ();
+                       profile_manager->load_preset (current);
+                       CriticalSelectionChanged();
+               }
+       }
+       
+       save_button.set_sensitive (current);
+       remove_button.set_sensitive (current);
+       new_button.set_sensitive (!current && !text.empty() && !preset_name_exists);
+}
+
+void
+ExportPresetSelector::save_current ()
+{
+       if (!profile_manager) { return; }
+       
+       previous = current = profile_manager->save_preset (entry.get_entry()->get_text());
+       sync_with_manager ();
+       update_selection (); // Update preset widget states
+}
+
+void
+ExportPresetSelector::remove_current ()
+{
+       if (!profile_manager) { return; }
+       
+       profile_manager->remove_preset();
+       entry.get_entry()->set_text ("");
+       sync_with_manager ();
+}
diff --git a/gtk2_ardour/export_preset_selector.h b/gtk2_ardour/export_preset_selector.h
new file mode 100644 (file)
index 0000000..3022e22
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+    Copyright (C) 2008 Paul Davis
+    Author: Sakari Bergen
+
+    This program 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 2 of the License, or
+    (at your option) any later version.
+
+    This program 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, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __export_preset_selector_h__
+#define __export_preset_selector_h__
+
+#include <sigc++/signal.h>
+#include <gtkmm.h>
+
+#include <ardour/export_profile_manager.h>
+
+class ExportPresetSelector : public Gtk::HBox
+{
+
+  public:
+       
+       ExportPresetSelector ();
+       
+       void set_manager (boost::shared_ptr<ARDOUR::ExportProfileManager> manager);
+       
+       sigc::signal<void> CriticalSelectionChanged;
+
+  private:
+
+       typedef boost::shared_ptr<ARDOUR::ExportProfileManager> ManagerPtr;
+       typedef ARDOUR::ExportProfileManager::PresetPtr PresetPtr;
+       typedef ARDOUR::ExportProfileManager::PresetList PresetList;
+       
+       ManagerPtr       profile_manager;
+       sigc::connection select_connection;
+       
+       void sync_with_manager ();
+       void update_selection ();
+       void save_current ();
+       void remove_current ();
+       
+       struct PresetCols : public Gtk::TreeModelColumnRecord
+       {
+         public:
+               Gtk::TreeModelColumn<PresetPtr>      preset;
+               Gtk::TreeModelColumn<Glib::ustring>  label;
+       
+               PresetCols () { add (preset); add (label); }
+       };
+       PresetCols                   cols;
+       Glib::RefPtr<Gtk::ListStore> list;
+       PresetPtr                    current;
+       PresetPtr                    previous;
+       
+       Gtk::Label          label;
+       Gtk::ComboBoxEntry  entry;
+       
+       Gtk::Button         save_button;
+       Gtk::Button         remove_button;
+       Gtk::Button         new_button;
+};
+
+#endif
index 0f02a1580ec05d782f1f11468b2a4ad71a15a7d6..5f9ccfb0c608b14d7237aa68292685ff2d51cf4a 100644 (file)
@@ -47,7 +47,6 @@ ExportTimespanSelector::ExportTimespanSelector () :
        option_hbox.pack_start (time_format_combo, false, false, 6);
        
        range_scroller.add (range_view);
-       range_scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
        
        pack_start (option_hbox, false, false, 0);
        pack_start (range_scroller, true, true, 6);
@@ -87,22 +86,6 @@ ExportTimespanSelector::ExportTimespanSelector () :
        range_list = Gtk::ListStore::create (range_cols);
        range_view.set_model (range_list);
        range_view.set_headers_visible (false);
-       
-       range_view.append_column_editable ("", range_cols.selected);
-       range_view.append_column_editable ("", range_cols.name);
-       
-       Gtk::CellRendererText * label_render = Gtk::manage (new Gtk::CellRendererText());
-       Gtk::TreeView::Column * label_col = Gtk::manage (new Gtk::TreeView::Column ("", *label_render));
-       label_col->add_attribute (label_render->property_markup(), range_cols.label);
-       range_view.append_column (*label_col);
-
-       if (Gtk::CellRendererToggle * renderer = dynamic_cast<Gtk::CellRendererToggle *> (range_view.get_column_cell_renderer (0))) {
-               renderer->signal_toggled().connect (sigc::hide (sigc::mem_fun (*this, &ExportTimespanSelector::update_selection)));
-       }
-       if (Gtk::CellRendererText * renderer = dynamic_cast<Gtk::CellRendererText *> (range_view.get_column_cell_renderer (1))) {
-               renderer->signal_edited().connect (sigc::mem_fun (*this, &ExportTimespanSelector::update_range_name));
-       }
-       
 }
 
 ExportTimespanSelector::~ExportTimespanSelector ()
@@ -111,89 +94,29 @@ ExportTimespanSelector::~ExportTimespanSelector ()
 }
 
 void
-ExportTimespanSelector::set_state (ARDOUR::ExportProfileManager::TimespanStatePtr const state_, ARDOUR::Session * session_)
-{
-       state = state_;
-       session = session_;
-
-       fill_range_list ();
-       set_selection_from_state ();
-       
-       CriticalSelectionChanged();
-}
-
-void
-ExportTimespanSelector::select_one_range (Glib::ustring id)
+ExportTimespanSelector::add_range_to_selection (ARDOUR::Location const * loc)
 {
-       if (!state) { return; }
-       
-       range_view.remove_column (*range_view.get_column (0));
-       
-       Glib::ustring real_id;
+       TimespanPtr span = session->get_export_handler()->add_timespan();
        
-       if (!id.compare (X_("session"))) {
-               real_id = state->session_range->id().to_s();
-       } else if (!id.compare (X_("selection"))) {
-               real_id = state->selection_range->id().to_s();
+       Glib::ustring id;
+       if (loc == state->session_range.get()) {
+               id = "session";
+       } else if (loc == state->selection_range.get()) {
+               id = "selection";
        } else {
-               real_id = id;
-       }
-       
-       for (Gtk::ListStore::Children::iterator it = range_list->children().begin(); it != range_list->children().end();) {
-               if (!it->get_value (range_cols.location)->id().to_s().compare (real_id)) {
-                       it->set_value (range_cols.selected, true);
-                       ++it;
-               } else {
-                       Gtk::ListStore::Children::iterator temp = it++;
-                       range_list->erase (temp);
-               }
+               id = loc->id().to_s();
        }
        
-       int x_offset, y_offset, width, height;
-       Gtk::CellRenderer * renderer = *range_view.get_column(0)->get_cell_renderers().begin();
-       renderer->get_size (range_view, x_offset, y_offset, width, height);
-       range_scroller.set_size_request (-1, height);
-       range_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_NEVER);
-       
-       update_selection();
+       span->set_range (loc->start(), loc->end());
+       span->set_name (loc->name());
+       span->set_range_id (id);
+       state->timespans->push_back (span);
 }
 
 void
-ExportTimespanSelector::fill_range_list ()
-{
-       range_list->clear();
-
-       Gtk::TreeModel::iterator iter;
-       Gtk::TreeModel::Row row;
-       for (LocationList::const_iterator it = state->ranges->begin(); it != state->ranges->end(); ++it) {
-               iter = range_list->append();
-               row = *iter;
-               
-               row[range_cols.location] = *it;
-               row[range_cols.selected] = false;
-               row[range_cols.name] = (*it)->name();
-               row[range_cols.label] = construct_label (*it);
-       }
-}
-
-void
-ExportTimespanSelector::set_selection_from_state ()
+ExportTimespanSelector::set_time_format_from_state ()
 {
        Gtk::TreeModel::Children::iterator tree_it;
-       
-       for (TimespanList::iterator it = state->timespans->begin(); it != state->timespans->end(); ++it) {
-               ustring id = (*it)->range_id();
-               for (tree_it = range_list->children().begin(); tree_it != range_list->children().end(); ++tree_it) {
-                       Location * loc = tree_it->get_value (range_cols.location);
-                       
-                       if ((!id.compare ("session") && loc == state->session_range.get()) ||
-                           (!id.compare ("selection") && loc == state->selection_range.get()) ||
-                           (!id.compare (loc->id().to_s()))) {
-                               tree_it->set_value (range_cols.selected, true);
-                       }
-               }
-       }
-       
        for (tree_it = time_format_list->children().begin(); tree_it != time_format_list->children().end(); ++tree_it) {
                if (tree_it->get_value (time_format_cols.format) == state->time_format) {
                        time_format_combo.set_active (tree_it);
@@ -202,40 +125,14 @@ ExportTimespanSelector::set_selection_from_state ()
 }
 
 void
-ExportTimespanSelector::update_selection ()
+ExportTimespanSelector::set_state (ARDOUR::ExportProfileManager::TimespanStatePtr const state_, ARDOUR::Session * session_)
 {
-       update_timespans ();
-       CriticalSelectionChanged ();
-}
+       state = state_;
+       session = session_;
 
-void
-ExportTimespanSelector::update_timespans ()
-{
-       state->timespans->clear();
-       
-       TimespanPtr span;
-       HandlerPtr handler = session->get_export_handler();
+       fill_range_list ();
        
-       for (Gtk::TreeStore::Children::iterator it = range_list->children().begin(); it != range_list->children().end(); ++it) {
-               if (it->get_value (range_cols.selected)) {
-                       span = handler->add_timespan();
-                       Location * loc = it->get_value (range_cols.location);
-                       
-                       Glib::ustring id;
-                       if (loc == state->session_range.get()) {
-                               id = "session";
-                       } else if (loc == state->selection_range.get()) {
-                               id = "selection";
-                       } else {
-                               id = loc->id().to_s();
-                       }
-                       
-                       span->set_range (loc->start(), loc->end());
-                       span->set_name (loc->name());
-                       span->set_range_id (id);
-                       state->timespans->push_back (span);
-               }
-       }
+       CriticalSelectionChanged();
 }
 
 void
@@ -250,7 +147,7 @@ ExportTimespanSelector::change_time_format ()
 }
 
 Glib::ustring
-ExportTimespanSelector::construct_label (ARDOUR::Location const * location)
+ExportTimespanSelector::construct_label (ARDOUR::Location const * location) const
 {
        Glib::ustring label;
        Glib::ustring start;
@@ -301,7 +198,7 @@ ExportTimespanSelector::construct_label (ARDOUR::Location const * location)
 
 
 Glib::ustring
-ExportTimespanSelector::bbt_str (nframes_t frames)
+ExportTimespanSelector::bbt_str (nframes_t frames) const
 {
        if (!session) {
                return "Error!";
@@ -324,7 +221,7 @@ ExportTimespanSelector::bbt_str (nframes_t frames)
 }
 
 Glib::ustring
-ExportTimespanSelector::smpte_str (nframes_t frames)
+ExportTimespanSelector::smpte_str (nframes_t frames) const
 {
        if (!session) {
                return "Error!";
@@ -349,7 +246,7 @@ ExportTimespanSelector::smpte_str (nframes_t frames)
 }
 
 Glib::ustring
-ExportTimespanSelector::ms_str (nframes_t frames)
+ExportTimespanSelector::ms_str (nframes_t frames) const
 {
        if (!session) {
                return "Error!";
@@ -392,3 +289,155 @@ ExportTimespanSelector::update_range_name (Glib::ustring const & path, Glib::ust
        
        CriticalSelectionChanged();
 }
+
+/*** ExportTimespanSelectorSingle ***/
+
+ExportTimespanSelectorSingle::ExportTimespanSelectorSingle (Glib::ustring range_id) :
+  ExportTimespanSelector (),
+  range_id (range_id)
+{
+       range_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_NEVER);
+       range_view.append_column_editable ("", range_cols.name);
+       
+       // Adjust selector height
+       int x_offset, y_offset, width, height;
+       Gtk::CellRenderer * renderer = *range_view.get_column(0)->get_cell_renderers().begin();
+       renderer->get_size (range_view, x_offset, y_offset, width, height);
+       range_scroller.set_size_request (-1, height);
+       
+       if (Gtk::CellRendererText * renderer = dynamic_cast<Gtk::CellRendererText *> (range_view.get_column_cell_renderer (0))) {
+               renderer->signal_edited().connect (sigc::mem_fun (*this, &ExportTimespanSelectorSingle::update_range_name));
+       }
+       
+       Gtk::CellRendererText * label_render = Gtk::manage (new Gtk::CellRendererText());
+       Gtk::TreeView::Column * label_col = Gtk::manage (new Gtk::TreeView::Column ("", *label_render));
+       label_col->add_attribute (label_render->property_markup(), range_cols.label);
+       range_view.append_column (*label_col);
+
+}
+
+void
+ExportTimespanSelectorSingle::fill_range_list ()
+{
+       if (!state) { return; }
+       
+       Glib::ustring id;
+       if (!range_id.compare (X_("session"))) {
+               id = state->session_range->id().to_s();
+       } else if (!range_id.compare (X_("selection"))) {
+               id = state->selection_range->id().to_s();
+       } else {
+               id = range_id;
+       }
+
+       range_list->clear();
+       state->timespans->clear();
+
+       Gtk::TreeModel::iterator iter;
+       Gtk::TreeModel::Row row;
+       for (LocationList::const_iterator it = state->ranges->begin(); it != state->ranges->end(); ++it) {
+       
+               if (!(*it)->id().to_s().compare (id)) {
+                       iter = range_list->append();
+                       row = *iter;
+                       
+                       row[range_cols.location] = *it;
+                       row[range_cols.selected] = true;
+                       row[range_cols.name] = (*it)->name();
+                       row[range_cols.label] = construct_label (*it);
+                       
+                       add_range_to_selection (*it);
+                       
+                       break;
+               }
+       }
+       
+       set_time_format_from_state();
+}
+
+/*** ExportTimespanSelectorMultiple ***/
+
+ExportTimespanSelectorMultiple::ExportTimespanSelectorMultiple () :
+  ExportTimespanSelector ()
+{
+       range_scroller.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       range_view.append_column_editable ("", range_cols.selected);
+       range_view.append_column_editable ("", range_cols.name);
+       
+       if (Gtk::CellRendererToggle * renderer = dynamic_cast<Gtk::CellRendererToggle *> (range_view.get_column_cell_renderer (0))) {
+               renderer->signal_toggled().connect (sigc::hide (sigc::mem_fun (*this, &ExportTimespanSelectorMultiple::update_selection)));
+       }
+       if (Gtk::CellRendererText * renderer = dynamic_cast<Gtk::CellRendererText *> (range_view.get_column_cell_renderer (1))) {
+               renderer->signal_edited().connect (sigc::mem_fun (*this, &ExportTimespanSelectorMultiple::update_range_name));
+       }
+       
+       Gtk::CellRendererText * label_render = Gtk::manage (new Gtk::CellRendererText());
+       Gtk::TreeView::Column * label_col = Gtk::manage (new Gtk::TreeView::Column ("", *label_render));
+       label_col->add_attribute (label_render->property_markup(), range_cols.label);
+       range_view.append_column (*label_col);
+
+}
+
+void
+ExportTimespanSelectorMultiple::fill_range_list ()
+{
+       if (!state) { return; }
+
+       range_list->clear();
+
+       Gtk::TreeModel::iterator iter;
+       Gtk::TreeModel::Row row;
+       for (LocationList::const_iterator it = state->ranges->begin(); it != state->ranges->end(); ++it) {
+       
+               iter = range_list->append();
+               row = *iter;
+               
+               row[range_cols.location] = *it;
+               row[range_cols.selected] = false;
+               row[range_cols.name] = (*it)->name();
+               row[range_cols.label] = construct_label (*it);
+       }
+       
+       set_selection_from_state ();
+}
+
+void
+ExportTimespanSelectorMultiple::set_selection_from_state ()
+{
+       Gtk::TreeModel::Children::iterator tree_it;
+       
+       for (TimespanList::iterator it = state->timespans->begin(); it != state->timespans->end(); ++it) {
+               ustring id = (*it)->range_id();
+               for (tree_it = range_list->children().begin(); tree_it != range_list->children().end(); ++tree_it) {
+                       Location * loc = tree_it->get_value (range_cols.location);
+                       
+                       if ((!id.compare ("session") && loc == state->session_range.get()) ||
+                           (!id.compare ("selection") && loc == state->selection_range.get()) ||
+                           (!id.compare (loc->id().to_s()))) {
+                               tree_it->set_value (range_cols.selected, true);
+                       }
+               }
+       }
+       
+       set_time_format_from_state();
+}
+
+void
+ExportTimespanSelectorMultiple::update_selection ()
+{
+       update_timespans ();
+       CriticalSelectionChanged ();
+}
+
+void
+ExportTimespanSelectorMultiple::update_timespans ()
+{
+       state->timespans->clear();
+       
+       for (Gtk::TreeStore::Children::iterator it = range_list->children().begin(); it != range_list->children().end(); ++it) {
+               if (it->get_value (range_cols.selected)) {
+                       add_range_to_selection (it->get_value (range_cols.location));
+               }
+       }
+}
+
index 757b2caad222f9797cb860091791873f8815c792..e8a97326bc737e360f41fd6b49765746b5034386 100644 (file)
@@ -41,52 +41,43 @@ namespace ARDOUR {
 
 using ARDOUR::CDMarkerFormat;
 
-/// 
+/// Timespan Selector base
 class ExportTimespanSelector : public Gtk::VBox {
-  private:
-
-       typedef std::list<ARDOUR::Location *> LocationList;
-       typedef boost::shared_ptr<ARDOUR::ExportHandler> HandlerPtr;
-
-       typedef boost::shared_ptr<ARDOUR::ExportTimespan> TimespanPtr;
-       typedef std::list<TimespanPtr> TimespanList;
-       typedef boost::shared_ptr<TimespanList> TimespanListPtr;
-
   public:
 
        ExportTimespanSelector ();
-       ~ExportTimespanSelector ();
+       virtual ~ExportTimespanSelector ();
 
        void set_state (ARDOUR::ExportProfileManager::TimespanStatePtr const state_, ARDOUR::Session * session_);
        
-       void select_one_range (Glib::ustring id);
-       
-       /* Compatibility with other elements */
-       
        sigc::signal<void> CriticalSelectionChanged;
 
-  private:
+  protected:
 
-       void fill_range_list ();
-       void set_selection_from_state ();
+       typedef std::list<ARDOUR::Location *> LocationList;
+       typedef boost::shared_ptr<ARDOUR::ExportHandler> HandlerPtr;
 
-       void update_selection ();
-       void update_timespans ();
+       typedef boost::shared_ptr<ARDOUR::ExportTimespan> TimespanPtr;
+       typedef std::list<TimespanPtr> TimespanList;
+       typedef boost::shared_ptr<TimespanList> TimespanListPtr;
+
+       ARDOUR::Session *                              session;
+       ARDOUR::ExportProfileManager::TimespanStatePtr state;
+
+       virtual void fill_range_list () = 0;
        
-       void change_time_format ();
+       void add_range_to_selection (ARDOUR::Location const * loc);
+       void set_time_format_from_state ();
        
-       Glib::ustring construct_label (ARDOUR::Location const * location);
+       void change_time_format ();
        
-       Glib::ustring bbt_str (nframes_t frames);
-       Glib::ustring smpte_str (nframes_t frames);
-       Glib::ustring ms_str (nframes_t frames);
+       Glib::ustring construct_label (ARDOUR::Location const * location) const;
+       Glib::ustring bbt_str (nframes_t frames) const;
+       Glib::ustring smpte_str (nframes_t frames) const;
+       Glib::ustring ms_str (nframes_t frames) const;
 
        void update_range_name (Glib::ustring const & path, Glib::ustring const & new_text);
 
-       ARDOUR::Session * session;
-       
-       ARDOUR::ExportProfileManager::TimespanStatePtr state;
-
        /*** GUI components ***/
        
        Gtk::HBox      option_hbox;
@@ -126,6 +117,34 @@ class ExportTimespanSelector : public Gtk::VBox {
        Gtk::TreeView                range_view;
        
        Gtk::ScrolledWindow          range_scroller;
+};
+
+/// Allows seleting multiple timespans
+class ExportTimespanSelectorMultiple : public ExportTimespanSelector
+{
+  public:
+       ExportTimespanSelectorMultiple ();
+
+  private:
+
+       virtual void fill_range_list ();
+
+       void set_selection_from_state ();
+       void update_selection ();
+       void update_timespans ();
+};
+
+/// Displays one timespan
+class ExportTimespanSelectorSingle : public ExportTimespanSelector
+{
+  public:
+       ExportTimespanSelectorSingle (Glib::ustring range_id);
+
+  private:
+
+       virtual void fill_range_list ();
+       
+       Glib::ustring range_id;
 
 };
 
index ae0ec5acd887cba7e9aab7e050a0ce284c3e4783..692d6d11c2b65c242e76c6efa9e13a3e31ab8bdd 100644 (file)
@@ -90,7 +90,7 @@ class Location : public PBD::StatefulDestructible
 
        int move_to (nframes_t pos);
 
-       const string& name() { return _name; }
+       const string& name() const { return _name; }
        void set_name (const string &str) { _name = str; name_changed(this); }
 
        void set_auto_punch (bool yn, void *src);