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:
Paul Davis 2012-06-28 13:30:03 +00:00
parent f1fd9c7bdc
commit 6e824e7797
174 changed files with 2923 additions and 2899 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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();
for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
if (str == (*i).name) {
return (*i).channels;
ChanCount ret;
string str;
switch (type_wanted()) {
case AudioTrack:
case AudioBus:
str = channel_combo.get_active_text();
for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
if (str == (*i).name) {
ret.set (DataType::AUDIO, (*i).channels);
break;
}
}
}
ret.set (DataType::MIDI, 0);
break;
return 0;
case MidiTrack:
ret.set (DataType::AUDIO, 0);
ret.set (DataType::MIDI, 1);
break;
case MixedTrack:
str = channel_combo.get_active_text();
for (ChannelSetups::iterator i = channel_setups.begin(); i != channel_setups.end(); ++i) {
if (str == (*i).name) {
ret.set (DataType::AUDIO, (*i).channels);
break;
}
}
ret.set (DataType::MIDI, 1);
break;
}
return ret;
}
string

View file

@ -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 ();

View file

@ -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,18 +1371,14 @@ 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);
if (tracks.size() != how_many) {
if (how_many == 1) {
error << _("could not create a new midi track") << endmsg;
} else {
error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
}
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 mixed track") << endmsg;
} else {
error << string_compose (_("could not create %1 new mixed tracks"), how_many) << endmsg;
}
}
}
@ -1400,7 +1391,18 @@ restart JACK with more ports."), PROGRAM_NAME));
msg.run ();
}
}
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 (
@ -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;
}
}

View file

@ -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,9 +284,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
ARDOUR::AudioEngine *engine;
Gtk::Tooltips _tooltips;
void goto_mixer_window ();
void toggle_mixer_window ();
void toggle_mixer_on_top ();
void goto_editor_window ();
void goto_mixer_window ();
void toggle_mixer_window ();
void toggle_mixer_on_top ();
int setup_windows ();
void setup_transport ();

View file

@ -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 */
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 (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()) {
tact->set_active (true);
/* Toggle the mixer to `visible' if required */
if (!tact->get_active ()) {
tact->set_active (true);
}
}
goto_mixer_window ();
}
goto_mixer_window ();
}
/** The main editor window has been closed */

View file

@ -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)));

View file

@ -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 ];

View file

@ -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

View file

@ -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;
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;
bool clamped = clamp_frames_per_unit (fpu);
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 ();
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}
};

View file

@ -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();

View file

@ -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 ();
}

View file

@ -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 ();
};

View file

@ -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);
}
};

View file

@ -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;
}
bool changed = false;
int order;
for (order = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
boost::shared_ptr<Route> route = (*ri)[_columns.route];
int const old_key = order;
int const new_key = route->order_key (N_ ("editor"));
new_order[new_key] = old_key;
if (new_key != old_key) {
changed = true;
}
TreeModel::Children rows = _model->children();
if (rows.empty()) {
return;
}
if (changed) {
_redisplay_does_not_reset_order_keys = true;
DEBUG_TRACE (DEBUG::OrderKeys, "editor sync order keys from model\n");
/* `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);
TreeModel::Children::iterator ri;
bool changed = false;
uint32_t order = 0;
for (ri = rows.begin(); ri != rows.end(); ++ri) {
boost::shared_ptr<Route> route = (*ri)[_columns.route];
bool visible = (*ri)[_columns.visible];
uint32_t old_key = route->order_key (EditorSort);
uint32_t new_key;
if (!visible) {
new_key = UINT_MAX;
} else {
new_key = order;
}
assert (co.size() == _model->children().size ());
if (old_key != new_key) {
route->set_order_key (EditorSort, new_key);
changed = true;
}
_model->reorder (co);
_redisplay_does_not_reset_order_keys = false;
order++;
}
if (changed) {
/* 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();
RouteList r (*routes);
EditorOrderRouteSorter sorter;
r.sort (sorter);
_editor->handle_new_route (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;
/* new session: stamp all routes with the right editor order
* key
*/
_no_redisplay = true;
_editor->add_routes (*(routes.get()));
} else {
for (i = rows.begin(); i != rows.end(); ++i) {
/* existing session: sort a copy of the route list by
* editor-order and add its contents to the display.
*/
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 ();
RouteList r (*routes);
EditorOrderRouteSorter sorter;
r.sort (sorter);
_editor->add_routes (r);
}
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;
}

View file

@ -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;

View file

@ -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) {

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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>&);

