View Issue Details

IDProjectCategoryView StatusLast Update
0002600ardourfeaturespublic2020-04-19 20:13
Reporternickm Assigned Topaul  
PrioritynormalSeverityfeatureReproducibilityhave not tried
Status closedResolutionfixed 
Target Version3.0-beta1 
Summary0002600: [PATCH] Playlist sorting feature for 3.0
DescriptionThis patch sorts the popup playlist menu.

Playlists are sorted based on a number extracted from their name after the last period in the name.

If a playlist is called Audio1.1, the sort id will be 1.

If a playlist is called Audio1.2, the sort id will be 2.

This is a bit of a hack, but is very useful nonetheless.

The hack part is contained in Playlist::_set_sort_id()

Patch against rev 4096
TagsNo tags attached.

Relationships

related to 0002614 closedpaul [PATCH] Playlist sorting for 2.0-ongoing 

Activities

2009-03-26 18:54

 

3.0-4096-playlist-sort.patch (4,648 bytes)   
Index: gtk2_ardour/route_time_axis.cc
===================================================================
--- gtk2_ardour/route_time_axis.cc	(revision 4906)
+++ gtk2_ardour/route_time_axis.cc	(working copy)
@@ -1466,6 +1466,13 @@
 }
 
 
+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)
 {
@@ -1484,26 +1491,29 @@
 	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);
 	
+    /* 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()) {
-			playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (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(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), 
-												     boost::weak_ptr<Playlist>(*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(), bind (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();
-			
 		}
 	}
 
Index: libs/ardour/playlist.cc
===================================================================
--- libs/ardour/playlist.cc	(revision 4906)
+++ libs/ardour/playlist.cc	(working copy)
@@ -26,6 +26,7 @@
 #include <climits>
 
 #include <sigc++/bind.h>
+#include <boost/lexical_cast.hpp>
 
 #include "pbd/failed_constructor.h"
 #include "pbd/stl_delete.h"
@@ -80,7 +81,7 @@
 	init (hide);
 	first_set_state = false;
 	_name = nom;
-	
+	_set_sort_id();
 }
 
 Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide)
@@ -92,6 +93,7 @@
 
 	init (hide);
 	_name = "unnamed"; /* reset by set_state */
+	_set_sort_id();
 
 	/* set state called by derived class */
 }
@@ -263,6 +265,35 @@
 	/* 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;
+        }
+    }
+}
+
 bool
 Playlist::set_name (const string& str)
 {
@@ -1746,6 +1777,7 @@
 		
 		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")) {
Index: libs/ardour/ardour/playlist.h
===================================================================
--- libs/ardour/ardour/playlist.h	(revision 4906)
+++ libs/ardour/ardour/playlist.h	(working copy)
@@ -74,6 +74,7 @@
 	bool used () const { return _refcnt != 0; }
 
 	bool set_name (const string& str);
+	int sort_id() { return _sort_id; }
 
 	const DataType& data_type() const { return _type; }
 
@@ -282,6 +283,9 @@
 	void timestamp_layer_op (boost::shared_ptr<Region>);
 
 	void _split_region (boost::shared_ptr<Region>, nframes_t position);
+	
+	int _sort_id;
+	void _set_sort_id ();
 };
 
 } /* namespace ARDOUR */
3.0-4096-playlist-sort.patch (4,648 bytes)   

seablade

2009-04-06 23:32

manager   ~0005861

Assigned to Paul to take a look at the patch.

     Seablade

2009-04-07 22:08

 

3.0-4949-playlist-sort.patch (6,036 bytes)   
Index: gtk2_ardour/route_time_axis.h
===================================================================
--- gtk2_ardour/route_time_axis.h	(revision 4969)
+++ gtk2_ardour/route_time_axis.h	(working copy)
@@ -293,7 +293,7 @@
 	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*, boost::weak_ptr<ARDOUR::Playlist>);
 
 	ArdourCanvas::SimpleRect* timestretch_rect;
 
