diff --git a/src/Menus.cpp b/src/Menus.cpp index 649fd0366..242ac1734 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -2398,7 +2398,7 @@ void AudacityProject::OnToogleAutomatedInputLevelAdjustment() } #endif -double AudacityProject::GetTime(Track *t) +double AudacityProject::GetTime(const Track *t) { double stime = 0.0; @@ -2428,43 +2428,46 @@ double AudacityProject::GetTime(Track *t) //sort based on flags. see Project.h for sort flags void AudacityProject::SortTracks(int flags) { - int ndx = 0; + size_t ndx = 0; int cmpValue; - wxArrayPtrVoid arr; - TrackListIterator iter(mTracks); - Track *track = iter.First(); + std::vector arr; + arr.reserve(mTracks->GetCount()); bool lastTrackLinked = false; //sort by linked tracks. Assumes linked track follows owner in list. - while (track) { + + // First find the permutation. + for (auto iter = mTracks->begin(), end = mTracks->end(); iter != end; ++iter) { + const auto &track = *iter; if(lastTrackLinked) { //insert after the last track since this track should be linked to it. ndx++; } else { - for (ndx = 0; ndx < (int)arr.GetCount(); ndx++) { - if(flags & kAudacitySortByName){ + for (ndx = 0; ndx < arr.size(); ++ndx) { + Track &arrTrack = **arr[ndx]; + if(flags & kAudacitySortByName) { //do case insensitive sort - cmpNoCase returns less than zero if the string is 'less than' its argument //also if we have case insensitive equality, then we need to sort by case as well //We sort 'b' before 'B' accordingly. We uncharacteristically use greater than for the case sensitive //compare because 'b' is greater than 'B' in ascii. - cmpValue = track->GetName().CmpNoCase(((Track *) arr[ndx])->GetName()); + cmpValue = track->GetName().CmpNoCase(arrTrack.GetName()); if (cmpValue < 0 || - (0 == cmpValue && track->GetName().CompareTo(((Track *) arr[ndx])->GetName()) > 0) ) + (0 == cmpValue && track->GetName().CompareTo(arrTrack.GetName()) > 0) ) break; } //sort by time otherwise - else if(flags & kAudacitySortByTime){ + else if(flags & kAudacitySortByTime) { //we have to search each track and all its linked ones to fine the minimum start time. - double time1,time2,tempTime; - Track* tempTrack; - int candidatesLookedAt; + double time1, time2, tempTime; + const Track* tempTrack; + size_t candidatesLookedAt; candidatesLookedAt = 0; - tempTrack = track; - time1=time2=std::numeric_limits::max(); //TODO: find max time value. (I don't think we have one yet) - while(tempTrack){ + tempTrack = &*track; + time1 = time2 = std::numeric_limits::max(); //TODO: find max time value. (I don't think we have one yet) + while(tempTrack) { tempTime = GetTime(tempTrack); - time1 = time1GetLinked()) tempTrack = tempTrack->GetLink(); else @@ -2472,13 +2475,13 @@ void AudacityProject::SortTracks(int flags) } //get candidate's (from sorted array) time - tempTrack = (Track *) arr[ndx]; - while(tempTrack){ + tempTrack = &arrTrack; + while(tempTrack) { tempTime = GetTime(tempTrack); - time2 = time2GetLinked() && (ndx+candidatesLookedAt < (int)arr.GetCount()-1) ) { + time2 = std::min(time2, tempTime); + if(tempTrack->GetLinked() && (ndx+candidatesLookedAt < arr.size()-1) ) { candidatesLookedAt++; - tempTrack = (Track*) arr[ndx+candidatesLookedAt]; + tempTrack = &**arr[ndx+candidatesLookedAt]; } else tempTrack = NULL; @@ -2491,15 +2494,13 @@ void AudacityProject::SortTracks(int flags) } } } - arr.Insert(track, ndx); + arr.insert(arr.begin() + ndx, iter); lastTrackLinked = track->GetLinked(); - track = iter.RemoveCurrent(); } - for (ndx = 0; ndx < (int)arr.GetCount(); ndx++) { - mTracks->Add((Track *)arr[ndx]); - } + // Now apply the permutation + mTracks->Permute(arr); } void AudacityProject::OnSortTime() diff --git a/src/Menus.h b/src/Menus.h index ae0aaa66d..f8cc32084 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -170,7 +170,7 @@ void OnZeroCrossing(); void OnLockPlayRegion(); void OnUnlockPlayRegion(); -double GetTime(Track *t); +double GetTime(const Track *t); void OnSortTime(); void OnSortName(); diff --git a/src/Track.cpp b/src/Track.cpp index 6f1304b68..f9d2ee467 100644 --- a/src/Track.cpp +++ b/src/Track.cpp @@ -851,6 +851,19 @@ void TrackList::ResizedEvent(TrackNodePointer node) } } +void TrackList::Permute(const std::vector &permutation) +{ + for (const auto iter : permutation) { + Track *track = *iter; + erase(iter); + track->SetOwner(this, insert(end(), track)); + } + auto n = begin(); + RecalcPositions(n); + UpdatedEvent(n); + ResizedEvent(n); +} + void TrackList::Add(Track * t) { push_back(t); diff --git a/src/Track.h b/src/Track.h index 326fa4f28..e041ac9df 100644 --- a/src/Track.h +++ b/src/Track.h @@ -423,6 +423,9 @@ class AUDACITY_DLL_API TrackList final : public wxEvtHandler, public ListOfTrack friend class TrackListIterator; friend class SyncLockedTracksIterator; + /// For use in sorting: assume each iterator points into this list, no duplications + void Permute(const std::vector &permutation); + /// Add this Track or all children of this TrackList. void Add(Track * t); void AddToHead(Track * t);