Make crossfade convert-to-full and activate/deactivate work across edit groups (...
authorCarl Hetherington <carl@carlh.net>
Wed, 1 Feb 2012 01:07:52 +0000 (01:07 +0000)
committerCarl Hetherington <carl@carlh.net>
Wed, 1 Feb 2012 01:07:52 +0000 (01:07 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@11413 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_selection.cc
libs/ardour/ardour/audioplaylist.h
libs/ardour/audio_playlist.cc

index fd7be603cd71eb4f993a3f5ca7f3c6cad5ab6092..83ca9ee0e82e4ee725c8b881a8413a5737a4c45b 100644 (file)
@@ -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<Crossfade> xfade, Menu_Helpers::MenuList& edit_items, bool many)
+Editor::add_crossfade_context_items (AudioStreamView* view, boost::shared_ptr<Crossfade> 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<Crossfade> (xfade))));
-       items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun(*this, &Editor::edit_xfade), boost::weak_ptr<Crossfade> (xfade))));
+       items.push_back (
+               MenuElem (str, sigc::bind (sigc::mem_fun (*this, &Editor::toggle_xfade_active), &view->trackview(), boost::weak_ptr<Crossfade> (xfade)))
+               );
+       
+       items.push_back (
+               MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &Editor::edit_xfade), boost::weak_ptr<Crossfade> (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<Crossfade> wxfade)
+Editor::toggle_xfade_active (RouteTimeAxisView* tv, boost::weak_ptr<Crossfade> wxfade)
 {
        boost::shared_ptr<Crossfade> 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<boost::shared_ptr<Crossfade> > all = get_equivalent_crossfades (*tv, xfade, ARDOUR::Properties::edit.property_id);
+
+       _session->begin_reversible_command (_("Change crossfade active state"));
+       
+       for (vector<boost::shared_ptr<Crossfade> >::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<Crossfade> wxfade)
+Editor::toggle_xfade_length (RouteTimeAxisView* tv, boost::weak_ptr<Crossfade> wxfade)
 {
        boost::shared_ptr<Crossfade> xfade (wxfade.lock());
-       if (xfade) {
-               XMLNode& before = xfade->get_state ();
-               xfade->set_follow_overlap (!xfade->following_overlap());
-               XMLNode& after = xfade->get_state ();
+       if (!xfade) {
+               return;
+       }
+       
+       vector<boost::shared_ptr<Crossfade> > 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"));
-               _session->add_command (new MementoCommand<Crossfade> (*xfade.get(), &before, &after));
-               _session->commit_reversible_command ();
+       /* 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<boost::shared_ptr<Crossfade> >::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<Crossfade> (*i->get(), &before, &after));
        }
+       
+       _session->commit_reversible_command ();
 }
 
 void
index e0cbf8351706525246e5053edef6d349ae4a269a..7147b6378d12a4f36509570d57d0d26e9836eaf4 100644 (file)
@@ -630,18 +630,21 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
 
        void get_equivalent_regions (RegionView* rv, std::vector<RegionView*> &, PBD::PropertyID) const;
        RegionSelection get_equivalent_regions (RegionSelection &, PBD::PropertyID) const;
+       std::vector<boost::shared_ptr<ARDOUR::Crossfade> > get_equivalent_crossfades (
+               RouteTimeAxisView&, boost::shared_ptr<ARDOUR::Crossfade>, PBD::PropertyID
+               ) const;
        void mapover_tracks (sigc::slot<void,RouteTimeAxisView&,uint32_t> sl, TimeAxisView*, PBD::PropertyID) const;
        void mapover_tracks_with_unique_playlists (sigc::slot<void,RouteTimeAxisView&,uint32_t> 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<RegionView*>*) const;
        void mapped_use_new_playlist (RouteTimeAxisView&, uint32_t, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);
        void mapped_use_copy_playlist (RouteTimeAxisView&, uint32_t, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);
        void mapped_clear_playlist (RouteTimeAxisView&, uint32_t);
-
-       /* end */
-
+       void mapped_get_equivalent_crossfades (
+               RouteTimeAxisView&, uint32_t, boost::shared_ptr<ARDOUR::Crossfade>, std::vector<boost::shared_ptr<ARDOUR::Crossfade> >*
+               ) 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<ARDOUR::Crossfade>);
-       void toggle_xfade_length (boost::weak_ptr<ARDOUR::Crossfade>);
+       void toggle_xfade_active (RouteTimeAxisView *, boost::weak_ptr<ARDOUR::Crossfade>);
+       void toggle_xfade_length (RouteTimeAxisView *, boost::weak_ptr<ARDOUR::Crossfade>);
        void edit_xfade (boost::weak_ptr<ARDOUR::Crossfade>);
        void xfade_edit_left_region ();
        void xfade_edit_right_region ();
index 010984c26e42544d2eafbafbf8fbeb3a5f5cd196..b99aa67ea547afcb9a4a15d094a096052cdcd2d4 100644 (file)
@@ -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<Crossfade> basis, vector<boost::shared_ptr<Crossfade> >* equivs
+       ) const
+{
+       boost::shared_ptr<Playlist> pl;
+       vector<boost::shared_ptr<Crossfade> > results;
+       boost::shared_ptr<Track> tr;
+
+       if ((tr = tv.track()) == 0) {
+               /* bus */
+               return;
+       }
+
+       if ((pl = tr->playlist()) != 0) {
+               boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist> (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<RegionView*>& equivalent_regions, PBD::PropertyID property) const
 {
@@ -507,6 +535,18 @@ Editor::get_equivalent_regions (RegionSelection & basis, PBD::PropertyID prop) c
        return equivalent;
 }
 
+vector<boost::shared_ptr<Crossfade> >
+Editor::get_equivalent_crossfades (RouteTimeAxisView& v, boost::shared_ptr<Crossfade> c, PBD::PropertyID prop) const
+{
+       vector<boost::shared_ptr<Crossfade> > 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> region)
index 5b1af2dc1ff2e86e08b4e073fea6d74f8e937a08..fea70aade7dae16782d9a2e93eafe7ef0cccc324 100644 (file)
@@ -92,6 +92,7 @@ public:
        void update (const CrossfadeListProperty::ChangeRecord &);
 
        boost::shared_ptr<Crossfade> find_crossfade (const PBD::ID &) const;
+       void get_equivalent_crossfades (boost::shared_ptr<Crossfade>, std::vector<boost::shared_ptr<Crossfade> > &);
 
 protected:
 
index 56f2c4fe83bf3a0cd0c76eda6d1be3da3d427b30..76d0228547d01f1aae99a151cda1976cc61636c2 100644 (file)
@@ -1194,3 +1194,13 @@ AudioPlaylist::pre_uncombine (vector<boost::shared_ptr<Region> >& originals, boo
                _session.add_command (new StatefulDiffCommand (*i));
        }
 }
+
+void
+AudioPlaylist::get_equivalent_crossfades (boost::shared_ptr<Crossfade> c, vector<boost::shared_ptr<Crossfade> > & results)
+{
+       for (list<boost::shared_ptr<Crossfade> >::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
+               if ((*i)->equivalent (c)) {
+                       results.push_back (*i);
+               }
+       }
+}