diff options
| author | Florian Jung <flo@windfisch.org> | 2011-06-28 15:43:50 +0000 | 
|---|---|---|
| committer | Florian Jung <flo@windfisch.org> | 2011-06-28 15:43:50 +0000 | 
| commit | 9633b537bea22bc753ca8e3e0481fd38419524ae (patch) | |
| tree | 306dc2a88ddc95f478f5b08fd393c22e5d2a29d6 /muse2/muse | |
| parent | 416fa4c9121621bec775f2590554e6219c045f96 (diff) | |
autoexpand now works properly also for moving notes
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/midiedit/dcanvas.cpp | 159 | ||||
| -rw-r--r-- | muse2/muse/midiedit/ecanvas.cpp | 7 | ||||
| -rw-r--r-- | muse2/muse/midiedit/prcanvas.cpp | 136 | ||||
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 3 | ||||
| -rw-r--r-- | muse2/muse/part.cpp | 2 | 
5 files changed, 139 insertions, 168 deletions
| diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index b19831a0..4b5c3ea9 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -104,9 +104,9 @@ Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp  {          if(editor->parts()->empty())      return Undo(); //return empty list -     +      PartsToChangeMap parts2change; -  Undo operations; +  Undo operations;      for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)    { @@ -153,85 +153,66 @@ Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp          ip2c->second.xdiff = npartoffset;      }    } -     +   +  bool forbidden=false;    for(iPartToChange ip2c = parts2change.begin(); ip2c != parts2change.end(); ++ip2c)    {      Part* opart = ip2c->first;      int diff = ip2c->second.xdiff; -    Part* newPart = opart->clone(); -     -    newPart->setLenTick(newPart->lenTick() + diff); -     -    // BUG FIX: #1650953 -    // Added by T356. -    // Fixes posted "select and drag past end of part - crashing" bug -    for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) +    if (opart->hasHiddenNotes())      { -      if(ip->second == opart) -      { -        editor->parts()->erase(ip); -        break; -      } -    } -       -    editor->parts()->add(newPart); -    // Do port controller values but not clone parts.  -    operations.push_back(UndoOp(UndoOp::ModifyPart, opart, newPart, true, false)); -     -    ip2c->second.npart = newPart; +			forbidden=true; +			break; +		} +    schedule_resize_all_same_len_clone_parts(opart, opart->lenTick() + diff, operations); +  }     + +	 +	if (!forbidden) +	{ +		std::vector< CItem* > doneList; +		typedef std::vector< CItem* >::iterator iDoneList; +		 +		for(iCItem ici = items.begin(); ici != items.end(); ++ici)  +		{ +			CItem* ci = ici->second; +			 +			int x = ci->pos().x(); +			int y = ci->pos().y(); +			int nx = x + dx; +			int ny = pitch2y(y2pitch(y) + dp); +			QPoint newpos = raster(QPoint(nx, ny)); +			selectItem(ci, true); +			 +			iDoneList idl; +			for(idl = doneList.begin(); idl != doneList.end(); ++idl) +				// This compares EventBase pointers to see if they're the same... +				if((*idl)->event() == ci->event()) +					break; +				 +			// Do not process if the event has already been processed (meaning it's an event in a clone part)... +			if (idl == doneList.end()) +			{ +				operations.push_back(moveItem(ci, newpos, dtype)); +				doneList.push_back(ci); +			} +			ci->move(newpos); +						 +			if(moving.size() == 1)  +						itemReleased(curItem, newpos); + +			if(dtype == MOVE_COPY || dtype == MOVE_CLONE) +						selectItem(ci, false); +		}   +					 +  	return operations;    } -     -  iPartToChange icp = parts2change.find(curPart); -  if(icp != parts2change.end()) -  { -    curPart = icp->second.npart; -    curPartId = curPart->sn(); -  }   -     -  std::vector< CItem* > doneList; -  typedef std::vector< CItem* >::iterator iDoneList; -   -  for(iCItem ici = items.begin(); ici != items.end(); ++ici)  +  else    { -    CItem* ci = ici->second; -     -    // If this item's part is in the parts2change list, change the item's part to the new part. -    Part* pt = ci->part(); -    iPartToChange ip2c = parts2change.find(pt); -    if(ip2c != parts2change.end()) -      ci->setPart(ip2c->second.npart); -     -    int x = ci->pos().x(); -    int y = ci->pos().y(); -    int nx = x + dx; -    int ny = pitch2y(y2pitch(y) + dp); -    QPoint newpos = raster(QPoint(nx, ny)); -    selectItem(ci, true); -     -    iDoneList idl; -    for(idl = doneList.begin(); idl != doneList.end(); ++idl) -      // This compares EventBase pointers to see if they're the same... -      if((*idl)->event() == ci->event()) -        break; -       -    // Do not process if the event has already been processed (meaning it's an event in a clone part)... -    if (idl == doneList.end()) -    { -      operations.push_back(moveItem(ci, newpos, dtype)); -      doneList.push_back(ci); -    } -    ci->move(newpos); -           -    if(moving.size() == 1) { -          itemReleased(curItem, newpos); -          } -    if(dtype == MOVE_COPY || dtype == MOVE_CLONE) -          selectItem(ci, false); -  }   -       -  return operations; +		return Undo(); //return empty list +	}  }  //--------------------------------------------------------- @@ -261,9 +242,10 @@ UndoOp DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype)        //item->setPart(part);        item->setEvent(newEvent); -      // Added by T356.  -      if(((int)newEvent.endTick() - (int)part->lenTick()) > 0)   -        printf("DrumCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData()); +      // Added by T356, removed by flo93: with operation groups, it happens that the +      // part is too short right now, even if it's queued for being extended +      //if(((int)newEvent.endTick() - (int)part->lenTick()) > 0)   +      //  printf("DrumCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData());        if (dtype == MOVE_COPY || dtype == MOVE_CLONE)              return UndoOp(UndoOp::AddEvent, newEvent, part, false, false); @@ -361,20 +343,23 @@ void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace)        // Added by T356.        Part* part = nevent->part(); -      song->startUndo(); -      int modified=SC_EVENT_MODIFIED; +      Undo operations;        int diff = event.endTick()-part->lenTick(); -      if (diff > 0)  {// too short part? extend it -            Part* newPart = part->clone(); -            newPart->setLenTick(newPart->lenTick()+diff); -            // Indicate no undo, and do port controller values but not clone parts.  -            audio->msgChangePart(part, newPart, false, true, false); -            modified=modified|SC_PART_MODIFIED; -            part = newPart; // reassign +       +      if (! ((diff > 0) && part->hasHiddenNotes()) ) //operation is allowed +      { +        operations.push_back(UndoOp(UndoOp::AddEvent,event, part, false, false)); +         +        if (diff > 0)// part must be extended? +        { +              schedule_resize_all_same_len_clone_parts(part, event.endTick(), operations); +              printf("newItem: extending\n");              } -      // Indicate no undo, and do not do port controller values and clone parts.  -      audio->msgAddEvent(event, part, false, false, false);  -      song->endUndo(modified); +      } +      //else forbid action by not applying it +      song->applyOperationGroup(operations); +      songChanged(SC_EVENT_INSERTED); //this forces an update of the itemlist, which is neccessary +                                      //to remove "forbidden" events from the list again        }  //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp index ef47e0d6..a829650c 100644 --- a/muse2/muse/midiedit/ecanvas.cpp +++ b/muse2/muse/midiedit/ecanvas.cpp @@ -416,7 +416,12 @@ void EventCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir)        Undo operations = moveCanvasItems(moving, dp, dx, dragtype); -      song->applyOperationGroup(operations); +      if (operations.empty()) +        songChanged(SC_EVENT_MODIFIED); //this is a hack to force the canvas to repopulate +      	                                //itself. otherwise, if a moving operation was forbidden, +      	                                //the canvas would still show the movement +      else +        song->applyOperationGroup(operations);        moving.clear();        updateSelection(); diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index 11a142e1..a659ad26 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -261,8 +261,8 @@ Undo PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty    if(editor->parts()->empty())      return Undo(); //return empty list -  Undo operations;      PartsToChangeMap parts2change; +  Undo operations;      for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)    { @@ -310,84 +310,65 @@ Undo PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty      }    } +  bool forbidden=false;    for(iPartToChange ip2c = parts2change.begin(); ip2c != parts2change.end(); ++ip2c)    {      Part* opart = ip2c->first;      int diff = ip2c->second.xdiff; -    Part* newPart = opart->clone(); -     -    newPart->setLenTick(newPart->lenTick() + diff); -     -    // BUG FIX: #1650953 -    // Added by T356. -    // Fixes posted "select and drag past end of part - crashing" bug -    for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) +    if (opart->hasHiddenNotes())      { -      if(ip->second == opart) -      { -        editor->parts()->erase(ip); -        break; -      } -    } -       -    editor->parts()->add(newPart); -    // Do port controller values but not clone parts.  -    operations.push_back(UndoOp(UndoOp::ModifyPart, opart, newPart, true, false)); -     -    ip2c->second.npart = newPart; +			forbidden=true; +			break; +		} +    schedule_resize_all_same_len_clone_parts(opart, opart->lenTick() + diff, operations); +  }     + +	 +	if (!forbidden) +	{ +		std::vector< CItem* > doneList; +		typedef std::vector< CItem* >::iterator iDoneList; +		 +		for(iCItem ici = items.begin(); ici != items.end(); ++ici)  +		{ +			CItem* ci = ici->second; +			 +			int x = ci->pos().x(); +			int y = ci->pos().y(); +			int nx = x + dx; +			int ny = pitch2y(y2pitch(y) + dp); +			QPoint newpos = raster(QPoint(nx, ny)); +			selectItem(ci, true); +			 +			iDoneList idl; +			for(idl = doneList.begin(); idl != doneList.end(); ++idl) +				// This compares EventBase pointers to see if they're the same... +				if((*idl)->event() == ci->event()) +					break; +				 +			// Do not process if the event has already been processed (meaning it's an event in a clone part)... +			if (idl == doneList.end()) +			{ +				operations.push_back(moveItem(ci, newpos, dtype)); +				doneList.push_back(ci); +			} +			ci->move(newpos); +						 +			if(moving.size() == 1)  +						itemReleased(curItem, newpos); + +			if(dtype == MOVE_COPY || dtype == MOVE_CLONE) +						selectItem(ci, false); +		}   +					 +  	return operations;    } -     -  iPartToChange icp = parts2change.find(curPart); -  if(icp != parts2change.end()) -  { -    curPart = icp->second.npart; -    curPartId = curPart->sn(); -  }   -     -  std::vector< CItem* > doneList; -  typedef std::vector< CItem* >::iterator iDoneList; -   -   -  for(iCItem ici = items.begin(); ici != items.end(); ++ici)  +  else    { -    CItem* ci = ici->second; -     -    // If this item's part is in the parts2change list, change the item's part to the new part. -    Part* pt = ci->part(); -    iPartToChange ip2c = parts2change.find(pt); -    if(ip2c != parts2change.end()) -      ci->setPart(ip2c->second.npart); -     -    int x = ci->pos().x(); -    int y = ci->pos().y(); -    int nx = x + dx; -    int ny = pitch2y(y2pitch(y) + dp); -    QPoint newpos = raster(QPoint(nx, ny)); -    selectItem(ci, true); -     -    iDoneList idl; -    for(idl = doneList.begin(); idl != doneList.end(); ++idl) -      // This compares EventBase pointers to see if they're the same... -      if((*idl)->event() == ci->event()) -        break; -       -    // Do not process if the event has already been processed (meaning it's an event in a clone part)... -    if (idl == doneList.end()) -    { -      operations.push_back(moveItem(ci, newpos, dtype)); -      doneList.push_back(ci); -    } -    ci->move(newpos); -           -    if(moving.size() == 1)  -          itemReleased(curItem, newpos); -    if(dtype == MOVE_COPY || dtype == MOVE_CLONE) -          selectItem(ci, false); -  }   -       -  return operations; +		return Undo(); //return empty list +	}  }  //--------------------------------------------------------- @@ -427,9 +408,10 @@ UndoOp PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype)        item->setEvent(newEvent); -      // Added by T356.  -      if(((int)newEvent.endTick() - (int)part->lenTick()) > 0)   -        printf("PianoCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData()); +      // Added by T356, removed by flo93: with operation groups, it happens that the +      // part is too short right now, even if it's queued for being extended +      //if(((int)newEvent.endTick() - (int)part->lenTick()) > 0)   +      //  printf("PianoCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData());        if (dtype == MOVE_COPY || dtype == MOVE_CLONE)              return UndoOp(UndoOp::AddEvent, newEvent, part, false, false); @@ -491,11 +473,13 @@ void PianoCanvas::newItem(CItem* item, bool noSnap)                schedule_resize_all_same_len_clone_parts(part, event.endTick(), operations);                printf("newItem: extending\n");              } +         +        song->applyOperationGroup(operations);        }        //else forbid action by not applying it -      song->applyOperationGroup(operations); -      songChanged(SC_EVENT_INSERTED); //this forces an update of the itemlist, which is neccessary -                                      //to remove "forbidden" events from the list again +      else       +          songChanged(SC_EVENT_INSERTED); //this forces an update of the itemlist, which is neccessary +                                          //to remove "forbidden" events from the list again        }  //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index c14c14fd..c2380539 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4456,8 +4456,7 @@ void staff_t::update_part_indices()   *     between, for example, when a cis is tied to a des   *    * CURRENT TODO - *   o do autoexpand correctly in prcanvas.cpp, then port that to  - *     dcanvas.cpp, steprec.cpp and scoreedit.cpp + *   o do autoexpand in steprec.cpp and scoreedit.cpp   *    * IMPORTANT TODO   *   o shrink a part from its beginning as well! watch out for clones! diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index 9bb3431c..67cf441e 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -1179,7 +1179,5 @@ bool Part::hasHiddenNotes()  		if (ev->second.endTick() > lastNote)  			lastNote=ev->second.endTick(); -	printf ("in hasHiddenNotes: lastNote=%i, lenTick=%i\n",lastNote, lenTick()); -	  	return lastNote > lenTick();  } | 
