Update of /cvsroot/audacity/audacity-src/src
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv20133

Modified Files:
        LabelTrack.cpp LabelTrack.h Menus.cpp WaveClip.cpp WaveClip.h 
        WaveTrack.cpp 
Log Message:
Al Dimond's patch for Repeating Labels with track linking on, covering some 
other bugs as well.

Index: WaveClip.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/WaveClip.cpp,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- WaveClip.cpp        9 Oct 2009 14:28:48 -0000       1.57
+++ WaveClip.cpp        18 Oct 2009 19:58:17 -0000      1.58
@@ -308,6 +308,7 @@
    mAppendBuffer = NULL;
    mAppendBufferLen = 0;
    mDirty = 0;
+   mIsPlaceholder = false;
 }
 
 WaveClip::WaveClip(WaveClip& orig, DirManager *projDirManager)
@@ -339,6 +340,7 @@
    mAppendBuffer = NULL;
    mAppendBufferLen = 0;
    mDirty = 0;
+   mIsPlaceholder = orig.GetIsPlaceholder();
 }
 
 WaveClip::~WaveClip()

Index: LabelTrack.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/LabelTrack.h,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- LabelTrack.h        12 Sep 2009 06:05:41 -0000      1.51
+++ LabelTrack.h        18 Oct 2009 19:58:17 -0000      1.52
@@ -117,6 +117,7 @@
    virtual bool Copy (double t0, double t1, Track ** dest);// const;
    virtual bool Clear(double t0, double t1);
    virtual bool Paste(double t, Track * src);
+   bool Repeat(double t0, double t1, int n);
 
    virtual bool Silence(double t0, double t1);
    virtual bool InsertSilence(double t, double len);

Index: WaveClip.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/WaveClip.h,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- WaveClip.h  9 Oct 2009 14:28:48 -0000       1.40
+++ WaveClip.h  18 Oct 2009 19:58:17 -0000      1.41
@@ -213,6 +213,10 @@
    // Cache of values to colour pixels of Spectrogram - used by TrackArtist
    SpecPxCache    *mSpecPxCache;
 
+   // AWD, Oct 2009: for pasting whitespace at the end of selection
+   bool GetIsPlaceholder() { return mIsPlaceholder; };
+   void SetIsPlaceholder(bool val) { mIsPlaceholder = val; };
+
 protected:
    wxRect mDisplayRect;
 
@@ -239,6 +243,9 @@
    // Cut Lines are nothing more than ordinary wave clips, with the
    // offset relative to the start of the clip.
    WaveClipList mCutLines;
+
+   // AWD, Oct. 2009: for whitespace-at-end-of-selection pasting
+   bool mIsPlaceholder;
 };
 
 #endif

