From 452672f78f5f0f9195bfd48398e29b18a8fb1df7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 1 Feb 2012 01:07:52 +0000 Subject: [PATCH] Make crossfade convert-to-full and activate/deactivate work across edit groups (#4658). git-svn-id: svn://localhost/ardour2/branches/3.0@11413 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor.cc | 69 ++++++++++++++++++++---------- gtk2_ardour/editor.h | 15 ++++--- gtk2_ardour/editor_selection.cc | 40 +++++++++++++++++ libs/ardour/ardour/audioplaylist.h | 1 + libs/ardour/audio_playlist.cc | 10 +++++ 5 files changed, 106 insertions(+), 29 deletions(-) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index fd7be603cd..83ca9ee0e8 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1718,7 +1718,7 @@ Editor::build_track_selection_context_menu () * @param edit_items List to add the items to. */ void -Editor::add_crossfade_context_items (AudioStreamView* /*view*/, boost::shared_ptr xfade, Menu_Helpers::MenuList& edit_items, bool many) +Editor::add_crossfade_context_items (AudioStreamView* view, boost::shared_ptr xfade, Menu_Helpers::MenuList& edit_items, bool many) { using namespace Menu_Helpers; Menu *xfade_menu = manage (new Menu); @@ -1732,8 +1732,13 @@ Editor::add_crossfade_context_items (AudioStreamView* /*view*/, boost::shared_pt str = _("Unmute"); } - items.push_back (MenuElem (str, sigc::bind (sigc::mem_fun(*this, &Editor::toggle_xfade_active), boost::weak_ptr (xfade)))); - items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun(*this, &Editor::edit_xfade), boost::weak_ptr (xfade)))); + items.push_back ( + MenuElem (str, sigc::bind (sigc::mem_fun (*this, &Editor::toggle_xfade_active), &view->trackview(), boost::weak_ptr (xfade))) + ); + + items.push_back ( + MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &Editor::edit_xfade), boost::weak_ptr (xfade))) + ); if (xfade->can_follow_overlap()) { @@ -1743,7 +1748,9 @@ Editor::add_crossfade_context_items (AudioStreamView* /*view*/, boost::shared_pt str = _("Convert to Full"); } - items.push_back (MenuElem (str, sigc::bind (sigc::mem_fun(*this, &Editor::toggle_xfade_length), xfade))); + items.push_back ( + MenuElem (str, sigc::bind (sigc::mem_fun (*this, &Editor::toggle_xfade_length), &view->trackview(), xfade)) + ); } if (many) { @@ -3632,34 +3639,50 @@ Editor::set_stationary_playhead (bool yn) } void -Editor::toggle_xfade_active (boost::weak_ptr wxfade) +Editor::toggle_xfade_active (RouteTimeAxisView* tv, boost::weak_ptr wxfade) { boost::shared_ptr xfade (wxfade.lock()); - if (xfade) { - xfade->clear_changes (); - xfade->set_active (!xfade->active()); - _session->begin_reversible_command (_("Change crossfade active state")); - _session->add_command (new StatefulDiffCommand (xfade)); - _session->commit_reversible_command (); + if (!xfade) { + return; } + + vector > all = get_equivalent_crossfades (*tv, xfade, ARDOUR::Properties::edit.property_id); + + _session->begin_reversible_command (_("Change crossfade active state")); + + for (vector >::iterator i = all.begin(); i != all.end(); ++i) { + (*i)->clear_changes (); + (*i)->set_active (!(*i)->active()); + _session->add_command (new StatefulDiffCommand (*i)); + } + + _session->commit_reversible_command (); } void -Editor::toggle_xfade_length (boost::weak_ptr wxfade) +Editor::toggle_xfade_length (RouteTimeAxisView* tv, boost::weak_ptr wxfade) { boost::shared_ptr xfade (wxfade.lock()); - if (xfade) { - XMLNode& before = xfade->get_state (); - xfade->set_follow_overlap (!xfade->following_overlap()); - XMLNode& after = xfade->get_state (); - - /* This can't be a StatefulDiffCommand as the fade shapes are not - managed by the Stateful properties system. - */ - _session->begin_reversible_command (_("Change crossfade length")); - _session->add_command (new MementoCommand (*xfade.get(), &before, &after)); - _session->commit_reversible_command (); + if (!xfade) { + return; } + + vector > all = get_equivalent_crossfades (*tv, xfade, ARDOUR::Properties::edit.property_id); + + /* This can't be a StatefulDiffCommand as the fade shapes are not + managed by the Stateful properties system. + */ + _session->begin_reversible_command (_("Change crossfade length")); + + for (vector >::iterator i = all.begin(); i != all.end(); ++i) { + XMLNode& before = (*i)->get_state (); + (*i)->set_follow_overlap (!(*i)->following_overlap()); + XMLNode& after = (*i)->get_state (); + + _session->add_command (new MementoCommand (*i->get(), &before, &after)); + } + + _session->commit_reversible_command (); } void diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index e0cbf83517..7147b6378d 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -630,18 +630,21 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void get_equivalent_regions (RegionView* rv, std::vector &, PBD::PropertyID) const; RegionSelection get_equivalent_regions (RegionSelection &, PBD::PropertyID) const; + std::vector > get_equivalent_crossfades ( + RouteTimeAxisView&, boost::shared_ptr, PBD::PropertyID + ) const; void mapover_tracks (sigc::slot sl, TimeAxisView*, PBD::PropertyID) const; void mapover_tracks_with_unique_playlists (sigc::slot sl, TimeAxisView*, PBD::PropertyID) const; /* functions to be passed to mapover_tracks(), possibly with sigc::bind()-supplied arguments */ - void mapped_get_equivalent_regions (RouteTimeAxisView&, uint32_t, RegionView *, std::vector*) const; void mapped_use_new_playlist (RouteTimeAxisView&, uint32_t, std::vector > const &); void mapped_use_copy_playlist (RouteTimeAxisView&, uint32_t, std::vector > const &); void mapped_clear_playlist (RouteTimeAxisView&, uint32_t); - - /* end */ - + void mapped_get_equivalent_crossfades ( + RouteTimeAxisView&, uint32_t, boost::shared_ptr, std::vector >* + ) const; + void button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type); bool button_release_can_deselect; @@ -1895,8 +1898,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD ImageFrameSocketHandler* image_socket_listener ; #endif - void toggle_xfade_active (boost::weak_ptr); - void toggle_xfade_length (boost::weak_ptr); + void toggle_xfade_active (RouteTimeAxisView *, boost::weak_ptr); + void toggle_xfade_length (RouteTimeAxisView *, boost::weak_ptr); void edit_xfade (boost::weak_ptr); void xfade_edit_left_region (); void xfade_edit_right_region (); diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index 010984c26e..b99aa67ea5 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -27,6 +27,7 @@ #include "ardour/route_group.h" #include "ardour/profile.h" #include "ardour/midi_region.h" +#include "ardour/audioplaylist.h" #include "editor.h" #include "actions.h" @@ -35,6 +36,7 @@ #include "audio_streamview.h" #include "automation_line.h" #include "control_point.h" +#include "crossfade_view.h" #include "editor_regions.h" #include "editor_cursors.h" #include "midi_region_view.h" @@ -474,6 +476,32 @@ Editor::mapped_get_equivalent_regions (RouteTimeAxisView& tv, uint32_t, RegionVi } } +void +Editor::mapped_get_equivalent_crossfades ( + RouteTimeAxisView& tv, uint32_t, boost::shared_ptr basis, vector >* equivs + ) const +{ + boost::shared_ptr pl; + vector > results; + boost::shared_ptr tr; + + if ((tr = tv.track()) == 0) { + /* bus */ + return; + } + + if ((pl = tr->playlist()) != 0) { + boost::shared_ptr apl = boost::dynamic_pointer_cast (pl); + if (apl) { + apl->get_equivalent_crossfades (basis, *equivs); + } + } + + /* We might have just checked basis for equivalency with itself, so we need to remove dupes */ + sort (equivs->begin (), equivs->end ()); + unique (equivs->begin (), equivs->end ()); +} + void Editor::get_equivalent_regions (RegionView* basis, vector& equivalent_regions, PBD::PropertyID property) const { @@ -507,6 +535,18 @@ Editor::get_equivalent_regions (RegionSelection & basis, PBD::PropertyID prop) c return equivalent; } +vector > +Editor::get_equivalent_crossfades (RouteTimeAxisView& v, boost::shared_ptr c, PBD::PropertyID prop) const +{ + vector > e; + mapover_tracks_with_unique_playlists ( + sigc::bind (sigc::mem_fun (*this, &Editor::mapped_get_equivalent_crossfades), c, &e), + &v, + prop + ); + + return e; +} int Editor::get_regionview_count_from_region_list (boost::shared_ptr region) diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h index 5b1af2dc1f..fea70aade7 100644 --- a/libs/ardour/ardour/audioplaylist.h +++ b/libs/ardour/ardour/audioplaylist.h @@ -92,6 +92,7 @@ public: void update (const CrossfadeListProperty::ChangeRecord &); boost::shared_ptr find_crossfade (const PBD::ID &) const; + void get_equivalent_crossfades (boost::shared_ptr, std::vector > &); protected: diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index 56f2c4fe83..76d0228547 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -1194,3 +1194,13 @@ AudioPlaylist::pre_uncombine (vector >& originals, boo _session.add_command (new StatefulDiffCommand (*i)); } } + +void +AudioPlaylist::get_equivalent_crossfades (boost::shared_ptr c, vector > & results) +{ + for (list >::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) { + if ((*i)->equivalent (c)) { + results.push_back (*i); + } + } +}