35 #include <KDABLibFakes> 
   39 class AttributesModel::Private
 
   49     int dataDimension = 1;
 
   54 AttributesModel::Private::Private()
 
   55     : palette(
Palette::defaultPalette())
 
   61 AttributesModel::AttributesModel(QAbstractItemModel *model, QObject *parent )
 
   84     if (mapA.count() != mapB.count()) {
 
   89     for (; itA != mapA.constEnd(); ++itA, ++itB) {
 
   90         if (itA->count() != itB->count()) {
 
   95         for (; it2A != itA->constEnd(); ++it2A, ++it2B) {
 
   96             if (it2A.key() != it2B.key()) {
 
  112     if (!other || 
d->paletteType != other->d->
paletteType) {
 
  117         if (
d->dataMap.count() != other->d->dataMap.count()) {
 
  122         for (; itA != 
d->dataMap.constEnd(); ++itA, ++itB) {
 
  123             if (itA->count() != itB->count()) {
 
  128             for (; it2A != itA->constEnd(); ++it2A, ++it2B) {
 
  129                 if (it2A->count() != it2B->count()) {
 
  134                 for (; it3A != it2A->constEnd(); ++it3A, ++it3B) {
 
  135                     if (it3A.key() != it3B.key()) {
 
  146     if (!compareHeaderDataMaps(
d->horizontalHeaderDataMap, other->d->horizontalHeaderDataMap) || !compareHeaderDataMaps(
d->verticalHeaderDataMap, other->d->verticalHeaderDataMap)) {
 
  151         if (
d->modelDataMap.count() != other->d->modelDataMap.count()) {
 
  156         for (; itA != 
d->modelDataMap.constEnd(); ++itA, ++itB) {
 
  157             if (itA.key() != itB.key()) {
 
  169     int role, 
const QVariant &a, 
const QVariant &b)
 const 
  176             return (a.value<QBrush>() == b.value<QBrush>());
 
  178             return (a.value<QPen>() == b.value<QPen>());
 
  206             return (a.value<
bool>() == b.value<
bool>());
 
  221         const QVariant sourceData = sourceModel()->headerData(section, orientation, role);
 
  222         if (sourceData.isValid()) {
 
  230     if (mapIt != map.constEnd()) {
 
  233         if (dataMapIt != dataMap.constEnd()) {
 
  234             return dataMapIt.value();
 
  245     const int dataset = section / 
d->dataDimension;
 
  248     case Qt::DisplayRole:
 
  250         return QString {QLatin1String(orientation == Qt::Vertical ? 
"Series " : 
"Item ") + QString::number(dataset)};
 
  252         return d->palette.getBrush(dataset);
 
  257             return QPen(brush.color());
 
  274             v = defaultsForRole(role);
 
  297     if (
index.isValid()) {
 
  298         Q_ASSERT(
index.model() == 
this);
 
  300     if (!sourceModel()) {
 
  304     if (
index.isValid()) {
 
  306         if (sourceData.isValid()) {
 
  312     if (
d->dataMap.contains(
index.column())) {
 
  314         if (colDataMap.contains(
index.row())) {
 
  316             if (dataMap.contains(role)) {
 
  317                 const QVariant v = dataMap[role];
 
  325     if (
index.isValid()) {
 
  355 QVariant AttributesModel::defaultsForRole(
int role)
 const 
  358     return d->defaultsMap.value(role);
 
  368         dataMap.insert(role, value);
 
  380                                     const QVariant &value, 
int role)
 
  382     if (sourceModel() && 
headerData(section, orientation, role) == value) {
 
  387         return sourceModel()->setHeaderData(section, orientation, value, role);
 
  392         dataMap.insert(role, value);
 
  394             int numRows = 
rowCount(QModelIndex());
 
  396             if (orientation == Qt::Horizontal && numRows > 0)
 
  398                                          index(numRows - 1, section, QModelIndex()));
 
  399             else if (orientation == Qt::Vertical && numCols > 0)
 
  401                                          index(section, numCols - 1, QModelIndex()));
 
  402             Q_EMIT headerDataChanged(orientation, section, section);
 
  406             if (section != -1 && numRows > 0)
 
  407                 Q_EMIT dataChanged(
index(0, section, QModelIndex()),
 
  408                                    index(numRows - 1, section, QModelIndex()));
 
  416     return setHeaderData(section, orientation, QVariant(), role);
 
  421     if (
d->paletteType == type) {
 
  424     d->paletteType = type;
 
  436         qWarning(
"Unknown palette type!");
 
  442     return d->paletteType;
 
  447     d->modelDataMap.insert(role, value);
 
  448     int numRows = rowCount(QModelIndex());
 
  449     int numCols = columnCount(QModelIndex());
 
  450     if (sourceModel() && numRows > 0 && numCols > 0) {
 
  451         Q_EMIT attributesChanged(index(0, 0, QModelIndex()),
 
  452                                  index(numRows - 1, numCols - 1, QModelIndex()));
 
  461     return d->modelDataMap.value(role, QVariant());
 
  484     QAbstractItemModel *oldModel = sourceModel();
 
  485     if (oldModel != 
nullptr) {
 
  486         disconnect(oldModel, &QAbstractItemModel::dataChanged,
 
  487                    this, &AttributesModel::slotDataChanged);
 
  488         disconnect(oldModel, &QAbstractItemModel::rowsInserted,
 
  489                    this, &AttributesModel::slotRowsInserted);
 
  490         disconnect(oldModel, &QAbstractItemModel::rowsRemoved,
 
  491                    this, &AttributesModel::slotRowsRemoved);
 
  492         disconnect(oldModel, &QAbstractItemModel::rowsAboutToBeInserted,
 
  493                    this, &AttributesModel::slotRowsAboutToBeInserted);
 
  494         disconnect(oldModel, &QAbstractItemModel::rowsAboutToBeRemoved,
 
  495                    this, &AttributesModel::slotRowsAboutToBeRemoved);
 
  496         disconnect(oldModel, &QAbstractItemModel::columnsInserted,
 
  497                    this, &AttributesModel::slotColumnsInserted);
 
  498         disconnect(oldModel, &QAbstractItemModel::columnsRemoved,
 
  499                    this, &AttributesModel::slotColumnsRemoved);
 
  500         disconnect(oldModel, &QAbstractItemModel::columnsAboutToBeInserted,
 
  501                    this, &AttributesModel::slotColumnsAboutToBeInserted);
 
  502         disconnect(oldModel, &QAbstractItemModel::columnsAboutToBeRemoved,
 
  503                    this, &AttributesModel::slotColumnsAboutToBeRemoved);
 
  504         disconnect(oldModel, &QAbstractItemModel::modelAboutToBeReset,
 
  505                    this, &AttributesModel::modelAboutToBeReset);
 
  506         disconnect(oldModel, &QAbstractItemModel::modelReset,
 
  507                    this, &AttributesModel::modelReset);
 
  508         disconnect(oldModel, &QAbstractItemModel::layoutChanged,
 
  509                    this, &AttributesModel::layoutChanged);
 
  511     QAbstractProxyModel::setSourceModel(newModel);
 
  512     if (newModel != 
nullptr) {
 
  513         connect(newModel, &QAbstractItemModel::dataChanged,
 
  514                 this, &AttributesModel::slotDataChanged);
 
  515         connect(newModel, &QAbstractItemModel::rowsInserted,
 
  516                 this, &AttributesModel::slotRowsInserted);
 
  517         connect(newModel, &QAbstractItemModel::rowsRemoved,
 
  518                 this, &AttributesModel::slotRowsRemoved);
 
  519         connect(newModel, &QAbstractItemModel::rowsAboutToBeInserted,
 
  520                 this, &AttributesModel::slotRowsAboutToBeInserted);
 
  521         connect(newModel, &QAbstractItemModel::rowsAboutToBeRemoved,
 
  522                 this, &AttributesModel::slotRowsAboutToBeRemoved);
 
  523         connect(newModel, &QAbstractItemModel::columnsInserted,
 
  524                 this, &AttributesModel::slotColumnsInserted);
 
  525         connect(newModel, &QAbstractItemModel::columnsRemoved,
 
  526                 this, &AttributesModel::slotColumnsRemoved);
 
  527         connect(newModel, &QAbstractItemModel::columnsAboutToBeInserted,
 
  528                 this, &AttributesModel::slotColumnsAboutToBeInserted);
 
  529         connect(newModel, &QAbstractItemModel::columnsAboutToBeRemoved,
 
  530                 this, &AttributesModel::slotColumnsAboutToBeRemoved);
 
  531         connect(newModel, &QAbstractItemModel::modelAboutToBeReset,
 
  532                 this, &AttributesModel::modelAboutToBeReset);
 
  533         connect(newModel, &QAbstractItemModel::modelReset,
 
  534                 this, &AttributesModel::modelReset);
 
  535         connect(newModel, &QAbstractItemModel::layoutChanged,
 
  536                 this, &AttributesModel::layoutChanged);
 
  540 void AttributesModel::slotRowsAboutToBeInserted(
const QModelIndex &parent, 
int start, 
int end)
 
  545 void AttributesModel::slotColumnsAboutToBeInserted(
const QModelIndex &parent, 
int start, 
int end)
 
  550 void AttributesModel::slotRowsInserted(
const QModelIndex &parent, 
int start, 
int end)
 
  558 void AttributesModel::slotColumnsInserted(
const QModelIndex &parent, 
int start, 
int end)
 
  566 void AttributesModel::slotRowsAboutToBeRemoved(
const QModelIndex &parent, 
int start, 
int end)
 
  571 void AttributesModel::slotColumnsAboutToBeRemoved(
const QModelIndex &parent, 
int start, 
int end)
 
  576 void AttributesModel::slotRowsRemoved(
const QModelIndex &parent, 
int start, 
int end)
 
  584 void AttributesModel::removeEntriesFromDataMap(
int start, 
int end)
 
  588     if (it != 
d->dataMap.end()) {
 
  590         QVector<int> indexesToDel;
 
  591         for (
int i = start; i < end && it != 
d->dataMap.end(); ++i) {
 
  592             d->dataMap[i] = it.value();
 
  593             indexesToDel << it.key();
 
  596         if (indexesToDel.isEmpty()) {
 
  597             for (
int i = start; i < end; ++i) {
 
  601         for (
int i = 0; i < indexesToDel.count(); ++i) {
 
  602             d->dataMap.remove(indexesToDel[i]);
 
  607 void AttributesModel::removeEntriesFromDirectionDataMaps(Qt::Orientation dir, 
int start, 
int end)
 
  612     if (it != sectionDataMap.end()) {
 
  613         QVector<int> indexesToDel;
 
  614         for (
int i = start; i < end && it != sectionDataMap.end(); ++i) {
 
  615             sectionDataMap[i] = it.value();
 
  616             indexesToDel << it.key();
 
  619         if (indexesToDel.isEmpty()) {
 
  620             for (
int i = start; i < end; ++i) {
 
  624         for (
int i = 0; i < indexesToDel.count(); ++i) {
 
  625             sectionDataMap.remove(indexesToDel[i]);
 
  630 void AttributesModel::slotColumnsRemoved(
const QModelIndex &parent, 
int start, 
int end)
 
  635     Q_ASSERT_X(sourceModel(), 
"removeColumn", 
"This should only be triggered if a valid source Model exists!");
 
  636     for (
int i = start; i <= end; ++i) {
 
  637         d->verticalHeaderDataMap.remove(start);
 
  639     removeEntriesFromDataMap(start, end);
 
  640     removeEntriesFromDirectionDataMaps(Qt::Horizontal, start, end);
 
  641     removeEntriesFromDirectionDataMaps(Qt::Vertical, start, end);
 
  646 void AttributesModel::slotDataChanged(
const QModelIndex &topLeft, 
const QModelIndex &bottomRight)
 
  653     if (value.isValid()) {
 
  654         d->defaultsMap.insert(role, value);
 
  658         if (it != 
d->defaultsMap.end()) {
 
  659             d->defaultsMap.erase(it);
 
  669     d->dataDimension = dimension;
 
  674     return d->dataDimension;
 
Declaring the class KDChart::DataValueAttributes.
Base class for all proxy models used inside KD Chart.
QModelIndex index(int row, int col, const QModelIndex &index) const override
Reimplemented for internal purposes.
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
Reimplemented for internal purposes.
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
Reimplemented for internal purposes.
QModelIndex parent(const QModelIndex &index) const override
Reimplemented for internal purposes.
A proxy model used for decorating data with attributes.
virtual QVariant defaultHeaderData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
int datasetDimension() const
void attributesChanged(const QModelIndex &, const QModelIndex &)
PaletteType paletteType() const
QVariant data(int role) const
int rowCount(const QModelIndex &) const override
bool compareAttributes(int role, const QVariant &a, const QVariant &b) const
void setDatasetDimension(int dimension)
~AttributesModel() override
bool resetHeaderData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole)
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role=Qt::DisplayRole) override
QVariant modelData(int role) const
void setPaletteType(PaletteType type)
void setSourceModel(QAbstractItemModel *sourceModel) override
bool resetData(const QModelIndex &index, int role=Qt::DisplayRole)
void setDefaultForRole(int role, const QVariant &value)
void initFrom(const AttributesModel *other)
bool compare(const AttributesModel *other) const
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole) override
bool isKnownAttributesRole(int role) const
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
int columnCount(const QModelIndex &) const override
bool setModelData(const QVariant value, int role)
Set of attributes for changing the appearance of bar charts.
Diagram attributes dealing with data value labels.
static const QVariant & defaultAttributesAsVariant()
Set of attributes for changing the appearance of line charts.
A Palette is a set of brushes (or colors) to be used for painting data sets.
static const Palette & subduedPalette()
static const Palette & defaultPalette()
static const Palette & rainbowPalette()
A set of attributes controlling the appearance of pie charts.
Attributes to customize the appearance of a column in a stock chart.
A set of 3D bar attributes.
A set of 3D line attributes.
A set of 3D pie attributes.
Cell-specific attributes regarding value tracking.
@ DataValueLabelAttributesRole
@ ThreeDLineAttributesRole
@ ThreeDBarAttributesRole
@ ThreeDPieAttributesRole
@ ValueTrackerAttributesRole