Index: LabelTrack.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/LabelTrack.cpp,v
retrieving revision 1.118
retrieving revision 1.119
diff -u -d -r1.118 -r1.119
--- LabelTrack.cpp      29 Sep 2009 00:28:07 -0000      1.118
+++ LabelTrack.cpp      18 Oct 2009 19:58:16 -0000      1.119
@@ -278,14 +278,14 @@
 {
    for (unsigned int i=0;i<mLabels.GetCount();i++){
       // label is after the insert point
-      if (mLabels[i]->t > pt) {
+      if (mLabels[i]->t >= pt) {
          mLabels[i]->t = mLabels[i]->t + length;
          mLabels[i]->t1 = mLabels[i]->t1 + length;
       // label is before the insert point
-      }else if (mLabels[i]->t1 < pt) {
+      }else if (mLabels[i]->t1 <= pt) {
          //nothing
       // insert point is inside the label
-      }else if (mLabels[i]->t < pt && mLabels[i]->t1 > pt){
+      }else{
          mLabels[i]->t1 = mLabels[i]->t1 + length;
       }
    }
@@ -2176,6 +2176,54 @@
    return true;
 }
 
+// This repeats the labels in a time interval a specified number of times.
+// Like Paste(), it does not shift existing labels over
+//  - It assumes that you've already called ShiftLabelsOnInsert(), because
+//  sometimes with linking enabled that's hard to avoid.
+//  - It assumes that you inserted the necessary extra time at t1, not t0.
+bool LabelTrack::Repeat(double t0, double t1, int n)
+{
+   // Sanity-check the arguments
+   if (n < 0 || t1 < t0) return false;
+
+   double tLen = t1 - t0;
+
+   for (unsigned int i = 0; i < mLabels.GetCount(); i++)
+   {
+      if (mLabels[i]->t >= t0 && mLabels[i]->t <= t1 &&
+            mLabels[i]->t1 >= t0 && mLabels[i]->t1 <= t1)
+      {
+         // Label is completely inside the selection; duplicate it in each
+         // repeat interval
+         unsigned int pos = i; // running label insertion position in mLabels
+
+         for (int j = 1; j <= n; j++)
+         {
+            LabelStruct *l = new LabelStruct();
+            l->t = mLabels[i]->t + j * tLen;
+            l->t1 = mLabels[i]->t1 + j * tLen;
+            l->title = mLabels[i]->title;
+
+            // Figure out where to insert
+            while (pos < mLabels.Count() && mLabels[pos]->t < l->t)
+               pos++;
+            mLabels.Insert(l, pos);
+         }
+      }
+      else if (mLabels[i]->t < t0 &&
+            mLabels[i]->t1 >= t0 && mLabels[i]->t1 <= t1)
+      {
+         // Label ends inside the selection; ShiftLabelsOnInsert() hasn't 
touched
+         // it, and we need to extend it through to the last repeat interval
+         mLabels[i]->t1 += n * tLen;
+      }
+      
+      // Other cases have already been handled by ShiftLabelsOnInsert()
+   }
+
+   return true;
+}
+
 bool LabelTrack::Clear(double t0, double t1)
 {
    AudacityProject *p = GetActiveProject();   

Index: WaveTrack.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/WaveTrack.cpp,v
retrieving revision 1.169
retrieving revision 1.170
diff -u -d -r1.169 -r1.170
--- WaveTrack.cpp       11 Oct 2009 14:55:47 -0000      1.169
+++ WaveTrack.cpp       18 Oct 2009 19:58:17 -0000      1.170
@@ -438,6 +438,25 @@
          }
       }
    }
+   
+   // AWD, Oct 2009: If the selection ends in whitespace, create a placeholder
+   // clip representing that whitespace
+   if (newTrack->GetEndTime() + 1.0 / newTrack->GetRate() < t1 - t0)
+   {
+      WaveClip *placeholder = new WaveClip(mDirManager,
+            newTrack->GetSampleFormat(), newTrack->GetRate());
+      placeholder->SetIsPlaceholder(true);
+      if ( ! placeholder->InsertSilence(
+               0, (t1 - t0) - newTrack->GetEndTime()) )
+      {
+         delete placeholder;
+      }
+      else
+      {
+         placeholder->Offset(newTrack->GetEndTime());
+         newTrack->mClips.Append(placeholder);
+      }
+   }
 
    *dest = newTrack;
 
@@ -518,7 +537,10 @@
 
    // If duration is 0, then it's just a plain paste
    if (dur == 0.0) {
-      return Paste(t0, src, tracks, relativeLabels);
+      if (useHandlePaste)
+         return HandlePaste(t0, src);
+      else
+         return Paste(t0, src, tracks, relativeLabels);
    }
 
    // If provided time warper was NULL, use a default one that does nothing
@@ -863,38 +885,74 @@
       // the present track is in a project with groups but doesn't belong to 
any of them
       return HandlePaste(t0, src);
 
