From e739191ae2c82d50cc15b0a455579fcfeee90156 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 14 May 2022 18:17:58 +0200 Subject: [PATCH] Display last export channel state --- gtk2_ardour/export_channel_selector.cc | 125 ++++++++++++++++++++++--- gtk2_ardour/export_channel_selector.h | 4 +- 2 files changed, 116 insertions(+), 13 deletions(-) diff --git a/gtk2_ardour/export_channel_selector.cc b/gtk2_ardour/export_channel_selector.cc index 9d595fe2e9..91f24c191b 100644 --- a/gtk2_ardour/export_channel_selector.cc +++ b/gtk2_ardour/export_channel_selector.cc @@ -4,7 +4,7 @@ * 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) 2013-2022 Robin Gareus * Copyright (C) 2015 Ben Loftis * Copyright (C) 2015 Nick Mainsbridge * @@ -29,6 +29,7 @@ #include #include "pbd/convert.h" +#include "pbd/unwind.h" #include "ardour/audio_track.h" #include "ardour/audioregion.h" @@ -89,9 +90,7 @@ PortExportChannelSelector::PortExportChannelSelector (ARDOUR::Session * session, /* Finalize */ - sync_with_manager(); show_all_children (); - } PortExportChannelSelector::~PortExportChannelSelector () @@ -236,12 +235,12 @@ PortExportChannelSelector::ChannelTreeView::set_config (ChannelConfigPtr c) ExportChannelConfiguration::ChannelList chan_list = config->get_channels(); for (ExportChannelConfiguration::ChannelList::iterator c_it = chan_list.begin(); c_it != chan_list.end(); ++c_it) { - for (Gtk::ListStore::Children::iterator r_it = route_list->children().begin(); r_it != route_list->children().end(); ++r_it) { + PortExportChannel* pec; + if (!(pec = dynamic_cast (c_it->get()))) { + continue; + } - ARDOUR::PortExportChannel * pec; - if (!(pec = dynamic_cast (c_it->get()))) { - continue; - } + for (Gtk::ListStore::Children::iterator r_it = route_list->children().begin(); r_it != route_list->children().end(); ++r_it) { Glib::RefPtr port_list = r_it->get_value (route_cols.port_list_col); std::set > route_ports; @@ -508,7 +507,6 @@ RegionExportChannelSelector::RegionExportChannelSelector (ARDOUR::Session * _ses fades_button.signal_toggled ().connect (sigc::mem_fun (*this, &RegionExportChannelSelector::handle_selection)); vbox.pack_start (fades_button, false, false); - sync_with_manager(); vbox.show_all_children (); show_all_children (); } @@ -569,6 +567,7 @@ RegionExportChannelSelector::handle_selection () TrackExportChannelSelector::TrackExportChannelSelector (ARDOUR::Session * session, ProfileManagerPtr manager) : ExportChannelSelector(session, manager) , track_output_button(_("Apply track/bus processing")) + , _syncing_with_manager (false) { pack_start(main_layout); @@ -648,8 +647,108 @@ TrackExportChannelSelector::~TrackExportChannelSelector () void TrackExportChannelSelector::sync_with_manager () { - // TODO implement properly - update_config(); + if (sync_with_manager_state ()) { + update_config(); + } +} + +bool +TrackExportChannelSelector::sync_with_manager_state () +{ + auto const& statelist = manager->get_channel_configs (); + if (!statelist.front()) { + return true; + } + + size_t selected = 0; + for (auto const& i : track_list->children()) { + Gtk::TreeModel::Row row = *i; + if (row[track_cols.selected]) { + ++selected; + } + } + + PBD::Unwinder uw (_syncing_with_manager, true); + + auto channel_list = statelist.front()->config->get_channels(); + if (!channel_list.empty ()) { + if (boost::dynamic_pointer_cast (channel_list.front ())) { + track_output_button.set_active (false); + } else { + track_output_button.set_active (true); + } + } + + if (selected > 0) { + /* Use Editor Selection */ + return true; + } + + for (auto const& state : statelist) { + ExportChannelConfiguration::ChannelList const& chan_list = state->config->get_channels (); + + for (auto const& c : chan_list) { + boost::shared_ptr pem; + boost::shared_ptr pec; + boost::shared_ptr rec; + + if ((rec = boost::dynamic_pointer_cast (c))) { + for (auto const& i : track_list->children ()) { + Gtk::TreeModel::Row row = *i; + boost::shared_ptr route = row[track_cols.route]; + if (route == rec->route ()) { + row[track_cols.selected] = true; + break; + } + } + } else if ((pem = boost::dynamic_pointer_cast (c))) { + bool breakout = false; + for (auto const& i : track_list->children ()) { + Gtk::TreeModel::Row row = *i; + boost::shared_ptr route = row[track_cols.route]; + uint32_t n_audio = route->n_outputs().n_audio(); + uint32_t n_midi = route->n_outputs().n_midi(); + if (n_audio > 0 || n_midi == 0) { + continue; + } + for (uint32_t i = 0; i < n_midi; ++i) { + boost::shared_ptr port = route->output()->midi (i); + assert (pem->port ()); + if (port && port == pem->port ()) { + row[track_cols.selected] = true; + breakout = true; + } + } + if (breakout) { + continue; + } + } + } else if ((pec = boost::dynamic_pointer_cast (c))) { + for (auto const& i : track_list->children ()) { + Gtk::TreeModel::Row row = *i; + boost::shared_ptr route = row[track_cols.route]; + std::set> route_ports; + std::set> intersection; + PortSet& ps (route->output()->ports ()); + for (PortSet::audio_iterator p = ps.audio_begin (); p != ps.audio_end (); ++p) { + route_ports.insert (*p); + } + + std::set_intersection (pec->get_ports().begin(), pec->get_ports().end(), + route_ports.begin(), route_ports.end(), + std::insert_iterator>> (intersection, intersection.begin ())); + + if (!intersection.empty()) { + row[track_cols.selected] = true; + break; + } + } + } else { + assert (0); + } + } + } + return false; } void @@ -716,7 +815,9 @@ TrackExportChannelSelector::select_none () void TrackExportChannelSelector::track_outputs_selected () { - update_config(); + if (!_syncing_with_manager) { + update_config(); + } } void diff --git a/gtk2_ardour/export_channel_selector.h b/gtk2_ardour/export_channel_selector.h index 9ca1c138c6..a8d528f388 100644 --- a/gtk2_ardour/export_channel_selector.h +++ b/gtk2_ardour/export_channel_selector.h @@ -252,7 +252,7 @@ class TrackExportChannelSelector : public ExportChannelSelector TrackExportChannelSelector (ARDOUR::Session * session, ProfileManagerPtr manager); ~TrackExportChannelSelector (); - virtual void sync_with_manager (); + void sync_with_manager (); bool track_output () const { return track_output_button.get_active(); } bool channel_limit_reached () const { return false; } @@ -260,6 +260,7 @@ class TrackExportChannelSelector : public ExportChannelSelector private: void fill_list(); + bool sync_with_manager_state (); void add_track (boost::shared_ptr route, bool selected); void update_config(); ChannelConfigList configs; @@ -293,6 +294,7 @@ class TrackExportChannelSelector : public ExportChannelSelector void select_none (); void track_outputs_selected (); + bool _syncing_with_manager; }; #endif /* __export_channel_selector_h__ */