21#include "moc_qgsrasterattributetablemodel.cpp"
24 : QAbstractTableModel( parent )
41 return mRat && mRat->hasColor();
46 return mRat && mRat->hasRamp();
54 const QList<QgsRasterAttributeTable::Field> &ratFields { mRat->fields() };
57 headers.push_back( f.name );
62 headers.append( ratColorHeaderName() );
71 if ( section < 0 || section >= hNames.count() )
76 const QString fieldName { hNames.at( section ) };
77 const bool isColor {
hasColor() && section == hNames.count() - 1 };
81 return tr(
"Virtual color field generated from the values in RGB(A) data columns" );
92 return QStringLiteral( R
"HTML(
94 <dt>Role</dt><dd>%1</dd>
95 <dt>Type</dt><dd>%2</dd>
96 <dt>Description</dt><dd>%3</dd>
108 *errorMessage = tr(
"Raster Attribute Table is not set for this model." );
112 return mRat->isValid( errorMessage );
117 return mRat && mRat->isDirty();
122 if ( !editChecks( errorMessage ) )
131 *errorMessage = QObject::tr(
"Invalid position '%1' for field insertion." ).arg( position );
136 const int newPosition { std::clamp( position, 0,
static_cast<int>( mRat->fields().count() ) ) };
137 const QgsRasterAttributeTable::Field field { name, usage, type };
139 const bool retVal { mRat->insertField( newPosition, field, errorMessage ) };
152 if ( !editChecks( errorMessage ) )
157 if ( position < 0 || position >= mRat->fields().count() )
161 *errorMessage = QObject::tr(
"Invalid position '%1' for field removal." ).arg( position );
167 const bool retVal { mRat->removeField( mRat->fields().at( position ).name, errorMessage ) };
174 if ( !editChecks( errorMessage ) )
179 if ( !mRat->hasColor() && !mRat->hasRamp() )
183 *errorMessage = tr(
"Raster attribute table does not have color or ramp information." );
190 const QList<QgsRasterAttributeTable::Field> ratFields { mRat->fields() };
191 for (
const QgsRasterAttributeTable::Field &f : std::as_const( ratFields ) )
193 if ( f.isColor() || f.isRamp() )
195 ret &= mRat->removeField( f.name, errorMessage );
208 if ( !editChecks( errorMessage ) )
213 if ( position < 0 || position > mRat->data().count() )
217 *errorMessage = tr(
"Position is not valid or the table is empty." );
223 const bool retVal { mRat->insertRow( position, rowData, errorMessage ) };
230 if ( !editChecks( errorMessage ) )
239 *errorMessage = QObject::tr(
"Invalid position '%1' for color insertion." ).arg( position );
245 const bool retVal { mRat->insertColor( position, errorMessage ) };
252 if ( !editChecks( errorMessage ) )
261 *errorMessage = QObject::tr(
"Invalid position '%1' for color ramp insertion." ).arg( position );
267 const bool retVal { mRat->insertRamp( position, errorMessage ) };
274 if ( !editChecks( errorMessage ) )
279 if ( position < 0 || position >= mRat->data().count() )
283 *errorMessage = tr(
"Position is not valid or the table is empty." );
289 const bool retVal { mRat->removeRow( position, errorMessage ) };
294bool QgsRasterAttributeTableModel::editChecks( QString *errorMessage )
300 *errorMessage = QObject::tr(
"Raster Attribute Table is not set for this model." );
309 *errorMessage = QObject::tr(
"Raster Attribute Table is not editable." );
317QString QgsRasterAttributeTableModel::ratColorHeaderName()
const
319 return tr(
"Color" );
324 return ( !parent.isValid() && mRat ) ? mRat->data().count() : 0;
329 return ( !parent.isValid() && mRat ) ? ( mRat->fields().count() + ( mRat->hasColor() || mRat->hasRamp() ? 1 : 0 ) ) : 0;
334 if ( mRat && index.isValid() && index.row() <
rowCount( QModelIndex() ) && index.column() <
columnCount( QModelIndex() ) )
336 const QString fieldName {
headerNames().at( index.column() ) };
339 const QgsRasterAttributeTable::Field field { mRat->fieldByName( fieldName, &ok ) };
340 if ( !isColorOrRamp && !ok )
348 case Qt::ItemDataRole::ForegroundRole:
351 const QColor tempColor { mRat->color( index.row() ) };
352 const double darkness { 1 - ( 0.299 * tempColor.red() + 0.587 * tempColor.green() + 0.114 * tempColor.blue() ) / 255 };
353 return darkness > 0.5 ? QColor( Qt::GlobalColor::white ) : QColor( Qt::GlobalColor::black );
355 case Qt::ItemDataRole::EditRole:
356 case Qt::ItemDataRole::BackgroundRole:
357 return mRat->color( index.row() );
358 case Qt::ItemDataRole::DisplayRole:
359 return mRat->color( index.row() ).name();
364 else if ( isColorOrRamp &&
hasRamp() )
368 case Qt::ItemDataRole::BackgroundRole:
382 case Qt::ItemDataRole::EditRole:
384 return QVariant::fromValue( mRat->ramp( index.row() ) );
390 else if ( role == Qt::ItemDataRole::TextAlignmentRole && field.
type != QMetaType::Type::QString )
392 return QVariant( Qt::AlignmentFlag::AlignRight | Qt::AlignmentFlag::AlignVCenter );
394 else if ( role == Qt::ItemDataRole::ToolTipRole && ( isColorOrRamp ) )
396 return tr(
"This data is part of a color definition: click on '%1' column to edit." ).arg( ratColorHeaderName() );
398 else if ( role == Qt::ItemDataRole::DisplayRole || role == Qt::ItemDataRole::EditRole )
400 return mRat->data().at( index.row() ).at( index.column() );
402 else if ( role == Qt::ItemDataRole::FontRole && ( isColorOrRamp ) )
405 font.setItalic(
true );
414 if ( mRat && index.isValid() && role == Qt::ItemDataRole::EditRole )
416 const QString fieldName {
headerNames().at( index.column() ) };
419 const QgsRasterAttributeTable::Field field { mRat->fieldByName( fieldName, &ok ) };
420 if ( !isColorOrRamp && !ok )
426 if ( !value.canConvert( QMetaType::Type::QColor ) || !mRat->setColor( index.row(), value.value<QColor>() ) )
430 const QModelIndex colorColIdx { QgsRasterAttributeTableModel::index( index.row(),
columnCount( QModelIndex() ) - 1, QModelIndex() ) };
431 emit dataChanged( colorColIdx, colorColIdx );
433 const QList<QgsRasterAttributeTable::Field> &ratFields { mRat->fields() };
434 for (
int fIdx = 0; fIdx < ratFields.count(); ++fIdx )
436 if ( ratFields[fIdx].isColor() )
438 const QModelIndex fieldColIdx { QgsRasterAttributeTableModel::index( index.row(), fIdx, QModelIndex() ) };
439 emit dataChanged( fieldColIdx, fieldColIdx );
444 else if (
hasRamp() && isColorOrRamp )
446 const QgsGradientColorRamp ramp { qvariant_cast<QgsGradientColorRamp>( value ) };
447 if ( !mRat->setRamp( index.row(), ramp.
color1(), ramp.
color2() ) )
451 const QModelIndex colorColIdx { QgsRasterAttributeTableModel::index( index.row(),
columnCount( QModelIndex() ) - 1, QModelIndex() ) };
452 emit dataChanged( colorColIdx, colorColIdx );
454 const QList<QgsRasterAttributeTable::Field> &ratFields { mRat->fields() };
455 for (
int fIdx = 0; fIdx < ratFields.count(); ++fIdx )
457 if ( ratFields[fIdx].isRamp() )
459 const QModelIndex fieldColIdx { QgsRasterAttributeTableModel::index( index.row(), fIdx, QModelIndex() ) };
460 emit dataChanged( fieldColIdx, fieldColIdx );
467 const bool retVal { mRat->setValue( index.row(), index.column(), value ) };
470 const QModelIndex fieldColIdx { QgsRasterAttributeTableModel::index( index.row(), index.column(), QModelIndex() ) };
471 emit dataChanged( fieldColIdx, fieldColIdx );
481 if ( orientation == Qt::Orientation::Horizontal )
484 if ( section < hNames.length() )
488 case Qt::ItemDataRole::DisplayRole:
490 return hNames.at( section );
492 case Qt::ItemDataRole::ToolTipRole:
497 return QAbstractTableModel::headerData( section, orientation, role );
501 return QAbstractTableModel::headerData( section, orientation, role );
509 if ( index.isValid() )
511 flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
514 if ( index.column() < mRat->fields().count() )
516 const QList<QgsRasterAttributeTable::Field> fields = mRat->fields();
517 const QgsRasterAttributeTable::Field &field { fields.at( index.column() ) };
520 flags |= Qt::ItemIsEditable;
525 flags |= Qt::ItemIsEditable;
531 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.