mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-28 09:27:39 +01:00
initial dirty work on a state substitution dialog - lots of cleanup and imporvement needed
This commit is contained in:
parent
7c6dbf3f6b
commit
9f068afe02
5 changed files with 309 additions and 5 deletions
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "editor.h"
|
||||
#include "mixer_snapshot_dialog.h"
|
||||
#include "mixer_snapshot_substitution_dialog.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "pbd/basename.h"
|
||||
|
|
@ -198,7 +199,11 @@ void MixerSnapshotDialog::popup_context_menu(int btn, int64_t time, TreeModel::i
|
|||
void MixerSnapshotDialog::load_snapshot(TreeModel::iterator& iter)
|
||||
{
|
||||
MixerSnapshot* snap = (*iter)[_columns.snapshot];
|
||||
snap->recall();
|
||||
|
||||
MixerSnapshotSubstitutionDialog* d = new MixerSnapshotSubstitutionDialog(snap);
|
||||
d->show_all();
|
||||
// d->signal_response().connect(sigc::bind(sigc::mem_fun(*this, &MixerSnapshotDialog::sub_dialog_finished), d));
|
||||
// snap->recall();
|
||||
}
|
||||
|
||||
void MixerSnapshotDialog::rename_snapshot(TreeModel::iterator& iter)
|
||||
|
|
|
|||
249
gtk2_ardour/mixer_snapshot_substitution_dialog.cc
Normal file
249
gtk2_ardour/mixer_snapshot_substitution_dialog.cc
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
Copyright (C) 2019 Nikolaus Gullotta
|
||||
|
||||
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 <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
#include <gtkmm/comboboxtext.h>
|
||||
#include <gtkmm/table.h>
|
||||
#include <gtkmm/stock.h>
|
||||
|
||||
#include "mixer_snapshot_substitution_dialog.h"
|
||||
|
||||
#include "ardour/mixer_snapshot.h"
|
||||
#include "ardour/utils.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace Gtk;
|
||||
using namespace PBD;
|
||||
using namespace std;
|
||||
|
||||
MixerSnapshotSubstitutionDialog::MixerSnapshotSubstitutionDialog(MixerSnapshot* snapshot)
|
||||
: ArdourDialog (_("Substitutions"), true)
|
||||
, _snapshot(snapshot)
|
||||
{
|
||||
RouteList rl = _snapshot->get_session()->get_routelist();
|
||||
|
||||
Table* table = manage(new Table(rl.size(), 1));
|
||||
|
||||
int n = 0;
|
||||
Label* dst = manage(new Label(_("Destination: "), ALIGN_CENTER, ALIGN_CENTER));
|
||||
Label* src = manage(new Label(_("Source: "), ALIGN_CENTER, ALIGN_CENTER));
|
||||
table->attach(*dst, 0, 1, n, n+1);
|
||||
table->attach(*src, 1, 2, n, n+1);
|
||||
n++;
|
||||
|
||||
|
||||
for(RouteList::const_iterator it = rl.begin(); it != rl.end(); it++) {
|
||||
boost::shared_ptr<Route> route = (*it);
|
||||
|
||||
if(route) {
|
||||
ComboBoxText* combo = manage(new ComboBoxText());
|
||||
fill_combo_box(combo, route->name());
|
||||
|
||||
Label* l = manage(new Label(route->name(), ALIGN_LEFT, ALIGN_CENTER, false));
|
||||
table->attach(*l, 0, 1, n, n+1);
|
||||
table->attach(*combo, 1, 2, n, n+1);
|
||||
|
||||
substitutions.push_back(route_combo(route, combo));
|
||||
}
|
||||
n++;
|
||||
}
|
||||
|
||||
ComboBoxText* sel_combo = manage(new ComboBoxText());
|
||||
Label* sel = manage(new Label(_("All Selected: ")));
|
||||
fill_combo_box(sel_combo, "");
|
||||
table->attach(*sel, 0, 1, n, n+1);
|
||||
table->attach(*sel_combo, 1, 2, n, n+1);
|
||||
n++;
|
||||
|
||||
|
||||
add_button (Stock::CANCEL, RESPONSE_CANCEL);
|
||||
add_button (Stock::APPLY, RESPONSE_ACCEPT);
|
||||
set_default_response(RESPONSE_ACCEPT);
|
||||
|
||||
get_vbox()->pack_start(*table, true, true);
|
||||
}
|
||||
|
||||
void MixerSnapshotSubstitutionDialog::fill_combo_box(ComboBoxText* box, const string route_name)
|
||||
{
|
||||
box->append(" --- ");
|
||||
box->set_active_text(" --- ");
|
||||
|
||||
vector<MixerSnapshot::State> routes = _snapshot->get_routes();
|
||||
|
||||
for(vector<MixerSnapshot::State>::iterator i = routes.begin(); i != routes.end(); i++) {
|
||||
string state_name = (*i).name;
|
||||
box->append(state_name);
|
||||
if(state_name == route_name) {
|
||||
box->set_active_text(state_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MixerSnapshotSubstitutionDialog::on_response(int r)
|
||||
{
|
||||
if(r == RESPONSE_CANCEL) {
|
||||
close_self();
|
||||
return;
|
||||
}
|
||||
|
||||
vector<MixerSnapshot::State> dirty = _snapshot->get_routes();
|
||||
vector<MixerSnapshot::State> clean = _snapshot->get_routes();
|
||||
vector<MixerSnapshot::State> new_s;
|
||||
vector<MixerSnapshot::State> del_s;
|
||||
|
||||
if(r == RESPONSE_ACCEPT) {
|
||||
for(vector<route_combo>::iterator c = substitutions.begin(); c != substitutions.end(); c++) {
|
||||
string route_name = (*c).first->name();
|
||||
string subst_name = (*c).second->get_active_text();
|
||||
int n = 0;
|
||||
for(vector<MixerSnapshot::State>::iterator s = dirty.begin(); s != dirty.end(); s++) {
|
||||
MixerSnapshot::State state = (*s);
|
||||
if(route_name == state.name) {
|
||||
//state and substitution are matches
|
||||
if(route_name == subst_name) {
|
||||
break;
|
||||
}
|
||||
|
||||
//empty sub - erase it
|
||||
if(subst_name == " --- ") {
|
||||
del_s.push_back(state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(subst_name == " --- ") {
|
||||
break;
|
||||
}
|
||||
|
||||
bool route_state_exists = state_exists(route_name);
|
||||
bool subst_state_exists = state_exists(subst_name);
|
||||
|
||||
//state exists but we are picking a different source
|
||||
if(route_name != subst_name) {
|
||||
if(route_state_exists && subst_state_exists) {
|
||||
XMLNode copy (get_state_by_name(subst_name).node);
|
||||
sanitize_node(copy, route_name);
|
||||
state.node = copy;
|
||||
}
|
||||
|
||||
//state did *not* exist, make it and add the substitute node
|
||||
if(!route_state_exists && subst_state_exists) {
|
||||
//copy the substitute node
|
||||
XMLNode copy (get_state_by_name(subst_name).node);
|
||||
sanitize_node(copy, route_name);
|
||||
MixerSnapshot::State s {
|
||||
"",
|
||||
route_name,
|
||||
copy
|
||||
};
|
||||
|
||||
new_s.push_back(s);
|
||||
}
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(vector<MixerSnapshot::State>::iterator s = new_s.begin(); s != new_s.end(); s++) {
|
||||
dirty.push_back((*s));
|
||||
}
|
||||
|
||||
for(vector<MixerSnapshot::State>::iterator d = del_s.begin(); d != del_s.end(); d++) {
|
||||
for(vector<MixerSnapshot::State>::iterator s = dirty.begin(); s != dirty.end(); s++) {
|
||||
if((*d).id == (*s).id) {
|
||||
dirty.erase(s);
|
||||
s--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(vector<MixerSnapshot::State>::iterator s = dirty.begin(); s != dirty.end(); s++) {
|
||||
cout << (*s).name << endl;
|
||||
}
|
||||
|
||||
_snapshot->set_route_states(dirty);
|
||||
_snapshot->recall();
|
||||
_snapshot->set_route_states(clean);
|
||||
close_self();
|
||||
}
|
||||
|
||||
bool MixerSnapshotSubstitutionDialog::state_exists(const string name)
|
||||
{
|
||||
vector<MixerSnapshot::State> routes = _snapshot->get_routes();
|
||||
|
||||
for(vector<MixerSnapshot::State>::iterator i = routes.begin(); i != routes.end(); i++) {
|
||||
if((*i).name == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
MixerSnapshot::State MixerSnapshotSubstitutionDialog::get_state_by_name(const string name) {
|
||||
vector<MixerSnapshot::State> routes = _snapshot->get_routes();
|
||||
for(vector<MixerSnapshot::State>::iterator i = routes.begin(); i != routes.end(); i++) {
|
||||
if((*i).name == name) {
|
||||
return (*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XMLNode& MixerSnapshotSubstitutionDialog::sanitize_node(XMLNode& node, const string route_name)
|
||||
{
|
||||
//remove I/O
|
||||
node.remove_node_and_delete("IO", "direction", "Input");
|
||||
node.remove_node_and_delete("IO", "direction", "Output");
|
||||
node.remove_node_and_delete("IO", "direction", "Output");
|
||||
|
||||
//remove diskwriter and reader
|
||||
node.remove_node_and_delete("Processor", "type", "diskwriter");
|
||||
node.remove_node_and_delete("Processor", "type", "diskreader");
|
||||
|
||||
//remove any sidechain stuff
|
||||
// node.remove_node_and_delete("Processor", "type", "sidechain");
|
||||
|
||||
//set node <Route name=""> to destination's name
|
||||
node.set_property(X_("name"), route_name);
|
||||
|
||||
//unlink playlists
|
||||
node.remove_property(X_("id"));
|
||||
node.remove_property(X_("audio-playlist"));
|
||||
|
||||
XMLNode* pi_node = find_named_node(node, X_("PresentationInfo"));
|
||||
XMLNode* proc_node = find_named_node(node, X_("PresentationInfo"));
|
||||
|
||||
if(pi_node) {
|
||||
pi_node->remove_property(X_("order"));
|
||||
}
|
||||
|
||||
|
||||
XMLNodeList nlist = node.children();
|
||||
for(XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); niter++) {
|
||||
if((*niter)->name() != "Processor") {
|
||||
continue;
|
||||
}
|
||||
|
||||
(*niter)->remove_node_and_delete("Processor", "type", "sidechain");
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
48
gtk2_ardour/mixer_snapshot_substitution_dialog.h
Normal file
48
gtk2_ardour/mixer_snapshot_substitution_dialog.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
Copyright (C) 2019 Nikolaus Gullotta
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef __ardour_mixer_snapshot_substitution_dialog_h__
|
||||
#define __ardour_mixer_snapshot_substitution_dialog_h__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
|
||||
#include "ardour_dialog.h"
|
||||
|
||||
#include "ardour/mixer_snapshot.h"
|
||||
|
||||
typedef std::pair<boost::shared_ptr<ARDOUR::Route>, Gtk::ComboBoxText*> route_combo;
|
||||
|
||||
class MixerSnapshotSubstitutionDialog : public ArdourDialog
|
||||
{
|
||||
public:
|
||||
MixerSnapshotSubstitutionDialog(ARDOUR::MixerSnapshot*);
|
||||
private:
|
||||
bool state_exists(const std::string);
|
||||
ARDOUR::MixerSnapshot::State get_state_by_name(const std::string);
|
||||
void fill_combo_box(Gtk::ComboBoxText*, const std::string);
|
||||
void on_response(int);
|
||||
XMLNode& sanitize_node(XMLNode&, const std::string);
|
||||
|
||||
std::vector<route_combo> substitutions;
|
||||
|
||||
ARDOUR::MixerSnapshot* _snapshot;
|
||||
};
|
||||
|
||||
#endif /* __ardour_mixer_snapshot_substitution_dialog_h__ */
|
||||
|
|
@ -105,6 +105,8 @@ class LIBARDOUR_API MixerSnapshot
|
|||
std::string get_last_modified_with() {return last_modified_with;};
|
||||
void set_last_modified_with(std::string new_modified_with) {last_modified_with = new_modified_with;};
|
||||
|
||||
void set_route_states(std::vector<State> states) { route_states = states;};
|
||||
|
||||
private:
|
||||
ARDOUR::Session* _session;
|
||||
|
||||
|
|
|
|||
|
|
@ -330,17 +330,17 @@ void MixerSnapshot::recall()
|
|||
for(vector<State>::const_iterator i = route_states.begin(); i != route_states.end(); i++) {
|
||||
State state = (*i);
|
||||
|
||||
boost::shared_ptr<Route> route = _session->route_by_id(PBD::ID(state.id));
|
||||
// boost::shared_ptr<Route> route;// = _session->route_by_id(PBD::ID(state.id));
|
||||
|
||||
if(!route) {
|
||||
route = _session->route_by_name(state.name);
|
||||
}
|
||||
boost::shared_ptr<Route> route = _session->route_by_name(state.name);
|
||||
|
||||
if(route) {
|
||||
printf("Setting state %s for route %s\n", state.name.c_str(), route->name().c_str());
|
||||
XMLNode& bfr = route->get_state();
|
||||
route->set_state(sanitize_node(state.node), PBD::Stateful::loading_state_version);
|
||||
reassign_masters(route, state.node);
|
||||
_session->add_command(new MementoCommand<Route>((*route), &bfr, &route->get_state()));
|
||||
route->emit_pending_signals();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue