File indexing completed on 2024-05-12 03:47:46

0001 /*
0002     File                 : macros.h
0003     Project              : LabPlot
0004     Description          : Various preprocessor macros for curve classes
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2019 Martin Marmsoler <martin.marmsoler@gmail.com>
0007     SPDX-FileCopyrightText: 2022 Alexander Semke <alexander.semke@web.de>
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #ifndef MACROSCURVE_H
0012 #define MACROSCURVE_H
0013 
0014 #include "backend/core/AbstractColumn.h"
0015 #include "backend/lib/commandtemplates.h"
0016 #include <QObject>
0017 
0018 /*!
0019   This macro is used to connect the column to the XYCurveQ_SLOTS:
0020     - <column_prefix>ColumnAboutToBeRemoved
0021     - <column_prefix>DataChanged
0022   This means these slots must be available when using this function.
0023   \param column pointer to a AbstractColumn
0024   \param prefix columnnames should have always the same style. For example xColumn -> prefix = x, xErrorPlusColumn -> prefix = xErrorPlus
0025   */
0026 #define CURVE_COLUMN_CONNECT(class_name, Prefix, prefix, recalc_func)                                                                                          \
0027     void class_name::connect##Prefix##Column(const AbstractColumn* column) {                                                                                   \
0028         connect(column->parentAspect(), &AbstractAspect::childAspectAboutToBeRemoved, this, &class_name::prefix##ColumnAboutToBeRemoved);                      \
0029         /* When the column is reused with different name, the curve should be informed to disconnect */                                                        \
0030         connect(column, &AbstractColumn::aboutToReset, this, &class_name::prefix##ColumnAboutToBeRemoved);                                                     \
0031         /* after the curve was updated, emit the signal to update the plot ranges */                                                                           \
0032         connect(column, &AbstractColumn::dataChanged, this, &class_name::recalc_func); /* must be before DataChanged*/                                         \
0033         connect(column, &AbstractColumn::dataChanged, this, &class_name::prefix##DataChanged);                                                                 \
0034     }
0035 
0036 #define CURVE_COLUMN_CONNECT_CALL(curve, column, Prefix) curve->connect##Prefix##Column(column);
0037 
0038 /*!
0039  * This macro is used to connect and disconnect the column from the curve
0040  * The new column is connected to the curve and the old column is diconnected
0041  * The columnPath is updated
0042  */
0043 #define CURVE_COLUMN_SETTER_CMD_IMPL_F_S(class_name, Prefix, prefix, finalize_method)                                                                          \
0044     class class_name##Set##Prefix##ColumnCmd : public StandardSetterCmd<class_name::Private, const AbstractColumn*> {                                          \
0045     public:                                                                                                                                                    \
0046         class_name##Set##Prefix##ColumnCmd(class_name::Private* target, const AbstractColumn* newValue, const KLocalizedString& description)                   \
0047             : StandardSetterCmd<class_name::Private, const AbstractColumn*>(target, &class_name::Private::prefix##Column, newValue, description)               \
0048             , m_private(target)                                                                                                                                \
0049             , m_column(newValue) {                                                                                                                             \
0050         }                                                                                                                                                      \
0051         virtual void finalize() override {                                                                                                                     \
0052             m_target->finalize_method();                                                                                                                       \
0053             Q_EMIT m_target->q->prefix##ColumnChanged(m_target->*m_field);                                                                                     \
0054         }                                                                                                                                                      \
0055         void redo() override {                                                                                                                                 \
0056             m_columnOld = m_private->prefix##Column;                                                                                                           \
0057             if (m_columnOld) {                                                                                                                                 \
0058                 /* disconnect only when column valid, because otherwise all                                                                                    \
0059                  * signals are disconnected */                                                                                                                 \
0060                 QObject::disconnect(m_columnOld, nullptr, m_private->q, nullptr);                                                                              \
0061             }                                                                                                                                                  \
0062             m_private->prefix##Column = m_column;                                                                                                              \
0063             if (m_column) {                                                                                                                                    \
0064                 m_private->q->set##Prefix##ColumnPath(m_column->path());                                                                                       \
0065                 CURVE_COLUMN_CONNECT_CALL(m_private->q, m_column, Prefix)                                                                                      \
0066             } else                                                                                                                                             \
0067                 m_private->q->set##Prefix##ColumnPath(QStringLiteral(""));                                                                                     \
0068             finalize();                                                                                                                                        \
0069             Q_EMIT m_private->q->prefix##ColumnChanged(m_column);                                                                                              \
0070             /* emit DataChanged() in order to notify the plot about the changes */                                                                             \
0071             Q_EMIT m_private->q->prefix##DataChanged();                                                                                                        \
0072         }                                                                                                                                                      \
0073         void undo() override {                                                                                                                                 \
0074             if (m_private->prefix##Column)                                                                                                                     \
0075                 QObject::disconnect(m_private->prefix##Column, nullptr, m_private->q, nullptr);                                                                \
0076             m_private->prefix##Column = m_columnOld;                                                                                                           \
0077             if (m_columnOld) {                                                                                                                                 \
0078                 m_private->q->set##Prefix##ColumnPath(m_columnOld->path());                                                                                    \
0079                 CURVE_COLUMN_CONNECT_CALL(m_private->q, m_column, Prefix)                                                                                      \
0080             } else                                                                                                                                             \
0081                 m_private->q->set##Prefix##ColumnPath(QStringLiteral(""));                                                                                     \
0082             finalize();                                                                                                                                        \
0083             Q_EMIT m_private->q->prefix##ColumnChanged(m_columnOld);                                                                                           \
0084             /* emit DataChanged() in order to notify the plot about the changes */                                                                             \
0085             Q_EMIT m_private->q->prefix##DataChanged();                                                                                                        \
0086         }                                                                                                                                                      \
0087                                                                                                                                                                \
0088     private:                                                                                                                                                   \
0089         class_name::Private* m_private;                                                                                                                        \
0090         const AbstractColumn* m_column{nullptr};                                                                                                               \
0091         const AbstractColumn* m_columnOld{nullptr};                                                                                                            \
0092     };
0093 
0094 #endif // MACROSXYCURVE_H