QGIS API Documentation 3.99.0-Master (e9821da5c6b)
Loading...
Searching...
No Matches
qgscreaterasterattributetabledialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgscreaterasterattributetabledialog.cpp - QgsCreateRasterAttributeTableDialog
3
4 ---------------------
5 begin : 13.10.2022
6 copyright : (C) 2022 by Alessandro Pasotti
7 email : elpaso at itopen dot it
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
17
18#include "qgsgui.h"
19#include "qgsmessagebar.h"
20#include "qgsrasterlayer.h"
21
22#include <QMessageBox>
23#include <QString>
24
25#include "moc_qgscreaterasterattributetabledialog.cpp"
26
27using namespace Qt::StringLiterals;
28
30 : QDialog( parent )
31 , mRasterLayer( rasterLayer )
32{
33 Q_ASSERT( mRasterLayer );
34 Q_ASSERT( mRasterLayer->canCreateRasterAttributeTable() );
35
36 setupUi( this );
37
38 // Apparently, some drivers (HFA) ignore Min/Max fields and set them to generic,
39 // for this reason we disable the native support for thematic RATs (later in the loop)
40 bool nativeRatSupported { mRasterLayer->dataProvider()->providerCapabilities().testFlag( Qgis::RasterProviderCapability::NativeRasterAttributeTable ) };
41
42 connect( mNativeRadioButton, &QRadioButton::toggled, this, &QgsCreateRasterAttributeTableDialog::updateButtons );
43 connect( mDbfRadioButton, &QRadioButton::toggled, this, &QgsCreateRasterAttributeTableDialog::updateButtons );
44
45
46 // Check for existing RATs
47 QStringList existingRatsInfo;
48 if ( mRasterLayer->attributeTableCount() > 0 )
49 {
50 for ( int bandNo = 1; bandNo <= mRasterLayer->bandCount(); ++bandNo )
51 {
52 if ( QgsRasterAttributeTable *rat = mRasterLayer->attributeTable( bandNo ) )
53 {
54 // disable the native support for thematic RATs
55 if ( nativeRatSupported && rat->type() != Qgis::RasterAttributeTableType::Athematic )
56 {
57 nativeRatSupported = false;
58 existingRatsInfo.push_back( tr( "The data provider supports attribute table storage but some drivers do not support 'thematic' types, for this reason the option is disabled." ) );
59 }
60 if ( !rat->filePath().isEmpty() )
61 {
62 existingRatsInfo.push_back( tr( "Raster band %1 already has an associated attribute table at %2." ).arg( QString::number( bandNo ), rat->filePath() ) );
63 }
64 else
65 {
66 existingRatsInfo.push_back( tr( "Raster band %1 already has an associated attribute table." ).arg( bandNo ) );
67 }
68 }
69 }
70 }
71
72 if ( !existingRatsInfo.isEmpty() )
73 {
74 mCreateInfoLabel->setText( mCreateInfoLabel->text().append( u"<br><ul><li>"_s + existingRatsInfo.join( "</li><li>"_L1 ) ).append( u"</ul>"_s ) );
75 mCreateInfoLabel->adjustSize();
76 mCreateInfoLabel->show();
77 }
78
79 if ( !nativeRatSupported )
80 {
81 mNativeRadioButton->setEnabled( false );
82 mDbfRadioButton->setChecked( true );
83 }
84 else
85 {
86 mDbfPathWidget->setFilter( u"VAT DBF Files (*.vat.dbf)"_s );
87 if ( QFile::exists( mRasterLayer->dataProvider()->dataSourceUri() ) )
88 {
89 mDbfPathWidget->setFilePath( mRasterLayer->dataProvider()->dataSourceUri() + ".vat.dbf" );
90 }
91 }
92
93 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
94 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
95
96 updateButtons();
97
99}
100
102{
103 return mDbfPathWidget->filePath();
104}
105
107{
108 return mDbfRadioButton->isChecked();
109}
110
112{
113 return mOpenRat->isChecked();
114}
115
117{
118 mMessageBar = bar;
119}
120
122{
123 if ( !visible )
124 {
125 mOpenRat->setChecked( false );
126 }
127
128 mOpenRat->setVisible( visible );
129}
130
132{
133 QString errorMessage;
134 int bandNumber { 0 };
135 QgsRasterAttributeTable *rat { QgsRasterAttributeTable::createFromRaster( mRasterLayer, &bandNumber ) };
136 bool success { false };
137
138 if ( !rat )
139 {
140 notify( tr( "Error Creating Raster Attribute Table" ), tr( "The raster attribute table could not be created." ), Qgis::MessageLevel::Critical );
141 }
142 else
143 {
144 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, rat );
145
146 // Save it
147 const bool storageIsFile { saveToFile() };
148 if ( storageIsFile )
149 {
150 const QString destinationPath { filePath() };
151 if ( !QFile::exists( destinationPath ) || QMessageBox::warning( nullptr, tr( "Confirm Overwrite" ), tr( "Are you sure you want to overwrite the existing attribute table at '%1'?" ).arg( destinationPath ), QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::Yes )
152 {
153 success = rat->writeToFile( destinationPath, &errorMessage );
154 if ( !success )
155 {
156 notify( tr( "Error Saving Raster Attribute Table" ), errorMessage, Qgis::MessageLevel::Critical );
157 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, nullptr );
158 }
159 }
160 }
161 else
162 {
163 success = mRasterLayer->dataProvider()->writeNativeAttributeTable( &errorMessage ); //#spellok
164 if ( !success )
165 {
166 notify( tr( "Error Saving Raster Attribute Table" ), errorMessage, Qgis::MessageLevel::Critical );
167 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, nullptr );
168 }
169 }
170 }
171
172 if ( success )
173 {
174 notify( tr( "Raster Attribute Table Saved" ), tr( "The new Raster Attribute Table was successfully created." ), Qgis::MessageLevel::Success );
175 }
176
177 QDialog::accept();
178}
179
180void QgsCreateRasterAttributeTableDialog::notify( const QString &title, const QString &message, Qgis::MessageLevel level )
181{
182 if ( mMessageBar )
183 {
184 mMessageBar->pushMessage( message, level );
185 }
186 else
187 {
188 switch ( level )
189 {
193 {
194 QMessageBox::information( nullptr, title, message );
195 break;
196 }
198 {
199 QMessageBox::warning( nullptr, title, message );
200 break;
201 }
203 {
204 QMessageBox::critical( nullptr, title, message );
205 break;
206 }
207 }
208 }
209}
210
211void QgsCreateRasterAttributeTableDialog::updateButtons()
212{
213 mDbfPathWidget->setEnabled( mDbfRadioButton->isChecked() );
214}
@ NativeRasterAttributeTable
Indicates that the provider supports native raster attribute table.
Definition qgis.h:4990
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:159
@ NoLevel
No level.
Definition qgis.h:164
@ Warning
Warning message.
Definition qgis.h:161
@ Critical
Critical/error message.
Definition qgis.h:162
@ Info
Information message.
Definition qgis.h:160
@ Success
Used for reporting a successful operation.
Definition qgis.h:163
QgsCreateRasterAttributeTableDialog(QgsRasterLayer *rasterLayer, QWidget *parent=nullptr)
Creates a new QgsCreateRasterAttributeTableDialog.
void setOpenWhenDoneVisible(bool visible)
Sets the visibility of the "Open newly created raster attribute table" option to visible,...
QString filePath() const
Returns the file path in case of VAT.DBF save option.
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
bool openWhenDone() const
Returns true if the option to open the newly created attribute table is checked.
bool saveToFile() const
Returns true if the option to save to a file is selected.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition qgsgui.cpp:224
A bar for displaying non-blocking messages to the user.
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::MessageLevel::Info, int duration=-1)
A convenience method for pushing a message with the specified text to the bar.
Represents a Raster Attribute Table (RAT).
static QgsRasterAttributeTable * createFromRaster(QgsRasterLayer *rasterLayer, int *bandNumber=nullptr)
Creates a new Raster Attribute Table from a raster layer, the renderer must be Paletted or SingleBand...
bool writeToFile(const QString &path, QString *errorMessage=nullptr)
Writes the Raster Attribute Table to a DBF file specified by path, optionally reporting any error in ...
Represents a raster layer.