1 /*
2  * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB.  All rights reserved.
3  *
4  * This file is part of the KD Chart library.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef __KCHART_ATTRIBUTES_MODEL_H__
21 #define __KCHART_ATTRIBUTES_MODEL_H__
22 
23 #include "KChartAbstractProxyModel.h"
24 #include <QMap>
25 #include <QVariant>
26 
27 #include "KChartGlobal.h"
28 
29 namespace KChart {
30 
31 /**
32   * @brief A proxy model used for decorating data with attributes.
33   *
34   *        An AttributesModel forwards data from and to the source model and adds attributes,
35   *        data that influences the graphical rendering of the source model data.
36   *        The attributes are distinguished from the source model's data by their @p role values.
37   *        Therefore this class does not need to, and does not, change the data layout from the
38   *        source model's; indexes that refer to the same data have the same row and column
39   *        values in both models.
40   *        Attribute changes, that is changes to data with the attribute role, via the interface
41   *        of this class (including setData()) are stored internally and not forwarded to the source model.
42   */
43 class KCHART_EXPORT AttributesModel : public AbstractProxyModel
44 {
45     Q_OBJECT
46     KCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC( AttributesModel )
47 public:
48     enum PaletteType {
49         PaletteTypeDefault = 0,
50         PaletteTypeRainbow = 1,
51         PaletteTypeSubdued = 2
52     };
53 
54     explicit AttributesModel( QAbstractItemModel* model, QObject * parent = nullptr );
55     ~AttributesModel();
56 
57     /** Copies the internal data (maps and palette) of another
58      *  AttributesModel* into this one.
59      */
60     void initFrom( const AttributesModel* other );
61 
62     /** Returns true if both, all of the attributes set, and
63      * the palette set is equal in both of the AttributeModels.
64      */
65     bool compare( const AttributesModel* other ) const;
66 
67     bool compareAttributes( int role, const QVariant& a, const QVariant& b ) const;
68 
69     /* Attributes Model specific API */
70     bool setModelData( const QVariant value, int role );
71     QVariant modelData( int role ) const;
72 
73     /** Returns whether the given role corresponds to one of the known
74      * internally used ones. */
75     bool isKnownAttributesRole( int role ) const;
76 
77     /** Sets the palettetype used by this attributesmodel */
78     void setPaletteType( PaletteType type );
79     PaletteType paletteType() const;
80 
81     /** Returns the data that were specified at global level,
82       * or the default data, or QVariant().
83       */
84     QVariant data(int role) const;
85 
86     /** Returns the data that were specified at per column level,
87       * or the globally set data, or the default data, or QVariant().
88       */
89     QVariant data(int column, int role) const;
90 
91     /** \reimpl */
92     QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
93     /** \reimpl */
94     int rowCount(const QModelIndex& ) const override;
95     /** \reimpl */
96     int columnCount(const QModelIndex& ) const override;
97     /** \reimpl */
98     QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const override;
99     /** \reimpl */
100     bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::DisplayRole) override;
101     /** Remove any explicit attributes settings that might have been specified before. */
102     bool resetData ( const QModelIndex & index, int role = Qt::DisplayRole);
103     /** \reimpl */
104     bool setHeaderData ( int section, Qt::Orientation orientation, const QVariant & value,
105                          int role = Qt::DisplayRole) override;
106     /** Returns default values for the header data. */
107     virtual QVariant defaultHeaderData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
108     /** Remove any explicit attributes settings that might have been specified before. */
109     bool resetHeaderData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole);
110     /** \reimpl */
111     void setSourceModel ( QAbstractItemModel* sourceModel ) override;
112 
113     /** Define the default value for a certain role.
114         Passing a default-constructed QVariant is equivalent to removing the default. */
115     void setDefaultForRole( int role, const QVariant& value );
116 
117     /** Set the dimension of the dataset in the source model. \sa AbstractDiagram::setDatasetDimension */
118     void setDatasetDimension( int dimension );
119     int datasetDimension() const;
120 
121 Q_SIGNALS:
122     void attributesChanged( const QModelIndex&, const QModelIndex& );
123 
124 private Q_SLOTS:
125     void slotRowsAboutToBeInserted( const QModelIndex& parent, int start, int end );
126     void slotColumnsAboutToBeInserted( const QModelIndex& parent, int start, int end );
127     void slotRowsInserted( const QModelIndex& parent, int start, int end );
128     void slotColumnsInserted( const QModelIndex& parent, int start, int end );
129 
130     void slotRowsAboutToBeRemoved( const QModelIndex& parent, int start, int end );
131     void slotColumnsAboutToBeRemoved( const QModelIndex& parent, int start, int end );
132     void slotRowsRemoved( const QModelIndex& parent, int start, int end );
133     void slotColumnsRemoved( const QModelIndex& parent, int start, int end );
134 
135     void slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight );
136 
137 private:
138     // helper
139     QVariant defaultsForRole( int role ) const;
140     bool compareHeaderDataMaps( const QMap< int, QMap< int, QVariant > >& mapA,
141                                 const QMap< int, QMap< int, QVariant > >& mapB ) const;
142 
143     void removeEntriesFromDataMap( int start, int end );
144     void removeEntriesFromDirectionDataMaps( Qt::Orientation dir, int start, int end );
145 };
146 
147 }
148 
149 #endif
150