mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-16 11:46:25 +01:00
merge 12717:12954 from svn+ssh://ardoursvn@subversion.ardour.org/ardour2/branches/3.0
git-svn-id: svn://localhost/ardour2/branches/3.0-SG@12955 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
f1fd9c7bdc
commit
6e824e7797
174 changed files with 2923 additions and 2899 deletions
|
|
@ -164,6 +164,7 @@ static const char* authors[] = {
|
|||
N_("Taybin Rutkin"),
|
||||
N_("Andreas Ruge"),
|
||||
N_("Sampo Savolainen"),
|
||||
N_("Rodrigo Severo"),
|
||||
N_("Per Sigmond"),
|
||||
N_("Lincoln Spiteri"),
|
||||
N_("Mike Start"),
|
||||
|
|
@ -201,7 +202,7 @@ static const char* translators[] = {
|
|||
|
||||
static const char* gpl = X_("\n\
|
||||
Ardour comes with NO WARRANTY. It is free software, and you are welcome to redistribute it\n\
|
||||
under the terms of the GNU Public License, shown below.\n\
|
||||
under the terms of the GNU General Public License, shown below.\n\
|
||||
\n\
|
||||
GNU GENERAL PUBLIC LICENSE\n\
|
||||
Version 2, June 1991\n\
|
||||
|
|
@ -553,15 +554,14 @@ About::About ()
|
|||
{
|
||||
// set_type_hint(Gdk::WINDOW_TYPE_HINT_SPLASHSCREEN);
|
||||
|
||||
string path;
|
||||
string t;
|
||||
|
||||
sys::path splash_file;
|
||||
std::string splash_file;
|
||||
|
||||
SearchPath spath(ardour_data_search_path());
|
||||
|
||||
if (find_file_in_search_path (spath, "splash.png", splash_file)) {
|
||||
set_logo (Gdk::Pixbuf::create_from_file (splash_file.to_string()));
|
||||
set_logo (Gdk::Pixbuf::create_from_file (splash_file));
|
||||
} else {
|
||||
error << "Could not find splash file" << endmsg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ vector<RefPtr<Gtk::Action> > ActionManager::edit_point_in_region_sensitive_actio
|
|||
void
|
||||
ActionManager::init ()
|
||||
{
|
||||
sys::path ui_file;
|
||||
std::string ui_file;
|
||||
|
||||
ui_manager = UIManager::create ();
|
||||
|
||||
|
|
@ -76,8 +76,8 @@ ActionManager::init ()
|
|||
bool loaded = false;
|
||||
|
||||
try {
|
||||
ui_manager->add_ui_from_file (ui_file.to_string());
|
||||
info << string_compose (_("Loading menus from %1"), ui_file.to_string()) << endmsg;
|
||||
ui_manager->add_ui_from_file (ui_file);
|
||||
info << string_compose (_("Loading menus from %1"), ui_file) << endmsg;
|
||||
loaded = true;
|
||||
} catch (Glib::MarkupError& err) {
|
||||
error << string_compose (_("badly formatted UI definition file: %1"), err.what()) << endmsg;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ AddRouteDialog::AddRouteDialog (Session* s)
|
|||
|
||||
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);
|
||||
|
||||
|
|
@ -191,6 +192,23 @@ AddRouteDialog::channel_combo_changed ()
|
|||
refill_track_modes ();
|
||||
}
|
||||
|
||||
AddRouteDialog::TypeWanted
|
||||
AddRouteDialog::type_wanted() const
|
||||
{
|
||||
switch (track_bus_combo.get_active_row_number ()) {
|
||||
case 0:
|
||||
return AudioTrack;
|
||||
case 1:
|
||||
return MidiTrack;
|
||||
case 2:
|
||||
return MixedTrack;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return AudioBus;
|
||||
}
|
||||
|
||||
void
|
||||
AddRouteDialog::maybe_update_name_template_entry ()
|
||||
{
|
||||
|
|
@ -198,59 +216,68 @@ AddRouteDialog::maybe_update_name_template_entry ()
|
|||
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;
|
||||
}
|
||||
|
||||
if (audio_tracks_wanted ()) {
|
||||
switch (type_wanted()) {
|
||||
case AudioTrack:
|
||||
name_template_entry.set_text (_("Audio"));
|
||||
} else if (midi_tracks_wanted()) {
|
||||
break;
|
||||
case MidiTrack:
|
||||
name_template_entry.set_text (_("MIDI"));
|
||||
} else {
|
||||
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 ()
|
||||
{
|
||||
if (midi_tracks_wanted()) {
|
||||
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);
|
||||
} else if (audio_tracks_wanted()) {
|
||||
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);
|
||||
} else {
|
||||
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:
|
||||
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 ();
|
||||
}
|
||||
|
||||
bool
|
||||
AddRouteDialog::audio_tracks_wanted ()
|
||||
{
|
||||
return track_bus_combo.get_active_row_number () == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
AddRouteDialog::midi_tracks_wanted ()
|
||||
{
|
||||
return track_bus_combo.get_active_row_number () == 1;
|
||||
}
|
||||
|
||||
string
|
||||
AddRouteDialog::name_template ()
|
||||
|
|
@ -303,18 +330,42 @@ AddRouteDialog::mode ()
|
|||
return ARDOUR::Normal;
|
||||
}
|
||||
|
||||
int
|
||||
ChanCount
|
||||
AddRouteDialog::channels ()
|
||||
{
|
||||
string str = channel_combo.get_active_text();
|
||||
|
||||
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) {
|
||||
return (*i).channels;
|
||||
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 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
string
|
||||
|
|
|
|||
|
|
@ -48,9 +48,15 @@ class AddRouteDialog : public ArdourDialog
|
|||
AddRouteDialog (ARDOUR::Session*);
|
||||
~AddRouteDialog ();
|
||||
|
||||
bool audio_tracks_wanted ();
|
||||
bool midi_tracks_wanted ();
|
||||
int channels ();
|
||||
enum TypeWanted {
|
||||
AudioTrack,
|
||||
MidiTrack,
|
||||
MixedTrack,
|
||||
AudioBus
|
||||
};
|
||||
TypeWanted type_wanted() const;
|
||||
|
||||
ARDOUR::ChanCount channels ();
|
||||
int count ();
|
||||
|
||||
std::string name_template ();
|
||||
|
|
|
|||
|
|
@ -753,12 +753,6 @@ void
|
|||
ARDOUR_UI::finish()
|
||||
{
|
||||
if (_session) {
|
||||
int tries = 0;
|
||||
|
||||
if (_session->transport_rolling() && (++tries < 8)) {
|
||||
_session->request_stop (false, true);
|
||||
usleep (10000);
|
||||
}
|
||||
|
||||
if (_session->dirty()) {
|
||||
vector<string> actions;
|
||||
|
|
@ -1116,7 +1110,7 @@ ARDOUR_UI::update_wall_clock ()
|
|||
void
|
||||
ARDOUR_UI::redisplay_recent_sessions ()
|
||||
{
|
||||
std::vector<sys::path> session_directories;
|
||||
std::vector<std::string> session_directories;
|
||||
RecentSessionsSorter cmp;
|
||||
|
||||
recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
|
||||
|
|
@ -1137,10 +1131,10 @@ ARDOUR_UI::redisplay_recent_sessions ()
|
|||
session_directories.push_back ((*i).second);
|
||||
}
|
||||
|
||||
for (vector<sys::path>::const_iterator i = session_directories.begin();
|
||||
for (vector<std::string>::const_iterator i = session_directories.begin();
|
||||
i != session_directories.end(); ++i)
|
||||
{
|
||||
std::vector<sys::path> state_file_paths;
|
||||
std::vector<std::string> state_file_paths;
|
||||
|
||||
// now get available states for this session
|
||||
|
||||
|
|
@ -1148,7 +1142,7 @@ ARDOUR_UI::redisplay_recent_sessions ()
|
|||
|
||||
vector<string*>* states;
|
||||
vector<const gchar*> item;
|
||||
string fullpath = i->to_string();
|
||||
string fullpath = *i;
|
||||
|
||||
/* remove any trailing / */
|
||||
|
||||
|
|
@ -1366,7 +1360,8 @@ ARDOUR_UI::open_session ()
|
|||
|
||||
|
||||
void
|
||||
ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many, const string& name_template, PluginInfoPtr instrument)
|
||||
ARDOUR_UI::session_add_mixed_track (const ChanCount& input, const ChanCount& output, RouteGroup* route_group,
|
||||
uint32_t how_many, const string& name_template, PluginInfoPtr instrument)
|
||||
{
|
||||
list<boost::shared_ptr<MidiTrack> > tracks;
|
||||
|
||||
|
|
@ -1376,19 +1371,15 @@ ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t
|
|||
}
|
||||
|
||||
try {
|
||||
if (disk) {
|
||||
|
||||
tracks = _session->new_midi_track (instrument, ARDOUR::Normal, route_group, how_many, name_template);
|
||||
tracks = _session->new_midi_track (input, output, instrument, ARDOUR::Normal, route_group, how_many, name_template);
|
||||
|
||||
if (tracks.size() != how_many) {
|
||||
if (how_many == 1) {
|
||||
error << _("could not create a new midi track") << endmsg;
|
||||
error << _("could not create a new mixed track") << endmsg;
|
||||
} else {
|
||||
error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
|
||||
error << string_compose (_("could not create %1 new mixed tracks"), how_many) << endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
catch (...) {
|
||||
|
|
@ -1402,6 +1393,17 @@ restart JACK with more ports."), PROGRAM_NAME));
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many, const string& name_template, PluginInfoPtr instrument)
|
||||
{
|
||||
ChanCount one_midi_channel;
|
||||
one_midi_channel.set (DataType::MIDI, 1);
|
||||
|
||||
if (disk) {
|
||||
session_add_mixed_track (one_midi_channel, one_midi_channel, route_group, how_many, name_template, instrument);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::session_add_audio_route (
|
||||
bool track,
|
||||
|
|
@ -2072,7 +2074,7 @@ ARDOUR_UI::snapshot_session (bool switch_to_it)
|
|||
}
|
||||
}
|
||||
|
||||
vector<sys::path> p;
|
||||
vector<std::string> p;
|
||||
get_state_files_in_directory (_session->session_directory().root_path(), p);
|
||||
vector<string> n = get_file_names_no_extension (p);
|
||||
if (find (n.begin(), n.end(), snapname) != n.end()) {
|
||||
|
|
@ -2911,7 +2913,7 @@ require some unused files to continue to exist."));
|
|||
|
||||
dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
|
||||
|
||||
const string dead_directory = _session->session_directory().dead_path().to_string();
|
||||
const string dead_directory = _session->session_directory().dead_path();
|
||||
|
||||
/* subst:
|
||||
%1 - number of files removed
|
||||
|
|
@ -3125,8 +3127,8 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
|
|||
return;
|
||||
}
|
||||
|
||||
uint32_t input_chan = add_route_dialog->channels ();
|
||||
uint32_t output_chan;
|
||||
ChanCount input_chan= add_route_dialog->channels ();
|
||||
ChanCount output_chan;
|
||||
string name_template = add_route_dialog->name_template ();
|
||||
PluginInfoPtr instrument = add_route_dialog->requested_instrument ();
|
||||
RouteGroup* route_group = add_route_dialog->route_group ();
|
||||
|
|
@ -3134,19 +3136,27 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
|
|||
AutoConnectOption oac = Config->get_output_auto_connect();
|
||||
|
||||
if (oac & AutoConnectMaster) {
|
||||
output_chan = (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan);
|
||||
output_chan.set (DataType::AUDIO, (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan.n_audio()));
|
||||
output_chan.set (DataType::MIDI, 0);
|
||||
} else {
|
||||
output_chan = input_chan;
|
||||
}
|
||||
|
||||
/* XXX do something with name template */
|
||||
|
||||
if (add_route_dialog->midi_tracks_wanted()) {
|
||||
switch (add_route_dialog->type_wanted()) {
|
||||
case AddRouteDialog::AudioTrack:
|
||||
session_add_audio_track (input_chan.n_audio(), output_chan.n_audio(), add_route_dialog->mode(), route_group, count, name_template);
|
||||
break;
|
||||
case AddRouteDialog::MidiTrack:
|
||||
session_add_midi_track (route_group, count, name_template, instrument);
|
||||
} else if (add_route_dialog->audio_tracks_wanted()) {
|
||||
session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count, name_template);
|
||||
} else {
|
||||
session_add_audio_bus (input_chan, output_chan, route_group, count, name_template);
|
||||
break;
|
||||
case AddRouteDialog::MixedTrack:
|
||||
session_add_mixed_track (input_chan, output_chan, route_group, count, name_template, instrument);
|
||||
break;
|
||||
case AddRouteDialog::AudioBus:
|
||||
session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -231,6 +231,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
session_add_midi_route (true, route_group, how_many, name_template, instrument);
|
||||
}
|
||||
|
||||
void session_add_mixed_track (const ARDOUR::ChanCount& input, const ARDOUR::ChanCount& output, ARDOUR::RouteGroup* route_group, uint32_t how_many, std::string const & name_template,
|
||||
ARDOUR::PluginInfoPtr instrument);
|
||||
|
||||
/*void session_add_midi_bus () {
|
||||
session_add_midi_route (false);
|
||||
}*/
|
||||
|
|
@ -256,8 +259,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
void get_process_buffers ();
|
||||
void drop_process_buffers ();
|
||||
|
||||
void goto_editor_window ();
|
||||
|
||||
protected:
|
||||
friend class PublicEditor;
|
||||
|
||||
|
|
@ -283,6 +284,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
ARDOUR::AudioEngine *engine;
|
||||
Gtk::Tooltips _tooltips;
|
||||
|
||||
void goto_editor_window ();
|
||||
void goto_mixer_window ();
|
||||
void toggle_mixer_window ();
|
||||
void toggle_mixer_on_top ();
|
||||
|
|
|
|||
|
|
@ -133,25 +133,21 @@ ARDOUR_UI::toggle_mixer_window ()
|
|||
void
|
||||
ARDOUR_UI::toggle_mixer_on_top ()
|
||||
{
|
||||
/* Only called if the editor window received the shortcut key or if selected
|
||||
from the editor window menu, so the mixer is definitely not on top, and
|
||||
we can unconditionally make it so here.
|
||||
|
||||
XXX this might not work so well where there is a global menu bar, e.g.
|
||||
on OS X.
|
||||
*/
|
||||
|
||||
/* Toggle the mixer to `visible' if required */
|
||||
if (gtk_window_is_active(Mixer_UI::instance()->gobj())) {
|
||||
goto_editor_window ();
|
||||
} else {
|
||||
Glib::RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-mixer"));
|
||||
if (act) {
|
||||
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
|
||||
|
||||
if (!tact->get_active()) {
|
||||
/* Toggle the mixer to `visible' if required */
|
||||
if (!tact->get_active ()) {
|
||||
tact->set_active (true);
|
||||
}
|
||||
}
|
||||
|
||||
goto_mixer_window ();
|
||||
}
|
||||
}
|
||||
|
||||
/** The main editor window has been closed */
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ ARDOUR_UI::install_actions ()
|
|||
|
||||
#ifdef WITH_CMT
|
||||
|
||||
sys::path anicomp_file_path;
|
||||
std::string anicomp_file_path;
|
||||
|
||||
if (PBD::find_file_in_search_path (Glib::getenv("PATH"), "AniComp", anicomp_file_path)) {
|
||||
act = ActionManager::register_action (main_actions, X_("aniConnect"), _("Connect"), (sigc::mem_fun (*editor, &PublicEditor::connect_to_image_compositor)));
|
||||
|
|
|
|||
|
|
@ -568,12 +568,13 @@ AUPluginUI::parent_carbon_window ()
|
|||
|
||||
int packing_extra = 6; // this is the total vertical packing in our top level window
|
||||
|
||||
MoveWindow (carbon_window, x, y + titlebar_height + top_box.get_height() + packing_extra, false);
|
||||
ShowWindow (carbon_window);
|
||||
|
||||
// create the cocoa window for the carbon one and make it visible
|
||||
cocoa_parent = [[NSWindow alloc] initWithWindowRef: carbon_window];
|
||||
|
||||
PositionWindow (carbon_window, [cocoa_parent windowRef], kWindowCascadeStartAtParentWindowScreen);
|
||||
MoveWindow (carbon_window, x, y + titlebar_height + top_box.get_height() + packing_extra, false);
|
||||
ShowWindow (carbon_window);
|
||||
|
||||
SetWindowActivationScope (carbon_window, kWindowActivationScopeNone);
|
||||
|
||||
_notify = [ [NotificationObject alloc] initWithPluginUI:this andCocoaParent:cocoa_parent andTopLevelParent:win ];
|
||||
|
|
|
|||
|
|
@ -221,6 +221,8 @@ BundleEditor::BundleEditor (Session* session, boost::shared_ptr<UserBundle> bund
|
|||
|
||||
add_button (Gtk::Stock::CLOSE, Gtk::RESPONSE_ACCEPT);
|
||||
show_all ();
|
||||
|
||||
signal_key_press_event().connect (sigc::mem_fun (_matrix, &BundleEditorMatrix::key_press));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -214,18 +214,22 @@ show_me_the_size (Requisition* r, const char* what)
|
|||
cerr << "size of " << what << " = " << r->width << " x " << r->height << endl;
|
||||
}
|
||||
|
||||
#ifdef GTKOSX
|
||||
static void
|
||||
pane_size_watcher (Paned* pane)
|
||||
{
|
||||
/* if the handle of a pane vanishes into (at least) the tabs of a notebook,
|
||||
it is no longer accessible. so stop that. this doesn't happen on X11,
|
||||
just the quartz backend.
|
||||
it is:
|
||||
|
||||
X: hard to access
|
||||
Quartz: impossible to access
|
||||
|
||||
so stop that by preventing it from ever getting too narrow. 35
|
||||
pixels is basically a rough guess at the tab width.
|
||||
|
||||
ugh.
|
||||
*/
|
||||
|
||||
int max_width_of_lhs = GTK_WIDGET(pane->gobj())->allocation.width - 25;
|
||||
int max_width_of_lhs = GTK_WIDGET(pane->gobj())->allocation.width - 35;
|
||||
|
||||
gint pos = pane->get_position ();
|
||||
|
||||
|
|
@ -233,7 +237,6 @@ pane_size_watcher (Paned* pane)
|
|||
pane->set_position (max_width_of_lhs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Editor::Editor ()
|
||||
: _join_object_range_state (JOIN_OBJECT_RANGE_NONE)
|
||||
|
|
@ -602,13 +605,13 @@ Editor::Editor ()
|
|||
|
||||
editor_summary_pane.signal_size_allocate().connect (sigc::bind (sigc::mem_fun (*this, &Editor::pane_allocation_handler), static_cast<Paned*> (&editor_summary_pane)));
|
||||
|
||||
/* XXX: editor_summary_pane might need similar special OS X treatment to the edit_pane */
|
||||
/* XXX: editor_summary_pane might need similar to the edit_pane */
|
||||
|
||||
edit_pane.signal_size_allocate().connect (sigc::bind (sigc::mem_fun(*this, &Editor::pane_allocation_handler), static_cast<Paned*> (&edit_pane)));
|
||||
#ifdef GTKOSX
|
||||
|
||||
Glib::PropertyProxy<int> proxy = edit_pane.property_position();
|
||||
proxy.signal_changed().connect (bind (sigc::ptr_fun (pane_size_watcher), static_cast<Paned*> (&edit_pane)));
|
||||
#endif
|
||||
|
||||
top_hbox.pack_start (toolbar_frame);
|
||||
|
||||
HBox *hbox = manage (new HBox);
|
||||
|
|
@ -917,12 +920,9 @@ Editor::zoom_adjustment_changed ()
|
|||
}
|
||||
|
||||
double fpu = zoom_range_clock->current_duration() / _canvas_width;
|
||||
bool clamped = clamp_frames_per_unit (fpu);
|
||||
|
||||
if (fpu < 1.0) {
|
||||
fpu = 1.0;
|
||||
zoom_range_clock->set ((framepos_t) floor (fpu * _canvas_width));
|
||||
} else if (fpu > _session->current_end_frame() / _canvas_width) {
|
||||
fpu = _session->current_end_frame() / _canvas_width;
|
||||
if (clamped) {
|
||||
zoom_range_clock->set ((framepos_t) floor (fpu * _canvas_width));
|
||||
}
|
||||
|
||||
|
|
@ -1271,7 +1271,7 @@ Editor::set_session (Session *t)
|
|||
_session->StepEditStatusChange.connect (_session_connections, invalidator (*this), boost::bind (&Editor::step_edit_status_change, this, _1), gui_context());
|
||||
_session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&Editor::map_transport_state, this), gui_context());
|
||||
_session->PositionChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::map_position_change, this, _1), gui_context());
|
||||
_session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Editor::handle_new_route, this, _1), gui_context());
|
||||
_session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Editor::add_routes, this, _1), gui_context());
|
||||
_session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::update_title, this), gui_context());
|
||||
_session->tempo_map().PropertyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::tempo_map_changed, this, _1), gui_context());
|
||||
_session->Located.connect (_session_connections, invalidator (*this), boost::bind (&Editor::located, this), gui_context());
|
||||
|
|
@ -4048,19 +4048,31 @@ Editor::on_key_release_event (GdkEventKey* ev)
|
|||
void
|
||||
Editor::reset_x_origin (framepos_t frame)
|
||||
{
|
||||
queue_visual_change (frame);
|
||||
pending_visual_change.add (VisualChange::TimeOrigin);
|
||||
pending_visual_change.time_origin = frame;
|
||||
ensure_visual_change_idle_handler ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::reset_y_origin (double y)
|
||||
{
|
||||
queue_visual_change_y (y);
|
||||
pending_visual_change.add (VisualChange::YOrigin);
|
||||
pending_visual_change.y_origin = y;
|
||||
ensure_visual_change_idle_handler ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::reset_zoom (double fpu)
|
||||
{
|
||||
queue_visual_change (fpu);
|
||||
clamp_frames_per_unit (fpu);
|
||||
|
||||
if (fpu == frames_per_unit) {
|
||||
return;
|
||||
}
|
||||
|
||||
pending_visual_change.add (VisualChange::ZoomLevel);
|
||||
pending_visual_change.frames_per_unit = fpu;
|
||||
ensure_visual_change_idle_handler ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4165,41 +4177,20 @@ Editor::use_visual_state (VisualState& vs)
|
|||
_routes->resume_redisplay ();
|
||||
}
|
||||
|
||||
/** This is the core function that controls the zoom level of the canvas. It is called
|
||||
* whenever one or more calls are made to reset_zoom(). It executes in an idle handler.
|
||||
* @param fpu New frames per unit; should already have been clamped so that it is sensible.
|
||||
*/
|
||||
void
|
||||
Editor::set_frames_per_unit (double fpu)
|
||||
{
|
||||
/* this is the core function that controls the zoom level of the canvas. it is called
|
||||
whenever one or more calls are made to reset_zoom(). it executes in an idle handler.
|
||||
*/
|
||||
|
||||
if (fpu == frames_per_unit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fpu < 2.0) {
|
||||
fpu = 2.0;
|
||||
}
|
||||
|
||||
|
||||
/* don't allow zooms that fit more than the maximum number
|
||||
of frames into an 800 pixel wide space.
|
||||
*/
|
||||
|
||||
if (max_framepos / fpu < 800.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tempo_lines)
|
||||
if (tempo_lines) {
|
||||
tempo_lines->tempo_map_changed();
|
||||
}
|
||||
|
||||
frames_per_unit = fpu;
|
||||
post_zoom ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::post_zoom ()
|
||||
{
|
||||
// convert fpu to frame count
|
||||
/* convert fpu to frame count */
|
||||
|
||||
framepos_t frames = (framepos_t) floor (frames_per_unit * _canvas_width);
|
||||
|
||||
|
|
@ -4233,32 +4224,6 @@ Editor::post_zoom ()
|
|||
instant_save ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::queue_visual_change (framepos_t where)
|
||||
{
|
||||
pending_visual_change.add (VisualChange::TimeOrigin);
|
||||
pending_visual_change.time_origin = where;
|
||||
ensure_visual_change_idle_handler ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::queue_visual_change (double fpu)
|
||||
{
|
||||
pending_visual_change.add (VisualChange::ZoomLevel);
|
||||
pending_visual_change.frames_per_unit = fpu;
|
||||
|
||||
ensure_visual_change_idle_handler ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::queue_visual_change_y (double y)
|
||||
{
|
||||
pending_visual_change.add (VisualChange::YOrigin);
|
||||
pending_visual_change.y_origin = y;
|
||||
|
||||
ensure_visual_change_idle_handler ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::ensure_visual_change_idle_handler ()
|
||||
{
|
||||
|
|
@ -4276,6 +4241,18 @@ Editor::_idle_visual_changer (void* arg)
|
|||
int
|
||||
Editor::idle_visual_changer ()
|
||||
{
|
||||
/* set_horizontal_position() below (and maybe other calls) call
|
||||
gtk_main_iteration(), so it's possible that a signal will be handled
|
||||
half-way through this method. If this signal wants an
|
||||
idle_visual_changer we must schedule another one after this one, so
|
||||
mark the idle_handler_id as -1 here to allow that. Also make a note
|
||||
that we are doing the visual change, so that changes in response to
|
||||
super-rapid-screen-update can be dropped if we are still processing
|
||||
the last one.
|
||||
*/
|
||||
pending_visual_change.idle_handler_id = -1;
|
||||
pending_visual_change.being_handled = true;
|
||||
|
||||
VisualChange::Type p = pending_visual_change.pending;
|
||||
pending_visual_change.pending = (VisualChange::Type) 0;
|
||||
|
||||
|
|
@ -4304,7 +4281,7 @@ Editor::idle_visual_changer ()
|
|||
|
||||
_summary->set_overlays_dirty ();
|
||||
|
||||
pending_visual_change.idle_handler_id = -1;
|
||||
pending_visual_change.being_handled = false;
|
||||
return 0; /* this is always a one-shot call */
|
||||
}
|
||||
|
||||
|
|
@ -4808,9 +4785,8 @@ Editor::axis_views_from_routes (boost::shared_ptr<RouteList> r) const
|
|||
return t;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Editor::handle_new_route (RouteList& routes)
|
||||
Editor::add_routes (RouteList& routes)
|
||||
{
|
||||
ENSURE_GUI_THREAD (*this, &Editor::handle_new_route, routes)
|
||||
|
||||
|
|
@ -4820,7 +4796,7 @@ Editor::handle_new_route (RouteList& routes)
|
|||
for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
|
||||
boost::shared_ptr<Route> route = (*x);
|
||||
|
||||
if (route->is_hidden() || route->is_monitor()) {
|
||||
if (route->is_hidden()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -5226,7 +5202,14 @@ Editor::super_rapid_screen_update ()
|
|||
|
||||
if (!_stationary_playhead) {
|
||||
|
||||
if (!_dragging_playhead && _follow_playhead && _session->requested_return_frame() < 0) {
|
||||
if (!_dragging_playhead && _follow_playhead && _session->requested_return_frame() < 0 && !pending_visual_change.being_handled) {
|
||||
/* We only do this if we aren't already
|
||||
handling a visual change (ie if
|
||||
pending_visual_change.being_handled is
|
||||
false) so that these requests don't stack
|
||||
up there are too many of them to handle in
|
||||
time.
|
||||
*/
|
||||
reset_x_origin_to_follow_playhead ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ namespace ARDOUR {
|
|||
class Region;
|
||||
class Location;
|
||||
class TempoSection;
|
||||
class NamedSelection;
|
||||
class Session;
|
||||
class Filter;
|
||||
class ChanCount;
|
||||
|
|
@ -525,7 +524,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
Editing::ZoomFocus zoom_focus;
|
||||
|
||||
void set_frames_per_unit (double);
|
||||
void post_zoom ();
|
||||
bool clamp_frames_per_unit (double &) const;
|
||||
|
||||
Editing::MouseMode mouse_mode;
|
||||
Editing::MouseMode pre_internal_mouse_mode;
|
||||
|
|
@ -705,7 +704,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
void popup_control_point_context_menu (ArdourCanvas::Item *, GdkEvent *);
|
||||
Gtk::Menu _control_point_context_menu;
|
||||
|
||||
void handle_new_route (ARDOUR::RouteList&);
|
||||
void add_routes (ARDOUR::RouteList&);
|
||||
void timeaxisview_deleted (TimeAxisView *);
|
||||
|
||||
Gtk::HBox global_hpacker;
|
||||
|
|
@ -1029,22 +1028,19 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
double y_origin;
|
||||
|
||||
int idle_handler_id;
|
||||
/** true if we are currently in the idle handler */
|
||||
bool being_handled;
|
||||
|
||||
VisualChange() : pending ((VisualChange::Type) 0), time_origin (0), frames_per_unit (0), idle_handler_id (-1) {}
|
||||
VisualChange() : pending ((VisualChange::Type) 0), time_origin (0), frames_per_unit (0), idle_handler_id (-1), being_handled (false) {}
|
||||
void add (Type t) {
|
||||
pending = Type (pending | t);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
VisualChange pending_visual_change;
|
||||
|
||||
static int _idle_visual_changer (void *arg);
|
||||
int idle_visual_changer ();
|
||||
|
||||
void queue_visual_change (framepos_t);
|
||||
void queue_visual_change (double);
|
||||
void queue_visual_change_y (double);
|
||||
void ensure_visual_change_idle_handler ();
|
||||
|
||||
/* track views */
|
||||
|
|
@ -1213,7 +1209,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
void temporal_zoom_region (bool both_axes);
|
||||
void zoom_to_region (bool both_axes);
|
||||
void temporal_zoom_session ();
|
||||
void temporal_zoom (gdouble scale);
|
||||
void temporal_zoom (double scale);
|
||||
void temporal_zoom_by_frame (framepos_t start, framepos_t end);
|
||||
void temporal_zoom_to_frame (bool coarser, framepos_t frame);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@
|
|||
#include <gio/gio.h>
|
||||
#include <gtk/gtkiconfactory.h>
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
#include "pbd/file_utils.h"
|
||||
#include "pbd/search_path.h"
|
||||
|
||||
#include "gtkmm2ext/tearoff.h"
|
||||
|
||||
|
|
@ -641,11 +639,11 @@ Editor::load_bindings ()
|
|||
|
||||
key_bindings.set_action_map (editor_action_map);
|
||||
|
||||
sys::path binding_file;
|
||||
std::string binding_file;
|
||||
|
||||
if (find_file_in_search_path (ardour_config_search_path(), "editor.bindings", binding_file)) {
|
||||
key_bindings.load (binding_file.to_string());
|
||||
info << string_compose (_("Loaded editor bindings from %1"), binding_file.to_string()) << endmsg;
|
||||
key_bindings.load (binding_file);
|
||||
info << string_compose (_("Loaded editor bindings from %1"), binding_file) << endmsg;
|
||||
} else {
|
||||
error << string_compose (_("Could not find editor.bindings in search path %1"), ardour_config_search_path().to_string()) << endmsg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -934,7 +934,10 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region, uint32_t
|
|||
|
||||
existing_track = at.front();
|
||||
} else if (mr) {
|
||||
list<boost::shared_ptr<MidiTrack> > mt (_session->new_midi_track (boost::shared_ptr<PluginInfo>(), Normal, 0, 1));
|
||||
list<boost::shared_ptr<MidiTrack> > mt (_session->new_midi_track (ChanCount (DataType::MIDI, 1),
|
||||
ChanCount (DataType::MIDI, 1),
|
||||
boost::shared_ptr<PluginInfo>(),
|
||||
Normal, 0, 1));
|
||||
|
||||
if (mt.empty()) {
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ struct EditorOrderTimeAxisViewSorter {
|
|||
RouteTimeAxisView* ra = dynamic_cast<RouteTimeAxisView*> (a);
|
||||
RouteTimeAxisView* rb = dynamic_cast<RouteTimeAxisView*> (b);
|
||||
assert (ra && rb);
|
||||
return ra->route()->order_key (N_ ("editor")) < rb->route()->order_key (N_ ("editor"));
|
||||
return ra->route()->order_key (EditorSort) < rb->route()->order_key (EditorSort);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
|
|||
vector<boost::shared_ptr<AudioFileSource> > sources;
|
||||
uint32_t nchans;
|
||||
|
||||
const string sound_directory = _session->session_directory().sound_path().to_string();
|
||||
const string sound_directory = _session->session_directory().sound_path();
|
||||
|
||||
nchans = region->n_channels();
|
||||
|
||||
|
|
@ -382,7 +382,7 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list
|
|||
string path;
|
||||
vector<boost::shared_ptr<AudioFileSource> > sources;
|
||||
|
||||
const string sound_directory = _session->session_directory().sound_path().to_string();
|
||||
const string sound_directory = _session->session_directory().sound_path();
|
||||
|
||||
uint32_t channels = count.n_audio();
|
||||
|
||||
|
|
|
|||
|
|
@ -177,10 +177,10 @@ EditorGroupTabs::default_properties () const
|
|||
return plist;
|
||||
}
|
||||
|
||||
string
|
||||
RouteSortOrderKey
|
||||
EditorGroupTabs::order_key () const
|
||||
{
|
||||
return X_("editor");
|
||||
return EditorSort;
|
||||
}
|
||||
|
||||
RouteList
|
||||
|
|
@ -201,5 +201,5 @@ EditorGroupTabs::selected_routes () const
|
|||
void
|
||||
EditorGroupTabs::sync_order_keys ()
|
||||
{
|
||||
_editor->_routes->sync_order_keys ("");
|
||||
_editor->_routes->sync_order_keys_from_model ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ private:
|
|||
}
|
||||
void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *);
|
||||
PBD::PropertyList default_properties () const;
|
||||
std::string order_key () const;
|
||||
ARDOUR::RouteSortOrderKey order_key () const;
|
||||
ARDOUR::RouteList selected_routes () const;
|
||||
void sync_order_keys ();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1327,14 +1327,30 @@ Editor::tav_zoom_smooth (bool coarser, bool force_all)
|
|||
_routes->resume_redisplay ();
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::clamp_frames_per_unit (double& fpu) const
|
||||
{
|
||||
bool clamped = false;
|
||||
|
||||
if (fpu < 2.0) {
|
||||
fpu = 2.0;
|
||||
clamped = true;
|
||||
}
|
||||
|
||||
if (max_framepos / fpu < 800) {
|
||||
fpu = max_framepos / 800.0;
|
||||
clamped = true;
|
||||
}
|
||||
|
||||
return clamped;
|
||||
}
|
||||
|
||||
void
|
||||
Editor::temporal_zoom_step (bool coarser)
|
||||
{
|
||||
ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_step, coarser)
|
||||
|
||||
double nfpu;
|
||||
|
||||
nfpu = frames_per_unit;
|
||||
double nfpu = frames_per_unit;
|
||||
|
||||
if (coarser) {
|
||||
nfpu = min (9e6, nfpu * 1.61803399);
|
||||
|
|
@ -1346,9 +1362,11 @@ Editor::temporal_zoom_step (bool coarser)
|
|||
}
|
||||
|
||||
void
|
||||
Editor::temporal_zoom (gdouble fpu)
|
||||
Editor::temporal_zoom (double fpu)
|
||||
{
|
||||
if (!_session) return;
|
||||
if (!_session) {
|
||||
return;
|
||||
}
|
||||
|
||||
framepos_t current_page = current_page_frames();
|
||||
framepos_t current_leftmost = leftmost_frame;
|
||||
|
|
@ -1362,9 +1380,8 @@ Editor::temporal_zoom (gdouble fpu)
|
|||
double nfpu;
|
||||
double l;
|
||||
|
||||
/* XXX this limit is also in ::set_frames_per_unit() */
|
||||
|
||||
if (frames_per_unit <= 1.0 && fpu <= frames_per_unit) {
|
||||
clamp_frames_per_unit (fpu);
|
||||
if (fpu == frames_per_unit) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5394,8 +5411,7 @@ Editor::split_region ()
|
|||
|
||||
struct EditorOrderRouteSorter {
|
||||
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
|
||||
/* use of ">" forces the correct sort order */
|
||||
return a->order_key ("editor") < b->order_key ("editor");
|
||||
return a->order_key (EditorSort) < b->order_key (EditorSort);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,18 @@
|
|||
#include <cmath>
|
||||
#include <cassert>
|
||||
|
||||
#include "pbd/unknown_type.h"
|
||||
#include "pbd/unwind.h"
|
||||
|
||||
#include "ardour/debug.h"
|
||||
#include "ardour/route.h"
|
||||
#include "ardour/midi_track.h"
|
||||
#include "ardour/session.h"
|
||||
|
||||
#include "gtkmm2ext/cell_renderer_pixbuf_multi.h"
|
||||
#include "gtkmm2ext/cell_renderer_pixbuf_toggle.h"
|
||||
#include "gtkmm2ext/treeutils.h"
|
||||
|
||||
#include "editor.h"
|
||||
#include "keyboard.h"
|
||||
#include "ardour_ui.h"
|
||||
|
|
@ -38,15 +48,6 @@
|
|||
#include "editor_group_tabs.h"
|
||||
#include "editor_routes.h"
|
||||
|
||||
#include "pbd/unknown_type.h"
|
||||
|
||||
#include "ardour/route.h"
|
||||
#include "ardour/midi_track.h"
|
||||
|
||||
#include "gtkmm2ext/cell_renderer_pixbuf_multi.h"
|
||||
#include "gtkmm2ext/cell_renderer_pixbuf_toggle.h"
|
||||
#include "gtkmm2ext/treeutils.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -67,9 +68,7 @@ EditorRoutes::EditorRoutes (Editor* e)
|
|||
: EditorComponent (e)
|
||||
, _ignore_reorder (false)
|
||||
, _no_redisplay (false)
|
||||
, _redisplay_does_not_sync_order_keys (false)
|
||||
, _redisplay_does_not_reset_order_keys (false)
|
||||
,_menu (0)
|
||||
, _menu (0)
|
||||
, old_focus (0)
|
||||
, selection_countdown (0)
|
||||
, name_editable (0)
|
||||
|
|
@ -282,7 +281,7 @@ EditorRoutes::EditorRoutes (Editor* e)
|
|||
|
||||
_display.set_enable_search (false);
|
||||
|
||||
Route::SyncOrderKeys.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::sync_order_keys, this, _1), gui_context());
|
||||
Route::SyncOrderKeys.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::sync_model_from_order_keys, this, _1), gui_context());
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -502,12 +501,7 @@ EditorRoutes::redisplay ()
|
|||
*/
|
||||
int n;
|
||||
|
||||
/* Order keys must not take children into account, so use a separate counter
|
||||
for that.
|
||||
*/
|
||||
int order_key;
|
||||
|
||||
for (n = 0, order_key = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) {
|
||||
for (n = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) {
|
||||
TimeAxisView *tv = (*i)[_columns.tv];
|
||||
boost::shared_ptr<Route> route = (*i)[_columns.route];
|
||||
|
||||
|
|
@ -516,13 +510,6 @@ EditorRoutes::redisplay ()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!_redisplay_does_not_reset_order_keys) {
|
||||
/* this reorder is caused by user action, so reassign sort order keys
|
||||
to tracks.
|
||||
*/
|
||||
route->set_order_key (N_ ("editor"), order_key);
|
||||
}
|
||||
|
||||
bool visible = tv->marked_for_display ();
|
||||
|
||||
/* show or hide the TimeAxisView */
|
||||
|
|
@ -534,7 +521,6 @@ EditorRoutes::redisplay ()
|
|||
}
|
||||
|
||||
n++;
|
||||
order_key++;
|
||||
}
|
||||
|
||||
/* whenever we go idle, update the track view list to reflect the new order.
|
||||
|
|
@ -555,24 +541,23 @@ EditorRoutes::redisplay ()
|
|||
*/
|
||||
_editor->vertical_adjustment.set_value (_editor->full_canvas_height - _editor->_canvas_height);
|
||||
}
|
||||
|
||||
if (!_redisplay_does_not_reset_order_keys && !_redisplay_does_not_sync_order_keys) {
|
||||
_session->sync_order_keys (N_ ("editor"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EditorRoutes::route_deleted (Gtk::TreeModel::Path const &)
|
||||
{
|
||||
if (!_session || _session->deletion_in_progress()) {
|
||||
return;
|
||||
}
|
||||
/* this happens as the second step of a DnD within the treeview as well
|
||||
as when a row/route is actually deleted.
|
||||
*/
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview row deleted\n");
|
||||
sync_order_keys_from_model ();
|
||||
}
|
||||
|
||||
/* this could require an order reset & sync */
|
||||
_session->set_remote_control_ids();
|
||||
_ignore_reorder = true;
|
||||
redisplay ();
|
||||
_ignore_reorder = false;
|
||||
void
|
||||
EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview reordered\n");
|
||||
sync_order_keys_from_model ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -590,11 +575,7 @@ EditorRoutes::visible_changed (std::string const & path)
|
|||
bool visible = (*iter)[_columns.visible];
|
||||
|
||||
if (tv->set_marked_for_display (!visible)) {
|
||||
_redisplay_does_not_reset_order_keys = true;
|
||||
_session->set_remote_control_ids();
|
||||
update_visibility ();
|
||||
redisplay ();
|
||||
_redisplay_does_not_reset_order_keys = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -618,7 +599,6 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
|
|||
{
|
||||
TreeModel::Row row;
|
||||
|
||||
_redisplay_does_not_sync_order_keys = true;
|
||||
suspend_redisplay ();
|
||||
|
||||
for (list<RouteTimeAxisView*>::iterator x = routes.begin(); x != routes.end(); ++x) {
|
||||
|
|
@ -649,15 +629,6 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
|
|||
row[_columns.solo_safe_state] = (*x)->route()->solo_safe();
|
||||
row[_columns.name_editable] = true;
|
||||
|
||||
_ignore_reorder = true;
|
||||
|
||||
/* added a new fresh one at the end */
|
||||
if ((*x)->route()->order_key (N_ ("editor")) == -1) {
|
||||
(*x)->route()->set_order_key (N_ ("editor"), _model->children().size()-1);
|
||||
}
|
||||
|
||||
_ignore_reorder = false;
|
||||
|
||||
boost::weak_ptr<Route> wr ((*x)->route());
|
||||
|
||||
(*x)->route()->gui_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context());
|
||||
|
|
@ -690,7 +661,10 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
|
|||
update_input_active_display ();
|
||||
update_active_display ();
|
||||
resume_redisplay ();
|
||||
_redisplay_does_not_sync_order_keys = false;
|
||||
|
||||
/* now update route order keys from the treeview/track display order */
|
||||
|
||||
sync_order_keys_from_model ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -719,12 +693,6 @@ EditorRoutes::route_removed (TimeAxisView *tv)
|
|||
TreeModel::Children rows = _model->children();
|
||||
TreeModel::Children::iterator ri;
|
||||
|
||||
/* the core model has changed, there is no need to sync
|
||||
view orders.
|
||||
*/
|
||||
|
||||
_redisplay_does_not_sync_order_keys = true;
|
||||
|
||||
for (ri = rows.begin(); ri != rows.end(); ++ri) {
|
||||
if ((*ri)[_columns.tv] == tv) {
|
||||
_model->erase (ri);
|
||||
|
|
@ -732,7 +700,9 @@ EditorRoutes::route_removed (TimeAxisView *tv)
|
|||
}
|
||||
}
|
||||
|
||||
_redisplay_does_not_sync_order_keys = false;
|
||||
/* the deleted signal for the treeview/model will take
|
||||
care of any updates.
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -787,6 +757,11 @@ EditorRoutes::update_visibility ()
|
|||
(*i)[_columns.visible] = tv->marked_for_display ();
|
||||
}
|
||||
|
||||
/* force route order keys catch up with visibility changes
|
||||
*/
|
||||
|
||||
sync_order_keys_from_model ();
|
||||
|
||||
resume_redisplay ();
|
||||
}
|
||||
|
||||
|
|
@ -824,57 +799,109 @@ EditorRoutes::show_track_in_display (TimeAxisView& tv)
|
|||
}
|
||||
|
||||
void
|
||||
EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
|
||||
EditorRoutes::sync_order_keys_from_model ()
|
||||
{
|
||||
redisplay ();
|
||||
}
|
||||
|
||||
/** If src != "editor", take editor order keys from each route and use them to rearrange the
|
||||
* route list so that the visual arrangement of routes matches the order keys from the routes.
|
||||
*/
|
||||
void
|
||||
EditorRoutes::sync_order_keys (string const & src)
|
||||
{
|
||||
map<int, int> new_order;
|
||||
TreeModel::Children rows = _model->children();
|
||||
TreeModel::Children::iterator ri;
|
||||
|
||||
if (src == N_ ("editor") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
|
||||
if (_ignore_reorder || !_session || _session->deletion_in_progress()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TreeModel::Children rows = _model->children();
|
||||
|
||||
if (rows.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, "editor sync order keys from model\n");
|
||||
|
||||
TreeModel::Children::iterator ri;
|
||||
bool changed = false;
|
||||
int order;
|
||||
uint32_t order = 0;
|
||||
|
||||
for (order = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
|
||||
for (ri = rows.begin(); ri != rows.end(); ++ri) {
|
||||
boost::shared_ptr<Route> route = (*ri)[_columns.route];
|
||||
bool visible = (*ri)[_columns.visible];
|
||||
|
||||
int const old_key = order;
|
||||
int const new_key = route->order_key (N_ ("editor"));
|
||||
uint32_t old_key = route->order_key (EditorSort);
|
||||
uint32_t new_key;
|
||||
|
||||
new_order[new_key] = old_key;
|
||||
if (!visible) {
|
||||
new_key = UINT_MAX;
|
||||
} else {
|
||||
new_key = order;
|
||||
}
|
||||
|
||||
if (new_key != old_key) {
|
||||
if (old_key != new_key) {
|
||||
route->set_order_key (EditorSort, new_key);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
order++;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
_redisplay_does_not_reset_order_keys = true;
|
||||
|
||||
/* `compact' new_order into a vector */
|
||||
vector<int> co;
|
||||
for (map<int, int>::const_iterator i = new_order.begin(); i != new_order.end(); ++i) {
|
||||
co.push_back (i->second);
|
||||
}
|
||||
|
||||
assert (co.size() == _model->children().size ());
|
||||
|
||||
_model->reorder (co);
|
||||
_redisplay_does_not_reset_order_keys = false;
|
||||
/* tell the world that we changed the editor sort keys */
|
||||
_session->sync_order_keys (EditorSort);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EditorRoutes::sync_model_from_order_keys (RouteSortOrderKey src)
|
||||
{
|
||||
if (!_session || _session->deletion_in_progress()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("editor sync model from order keys, src = %1\n", enum_2_string (src)));
|
||||
|
||||
if (src == MixerSort) {
|
||||
|
||||
if (!Config->get_sync_all_route_ordering()) {
|
||||
/* mixer sort keys changed - we don't care */
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, "reset editor order key to match mixer\n");
|
||||
|
||||
/* mixer sort keys were changed, update the editor sort
|
||||
* keys since "sync mixer+editor order" is enabled.
|
||||
*/
|
||||
|
||||
boost::shared_ptr<RouteList> r = _session->get_routes ();
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
(*i)->sync_order_keys (src);
|
||||
}
|
||||
}
|
||||
|
||||
/* we could get here after either a change in the Mixer or Editor sort
|
||||
* order, but either way, the mixer order keys reflect the intended
|
||||
* order for the GUI, so reorder the treeview model to match it.
|
||||
*/
|
||||
|
||||
vector<int> neworder;
|
||||
TreeModel::Children rows = _model->children();
|
||||
uint32_t n = 0;
|
||||
|
||||
if (rows.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
neworder.assign (rows.size(), 0);
|
||||
|
||||
for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++n) {
|
||||
boost::shared_ptr<Route> route = (*ri)[_columns.route];
|
||||
neworder[route->order_key (EditorSort)] = n;
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("editor change order for %1 to %2\n",
|
||||
route->name(), route->order_key (MixerSort)));
|
||||
}
|
||||
|
||||
{
|
||||
Unwinder<bool> uw (_ignore_reorder, true);
|
||||
_model->reorder (neworder);
|
||||
}
|
||||
|
||||
redisplay ();
|
||||
}
|
||||
|
||||
void
|
||||
EditorRoutes::hide_all_tracks (bool /*with_select*/)
|
||||
|
|
@ -925,6 +952,11 @@ EditorRoutes::set_all_tracks_visibility (bool yn)
|
|||
(*i)[_columns.visible] = yn;
|
||||
}
|
||||
|
||||
/* force route order keys catch up with visibility changes
|
||||
*/
|
||||
|
||||
sync_order_keys_from_model ();
|
||||
|
||||
resume_redisplay ();
|
||||
}
|
||||
|
||||
|
|
@ -982,6 +1014,11 @@ EditorRoutes::set_all_audio_midi_visibility (int tracks, bool yn)
|
|||
}
|
||||
}
|
||||
|
||||
/* force route order keys catch up with visibility changes
|
||||
*/
|
||||
|
||||
sync_order_keys_from_model ();
|
||||
|
||||
resume_redisplay ();
|
||||
}
|
||||
|
||||
|
|
@ -1192,8 +1229,14 @@ EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path
|
|||
|
||||
struct EditorOrderRouteSorter {
|
||||
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
|
||||
/* use of ">" forces the correct sort order */
|
||||
return a->order_key (N_ ("editor")) < b->order_key (N_ ("editor"));
|
||||
if (a->is_master()) {
|
||||
/* master before everything else */
|
||||
return true;
|
||||
} else if (b->is_master()) {
|
||||
/* everything else before master */
|
||||
return false;
|
||||
}
|
||||
return a->order_key (EditorSort) < b->order_key (EditorSort);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1209,49 +1252,32 @@ EditorRoutes::initial_display ()
|
|||
}
|
||||
|
||||
boost::shared_ptr<RouteList> routes = _session->get_routes();
|
||||
|
||||
if (ARDOUR_UI::instance()->session_is_new ()) {
|
||||
|
||||
/* new session: stamp all routes with the right editor order
|
||||
* key
|
||||
*/
|
||||
|
||||
_editor->add_routes (*(routes.get()));
|
||||
|
||||
} else {
|
||||
|
||||
/* existing session: sort a copy of the route list by
|
||||
* editor-order and add its contents to the display.
|
||||
*/
|
||||
|
||||
RouteList r (*routes);
|
||||
EditorOrderRouteSorter sorter;
|
||||
|
||||
r.sort (sorter);
|
||||
_editor->handle_new_route (r);
|
||||
_editor->add_routes (r);
|
||||
|
||||
/* don't show master bus in a new session */
|
||||
|
||||
if (ARDOUR_UI::instance()->session_is_new ()) {
|
||||
|
||||
TreeModel::Children rows = _model->children();
|
||||
TreeModel::Children::iterator i;
|
||||
|
||||
_no_redisplay = true;
|
||||
|
||||
for (i = rows.begin(); i != rows.end(); ++i) {
|
||||
|
||||
TimeAxisView *tv = (*i)[_columns.tv];
|
||||
RouteTimeAxisView *rtv;
|
||||
|
||||
if ((rtv = dynamic_cast<RouteTimeAxisView*>(tv)) != 0) {
|
||||
if (rtv->route()->is_master()) {
|
||||
_display.get_selection()->unselect (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_no_redisplay = false;
|
||||
redisplay ();
|
||||
}
|
||||
|
||||
resume_redisplay ();
|
||||
}
|
||||
|
||||
void
|
||||
EditorRoutes::track_list_reorder (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int* /*new_order*/)
|
||||
{
|
||||
_redisplay_does_not_sync_order_keys = true;
|
||||
_session->set_remote_control_ids();
|
||||
redisplay ();
|
||||
_redisplay_does_not_sync_order_keys = false;
|
||||
}
|
||||
|
||||
void
|
||||
EditorRoutes::display_drag_data_received (const RefPtr<Gdk::DragContext>& context,
|
||||
int x, int y,
|
||||
|
|
@ -1370,18 +1396,26 @@ EditorRoutes::move_selected_tracks (bool up)
|
|||
}
|
||||
|
||||
for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
|
||||
neworder.push_back (leading->second->order_key (N_ ("editor")));
|
||||
uint32_t order = leading->second->order_key (EditorSort);
|
||||
neworder.push_back (order);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, "New order after moving tracks:\n");
|
||||
for (vector<int>::iterator i = neworder.begin(); i != neworder.end(); ++i) {
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("\t%1\n", *i));
|
||||
}
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, "-------\n");
|
||||
|
||||
for (vector<int>::iterator i = neworder.begin(); i != neworder.end(); ++i) {
|
||||
if (*i >= (int) neworder.size()) {
|
||||
cerr << "Trying to move something to " << *i << " of " << neworder.size() << endl;
|
||||
}
|
||||
assert (*i < (int) neworder.size ());
|
||||
}
|
||||
#endif
|
||||
|
||||
_model->reorder (neworder);
|
||||
|
||||
_session->sync_order_keys (N_ ("editor"));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1560,3 +1594,27 @@ EditorRoutes::show_tracks_with_regions_at_playhead ()
|
|||
|
||||
resume_redisplay ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
EditorRoutes::count_displayed_non_special_routes () const
|
||||
{
|
||||
if (!_model) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t cnt = 0;
|
||||
TreeModel::Children rows = _model->children ();
|
||||
for (TreeModel::Children::iterator i = rows.begin(); i != rows.end(); ++i) {
|
||||
bool visible = (*i)[_columns.visible];
|
||||
if (visible) {
|
||||
boost::shared_ptr<Route> route = (*i)[_columns.route];
|
||||
if (route) {
|
||||
if (route->is_master() || route->is_monitor()) {
|
||||
continue;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ public:
|
|||
_no_redisplay = true;
|
||||
}
|
||||
|
||||
void allow_redisplay () {
|
||||
_no_redisplay = false;
|
||||
}
|
||||
|
||||
void resume_redisplay () {
|
||||
_no_redisplay = false;
|
||||
redisplay ();
|
||||
|
|
@ -55,8 +59,8 @@ public:
|
|||
std::list<TimeAxisView*> views () const;
|
||||
void hide_all_tracks (bool);
|
||||
void clear ();
|
||||
void sync_order_keys (std::string const &);
|
||||
|
||||
uint32_t count_displayed_non_special_routes () const;
|
||||
void sync_order_keys_from_model ();
|
||||
private:
|
||||
|
||||
void initial_display ();
|
||||
|
|
@ -68,6 +72,7 @@ private:
|
|||
void on_tv_solo_safe_toggled (std::string const &);
|
||||
void build_menu ();
|
||||
void show_menu ();
|
||||
void sync_model_from_order_keys (ARDOUR::RouteSortOrderKey);
|
||||
void route_deleted (Gtk::TreeModel::Path const &);
|
||||
void visible_changed (std::string const &);
|
||||
void active_changed (std::string const &);
|
||||
|
|
@ -98,7 +103,6 @@ private:
|
|||
Glib::RefPtr<Gdk::DragContext> const &, gint, gint, Gtk::SelectionData const &, guint, guint
|
||||
);
|
||||
|
||||
void track_list_reorder (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const & iter, int* new_order);
|
||||
bool selection_filter (Glib::RefPtr<Gtk::TreeModel> const &, Gtk::TreeModel::Path const &, bool);
|
||||
void name_edit (std::string const &, std::string const &);
|
||||
void solo_changed_so_update_mute ();
|
||||
|
|
@ -150,8 +154,6 @@ private:
|
|||
|
||||
bool _ignore_reorder;
|
||||
bool _no_redisplay;
|
||||
bool _redisplay_does_not_sync_order_keys;
|
||||
bool _redisplay_does_not_reset_order_keys;
|
||||
|
||||
Gtk::Menu* _menu;
|
||||
Gtk::Widget* old_focus;
|
||||
|
|
|
|||
|
|
@ -779,7 +779,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
|
|||
|
||||
RouteTimeAxisView* closest = 0;
|
||||
int distance = INT_MAX;
|
||||
int key = rtv->route()->order_key ("editor");
|
||||
int key = rtv->route()->order_key (EditorSort);
|
||||
|
||||
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
|
||||
|
||||
|
|
@ -794,7 +794,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
|
|||
if (result.second) {
|
||||
/* newly added to already_in_selection */
|
||||
|
||||
int d = artv->route()->order_key ("editor");
|
||||
int d = artv->route()->order_key (EditorSort);
|
||||
|
||||
d -= key;
|
||||
|
||||
|
|
@ -810,7 +810,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
|
|||
|
||||
/* now add all tracks between that one and this one */
|
||||
|
||||
int okey = closest->route()->order_key ("editor");
|
||||
int okey = closest->route()->order_key (EditorSort);
|
||||
|
||||
if (okey > key) {
|
||||
swap (okey, key);
|
||||
|
|
@ -820,7 +820,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
|
|||
RouteTimeAxisView* artv = dynamic_cast<RouteTimeAxisView*>(*x);
|
||||
if (artv && artv != rtv) {
|
||||
|
||||
int k = artv->route()->order_key ("editor");
|
||||
int k = artv->route()->order_key (EditorSort);
|
||||
|
||||
if (k >= okey && k <= key) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,208 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2000 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 <cstdlib>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
#include <gtkmm.h>
|
||||
|
||||
#include "ardour/named_selection.h"
|
||||
#include "ardour/session_selection.h"
|
||||
#include "ardour/playlist.h"
|
||||
|
||||
#include "editor.h"
|
||||
#include "keyboard.h"
|
||||
#include "selection.h"
|
||||
#include "time_axis_view.h"
|
||||
#include "ardour_ui.h"
|
||||
#include "prompter.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using namespace Gtk;
|
||||
using namespace Gtkmm2ext;
|
||||
|
||||
void
|
||||
Editor::handle_new_named_selection ()
|
||||
{
|
||||
ARDOUR_UI::instance()->call_slot (boost::bind (&Editor::redisplay_named_selections, this));
|
||||
}
|
||||
|
||||
void
|
||||
Editor::add_named_selection_to_named_selection_display (boost::shared_ptr<NamedSelection> selection)
|
||||
{
|
||||
TreeModel::Row row = *(named_selection_model->append());
|
||||
row[named_selection_columns.text] = selection.name;
|
||||
row[named_selection_columns.selection] = selection;
|
||||
}
|
||||
|
||||
void
|
||||
Editor::redisplay_named_selections ()
|
||||
{
|
||||
named_selection_model->clear ();
|
||||
session->foreach_named_selection (*this, &Editor::add_named_selection_to_named_selection_display);
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::named_selection_display_key_release (GdkEventKey* ev)
|
||||
{
|
||||
if (session == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ev->keyval) {
|
||||
case GDK_Delete:
|
||||
remove_selected_named_selections ();
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
Editor::remove_selected_named_selections ()
|
||||
{
|
||||
Glib::RefPtr<TreeSelection> selection = named_selection_display.get_selection();
|
||||
TreeView::Selection::ListHandle_Path rows = selection->get_selected_rows ();
|
||||
|
||||
if (selection->count_selected_rows() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (TreeView::Selection::ListHandle_Path::iterator i = rows.begin(); i != rows.end(); ++i) {
|
||||
|
||||
TreeIter iter;
|
||||
|
||||
if ((iter = named_selection_model->get_iter (*i))) {
|
||||
session->remove_named_selection ((*iter)[named_selection_columns.selection]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::named_selection_display_button_release (GdkEventButton *ev)
|
||||
{
|
||||
TreeModel::Children rows = named_selection_model->children();
|
||||
TreeModel::Children::iterator i;
|
||||
Glib::RefPtr<TreeSelection> selection = named_selection_display.get_selection();
|
||||
|
||||
for (i = rows.begin(); i != rows.end(); ++i) {
|
||||
if (selection->is_selected (i)) {
|
||||
switch (ev->button) {
|
||||
case 1:
|
||||
if (Keyboard::is_delete_event (ev)) {
|
||||
session->remove_named_selection ((*i)[named_selection_columns.selection]);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Editor::named_selection_display_selection_changed ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Editor::create_named_selection ()
|
||||
{
|
||||
string name;
|
||||
|
||||
if (session == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for a range-based selection */
|
||||
|
||||
if (selection->time.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TrackViewList *views = get_valid_views (selection->time.track, selection->time.group);
|
||||
|
||||
if (views->empty()) {
|
||||
delete views;
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Playlist> what_we_found;
|
||||
list<boost::shared_ptr<Playlist> > thelist;
|
||||
|
||||
for (TrackViewList::iterator i = views->begin(); i != views->end(); ++i) {
|
||||
|
||||
boost::shared_ptr<Playlist> pl = (*i)->playlist();
|
||||
|
||||
if (pl && (what_we_found = pl->copy (selection->time, false)) != 0) {
|
||||
thelist.push_back (what_we_found);
|
||||
}
|
||||
}
|
||||
|
||||
if (!thelist.empty()) {
|
||||
|
||||
ArdourPrompter p;
|
||||
|
||||
p.set_prompt (_("Name for Chunk:"));
|
||||
p.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
|
||||
p.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
|
||||
p.change_labels (_("Create Chunk"), _("Forget it"));
|
||||
p.show_all ();
|
||||
|
||||
switch (p.run ()) {
|
||||
|
||||
case Gtk::RESPONSE_ACCEPT:
|
||||
p.get_result (name);
|
||||
if (name.empty()) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<NamedSelection> ns (new NamedSelection (name, thelist));
|
||||
|
||||
/* make the one we just added be selected */
|
||||
|
||||
TreeModel::Children::iterator added = named_selection_model->children().end();
|
||||
--added;
|
||||
named_selection_display.get_selection()->select (*added);
|
||||
|
||||
} else {
|
||||
error << _("No selectable material found in the currently selected time range") << endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ EditorSnapshots::redisplay ()
|
|||
return;
|
||||
}
|
||||
|
||||
vector<sys::path> state_file_paths;
|
||||
vector<std::string> state_file_paths;
|
||||
|
||||
get_state_files_in_directory (_session->session_directory().root_path(),
|
||||
state_file_paths);
|
||||
|
|
|
|||
|
|
@ -71,31 +71,29 @@ using namespace Glib;
|
|||
using ARDOUR::SoundGrid;
|
||||
|
||||
EngineControl::EngineControl ()
|
||||
: periods_adjustment (2, 2, 16, 1, 2)
|
||||
, periods_spinner (periods_adjustment)
|
||||
, priority_adjustment (60, 10, 90, 1, 10)
|
||||
, priority_spinner (priority_adjustment)
|
||||
, ports_adjustment (128, 8, 1024, 1, 16)
|
||||
, ports_spinner (ports_adjustment)
|
||||
, input_latency_adjustment (0, 0, 99999, 1)
|
||||
, input_latency (input_latency_adjustment)
|
||||
, output_latency_adjustment (0, 0, 99999, 1)
|
||||
, output_latency (output_latency_adjustment)
|
||||
, realtime_button (_("Realtime"))
|
||||
, no_memory_lock_button (_("Do not lock memory"))
|
||||
, unlock_memory_button (_("Unlock memory"))
|
||||
, soft_mode_button (_("No zombies"))
|
||||
, monitor_button (_("Provide monitor ports"))
|
||||
, force16bit_button (_("Force 16 bit"))
|
||||
, hw_monitor_button (_("H/W monitoring"))
|
||||
, hw_meter_button (_("H/W metering"))
|
||||
, verbose_output_button (_("Verbose output"))
|
||||
, start_button (_("Start"))
|
||||
, stop_button (_("Stop"))
|
||||
#ifdef __APPLE_
|
||||
, basic_packer (5, 2)
|
||||
, options_packer (4, 2)
|
||||
, device_packer (4, 2)
|
||||
: periods_adjustment (2, 2, 16, 1, 2),
|
||||
periods_spinner (periods_adjustment),
|
||||
ports_adjustment (128, 8, 1024, 1, 16),
|
||||
ports_spinner (ports_adjustment),
|
||||
input_latency_adjustment (0, 0, 99999, 1),
|
||||
input_latency (input_latency_adjustment),
|
||||
output_latency_adjustment (0, 0, 99999, 1),
|
||||
output_latency (output_latency_adjustment),
|
||||
realtime_button (_("Realtime")),
|
||||
no_memory_lock_button (_("Do not lock memory")),
|
||||
unlock_memory_button (_("Unlock memory")),
|
||||
soft_mode_button (_("No zombies")),
|
||||
monitor_button (_("Provide monitor ports")),
|
||||
force16bit_button (_("Force 16 bit")),
|
||||
hw_monitor_button (_("H/W monitoring")),
|
||||
hw_meter_button (_("H/W metering")),
|
||||
verbose_output_button (_("Verbose output")),
|
||||
start_button (_("Start")),
|
||||
stop_button (_("Stop")),
|
||||
#ifdef __APPLE__
|
||||
basic_packer (5, 2),
|
||||
options_packer (4, 2),
|
||||
device_packer (4, 2)
|
||||
#else
|
||||
, basic_packer (8, 2)
|
||||
, options_packer (14, 2)
|
||||
|
|
@ -261,19 +259,10 @@ EngineControl::EngineControl ()
|
|||
++row;
|
||||
|
||||
realtime_button.set_active (true);
|
||||
realtime_button.signal_toggled().connect (sigc::mem_fun (*this, &EngineControl::realtime_changed));
|
||||
realtime_changed ();
|
||||
|
||||
#if PROVIDE_TOO_MANY_OPTIONS
|
||||
|
||||
#ifndef __APPLE__
|
||||
label = manage (new Label (_("Realtime Priority")));
|
||||
label->set_alignment (1.0, 0.5);
|
||||
options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
|
||||
options_packer.attach (priority_spinner, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
|
||||
++row;
|
||||
priority_spinner.set_value (60);
|
||||
|
||||
options_packer.attach (no_memory_lock_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
|
||||
++row;
|
||||
options_packer.attach (unlock_memory_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
|
||||
|
|
@ -434,8 +423,6 @@ EngineControl::build_command_line (vector<string>& cmd)
|
|||
|
||||
if (realtime_button.get_active()) {
|
||||
cmd.push_back ("-R");
|
||||
cmd.push_back ("-P");
|
||||
cmd.push_back (to_string ((uint32_t) floor (priority_spinner.get_value()), std::dec));
|
||||
} else {
|
||||
cmd.push_back ("-r"); /* override jackd's default --realtime */
|
||||
}
|
||||
|
|
@ -678,14 +665,6 @@ EngineControl::setup_engine ()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::realtime_changed ()
|
||||
{
|
||||
#ifndef __APPLE__
|
||||
priority_spinner.set_sensitive (realtime_button.get_active());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
EngineControl::enumerate_devices (const string& driver)
|
||||
{
|
||||
|
|
@ -1167,10 +1146,6 @@ EngineControl::get_state ()
|
|||
child->add_property ("val", to_string (periods_adjustment.get_value(), std::dec));
|
||||
root->add_child_nocopy (*child);
|
||||
|
||||
child = new XMLNode ("priority");
|
||||
child->add_property ("val", to_string (priority_adjustment.get_value(), std::dec));
|
||||
root->add_child_nocopy (*child);
|
||||
|
||||
child = new XMLNode ("ports");
|
||||
child->add_property ("val", to_string (ports_adjustment.get_value(), std::dec));
|
||||
root->add_child_nocopy (*child);
|
||||
|
|
@ -1317,9 +1292,6 @@ EngineControl::set_state (const XMLNode& root)
|
|||
if (child->name() == "periods") {
|
||||
val = atoi (strval);
|
||||
periods_adjustment.set_value(val);
|
||||
} else if (child->name() == "priority") {
|
||||
val = atoi (strval);
|
||||
priority_adjustment.set_value(val);
|
||||
} else if (child->name() == "ports") {
|
||||
val = atoi (strval);
|
||||
ports_adjustment.set_value(val);
|
||||
|
|
|
|||
|
|
@ -53,8 +53,6 @@ class EngineControl : public Gtk::VBox {
|
|||
private:
|
||||
Gtk::Adjustment periods_adjustment;
|
||||
Gtk::SpinButton periods_spinner;
|
||||
Gtk::Adjustment priority_adjustment;
|
||||
Gtk::SpinButton priority_spinner;
|
||||
Gtk::Adjustment ports_adjustment;
|
||||
Gtk::SpinButton ports_spinner;
|
||||
Gtk::Adjustment input_latency_adjustment;
|
||||
|
|
@ -163,7 +161,6 @@ class EngineControl : public Gtk::VBox {
|
|||
|
||||
bool _used;
|
||||
|
||||
void realtime_changed ();
|
||||
void driver_changed ();
|
||||
void interface_changed ();
|
||||
void build_command_line (std::vector<std::string>&);
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@
|
|||
|
||||
#include <sigc++/signal.h>
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
|
||||
#include "ardour/audioregion.h"
|
||||
#include "ardour/export_status.h"
|
||||
#include "ardour/export_handler.h"
|
||||
|
|
@ -185,7 +183,7 @@ ExportDialog::init_gui ()
|
|||
get_vbox()->pack_start (warning_widget, false, false, 0);
|
||||
get_vbox()->pack_start (progress_widget, false, false, 0);
|
||||
|
||||
advanced = Gtk::manage (new Gtk::Expander (_("Advanced options")));
|
||||
advanced = Gtk::manage (new Gtk::Expander (_("Time span and channel options")));
|
||||
advanced->property_expanded().signal_changed().connect(
|
||||
sigc::mem_fun(*this, &ExportDialog::expanded_changed));
|
||||
advanced->add (*advanced_paned);
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
|
||||
#include "ardour/export_format_specification.h"
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
|
||||
#include "gui_thread.h"
|
||||
#include "utils.h"
|
||||
#include "i18n.h"
|
||||
|
|
@ -37,7 +35,7 @@ ExportFileNotebook::ExportFileNotebook () :
|
|||
/* Last page */
|
||||
|
||||
new_file_button.set_image (*Gtk::manage (new Gtk::Image (::get_icon("add"))));
|
||||
new_file_button.set_label (_(" Click here to add another format"));
|
||||
new_file_button.set_label (_("Add another format"));
|
||||
new_file_button.set_alignment (0, 0.5);
|
||||
new_file_button.set_relief (Gtk::RELIEF_NONE);
|
||||
|
||||
|
|
@ -281,8 +279,7 @@ ExportFileNotebook::FilePage::update_example_filename()
|
|||
}
|
||||
|
||||
if (example != "") {
|
||||
sys::path path(example);
|
||||
filename_selector.set_example_filename(path.leaf());
|
||||
filename_selector.set_example_filename(Glib::path_get_basename (example));
|
||||
} else {
|
||||
filename_selector.set_example_filename("");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ ExportFormatDialog::ExportFormatDialog (FormatPtr format, bool new_dialog) :
|
|||
applying_changes_from_engine (0),
|
||||
|
||||
name_label (_("Label: "), Gtk::ALIGN_LEFT),
|
||||
name_generated_part ("", Gtk::ALIGN_LEFT),
|
||||
|
||||
normalize_checkbox (_("Normalize to:")),
|
||||
normalize_adjustment (0.00, -90.00, 0.00, 0.1, 0.2),
|
||||
|
|
@ -72,16 +73,22 @@ ExportFormatDialog::ExportFormatDialog (FormatPtr format, bool new_dialog) :
|
|||
|
||||
/* Pack containers in dialog */
|
||||
|
||||
get_vbox()->pack_start (name_hbox, false, false, 0);
|
||||
get_vbox()->pack_start (silence_table, false, false, 6);
|
||||
get_vbox()->pack_start (format_table, false, false, 6);
|
||||
get_vbox()->pack_start (encoding_options_vbox, false, false, 0);
|
||||
get_vbox()->pack_start (cue_toc_vbox, false, false, 0);
|
||||
get_vbox()->pack_start (name_hbox, false, false, 6);
|
||||
|
||||
/* Name, new and remove */
|
||||
|
||||
name_hbox.pack_start (name_label, false, false, 0);
|
||||
name_hbox.pack_start (name_entry, true, true, 0);
|
||||
name_hbox.pack_start (name_entry, false, false, 0);
|
||||
name_hbox.pack_start (name_generated_part, true, true, 0);
|
||||
name_entry.set_width_chars(20);
|
||||
update_description();
|
||||
manager.DescriptionChanged.connect(
|
||||
*this, invalidator (*this),
|
||||
boost::bind (&ExportFormatDialog::update_description, this), gui_context());
|
||||
|
||||
/* Normalize */
|
||||
|
||||
|
|
@ -710,6 +717,13 @@ ExportFormatDialog::update_with_toc ()
|
|||
manager.select_with_toc (with_toc.get_active());
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatDialog::update_description()
|
||||
{
|
||||
std::string text = ": " + format->description(false);
|
||||
name_generated_part.set_text(text);
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatDialog::update_name ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ class ExportFormatDialog : public ArdourDialog, public PBD::ScopedConnectionList
|
|||
void change_compatibility (bool compatibility, boost::weak_ptr<T> w_ptr, Glib::RefPtr<Gtk::ListStore> & list, ColsT & cols,
|
||||
std::string const & c_incompatible = "red", std::string const & c_compatible = "white");
|
||||
|
||||
void update_description();
|
||||
|
||||
uint32_t applying_changes_from_engine;
|
||||
|
||||
/*** Non-interactive selections ***/
|
||||
|
|
@ -151,6 +153,7 @@ class ExportFormatDialog : public ArdourDialog, public PBD::ScopedConnectionList
|
|||
|
||||
Gtk::Label name_label;
|
||||
Gtk::Entry name_entry;
|
||||
Gtk::Label name_generated_part;
|
||||
|
||||
/* Normalize */
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
|
||||
#include "ardour/audioengine.h"
|
||||
#include "ardour/sndfile_helpers.h"
|
||||
|
||||
|
|
@ -157,7 +155,7 @@ ExportRangeMarkersDialog::is_filepath_valid(string &filepath)
|
|||
|
||||
// directory needs to exist and be writable
|
||||
string dirpath = Glib::path_get_dirname (filepath);
|
||||
if (!exists_and_writable (sys::path (dirpath))) {
|
||||
if (!exists_and_writable (dirpath)) {
|
||||
string txt = _("Cannot write file in: ") + dirpath;
|
||||
MessageDialog msg (*this, txt, false, MESSAGE_ERROR, BUTTONS_OK, true);
|
||||
msg.run();
|
||||
|
|
|
|||
|
|
@ -160,6 +160,8 @@ GlobalPortMatrixWindow::GlobalPortMatrixWindow (Session* s, DataType t)
|
|||
break;
|
||||
}
|
||||
|
||||
signal_key_press_event().connect (sigc::mem_fun (_port_matrix, &PortMatrix::key_press));
|
||||
|
||||
add (_port_matrix);
|
||||
_port_matrix.show ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -435,24 +435,23 @@ GroupTabs::subgroup (RouteGroup* g, bool aux, Placement placement)
|
|||
}
|
||||
|
||||
struct CollectSorter {
|
||||
CollectSorter (string const & key) : _key (key) {}
|
||||
CollectSorter (RouteSortOrderKey key) : _key (key) {}
|
||||
|
||||
bool operator () (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
|
||||
return a->order_key (_key) < b->order_key (_key);
|
||||
}
|
||||
|
||||
string _key;
|
||||
RouteSortOrderKey _key;
|
||||
};
|
||||
|
||||
struct OrderSorter {
|
||||
OrderSorter (string const & key) : _key (key) {}
|
||||
OrderSorter (RouteSortOrderKey key) : _key (key) {}
|
||||
|
||||
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
|
||||
/* use of ">" forces the correct sort order */
|
||||
return a->order_key (_key) < b->order_key (_key);
|
||||
}
|
||||
|
||||
string _key;
|
||||
RouteSortOrderKey _key;
|
||||
};
|
||||
|
||||
/** Collect all members of a RouteGroup so that they are together in the Editor or Mixer.
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ private:
|
|||
|
||||
virtual void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *) {}
|
||||
virtual PBD::PropertyList default_properties () const = 0;
|
||||
virtual std::string order_key () const = 0;
|
||||
virtual ARDOUR::RouteSortOrderKey order_key () const = 0;
|
||||
virtual ARDOUR::RouteList selected_routes () const = 0;
|
||||
virtual void sync_order_keys () = 0;
|
||||
|
||||
|
|
|
|||
BIN
gtk2_ardour/icons/fader_belt_h_medium.png
Normal file
BIN
gtk2_ardour/icons/fader_belt_h_medium.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
BIN
gtk2_ardour/icons/fader_belt_h_medium_desensitised.png
Normal file
BIN
gtk2_ardour/icons/fader_belt_h_medium_desensitised.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
|
|
@ -59,10 +59,7 @@ ArdourKeyboard::setup_keybindings ()
|
|||
|
||||
/* set up the per-user bindings path */
|
||||
|
||||
sys::path p (user_config_directory ());
|
||||
p /= "ardour.bindings";
|
||||
|
||||
user_keybindings_path = p.to_string ();
|
||||
user_keybindings_path = Glib::build_filename (user_config_directory(), "ardour.bindings");
|
||||
|
||||
if (Glib::file_test (user_keybindings_path, Glib::FILE_TEST_EXISTS)) {
|
||||
std::pair<string,string> newpair;
|
||||
|
|
@ -124,7 +121,7 @@ ArdourKeyboard::setup_keybindings ()
|
|||
if (!Glib::path_is_absolute (keybindings_path)) {
|
||||
|
||||
/* not absolute - look in the usual places */
|
||||
sys::path keybindings_file;
|
||||
std::string keybindings_file;
|
||||
|
||||
if ( ! find_file_in_search_path (ardour_config_search_path(), keybindings_path, keybindings_file)) {
|
||||
|
||||
|
|
@ -142,7 +139,7 @@ ArdourKeyboard::setup_keybindings ()
|
|||
|
||||
/* use it */
|
||||
|
||||
keybindings_path = keybindings_file.to_string();
|
||||
keybindings_path = keybindings_file;
|
||||
break;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#include "gtkmm2ext/utils.h"
|
||||
|
||||
#include "pbd/strsplit.h"
|
||||
#include "pbd/replace_all.h"
|
||||
|
||||
#include "ardour/profile.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ fixup_bundle_environment (int, char* [])
|
|||
std::string path;
|
||||
std::string exec_dir = Glib::path_get_dirname (execpath);
|
||||
std::string bundle_dir;
|
||||
std::string userconfigdir = user_config_directory().to_string();
|
||||
std::string userconfigdir = user_config_directory();
|
||||
|
||||
bundle_dir = Glib::path_get_dirname (exec_dir);
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ fixup_bundle_environment (int /*argc*/, char* argv[])
|
|||
|
||||
std::string path;
|
||||
std::string dir_path = Glib::path_get_dirname (Glib::path_get_dirname (argv[0]));
|
||||
std::string userconfigdir = user_config_directory().to_string();
|
||||
std::string userconfigdir = user_config_directory();
|
||||
|
||||
/* note that this function is POSIX/Linux specific, so using / as
|
||||
a dir separator in this context is just fine.
|
||||
|
|
|
|||
|
|
@ -337,8 +337,13 @@ MidiRegionView::canvas_event(GdkEvent* ev)
|
|||
}
|
||||
|
||||
if (ev->type == GDK_2BUTTON_PRESS) {
|
||||
// cannot use double-click to exit internal mode if single-click is being used
|
||||
MouseMode m = trackview.editor().current_mouse_mode();
|
||||
|
||||
if ((m != MouseObject || !Keyboard::modifier_state_contains (ev->button.state, Keyboard::insert_note_modifier())) && (m != MouseDraw)) {
|
||||
return trackview.editor().toggle_internal_editing_from_double_click (ev);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!trackview.editor().internal_editing() && trackview.editor().current_mouse_mode() != MouseGain) ||
|
||||
(trackview.editor().current_mouse_mode() == MouseTimeFX) ||
|
||||
|
|
@ -680,7 +685,11 @@ MidiRegionView::scroll (GdkEventScroll* ev)
|
|||
change_velocities (true, fine, false, together);
|
||||
} else if (ev->direction == GDK_SCROLL_DOWN) {
|
||||
change_velocities (false, fine, false, together);
|
||||
} else {
|
||||
/* left, right: we don't use them */
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3733,6 +3742,9 @@ void
|
|||
MidiRegionView::edit_patch_change (ArdourCanvas::CanvasPatchChange* pc)
|
||||
{
|
||||
PatchChangeDialog d (&_source_relative_time_converter, trackview.session(), *pc->patch (), instrument_info(), Gtk::Stock::APPLY);
|
||||
|
||||
d.set_position (Gtk::WIN_POS_MOUSE);
|
||||
|
||||
if (d.run () != Gtk::RESPONSE_ACCEPT) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
#include "pbd/file_utils.h"
|
||||
#include "pbd/search_path.h"
|
||||
#include "pbd/error.h"
|
||||
|
||||
#include "ardour/filesystem_paths.h"
|
||||
|
|
@ -82,11 +80,11 @@ MixerActor::load_bindings ()
|
|||
|
||||
bindings.set_action_map (myactions);
|
||||
|
||||
sys::path binding_file;
|
||||
std::string binding_file;
|
||||
|
||||
if (find_file_in_search_path (ardour_config_search_path(), "mixer.bindings", binding_file)) {
|
||||
bindings.load (binding_file.to_string());
|
||||
info << string_compose (_("Loaded mixer bindings from %1"), binding_file.to_string()) << endmsg;
|
||||
bindings.load (binding_file);
|
||||
info << string_compose (_("Loaded mixer bindings from %1"), binding_file) << endmsg;
|
||||
} else {
|
||||
error << string_compose (_("Could not find mixer.bindings in search path %1"), ardour_config_search_path().to_string()) << endmsg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,10 +170,10 @@ MixerGroupTabs::default_properties () const
|
|||
return plist;
|
||||
}
|
||||
|
||||
string
|
||||
RouteSortOrderKey
|
||||
MixerGroupTabs::order_key () const
|
||||
{
|
||||
return X_("signal");
|
||||
return MixerSort;
|
||||
}
|
||||
|
||||
RouteList
|
||||
|
|
@ -192,5 +192,5 @@ MixerGroupTabs::selected_routes () const
|
|||
void
|
||||
MixerGroupTabs::sync_order_keys ()
|
||||
{
|
||||
_mixer->sync_order_keys ("");
|
||||
_mixer->sync_order_keys_from_model ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ private:
|
|||
}
|
||||
|
||||
PBD::PropertyList default_properties () const;
|
||||
std::string order_key () const;
|
||||
ARDOUR::RouteSortOrderKey order_key () const;
|
||||
ARDOUR::RouteList selected_routes () const;
|
||||
void sync_order_keys ();
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "pbd/convert.h"
|
||||
#include "pbd/stacktrace.h"
|
||||
#include "pbd/unwind.h"
|
||||
|
||||
#include <glibmm/thread.h>
|
||||
|
||||
#include <gtkmm2ext/gtk_ui.h>
|
||||
|
|
@ -36,6 +38,7 @@
|
|||
#include <gtkmm2ext/tearoff.h>
|
||||
#include <gtkmm2ext/window_title.h>
|
||||
|
||||
#include "ardour/debug.h"
|
||||
#include "ardour/plugin_manager.h"
|
||||
#include "ardour/route_group.h"
|
||||
#include "ardour/session.h"
|
||||
|
|
@ -63,6 +66,7 @@ using namespace Gtkmm2ext;
|
|||
using namespace std;
|
||||
|
||||
using PBD::atoi;
|
||||
using PBD::Unwinder;
|
||||
|
||||
Mixer_UI* Mixer_UI::_instance = 0;
|
||||
|
||||
|
|
@ -78,22 +82,19 @@ Mixer_UI::instance ()
|
|||
|
||||
Mixer_UI::Mixer_UI ()
|
||||
: Window (Gtk::WINDOW_TOPLEVEL)
|
||||
, _visible (false)
|
||||
, no_track_list_redisplay (false)
|
||||
, in_group_row_change (false)
|
||||
, track_menu (0)
|
||||
, _monitor_section (0)
|
||||
, _strip_width (Config->get_default_narrow_ms() ? Narrow : Wide)
|
||||
, ignore_reorder (false)
|
||||
, _following_editor_selection (false)
|
||||
{
|
||||
/* allow this window to become the key focus window */
|
||||
set_flags (CAN_FOCUS);
|
||||
|
||||
_strip_width = Config->get_default_narrow_ms() ? Narrow : Wide;
|
||||
track_menu = 0;
|
||||
_monitor_section = 0;
|
||||
no_track_list_redisplay = false;
|
||||
in_group_row_change = false;
|
||||
_visible = false;
|
||||
strip_redisplay_does_not_reset_order_keys = false;
|
||||
strip_redisplay_does_not_sync_order_keys = false;
|
||||
ignore_sync = false;
|
||||
|
||||
Route::SyncOrderKeys.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::sync_order_keys, this, _1), gui_context());
|
||||
Route::SyncOrderKeys.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::sync_model_from_order_keys, this, _1), gui_context());
|
||||
|
||||
scroller_base.set_flags (Gtk::CAN_FOCUS);
|
||||
scroller_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
|
||||
|
|
@ -305,14 +306,12 @@ Mixer_UI::hide_window (GdkEventAny *ev)
|
|||
|
||||
|
||||
void
|
||||
Mixer_UI::add_strip (RouteList& routes)
|
||||
Mixer_UI::add_strips (RouteList& routes)
|
||||
{
|
||||
ENSURE_GUI_THREAD (*this, &Mixer_UI::add_strip, routes)
|
||||
|
||||
MixerStrip* strip;
|
||||
|
||||
no_track_list_redisplay = true;
|
||||
strip_redisplay_does_not_sync_order_keys = true;
|
||||
{
|
||||
Unwinder<bool> uw (no_track_list_redisplay, true);
|
||||
|
||||
for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
|
||||
boost::shared_ptr<Route> route = (*x);
|
||||
|
|
@ -360,21 +359,15 @@ Mixer_UI::add_strip (RouteList& routes)
|
|||
row[track_columns.route] = route;
|
||||
row[track_columns.strip] = strip;
|
||||
|
||||
if (route->order_key (N_("signal")) == -1) {
|
||||
route->set_order_key (N_("signal"), track_model->children().size()-1);
|
||||
}
|
||||
|
||||
route->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::strip_property_changed, this, _1, strip), gui_context());
|
||||
|
||||
strip->WidthChanged.connect (sigc::mem_fun(*this, &Mixer_UI::strip_width_changed));
|
||||
strip->signal_button_release_event().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
|
||||
}
|
||||
}
|
||||
|
||||
no_track_list_redisplay = false;
|
||||
|
||||
sync_order_keys_from_model ();
|
||||
redisplay_track_list ();
|
||||
|
||||
strip_redisplay_does_not_sync_order_keys = false;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -393,64 +386,119 @@ Mixer_UI::remove_strip (MixerStrip* strip)
|
|||
strips.erase (i);
|
||||
}
|
||||
|
||||
strip_redisplay_does_not_sync_order_keys = true;
|
||||
|
||||
for (ri = rows.begin(); ri != rows.end(); ++ri) {
|
||||
if ((*ri)[track_columns.strip] == strip) {
|
||||
track_model->erase (ri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
strip_redisplay_does_not_sync_order_keys = false;
|
||||
}
|
||||
|
||||
void
|
||||
Mixer_UI::sync_order_keys (string const & src)
|
||||
Mixer_UI::sync_order_keys_from_model ()
|
||||
{
|
||||
TreeModel::Children rows = track_model->children();
|
||||
TreeModel::Children::iterator ri;
|
||||
|
||||
if (src == N_("signal") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
|
||||
if (ignore_reorder || !_session || _session->deletion_in_progress()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<int,int> keys;
|
||||
TreeModel::Children rows = track_model->children();
|
||||
|
||||
if (rows.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, "mixer sync order keys from model\n");
|
||||
|
||||
TreeModel::Children::iterator ri;
|
||||
bool changed = false;
|
||||
uint32_t order = 0;
|
||||
|
||||
unsigned order = 0;
|
||||
for (ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
|
||||
for (ri = rows.begin(); ri != rows.end(); ++ri) {
|
||||
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
|
||||
unsigned int old_key = order;
|
||||
unsigned int new_key = route->order_key (N_("signal"));
|
||||
bool visible = (*ri)[track_columns.visible];
|
||||
|
||||
keys[new_key] = old_key;
|
||||
uint32_t old_key = route->order_key (MixerSort);
|
||||
uint32_t new_key;
|
||||
|
||||
if (new_key != old_key) {
|
||||
if (!visible) {
|
||||
new_key = UINT_MAX;
|
||||
} else {
|
||||
new_key = order;
|
||||
}
|
||||
|
||||
if (old_key != new_key) {
|
||||
route->set_order_key (MixerSort, new_key);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (keys.size() != rows.size()) {
|
||||
PBD::stacktrace (cerr, 20);
|
||||
order++;
|
||||
}
|
||||
assert(keys.size() == rows.size());
|
||||
|
||||
// Remove any gaps in keys caused by automation children tracks
|
||||
vector<int> neworder;
|
||||
for (std::map<int,int>::const_iterator i = keys.begin(); i != keys.end(); ++i) {
|
||||
neworder.push_back(i->second);
|
||||
}
|
||||
assert(neworder.size() == rows.size());
|
||||
|
||||
if (changed) {
|
||||
strip_redisplay_does_not_reset_order_keys = true;
|
||||
track_model->reorder (neworder);
|
||||
strip_redisplay_does_not_reset_order_keys = false;
|
||||
/* tell everyone that we changed the mixer sort keys */
|
||||
_session->sync_order_keys (MixerSort);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Mixer_UI::sync_model_from_order_keys (RouteSortOrderKey src)
|
||||
{
|
||||
if (!_session || _session->deletion_in_progress()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("mixer sync model from order keys, src = %1\n", enum_2_string (src)));
|
||||
|
||||
if (src == EditorSort) {
|
||||
|
||||
if (!Config->get_sync_all_route_ordering()) {
|
||||
/* editor sort keys changed - we don't care */
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, "reset mixer order key to match editor\n");
|
||||
|
||||
/* editor sort keys were changed, update the mixer sort
|
||||
* keys since "sync mixer+editor order" is enabled.
|
||||
*/
|
||||
|
||||
boost::shared_ptr<RouteList> r = _session->get_routes ();
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
(*i)->sync_order_keys (src);
|
||||
}
|
||||
}
|
||||
|
||||
/* we could get here after either a change in the Mixer or Editor sort
|
||||
* order, but either way, the mixer order keys reflect the intended
|
||||
* order for the GUI, so reorder the treeview model to match it.
|
||||
*/
|
||||
|
||||
vector<int> neworder;
|
||||
TreeModel::Children rows = track_model->children();
|
||||
uint32_t n = 0;
|
||||
|
||||
if (rows.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
neworder.assign (rows.size(), 0);
|
||||
|
||||
for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++n) {
|
||||
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
|
||||
neworder[route->order_key (MixerSort)] = n;
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("mixer change order for %1 to %2\n",
|
||||
route->name(), route->order_key (MixerSort)));
|
||||
}
|
||||
|
||||
{
|
||||
Unwinder<bool> uw (ignore_reorder, true);
|
||||
track_model->reorder (neworder);
|
||||
}
|
||||
|
||||
redisplay_track_list ();
|
||||
}
|
||||
|
||||
void
|
||||
Mixer_UI::follow_editor_selection ()
|
||||
{
|
||||
|
|
@ -579,7 +627,7 @@ Mixer_UI::set_session (Session* sess)
|
|||
|
||||
initial_track_display ();
|
||||
|
||||
_session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::add_strip, this, _1), gui_context());
|
||||
_session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::add_strips, this, _1), gui_context());
|
||||
_session->route_group_added.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::add_route_group, this, _1), gui_context());
|
||||
_session->route_group_removed.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::route_groups_changed, this), gui_context());
|
||||
_session->route_groups_reordered.connect (_session_connections, invalidator (*this), boost::bind (&Mixer_UI::route_groups_changed, this), gui_context());
|
||||
|
|
@ -696,7 +744,8 @@ Mixer_UI::set_all_strips_visibility (bool yn)
|
|||
TreeModel::Children rows = track_model->children();
|
||||
TreeModel::Children::iterator i;
|
||||
|
||||
no_track_list_redisplay = true;
|
||||
{
|
||||
Unwinder<bool> uw (no_track_list_redisplay, true);
|
||||
|
||||
for (i = rows.begin(); i != rows.end(); ++i) {
|
||||
|
||||
|
|
@ -713,8 +762,8 @@ Mixer_UI::set_all_strips_visibility (bool yn)
|
|||
|
||||
(*i)[track_columns.visible] = yn;
|
||||
}
|
||||
}
|
||||
|
||||
no_track_list_redisplay = false;
|
||||
redisplay_track_list ();
|
||||
}
|
||||
|
||||
|
|
@ -725,7 +774,8 @@ Mixer_UI::set_all_audio_visibility (int tracks, bool yn)
|
|||
TreeModel::Children rows = track_model->children();
|
||||
TreeModel::Children::iterator i;
|
||||
|
||||
no_track_list_redisplay = true;
|
||||
{
|
||||
Unwinder<bool> uw (no_track_list_redisplay, true);
|
||||
|
||||
for (i = rows.begin(); i != rows.end(); ++i) {
|
||||
TreeModel::Row row = (*i);
|
||||
|
|
@ -759,8 +809,8 @@ Mixer_UI::set_all_audio_visibility (int tracks, bool yn)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
no_track_list_redisplay = false;
|
||||
redisplay_track_list ();
|
||||
}
|
||||
|
||||
|
|
@ -801,30 +851,18 @@ Mixer_UI::hide_all_audiotracks ()
|
|||
void
|
||||
Mixer_UI::track_list_reorder (const TreeModel::Path&, const TreeModel::iterator&, int* /*new_order*/)
|
||||
{
|
||||
strip_redisplay_does_not_sync_order_keys = true;
|
||||
_session->set_remote_control_ids();
|
||||
redisplay_track_list ();
|
||||
strip_redisplay_does_not_sync_order_keys = false;
|
||||
}
|
||||
|
||||
void
|
||||
Mixer_UI::track_list_change (const Gtk::TreeModel::Path&, const Gtk::TreeModel::iterator&)
|
||||
{
|
||||
// never reset order keys because of a property change
|
||||
strip_redisplay_does_not_reset_order_keys = true;
|
||||
_session->set_remote_control_ids();
|
||||
redisplay_track_list ();
|
||||
strip_redisplay_does_not_reset_order_keys = false;
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview reordered\n");
|
||||
sync_order_keys_from_model ();
|
||||
}
|
||||
|
||||
void
|
||||
Mixer_UI::track_list_delete (const Gtk::TreeModel::Path&)
|
||||
{
|
||||
/* this could require an order sync */
|
||||
if (_session && !_session->deletion_in_progress()) {
|
||||
_session->set_remote_control_ids();
|
||||
redisplay_track_list ();
|
||||
}
|
||||
/* this happens as the second step of a DnD within the treeview as well
|
||||
as when a row/route is actually deleted.
|
||||
*/
|
||||
DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview row deleted\n");
|
||||
sync_order_keys_from_model ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -832,13 +870,13 @@ Mixer_UI::redisplay_track_list ()
|
|||
{
|
||||
TreeModel::Children rows = track_model->children();
|
||||
TreeModel::Children::iterator i;
|
||||
long order;
|
||||
|
||||
if (no_track_list_redisplay) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (order = 0, i = rows.begin(); i != rows.end(); ++i, ++order) {
|
||||
for (i = rows.begin(); i != rows.end(); ++i) {
|
||||
|
||||
MixerStrip* strip = (*i)[track_columns.strip];
|
||||
|
||||
if (strip == 0) {
|
||||
|
|
@ -846,10 +884,6 @@ Mixer_UI::redisplay_track_list ()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!strip_redisplay_does_not_reset_order_keys) {
|
||||
strip->route()->set_order_key (N_("signal"), order);
|
||||
}
|
||||
|
||||
bool const visible = (*i)[track_columns.visible];
|
||||
|
||||
if (visible) {
|
||||
|
|
@ -859,6 +893,7 @@ Mixer_UI::redisplay_track_list ()
|
|||
|
||||
if (strip->route()->is_master() || strip->route()->is_monitor()) {
|
||||
out_packer.reorder_child (*strip, -1);
|
||||
|
||||
} else {
|
||||
strip_packer.reorder_child (*strip, -1); /* put at end */
|
||||
}
|
||||
|
|
@ -888,10 +923,6 @@ Mixer_UI::redisplay_track_list ()
|
|||
}
|
||||
}
|
||||
|
||||
if (!strip_redisplay_does_not_reset_order_keys && !strip_redisplay_does_not_sync_order_keys) {
|
||||
_session->sync_order_keys (N_("signal"));
|
||||
}
|
||||
|
||||
_group_tabs->set_dirty ();
|
||||
}
|
||||
|
||||
|
|
@ -924,8 +955,17 @@ Mixer_UI::strip_width_changed ()
|
|||
|
||||
struct SignalOrderRouteSorter {
|
||||
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
|
||||
/* use of ">" forces the correct sort order */
|
||||
return a->order_key (N_("signal")) < b->order_key (N_("signal"));
|
||||
if (a->is_master() || a->is_monitor()) {
|
||||
/* "a" is a special route (master, monitor, etc), and comes
|
||||
* last in the mixer ordering
|
||||
*/
|
||||
return false;
|
||||
} else if (b->is_master() || b->is_monitor()) {
|
||||
/* everything comes before b */
|
||||
return true;
|
||||
}
|
||||
return a->order_key (MixerSort) < b->order_key (MixerSort);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -938,13 +978,13 @@ Mixer_UI::initial_track_display ()
|
|||
|
||||
copy.sort (sorter);
|
||||
|
||||
no_track_list_redisplay = true;
|
||||
{
|
||||
Unwinder<bool> uw1 (no_track_list_redisplay, true);
|
||||
Unwinder<bool> uw2 (ignore_reorder, true);
|
||||
|
||||
track_model->clear ();
|
||||
|
||||
add_strip (copy);
|
||||
|
||||
no_track_list_redisplay = false;
|
||||
add_strips (copy);
|
||||
}
|
||||
|
||||
redisplay_track_list ();
|
||||
}
|
||||
|
|
@ -1551,18 +1591,6 @@ Mixer_UI::on_key_press_event (GdkEventKey* ev)
|
|||
|
||||
KeyboardKey k (ev->state, ev->keyval);
|
||||
|
||||
GtkAccelKey key;
|
||||
|
||||
/* Handle toggle-mixer-on-top here, so it can do a different thing if the
|
||||
mixer is already on top and received this key press.
|
||||
*/
|
||||
if (gtk_accel_map_lookup_entry("<Actions>/Common/toggle-mixer-on-top", &key)) {
|
||||
if (int (k.state()) == key.accel_mods && k.key() == key.accel_key) {
|
||||
ARDOUR_UI::instance()->goto_editor_window();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bindings.activate (k, Bindings::Press)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1670,7 +1698,6 @@ Mixer_UI::setup_track_display ()
|
|||
track_display.set_headers_visible (true);
|
||||
|
||||
track_model->signal_row_deleted().connect (sigc::mem_fun (*this, &Mixer_UI::track_list_delete));
|
||||
track_model->signal_row_changed().connect (sigc::mem_fun (*this, &Mixer_UI::track_list_change));
|
||||
track_model->signal_rows_reordered().connect (sigc::mem_fun (*this, &Mixer_UI::track_list_reorder));
|
||||
|
||||
CellRendererToggle* track_list_visible_cell = dynamic_cast<CellRendererToggle*>(track_display.get_column_cell_renderer (1));
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "pbd/signals.h"
|
||||
|
||||
#include "ardour/ardour.h"
|
||||
#include "ardour/types.h"
|
||||
#include "ardour/session_handle.h"
|
||||
|
||||
#include "enums.h"
|
||||
|
|
@ -129,7 +130,7 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR
|
|||
void scroll_left ();
|
||||
void scroll_right ();
|
||||
|
||||
void add_strip (ARDOUR::RouteList&);
|
||||
void add_strips (ARDOUR::RouteList&);
|
||||
void remove_strip (MixerStrip *);
|
||||
|
||||
MixerStrip* strip_by_route (boost::shared_ptr<ARDOUR::Route>);
|
||||
|
|
@ -160,7 +161,6 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR
|
|||
bool track_display_button_press (GdkEventButton*);
|
||||
void strip_width_changed ();
|
||||
|
||||
void track_list_change (const Gtk::TreeModel::Path&,const Gtk::TreeModel::iterator&);
|
||||
void track_list_delete (const Gtk::TreeModel::Path&);
|
||||
void track_list_reorder (const Gtk::TreeModel::Path& path, const Gtk::TreeModel::iterator& iter, int* new_order);
|
||||
|
||||
|
|
@ -244,10 +244,9 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR
|
|||
|
||||
Width _strip_width;
|
||||
|
||||
void sync_order_keys (std::string const &);
|
||||
bool strip_redisplay_does_not_reset_order_keys;
|
||||
bool strip_redisplay_does_not_sync_order_keys;
|
||||
bool ignore_sync;
|
||||
void sync_order_keys_from_model ();
|
||||
void sync_model_from_order_keys (ARDOUR::RouteSortOrderKey);
|
||||
bool ignore_reorder;
|
||||
|
||||
void parameter_changed (std::string const &);
|
||||
void set_route_group_activation (ARDOUR::RouteGroup *, bool);
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ NagScreen::maybe_nag (std::string why)
|
|||
bool really_subscribed;
|
||||
bool maybe_subscribed;
|
||||
|
||||
path = Glib::build_filename (user_config_directory().to_string(), ".nevernag");
|
||||
path = Glib::build_filename (user_config_directory(), ".nevernag");
|
||||
|
||||
if (Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
|
||||
return 0;
|
||||
|
|
@ -114,7 +114,7 @@ NagScreen::mark_never_again ()
|
|||
{
|
||||
std::string path;
|
||||
|
||||
path = Glib::build_filename (user_config_directory().to_string(), ".nevernag");
|
||||
path = Glib::build_filename (user_config_directory(), ".nevernag");
|
||||
|
||||
ofstream nagfile (path.c_str());
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ NagScreen::mark_subscriber ()
|
|||
{
|
||||
std::string path;
|
||||
|
||||
path = Glib::build_filename (user_config_directory().to_string(), ".askedaboutsub");
|
||||
path = Glib::build_filename (user_config_directory(), ".askedaboutsub");
|
||||
|
||||
ofstream subsfile (path.c_str());
|
||||
}
|
||||
|
|
@ -134,7 +134,7 @@ NagScreen::mark_affirmed_subscriber ()
|
|||
{
|
||||
std::string path;
|
||||
|
||||
path = Glib::build_filename (user_config_directory().to_string(), ".isubscribe");
|
||||
path = Glib::build_filename (user_config_directory(), ".isubscribe");
|
||||
|
||||
ofstream subsfile (path.c_str());
|
||||
}
|
||||
|
|
@ -152,13 +152,13 @@ NagScreen::is_subscribed (bool& really)
|
|||
subscribed. we try to trust our users :)
|
||||
*/
|
||||
|
||||
path = Glib::build_filename (user_config_directory().to_string(), ".isubscribe");
|
||||
path = Glib::build_filename (user_config_directory(), ".isubscribe");
|
||||
if (file_test (path, FILE_TEST_EXISTS)) {
|
||||
really = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
path = Glib::build_filename (user_config_directory().to_string(), ".askedaboutsub");
|
||||
path = Glib::build_filename (user_config_directory(), ".askedaboutsub");
|
||||
if (file_test (path, FILE_TEST_EXISTS)) {
|
||||
/* they never said they were subscribed but they
|
||||
did once express an interest in it.
|
||||
|
|
|
|||
|
|
@ -100,8 +100,6 @@ PluginUIWindow::PluginUIWindow (
|
|||
Label* label = manage (new Label());
|
||||
label->set_markup ("<b>THIS IS THE PLUGIN UI</b>");
|
||||
|
||||
std::cout << "SHOW UI " << insert->plugin()->unique_id()
|
||||
<< " editor: " << editor << std::endl;
|
||||
if (editor && insert->plugin()->has_editor()) {
|
||||
switch (insert->type()) {
|
||||
case ARDOUR::Windows_VST:
|
||||
|
|
@ -560,6 +558,15 @@ PlugUIBase::latency_button_clicked ()
|
|||
if (!latency_gui) {
|
||||
latency_gui = new LatencyGUI (*(insert.get()), insert->session().frame_rate(), insert->session().get_block_size());
|
||||
latency_dialog = new ArdourWindow (_("Edit Latency"));
|
||||
latency_dialog->set_position (WIN_POS_MOUSE);
|
||||
/* use both keep-above and transient for to try cover as many
|
||||
different WM's as possible.
|
||||
*/
|
||||
latency_dialog->set_keep_above (true);
|
||||
Window* win = dynamic_cast<Window*> (bypass_button.get_toplevel ());
|
||||
if (win) {
|
||||
latency_dialog->set_transient_for (*win);
|
||||
}
|
||||
latency_dialog->add (*latency_gui);
|
||||
latency_dialog->signal_hide().connect (sigc::mem_fun (*this, &PlugUIBase::set_latency_label));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ struct RouteIOs {
|
|||
class RouteIOsComparator {
|
||||
public:
|
||||
bool operator() (RouteIOs const & a, RouteIOs const & b) {
|
||||
return a.route->order_key (X_("editor")) < b.route->order_key (X_("editor"));
|
||||
return a.route->order_key (EditorSort) < b.route->order_key (EditorSort);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ PortMatrix::init ()
|
|||
_session->engine().PortRegisteredOrUnregistered.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
|
||||
|
||||
/* watch for route order keys changing, which changes the order of things in our global ports list(s) */
|
||||
_session->RouteOrderKeyChanged.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports_proxy, this), gui_context());
|
||||
Route::SyncOrderKeys.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports_proxy, this, _1), gui_context());
|
||||
|
||||
/* Part 3: other stuff */
|
||||
|
||||
|
|
@ -504,12 +504,16 @@ PortMatrix::popup_menu (BundleChannel column, BundleChannel row, uint32_t t)
|
|||
}
|
||||
|
||||
items.push_back (MenuElem (_("Rescan"), sigc::mem_fun (*this, &PortMatrix::setup_all_ports)));
|
||||
|
||||
items.push_back (CheckMenuElem (_("Show individual ports"), sigc::mem_fun (*this, &PortMatrix::toggle_show_only_bundles)));
|
||||
CheckMenuItem* i = dynamic_cast<CheckMenuItem*> (&items.back());
|
||||
_inhibit_toggle_show_only_bundles = true;
|
||||
i->set_active (!_show_only_bundles);
|
||||
_inhibit_toggle_show_only_bundles = false;
|
||||
|
||||
items.push_back (MenuElem (_("Flip"), sigc::mem_fun (*this, &PortMatrix::flip)));
|
||||
items.back().set_sensitive (can_flip ());
|
||||
|
||||
_menu->popup (1, t);
|
||||
}
|
||||
|
||||
|
|
@ -594,13 +598,15 @@ PortMatrix::setup_global_ports ()
|
|||
}
|
||||
|
||||
void
|
||||
PortMatrix::setup_global_ports_proxy ()
|
||||
PortMatrix::setup_global_ports_proxy (RouteSortOrderKey sk)
|
||||
{
|
||||
if (sk == EditorSort) {
|
||||
/* Avoid a deadlock by calling this in an idle handler: see IOSelector::io_changed_proxy
|
||||
for a discussion.
|
||||
*/
|
||||
|
||||
Glib::signal_idle().connect_once (sigc::mem_fun (*this, &PortMatrix::setup_global_ports));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1122,3 +1128,75 @@ PortMatrix::bundle_with_channels (boost::shared_ptr<ARDOUR::Bundle> b)
|
|||
{
|
||||
return b && b->nchannels() != ARDOUR::ChanCount::ZERO;
|
||||
}
|
||||
|
||||
/** See if a `flip' is possible.
|
||||
* @return If flip is possible, the new (row, column) notebook indices that
|
||||
* should be selected; otherwise, (-1, -1)
|
||||
*/
|
||||
pair<int, int>
|
||||
PortMatrix::check_flip () const
|
||||
{
|
||||
/* Look for the row's port group name in the columns */
|
||||
|
||||
int new_column = 0;
|
||||
boost::shared_ptr<const PortGroup> r = visible_ports (_row_index);
|
||||
PortGroupList::List::const_iterator i = _ports[_column_index].begin();
|
||||
while (i != _ports[_column_index].end() && (*i)->name != r->name) {
|
||||
++i;
|
||||
++new_column;
|
||||
}
|
||||
|
||||
if (i == _ports[_column_index].end ()) {
|
||||
return make_pair (-1, -1);
|
||||
}
|
||||
|
||||
/* Look for the column's port group name in the rows */
|
||||
|
||||
int new_row = 0;
|
||||
boost::shared_ptr<const PortGroup> c = visible_ports (_column_index);
|
||||
i = _ports[_row_index].begin();
|
||||
while (i != _ports[_row_index].end() && (*i)->name != c->name) {
|
||||
++i;
|
||||
++new_row;
|
||||
}
|
||||
|
||||
if (i == _ports[_row_index].end ()) {
|
||||
return make_pair (-1, -1);
|
||||
}
|
||||
|
||||
if (_arrangement == LEFT_TO_BOTTOM) {
|
||||
new_row = _ports[_row_index].size() - new_row - 1;
|
||||
}
|
||||
|
||||
return make_pair (new_row, new_column);
|
||||
}
|
||||
|
||||
bool
|
||||
PortMatrix::can_flip () const
|
||||
{
|
||||
return check_flip().first != -1;
|
||||
}
|
||||
|
||||
/** Flip the column and row pages around, if possible */
|
||||
void
|
||||
PortMatrix::flip ()
|
||||
{
|
||||
pair<int, int> n = check_flip ();
|
||||
if (n.first == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
_vnotebook.set_current_page (n.first);
|
||||
_hnotebook.set_current_page (n.second);
|
||||
}
|
||||
|
||||
bool
|
||||
PortMatrix::key_press (GdkEventKey* k)
|
||||
{
|
||||
if (k->keyval == GDK_f) {
|
||||
flip ();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,9 @@ public:
|
|||
|
||||
PortMatrixNode::State get_association (PortMatrixNode) const;
|
||||
|
||||
void flip ();
|
||||
bool key_press (GdkEventKey *);
|
||||
|
||||
/** @param c Channels; where c[0] is from _ports[0] and c[1] is from _ports[1].
|
||||
* @param s New state.
|
||||
*/
|
||||
|
|
@ -185,7 +188,7 @@ private:
|
|||
void disassociate_all_on_channel (boost::weak_ptr<ARDOUR::Bundle>, uint32_t, int);
|
||||
void disassociate_all_on_bundle (boost::weak_ptr<ARDOUR::Bundle>, int);
|
||||
void setup_global_ports ();
|
||||
void setup_global_ports_proxy ();
|
||||
void setup_global_ports_proxy (ARDOUR::RouteSortOrderKey);
|
||||
void toggle_show_only_bundles ();
|
||||
bool on_scroll_event (GdkEventScroll *);
|
||||
boost::shared_ptr<ARDOUR::IO> io_from_bundle (boost::shared_ptr<ARDOUR::Bundle>) const;
|
||||
|
|
@ -199,10 +202,12 @@ private:
|
|||
void add_disassociate_option (Gtk::Menu_Helpers::MenuList &, boost::weak_ptr<ARDOUR::Bundle>, int, int);
|
||||
void port_connected_or_disconnected ();
|
||||
void update_tab_highlighting ();
|
||||
std::pair<int, int> check_flip () const;
|
||||
bool can_flip () const;
|
||||
|
||||
Gtk::Window* _parent;
|
||||
|
||||
/// port type that we are working with, or NIL if we are working with all of them
|
||||
/** port type that we are working with, or NIL if we are working with all of them */
|
||||
ARDOUR::DataType _type;
|
||||
PBD::ScopedConnectionList _route_connections;
|
||||
PBD::ScopedConnectionList _changed_connections;
|
||||
|
|
|
|||
|
|
@ -91,11 +91,11 @@ Glib::RefPtr<Gdk::Pixbuf> RouteTimeAxisView::slider_desensitised;
|
|||
void
|
||||
RouteTimeAxisView::setup_slider_pix ()
|
||||
{
|
||||
if ((slider = ::get_icon ("fader_belt_h")) == 0) {
|
||||
if ((slider = ::get_icon ("fader_belt_h_medium")) == 0) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
if ((slider_desensitised = ::get_icon ("fader_belt_h_desensitised")) == 0) {
|
||||
if ((slider_desensitised = ::get_icon ("fader_belt_h_medium_desensitised")) == 0) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
}
|
||||
|
|
@ -205,7 +205,11 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
|||
}
|
||||
|
||||
controls_table.attach (route_group_button, 7, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
|
||||
controls_table.attach (gm.get_gain_slider(), 0, 5, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
|
||||
Gtk::VBox* pad = manage (new Gtk::VBox);
|
||||
pad->pack_start (gm.get_gain_slider(), false, false);
|
||||
pad->pack_start (*manage (new Gtk::Label), true, true);
|
||||
pad->show_all ();
|
||||
controls_table.attach (*pad, 0, 5, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
|
||||
|
||||
ARDOUR_UI::instance()->set_tip(*solo_button,_("Solo"));
|
||||
ARDOUR_UI::instance()->set_tip(*mute_button,_("Mute"));
|
||||
|
|
|
|||
|
|
@ -1628,14 +1628,14 @@ RouteUI::adjust_latency ()
|
|||
void
|
||||
RouteUI::save_as_template ()
|
||||
{
|
||||
sys::path path;
|
||||
std::string path;
|
||||
std::string safe_name;
|
||||
string name;
|
||||
|
||||
path = ARDOUR::user_route_template_directory ();
|
||||
|
||||
if (g_mkdir_with_parents (path.to_string().c_str(), 0755)) {
|
||||
error << string_compose (_("Cannot create route template directory %1"), path.to_string()) << endmsg;
|
||||
if (g_mkdir_with_parents (path.c_str(), 0755)) {
|
||||
error << string_compose (_("Cannot create route template directory %1"), path) << endmsg;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1657,9 +1657,9 @@ RouteUI::save_as_template ()
|
|||
safe_name = legalize_for_path (name);
|
||||
safe_name += template_suffix;
|
||||
|
||||
path /= safe_name;
|
||||
path = Glib::build_filename (path, safe_name);
|
||||
|
||||
_route->save_as_template (path.to_string(), name);
|
||||
_route->save_as_template (path, name);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1716,13 +1716,17 @@ void
|
|||
RouteUI::open_remote_control_id_dialog ()
|
||||
{
|
||||
ArdourDialog dialog (_("Remote Control ID"));
|
||||
SpinButton* spin = 0;
|
||||
|
||||
dialog.get_vbox()->set_border_width (18);
|
||||
|
||||
if (Config->get_remote_model() == UserOrdered) {
|
||||
uint32_t const limit = _session->ntracks() + _session->nbusses () + 4;
|
||||
|
||||
HBox* hbox = manage (new HBox);
|
||||
hbox->set_spacing (6);
|
||||
hbox->pack_start (*manage (new Label (_("Remote control ID:"))));
|
||||
SpinButton* spin = manage (new SpinButton);
|
||||
spin = manage (new SpinButton);
|
||||
spin->set_digits (0);
|
||||
spin->set_increments (1, 10);
|
||||
spin->set_range (0, limit);
|
||||
|
|
@ -1732,11 +1736,22 @@ RouteUI::open_remote_control_id_dialog ()
|
|||
|
||||
dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
|
||||
dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT);
|
||||
} else {
|
||||
Label* l = manage (new Label());
|
||||
l->set_markup (string_compose (_("Remote Control IDs are currently determined by track/bus ordering in %1\n\n"
|
||||
"This %2 has remote control ID %3\n\n\n"
|
||||
"<span size=\"small\" style=\"italic\">Use the User Interaction tab of the Preferences window if you want to change this</span>"),
|
||||
(Config->get_remote_model() == MixerOrdered ? _("the mixer") : ("the editor")),
|
||||
(is_track() ? _("track") : _("bus")),
|
||||
_route->remote_control_id()));
|
||||
dialog.get_vbox()->pack_start (*l);
|
||||
dialog.add_button (Stock::OK, RESPONSE_CANCEL);
|
||||
}
|
||||
|
||||
dialog.show_all ();
|
||||
int const r = dialog.run ();
|
||||
|
||||
if (r == RESPONSE_ACCEPT) {
|
||||
if (r == RESPONSE_ACCEPT && spin) {
|
||||
_route->set_remote_control_id (spin->get_value_as_int ());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
#include "sfdb_freesound_mootcher.h"
|
||||
|
||||
#include "pbd/xml++.h"
|
||||
#include "pbd/filesystem.h"
|
||||
#include "pbd/error.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -91,10 +91,12 @@ void Mootcher::changeWorkingDir(const char *saveLocation)
|
|||
|
||||
void Mootcher::ensureWorkingDir ()
|
||||
{
|
||||
PBD::sys::path p = basePath;
|
||||
p /= "snd";
|
||||
if (!PBD::sys::is_directory (p)) {
|
||||
PBD::sys::create_directories (p);
|
||||
std::string p = Glib::build_filename (basePath, "snd");
|
||||
|
||||
if (!Glib::file_test (p, Glib::FILE_TEST_IS_DIR)) {
|
||||
if (g_mkdir_with_parents (p.c_str(), 0775) != 0) {
|
||||
PBD::error << "Unable to create Mootcher working dir" << endmsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1301,8 +1301,7 @@ SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool&
|
|||
bool
|
||||
SoundFileOmega::check_link_status (const Session* s, const vector<string>& paths)
|
||||
{
|
||||
sys::path path = s->session_directory().sound_path() / "linktest";
|
||||
string tmpdir = path.to_string();
|
||||
std::string tmpdir(Glib::build_filename (s->session_directory().sound_path(), "linktest"));
|
||||
bool ret = false;
|
||||
|
||||
if (mkdir (tmpdir.c_str(), 0744)) {
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ ShuttleControl::on_button_release_event (GdkEventButton* ev)
|
|||
|
||||
case 2:
|
||||
if (_session->transport_rolling()) {
|
||||
_session->request_transport_speed (1.0);
|
||||
_session->request_transport_speed (1.0, Config->get_shuttle_behaviour() == Wheel);
|
||||
}
|
||||
return true;
|
||||
|
||||
|
|
@ -479,7 +479,7 @@ ShuttleControl::use_shuttle_fract (bool force)
|
|||
speed = shuttle_max_speed * shuttle_fract;
|
||||
}
|
||||
|
||||
_session->request_transport_speed_nonzero (speed);
|
||||
_session->request_transport_speed_nonzero (speed, true);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -648,6 +648,9 @@ ShuttleControl::parameter_changed (std::string p)
|
|||
if (_session->transport_speed() == 1.0) {
|
||||
queue_draw ();
|
||||
} else {
|
||||
/* reset current speed and
|
||||
revert to 1.0 as the default
|
||||
*/
|
||||
_session->request_transport_speed (1.0);
|
||||
/* redraw when speed changes */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ Splash::Splash ()
|
|||
{
|
||||
assert (the_splash == 0);
|
||||
|
||||
sys::path splash_file;
|
||||
std::string splash_file;
|
||||
|
||||
if (!find_file_in_search_path (ardour_data_search_path(), "splash.png", splash_file)) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
try {
|
||||
pixbuf = Gdk::Pixbuf::create_from_file (splash_file.to_string());
|
||||
pixbuf = Gdk::Pixbuf::create_from_file (splash_file);
|
||||
}
|
||||
|
||||
catch (...) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/file_utils.h"
|
||||
#include "pbd/filesystem.h"
|
||||
#include "pbd/replace_all.h"
|
||||
#include "pbd/whitespace.h"
|
||||
|
||||
|
|
@ -38,6 +37,7 @@
|
|||
#include "ardour/session.h"
|
||||
#include "ardour/session_state_utils.h"
|
||||
#include "ardour/template_utils.h"
|
||||
#include "ardour/filename_extensions.h"
|
||||
|
||||
#include "ardour_ui.h"
|
||||
#include "startup.h"
|
||||
|
|
@ -122,7 +122,7 @@ Ardour will play NO role in monitoring"))
|
|||
set_default_icon_list (window_icons);
|
||||
}
|
||||
|
||||
new_user = !exists (been_here_before_path ());
|
||||
new_user = !Glib::file_test(been_here_before_path(), Glib::FILE_TEST_EXISTS);
|
||||
|
||||
bool need_audio_setup = !EngineControl::engine_running();
|
||||
|
||||
|
|
@ -130,16 +130,6 @@ Ardour will play NO role in monitoring"))
|
|||
|
||||
if (new_user) {
|
||||
|
||||
/* Create the config directory so that we have somewhere to put the
|
||||
been_here_before file.
|
||||
*/
|
||||
try {
|
||||
sys::create_directories (user_config_directory ());
|
||||
}
|
||||
catch (const sys::filesystem_error& ex) {
|
||||
error << "Could not create user configuration directory" << endmsg;
|
||||
}
|
||||
|
||||
setup_new_user_page ();
|
||||
setup_first_time_config_page ();
|
||||
setup_monitoring_choice_page ();
|
||||
|
|
@ -246,8 +236,8 @@ std::string
|
|||
ArdourStartup::session_template_name ()
|
||||
{
|
||||
if (!load_template_override.empty()) {
|
||||
string the_path = (ARDOUR::user_template_directory()/ (load_template_override + ".template")).to_string();
|
||||
return the_path;
|
||||
string the_path(ARDOUR::user_template_directory());
|
||||
return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
|
||||
}
|
||||
|
||||
if (ic_existing_session_button.get_active()) {
|
||||
|
|
@ -651,7 +641,7 @@ ArdourStartup::on_apply ()
|
|||
Config->set_use_monitor_bus (use_monitor_section_button.get_active());
|
||||
|
||||
/* "touch" the been-here-before path now that we're about to save Config */
|
||||
ofstream fout (been_here_before_path().to_string().c_str());
|
||||
ofstream fout (been_here_before_path().c_str());
|
||||
|
||||
Config->save_state ();
|
||||
}
|
||||
|
|
@ -910,7 +900,7 @@ ArdourStartup::new_name_changed ()
|
|||
int
|
||||
ArdourStartup::redisplay_recent_sessions ()
|
||||
{
|
||||
std::vector<sys::path> session_directories;
|
||||
std::vector<std::string> session_directories;
|
||||
RecentSessionsSorter cmp;
|
||||
|
||||
recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
|
||||
|
|
@ -931,9 +921,9 @@ ArdourStartup::redisplay_recent_sessions ()
|
|||
session_directories.push_back ((*i).second);
|
||||
}
|
||||
|
||||
for (vector<sys::path>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
|
||||
for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
|
||||
{
|
||||
std::vector<sys::path> state_file_paths;
|
||||
std::vector<std::string> state_file_paths;
|
||||
|
||||
// now get available states for this session
|
||||
|
||||
|
|
@ -941,7 +931,7 @@ ArdourStartup::redisplay_recent_sessions ()
|
|||
|
||||
vector<string*>* states;
|
||||
vector<const gchar*> item;
|
||||
string fullpath = (*i).to_string();
|
||||
string fullpath = *i;
|
||||
|
||||
/* remove any trailing / */
|
||||
|
||||
|
|
@ -1402,11 +1392,9 @@ ArdourStartup::existing_session_selected ()
|
|||
move_along_now ();
|
||||
}
|
||||
|
||||
sys::path
|
||||
std::string
|
||||
ArdourStartup::been_here_before_path () const
|
||||
{
|
||||
sys::path b = user_config_directory();
|
||||
b /= ".a3"; // XXXX use more specific version so we can catch upgrades
|
||||
return b;
|
||||
// XXXX use more specific version so we can catch upgrades
|
||||
return Glib::build_filename (user_config_directory (), ".a3");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,8 +39,6 @@
|
|||
#include <gtkmm/liststore.h>
|
||||
#include <gtkmm/combobox.h>
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
|
||||
#include "ardour/utils.h"
|
||||
|
||||
class EngineControl;
|
||||
|
|
@ -87,7 +85,7 @@ class ArdourStartup : public Gtk::Assistant {
|
|||
bool new_user;
|
||||
bool new_only;
|
||||
|
||||
PBD::sys::path been_here_before_path () const;
|
||||
std::string been_here_before_path () const;
|
||||
|
||||
void on_apply ();
|
||||
void on_cancel ();
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
#include "pbd/file_utils.h"
|
||||
|
||||
#include "gtkmm2ext/keyboard.h"
|
||||
|
|
@ -708,10 +707,10 @@ StepEntry::load_bindings ()
|
|||
|
||||
bindings.set_action_map (myactions);
|
||||
|
||||
sys::path binding_file;
|
||||
std::string binding_file;
|
||||
|
||||
if (find_file_in_search_path (ardour_config_search_path(), "step_editing.bindings", binding_file)) {
|
||||
bindings.load (binding_file.to_string());
|
||||
bindings.load (binding_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ ThemeManager::button_press_event (GdkEventButton* ev)
|
|||
void
|
||||
load_rc_file (const string& filename, bool themechange)
|
||||
{
|
||||
sys::path rc_file_path;
|
||||
std::string rc_file_path;
|
||||
|
||||
if (!find_file_in_search_path (ardour_config_search_path(), filename, rc_file_path)) {
|
||||
warning << string_compose (_("Unable to find UI style file %1 in search path %2. %3 will look strange"),
|
||||
|
|
@ -211,9 +211,9 @@ load_rc_file (const string& filename, bool themechange)
|
|||
return;
|
||||
}
|
||||
|
||||
info << "Loading ui configuration file " << rc_file_path.to_string() << endmsg;
|
||||
info << "Loading ui configuration file " << rc_file_path << endmsg;
|
||||
|
||||
Gtkmm2ext::UI::instance()->load_rcfile (rc_file_path.to_string(), themechange);
|
||||
Gtkmm2ext::UI::instance()->load_rcfile (rc_file_path, themechange);
|
||||
}
|
||||
|
||||
/* hmm, this is a problem. the profile doesn't
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/xml++.h"
|
||||
#include "pbd/filesystem.h"
|
||||
#include "pbd/file_utils.h"
|
||||
#include "pbd/error.h"
|
||||
|
||||
|
|
@ -65,7 +64,7 @@ UIConfiguration::load_defaults ()
|
|||
{
|
||||
int found = 0;
|
||||
|
||||
sys::path default_ui_rc_file;
|
||||
std::string default_ui_rc_file;
|
||||
std::string rcfile;
|
||||
|
||||
if (getenv ("ARDOUR_SAE")) {
|
||||
|
|
@ -78,7 +77,7 @@ UIConfiguration::load_defaults ()
|
|||
XMLTree tree;
|
||||
found = 1;
|
||||
|
||||
string rcfile = default_ui_rc_file.to_string();
|
||||
string rcfile = default_ui_rc_file;
|
||||
|
||||
info << string_compose (_("Loading default ui configuration file %1"), rcfile) << endl;
|
||||
|
||||
|
|
@ -103,13 +102,13 @@ UIConfiguration::load_state ()
|
|||
{
|
||||
bool found = false;
|
||||
|
||||
sys::path default_ui_rc_file;
|
||||
std::string default_ui_rc_file;
|
||||
|
||||
if ( find_file_in_search_path (ardour_config_search_path(), "ardour3_ui_default.conf", default_ui_rc_file)) {
|
||||
XMLTree tree;
|
||||
found = true;
|
||||
|
||||
string rcfile = default_ui_rc_file.to_string();
|
||||
string rcfile = default_ui_rc_file;
|
||||
|
||||
info << string_compose (_("Loading default ui configuration file %1"), rcfile) << endl;
|
||||
|
||||
|
|
@ -124,13 +123,13 @@ UIConfiguration::load_state ()
|
|||
}
|
||||
}
|
||||
|
||||
sys::path user_ui_rc_file;
|
||||
std::string user_ui_rc_file;
|
||||
|
||||
if (find_file_in_search_path (ardour_config_search_path(), "ardour3_ui.conf", user_ui_rc_file)) {
|
||||
XMLTree tree;
|
||||
found = true;
|
||||
|
||||
string rcfile = user_ui_rc_file.to_string();
|
||||
string rcfile = user_ui_rc_file;
|
||||
|
||||
info << string_compose (_("Loading user ui configuration file %1"), rcfile) << endmsg;
|
||||
|
||||
|
|
@ -160,18 +159,8 @@ UIConfiguration::save_state()
|
|||
{
|
||||
XMLTree tree;
|
||||
|
||||
try {
|
||||
sys::create_directories (user_config_directory ());
|
||||
}
|
||||
catch (const sys::filesystem_error& ex) {
|
||||
error << "Could not create user configuration directory" << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sys::path rcfile_path(user_config_directory());
|
||||
|
||||
rcfile_path /= "ardour3_ui.conf";
|
||||
const string rcfile = rcfile_path.to_string();
|
||||
std::string rcfile(user_config_directory());
|
||||
rcfile = Glib::build_filename (rcfile, "ardour3_ui.conf");
|
||||
|
||||
// this test seems bogus?
|
||||
if (rcfile.length()) {
|
||||
|
|
|
|||
|
|
@ -498,14 +498,14 @@ get_xpm (std::string name)
|
|||
|
||||
spath.add_subdirectory_to_paths("pixmaps");
|
||||
|
||||
sys::path data_file_path;
|
||||
std::string data_file_path;
|
||||
|
||||
if(!find_file_in_search_path (spath, name, data_file_path)) {
|
||||
fatal << string_compose (_("cannot find XPM file for %1"), name) << endmsg;
|
||||
}
|
||||
|
||||
try {
|
||||
xpm_map[name] = Gdk::Pixbuf::create_from_file (data_file_path.to_string());
|
||||
xpm_map[name] = Gdk::Pixbuf::create_from_file (data_file_path);
|
||||
} catch(const Glib::Error& e) {
|
||||
warning << "Caught Glib::Error: " << e.what() << endmsg;
|
||||
}
|
||||
|
|
@ -524,13 +524,13 @@ get_icon_path (const char* cname)
|
|||
|
||||
spath.add_subdirectory_to_paths("icons");
|
||||
|
||||
sys::path data_file_path;
|
||||
std::string data_file_path;
|
||||
|
||||
if (!find_file_in_search_path (spath, name, data_file_path)) {
|
||||
fatal << string_compose (_("cannot find icon image for %1 using %2"), name, spath.to_string()) << endmsg;
|
||||
}
|
||||
|
||||
return data_file_path.to_string();
|
||||
return data_file_path;
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf>
|
||||
|
|
|
|||
|
|
@ -49,9 +49,12 @@ class AudioPort : public Port
|
|||
friend class AudioEngine;
|
||||
|
||||
AudioPort (std::string const &, Flags);
|
||||
/* special access for engine only */
|
||||
Sample* engine_get_whole_audio_buffer ();
|
||||
|
||||
private:
|
||||
AudioBuffer* _buffer;
|
||||
bool _buf_valid;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include "pbd/xml++.h"
|
||||
#include "pbd/id.h"
|
||||
#include "pbd/filesystem.h"
|
||||
#include "ardour/element_importer.h"
|
||||
#include "ardour/element_import_handler.h"
|
||||
#include "ardour/import_status.h"
|
||||
|
|
@ -100,7 +99,7 @@ class AudioRegionImporter : public ElementImporter
|
|||
|
||||
bool parse_xml_region ();
|
||||
bool parse_source_xml ();
|
||||
PBD::sys::path get_sound_dir (XMLTree const & tree);
|
||||
std::string get_sound_dir (XMLTree const & tree);
|
||||
|
||||
void prepare_region ();
|
||||
void prepare_sources ();
|
||||
|
|
|
|||
|
|
@ -268,6 +268,9 @@ private:
|
|||
Glib::Mutex _process_lock;
|
||||
Glib::Cond session_removed;
|
||||
bool session_remove_pending;
|
||||
frameoffset_t session_removal_countdown;
|
||||
gain_t session_removal_gain;
|
||||
gain_t session_removal_gain_step;
|
||||
bool _running;
|
||||
bool _has_run;
|
||||
mutable framecnt_t _buffer_size;
|
||||
|
|
@ -283,6 +286,8 @@ private:
|
|||
bool _pre_freewheel_mmc_enabled;
|
||||
int _usecs_per_cycle;
|
||||
bool port_remove_in_progress;
|
||||
Glib::Thread* m_meter_thread;
|
||||
ProcessThread* _main_thread;
|
||||
|
||||
SerializedRCUManager<Ports> ports;
|
||||
|
||||
|
|
@ -331,11 +336,8 @@ private:
|
|||
void start_metering_thread ();
|
||||
void stop_metering_thread ();
|
||||
|
||||
Glib::Thread* m_meter_thread;
|
||||
static gint m_meter_exit;
|
||||
|
||||
ProcessThread* _main_thread;
|
||||
|
||||
struct ThreadData {
|
||||
AudioEngine* engine;
|
||||
boost::function<void()> f;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ namespace PBD {
|
|||
extern uint64_t TempoMap;
|
||||
extern uint64_t SoundGrid;
|
||||
extern uint64_t SGSurface;
|
||||
extern uint64_t OrderKeys;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ class ExportFormatManager : public PBD::ScopedConnectionList
|
|||
/* Signals */
|
||||
|
||||
PBD::Signal1<void,bool> CompleteChanged;
|
||||
PBD::Signal0<void> DescriptionChanged;
|
||||
|
||||
/* Access to lists */
|
||||
|
||||
|
|
@ -142,6 +143,7 @@ class ExportFormatManager : public PBD::ScopedConnectionList
|
|||
|
||||
bool pending_selection_change;
|
||||
void selection_changed ();
|
||||
void check_for_description_change ();
|
||||
|
||||
/* Formats and compatibilities */
|
||||
|
||||
|
|
@ -161,6 +163,8 @@ class ExportFormatManager : public PBD::ScopedConnectionList
|
|||
FormatList formats;
|
||||
SampleRateList sample_rates;
|
||||
|
||||
std::string prev_description;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ class ExportFormatSpecification : public ExportFormatBase {
|
|||
|
||||
PBD::UUID const & id () { return _id; }
|
||||
std::string const & name () const { return _name; }
|
||||
std::string description ();
|
||||
std::string description (bool include_name = true);
|
||||
|
||||
bool has_broadcast_info () const { return _has_broadcast_info; }
|
||||
uint32_t channel_limit () const { return _channel_limit; }
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ namespace AudioGrapher {
|
|||
class SampleRateConverter;
|
||||
class PeakReader;
|
||||
class Normalizer;
|
||||
template <typename T> class Chunker;
|
||||
template <typename T> class SampleFormatConverter;
|
||||
template <typename T> class Interleaver;
|
||||
template <typename T> class SndfileWriter;
|
||||
|
|
@ -209,12 +210,14 @@ class ExportGraphBuilder
|
|||
|
||||
private:
|
||||
typedef boost::shared_ptr<AudioGrapher::Interleaver<Sample> > InterleaverPtr;
|
||||
typedef boost::shared_ptr<AudioGrapher::Chunker<Sample> > ChunkerPtr;
|
||||
|
||||
ExportGraphBuilder & parent;
|
||||
FileSpec config;
|
||||
boost::ptr_list<SilenceHandler> children;
|
||||
InterleaverPtr interleaver;
|
||||
framecnt_t max_frames;
|
||||
ChunkerPtr chunker;
|
||||
framecnt_t max_frames_out;
|
||||
};
|
||||
|
||||
Session const & session;
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ class ExportProfileManager
|
|||
private:
|
||||
typedef boost::shared_ptr<ExportHandler> HandlerPtr;
|
||||
|
||||
typedef std::pair<PBD::UUID, PBD::sys::path> FilePair;
|
||||
typedef std::map<PBD::UUID, PBD::sys::path> FileMap;
|
||||
typedef std::pair<PBD::UUID, std::string> FilePair;
|
||||
typedef std::map<PBD::UUID, std::string> FileMap;
|
||||
|
||||
std::string const xml_node_name;
|
||||
HandlerPtr handler;
|
||||
|
|
@ -76,7 +76,7 @@ class ExportProfileManager
|
|||
|
||||
std::string preset_filename (std::string const & preset_name);
|
||||
void load_presets ();
|
||||
void load_preset_from_disk (PBD::sys::path const & path);
|
||||
void load_preset_from_disk (std::string const & path);
|
||||
|
||||
bool set_state (XMLNode const & root);
|
||||
bool set_global_state (XMLNode const & root);
|
||||
|
|
@ -90,9 +90,9 @@ class ExportProfileManager
|
|||
ExportPresetPtr current_preset;
|
||||
FileMap preset_file_map;
|
||||
|
||||
std::vector<PBD::sys::path> find_file (std::string const & pattern);
|
||||
std::vector<std::string> find_file (std::string const & pattern);
|
||||
|
||||
PBD::sys::path export_config_dir;
|
||||
std::string export_config_dir;
|
||||
PBD::SearchPath search_path;
|
||||
|
||||
/* Timespans */
|
||||
|
|
@ -195,7 +195,7 @@ class ExportProfileManager
|
|||
FormatStatePtr duplicate_format_state (FormatStatePtr state);
|
||||
void remove_format_state (FormatStatePtr state);
|
||||
|
||||
PBD::sys::path save_format_to_disk (ExportFormatSpecPtr format);
|
||||
std::string save_format_to_disk (ExportFormatSpecPtr format);
|
||||
void remove_format_profile (ExportFormatSpecPtr format);
|
||||
ExportFormatSpecPtr get_new_format (ExportFormatSpecPtr original);
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ class ExportProfileManager
|
|||
void load_formats ();
|
||||
|
||||
ExportFormatSpecPtr load_format (XMLNode & node);
|
||||
void load_format_from_disk (PBD::sys::path const & path);
|
||||
void load_format_from_disk (std::string const & path);
|
||||
|
||||
boost::shared_ptr<FormatList> format_list;
|
||||
FileMap format_file_map;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#ifndef ARDOUR_FILESYSTEM_PATHS_INCLUDED
|
||||
#define ARDOUR_FILESYSTEM_PATHS_INCLUDED
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
#include "pbd/search_path.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
|
@ -28,14 +27,15 @@ namespace ARDOUR {
|
|||
/**
|
||||
* @return the path to the directory used to store user specific ardour
|
||||
* configuration files.
|
||||
* @post user_config_directory() exists
|
||||
*/
|
||||
PBD::sys::path user_config_directory ();
|
||||
std::string user_config_directory ();
|
||||
|
||||
/**
|
||||
* @return the path to the directory that contains the system wide ardour
|
||||
* modules.
|
||||
*/
|
||||
PBD::sys::path ardour_dll_directory ();
|
||||
std::string ardour_dll_directory ();
|
||||
|
||||
/**
|
||||
* @return the search path to be used when looking for per-system
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __ardour_named_selection_h__
|
||||
#define __ardour_named_selection_h__
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "pbd/stateful.h"
|
||||
|
||||
class XMLNode;
|
||||
|
||||
namespace ARDOUR
|
||||
{
|
||||
|
||||
class Session;
|
||||
class Playlist;
|
||||
|
||||
class NamedSelection : public PBD::Stateful
|
||||
{
|
||||
public:
|
||||
NamedSelection (std::string, std::list<boost::shared_ptr<Playlist> >&);
|
||||
NamedSelection (Session&, const XMLNode&);
|
||||
virtual ~NamedSelection ();
|
||||
|
||||
std::string name;
|
||||
std::list<boost::shared_ptr<Playlist> > playlists;
|
||||
|
||||
XMLNode& get_state (void);
|
||||
|
||||
int set_state (const XMLNode&, int version);
|
||||
|
||||
static PBD::Signal1<void,NamedSelection*> NamedSelectionCreated;
|
||||
};
|
||||
|
||||
}/* namespace ARDOUR */
|
||||
|
||||
#endif /* __ardour_named_selection_h__ */
|
||||
|
||||
|
|
@ -126,6 +126,7 @@ public:
|
|||
|
||||
PBD::Signal1<void,bool> MonitorInputChanged;
|
||||
static PBD::Signal2<void,boost::shared_ptr<Port>,boost::shared_ptr<Port> > PostDisconnect;
|
||||
static PBD::Signal0<void> PortDrop;
|
||||
|
||||
static void set_cycle_framecnt (pframes_t n) {
|
||||
_cycle_nframes = n;
|
||||
|
|
@ -167,6 +168,8 @@ private:
|
|||
*/
|
||||
std::set<std::string> _connections;
|
||||
|
||||
void drop ();
|
||||
PBD::ScopedConnection drop_connection;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,8 +101,10 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
|||
bool set_name (const std::string& str);
|
||||
static void set_name_in_state (XMLNode &, const std::string &);
|
||||
|
||||
int32_t order_key (std::string const &) const;
|
||||
void set_order_key (std::string const &, int32_t);
|
||||
uint32_t order_key (RouteSortOrderKey) const;
|
||||
bool has_order_key (RouteSortOrderKey) const;
|
||||
void set_order_key (RouteSortOrderKey, uint32_t);
|
||||
void sync_order_keys (RouteSortOrderKey);
|
||||
|
||||
bool is_hidden() const { return _flags & Hidden; }
|
||||
bool is_master() const { return _flags & MasterOut; }
|
||||
|
|
@ -286,7 +288,6 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
|||
PBD::Signal0<void> meter_change;
|
||||
PBD::Signal0<void> signal_latency_changed;
|
||||
PBD::Signal0<void> initial_delay_changed;
|
||||
PBD::Signal0<void> order_key_changed;
|
||||
|
||||
/** Emitted with the process lock held */
|
||||
PBD::Signal0<void> io_changed;
|
||||
|
|
@ -427,12 +428,10 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
|||
|
||||
PBD::Signal0<void> RemoteControlIDChanged;
|
||||
|
||||
/* for things concerned about any route's RID changes */
|
||||
/* for things concerned about *any* route's RID changes */
|
||||
|
||||
static PBD::Signal0<void> RemoteControlIDChange;
|
||||
|
||||
void sync_order_keys (std::string const &);
|
||||
static PBD::Signal1<void,std::string const &> SyncOrderKeys;
|
||||
static PBD::Signal1<void,RouteSortOrderKey> SyncOrderKeys;
|
||||
|
||||
bool has_external_redirects() const;
|
||||
|
||||
|
|
@ -518,7 +517,6 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
|||
void silence_unlocked (framecnt_t);
|
||||
|
||||
ChanCount processor_max_streams;
|
||||
uint32_t _remote_control_id;
|
||||
|
||||
uint32_t pans_required() const;
|
||||
ChanCount n_process_buffers ();
|
||||
|
|
@ -534,8 +532,9 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
|
|||
|
||||
static uint32_t order_key_cnt;
|
||||
|
||||
typedef std::map<std::string, long> OrderKeys;
|
||||
typedef std::map<RouteSortOrderKey,uint32_t> OrderKeys;
|
||||
OrderKeys order_keys;
|
||||
uint32_t* _remote_control_id;
|
||||
|
||||
void input_change_handler (IOChange, void *src);
|
||||
void output_change_handler (IOChange, void *src);
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ class MidiControlUI;
|
|||
class MidiRegion;
|
||||
class MidiSource;
|
||||
class MidiTrack;
|
||||
class NamedSelection;
|
||||
class Playlist;
|
||||
class PluginInsert;
|
||||
class PluginInfo;
|
||||
|
|
@ -235,7 +234,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
|
||||
};
|
||||
|
||||
void sync_order_keys (std::string const &);
|
||||
void sync_order_keys (RouteSortOrderKey);
|
||||
|
||||
template<class T> void foreach_route (T *obj, void (T::*func)(Route&));
|
||||
template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>));
|
||||
|
|
@ -329,8 +328,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
void goto_start ();
|
||||
void use_rf_shuttle_speed ();
|
||||
void allow_auto_play (bool yn);
|
||||
void request_transport_speed (double speed);
|
||||
void request_transport_speed_nonzero (double);
|
||||
void request_transport_speed (double speed, bool as_default = false);
|
||||
void request_transport_speed_nonzero (double, bool as_default = false);
|
||||
void request_overwrite_buffer (Track *);
|
||||
void adjust_playback_buffering();
|
||||
void adjust_capture_buffering();
|
||||
|
|
@ -454,6 +453,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
);
|
||||
|
||||
std::list<boost::shared_ptr<MidiTrack> > new_midi_track (
|
||||
const ChanCount& input, const ChanCount& output,
|
||||
boost::shared_ptr<PluginInfo> instrument = boost::shared_ptr<PluginInfo>(),
|
||||
TrackMode mode = Normal,
|
||||
RouteGroup* route_group = 0, uint32_t how_many = 1, std::string name_template = ""
|
||||
|
|
@ -463,8 +463,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
void resort_routes ();
|
||||
void resort_routes_using (boost::shared_ptr<RouteList>);
|
||||
|
||||
void set_remote_control_ids();
|
||||
|
||||
AudioEngine & engine() { return _engine; }
|
||||
AudioEngine const & engine () const { return _engine; }
|
||||
|
||||
|
|
@ -579,16 +577,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
|
||||
void add_playlist (boost::shared_ptr<Playlist>, bool unused = false);
|
||||
|
||||
/* named selections */
|
||||
|
||||
boost::shared_ptr<NamedSelection> named_selection_by_name (std::string name);
|
||||
void add_named_selection (boost::shared_ptr<NamedSelection>);
|
||||
void remove_named_selection (boost::shared_ptr<NamedSelection>);
|
||||
|
||||
template<class T> void foreach_named_selection (T& obj, void (T::*func)(boost::shared_ptr<NamedSelection>));
|
||||
PBD::Signal0<void> NamedSelectionAdded;
|
||||
PBD::Signal0<void> NamedSelectionRemoved;
|
||||
|
||||
/* Curves and AutomationLists (TODO when they go away) */
|
||||
void add_automation_list(AutomationList*);
|
||||
|
||||
|
|
@ -818,8 +806,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
void send_mmc_locate (framepos_t);
|
||||
int send_full_time_code (framepos_t);
|
||||
|
||||
PBD::Signal0<void> RouteOrderKeyChanged;
|
||||
|
||||
bool step_editing() const { return (_step_editors > 0); }
|
||||
|
||||
void request_suspend_timecode_transmission ();
|
||||
|
|
@ -871,9 +857,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
void destroy ();
|
||||
|
||||
enum SubState {
|
||||
PendingDeclickIn = 0x1,
|
||||
PendingDeclickOut = 0x2,
|
||||
PendingDeclickIn = 0x1, ///< pending de-click fade-in for start
|
||||
PendingDeclickOut = 0x2, ///< pending de-click fade-out for stop
|
||||
StopPendingCapture = 0x4,
|
||||
PendingLoopDeclickIn = 0x8, ///< pending de-click fade-in at the start of a loop
|
||||
PendingLoopDeclickOut = 0x10, ///< pending de-click fade-out at the end of a loop
|
||||
PendingLocate = 0x20,
|
||||
};
|
||||
|
||||
|
|
@ -902,6 +890,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
|
||||
// varispeed playback
|
||||
double _transport_speed;
|
||||
double _default_transport_speed;
|
||||
double _last_transport_speed;
|
||||
double _target_transport_speed;
|
||||
CubicInterpolation interpolation;
|
||||
|
|
@ -990,12 +979,25 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
int process_routes (pframes_t, bool& need_butler);
|
||||
int silent_process_routes (pframes_t, bool& need_butler);
|
||||
|
||||
/** @return 1 if there is a pending declick fade-in,
|
||||
-1 if there is a pending declick fade-out,
|
||||
0 if there is no pending declick.
|
||||
*/
|
||||
int get_transport_declick_required () {
|
||||
if (transport_sub_state & PendingDeclickIn) {
|
||||
transport_sub_state &= ~PendingDeclickIn;
|
||||
return 1;
|
||||
} else if (transport_sub_state & PendingDeclickOut) {
|
||||
/* XXX: not entirely sure why we don't clear this */
|
||||
return -1;
|
||||
} else if (transport_sub_state & PendingLoopDeclickOut) {
|
||||
/* Return the declick out first ... */
|
||||
transport_sub_state &= ~PendingLoopDeclickOut;
|
||||
return -1;
|
||||
} else if (transport_sub_state & PendingLoopDeclickIn) {
|
||||
/* ... then the declick in on the next call */
|
||||
transport_sub_state &= ~PendingLoopDeclickIn;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1037,6 +1039,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
int load_state (std::string snapshot_name);
|
||||
|
||||
framepos_t _last_roll_location;
|
||||
/** the session frame time at which we last rolled, located, or changed transport direction */
|
||||
framepos_t _last_roll_or_reversal_location;
|
||||
framepos_t _last_record_location;
|
||||
|
||||
|
|
@ -1085,6 +1088,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
|
||||
PBD::ScopedConnectionList loop_connections;
|
||||
void auto_loop_changed (Location *);
|
||||
void auto_loop_declick_range (Location *, framepos_t &, framepos_t &);
|
||||
|
||||
void first_stage_init (std::string path, std::string snapshot_name);
|
||||
int second_stage_init ();
|
||||
|
|
@ -1193,7 +1197,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
void start_locate (framepos_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
|
||||
void force_locate (framepos_t frame, bool with_roll = false);
|
||||
void set_track_speed (Track *, double speed);
|
||||
void set_transport_speed (double speed, bool abort = false, bool clear_state = false);
|
||||
void set_transport_speed (double speed, bool abort = false, bool clear_state = false, bool as_default = false);
|
||||
void stop_transport (bool abort = false, bool clear_state = false);
|
||||
void start_transport ();
|
||||
void realtime_stop (bool abort, bool clear_state);
|
||||
|
|
@ -1289,17 +1293,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
void playlist_ranges_moved (std::list<Evoral::RangeMove<framepos_t> > const &);
|
||||
void playlist_regions_extended (std::list<Evoral::Range<framepos_t> > const &);
|
||||
|
||||
/* NAMED SELECTIONS */
|
||||
|
||||
mutable Glib::Mutex named_selection_lock;
|
||||
typedef std::set<boost::shared_ptr<NamedSelection> > NamedSelectionList;
|
||||
NamedSelectionList named_selections;
|
||||
|
||||
int load_named_selections (const XMLNode&);
|
||||
|
||||
NamedSelection *named_selection_factory (std::string name);
|
||||
NamedSelection *XMLNamedSelectionFactory (const XMLNode&);
|
||||
|
||||
/* CURVES and AUTOMATION LISTS */
|
||||
std::map<PBD::ID, AutomationList*> automation_lists;
|
||||
|
||||
|
|
@ -1470,7 +1463,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
XMLNode& get_control_protocol_state ();
|
||||
|
||||
void set_history_depth (uint32_t depth);
|
||||
void sync_order_keys ();
|
||||
|
||||
static bool _disable_all_loaded_plugins;
|
||||
|
||||
|
|
@ -1509,8 +1501,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
|
||||
void setup_midi_machine_control ();
|
||||
|
||||
void route_order_key_changed ();
|
||||
|
||||
void step_edit_status_change (bool);
|
||||
uint32_t _step_editors;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class SessionDirectory
|
||||
|
|
@ -33,7 +31,7 @@ public:
|
|||
/**
|
||||
* @param session_path An absolute path to a session directory.
|
||||
*/
|
||||
SessionDirectory (const PBD::sys::path& session_path);
|
||||
SessionDirectory (const std::string& session_path);
|
||||
|
||||
/**
|
||||
* Change the root path of this SessionDirectory object
|
||||
|
|
@ -43,7 +41,7 @@ public:
|
|||
/**
|
||||
* @return the absolute path to the root directory of the session
|
||||
*/
|
||||
const PBD::sys::path root_path() const { return m_root_path; }
|
||||
const std::string root_path() const { return m_root_path; }
|
||||
|
||||
/**
|
||||
* @return the absolute path to the directory in which
|
||||
|
|
@ -54,40 +52,40 @@ public:
|
|||
* directory otherwise it will return the new location
|
||||
* of root_path()/interchange/session_name/audiofiles
|
||||
*/
|
||||
const PBD::sys::path sound_path () const;
|
||||
const std::string sound_path () const;
|
||||
|
||||
/**
|
||||
* @return the absolute path to the directory in which
|
||||
* the session stores MIDI files, ie
|
||||
* root_path()/interchange/session_name/midifiles
|
||||
*/
|
||||
const PBD::sys::path midi_path () const;
|
||||
const std::string midi_path () const;
|
||||
|
||||
/**
|
||||
* @return the absolute path to the directory in which
|
||||
* the session stores MIDNAM patch files, ie
|
||||
* root_path()/interchange/session_name/patchfiles
|
||||
*/
|
||||
const PBD::sys::path midi_patch_path () const;
|
||||
const std::string midi_patch_path () const;
|
||||
|
||||
/**
|
||||
* @return The absolute path to the directory in which all
|
||||
* peak files are stored for a session.
|
||||
*/
|
||||
const PBD::sys::path peak_path () const;
|
||||
const std::string peak_path () const;
|
||||
|
||||
/**
|
||||
* @return The absolute path to the directory that source
|
||||
* files are moved to when they are no longer part of the
|
||||
* session.
|
||||
*/
|
||||
const PBD::sys::path dead_path () const;
|
||||
const std::string dead_path () const;
|
||||
|
||||
/**
|
||||
* @return The absolute path to the directory that audio
|
||||
* files are created in by default when exporting.
|
||||
*/
|
||||
const PBD::sys::path export_path () const;
|
||||
const std::string export_path () const;
|
||||
|
||||
/**
|
||||
* @return true if session directory and all the required
|
||||
|
|
@ -98,11 +96,8 @@ public:
|
|||
/**
|
||||
* Create the session directory and all the subdirectories.
|
||||
*
|
||||
* @throw PBD::sys::filesystem_error if the directories were
|
||||
* not able to be created.
|
||||
*
|
||||
* @return true If a new session directory was created, otherwise
|
||||
* (if it already existed) false.
|
||||
* @return true If a new session directory and subdirectories were
|
||||
* created, otherwise false.
|
||||
*
|
||||
* @post is_valid ()
|
||||
*/
|
||||
|
|
@ -113,7 +108,7 @@ public:
|
|||
* are created for different source types.
|
||||
* i.e root_path()/interchange/session_name
|
||||
*/
|
||||
const PBD::sys::path sources_root() const;
|
||||
const std::string sources_root() const;
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -121,15 +116,15 @@ private:
|
|||
* @return The path to the old style sound directory.
|
||||
* It isn't created by create().
|
||||
*/
|
||||
const PBD::sys::path old_sound_path () const;
|
||||
const std::string old_sound_path () const;
|
||||
|
||||
/**
|
||||
* @return a vector containing the fullpath of all subdirectories.
|
||||
*/
|
||||
const std::vector<PBD::sys::path> sub_directories () const;
|
||||
const std::vector<std::string> sub_directories () const;
|
||||
|
||||
/// The path to the root of the session directory.
|
||||
PBD::sys::path m_root_path;
|
||||
std::string m_root_path;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ public:
|
|||
/* only one of each of these events can be queued at any one time */
|
||||
|
||||
StopOnce,
|
||||
AutoLoop
|
||||
AutoLoop,
|
||||
AutoLoopDeclick,
|
||||
};
|
||||
|
||||
enum Action {
|
||||
|
|
@ -70,6 +71,10 @@ public:
|
|||
bool second_yes_or_no;
|
||||
};
|
||||
|
||||
union {
|
||||
bool third_yes_or_no;
|
||||
};
|
||||
|
||||
/* 4 members to handle a multi-group event handled in RT context */
|
||||
|
||||
typedef boost::function<void (SessionEvent*)> RTeventCallback;
|
||||
|
|
@ -84,7 +89,7 @@ public:
|
|||
|
||||
boost::shared_ptr<Region> region;
|
||||
|
||||
SessionEvent (Type t, Action a, framepos_t when, framepos_t where, double spd, bool yn = false, bool yn2 = false)
|
||||
SessionEvent (Type t, Action a, framepos_t when, framepos_t where, double spd, bool yn = false, bool yn2 = false, bool yn3 = false)
|
||||
: type (t)
|
||||
, action (a)
|
||||
, action_frame (when)
|
||||
|
|
@ -92,6 +97,7 @@ public:
|
|||
, speed (spd)
|
||||
, yes_or_no (yn)
|
||||
, second_yes_or_no (yn2)
|
||||
, third_yes_or_no (yn3)
|
||||
, event_loop (0) {}
|
||||
|
||||
void set_ptr (void* p) {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
/**
|
||||
|
|
@ -34,7 +32,7 @@ namespace ARDOUR {
|
|||
*
|
||||
* @return true if successful, false otherwise.
|
||||
*/
|
||||
bool create_backup_file (const PBD::sys::path & file_path);
|
||||
bool create_backup_file (const std::string & file_path);
|
||||
|
||||
/**
|
||||
* Get the absolute paths to all state files in the directory
|
||||
|
|
@ -43,8 +41,8 @@ bool create_backup_file (const PBD::sys::path & file_path);
|
|||
* @param directory_path The absolute path to a directory.
|
||||
* @param result vector to contain resulting state files.
|
||||
*/
|
||||
void get_state_files_in_directory (const PBD::sys::path & directory_path,
|
||||
std::vector<PBD::sys::path>& result);
|
||||
void get_state_files_in_directory (const std::string& directory_path,
|
||||
std::vector<std::string>& result);
|
||||
|
||||
/**
|
||||
* Given a vector of paths to files, return a vector containing
|
||||
|
|
@ -54,7 +52,7 @@ void get_state_files_in_directory (const PBD::sys::path & directory_path,
|
|||
* @return a vector containing a list of file names without any
|
||||
* filename extension.
|
||||
*/
|
||||
std::vector<std::string> get_file_names_no_extension (const std::vector<PBD::sys::path> & file_paths);
|
||||
std::vector<std::string> get_file_names_no_extension (const std::vector<std::string> & file_paths);
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
|
|
|
|||
|
|
@ -8,17 +8,6 @@ namespace ARDOUR {
|
|||
|
||||
int find_session (std::string str, std::string& path, std::string& snapshot, bool& isnew);
|
||||
|
||||
/**
|
||||
* Create a SessionDirectory at the path specified by
|
||||
* session_directory_path, this includes all subdirectories.
|
||||
*
|
||||
* @return true if the session directory was able to be created
|
||||
* or if it already existed, false otherwise.
|
||||
*
|
||||
* @see SessionDirectory
|
||||
*/
|
||||
bool create_session_directory (const std::string& session_directory_path);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,17 +2,16 @@
|
|||
#ifndef TEMPLATE_UTILS_INCLUDED
|
||||
#define TEMPLATE_UTILS_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
PBD::sys::path system_template_directory ();
|
||||
PBD::sys::path system_route_template_directory ();
|
||||
std::string system_template_directory ();
|
||||
std::string system_route_template_directory ();
|
||||
|
||||
PBD::sys::path user_template_directory ();
|
||||
PBD::sys::path user_route_template_directory ();
|
||||
std::string user_template_directory ();
|
||||
std::string user_route_template_directory ();
|
||||
|
||||
struct TemplateInfo {
|
||||
std::string name;
|
||||
|
|
|
|||
|
|
@ -351,6 +351,11 @@ namespace ARDOUR {
|
|||
PostFader
|
||||
};
|
||||
|
||||
enum RouteSortOrderKey {
|
||||
EditorSort,
|
||||
MixerSort
|
||||
};
|
||||
|
||||
enum MonitorModel {
|
||||
HardwareMonitoring, ///< JACK does monitoring
|
||||
SoftwareMonitoring, ///< Ardour does monitoring
|
||||
|
|
|
|||
|
|
@ -46,16 +46,16 @@ static const char* TAG = "http://ardour.org/ontology/Tag";
|
|||
|
||||
AudioLibrary::AudioLibrary ()
|
||||
{
|
||||
sys::path sfdb_file_path(user_config_directory ());
|
||||
std::string sfdb_file_path(user_config_directory ());
|
||||
|
||||
sfdb_file_path /= sfdb_file_name;
|
||||
sfdb_file_path = Glib::build_filename (sfdb_file_path, sfdb_file_name);
|
||||
|
||||
src = Glib::filename_to_uri (sfdb_file_path.to_string ());
|
||||
src = Glib::filename_to_uri (sfdb_file_path);
|
||||
|
||||
// workaround for possible bug in raptor that crashes when saving to a
|
||||
// non-existant file.
|
||||
|
||||
touch_file(sfdb_file_path.to_string());
|
||||
touch_file(sfdb_file_path);
|
||||
|
||||
lrdf_read_file(src.c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ AudioPlaylistSource::sample_rate () const
|
|||
int
|
||||
AudioPlaylistSource::setup_peakfile ()
|
||||
{
|
||||
_peak_path = Glib::build_filename (_session.session_directory().peak_path().to_string(), name() + ARDOUR::peakfile_suffix);
|
||||
_peak_path = Glib::build_filename (_session.session_directory().peak_path(), name() + ARDOUR::peakfile_suffix);
|
||||
return initialize_peakfile (false, string());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,5 +78,13 @@ AudioPort::get_audio_buffer (pframes_t nframes)
|
|||
return *_buffer;
|
||||
}
|
||||
|
||||
Sample*
|
||||
AudioPort::engine_get_whole_audio_buffer ()
|
||||
{
|
||||
/* caller must hold process lock */
|
||||
return (Sample *) jack_port_get_buffer (_jack_port, _cycle_nframes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
#include <glibmm/miscutils.h>
|
||||
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/compose.h"
|
||||
#include "pbd/error.h"
|
||||
|
|
@ -232,8 +234,7 @@ AudioRegionImporter::parse_source_xml ()
|
|||
{
|
||||
uint32_t channels;
|
||||
char buf[128];
|
||||
PBD::sys::path source_dir = get_sound_dir (source);
|
||||
PBD::sys::path source_path;
|
||||
std::string source_dir(get_sound_dir (source));
|
||||
XMLNode * source_node;
|
||||
XMLProperty *prop;
|
||||
|
||||
|
|
@ -266,15 +267,12 @@ AudioRegionImporter::parse_source_xml ()
|
|||
for (XMLNodeList::const_iterator it = sources.begin(); it != sources.end(); ++it) {
|
||||
prop = (*it)->property ("id");
|
||||
if (prop && !source_id.compare (prop->value())) {
|
||||
source_path = source_dir;
|
||||
prop = (*it)->property ("name");
|
||||
if (!prop) {
|
||||
error << string_compose (X_("AudioRegionImporter (%1): source %2 has no \"name\" property"), name, source_id) << endmsg;
|
||||
return false;
|
||||
}
|
||||
source_path /= prop->value();
|
||||
filenames.push_back (source_path.to_string());
|
||||
|
||||
filenames.push_back (Glib::build_filename (source_dir, prop->value()));
|
||||
source_found = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -289,15 +287,11 @@ AudioRegionImporter::parse_source_xml ()
|
|||
return true;
|
||||
}
|
||||
|
||||
PBD::sys::path
|
||||
std::string
|
||||
AudioRegionImporter::get_sound_dir (XMLTree const & tree)
|
||||
{
|
||||
PBD::sys::path source_dir = tree.filename();
|
||||
source_dir = source_dir.branch_path();
|
||||
SessionDirectory session_dir(source_dir);
|
||||
source_dir = session_dir.sound_path();
|
||||
|
||||
return source_dir;
|
||||
SessionDirectory session_dir(Glib::path_get_dirname (tree.filename()));
|
||||
return session_dir.sound_path();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "ardour/filesystem_paths.h"
|
||||
#include "ardour/io.h"
|
||||
#include "ardour/audio_unit.h"
|
||||
#include "ardour/route.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/tempo.h"
|
||||
#include "ardour/utils.h"
|
||||
|
|
@ -809,7 +810,7 @@ AUPlugin::get_parameter (uint32_t which) const
|
|||
float val = 0.0;
|
||||
if (which < descriptors.size()) {
|
||||
const AUParameterDescriptor& d (descriptors[which]);
|
||||
DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("get value of parameter %1 in scope %2 element %3\n", d.id, d.scope, d.element));
|
||||
// DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("get value of parameter %1 in scope %2 element %3\n", d.id, d.scope, d.element));
|
||||
unit->GetParameter(d.id, d.scope, d.element, val);
|
||||
}
|
||||
return val;
|
||||
|
|
@ -1079,8 +1080,21 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out) con
|
|||
audio_out = 2;
|
||||
found = true;
|
||||
} else if (possible_out < -2) {
|
||||
/* explicitly variable number of outputs, pick maximum */
|
||||
audio_out = -possible_out;
|
||||
/* explicitly variable number of outputs.
|
||||
|
||||
Since Ardour can handle any configuration,
|
||||
we have to somehow pick a number.
|
||||
|
||||
We'll use the number of inputs
|
||||
to the master bus, or 2 if there
|
||||
is no master bus.
|
||||
*/
|
||||
boost::shared_ptr<Route> master = _session.master_out();
|
||||
if (master) {
|
||||
audio_out = master->input()->n_ports().n_audio();
|
||||
} else {
|
||||
audio_out = 2;
|
||||
}
|
||||
found = true;
|
||||
} else {
|
||||
/* exact number of outputs */
|
||||
|
|
@ -1143,6 +1157,7 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out) con
|
|||
/* request is too large */
|
||||
}
|
||||
|
||||
|
||||
if (possible_out == -1) {
|
||||
/* any output configuration possible, provide stereo out */
|
||||
audio_out = 2;
|
||||
|
|
@ -1154,8 +1169,21 @@ AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out) con
|
|||
audio_out = 2;
|
||||
found = true;
|
||||
} else if (possible_out < -2) {
|
||||
/* explicitly variable number of outputs, pick maximum */
|
||||
audio_out = -possible_out;
|
||||
/* explicitly variable number of outputs.
|
||||
|
||||
Since Ardour can handle any configuration,
|
||||
we have to somehow pick a number.
|
||||
|
||||
We'll use the number of inputs
|
||||
to the master bus, or 2 if there
|
||||
is no master bus.
|
||||
*/
|
||||
boost::shared_ptr<Route> master = _session.master_out();
|
||||
if (master) {
|
||||
audio_out = master->input()->n_ports().n_audio();
|
||||
} else {
|
||||
audio_out = 2;
|
||||
}
|
||||
found = true;
|
||||
} else {
|
||||
/* exact number of outputs */
|
||||
|
|
@ -1329,8 +1357,10 @@ AUPlugin::connect_and_run (BufferSet& bufs, ChanMapping in_map, ChanMapping out_
|
|||
buffers->mBuffers[i].mDataByteSize = nframes * sizeof (Sample);
|
||||
/* setting this to 0 indicates to the AU that it can provide buffers here
|
||||
if necessary. if it can process in-place, it will use the buffers provided
|
||||
as input by ::render_callback() above. no documentation on what setting it
|
||||
to a non-null value means.
|
||||
as input by ::render_callback() above.
|
||||
|
||||
a non-null values tells the plugin to render into the buffer pointed
|
||||
at by the value.
|
||||
*/
|
||||
buffers->mBuffers[i].mData = 0;
|
||||
}
|
||||
|
|
@ -1365,8 +1395,8 @@ AUPlugin::connect_and_run (BufferSet& bufs, ChanMapping in_map, ChanMapping out_
|
|||
ts.mSampleTime = frames_processed;
|
||||
ts.mFlags = kAudioTimeStampSampleTimeValid;
|
||||
|
||||
// DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("%1 render flags=%2 time=%3 nframes=%4 buffers=%5\n",
|
||||
// name(), flags, frames_processed, nframes, buffers->mNumberBuffers));
|
||||
DEBUG_TRACE (DEBUG::AudioUnits, string_compose ("%1 render flags=%2 time=%3 nframes=%4 buffers=%5\n",
|
||||
name(), flags, frames_processed, nframes, buffers->mNumberBuffers));
|
||||
|
||||
if ((err = unit->Render (&flags, &ts, 0, nframes, buffers)) == noErr) {
|
||||
|
||||
|
|
@ -2163,7 +2193,7 @@ AUPluginInfo::load (Session& session)
|
|||
Glib::ustring
|
||||
AUPluginInfo::au_cache_path ()
|
||||
{
|
||||
return Glib::build_filename (ARDOUR::user_config_directory().to_string(), "au_cache");
|
||||
return Glib::build_filename (ARDOUR::user_config_directory(), "au_cache");
|
||||
}
|
||||
|
||||
PluginInfoList*
|
||||
|
|
|
|||
|
|
@ -62,26 +62,26 @@ AudioEngine* AudioEngine::_instance = 0;
|
|||
#define GET_PRIVATE_JACK_POINTER_RET(j,r) jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return r; }
|
||||
|
||||
AudioEngine::AudioEngine (string client_name, string session_uuid)
|
||||
: ports (new Ports)
|
||||
: _jack (0)
|
||||
, session_remove_pending (false)
|
||||
, session_removal_countdown (-1)
|
||||
, _running (false)
|
||||
, _has_run (false)
|
||||
, _buffer_size (0)
|
||||
, _frame_rate (0)
|
||||
, monitor_check_interval (INT32_MAX)
|
||||
, last_monitor_check (0)
|
||||
, _processed_frames (0)
|
||||
, _freewheeling (false)
|
||||
, _pre_freewheel_mmc_enabled (false)
|
||||
, _usecs_per_cycle (0)
|
||||
, port_remove_in_progress (false)
|
||||
, m_meter_thread (0)
|
||||
, _main_thread (0)
|
||||
, ports (new Ports)
|
||||
{
|
||||
_instance = this; /* singleton */
|
||||
|
||||
session_remove_pending = false;
|
||||
_running = false;
|
||||
_has_run = false;
|
||||
last_monitor_check = 0;
|
||||
monitor_check_interval = INT32_MAX;
|
||||
_processed_frames = 0;
|
||||
_usecs_per_cycle = 0;
|
||||
_jack = 0;
|
||||
_frame_rate = 0;
|
||||
_buffer_size = 0;
|
||||
_freewheeling = false;
|
||||
_pre_freewheel_mmc_enabled = false;
|
||||
_main_thread = 0;
|
||||
port_remove_in_progress = false;
|
||||
|
||||
m_meter_thread = 0;
|
||||
g_atomic_int_set (&m_meter_exit, 0);
|
||||
|
||||
if (connect_to_jack (client_name, session_uuid)) {
|
||||
|
|
@ -475,21 +475,51 @@ AudioEngine::process_callback (pframes_t nframes)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (session_remove_pending) {
|
||||
|
||||
/* perform the actual session removal */
|
||||
|
||||
if (session_removal_countdown < 0) {
|
||||
|
||||
/* fade out over 1 second */
|
||||
session_removal_countdown = _frame_rate/2;
|
||||
session_removal_gain = 1.0;
|
||||
session_removal_gain_step = 1.0/session_removal_countdown;
|
||||
|
||||
} else if (session_removal_countdown > 0) {
|
||||
|
||||
/* we'll be fading audio out.
|
||||
|
||||
if this is the last time we do this as part
|
||||
of session removal, do a MIDI panic now
|
||||
to get MIDI stopped. This relies on the fact
|
||||
that "immediate data" (aka "out of band data") from
|
||||
MIDI tracks is *appended* after any other data,
|
||||
so that it emerges after any outbound note ons, etc.
|
||||
*/
|
||||
|
||||
if (session_removal_countdown <= nframes) {
|
||||
_session->midi_panic ();
|
||||
}
|
||||
|
||||
} else {
|
||||
/* fade out done */
|
||||
_session = 0;
|
||||
session_removal_countdown = -1; // reset to "not in progress"
|
||||
session_remove_pending = false;
|
||||
session_removed.signal(); // wakes up thread that initiated session removal
|
||||
}
|
||||
}
|
||||
|
||||
if (_session == 0) {
|
||||
|
||||
if (!_freewheeling) {
|
||||
MIDI::Manager::instance()->cycle_start(nframes);
|
||||
MIDI::Manager::instance()->cycle_end();
|
||||
}
|
||||
_processed_frames = next_processed_frames;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (session_remove_pending) {
|
||||
/* perform the actual session removal */
|
||||
_session = 0;
|
||||
session_remove_pending = false;
|
||||
session_removed.signal();
|
||||
_processed_frames = next_processed_frames;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -559,8 +589,6 @@ AudioEngine::process_callback (pframes_t nframes)
|
|||
|
||||
if (_session->silent()) {
|
||||
|
||||
boost::shared_ptr<Ports> p = ports.reader();
|
||||
|
||||
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
|
||||
|
||||
if (i->second->sends_output()) {
|
||||
|
|
@ -569,6 +597,34 @@ AudioEngine::process_callback (pframes_t nframes)
|
|||
}
|
||||
}
|
||||
|
||||
if (session_remove_pending && session_removal_countdown) {
|
||||
|
||||
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
|
||||
|
||||
if (i->second->sends_output()) {
|
||||
|
||||
boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
|
||||
if (ap) {
|
||||
Sample* s = ap->engine_get_whole_audio_buffer ();
|
||||
gain_t g = session_removal_gain;
|
||||
|
||||
for (pframes_t n = 0; n < nframes; ++n) {
|
||||
*s++ *= g;
|
||||
g -= session_removal_gain_step;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (session_removal_countdown > nframes) {
|
||||
session_removal_countdown -= nframes;
|
||||
} else {
|
||||
session_removal_countdown = 0;
|
||||
}
|
||||
|
||||
session_removal_gain -= (nframes * session_removal_gain_step);
|
||||
}
|
||||
|
||||
// Finalize ports
|
||||
|
||||
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ watermark ()
|
|||
void
|
||||
block_mothership ()
|
||||
{
|
||||
string hangup = Glib::build_filename (ARDOUR::user_config_directory().to_string(), OFF_THE_HOOK);
|
||||
string hangup = Glib::build_filename (ARDOUR::user_config_directory(), OFF_THE_HOOK);
|
||||
int fd;
|
||||
if ((fd = ::open (hangup.c_str(), O_RDWR|O_CREAT, 0600)) >= 0) {
|
||||
close (fd);
|
||||
|
|
@ -62,14 +62,14 @@ block_mothership ()
|
|||
void
|
||||
unblock_mothership ()
|
||||
{
|
||||
string hangup = Glib::build_filename (ARDOUR::user_config_directory().to_string(), OFF_THE_HOOK);
|
||||
string hangup = Glib::build_filename (ARDOUR::user_config_directory(), OFF_THE_HOOK);
|
||||
::unlink (hangup.c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
mothership_blocked ()
|
||||
{
|
||||
string hangup = Glib::build_filename (ARDOUR::user_config_directory().to_string(), OFF_THE_HOOK);
|
||||
string hangup = Glib::build_filename (ARDOUR::user_config_directory(), OFF_THE_HOOK);
|
||||
return Glib::file_test (hangup, Glib::FILE_TEST_EXISTS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ ControlProtocolManager::load_mandatory_protocols ()
|
|||
void
|
||||
ControlProtocolManager::discover_control_protocols ()
|
||||
{
|
||||
vector<sys::path> cp_modules;
|
||||
vector<std::string> cp_modules;
|
||||
|
||||
Glib::PatternSpec so_extension_pattern("*.so");
|
||||
Glib::PatternSpec dylib_extension_pattern("*.dylib");
|
||||
|
|
@ -211,8 +211,8 @@ ControlProtocolManager::discover_control_protocols ()
|
|||
DEBUG_TRACE (DEBUG::ControlProtocols,
|
||||
string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string()));
|
||||
|
||||
for (vector<sys::path>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
|
||||
control_protocol_discover ((*i).to_string());
|
||||
for (vector<std::string>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) {
|
||||
control_protocol_discover (*i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,18 +36,11 @@ namespace ARDOUR {
|
|||
SearchPath
|
||||
control_protocol_search_path ()
|
||||
{
|
||||
SearchPath spath (user_config_directory ());
|
||||
|
||||
SearchPath spath(user_config_directory ());
|
||||
spath += ardour_dll_directory ();
|
||||
spath.add_subdirectory_to_paths (surfaces_dir_name);
|
||||
|
||||
bool surfaces_path_defined = false;
|
||||
SearchPath spath_env (Glib::getenv(surfaces_env_variable_name, surfaces_path_defined));
|
||||
|
||||
if (surfaces_path_defined) {
|
||||
spath += spath_env;
|
||||
}
|
||||
|
||||
spath += SearchPath(Glib::getenv(surfaces_env_variable_name));
|
||||
return spath;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,5 +58,6 @@ uint64_t PBD::DEBUG::TempoMath = PBD::new_debug_bit ("tempomath");
|
|||
uint64_t PBD::DEBUG::TempoMap = PBD::new_debug_bit ("tempomap");
|
||||
uint64_t PBD::DEBUG::SoundGrid = PBD::new_debug_bit ("soundgrid");
|
||||
uint64_t PBD::DEBUG::SGSurface = PBD::new_debug_bit ("sgsurface");
|
||||
uint64_t PBD::DEBUG::OrderKeys = PBD::new_debug_bit ("orderkeys");
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ setup_enum_writer ()
|
|||
AutoState _AutoState;
|
||||
AutoStyle _AutoStyle;
|
||||
AutoConnectOption _AutoConnectOption;
|
||||
RouteSortOrderKey _RouteSortOrderKey;
|
||||
Session::StateOfTheState _Session_StateOfTheState;
|
||||
Route::Flag _Route_Flag;
|
||||
Source::Flag _Source_Flag;
|
||||
|
|
@ -397,6 +398,10 @@ setup_enum_writer ()
|
|||
REGISTER_CLASS_ENUM (Route, MonitorOut);
|
||||
REGISTER_BITS (_Route_Flag);
|
||||
|
||||
REGISTER_ENUM (MixerSort);
|
||||
REGISTER_ENUM (EditorSort);
|
||||
REGISTER (_RouteSortOrderKey);
|
||||
|
||||
REGISTER_CLASS_ENUM (Source, Writable);
|
||||
REGISTER_CLASS_ENUM (Source, CanRename);
|
||||
REGISTER_CLASS_ENUM (Source, Broadcast);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ ExportFilename::ExportFilename (Session & session) :
|
|||
std::time (&rawtime);
|
||||
time_struct = localtime (&rawtime);
|
||||
|
||||
folder = session.session_directory().export_path().to_string();
|
||||
folder = session.session_directory().export_path();
|
||||
|
||||
XMLNode * instant_node = session.instant_xml ("ExportFilename");
|
||||
if (instant_node) {
|
||||
|
|
@ -102,7 +102,7 @@ ExportFilename::set_state (const XMLNode & node)
|
|||
|
||||
if ((prop = child->property ("relative"))) {
|
||||
if (!prop->value().compare ("true")) {
|
||||
folder = session.session_directory().root_path().to_string();
|
||||
folder = session.session_directory().root_path();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -345,7 +345,7 @@ ExportFilename::analyse_folder ()
|
|||
{
|
||||
FieldPair pair;
|
||||
|
||||
string session_dir = session.session_directory().root_path().to_string();
|
||||
string session_dir = session.session_directory().root_path();
|
||||
string::size_type session_dir_len = session_dir.length();
|
||||
|
||||
string folder_beginning = folder.substr (0, session_dir_len);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ ExportFormatManager::ExportFormatManager (ExportFormatSpecPtr specification) :
|
|||
init_qualities ();
|
||||
init_formats ();
|
||||
init_sample_rates ();
|
||||
|
||||
prev_description = current_selection->description();
|
||||
}
|
||||
|
||||
ExportFormatManager::~ExportFormatManager ()
|
||||
|
|
@ -255,66 +257,77 @@ void
|
|||
ExportFormatManager::set_name (string name)
|
||||
{
|
||||
current_selection->set_name (name);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::select_src_quality (ExportFormatBase::SRCQuality value)
|
||||
{
|
||||
current_selection->set_src_quality (value);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::select_with_cue (bool value)
|
||||
{
|
||||
current_selection->set_with_cue (value);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::select_with_toc (bool value)
|
||||
{
|
||||
current_selection->set_with_toc (value);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::select_trim_beginning (bool value)
|
||||
{
|
||||
current_selection->set_trim_beginning (value);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::select_silence_beginning (AnyTime const & time)
|
||||
{
|
||||
current_selection->set_silence_beginning (time);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::select_trim_end (bool value)
|
||||
{
|
||||
current_selection->set_trim_end (value);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::select_silence_end (AnyTime const & time)
|
||||
{
|
||||
current_selection->set_silence_end (time);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::select_normalize (bool value)
|
||||
{
|
||||
current_selection->set_normalize (value);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::select_normalize_target (float value)
|
||||
{
|
||||
current_selection->set_normalize_target (value);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::select_tagging (bool tag)
|
||||
{
|
||||
current_selection->set_tag (tag);
|
||||
check_for_description_change ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -694,15 +707,26 @@ ExportFormatManager::selection_changed ()
|
|||
|
||||
}
|
||||
|
||||
/* Signal completeness */
|
||||
/* Signal completeness and possible description change */
|
||||
|
||||
CompleteChanged (current_selection->is_complete());
|
||||
check_for_description_change ();
|
||||
|
||||
/* Reset pending state */
|
||||
|
||||
pending_selection_change = false;
|
||||
}
|
||||
|
||||
void
|
||||
ExportFormatManager::check_for_description_change ()
|
||||
{
|
||||
std::string new_description = current_selection->description();
|
||||
if (new_description == prev_description) { return; }
|
||||
|
||||
prev_description = new_description;
|
||||
DescriptionChanged();
|
||||
}
|
||||
|
||||
ExportFormatManager::QualityPtr
|
||||
ExportFormatManager::get_selected_quality ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ namespace ARDOUR
|
|||
|
||||
using namespace PBD;
|
||||
using std::string;
|
||||
using std::list;
|
||||
|
||||
ExportFormatSpecification::Time &
|
||||
ExportFormatSpecification::Time::operator= (AnyTime const & other)
|
||||
|
|
@ -524,64 +525,73 @@ ExportFormatSpecification::set_format (boost::shared_ptr<ExportFormat> format)
|
|||
}
|
||||
|
||||
string
|
||||
ExportFormatSpecification::description ()
|
||||
ExportFormatSpecification::description (bool include_name)
|
||||
{
|
||||
string desc;
|
||||
|
||||
desc = _name + ": ";
|
||||
list<string> components;
|
||||
|
||||
if (_normalize) {
|
||||
desc += _("normalize, ");
|
||||
components.push_back (_("normalize"));
|
||||
}
|
||||
|
||||
if (_trim_beginning && _trim_end) {
|
||||
desc += _("trim, ");
|
||||
components.push_back ( _("trim"));
|
||||
} else if (_trim_beginning) {
|
||||
desc += _("trim start, ");
|
||||
components.push_back (_("trim start"));
|
||||
} else if (_trim_end) {
|
||||
desc += _("trim end, ");
|
||||
components.push_back (_("trim end"));
|
||||
}
|
||||
|
||||
desc += _format_name + ", ";
|
||||
if (_format_name != "") {
|
||||
components.push_back (_format_name);
|
||||
}
|
||||
|
||||
if (has_sample_format) {
|
||||
desc += HasSampleFormat::get_sample_format_name (sample_format()) + ", ";
|
||||
components.push_back (HasSampleFormat::get_sample_format_name (sample_format()));
|
||||
}
|
||||
|
||||
switch (sample_rate()) {
|
||||
case SR_22_05:
|
||||
desc += "22,5 kHz";
|
||||
components.push_back ("22,5 kHz");
|
||||
break;
|
||||
case SR_44_1:
|
||||
desc += "44,1 kHz";
|
||||
components.push_back ("44,1 kHz");
|
||||
break;
|
||||
case SR_48:
|
||||
desc += "48 kHz";
|
||||
components.push_back ("48 kHz");
|
||||
break;
|
||||
case SR_88_2:
|
||||
desc += "88,2 kHz";
|
||||
components.push_back ("88,2 kHz");
|
||||
break;
|
||||
case SR_96:
|
||||
desc += "96 kHz";
|
||||
components.push_back ("96 kHz");
|
||||
break;
|
||||
case SR_192:
|
||||
desc += "192 kHz";
|
||||
components.push_back ("192 kHz");
|
||||
break;
|
||||
case SR_Session:
|
||||
desc += _("Session rate");
|
||||
components.push_back (_("Session rate"));
|
||||
break;
|
||||
case SR_None:
|
||||
break;
|
||||
}
|
||||
|
||||
if (_with_toc) {
|
||||
desc += ", TOC";
|
||||
components.push_back ("TOC");
|
||||
}
|
||||
|
||||
if (_with_cue) {
|
||||
desc += ", CUE";
|
||||
components.push_back ("CUE");
|
||||
}
|
||||
|
||||
string desc;
|
||||
if (include_name) {
|
||||
desc = _name + ": ";
|
||||
}
|
||||
|
||||
for (list<string>::const_iterator it = components.begin(); it != components.end(); ++it) {
|
||||
if (it != components.begin()) { desc += ", "; }
|
||||
desc += *it;
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,17 +36,8 @@ SearchPath
|
|||
export_formats_search_path ()
|
||||
{
|
||||
SearchPath spath;
|
||||
|
||||
spath = user_config_directory ();
|
||||
spath.add_subdirectory_to_paths (export_formats_dir_name);
|
||||
|
||||
bool export_path_defined = false;
|
||||
SearchPath spath_env = Glib::getenv (export_env_variable_name, export_path_defined);
|
||||
|
||||
if (export_path_defined) {
|
||||
spath += spath_env;
|
||||
}
|
||||
|
||||
spath += Glib::build_filename (user_config_directory (), export_formats_dir_name);
|
||||
spath += SearchPath(Glib::getenv (export_env_variable_name));
|
||||
return spath;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "ardour/export_graph_builder.h"
|
||||
|
||||
#include "audiographer/process_context.h"
|
||||
#include "audiographer/general/chunker.h"
|
||||
#include "audiographer/general/interleaver.h"
|
||||
#include "audiographer/general/normalizer.h"
|
||||
#include "audiographer/general/peak_reader.h"
|
||||
|
|
@ -18,7 +19,7 @@
|
|||
#include "ardour/export_timespan.h"
|
||||
#include "ardour/sndfile_helpers.h"
|
||||
|
||||
#include "pbd/filesystem.h"
|
||||
#include "pbd/file_utils.h"
|
||||
#include "pbd/cpus.h"
|
||||
|
||||
using namespace AudioGrapher;
|
||||
|
|
@ -216,7 +217,7 @@ ExportGraphBuilder::Encoder::copy_files (std::string orig_path)
|
|||
{
|
||||
while (filenames.size()) {
|
||||
ExportFilenamePtr & filename = filenames.front();
|
||||
PBD::sys::copy_file (orig_path, filename->get_path (config.format).c_str());
|
||||
PBD::copy_file (orig_path, filename->get_path (config.format).c_str());
|
||||
filenames.pop_front();
|
||||
}
|
||||
}
|
||||
|
|
@ -474,11 +475,18 @@ ExportGraphBuilder::ChannelConfig::ChannelConfig (ExportGraphBuilder & parent, F
|
|||
typedef ExportChannelConfiguration::ChannelList ChannelList;
|
||||
|
||||
config = new_config;
|
||||
max_frames = parent.session.engine().frames_per_cycle();
|
||||
|
||||
framecnt_t max_frames = parent.session.engine().frames_per_cycle();
|
||||
interleaver.reset (new Interleaver<Sample> ());
|
||||
interleaver->init (new_config.channel_config->get_n_chans(), max_frames);
|
||||
|
||||
// Make the chunk size divisible by the channel count
|
||||
int chan_count = new_config.channel_config->get_n_chans();
|
||||
max_frames_out = 8192;
|
||||
max_frames_out -= max_frames_out % chan_count;
|
||||
chunker.reset (new Chunker<Sample> (max_frames_out));
|
||||
interleaver->add_output(chunker);
|
||||
|
||||
ChannelList const & channel_list = config.channel_config->get_channels();
|
||||
unsigned chan = 0;
|
||||
for (ChannelList::const_iterator it = channel_list.begin(); it != channel_list.end(); ++it, ++chan) {
|
||||
|
|
@ -498,6 +506,8 @@ ExportGraphBuilder::ChannelConfig::ChannelConfig (ExportGraphBuilder & parent, F
|
|||
void
|
||||
ExportGraphBuilder::ChannelConfig::add_child (FileSpec const & new_config)
|
||||
{
|
||||
assert (*this == new_config);
|
||||
|
||||
for (boost::ptr_list<SilenceHandler>::iterator it = children.begin(); it != children.end(); ++it) {
|
||||
if (*it == new_config) {
|
||||
it->add_child (new_config);
|
||||
|
|
@ -505,9 +515,8 @@ ExportGraphBuilder::ChannelConfig::add_child (FileSpec const & new_config)
|
|||
}
|
||||
}
|
||||
|
||||
framecnt_t const max_frames_out = new_config.channel_config->get_n_chans() * max_frames;
|
||||
children.push_back (new SilenceHandler (parent, new_config, max_frames_out));
|
||||
interleaver->add_output (children.back().sink ());
|
||||
chunker->add_output (children.back().sink ());
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
#include <glibmm/convert.h>
|
||||
|
||||
#include "pbd/convert.h"
|
||||
#include "pbd/filesystem.h"
|
||||
|
||||
#include "ardour/export_graph_builder.h"
|
||||
#include "ardour/export_timespan.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,11 @@
|
|||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include <glibmm/fileutils.h>
|
||||
#include <glibmm/miscutils.h>
|
||||
|
||||
#include "pbd/enumwriter.h"
|
||||
#include "pbd/xml++.h"
|
||||
|
|
@ -36,6 +40,7 @@
|
|||
#include "ardour/export_preset.h"
|
||||
#include "ardour/export_handler.h"
|
||||
#include "ardour/export_failed.h"
|
||||
#include "ardour/directory_names.h"
|
||||
#include "ardour/filename_extensions.h"
|
||||
#include "ardour/route.h"
|
||||
#include "ardour/session.h"
|
||||
|
|
@ -63,8 +68,7 @@ ExportProfileManager::ExportProfileManager (Session & s, std::string xml_node_na
|
|||
{
|
||||
/* Initialize path variables */
|
||||
|
||||
export_config_dir = user_config_directory();
|
||||
export_config_dir /= "export";
|
||||
export_config_dir = Glib::build_filename (user_config_directory(), export_dir_name);
|
||||
|
||||
search_path += export_formats_search_path();
|
||||
|
||||
|
|
@ -72,8 +76,10 @@ ExportProfileManager::ExportProfileManager (Session & s, std::string xml_node_na
|
|||
|
||||
/* create export config directory if necessary */
|
||||
|
||||
if (!sys::exists (export_config_dir)) {
|
||||
sys::create_directory (export_config_dir);
|
||||
if (!Glib::file_test (export_config_dir, Glib::FILE_TEST_EXISTS)) {
|
||||
if (g_mkdir_with_parents (export_config_dir.c_str(), 0755) != 0) {
|
||||
error << string_compose (_("Unable to create export format directory %1: %2"), export_config_dir, g_strerror(errno)) << endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
load_presets ();
|
||||
|
|
@ -165,9 +171,9 @@ ExportProfileManager::load_preset (ExportPresetPtr preset)
|
|||
void
|
||||
ExportProfileManager::load_presets ()
|
||||
{
|
||||
vector<sys::path> found = find_file (string_compose (X_("*%1"),export_preset_suffix));
|
||||
vector<std::string> found = find_file (string_compose (X_("*%1"),export_preset_suffix));
|
||||
|
||||
for (vector<sys::path>::iterator it = found.begin(); it != found.end(); ++it) {
|
||||
for (vector<std::string>::iterator it = found.begin(); it != found.end(); ++it) {
|
||||
load_preset_from_disk (*it);
|
||||
}
|
||||
}
|
||||
|
|
@ -176,7 +182,7 @@ std::string
|
|||
ExportProfileManager::preset_filename (std::string const & preset_name)
|
||||
{
|
||||
string safe_name = legalize_for_path (preset_name);
|
||||
return export_config_dir.to_string() + "/" + safe_name + export_preset_suffix;
|
||||
return Glib::build_filename (export_config_dir, safe_name + export_preset_suffix);
|
||||
}
|
||||
|
||||
ExportPresetPtr
|
||||
|
|
@ -228,7 +234,9 @@ ExportProfileManager::remove_preset ()
|
|||
|
||||
FileMap::iterator it = preset_file_map.find (current_preset->id());
|
||||
if (it != preset_file_map.end()) {
|
||||
sys::remove (it->second);
|
||||
if (g_remove (it->second.c_str()) != 0) {
|
||||
error << string_compose (_("Unable to remove export preset %1: %2"), it->second, g_strerror(errno)) << endmsg;
|
||||
}
|
||||
preset_file_map.erase (it);
|
||||
}
|
||||
|
||||
|
|
@ -237,9 +245,9 @@ ExportProfileManager::remove_preset ()
|
|||
}
|
||||
|
||||
void
|
||||
ExportProfileManager::load_preset_from_disk (PBD::sys::path const & path)
|
||||
ExportProfileManager::load_preset_from_disk (std::string const & path)
|
||||
{
|
||||
ExportPresetPtr preset (new ExportPreset (path.to_string(), session));
|
||||
ExportPresetPtr preset (new ExportPreset (path, session));
|
||||
|
||||
/* Handle id to filename mapping and don't add duplicates to list */
|
||||
|
||||
|
|
@ -300,10 +308,10 @@ ExportProfileManager::serialize_local_profile (XMLNode & root)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<sys::path>
|
||||
std::vector<std::string>
|
||||
ExportProfileManager::find_file (std::string const & pattern)
|
||||
{
|
||||
vector<sys::path> found;
|
||||
vector<std::string> found;
|
||||
|
||||
Glib::PatternSpec pattern_spec (pattern);
|
||||
find_matching_files_in_search_path (search_path, pattern_spec, found);
|
||||
|
|
@ -517,7 +525,7 @@ ExportProfileManager::remove_format_state (FormatStatePtr state)
|
|||
}
|
||||
}
|
||||
|
||||
sys::path
|
||||
std::string
|
||||
ExportProfileManager::save_format_to_disk (ExportFormatSpecPtr format)
|
||||
{
|
||||
// TODO filename character stripping
|
||||
|
|
@ -531,19 +539,18 @@ ExportProfileManager::save_format_to_disk (ExportFormatSpecPtr format)
|
|||
|
||||
new_name = legalize_for_path (new_name);
|
||||
|
||||
sys::path new_path (export_config_dir);
|
||||
new_path /= new_name;
|
||||
std::string new_path = Glib::build_filename (export_config_dir, new_name);
|
||||
|
||||
/* Check if format is on disk already */
|
||||
FileMap::iterator it;
|
||||
if ((it = format_file_map.find (format->id())) != format_file_map.end()) {
|
||||
|
||||
/* Check if config is not in user config dir */
|
||||
if (it->second.branch_path().to_string().compare (export_config_dir.to_string())) {
|
||||
if (Glib::path_get_dirname (it->second) != export_config_dir) {
|
||||
|
||||
/* Write new file */
|
||||
|
||||
XMLTree tree (new_path.to_string());
|
||||
XMLTree tree (new_path);
|
||||
tree.set_root (&format->get_state());
|
||||
tree.write();
|
||||
|
||||
|
|
@ -551,12 +558,14 @@ ExportProfileManager::save_format_to_disk (ExportFormatSpecPtr format)
|
|||
|
||||
/* Update file and rename if necessary */
|
||||
|
||||
XMLTree tree (it->second.to_string());
|
||||
XMLTree tree (it->second);
|
||||
tree.set_root (&format->get_state());
|
||||
tree.write();
|
||||
|
||||
if (new_name.compare (it->second.leaf())) {
|
||||
sys::rename (it->second, new_path);
|
||||
if (new_name != Glib::path_get_basename (it->second)) {
|
||||
if (g_rename (it->second.c_str(), new_path.c_str()) != 0) {
|
||||
error << string_compose (_("Unable to rename export format %1 to %2: %3"), it->second, new_path, g_strerror(errno)) << endmsg;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -565,7 +574,7 @@ ExportProfileManager::save_format_to_disk (ExportFormatSpecPtr format)
|
|||
} else {
|
||||
/* Write new file */
|
||||
|
||||
XMLTree tree (new_path.to_string());
|
||||
XMLTree tree (new_path);
|
||||
tree.set_root (&format->get_state());
|
||||
tree.write();
|
||||
}
|
||||
|
|
@ -586,7 +595,10 @@ ExportProfileManager::remove_format_profile (ExportFormatSpecPtr format)
|
|||
|
||||
FileMap::iterator it = format_file_map.find (format->id());
|
||||
if (it != format_file_map.end()) {
|
||||
sys::remove (it->second);
|
||||
if (g_remove (it->second.c_str()) != 0) {
|
||||
error << string_compose (_("Unable to remove export profile %1: %2"), it->second, g_strerror(errno)) << endmsg;
|
||||
return;
|
||||
}
|
||||
format_file_map.erase (it);
|
||||
}
|
||||
|
||||
|
|
@ -604,7 +616,7 @@ ExportProfileManager::get_new_format (ExportFormatSpecPtr original)
|
|||
format->set_name ("empty format");
|
||||
}
|
||||
|
||||
sys::path path = save_format_to_disk (format);
|
||||
std::string path = save_format_to_disk (format);
|
||||
FilePair pair (format->id(), path);
|
||||
format_file_map.insert (pair);
|
||||
|
||||
|
|
@ -669,17 +681,17 @@ ExportProfileManager::serialize_format (FormatStatePtr state)
|
|||
void
|
||||
ExportProfileManager::load_formats ()
|
||||
{
|
||||
vector<sys::path> found = find_file (string_compose ("*%1", export_format_suffix));
|
||||
vector<std::string> found = find_file (string_compose ("*%1", export_format_suffix));
|
||||
|
||||
for (vector<sys::path>::iterator it = found.begin(); it != found.end(); ++it) {
|
||||
for (vector<std::string>::iterator it = found.begin(); it != found.end(); ++it) {
|
||||
load_format_from_disk (*it);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ExportProfileManager::load_format_from_disk (PBD::sys::path const & path)
|
||||
ExportProfileManager::load_format_from_disk (std::string const & path)
|
||||
{
|
||||
XMLTree const tree (path.to_string());
|
||||
XMLTree const tree (path);
|
||||
ExportFormatSpecPtr format = handler->add_format (*tree.root());
|
||||
|
||||
/* Handle id to filename mapping and don't add duplicates to list */
|
||||
|
|
@ -837,20 +849,20 @@ ExportProfileManager::check_config (boost::shared_ptr<Warnings> warnings,
|
|||
|
||||
string path = *path_it;
|
||||
|
||||
if (sys::exists (sys::path (path))) {
|
||||
if (Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
|
||||
warnings->conflicting_filenames.push_back (path);
|
||||
}
|
||||
|
||||
if (format->with_toc()) {
|
||||
string marker_file = handler->get_cd_marker_filename(path, CDMarkerTOC);
|
||||
if (sys::exists (sys::path (marker_file))) {
|
||||
if (Glib::file_test (marker_file, Glib::FILE_TEST_EXISTS)) {
|
||||
warnings->conflicting_filenames.push_back (marker_file);
|
||||
}
|
||||
}
|
||||
|
||||
if (format->with_cue()) {
|
||||
string marker_file = handler->get_cd_marker_filename(path, CDMarkerCUE);
|
||||
if (sys::exists (sys::path (marker_file))) {
|
||||
if (Glib::file_test (marker_file, Glib::FILE_TEST_EXISTS)) {
|
||||
warnings->conflicting_filenames.push_back (marker_file);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,12 +28,11 @@
|
|||
|
||||
#include "pbd/convert.h"
|
||||
#include "pbd/basename.h"
|
||||
#include "pbd/mountpoint.h"
|
||||
#include "pbd/stl_delete.h"
|
||||
#include "pbd/strsplit.h"
|
||||
#include "pbd/shortpath.h"
|
||||
#include "pbd/enumwriter.h"
|
||||
#include "pbd/filesystem.h"
|
||||
#include "pbd/file_utils.h"
|
||||
|
||||
#include <glibmm/miscutils.h>
|
||||
#include <glibmm/fileutils.h>
|
||||
|
|
@ -278,7 +277,7 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist
|
|||
++j;
|
||||
|
||||
while (j != hits.end()) {
|
||||
if (PBD::sys::inodes_same (*i, *j)) {
|
||||
if (PBD::equivalent_paths (*i, *j)) {
|
||||
/* *i and *j are the same file; break out of the loop early */
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue