xybrid/xybrid/editing/compositecommand.cpp

69 lines
2.0 KiB
C++

#include "compositecommand.h"
#include "data/project.h"
#include "uisocket.h"
#include "mainwindow.h"
#include "editing/projectcommands.h"
#include "editing/patterncommands.h"
#include <QDebug>
using Xybrid::Data::Project;
using Xybrid::Data::Pattern;
using namespace Xybrid::Editing;
CompositeCommand::CompositeCommand(std::shared_ptr<Project> p) {
project = p;
}
CompositeCommand* CompositeCommand::reserve(int count) {
if (count <= 0) return this;
children.reserve(static_cast<size_t>(count));
return this;
}
CompositeCommand* CompositeCommand::compose(ProjectCommand* c) {
if (!project) {
project = c->project;
} else if (c->project != project && !c->cancel()) return this; // fail
c->composed = true;
if (!children.empty() && children.back()->mergeWith(c)) c->cancel();
else children.emplace_back(c);
return this;
}
CompositeCommand* CompositeCommand::compose(PatternCommand* c) {
if (!project) {
project = c->pattern->project->socket->window->getProject();
} else if (c->pattern->project != project.get() && !c->cancel()) return this; // fail
if (!pattern) pattern = c->pattern;
c->composed = true;
if (!children.empty() && children.back()->mergeWith(c)) c->cancel();
else children.emplace_back(c);
return this;
}
bool CompositeCommand::commit(QString name) {
if (!project || !project->socket || !project->socket->undoStack) return cancel();
if (children.empty()) return cancel(); // no children? no action
if (!name.isEmpty()) setText(name);
project->socket->undoStack->push(this);
return true;
}
bool CompositeCommand::cancel() {
delete this;
return false;
}
void CompositeCommand::redo() {
for (auto i = children.begin(); i != children.end(); i++) (*i)->redo();
if (pattern) emit project->socket->patternUpdated(pattern.get());
}
void CompositeCommand::undo() {
for (auto i = children.rbegin(); i != children.rend(); i++) (*i)->undo();
if (pattern) emit project->socket->patternUpdated(pattern.get());
}