17#include "moc_qgsrasterattributetablemodel.cpp" 
   23  : QAbstractTableModel( parent )
 
 
   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() ) ) };
 
  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 ) )
 
  182      *errorMessage = tr( 
"Raster attribute table does not have color or ramp information." );
 
  189  const QList<QgsRasterAttributeTable::Field> ratFields { mRat->
fields() };
 
  192    if ( f.isColor() || f.isRamp() )
 
 
  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;
 
 
  335    const QString fieldName { 
headerNames().at( index.column() ) };
 
  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() ) };
 
  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 )
 
  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();
 
  517          if ( !field.isColor() && !field.isRamp() )
 
  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.
 
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
 
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.
 
Represents a Raster Attribute Table (RAT).
 
const QgsRasterAttributeTable::Field fieldByName(const QString name, bool *ok=nullptr) const
Returns a field by name or a default constructed field with empty name if the field is not found.
 
bool isDirty() const
Returns true if the Raster Attribute Table was modified from its last reading from the storage.
 
bool setColor(const int row, const QColor &color)
Sets the color for the row at rowIndex to color.
 
QgsGradientColorRamp ramp(int row) const
Returns the gradient color ramp of the rat row or a default constructed gradient if row does not exis...
 
bool insertField(int position, const QgsRasterAttributeTable::Field &field, QString *errorMessage=nullptr)
Inserts a new field at position, optionally reporting any error in errorMessage, returns true on succ...
 
bool hasColor() const
Returns true if the Raster Attribute Table has color RGBA information.
 
bool setValue(const int row, const int column, const QVariant &value)
Sets the value for row and column.
 
QList< QgsRasterAttributeTable::Field > fields() const
Returns the Raster Attribute Table fields.
 
bool removeRow(int position=0, QString *errorMessage=nullptr)
Removes the row in the Raster Attribute Table at position, optionally reporting any error in errorMes...
 
static QHash< Qgis::RasterAttributeTableFieldUsage, QgsRasterAttributeTable::UsageInformation > usageInformation()
Returns information about supported Raster Attribute Table usages.
 
bool insertRow(int position, const QVariantList &rowData, QString *errorMessage=nullptr)
Inserts a row of rowData in the Raster Attribute Table at position, optionally reporting any error in...
 
bool insertColor(int position, QString *errorMessage=nullptr)
Create RGBA fields and inserts them at position, optionally reporting any error in errorMessage,...
 
bool isValid(QString *errorMessage=nullptr) const
Returns true if the Raster Attribute Table is valid, optionally reporting validity checks results in ...
 
const QList< QList< QVariant > > data() const
Returns the Raster Attribute Table rows.
 
bool setRamp(const int row, const QColor &colorMin, const QColor &colorMax)
Sets the color ramp for the row at rowIndex to colorMin and colorMax.
 
PRIVATE QColor color(int row) const
Returns the color of the rat row or an invalid color if row does not exist or if there is no color de...
 
static QString usageName(const Qgis::RasterAttributeTableFieldUsage fieldusage)
Returns the translated human readable name of fieldUsage.
 
bool hasRamp() const
Returns true if the Raster Attribute Table has ramp RGBA information.
 
bool insertRamp(int position, QString *errorMessage=nullptr)
Create RGBA minimum and maximum fields and inserts them at position, optionally reporting any error i...
 
bool removeField(const QString &name, QString *errorMessage=nullptr)
Removes the field with name, optionally reporting any error in errorMessage, returns true on success.
 
static QMetaType::Type variantTypeToMetaType(QVariant::Type variantType)
Converts a QVariant::Type to a QMetaType::Type.