File indexing completed on 2024-05-12 16:33:28

0001 /* This file is part of the KDE project
0002 
0003    Copyright 2007 Johannes Simon <johannes.simon@gmail.com>
0004 
0005    This library is free software; you can redistribute it and/or
0006    modify it under the terms of the GNU Library General Public
0007    License as published by the Free Software Foundation; either
0008    version 2 of the License, or (at your option) any later version.
0009 
0010    This library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public License
0016    along with this library; see the file COPYING.LIB.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018    Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #ifndef KCHART_PROXYMODEL_H
0022 #define KCHART_PROXYMODEL_H
0023 
0024 
0025 #define INTERNAL_TABLE_NAME "ChartTable"
0026 
0027 
0028 // KoChart
0029 #include "ChartShape.h"
0030 #include "CellRegion.h"
0031 
0032 
0033 namespace KoChart
0034 {
0035     class ChartModel;
0036 }
0037 
0038 
0039 // Qt
0040 #include <QAbstractTableModel>
0041 
0042 
0043 namespace KoChart {
0044 
0045 /**
0046  * @brief The ChartProxyModel is a factory for the DataSet's and decorates the ChartTableModel.
0047  *
0048  * TODO: Rename this class to something more meaningful (and correct) like
0049  * "DataProvider" and maybe split it up into one class that handles the
0050  * QAbstractItemModel part, and another one that handles CellRegions for
0051  * all the data points.
0052  */
0053 class ChartProxyModel : public QAbstractTableModel
0054 {
0055     Q_OBJECT
0056 
0057 public:
0058     ChartProxyModel(ChartShape *shape, TableSource *source);
0059     ~ChartProxyModel();
0060 
0061     /**
0062      * Used for data retrieval of all relevant dimensions: x, y, z, etc.
0063      *
0064      * This enum may be extended at a later point to store and retrieve
0065      * attributes.
0066      */
0067     enum DataRole {
0068         XDataRole = Qt::UserRole,
0069         YDataRole,
0070         CustomDataRole,
0071         LabelDataRole,
0072         CategoryDataRole
0073     };
0074 
0075     /**
0076      * Re-initializes the model with data from an arbitrary region.
0077      *
0078      * All data will be taken from the data source passed in the constructor.
0079      * The ProxyModel will not react on insertions or removals in one of
0080      * these models.
0081      */
0082     void reset(const CellRegion &region);
0083 
0084     /**
0085      * The CellRegion that data in this proxy model is taken from.
0086      *
0087      * In ODF, this is an attribute of the PlotArea, but here the proxy model
0088      * manages all data sets, thus it's also responsible for this attribute.
0089      *
0090      * See table:cell-range-address, ODF v1.2, ยง19.595
0091      */
0092     CellRegion cellRangeAddress() const;
0093 
0094     /**
0095     * Load series from ODF
0096     */
0097     bool loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context, ChartType type);
0098     void saveOdf(KoShapeSavingContext &context) const;
0099 
0100     /**
0101      * Returns data or properties of a data point.
0102      *
0103      * TODO: Not implemented yet. At the moment, DataSet's data and attribute
0104      * getter are used instead.
0105      */
0106     QVariant data(const QModelIndex &index, int role) const override;
0107 
0108     /**
0109      * Returns properties that are global to either a data set or a category,
0110      * depending on the orientation.
0111      *
0112      * If @a orientation is Qt::Horizontal, this method will return properties
0113      * global do the data set with number @a section.
0114      * If @a orientation is Qt::Vertical, it will return properties global to
0115      * the category with index @a section.
0116      *
0117      * TODO: Not implemented yet. At the moment, DataSet's data and attribute
0118      * getter are used instead.
0119      */
0120     QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
0121 
0122     QModelIndex parent(const QModelIndex &index) const override;
0123 
0124     /**
0125      * Returns the number of data sets in this model.
0126      */
0127     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0128 
0129     /**
0130      * Returns maximum the number of data points the data sets have.
0131      */
0132     int columnCount(const QModelIndex &parent = QModelIndex()) const override;
0133 
0134     // The following methods are specific to the chart
0135     void setFirstRowIsLabel(bool b);
0136     void setFirstColumnIsLabel(bool b);
0137     void setDataDirection(Qt::Orientation orientation);
0138     void setDataDimensions(int dimensions);
0139 
0140     bool firstRowIsLabel() const;
0141     bool firstColumnIsLabel() const;
0142     Qt::Orientation dataDirection();
0143     
0144     /**
0145      * @see setCategoryDataRegion()
0146      */
0147     CellRegion categoryDataRegion() const;
0148 
0149     /**
0150      * Sets the region to use for categories, i.e. the labels for a certain
0151      * index in all data sets. This is what will be used to label points
0152      * on the x axis in a cartesian chart and what will be used as legend
0153      * items in a polar chart.
0154      */
0155     void setCategoryDataRegion(const CellRegion &region);
0156 
0157     /**
0158      * A list of all data sets that are currently being used in the chart.
0159      */
0160     QList<DataSet*> dataSets() const;
0161 
0162     /**
0163      * Insert @p count number of rows at position @p row.
0164      * 
0165      * Effectively adds DataSet(s) to the model
0166      */
0167     bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
0168     /**
0169      * Remove @p count number of rows at position @p row.
0170      * 
0171      * Effectively removes DataSet(s) from the model
0172      */
0173     bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
0174 
0175     /**
0176      * Clears the list of data sets, but keeps them in a list of "removed"
0177      * data sets for the next time that reset() is called. The latter list
0178      * will be re-used so that properties of data sets don't get lost.
0179      */
0180     void invalidateDataSets();
0181 
0182     /**
0183      * Called by ChartShape when it begins loading from ODF.
0184      *
0185      * The proxy model will then avoid any insertion, removal or data-change
0186      * signals or calls to speed up loading (significantly for large amounts
0187      * of data).
0188      *
0189      * Properties like firstRowIsLabel() can still be modified, the changes
0190      * will simply not get propagated until endLoading() is called.
0191      */
0192     void beginLoading();
0193 
0194     /**
0195      * Called by ChartShape when it is done loading from ODF.
0196      *
0197      * The proxy model will then be reset with its current properties.
0198      */
0199     void endLoading();
0200 
0201     /**
0202      * Returns true if beginLoading() got called and endLoading() not
0203      * yet what means we are in a longer loading process.
0204      */
0205     bool isLoading() const;
0206 
0207     /**
0208      * Returns true if changes to datasets or data does not result in auto calculating changes
0209      */
0210     bool manualControl();
0211 
0212 public Q_SLOTS:
0213     /**
0214      * Connected to dataChanged() signal of source models in TableSource.
0215      */
0216     virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
0217 
0218     /**
0219      * Called by the TableSource whenever a table is added to it.
0220      *
0221      * TODO: It might improve performance if tables are only added when
0222      * they are really in use. That is not necessarily the case if they
0223      * are in the TableSource.
0224      */
0225     void addTable(Table *table);
0226 
0227     /**
0228      * Called by the TableSource whenever a table is removed from it.
0229      */
0230     void removeTable(Table *table);
0231 
0232     /**
0233      * Set manual control to @p value
0234      * 
0235      * If false, dataset structure is recalculated on changes to base data.
0236      */
0237     void setManualControl(bool value);
0238 
0239 Q_SIGNALS:
0240     void dataChanged();
0241 
0242 private:
0243     void addDataSet(int pos);
0244 
0245 private:
0246     class Private;
0247     Private *const d;
0248 };
0249 
0250 } // namespace KoChart
0251 
0252 #endif // KCHART_PROXYMODEL_H