21#include "moc_qgsrasterattributetablemodel.cpp"
24 : QAbstractTableModel( parent )
40 return mRat && mRat->hasColor();
45 return mRat && mRat->hasRamp();
53 const QList<QgsRasterAttributeTable::Field> &ratFields { mRat->fields() };
56 headers.push_back( f.name );
61 headers.append( ratColorHeaderName() );
70 if ( section < 0 || section >= hNames.count() )
75 const QString fieldName { hNames.at( section ) };
76 const bool isColor {
hasColor() && section == hNames.count() - 1 };
80 return tr(
"Virtual color field generated from the values in RGB(A) data columns" );
91 return QStringLiteral( R
"HTML(
93 <dt>Role</dt><dd>%1</dd>
94 <dt>Type</dt><dd>%2</dd>
95 <dt>Description</dt><dd>%3</dd>
107 *errorMessage = tr(
"Raster Attribute Table is not set for this model." );
111 return mRat->isValid( errorMessage );
116 return mRat && mRat->isDirty();
121 if ( !editChecks( errorMessage ) )
130 *errorMessage = QObject::tr(
"Invalid position '%1' for field insertion." ).arg( position );
135 const int newPosition { std::clamp( position, 0,
static_cast<int>( mRat->fields().count() ) ) };
136 const QgsRasterAttributeTable::Field field { name, usage, type };
138 const bool retVal { mRat->insertField( newPosition, field, errorMessage ) };
151 if ( !editChecks( errorMessage ) )
156 if ( position < 0 || position >= mRat->fields().count() )
160 *errorMessage = QObject::tr(
"Invalid position '%1' for field removal." ).arg( position );
166 const bool retVal { mRat->removeField( mRat->fields().at( position ).name, errorMessage ) };
173 if ( !editChecks( errorMessage ) )
178 if ( !mRat->hasColor() && !mRat->hasRamp() )
182 *errorMessage = tr(
"Raster attribute table does not have color or ramp information." );
189 const QList<QgsRasterAttributeTable::Field> ratFields { mRat->fields() };
190 for (
const QgsRasterAttributeTable::Field &f : std::as_const( ratFields ) )
192 if ( f.isColor() || f.isRamp() )
194 ret &= mRat->removeField( f.name, errorMessage );
207 if ( !editChecks( errorMessage ) )
212 if ( position < 0 || position > mRat->data().count() )
216 *errorMessage = tr(
"Position is not valid or the table is empty." );
222 const bool retVal { mRat->insertRow( position, rowData, errorMessage ) };
229 if ( !editChecks( errorMessage ) )
238 *errorMessage = QObject::tr(
"Invalid position '%1' for color insertion." ).arg( position );
244 const bool retVal { mRat->insertColor( position, errorMessage ) };
251 if ( !editChecks( errorMessage ) )
260 *errorMessage = QObject::tr(
"Invalid position '%1' for color ramp insertion." ).arg( position );
266 const bool retVal { mRat->insertRamp( position, errorMessage ) };
273 if ( !editChecks( errorMessage ) )
278 if ( position < 0 || position >= mRat->data().count() )
282 *errorMessage = tr(
"Position is not valid or the table is empty." );
288 const bool retVal { mRat->removeRow( position, errorMessage ) };
293bool QgsRasterAttributeTableModel::editChecks( QString *errorMessage )
299 *errorMessage = QObject::tr(
"Raster Attribute Table is not set for this model." );
308 *errorMessage = QObject::tr(
"Raster Attribute Table is not editable." );
316QString QgsRasterAttributeTableModel::ratColorHeaderName()
const
318 return tr(
"Color" );
323 return ( !parent.isValid() && mRat ) ? mRat->data().count() : 0;
328 return ( !parent.isValid() && mRat ) ? ( mRat->fields().count() + ( mRat->hasColor() || mRat->hasRamp() ? 1 : 0 ) ) : 0;
333 if ( mRat && index.isValid() && index.row() <
rowCount( QModelIndex() ) && index.column() <
columnCount( QModelIndex() ) )
335 const QString fieldName {
headerNames().at( index.column() ) };
338 const QgsRasterAttributeTable::Field field { mRat->fieldByName( fieldName, &ok ) };
339 if ( !isColorOrRamp && !ok )
347 case Qt::ItemDataRole::ForegroundRole:
350 const QColor tempColor { mRat->color( index.row() ) };
351 const double darkness { 1 - ( 0.299 * tempColor.red() + 0.587 * tempColor.green() + 0.114 * tempColor.blue() ) / 255 };
352 return darkness > 0.5 ? QColor( Qt::GlobalColor::white ) : QColor( Qt::GlobalColor::black );
354 case Qt::ItemDataRole::EditRole:
355 case Qt::ItemDataRole::BackgroundRole:
356 return mRat->color( index.row() );
357 case Qt::ItemDataRole::DisplayRole:
358 return mRat->color( index.row() ).name();
363 else if ( isColorOrRamp &&
hasRamp() )
367 case Qt::ItemDataRole::BackgroundRole:
381 case Qt::ItemDataRole::EditRole:
383 return QVariant::fromValue( mRat->ramp( index.row() ) );
389 else if ( role == Qt::ItemDataRole::TextAlignmentRole && field.
type != QMetaType::Type::QString )
391 return QVariant( Qt::AlignmentFlag::AlignRight | Qt::AlignmentFlag::AlignVCenter );
393 else if ( role == Qt::ItemDataRole::ToolTipRole && ( isColorOrRamp ) )
395 return tr(
"This data is part of a color definition: click on '%1' column to edit." ).arg( ratColorHeaderName() );
397 else if ( role == Qt::ItemDataRole::DisplayRole || role == Qt::ItemDataRole::EditRole )
399 return mRat->data().at( index.row() ).at( index.column() );
401 else if ( role == Qt::ItemDataRole::FontRole && ( isColorOrRamp ) )
404 font.setItalic(
true );
413 if ( mRat && index.isValid() && role == Qt::ItemDataRole::EditRole )
415 const QString fieldName {
headerNames().at( index.column() ) };
418 const QgsRasterAttributeTable::Field field { mRat->fieldByName( fieldName, &ok ) };
419 if ( !isColorOrRamp && !ok )
425 if ( !value.canConvert( QMetaType::Type::QColor ) || !mRat->setColor( index.row(), value.value<QColor>() ) )
429 const QModelIndex colorColIdx { QgsRasterAttributeTableModel::index( index.row(),
columnCount( QModelIndex() ) - 1, QModelIndex() ) };
430 emit dataChanged( colorColIdx, colorColIdx );
432 const QList<QgsRasterAttributeTable::Field> &ratFields { mRat->fields() };
433 for (
int fIdx = 0; fIdx < ratFields.count(); ++fIdx )
435 if ( ratFields[fIdx].isColor() )
437 const QModelIndex fieldColIdx { QgsRasterAttributeTableModel::index( index.row(), fIdx, QModelIndex() ) };
438 emit dataChanged( fieldColIdx, fieldColIdx );
443 else if (
hasRamp() && isColorOrRamp )
445 const QgsGradientColorRamp ramp { qvariant_cast<QgsGradientColorRamp>( value ) };
446 if ( !mRat->setRamp( index.row(), ramp.
color1(), ramp.
color2() ) )
450 const QModelIndex colorColIdx { QgsRasterAttributeTableModel::index( index.row(),
columnCount( QModelIndex() ) - 1, QModelIndex() ) };
451 emit dataChanged( colorColIdx, colorColIdx );
453 const QList<QgsRasterAttributeTable::Field> &ratFields { mRat->fields() };
454 for (
int fIdx = 0; fIdx < ratFields.count(); ++fIdx )
456 if ( ratFields[fIdx].isRamp() )
458 const QModelIndex fieldColIdx { QgsRasterAttributeTableModel::index( index.row(), fIdx, QModelIndex() ) };
459 emit dataChanged( fieldColIdx, fieldColIdx );
466 const bool retVal { mRat->setValue( index.row(), index.column(), value ) };
469 const QModelIndex fieldColIdx { QgsRasterAttributeTableModel::index( index.row(), index.column(), QModelIndex() ) };
470 emit dataChanged( fieldColIdx, fieldColIdx );
480 if ( orientation == Qt::Orientation::Horizontal )
483 if ( section < hNames.length() )
487 case Qt::ItemDataRole::DisplayRole:
489 return hNames.at( section );
491 case Qt::ItemDataRole::ToolTipRole:
496 return QAbstractTableModel::headerData( section, orientation, role );
500 return QAbstractTableModel::headerData( section, orientation, role );
508 if ( index.isValid() )
510 flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
513 if ( index.column() < mRat->fields().count() )
515 const QList<QgsRasterAttributeTable::Field> fields = mRat->fields();
516 const QgsRasterAttributeTable::Field &field { fields.at( index.column() ) };
519 flags |= Qt::ItemIsEditable;
524 flags |= Qt::ItemIsEditable;
530 return Qt::NoItemFlags;
RasterAttributeTableFieldUsage
The RasterAttributeTableFieldUsage enum represents the usage of a Raster Attribute Table field.
QColor color1() const
Returns the gradient start color.
QColor color2() const
Returns the gradient end color.
QStringList headerNames() const
Returns all the header names, including the "virtual" color header if the Raster Attribute Table has ...
bool removeColorOrRamp(QString *errorMessage=nullptr)
Removes all color or ramp information, optionally reporting any error in errorMessage,...
bool hasRamp() const
Returns true if the Raster Attribute Table has ramp information.
int rowCount(const QModelIndex &parent) const override
bool isDirty()
Returns true if the Raster Attribute Table was modified since it was last saved or read.
bool hasColor() const
Returns true if the Raster Attribute Table has color information.
bool removeField(const int position, QString *errorMessage=nullptr)
Remove the field at given position, optionally reporting any error in errorMessage,...
bool insertColor(int position, QString *errorMessage=nullptr)
Create RGBA fields and inserts them at position, optionally reporting any error in errorMessage,...
bool insertRow(const int position, const QVariantList &rowData, QString *errorMessage=nullptr)
Inserts a new row before position, optionally reporting any error in errorMessage,...
int columnCount(const QModelIndex &parent) const override
bool editable() const
Returns true if the Raster Attribute Table is editable.
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
QString headerTooltip(const int section) const
Returns the tooltip for the given section.
bool setData(const QModelIndex &index, const QVariant &value, int role) override
void setEditable(bool editable)
Sets the Raster Attribute Table editable state to editable.
QgsRasterAttributeTableModel(QgsRasterAttributeTable *rat, QObject *parent=nullptr)
Creates a new QgsRasterAttributeTableModel from raster attribute table rat and optional parent.
bool insertField(const int position, const QString &name, const Qgis::RasterAttributeTableFieldUsage usage, const QMetaType::Type type, QString *errorMessage=nullptr)
Inserts a field at the given position.
bool isValid(QString *errorMessage=nullptr)
Checks if the Raster Attribute Table is valid, optionally returns validation errors in errorMessage.
QVariant data(const QModelIndex &index, int role) const override
bool insertRamp(int position, QString *errorMessage=nullptr)
Create RGBA minimum and maximum fields and inserts them at position, optionally reporting any error i...
Qt::ItemFlags flags(const QModelIndex &index) const override
bool removeRow(const int position, QString *errorMessage=nullptr)
Removes the row at position, optionally reporting any error in errorMessage, returns true on success.
The Field class represents a Raster Attribute Table field, including its name, usage and type.
bool isRamp() const
Returns true if the field carries a color ramp component information (RedMin/RedMax,...
bool isColor() const
Returns true if the field carries a color component (Red, Green, Blue and optionally Alpha) informati...
Represents a Raster Attribute Table (RAT).
static QHash< Qgis::RasterAttributeTableFieldUsage, QgsRasterAttributeTable::UsageInformation > usageInformation()
Returns information about supported Raster Attribute Table usages.
static QString usageName(const Qgis::RasterAttributeTableFieldUsage fieldusage)
Returns the translated human readable name of fieldUsage.
static QMetaType::Type variantTypeToMetaType(QVariant::Type variantType)
Converts a QVariant::Type to a QMetaType::Type.