View file

@ -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);

View file

@ -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("");
}

View file

@ -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 ()
{

View file

@ -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 */

View file

@ -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();

View file

@ -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 ();
}

View file

@ -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.

View file

@ -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;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -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;
}

View file

@ -32,7 +32,6 @@
#include "gtkmm2ext/utils.h"
#include "pbd/strsplit.h"
#include "pbd/replace_all.h"
#include "ardour/profile.h"

View file

@ -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.

View file

@ -337,7 +337,12 @@ MidiRegionView::canvas_event(GdkEvent* ev)
}
if (ev->type == GDK_2BUTTON_PRESS) {
return trackview.editor().toggle_internal_editing_from_double_click (ev);
// 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) ||
@ -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;
}

View file

@ -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;
}

View file

@ -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 ();
}

View file

@ -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 ();

View file

@ -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,76 +306,68 @@ 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;
for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
boost::shared_ptr<Route> route = (*x);
if (route->is_hidden()) {
continue;
}
if (route->is_monitor()) {
if (!_monitor_section) {
_monitor_section = new MonitorSection (_session);
{
Unwinder<bool> uw (no_track_list_redisplay, true);
for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
boost::shared_ptr<Route> route = (*x);
if (route->is_hidden()) {
continue;
}
if (route->is_monitor()) {
XMLNode* mnode = ARDOUR_UI::instance()->tearoff_settings (X_("monitor-section"));
if (mnode) {
_monitor_section->tearoff().set_state (*mnode);
}
}
out_packer.pack_end (_monitor_section->tearoff(), false, false);
_monitor_section->set_session (_session);
_monitor_section->tearoff().show_all ();
route->DropReferences.connect (*this, invalidator(*this), boost::bind (&Mixer_UI::monitor_section_going_away, this), gui_context());
/* no regular strip shown for control out */
continue;
}
strip = new MixerStrip (*this, _session, route);
strips.push_back (strip);
Config->get_default_narrow_ms() ? _strip_width = Narrow : _strip_width = Wide;
if (strip->width_owner() != strip) {
strip->set_width_enum (_strip_width, this);
if (!_monitor_section) {
_monitor_section = new MonitorSection (_session);
XMLNode* mnode = ARDOUR_UI::instance()->tearoff_settings (X_("monitor-section"));
if (mnode) {
_monitor_section->tearoff().set_state (*mnode);
}
}
out_packer.pack_end (_monitor_section->tearoff(), false, false);
_monitor_section->set_session (_session);
_monitor_section->tearoff().show_all ();
route->DropReferences.connect (*this, invalidator(*this), boost::bind (&Mixer_UI::monitor_section_going_away, this), gui_context());
/* no regular strip shown for control out */
continue;
}
strip = new MixerStrip (*this, _session, route);
strips.push_back (strip);
Config->get_default_narrow_ms() ? _strip_width = Narrow : _strip_width = Wide;
if (strip->width_owner() != strip) {
strip->set_width_enum (_strip_width, this);
}
show_strip (strip);
TreeModel::Row row = *(track_model->append());
row[track_columns.text] = route->name();
row[track_columns.visible] = strip->route()->is_master() ? true : strip->marked_for_display();
row[track_columns.route] = route;
row[track_columns.strip] = strip;
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));
}
show_strip (strip);
TreeModel::Row row = *(track_model->append());
row[track_columns.text] = route->name();
row[track_columns.visible] = strip->route()->is_master() ? true : strip->marked_for_display();
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,62 +386,117 @@ 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;
}
order++;
}
if (changed) {
/* 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);
}
}
if (keys.size() != rows.size()) {
PBD::stacktrace (cerr, 20);
}
assert(keys.size() == rows.size());
/* 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.
*/
// 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());
TreeModel::Children rows = track_model->children();
uint32_t n = 0;
if (changed) {
strip_redisplay_does_not_reset_order_keys = true;
track_model->reorder (neworder);
strip_redisplay_does_not_reset_order_keys = false;
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
@ -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,25 +744,26 @@ Mixer_UI::set_all_strips_visibility (bool yn)
TreeModel::Children rows = track_model->children();
TreeModel::Children::iterator i;
no_track_list_redisplay = true;
for (i = rows.begin(); i != rows.end(); ++i) {
TreeModel::Row row = (*i);
MixerStrip* strip = row[track_columns.strip];
if (strip == 0) {
continue;
{
Unwinder<bool> uw (no_track_list_redisplay, true);
for (i = rows.begin(); i != rows.end(); ++i) {
TreeModel::Row row = (*i);
MixerStrip* strip = row[track_columns.strip];
if (strip == 0) {
continue;
}
if (strip->route()->is_master() || strip->route()->is_monitor()) {
continue;
}
(*i)[track_columns.visible] = yn;
}
if (strip->route()->is_master() || strip->route()->is_monitor()) {
continue;
}
(*i)[track_columns.visible] = yn;
}
no_track_list_redisplay = false;
redisplay_track_list ();
}
@ -725,42 +774,43 @@ 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;
for (i = rows.begin(); i != rows.end(); ++i) {
TreeModel::Row row = (*i);
MixerStrip* strip = row[track_columns.strip];
if (strip == 0) {
continue;
}
if (strip->route()->is_master() || strip->route()->is_monitor()) {
continue;
}
boost::shared_ptr<AudioTrack> at = strip->audio_track();
switch (tracks) {
case 0:
(*i)[track_columns.visible] = yn;
break;
case 1:
if (at) { /* track */
(*i)[track_columns.visible] = yn;
{
Unwinder<bool> uw (no_track_list_redisplay, true);
for (i = rows.begin(); i != rows.end(); ++i) {
TreeModel::Row row = (*i);
MixerStrip* strip = row[track_columns.strip];
if (strip == 0) {
continue;
}
break;
case 2:
if (!at) { /* bus */
(*i)[track_columns.visible] = yn;
if (strip->route()->is_master() || strip->route()->is_monitor()) {
continue;
}
boost::shared_ptr<AudioTrack> at = strip->audio_track();
switch (tracks) {
case 0:
(*i)[track_columns.visible] = yn;
break;
case 1:
if (at) { /* track */
(*i)[track_columns.visible] = yn;
}
break;
case 2:
if (!at) { /* bus */
(*i)[track_columns.visible] = yn;
}
break;
}
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;
track_model->clear ();
add_strips (copy);
}
redisplay_track_list ();
}
@ -1548,25 +1588,13 @@ Mixer_UI::on_key_press_event (GdkEventKey* ev)
if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
return true;
}
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;
}
return forward_key_press (ev);
}
@ -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));

View file

@ -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);

View file

@ -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.

View file

@ -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));
}

