X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fexport_channel_selector.cc;h=d55a223b93107642825a291ca7838484db867f8e;hb=62c4e88a9d8f4a7b019243fe9a10830b1da0150c;hp=6f32ae783e3b75e244246d7f6ece1b8cd68fc7e5;hpb=52363ebefd165916fa6ba1e4ffb6f0cc5ac436c3;p=ardour.git diff --git a/gtk2_ardour/export_channel_selector.cc b/gtk2_ardour/export_channel_selector.cc index 6f32ae783e..d55a223b93 100644 --- a/gtk2_ardour/export_channel_selector.cc +++ b/gtk2_ardour/export_channel_selector.cc @@ -1,26 +1,32 @@ /* - 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_channel_selector.h" + * Copyright (C) 2008-2013 Sakari Bergen + * Copyright (C) 2008-2016 Paul Davis + * Copyright (C) 2009-2011 Carl Hetherington + * Copyright (C) 2009-2012 David Robillard + * Copyright (C) 2013-2015 Colin Fletcher + * Copyright (C) 2013-2019 Robin Gareus + * Copyright (C) 2015 Ben Loftis + * Copyright (C) 2015 Nick Mainsbridge + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #include +#include + +#include #include "pbd/convert.h" @@ -30,10 +36,12 @@ #include "ardour/io.h" #include "ardour/route.h" #include "ardour/session.h" +#include "ardour/selection.h" -#include +#include "export_channel_selector.h" +#include "route_sorter.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace Glib; @@ -85,9 +93,6 @@ PortExportChannelSelector::PortExportChannelSelector (ARDOUR::Session * session, PortExportChannelSelector::~PortExportChannelSelector () { -// if (session) { -// session->add_instant_xml (get_state(), false); -// } } void @@ -98,6 +103,11 @@ PortExportChannelSelector::sync_with_manager () split_checkbox.set_active (state->config->get_split()); channels_spinbutton.set_value (state->config->get_n_chans()); + /* when loading presets, config is ready set here (shared ptr) + * fill_route_list () -> update_channel_count () -> set_channel_count () -> update_config() + * will call config->clear_channels(); and clear the config + */ + channel_view.set_config (ChannelConfigPtr ()); fill_route_list (); channel_view.set_config (state->config); } @@ -106,12 +116,16 @@ void PortExportChannelSelector::fill_route_list () { channel_view.clear_routes (); - RouteList routes = *_session->get_routes(); + RouteList routes = _session->get_routelist(); /* Add master bus and then everything else */ - ARDOUR::IO* master = _session->master_out()->output().get(); - channel_view.add_route (master); + if (_session->master_out()) { + ARDOUR::IO* master = _session->master_out()->output().get(); + channel_view.add_route (master); + } + + routes.sort (Stripable::Sorter ()); for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) { if ((*it)->is_master () || (*it)->is_monitor ()) { @@ -152,7 +166,7 @@ PortExportChannelSelector::RouteCols::Channel & PortExportChannelSelector::RouteCols::get_channel (uint32_t channel) { if (channel > n_channels) { - std::cout << "Invalid channel cout for get_channel!" << std::endl; + std::cout << "Invalid channel count for get_channel!" << std::endl; } std::list::iterator it = channels.begin(); @@ -177,16 +191,21 @@ PortExportChannelSelector::ChannelTreeView::ChannelTreeView (uint32_t max_channe /* Add column with toggle and text */ - append_column_editable (_("Bus or Track"), route_cols.selected); + append_column_editable (_("Export"), route_cols.selected); Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText); text_renderer->property_editable() = false; + text_renderer->set_alignment (0.0, 0.5); - Gtk::TreeView::Column* column = get_column (0); + Gtk::TreeView::Column* column = Gtk::manage (new Gtk::TreeView::Column); + column->set_title (_("Bus or Track")); column->pack_start (*text_renderer); + column->set_expand (true); column->add_attribute (text_renderer->property_text(), route_cols.name); + append_column (*column); Gtk::CellRendererToggle *toggle = dynamic_cast(get_column_cell_renderer (0)); + toggle->set_alignment (0.0, 0.5); toggle->signal_toggled().connect (sigc::mem_fun (*this, &PortExportChannelSelector::ChannelTreeView::update_toggle_selection)); static_columns = get_columns().size(); @@ -202,6 +221,7 @@ PortExportChannelSelector::ChannelTreeView::set_config (ChannelConfigPtr c) if (config == c) { return; } config = c; + if (!config) { return; } uint32_t i = 1; ExportChannelConfiguration::ChannelList chan_list = config->get_channels(); @@ -222,7 +242,7 @@ PortExportChannelSelector::ChannelTreeView::set_config (ChannelConfigPtr c) for (Gtk::ListStore::Children::const_iterator p_it = port_list->children().begin(); p_it != port_list->children().end(); ++p_it) { route_ports.insert ((*p_it)->get_value (route_cols.port_cols.port)); port_labels.insert (make_pair ((*p_it)->get_value (route_cols.port_cols.port), - (*p_it)->get_value (route_cols.port_cols.label))); + (*p_it)->get_value (route_cols.port_cols.label))); } std::set_intersection (pec->get_ports().begin(), pec->get_ports().end(), @@ -313,6 +333,7 @@ PortExportChannelSelector::ChannelTreeView::set_channel_count (uint32_t channels Gtk::CellRendererCombo* combo_renderer = Gtk::manage (new Gtk::CellRendererCombo); combo_renderer->property_text_column() = 2; + combo_renderer->property_has_entry() = false; column->pack_start (*combo_renderer); append_column (*column); @@ -438,15 +459,15 @@ RegionExportChannelSelector::RegionExportChannelSelector (ARDOUR::Session * _ses ProfileManagerPtr manager, ARDOUR::AudioRegion const & region, ARDOUR::AudioTrack & track) : - ExportChannelSelector (_session, manager), - region (region), - track (track), - region_chans (region.n_channels()), - track_chans (track.n_outputs().n_audio()), - - raw_button (type_group), - fades_button (type_group), - processed_button (type_group) + ExportChannelSelector (_session, manager), + region (region), + track (track), + region_chans (region.n_channels()), + track_chans (track.n_outputs().n_audio()), + + raw_button (type_group), + fades_button (type_group), + processed_button (type_group) { pack_start (vbox); @@ -456,15 +477,15 @@ RegionExportChannelSelector::RegionExportChannelSelector (ARDOUR::Session * _ses raw_button.set_label (string_compose (_("Region contents without fades nor region gain (channels: %1)"), region_chans)); raw_button.signal_toggled ().connect (sigc::mem_fun (*this, &RegionExportChannelSelector::handle_selection)); - vbox.pack_start (raw_button); + vbox.pack_start (raw_button, false, false); fades_button.set_label (string_compose (_("Region contents with fades and region gain (channels: %1)"), region_chans)); fades_button.signal_toggled ().connect (sigc::mem_fun (*this, &RegionExportChannelSelector::handle_selection)); - vbox.pack_start (fades_button); + vbox.pack_start (fades_button, false, false); processed_button.set_label (string_compose (_("Track output (channels: %1)"), track_chans)); processed_button.signal_toggled ().connect (sigc::mem_fun (*this, &RegionExportChannelSelector::handle_selection)); - vbox.pack_start (processed_button); + vbox.pack_start (processed_button, false, false); sync_with_manager(); vbox.show_all_children (); @@ -520,7 +541,8 @@ RegionExportChannelSelector::handle_selection () factory.reset (new RegionExportChannelFactory (_session, region, track, type)); state->config->set_region_processing_type (type); - for (size_t chan = 0; chan < region_chans; ++chan) { + const size_t cc = type == RegionExportChannelFactory::Processed ? track_chans : region_chans; + for (size_t chan = 0; chan < cc; ++chan) { state->config->register_channel (factory->create (chan)); } @@ -531,15 +553,38 @@ RegionExportChannelSelector::handle_selection () TrackExportChannelSelector::TrackExportChannelSelector (ARDOUR::Session * session, ProfileManagerPtr manager) : ExportChannelSelector(session, manager) - , region_contents_button(source_group, _("Export region contents")) - , track_output_button(source_group, _("Export track output")) + , track_output_button(_("Apply track/bus processing")) { pack_start(main_layout); + // Populate Selection Menu + { + using namespace Gtk::Menu_Helpers; + + select_menu.set_text (_("Selection Actions")); + select_menu.disable_scrolling (); + + select_menu.AddMenuElem (MenuElem (_("Select tracks"), sigc::mem_fun (*this, &TrackExportChannelSelector::select_tracks))); + select_menu.AddMenuElem (MenuElem (_("Select busses"), sigc::mem_fun (*this, &TrackExportChannelSelector::select_busses))); + select_menu.AddMenuElem (MenuElem (_("Deselect all"), sigc::mem_fun (*this, &TrackExportChannelSelector::select_none))); + select_menu.AddMenuElem (SeparatorElem ()); + + exclude_hidden = new Gtk::CheckMenuItem (_("Exclude Hidden")); + exclude_hidden->set_active (false); + exclude_hidden->show(); + select_menu.AddMenuElem (*exclude_hidden); + + exclude_muted = new Gtk::CheckMenuItem (_("Exclude Muted")); + exclude_muted->set_active (true); + exclude_muted->show(); + select_menu.AddMenuElem (*exclude_muted); + } + // Options - options_box.pack_start(region_contents_button); - options_box.pack_start(track_output_button); - main_layout.pack_start(options_box); + options_box.set_spacing (8); + options_box.pack_start (track_output_button, false, false); + options_box.pack_start (select_menu, false, false); + main_layout.pack_start (options_box, false, false); // Track scroller track_scroller.add (track_view); @@ -549,25 +594,40 @@ TrackExportChannelSelector::TrackExportChannelSelector (ARDOUR::Session * sessio // Track list track_list = Gtk::ListStore::create (track_cols); + track_list->set_sort_column (track_cols.order_key, Gtk::SORT_ASCENDING); track_view.set_model (track_list); track_view.set_headers_visible (true); - track_view.append_column_editable (_("Track"), track_cols.selected); + track_view.append_column_editable (_("Export"), track_cols.selected); Gtk::CellRendererToggle *toggle = dynamic_cast(track_view.get_column_cell_renderer (0)); + toggle->set_alignment (0.0, 0.5); + toggle->signal_toggled().connect (sigc::hide (sigc::mem_fun (*this, &TrackExportChannelSelector::update_config))); Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText); text_renderer->property_editable() = false; + text_renderer->set_alignment (0.0, 0.5); - Gtk::TreeView::Column* column = track_view.get_column (0); - column->pack_start (*text_renderer); + Gtk::TreeView::Column* column = Gtk::manage (new Gtk::TreeView::Column); + column->set_title (_("Track name")); + + track_view.append_column (*column); + column->pack_start (*text_renderer, false); column->add_attribute (text_renderer->property_text(), track_cols.label); + track_output_button.signal_clicked().connect (sigc::mem_fun (*this, &TrackExportChannelSelector::track_outputs_selected)); + fill_list(); show_all_children (); } +TrackExportChannelSelector::~TrackExportChannelSelector () +{ + delete exclude_hidden; + delete exclude_muted; +} + void TrackExportChannelSelector::sync_with_manager () { @@ -575,11 +635,73 @@ TrackExportChannelSelector::sync_with_manager () update_config(); } +void +TrackExportChannelSelector::select_tracks () +{ + bool excl_hidden = exclude_hidden->get_active (); + bool excl_muted = exclude_muted->get_active (); + + for (Gtk::ListStore::Children::iterator it = track_list->children().begin(); it != track_list->children().end(); ++it) { + Gtk::TreeModel::Row row = *it; + boost::shared_ptr route = row[track_cols.route]; + if (boost::dynamic_pointer_cast (route)) { + if (excl_muted && route->muted ()) { + continue; + } + if (excl_hidden && route->is_hidden ()) { + continue; + } + row[track_cols.selected] = true; + } + } + update_config(); +} + +void +TrackExportChannelSelector::select_busses () +{ + bool excl_hidden = exclude_hidden->get_active (); + bool excl_muted = exclude_muted->get_active (); + + for (Gtk::ListStore::Children::iterator it = track_list->children().begin(); it != track_list->children().end(); ++it) { + Gtk::TreeModel::Row row = *it; + boost::shared_ptr route = row[track_cols.route]; + if (!boost::dynamic_pointer_cast (route)) { + if (excl_muted && route->muted ()) { + continue; + } + if (excl_hidden && route->is_hidden ()) { + continue; + } + row[track_cols.selected] = true; + } + } + update_config(); +} + +void +TrackExportChannelSelector::select_none () +{ + for (Gtk::ListStore::Children::iterator it = track_list->children().begin(); it != track_list->children().end(); ++it) { + Gtk::TreeModel::Row row = *it; + row[track_cols.selected] = false; + } + update_config(); +} + +void +TrackExportChannelSelector::track_outputs_selected () +{ + update_config(); +} + void TrackExportChannelSelector::fill_list() { track_list->clear(); - RouteList routes = *_session->get_routes(); + RouteList routes = _session->get_routelist(); + + CoreSelection const& cs (_session->selection()); for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) { if (!boost::dynamic_pointer_cast(*it)) { @@ -587,26 +709,36 @@ TrackExportChannelSelector::fill_list() if ((*it)->is_master () || (*it)->is_monitor ()) { continue; } + if (!(*it)->active ()) { + // don't include inactive busses + continue; + } + // not monitor or master bus - add_track (*it); + add_track (*it, cs.selected (*it)); } } for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) { if (boost::dynamic_pointer_cast(*it)) { - add_track (*it); + if (!(*it)->active ()) { + // don't include inactive tracks + continue; + } + add_track (*it, cs.selected (*it)); } } } void -TrackExportChannelSelector::add_track (boost::shared_ptr route) +TrackExportChannelSelector::add_track (boost::shared_ptr route, bool selected) { Gtk::TreeModel::iterator iter = track_list->append(); Gtk::TreeModel::Row row = *iter; - row[track_cols.selected] = true; + row[track_cols.selected] = selected; row[track_cols.label] = route->name(); row[track_cols.route] = route; + row[track_cols.order_key] = route->presentation_info().order(); } void @@ -621,7 +753,7 @@ TrackExportChannelSelector::update_config() continue; } - ExportProfileManager::ChannelConfigStatePtr state = manager->add_channel_config(); + ExportProfileManager::ChannelConfigStatePtr state; boost::shared_ptr route = row[track_cols.route]; @@ -633,16 +765,30 @@ TrackExportChannelSelector::update_config() ExportChannelPtr channel (new PortExportChannel ()); PortExportChannel * pec = static_cast (channel.get()); pec->add_port(port); + if (!state) { + state = manager->add_channel_config(); + } state->config->register_channel(channel); } } } else { std::list list; RouteExportChannel::create_from_route (list, route); + if (list.size () == 0) { + continue; + } + state = manager->add_channel_config(); state->config->register_channels (list); } - state->config->set_name (route->name()); + if (state) { + if (_session->config.get_track_name_number() && route->track_number() > 0) { + state->config->set_name (string_compose ("%1-%2", route->track_number(), route->name())); + } else { + state->config->set_name (route->name()); + } + } + } CriticalSelectionChanged ();