playlist sort patch from nick_m, improves ordering of playlists in menu. small effect...
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 26 Jun 2009 17:43:38 +0000 (17:43 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 26 Jun 2009 17:43:38 +0000 (17:43 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@5284 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/route_time_axis.cc
gtk2_ardour/route_time_axis.h
libs/ardour/ardour/playlist.h
libs/ardour/location.cc
libs/ardour/playlist.cc

index e92960724985b957a31f938fb5b74e7848d68d64..63abdc2516d647dbf42ea4da4ca333d9b5cca1b4 100644 (file)
@@ -1354,6 +1354,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)
 {
@@ -1367,33 +1373,32 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
        menu->set_name ("ArdourContextMenu");
        playlist_items.clear();
 
-       if (playlist_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.get_playlists (playlists);
        
-       for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+       _session.get_playlists (playlists);
 
-               if ((*i)->get_orig_diskstream_id() == ds->id()) {
-                       playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist),
-                                                                                                    boost::weak_ptr<Playlist> (*i))));
+    /* 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());
 
-                       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(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), 
-                                                                                                    boost::weak_ptr<Playlist>(*i))));
-                       static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
-                       
+               item->signal_toggled().connect(bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), item, boost::weak_ptr<Playlist> (*i)));
+               
+               if (ds->playlist()->id() == (*i)->id()) {
+                       item->set_active();
                }
        }
 
@@ -1404,26 +1409,28 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
        if (!edit_group() || !edit_group()->is_active()) {
                playlist_items.push_back (MenuElem (_("New"), bind(mem_fun(editor, &PublicEditor::new_playlists), this)));
                playlist_items.push_back (MenuElem (_("New Copy"), bind(mem_fun(editor, &PublicEditor::copy_playlists), this)));
-
        } else {
                // Use a label which tells the user what is happening
                playlist_items.push_back (MenuElem (_("New Take"), bind(mem_fun(editor, &PublicEditor::new_playlists), this)));
                playlist_items.push_back (MenuElem (_("Copy Take"), bind(mem_fun(editor, &PublicEditor::copy_playlists), this)));
-               
        }
 
        playlist_items.push_back (SeparatorElem());
        playlist_items.push_back (MenuElem (_("Clear Current"), bind(mem_fun(editor, &PublicEditor::clear_playlists), this)));
        playlist_items.push_back (SeparatorElem());
-
        playlist_items.push_back (MenuElem(_("Select from all ..."), mem_fun(*this, &RouteTimeAxisView::show_playlist_selector)));
 }
 
 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) {
@@ -1434,13 +1441,13 @@ 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);
 
-
                if (edit_group() && edit_group()->is_active()) {
                        //PBD::stacktrace(cerr, 20);
                        std::string group_string = "."+edit_group()->name()+".";
index 75862965aba81b199a09ba39cf40f7314f8c26a9..2aa33c3cfa333e6067c0e8f13273a7c8977f58a5 100644 (file)
@@ -249,7 +249,7 @@ protected:
        Gtk::Menu*          playlist_action_menu;
        Gtk::MenuItem*      playlist_item;
 
-       void use_playlist (boost::weak_ptr<ARDOUR::Playlist>);
+       void use_playlist (Gtk::RadioMenuItem*, boost::weak_ptr<ARDOUR::Playlist>);
 
        ArdourCanvas::SimpleRect* timestretch_rect;
 
index 232c0c15d4ee8c466ce9ff9df3bbed14165f5a60..9e30130d756abc0e5a84496572bb1207c0a1e567 100644 (file)
@@ -68,6 +68,8 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
 
        std::string name() const { return _name; }
        void set_name (std::string str);
+       
+       int sort_id() { return _sort_id; }
 
        bool frozen() const { return _frozen; }
        void set_frozen (bool yn);
@@ -178,6 +180,7 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
        RegionList       regions;  /* the current list of regions in the playlist */
        std::set<boost::shared_ptr<Region> > all_regions; /* all regions ever added to this playlist */
        string          _name;
+       int             _sort_id;
        Session&        _session;
        mutable gint    block_notifications;
        mutable gint    ignore_state_changes;
@@ -221,6 +224,8 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
        void delay_notifications ();
        void release_notifications ();
        virtual void flush_notifications ();
+       
+       void _set_sort_id ();
 
        void notify_region_removed (boost::shared_ptr<Region>);
        void notify_region_added (boost::shared_ptr<Region>);
index 61471ee5b0ddccb63c51974002b3a3985f976154..103074511ce17aa97e03aa63f8e72993c6d0f64d 100644 (file)
@@ -377,7 +377,7 @@ Location::set_state (const XMLNode& node)
                */
                
        _start = atoi (prop->value().c_str());
-               
+
        if ((prop = node.property ("end")) == 0) {
                  error << _("XML node for Location has no end information") << endmsg; 
                  return -1;
index 9960074e9a7c6f7aa733daccf5d2c2b66c05f776..eae97e19df0431198da30a6052b2973d53c77ef7 100644 (file)
@@ -39,6 +39,8 @@
 #include <ardour/playlist_factory.h>
 #include <ardour/transient_detector.h>
 
+#include <boost/lexical_cast.hpp>
+
 #include "i18n.h"
 
 using namespace std;
@@ -78,7 +80,7 @@ Playlist::Playlist (Session& sess, string nom, bool hide)
        init (hide);
        first_set_state = false;
        _name = nom;
-       
+       _set_sort_id();
 }
 
 Playlist::Playlist (Session& sess, const XMLNode& node, bool hide)
@@ -86,6 +88,7 @@ Playlist::Playlist (Session& sess, const XMLNode& node, bool hide)
 {
        init (hide);
        _name = "unnamed"; /* reset by set_state */
+       _set_sort_id();
 
        /* set state called by derived class */
 }
@@ -269,6 +272,35 @@ Playlist::~Playlist ()
        /* GoingAway must be emitted by derived classes */
 }
 
+void
+Playlist::_set_sort_id ()
+{
+    /* 
+        Playlists are given names like <track name>.<id> 
+        or <track name>.<edit group name>.<id> where id 
+        is an integer. We extract the id and sort by that.
+    */
+
+    size_t dot_position = _name.find_last_of(".");
+    if (dot_position == string::npos)
+    {
+        _sort_id = 0;
+    }
+    else
+    {
+        string t = _name.substr(dot_position + 1);
+        
+        try
+        {
+            _sort_id = boost::lexical_cast<int>(t);
+        }
+        catch (boost::bad_lexical_cast e)
+        {
+            _sort_id = 0;
+        }
+    }
+}    
+
 void
 Playlist::set_name (string str)
 {
@@ -293,6 +325,8 @@ Playlist::set_name (string str)
        }
 
        _name = name; 
+       _set_sort_id();
+       
        NameChanged(); /* EMIT SIGNAL */
 }
 
@@ -1730,6 +1764,7 @@ Playlist::set_state (const XMLNode& node)
                
                if (prop->name() == X_("name")) {
                        _name = prop->value();
+                       _set_sort_id();
                } else if (prop->name() == X_("orig_diskstream_id")) {
                        _orig_diskstream_id = prop->value ();
                } else if (prop->name() == X_("frozen")) {