View file

@ -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);
}
};

View file

@ -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)
{
/* 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));
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;
}

View file

@ -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;

View file

@ -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"));

View file

@ -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,27 +1716,42 @@ void
RouteUI::open_remote_control_id_dialog ()
{
ArdourDialog dialog (_("Remote Control ID"));
SpinButton* spin = 0;
uint32_t const limit = _session->ntracks() + _session->nbusses () + 4;
dialog.get_vbox()->set_border_width (18);
HBox* hbox = manage (new HBox);
hbox->set_spacing (6);
hbox->pack_start (*manage (new Label (_("Remote control ID:"))));
SpinButton* spin = manage (new SpinButton);
spin->set_digits (0);
spin->set_increments (1, 10);
spin->set_range (0, limit);
spin->set_value (_route->remote_control_id());
hbox->pack_start (*spin);
dialog.get_vbox()->pack_start (*hbox);
dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT);
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:"))));
spin = manage (new SpinButton);
spin->set_digits (0);
spin->set_increments (1, 10);
spin->set_range (0, limit);
spin->set_value (_route->remote_control_id());
hbox->pack_start (*spin);
dialog.get_vbox()->pack_start (*hbox);
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 ());
}
}

View file

@ -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;
}
}
}

View file

@ -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)) {

View file

@ -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 */
}

