File indexing completed on 2024-06-23 03:46:07

0001 /*
0002     File                 : Column.h
0003     Project              : LabPlot
0004     Description          : Aspect that manages a column
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2007-2009 Tilman Benkert <thzs@gmx.net>
0007     SPDX-FileCopyrightText: 2013-2017 Alexander Semke <alexander.semke@web.de>
0008     SPDX-FileCopyrightText: 2017 Stefan Gerlach <stefan.gerlach@uni.kn>
0009     SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 
0012 #ifndef COLUMN_H
0013 #define COLUMN_H
0014 
0015 #include "backend/core/AbstractColumn.h"
0016 
0017 class AbstractSimpleFilter;
0018 class CartesianPlot;
0019 class ColumnStringIO;
0020 class QAction;
0021 class QActionGroup;
0022 class XmlStreamReader;
0023 class ColumnPrivate;
0024 class ColumnSetGlobalFormulaCmd;
0025 
0026 #ifdef SDK
0027 #include "labplot_export.h"
0028 class LABPLOT_EXPORT Column : public AbstractColumn {
0029 #else
0030 class Column : public AbstractColumn {
0031 #endif
0032     Q_OBJECT
0033 
0034 public:
0035     explicit Column(const QString& name, AbstractColumn::ColumnMode = ColumnMode::Double);
0036     // Templating does not work, because then ColumnPrivate.h must be included into this header,
0037     // But Column.h is already included in ColumnPrivate.h
0038     Column(const QString& name, const QVector<double>& data);
0039     Column(const QString& name, const QVector<int>& data);
0040     Column(const QString& name, const QVector<qint64>& data);
0041     Column(const QString& name, const QVector<QString>& data);
0042     Column(const QString& name, const QVector<QDateTime>& data, ColumnMode);
0043     void init();
0044     ~Column() override;
0045 
0046     QIcon icon() const override;
0047     QMenu* createContextMenu() override;
0048 
0049     void updateLocale();
0050 
0051     AbstractColumn::ColumnMode columnMode() const override;
0052     QString columnModeString() const;
0053     void setColumnMode(AbstractColumn::ColumnMode) override;
0054     void setColumnModeFast(AbstractColumn::ColumnMode);
0055 
0056     bool isDraggable() const override;
0057     QVector<AspectType> dropableOn() const override;
0058 
0059     bool copy(const AbstractColumn*) override;
0060     bool copy(const AbstractColumn* source, int source_start, int dest_start, int num_rows) override;
0061 
0062     AbstractColumn::PlotDesignation plotDesignation() const override;
0063     QString plotDesignationString(bool withBrackets = true) const;
0064     void setPlotDesignation(AbstractColumn::PlotDesignation) override;
0065 
0066     bool isReadOnly() const override;
0067     void resizeTo(int);
0068     int rowCount() const override;
0069     int rowCount(double min, double max) const override;
0070     int availableRowCount(int max = -1) const override;
0071     int width() const;
0072     void setWidth(const int);
0073     void clear(QUndoCommand* parent = nullptr) override;
0074     AbstractSimpleFilter* outputFilter() const;
0075     ColumnStringIO* asStringColumn() const;
0076 
0077     void setFormula(const QString& formula, const QStringList& variableNames, const QVector<Column*>& columns, bool autoUpdate = false, bool autoResize = true);
0078     QString formula() const;
0079     struct FormulaData {
0080 #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) // required to use in QVector
0081         FormulaData() = default;
0082 #endif
0083         FormulaData(const QString& variableName, const QString& columnPath)
0084             : m_variableName(variableName)
0085             , m_columnPath(columnPath) {
0086         }
0087         FormulaData(const QString& variableName, Column* column)
0088             : m_column(column)
0089             , m_variableName(variableName)
0090             , m_columnPath(column->path()) {
0091         }
0092         QString columnName() const {
0093             return (m_column ? m_column->path() : m_columnPath);
0094         }
0095         bool setColumnPath(const QString& path) {
0096             if (m_column && m_column->path() != path)
0097                 return false;
0098             else if (!m_column)
0099                 m_columnPath = path;
0100             return true;
0101         }
0102         void setColumn(Column* c) {
0103             m_column = c;
0104             if (c)
0105                 m_columnPath = c->path(); // do not clear path
0106         }
0107         // column can be changed only with setColumn
0108         const Column* column() const {
0109             return m_column;
0110         }
0111         const QString& variableName() const {
0112             return m_variableName;
0113         }
0114 
0115     private:
0116         // Should be only accessible by the columnName() function
0117         Column* m_column{nullptr};
0118         QString m_variableName;
0119         QString m_columnPath;
0120         friend ColumnSetGlobalFormulaCmd;
0121     };
0122 
0123     const QVector<FormulaData>& formulaData() const;
0124     void setFormulaVariableColumn(Column*);
0125     void setFormulVariableColumnsPath(int index, const QString& path);
0126     void setFormulVariableColumn(int index, Column*);
0127     bool formulaAutoUpdate() const;
0128     bool formulaAutoResize() const;
0129 
0130     QString formula(int) const override;
0131     QVector<Interval<int>> formulaIntervals() const override;
0132     void setFormula(const Interval<int>&, const QString&) override;
0133     void setFormula(int, const QString&) override;
0134     void clearFormulas() override;
0135 
0136     const AbstractColumn::ColumnStatistics& statistics() const;
0137     void* data() const;
0138     void setData(void*);
0139     bool hasValues() const;
0140     bool valueLabelsInitialized() const;
0141     double valueLabelsMinimum() const;
0142     double valueLabelsMaximum() const;
0143     void setLabelsMode(ColumnMode mode);
0144     void removeValueLabel(const QString&);
0145     void valueLabelsRemoveAll();
0146 
0147     Properties properties() const override;
0148     void invalidateProperties() override;
0149 
0150     void setFromColumn(int, AbstractColumn*, int);
0151     QString textAt(int) const override;
0152     void setTextAt(int, const QString&) override;
0153     void setText(const QVector<QString>&);
0154     void replaceTexts(int, const QVector<QString>&) override;
0155     int dictionaryIndex(int row) const override;
0156     const QMap<QString, int>& frequencies() const;
0157 
0158     QDate dateAt(int) const override;
0159     void setDateAt(int, QDate) override;
0160     QTime timeAt(int) const override;
0161     void setTimeAt(int, QTime) override;
0162     void setDateTimes(const QVector<QDateTime>&);
0163     QDateTime dateTimeAt(int) const override;
0164     void setDateTimeAt(int, const QDateTime&) override;
0165     void replaceDateTimes(int, const QVector<QDateTime>&) override;
0166 
0167     double doubleAt(int) const override;
0168     double valueAt(int) const override;
0169     void setValues(const QVector<double>&);
0170     void setValueAt(int, double) override;
0171     void replaceValues(int, const QVector<double>&) override;
0172 
0173     int integerAt(int) const override;
0174     void setIntegers(const QVector<int>&);
0175     void setIntegerAt(int, int) override;
0176     void replaceInteger(int, const QVector<int>&) override;
0177 
0178     qint64 bigIntAt(int) const override;
0179     void setBigIntAt(int, qint64) override;
0180     void setBigInts(const QVector<qint64>&);
0181     void replaceBigInt(int, const QVector<qint64>&) override;
0182 
0183     double maximum(int count = 0) const override;
0184     double maximum(int startIndex, int endIndex) const override;
0185     double minimum(int count = 0) const override;
0186     double minimum(int startIndex, int endIndex) const override;
0187     static int calculateMaxSteps(unsigned int value);
0188     static int indexForValue(double x, QVector<double>& column, Properties properties = Properties::No);
0189     static int indexForValue(const double x, const QVector<QPointF>& column, Properties properties = Properties::No);
0190     static int indexForValue(double x, QVector<QLineF>& lines, Properties properties = Properties::No);
0191     int indexForValue(double x) const override;
0192     bool indicesMinMax(double v1, double v2, int& start, int& end) const override;
0193 
0194     void setChanged();
0195     void setSuppressDataChangedSignal(const bool);
0196 
0197     void addUsedInPlots(QVector<CartesianPlot*>&);
0198 
0199     // Value Labels
0200     template<typename T>
0201     struct ValueLabel {
0202         T value;
0203         QString label;
0204     };
0205     AbstractColumn::ColumnMode labelsMode() const;
0206     int valueLabelsCount() const;
0207     int valueLabelsCount(double min, double max) const;
0208     int valueLabelsIndexForValue(double x) const;
0209     double valueLabelsValueAt(int index) const;
0210     QString valueLabelAt(int index) const;
0211     void addValueLabel(qint64, const QString&);
0212     const QVector<ValueLabel<qint64>>* bigIntValueLabels() const;
0213     void addValueLabel(int, const QString&);
0214     const QVector<ValueLabel<int>>* intValueLabels() const;
0215     void addValueLabel(double, const QString&);
0216     const QVector<ValueLabel<double>>* valueLabels() const;
0217     void addValueLabel(const QDateTime&, const QString&);
0218     const QVector<ValueLabel<QDateTime>>* dateTimeValueLabels() const;
0219     void addValueLabel(const QString&, const QString&);
0220     const QVector<ValueLabel<QString>>* textValueLabels() const;
0221 
0222     void save(QXmlStreamWriter*) const override;
0223     bool load(XmlStreamReader*, bool preview) override;
0224     void finalizeLoad();
0225 
0226 public Q_SLOTS:
0227     void pasteData();
0228     void updateFormula();
0229 
0230 private:
0231     bool XmlReadInputFilter(XmlStreamReader*);
0232     bool XmlReadOutputFilter(XmlStreamReader*);
0233     bool XmlReadFormula(XmlStreamReader*);
0234     bool XmlReadRow(XmlStreamReader*);
0235 
0236     void handleRowInsertion(int before, int count, QUndoCommand* parent) override;
0237     void handleRowRemoval(int first, int count, QUndoCommand* parent) override;
0238 
0239     bool m_suppressDataChangedSignal{false};
0240     QAction* m_copyDataAction{nullptr};
0241     QAction* m_pasteDataAction{nullptr};
0242     QActionGroup* m_usedInActionGroup{nullptr};
0243 
0244     ColumnPrivate* d;
0245     ColumnStringIO* m_string_io;
0246 
0247 Q_SIGNALS:
0248     void requestProjectContextMenu(QMenu*);
0249     void formulaChanged(const AbstractColumn*);
0250 
0251 private Q_SLOTS:
0252     void navigateTo(QAction*);
0253     void handleFormatChange();
0254     void copyData();
0255 
0256     friend class ColumnPrivate;
0257     friend class ColumnStringIO;
0258     friend class ColumnRemoveRowsCmd;
0259     friend class ColumnInsertRowsCmd;
0260 };
0261 
0262 #endif