void redo() { if (_redoStack.empty()) { rMessage() << "Redo: no redo available" << std::endl; } else { Operation* operation = _redoStack.back(); rMessage() << "Redo: " << operation->_command << std::endl; startUndo(); trackersRedo(); operation->_snapshot.restore(); finishUndo(operation->_command); _redoStack.pop_back(); for (Observers::iterator i = _observers.begin(); i != _observers.end(); /* in-loop */) { Observer* observer = *(i++); observer->postRedo(); } // Trigger the onPostUndo event on all scene nodes PostRedoWalker walker; GlobalSceneGraph().root()->traverse(walker); GlobalSceneGraph().sceneChanged(); } }
void start(){ m_redo_stack.clear(); if ( m_undo_stack.size() == m_undo_levels ) { m_undo_stack.pop_front(); } startUndo(); trackersBegin(); }
void start() { _redoStack.clear(); if (_undoStack.size() == _undoLevels) { _undoStack.pop_front(); } startUndo(); trackersBegin(); }
void Song::cmdGluePart(Track* track, Part* oPart) { PartList* pl = track->parts(); Part* nextPart = 0; for (iPart ip = pl->begin(); ip != pl->end(); ++ip) { if (ip->second == oPart) { ++ip; if (ip == pl->end()) return; nextPart = ip->second; break; } } Part* nPart = track->newPart(oPart); nPart->setLenTick(nextPart->tick() + nextPart->lenTick() - oPart->tick()); // populate nPart with Events from oPart and nextPart EventList* sl1 = oPart->events(); EventList* dl = nPart->events(); for (iEvent ie = sl1->begin(); ie != sl1->end(); ++ie) dl->add(ie->second); EventList* sl2 = nextPart->events(); //int frameOffset = nextPart->frame() - oPart->frame(); //for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie) { // Event event = ie->second.clone(); // event.setFrame(event.frame() + frameOffset); // dl->add(event); // } // p3.3.54 Changed. { int tickOffset = nextPart->tick() - oPart->tick(); for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie) { Event event = ie->second.clone(); event.setTick(event.tick() + tickOffset); dl->add(event); } } startUndo(); audio->msgRemovePart(nextPart, false); // Indicate no undo, and do port controller values but not clone parts. //audio->msgChangePart(oPart, nPart, false); audio->msgChangePart(oPart, nPart, false, true, false); endUndo(SC_PART_MODIFIED | SC_PART_REMOVED); }
void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len)/*{{{*/ { { startUndo(); MidiPart* nPart = new MidiPart(*(MidiPart*) oPart); nPart->setLenTick(len); // Indicate no undo, and do port controller values but not clone parts. audio->msgChangePart(oPart, nPart, false, true, false); // cut Events in nPart // Changed by T356. Don't delete events if this is a clone part. // The other clones might be longer than this one and need these events. if (nPart->cevents()->arefCount() <= 1) { if (oPart->lenTick() > len) { EventList* el = nPart->events(); iEvent ie = el->lower_bound(len); for (; ie != el->end();) { iEvent i = ie; ++ie; // Indicate no undo, and do port controller values and clone parts. audio->msgDeleteEvent(i->second, nPart, false, true, true); } } } /* // cut Events in nPart // Changed by T356. Don't delete events if this is a clone part. // The other clones might be longer than this one and need these events. if(oPart->cevents()->arefCount() <= 1) { if (oPart->lenTick() > len) { EventList* el = nPart->events(); iEvent ie = el->lower_bound(len); for (; ie != el->end();) { iEvent i = ie; ++ie; // Indicate no undo, and do not do port controller values and clone parts. //audio->msgDeleteEvent(i->second, nPart, false); audio->msgDeleteEvent(i->second, nPart, false, false, false); } } } // Indicate no undo, and do port controller values but not clone parts. //audio->msgChangePart(oPart, nPart, false); audio->msgChangePart(oPart, nPart, false, true, false); */ endUndo(SC_PART_MODIFIED); } }/*}}}*/
void redo(){ if ( m_redo_stack.empty() ) { globalOutputStream() << "Redo: no redo available\n"; } else { Operation* operation = m_redo_stack.back(); globalOutputStream() << "Redo: " << operation->m_command.c_str() << "\n"; startUndo(); trackersRedo(); operation->m_snapshot.restore(); finishUndo( operation->m_command.c_str() ); m_redo_stack.pop_back(); } }
void Song::cmdSplitPart(Track* track, Part* part, int tick) { int l1 = tick - part->tick(); int l2 = part->lenTick() - l1; if (l1 <= 0 || l2 <= 0) return; Part* p1; Part* p2; track->splitPart(part, tick, p1, p2); startUndo(); // Indicate no undo, and do port controller values but not clone parts. //audio->msgChangePart(part, p1, false); audio->msgChangePart(part, p1, false, true, false); audio->msgAddPart(p2, false); endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED); }
void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len) { switch (track->type()) { case Track::WAVE: { WavePart* nPart = new WavePart(*(WavePart*) oPart); EventList* el = nPart->events(); unsigned new_partlength = tempomap.deltaTick2frame(oPart->tick(), oPart->tick() + len); //printf("new partlength in frames: %d\n", new_partlength); // 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 if (new_partlength < oPart->lenFrame()) { startUndo(); for (iEvent i = el->begin(); i != el->end(); i++) { Event e = i->second; unsigned event_startframe = e.frame(); unsigned event_endframe = event_startframe + e.lenFrame(); //printf("Event frame=%d, length=%d\n", event_startframe, event_length); if (event_endframe < new_partlength) continue; if (event_startframe > new_partlength) { // If event start was after the new length, remove it from part // Indicate no undo, and do not do port controller values and clone parts. //audio->msgDeleteEvent(e, nPart, false); audio->msgDeleteEvent(e, nPart, false, false, false); continue; } if (event_endframe > new_partlength) { // If this event starts before new length and ends after, shrink it Event newEvent = e.clone(); newEvent.setLenFrame(new_partlength - event_startframe); // Indicate no undo, and do not do port controller values and clone parts. //audio->msgChangeEvent(e, newEvent, nPart, false); audio->msgChangeEvent(e, newEvent, nPart, false, false, false); } } nPart->setLenFrame(new_partlength); // Indicate no undo, and do not do port controller values and clone parts. //audio->msgChangePart(oPart, nPart, false); audio->msgChangePart(oPart, nPart, false, false, false); endUndo(SC_PART_MODIFIED); } // If the part is expanded there can be no additional events beginning after the previous final position // since those are removed if the part has been shrunk at some time (see above) // The only thing we need to check is the final event: If it has data after the previous final position, // we'll expand that event else { if (!el->empty()) { iEvent i = el->end(); i--; Event last = i->second; unsigned last_start = last.frame(); SndFileR file = last.sndFile(); if (file.isNull()) return; unsigned clipframes = (file.samples() - last.spos()); // / file.channels(); Event newEvent = last.clone(); //printf("SndFileR samples=%d channels=%d event samplepos=%d clipframes=%d\n", file.samples(), file.channels(), last.spos(), clipframes); unsigned new_eventlength = new_partlength - last_start; if (new_eventlength > clipframes) // Shrink event length if new partlength exceeds last clip new_eventlength = clipframes; newEvent.setLenFrame(new_eventlength); startUndo(); // Indicate no undo, and do not do port controller values and clone parts. //audio->msgChangeEvent(last, newEvent, nPart, false); audio->msgChangeEvent(last, newEvent, nPart, false, false, false); } else { startUndo(); } nPart->setLenFrame(new_partlength); // Indicate no undo, and do not do port controller values and clone parts. //audio->msgChangePart(oPart, nPart, false); audio->msgChangePart(oPart, nPart, false, false, false); endUndo(SC_PART_MODIFIED); } } break; case Track::MIDI: case Track::DRUM: { startUndo(); MidiPart* nPart = new MidiPart(*(MidiPart*) oPart); nPart->setLenTick(len); // Indicate no undo, and do port controller values but not clone parts. audio->msgChangePart(oPart, nPart, false, true, false); // cut Events in nPart // Changed by T356. Don't delete events if this is a clone part. // The other clones might be longer than this one and need these events. if (nPart->cevents()->arefCount() <= 1) { if (oPart->lenTick() > len) { EventList* el = nPart->events(); iEvent ie = el->lower_bound(len); for (; ie != el->end();) { iEvent i = ie; ++ie; // Indicate no undo, and do port controller values and clone parts. audio->msgDeleteEvent(i->second, nPart, false, true, true); } } } /* // cut Events in nPart // Changed by T356. Don't delete events if this is a clone part. // The other clones might be longer than this one and need these events. if(oPart->cevents()->arefCount() <= 1) { if (oPart->lenTick() > len) { EventList* el = nPart->events(); iEvent ie = el->lower_bound(len); for (; ie != el->end();) { iEvent i = ie; ++ie; // Indicate no undo, and do not do port controller values and clone parts. //audio->msgDeleteEvent(i->second, nPart, false); audio->msgDeleteEvent(i->second, nPart, false, false, false); } } } // Indicate no undo, and do port controller values but not clone parts. //audio->msgChangePart(oPart, nPart, false); audio->msgChangePart(oPart, nPart, false, true, false); */ endUndo(SC_PART_MODIFIED); break; } default: break; } }