724 lines
28 KiB
C++
724 lines
28 KiB
C++
/****************************************************************************
|
|
** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved.
|
|
**
|
|
** This file is part of the KD Chart library.
|
|
**
|
|
** Licensees holding valid commercial KD Chart licenses may use this file in
|
|
** accordance with the KD Chart Commercial License Agreement provided with
|
|
** the Software.
|
|
**
|
|
**
|
|
** This file may be distributed and/or modified under the terms of the
|
|
** GNU General Public License version 2 and version 3 as published by the
|
|
** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
|
|
**
|
|
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
**
|
|
** Contact info@kdab.com if any conditions of this licensing are not
|
|
** clear to you.
|
|
**
|
|
**********************************************************************/
|
|
|
|
#include "KDChartAttributesModel.h"
|
|
#include "KDChartPalette.h"
|
|
#include "KDChartGlobal.h"
|
|
|
|
#include <QDebug>
|
|
#include <QPen>
|
|
#include <QPointer>
|
|
|
|
#include <KDChartTextAttributes>
|
|
#include <KDChartFrameAttributes>
|
|
#include <KDChartBackgroundAttributes>
|
|
#include <KDChartDataValueAttributes>
|
|
#include <KDChartMarkerAttributes>
|
|
#include <KDChartBarAttributes>
|
|
#include <KDChartStockBarAttributes>
|
|
#include <KDChartLineAttributes>
|
|
#include <KDChartPieAttributes>
|
|
#include <KDChartAbstractThreeDAttributes>
|
|
#include <KDChartThreeDBarAttributes>
|
|
#include <KDChartThreeDLineAttributes>
|
|
#include <KDChartThreeDPieAttributes>
|
|
#include <KDChartGridAttributes>
|
|
#include <KDChartValueTrackerAttributes>
|
|
|
|
#include <KDABLibFakes>
|
|
|
|
|
|
using namespace KDChart;
|
|
|
|
AttributesModel::AttributesModel( QAbstractItemModel* model, QObject * parent/* = 0 */ )
|
|
: AbstractProxyModel( parent ),
|
|
mPaletteType( PaletteTypeDefault )
|
|
{
|
|
setSourceModel(model);
|
|
setDefaultForRole( KDChart::DataValueLabelAttributesRole,
|
|
DataValueAttributes::defaultAttributesAsVariant() );
|
|
}
|
|
|
|
AttributesModel::~AttributesModel()
|
|
{
|
|
}
|
|
|
|
void AttributesModel::initFrom( const AttributesModel* other )
|
|
{
|
|
if( other == this || ! other ) return;
|
|
|
|
mDataMap = other->mDataMap;
|
|
mHorizontalHeaderDataMap = other->mHorizontalHeaderDataMap;
|
|
mVerticalHeaderDataMap = other->mVerticalHeaderDataMap;
|
|
mModelDataMap = other->mModelDataMap;
|
|
mDefaultsMap = other->mDefaultsMap;
|
|
|
|
setPaletteType( other->paletteType() );
|
|
}
|
|
|
|
bool AttributesModel::compare( const AttributesModel* other )const
|
|
{
|
|
if( other == this ) return true;
|
|
if( ! other ){
|
|
//qDebug() << "AttributesModel::compare() cannot compare to Null pointer";
|
|
return false;
|
|
}
|
|
|
|
{
|
|
if (mDataMap.count() != other->mDataMap.count()){
|
|
//qDebug() << "AttributesModel::compare() dataMap have different sizes";
|
|
return false;
|
|
}
|
|
QMap<int, QMap<int, QMap<int, QVariant> > >::const_iterator itA = mDataMap.constBegin();
|
|
QMap<int, QMap<int, QMap<int, QVariant> > >::const_iterator itB = other->mDataMap.constBegin();
|
|
while (itA != mDataMap.constEnd()) {
|
|
if ((*itA).count() != (*itB).count()){
|
|
//qDebug() << "AttributesModel::compare() dataMap/map have different sizes";
|
|
return false;
|
|
}
|
|
QMap<int, QMap<int, QVariant> >::const_iterator it2A = (*itA).constBegin();
|
|
QMap<int, QMap<int, QVariant> >::const_iterator it2B = (*itB).constBegin();
|
|
while (it2A != itA->constEnd()) {
|
|
if ((*it2A).count() != (*it2B).count()){
|
|
//qDebug() << "AttributesModel::compare() dataMap/map/map have different sizes:"
|
|
// << (*it2A).count() << (*it2B).count();
|
|
return false;
|
|
}
|
|
QMap<int, QVariant>::const_iterator it3A = (*it2A).constBegin();
|
|
QMap<int, QVariant>::const_iterator it3B = (*it2B).constBegin();
|
|
while (it3A != it2A->constEnd()) {
|
|
if ( it3A.key() != it3B.key() ){
|
|
//qDebug( "AttributesModel::compare()\n"
|
|
// " dataMap[%i, %i] values have different types. A: %x B: %x",
|
|
// itA.key(), it2A.key(), it3A.key(), it3B.key());
|
|
return false;
|
|
}
|
|
if ( ! compareAttributes( it3A.key(), it3A.value(), it3B.value() ) ){
|
|
//qDebug( "AttributesModel::compare()\n"
|
|
// " dataMap[%i, %i] values are different. Role: %x", itA.key(), it2A.key(), it3A.key());
|
|
return false;
|
|
}
|
|
++it3A;
|
|
++it3B;
|
|
}
|
|
++it2A;
|
|
++it2B;
|
|
}
|
|
++itA;
|
|
++itB;
|
|
}
|
|
}
|
|
{
|
|
if (mHorizontalHeaderDataMap.count() != other->mHorizontalHeaderDataMap.count()){
|
|
//qDebug() << "AttributesModel::compare() horizontalHeaderDataMap have different sizes";
|
|
return false;
|
|
}
|
|
QMap<int, QMap<int, QVariant> >::const_iterator itA = mHorizontalHeaderDataMap.constBegin();
|
|
QMap<int, QMap<int, QVariant> >::const_iterator itB = other->mHorizontalHeaderDataMap.constBegin();
|
|
while (itA != mHorizontalHeaderDataMap.constEnd()) {
|
|
if ((*itA).count() != (*itB).count()){
|
|
//qDebug() << "AttributesModel::compare() horizontalHeaderDataMap/map have different sizes";
|
|
return false;
|
|
}
|
|
QMap<int, QVariant>::const_iterator it2A = (*itA).constBegin();
|
|
QMap<int, QVariant>::const_iterator it2B = (*itB).constBegin();
|
|
while (it2A != itA->constEnd()) {
|
|
if ( it2A.key() != it2B.key() ){
|
|
//qDebug( "AttributesModel::compare()\n"
|
|
// " horizontalHeaderDataMap[ %i ] values have different types. A: %x B: %x",
|
|
// itA.key(), it2A.key(), it2B.key());
|
|
return false;
|
|
}
|
|
if ( ! compareAttributes( it2A.key(), it2A.value(), it2B.value() ) ){
|
|
//qDebug( "AttributesModel::compare()\n"
|
|
// " horizontalHeaderDataMap[ %i ] values are different. Role: %x", itA.key(), it2A.key() );
|
|
return false;
|
|
}
|
|
++it2A;
|
|
++it2B;
|
|
}
|
|
++itA;
|
|
++itB;
|
|
}
|
|
}
|
|
{
|
|
if (mVerticalHeaderDataMap.count() != other->mVerticalHeaderDataMap.count()){
|
|
//qDebug() << "AttributesModel::compare() verticalHeaderDataMap have different sizes";
|
|
return false;
|
|
}
|
|
QMap<int, QMap<int, QVariant> >::const_iterator itA = mVerticalHeaderDataMap.constBegin();
|
|
QMap<int, QMap<int, QVariant> >::const_iterator itB = other->mVerticalHeaderDataMap.constBegin();
|
|
while (itA != mVerticalHeaderDataMap.constEnd()) {
|
|
if ((*itA).count() != (*itB).count()){
|
|
//qDebug() << "AttributesModel::compare() verticalHeaderDataMap/map have different sizes";
|
|
return false;
|
|
}
|
|
QMap<int, QVariant>::const_iterator it2A = (*itA).constBegin();
|
|
QMap<int, QVariant>::const_iterator it2B = (*itB).constBegin();
|
|
while (it2A != itA->constEnd()) {
|
|
if ( it2A.key() != it2B.key() ){
|
|
//qDebug( "AttributesModel::compare()\n"
|
|
// " verticalHeaderDataMap[ %i ] values have different types. A: %x B: %x",
|
|
// itA.key(), it2A.key(), it2B.key());
|
|
return false;
|
|
}
|
|
if ( ! compareAttributes( it2A.key(), it2A.value(), it2B.value() ) ){
|
|
//qDebug( "AttributesModel::compare()\n"
|
|
// " verticalHeaderDataMap[ %i ] values are different. Role: %x", itA.key(), it2A.key() );
|
|
return false;
|
|
}
|
|
++it2A;
|
|
++it2B;
|
|
}
|
|
++itA;
|
|
++itB;
|
|
}
|
|
}
|
|
{
|
|
if (mModelDataMap.count() != other->mModelDataMap.count()){
|
|
//qDebug() << "AttributesModel::compare() modelDataMap have different sizes:" << mModelDataMap.count() << other->mModelDataMap.count();
|
|
return false;
|
|
}
|
|
QMap<int, QVariant>::const_iterator itA = mModelDataMap.constBegin();
|
|
QMap<int, QVariant>::const_iterator itB = other->mModelDataMap.constBegin();
|
|
while (itA != mModelDataMap.constEnd()) {
|
|
if ( itA.key() != itB.key() ){
|
|
//qDebug( "AttributesModel::compare()\n"
|
|
// " modelDataMap values have different types. A: %x B: %x",
|
|
// itA.key(), itB.key());
|
|
return false;
|
|
}
|
|
if ( ! compareAttributes( itA.key(), itA.value(), itB.value() ) ){
|
|
//qDebug( "AttributesModel::compare()\n"
|
|
// " modelDataMap values are different. Role: %x", itA.key() );
|
|
return false;
|
|
}
|
|
++itA;
|
|
++itB;
|
|
}
|
|
}
|
|
if (paletteType() != other->paletteType()){
|
|
//qDebug() << "AttributesModel::compare() palette types are different";
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AttributesModel::compareAttributes(
|
|
int role, const QVariant& a, const QVariant& b )const
|
|
{
|
|
if( isKnownAttributesRole( role ) ){
|
|
switch( role ) {
|
|
case DataValueLabelAttributesRole:
|
|
return (qVariantValue<DataValueAttributes>( a ) ==
|
|
qVariantValue<DataValueAttributes>( b ));
|
|
case DatasetBrushRole:
|
|
return (qVariantValue<QBrush>( a ) ==
|
|
qVariantValue<QBrush>( b ));
|
|
case DatasetPenRole:
|
|
return (qVariantValue<QPen>( a ) ==
|
|
qVariantValue<QPen>( b ));
|
|
case ThreeDAttributesRole:
|
|
// As of yet there is no ThreeDAttributes class,
|
|
// and the AbstractThreeDAttributes class is pure virtual,
|
|
// so we ignore this role for now.
|
|
// (khz, 04.04.2007)
|
|
/*
|
|
return (qVariantValue<ThreeDAttributes>( a ) ==
|
|
qVariantValue<ThreeDAttributes>( b ));
|
|
*/
|
|
break;
|
|
case LineAttributesRole:
|
|
return (qVariantValue<LineAttributes>( a ) ==
|
|
qVariantValue<LineAttributes>( b ));
|
|
case ThreeDLineAttributesRole:
|
|
return (qVariantValue<ThreeDLineAttributes>( a ) ==
|
|
qVariantValue<ThreeDLineAttributes>( b ));
|
|
case BarAttributesRole:
|
|
return (qVariantValue<BarAttributes>( a ) ==
|
|
qVariantValue<BarAttributes>( b ));
|
|
case StockBarAttributesRole:
|
|
return (qVariantValue<StockBarAttributes>( a ) ==
|
|
qVariantValue<StockBarAttributes>( b ));
|
|
case ThreeDBarAttributesRole:
|
|
return (qVariantValue<ThreeDBarAttributes>( a ) ==
|
|
qVariantValue<ThreeDBarAttributes>( b ));
|
|
case PieAttributesRole:
|
|
return (qVariantValue<PieAttributes>( a ) ==
|
|
qVariantValue<PieAttributes>( b ));
|
|
case ThreeDPieAttributesRole:
|
|
return (qVariantValue<ThreeDPieAttributes>( a ) ==
|
|
qVariantValue<ThreeDPieAttributes>( b ));
|
|
case ValueTrackerAttributesRole:
|
|
return (qVariantValue<ValueTrackerAttributes>( a ) ==
|
|
qVariantValue<ValueTrackerAttributes>( b ));
|
|
case DataHiddenRole:
|
|
return (qVariantValue<bool>( a ) ==
|
|
qVariantValue<bool>( b ));
|
|
default:
|
|
Q_ASSERT( false ); // all of our own roles need to be handled
|
|
break;
|
|
}
|
|
}else{
|
|
return (a == b);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
QVariant AttributesModel::headerData ( int section,
|
|
Qt::Orientation orientation,
|
|
int role/* = Qt::DisplayRole */ ) const
|
|
{
|
|
if( sourceModel() ) {
|
|
const QVariant sourceData = sourceModel()->headerData( section, orientation, role );
|
|
if ( sourceData.isValid() ) return sourceData;
|
|
}
|
|
|
|
if( orientation == Qt::Horizontal && role == ColumnDataRole )
|
|
{
|
|
// it seems the source model doesn't like the idea of handing out all the column data at once...
|
|
// so we have to do it manually.
|
|
QVariantList result;
|
|
const int rows = sourceModel()->rowCount();
|
|
for( int row = 0; row < rows; ++row )
|
|
result.push_back( sourceModel()->index( row, section ).data() );
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
// the source model didn't have data set, let's use our stored values
|
|
const QMap<int, QMap<int, QVariant> >& map = orientation == Qt::Horizontal ? mHorizontalHeaderDataMap : mVerticalHeaderDataMap;
|
|
if ( map.contains( section ) ) {
|
|
const QMap<int, QVariant> &dataMap = map[ section ];
|
|
if ( dataMap.contains( role ) ) {
|
|
return dataMap[ role ];
|
|
}
|
|
}
|
|
|
|
return defaultHeaderData( section, orientation, role );
|
|
}
|
|
|
|
|
|
QVariant AttributesModel::defaultHeaderData ( int section, Qt::Orientation orientation, int role ) const
|
|
{
|
|
// Default values if nothing else matches
|
|
switch ( role ) {
|
|
case Qt::DisplayRole:
|
|
//TODO for KDChart 3.0: Change to "return QString::number( section+1 );"
|
|
return QString(QLatin1String( orientation == Qt::Vertical ? "Series " : "Item " ) + QString::number( section ) );
|
|
|
|
case KDChart::DatasetBrushRole: {
|
|
if ( paletteType() == PaletteTypeSubdued )
|
|
return Palette::subduedPalette().getBrush( section );
|
|
else if ( paletteType() == PaletteTypeRainbow )
|
|
return Palette::rainbowPalette().getBrush( section );
|
|
else if ( paletteType() == PaletteTypeDefault )
|
|
return Palette::defaultPalette().getBrush( section );
|
|
else
|
|
qWarning("Unknown type of fallback palette!");
|
|
} break;
|
|
case KDChart::DatasetPenRole: {
|
|
// default to the color set for the brush (or it's defaults)
|
|
// but only if no per model override was set
|
|
if ( !modelData( role ).isValid() ) {
|
|
QBrush brush = qVariantValue<QBrush>( headerData( section, orientation, DatasetBrushRole ) );
|
|
return QPen( brush.color() );
|
|
}
|
|
} break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
// Note: Our users NEED this method - even if
|
|
// we do not need it at drawing time!
|
|
// (khz, 2006-07-28)
|
|
QVariant AttributesModel::data( int role ) const
|
|
{
|
|
if ( isKnownAttributesRole( role ) ) {
|
|
// check if there is something set at global level
|
|
QVariant v = modelData( role );
|
|
|
|
// else return the default setting, if any
|
|
if ( !v.isValid() )
|
|
v = defaultsForRole( role );
|
|
return v;
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
|
|
// Note: Our users NEED this method - even if
|
|
// we do not need it at drawing time!
|
|
// (khz, 2006-07-28)
|
|
QVariant AttributesModel::data( int column, int role ) const
|
|
{
|
|
if ( isKnownAttributesRole( role ) ) {
|
|
// check if there is something set for the column (dataset)
|
|
QVariant v;
|
|
v = headerData( column, Qt::Horizontal, role );
|
|
|
|
// check if there is something set at global level
|
|
if ( !v.isValid() )
|
|
v = data( role ); // includes automatic fallback to default
|
|
return v;
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
|
|
QVariant AttributesModel::data( const QModelIndex& index, int role ) const
|
|
{
|
|
//qDebug() << "AttributesModel::data(" << index << role << ")";
|
|
if( index.isValid() ) {
|
|
Q_ASSERT( index.model() == this );
|
|
}
|
|
|
|
if( sourceModel() == 0 )
|
|
return QVariant();
|
|
|
|
if( index.isValid() )
|
|
{
|
|
const QVariant sourceData = sourceModel()->data( mapToSource(index), role );
|
|
if( sourceData.isValid() )
|
|
return sourceData;
|
|
}
|
|
|
|
// check if we are storing a value for this role at this cell index
|
|
if( mDataMap.contains( index.column() ) )
|
|
{
|
|
const QMap< int, QMap< int, QVariant > >& colDataMap = mDataMap[ index.column() ];
|
|
if( colDataMap.contains( index.row() ) )
|
|
{
|
|
const QMap< int, QVariant >& dataMap = colDataMap[ index.row() ];
|
|
if( dataMap.contains( role ) )
|
|
{
|
|
const QVariant v = dataMap[ role ];
|
|
if( v.isValid() )
|
|
return v;
|
|
}
|
|
}
|
|
}
|
|
// check if there is something set for the column (dataset), or at global level
|
|
if( index.isValid() )
|
|
return data( index.column(), role ); // includes automatic fallback to default
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
|
|
bool AttributesModel::isKnownAttributesRole( int role ) const
|
|
{
|
|
bool oneOfOurs = false;
|
|
switch( role ) {
|
|
// fallthrough intended
|
|
case DataValueLabelAttributesRole:
|
|
case DatasetBrushRole:
|
|
case DatasetPenRole:
|
|
case ThreeDAttributesRole:
|
|
case LineAttributesRole:
|
|
case ThreeDLineAttributesRole:
|
|
case BarAttributesRole:
|
|
case StockBarAttributesRole:
|
|
case ThreeDBarAttributesRole:
|
|
case PieAttributesRole:
|
|
case ThreeDPieAttributesRole:
|
|
case ValueTrackerAttributesRole:
|
|
case DataHiddenRole:
|
|
oneOfOurs = true;
|
|
default:
|
|
break;
|
|
}
|
|
return oneOfOurs;
|
|
}
|
|
|
|
QVariant AttributesModel::defaultsForRole( int role ) const
|
|
{
|
|
// returns default-constructed QVariant if not found
|
|
return mDefaultsMap.value( role );
|
|
}
|
|
|
|
bool AttributesModel::setData ( const QModelIndex & index, const QVariant & value, int role )
|
|
{
|
|
if ( !isKnownAttributesRole( role ) ) {
|
|
return sourceModel()->setData( mapToSource(index), value, role );
|
|
} else {
|
|
QMap< int, QMap< int, QVariant> > &colDataMap = mDataMap[ index.column() ];
|
|
QMap<int, QVariant> &dataMap = colDataMap[ index.row() ];
|
|
//qDebug() << "AttributesModel::setData" <<"role" << role << "value" << value;
|
|
dataMap.insert( role, value );
|
|
emit attributesChanged( index, index );
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool AttributesModel::resetData ( const QModelIndex & index, int role )
|
|
{
|
|
return setData ( index, QVariant(), role );
|
|
}
|
|
|
|
bool AttributesModel::setHeaderData ( int section, Qt::Orientation orientation,
|
|
const QVariant & value, int role )
|
|
{
|
|
if( sourceModel() != 0 && headerData( section, orientation, role ) == value )
|
|
return true;
|
|
if ( !isKnownAttributesRole( role ) ) {
|
|
return sourceModel()->setHeaderData( section, orientation, value, role );
|
|
} else {
|
|
QMap<int, QMap<int, QVariant> > §ionDataMap
|
|
= orientation == Qt::Horizontal ? mHorizontalHeaderDataMap : mVerticalHeaderDataMap;
|
|
QMap<int, QVariant> &dataMap = sectionDataMap[ section ];
|
|
dataMap.insert( role, value );
|
|
if( sourceModel() ){
|
|
emit attributesChanged( index( 0, section, QModelIndex() ),
|
|
index( rowCount( QModelIndex() ), section, QModelIndex() ) );
|
|
emit headerDataChanged( orientation, section, section );
|
|
if ( section != -1 )
|
|
emit dataChanged( index( 0, section, QModelIndex() ),
|
|
index( rowCount( QModelIndex() ) - 1, section, QModelIndex() ) );
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool AttributesModel::resetHeaderData ( int section, Qt::Orientation orientation, int role )
|
|
{
|
|
return setHeaderData ( section, orientation, QVariant(), role );
|
|
}
|
|
|
|
void AttributesModel::setPaletteType( AttributesModel::PaletteType type )
|
|
{
|
|
mPaletteType = type;
|
|
}
|
|
|
|
AttributesModel::PaletteType AttributesModel::paletteType() const
|
|
{
|
|
return mPaletteType;
|
|
}
|
|
|
|
bool KDChart::AttributesModel::setModelData( const QVariant value, int role )
|
|
{
|
|
mModelDataMap.insert( role, value );
|
|
if( sourceModel() ){
|
|
emit attributesChanged( index( 0, 0, QModelIndex() ),
|
|
index( rowCount( QModelIndex() ),
|
|
columnCount( QModelIndex() ), QModelIndex() ) );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
QVariant KDChart::AttributesModel::modelData( int role ) const
|
|
{
|
|
return mModelDataMap.value( role, QVariant() );
|
|
}
|
|
|
|
int AttributesModel::rowCount( const QModelIndex& index ) const
|
|
{
|
|
if ( sourceModel() ) {
|
|
return sourceModel()->rowCount( mapToSource(index) );
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int AttributesModel::columnCount( const QModelIndex& index ) const
|
|
{
|
|
if ( sourceModel() ) {
|
|
return sourceModel()->columnCount( mapToSource(index) );
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void AttributesModel::setSourceModel( QAbstractItemModel* sourceModel )
|
|
{
|
|
if( this->sourceModel() != 0 )
|
|
{
|
|
disconnect( this->sourceModel(), SIGNAL( dataChanged( const QModelIndex&, const QModelIndex&)),
|
|
this, SLOT( slotDataChanged( const QModelIndex&, const QModelIndex&)));
|
|
disconnect( this->sourceModel(), SIGNAL( rowsInserted( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotRowsInserted( const QModelIndex&, int, int ) ) );
|
|
disconnect( this->sourceModel(), SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotRowsRemoved( const QModelIndex&, int, int ) ) );
|
|
disconnect( this->sourceModel(), SIGNAL( rowsAboutToBeInserted( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotRowsAboutToBeInserted( const QModelIndex&, int, int ) ) );
|
|
disconnect( this->sourceModel(), SIGNAL( rowsAboutToBeRemoved( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotRowsAboutToBeRemoved( const QModelIndex&, int, int ) ) );
|
|
disconnect( this->sourceModel(), SIGNAL( columnsInserted( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotColumnsInserted( const QModelIndex&, int, int ) ) );
|
|
disconnect( this->sourceModel(), SIGNAL( columnsRemoved( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotColumnsRemoved( const QModelIndex&, int, int ) ) );
|
|
disconnect( this->sourceModel(), SIGNAL( columnsAboutToBeInserted( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotColumnsAboutToBeInserted( const QModelIndex&, int, int ) ) );
|
|
disconnect( this->sourceModel(), SIGNAL( columnsAboutToBeRemoved( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotColumnsAboutToBeRemoved( const QModelIndex&, int, int ) ) );
|
|
disconnect( this->sourceModel(), SIGNAL( modelReset() ),
|
|
this, SIGNAL( modelReset() ) );
|
|
disconnect( this->sourceModel(), SIGNAL( layoutChanged() ),
|
|
this, SIGNAL( layoutChanged() ) );
|
|
}
|
|
QAbstractProxyModel::setSourceModel( sourceModel );
|
|
if( this->sourceModel() != NULL )
|
|
{
|
|
connect( this->sourceModel(), SIGNAL( dataChanged( const QModelIndex&, const QModelIndex&)),
|
|
this, SLOT( slotDataChanged( const QModelIndex&, const QModelIndex&)));
|
|
connect( this->sourceModel(), SIGNAL( rowsInserted( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotRowsInserted( const QModelIndex&, int, int ) ) );
|
|
connect( this->sourceModel(), SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotRowsRemoved( const QModelIndex&, int, int ) ) );
|
|
connect( this->sourceModel(), SIGNAL( rowsAboutToBeInserted( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotRowsAboutToBeInserted( const QModelIndex&, int, int ) ) );
|
|
connect( this->sourceModel(), SIGNAL( rowsAboutToBeRemoved( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotRowsAboutToBeRemoved( const QModelIndex&, int, int ) ) );
|
|
connect( this->sourceModel(), SIGNAL( columnsInserted( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotColumnsInserted( const QModelIndex&, int, int ) ) );
|
|
connect( this->sourceModel(), SIGNAL( columnsRemoved( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotColumnsRemoved( const QModelIndex&, int, int ) ) );
|
|
connect( this->sourceModel(), SIGNAL( columnsAboutToBeInserted( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotColumnsAboutToBeInserted( const QModelIndex&, int, int ) ) );
|
|
connect( this->sourceModel(), SIGNAL( columnsAboutToBeRemoved( const QModelIndex&, int, int ) ),
|
|
this, SLOT( slotColumnsAboutToBeRemoved( const QModelIndex&, int, int ) ) );
|
|
connect( this->sourceModel(), SIGNAL( modelReset() ),
|
|
this, SIGNAL( modelReset() ) );
|
|
connect( this->sourceModel(), SIGNAL( layoutChanged() ),
|
|
this, SIGNAL( layoutChanged() ) );
|
|
}
|
|
}
|
|
|
|
void AttributesModel::slotRowsAboutToBeInserted( const QModelIndex& parent, int start, int end )
|
|
{
|
|
beginInsertRows( mapFromSource( parent ), start, end );
|
|
}
|
|
|
|
void AttributesModel::slotColumnsAboutToBeInserted( const QModelIndex& parent, int start, int end )
|
|
{
|
|
beginInsertColumns( mapFromSource( parent ), start, end );
|
|
}
|
|
|
|
void AttributesModel::slotRowsInserted( const QModelIndex& parent, int start, int end )
|
|
{
|
|
Q_UNUSED( parent );
|
|
Q_UNUSED( start );
|
|
Q_UNUSED( end );
|
|
endInsertRows();
|
|
}
|
|
|
|
void AttributesModel::slotColumnsInserted( const QModelIndex& parent, int start, int end )
|
|
{
|
|
Q_UNUSED( parent );
|
|
Q_UNUSED( start );
|
|
Q_UNUSED( end );
|
|
endInsertColumns();
|
|
}
|
|
|
|
void AttributesModel::slotRowsAboutToBeRemoved( const QModelIndex& parent, int start, int end )
|
|
{
|
|
beginRemoveRows( mapFromSource( parent ), start, end );
|
|
}
|
|
|
|
void AttributesModel::slotColumnsAboutToBeRemoved( const QModelIndex& parent, int start, int end )
|
|
{
|
|
beginRemoveColumns( mapFromSource( parent ), start, end );
|
|
}
|
|
|
|
void AttributesModel::slotRowsRemoved( const QModelIndex& parent, int start, int end )
|
|
{
|
|
Q_UNUSED( parent );
|
|
Q_UNUSED( start );
|
|
Q_UNUSED( end );
|
|
endRemoveRows();
|
|
}
|
|
|
|
void AttributesModel::slotColumnsRemoved( const QModelIndex& parent, int start, int end )
|
|
{
|
|
Q_UNUSED( parent );
|
|
Q_UNUSED( start );
|
|
Q_UNUSED( end );
|
|
endRemoveColumns();
|
|
}
|
|
|
|
void AttributesModel::slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight )
|
|
{
|
|
emit dataChanged( mapFromSource( topLeft ), mapFromSource( bottomRight ) );
|
|
}
|
|
|
|
/** needed for serialization */
|
|
const QMap<int, QMap<int, QMap<int, QVariant> > > AttributesModel::dataMap()const
|
|
{
|
|
return mDataMap;
|
|
}
|
|
/** needed for serialization */
|
|
const QMap<int, QMap<int, QVariant> > AttributesModel::horizontalHeaderDataMap()const
|
|
{
|
|
return mHorizontalHeaderDataMap;
|
|
}
|
|
/** needed for serialization */
|
|
const QMap<int, QMap<int, QVariant> > AttributesModel::verticalHeaderDataMap()const
|
|
{
|
|
return mVerticalHeaderDataMap;
|
|
}
|
|
/** needed for serialization */
|
|
const QMap<int, QVariant> AttributesModel::modelDataMap()const
|
|
{
|
|
return mModelDataMap;
|
|
}
|
|
|
|
/** needed for serialization */
|
|
void AttributesModel::setDataMap( const QMap<int, QMap<int, QMap<int, QVariant> > > map )
|
|
{
|
|
mDataMap = map;
|
|
}
|
|
/** needed for serialization */
|
|
void AttributesModel::setHorizontalHeaderDataMap( const QMap<int, QMap<int, QVariant> > map )
|
|
{
|
|
mHorizontalHeaderDataMap = map;
|
|
}
|
|
/** needed for serialization */
|
|
void AttributesModel::setVerticalHeaderDataMap( const QMap<int, QMap<int, QVariant> > map )
|
|
{
|
|
mVerticalHeaderDataMap = map;
|
|
}
|
|
/** needed for serialization */
|
|
void AttributesModel::setModelDataMap( const QMap<int, QVariant> map )
|
|
{
|
|
mModelDataMap = map;
|
|
}
|
|
|
|
void AttributesModel::setDefaultForRole( int role, const QVariant& value )
|
|
{
|
|
if ( value.isValid() ) {
|
|
mDefaultsMap.insert( role, value );
|
|
} else {
|
|
// erase the possibily existing value to not let the map grow:
|
|
QMap<int, QVariant>::iterator it = mDefaultsMap.find( role );
|
|
if ( it != mDefaultsMap.end() ) {
|
|
mDefaultsMap.erase( it );
|
|
}
|
|
}
|
|
|
|
Q_ASSERT( defaultsForRole( role ) == value );
|
|
}
|