diff options
| author | Florian Jung <flo@windfisch.org> | 2013-08-10 17:22:58 +0200 | 
|---|---|---|
| committer | Florian Jung <flo@windfisch.org> | 2013-08-10 17:22:58 +0200 | 
| commit | cf5765018e4b742bbf490cf9fd57757bfb921f83 (patch) | |
| tree | ac6755ee9f4358f39bb2214121c9f36b1669c79b /muse2/muse | |
| parent | d51caef570ef25b97b9b4687bd870a5afcc623ec (diff) | |
removed ModifyPart/changePart. Replaced with ModifyPartLength etc.
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/arranger/pcanvas.cpp | 182 | ||||
| -rw-r--r-- | muse2/muse/audio.cpp | 4 | ||||
| -rw-r--r-- | muse2/muse/audio.h | 6 | ||||
| -rw-r--r-- | muse2/muse/functions.cpp | 28 | ||||
| -rw-r--r-- | muse2/muse/midiseq.cpp | 3 | ||||
| -rw-r--r-- | muse2/muse/part.cpp | 62 | ||||
| -rw-r--r-- | muse2/muse/seqmsg.cpp | 15 | ||||
| -rw-r--r-- | muse2/muse/song.cpp | 69 | ||||
| -rw-r--r-- | muse2/muse/song.h | 2 | ||||
| -rw-r--r-- | muse2/muse/structure.cpp | 63 | ||||
| -rw-r--r-- | muse2/muse/undo.cpp | 125 | ||||
| -rw-r--r-- | muse2/muse/undo.h | 23 | 
12 files changed, 229 insertions, 353 deletions
| diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 646a9382..0e1e04a8 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -64,6 +64,10 @@  #include "utils.h"  #include "dialogs.h"  #include "widgets/pastedialog.h" +#include "undo.h" + +using MusECore::Undo; +using MusECore::UndoOp;  #define ABS(x) (abs(x)) @@ -189,12 +193,12 @@ void PartCanvas::returnPressed()        if (editMode) {            //this check is neccessary, because it returnPressed may be called            //twice. the second call would cause a crash, however! -          MusECore::Part* oldPart = editPart->part(); -          MusECore::Part* newPart = oldPart->clone(); -           -          newPart->setName(lineEditor->text()); +          MusECore::Part* part = editPart->part();            // Indicate do undo, and do port controller values but not clone parts.  -          MusEGlobal::audio->msgChangePart(oldPart, newPart, true, true, false); +           +          Undo operations; +          operations.push_back(UndoOp(UndoOp::ModifyPartName,part, part->name().toUtf8().data(), lineEditor->text().toUtf8().data())); // FIXME char sucks, better use QString directly. +          MusEGlobal::song->applyOperationGroup(operations);            editMode = false; @@ -314,7 +318,7 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp      bool result=moveItem(operations, ci, newpos, dtype);      if (result) -    	ci->move(newpos); +        ci->move(newpos);      if(moving.size() == 1) {            itemReleased(curItem, newpos); @@ -333,102 +337,89 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp  //---------------------------------------------------------  bool PartCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& newpos, DragType t) -      { -      NPart* npart    = (NPart*) item; -      MusECore::Part* spart     = npart->part(); -      MusECore::Track* track    = npart->track(); -      MusECore::Track* dtrack=NULL; -      unsigned dtick  = newpos.x(); -      unsigned ntrack = y2pitch(item->mp().y()); -      MusECore::Track::TrackType type = track->type(); -      if (tracks->index(track) == ntrack && (dtick == spart->tick())) { -            return false; -            } -      if (ntrack >= tracks->size()) { -            ntrack = tracks->size(); -            if (MusEGlobal::debugMsg) -                printf("PartCanvas::moveItem - add new track\n"); -            dtrack = MusEGlobal::song->addTrack(operations, type);  // Add at end of list. - -            if (type == MusECore::Track::WAVE) { -                  MusECore::WaveTrack* st = (MusECore::WaveTrack*) track; -                  MusECore::WaveTrack* dt = (MusECore::WaveTrack*) dtrack; -                  dt->setChannels(st->channels()); -                  } -            emit tracklistChanged(); -            } -      else -      {       -            dtrack = tracks->index(ntrack); -            if (dtrack->type() != type) { -                  QMessageBox::critical(this, QString("MusE"), -                     tr("Cannot copy/move/clone to different Track-Type")); -                  return false; -                  } -            } -       -      MusECore::Part* dpart; -      bool clone = (t == MOVE_CLONE || (t == MOVE_COPY && spart->events()->arefCount() > 1)); -       -      if(t == MOVE_MOVE) -      { -        // This doesn't increment aref count, and doesn't chain clones. -        // It also gives the new part a new serial number, but it is  -        //  overwritten with the old one by Song::changePart(), from Audio::msgChangePart() below.  -        dpart = spart->clone(); -        dpart->setTrack(dtrack); -      }   -      else +{ +    NPart* npart    = (NPart*) item; +    MusECore::Part* spart     = npart->part(); +    MusECore::Track* track    = npart->track(); +    MusECore::Track* dtrack=NULL; +    unsigned dtick  = newpos.x(); // FIXME TODO make subtick-compatible! +    unsigned ntrack = y2pitch(item->mp().y()); +    MusECore::Track::TrackType type = track->type(); +    int new_partend; +    if (tracks->index(track) == ntrack && (dtick == spart->tick())) { +        return false; +    } +    if (ntrack >= tracks->size()) { +        ntrack = tracks->size(); +        if (MusEGlobal::debugMsg) +            printf("PartCanvas::moveItem - add new track\n"); +        dtrack = MusEGlobal::song->addTrack(operations, type);  // Add at end of list. +         +        if (type == MusECore::Track::WAVE) { +            MusECore::WaveTrack* st = (MusECore::WaveTrack*) track; +            MusECore::WaveTrack* dt = (MusECore::WaveTrack*) dtrack; +            dt->setChannels(st->channels()); +        } +        emit tracklistChanged(); +    } +    else +    {       +        dtrack = tracks->index(ntrack); +        if (dtrack->type() != type) { +            QMessageBox::critical(this, QString("MusE"), +                                  tr("Cannot copy/move/clone to different Track-Type")); +                                  return false; +        } +    } +     +     +     +    if(t == MOVE_MOVE) +    { +        operations.push_back(MusECore::UndoOp(MusECore::UndoOp::ModifyPartTick,spart,spart->tick(),dtick)); +         +        new_partend=(spart->lenTick() + dtick); +    }   +    else +    { +        MusECore::Part* dpart; +        bool clone = (t == MOVE_CLONE || (t == MOVE_COPY && spart->events()->arefCount() > 1)); +                  // This increments aref count if cloned, and chains clones.          // It also gives the new part a new serial number.          dpart = dtrack->newPart(spart, clone); - -      dpart->setTick(dtick); - -      if(t == MOVE_MOVE)  -        item->setPart(dpart); -      if (t == MOVE_COPY && !clone) { +         +        dpart->setTick(dtick); +        if (t == MOVE_COPY && !clone) {              // Copy Events              MusECore::EventList* se = spart->events();              MusECore::EventList* de = dpart->events();              for (MusECore::iEvent i = se->begin(); i != se->end(); ++i) { -                  MusECore::Event oldEvent = i->second; -                  MusECore::Event ev = oldEvent.clone(); -                  de->add(ev); -                  } +                MusECore::Event oldEvent = i->second; +                MusECore::Event ev = oldEvent.clone(); +                de->add(ev);              } - - -      if (t == MOVE_COPY || t == MOVE_CLONE) { -            dpart->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it -                                          // so we must decrement it first :/ -            // These will not increment ref count, and will not chain clones...  -            // TODO DELETETHIS: is the above comment still correct (by flo93)? i doubt it! -            operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart)); -            } -      else if (t == MOVE_MOVE) { -            // In all cases found ev lists were same. So this is redundant - Redo incs then decs the same list. -            // But just in case we ever have two different lists... -            dpart->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it -                                          // so we must decrement it first :/ -            spart->events()->incARef(1);  // the later MusEGlobal::song->applyOperationGroup() will decrement it -                                          // so we must increment it first :/ -            dpart->setSelected(spart->selected()); -            // These will increment ref count if not a clone, and will chain clones... -            // TODO DELETETHIS: is the above comment still correct (by flo93)? i doubt it! -            operations.push_back(MusECore::UndoOp(MusECore::UndoOp::ModifyPart,spart, dpart, true, false)); -             -            spart->setSelected(false); -            } -      // else // will never happen -> operations will never be empty -       -      if (MusEGlobal::song->len() < (dpart->lenTick() + dpart->tick())) +        } +         +        dpart->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it +        // so we must decrement it first :/ +        // These will not increment ref count, and will not chain clones...  +        // TODO DELETETHIS: is the above comment still correct (by flo93)? i doubt it! +        operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart)); +         +        new_partend=(dpart->lenTick() + dpart->tick()); +         +    } +     +    if (MusEGlobal::song->len() < new_partend) // FIXME this is buggy anyway.              operations.push_back(  MusECore::UndoOp(MusECore::UndoOp::ModifySongLen,  -                                                    dpart->lenTick() + dpart->tick(), +                                                    new_partend,                                                      MusEGlobal::song->len() )  ); -       -      return true; -      } +             +             +             +    return true; +}  //---------------------------------------------------------  //   raster @@ -866,9 +857,10 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt)                          MusECore::Event ev = oldEvent.clone();                          de->add(ev);                          } -                  // Indicate undo, and do port controller values but not clone parts.  -                  // changed by flo93: removed start and endUndo, instead changed first bool to true -                  MusEGlobal::audio->msgChangePart(spart, dpart, true, true, false); +                  Undo operations; +                  operations.push_back(UndoOp(UndoOp::DeletePart, spart)); +                  operations.push_back(UndoOp(UndoOp::AddPart, dpart)); +                  MusEGlobal::song->applyOperationGroup(operations);                    break;                    }              case 16: // Export to file diff --git a/muse2/muse/audio.cpp b/muse2/muse/audio.cpp index 659ae8a9..bbc803c5 100644 --- a/muse2/muse/audio.cpp +++ b/muse2/muse/audio.cpp @@ -76,9 +76,9 @@ void initAudio()  extern double curTime();  const char* seqMsgList[] = { -      "SEQM_ADD_TRACK", "SEQM_REMOVE_TRACK", //"SEQM_CHANGE_TRACK",   DELETETHIS +      "SEQM_ADD_TRACK", "SEQM_REMOVE_TRACK",        "SEQM_MOVE_TRACK", -      "SEQM_ADD_PART", "SEQM_REMOVE_PART", "SEQM_CHANGE_PART", +      "SEQM_ADD_PART", "SEQM_REMOVE_PART",        "SEQM_ADD_EVENT", "SEQM_REMOVE_EVENT", "SEQM_CHANGE_EVENT",        "SEQM_ADD_TEMPO", "SEQM_SET_TEMPO", "SEQM_REMOVE_TEMPO", "SEQM_ADD_SIG", "SEQM_REMOVE_SIG",        "SEQM_SET_GLOBAL_TEMPO", diff --git a/muse2/muse/audio.h b/muse2/muse/audio.h index a403e5bf..e8d22f78 100644 --- a/muse2/muse/audio.h +++ b/muse2/muse/audio.h @@ -60,9 +60,9 @@ class Track;  //---------------------------------------------------------  enum { -      SEQM_ADD_TRACK, SEQM_REMOVE_TRACK,   //SEQM_CHANGE_TRACK,   DELETETHIS +      SEQM_ADD_TRACK, SEQM_REMOVE_TRACK,        SEQM_MOVE_TRACK, -      SEQM_ADD_PART, SEQM_REMOVE_PART, SEQM_CHANGE_PART, +      SEQM_ADD_PART, SEQM_REMOVE_PART,        SEQM_ADD_EVENT, SEQM_REMOVE_EVENT, SEQM_CHANGE_EVENT,        SEQM_ADD_TEMPO, SEQM_SET_TEMPO, SEQM_REMOVE_TEMPO, SEQM_ADD_SIG, SEQM_REMOVE_SIG,        SEQM_ADD_KEY, SEQM_REMOVE_KEY, @@ -234,11 +234,9 @@ class Audio {        void msgRemoveTrack(Track*, bool u = true);        void msgRemoveTracks(); -      //void msgChangeTrack(Track* oldTrack, Track* newTrack, bool u = true); DELETETHIS        void msgMoveTrack(int idx1, int dx2, bool u = true);        void msgAddPart(Part*, bool u = true);        void msgRemovePart(Part*, bool u = true); -      void msgChangePart(Part* oldPart, Part* newPart, bool u = true, bool doCtrls = true, bool doClones = false);        void msgAddEvent(Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false);        void msgDeleteEvent(Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false);        void msgChangeEvent(Event&, Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false); diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index fa53f5d4..449461c5 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -2,7 +2,7 @@  //  MusE  //  Linux Music Editor  //    $Id: functions.cpp,v 1.20.2.19 2011/05/05 20:10 flo93 Exp $ -//  (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +//  (C) Copyright 2011,2013 Florian Jung (flo93@sourceforge.net)  //  //  This program is free software; you can redistribute it and/or  //  modify it under the terms of the GNU General Public License @@ -1310,11 +1310,7 @@ void shrink_parts(int raster)  				if (len<min_len) len=min_len;  				if (len < part->second->lenTick()) -				{ -					MidiPart* new_part = new MidiPart(*(MidiPart*)part->second); -					new_part->setLenTick(len); -					operations.push_back(UndoOp(UndoOp::ModifyPart, part->second, new_part, true, false)); -				} +					operations.push_back(UndoOp(UndoOp::ModifyPartLength, part->second, part->second->lenTick(), len, true, false));  			}  	MusEGlobal::song->applyOperationGroup(operations); @@ -1326,8 +1322,8 @@ void schedule_resize_all_same_len_clone_parts(Part* part, unsigned new_len, Undo  	QSet<const Part*> already_done;  	for (Undo::iterator op_it=operations.begin(); op_it!=operations.end();op_it++) -		if (op_it->type==UndoOp::ModifyPart || op_it->type==UndoOp::DeletePart) -			already_done.insert(op_it->nPart); +		if (op_it->type==UndoOp::DeletePart) +			already_done.insert(op_it->part);  	unsigned old_len= part->type() == Pos::FRAMES ? part->lenFrame() : part->lenTick();  	if (old_len!=new_len) @@ -1338,18 +1334,12 @@ void schedule_resize_all_same_len_clone_parts(Part* part, unsigned new_len, Undo  			if (part->type() == Pos::FRAMES)  			{  			  if (part_it->lenFrame()==old_len && !already_done.contains(part_it)) -			  { -				  WavePart* new_part = new WavePart(*(WavePart*)part_it); -				  new_part->setLenFrame(new_len); -				  operations.push_back(UndoOp(UndoOp::ModifyPart, part_it, new_part, true, false)); -			  } +				  operations.push_back(UndoOp(UndoOp::ModifyPartLengthFrames, part_it, part_it->lenFrame(), new_len, true, false)); // FIXME FINDMICH frames suck :(  			}  			else  			if (part_it->lenTick()==old_len && !already_done.contains(part_it))  			{ -				MidiPart* new_part = new MidiPart(*(MidiPart*)part_it); -				new_part->setLenTick(new_len); -				operations.push_back(UndoOp(UndoOp::ModifyPart, part_it, new_part, true, false)); +				operations.push_back(UndoOp(UndoOp::ModifyPartLength, part_it, part_it->lenTick(), new_len, true, false));  			}  			part_it=part_it->nextClone(); @@ -1381,11 +1371,7 @@ void expand_parts(int raster)  				if (len<min_len) len=min_len;  				if (len > part->second->lenTick()) -				{ -					MidiPart* new_part = new MidiPart(*(MidiPart*)part->second); -					new_part->setLenTick(len); -					operations.push_back(UndoOp(UndoOp::ModifyPart, part->second, new_part, true, false)); -				} +					operations.push_back(UndoOp(UndoOp::ModifyPartLength, part->second, part->second->lenTick(), len, true, false));  			}  	MusEGlobal::song->applyOperationGroup(operations); diff --git a/muse2/muse/midiseq.cpp b/muse2/muse/midiseq.cpp index b94e284e..8aa6c289 100644 --- a/muse2/muse/midiseq.cpp +++ b/muse2/muse/midiseq.cpp @@ -119,9 +119,6 @@ void MidiSeq::processMsg(const ThreadMsg* m)              case MusECore::SEQM_REMOVE_PART:                    MusEGlobal::song->cmdRemovePart((Part*)msg->p1);                    break; -            case MusECore::SEQM_CHANGE_PART: -                  MusEGlobal::song->cmdChangePart((Part*)msg->p1, (Part*)msg->p2, msg->a, msg->b); -                  break;              case MusECore::SEQM_SET_TRACK_OUT_CHAN: diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index c530b1f3..10c7f201 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -372,8 +372,6 @@ void addPortCtrlEvents(Event& event, Part* part, bool doClones)  {    // Traverse and process the clone chain ring until we arrive at the same part again.    // The loop is a safety net. -  // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents, -  //  we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain.    Part* p = part;     while(1)    { @@ -434,8 +432,6 @@ void addPortCtrlEvents(Part* part, bool doClones)  {    // Traverse and process the clone chain ring until we arrive at the same part again.    // The loop is a safety net. -  // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents, -  //  we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain.    Part* p = part;     while(1)    { @@ -499,8 +495,6 @@ void removePortCtrlEvents(Event& event, Part* part, bool doClones)  {    // Traverse and process the clone chain ring until we arrive at the same part again.    // The loop is a safety net. -  // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents, -  //  we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain.    Part* p = part;     while(1)    { @@ -555,8 +549,6 @@ void removePortCtrlEvents(Part* part, bool doClones)  {    // Traverse and process the clone chain ring until we arrive at the same part again.    // The loop is a safety net. -  // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents, -  //  we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain.    Part* p = part;     while(1)    { @@ -850,6 +842,10 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo                    EventList* el = nPart->events();                    unsigned new_partlength = MusEGlobal::tempomap.deltaTick2frame(oPart->tick(), oPart->tick() + len); +                  // TODO FINDMICH FIXME this is totally broken. we don't want to remove events just because they're beyond end-of-part. +                  // we also don't want to auto-resize the last event. +                   +                  /*                    // If new nr of frames is less than previous what can happen is:                    // -   0 or more events are beginning after the new final position. Those are removed from the part                    // -   The last event begins before new final position and ends after it. If so, it will be resized to end at new part length @@ -865,7 +861,7 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo                                }                          nPart->setLenFrame(new_partlength);                          // Do not do port controller values and clone parts.  -                        operations.push_back(UndoOp(UndoOp::ModifyPart, oPart, nPart, false, false)); +                        operations.push_back(UndoOp(UndoOp::Modify***Part, oPart, nPart, false, false));                          MusEGlobal::song->applyOperationGroup(operations);                          } @@ -890,9 +886,9 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo                          nPart->setLenFrame(new_partlength);                          // Do not do port controller values and clone parts.  -                        operations.push_back(UndoOp(UndoOp::ModifyPart, oPart, nPart, false, false)); +                        operations.push_back(UndoOp(UndoOp::Modify***Part, oPart, nPart, false, false));                          MusEGlobal::song->applyOperationGroup(operations); -                        } +                        } */                    }                    break;              case Track::MIDI: @@ -907,10 +903,8 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo  									{  										if (part_it->lenTick()==orig_len)  										{ -											MidiPart* newPart = new MidiPart(*part_it); -											newPart->setLenTick(len);  											// Do port controller values but not clone parts.  -											operations.push_back(UndoOp(UndoOp::ModifyPart, part_it, newPart, true, false)); +											operations.push_back(UndoOp(UndoOp::ModifyPartLength, part_it, part_it->lenTick(), len, true, false));  										}  										part_it=(MidiPart*)part_it->nextClone(); @@ -1032,45 +1026,23 @@ void Song::cmdSplitPart(Track* track, Part* part, int tick)        Part* p2;        track->splitPart(part, tick, p1, p2); -      //MusEGlobal::song->informAboutNewParts(part, p1); // is unneccessary because of ChangePart below +      MusEGlobal::song->informAboutNewParts(part, p1);        MusEGlobal::song->informAboutNewParts(part, p2); -      startUndo(); -      // Indicate no undo, and do port controller values but not clone parts.  -      MusEGlobal::audio->msgChangePart(part, p1, false, true, false); -      MusEGlobal::audio->msgAddPart(p2, false); -      endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED); +      Undo operations; +      operations.push_back(UndoOp(UndoOp::DeletePart, part)); +      operations.push_back(UndoOp(UndoOp::AddPart, p1)); +      operations.push_back(UndoOp(UndoOp::AddPart, p2)); +      applyOperationGroup(operations);        } -//--------------------------------------------------------- -//   changePart -//--------------------------------------------------------- - -void Song::changePart(Part* oPart, Part* nPart) -      { -      nPart->setSn(oPart->sn()); - -      Track* oTrack = oPart->track(); -      Track* nTrack = nPart->track(); - -      oTrack->parts()->remove(oPart); -      nTrack->parts()->add(nPart); -       -       -      // Added by T356.  -      // adjust song len: -      unsigned epos = nPart->tick() + nPart->lenTick(); -      if (epos > len()) -            _len = epos; -       -      }  //---------------------------------------------------------  //   cmdGluePart  //---------------------------------------------------------  void Song::cmdGluePart(Track* track, Part* oPart) -      { +      { /* disabled for now, to be deleted        // p3.3.54        if(track->type() != Track::WAVE && !track->isMidiTrack())          return; @@ -1126,8 +1098,8 @@ void Song::cmdGluePart(Track* track, Part* oPart)        startUndo();        MusEGlobal::audio->msgRemovePart(nextPart, false);        // Indicate no undo, and do port controller values but not clone parts.  -      MusEGlobal::audio->msgChangePart(oPart, nPart, false, true, false); -      endUndo(SC_PART_MODIFIED | SC_PART_REMOVED); +      MusEGlobal::audio->msgChange***Part(oPart, nPart, false, true, false); +      endUndo(SC_PART_MODIFIED | SC_PART_REMOVED); */        }  //--------------------------------------------------------- diff --git a/muse2/muse/seqmsg.cpp b/muse2/muse/seqmsg.cpp index fcffc332..61714b98 100644 --- a/muse2/muse/seqmsg.cpp +++ b/muse2/muse/seqmsg.cpp @@ -923,21 +923,6 @@ bool Song::msgRemoveParts()        }  //--------------------------------------------------------- -//   msgChangePart -//--------------------------------------------------------- - -void Audio::msgChangePart(Part* oldPart, Part* newPart, bool doUndoFlag, bool doCtrls, bool doClones) -      { -      AudioMsg msg; -      msg.id = SEQM_CHANGE_PART; -      msg.p1 = oldPart; -      msg.p2 = newPart; -      msg.a = doCtrls; -      msg.b = doClones; -      sendMessage(&msg, doUndoFlag); -      } - -//---------------------------------------------------------  //   msgAddEvent  //--------------------------------------------------------- diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 8a7bf39f..d457cb1d 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -886,42 +886,23 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start              // Round the end up (again) using the Arranger part snap raster value.               endTick   = AL::sigmap.raster2(endTick, arrangerRaster()); -             -            removePortCtrlEvents(part, false); // Remove all of the part's port controller values. Don't do clone parts. - -            // Clone the part. This doesn't increment aref count, and doesn't chain clones. -            // It also gives the new part a new serial number, but it is  -            //  overwritten with the old one by Song::changePart(), below.  -            Part* newPart = part->clone(); -             -            newPart->setLenTick(endTick);  // Set the new part's length. -            changePart(part, newPart);     // Change the part. -             -            part->events()->incARef(-1);   // Manually adjust reference counts. HACK! -            newPart->events()->incARef(1); -             -            replaceClone(part, newPart);   // Replace the part in the clone chain with the new part. -             -            // Now add all of the new part's port controller values. Indicate do not do clone parts. -            addPortCtrlEvents(newPart, false); -                          // Create an undo op. Indicate do port controller values but not clone parts.  -            addUndo(UndoOp(UndoOp::ModifyPart, part, newPart, true, false)); +            addUndo(UndoOp(UndoOp::ModifyPartLength, part, part->lenTick(), endTick, true, false)); // FIXME XTICKS! FINDMICHJETZT!              updateFlags |= SC_PART_MODIFIED;              if (_recMode == REC_REPLACE)              { -                  iEvent si = newPart->events()->lower_bound(startTick - newPart->tick()); -                  iEvent ei = newPart->events()->lower_bound(newPart->endTick() - newPart->tick()); +                  iEvent si = part->events()->lower_bound(startTick - part->tick()); +                  iEvent ei = part->events()->lower_bound(part->endTick() - part->tick());                    for (iEvent i = si; i != ei; ++i)                     {                      Event event = i->second;                      // Indicate do port controller values and clone parts.  -                    addUndo(UndoOp(UndoOp::DeleteEvent, event, newPart, true, true)); +                    addUndo(UndoOp(UndoOp::DeleteEvent, event, part, true, true));                      // Remove the event from the new part's port controller values, and do all clone parts. -                    removePortCtrlEvents(event, newPart, true); +                    removePortCtrlEvents(event, part, true);                    } -                  newPart->events()->erase(si, ei); +                  part->events()->erase(si, ei);              }              for (iEvent i = s; i != e; ++i) { @@ -929,13 +910,13 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start                    event.setTick(event.tick() - partTick);                    Event e;                    // Create an undo op. Indicate do port controller values and clone parts.  -                  addUndo(UndoOp(UndoOp::AddEvent, e, event, newPart, true, true)); +                  addUndo(UndoOp(UndoOp::AddEvent, e, event, part, true, true)); -                  if(newPart->events()->find(event) == newPart->events()->end()) -                    newPart->events()->add(event); +                  if(part->events()->find(event) == part->events()->end()) +                    part->events()->add(event);                    // Add the event to the new part's port controller values, and do all clone parts. -                  addPortCtrlEvents(event, newPart, true); +                  addPortCtrlEvents(event, part, true);                    }              }        else { @@ -1886,7 +1867,6 @@ void Song::processMsg(AudioMsg* msg)                    updateFlags = SC_EVENT_MODIFIED;                    break; -            // Moved here from MidiSeq::processMsg   p4.0.34              case SEQM_ADD_TRACK:                    insertTrack2(msg->track, msg->ival);                    break; @@ -1899,9 +1879,6 @@ void Song::processMsg(AudioMsg* msg)              case SEQM_REMOVE_PART:                    cmdRemovePart((Part*)msg->p1);                    break; -            case SEQM_CHANGE_PART: -                  cmdChangePart((Part*)msg->p1, (Part*)msg->p2, msg->a, msg->b); -                  break;              case SEQM_ADD_TEMPO:                    addUndo(UndoOp(UndoOp::AddTempo, msg->a, msg->b)); @@ -1980,32 +1957,6 @@ void Song::cmdRemovePart(Part* part)        }  //--------------------------------------------------------- -//   cmdChangePart -//--------------------------------------------------------- - -void Song::cmdChangePart(Part* oldPart, Part* newPart, bool doCtrls, bool doClones) -      { -      if(doCtrls) -        removePortCtrlEvents(oldPart, doClones); -       -      changePart(oldPart, newPart); -       -      addUndo(UndoOp(UndoOp::ModifyPart, oldPart, newPart, doCtrls, doClones)); -       -      // Changed by T356. Do not decrement ref count if the new part is a clone of the old part, since the event list -      //  will still be active. -      if(oldPart->cevents() != newPart->cevents()) -        oldPart->events()->incARef(-1); -       -      replaceClone(oldPart, newPart); - -      if(doCtrls) -        addPortCtrlEvents(newPart, doClones); -       -      updateFlags = SC_PART_MODIFIED; -      } - -//---------------------------------------------------------  //   panic  //--------------------------------------------------------- diff --git a/muse2/muse/song.h b/muse2/muse/song.h index f6b1403d..909e54fc 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -298,12 +298,10 @@ class Song : public QObject {        void addPart(Part* part);        void removePart(Part* part); -      void changePart(Part*, Part*);        PartList* getSelectedMidiParts() const;        PartList* getSelectedWaveParts() const;        bool msgRemoveParts(); -      void cmdChangePart(Part* oldPart, Part* newPart, bool doCtrls, bool doClones);        void cmdRemovePart(Part* part);        void cmdAddPart(Part* part);        int arrangerRaster() { return _arrangerRaster; }        // Used by Song::cmdAddRecordedWave to snap new wave parts diff --git a/muse2/muse/structure.cpp b/muse2/muse/structure.cpp index 65489cac..ad22b8d3 100644 --- a/muse2/muse/structure.cpp +++ b/muse2/muse/structure.cpp @@ -5,6 +5,7 @@  //  //  (C) Copyright 1999-2004 Werner Schweer (ws@seh.de)  //  (C) Copyright 2011  Robert Jonsson (rj@spamatica.se) +//  (C) Copyright 2013  Florian Jung (flo93@sourceforge.net)  //  //  This program is free software; you can redistribute it and/or  //  modify it under the terms of the GNU General Public License @@ -161,19 +162,15 @@ void globalCut(bool onlySelectedTracks)                    else if ((t < lpos) && ((t+l) > lpos) && ((t+l) <= rpos)) {                        // remove part tail                        int len = lpos - t; -                      Part *nPart; -                      if (track->isMidiTrack()) -                        nPart = new MidiPart(*(MidiPart*)part); -                      else -                        nPart = new WavePart(*(WavePart*)part); - -                      nPart->setLenTick(len); -                      // cut Events in nPart -                      EventList* el = nPart->events(); -                      for (iEvent ie = el->lower_bound(len); ie != el->end(); ++ie) -                            operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, nPart, false, false)); - -                      operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true)); +                       +                      if (part->nextClone()==part) // no clones +                      { +                            // cut Events +                            EventList* el = part->events(); +                            for (iEvent ie = el->lower_bound(len); ie != el->end(); ++ie) +                                    operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, part, false, false)); +                      } +                      operations.push_back(UndoOp(UndoOp::ModifyPartLength, part, part->lenTick(), len, true, true));                    }                    else if ((t < lpos) && ((t+l) > lpos) && ((t+l) > rpos)) {                          //---------------------- @@ -190,8 +187,9 @@ void globalCut(bool onlySelectedTracks)                          p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/                          p3->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ -                        // Indicate no undo, and do port controller values and clone parts. -                        operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, true)); +                        MusEGlobal::song->informAboutNewParts(part,p1,p3); +                        operations.push_back(UndoOp(UndoOp::DeletePart,part)); +                        operations.push_back(UndoOp(UndoOp::AddPart,p1));                          operations.push_back(UndoOp(UndoOp::AddPart,p3));                          }                    else if ((t >= lpos) && (t < rpos) && (t+l) > rpos) { @@ -203,19 +201,15 @@ void globalCut(bool onlySelectedTracks)                          delete p1;                          p2->setTick(lpos);                          p2->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ -                        operations.push_back(UndoOp(UndoOp::ModifyPart,part, p2, true, true)); +                         +                        MusEGlobal::song->informAboutNewParts(part,p2); +                        operations.push_back(UndoOp(UndoOp::DeletePart,part)); +                        operations.push_back(UndoOp(UndoOp::AddPart,p2));                          }                    else if (t >= rpos) {                          // move part to the left -                        Part *nPart; -                        if (track->isMidiTrack()) -                          nPart = new MidiPart(*(MidiPart*)part); -                        else -                          nPart = new WavePart(*(WavePart*)part);                          int nt = part->tick(); -                        nPart->setTick(nt - (rpos -lpos)); -                        // Indicate no undo, and do port controller values but not clone parts. -                        operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, false)); +                        operations.push_back(UndoOp(UndoOp::ModifyPartTick,part,part->tick(), nt - (rpos -lpos) ));                          }                    }              } @@ -268,17 +262,13 @@ Undo movePartsTotheRight(unsigned int startTicks, int moveTicks, bool only_selec                          p2->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/                          p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ -                        operations.push_back(UndoOp(UndoOp::ModifyPart, part, p1, true, true)); +                        MusEGlobal::song->informAboutNewParts(part,p1,p2); +                        operations.push_back(UndoOp(UndoOp::DeletePart, part)); +                        operations.push_back(UndoOp(UndoOp::AddPart, p1));                          operations.push_back(UndoOp(UndoOp::AddPart, p2));                          }                    else if (t >= startTicks) { -                        Part *nPart; -                        if (track->isMidiTrack()) -                          nPart = new MidiPart(*(MidiPart*)part); -                        else -                          nPart = new WavePart(*(WavePart*)part); -                        nPart->setTick(t + moveTicks); -                        operations.push_back(UndoOp(UndoOp::ModifyPart, part, nPart, true, false)); +                        operations.push_back(UndoOp(UndoOp::ModifyPartTick, part, part->tick(), t + moveTicks));                          }                    }              } @@ -323,19 +313,20 @@ Undo partSplitter(unsigned int pos, bool onlySelectedTracks)                      p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it                      p2->events()->incARef(-1); // so we must decrement it first :/ -                    //MusEGlobal::song->informAboutNewParts(part, p1); // is unneccessary because of ModifyPart +                    MusEGlobal::song->informAboutNewParts(part, p1);                      MusEGlobal::song->informAboutNewParts(part, p2); -                    operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, false)); +                    operations.push_back(UndoOp(UndoOp::DeletePart,part)); +                    operations.push_back(UndoOp(UndoOp::AddPart,p1));                      operations.push_back(UndoOp(UndoOp::AddPart,p2));                      if (MusEGlobal::debugMsg)                      {                            printf("in partSplitter: part1 %d\n",p1->events()->refCount());                            printf("in partSplitter: part2 %d\n",p2->events()->refCount()); -                          } -                    break;                      } +                    break;                }          } +    }      return operations;  } diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index fc6fc1d8..924ba745 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -50,7 +50,7 @@ const char* UndoOp::typeName()        {        static const char* name[] = {              "AddTrack", "DeleteTrack",  -            "AddPart",  "DeletePart",  "ModifyPart", +            "AddPart",  "DeletePart",  "ModifyPartTick", "ModifyPartLength", "ModifyPartLengthFrames", "ModifyPartName",              "AddEvent", "DeleteEvent", "ModifyEvent",              "AddTempo", "DeleteTempo",              "AddSig", "DeleteSig", @@ -77,7 +77,10 @@ void UndoOp::dump()                    break;              case AddPart:              case DeletePart: -            case ModifyPart: +            case ModifyPartTick: +            case ModifyPartLength: +            case ModifyPartLengthFrames: +            case ModifyPartName:                    break;              case AddEvent:              case DeleteEvent: @@ -136,11 +139,7 @@ void UndoList::clearDelete()                    break;              case UndoOp::DeletePart: -                  delete i->oPart; -                  break; - -            case UndoOp::ModifyPart: -                  delete i->oPart; +                  delete i->part;                    break;              case UndoOp::ModifyMarker: @@ -176,12 +175,9 @@ void UndoList::clearDelete()                    break;              case UndoOp::AddPart: -                  delete i->oPart; +                  delete i->part;                    break; -            case UndoOp::ModifyPart: -                  delete i->nPart; -                  break;              case UndoOp::ModifyMarker:                    if (i->realMarker)                      delete i->realMarker; @@ -295,12 +291,12 @@ void cleanOperationGroup(Undo& group)  			else  				processed_tracks.insert(op->track);  		} -		else if ((op->type==UndoOp::ModifyPart) || (op->type==UndoOp::DeletePart)) +		else if (op->type==UndoOp::DeletePart)  		{ -			if (processed_parts.find(op->oPart)!=processed_parts.end()) +			if (processed_parts.find(op->part)!=processed_parts.end())  				group.erase(op);  			else -				processed_parts.insert(op->oPart); +				processed_parts.insert(op->part);  		}  		op=op_; @@ -370,28 +366,33 @@ void Song::doUndo2()                          break;                    case UndoOp::AddPart:                          { -                        Part* part = i->oPart; +                        Part* part = i->part;                          removePart(part);                          updateFlags |= SC_PART_REMOVED; -                        i->oPart->events()->incARef(-1); -                        unchainClone(i->oPart); +                        i->part->events()->incARef(-1); +                        unchainClone(i->part);                          }                          break;                    case UndoOp::DeletePart: -                        addPart(i->oPart); +                        addPart(i->part);                          updateFlags |= SC_PART_INSERTED; -                        i->oPart->events()->incARef(1); -                        chainClone(i->oPart); +                        i->part->events()->incARef(1); +                        chainClone(i->part);                          break; -                  case UndoOp::ModifyPart: -                        if(i->doCtrls) -                          removePortCtrlEvents(i->nPart, i->doClones); -                        changePart(i->nPart, i->oPart); -                        i->nPart->events()->incARef(-1); -                        i->oPart->events()->incARef(1); -                        replaceClone(i->nPart, i->oPart); -                        if(i->doCtrls) -                          addPortCtrlEvents(i->oPart, i->doClones); +                  case UndoOp::ModifyPartName: +                        i->part->setName(i->_oldName); +                        updateFlags |= SC_PART_MODIFIED; +                        break; +                  case UndoOp::ModifyPartTick: // TODO FIXME (?) do port ctrls/clones? +                        i->part->setTick(i->old_partlen_or_tick); +                        updateFlags |= SC_PART_MODIFIED; +                        break; +                  case UndoOp::ModifyPartLength: // TODO FIXME (?) do port ctrls/clones? +                        i->part->setLenTick(i->old_partlen_or_tick); +                        updateFlags |= SC_PART_MODIFIED; +                        break; +                  case UndoOp::ModifyPartLengthFrames: // TODO FIXME  FINDMICH frames deprecated!   do port ctrls/clones? +                        i->part->setLenFrame(i->old_partlen_or_tick);                          updateFlags |= SC_PART_MODIFIED;                          break;                    case UndoOp::AddEvent: @@ -484,26 +485,31 @@ void Song::doRedo2()                          }                          break;                    case UndoOp::AddPart: -                        addPart(i->oPart); +                        addPart(i->part);                          updateFlags |= SC_PART_INSERTED; -                        i->oPart->events()->incARef(1); -                        chainClone(i->oPart); +                        i->part->events()->incARef(1); +                        chainClone(i->part);                          break;                    case UndoOp::DeletePart: -                        removePart(i->oPart); +                        removePart(i->part);                          updateFlags |= SC_PART_REMOVED; -                        i->oPart->events()->incARef(-1); -                        unchainClone(i->oPart); +                        i->part->events()->incARef(-1); +                        unchainClone(i->part);                          break; -                  case UndoOp::ModifyPart: -                        if(i->doCtrls) -                          removePortCtrlEvents(i->oPart, i->doClones); -                        changePart(i->oPart, i->nPart); -                        i->nPart->events()->incARef(1); -                        i->oPart->events()->incARef(-1); -                        replaceClone(i->oPart, i->nPart); -                        if(i->doCtrls) -                          addPortCtrlEvents(i->nPart, i->doClones); +                  case UndoOp::ModifyPartName: +                        i->part->setName(i->_newName); +                        updateFlags |= SC_PART_MODIFIED; +                        break; +                  case UndoOp::ModifyPartTick: // TODO FIXME (?) do port ctrls/clones? +                        i->part->setTick(i->new_partlen_or_tick); +                        updateFlags |= SC_PART_MODIFIED; +                        break; +                  case UndoOp::ModifyPartLength: // TODO FIXME (?) do port ctrls/clones? +                        i->part->setLenTick(i->new_partlen_or_tick); +                        updateFlags |= SC_PART_MODIFIED; +                        break; +                  case UndoOp::ModifyPartLengthFrames: // TODO FIXME  FINDMICH frames deprecated!   do port ctrls/clones? +                        i->part->setLenFrame(i->new_partlen_or_tick);                          updateFlags |= SC_PART_MODIFIED;                          break;                    case UndoOp::AddEvent: @@ -590,10 +596,12 @@ UndoOp::UndoOp(UndoType type_, int n, Track* track_)        track  = track_;        } -UndoOp::UndoOp(UndoType type_, Part* part) +UndoOp::UndoOp(UndoType type_, Part* part, unsigned old_len_or_tick, unsigned new_len_or_tick, bool, bool)        {        type  = type_; -      oPart = part; +      part = part; +      old_partlen_or_tick=old_len_or_tick; +      new_partlen_or_tick=new_len_or_tick;        }  UndoOp::UndoOp(UndoType type_, Event& oev, Event& nev, Part* part_, bool doCtrls_, bool doClones_) @@ -615,15 +623,6 @@ UndoOp::UndoOp(UndoType type_, Event& nev, Part* part_, bool doCtrls_, bool doCl        doClones = doClones_;        } -UndoOp::UndoOp(UndoType type_, Part* oPart_, Part* nPart_, bool doCtrls_, bool doClones_) -      { -      type  = type_; -      oPart = oPart_; -      nPart = nPart_; -      doCtrls = doCtrls_; -      doClones = doClones_; -      } -  UndoOp::UndoOp(UndoType type_, int c, int ctrl_, int ov, int nv)        {        type    = type_; @@ -649,10 +648,20 @@ UndoOp::UndoOp(UndoType type_, const char* changedFile, const char* changeData,        endframe   = endframe_;        } +UndoOp::UndoOp(UndoOp::UndoType type_, Part* part_, const char* old_name, const char* new_name) +{ +    type=type_; +    part=part_; +    _oldName = new char[strlen(old_name) + 1]; +    _newName = new char[strlen(new_name) + 1]; +    strcpy(_oldName, old_name); +    strcpy(_newName, new_name); +} +  UndoOp::UndoOp(UndoOp::UndoType type_, Track* track_, const char* old_name, const char* new_name)  {    type = type_; -  _renamedTrack = track_; +  track = track_;    _oldName = new char[strlen(old_name) + 1];    _newName = new char[strlen(new_name) + 1];    strcpy(_oldName, old_name); @@ -727,7 +736,7 @@ bool Song::doUndo1()                          break;                    case UndoOp::ModifyTrackName: -                          i->_renamedTrack->setName(i->_oldName); +                          i->track->setName(i->_oldName);                            updateFlags |= SC_TRACK_MODIFIED;                          break;                    case UndoOp::ModifyClip: @@ -851,7 +860,7 @@ bool Song::doRedo1()                          removeTrack1(i->track);                          break;                    case UndoOp::ModifyTrackName: -                          i->_renamedTrack->setName(i->_newName); +                          i->track->setName(i->_newName);                            updateFlags |= SC_TRACK_MODIFIED;                          break;                    case UndoOp::ModifyClip: diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h index 2f582d8e..4fded825 100644 --- a/muse2/muse/undo.h +++ b/muse2/muse/undo.h @@ -46,7 +46,7 @@ extern std::list<QString> temporaryWavFiles; //!< Used for storing all tmp-files  struct UndoOp {        enum UndoType {              AddTrack, DeleteTrack, -            AddPart,  DeletePart,  ModifyPart, +            AddPart,  DeletePart,  ModifyPartTick, ModifyPartLength, ModifyPartLengthFrames, /* FINDMICH FIXME frames are to be deprecated */ ModifyPartName,              AddEvent, DeleteEvent, ModifyEvent,              AddTempo, DeleteTempo,              AddSig,   DeleteSig, @@ -71,11 +71,9 @@ struct UndoOp {                    int trackno;                    };              struct { -                  Part* oPart; -                  Part* nPart; -                  }; -            struct { -                  Part* part; // this part is only relevant for EVENT operations, NOT for part ops! +                  Part* part; +                  unsigned old_partlen_or_tick; // FIXME FINDMICHJETZT XTicks!! +                  unsigned new_partlen_or_tick;                    };              struct {                    int channel; @@ -94,16 +92,14 @@ struct UndoOp {                    Marker* copyMarker;                  };              struct { -                  Track* _renamedTrack; -                  char* _oldName; -                  char* _newName; -                }; -            struct {                    Track* _propertyTrack;                    int _oldPropValue;                    int _newPropValue;                  };              }; + +      char* _oldName; +      char* _newName;        Event oEvent;        Event nEvent;        bool doCtrls; @@ -115,10 +111,11 @@ struct UndoOp {        UndoOp();        UndoOp(UndoType type, int a, int b, int c=0);        UndoOp(UndoType type, int n, Track* track); -      UndoOp(UndoType type, Part* part); +      UndoOp(UndoType type, Part* part, unsigned old_len_or_tick=-1, unsigned new_len_or_tick=-1, bool doCtrls=false, bool doClones=false); // FIXME these bools are UNUSED!! +      UndoOp(UndoType type, Part* part, const char* old_name, const char* new_name);        UndoOp(UndoType type, Event& oev, Event& nev, Part* part, bool doCtrls, bool doClones);        UndoOp(UndoType type, Event& nev, Part* part, bool doCtrls, bool doClones); -      UndoOp(UndoType type, Part* oPart, Part* nPart, bool doCtrls, bool doClones); +      UndoOp(UndoType type, Part* part, unsigned tick, bool doCtrls, bool doClones); // FIXME FINDMICHJETZT XTicks!        UndoOp(UndoType type, int c, int ctrl, int ov, int nv);        UndoOp(UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe);        UndoOp(UndoType type, Marker* copyMarker, Marker* realMarker); | 
