From: Sakari Bergen Date: Mon, 29 Sep 2008 17:01:52 +0000 (+0000) Subject: * Fixed const correctness error in Location X-Git-Tag: 3.0-alpha5~4078 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=ef9beb3f60b5499d4db48b771627b6facfe872d3;p=ardour.git * Fixed const correctness error in Location * 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 --- diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 0388910ebd..818b0fa15c 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -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 diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc index ac68f6d907..b382200d38 100644 --- a/gtk2_ardour/editor_export_audio.cc +++ b/gtk2_ardour/editor_export_audio.cc @@ -24,7 +24,7 @@ #include -#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 index 0000000000..7ae81a016a --- /dev/null +++ b/gtk2_ardour/export_dialog.cc @@ -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 + +#include + +#include +#include + +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 (_("Some already existing files will be overwritten."), 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 warnings = profile_manager->get_warnings(); + + for (std::list::iterator it = warnings->errors.begin(); it != warnings->errors.end(); ++it) { + add_error (*it); + } + + for (std::list::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::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) + "" + it->substr (pos + 1) + ""; + } + } +} + +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 = _("Error: ") + text + ""; + } else { + warn_string = _("Error: ") + text + "\n" + warn_string; + } + + warn_label.set_markup (warn_string); +} + +void +ExportDialog::add_warning (Glib::ustring const & text) +{ + if (warn_string.empty()) { + warn_string = _("Warning: ") + text + ""; + } else { + warn_string = warn_string + _("\nWarning: ") + text + ""; + } + + 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 index 0000000000..c0c5a24b20 --- /dev/null +++ b/gtk2_ardour/export_dialog.h @@ -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 + +#include +#include + +#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 + +#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 preset_selector; + boost::shared_ptr timespan_selector; + boost::shared_ptr channel_selector; + boost::shared_ptr 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 HandlerPtr; + typedef boost::shared_ptr ManagerPtr; + typedef boost::shared_ptr 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 index 0000000000..001b180560 --- /dev/null +++ b/gtk2_ardour/export_file_notebook.cc @@ -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 + +#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 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 (get_nth_page (n - 1)))) { + return page->get_format_name(); + } + return ""; +} + +void +ExportFileNotebook::add_new_file_page () +{ + FilePage * page; + if ((page = dynamic_cast (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 (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 index 0000000000..aed9a0fcc2 --- /dev/null +++ b/gtk2_ardour/export_file_notebook.h @@ -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 +#include + +#include + +#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 manager); + void sync_with_manager (); + + Glib::ustring get_nth_format_name (uint32_t n); + + sigc::signal CriticalSelectionChanged; + + private: + + typedef boost::shared_ptr ManagerPtr; + typedef boost::shared_ptr FormatPtr; + typedef boost::shared_ptr 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 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 index e653a48bf0..0000000000 --- a/gtk2_ardour/export_main_dialog.cc +++ /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 - -#include - -#include "utils.h" - -#include -#include -#include -#include -#include - -#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 (_("Some already existing files will be overwritten."), 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 warnings = profile_manager->get_warnings(); - - for (std::list::iterator it = warnings->errors.begin(); it != warnings->errors.end(); ++it) { - add_error (*it); - } - - for (std::list::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::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) + "" + it->substr (pos + 1) + ""; - } - } -} - -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 (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 (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 (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 = _("Error: ") + text + ""; - } else { - warn_string = _("Error: ") + text + "\n" + warn_string; - } - - warn_label.set_markup (warn_string); -} - -void -ExportMainDialog::add_warning (Glib::ustring const & text) -{ - if (warn_string.empty()) { - warn_string = _("Warning: ") + text + ""; - } else { - warn_string = warn_string + _("\nWarning: ") + text + ""; - } - - 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 index e578833515..0000000000 --- a/gtk2_ardour/export_main_dialog.h +++ /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 - -#include -#include - -#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 - -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 TimespanPtr; - typedef boost::shared_ptr > TimespanList; - - typedef boost::shared_ptr ChannelConfigPtr; - typedef std::list ChannelConfigList; - - typedef boost::shared_ptr FilenamePtr; - - typedef boost::shared_ptr HandlerPtr; - typedef boost::shared_ptr FormatPtr; - typedef boost::shared_ptr ManagerPtr; - typedef boost::shared_ptr 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 preset; - Gtk::TreeModelColumn label; - - PresetCols () { add (preset); add (label); } - }; - PresetCols preset_cols; - Glib::RefPtr 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 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 index 0000000000..bfbb6a884d --- /dev/null +++ b/gtk2_ardour/export_preset_selector.cc @@ -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 + +#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 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 index 0000000000..3022e224bc --- /dev/null +++ b/gtk2_ardour/export_preset_selector.h @@ -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 +#include + +#include + +class ExportPresetSelector : public Gtk::HBox +{ + + public: + + ExportPresetSelector (); + + void set_manager (boost::shared_ptr manager); + + sigc::signal CriticalSelectionChanged; + + private: + + typedef boost::shared_ptr 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 preset; + Gtk::TreeModelColumn label; + + PresetCols () { add (preset); add (label); } + }; + PresetCols cols; + Glib::RefPtr list; + PresetPtr current; + PresetPtr previous; + + Gtk::Label label; + Gtk::ComboBoxEntry entry; + + Gtk::Button save_button; + Gtk::Button remove_button; + Gtk::Button new_button; +}; + +#endif diff --git a/gtk2_ardour/export_timespan_selector.cc b/gtk2_ardour/export_timespan_selector.cc index 0f02a1580e..5f9ccfb0c6 100644 --- a/gtk2_ardour/export_timespan_selector.cc +++ b/gtk2_ardour/export_timespan_selector.cc @@ -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 (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 (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 (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 (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 (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)); + } + } +} + diff --git a/gtk2_ardour/export_timespan_selector.h b/gtk2_ardour/export_timespan_selector.h index 757b2caad2..e8a97326bc 100644 --- a/gtk2_ardour/export_timespan_selector.h +++ b/gtk2_ardour/export_timespan_selector.h @@ -41,52 +41,43 @@ namespace ARDOUR { using ARDOUR::CDMarkerFormat; -/// +/// Timespan Selector base class ExportTimespanSelector : public Gtk::VBox { - private: - - typedef std::list LocationList; - typedef boost::shared_ptr HandlerPtr; - - typedef boost::shared_ptr TimespanPtr; - typedef std::list TimespanList; - typedef boost::shared_ptr 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 CriticalSelectionChanged; - private: + protected: - void fill_range_list (); - void set_selection_from_state (); + typedef std::list LocationList; + typedef boost::shared_ptr HandlerPtr; - void update_selection (); - void update_timespans (); + typedef boost::shared_ptr TimespanPtr; + typedef std::list TimespanList; + typedef boost::shared_ptr 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; }; diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h index ae0ec5acd8..692d6d11c2 100644 --- a/libs/ardour/ardour/location.h +++ b/libs/ardour/ardour/location.h @@ -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);