13
0
livetrax/gtk2_ardour/add_route_dialog.cc
Todd Naugle 203a72f883 Create new Groups with a consistent set of default properties.
This is part of a larger fix for #6450. Previously new route groups were
created with different default properties depending on which code created
the new group. The group tab method had all properties set and that is now
going to be the default for all other methods (mixer strip button, etc).
2015-09-21 14:52:25 -05:00

585 lines
14 KiB
C++

/*
Copyright (C) 2003 Paul Davis
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 <cstdio>
#include <cmath>
#include <sigc++/bind.h>
#include <gtkmm/stock.h>
#include <gtkmm/messagedialog.h>
#include <gtkmm/separator.h>
#include <gtkmm/table.h>
#include "pbd/error.h"
#include "pbd/convert.h"
#include "gtkmm2ext/utils.h"
#include "ardour/plugin_manager.h"
#include "ardour/profile.h"
#include "ardour/template_utils.h"
#include "ardour/route_group.h"
#include "ardour/session.h"
#include "utils.h"
#include "add_route_dialog.h"
#include "route_group_dialog.h"
#include "i18n.h"
using namespace Gtk;
using namespace Gtkmm2ext;
using namespace std;
using namespace PBD;
using namespace ARDOUR;
using namespace ARDOUR_UI_UTILS;
std::vector<std::string> AddRouteDialog::channel_combo_strings;
AddRouteDialog::AddRouteDialog ()
: ArdourDialog (_("Add Track or Bus"))
, routes_adjustment (1, 1, 128, 1, 4)
, routes_spinner (routes_adjustment)
, configuration_label (_("Configuration:"))
, mode_label (_("Record Mode:"))
, instrument_label (_("Instrument:"))
{
set_name ("AddRouteDialog");
set_modal (true);
set_skip_taskbar_hint (true);
set_resizable (false);
name_template_entry.set_name (X_("AddRouteDialogNameTemplateEntry"));
// routes_spinner.set_name (X_("AddRouteDialogSpinner"));
channel_combo.set_name (X_("ChannelCountSelector"));
mode_combo.set_name (X_("ChannelCountSelector"));
refill_channel_setups ();
refill_route_groups ();
refill_track_modes ();
channel_combo.set_active_text (channel_combo_strings.front());
track_bus_combo.append_text (_("Audio Tracks"));
track_bus_combo.append_text (_("MIDI Tracks"));
track_bus_combo.append_text (_("Audio+MIDI Tracks"));
track_bus_combo.append_text (_("Busses"));
track_bus_combo.set_active (0);
insert_at_combo.append_text (_("First"));
insert_at_combo.append_text (_("Before Selection"));
insert_at_combo.append_text (_("After Selection"));
insert_at_combo.append_text (_("Last"));
insert_at_combo.set_active (1);
VBox* vbox = manage (new VBox);
Gtk::Label* l;
get_vbox()->set_spacing (4);
vbox->set_spacing (18);
vbox->set_border_width (5);
HBox *type_hbox = manage (new HBox);
type_hbox->set_spacing (6);
/* track/bus choice */
type_hbox->pack_start (*manage (new Label (_("Add:"))));
type_hbox->pack_start (routes_spinner);
type_hbox->pack_start (track_bus_combo);
vbox->pack_start (*type_hbox, false, true);
VBox* options_box = manage (new VBox);
Table *table2 = manage (new Table (3, 3, false));
options_box->set_spacing (6);
table2->set_row_spacings (6);
table2->set_col_spacing (1, 6);
l = manage (new Label (_("<b>Options</b>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
l->set_use_markup ();
options_box->pack_start (*l, false, true);
l = manage (new Label ("", Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
l->set_padding (8, 0);
table2->attach (*l, 0, 1, 0, 3, Gtk::FILL, Gtk::FILL, 0, 0);
int n = 0;
l = manage (new Label (_("Name:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
table2->attach (*l, 1, 2, n, n + 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
table2->attach (name_template_entry, 2, 3, n, n + 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL, 0, 0);
++n;
/* Route configuration */
configuration_label.set_alignment (Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
table2->attach (configuration_label, 1, 2, n, n + 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
table2->attach (channel_combo, 2, 3, n, n + 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL, 0, 0);
++n;
if (!ARDOUR::Profile->get_sae ()) {
/* Track mode */
mode_label.set_alignment (Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
table2->attach (mode_label, 1, 2, n, n + 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
table2->attach (mode_combo, 2, 3, n, n + 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL, 0, 0);
++n;
}
instrument_label.set_alignment (Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
table2->attach (instrument_label, 1, 2, n, n + 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
table2->attach (instrument_combo, 2, 3, n, n + 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL, 0, 0);
++n;
/* Group choice */
l = manage (new Label (_("Group:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
table2->attach (*l, 1, 2, n, n + 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
table2->attach (route_group_combo, 2, 3, n, n + 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL, 0, 0);
++n;
/* New route will be inserted at.. */
l = manage (new Label (_("Insert:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, false));
table2->attach (*l, 1, 2, n, n + 1, Gtk::FILL, Gtk::EXPAND, 0, 0);
table2->attach (insert_at_combo, 2, 3, n, n + 1, Gtk::FILL, Gtk::EXPAND | Gtk::FILL, 0, 0);
++n;
options_box->pack_start (*table2, false, true);
vbox->pack_start (*options_box, false, true);
get_vbox()->pack_start (*vbox, false, false);
track_bus_combo.signal_changed().connect (sigc::mem_fun (*this, &AddRouteDialog::track_type_chosen));
channel_combo.signal_changed().connect (sigc::mem_fun (*this, &AddRouteDialog::channel_combo_changed));
channel_combo.set_row_separator_func (sigc::mem_fun (*this, &AddRouteDialog::channel_separator));
route_group_combo.set_row_separator_func (sigc::mem_fun (*this, &AddRouteDialog::route_separator));
route_group_combo.signal_changed ().connect (sigc::mem_fun (*this, &AddRouteDialog::group_changed));
show_all_children ();
/* track template info will be managed whenever
this dialog is shown, via ::on_show()
*/
add_button (Stock::CANCEL, RESPONSE_CANCEL);
add_button (Stock::ADD, RESPONSE_ACCEPT);
set_response_sensitive (RESPONSE_ACCEPT, true);
set_default_response (RESPONSE_ACCEPT);
track_type_chosen ();
}
AddRouteDialog::~AddRouteDialog ()
{
}
void
AddRouteDialog::channel_combo_changed ()
{
maybe_update_name_template_entry ();
refill_track_modes ();
}
AddRouteDialog::TypeWanted
AddRouteDialog::type_wanted() const
{
std::string str = track_bus_combo.get_active_text();
if (str == _("Busses")) {
return AudioBus;
} else if (str == _("MIDI Tracks")){
return MidiTrack;
} else if (str == _("Audio+MIDI Tracks")) {
return MixedTrack;
} else {
return AudioTrack;
}
}
void
AddRouteDialog::maybe_update_name_template_entry ()
{
if (
name_template_entry.get_text() != "" &&
name_template_entry.get_text() != _("Audio") &&
name_template_entry.get_text() != _("MIDI") &&
name_template_entry.get_text() != _("Audio+MIDI") &&
name_template_entry.get_text() != _("Bus")) {
return;
}
switch (type_wanted()) {
case AudioTrack:
name_template_entry.set_text (_("Audio"));
break;
case MidiTrack:
name_template_entry.set_text (_("MIDI"));
break;
case MixedTrack:
name_template_entry.set_text (_("Audio+MIDI"));
break;
case AudioBus:
name_template_entry.set_text (_("Bus"));
break;
}
}
void
AddRouteDialog::track_type_chosen ()
{
switch (type_wanted()) {
case AudioTrack:
mode_combo.set_sensitive (true);
channel_combo.set_sensitive (true);
instrument_combo.set_sensitive (false);
configuration_label.set_sensitive (true);
mode_label.set_sensitive (true);
instrument_label.set_sensitive (false);
break;
case MidiTrack:
channel_combo.set_sensitive (false);
mode_combo.set_sensitive (false);
instrument_combo.set_sensitive (true);
configuration_label.set_sensitive (false);
mode_label.set_sensitive (false);
instrument_label.set_sensitive (true);
break;
case MixedTrack:
{
MessageDialog msg (_("Audio+MIDI tracks are intended for use <b>ONLY</b> with plugins that use both audio and MIDI input data\n\n"
"If you do not plan to use such a plugin, then use a normal audio or MIDI track instead."),
true, MESSAGE_INFO, BUTTONS_OK, true);
msg.set_position (WIN_POS_MOUSE);
msg.run ();
}
channel_combo.set_sensitive (true);
mode_combo.set_sensitive (true);
instrument_combo.set_sensitive (true);
configuration_label.set_sensitive (true);
mode_label.set_sensitive (true);
instrument_label.set_sensitive (true);
break;
case AudioBus:
mode_combo.set_sensitive (false);
channel_combo.set_sensitive (true);
instrument_combo.set_sensitive (false);
configuration_label.set_sensitive (true);
mode_label.set_sensitive (true);
instrument_label.set_sensitive (false);
break;
}
maybe_update_name_template_entry ();
}
string
AddRouteDialog::name_template () const
{
return name_template_entry.get_text ();
}
bool
AddRouteDialog::name_template_is_default() const
{
string n = name_template();
if (n == _("Audio") ||
n == _("MIDI") ||
n == _("Audio+MIDI") ||
n == _("Bus")) {
return true;
}
return false;
}
int
AddRouteDialog::count ()
{
return (int) floor (routes_adjustment.get_value ());
}
void
AddRouteDialog::refill_track_modes ()
{
vector<string> s;
s.push_back (_("Normal"));
if (!ARDOUR::Profile->get_sae ()) {
s.push_back (_("Non Layered"));
s.push_back (_("Tape"));
}
set_popdown_strings (mode_combo, s);
mode_combo.set_active_text (s.front());
}
ARDOUR::TrackMode
AddRouteDialog::mode ()
{
if (ARDOUR::Profile->get_sae()) {
return ARDOUR::Normal;
}
std::string str = mode_combo.get_active_text();
if (str == _("Normal")) {
return ARDOUR::Normal;
} else if (str == _("Non Layered")){
return ARDOUR::NonLayered;
} else if (str == _("Tape")) {
return ARDOUR::Destructive;
} else {
fatal << string_compose (X_("programming error: unknown track mode in add route dialog combo = %1"), str)
<< endmsg;
abort(); /*NOTREACHED*/
}
/* keep gcc happy */
return ARDOUR::Normal;
}
ChanCount
AddRouteDialog::channels ()
{
ChanCount ret;
string str;
switch (type_wanted()) {
case AudioTrack:
case AudioBus:
str = channel_combo.get_active_text();
for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
if (str == (*i).name) {
ret.set (DataType::AUDIO, (*i).channels);
break;
}
}
ret.set (DataType::MIDI, 0);
break;
case MidiTrack:
ret.set (DataType::AUDIO, 0);
ret.set (DataType::MIDI, 1);
break;
case MixedTrack:
str = channel_combo.get_active_text();
for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
if (str == (*i).name) {
ret.set (DataType::AUDIO, (*i).channels);
break;
}
}
ret.set (DataType::MIDI, 1);
break;
}
return ret;
}
string
AddRouteDialog::track_template ()
{
string str = channel_combo.get_active_text();
for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
if (str == (*i).name) {
return (*i).template_path;
}
}
return string();
}
void
AddRouteDialog::on_show ()
{
refill_channel_setups ();
refill_route_groups ();
Dialog::on_show ();
}
void
AddRouteDialog::refill_channel_setups ()
{
ChannelSetup chn;
route_templates.clear ();
channel_combo_strings.clear ();
channel_setups.clear ();
chn.name = _("Mono");
chn.channels = 1;
channel_setups.push_back (chn);
chn.name = _("Stereo");
chn.channels = 2;
channel_setups.push_back (chn);
chn.name = "separator";
channel_setups.push_back (chn);
ARDOUR::find_route_templates (route_templates);
if (!ARDOUR::Profile->get_sae()) {
if (!route_templates.empty()) {
vector<string> v;
for (vector<TemplateInfo>::iterator x = route_templates.begin(); x != route_templates.end(); ++x) {
chn.name = x->name;
chn.channels = 0;
chn.template_path = x->path;
channel_setups.push_back (chn);
}
}
/* clear template path for the rest */
chn.template_path = "";
chn.name = _("3 Channel");
chn.channels = 3;
channel_setups.push_back (chn);
chn.name = _("4 Channel");
chn.channels = 4;
channel_setups.push_back (chn);
chn.name = _("5 Channel");
chn.channels = 5;
channel_setups.push_back (chn);
chn.name = _("6 Channel");
chn.channels = 6;
channel_setups.push_back (chn);
chn.name = _("8 Channel");
chn.channels = 8;
channel_setups.push_back (chn);
chn.name = _("12 Channel");
chn.channels = 12;
channel_setups.push_back (chn);
chn.name = _("Custom");
chn.channels = 0;
channel_setups.push_back (chn);
}
for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
channel_combo_strings.push_back ((*i).name);
}
set_popdown_strings (channel_combo, channel_combo_strings);
channel_combo.set_active_text (channel_combo_strings.front());
}
void
AddRouteDialog::add_route_group (RouteGroup* g)
{
route_group_combo.insert_text (3, g->name ());
}
RouteGroup*
AddRouteDialog::route_group ()
{
if (!_session || route_group_combo.get_active_row_number () == 2) {
return 0;
}
return _session->route_group_by_name (route_group_combo.get_active_text());
}
void
AddRouteDialog::refill_route_groups ()
{
route_group_combo.clear ();
route_group_combo.append_text (_("New Group..."));
route_group_combo.append_text ("separator");
route_group_combo.append_text (_("No Group"));
if (_session) {
_session->foreach_route_group (sigc::mem_fun (*this, &AddRouteDialog::add_route_group));
}
route_group_combo.set_active (2);
}
void
AddRouteDialog::group_changed ()
{
if (_session && route_group_combo.get_active_text () == _("New Group...")) {
RouteGroup* g = new RouteGroup (*_session, "");
RouteGroupDialog d (g, true);
if (d.do_run ()) {
delete g;
route_group_combo.set_active (2);
} else {
if (_session) {
_session->add_route_group (g);
}
add_route_group (g);
route_group_combo.set_active (3);
}
}
}
AddRouteDialog::InsertAt
AddRouteDialog::insert_at ()
{
std::string str = insert_at_combo.get_active_text();
if (str == _("First")) {
return First;
} else if (str == _("After Selection")) {
return AfterSelection;
} else if (str == _("Before Selection")){
return BeforeSelection;
}
return Last;
}
bool
AddRouteDialog::channel_separator (const Glib::RefPtr<Gtk::TreeModel> &, const Gtk::TreeModel::iterator &i)
{
channel_combo.set_active (i);
return channel_combo.get_active_text () == "separator";
}
bool
AddRouteDialog::route_separator (const Glib::RefPtr<Gtk::TreeModel> &, const Gtk::TreeModel::iterator &i)
{
route_group_combo.set_active (i);
return route_group_combo.get_active_text () == "separator";
}
PluginInfoPtr
AddRouteDialog::requested_instrument ()
{
return instrument_combo.selected_instrument();
}