File indexing completed on 2024-05-12 15:27:00

0001 /***************************************************************************
0002     File                 : macros.h
0003     Project              : LabPlot
0004     Description          : Various preprocessor macros for the curve class
0005     --------------------------------------------------------------------
0006     Copyright            : (C) 2019 Martin Marmsoler (martin.marmsoler@gmail.com)
0007 
0008  ***************************************************************************/
0009 
0010 /***************************************************************************
0011  *                                                                         *
0012  *  This program is free software; you can redistribute it and/or modify   *
0013  *  it under the terms of the GNU General Public License as published by   *
0014  *  the Free Software Foundation; either version 2 of the License, or      *
0015  *  (at your option) any later version.                                    *
0016  *                                                                         *
0017  *  This program is distributed in the hope that it will be useful,        *
0018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0020  *  GNU General Public License for more details.                           *
0021  *                                                                         *
0022  *   You should have received a copy of the GNU General Public License     *
0023  *   along with this program; if not, write to the Free Software           *
0024  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0025  *   Boston, MA  02110-1301  USA                                           *
0026  *                                                                         *
0027  ***************************************************************************/
0028 
0029 #ifndef MACROSXYCURVE_H
0030 #define MACROSXYCURVE_H
0031 
0032 #include "backend/lib/commandtemplates.h"
0033 #include "backend/worksheet/plots/cartesian/XYCurve.h"
0034 #include <QObject>
0035 class AbstractColumn;
0036 
0037 /*!
0038   This macro is used to connect the column to the XYCurve slots:
0039     - <column_prefix>ColumnAboutToBeRemoved
0040     - <column_prefix>ColumnNameChanged
0041     - <column_prefix>DataChanged
0042   This means these slots must be available when using this function.
0043   \param column pointer to a AbstractColumn
0044   \param column_prefix columnnames should have always the same style. For example xColumn -> column_prefix = x, xErrorPlusColumn -> column_prefix = xErrorPlus
0045   */
0046 #define XYCURVE_COLUMN_CONNECT(column_prefix) \
0047 void columnConnect ## column_prefix ## Column(const AbstractColumn* column) { \
0048     connect(column->parentAspect(), &AbstractAspect::aspectAboutToBeRemoved, this, &XYCurve::column_prefix ## ColumnAboutToBeRemoved); \
0049     auto* parent = column->parentAspect(); \
0050     while (parent) { \
0051         connect(parent, &AbstractAspect::aspectAboutToBeRemoved, this, &XYCurve::column_prefix ## ColumnAboutToBeRemoved); \
0052         parent = parent->parentAspect(); \
0053     } \
0054     /* When the column is reused with different name, the curve should be informed to disconnect */ \
0055     connect(column, &AbstractColumn::reset, this, &XYCurve::column_prefix ## ColumnAboutToBeRemoved); \
0056     connect(column, &AbstractAspect::aspectDescriptionChanged, this, &XYCurve::column_prefix ## ColumnNameChanged); \
0057     /* after the curve was updated, emit the signal to update the plot ranges */ \
0058     connect(column, &AbstractColumn::dataChanged, this, &XYCurve::recalcLogicalPoints); /* must be before DataChanged*/ \
0059     connect(column, &AbstractColumn::dataChanged, this, &XYCurve::column_prefix ## DataChanged);\
0060 }
0061 
0062 #define XYCURVE_COLUMN_CONNECT_CALL(curve, column, column_prefix) \
0063     curve->columnConnect ## column_prefix ## Column(column); \
0064 
0065 /*!
0066  * This macro is used to connect and disconnect the column from the curve
0067  * The new column is connected to the curve and the old column is diconnected
0068  * The columnPath is updated
0069 */
0070 #define XYCURVE_COLUMN_SETTER_CMD_IMPL_F_S(cmd_name, prefix, finalize_method) \
0071 class XYCurve ## Set ## cmd_name ## ColumnCmd: public StandardSetterCmd<XYCurve::Private, const AbstractColumn*> { \
0072 public: \
0073     XYCurve ## Set ## cmd_name ## ColumnCmd(XYCurve::Private *target, const AbstractColumn* newValue, const KLocalizedString &description) \
0074         : StandardSetterCmd<XYCurve::Private, const AbstractColumn*>(target, &XYCurve::Private::prefix ## Column, newValue, description), \
0075         m_private(target), \
0076         m_column(newValue) \
0077           {} \
0078         virtual void finalize() override { m_target->finalize_method(); emit m_target->q->prefix ## ColumnChanged(m_target->*m_field); } \
0079         void redo() override { \
0080             m_columnOld = m_private->prefix ## Column; \
0081             if (m_columnOld) {\
0082                 /* disconnect only when column valid, because otherwise all
0083                  * signals are disconnected */ \
0084                 QObject::disconnect(m_columnOld, nullptr, m_private->q, nullptr); \
0085             }\
0086             m_private->prefix ## Column = m_column; \
0087             if (m_column) { \
0088                 m_private->q->set ## cmd_name ## ColumnPath(m_column->path());\
0089                 XYCURVE_COLUMN_CONNECT_CALL(m_private->q, m_column, prefix) \
0090             } else \
0091                 m_private->q->set ## cmd_name ## ColumnPath("");\
0092             finalize();\
0093             emit m_private->q->prefix ## ColumnChanged(m_column);\
0094             /* emit DataChanged() in order to notify the plot about the changes */ \
0095             emit m_private->q->prefix ## DataChanged();\
0096         }\
0097         void undo() override { \
0098             if (m_private->prefix ## Column)\
0099                 QObject::disconnect(m_private->prefix ## Column, nullptr, m_private->q, nullptr); \
0100             m_private->prefix ## Column = m_columnOld;\
0101             if (m_columnOld) {\
0102                 m_private->q->set ## cmd_name ## ColumnPath(m_columnOld->path());\
0103                 XYCURVE_COLUMN_CONNECT_CALL(m_private->q, m_column, prefix)\
0104             } else\
0105                 m_private->q->set ## cmd_name ## ColumnPath("");\
0106             finalize();\
0107             emit m_private->q->prefix ## ColumnChanged(m_columnOld);\
0108             /* emit DataChanged() in order to notify the plot about the changes */ \
0109             emit m_private->q->prefix ## DataChanged();\
0110         } \
0111 private: \
0112     XYCurvePrivate* m_private; \
0113     const AbstractColumn* m_column{nullptr}; \
0114     const AbstractColumn* m_columnOld{nullptr}; \
0115 };
0116 
0117 #endif // MACROSXYCURVE_H