summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse2/muse/app.cpp15
-rw-r--r--muse2/muse/arranger/pcanvas.cpp180
-rw-r--r--muse2/muse/arranger/pcanvas.h8
-rw-r--r--muse2/muse/audio.h6
-rw-r--r--muse2/muse/functions.cpp2
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp3
-rw-r--r--muse2/muse/seqmsg.cpp20
-rw-r--r--muse2/muse/undo.cpp7
-rw-r--r--muse2/muse/undo.h4
9 files changed, 110 insertions, 135 deletions
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp
index 72cdad6a..04c55b01 100644
--- a/muse2/muse/app.cpp
+++ b/muse2/muse/app.cpp
@@ -2971,14 +2971,13 @@ void MusE::cmd(int cmd)
arranger->cmd(Arranger::CMD_INSERT_EMPTYMEAS);
break;
case CMD_DELETE:
- song->startUndo();
- if (song->msgRemoveParts()) {
- song->endUndo(SC_PART_REMOVED);
- break;
- }
- else
- audio->msgRemoveTracks();
- song->endUndo(SC_TRACK_REMOVED);
+ if (!song->msgRemoveParts()) //automatically does undo if neccessary and returns true then
+ {
+ //msgRemoveParts() returned false -> no parts to remove?
+ song->startUndo();
+ audio->msgRemoveTracks(); //TODO FINDME this could still be speeded up!
+ song->endUndo(SC_TRACK_REMOVED);
+ }
break;
case CMD_DELETE_TRACK:
song->startUndo();
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp
index 54f431cc..e17d08e1 100644
--- a/muse2/muse/arranger/pcanvas.cpp
+++ b/muse2/muse/arranger/pcanvas.cpp
@@ -259,8 +259,10 @@ void PartCanvas::updateSong(DragType t, int flags)
// moveCanvasItems
//---------------------------------------------------------
-void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int*)
+void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype)
{
+ Undo operations;
+
for(iCItem ici = items.begin(); ici != items.end(); ++ici)
{
CItem* ci = ici->second;
@@ -278,15 +280,21 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp
QPoint newpos = raster(QPoint(nx, ny));
selectItem(ci, true);
- if (moveItem(ci, newpos, dtype))
+ UndoOp operation=moveItem(ci, newpos, dtype);
+ if (operation.type != UndoOp::DoNothing)
+ {
ci->move(newpos);
+ operations.push_back(operation);
+ }
if(moving.size() == 1) {
itemReleased(curItem, newpos);
}
if(dtype == MOVE_COPY || dtype == MOVE_CLONE)
selectItem(ci, false);
- }
+ }
+
+ song->applyOperationGroup(operations);
}
//---------------------------------------------------------
@@ -295,7 +303,7 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp
//---------------------------------------------------------
// Changed by T356.
-bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t)
+UndoOp PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t)
{
UndoOp result;
NPart* npart = (NPart*) item;
@@ -305,7 +313,7 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t)
unsigned ntrack = y2pitch(item->mp().y());
Track::TrackType type = track->type();
if (tracks->index(track) == ntrack && (dtick == spart->tick())) {
- return false; //FINDMICH
+ return UndoOp(UndoOp::DoNothing);
}
if (ntrack >= tracks->size()) {
ntrack = tracks->size();
@@ -323,7 +331,7 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t)
if (dtrack->type() != type) {
QMessageBox::critical(this, QString("MusE"),
tr("Cannot copy/move/clone to different Track-Type"));
- return false; //FINDMICH
+ return UndoOp(UndoOp::DoNothing);
}
Part* dpart;
@@ -341,6 +349,8 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t)
// 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->events()->incARef(-1); // the later song->applyOperationGroup() will increment it
+ // so we must decrement it first :/
dpart->setTick(dtick);
@@ -359,33 +369,24 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t)
}
}
if (t == MOVE_COPY || t == MOVE_CLONE) {
- // These will not increment ref count, and will not chain clones...
- if (dtrack->type() == Track::WAVE)
- audio->msgAddPart((WavePart*)dpart,false);
- else
- audio->msgAddPart(dpart,false);
+ // These will not increment ref count, and will not chain clones...
+ // TODO: is this still correct (by flo93)?
+ result=UndoOp(UndoOp::AddPart,dpart);
}
else if (t == MOVE_MOVE) {
dpart->setSelected(spart->selected());
// These will increment ref count if not a clone, and will chain clones...
-
- if (dtrack->type() == Track::WAVE) {
- // Indicate no undo, and do not do port controller values and clone parts.
- audio->msgChangePart((WavePart*)spart, (WavePart*)dpart, false, false, false);
- }
- else {
- // Indicate no undo, and do port controller values but not clone parts.
- audio->msgChangePart(spart, dpart, false, true, false);
- }
+ // TODO: is this still correct (by flo93)?
+ result=UndoOp(UndoOp::ModifyPart,spart, dpart, true, false);
+
spart->setSelected(false);
-
}
+ // else // will never happen -> result will always be defined
if (song->len() < (dpart->lenTick() + dpart->tick()))
song->setLen(dpart->lenTick() + dpart->tick());
- return true; //FINDMICH
- //TODO FINDMICH returns nothing... should be fixed (flo93)
+ return result;
}
//---------------------------------------------------------
@@ -521,7 +522,7 @@ void PartCanvas::newItem(CItem* i, bool noSnap)
len = AL::sigmap.rasterStep(p->tick(), *_raster);
p->setLenTick(len);
p->setSelected(true);
- audio->msgAddPart(p);
+ audio->msgAddPart(p, true); //indicate undo
}
//---------------------------------------------------------
@@ -531,7 +532,7 @@ void PartCanvas::newItem(CItem* i, bool noSnap)
bool PartCanvas::deleteItem(CItem* i)
{
Part* p = ((NPart*)(i))->part();
- audio->msgRemovePart(p); //Invokes songChanged which calls partsChanged which makes it difficult to delete them there
+ audio->msgRemovePart(p, true); //Invokes songChanged which calls partsChanged which makes it difficult to delete them there
return true;
}
@@ -712,11 +713,9 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt)
Event ev = oldEvent.clone();
de->add(ev);
}
- song->startUndo();
- // Indicate no undo, and do port controller values but not clone parts.
- audio->msgChangePart(spart, dpart, false, true, false);
-
- song->endUndo(SC_PART_MODIFIED);
+ // Indicate undo, and do port controller values but not clone parts.
+ // changed by flo93: removed start and endUndo, instead changed first bool to true
+ audio->msgChangePart(spart, dpart, true, true, false);
break; // Has to be break here, right?
}
case 16: // Export to file
@@ -929,14 +928,10 @@ void PartCanvas::keyPress(QKeyEvent* event)
key += Qt::CTRL;
if (key == shortcuts[SHRT_DELETE].key) {
- if (getCurrentDrag()) {
- //printf("dragging!!\n");
+ if (getCurrentDrag())
return;
- }
- song->startUndo();
song->msgRemoveParts();
- song->endUndo(SC_PART_REMOVED);
return;
}
else if (key == shortcuts[SHRT_POS_DEC].key) {
@@ -1807,26 +1802,23 @@ void PartCanvas::cmd(int cmd)
}
switch (cmd) {
case CMD_CUT_PART:
+ {
copy(&pl);
- song->startUndo();
- bool loop;
- do
- {
- loop = false;
- for (iCItem i = items.begin(); i != items.end(); ++i) {
- if (!i->second->isSelected())
- continue;
- NPart* p = (NPart*)(i->second);
- Part* part = p->part();
- audio->msgRemovePart(part);
-
- loop = true;
- break;
- }
- } while (loop);
- song->endUndo(SC_PART_REMOVED);
+ Undo operations;
+
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (i->second->isSelected()) {
+ NPart* p = (NPart*)(i->second);
+ Part* part = p->part();
+ operations.push_back(UndoOp(UndoOp::DeletePart, part));
+ }
+ }
+
+ song->applyOperationGroup(operations);
+
break;
+ }
case CMD_COPY_PART:
copy(&pl);
break;
@@ -1846,11 +1838,10 @@ void PartCanvas::cmd(int cmd)
paste(false, false, true);
break;
case CMD_INSERT_EMPTYMEAS:
- song->startUndo();
int startPos=song->vcpos();
int oneMeas=AL::sigmap.ticksMeasure(startPos);
- movePartsTotheRight(startPos,oneMeas);
- song->endUndo(SC_PART_INSERTED);
+ Undo temp=movePartsTotheRight(startPos,oneMeas);
+ song->applyOperationGroup(temp);
break;
}
}
@@ -1947,8 +1938,10 @@ void PartCanvas::copy(PartList* pl)
// pasteAt
//---------------------------------------------------------
-int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool clone, bool toTrack)
+Undo PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool clone, bool toTrack, int* finalPosPtr)
{
+ Undo operations;
+
QByteArray ba = pt.toLatin1();
const char* ptxt = ba.constData();
Xml xml(ptxt);
@@ -1959,7 +1952,6 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool
int done = 0;
bool end = false;
- //song->startUndo();
for (;;) {
Xml::Token token = xml.parse();
const QString& tag = xml.s1();
@@ -1973,6 +1965,7 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool
// Read the part.
Part* p = 0;
p = readXmlPart(xml, track, clone, toTrack);
+
// If it could not be created...
if(!p)
{
@@ -1980,6 +1973,9 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool
++notDone;
break;
}
+
+ p->events()->incARef(-1); // the later song->applyOperationGroup() will increment it
+ // so we must decrement it first :/
// Increment the number of parts done.
++done;
@@ -1992,8 +1988,7 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool
if (p->tick()+p->lenTick()>finalPos) {
finalPos=p->tick()+p->lenTick();
}
- //pos += p->lenTick();
- audio->msgAddPart(p,false);
+ operations.push_back(UndoOp(UndoOp::AddPart,p));
}
else
xml.unknown("PartCanvas::pasteAt");
@@ -2008,8 +2003,6 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool
break;
}
- //song->endUndo(SC_PART_INSERTED);
- //return pos;
if(notDone)
{
@@ -2020,7 +2013,8 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool
tr(" could not be pasted.\nLikely the selected track is the wrong type."));
}
- return finalPos;
+ if (finalPosPtr) *finalPosPtr=finalPos;
+ return operations;
}
@@ -2110,30 +2104,30 @@ void PartCanvas::paste(bool clone, bool toTrack, bool doInsert)
return;
}
- int endPos=0;
- unsigned int startPos=song->vcpos();
if (!txt.isEmpty())
{
- song->startUndo();
- endPos=pasteAt(txt, track, startPos, clone, toTrack);
+ int endPos=0;
+ unsigned int startPos=song->vcpos();
+ Undo operations=pasteAt(txt, track, startPos, clone, toTrack, &endPos);
Pos p(endPos, true);
song->setPos(0, p);
- if (!doInsert)
- song->endUndo(SC_PART_INSERTED);
+ if (doInsert) {
+ int offset = endPos-startPos;
+ Undo temp=movePartsTotheRight(startPos, offset);
+ operations.insert(operations.end(), temp.begin(), temp.end());
+ }
+ song->applyOperationGroup(operations);
}
- if (doInsert) {
- int offset = endPos-startPos;
- movePartsTotheRight(startPos, offset);
- song->endUndo(SC_PART_INSERTED);
- }
}
//---------------------------------------------------------
// movePartsToTheRight
//---------------------------------------------------------
-void PartCanvas::movePartsTotheRight(unsigned int startTicks, int length)
+Undo PartCanvas::movePartsTotheRight(unsigned int startTicks, int length)
{
+ Undo operations;
+
// all parts that start after the pasted parts will be moved the entire length of the pasted parts
for (iCItem i = items.begin(); i != items.end(); ++i) {
if (!i->second->isSelected()) {
@@ -2141,12 +2135,8 @@ void PartCanvas::movePartsTotheRight(unsigned int startTicks, int length)
if (part->tick() >= startTicks) {
Part *newPart = part->clone();
newPart->setTick(newPart->tick()+length);
- if (part->track()->type() == Track::WAVE) {
- audio->msgChangePart((WavePart*)part,(WavePart*)newPart,false,false,false);
- } else {
- audio->msgChangePart(part,newPart,false,false,false);
- }
-
+
+ operations.push_back(UndoOp(UndoOp::ModifyPart,part,newPart,false,false));
}
}
}
@@ -2159,9 +2149,11 @@ void PartCanvas::movePartsTotheRight(unsigned int startTicks, int length)
Marker *oldMarker = new Marker();
*oldMarker = *m;
m->setTick(m->tick()+length);
- song->addUndo(UndoOp(UndoOp::ModifyMarker,oldMarker, m));
+ operations.push_back(UndoOp(UndoOp::ModifyMarker,oldMarker, m));
}
}
+
+ return operations;
}
//---------------------------------------------------------
// startDrag
@@ -2284,11 +2276,11 @@ void PartCanvas::viewDropEvent(QDropEvent* event)
Track* track = 0;
if (trackNo < tracks->size())
track = tracks->index(trackNo);
- if (track) {
- song->startUndo();
- pasteAt(text, track, x);
- song->endUndo(SC_PART_INSERTED);
- }
+ if (track)
+ {
+ Undo temp=pasteAt(text, track, x);
+ song->applyOperationGroup(temp);
+ }
}
else if (type == 2)
{
@@ -2967,8 +2959,6 @@ double PartCanvas::valToDb(double inV)
void PartCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir)
{
- song->startUndo();
-
int dp = y2pitch(pos.y()) - y2pitch(start.y());
int dx = pos.x() - start.x();
@@ -2976,19 +2966,9 @@ void PartCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir)
dp = 0;
else if (dir == 2)
dx = 0;
+
+ moveCanvasItems(moving, dp, dx, dragtype);
-
-
- int modified = 0;
-
- moveCanvasItems(moving, dp, dx, dragtype, &modified);
-
- if (dragtype == MOVE_COPY || dragtype == MOVE_CLONE)
- modified|=SC_PART_INSERTED;
- else
- modified|=SC_PART_MODIFIED;
-
- song->endUndo(modified);
moving.clear();
updateSelection();
redraw();
diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h
index daa244b2..acfe565e 100644
--- a/muse2/muse/arranger/pcanvas.h
+++ b/muse2/muse/arranger/pcanvas.h
@@ -86,8 +86,8 @@ class PartCanvas : public Canvas {
virtual void resizeItem(CItem*,bool);
virtual void newItem(CItem*,bool);
virtual bool deleteItem(CItem*);
- virtual void moveCanvasItems(CItemList&, int, int, DragType, int*);
- virtual bool moveItem(CItem*, const QPoint&, DragType);
+ virtual void moveCanvasItems(CItemList&, int, int, DragType);
+ virtual UndoOp moveItem(CItem*, const QPoint&, DragType);
virtual void updateSong(DragType, int);
virtual void startDrag(CItem*, DragType);
@@ -102,8 +102,8 @@ class PartCanvas : public Canvas {
void copy(PartList*);
void paste(bool clone = false, bool toTrack = true, bool doInsert=false);
- int pasteAt(const QString&, Track*, unsigned int, bool clone = false, bool toTrack = true);
- void movePartsTotheRight(unsigned int startTick, int length);
+ Undo pasteAt(const QString&, Track*, unsigned int, bool clone = false, bool toTrack = true, int* finalPosPtr = NULL);
+ Undo movePartsTotheRight(unsigned int startTick, int length);
//Part* readClone(Xml&, Track*, bool toTrack = true);
void drawWavePart(QPainter&, const QRect&, WavePart*, const QRect&);
//void drawMidiPart(QPainter&, const QRect& rect, EventList* events, MidiTrack*mt, const QRect& r, int pTick, int from, int to);
diff --git a/muse2/muse/audio.h b/muse2/muse/audio.h
index 940dd2a5..e332f516 100644
--- a/muse2/muse/audio.h
+++ b/muse2/muse/audio.h
@@ -124,7 +124,6 @@ class Audio {
bool idle; // do nothing in idle mode
bool _freewheel;
bool _bounce;
- //bool loopPassed;
unsigned _loopFrame; // Startframe of loop if in LOOP mode. Not quite the same as left marker !
int _loopCount; // Number of times we have looped so far
@@ -202,13 +201,9 @@ class Audio {
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);
void msgChangePart(Part* oldPart, Part* newPart, bool u = true, bool doCtrls = true, bool doClones = false);
- //void msgAddEvent(Event&, Part*, bool u = true);
void msgAddEvent(Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false);
- //void msgDeleteEvent(Event&, Part*, bool u = true);
void msgDeleteEvent(Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false);
- //void msgChangeEvent(Event&, Event&, Part*, bool u = true);
void msgChangeEvent(Event&, Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false);
void msgScanAlsaMidiPorts();
void msgAddTempo(int tick, int tempo, bool doUndoFlag = true);
@@ -250,7 +245,6 @@ class Audio {
void msgResetMidiDevices();
void msgIdle(bool);
void msgBounce();
- //void msgSetPluginCtrlVal(PluginI* /*plugin*/, int /*param*/, double /*val*/);
void msgSetPluginCtrlVal(AudioTrack*, int /*param*/, double /*val*/);
void msgSwapControllerIDX(AudioTrack*, int, int);
void msgClearControllerEvents(AudioTrack*, int);
diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp
index 4a65d19c..a6c9c95a 100644
--- a/muse2/muse/functions.cpp
+++ b/muse2/muse/functions.cpp
@@ -759,7 +759,7 @@ void paste_at(Part* dest_part, const QString& pt, int pos)
goto end_of_paste_at;
}
else
- xml.unknown("pasteAt");
+ xml.unknown("paste_at");
break;
case Xml::Attribut:
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 0ec300cf..ca88d36a 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -4457,7 +4457,8 @@ void staff_t::update_part_indices()
*
* CURRENT TODO
* o speed up list editor
- * o speed up arranger
+ * o insert empty measure should also work inside parts
+ * o canvas editor: create clone via "alt+drag" moves window instead
*
* o rename stuff: UndoOp -> Operation, Undo -> OpList,
* UndoType -> OpType, iUndoOp, riUndoOp -> iOperation,
diff --git a/muse2/muse/seqmsg.cpp b/muse2/muse/seqmsg.cpp
index 0aa74aaa..57aadc18 100644
--- a/muse2/muse/seqmsg.cpp
+++ b/muse2/muse/seqmsg.cpp
@@ -893,31 +893,23 @@ void Audio::msgRemovePart(Part* part, bool doUndoFlag)
bool Song::msgRemoveParts()
{
- bool loop;
+ Undo operations;
bool partSelected = false;
- do {
- loop = false;
+
TrackList* tl = song->tracks();
for (iTrack it = tl->begin(); it != tl->end(); ++it) {
PartList* pl = (*it)->parts();
for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
if (ip->second->selected()) {
- if ((*it)->type() == Track::WAVE) {
- audio->msgRemovePart((WavePart*)(ip->second));
- }
- else {
- audio->msgRemovePart(ip->second, false);
- }
- loop = true;
+ operations.push_back(UndoOp(UndoOp::DeletePart,ip->second));
partSelected = true;
- break;
}
}
- if (loop)
- break;
}
- } while (loop);
+
+ song->applyOperationGroup(operations);
+
return partSelected;
}
diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp
index c57bb5c1..c5b211b2 100644
--- a/muse2/muse/undo.cpp
+++ b/muse2/muse/undo.cpp
@@ -480,6 +480,7 @@ void Song::doUndo2()
break;
case UndoOp::ModifyClip:
case UndoOp::ModifyMarker:
+ case UndoOp::DoNothing:
break;
}
}
@@ -716,6 +717,7 @@ void Song::doRedo2()
break;
case UndoOp::ModifyClip:
case UndoOp::ModifyMarker:
+ case UndoOp::DoNothing:
break;
}
}
@@ -725,6 +727,11 @@ UndoOp::UndoOp()
{
}
+UndoOp::UndoOp(UndoType type_)
+{
+ type = type_;
+}
+
UndoOp::UndoOp(UndoType type_, int a_, int b_, int c_)
{
type = type_;
diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h
index 88810b80..b8f69d9f 100644
--- a/muse2/muse/undo.h
+++ b/muse2/muse/undo.h
@@ -36,7 +36,8 @@ struct UndoOp {
AddKey, DeleteKey,
SwapTrack,
ModifyClip,
- ModifyMarker
+ ModifyMarker,
+ DoNothing
};
UndoType type;
@@ -99,6 +100,7 @@ struct UndoOp {
UndoOp(UndoType type, SigEvent* oevent, SigEvent* nevent);
UndoOp(UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe);
UndoOp(UndoType type, Marker* copyMarker, Marker* realMarker);
+ UndoOp(UndoType type);
};
class Undo : public std::list<UndoOp> {