QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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 "qgshelp.h"
20#include "qgsmessagebar.h"
21#include "qgsrasterlayer.h"
22
23#include <QMessageBox>
24#include <QString>
25
26#include "moc_qgscreaterasterattributetabledialog.cpp"
27
28using namespace Qt::StringLiterals;
29
31 : QDialog( parent )
32 , mRasterLayer( rasterLayer )
33{
34 Q_ASSERT( mRasterLayer );
35 Q_ASSERT( mRasterLayer->canCreateRasterAttributeTable() );
36
37 setupUi( this );
38
39 // Apparently, some drivers (HFA) ignore Min/Max fields and set them to generic,
40 // for this reason we disable the native support for thematic RATs (later in the loop)
41 bool nativeRatSupported { mRasterLayer->dataProvider()->providerCapabilities().testFlag( Qgis::RasterProviderCapability::NativeRasterAttributeTable ) };
42
43 connect( mNativeRadioButton, &QRadioButton::toggled, this, &QgsCreateRasterAttributeTableDialog::updateButtons );
44 connect( mDbfRadioButton, &QRadioButton::toggled, this, &QgsCreateRasterAttributeTableDialog::updateButtons );
45
46
47 // Check for existing RATs
48 QStringList existingRatsInfo;
49 if ( mRasterLayer->attributeTableCount() > 0 )
50 {
51 for ( int bandNo = 1; bandNo <= mRasterLayer->bandCount(); ++bandNo )
52 {
53 if ( QgsRasterAttributeTable *rat = mRasterLayer->attributeTable( bandNo ) )
54 {
55 // disable the native support for thematic RATs
56 if ( nativeRatSupported && rat->type() != Qgis::RasterAttributeTableType::Athematic )
57 {
58 nativeRatSupported = false;
59 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." ) );
60 }
61 if ( !rat->filePath().isEmpty() )
62 {
63 existingRatsInfo.push_back( tr( "Raster band %1 already has an associated attribute table at %2." ).arg( QString::number( bandNo ), rat->filePath() ) );
64 }
65 else
66 {
67 existingRatsInfo.push_back( tr( "Raster band %1 already has an associated attribute table." ).arg( bandNo ) );
68 }
69 }
70 }
71 }
72
73 if ( !existingRatsInfo.isEmpty() )
74 {
75 mCreateInfoLabel->setText( mCreateInfoLabel->text().append( u"<br><ul><li>"_s + existingRatsInfo.join( "</li><li>"_L1 ) ).append( u"</ul>"_s ) );
76 mCreateInfoLabel->adjustSize();
77 mCreateInfoLabel->show();
78 }
79
80 if ( !nativeRatSupported )
81 {
82 mNativeRadioButton->setEnabled( false );
83 mDbfRadioButton->setChecked( true );
84 }
85 else
86 {
87 mDbfPathWidget->setFilter( u"VAT DBF Files (*.vat.dbf)"_s );
88 if ( QFile::exists( mRasterLayer->dataProvider()->dataSourceUri() ) )
89 {
90 mDbfPathWidget->setFilePath( mRasterLayer->dataProvider()->dataSourceUri() + ".vat.dbf" );
91 }
92 }
93
94 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
95 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
96 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, [] { QgsHelp::openHelp( u"working_with_raster/raster_properties.html#raster-attribute-tables"_s ); } );
97
98 updateButtons();
99
101}
102
104{
105 return mDbfPathWidget->filePath();
106}
107
109{
110 return mDbfRadioButton->isChecked();
111}
112
114{
115 return mOpenRat->isChecked();
116}
117
119{
120 mMessageBar = bar;
121}
122
124{
125 if ( !visible )
126 {
127 mOpenRat->setChecked( false );
128 }
129
130 mOpenRat->setVisible( visible );
131}
132
134{
135 QString errorMessage;
136 int bandNumber { 0 };
137 QgsRasterAttributeTable *rat { QgsRasterAttributeTable::createFromRaster( mRasterLayer, &bandNumber ) };
138 bool success { false };
139
140 if ( !rat )
141 {
142 notify( tr( "Error Creating Raster Attribute Table" ), tr( "The raster attribute table could not be created." ), Qgis::MessageLevel::Critical );
143 }
144 else
145 {
146 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, rat );
147
148 // Save it
149 const bool storageIsFile { saveToFile() };
150 if ( storageIsFile )
151 {
152 const QString destinationPath { filePath() };
153 if ( !QFile::exists( destinationPath )
154 || QMessageBox::
155 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 )
156 == QMessageBox::Yes )
157 {
158 success = rat->writeToFile( destinationPath, &errorMessage );
159 if ( !success )
160 {
161 notify( tr( "Error Saving Raster Attribute Table" ), errorMessage, Qgis::MessageLevel::Critical );
162 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, nullptr );
163 }
164 }
165 }
166 else
167 {
168 success = mRasterLayer->dataProvider()->writeNativeAttributeTable( &errorMessage ); //#spellok
169 if ( !success )
170 {
171 notify( tr( "Error Saving Raster Attribute Table" ), errorMessage, Qgis::MessageLevel::Critical );
172 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, nullptr );
173 }
174 }
175 }
176
177 if ( success )
178 {
179 notify( tr( "Raster Attribute Table Saved" ), tr( "The new Raster Attribute Table was successfully created." ), Qgis::MessageLevel::Success );
180 }
181
182 QDialog::accept();
183}
184
185void QgsCreateRasterAttributeTableDialog::notify( const QString &title, const QString &message, Qgis::MessageLevel level )
186{
187 if ( mMessageBar )
188 {
189 mMessageBar->pushMessage( message, level );
190 }
191 else
192 {
193 switch ( level )
194 {
198 {
199 QMessageBox::information( nullptr, title, message );
200 break;
201 }
203 {
204 QMessageBox::warning( nullptr, title, message );
205 break;
206 }
208 {
209 QMessageBox::critical( nullptr, title, message );
210 break;
211 }
212 }
213 }
214}
215
216void QgsCreateRasterAttributeTableDialog::updateButtons()
217{
218 mDbfPathWidget->setEnabled( mDbfRadioButton->isChecked() );
219}
@ NativeRasterAttributeTable
Indicates that the provider supports native raster attribute table.
Definition qgis.h:5051
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:160
@ NoLevel
No level.
Definition qgis.h:165
@ Warning
Warning message.
Definition qgis.h:162
@ Critical
Critical/error message.
Definition qgis.h:163
@ Info
Information message.
Definition qgis.h:161
@ Success
Used for reporting a successful operation.
Definition qgis.h:164
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
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:41
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.