Skip to content

Commit

Permalink
Merge pull request #51218 from elpaso/bugfix-gh51200-rat-editing
Browse files Browse the repository at this point in the history
Raster Attribute Table GUI enhancements/fixes
  • Loading branch information
elpaso committed Dec 16, 2022
2 parents 7da101a + 4f32ed5 commit 8b5e9c4
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 30 deletions.
Expand Up @@ -28,7 +28,7 @@ methods to handle data from QGIS and to import/export a Raster Attribute Table f
class UsageInformation
{
%Docstring(signature="appended")
The UsageInformation struct represents information about a field usage.
The UsageInformation class represents information about a field usage.

.. versionadded:: 3.30
%End
Expand Down Expand Up @@ -58,7 +58,7 @@ The UsageInformation struct represents information about a field usage.
class Field
{
%Docstring(signature="appended")
The Field struct represents a Raster Attribute Table field, including its name, usage and type.
The Field class represents a Raster Attribute Table field, including its name, usage and type.

.. versionadded:: 3.30
%End
Expand Down Expand Up @@ -91,7 +91,7 @@ Returns ``True`` if the field carries a color ramp component information (RedMin
class MinMaxClass
{
%Docstring(signature="appended")
The Field struct represents a Raster Attribute Table classification entry for a thematic Raster Attribute Table.
The Field class represents a Raster Attribute Table classification entry for a thematic Raster Attribute Table.

.. versionadded:: 3.30
%End
Expand Down
7 changes: 3 additions & 4 deletions src/core/raster/qgsrasterattributetable.h
Expand Up @@ -19,7 +19,6 @@
#include "qgsfields.h"
#include "qgsfeature.h"
#include "qgis_core.h"
#include "gdal.h"
#include "qgis_sip.h"
#include "qgis.h"
#include "qgscolorrampimpl.h"
Expand Down Expand Up @@ -50,7 +49,7 @@ class CORE_EXPORT QgsRasterAttributeTable

/**
* \ingroup core
* \brief The UsageInformation struct represents information about a field usage.
* \brief The UsageInformation class represents information about a field usage.
* \since QGIS 3.30
*/
class CORE_EXPORT UsageInformation
Expand Down Expand Up @@ -84,7 +83,7 @@ class CORE_EXPORT QgsRasterAttributeTable

/**
* \ingroup core
* \brief The Field struct represents a Raster Attribute Table field, including its name, usage and type.
* \brief The Field class represents a Raster Attribute Table field, including its name, usage and type.
* \since QGIS 3.30
*/
class CORE_EXPORT Field
Expand Down Expand Up @@ -114,7 +113,7 @@ class CORE_EXPORT QgsRasterAttributeTable

/**
* \ingroup core
* \brief The Field struct represents a Raster Attribute Table classification entry for a thematic Raster Attribute Table.
* \brief The Field class represents a Raster Attribute Table classification entry for a thematic Raster Attribute Table.
* \since QGIS 3.30
*/
class CORE_EXPORT MinMaxClass
Expand Down
19 changes: 6 additions & 13 deletions src/gui/raster/qgsrasterattributetableaddcolumndialog.cpp
Expand Up @@ -15,7 +15,6 @@
***************************************************************************/
#include "qgsrasterattributetableaddcolumndialog.h"
#include "qgsrasterattributetable.h"
#include "qgsfield.h"
#include "qgsgui.h"

#include <QPushButton>
Expand All @@ -35,10 +34,10 @@ QgsRasterAttributeTableAddColumnDialog::QgsRasterAttributeTableAddColumnDialog(
connect( mColor, &QRadioButton::toggled, this, [ = ]( bool ) { updateDialog(); } );
connect( mUsage, qOverload<int>( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { updateDialog(); } );

mDataType->addItem( QgsFields::iconForFieldType( QVariant::Type::String ), tr( "String" ), QVariant::String );
mDataType->addItem( QgsFields::iconForFieldType( QVariant::Type::Int ), tr( "Integer" ), QVariant::Int );
mDataType->addItem( QgsFields::iconForFieldType( QVariant::Type::LongLong ), tr( "Long Integer" ), QVariant::LongLong );
mDataType->addItem( QgsFields::iconForFieldType( QVariant::Type::Double ), tr( "Double" ), QVariant::Double );
mDataType->addItem( QgsFields::iconForFieldType( QVariant::Type::String ), tr( "String" ), static_cast<int>( QVariant::Type::String ) );
mDataType->addItem( QgsFields::iconForFieldType( QVariant::Type::Int ), tr( "Integer" ), static_cast<int>( QVariant::Type::Int ) );
mDataType->addItem( QgsFields::iconForFieldType( QVariant::Type::LongLong ), tr( "Long Integer" ), static_cast<int>( QVariant::Type::LongLong ) );
mDataType->addItem( QgsFields::iconForFieldType( QVariant::Type::Double ), tr( "Double" ), static_cast<int>( QVariant::Type::Double ) );
mStandardColumn->setChecked( true );

updateDialog();
Expand Down Expand Up @@ -96,25 +95,19 @@ void QgsRasterAttributeTableAddColumnDialog::updateDialog()
const bool canAddMinMax { !hasMinMax &&mAttributeTable->type() == Qgis::RasterAttributeTableType::Thematic };
const bool canAddMinAndMax { !hasMinAndMax &&mAttributeTable->type() == Qgis::RasterAttributeTableType::Athematic };

bool canAddColor { true };
bool canAddRamp { true };

if ( mAttributeTable->hasColor() || mAttributeTable->hasRamp() )
{
mColor->setChecked( false );
mColor->setEnabled( false );
mRamp->setChecked( false );
mRamp->setEnabled( false );
mStandardColumn->setChecked( true );
canAddColor = false;
canAddRamp = false;
}
else if ( mAttributeTable->type() == Qgis::RasterAttributeTableType::Thematic )
{
mColor->setEnabled( true );
mRamp->setChecked( false );
mRamp->setEnabled( false );
canAddRamp = false;
}
else
{
Expand Down Expand Up @@ -161,8 +154,8 @@ void QgsRasterAttributeTableAddColumnDialog::updateDialog()
if ( ( it.key() == Qgis::RasterAttributeTableFieldUsage::MinMax && ! canAddMinMax ) ||
( it.key() == Qgis::RasterAttributeTableFieldUsage::Min && ! canAddMinAndMax ) ||
( it.key() == Qgis::RasterAttributeTableFieldUsage::Max && ! canAddMinAndMax ) ||
( it.value().isColor && ! canAddColor ) ||
( it.value().isRamp && ! canAddRamp ) )
( it.value().isColor ) ||
( it.value().isRamp ) )
{
continue;
}
Expand Down
14 changes: 7 additions & 7 deletions src/gui/raster/qgsrasterattributetablemodel.cpp
Expand Up @@ -72,7 +72,7 @@ QString QgsRasterAttributeTableModel::headerTooltip( const int section ) const
}

const QString fieldName { hNames.at( section ) };
const bool isColor { section == hNames.count( ) - 1 };
const bool isColor { hasColor() && section == hNames.count( ) - 1 }; // *NOPAD*

if ( isColor )
{
Expand Down Expand Up @@ -330,14 +330,14 @@ QVariant QgsRasterAttributeTableModel::data( const QModelIndex &index, int role
if ( mRat && index.isValid() && index.row() < rowCount( QModelIndex() ) && index.column() < columnCount( QModelIndex() ) )
{
const QString fieldName { headerNames().at( index.column() ) };
const bool isColorOrRamp { index.column() == columnCount( QModelIndex() ) - 1 };
const bool isColorOrRamp { ( hasColor() || hasRamp() ) && index.column() == columnCount( QModelIndex() ) - 1 }; // *NOPAD*
bool ok;
const QgsRasterAttributeTable::Field field { mRat->fieldByName( fieldName, &ok ) };
if ( ! isColorOrRamp && ! ok )
{
return QVariant();
}
if ( hasColor() && isColorOrRamp )
if ( isColorOrRamp && hasColor() )
{
switch ( role )
{
Expand All @@ -357,7 +357,7 @@ QVariant QgsRasterAttributeTableModel::data( const QModelIndex &index, int role
return QVariant();
}
}
else if ( hasRamp() && isColorOrRamp )
else if ( isColorOrRamp && hasRamp() )
{
switch ( role )
{
Expand All @@ -383,19 +383,19 @@ QVariant QgsRasterAttributeTableModel::data( const QModelIndex &index, int role
return QVariant();
}
}
else if ( ! isColorOrRamp && role == Qt::ItemDataRole::TextAlignmentRole && field.type != QVariant::String )
else if ( role == Qt::ItemDataRole::TextAlignmentRole && field.type != QVariant::String )
{
return QVariant( Qt::AlignmentFlag::AlignRight | Qt::AlignmentFlag::AlignVCenter );
}
else if ( role == Qt::ItemDataRole::ToolTipRole && ( field.isColor() || field.isRamp() ) )
else if ( role == Qt::ItemDataRole::ToolTipRole && ( isColorOrRamp ) )
{
return tr( "This data is part of a color definition: click on '%1' column to edit." ).arg( ratColorHeaderName() );
}
else if ( role == Qt::ItemDataRole::DisplayRole || role == Qt::ItemDataRole::EditRole )
{
return mRat->data().at( index.row() ).at( index.column() );
}
else if ( role == Qt::ItemDataRole::FontRole && ( field.isColor() || field.isRamp() ) )
else if ( role == Qt::ItemDataRole::FontRole && ( isColorOrRamp ) )
{
QFont font;
font.setItalic( true );
Expand Down
42 changes: 39 additions & 3 deletions src/gui/raster/qgsrasterattributetablewidget.cpp
Expand Up @@ -22,9 +22,6 @@
#include "qgsrasterattributetableaddrowdialog.h"
#include "qgscolorbutton.h"
#include "qgsgradientcolorrampdialog.h"
#include "qgspalettedrasterrenderer.h"
#include "qgssinglebandpseudocolorrenderer.h"
#include "qgsrastershader.h"

#include <QToolBar>
#include <QAction>
Expand Down Expand Up @@ -377,6 +374,7 @@ void QgsRasterAttributeTableWidget::addColumn()
}
}
}
setDelegates();
}
}

Expand Down Expand Up @@ -512,17 +510,26 @@ void QgsRasterAttributeTableWidget::setDelegates()
const QList<QgsRasterAttributeTable::Field> tableFields { mAttributeTableBuffer->fields() };
int fieldIdx { 0 };
const QHash<Qgis::RasterAttributeTableFieldUsage, QgsRasterAttributeTable::UsageInformation> usageInfo { QgsRasterAttributeTable::usageInformation() };

for ( const QgsRasterAttributeTable::Field &f : std::as_const( tableFields ) )
{
// Clear all delegates.
mRATView->setItemDelegateForColumn( fieldIdx, nullptr );

if ( usageInfo[f.usage].maybeClass )
{
mClassifyComboBox->addItem( QgsFields::iconForFieldType( f.type ), f.name, QVariant( fieldIdx ) );
}

// Set delegates for doubles
if ( ( ! f.isColor() && ! f.isRamp() ) && f.type == QVariant::Type::Double )
{
mRATView->setItemDelegateForColumn( fieldIdx, new LocalizedDoubleDelegate( mRATView ) );
}
fieldIdx++;
}

// Set delegates for color and ramp
if ( mAttributeTableBuffer->hasColor() )
{
if ( mAttributeTableBuffer->usages().contains( Qgis::RasterAttributeTableFieldUsage::Alpha ) )
Expand Down Expand Up @@ -611,5 +618,34 @@ QWidget *ColorRampAlphaDelegate::createEditor( QWidget *parent, const QStyleOpti
return editor;
}


QString LocalizedDoubleDelegate::displayText( const QVariant &value, const QLocale &locale ) const
{
Q_UNUSED( locale );
const QString s( value.toString() );
const int dotPosition( s.indexOf( '.' ) );
int precision;
if ( dotPosition < 0 && s.indexOf( 'e' ) < 0 )
{
precision = 0;
return QLocale().toString( value.toDouble(), 'f', precision );
}
else
{
if ( dotPosition < 0 ) precision = 0;
else precision = s.length() - dotPosition - 1;

if ( -1 < value.toDouble() && value.toDouble() < 1 )
{
return QLocale().toString( value.toDouble(), 'g', precision );
}
else
{
return QLocale().toString( value.toDouble(), 'f', precision );
}
}
return QLocale().toString( value.toDouble( ), 'f' );
}

///@endcond private

18 changes: 18 additions & 0 deletions src/gui/raster/qgsrasterattributetablewidget.h
Expand Up @@ -21,6 +21,7 @@
#include "qgsrasterattributetablemodel.h"
#include "qgscolorrampimpl.h"
#include "qgspanelwidget.h"
#include "qgslocaleawarenumericlineeditdelegate.h"

#include <QWidget>
#include <QStyledItemDelegate>
Expand Down Expand Up @@ -97,6 +98,23 @@ class ColorRampAlphaDelegate: public ColorRampDelegate
// QAbstractItemDelegate interface
QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
};


class LocalizedDoubleDelegate: public QgsLocaleAwareNumericLineEditDelegate
{

Q_OBJECT

public:

LocalizedDoubleDelegate( QWidget *parent = nullptr ): QgsLocaleAwareNumericLineEditDelegate( Qgis::DataType::Float64, parent ) {};

// QStyledItemDelegate interface
QString displayText( const QVariant &value, const QLocale &locale ) const override;
};



#endif
///@endcond private

Expand Down

0 comments on commit 8b5e9c4

Please sign in to comment.