Index: gtk2_ardour/route_time_axis.cc
===================================================================
--- gtk2_ardour/route_time_axis.cc	(revision 4969)
+++ gtk2_ardour/route_time_axis.cc	(working copy)
@@ -1466,6 +1466,13 @@
 }
 
 
+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)
 {
@@ -1484,26 +1491,32 @@
 	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);
 	
+    /* 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 ((*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))));
-
-			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();
 		}
 	}
 
@@ -1530,9 +1543,14 @@
 }
 
 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());
 
@@ -1544,8 +1562,8 @@
 	
 	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);
Index: libs/ardour/ardour/playlist.h
===================================================================
--- libs/ardour/ardour/playlist.h	(revision 4969)
+++ libs/ardour/ardour/playlist.h	(working copy)
@@ -74,6 +74,7 @@
 	bool used () const { return _refcnt != 0; }
 
 	bool set_name (const string& str);
+	int sort_id() { return _sort_id; }
 
 	const DataType& data_type() const { return _type; }
 
@@ -282,6 +283,9 @@
 	void timestamp_layer_op (boost::shared_ptr<Region>);
 
 	void _split_region (boost::shared_ptr<Region>, nframes_t position);
+	
+	int _sort_id;
+	void _set_sort_id ();
 };
 
 } /* namespace ARDOUR */
Index: libs/ardour/playlist.cc
===================================================================
--- libs/ardour/playlist.cc	(revision 4969)
+++ libs/ardour/playlist.cc	(working copy)
@@ -26,6 +26,7 @@
 #include <climits>
 
 #include <sigc++/bind.h>
+#include <boost/lexical_cast.hpp>
 
 #include "pbd/failed_constructor.h"
 #include "pbd/stl_delete.h"
@@ -80,7 +81,7 @@
 	init (hide);
 	first_set_state = false;
 	_name = nom;
-	
+	_set_sort_id();
 }
 
 Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide)
@@ -92,6 +93,7 @@
 
 	init (hide);
 	_name = "unnamed"; /* reset by set_state */
+	_set_sort_id();
 
 	/* set state called by derived class */
 }
@@ -263,6 +265,35 @@
 	/* 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;
+        }
+    }
+}
+
 bool
 Playlist::set_name (const string& str)
 {
@@ -1746,6 +1777,7 @@
 		
 		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")) {
3.0-4949-playlist-sort.patch (6,036 bytes)   

nickm

2009-04-07 22:09

reporter   ~0005862

I've just added a new version of the patch against 4949 which avoids spurious calls to use_playlist which slow things down when using edit groups with large numbers of tracks. The 2.0 version of the patch (0002614) already has this change.

cth103

2010-07-25 23:23

administrator   ~0008642

This has been applied to SVN at some point in the past.

system

2020-04-19 20:13

developer   ~0021884

Issue has been closed automatically, by Trigger Close Plugin.
Feel free to re-open with additional information if you think the issue is not resolved.

Issue History

Date Modified Username Field Change
2009-03-26 18:54 nickm New Issue
2009-03-26 18:54 nickm File Added: 3.0-4096-playlist-sort.patch
2009-04-06 23:27 seablade Relationship added related to 0002614
2009-04-06 23:32 seablade Note Added: 0005861
2009-04-06 23:32 seablade Assigned To => paul
2009-04-06 23:32 seablade Status new => assigned
2009-04-07 22:08 nickm File Added: 3.0-4949-playlist-sort.patch
2009-04-07 22:09 nickm Note Added: 0005862
2010-07-21 15:45 cth103 cost => 0.00
2010-07-21 15:45 cth103 Target Version => 3.0-beta1
2010-07-25 23:23 cth103 Note Added: 0008642
2010-07-25 23:23 cth103 Status assigned => resolved
2010-07-25 23:23 cth103 Resolution open => fixed
2020-04-19 20:13 system Note Added: 0021884
2020-04-19 20:13 system Status resolved => closed