File indexing completed on 2024-12-15 04:01:01

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #pragma once
0008 
0009 #include <QVector>
0010 
0011 #include "command/base.hpp"
0012 #include "model/property/property.hpp"
0013 
0014 namespace glaxnimate::command {
0015 
0016 class SetPropertyValue : public MergeableCommand<Id::SetPropertyValue, SetPropertyValue>
0017 {
0018 public:
0019     SetPropertyValue(model::BaseProperty* prop, const QVariant& value, bool commit = true)
0020         : SetPropertyValue(prop, prop->value(), value, commit)
0021     {}
0022 
0023     SetPropertyValue(model::BaseProperty* prop, const QVariant& before, const QVariant& after, bool commit = true, const QString& name = {})
0024         : Parent(name.isEmpty() ? i18n("Update %1", prop->name()) : name, commit),
0025             prop(prop),
0026             before(before),
0027             after(after)
0028     {}
0029 
0030     void undo() override
0031     {
0032         prop->set_value(before);
0033     }
0034 
0035     void redo() override
0036     {
0037         prop->set_value(after);
0038     }
0039 
0040 
0041     bool merge_with(const SetPropertyValue& other)
0042     {
0043         if ( other.prop != prop )
0044             return false;
0045         after = other.after;
0046         return true;
0047     }
0048 
0049 private:
0050     model::BaseProperty* prop;
0051     QVariant before;
0052     QVariant after;
0053 };
0054 
0055 
0056 class SetMultipleProperties : public MergeableCommand<Id::SetMultipleProperties, SetMultipleProperties>
0057 {
0058 public:
0059     template<class... Args>
0060     SetMultipleProperties(
0061         const QString& name,
0062         bool commit,
0063         const QVector<model::BaseProperty*>& props,
0064         Args... vals
0065     ) : SetMultipleProperties(name, props, {}, {QVariant::fromValue(vals)...}, commit)
0066     {}
0067 
0068     /**
0069      * \pre props.size() == after.size() && (props.size() == before.size() || before.empty())
0070      *
0071      * If before.empty() it will be populated by the properties
0072      */
0073     SetMultipleProperties(
0074         const QString& name,
0075         const QVector<model::BaseProperty*>& props,
0076         const QVariantList& before,
0077         const QVariantList& after,
0078         bool commit
0079     )
0080         : Parent(name, commit), props(props), before(before), after(after)
0081     {
0082         if ( before.empty() )
0083             for ( auto prop : props )
0084                 this->before.push_back(prop->value());
0085     }
0086 
0087     void undo() override
0088     {
0089         for ( int i = 0; i < props.size(); i++ )
0090             props[i]->set_value(before[i]);
0091     }
0092 
0093     void redo() override
0094     {
0095         for ( int i = 0; i < props.size(); i++ )
0096             props[i]->set_value(after[i]);
0097     }
0098 
0099 
0100     bool merge_with(const SetMultipleProperties& other)
0101     {
0102         if ( other.props.size() != props.size() )
0103             return false;
0104 
0105         for ( int i = 0; i < props.size(); i++ )
0106             if ( props[i] != other.props[i] )
0107                 return false;
0108 
0109         after = other.after;
0110         return true;
0111     }
0112 
0113 private:
0114     QVector<model::BaseProperty*> props;
0115     QVariantList before;
0116     QVariantList after;
0117 };
0118 
0119 } // namespace glaxnimate::command