ardour/gtk2_ardour/strip_import_dialog.cc
2025-12-01 22:19:12 +01:00

748 lines
23 KiB
C++

/*
* Copyright (C) 2025 Robin Gareus <robin@gareus.org>
*
* 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 <ytkmm/sizegroup.h>
#include <ytkmm/stock.h>
#include "pbd/basename.h"
#include "pbd/file_utils.h"
#include "pbd/replace_all.h"
#include "ardour/directory_names.h"
#include "ardour/filename_extensions.h"
#include "ardour/filesystem_paths.h"
#include "ardour/recent_sessions.h"
#include "ardour/session.h"
#include "gtkmm2ext/utils.h"
#include "widgets/ardour_button.h"
#include "widgets/ardour_dropdown.h"
#include "widgets/ardour_spacer.h"
#include "strip_import_dialog.h"
#include "pbd/i18n.h"
using namespace Gtk;
using namespace std;
using namespace PBD;
using namespace ARDOUR;
using namespace ArdourWidgets;
StripImportDialog::StripImportDialog (Session* s)
: ArdourDialog (_("Import Track/Bus State"))
, _add_rid (0)
, _add_eid (0)
{
set_session (s);
_open_button = manage (new Button (Stock::GO_FORWARD));
_ok_button = manage (new Button (Stock::OK));
get_action_area ()->pack_start (_info_text);
add_button (Stock::CANCEL, RESPONSE_CANCEL);
get_action_area ()->pack_end (*_open_button);
get_action_area ()->pack_end (*_ok_button);
_open_button->show ();
_ok_button->hide ();
_open_button->signal_clicked ().connect (mem_fun (*this, &StripImportDialog::maybe_switch_to_import_page), false);
_ok_button->signal_clicked ().connect (mem_fun (*this, &StripImportDialog::ok_activated), false);
_open_button->set_sensitive (false);
_ok_button->set_sensitive (false);
get_vbox ()->pack_start (_page_file);
setup_file_page ();
}
StripImportDialog::~StripImportDialog ()
{
_notebook_connection.disconnect ();
_chooser_connection.disconnect ();
}
/* ****************************************************************************
* Page One .. pick file to import
*/
void
StripImportDialog::setup_file_page ()
{
/* file-chooser */
_chooser.set_size_request (450, 300);
_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir ()));
FileFilter tracks_filter;
tracks_filter.add_pattern (string_compose (X_("*%1"), routestate_suffix));
tracks_filter.set_name (string_compose (_("%1 tracks"), PROGRAM_NAME));
_chooser.add_filter (tracks_filter);
FileFilter template_filter;
template_filter.add_pattern (string_compose (X_("*%1"), template_suffix));
template_filter.set_name (string_compose (_("%1 tracks"), PROGRAM_NAME));
_chooser.add_filter (template_filter);
FileFilter session_filter;
session_filter.add_pattern (string_compose (X_("*%1"), ARDOUR::statefile_suffix));
session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
_chooser.add_filter (session_filter);
FileFilter all_filter;
all_filter.add_pattern (string_compose (X_("*%1"), ARDOUR::statefile_suffix));
all_filter.add_pattern (string_compose (X_("*%1"), template_suffix));
all_filter.add_pattern (string_compose (X_("*%1"), routestate_suffix));
all_filter.set_name (_("All supported files"));
_chooser.add_filter (all_filter);
_chooser.set_filter (all_filter);
Gtkmm2ext::add_volume_shortcuts (_chooser);
_chooser_connection = _chooser.signal_selection_changed ().connect (mem_fun (*this, &StripImportDialog::file_selection_changed));
_chooser.signal_file_activated ().connect (sigc::mem_fun (*this, &StripImportDialog::maybe_switch_to_import_page));
_notebook.append_page (_chooser, _("File"));
guint page = 1;
/* recent Sessions */
ARDOUR::RecentSessions rs;
ARDOUR::read_recent_sessions (rs);
if (!rs.empty ()) {
_recent_model = TreeStore::create (_columns);
/* setup model - compare to SessionDialog::redisplay_recent_sessions */
for (auto const& [_, dir] : rs) {
string dirname = dir;
if (dirname.empty ()) {
continue;
}
if (dirname[dirname.length () - 1] == '/') {
dirname = dirname.substr (0, dirname.length () - 1);
}
/* check whether session still exists */
if (!Glib::file_test (dirname, Glib::FILE_TEST_EXISTS)) {
/* session doesn't exist */
continue;
}
/* now get available states for this session */
vector<string> state_file_names = Session::possible_states (dirname);
if (state_file_names.empty ()) {
/* no state file? */
continue;
}
TreeModel::Row row = *(_recent_model->append ());
if (state_file_names.size () > 1) {
row[_columns.name] = PBD::basename_nosuffix (dirname);
row[_columns.path] = "";
for (auto const& snap : state_file_names) {
Gtk::TreeModel::Row child_row = *(_recent_model->append (row.children ()));
child_row[_columns.name] = snap;
child_row[_columns.path] = Glib::build_filename (dirname, snap + statefile_suffix);
}
} else {
row[_columns.name] = state_file_names.front ();
row[_columns.path] = Glib::build_filename (dirname, state_file_names.front () + statefile_suffix);
}
}
_recent_treeview.set_model (_recent_model);
_recent_treeview.append_column (_("Session Name"), _columns.name);
_recent_treeview.set_headers_visible (true);
_recent_treeview.get_selection ()->set_mode (SELECTION_SINGLE);
_recent_treeview.get_selection ()->signal_changed ().connect (sigc::bind (sigc::mem_fun (*this, &StripImportDialog::treeview_selection_changed), &_recent_treeview, Snapshot));
_recent_treeview.signal_row_activated ().connect ([&] (const TreeModel::Path&, TreeViewColumn*) { maybe_switch_to_import_page (); });
_recent_scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC);
_recent_scroller.add (_recent_treeview);
_notebook.append_page (_recent_scroller, _("Recent Sessions"));
_notebook_type[page] = Snapshot;
_notebook_content[page++] = &_recent_treeview;
}
/* template list */
vector<TemplateInfo> templates;
find_session_templates (templates, false);
if (templates.size () > 0) {
_template_model = ListStore::create (_columns);
setup_model (_template_model, templates);
_template_treeview.set_model (_template_model);
_template_treeview.append_column (_("Name"), _columns.name);
_template_treeview.set_headers_visible (true);
_template_treeview.get_selection ()->signal_changed ().connect (sigc::bind (sigc::mem_fun (*this, &StripImportDialog::treeview_selection_changed), &_template_treeview, Template));
_template_treeview.signal_row_activated ().connect ([&] (const TreeModel::Path&, TreeViewColumn*) { maybe_switch_to_import_page (); });
_template_scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC);
_template_scroller.add (_template_treeview);
_notebook.append_page (_template_scroller, _("Session Templates"));
_notebook_type[page] = Template;
_notebook_content[page++] = &_template_treeview;
}
templates.clear ();
Searchpath local_path (_session->path ());
local_path.add_subdirectory_to_paths (routestates_dir_name);
find_presets (local_path, templates);
if (templates.size () > 0) {
_local_pset_model = ListStore::create (_columns);
setup_model (_local_pset_model, templates);
_local_pset_treeview.set_model (_local_pset_model);
_local_pset_treeview.append_column (_("Name"), _columns.name);
_local_pset_treeview.set_headers_visible (true);
_local_pset_treeview.get_selection ()->signal_changed ().connect (sigc::bind (sigc::mem_fun (*this, &StripImportDialog::treeview_selection_changed), &_local_pset_treeview, RouteState));
_local_pset_treeview.signal_row_activated ().connect ([&] (const TreeModel::Path&, TreeViewColumn*) { maybe_switch_to_import_page (); });
_local_pset_scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC);
_local_pset_scroller.add (_local_pset_treeview);
_notebook.append_page (_local_pset_scroller, _("Local Strip Templates"));
_notebook_type[page] = RouteState;
_notebook_content[page++] = &_local_pset_treeview;
}
templates.clear ();
Searchpath global_path (ardour_data_search_path ());
global_path.add_subdirectory_to_paths (routestates_dir_name);
find_presets (global_path, templates);
if (templates.size () > 0) {
_global_pset_model = ListStore::create (_columns);
setup_model (_global_pset_model, templates);
_global_pset_treeview.set_model (_global_pset_model);
_global_pset_treeview.append_column (_("Name"), _columns.name);
_global_pset_treeview.set_headers_visible (true);
_global_pset_treeview.get_selection ()->signal_changed ().connect (sigc::bind (sigc::mem_fun (*this, &StripImportDialog::treeview_selection_changed), &_global_pset_treeview, RouteState));
_global_pset_treeview.signal_row_activated ().connect ([&] (const TreeModel::Path&, TreeViewColumn*) { maybe_switch_to_import_page (); });
_global_pset_scroller.set_policy (POLICY_AUTOMATIC, POLICY_AUTOMATIC);
_global_pset_scroller.add (_global_pset_treeview);
_notebook.append_page (_global_pset_scroller, _("Global Strip Templates"));
_notebook_type[page] = RouteState;
_notebook_content[page++] = &_global_pset_treeview;
}
_notebook_connection = _notebook.signal_switch_page ().connect (sigc::mem_fun (*this, &StripImportDialog::page_changed));
_page_file.pack_start (_notebook);
_page_file.show_all ();
if (!rs.empty ()) {
_notebook.set_current_page (1);
} else if (page > 1) {
_notebook.set_current_page (page - 1);
}
}
void
StripImportDialog::page_changed (GtkNotebookPage*, guint page)
{
switch (page) {
case 0:
file_selection_changed ();
break;
default:
treeview_selection_changed (_notebook_content.at (page), _notebook_type.at (page));
break;
}
}
void
StripImportDialog::setup_model (Glib::RefPtr<Gtk::ListStore> model, vector<TemplateInfo> const& templates)
{
for (auto const& t : templates) {
TreeModel::Row row;
row = *(model->append ());
row[_columns.name] = t.name;
row[_columns.path] = t.path;
}
}
void
StripImportDialog::find_presets (Searchpath const& search_path, vector<TemplateInfo>& template_info)
{
vector<string> templates;
/* clang-format off */
find_paths_matching_filter (templates,
search_path,
[] (const string& str, void*) { return Glib::file_test (str, Glib::FILE_TEST_IS_DIR); },
0, true, true);
/* clang-format on */
if (templates.empty ()) {
return;
}
for (vector<string>::iterator i = templates.begin (); i != templates.end (); ++i) {
string file = session_template_dir_to_file (*i);
TemplateInfo rti;
rti.name = Glib::path_get_basename (*i);
rti.path = *i;
template_info.push_back (rti);
}
std::sort (template_info.begin (), template_info.end ());
}
void
StripImportDialog::file_selection_changed ()
{
parse_route_state (_chooser.get_filename ());
}
static string
template_dir_to_file (string const& dir, string const& suffix)
{
return Glib::build_filename (dir, Glib::path_get_basename (dir) + suffix);
}
void
StripImportDialog::treeview_selection_changed (Gtk::TreeView* treeview, SelectionType t)
{
Gtk::TreeModel::const_iterator selection = treeview->get_selection ()->get_selected ();
if (selection) {
switch (t) {
case Template:
parse_route_state (template_dir_to_file ((*selection)[_columns.path], template_suffix));
break;
case RouteState:
parse_route_state (template_dir_to_file ((*selection)[_columns.path], routestate_suffix));
break;
case Snapshot:
parse_route_state ((*selection)[_columns.path]);
break;
}
} else {
parse_route_state ("");
}
}
void
StripImportDialog::parse_route_state (std::string const& path)
{
_extern_map.clear ();
_path = path;
if (path.empty ()) {
goto out;
}
if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
goto out;
}
_extern_map = _session->parse_route_state (path, _match_pbd_id);
out:
if (_extern_map.empty ()) {
_info_text.set_text ("");
_info_text.hide ();
} else {
_info_text.set_text (string_compose (P_("%1 Track", "%1 Tracks", _extern_map.size ()), _extern_map.size ()));
_info_text.show ();
}
_open_button->set_sensitive (!_extern_map.empty ());
}
void
StripImportDialog::maybe_switch_to_import_page ()
{
if (_extern_map.empty ()) {
return;
}
// TODO cleanup managed items on _page_file
/* -> next page */
setup_strip_import_page ();
get_vbox ()->remove (_page_file);
get_vbox ()->pack_start (_page_strip);
_info_text.hide ();
_open_button->hide ();
_ok_button->show ();
}
/* ****************************************************************************
* Page Two map Tracks/State
*/
void
StripImportDialog::refill_import_table ()
{
Gtk::Label* l;
Gtkmm2ext::container_clear (_strip_table, true);
_strip_table.set_spacings (3);
Glib::RefPtr<SizeGroup> col_size_group (SizeGroup::create (SIZE_GROUP_HORIZONTAL));
l = manage (new Label (string_compose ("<b>%1</b>", _("Local Track/Bus"))));
l->set_use_markup ();
_strip_table.attach (*l, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK);
col_size_group->add_widget (*l);
l = manage (new Label (string_compose ("<b>%1</b>", _("External State"))));
l->set_use_markup ();
_strip_table.attach (*l, 2, 3, 0, 1, Gtk::FILL, Gtk::SHRINK);
col_size_group->add_widget (*l);
/* clang-format off */
_strip_table.attach (*manage (new ArdourVSpacer (1.0)), 1, 2, 0, 1, SHRINK , EXPAND | FILL, 8, 4);
_strip_table.attach (*manage (new ArdourHSpacer (1.0)), 0, 4, 1, 2, EXPAND | FILL, SHRINK, 4, 8);
/* clang-format on */
const bool show_all_local_tracks = _show_all_toggle->get_active ();
std::vector<std::pair<PBD::ID, PBD::ID>> sorted_map;
if (show_all_local_tracks) {
for (auto const& r : _route_map) {
PBD::ID d (0);
try {
d = _import_map.at (r.first);
} catch (...) {}
sorted_map.push_back (make_pair (r.first, d));
}
for (auto const& i : _import_map) {
if (_route_map.find (i.first) == _route_map.end ()) {
sorted_map.push_back (i);
}
}
} else {
for (auto const& i : _import_map) {
sorted_map.push_back (i);
}
}
std::sort (sorted_map.begin (), sorted_map.end (), [=] (auto& a, auto& b) {
try {
return _route_map.at (a.first).pi.order () < _route_map.at (b.first).pi.order ();
} catch (...) {
}
return a.second < b.second;
});
/* Refill table */
int r = 1;
for (auto& [rid, eid] : sorted_map /*_import_map*/) {
bool is_new = _route_map.find (rid) == _route_map.end ();
if (!is_new) {
l = manage (new Label (_route_map.at (rid).name, 0, 0.5));
} else {
l = manage (new Label (_("<i>New Track</i>"), 0, 0.5));
l->set_use_markup ();
}
++r;
_strip_table.attach (*l, 0, 1, r, r + 1, EXPAND | FILL, SHRINK);
#if 0
l = manage (new Label (_extern_map[eid], 1.0, 0.5));
_strip_table.attach (*l, 2, 3, r, r + 1, EXPAND | FILL, SHRINK);
#else
using namespace Menu_Helpers;
ArdourDropdown* dd = manage (new ArdourDropdown ());
if (show_all_local_tracks) {
dd->add_menu_elem (MenuElem ("---", sigc::bind (sigc::mem_fun (*this, &StripImportDialog::change_mapping), dd, rid, PBD::ID (0), "---")));
}
for (auto& [eid, einfo] : _extern_map) {
dd->add_menu_elem (MenuElem (Gtkmm2ext::markup_escape_text (einfo.name), sigc::bind (sigc::mem_fun (*this, &StripImportDialog::change_mapping), dd, rid, eid, einfo.name)));
}
assert (show_all_local_tracks || _extern_map.find (eid) != _extern_map.end ());
try {
dd->set_text (_extern_map.at (eid).name);
} catch (std::out_of_range const&) {
dd->set_text ("---");
}
_strip_table.attach (*dd, 2, 3, r, r + 1, EXPAND | FILL, SHRINK);
#endif
if (show_all_local_tracks && !is_new) {
continue;
}
ArdourButton* rm = manage (new ArdourButton ());
rm->set_icon (ArdourIcon::CloseCross);
rm->set_tweaks (ArdourButton::TrackHeader);
rm->signal_clicked.connect (sigc::bind (sigc::mem_fun (*this, &StripImportDialog::remove_mapping), rid));
_strip_table.attach (*rm, 3, 4, r, r + 1, Gtk::SHRINK, Gtk::SHRINK, 4, 0);
}
if (r > 1) {
++r;
_strip_table.attach (*manage (new ArdourVSpacer (1.0)), 1, 2, 2, r, SHRINK, EXPAND | FILL, 8, 4);
++r;
_strip_table.attach (*manage (new ArdourHSpacer (1.0)), 0, 4, r, r + 1, EXPAND | FILL, SHRINK, 4, 8);
}
++r;
/* Add options */
using namespace Menu_Helpers;
_add_rid = PBD::ID (0);
_add_eid = PBD::ID (0);
int64_t next_id = std::numeric_limits<uint64_t>::max () - 1;
PBD::ID next_new = PBD::ID (next_id);
while (_import_map.find (next_new) != _import_map.end ()) {
--next_id;
next_new = PBD::ID (next_id);
}
/* accumulate both dropdowns, so columns are equally spaced */
std::vector<std::string> sizing_texts;
_add_rid_dropdown = manage (new ArdourWidgets::ArdourDropdown ());
_add_rid_dropdown->add_menu_elem (MenuElem (_(" -- New Track -- "), sigc::bind (sigc::mem_fun (*this, &StripImportDialog::prepare_mapping), false, next_new, _("New Track"))));
sizing_texts.push_back (_(" -- New Track -- "));
if (!show_all_local_tracks) {
for (auto& [rid, rinfo] : _route_map) {
if (_import_map.find (rid) != _import_map.end ()) {
continue;
}
_add_rid_dropdown->add_menu_elem (MenuElem (Gtkmm2ext::markup_escape_text (rinfo.name), sigc::bind (sigc::mem_fun (*this, &StripImportDialog::prepare_mapping), false, rid, rinfo.name)));
sizing_texts.push_back (rinfo.name);
}
}
_add_eid_dropdown = manage (new ArdourWidgets::ArdourDropdown ());
for (auto& [eid, einfo] : _extern_map) {
_add_eid_dropdown->add_menu_elem (MenuElem (Gtkmm2ext::markup_escape_text (einfo.name), sigc::bind (sigc::mem_fun (*this, &StripImportDialog::prepare_mapping), true, eid, einfo.name)));
sizing_texts.push_back (einfo.name);
}
_add_rid_dropdown->set_sizing_texts (sizing_texts);
_add_eid_dropdown->set_sizing_texts (sizing_texts);
col_size_group->add_widget (*_add_rid_dropdown);
col_size_group->add_widget (*_add_eid_dropdown);
_add_new_mapping = manage (new ArdourButton ());
_add_new_mapping->set_icon (ArdourIcon::PlusSign);
_add_new_mapping->set_tweaks (ArdourButton::TrackHeader);
_add_new_mapping->signal_clicked.connect (sigc::mem_fun (*this, &StripImportDialog::add_mapping));
/* clang-format off */
_strip_table.attach (*_add_rid_dropdown, 0, 1, r, r + 1, EXPAND | FILL, SHRINK);
_strip_table.attach (*_add_eid_dropdown, 2, 3, r, r + 1, EXPAND | FILL, SHRINK);
_strip_table.attach (*_add_new_mapping, 3, 4, r, r + 1, Gtk::SHRINK, SHRINK, 4, 0);
/* clang-format on */
bool can_add = !_add_rid_dropdown->items ().empty () && !_add_eid_dropdown->items ().empty ();
_add_rid_dropdown->set_sensitive (can_add);
_add_eid_dropdown->set_sensitive (can_add);
_add_new_mapping->set_sensitive (false);
_ok_button->set_sensitive (!_import_map.empty ());
_strip_table.show_all ();
}
void
StripImportDialog::idle_refill_import_table ()
{
Glib::signal_idle ().connect ([&] () { refill_import_table (); return false; }, Glib::PRIORITY_HIGH_IDLE + 10);
}
void
StripImportDialog::change_mapping (ArdourDropdown* dd, PBD::ID const& rid, PBD::ID const& eid, std::string const& name)
{
if (eid == PBD::ID (0)) {
_import_map.erase (rid);
} else {
_import_map[rid] = eid;
}
dd->set_text (name);
if (_show_all_toggle->get_active ()) {
idle_refill_import_table ();
}
}
void
StripImportDialog::prepare_mapping (bool ext, PBD::ID const& id, std::string const& name)
{
if (ext) {
_add_eid_dropdown->set_text (name);
_add_eid = id;
} else {
_add_rid_dropdown->set_text (name);
_add_rid = id;
}
_add_new_mapping->set_sensitive (_add_rid != PBD::ID (0) && _add_eid != PBD::ID (0));
}
void
StripImportDialog::add_mapping ()
{
assert (_add_rid != PBD::ID (0));
assert (_add_eid != PBD::ID (0));
_import_map[_add_rid] = _add_eid;
idle_refill_import_table ();
}
void
StripImportDialog::remove_mapping (PBD::ID const& id)
{
if (1 == _import_map.erase (id)) {
idle_refill_import_table ();
}
}
void
StripImportDialog::clear_mapping ()
{
_import_map.clear ();
idle_refill_import_table ();
}
void
StripImportDialog::import_all_strips ()
{
_import_map.clear ();
int64_t next_id = std::numeric_limits<uint64_t>::max () - 1 - _extern_map.size ();
for (auto& [eid, einfo] : _extern_map) {
if (einfo.pi.special () || einfo.pi.hidden ()) {
continue;
}
#ifdef MIXBUS
if (einfo.mixbus > 0) {
continue;
}
#endif
PBD::ID next_new = PBD::ID (next_id++);
_import_map[next_new] = eid;
}
idle_refill_import_table ();
}
void
StripImportDialog::set_default_mapping (bool and_idle_update)
{
_import_map.clear ();
if (_match_pbd_id) {
/* try a 1:1 mapping */
for (auto& [eid, einfo] : _extern_map) {
if (_route_map.find (eid) != _route_map.end ()) {
_import_map[eid] = eid;
}
}
} else {
/* match by name */
for (auto& [eid, einfo] : _extern_map) {
// TODO consider building a reverse [pointer] map
for (auto& [rid, rinfo] : _route_map) {
#ifdef MIXBUS
if (einfo.mixbus > 0 && einfo.mixbus == rinfo.mixbus) {
_import_map[rid] = eid;
break;
}
#endif
if (einfo == rinfo) {
_import_map[rid] = eid;
break;
}
}
}
}
if (and_idle_update) {
idle_refill_import_table ();
}
}
void
StripImportDialog::setup_strip_import_page ()
{
_route_map.clear ();
for (auto const& r : *_session->get_routes ()) {
#ifdef MIXBUS
_route_map.emplace (r->id (), Session::RouteImportInfo (r->name (), r->presentation_info (), r->mixbus ()));
#else
_route_map.emplace (r->id (), Session::RouteImportInfo (r->name (), r->presentation_info (), 0));
#endif
}
using namespace Menu_Helpers;
_action = manage (new ArdourWidgets::ArdourDropdown ());
_action->add_menu_elem (MenuElem (_("Clear Mapping"), sigc::mem_fun (*this, &StripImportDialog::clear_mapping)));
_action->add_menu_elem (MenuElem (_("Import all as new tracks"), sigc::mem_fun (*this, &StripImportDialog::import_all_strips)));
_action->add_menu_elem (MenuElem (_match_pbd_id ? _("Reset - auto-map by ID") : _("Reset - auto-map by name"), sigc::bind (mem_fun (*this, &StripImportDialog::set_default_mapping), true)));
_action->set_text (_("Actions"));
_show_all_toggle = new ArdourButton (_("Show all local tracks"), ArdourButton::led_default_elements, true);
_show_all_toggle->set_led_left (true);
_show_all_toggle->set_can_focus (true);
_show_all_toggle->signal_clicked.connect (mem_fun (*this, &StripImportDialog::refill_import_table));
HBox* hbox = manage (new HBox ());
hbox->set_spacing (4);
hbox->pack_start (*_action, true, false);
hbox->pack_start (*_show_all_toggle, true, false);
VBox* vbox = manage (new VBox ());
vbox->pack_start (_strip_table, false, false, 4);
_strip_scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
_strip_scroller.add (*vbox);
_page_strip.set_spacing (4);
_page_strip.pack_start (_strip_scroller);
_page_strip.pack_end (*hbox, false, false, 4);
_page_strip.show_all ();
_ok_button->set_sensitive (true);
set_default_mapping (false);
refill_import_table ();
}
void
StripImportDialog::ok_activated ()
{
_session->import_route_state (_path, _import_map);
ArdourDialog::on_response (RESPONSE_ACCEPT);
}