summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-03-16 15:33:04 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-03-16 15:33:04 +0000
commit6ef5d85ae1f2c500c4163cd1df580b3f26991c1e (patch)
tree15194a52bb72f036117fc4c87c193a4cbb64be8b /gtk2_ardour
parent830911f6f9451d83a58043b3f9084d3caa164b7b (diff)
changes from 2.X starting in march 2009 through oct 20 2009 (5826 inclusive)
git-svn-id: svn://localhost/ardour2/branches/3.0@6761 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/about.cc7
-rw-r--r--gtk2_ardour/ardour.menus.in4
-rw-r--r--gtk2_ardour/ardour_ui.cc66
-rw-r--r--gtk2_ardour/ardour_ui.h1
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc1
-rw-r--r--gtk2_ardour/audio_region_view.cc7
-rw-r--r--gtk2_ardour/crossfade_edit.cc12
-rw-r--r--gtk2_ardour/editor.cc107
-rw-r--r--gtk2_ardour/editor.h10
-rw-r--r--gtk2_ardour/editor_actions.cc10
-rw-r--r--gtk2_ardour/editor_canvas.cc2
-rw-r--r--gtk2_ardour/editor_ops.cc4
-rw-r--r--gtk2_ardour/engine_dialog.cc46
-rw-r--r--gtk2_ardour/generic_pluginui.cc2
-rw-r--r--gtk2_ardour/io_selector.cc79
-rw-r--r--gtk2_ardour/io_selector.h10
-rw-r--r--gtk2_ardour/main.cc46
-rw-r--r--gtk2_ardour/marker.cc7
-rw-r--r--gtk2_ardour/mixer_strip.cc8
-rw-r--r--gtk2_ardour/nag.cc27
-rw-r--r--gtk2_ardour/nag.h1
-rw-r--r--gtk2_ardour/processor_box.cc35
-rw-r--r--gtk2_ardour/processor_box.h5
-rw-r--r--gtk2_ardour/public_editor.h4
-rw-r--r--gtk2_ardour/region_view.cc3
-rw-r--r--gtk2_ardour/region_view.h1
-rw-r--r--gtk2_ardour/route_time_axis.cc57
-rw-r--r--gtk2_ardour/route_time_axis.h2
-rw-r--r--gtk2_ardour/route_ui.cc17
-rw-r--r--gtk2_ardour/sfdb_ui.cc6
-rw-r--r--gtk2_ardour/time_axis_view.cc13
-rw-r--r--gtk2_ardour/time_axis_view_item.cc12
-rw-r--r--gtk2_ardour/time_axis_view_item.h1
33 files changed, 453 insertions, 160 deletions
diff --git a/gtk2_ardour/about.cc b/gtk2_ardour/about.cc
index e3734ec6ce..317be6f403 100644
--- a/gtk2_ardour/about.cc
+++ b/gtk2_ardour/about.cc
@@ -156,6 +156,7 @@ static const char* authors[] = {
N_("Nimal Ratnayake"),
N_("Dave Robillard"),
N_("Taybin Rutkin"),
+ N_("Andreas Ruge"),
N_("Sampo Savolainen"),
N_("Per Sigmond"),
N_("Lincoln Spiteri"),
@@ -168,7 +169,7 @@ static const char* authors[] = {
};
static const char* translators[] = {
- N_("French:\n\tAlain Fréhel <alain.frehel@free.fr>\n\tChristophe Combelles <ccomb@free.fr>\n"),
+ N_("French:\n\tAlain Fréhel <alain.frehel@free.fr>\n\tChristophe Combelles <ccomb@free.fr>\n\tMartin Blanchard\n"),
N_("German:\n\tKarsten Petersen <kapet@kapet.de>\
\n\tSebastian Arnold <mail@sebastian-arnold.net>\
\n\tRobert Schwede<schwede@ironshark.com>\n"),
@@ -181,6 +182,8 @@ static const char* translators[] = {
N_("Greek:\n\t Klearchos Gourgourinis <muadib@in.gr>\n"),
N_("Swedish:\n\t Petter Sundlöf <petter.sundlof@gmail.com>\n"),
N_("Polish:\n\t Piotr Zaryk <pzaryk@gmail.com>\n"),
+ N_("Czech:\n\t Pavel Frich\n"),
+ N_("Norwegian:\n\t Eivind Ødegård\n"),
0
};
@@ -559,7 +562,7 @@ About::About ()
}
set_translator_credits (t);
- set_copyright (_("Copyright (C) 1999-2009 Paul Davis\n"));
+ set_copyright (_("Copyright (C) 1999-2010 Paul Davis\n"));
set_license (gpl);
set_name (X_("ardour"));
set_website (X_("http://ardour.org/"));
diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in
index d5bb7b797c..26ce7c5323 100644
--- a/gtk2_ardour/ardour.menus.in
+++ b/gtk2_ardour/ardour.menus.in
@@ -286,6 +286,7 @@
<menuitem action='track-height-smaller'/>
<menuitem action='track-height-small'/>
</menu>
+ <menuitem action='track-record-enable-toggle'/>
<menuitem action='toggle-track-active'/>
<menuitem action='remove-track'/>
</menu>
@@ -433,7 +434,10 @@
<separator/>
</menu>
<menu name='Help' action='Help'>
+#ifndef GTKOSX
<menuitem action='About'/>
+#endif
+ <menuitem action='Chat'/>
</menu>
</menubar>
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 73b4e060fb..786e14aa69 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -42,6 +42,7 @@
#include "pbd/failed_constructor.h"
#include "pbd/enumwriter.h"
#include "pbd/memento_command.h"
+#include "pbd/openuri.h"
#include "pbd/file_utils.h"
#include "gtkmm2ext/gtk_ui.h"
@@ -2036,6 +2037,7 @@ ARDOUR_UI::snapshot_session ()
prompter.set_prompt (_("Name of New Snapshot"));
prompter.set_initial_text (timebuf);
+ again:
switch (prompter.run()) {
case RESPONSE_ACCEPT:
{
@@ -2043,6 +2045,21 @@ ARDOUR_UI::snapshot_session ()
bool do_save = (snapname.length() != 0);
+ if (do_save) {
+ if (snapname.find ('/') != string::npos) {
+ MessageDialog msg (_("To ensure compatibility with various systems\n"
+ "snapshot names may not contain a '/' character"));
+ msg.run ();
+ goto again;
+ }
+ if (snapname.find ('\\') != string::npos) {
+ MessageDialog msg (_("To ensure compatibility with various systems\n"
+ "snapshot names may not contain a '\\' character"));
+ msg.run ();
+ goto again;
+ }
+ }
+
vector<sys::path> p;
get_state_files_in_directory (_session->session_directory().root_path(), p);
vector<string> n = get_file_names_no_extension (p);
@@ -2493,6 +2510,10 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new)
(session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
(session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
+ /* absolute path or cwd-relative path specified for session name: infer session folder
+ from what was given.
+ */
+
session_path = Glib::path_get_dirname (session_name);
session_name = Glib::path_get_basename (session_name);
@@ -2529,6 +2550,22 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new)
continue;
}
+ if (session_name.find ('/') != Glib::ustring::npos) {
+ MessageDialog msg (*_startup, _("To ensure compatibility with various systems\n"
+ "session names may not contain a '/' character"));
+ msg.run ();
+ ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
+ continue;
+ }
+
+ if (session_name.find ('\\') != Glib::ustring::npos) {
+ MessageDialog msg (*_startup, _("To ensure compatibility with various systems\n"
+ "session names may not contain a '\\' character"));
+ msg.run ();
+ ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
+ continue;
+ }
+
_session_is_new = true;
}
@@ -2556,7 +2593,9 @@ ARDOUR_UI::close_session()
return;
}
- unload_session (true);
+ if (unload_session (true)) {
+ return;
+ }
ARDOUR_COMMAND_LINE::session_name = "";
get_session_parameters (true, false);
@@ -2727,6 +2766,16 @@ ARDOUR_UI::show ()
}
void
+ARDOUR_UI::launch_chat ()
+{
+#ifdef __APPLE__
+ open_uri("http://webchat.freenode.net/?channels=ardour-osx");
+#else
+ open_uri("http://webchat.freenode.net/?channels=ardour");
+#endif
+}
+
+void
ARDOUR_UI::show_about ()
{
if (about == 0) {
@@ -2734,6 +2783,7 @@ ARDOUR_UI::show_about ()
about->signal_response().connect(sigc::mem_fun (*this, &ARDOUR_UI::about_signal_response) );
}
+ about->set_transient_for(*editor);
about->show_all ();
}
@@ -2837,9 +2887,6 @@ require some unused files to continue to exist."));
const string dead_sound_directory = _session->session_directory().dead_sound_path().to_string();
-
-
-
/* subst:
%1 - number of files removed
%2 - location of "dead_sounds"
@@ -2848,19 +2895,22 @@ require some unused files to continue to exist."));
*/
const char* bprefix;
+ double space_adjusted = 0;
- if (rep.space < 1048576.0f) {
+ if (rep.space < 100000.0f) {
bprefix = X_("kilo");
- } else if (rep.space < 1048576.0f * 1000) {
+ } else if (rep.space < 1000000.0f * 1000) {
bprefix = X_("mega");
+ space_adjusted = truncf((float)rep.space / 1000.0);
} else {
bprefix = X_("giga");
+ space_adjusted = truncf((float)rep.space / (1000000.0 * 1000));
}
if (removed > 1) {
- txt.set_text (string_compose (plural_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
+ txt.set_text (string_compose (plural_msg, removed, _session->path() + "dead_sounds", space_adjusted, bprefix));
} else {
- txt.set_text (string_compose (singular_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
+ txt.set_text (string_compose (singular_msg, removed, _session->path() + "dead_sounds", space_adjusted, bprefix));
}
dhbox.pack_start (*dimage, true, false, 5);
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index 25bd74b55c..e131cf5431 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -115,6 +115,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void show_splash ();
void hide_splash ();
+ void launch_chat ();
void show_about ();
void hide_about ();
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index 532902a3d2..9630c37fae 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -218,6 +218,7 @@ ARDOUR_UI::install_actions ()
act = ActionManager::register_toggle_action (common_actions, X_("ToggleBigClock"), _("Big Clock"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_big_clock_window));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::register_action (common_actions, X_("About"), _("About"), sigc::mem_fun(*this, &ARDOUR_UI::show_about));
+ ActionManager::register_action (common_actions, X_("Chat"), _("Chat"), sigc::mem_fun(*this, &ARDOUR_UI::launch_chat));
ActionManager::register_toggle_action (common_actions, X_("ToggleThemeManager"), _("Theme Manager"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_theme_manager));
ActionManager::register_toggle_action (common_actions, X_("ToggleKeyEditor"), _("Key Bindings"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_key_editor));
ActionManager::register_toggle_action (common_actions, X_("ToggleBundleManager"), _("Bundle Manager"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_bundle_manager));
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 7a0e76606e..7b97d2f882 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -473,8 +473,6 @@ AudioRegionView::set_height (gdouble height)
// FIXME: ick
height -= 2;
- _height = height;
-
for (uint32_t n=0; n < wcnt; ++n) {
gdouble ht;
@@ -503,11 +501,6 @@ AudioRegionView::set_height (gdouble height)
manage_zero_line ();
reset_fade_shapes ();
-
- if (name_pixbuf) {
- name_pixbuf->raise_to_top();
- }
-
}
void
diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc
index c1201f2f9a..726194c41b 100644
--- a/gtk2_ardour/crossfade_edit.cc
+++ b/gtk2_ardour/crossfade_edit.cc
@@ -497,6 +497,18 @@ CrossfadeEditor::add_control_point (double x, double y)
void
CrossfadeEditor::Point::move_to (double nx, double ny, double xfract, double yfract)
{
+ if ( xfract < 0.0 ) {
+ xfract = 0.0;
+ } else if ( xfract > 1.0 ) {
+ xfract = 1.0;
+ }
+
+ if ( yfract < 0.0 ) {
+ yfract = 0.0;
+ } else if ( yfract > 1.0 ) {
+ yfract = 1.0;
+ }
+
const double half_size = rint(size/2.0);
double x1 = nx - half_size;
double x2 = nx + half_size;
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index f7b68fcbf1..572e192357 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -319,6 +319,7 @@ Editor::Editor ()
have_pending_keyboard_selection = false;
_follow_playhead = true;
+ _stationary_playhead = false;
_xfade_visibility = true;
editor_ruler_menu = 0;
no_ruler_shown_update = false;
@@ -1730,6 +1731,8 @@ Editor::add_region_context_items (StreamView* sv, boost::shared_ptr<Region> regi
region_mute_item->set_active();
fooc.block (false);
}
+
+ items.push_back (MenuElem (_("Transpose"), mem_fun(*this, &Editor::pitch_shift_regions)));
if (!Profile->get_sae()) {
items.push_back (CheckMenuElem (_("Opaque")));
@@ -2243,7 +2246,8 @@ Editor::set_state (const XMLNode& node, int /*version*/)
move (x, y);
if (_session && (prop = node.property ("playhead"))) {
- nframes64_t pos = atol (prop->value().c_str());
+ nframes64_t pos;
+ sscanf (prop->value().c_str(), "%" PRIi64, &pos);
playhead_cursor->set_position (pos);
} else {
playhead_cursor->set_position (0);
@@ -2341,6 +2345,18 @@ Editor::set_state (const XMLNode& node, int /*version*/)
}
}
+ if ((prop = node.property ("stationary-playhead"))) {
+ bool yn = (prop->value() == "yes");
+ set_stationary_playhead (yn);
+ RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-stationary-playhead"));
+ if (act) {
+ RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
+ if (tact->get_active() != yn) {
+ tact->set_active (yn);
+ }
+ }
+ }
+
if ((prop = node.property ("region-list-sort-type"))) {
RegionListSortType st;
_regions->reset_sort_type ((RegionListSortType) string_2_enum (prop->value(), st), true);
@@ -2447,6 +2463,7 @@ Editor::get_state ()
node->add_property ("show-waveforms-recording", _show_waveforms_recording ? "yes" : "no");
node->add_property ("show-measures", _show_measures ? "yes" : "no");
node->add_property ("follow-playhead", _follow_playhead ? "yes" : "no");
+ node->add_property ("stationary-playhead", _stationary_playhead ? "yes" : "no");
node->add_property ("xfades-visible", _xfade_visibility ? "yes" : "no");
node->add_property ("region-list-sort-type", enum_2_string (_regions->sort_type ()));
node->add_property ("mouse-mode", enum2str(mouse_mode));
@@ -3698,6 +3715,29 @@ Editor::set_follow_playhead (bool yn)
}
void
+Editor::toggle_stationary_playhead ()
+{
+ RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-stationary-playhead"));
+ if (act) {
+ RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
+ set_stationary_playhead (tact->get_active());
+ }
+}
+
+void
+Editor::set_stationary_playhead (bool yn)
+{
+ if (_stationary_playhead != yn) {
+ if ((_stationary_playhead = yn) == true) {
+ /* catch up */
+ // FIXME need a 3.0 equivalent of this 2.X call
+ // update_current_screen ();
+ }
+ instant_save ();
+ }
+}
+
+void
Editor::toggle_xfade_active (boost::weak_ptr<Crossfade> wxfade)
{
boost::shared_ptr<Crossfade> xfade (wxfade.lock());
@@ -4119,10 +4159,11 @@ Editor::undo_visual_state ()
return;
}
+ redo_visual_stack.push_back (current_visual_state());
+
VisualState* vs = undo_visual_stack.back();
undo_visual_stack.pop_back();
use_visual_state (*vs);
- redo_visual_stack.push_back (vs);
}
void
@@ -4132,10 +4173,11 @@ Editor::redo_visual_state ()
return;
}
+ undo_visual_stack.push_back (current_visual_state());
+
VisualState* vs = redo_visual_stack.back();
redo_visual_stack.pop_back();
use_visual_state (*vs);
- undo_visual_stack.push_back (vs);
}
void
@@ -4669,6 +4711,8 @@ _idle_resizer (gpointer arg)
void
Editor::add_to_idle_resize (TimeAxisView* view, int32_t h)
{
+ cerr << "add tav " << view << " with hdelta = " << h << endl;
+
if (resize_idle_id < 0) {
resize_idle_id = g_idle_add (_idle_resizer, this);
_pending_resize_amount = 0;
@@ -4682,6 +4726,8 @@ Editor::add_to_idle_resize (TimeAxisView* view, int32_t h)
_pending_resize_amount += h;
_pending_resize_view = view;
+ cerr << "Pending resize amount initially set at " << _pending_resize_amount << endl;
+
min_resulting = min (min_resulting, int32_t (_pending_resize_view->current_height()) + _pending_resize_amount);
if (selection->tracks.contains (_pending_resize_view)) {
@@ -4697,6 +4743,7 @@ Editor::add_to_idle_resize (TimeAxisView* view, int32_t h)
/* clamp */
if (uint32_t (min_resulting) < TimeAxisView::hSmall) {
_pending_resize_amount += TimeAxisView::hSmall - min_resulting;
+ cerr << "pending resize amount = " << _pending_resize_amount << endl;
}
}
@@ -4704,6 +4751,9 @@ Editor::add_to_idle_resize (TimeAxisView* view, int32_t h)
bool
Editor::idle_resize ()
{
+ cerr << "Idle resize, pra = " << _pending_resize_amount
+ << " set height to " << _pending_resize_view->current_height() << " + " << _pending_resize_amount << endl;
+
_pending_resize_view->idle_resize (_pending_resize_view->current_height() + _pending_resize_amount);
if (dynamic_cast<AutomationTimeAxisView*> (_pending_resize_view) == 0 &&
@@ -4716,6 +4766,7 @@ Editor::idle_resize ()
}
}
+ _pending_resize_amount = 0;
flush_canvas ();
_group_tabs->set_dirty ();
resize_idle_id = -1;
@@ -5121,33 +5172,33 @@ Editor::super_rapid_screen_update ()
playhead_cursor->set_position (frame);
}
-#undef CONTINUOUS_SCROLL
-#ifndef CONTINUOUS_SCROLL
+ if (!_stationary_playhead) {
- if (!_dragging_playhead && _follow_playhead && _session->requested_return_frame() < 0) {
- reset_x_origin_to_follow_playhead ();
- }
+ if (!_dragging_playhead && _follow_playhead && _session->requested_return_frame() < 0) {
+ reset_x_origin_to_follow_playhead ();
+ }
-#else // CONTINUOUS_SCROLL
-
- /* don't do continuous scroll till the new position is in the rightmost quarter of the
- editor canvas
- */
-
- double target = ((double)frame - (double)current_page_frames()/2.0) / frames_per_unit;
- if (target <= 0.0) {
- target = 0.0;
- }
- if (fabs(target - current) < current_page_frames() / frames_per_unit) {
- target = (target * 0.15) + (current * 0.85);
- } else {
- /* relax */
- }
-
- current = target;
- horizontal_adjustment.set_value (current);
-
-#endif // CONTINUOUS_SCROLL
+ } else {
+
+ /* don't do continuous scroll till the new position is in the rightmost quarter of the
+ editor canvas
+ */
+#if 0
+ // FIXME DO SOMETHING THAT WORKS HERE - this is 2.X code
+ double target = ((double)frame - (double)current_page_frames()/2.0) / frames_per_unit;
+ if (target <= 0.0) {
+ target = 0.0;
+ }
+ if (fabs(target - current) < current_page_frames() / frames_per_unit) {
+ target = (target * 0.15) + (current * 0.85);
+ } else {
+ /* relax */
+ }
+
+ current = target;
+ horizontal_adjustment.set_value (current);
+#endif
+ }
}
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 20e7567f36..0fc433d2fb 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -357,6 +357,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
/* playhead/screen stuff */
+ void set_stationary_playhead (bool yn);
+ void toggle_stationary_playhead ();
+ bool stationary_playhead() const { return _stationary_playhead; }
+
void set_follow_playhead (bool yn);
void toggle_follow_playhead ();
bool follow_playhead() const { return _follow_playhead; }
@@ -419,6 +423,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void goto_visual_state (uint32_t);
void save_visual_state (uint32_t);
+ void queue_draw_resize_line (int at);
+ void start_resize_line_ops ();
+ void end_resize_line_ops ();
+
TrackViewList const & get_track_views () {
return track_views;
}
@@ -1401,6 +1409,8 @@ public:
bool _show_measures;
/// true if the editor should follow the playhead, otherwise false
bool _follow_playhead;
+ /// true if we scroll the tracks rather than the playhead
+ bool _stationary_playhead;
/// true if waveforms should be shown while recording audio tracks, otherwise false
bool _show_waveforms_recording;
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index d137ed6351..ec7472df91 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -207,6 +207,7 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "track-record-enable-toggle", _("Toggle Record Enable"), sigc::mem_fun(*this, &Editor::toggle_record_enable));
ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::track_selection_sensitive_actions.push_back (act);
for (int i = 1; i <= 12; ++i) {
string const a = string_compose (X_("save-visual-state-%1"), i);
@@ -270,17 +271,23 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "move-selected-tracks-up", _("Move Selected Tracks Up"), sigc::bind (sigc::mem_fun(*_routes, &EditorRoutes::move_selected_tracks), true));
ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::track_selection_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "move-selected-tracks-down", _("Move Selected Tracks Down"), sigc::bind (sigc::mem_fun(*_routes, &EditorRoutes::move_selected_tracks), false));
ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::track_selection_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "scroll-tracks-up", _("Scroll Tracks Up"), sigc::mem_fun(*this, &Editor::scroll_tracks_up));
ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::track_selection_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "scroll-tracks-down", _("Scroll Tracks Down"), sigc::mem_fun(*this, &Editor::scroll_tracks_down));
+ ActionManager::track_selection_sensitive_actions.push_back (act);
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "step-tracks-up", _("Step Tracks Up"), sigc::mem_fun(*this, &Editor::scroll_tracks_up_line));
+ ActionManager::track_selection_sensitive_actions.push_back (act);
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "step-tracks-down", _("Step Tracks Down"), sigc::mem_fun(*this, &Editor::scroll_tracks_down_line));
ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::track_selection_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "scroll-backward", _("Scroll Backward"), sigc::bind (sigc::mem_fun(*this, &Editor::scroll_backward), 0.8f));
ActionManager::session_sensitive_actions.push_back (act);
@@ -550,6 +557,8 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "remove-last-capture", _("Remove Last Capture"), (sigc::mem_fun(*this, &Editor::remove_last_capture)));
ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::register_toggle_action (editor_actions, "toggle-stationary-playhead", _("Stationary Playhead"), (mem_fun(*this, &Editor::toggle_stationary_playhead)));
+
act = ActionManager::register_action (editor_actions, "insert-time", _("Insert Time"), (sigc::mem_fun(*this, &Editor::do_insert_time)));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::track_selection_sensitive_actions.push_back (act);
@@ -567,6 +576,7 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "fit-tracks", _("Fit Selected Tracks"), sigc::mem_fun(*this, &Editor::fit_selected_tracks));
ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::track_selection_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "track-height-largest", _("Largest"), sigc::bind (
sigc::mem_fun(*this, &Editor::set_track_height), TimeAxisView::hLargest));
ActionManager::session_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index 510b7e019f..4ea6d27ea2 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -801,7 +801,7 @@ Editor::scroll_canvas_horizontally ()
}
#ifndef GTKOSX
- if (!autoscroll_active) {
+ if (!autoscroll_active && !_stationary_playhead) {
/* force rulers and canvas to move in lock step */
while (gtk_events_pending ()) {
gtk_main_iteration ();
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index d4e8f4b54f..f7fe6e7b4a 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -1555,7 +1555,7 @@ Editor::temporal_zoom (gdouble fpu)
/* XXX this limit is also in ::set_frames_per_unit() */
- if (frames_per_unit <= 2.0 && fpu <= frames_per_unit) {
+ if (frames_per_unit <= 1.0 && fpu <= frames_per_unit) {
return;
}
@@ -2512,8 +2512,8 @@ Editor::rename_region()
d.get_vbox()->set_border_width (12);
d.get_vbox()->pack_start (hbox, false, false);
- d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+ d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
d.set_size_request (300, -1);
d.set_position (Gtk::WIN_POS_MOUSE);
diff --git a/gtk2_ardour/engine_dialog.cc b/gtk2_ardour/engine_dialog.cc
index 3213761c78..3717feb038 100644
--- a/gtk2_ardour/engine_dialog.cc
+++ b/gtk2_ardour/engine_dialog.cc
@@ -1255,24 +1255,34 @@ EngineControl::set_state (const XMLNode& root)
} else if (child->name() == "periodsize") {
period_size_combo.set_active_text(strval);
} else if (child->name() == "serverpath") {
- /* do not allow us to use a server path that doesn't
- exist on this system. this handles cases where
- the user has an RC file listing a serverpath
- from some other machine.
- */
- vector<string>::iterator x;
- for (x = server_strings.begin(); x != server_strings.end(); ++x) {
- if (*x == strval) {
- break;
- }
- }
- if (x != server_strings.end()) {
- serverpath_combo.set_active_text (strval);
- } else {
- warning << string_compose (_("configuration files contain a JACK server path that doesn't exist (%1)"),
- strval)
- << endmsg;
- }
+
+ /* only attempt to set this if we have bothered to look
+ up server names already. otherwise this is all
+ redundant (actually, all of this dialog/widget
+ is redundant in that case ...)
+ */
+
+ if (!server_strings.empty()) {
+ /* do not allow us to use a server path that doesn't
+ exist on this system. this handles cases where
+ the user has an RC file listing a serverpath
+ from some other machine.
+ */
+ vector<string>::iterator x;
+ for (x = server_strings.begin(); x != server_strings.end(); ++x) {
+ if (*x == strval) {
+ break;
+ }
+ }
+ if (x != server_strings.end()) {
+ serverpath_combo.set_active_text (strval);
+ } else {
+ warning << string_compose (_("configuration files contain a JACK server path that doesn't exist (%1)"),
+ strval)
+ << endmsg;
+ }
+ }
+
} else if (child->name() == "driver") {
driver_combo.set_active_text(strval);
} else if (child->name() == "interface") {
diff --git a/gtk2_ardour/generic_pluginui.cc b/gtk2_ardour/generic_pluginui.cc
index 636cdbc894..c8aa1f737d 100644
--- a/gtk2_ardour/generic_pluginui.cc
+++ b/gtk2_ardour/generic_pluginui.cc
@@ -322,7 +322,7 @@ GenericPluginUI::ControlUI::ControlUI ()
below). be sure to include a descender.
*/
- set_size_request_to_display_given_text (*automate_button.get_child(), _("Mgnual"), 5, 5);
+ set_size_request_to_display_given_text (automate_button, _("Mgnual"), 15, 10);
ignore_change = 0;
display = 0;
diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc
index 615ce9d69f..fd9ff2458d 100644
--- a/gtk2_ardour/io_selector.cc
+++ b/gtk2_ardour/io_selector.cc
@@ -29,6 +29,7 @@
#include "ardour/track.h"
#include "ardour/audio_track.h"
#include "ardour/midi_track.h"
+#include "ardour/mtdm.h"
#include "ardour/data_type.h"
#include "ardour/port.h"
#include "ardour/bundle.h"
@@ -216,16 +217,88 @@ IOSelectorWindow::io_name_changed (void* src)
}
PortInsertUI::PortInsertUI (Gtk::Window* parent, ARDOUR::Session* sess, boost::shared_ptr<ARDOUR::PortInsert> pi)
- : input_selector (parent, sess, pi->input())
- , output_selector (parent, sess, pi->output())
+ : _pi (pi)
+ , latency_button (_("Measure Latency"))
+ , input_selector (parent, sess, pi->input())
+ , output_selector (parent, sess, pi->output())
{
+ latency_hbox.pack_start (latency_button, false, false);
+ latency_hbox.pack_start (latency_display, false, false);
+ latency_frame.add (latency_hbox);
+
output_selector.set_min_height_divisor (2);
input_selector.set_min_height_divisor (2);
-
+
+ pack_start (latency_frame);
pack_start (output_selector, true, true);
pack_start (input_selector, true, true);
+
+ latency_button.signal_toggled().connect (mem_fun (*this, &PortInsertUI::latency_button_toggled));
}
+bool
+PortInsertUI::check_latency_measurement ()
+{
+ MTDM* mtdm = _pi->mtdm ();
+
+ if (mtdm->resolve () < 0) {
+ latency_display.set_text (_("No signal detected"));
+ return true;
+ }
+
+ if (mtdm->err () > 0.3) {
+ mtdm->invert ();
+ mtdm->resolve ();
+ }
+
+ char buf[64];
+ nframes_t sample_rate = AudioEngine::instance()->frame_rate();
+
+ if (sample_rate == 0) {
+ latency_display.set_text (_("Disconnected from audio engine"));
+ _pi->stop_latency_detection ();
+ return false;
+ }
+
+ snprintf (buf, sizeof (buf), "%10.3lf frames %10.3lf ms", mtdm->del (), mtdm->del () * 1000.0f/sample_rate);
+
+ bool solid = true;
+
+ if (mtdm->err () > 0.2) {
+ strcat (buf, " ??");
+ solid = false;
+ }
+
+ if (mtdm->inv ()) {
+ strcat (buf, " (Inv)");
+ solid = false;
+ }
+
+ if (solid) {
+ _pi->set_measured_latency ((nframes_t) rint (mtdm->del()));
+ strcat (buf, " (set)");
+ }
+
+ latency_display.set_text (buf);
+ return true;
+}
+
+void
+PortInsertUI::latency_button_toggled ()
+{
+ if (latency_button.get_active ()) {
+
+ _pi->start_latency_detection ();
+ latency_display.set_text (_("Detecting ..."));
+ latency_timeout = Glib::signal_timeout().connect (mem_fun (*this, &PortInsertUI::check_latency_measurement), 250);
+
+ } else {
+ _pi->stop_latency_detection ();
+ latency_timeout.disconnect ();
+ }
+}
+
+
void
PortInsertUI::redisplay ()
{
diff --git a/gtk2_ardour/io_selector.h b/gtk2_ardour/io_selector.h
index a4545dbfc4..11454f8531 100644
--- a/gtk2_ardour/io_selector.h
+++ b/gtk2_ardour/io_selector.h
@@ -98,8 +98,18 @@ class PortInsertUI : public Gtk::HBox
void finished (IOSelector::Result);
private:
+ boost::shared_ptr<ARDOUR::PortInsert> _pi;
+
+ Gtk::ToggleButton latency_button;
IOSelector input_selector;
IOSelector output_selector;
+ Gtk::Label latency_display;
+ Gtk::Frame latency_frame;
+ Gtk::HBox latency_hbox;
+ sigc::connection latency_timeout;
+
+ bool check_latency_measurement ();
+ void latency_button_toggled ();
};
class PortInsertWindow : public ArdourDialog
diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc
index 2b16de3d70..daa2491f0f 100644
--- a/gtk2_ardour/main.cc
+++ b/gtk2_ardour/main.cc
@@ -281,10 +281,52 @@ fixup_bundle_environment ()
#endif
+static gboolean
+tell_about_jack_death (void* /* ignored */)
+{
+ if (AudioEngine::instance()->processed_frames() == 0) {
+ /* died during startup */
+ MessageDialog msg (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK);
+ msg.set_position (Gtk::WIN_POS_CENTER);
+ msg.set_secondary_text (_(
+"JACK exited unexpectedly, and without notifying Ardour.\n\
+\n\
+This could be due to misconfiguration or to an error inside JACK.\n\
+\n\
+Click OK to exit Ardour."));
+
+ msg.run ();
+ _exit (0);
+
+ } else {
+
+ /* engine has already run, so this is a mid-session JACK death */
+
+ MessageDialog* msg = manage (new MessageDialog (_("JACK exited"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE));
+ msg->set_secondary_text (_(
+"JACK exited unexpectedly, and without notifying Ardour.\n\
+\n\
+This is probably due to an error inside JACK. You should restart JACK\n\
+and reconnect Ardour to it, or exit Ardour now. You cannot save your\n\
+session at this time, because we would lose your connection information.\n"));
+ msg->present ();
+ }
+ return false; /* do not call again */
+}
+
static void
-sigpipe_handler (int /*sig*/)
+sigpipe_handler (int sig)
{
- cerr << _("SIGPIPE received - JACK has probably died") << endl;
+ /* XXX fix this so that we do this again after a reconnect to JACK
+ */
+
+ static bool done_the_jack_thing = false;
+
+ if (!done_the_jack_thing) {
+ AudioEngine::instance()->died ();
+ g_idle_add (tell_about_jack_death, 0);
+ done_the_jack_thing = true;
+ }
}
#ifdef HAVE_LV2
diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc
index f4848228f8..f0f8068e8b 100644
--- a/gtk2_ardour/marker.cc
+++ b/gtk2_ardour/marker.cc
@@ -255,20 +255,17 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con
/* setup name pixbuf sizes */
name_font = get_font_for_style (N_("MarkerText"));
- Gtk::Window win;
Gtk::Label foo;
- win.add (foo);
Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (X_("Hg")); /* ascender + descender */
int width;
- int height;
layout->set_font_description (*name_font);
- Gtkmm2ext::get_ink_pixel_size (layout, width, height);
- name_height = height + 6;
+ Gtkmm2ext::get_ink_pixel_size (layout, width, name_height);
name_pixbuf = new ArdourCanvas::Pixbuf(*group);
name_pixbuf->property_x() = label_offset;
+ name_pixbuf->property_y() = (13/2) - (name_height/2);
set_name (annotation.c_str());
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 05a7f4628b..57faf1c3bb 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -207,6 +207,7 @@ MixerStrip::init ()
ARDOUR_UI::instance()->set_tip (&group_button, _("Mix group"), "");
group_button.add (group_label);
group_button.set_name ("MixerGroupButton");
+ Gtkmm2ext::set_size_request_to_display_given_text (group_button, "Group", 2, 2);
group_label.set_name ("MixerGroupButtonLabel");
comment_button.set_name ("MixerCommentButton");
@@ -1319,12 +1320,7 @@ MixerStrip::route_group_changed ()
RouteGroup *rg = _route->route_group();
if (rg) {
- /* XXX: this needs a better algorithm */
- string truncated = rg->name ();
- if (truncated.length () > 5) {
- truncated = truncated.substr (0, 5);
- }
- group_label.set_text (truncated);
+ group_label.set_text (PBD::short_version (rg->name(), 5));
} else {
switch (_width) {
case Wide:
diff --git a/gtk2_ardour/nag.cc b/gtk2_ardour/nag.cc
index 7ae1b6e809..7a7a4aadbb 100644
--- a/gtk2_ardour/nag.cc
+++ b/gtk2_ardour/nag.cc
@@ -5,6 +5,8 @@
#include <fstream>
#include <gtkmm/stock.h>
+#include "pbd/openuri.h"
+
#include "ardour/ardour.h"
#include "ardour/filesystem_paths.h"
@@ -176,35 +178,16 @@ NagScreen::offer_to_donate ()
/* we don't care if it fails */
- open_uri (uri);
+ PBD::open_uri (uri);
}
void
NagScreen::offer_to_subscribe ()
{
const char* uri = "http://ardour.org/subscribe";
-
- if (open_uri (uri)) {
+
+ if (PBD::open_uri (uri)) {
mark_subscriber ();
}
}
-bool
-NagScreen::open_uri (const char* uri)
-{
-#ifdef HAVE_GTK_OPEN_URI
- GError* err;
- return gtk_open_uri (0, uri, GDK_CURRENT_TIME, &err);
-#else
-#ifdef GTKOSX
- extern bool cocoa_open_url (const char*);
- return cocoa_open_url (uri);
-#else
- std::string command = "xdg-open ";
- command += uri;
- spawn_command_line_async (command);
-
- return true;
-#endif
-#endif
-}
diff --git a/gtk2_ardour/nag.h b/gtk2_ardour/nag.h
index 664cff76fe..911f09d926 100644
--- a/gtk2_ardour/nag.h
+++ b/gtk2_ardour/nag.h
@@ -32,7 +32,6 @@ class NagScreen : public ArdourDialog
void mark_affirmed_subscriber ();
void offer_to_donate ();
void offer_to_subscribe ();
- bool open_uri (const char*);
static bool is_subscribed (bool& really);
};
diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc
index 9c3c7902bb..201e89db3b 100644
--- a/gtk2_ardour/processor_box.cc
+++ b/gtk2_ardour/processor_box.cc
@@ -88,6 +88,7 @@ using namespace Gtkmm2ext;
ProcessorBox* ProcessorBox::_current_processor_box = 0;
RefPtr<Action> ProcessorBox::paste_action;
+RefPtr<Action> ProcessorBox::cut_action;
Glib::RefPtr<Gdk::Pixbuf> SendProcessorEntry::_slider;
ProcessorEntry::ProcessorEntry (boost::shared_ptr<Processor> p, Width w)
@@ -494,6 +495,7 @@ ProcessorBox::show_processor_menu (gint arg)
}
}
+ cut_action->set_sensitive (can_cut());
paste_action->set_sensitive (!_rr_selection.processors.empty());
processor_menu->popup (1, arg);
@@ -1054,6 +1056,27 @@ ProcessorBox::rename_processors ()
}
}
+bool
+ProcessorBox::can_cut () const
+{
+ vector<boost::shared_ptr<Processor> > sel;
+
+ get_selected_processors (sel);
+
+ /* cut_processors () does not cut inserts */
+
+ for (vector<boost::shared_ptr<Processor> >::const_iterator i = sel.begin (); i != sel.end (); ++i) {
+
+ if (boost::dynamic_pointer_cast<PluginInsert>((*i)) != 0 ||
+ (boost::dynamic_pointer_cast<Send>((*i)) != 0) ||
+ (boost::dynamic_pointer_cast<Return>((*i)) != 0)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void
ProcessorBox::cut_processors ()
{
@@ -1333,10 +1356,10 @@ ProcessorBox::deactivate_processor (boost::shared_ptr<Processor> r)
}
void
-ProcessorBox::get_selected_processors (ProcSelection& processors)
+ProcessorBox::get_selected_processors (ProcSelection& processors) const
{
- list<ProcessorEntry*> selection = processor_display.selection ();
- for (list<ProcessorEntry*>::iterator i = selection.begin(); i != selection.end(); ++i) {
+ const list<ProcessorEntry*> selection = processor_display.selection ();
+ for (list<ProcessorEntry*>::const_iterator i = selection.begin(); i != selection.end(); ++i) {
processors.push_back ((*i)->processor ());
}
}
@@ -1551,9 +1574,9 @@ ProcessorBox::register_actions ()
sigc::ptr_fun (ProcessorBox::rb_clear_post));
/* standard editing stuff */
- act = ActionManager::register_action (popup_act_grp, X_("cut"), _("Cut"),
- sigc::ptr_fun (ProcessorBox::rb_cut));
- ActionManager::plugin_selection_sensitive_actions.push_back(act);
+ cut_action = ActionManager::register_action (popup_act_grp, X_("cut"), _("Cut"),
+ sigc::ptr_fun (ProcessorBox::rb_cut));
+ ActionManager::plugin_selection_sensitive_actions.push_back(cut_action);
act = ActionManager::register_action (popup_act_grp, X_("copy"), _("Copy"),
sigc::ptr_fun (ProcessorBox::rb_copy));
ActionManager::plugin_selection_sensitive_actions.push_back(act);
diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h
index d5e4572659..74ab5c85bb 100644
--- a/gtk2_ardour/processor_box.h
+++ b/gtk2_ardour/processor_box.h
@@ -238,8 +238,11 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject, public ARD
void rename_processors ();
void for_selected_processors (void (ProcessorBox::*pmf)(boost::shared_ptr<ARDOUR::Processor>));
- void get_selected_processors (ProcSelection&);
+ void get_selected_processors (ProcSelection&) const;
+ bool can_cut() const;
+
+ static Glib::RefPtr<Gtk::Action> cut_action;
static Glib::RefPtr<Gtk::Action> paste_action;
void paste_processor_state (const XMLNodeList&, boost::shared_ptr<ARDOUR::Processor>);
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index e91f2911e3..1ddee9a585 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -228,6 +228,10 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
virtual void set_selected_mixer_strip (TimeAxisView&) = 0;
virtual void hide_track_in_display (TimeAxisView& tv, bool temporary = false) = 0;
+ virtual void set_stationary_playhead (bool yn) = 0;
+ virtual void toggle_stationary_playhead () = 0;
+ virtual bool stationary_playhead() const = 0;
+
/** Set whether the editor should follow the playhead.
* @param yn true to follow playhead, otherwise false.
*/
diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc
index 8e45b7ace0..85fa5b87e3 100644
--- a/gtk2_ardour/region_view.cc
+++ b/gtk2_ardour/region_view.cc
@@ -94,7 +94,6 @@ RegionView::RegionView (const RegionView& other)
current_visible_sync_position = other.current_visible_sync_position;
valid = false;
_pixel_width = other._pixel_width;
- _height = other._height;
GhostRegion::CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
}
@@ -114,7 +113,6 @@ RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> other
current_visible_sync_position = other.current_visible_sync_position;
valid = false;
_pixel_width = other._pixel_width;
- _height = other._height;
GhostRegion::CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
}
@@ -147,7 +145,6 @@ RegionView::init (Gdk::Color const & basic_color, bool wfd)
editor = 0;
valid = true;
in_destructor = false;
- _height = 0;
wait_for_data = wfd;
sync_mark = 0;
sync_line = 0;
diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h
index 43d8a00f17..d9bf4cd7e0 100644
--- a/gtk2_ardour/region_view.h
+++ b/gtk2_ardour/region_view.h
@@ -135,7 +135,6 @@ class RegionView : public TimeAxisViewItem
bool valid; ///< see StreamView::redisplay_diskstream()
bool _enable_display; ///< see StreamView::redisplay_diskstream()
double _pixel_width;
- double _height;
bool in_destructor;
bool wait_for_data;
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 62a2b2b8a0..4674bd3c19 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -1471,6 +1471,12 @@ RouteTimeAxisView::get_child_list()
}
+struct PlaylistSorter {
+ bool operator() (boost::shared_ptr<Playlist> a, boost::shared_ptr<Playlist> b) const {
+ return a->sort_id() < b->sort_id();
+ }
+};
+
void
RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
{
@@ -1486,32 +1492,36 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
delete playlist_menu;
- playlist_menu = new Menu;
- playlist_menu->set_name ("ArdourContextMenu");
- vector<boost::shared_ptr<Playlist> > playlists;
+ vector<boost::shared_ptr<Playlist> > playlists, playlists_ds;
boost::shared_ptr<Diskstream> ds = get_diskstream();
RadioMenuItem::Group playlist_group;
_session->playlists->get (playlists);
- for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
-
- if ((*i)->get_orig_diskstream_id() == ds->id()) {
- playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::use_playlist),
- boost::weak_ptr<Playlist> (*i))));
-
- if (ds->playlist()->id() == (*i)->id()) {
- static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
- }
- } else if (ds->playlist()->id() == (*i)->id()) {
- playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::use_playlist),
- boost::weak_ptr<Playlist>(*i))));
- static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
-
+ /* find the playlists for this diskstream */
+ for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ if (((*i)->get_orig_diskstream_id() == ds->id()) || (ds->playlist()->id() == (*i)->id())) {
+ playlists_ds.push_back(*i);
+ }
+ }
+
+ /* sort the playlists */
+ PlaylistSorter cmp;
+ sort(playlists_ds.begin(), playlists_ds.end(), cmp);
+
+ /* add the playlists to the menu */
+ for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists_ds.begin(); i != playlists_ds.end(); ++i) {
+ playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name()));
+ RadioMenuItem *item = static_cast<RadioMenuItem*>(&playlist_items.back());
+ item->signal_toggled().connect(sigc::bind (sigc::mem_fun (*this, &RouteTimeAxisView::use_playlist), item, boost::weak_ptr<Playlist> (*i)));
+
+ if (ds->playlist()->id() == (*i)->id()) {
+ item->set_active();
+
}
}
-
+
playlist_items.push_back (SeparatorElem());
playlist_items.push_back (MenuElem (_("Rename"), sigc::mem_fun(*this, &RouteTimeAxisView::rename_current_playlist)));
playlist_items.push_back (SeparatorElem());
@@ -1535,10 +1545,15 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
}
void
-RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
+RouteTimeAxisView::use_playlist (RadioMenuItem *item, boost::weak_ptr<Playlist> wpl)
{
assert (is_track());
+ // exit if we were triggered by deactivating the old playlist
+ if (!item->get_active()) {
+ return;
+ }
+
boost::shared_ptr<Playlist> pl (wpl.lock());
if (!pl) {
@@ -1549,8 +1564,8 @@ RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
if (apl) {
if (get_diskstream()->playlist() == apl) {
- // radio button cotnrols mean this function is called for both the
- // old and new playlist
+ // exit when use_playlist is called by the creation of the playlist menu
+ // or the playlist choice is unchanged
return;
}
get_diskstream()->use_playlist (apl);
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
index 39d65cd499..1a9909374f 100644
--- a/gtk2_ardour/route_time_axis.h
+++ b/gtk2_ardour/route_time_axis.h
@@ -294,7 +294,7 @@ protected:
virtual Gtk::Menu* build_mode_menu() { return 0; }
virtual Gtk::Menu* build_color_mode_menu() { return 0; }
- void use_playlist (boost::weak_ptr<ARDOUR::Playlist>);
+ void use_playlist (Gtk::RadioMenuItem *item, boost::weak_ptr<ARDOUR::Playlist> wpl);
ArdourCanvas::SimpleRect* timestretch_rect;
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index befed97743..6c96ebac48 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -262,9 +262,10 @@ RouteUI::mute_press (GdkEventButton* ev)
// Primary-button2 click is the midi binding click
// button2-click is "momentary"
- if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier))) {
- return false;
- }
+
+ if (mute_button->on_button_press_event (ev)) {
+ return true;
+ }
_mute_release = new SoloMuteRelease (_route->muted ());
}
@@ -357,9 +358,9 @@ RouteUI::solo_press(GdkEventButton* ev)
// Primary-button2 click is the midi binding click
// button2-click is "momentary"
- if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier))) {
- return false;
- }
+ if (solo_button->on_button_press_event (ev)) {
+ return true;
+ }
_solo_release = new SoloMuteRelease (_route->soloed());
}
@@ -491,10 +492,10 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
if (!ignore_toggle && is_track() && rec_enable_button) {
- if (Keyboard::is_button2_event (ev) && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
+ if (Keyboard::is_button2_event (ev)) {
// do nothing on midi sigc::bind event
- return false;
+ return rec_enable_button->on_button_press_event (ev);
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc
index 65ae061e5c..381489cf88 100644
--- a/gtk2_ardour/sfdb_ui.cc
+++ b/gtk2_ardour/sfdb_ui.cc
@@ -443,6 +443,10 @@ SoundFileBrowser::SoundFileBrowser (Gtk::Window& parent, string title, ARDOUR::S
chooser.set_select_multiple (true);
chooser.signal_update_preview().connect(sigc::mem_fun(*this, &SoundFileBrowser::update_preview));
chooser.signal_file_activated().connect (sigc::mem_fun (*this, &SoundFileBrowser::chooser_file_activated));
+#ifdef GTKOSX
+ /* some broken redraw behaviour - this is a bandaid */
+ chooser.signal_selection_changed().connect (mem_fun (chooser, &Widget::queue_draw));
+#endif
if (!persistent_folder.empty()) {
chooser.set_current_folder (persistent_folder);
@@ -1000,7 +1004,7 @@ SoundFileOmega::reset_options ()
channel_strings.push_back (_("sequence files"));
}
if (same_size) {
- channel_strings.push_back (_("all files in one region"));
+ channel_strings.push_back (_("all files in one track"));
}
}
diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc
index 16485f0082..04018dee7c 100644
--- a/gtk2_ardour/time_axis_view.cc
+++ b/gtk2_ardour/time_axis_view.cc
@@ -153,6 +153,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
resizer.signal_button_press_event().connect (sigc::mem_fun (*this, &TimeAxisView::resizer_button_press));
resizer.signal_button_release_event().connect (sigc::mem_fun (*this, &TimeAxisView::resizer_button_release));
resizer.signal_motion_notify_event().connect (sigc::mem_fun (*this, &TimeAxisView::resizer_motion));
+
resizer.set_events (Gdk::BUTTON_PRESS_MASK|
Gdk::BUTTON_RELEASE_MASK|
Gdk::POINTER_MOTION_MASK|
@@ -1307,13 +1308,11 @@ TimeAxisView::idle_resize (uint32_t h)
bool
TimeAxisView::resizer_motion (GdkEventMotion* ev)
{
- if (_resize_drag_start < 0) {
- return true;
- }
-
- int32_t const delta = (int32_t) floor (ev->y_root - _resize_drag_start);
- _editor.add_to_idle_resize (this, delta);
- _resize_drag_start = ev->y_root;
+ if (_resize_drag_start >= 0) {
+ int32_t const delta = (int32_t) floor (ev->y_root - _resize_drag_start);
+ _editor.add_to_idle_resize (this, delta);
+ _resize_drag_start = ev->y_root;
+ }
return true;
}
diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc
index 3ecb152fea..f36e5f4eb5 100644
--- a/gtk2_ardour/time_axis_view_item.cc
+++ b/gtk2_ardour/time_axis_view_item.cc
@@ -78,7 +78,7 @@ double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color const & base_color,
nframes64_t start, nframes64_t duration, bool recording,
Visibility vis)
- : trackview (tv), _recregion(recording)
+ : trackview (tv), _height (1.0), _recregion(recording)
{
if (!have_name_font) {
@@ -558,6 +558,8 @@ TimeAxisViewItem::set_name_text(const ustring& new_name)
void
TimeAxisViewItem::set_height (double height)
{
+ _height = height;
+
if (name_highlight) {
if (height < NAME_HIGHLIGHT_THRESH) {
name_highlight->hide ();
@@ -841,9 +843,7 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
if (name_highlight) {
- double height = name_highlight->property_y2 ();
-
- if (height < NAME_HIGHLIGHT_THRESH) {
+ if (_height < NAME_HIGHLIGHT_THRESH) {
name_highlight->hide();
high_enough_for_name = false;
} else {
@@ -853,7 +853,7 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
}
high_enough_for_name = true;
}
-
+
if (visibility & FullWidthNameHighlight) {
name_highlight->property_x2() = pixel_width;
} else {
@@ -878,6 +878,8 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
frame_handle_end->property_x2() = pixel_width;
}
}
+
+ update_name_pixbuf_visibility ();
}
void
diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h
index 5f97ddcf4f..0c4d5a3291 100644
--- a/gtk2_ardour/time_axis_view_item.h
+++ b/gtk2_ardour/time_axis_view_item.h
@@ -467,6 +467,7 @@ class TimeAxisViewItem : public Selectable, public PBD::ScopedConnectionList
ArdourCanvas::SimpleRect* frame_handle_start;
ArdourCanvas::SimpleRect* frame_handle_end;
+ double _height;
Visibility visibility;
bool _recregion;