File indexing completed on 2024-05-19 03:48:54

0001 /*
0002     File                 : commandtemplates.h
0003     Project              : LabPlot
0004     Description          : Undo/Redo command templates
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2009 Tilman Benkert <thzs@gmx.net>
0007     SPDX-FileCopyrightText: 2017 Alexander Semke <alexander.semke@web.de>
0008     SPDX-FileCopyrightText: 2020 Stefan Gerlach <stefan.gerlach@uni.kn>
0009 
0010     SPDX-License-Identifier: GPL-2.0-or-later
0011 */
0012 
0013 #ifndef COMMANDTEMPLATES_H
0014 #define COMMANDTEMPLATES_H
0015 
0016 #include <QUndoCommand>
0017 
0018 #include <KLocalizedString>
0019 
0020 #include "backend/lib/macros.h"
0021 
0022 /*!
0023  * \brief The LongExecutionCmd class
0024  * Use this undo command if you expect long execution times
0025  * Executes all child commands and sets the cursor to the waiting symbol
0026  */
0027 class LongExecutionCmd : public QUndoCommand {
0028 public:
0029     LongExecutionCmd(const QString& text, QUndoCommand* parent = nullptr)
0030         : QUndoCommand(text, parent) {
0031     }
0032 
0033     virtual void redo() override {
0034         WAIT_CURSOR;
0035         QUndoCommand::redo();
0036         RESET_CURSOR;
0037     }
0038 
0039     virtual void undo() override {
0040         WAIT_CURSOR;
0041         QUndoCommand::undo();
0042         RESET_CURSOR;
0043     }
0044 };
0045 
0046 template<class target_class, typename value_type>
0047 class StandardSetterCmd : public QUndoCommand {
0048 public:
0049     StandardSetterCmd(target_class* target,
0050                       value_type target_class::*field,
0051                       value_type newValue,
0052                       const KLocalizedString& description,
0053                       QUndoCommand* parent = nullptr) // use ki18n("%1: ...")
0054         : QUndoCommand(parent)
0055         , m_target(target)
0056         , m_field(field)
0057         , m_otherValue(newValue) {
0058         setText(description.subs(m_target->name()).toString());
0059     }
0060 
0061     virtual void initialize() {
0062     }
0063     virtual void finalize() {
0064     }
0065 
0066     void redo() override {
0067         initialize();
0068         value_type tmp = *m_target.*m_field;
0069         *m_target.*m_field = m_otherValue;
0070         m_otherValue = tmp;
0071         QUndoCommand::redo(); // redo all childs
0072         finalize();
0073     }
0074 
0075     void undo() override {
0076         redo();
0077     }
0078 
0079 protected:
0080     target_class* m_target;
0081     value_type target_class::*m_field;
0082     value_type m_otherValue;
0083 };
0084 
0085 template<class target_class, typename value_type>
0086 class StandardQVectorSetterCmd : public QUndoCommand {
0087 public:
0088     StandardQVectorSetterCmd(target_class* target,
0089                              QVector<value_type> target_class::*field,
0090                              int index,
0091                              value_type newValue,
0092                              const KLocalizedString& description) // use ki18n("%1: ...")
0093         : m_target(target)
0094         , m_field(field)
0095         , m_index(index)
0096         , m_otherValue(newValue) {
0097         setText(description.subs(m_target->name()).toString());
0098     }
0099 
0100     virtual void initialize() {
0101     }
0102     virtual void finalize() {
0103     }
0104 
0105     void redo() override {
0106         DEBUG(Q_FUNC_INFO);
0107         initialize();
0108         value_type tmp = (*m_target.*m_field).at(m_index);
0109         (*m_target.*m_field)[m_index] = m_otherValue;
0110         m_otherValue = tmp;
0111         QUndoCommand::redo(); // redo all childs
0112         finalize();
0113     }
0114 
0115     void undo() override {
0116         redo();
0117     }
0118 
0119 protected:
0120     target_class* m_target;
0121     QVector<value_type> target_class::*m_field;
0122     int m_index;
0123     value_type m_otherValue;
0124 };
0125 
0126 template<class target_class, typename value_type>
0127 class StandardMacroSetterCmd : public QUndoCommand {
0128 public:
0129     StandardMacroSetterCmd(target_class* target,
0130                            value_type target_class::*field,
0131                            value_type newValue,
0132                            const KLocalizedString& description) // use ki18n("%1: ...")
0133         : m_target(target)
0134         , m_field(field)
0135         , m_otherValue(newValue) {
0136         setText(description.subs(m_target->name()).toString());
0137     }
0138 
0139     virtual void initialize() {
0140     }
0141     virtual void finalize() {
0142     }
0143     virtual void finalizeUndo() {
0144     }
0145 
0146     void redo() override {
0147         initialize();
0148         value_type tmp = *m_target.*m_field;
0149         *m_target.*m_field = m_otherValue;
0150         m_otherValue = tmp;
0151         QUndoCommand::redo(); // redo all childs
0152         finalize();
0153     }
0154 
0155     // call finalizeUndo() at the end where only the signal is emitted
0156     // and no actual finalize-method is called that can potentially
0157     // cause  new entries on the undo-stack
0158     void undo() override {
0159         initialize();
0160         value_type tmp = *m_target.*m_field;
0161         *m_target.*m_field = m_otherValue;
0162         m_otherValue = tmp;
0163         QUndoCommand::undo(); // undo all childs
0164         finalizeUndo();
0165     }
0166 
0167 protected:
0168     target_class* m_target;
0169     value_type target_class::*m_field;
0170     value_type m_otherValue;
0171 };
0172 
0173 template<class target_class, typename value_type>
0174 class StandardSwapMethodSetterCmd : public QUndoCommand {
0175 public:
0176     StandardSwapMethodSetterCmd(target_class* target,
0177                                 value_type (target_class::*method)(value_type),
0178                                 value_type newValue,
0179                                 const KLocalizedString& description) // use ki18n("%1: ...")
0180         : m_target(target)
0181         , m_method(method)
0182         , m_otherValue(newValue) {
0183         setText(description.subs(m_target->name()).toString());
0184     }
0185 
0186     virtual void initialize() {
0187     }
0188     virtual void finalize() {
0189     }
0190 
0191     void redo() override {
0192         initialize();
0193         m_otherValue = (*m_target.*m_method)(m_otherValue);
0194         QUndoCommand::redo(); // redo all childs
0195         finalize();
0196     }
0197 
0198     void undo() override {
0199         redo();
0200     }
0201 
0202 protected:
0203     target_class* m_target;
0204     value_type (target_class::*m_method)(value_type);
0205     value_type m_otherValue;
0206 };
0207 
0208 #endif