+   // False return from this function causes its changes to not be pushed to
+   // the undo stack.  So we paste into this track first, so any failure
+   // (usually from "clips can't move" mode) comes before other changes.
+   // Failures to paste to the group tracks should not cause this function to
+   // return false; the result might be OK with the user, and if not he can
+   // easily undo it
+   if (!HandlePaste(t0, src))
+   {
+      return false;
+   }
+
    for( ; t; t = it.Next() ) {
       if (t->GetKind() == Track::Wave) {
+         WaveTrack *wt = (WaveTrack *)t;
          if (t==this) {
-            //paste in the track
-            if ( !( ((WaveTrack *)t)->HandlePaste(t0, src)) ) return false;
+            // This track has already been pasted; if it's a stereo track skip
+            // over the other channel as well.
             if (t->GetLinked()) t=it.Next();
          }
          else {
             if (! (t->GetSelected()) ) {
                if ( sel_len > length )
-                  // if selection is bigger than the content to add then we 
need to clear the extra length in the group tracks
-                  ((WaveTrack*)t)->HandleClear(t0+length, t0+sel_len, false, 
false);
+                  // if selection is bigger than the content to add then we
+                  // need to clear the extra length in the group tracks
+                  wt->HandleClear(t0+length, t0+sel_len, false, false);
                else if (sel_len < length) {               
-                  // if selection is smaller than the content to add then we 
need to add extra silence in the group tracks
-                  TrackFactory *factory = p->GetTrackFactory();
-                  WaveTrack *tmp = factory->NewWaveTrack( 
((WaveTrack*)t)->GetSampleFormat(), ((WaveTrack*)t)->GetRate());
-                  tmp->InsertSilence(0.0, length-sel_len);
-                  tmp->Flush();
-                  if ( !( ((WaveTrack *)t)->HandlePaste(t0+sel_len, tmp)) ) 
return false;
+                  // if selection is smaller than the content to add then we
+                  // need to add extra space in the group tracks. If the track
+                  // is empty at this point insert whitespace; otherwise,
+                  // silence
+                  if (wt->IsEmpty(t0+sel_len, t0+sel_len))
+                  {
+                     // Have to check if clips can move in this case
+                     bool clipsCanMove = true;
+                     gPrefs->Read(wxT("/GUI/EditClipCanMove"), &clipsCanMove);
+                     if (clipsCanMove)
+                     {
+                        Track *tmp = NULL;
+                        wt->Cut(t0 + sel_len,
+                              wt->GetEndTime()+1.0/wt->GetRate(), &tmp, false);
+                        wt->HandlePaste(t0 + length, tmp);
+                        delete tmp;
+                     }
+                  }
+                  else
+                  {
+                     TrackFactory *factory = p->GetTrackFactory();
+                     WaveTrack *tmp = factory->NewWaveTrack( 
wt->GetSampleFormat(), wt->GetRate());
+                     tmp->InsertSilence(0.0, length-sel_len);
+                     tmp->Flush();
+                     wt->HandlePaste(t0+sel_len, tmp);
+                  }
                }
             }
          }
       }
       else if (t->GetKind() == Track::Label) {
          LabelTrack *lt = (LabelTrack *)t;
-         if (relativeLabels && (sel_len != 0.0))
-            lt->ScaleLabels(info->sel0, info->sel1, length/sel_len);
-         else {
-            if ((length - sel_len) > 0.0)
-               lt->ShiftLabelsOnInsert(length-sel_len, t0);
-            else if ((length - sel_len) < 0.0)
-               lt->ShiftLabelsOnClear(info->sel0+length, info->sel1);
+         if (!t->GetSelected())
+         {
+            if (relativeLabels && (sel_len != 0.0))
+               lt->ScaleLabels(info->sel0, info->sel1, length/sel_len);
+            else {
+               if ((length - sel_len) > 0.0)
+                  lt->ShiftLabelsOnInsert(length-sel_len, t0);
+               else if ((length - sel_len) < 0.0)
+                  lt->ShiftLabelsOnClear(info->sel0+length, info->sel1);
+            }
          }
       }
    }
@@ -933,17 +991,21 @@
    //   the only behaviour which is different to what was done before, but it
    //   shouldn't confuse users too much.
    //
-   // - If multiple clips should be pasted, these are always pasted as single
-   //   clips, and the current clip is splitted, when necessary. This may seem
-   //   strange at first, but it probably is better than trying to auto-merge
-   //   anything. The user can still merge the clips by hand (which should be
-   //   a simple command reachable by a hotkey or single mouse click).
+   // - If multiple clips should be pasted, or a single clip that does not fill
+   // the duration of the pasted track, these are always pasted as single
+   // clips, and the current clip is splitted, when necessary. This may seem
+   // strange at first, but it probably is better than trying to auto-merge
+   // anything. The user can still merge the clips by hand (which should be a
+   // simple command reachable by a hotkey or single mouse click).
    //
 
    if (other->GetNumClips() == 0)
       return false;
 
    //printf("paste: we have at least one clip\n");
+   
+   bool singleClipMode = (other->GetNumClips() == 1 &&
+         other->GetStartTime() == 0.0);
 
    double insertDuration = other->GetEndTime();
    WaveClipList::compatibility_iterator it;
@@ -952,7 +1014,7 @@
    
    // Make room for the pasted data
    if (editClipCanMove) {
-      if (other->GetNumClips() > 1) {
+      if (!singleClipMode) {
          // We need to insert multiple clips, so split the current clip and
          // move everything to the right, then try to paste again
          if (!IsEmpty(t0, GetEndTime())) {
@@ -974,7 +1036,7 @@
       }
    }
 
-   if (other->GetNumClips() == 1)
+   if (singleClipMode)
    {
       // Single clip mode
       // printf("paste: checking for single clip mode!\n");
@@ -1054,11 +1116,15 @@
    {
       WaveClip* clip = it->GetData();
 
-      WaveClip* newClip = new WaveClip(*clip, mDirManager);
-      newClip->Resample(mRate);
-      newClip->Offset(t0);
-      newClip->MarkChanged();
-      mClips.Append(newClip);
+      // AWD Oct. 2009: Don't actually paste in placeholder clips
+      if (!clip->GetIsPlaceholder())
+      {
+         WaveClip* newClip = new WaveClip(*clip, mDirManager);
+         newClip->Resample(mRate);
+         newClip->Offset(t0);
+         newClip->MarkChanged();
+         mClips.Append(newClip);
+      }
    }
    return true;
 }

Index: Menus.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/Menus.cpp,v
retrieving revision 1.529
retrieving revision 1.530
diff -u -d -r1.529 -r1.530
--- Menus.cpp   18 Oct 2009 04:54:05 -0000      1.529
+++ Menus.cpp   18 Oct 2009 19:58:17 -0000      1.530
@@ -3299,6 +3299,10 @@
    bool advanceClipboard = true;
    double srcLength = c->GetEndTime();
 
+   // Keeps track of whether n would be the first WaveTrack in its group to
+   // receive data from the paste.
+   bool firstInGroup = true;
+
    while (n && c) {
       if (n->GetSelected()) {
          advanceClipboard = true;
@@ -3324,7 +3328,11 @@
          if (!c){
             c = tmpC;
             while (n && (c->GetKind() != n->GetKind()) )
+            {
                n = iter.Next();
+               if (n && n->GetKind() == Track::Label)
+                  firstInGroup = true;
+            }
             if (!n) c = NULL;               
          }
          
@@ -3357,7 +3365,12 @@
             ((WaveTrack *) c)->Lock();
 
          if (c->GetKind() == Track::Wave && n && n->GetKind() == Track::Wave)
-            pastedSomething = ((WaveTrack*)n)->ClearAndPaste(t0, t1, 
(WaveTrack*)c);
+         {
+            // If not the first in group we set useHandlePaste to true
+            pastedSomething = ((WaveTrack*)n)->ClearAndPaste(t0, t1,
+                  (WaveTrack*)c, true, true, NULL, false, !firstInGroup);
+            firstInGroup = !pastedSomething;
+         }
          else
             pastedSomething = n->Paste(t0, c);
                  
@@ -3372,12 +3385,23 @@
                if (!((WaveTrack *) n)->IsEmpty(t0, t1)) {
                   ((WaveTrack *) n)->Clear(t0, t1);
                }
+
+               // firstInGroup should always be false here, unless pasting to
+               // the first channel failed
+               if (firstInGroup)
+               {
+                  pastedSomething = ((WaveTrack *)n)->Paste(t0, c);
+                  firstInGroup = !pastedSomething;
+               }
+               else
+               {
+                  pastedSomething = ((WaveTrack *)n)->HandlePaste(t0, c);
+               }
             }
             else {
-               ((WaveTrack *) n)->Clear(t0, t1);
+               n->Clear(t0, t1);
+               n->Paste(t0, c);
             }
-            
-            n->Paste(t0, c);
          }
          
          if (msClipProject != this && c->GetKind() == Track::Wave)
@@ -3390,6 +3414,8 @@
       }
 
       n = iter.Next();
+      if (n && n->GetKind() == Track::Label)
+         firstInGroup = true;
    }
    
    // This block handles the cases where our clipboard is smaller


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Audacity-cvs mailing list
Audacity-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/audacity-cvs

Reply via email to