mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-06 14:52:34 +02:00
Clarify paste logic, throw to rollback on error, keep TimeTrack unique...
... though TimeTracks are not yet ever cut or copied; but next commit will change that.
This commit is contained in:
parent
608dcc9b3f
commit
ad34145ded
@ -4351,31 +4351,29 @@ void AudacityProject::OnPaste()
|
||||
if (c == NULL)
|
||||
return;
|
||||
Track *ff = NULL;
|
||||
const Track *tmpSrc = NULL;
|
||||
const Track *tmpC = NULL;
|
||||
const Track *prev = NULL;
|
||||
const Track *lastClipBeforeMismatch = NULL;
|
||||
const Track *mismatchedClip = NULL;
|
||||
const Track *prevClip = NULL;
|
||||
|
||||
bool bAdvanceClipboard = true;
|
||||
bool bPastedSomething = false;
|
||||
bool bTrackTypeMismatch = false;
|
||||
|
||||
while (n && c) {
|
||||
if (n->GetSelected()) {
|
||||
bAdvanceClipboard = true;
|
||||
if (tmpC)
|
||||
c = tmpC;
|
||||
if (mismatchedClip)
|
||||
c = mismatchedClip;
|
||||
if (c->GetKind() != n->GetKind()) {
|
||||
if (!bTrackTypeMismatch) {
|
||||
tmpSrc = prev;
|
||||
tmpC = c;
|
||||
if (!mismatchedClip) {
|
||||
lastClipBeforeMismatch = prevClip;
|
||||
mismatchedClip = c;
|
||||
}
|
||||
bTrackTypeMismatch = true;
|
||||
bAdvanceClipboard = false;
|
||||
c = tmpSrc;
|
||||
c = lastClipBeforeMismatch;
|
||||
|
||||
// If the types still don't match...
|
||||
while (c && c->GetKind() != n->GetKind()) {
|
||||
prev = c;
|
||||
prevClip = c;
|
||||
c = clipIter.Next();
|
||||
}
|
||||
}
|
||||
@ -4383,7 +4381,7 @@ void AudacityProject::OnPaste()
|
||||
// Handle case where the first track in clipboard
|
||||
// is of different type than the first selected track
|
||||
if (!c) {
|
||||
c = tmpC;
|
||||
c = mismatchedClip;
|
||||
while (n && (c->GetKind() != n->GetKind() || !n->GetSelected()))
|
||||
{
|
||||
// Must perform sync-lock adjustment before incrementing n
|
||||
@ -4399,39 +4397,40 @@ void AudacityProject::OnPaste()
|
||||
// The last possible case for cross-type pastes: triggered when we try to
|
||||
// paste 1+ tracks from one type into 1+ tracks of another type. If
|
||||
// there's a mix of types, this shouldn't run.
|
||||
if (!c) {
|
||||
wxMessageBox(
|
||||
_("Pasting one type of track into another is not allowed."),
|
||||
_("Error"), wxICON_ERROR, this);
|
||||
c = n;//so we don't trigger any !c conditions on our way out
|
||||
break;
|
||||
}
|
||||
if (!c)
|
||||
// Throw, so that any previous changes to the project in this loop
|
||||
// are discarded.
|
||||
throw SimpleMessageBoxException{
|
||||
_("Pasting one type of track into another is not allowed.")
|
||||
};
|
||||
|
||||
// When trying to copy from stereo to mono track, show error and exit
|
||||
// TODO: Automatically offer user to mix down to mono (unfortunately
|
||||
// this is not easy to implement
|
||||
if (c->GetLinked() && !n->GetLinked())
|
||||
{
|
||||
wxMessageBox(
|
||||
_("Copying stereo audio into a mono track is not allowed."),
|
||||
_("Error"), wxICON_ERROR, this);
|
||||
break;
|
||||
}
|
||||
// Throw, so that any previous changes to the project in this loop
|
||||
// are discarded.
|
||||
throw SimpleMessageBoxException{
|
||||
_("Copying stereo audio into a mono track is not allowed.")
|
||||
};
|
||||
|
||||
if (!ff)
|
||||
ff = n;
|
||||
|
||||
Maybe<WaveTrack::Locker> locker;
|
||||
if (msClipProject != this && c->GetKind() == Track::Wave)
|
||||
// Cause duplication of block files on disk, when copy is
|
||||
// between projects
|
||||
locker.create(static_cast<const WaveTrack*>(c));
|
||||
|
||||
if (c->GetKind() == Track::Wave && n && n->GetKind() == Track::Wave)
|
||||
wxASSERT( n && c );
|
||||
if (c->GetKind() == Track::Wave && n->GetKind() == Track::Wave)
|
||||
{
|
||||
bPastedSomething |=
|
||||
((WaveTrack*)n)->ClearAndPaste(t0, t1, (WaveTrack*)c, true, true);
|
||||
}
|
||||
else if (c->GetKind() == Track::Label &&
|
||||
n && n->GetKind() == Track::Label)
|
||||
n->GetKind() == Track::Label)
|
||||
{
|
||||
((LabelTrack *)n)->Clear(t0, t1);
|
||||
|
||||
@ -4444,6 +4443,7 @@ void AudacityProject::OnPaste()
|
||||
}
|
||||
else
|
||||
{
|
||||
n->Clear(t0, t1);
|
||||
bPastedSomething |= n->Paste(t0, c);
|
||||
}
|
||||
|
||||
@ -4464,7 +4464,7 @@ void AudacityProject::OnPaste()
|
||||
}
|
||||
|
||||
if (bAdvanceClipboard){
|
||||
prev = c;
|
||||
prevClip = c;
|
||||
c = clipIter.Next();
|
||||
}
|
||||
} // if (n->GetSelected())
|
||||
@ -4487,7 +4487,8 @@ void AudacityProject::OnPaste()
|
||||
|
||||
while (n) {
|
||||
if (n->GetSelected() && n->GetKind()==Track::Wave) {
|
||||
if (c && c->GetKind() == Track::Wave) {
|
||||
if (c) {
|
||||
wxASSERT(c->GetKind() == Track::Wave);
|
||||
bPastedSomething |=
|
||||
((WaveTrack *)n)->ClearAndPaste(t0, t1, (WaveTrack *)c, true, true);
|
||||
}
|
||||
@ -4598,29 +4599,40 @@ bool AudacityProject::HandlePasteNothingSelected()
|
||||
while (pClip) {
|
||||
Maybe<WaveTrack::Locker> locker;
|
||||
if ((msClipProject != this) && (pClip->GetKind() == Track::Wave))
|
||||
// Cause duplication of block files on disk, when copy is
|
||||
// between projects
|
||||
locker.create(static_cast<const WaveTrack*>(pClip));
|
||||
|
||||
Track::Holder pNewTrack;
|
||||
Track::Holder uNewTrack;
|
||||
Track *pNewTrack;
|
||||
switch (pClip->GetKind()) {
|
||||
case Track::Wave:
|
||||
{
|
||||
WaveTrack *w = (WaveTrack *)pClip;
|
||||
pNewTrack = mTrackFactory->NewWaveTrack(w->GetSampleFormat(), w->GetRate());
|
||||
uNewTrack = mTrackFactory->NewWaveTrack(w->GetSampleFormat(), w->GetRate()),
|
||||
pNewTrack = uNewTrack.get();
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef USE_MIDI
|
||||
case Track::Note:
|
||||
pNewTrack = mTrackFactory->NewNoteTrack();
|
||||
uNewTrack = mTrackFactory->NewNoteTrack(),
|
||||
pNewTrack = uNewTrack.get();
|
||||
break;
|
||||
#endif // USE_MIDI
|
||||
|
||||
case Track::Label:
|
||||
pNewTrack = mTrackFactory->NewLabelTrack();
|
||||
uNewTrack = mTrackFactory->NewLabelTrack(),
|
||||
pNewTrack = uNewTrack.get();
|
||||
break;
|
||||
case Track::Time:
|
||||
pNewTrack = mTrackFactory->NewTimeTrack();
|
||||
case Track::Time: {
|
||||
// Maintain uniqueness of the time track!
|
||||
pNewTrack = GetTracks()->GetTimeTrack();
|
||||
if (!pNewTrack)
|
||||
uNewTrack = mTrackFactory->NewTimeTrack(),
|
||||
pNewTrack = uNewTrack.get();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pClip = iterClip.Next();
|
||||
continue;
|
||||
@ -4632,10 +4644,13 @@ bool AudacityProject::HandlePasteNothingSelected()
|
||||
wxUnusedVar(bResult);
|
||||
|
||||
if (!pFirstNewTrack)
|
||||
pFirstNewTrack = pNewTrack.get();
|
||||
pFirstNewTrack = pNewTrack;
|
||||
|
||||
pNewTrack->SetSelected(true);
|
||||
FinishCopy(pClip, std::move(pNewTrack), *mTracks);
|
||||
if (uNewTrack)
|
||||
FinishCopy(pClip, std::move(uNewTrack), *mTracks);
|
||||
else
|
||||
FinishCopy(pClip, pNewTrack);
|
||||
|
||||
pClip = iterClip.Next();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user