View file

@ -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 (...) {

View file

@ -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,23 +122,13 @@ 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();
// setup_prerelease_page ();
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 ();
@ -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");
}

View file

@ -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 ();

View file

@ -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);
}
}

View 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

View file

@ -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()) {

View file

@ -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>

View file

@ -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

View file

@ -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 ();

View file

@ -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;

View file

@ -61,6 +61,7 @@ namespace PBD {
extern uint64_t TempoMap;
extern uint64_t SoundGrid;
extern uint64_t SGSurface;
extern uint64_t OrderKeys;
}
}

View file

@ -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 */
@ -154,13 +156,15 @@ class ExportFormatManager : public PBD::ScopedConnectionList
ExportFormatBasePtr get_compatibility_intersection ();
ExportFormatBasePtr universal_set;
ExportFormatSpecPtr current_selection;
ExportFormatSpecPtr current_selection;
CompatList compatibilities;
QualityList qualities;
FormatList formats;
SampleRateList sample_rates;
std::string prev_description;
};
} // namespace ARDOUR

View file

@ -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; }

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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__ */

View file

@ -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;
};
}

View file

@ -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;
@ -420,19 +421,17 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
MonitorBusRemoteControlID = 319,
};
void set_remote_control_id (uint32_t id, bool notify_class_listeners = true);
void set_remote_control_id (uint32_t id, bool notify_class_listeners = true);
uint32_t remote_control_id () const;
/* for things concerned about *this* route's RID */
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;
OrderKeys order_keys;
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);

View file

@ -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,10 +857,12 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void destroy ();
enum SubState {
PendingDeclickIn = 0x1,
PendingDeclickOut = 0x2,
StopPendingCapture = 0x4,
PendingLocate = 0x20,
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,
};
/* stuff used in process() should be close together to
@ -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;

View file

@ -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

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -351,6 +351,11 @@ namespace ARDOUR {
PostFader
};
enum RouteSortOrderKey {
EditorSort,
MixerSort
};
enum MonitorModel {
HardwareMonitoring, ///< JACK does monitoring
SoftwareMonitoring, ///< Ardour does monitoring

View file

@ -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());
}

View file

@ -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());
}

View file

@ -73,10 +73,18 @@ AudioBuffer&
AudioPort::get_audio_buffer (pframes_t nframes)
{
/* caller must hold process lock */
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, _cycle_nframes) +
_global_port_buffer_offset + _port_buffer_offset, nframes);
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, _cycle_nframes) +
_global_port_buffer_offset + _port_buffer_offset, 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);
}

View file

@ -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

View file

@ -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*

View file

@ -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) {

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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");

View file

@ -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);

View file

@ -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);

View file

@ -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 ()
{

View file

@ -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";
case SR_22_05:
components.push_back ("22,5 kHz");
break;
case SR_44_1:
desc += "44,1 kHz";
case SR_44_1:
components.push_back ("44,1 kHz");
break;
case SR_48:
desc += "48 kHz";
case SR_48:
components.push_back ("48 kHz");
break;
case SR_88_2:
desc += "88,2 kHz";
case SR_88_2:
components.push_back ("88,2 kHz");
break;
case SR_96:
desc += "96 kHz";
case SR_96:
components.push_back ("96 kHz");
break;
case SR_192:
desc += "192 kHz";
case SR_192:
components.push_back ("192 kHz");
break;
case SR_Session:
desc += _("Session rate");
case SR_Session:
components.push_back (_("Session rate"));
break;
case SR_None:
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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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"

View file

@ -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);
}
}

View 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