xybrid/xybrid/editing/projectcommands.cpp

146 lines
5.3 KiB
C++

#include "projectcommands.h"
#include "uisocket.h"
#include "mainwindow.h"
#include <QDebug>
#include <QUndoStack>
using Xybrid::Data::Project;
using Xybrid::Data::Pattern;
using namespace Xybrid::Editing;
bool ProjectCommand::commit() {
if (!project->socket || !project->socket->undoStack) return cancel();
project->socket->undoStack->push(this);
return true;
}
bool ProjectCommand::cancel() {
delete this;
return false;
}
ProjectSequencerDeltaCommand::ProjectSequencerDeltaCommand(const std::shared_ptr<Project>& project_) {
project = project_;
oldSeq = project->sequence;
oldSeqSel = project->socket->window->sequenceSelection();
seq = oldSeq;
seqSel = oldSeqSel;
setText("edit sequence");
}
bool ProjectSequencerDeltaCommand::mergeWith(const QUndoCommand* o_) {
if (o_->id() != id()) return false;
auto* o = static_cast<const ProjectSequencerDeltaCommand*>(o_);
if (o->project != project) return false;
seq = o->seq;
seqSel = o->seqSel;
return true;
}
void ProjectSequencerDeltaCommand::redo() {
project->sequence = seq;
emit project->socket->updatePatternLists();
project->socket->window->sequenceSelection(seqSel);
}
void ProjectSequencerDeltaCommand::undo() {
project->sequence = oldSeq;
emit project->socket->updatePatternLists();
project->socket->window->sequenceSelection(oldSeqSel);
}
ProjectPatternMoveCommand::ProjectPatternMoveCommand(const std::shared_ptr<Project>& project_, int f, int t) {
project = project_;
from = f;
to = t;
setText("move pattern");
}
bool ProjectPatternMoveCommand::mergeWith(const QUndoCommand* o_) {
if (o_->id() != id()) return false;
auto* o = static_cast<const ProjectPatternMoveCommand*>(o_);
if (o->project != project) return false;
to = o->to;
return true;
}
void ProjectPatternMoveCommand::redo() {
bool move = project->socket->window->patternSelection() == from && project->socket->window->sequenceSelection() == -1;
auto p = project->patterns[static_cast<size_t>(from)];
project->patterns.erase(project->patterns.begin() + from);
project->patterns.insert(project->patterns.begin() + to, p);
project->updatePatternIndices();
emit project->socket->updatePatternLists();
if (move) project->socket->window->patternSelection(to);
}
void ProjectPatternMoveCommand::undo() {
bool move = project->socket->window->patternSelection() == to && project->socket->window->sequenceSelection() == -1;
auto p = project->patterns[static_cast<size_t>(to)];
project->patterns.erase(project->patterns.begin() + to);
project->patterns.insert(project->patterns.begin() + from, p);
project->updatePatternIndices();
emit project->socket->updatePatternLists();
if (move) project->socket->window->patternSelection(from);
}
ProjectPatternAddCommand::ProjectPatternAddCommand(const std::shared_ptr<Project>& project_, int at, int atSeq, const std::shared_ptr<Pattern>& copyOf) {
project = project_;
if (at < 0) at = std::numeric_limits<int>::max();
this->at = std::max(0, std::min(at, static_cast<int>(project->patterns.size())));
this->atSeq = atSeq;
this->copyOf = copyOf;
if (copyOf) setText("duplicate pattern");
else setText("add pattern");
}
void ProjectPatternAddCommand::redo() {
auto np = project->newPattern(static_cast<size_t>(at));
if (copyOf) *np = *copyOf;
project->updatePatternIndices();
if (atSeq > -1) {
project->sequence.insert(project->sequence.begin() + atSeq, np);
emit project->socket->updatePatternLists();
project->socket->window->patternSelection(at);
project->socket->window->sequenceSelection(atSeq);
} else {
emit project->socket->updatePatternLists();
project->socket->window->patternSelection(at);
}
}
void ProjectPatternAddCommand::undo() {
project->removePattern(project->patterns[static_cast<size_t>(at)].get()); // ???
emit project->socket->updatePatternLists();
if (atSeq > -1) project->socket->window->sequenceSelection(std::max(0, atSeq - 1));
else if (copyOf) project->socket->window->patternSelection(static_cast<int>(copyOf->index));
}
ProjectPatternDeleteCommand::ProjectPatternDeleteCommand(const std::shared_ptr<Project>& project_, const std::shared_ptr<Pattern>& pattern_) {
project = project_;
pattern = pattern_;
setText("delete pattern");
oldSeq = project->sequence;
oldSeqSel = project->socket->window->sequenceSelection();
}
void ProjectPatternDeleteCommand::redo() {
int seqSel = oldSeqSel;
for (int i = 0; i <= oldSeqSel; i++) if (seqSel > 0 && project->sequence[static_cast<size_t>(i)].pattern() == pattern) seqSel--;
project->sequence.erase(std::remove(project->sequence.begin(), project->sequence.end(), pattern), project->sequence.end());
project->patterns.erase(project->patterns.begin() + static_cast<ptrdiff_t>(pattern->index));
project->updatePatternIndices();
emit project->socket->updatePatternLists();
project->socket->window->sequenceSelection(seqSel);
}
void ProjectPatternDeleteCommand::undo() {
project->patterns.insert(project->patterns.begin() + static_cast<ptrdiff_t>(pattern->index), pattern);
project->updatePatternIndices();
project->sequence = oldSeq;
emit project->socket->updatePatternLists();
project->socket->window->sequenceSelection(oldSeqSel);
}