View Issue Details

IDProjectCategoryView StatusLast Update
0005914ardourfeaturespublic2014-04-21 08:59
Reportersalvois Assigned To 
PrioritynormalSeverityfeatureReproducibilityhave not tried
Status newResolutionopen 
Product Version3.0 
Summary0005914: Exclode "whole file regions" from cleanup unused sources
DescriptionCurrently the "cleanup unused sources" function removes from the region list even the "whole file" regions (the ones shown in blue and acting as collapsible tree nodes). This way, the region list quickly becomes cluttered when there are many child regions, for example after splitting and quantizing a drums audio file. It would be useful that after a "cleanup unused sources" the tree nodes are retained for grouping purposes. Thank you.
TagsNo tags attached.

Activities

2014-04-20 20:38

 

cleanupregions.diff (2,182 bytes)   
diff --git a/gtk2_ardour/editor_regions.cc b/gtk2_ardour/editor_regions.cc
index 69620d4..939d04a 100644
--- a/gtk2_ardour/editor_regions.cc
+++ b/gtk2_ardour/editor_regions.cc
@@ -457,14 +457,16 @@ EditorRegions::remove_unused_regions ()
 	prompt  = _("Do you really want to remove unused regions?"
 		    "\n(This is destructive and cannot be undone)");
 
-	choices.push_back (_("No, do nothing."));
-	choices.push_back (_("Yes, remove."));
+	choices.push_back (_("Do nothing."));
+	choices.push_back (_("Remove all."));
+	choices.push_back (_("Remove if not whole file."));
 
 	Gtkmm2ext::Choice prompter (_("Remove unused regions"), prompt, choices);
 
-	if (prompter.run () == 1) {
+    int response_id = prompter.run();
+	if (response_id > 0) {
 		_no_redisplay = true;
-		_session->cleanup_regions ();
+		_session->cleanup_regions (response_id == 2);
 		_no_redisplay = false;
 		redisplay ();
 	}
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 38185a7..5c188e5 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -549,7 +549,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 	void add_source (boost::shared_ptr<Source>);
 	void remove_source (boost::weak_ptr<Source>);
 
-	void  cleanup_regions();
+	void  cleanup_regions(bool keep_whole_files);
 	int  cleanup_sources (CleanupReport&);
 	int  cleanup_trash_sources (CleanupReport&);
 
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index ffbe55a..14364d3 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -2557,7 +2557,7 @@ Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
 }
 
 void
-Session::cleanup_regions ()
+Session::cleanup_regions (bool keep_whole_files)
 {
 	const RegionFactory::RegionMap& regions (RegionFactory::regions());
 
@@ -2565,7 +2565,7 @@ Session::cleanup_regions ()
 
 		uint32_t used = playlists->region_use_count (i->second);
 
-		if (used == 0 && !i->second->automatic ()) {
+		if (used == 0 && !i->second->automatic () && !(keep_whole_files && i->second->whole_file())) {
 			RegionFactory::map_remove (i->second);
 		}
 	}
cleanupregions.diff (2,182 bytes)   

salvois

2014-04-20 20:39

reporter   ~0015758

Patch attached. Added an option to keep whole file regions in "Cleanup unused regions". Thanks to rgareus for his help. Please feel free to change or adapt the patch.

2014-04-21 08:58

 

cleanupregions_nochildren.diff (4,108 bytes)   
diff --git a/gtk2_ardour/editor_regions.cc b/gtk2_ardour/editor_regions.cc
index 69620d4..939d04a 100644
--- a/gtk2_ardour/editor_regions.cc
+++ b/gtk2_ardour/editor_regions.cc
@@ -457,14 +457,16 @@ EditorRegions::remove_unused_regions ()
 	prompt  = _("Do you really want to remove unused regions?"
 		    "\n(This is destructive and cannot be undone)");
 
-	choices.push_back (_("No, do nothing."));
-	choices.push_back (_("Yes, remove."));
+	choices.push_back (_("Do nothing."));
+	choices.push_back (_("Remove all."));
+	choices.push_back (_("Remove if not whole file."));
 
 	Gtkmm2ext::Choice prompter (_("Remove unused regions"), prompt, choices);
 
-	if (prompter.run () == 1) {
+    int response_id = prompter.run();
+	if (response_id > 0) {
 		_no_redisplay = true;
-		_session->cleanup_regions ();
+		_session->cleanup_regions (response_id == 2);
 		_no_redisplay = false;
 		redisplay ();
 	}
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 38185a7..03f43ac 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -524,6 +524,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
 	/* region info  */
 
+	bool has_children (boost::shared_ptr<Region const> parent) const;
 	boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>) const;
 
 	std::string path_from_region_name (DataType type, std::string name, std::string identifier);
@@ -549,7 +550,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 	void add_source (boost::shared_ptr<Source>);
 	void remove_source (boost::weak_ptr<Source>);
 
-	void  cleanup_regions();
+	void  cleanup_regions(bool keep_whole_files);
 	int  cleanup_sources (CleanupReport&);
 	int  cleanup_trash_sources (CleanupReport&);
 
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 1de5730..4c28751 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -3122,6 +3122,31 @@ Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ran
 
 /* Region management */
 
+bool
+Session::has_children (boost::shared_ptr<Region const> parent) const
+{
+	assert(parent->whole_file());
+	const RegionFactory::RegionMap& regions (RegionFactory::regions());
+	RegionFactory::RegionMap::const_iterator i;
+	boost::shared_ptr<Region> region;
+
+	Glib::Threads::Mutex::Lock lm (region_lock);
+
+	for (i = regions.begin(); i != regions.end(); ++i) {
+
+		region = i->second;
+
+		if (!region->whole_file()) {
+
+			if (parent->source_equivalent (region)) {
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 boost::shared_ptr<Region>
 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
 {
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index ffbe55a..e02a70f 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -2557,18 +2557,30 @@ Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
 }
 
 void
-Session::cleanup_regions ()
+Session::cleanup_regions (bool keep_whole_files)
 {
 	const RegionFactory::RegionMap& regions (RegionFactory::regions());
 
+	/* First pass: cleanup non-whole-file regions (or everything, is keep_whole_files == false) */
 	for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
 
 		uint32_t used = playlists->region_use_count (i->second);
 
-		if (used == 0 && !i->second->automatic ()) {
+		if (used == 0 && !i->second->automatic () && !(keep_whole_files && i->second->whole_file())) {
 			RegionFactory::map_remove (i->second);
 		}
 	}
+	if (keep_whole_files) {
+		/* Second pass: cleanup whole-file regions that have no children */
+		for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+
+			uint32_t used = playlists->region_use_count (i->second);
+
+			if (used == 0 && !i->second->automatic () && i->second->whole_file() && !has_children(i->second)) {
+				RegionFactory::map_remove (i->second);
+			}
+		}
+	}
 
 	/* dump the history list */
 	_history.clear ();
cleanupregions_nochildren.diff (4,108 bytes)   

salvois

2014-04-21 08:59

reporter   ~0015759

I've uploaded a new version of the patch. Now when cleaning up unused regions, under the option of keeping whole file regions, whole file regions are kept only if they have instantiated child regions.

Issue History

Date Modified Username Field Change
2014-04-19 11:04 salvois New Issue
2014-04-20 20:38 salvois File Added: cleanupregions.diff
2014-04-20 20:39 salvois Note Added: 0015758
2014-04-21 08:58 salvois File Added: cleanupregions_nochildren.diff
2014-04-21 08:59 salvois Note Added: 0015759