QGIS API Documentation  2.99.0-Master (c558d51)
qgsrasterformatsaveoptionswidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterformatsaveoptionswidget.cpp
3  -------------------
4  begin : July 2012
5  copyright : (C) 2012 by Etienne Tourigny
6  email : etourigny dot dev at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgslogger.h"
20 #include "qgsdialog.h"
21 #include "qgsrasterlayer.h"
22 #include "qgsproviderregistry.h"
23 #include "qgsrasterdataprovider.h"
24 
25 #include <QSettings>
26 #include <QInputDialog>
27 #include <QMessageBox>
28 #include <QTextEdit>
29 #include <QMouseEvent>
30 #include <QMenu>
31 
32 
33 QMap< QString, QStringList > QgsRasterFormatSaveOptionsWidget::mBuiltinProfiles;
34 
35 static const QString PYRAMID_JPEG_YCBCR_COMPRESSION( QStringLiteral( "JPEG_QUALITY_OVERVIEW=75 COMPRESS_OVERVIEW=JPEG PHOTOMETRIC_OVERVIEW=YCBCR INTERLEAVE_OVERVIEW=PIXEL" ) );
36 static const QString PYRAMID_JPEG_COMPRESSION( QStringLiteral( "JPEG_QUALITY_OVERVIEW=75 COMPRESS_OVERVIEW=JPEG INTERLEAVE_OVERVIEW=PIXEL" ) );
37 
39  QgsRasterFormatSaveOptionsWidget::Type type, const QString& provider )
40  : QWidget( parent )
41  , mFormat( format )
42  , mProvider( provider )
43  , mRasterLayer( nullptr )
44  , mRasterFileName( QString() )
45  , mPyramids( false )
46  , mPyramidsFormat( QgsRaster::PyramidsGTiff )
47 
48 {
49  setupUi( this );
50 
51  setType( type );
52 
53  if ( mBuiltinProfiles.isEmpty() )
54  {
55  // key=profileKey values=format,profileName,options
56  mBuiltinProfiles[ QStringLiteral( "z_adefault" )] = ( QStringList() << QLatin1String( "" ) << tr( "Default" ) << QLatin1String( "" ) );
57 
58  // these GTiff profiles are based on Tim's benchmarks at
59  // http://linfiniti.com/2011/05/gdal-efficiency-of-various-compression-algorithms/
60  // big: no compression | medium: reasonable size/speed tradeoff | small: smallest size
61  mBuiltinProfiles[ QStringLiteral( "z_gtiff_1big" )] =
62  ( QStringList() << QStringLiteral( "GTiff" ) << tr( "No compression" )
63  << QStringLiteral( "COMPRESS=NONE BIGTIFF=IF_NEEDED" ) );
64  mBuiltinProfiles[ QStringLiteral( "z_gtiff_2medium" )] =
65  ( QStringList() << QStringLiteral( "GTiff" ) << tr( "Low compression" )
66  << QStringLiteral( "COMPRESS=PACKBITS" ) );
67  mBuiltinProfiles[ QStringLiteral( "z_gtiff_3small" )] =
68  ( QStringList() << QStringLiteral( "GTiff" ) << tr( "High compression" )
69  << QStringLiteral( "COMPRESS=DEFLATE PREDICTOR=2 ZLEVEL=9" ) );
70  mBuiltinProfiles[ QStringLiteral( "z_gtiff_4jpeg" )] =
71  ( QStringList() << QStringLiteral( "GTiff" ) << tr( "JPEG compression" )
72  << QStringLiteral( "COMPRESS=JPEG JPEG_QUALITY=75" ) );
73 
74  // overview compression schemes for GTiff format, see
75  // http://www.gdal.org/gdaladdo.html and http://www.gdal.org/frmt_gtiff.html
76  // TODO - should we offer GDAL_TIFF_OVR_BLOCKSIZE option here or in QgsRasterPyramidsOptionsWidget ?
77  mBuiltinProfiles[ QStringLiteral( "z__pyramids_gtiff_1big" )] =
78  ( QStringList() << QStringLiteral( "_pyramids" ) << tr( "No compression" )
79  << QStringLiteral( "COMPRESS_OVERVIEW=NONE BIGTIFF_OVERVIEW=IF_NEEDED" ) );
80  mBuiltinProfiles[ QStringLiteral( "z__pyramids_gtiff_2medium" )] =
81  ( QStringList() << QStringLiteral( "_pyramids" ) << tr( "Low compression" )
82  << QStringLiteral( "COMPRESS_OVERVIEW=PACKBITS" ) );
83  mBuiltinProfiles[ QStringLiteral( "z__pyramids_gtiff_3small" )] =
84  ( QStringList() << QStringLiteral( "_pyramids" ) << tr( "High compression" )
85  << QStringLiteral( "COMPRESS_OVERVIEW=DEFLATE PREDICTOR_OVERVIEW=2 ZLEVEL=9" ) ); // how to set zlevel?
86  mBuiltinProfiles[ QStringLiteral( "z__pyramids_gtiff_4jpeg" )] =
87  ( QStringList() << QStringLiteral( "_pyramids" ) << tr( "JPEG compression" )
89  }
90 
91  connect( mProfileComboBox, SIGNAL( currentIndexChanged( const QString & ) ),
92  this, SLOT( updateOptions() ) );
93  connect( mOptionsTable, SIGNAL( cellChanged( int, int ) ), this, SLOT( optionsTableChanged() ) );
94  connect( mOptionsHelpButton, SIGNAL( clicked() ), this, SLOT( helpOptions() ) );
95  connect( mOptionsValidateButton, SIGNAL( clicked() ), this, SLOT( validateOptions() ) );
96 
97  // create eventFilter to map right click to swapOptionsUI()
98  // mOptionsLabel->installEventFilter( this );
99  mOptionsLineEdit->installEventFilter( this );
100  mOptionsStackedWidget->installEventFilter( this );
101 
102  updateControls();
103  updateProfiles();
104 
105  QgsDebugMsg( "done" );
106 }
107 
109 {
110 }
111 
112 void QgsRasterFormatSaveOptionsWidget::setFormat( const QString& format )
113 {
114  mFormat = format;
115  updateControls();
116  updateProfiles();
117 }
118 
119 void QgsRasterFormatSaveOptionsWidget::setProvider( const QString& provider )
120 {
121  mProvider = provider;
122  updateControls();
123 }
124 
125 // show/hide widgets - we need this function if widget is used in creator
127 {
128  QList< QWidget* > widgets = this->findChildren<QWidget *>();
129  if (( type == Table ) || ( type == LineEdit ) )
130  {
131  // hide all controls, except stacked widget
132  Q_FOREACH ( QWidget* widget, widgets )
133  widget->setVisible( false );
134  mOptionsStackedWidget->setVisible( true );
135  Q_FOREACH ( QWidget* widget, mOptionsStackedWidget->findChildren<QWidget *>() )
136  widget->setVisible( true );
137 
138  // show relevant page
139  if ( type == Table )
140  swapOptionsUI( 0 );
141  else if ( type == LineEdit )
142  swapOptionsUI( 1 );
143  }
144  else
145  {
146  // show all widgets, except profile buttons (unless Full)
147  Q_FOREACH ( QWidget* widget, widgets )
148  widget->setVisible( true );
149  if ( type != Full )
150  mProfileButtons->setVisible( false );
151 
152  // show elevant page
153  if ( type == ProfileLineEdit )
154  swapOptionsUI( 1 );
155  }
156 }
157 
158 QString QgsRasterFormatSaveOptionsWidget::pseudoFormat() const
159 {
160  return mPyramids ? QStringLiteral( "_pyramids" ) : mFormat;
161 }
162 
164 {
165  // build profiles list = user + builtin(last)
166  QString format = pseudoFormat();
167  QStringList profileKeys = profiles();
168  QMapIterator<QString, QStringList> it( mBuiltinProfiles );
169  while ( it.hasNext() )
170  {
171  it.next();
172  QString profileKey = it.key();
173  if ( ! profileKeys.contains( profileKey ) && !it.value().isEmpty() )
174  {
175  // insert key if is for all formats or this format (GTiff)
176  if ( it.value()[0] == QLatin1String( "" ) || it.value()[0] == format )
177  {
178  profileKeys.insert( 0, profileKey );
179  }
180  }
181  }
182  qSort( profileKeys );
183 
184  // populate mOptionsMap and mProfileComboBox
185  mOptionsMap.clear();
186  mProfileComboBox->blockSignals( true );
187  mProfileComboBox->clear();
188  Q_FOREACH ( const QString& profileKey, profileKeys )
189  {
190  QString profileName, profileOptions;
191  profileOptions = createOptions( profileKey );
192  if ( mBuiltinProfiles.contains( profileKey ) )
193  {
194  profileName = mBuiltinProfiles[ profileKey ][ 1 ];
195  if ( profileOptions.isEmpty() )
196  profileOptions = mBuiltinProfiles[ profileKey ][ 2 ];
197  }
198  else
199  {
200  profileName = profileKey;
201  }
202  mOptionsMap[ profileKey ] = profileOptions;
203  mProfileComboBox->addItem( profileName, profileKey );
204  }
205 
206  // update UI
207  mProfileComboBox->blockSignals( false );
208  // mProfileComboBox->setCurrentIndex( 0 );
209  QSettings mySettings;
210  mProfileComboBox->setCurrentIndex( mProfileComboBox->findData( mySettings.value(
211  mProvider + "/driverOptions/" + format.toLower() + "/defaultProfile",
212  "z_adefault" ) ) );
213  updateOptions();
214 }
215 
216 void QgsRasterFormatSaveOptionsWidget::updateOptions()
217 {
218  QString myOptions = mOptionsMap.value( currentProfileKey() );
219  QStringList myOptionsList = myOptions.trimmed().split( ' ', QString::SkipEmptyParts );
220 
221  // If the default JPEG compression profile was selected, remove PHOTOMETRIC_OVERVIEW=YCBCR
222  // if the raster is not RGB. Otherwise this is bound to fail afterwards.
223  if ( mRasterLayer && mRasterLayer->bandCount() != 3 &&
224  myOptions == PYRAMID_JPEG_YCBCR_COMPRESSION )
225  {
226  myOptions = PYRAMID_JPEG_COMPRESSION;
227  }
228 
229  if ( mOptionsStackedWidget->currentIndex() == 0 )
230  {
231  mOptionsTable->setRowCount( 0 );
232  for ( int i = 0; i < myOptionsList.count(); i++ )
233  {
234  QStringList key_value = myOptionsList[i].split( '=' );
235  if ( key_value.count() == 2 )
236  {
237  mOptionsTable->insertRow( i );
238  mOptionsTable->setItem( i, 0, new QTableWidgetItem( key_value[0] ) );
239  mOptionsTable->setItem( i, 1, new QTableWidgetItem( key_value[1] ) );
240  }
241  }
242  }
243  else
244  {
245  mOptionsLineEdit->setText( myOptions );
246  mOptionsLineEdit->setCursorPosition( 0 );
247  }
248 
249  emit optionsChanged();
250 }
251 
253 {
254  setCreateOptions();
255 }
256 
257 // typedefs for gdal provider function pointers
258 typedef QString validateCreationOptionsFormat_t( const QStringList& createOptions, QString format );
259 typedef QString helpCreationOptionsFormat_t( QString format );
260 
262 {
263  QString message;
264 
265  if ( mProvider == QLatin1String( "gdal" ) && mFormat != QLatin1String( "" ) && ! mPyramids )
266  {
267  // get helpCreationOptionsFormat() function ptr for provider
268  QLibrary *library = QgsProviderRegistry::instance()->providerLibrary( mProvider );
269  if ( library )
270  {
271  helpCreationOptionsFormat_t * helpCreationOptionsFormat =
272  ( helpCreationOptionsFormat_t * ) cast_to_fptr( library->resolve( "helpCreationOptionsFormat" ) );
273  if ( helpCreationOptionsFormat )
274  {
275  message = helpCreationOptionsFormat( mFormat );
276  }
277  else
278  {
279  message = library->fileName() + " does not have helpCreationOptionsFormat";
280  }
281  }
282  else
283  message = QStringLiteral( "cannot load provider library %1" ).arg( mProvider );
284 
285 
286  if ( message.isEmpty() )
287  message = tr( "Cannot get create options for driver %1" ).arg( mFormat );
288  }
289  else if ( mProvider == QLatin1String( "gdal" ) && mPyramids )
290  {
291  message = tr( "For details on pyramids options please see the following pages" );
292  message += QLatin1String( "\n\nhttp://www.gdal.org/gdaladdo.html\n\nhttp://www.gdal.org/frmt_gtiff.html" );
293  }
294  else
295  message = tr( "No help available" );
296 
297  // show simple non-modal dialog - should we make the basic xml prettier?
298  QgsDialog *dlg = new QgsDialog( this );
299  QTextEdit *textEdit = new QTextEdit( dlg );
300  textEdit->setReadOnly( true );
301  // message = tr( "Create Options:\n\n%1" ).arg( message );
302  textEdit->setText( message );
303  dlg->layout()->addWidget( textEdit );
304  dlg->resize( 600, 400 );
305 #ifdef Q_OS_MAC
306  dlg->exec(); //modal
307 #else
308  dlg->show(); //non modal
309 #endif
310 }
311 
312 QString QgsRasterFormatSaveOptionsWidget::validateOptions( bool gui, bool reportOK )
313 {
314  QStringList createOptions = options();
315  QString message;
316 
317  QgsDebugMsg( QString( "layer: [%1] file: [%2] format: [%3]" ).arg( mRasterLayer ? mRasterLayer->id() : "none", mRasterFileName, mFormat ) );
318  // if no rasterLayer is defined, but we have a raster fileName, then create a temp. rasterLayer to validate options
319  // ideally we should keep it for future access, but this is trickier
320  QgsRasterLayer* rasterLayer = mRasterLayer;
321  bool tmpLayer = false;
322  if ( !( mRasterLayer && rasterLayer->dataProvider() ) && ! mRasterFileName.isNull() )
323  {
324  // temporarily override /Projections/defaultBehaviour to avoid dialog prompt
325  // this is taken from qgsbrowserdockwidget.cpp
326  // TODO - integrate this into qgis core
327  QSettings settings;
328  QString defaultProjectionOption = settings.value( QStringLiteral( "/Projections/defaultBehaviour" ), "prompt" ).toString();
329  if ( settings.value( QStringLiteral( "/Projections/defaultBehaviour" ), "prompt" ).toString() == QLatin1String( "prompt" ) )
330  {
331  settings.setValue( QStringLiteral( "/Projections/defaultBehaviour" ), "useProject" );
332  }
333  tmpLayer = true;
334  rasterLayer = new QgsRasterLayer( mRasterFileName, QFileInfo( mRasterFileName ).baseName(), QStringLiteral( "gdal" ) );
335  // restore /Projections/defaultBehaviour
336  if ( defaultProjectionOption == QLatin1String( "prompt" ) )
337  {
338  settings.setValue( QStringLiteral( "/Projections/defaultBehaviour" ), defaultProjectionOption );
339  }
340  }
341 
342  if ( mProvider == QLatin1String( "gdal" ) && mPyramids )
343  {
344  if ( rasterLayer && rasterLayer->dataProvider() )
345  {
346  QgsDebugMsg( "calling validate pyramids on layer's data provider" );
347  message = rasterLayer->dataProvider()->validatePyramidsConfigOptions( mPyramidsFormat, createOptions, mFormat );
348  }
349  else
350  {
351  message = tr( "cannot validate pyramid options" );
352  }
353  }
354  else if ( !createOptions.isEmpty() && mProvider == QLatin1String( "gdal" ) && mFormat != QLatin1String( "" ) )
355  {
356  if ( rasterLayer && rasterLayer->dataProvider() )
357  {
358  QgsDebugMsg( "calling validate on layer's data provider" );
359  message = rasterLayer->dataProvider()->validateCreationOptions( createOptions, mFormat );
360  }
361  else
362  {
363  // get validateCreationOptionsFormat() function ptr for provider
364  QLibrary *library = QgsProviderRegistry::instance()->providerLibrary( mProvider );
365  if ( library )
366  {
367  validateCreationOptionsFormat_t * validateCreationOptionsFormat =
368  ( validateCreationOptionsFormat_t * ) cast_to_fptr( library->resolve( "validateCreationOptionsFormat" ) );
369  if ( validateCreationOptionsFormat )
370  {
371  message = validateCreationOptionsFormat( createOptions, mFormat );
372  }
373  else
374  {
375  message = library->fileName() + " does not have validateCreationOptionsFormat";
376  }
377  }
378  else
379  message = QStringLiteral( "cannot load provider library %1" ).arg( mProvider );
380  }
381  }
382  else if ( ! createOptions.isEmpty() )
383  {
384  QMessageBox::information( this, QLatin1String( "" ), tr( "Cannot validate creation options" ), QMessageBox::Close );
385  if ( tmpLayer )
386  delete rasterLayer;
387  return QString();
388  }
389 
390  if ( gui )
391  {
392  if ( message.isNull() )
393  {
394  if ( reportOK )
395  QMessageBox::information( this, QLatin1String( "" ), tr( "Valid" ), QMessageBox::Close );
396  }
397  else
398  {
399  QMessageBox::warning( this, QLatin1String( "" ), tr( "Invalid %1:\n\n%2\n\nClick on help button to get valid creation options for this format." ).arg( mPyramids ? tr( "pyramid creation option" ) : tr( "creation option" ), message ), QMessageBox::Close );
400  }
401  }
402 
403  if ( tmpLayer )
404  delete rasterLayer;
405 
406  return message;
407 }
408 
409 void QgsRasterFormatSaveOptionsWidget::optionsTableChanged()
410 {
411  QTableWidgetItem *key, *value;
412  QString options;
413  for ( int i = 0 ; i < mOptionsTable->rowCount(); i++ )
414  {
415  key = mOptionsTable->item( i, 0 );
416  if ( ! key || key->text().isEmpty() )
417  continue;
418  value = mOptionsTable->item( i, 1 );
419  if ( ! value || value->text().isEmpty() )
420  continue;
421  options += key->text() + '=' + value->text() + ' ';
422  }
423  options = options.trimmed();
424  mOptionsMap[ currentProfileKey()] = options;
425  mOptionsLineEdit->setText( options );
426  mOptionsLineEdit->setCursorPosition( 0 );
427 }
428 
429 void QgsRasterFormatSaveOptionsWidget::on_mOptionsLineEdit_editingFinished()
430 {
431  mOptionsMap[ currentProfileKey()] = mOptionsLineEdit->text().trimmed();
432 }
433 
434 void QgsRasterFormatSaveOptionsWidget::on_mProfileNewButton_clicked()
435 {
436  QString profileName = QInputDialog::getText( this, QLatin1String( "" ), tr( "Profile name:" ) );
437  if ( ! profileName.isEmpty() )
438  {
439  profileName = profileName.trimmed();
440  mOptionsMap[ profileName ] = QLatin1String( "" );
441  mProfileComboBox->addItem( profileName, profileName );
442  mProfileComboBox->setCurrentIndex( mProfileComboBox->count() - 1 );
443  }
444 }
445 
446 void QgsRasterFormatSaveOptionsWidget::on_mProfileDeleteButton_clicked()
447 {
448  int index = mProfileComboBox->currentIndex();
449  QString profileKey = currentProfileKey();
450  if ( index != -1 && ! mBuiltinProfiles.contains( profileKey ) )
451  {
452  mOptionsMap.remove( profileKey );
453  mProfileComboBox->removeItem( index );
454  }
455 }
456 
457 void QgsRasterFormatSaveOptionsWidget::on_mProfileResetButton_clicked()
458 {
459  QString profileKey = currentProfileKey();
460  if ( mBuiltinProfiles.contains( profileKey ) )
461  {
462  mOptionsMap[ profileKey ] = mBuiltinProfiles[ profileKey ][ 2 ];
463  }
464  else
465  {
466  mOptionsMap[ profileKey ] = QLatin1String( "" );
467  }
468  mOptionsLineEdit->setText( mOptionsMap.value( currentProfileKey() ) );
469  mOptionsLineEdit->setCursorPosition( 0 );
470  updateOptions();
471 }
472 
473 void QgsRasterFormatSaveOptionsWidget::optionsTableEnableDeleteButton()
474 {
475  mOptionsDeleteButton->setEnabled( mOptionsTable->currentRow() >= 0 );
476 }
477 
478 void QgsRasterFormatSaveOptionsWidget::on_mOptionsAddButton_clicked()
479 {
480  mOptionsTable->insertRow( mOptionsTable->rowCount() );
481  // select the added row
482  int newRow = mOptionsTable->rowCount() - 1;
483  QTableWidgetItem* item = new QTableWidgetItem();
484  mOptionsTable->setItem( newRow, 0, item );
485  mOptionsTable->setCurrentItem( item );
486 }
487 
488 void QgsRasterFormatSaveOptionsWidget::on_mOptionsDeleteButton_clicked()
489 {
490  if ( mOptionsTable->currentRow() >= 0 )
491  {
492  mOptionsTable->removeRow( mOptionsTable->currentRow() );
493  // select the previous row or the next one if there is no previous row
494  QTableWidgetItem* item = mOptionsTable->item( mOptionsTable->currentRow(), 0 );
495  mOptionsTable->setCurrentItem( item );
496  optionsTableChanged();
497  }
498 }
499 
500 
501 QString QgsRasterFormatSaveOptionsWidget::settingsKey( QString profileName ) const
502 {
503  if ( profileName != QLatin1String( "" ) )
504  profileName = "/profile_" + profileName;
505  else
506  profileName = "/profile_default" + profileName;
507  return mProvider + "/driverOptions/" + pseudoFormat().toLower() + profileName + "/create";
508 }
509 
510 QString QgsRasterFormatSaveOptionsWidget::currentProfileKey() const
511 {
512  return mProfileComboBox->currentData().toString();
513 }
514 
516 {
517  return mOptionsMap.value( currentProfileKey() ).trimmed().split( ' ', QString::SkipEmptyParts );
518 }
519 
520 QString QgsRasterFormatSaveOptionsWidget::createOptions( const QString& profileName ) const
521 {
522  QSettings mySettings;
523  return mySettings.value( settingsKey( profileName ), "" ).toString();
524 }
525 
526 void QgsRasterFormatSaveOptionsWidget::deleteCreateOptions( const QString& profileName )
527 {
528  QSettings mySettings;
529  mySettings.remove( settingsKey( profileName ) );
530 }
531 
532 void QgsRasterFormatSaveOptionsWidget::setCreateOptions()
533 {
534  QSettings mySettings;
535  QString myProfiles;
536  QMap< QString, QString >::const_iterator i = mOptionsMap.constBegin();
537  while ( i != mOptionsMap.constEnd() )
538  {
539  setCreateOptions( i.key(), i.value() );
540  myProfiles += i.key() + QStringLiteral( " " );
541  ++i;
542  }
543  mySettings.setValue( mProvider + "/driverOptions/" + pseudoFormat().toLower() + "/profiles",
544  myProfiles.trimmed() );
545  mySettings.setValue( mProvider + "/driverOptions/" + pseudoFormat().toLower() + "/defaultProfile",
546  currentProfileKey().trimmed() );
547 }
548 
549 void QgsRasterFormatSaveOptionsWidget::setCreateOptions( const QString& profileName, const QString& options )
550 {
551  QSettings mySettings;
552  mySettings.setValue( settingsKey( profileName ), options.trimmed() );
553 }
554 
555 void QgsRasterFormatSaveOptionsWidget::setCreateOptions( const QString& profileName, const QStringList& list )
556 {
557  setCreateOptions( profileName, list.join( QStringLiteral( " " ) ) );
558 }
559 
560 QStringList QgsRasterFormatSaveOptionsWidget::profiles() const
561 {
562  QSettings mySettings;
563  return mySettings.value( mProvider + "/driverOptions/" + pseudoFormat().toLower() + "/profiles", "" ).toString().trimmed().split( ' ', QString::SkipEmptyParts );
564 }
565 
566 void QgsRasterFormatSaveOptionsWidget::swapOptionsUI( int newIndex )
567 {
568  // set new page
569  int oldIndex;
570  if ( newIndex == -1 )
571  {
572  oldIndex = mOptionsStackedWidget->currentIndex();
573  newIndex = ( oldIndex + 1 ) % 2;
574  }
575  else
576  {
577  oldIndex = ( newIndex + 1 ) % 2;
578  }
579 
580  // resize pages to minimum - this works well with gdaltools merge ui, but not raster save as...
581  mOptionsStackedWidget->setCurrentIndex( newIndex );
582  mOptionsStackedWidget->widget( newIndex )->setSizePolicy(
583  QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) );
584  mOptionsStackedWidget->widget( oldIndex )->setSizePolicy(
585  QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ) );
586  layout()->activate();
587 
588  updateOptions();
589 }
590 
591 void QgsRasterFormatSaveOptionsWidget::updateControls()
592 {
593  bool valid = mProvider == QLatin1String( "gdal" ) && mFormat != QLatin1String( "" );
594  mOptionsValidateButton->setEnabled( valid );
595  mOptionsHelpButton->setEnabled( valid );
596 }
597 
598 // map options label left mouse click to optionsToggle()
599 bool QgsRasterFormatSaveOptionsWidget::eventFilter( QObject *obj, QEvent *event )
600 {
601  if ( event->type() == QEvent::MouseButtonPress )
602  {
603  QMouseEvent *mouseEvent = static_cast<QMouseEvent *>( event );
604  if ( mouseEvent && ( mouseEvent->button() == Qt::RightButton ) )
605  {
606  QMenu* menu = nullptr;
607  QString text;
608  if ( mOptionsStackedWidget->currentIndex() == 0 )
609  text = tr( "Use simple interface" );
610  else
611  text = tr( "Use table interface" );
612  if ( obj->objectName() == QLatin1String( "mOptionsLineEdit" ) )
613  {
614  menu = mOptionsLineEdit->createStandardContextMenu();
615  menu->addSeparator();
616  }
617  else
618  menu = new QMenu( this );
619  QAction* action = new QAction( text, menu );
620  menu->addAction( action );
621  connect( action, SIGNAL( triggered() ), this, SLOT( swapOptionsUI() ) );
622  menu->exec( mouseEvent->globalPos() );
623  delete menu;
624  return true;
625  }
626  }
627  // standard event processing
628  return QObject::eventFilter( obj, event );
629 }
630 
632 {
633  Q_UNUSED( event );
634  mOptionsTable->horizontalHeader()->resizeSection( 0, mOptionsTable->width() - 115 );
635  QgsDebugMsg( "done" );
636 }
637 
static const QString PYRAMID_JPEG_YCBCR_COMPRESSION(QStringLiteral("JPEG_QUALITY_OVERVIEW=75 COMPRESS_OVERVIEW=JPEG PHOTOMETRIC_OVERVIEW=YCBCR INTERLEAVE_OVERVIEW=PIXEL"))
static unsigned index
static QgsProviderRegistry * instance(const QString &pluginPath=QString::null)
Means of accessing canonical single instance.
QgsRasterFormatSaveOptionsWidget(QWidget *parent=nullptr, const QString &format="GTiff", QgsRasterFormatSaveOptionsWidget::Type type=Default, const QString &provider="gdal")
QString helpCreationOptionsFormat_t(QString format)
virtual QString validatePyramidsConfigOptions(QgsRaster::RasterPyramidsFormat pyramidsFormat, const QStringList &theConfigOptions, const QString &fileFormat)
Validates pyramid creation options for a specific dataset and destination format. ...
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
A generic dialog with layout and button box.
Definition: qgsdialog.h:30
QString validateCreationOptionsFormat_t(const QStringList &createOptions, QString format)
int bandCount() const
Get the number of bands in this layer.
QString validateOptions(bool gui=true, bool reportOk=true)
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsMapLayerRegistry.
#define cast_to_fptr(f)
Definition: qgis.h:126
QLibrary * providerLibrary(const QString &providerKey) const
Raster namespace.
Definition: qgsraster.h:28
virtual void showEvent(QShowEvent *event) override
static const QString PYRAMID_JPEG_COMPRESSION(QStringLiteral("JPEG_QUALITY_OVERVIEW=75 COMPRESS_OVERVIEW=JPEG INTERLEAVE_OVERVIEW=PIXEL"))
QVBoxLayout * layout()
Returns the central layout. Widgets added to it must have this dialog as parent.
Definition: qgsdialog.h:44
void setType(QgsRasterFormatSaveOptionsWidget::Type type=Default)
virtual QString validateCreationOptions(const QStringList &createOptions, const QString &format)
Validates creation options for a specific dataset and destination format.
QgsRasterDataProvider * dataProvider()
Returns the data provider.