mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-17 17:17:40 +02:00
Remove old iterators, type tests, GetLink(ed) from Track's interface
This commit is contained in:
commit
b0c5f42b9a
@ -5478,20 +5478,10 @@ void MenuCommandHandler::OnRedo(const CommandContext &context)
|
||||
ModifyUndoMenuItems(project);
|
||||
}
|
||||
|
||||
void MenuCommandHandler::FinishCopy
|
||||
(const Track *n, Track *dest)
|
||||
{
|
||||
if (dest) {
|
||||
dest->SetChannel(n->GetChannel());
|
||||
dest->SetLinked(n->GetLinked());
|
||||
dest->SetName(n->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
void MenuCommandHandler::FinishCopy
|
||||
(const Track *n, Track::Holder &&dest, TrackList &list)
|
||||
{
|
||||
FinishCopy( n, dest.get() );
|
||||
Track::FinishCopy( n, dest.get() );
|
||||
if (dest)
|
||||
list.Add(std::move(dest));
|
||||
}
|
||||
@ -6037,7 +6027,7 @@ bool MenuCommandHandler::HandlePasteNothingSelected(AudacityProject &project)
|
||||
if (uNewTrack)
|
||||
FinishCopy(pClip, std::move(uNewTrack), *tracks);
|
||||
else
|
||||
FinishCopy(pClip, pNewTrack);
|
||||
Track::FinishCopy(pClip, pNewTrack);
|
||||
}
|
||||
|
||||
// Select some pasted samples, which is probably impossible to get right
|
||||
|
@ -270,10 +270,7 @@ void OnExit(const CommandContext &context );
|
||||
void OnUndo(const CommandContext &context );
|
||||
void OnRedo(const CommandContext &context );
|
||||
|
||||
static void FinishCopy(const Track *n, Track *dest);
|
||||
static void FinishCopy
|
||||
(const Track *n, Track::Holder &&dest, TrackList &list);
|
||||
|
||||
static void FinishCopy(const Track *n, Track::Holder &&dest, TrackList &list);
|
||||
|
||||
void OnCut(const CommandContext &context );
|
||||
void OnSplitCut(const CommandContext &context );
|
||||
|
@ -235,10 +235,10 @@ class AUDACITY_DLL_API NoteTrack final
|
||||
mVisibleChannels = CHANNEL_BIT(c);
|
||||
}
|
||||
|
||||
TrackKind GetKind() const override { return TrackKind::Note; }
|
||||
|
||||
private:
|
||||
|
||||
TrackKind GetKind() const override { return TrackKind::Note; }
|
||||
|
||||
void AddToDuration( double delta );
|
||||
|
||||
// These are mutable to allow NoteTrack to switch details of representation
|
||||
|
@ -3138,46 +3138,7 @@ void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory)
|
||||
err = true;
|
||||
}
|
||||
|
||||
// Sanity checks for linked tracks; unsetting the linked property
|
||||
// doesn't fix the problem, but it likely leaves us with orphaned
|
||||
// blockfiles instead of much worse problems.
|
||||
if (t->GetLinked())
|
||||
{
|
||||
Track *l = t->GetLink();
|
||||
if (l)
|
||||
{
|
||||
// A linked track's partner should never itself be linked
|
||||
if (l->GetLinked())
|
||||
{
|
||||
wxLogWarning(
|
||||
wxT("Left track %s had linked right track %s with extra right track link.\n Removing extra link from right track."),
|
||||
t->GetName(), l->GetName());
|
||||
err = true;
|
||||
l->SetLinked(false);
|
||||
}
|
||||
|
||||
// Channels should be left and right
|
||||
if ( !( (t->GetChannel() == Track::LeftChannel &&
|
||||
l->GetChannel() == Track::RightChannel) ||
|
||||
(t->GetChannel() == Track::RightChannel &&
|
||||
l->GetChannel() == Track::LeftChannel) ) )
|
||||
{
|
||||
wxLogWarning(
|
||||
wxT("Track %s and %s had left/right track links out of order. Setting tracks to not be linked."),
|
||||
t->GetName(), l->GetName());
|
||||
err = true;
|
||||
t->SetLinked(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogWarning(
|
||||
wxT("Track %s had link to NULL track. Setting it to not be linked."),
|
||||
t->GetName());
|
||||
err = true;
|
||||
t->SetLinked(false);
|
||||
}
|
||||
}
|
||||
err = ( !t->LinkConsistencyCheck() ) || err;
|
||||
|
||||
mLastSavedTracks->Add(t->Duplicate());
|
||||
}
|
||||
@ -5222,7 +5183,7 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action )
|
||||
auto dest = ( wt->*action )( region.start, region.end );
|
||||
if( dest )
|
||||
{
|
||||
MenuCommandHandler::FinishCopy( wt, dest.get() );
|
||||
Track::FinishCopy( wt, dest.get() );
|
||||
if( !merged )
|
||||
merged = std::move(dest);
|
||||
else
|
||||
|
357
src/Track.cpp
357
src/Track.cpp
@ -46,12 +46,6 @@ and TimeTrack.
|
||||
#pragma warning( disable : 4786 )
|
||||
#endif
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
// if we are in a debug build of audacity
|
||||
/// Define this to do extended (slow) debuging of TrackListIterator
|
||||
// #define DEBUG_TLI
|
||||
#endif
|
||||
|
||||
Track::Track(const std::shared_ptr<DirManager> &projDirManager)
|
||||
: vrulerSize(36,0),
|
||||
mDirManager(projDirManager)
|
||||
@ -414,318 +408,61 @@ bool Track::IsLeader() const
|
||||
bool Track::IsSelectedLeader() const
|
||||
{ return IsSelected() && IsLeader(); }
|
||||
|
||||
// TrackListIterator
|
||||
TrackListIterator::TrackListIterator(TrackList * val, TrackNodePointer p)
|
||||
: l{ val }
|
||||
, cur{ p }
|
||||
void Track::FinishCopy
|
||||
(const Track *n, Track *dest)
|
||||
{
|
||||
}
|
||||
|
||||
TrackListIterator::TrackListIterator(TrackList * val)
|
||||
: l{ val }
|
||||
, cur{}
|
||||
{
|
||||
if (l)
|
||||
cur = l->getBegin();
|
||||
}
|
||||
|
||||
Track *TrackListIterator::StartWith(Track * val)
|
||||
{
|
||||
if (val == NULL) {
|
||||
return First();
|
||||
if (dest) {
|
||||
dest->SetChannel(n->GetChannel());
|
||||
dest->SetLinked(n->GetLinked());
|
||||
dest->SetName(n->GetName());
|
||||
}
|
||||
|
||||
if (l == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (val->mList.lock() == NULL)
|
||||
return nullptr;
|
||||
|
||||
cur = val->GetNode();
|
||||
return cur.first->get();
|
||||
}
|
||||
|
||||
Track *TrackListIterator::First(TrackList * val)
|
||||
bool Track::LinkConsistencyCheck()
|
||||
{
|
||||
if (val != NULL) {
|
||||
l = val;
|
||||
}
|
||||
|
||||
if (l == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cur = l->getBegin();
|
||||
|
||||
if (!l->isNull(cur)) {
|
||||
return cur.first->get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Track *TrackListIterator::Last()
|
||||
{
|
||||
if (l == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cur = l->getPrev( l->getEnd() );
|
||||
if ( l->isNull( cur ) )
|
||||
return nullptr;
|
||||
|
||||
return cur.first->get();
|
||||
}
|
||||
|
||||
Track *TrackListIterator::Next()
|
||||
{
|
||||
#ifdef DEBUG_TLI // if we are debugging this bit
|
||||
wxASSERT_MSG((!cur || (*l).Contains((*cur).t)), wxT("cur invalid at start of Next(). List changed since iterator created?")); // check that cur is in the list
|
||||
#endif
|
||||
|
||||
if (!l || l->isNull(cur))
|
||||
return nullptr;
|
||||
|
||||
cur = l->getNext( cur );
|
||||
|
||||
#ifdef DEBUG_TLI // if we are debugging this bit
|
||||
wxASSERT_MSG((!cur || (*l).Contains((*cur).t)), wxT("cur invalid after moving to next track.")); // check that cur is in the list if it is not null
|
||||
#endif
|
||||
|
||||
if (!l->isNull(cur))
|
||||
return cur.first->get();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Track *TrackListIterator::Prev()
|
||||
{
|
||||
if (!l || l->isNull(cur))
|
||||
return nullptr;
|
||||
|
||||
cur = l->getPrev( cur );
|
||||
if ( l->isNull( cur ) )
|
||||
return nullptr;
|
||||
|
||||
return cur.first->get();
|
||||
}
|
||||
|
||||
Track *TrackListIterator::operator *() const
|
||||
{
|
||||
if ( !l || l->isNull( cur ) )
|
||||
return nullptr;
|
||||
else
|
||||
return cur.first->get();
|
||||
}
|
||||
|
||||
bool TrackListIterator::operator == (const TrackListIterator &other) const
|
||||
{
|
||||
// Order these steps so as not to use operator == on default-constructed
|
||||
// std::list::iterator -- that crashes in the MSVC 2013 standard library
|
||||
bool isEnd = !l || l->isNull( cur );
|
||||
bool otherIsEnd = !other.l || other.l->isNull( other.cur );
|
||||
|
||||
return (isEnd == otherIsEnd && (isEnd || cur == other.cur));
|
||||
}
|
||||
|
||||
//
|
||||
// TrackListCondIterator (base class for iterators that iterate over all tracks
|
||||
// that meet a condition)
|
||||
//
|
||||
|
||||
Track *TrackListCondIterator::StartWith(Track *val)
|
||||
{
|
||||
Track *t = TrackListIterator::StartWith(val);
|
||||
|
||||
if (t && !this->Condition(t))
|
||||
return nullptr;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
Track *TrackListCondIterator::First(TrackList *val)
|
||||
{
|
||||
Track *t = TrackListIterator::First(val);
|
||||
|
||||
while (t && !this->Condition(t)) {
|
||||
t = TrackListIterator::Next();
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
Track *TrackListCondIterator::Next()
|
||||
{
|
||||
while (Track *t = TrackListIterator::Next()) {
|
||||
if (this->Condition(t)) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Track *TrackListCondIterator::Prev()
|
||||
{
|
||||
while (Track *t = TrackListIterator::Prev())
|
||||
// Sanity checks for linked tracks; unsetting the linked property
|
||||
// doesn't fix the problem, but it likely leaves us with orphaned
|
||||
// blockfiles instead of much worse problems.
|
||||
bool err = false;
|
||||
if (GetLinked())
|
||||
{
|
||||
if (this->Condition(t)) {
|
||||
return t;
|
||||
Track *l = GetLink();
|
||||
if (l)
|
||||
{
|
||||
// A linked track's partner should never itself be linked
|
||||
if (l->GetLinked())
|
||||
{
|
||||
wxLogWarning(
|
||||
wxT("Left track %s had linked right track %s with extra right track link.\n Removing extra link from right track."),
|
||||
GetName().c_str(), l->GetName());
|
||||
err = true;
|
||||
l->SetLinked(false);
|
||||
}
|
||||
|
||||
// Channels should be left and right
|
||||
if ( !( (GetChannel() == Track::LeftChannel &&
|
||||
l->GetChannel() == Track::RightChannel) ||
|
||||
(GetChannel() == Track::RightChannel &&
|
||||
l->GetChannel() == Track::LeftChannel) ) )
|
||||
{
|
||||
wxLogWarning(
|
||||
wxT("Track %s and %s had left/right track links out of order. Setting tracks to not be linked."),
|
||||
GetName(), l->GetName());
|
||||
err = true;
|
||||
SetLinked(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogWarning(
|
||||
wxT("Track %s had link to NULL track. Setting it to not be linked."),
|
||||
GetName());
|
||||
err = true;
|
||||
SetLinked(false);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Track *TrackListCondIterator::Last()
|
||||
{
|
||||
Track *t = TrackListIterator::Last();
|
||||
|
||||
while (t && !this->Condition(t)) {
|
||||
t = TrackListIterator::Prev();
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// TrackListOfKindIterator
|
||||
TrackListOfKindIterator::TrackListOfKindIterator(TrackKind kind, TrackList * val)
|
||||
: TrackListCondIterator(val)
|
||||
{
|
||||
this->kind = kind;
|
||||
}
|
||||
|
||||
bool TrackListOfKindIterator::Condition(Track *t)
|
||||
{
|
||||
return kind == Track::All || t->GetKind() == kind;
|
||||
}
|
||||
|
||||
//SelectedTrackListOfKindIterator
|
||||
bool SelectedTrackListOfKindIterator::Condition(Track *t)
|
||||
{
|
||||
return TrackListOfKindIterator::Condition(t) && t->GetSelected();
|
||||
}
|
||||
|
||||
// SyncLockedTracksIterator
|
||||
//
|
||||
// Based on TrackListIterator returns only tracks belonging to the group
|
||||
// in which the starting track is a member.
|
||||
//
|
||||
SyncLockedTracksIterator::SyncLockedTracksIterator(TrackList * val)
|
||||
: TrackListIterator(val),
|
||||
mInLabelSection(false)
|
||||
{
|
||||
}
|
||||
|
||||
Track *SyncLockedTracksIterator::StartWith(Track * member)
|
||||
{
|
||||
Track *t = NULL;
|
||||
|
||||
// A sync-locked group consists of any positive number of wave (or note)
|
||||
// tracks followed by any
|
||||
// non-negative number of label tracks. Step back through any label tracks,
|
||||
// and then through the wave tracks above them.
|
||||
|
||||
while (member && member->GetKind() == Track::Label) {
|
||||
member = l->GetPrev(member);
|
||||
}
|
||||
|
||||
while (member && IsSyncLockableNonLabelTrack(member)) {
|
||||
t = member;
|
||||
member = l->GetPrev(member);
|
||||
}
|
||||
|
||||
// Make it current (if t is still NULL there are no wave tracks, so we're
|
||||
// not in a sync-locked group).
|
||||
if (t)
|
||||
cur = t->GetNode();
|
||||
|
||||
mInLabelSection = false;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
bool SyncLockedTracksIterator::IsGoodNextTrack(const Track *t) const
|
||||
{
|
||||
if (!t)
|
||||
return false;
|
||||
|
||||
const bool isLabel = ( t->GetKind() == Track::Label );
|
||||
const bool isSyncLockable = IsSyncLockableNonLabelTrack( t );
|
||||
|
||||
if ( !( isLabel || isSyncLockable ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mInLabelSection && !isLabel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Track *SyncLockedTracksIterator::Next()
|
||||
{
|
||||
Track *t = TrackListIterator::Next();
|
||||
|
||||
if (!t)
|
||||
return nullptr;
|
||||
|
||||
if ( ! IsGoodNextTrack(t) ) {
|
||||
cur = l->getEnd();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mInLabelSection = ( t->GetKind() == Track::Label );
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
Track *SyncLockedTracksIterator::Prev()
|
||||
{
|
||||
Track *t = TrackListIterator::Prev();
|
||||
|
||||
//
|
||||
// Ways to end a sync-locked group in reverse
|
||||
//
|
||||
|
||||
// Beginning of tracks
|
||||
if (!t)
|
||||
return nullptr;
|
||||
|
||||
const bool isLabel = ( t->GetKind() == Track::Label );
|
||||
const bool isSyncLockable = IsSyncLockableNonLabelTrack( t );
|
||||
|
||||
if ( !( isLabel || isSyncLockable ) ) {
|
||||
cur = l->getEnd();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( !mInLabelSection && isLabel ) {
|
||||
cur = l->getEnd();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mInLabelSection = isLabel;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
Track *SyncLockedTracksIterator::Last()
|
||||
{
|
||||
if ( !l || l->isNull( cur ) )
|
||||
return nullptr;
|
||||
|
||||
Track *t = cur.first->get();
|
||||
|
||||
while (const auto next = l->GetNext(t)) {
|
||||
if ( ! IsGoodNextTrack(next) )
|
||||
break;
|
||||
t = Next();
|
||||
}
|
||||
|
||||
return t;
|
||||
return ! err;
|
||||
}
|
||||
|
||||
std::pair<Track *, Track *> TrackList::FindSyncLockGroup(Track *pMember) const
|
||||
@ -844,7 +581,7 @@ void TrackList::RecalcPositions(TrackNodePointer node)
|
||||
}
|
||||
|
||||
const auto theEnd = end();
|
||||
for (auto n = TrackListIterator{ this, node }; n != theEnd; ++n) {
|
||||
for (auto n = Find( node.first->get() ); n != theEnd; ++n) {
|
||||
t = *n;
|
||||
t->SetIndex(i++);
|
||||
t->DoSetY(y);
|
||||
|
216
src/Track.h
216
src/Track.h
@ -191,8 +191,6 @@ class AUDACITY_DLL_API Track /* not final */
|
||||
: public CommonTrackPanelCell, public XMLTagHandler
|
||||
{
|
||||
friend class TrackList;
|
||||
friend class TrackListIterator;
|
||||
friend class SyncLockedTracksIterator;
|
||||
|
||||
// To be TrackDisplay
|
||||
private:
|
||||
@ -317,13 +315,24 @@ public:
|
||||
void SetMinimized(bool isMinimized);
|
||||
protected:
|
||||
virtual void DoSetMinimized(bool isMinimized);
|
||||
public:
|
||||
|
||||
Track *GetLink() const;
|
||||
public:
|
||||
static void FinishCopy (const Track *n, Track *dest);
|
||||
|
||||
// For use when loading a file. Return true if ok, else make repair
|
||||
bool LinkConsistencyCheck();
|
||||
|
||||
private:
|
||||
std::shared_ptr<TrackList> GetOwner() const { return mList.lock(); }
|
||||
|
||||
Track *GetLink() const;
|
||||
bool GetLinked () const { return mLinked; }
|
||||
public:
|
||||
void SetLinked (bool l);
|
||||
private:
|
||||
// No need yet to make this virtual
|
||||
void DoSetLinked(bool l);
|
||||
|
||||
TrackNodePointer GetNode() const;
|
||||
void SetOwner
|
||||
(const std::weak_ptr<TrackList> &list, TrackNodePointer node);
|
||||
@ -360,13 +369,9 @@ private:
|
||||
void SetDefaultName( const wxString &n ) { mDefaultName = n; }
|
||||
|
||||
bool GetSelected() const { return mSelected; }
|
||||
|
||||
virtual void SetSelected(bool s);
|
||||
|
||||
bool GetLinked () const { return mLinked; }
|
||||
void SetLinked (bool l);
|
||||
private:
|
||||
// No need yet to make this virtual
|
||||
void DoSetLinked(bool l);
|
||||
public:
|
||||
|
||||
virtual ChannelType GetChannel() const { return mChannel;}
|
||||
@ -413,20 +418,9 @@ public:
|
||||
// May assume precondition: t0 <= t1
|
||||
virtual void InsertSilence(double WXUNUSED(t), double WXUNUSED(len)) = 0;
|
||||
|
||||
// to do: privatize this
|
||||
private:
|
||||
virtual TrackKind GetKind() const { return TrackKind::None; }
|
||||
|
||||
// to do: remove these
|
||||
static const TrackKind Label = TrackKind::Label;
|
||||
#ifdef USE_MIDI
|
||||
static const TrackKind Note = TrackKind::Note;
|
||||
#endif
|
||||
static const TrackKind Wave = TrackKind::Wave;
|
||||
static const TrackKind Time = TrackKind::Time;
|
||||
static const TrackKind All = TrackKind::All;
|
||||
static const TrackKind None = TrackKind::None;
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
friend typename std::enable_if< std::is_pointer<T>::value, T >::type
|
||||
track_cast(Track *track);
|
||||
@ -437,7 +431,6 @@ private:
|
||||
T
|
||||
>::type
|
||||
track_cast(const Track *track);
|
||||
friend class TrackListOfKindIterator;
|
||||
|
||||
public:
|
||||
bool SameKindAs(const Track &track) const
|
||||
@ -1079,170 +1072,6 @@ template <
|
||||
}
|
||||
};
|
||||
|
||||
class AUDACITY_DLL_API TrackListIterator /* not final */
|
||||
: public std::iterator< std::forward_iterator_tag, Track *const >
|
||||
{
|
||||
public:
|
||||
// The default-constructed value can serve as the end iterator for
|
||||
// traversal over any track list.
|
||||
TrackListIterator() {}
|
||||
explicit TrackListIterator(TrackList * val);
|
||||
explicit TrackListIterator(TrackList * val, TrackNodePointer p);
|
||||
TrackListIterator(const TrackListIterator&) = default;
|
||||
TrackListIterator& operator=(const TrackListIterator&) = default;
|
||||
virtual ~TrackListIterator() {}
|
||||
|
||||
// Iterate functions
|
||||
virtual Track *First(TrackList * val = nullptr);
|
||||
virtual Track *StartWith(Track * val);
|
||||
virtual Track *Next();
|
||||
virtual Track *Prev();
|
||||
virtual Track *Last();
|
||||
|
||||
// Provide minimal STL forward-iterator idiom:
|
||||
|
||||
// unlike Next, this is non-mutating.
|
||||
// An end iterator may be safely dereferenced, returning nullptr.
|
||||
Track *operator * () const;
|
||||
|
||||
TrackListIterator &operator++ () { (void) Next(); return *this; }
|
||||
TrackListIterator operator++ (int)
|
||||
{ auto copy = *this; operator++(); return copy; }
|
||||
|
||||
bool operator == (const TrackListIterator &other) const;
|
||||
bool operator != (const TrackListIterator &other) const
|
||||
{ return !(*this == other); }
|
||||
|
||||
protected:
|
||||
friend TrackList;
|
||||
|
||||
TrackList *l {};
|
||||
TrackNodePointer cur{};
|
||||
};
|
||||
|
||||
class AUDACITY_DLL_API TrackListConstIterator
|
||||
: public std::iterator< std::forward_iterator_tag, const Track *const >
|
||||
{
|
||||
public:
|
||||
// The default-constructed value can serve as the end iterator for
|
||||
// traversal over any track list.
|
||||
TrackListConstIterator() {}
|
||||
explicit TrackListConstIterator(
|
||||
const TrackList * val, TrackNodePointer p)
|
||||
: mIter(const_cast<TrackList*>(val), p)
|
||||
{}
|
||||
explicit TrackListConstIterator(
|
||||
const TrackList * val)
|
||||
: mIter(const_cast<TrackList*>(val))
|
||||
{}
|
||||
TrackListConstIterator(const TrackListConstIterator&) = default;
|
||||
TrackListConstIterator& operator=(const TrackListConstIterator&) = default;
|
||||
~TrackListConstIterator() {}
|
||||
|
||||
// Iterate functions
|
||||
const Track *First(const TrackList * val = NULL)
|
||||
{ return mIter.First(const_cast<TrackList*>(val)); }
|
||||
const Track *StartWith(const Track * val)
|
||||
{ return mIter.StartWith(const_cast<Track*>(val)); }
|
||||
const Track *Next()
|
||||
{ return mIter.Next(); }
|
||||
const Track *Prev()
|
||||
{ return mIter.Prev(); }
|
||||
const Track *Last()
|
||||
{ return mIter.Last(); }
|
||||
|
||||
// Provide minimal STL forward-iterator idiom:
|
||||
|
||||
// unlike Next, this is non-mutating.
|
||||
// An end iterator may be safely dereferenced, returning nullptr.
|
||||
const Track *operator * () const { return *mIter; }
|
||||
|
||||
TrackListConstIterator &operator++ () { (void) Next(); return *this; }
|
||||
TrackListConstIterator operator++ (int)
|
||||
{ auto copy = *this; operator++(); return copy; }
|
||||
|
||||
bool operator == (const TrackListConstIterator &other) const
|
||||
{ return mIter == other.mIter; }
|
||||
bool operator != (const TrackListConstIterator &other) const
|
||||
{ return !(*this == other); }
|
||||
|
||||
private:
|
||||
TrackListIterator mIter;
|
||||
};
|
||||
|
||||
// TrackListCondIterator (base class for iterators that iterate over all tracks)
|
||||
// that meet a condition)
|
||||
class AUDACITY_DLL_API TrackListCondIterator /* not final */ : public TrackListIterator
|
||||
{
|
||||
public:
|
||||
TrackListCondIterator(TrackList *val = NULL)
|
||||
: TrackListIterator(val) {}
|
||||
virtual ~TrackListCondIterator() {}
|
||||
|
||||
// Iteration functions
|
||||
Track *First(TrackList *val = NULL) override;
|
||||
Track *StartWith(Track *val) override;
|
||||
Track *Next() override;
|
||||
Track *Prev() override;
|
||||
Track *Last() override;
|
||||
|
||||
protected:
|
||||
// NEW virtual
|
||||
virtual bool Condition(Track *t) = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// TrackListOfKindIterator
|
||||
//
|
||||
// Based on TrackListIterator and returns only tracks of the specified type.
|
||||
//
|
||||
class AUDACITY_DLL_API TrackListOfKindIterator /* not final */ : public TrackListCondIterator
|
||||
{
|
||||
public:
|
||||
TrackListOfKindIterator(TrackKind kind, TrackList * val = nullptr);
|
||||
virtual ~TrackListOfKindIterator() {}
|
||||
|
||||
protected:
|
||||
virtual bool Condition(Track *t) override;
|
||||
|
||||
private:
|
||||
TrackKind kind;
|
||||
};
|
||||
|
||||
//
|
||||
// SelectedTrackListOfKindIterator
|
||||
//
|
||||
// Based on TrackListOfKindIterator and returns only tracks selected.
|
||||
//
|
||||
class AUDACITY_DLL_API SelectedTrackListOfKindIterator final : public TrackListOfKindIterator
|
||||
{
|
||||
public:
|
||||
SelectedTrackListOfKindIterator(TrackKind kind, TrackList * val = NULL) : TrackListOfKindIterator(kind, val) {}
|
||||
virtual ~SelectedTrackListOfKindIterator() {}
|
||||
|
||||
protected:
|
||||
bool Condition(Track *t) override;
|
||||
};
|
||||
|
||||
// SyncLockedTracksIterator returns only tracks belonging to the sync-locked tracks
|
||||
// in which the starting track is a member.
|
||||
class AUDACITY_DLL_API SyncLockedTracksIterator final : public TrackListIterator
|
||||
{
|
||||
public:
|
||||
SyncLockedTracksIterator(TrackList * val);
|
||||
virtual ~SyncLockedTracksIterator() {}
|
||||
|
||||
// Iterate functions
|
||||
Track *StartWith(Track *member) override;
|
||||
Track *Next() override;
|
||||
Track *Prev() override;
|
||||
Track *Last() override;
|
||||
|
||||
private:
|
||||
bool IsGoodNextTrack(const Track *t) const;
|
||||
bool mInLabelSection;
|
||||
};
|
||||
|
||||
|
||||
/** \brief TrackList is a flat linked list of tracks supporting Add, Remove,
|
||||
* Clear, and Contains, plus serialization of the list of tracks.
|
||||
@ -1305,14 +1134,13 @@ class TrackList final : public wxEvtHandler, public ListOfTracks
|
||||
// Iteration
|
||||
|
||||
// Hide the inherited begin() and end()
|
||||
using iterator = TrackListIterator;
|
||||
using const_iterator = TrackListConstIterator;
|
||||
using iterator = TrackIter<Track>;
|
||||
using const_iterator = TrackIter<const Track>;
|
||||
using value_type = Track *;
|
||||
iterator begin() { return iterator{
|
||||
this, { ListOfTracks::begin(), this } }; }
|
||||
iterator end() { return {}; }
|
||||
const_iterator begin() const { return const_iterator{ this }; }
|
||||
const_iterator end() const { return {}; }
|
||||
iterator begin() { return Any().begin(); }
|
||||
iterator end() { return Any().end(); }
|
||||
const_iterator begin() const { return Any().begin(); }
|
||||
const_iterator end() const { return Any().end(); }
|
||||
const_iterator cbegin() const { return begin(); }
|
||||
const_iterator cend() const { return end(); }
|
||||
|
||||
@ -1472,8 +1300,6 @@ public:
|
||||
}
|
||||
|
||||
friend class Track;
|
||||
friend class TrackListIterator;
|
||||
friend class SyncLockedTracksIterator;
|
||||
|
||||
/// For use in sorting: assume each iterator points into this list, no duplications
|
||||
void Permute(const std::vector<TrackNodePointer> &permutation);
|
||||
|
@ -89,11 +89,6 @@ subset of the TrackPanel methods from all over the place.
|
||||
|
||||
*//**************************************************************//**
|
||||
|
||||
\class TrackListIterator
|
||||
\brief An iterator for a TrackList.
|
||||
|
||||
*//**************************************************************//**
|
||||
|
||||
\class TrackListNode
|
||||
\brief Used by TrackList, points to a Track.
|
||||
|
||||
|
@ -640,12 +640,10 @@ private:
|
||||
// Protected methods
|
||||
//
|
||||
|
||||
public:
|
||||
// to do: privatize this
|
||||
TrackKind GetKind() const override { return TrackKind::Wave; }
|
||||
|
||||
private:
|
||||
|
||||
TrackKind GetKind() const override { return TrackKind::Wave; }
|
||||
|
||||
//
|
||||
// Private variables
|
||||
//
|
||||
|
@ -57,8 +57,7 @@ UIHandlePtr NoteTrackButtonHandle::HitTest
|
||||
TrackInfo::GetMidiControlsRect(rect, midiRect);
|
||||
if ( TrackInfo::HideTopItem( rect, midiRect ) )
|
||||
return {};
|
||||
if (pTrack->GetKind() == Track::Note &&
|
||||
midiRect.Contains(state.m_x, state.m_y)) {
|
||||
if (midiRect.Contains(state.m_x, state.m_y)) {
|
||||
auto channel = pTrack->FindChannel(midiRect, state.m_x, state.m_y);
|
||||
auto result = std::make_shared<NoteTrackButtonHandle>(
|
||||
pTrack, channel, midiRect );
|
||||
|
@ -111,7 +111,6 @@ void NoteTrackMenuTable::OnChangeOctave(wxCommandEvent &event)
|
||||
|
||||
wxASSERT(event.GetId() == OnUpOctaveID
|
||||
|| event.GetId() == OnDownOctaveID);
|
||||
wxASSERT(pTrack->GetKind() == Track::Note);
|
||||
|
||||
const bool bDown = (OnDownOctaveID == event.GetId());
|
||||
pTrack->SetBottomNote
|
||||
|
@ -64,10 +64,10 @@ unsigned NoteTrackVRulerControls::HandleWheelRotation
|
||||
const auto pTrack = FindTrack();
|
||||
if (!pTrack)
|
||||
return RefreshNone;
|
||||
wxASSERT(pTrack->GetKind() == Track::Note);
|
||||
auto steps = evt.steps;
|
||||
|
||||
auto steps = evt.steps;
|
||||
const auto nt = static_cast<NoteTrack*>(pTrack.get());
|
||||
|
||||
if (event.CmdDown() && !event.ShiftDown()) {
|
||||
if (steps > 0)
|
||||
nt->ZoomIn(evt.rect, evt.event.m_y);
|
||||
|
@ -76,7 +76,7 @@ UIHandlePtr StretchHandle::HitTest
|
||||
// within the selection
|
||||
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
|
||||
if (!pTrack || !pTrack->GetSelected() || pTrack->GetKind() != Track::Note)
|
||||
if (!pTrack || !pTrack->GetSelected())
|
||||
return {};
|
||||
|
||||
const wxRect &rect = st.rect;
|
||||
|
@ -104,12 +104,9 @@ UIHandlePtr CutlineHandle::HitTest
|
||||
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
/// method that tells us if the mouse event landed on an
|
||||
/// editable Cutline
|
||||
if (pTrack->GetKind() != Track::Wave)
|
||||
return {};
|
||||
|
||||
WaveTrack *wavetrack = pTrack.get();
|
||||
WaveTrackLocation location;
|
||||
if (!IsOverCutline(viewInfo, wavetrack, rect, state, &location))
|
||||
if (!IsOverCutline(viewInfo, pTrack.get(), rect, state, &location))
|
||||
return {};
|
||||
|
||||
auto result = std::make_shared<CutlineHandle>( pTrack, location );
|
||||
|
@ -115,7 +115,9 @@ UIHandlePtr SampleHandle::HitTest
|
||||
{
|
||||
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
|
||||
WaveTrack *wavetrack = pTrack.get();
|
||||
/// method that tells us if the mouse event landed on an
|
||||
/// editable sample
|
||||
const auto wavetrack = pTrack.get();
|
||||
|
||||
const int displayType = wavetrack->GetDisplay();
|
||||
if (WaveTrack::Waveform != displayType)
|
||||
@ -173,12 +175,8 @@ namespace {
|
||||
/// @return true if we can edit the samples, false otherwise.
|
||||
bool IsSampleEditingPossible
|
||||
(const wxMouseEvent &event,
|
||||
const wxRect &rect, const ViewInfo &viewInfo, Track *pTrack, int width)
|
||||
const wxRect &rect, const ViewInfo &viewInfo, WaveTrack *wt, int width)
|
||||
{
|
||||
if (pTrack->GetKind() != Track::Wave)
|
||||
return false;
|
||||
WaveTrack *wt = static_cast<WaveTrack*>(pTrack);
|
||||
|
||||
//Get out of here if we shouldn't be drawing right now:
|
||||
//If we aren't displaying the waveform, Display a message dialog
|
||||
const int display = wt->GetDisplay();
|
||||
|
@ -207,8 +207,7 @@ void WaveColorMenuTable::OnWaveColorChange(wxCommandEvent & event)
|
||||
{
|
||||
int id = event.GetId();
|
||||
wxASSERT(id >= OnInstrument1ID && id <= OnInstrument4ID);
|
||||
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
wxASSERT(pTrack && pTrack->GetKind() == Track::Wave);
|
||||
const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
|
||||
int newWaveColor = id - OnInstrument1ID;
|
||||
|
||||
@ -307,8 +306,7 @@ void FormatMenuTable::OnFormatChange(wxCommandEvent & event)
|
||||
{
|
||||
int id = event.GetId();
|
||||
wxASSERT(id >= On16BitID && id <= OnFloatID);
|
||||
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
wxASSERT(pTrack && pTrack->GetKind() == Track::Wave);
|
||||
const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
|
||||
sampleFormat newFormat = int16Sample;
|
||||
|
||||
@ -448,8 +446,7 @@ void RateMenuTable::OnRateChange(wxCommandEvent & event)
|
||||
{
|
||||
int id = event.GetId();
|
||||
wxASSERT(id >= OnRate8ID && id <= OnRate384ID);
|
||||
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
wxASSERT(pTrack->GetKind() == Track::Wave);
|
||||
const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
|
||||
SetRate(pTrack, gRates[id - OnRate8ID]);
|
||||
|
||||
@ -459,8 +456,7 @@ void RateMenuTable::OnRateChange(wxCommandEvent & event)
|
||||
|
||||
void RateMenuTable::OnRateOther(wxCommandEvent &)
|
||||
{
|
||||
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
wxASSERT(pTrack && pTrack->GetKind() == Track::Wave);
|
||||
const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
|
||||
int newRate;
|
||||
|
||||
@ -710,8 +706,7 @@ void WaveTrackMenuTable::OnSetDisplay(wxCommandEvent & event)
|
||||
{
|
||||
int idInt = event.GetId();
|
||||
wxASSERT(idInt >= OnWaveformID && idInt <= OnSpectrumID);
|
||||
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
wxASSERT(pTrack && pTrack->GetKind() == Track::Wave);
|
||||
const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
|
||||
bool linear = false;
|
||||
WaveTrack::WaveTrackDisplay id;
|
||||
|
@ -54,7 +54,6 @@ void WaveTrackVRulerControls::DoZoomPreset( int i)
|
||||
const auto pTrack = FindTrack();
|
||||
if (!pTrack)
|
||||
return;
|
||||
wxASSERT(pTrack->GetKind() == Track::Wave);
|
||||
|
||||
const auto wt = static_cast<WaveTrack*>(pTrack.get());
|
||||
|
||||
@ -84,10 +83,9 @@ unsigned WaveTrackVRulerControls::HandleWheelRotation
|
||||
const auto pTrack = FindTrack();
|
||||
if (!pTrack)
|
||||
return RefreshNone;
|
||||
wxASSERT(pTrack->GetKind() == Track::Wave);
|
||||
const auto wt = static_cast<WaveTrack*>(pTrack.get());
|
||||
auto steps = evt.steps;
|
||||
|
||||
WaveTrack *const wt = static_cast<WaveTrack*>(pTrack.get());
|
||||
const bool isDB =
|
||||
wt->GetDisplay() == WaveTrack::Waveform &&
|
||||
wt->GetWaveformSettings().scaleType == WaveformSettings::stLogarithmic;
|
||||
|
Loading…
x
Reference in New Issue
Block a user