File indexing completed on 2024-05-12 04:20:32

0001 /*
0002  * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
0003  *
0004  * This file is part of the KD Chart library.
0005  *
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #ifndef KCHARTDATASETPROXYMODEL_H
0010 #define KCHARTDATASETPROXYMODEL_H
0011 
0012 #include <QVector>
0013 #include <QSortFilterProxyModel>
0014 
0015 #include "kchart_export.h"
0016 
0017 namespace KChart {
0018 
0019     class IndexOutOfBoundsException;
0020 
0021     typedef QVector<int> DatasetDescriptionVector;
0022 
0023     /** DatasetProxyModel takes a KChart dataset configuration and translates
0024         it into a filtering proxy model.
0025 
0026         The resulting model will only contain the part of the model that is
0027         selected by the dataset, and the according row and column header
0028         data.
0029 
0030         Currently, this model is implemented for table models only. The way it
0031         would work with models representing a tree is to be decided.
0032 
0033         The column selection is configured by passing a dataset description
0034         vector to the model. This vector (of integers) is supposed to have one
0035         value for each column of the original model. If the value at position
0036         x is -1, column x of the original model is not included in the
0037         dataset. If it is between 0 and (columnCount() -1), it is the column
0038         the source column is mapped to in the resulting model. Any other value
0039         is an error.
0040     */
0041     class KCHART_EXPORT DatasetProxyModel : public QSortFilterProxyModel
0042     {
0043         Q_OBJECT
0044     public:
0045         /** Create a DatasetProxyModel.
0046             Without further configuration, this model is invalid.
0047             @see setDatasetDescriptionVector
0048         */
0049         explicit DatasetProxyModel ( QObject* parent = nullptr );
0050 
0051         QModelIndex buddy( const QModelIndex& index ) const override;
0052 
0053         Qt::ItemFlags flags( const QModelIndex& index ) const override;
0054 
0055         QModelIndex index( int row, int column,
0056                            const QModelIndex &parent = QModelIndex() ) const override;
0057         QModelIndex parent(const QModelIndex &child ) const override;
0058 
0059         /** Implements the mapping from the source to the proxy indexes. */
0060         QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const override;
0061 
0062         /** Implements the mapping from the proxy to the source indexes. */
0063         QModelIndex mapToSource ( const QModelIndex& proxyIndex ) const override;
0064 
0065         /** Overloaded from base class. */
0066         QVariant data(const QModelIndex &index, int role) const override;
0067 
0068         /** Overloaded from base class. */
0069         bool setData( const QModelIndex& index, const QVariant& value, int role ) override;
0070 
0071         /** Overloaded from base class. */
0072         QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
0073 
0074         /** Overloaded from base class. */
0075         void setSourceModel(QAbstractItemModel *sourceModel) override;
0076 
0077         /** Set the root index of the table in
0078         the source model */
0079         void setSourceRootIndex(const QModelIndex& rootIdx);
0080 
0081 
0082     public Q_SLOTS:
0083         /** Reset all dataset description.
0084             After that, the result of the proxying is an empty model (a new
0085             dataset description needs to be set to achieve a non-empty result).
0086         */
0087         void resetDatasetDescriptions();
0088 
0089         /** Configure the dataset selection for the columns.
0090             Every call to this method resets the previous dataset
0091             description.
0092         */
0093         void setDatasetColumnDescriptionVector ( const KChart::DatasetDescriptionVector& columnConfig );
0094 
0095         /** Configure the dataset selection for the rows.
0096             Every call to this method resets the previous dataset
0097             description.
0098         */
0099         void setDatasetRowDescriptionVector ( const KChart::DatasetDescriptionVector& rowConfig );
0100 
0101         /** Convenience method to configure rows and columns in one step. */
0102         void setDatasetDescriptionVectors (
0103             const KChart::DatasetDescriptionVector& rowConfig,
0104             const KChart::DatasetDescriptionVector& columnConfig );
0105 
0106         // FIXME: add convenience methods to configure common dataset
0107         // selections (like rectangular areas etc)
0108 
0109     protected:
0110         /** Decide whether the column is accepted. */
0111         bool filterAcceptsColumn ( int sourceColumn,
0112                                    const QModelIndex & ) const override;
0113 
0114 
0115         /** Decide whether the row is accepted. */
0116         bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const override;
0117 
0118     private:
0119 
0120         /** Map a proxy column to a source column. */
0121         int mapProxyColumnToSource ( const int& proxyColumn ) const;
0122 
0123         /** Map a source column to a proxy column. */
0124         int mapSourceColumnToProxy ( const int& sourceColumn ) const;
0125 
0126         /** Map a proxy row to a source row. */
0127         int mapProxyRowToSource ( const int& proxyRow ) const;
0128 
0129         /** Map a source row to a proxy row. */
0130         int mapSourceRowToProxy ( const int& sourceRow ) const;
0131 
0132         /** Initialize the transformation vectors from the dataset
0133             description.
0134 
0135             The input parameter "Configuration" is a vector that specifies
0136             what srce column will be mapped to what proxy column. Example:
0137 
0138             position: [0][1][2]
0139             value:    [2][0][1]
0140 
0141             This will map the source column 2 to proxy column 0, source 0 to
0142             proxy 1, and source 1 to proxy 2. Source needs to have at least 2
0143             column. The source-to-proxy mapping looks the same, except that it
0144             may contain values of -1, which means this column is not part of
0145             the resulting model. The values in the configuration vector must
0146             be unique (otherwise, a 1-to-1 mapping in both directions is
0147             impossible).
0148 
0149             sourceCount is the number of columns in the source model. The proxy-to-source map has
0150             as many elements as the proxy has columns, the source-to-proxy map
0151             has as many elements as the source has columns. Same goes for rows
0152             (the mapping logic is the same).
0153 
0154          */
0155         void initializeDatasetDecriptors (
0156             const DatasetDescriptionVector& inConfiguration,
0157             int sourceCount,
0158             DatasetDescriptionVector& outSourceToProxyMap,
0159             DatasetDescriptionVector& outProxyToSourceMap );
0160 
0161         DatasetDescriptionVector mColSrcToProxyMap;
0162         DatasetDescriptionVector mColProxyToSrcMap;
0163         DatasetDescriptionVector mRowSrcToProxyMap;
0164         DatasetDescriptionVector mRowProxyToSrcMap;
0165 
0166         int mProxyRowCount;
0167         int mProxyColumnCount;
0168         QModelIndex mRootIndex;
0169     };
0170 
0171 }
0172 
0173 
0174 #endif