QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsrasterlayersaveasdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterlayersaveasdialog.cpp
3  ---------------------
4  begin : May 2012
5  copyright : (C) 2012 by Marco Hugentobler
6  email : marco dot hugentobler at sourcepole dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 #include "qgsapplication.h"
16 #include "qgslogger.h"
17 #include "qgscoordinatetransform.h"
18 #include "qgsrasterlayer.h"
20 #include "qgsrasterdataprovider.h"
23 
24 #include <QFileDialog>
25 #include <QMessageBox>
26 #include <QSettings>
27 
29  QgsRasterDataProvider* sourceProvider, const QgsRectangle& currentExtent,
30  const QgsCoordinateReferenceSystem& layerCrs, const QgsCoordinateReferenceSystem& currentCrs,
31  QWidget* parent, Qt::WindowFlags f ) :
32  QDialog( parent, f )
33  , mRasterLayer( rasterLayer ), mDataProvider( sourceProvider )
34  , mCurrentExtent( currentExtent ), mLayerCrs( layerCrs )
35  , mCurrentCrs( currentCrs )
36  , mResolutionState( OriginalResolution )
37 {
38  setupUi( this );
39  mAddNoDataManuallyToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) );
40  mLoadTransparentNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionCopySelected.png" ) );
41  mRemoveSelectedNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) );
42  mRemoveAllNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionRemove.png" ) );
43 
44  mNoDataTableWidget->setColumnCount( 2 );
45  mNoDataTableWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( tr( "From" ) ) );
46  mNoDataTableWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( tr( "To" ) ) );
47 
48  on_mRawModeRadioButton_toggled( true );
49 
50  setValidators();
51 
52  toggleResolutionSize();
53 
54  //only one hardcoded format at the moment
55  QStringList myFormats;
56  myFormats << "GTiff";
57  foreach ( QString myFormat, myFormats )
58  {
59  mFormatComboBox->addItem( myFormat );
60  }
61 
62  //fill reasonable default values depending on the provider
63  if ( mDataProvider )
64  {
65  if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
66  {
67  setOriginalResolution();
68  int xSize = mDataProvider->xSize();
69  int ySize = mDataProvider->ySize();
70  mMaximumSizeXLineEdit->setText( QString::number( xSize ) );
71  mMaximumSizeYLineEdit->setText( QString::number( ySize ) );
72  }
73  else //wms, sometimes wcs
74  {
75  mTileModeCheckBox->setChecked( true );
76  mMaximumSizeXLineEdit->setText( QString::number( 2000 ) );
77  mMaximumSizeYLineEdit->setText( QString::number( 2000 ) );
78  }
79 
80  // setup creation option widget
81  mCreateOptionsWidget->setProvider( mDataProvider->name() );
82  if ( mDataProvider->name() == "gdal" )
83  {
84  mCreateOptionsWidget->setFormat( myFormats[0] );
85  }
86  mCreateOptionsWidget->setRasterLayer( mRasterLayer );
87  mCreateOptionsWidget->update();
88  }
89 
90  // Only do pyramids if dealing directly with GDAL.
91  if ( mDataProvider && mDataProvider->capabilities() & QgsRasterDataProvider::BuildPyramids )
92  {
93  // setup pyramids option widget
94  // mPyramidsOptionsWidget->createOptionsWidget()->setType( QgsRasterFormatSaveOptionsWidget::ProfileLineEdit );
95  mPyramidsOptionsWidget->createOptionsWidget()->setRasterLayer( mRasterLayer );
96 
97  // TODO enable "use existing", has no effect for now, because using Create() in gdal provider
98  // if ( ! mDataProvider->hasPyramids() )
99  // mPyramidsButtonGroup->button( QgsRaster::PyramidsCopyExisting )->setEnabled( false );
100  mPyramidsUseExistingCheckBox->setEnabled( false );
101  mPyramidsUseExistingCheckBox->setVisible( false );
102 
103  populatePyramidsLevels();
104  connect( mPyramidsOptionsWidget, SIGNAL( overviewListChanged() ),
105  this, SLOT( populatePyramidsLevels() ) );
106  }
107  else
108  {
109  mPyramidsGroupBox->setEnabled( false );
110  }
111 
112  // restore checked state for most groupboxes (default is to restore collapsed state)
113  // create options and pyramids will be preset, if user has selected defaults in the gdal options dlg
114  mCreateOptionsGroupBox->setSaveCheckedState( true );
115  //mTilesGroupBox->setSaveCheckedState( true );
116  // don't restore nodata, it needs user input
117  // pyramids are not necessarily built every time
118 
119  mTilesGroupBox->hide();
120 
121  mCrsSelector->setLayerCrs( mLayerCrs );
122  mCrsSelector->setCrs( mCurrentCrs );
123  connect( mCrsSelector, SIGNAL( crsChanged( QgsCoordinateReferenceSystem ) ),
124  this, SLOT( crsChanged() ) );
125 
126  QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
127  if ( okButton )
128  {
129  okButton->setEnabled( false );
130  }
131 
132  mExtentGroupBox->setOutputCrs( outputCrs() );
133  mExtentGroupBox->setOriginalExtent( mDataProvider->extent(), mLayerCrs );
134  mExtentGroupBox->setCurrentExtent( mCurrentExtent, mCurrentCrs );
135  mExtentGroupBox->setOutputExtentFromOriginal();
136  connect( mExtentGroupBox, SIGNAL( extentChanged( QgsRectangle ) ), this, SLOT( extentChanged() ) );
137 
138  recalcResolutionSize();
139 }
140 
141 void QgsRasterLayerSaveAsDialog::setValidators()
142 {
143  mXResolutionLineEdit->setValidator( new QDoubleValidator( this ) );
144  mYResolutionLineEdit->setValidator( new QDoubleValidator( this ) );
145  mColumnsLineEdit->setValidator( new QIntValidator( this ) );
146  mRowsLineEdit->setValidator( new QIntValidator( this ) );
147  mMaximumSizeXLineEdit->setValidator( new QIntValidator( this ) );
148  mMaximumSizeYLineEdit->setValidator( new QIntValidator( this ) );
149 }
150 
152 {
153 }
154 
155 void QgsRasterLayerSaveAsDialog::on_mBrowseButton_clicked()
156 {
157  QString fileName;
158 
159  QSettings settings;
160  QString dirName = mSaveAsLineEdit->text().isEmpty() ? settings.value( "/UI/lastRasterFileDir", "." ).toString() : mSaveAsLineEdit->text();
161 
162  if ( mTileModeCheckBox->isChecked() )
163  {
164  while ( true )
165  {
166  // TODO: would not it be better to select .vrt file instead of directory?
167  fileName = QFileDialog::getExistingDirectory( this, tr( "Select output directory" ), dirName );
168  //fileName = QFileDialog::getSaveFileName( this, tr( "Select output file" ), QString(), tr( "VRT" ) + " (*.vrt *.VRT)" );
169 
170  if ( fileName.isEmpty() ) break; // canceled
171 
172  // Check if directory is empty
173  QDir dir( fileName );
174  QString baseName = QFileInfo( fileName ).baseName();
175  QStringList filters;
176  filters << QString( "%1.*" ).arg( baseName );
177  QStringList files = dir.entryList( filters );
178  if ( !files.isEmpty() )
179  {
180  QMessageBox::StandardButton button = QMessageBox::warning( this, tr( "Warning" ),
181  tr( "The directory %1 contains files which will be overwritten: %2" ).arg( dir.absolutePath() ).arg( files.join( ", " ) ),
182  QMessageBox::Ok | QMessageBox::Cancel );
183 
184  if ( button == QMessageBox::Ok )
185  {
186  break;
187  }
188  else
189  {
190  fileName = "";
191  }
192  }
193  else
194  {
195  break;
196  }
197  }
198  }
199  else
200  {
201  fileName = QFileDialog::getSaveFileName( this, tr( "Select output file" ), dirName, tr( "GeoTIFF" ) + " (*.tif *.tiff *.TIF *.TIFF)" );
202  }
203 
204  if ( !fileName.isEmpty() )
205  {
206  mSaveAsLineEdit->setText( fileName );
207  }
208 }
209 
210 void QgsRasterLayerSaveAsDialog::on_mSaveAsLineEdit_textChanged( const QString& text )
211 {
212  QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
213  if ( !okButton )
214  {
215  return;
216  }
217 
218  okButton->setEnabled( QFileInfo( text ).absoluteDir().exists() );
219 }
220 
221 
222 void QgsRasterLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( const QString & text )
223 {
224  //gdal-specific
225  if ( mDataProvider && mDataProvider->name() == "gdal" )
226  {
227  mCreateOptionsWidget->setFormat( text );
228  mCreateOptionsWidget->update();
229  }
230 }
231 
233 {
234  return mColumnsLineEdit->text().toInt();
235 }
236 
238 {
239  return mRowsLineEdit->text().toInt();
240 }
241 
243 {
244  return mXResolutionLineEdit->text().toDouble();
245 }
246 
248 {
249  return mYResolutionLineEdit->text().toDouble();
250 }
251 
253 {
254  return mMaximumSizeXLineEdit->text().toInt();
255 }
256 
258 {
259  return mMaximumSizeYLineEdit->text().toInt();
260 }
261 
263 {
264  return mTileModeCheckBox->isChecked();
265 }
266 
268 {
269  return mSaveAsLineEdit->text();
270 }
271 
273 {
274  return mFormatComboBox->currentText();
275 }
276 
278 {
279  return mCreateOptionsGroupBox->isChecked() ? mCreateOptionsWidget->options() : QStringList();
280 }
281 
283 {
284  return mExtentGroupBox->outputExtent();
285 }
286 
288 {
289  mFormatLabel->hide();
290  mFormatComboBox->hide();
291 }
292 
294 {
295  mSaveAsLabel->hide();
296  mSaveAsLineEdit->hide();
297  mBrowseButton->hide();
298  QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
299  if ( okButton )
300  {
301  okButton->setEnabled( true );
302  }
303 }
304 
305 void QgsRasterLayerSaveAsDialog::toggleResolutionSize()
306 {
307  bool hasResolution = mDataProvider && mDataProvider->capabilities() & QgsRasterDataProvider::Size;
308 
309  bool on = mResolutionRadioButton->isChecked();
310  mXResolutionLineEdit->setEnabled( on );
311  mYResolutionLineEdit->setEnabled( on );
312  mOriginalResolutionPushButton->setEnabled( on && hasResolution );
313  mColumnsLineEdit->setEnabled( !on );
314  mRowsLineEdit->setEnabled( !on );
315  mOriginalSizePushButton->setEnabled( !on && hasResolution );
316 }
317 
318 void QgsRasterLayerSaveAsDialog::setOriginalResolution()
319 {
320  double xRes, yRes;
321 
322  if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
323  {
324  xRes = mDataProvider->extent().width() / mDataProvider->xSize();
325  yRes = mDataProvider->extent().height() / mDataProvider->ySize();
326  }
327  else
328  {
329  // Init to something if no original resolution is available
330  xRes = yRes = mDataProvider->extent().width() / 100;
331  }
332  setResolution( xRes, yRes, mLayerCrs );
333  mResolutionState = OriginalResolution;
334  recalcSize();
335 }
336 
337 void QgsRasterLayerSaveAsDialog::setResolution( double xRes, double yRes, const QgsCoordinateReferenceSystem& srcCrs )
338 {
339  if ( srcCrs != outputCrs() )
340  {
341  // We reproject pixel rectangle from center of selected extent, of course, it gives
342  // bigger xRes,yRes than reprojected edges (envelope), it may also be that
343  // close to margins are higher resolutions (even very, too high)
344  // TODO: consider more precise resolution calculation
345 
346  QgsPoint center = outputRectangle().center();
347  QgsCoordinateTransform ct( srcCrs, outputCrs() );
348  QgsPoint srsCenter = ct.transform( center, QgsCoordinateTransform::ReverseTransform );
349 
350  QgsRectangle srcExtent( srsCenter.x() - xRes / 2, srsCenter.y() - yRes / 2, srsCenter.x() + xRes / 2, srsCenter.y() + yRes / 2 );
351 
352  QgsRectangle extent = ct.transform( srcExtent );
353  xRes = extent.width();
354  yRes = extent.height();
355  }
356  mXResolutionLineEdit->setText( QString::number( xRes ) );
357  mYResolutionLineEdit->setText( QString::number( yRes ) );
358 }
359 
360 void QgsRasterLayerSaveAsDialog::recalcSize()
361 {
362  QgsDebugMsg( "Entered" );
363  QgsRectangle extent = outputRectangle();
364  int xSize = xResolution() != 0 ? static_cast<int>( qRound( extent.width() / xResolution() ) ) : 0;
365  int ySize = yResolution() != 0 ? static_cast<int>( qRound( extent.height() / yResolution() ) ) : 0;
366  mColumnsLineEdit->setText( QString::number( xSize ) );
367  mRowsLineEdit->setText( QString::number( ySize ) );
368  updateResolutionStateMsg();
369 }
370 
371 void QgsRasterLayerSaveAsDialog::setOriginalSize()
372 {
373  mColumnsLineEdit->setText( QString::number( mDataProvider->xSize() ) );
374  mRowsLineEdit->setText( QString::number( mDataProvider->ySize() ) );
375  recalcResolution();
376 }
377 
378 void QgsRasterLayerSaveAsDialog::recalcResolution()
379 {
380  QgsDebugMsg( "Entered" );
381  QgsRectangle extent = outputRectangle();
382  double xRes = nColumns() != 0 ? extent.width() / nColumns() : 0;
383  double yRes = nRows() != 0 ? extent.height() / nRows() : 0;
384  mXResolutionLineEdit->setText( QString::number( xRes ) );
385  mYResolutionLineEdit->setText( QString::number( yRes ) );
386  updateResolutionStateMsg();
387 }
388 
389 void QgsRasterLayerSaveAsDialog::recalcResolutionSize()
390 {
391  QgsDebugMsg( "Entered" );
392  if ( mResolutionRadioButton->isChecked() )
393  {
394  recalcSize();
395  }
396  else
397  {
398  mResolutionState = UserResolution;
399  recalcResolution();
400  }
401 }
402 
403 void QgsRasterLayerSaveAsDialog::updateResolutionStateMsg()
404 {
405  QString msg;
406  switch ( mResolutionState )
407  {
408  case OriginalResolution:
409  msg = tr( "layer" );
410  break;
411  case UserResolution:
412  msg = tr( "user defined" );
413  break;
414  default:
415  break;
416  }
417  msg = tr( "Resolution (current: %1)" ).arg( msg );
418  mResolutionGroupBox->setTitle( msg );
419 }
420 
421 void QgsRasterLayerSaveAsDialog::extentChanged()
422 {
423  // Whenever extent changes with fixed size, original resolution is lost
424  if ( mSizeRadioButton->isChecked() )
425  {
426  mResolutionState = UserResolution;
427  }
428  recalcResolutionSize();
429 }
430 
431 void QgsRasterLayerSaveAsDialog::crsChanged()
432 {
433  if ( outputCrs() != mPreviousCrs )
434  {
435  mExtentGroupBox->setOutputCrs( outputCrs() );
436  QgsExtentGroupBox::ExtentState state = mExtentGroupBox->extentState();
437 
438  // Reset extent
439  // We could reproject previous but that would add additional space also if
440  // it is was not necessary or at leas it could decrease accuracy
441  if ( state == QgsExtentGroupBox::OriginalExtent )
442  {
443  mExtentGroupBox->setOutputExtentFromOriginal();
444  }
445  else if ( state == QgsExtentGroupBox::CurrentExtent )
446  {
447  mExtentGroupBox->setOutputExtentFromCurrent();
448  }
449  else
450  {
451  mExtentGroupBox->setOutputExtentFromUser( mExtentGroupBox->outputExtent(), mPreviousCrs );
452  }
453 
454  // Reset resolution
455  if ( mResolutionRadioButton->isChecked() )
456  {
457  if ( mResolutionState == OriginalResolution )
458  {
459  setOriginalResolution();
460  }
461  else
462  {
463  // reset from present resolution and present crs
464  setResolution( xResolution(), yResolution(), mPreviousCrs );
465  }
466  }
467  else
468  {
469  // Size does not change, we just recalc resolution from new extent
470  recalcResolution();
471  }
472  }
473  mPreviousCrs = outputCrs();
474 }
475 
477 {
478  return mCrsSelector->crs();
479 }
480 
482 {
483  if ( mRenderedModeRadioButton->isChecked() ) return RenderedImageMode;
484  return RawDataMode;
485 }
486 
487 void QgsRasterLayerSaveAsDialog::on_mRawModeRadioButton_toggled( bool checked )
488 {
489  mNoDataGroupBox->setEnabled( checked && mDataProvider->bandCount() == 1 );
490 }
491 
492 void QgsRasterLayerSaveAsDialog::on_mAddNoDataManuallyToolButton_clicked()
493 {
494  addNoDataRow( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
495 }
496 
497 void QgsRasterLayerSaveAsDialog::on_mLoadTransparentNoDataToolButton_clicked()
498 {
499  if ( !mRasterLayer->renderer() ) return;
500  const QgsRasterTransparency* rasterTransparency = mRasterLayer->renderer()->rasterTransparency();
501  if ( !rasterTransparency ) return;
502 
503  foreach ( QgsRasterTransparency::TransparentSingleValuePixel transparencyPixel, rasterTransparency->transparentSingleValuePixelList() )
504  {
505  if ( transparencyPixel.percentTransparent == 100 )
506  {
507  addNoDataRow( transparencyPixel.min, transparencyPixel.max );
508  if ( transparencyPixel.min != transparencyPixel.max )
509  {
510  setNoDataToEdited( mNoDataTableWidget->rowCount() - 1 );
511  }
512  }
513  }
514 }
515 
516 void QgsRasterLayerSaveAsDialog::on_mRemoveSelectedNoDataToolButton_clicked()
517 {
518  mNoDataTableWidget->removeRow( mNoDataTableWidget->currentRow() );
519 }
520 
521 void QgsRasterLayerSaveAsDialog::on_mRemoveAllNoDataToolButton_clicked()
522 {
523  while ( mNoDataTableWidget->rowCount() > 0 )
524  {
525  mNoDataTableWidget->removeRow( 0 );
526  }
527 }
528 
529 void QgsRasterLayerSaveAsDialog::addNoDataRow( double min, double max )
530 {
531  mNoDataTableWidget->insertRow( mNoDataTableWidget->rowCount() );
532  for ( int i = 0; i < 2; i++ )
533  {
534  double value = i == 0 ? min : max;
535  QLineEdit *lineEdit = new QLineEdit();
536  lineEdit->setFrame( false );
537  lineEdit->setContentsMargins( 1, 1, 1, 1 );
538  QString valueString;
539  switch ( mRasterLayer->dataProvider()->srcDataType( 1 ) )
540  {
541  case QGis::Float32:
542  case QGis::Float64:
543  lineEdit->setValidator( new QDoubleValidator( 0 ) );
544  if ( !qIsNaN( value ) )
545  {
546  valueString = QgsRasterBlock::printValue( value );
547  }
548  break;
549  default:
550  lineEdit->setValidator( new QIntValidator( 0 ) );
551  if ( !qIsNaN( value ) )
552  {
553  valueString = QString::number( static_cast<int>( value ) );
554  }
555  break;
556  }
557  lineEdit->setText( valueString );
558  mNoDataTableWidget->setCellWidget( mNoDataTableWidget->rowCount() - 1, i, lineEdit );
559 
560  adjustNoDataCellWidth( mNoDataTableWidget->rowCount() - 1, i );
561 
562  connect( lineEdit, SIGNAL( textEdited( const QString & ) ), this, SLOT( noDataCellTextEdited( const QString & ) ) );
563  }
564  mNoDataTableWidget->resizeColumnsToContents();
565  mNoDataTableWidget->resizeRowsToContents();
566 }
567 
568 void QgsRasterLayerSaveAsDialog::noDataCellTextEdited( const QString & text )
569 {
570  Q_UNUSED( text );
571 
572  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( sender() );
573  if ( !lineEdit ) return;
574  int row = -1;
575  int column = -1;
576  for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
577  {
578  for ( int c = 0 ; c < mNoDataTableWidget->columnCount(); c++ )
579  {
580  if ( mNoDataTableWidget->cellWidget( r, c ) == sender() )
581  {
582  row = r;
583  column = c;
584  break;
585  }
586  }
587  if ( row != -1 ) break;
588  }
589  QgsDebugMsg( QString( "row = %1 column =%2" ).arg( row ).arg( column ) );
590 
591  if ( column == 0 )
592  {
593  QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, 1 ) );
594  if ( !toLineEdit ) return;
595  bool toChanged = mNoDataToEdited.value( row );
596  QgsDebugMsg( QString( "toChanged = %1" ).arg( toChanged ) );
597  if ( !toChanged )
598  {
599  toLineEdit->setText( lineEdit->text() );
600  }
601  }
602  else if ( column == 1 )
603  {
604  setNoDataToEdited( row );
605  }
606 }
607 
608 void QgsRasterLayerSaveAsDialog::on_mTileModeCheckBox_toggled( bool toggled )
609 {
610  if ( toggled )
611  {
612  // enable pyramids
613 
614  // Disabled (Radim), auto enabling of pyramids was making impression that
615  // we (programmers) know better what you (user) want to do,
616  // certainly auto expaning was bad experience
617 
618  //if ( ! mPyramidsGroupBox->isChecked() )
619  // mPyramidsGroupBox->setChecked( true );
620 
621  // Auto expanding mPyramidsGroupBox is bad - it auto crolls content of dialog
622  //if ( mPyramidsGroupBox->isCollapsed() )
623  // mPyramidsGroupBox->setCollapsed( false );
624  //mPyramidsOptionsWidget->checkAllLevels( true );
625 
626  // Show / hide tile options
627  mTilesGroupBox->show();
628  }
629  else
630  {
631  mTilesGroupBox->hide();
632  }
633 }
634 
635 void QgsRasterLayerSaveAsDialog::on_mPyramidsGroupBox_toggled( bool toggled )
636 {
637  Q_UNUSED( toggled );
638  populatePyramidsLevels();
639 }
640 
641 void QgsRasterLayerSaveAsDialog::populatePyramidsLevels()
642 {
643  QString text;
644 
645  if ( mPyramidsGroupBox->isChecked() )
646  {
647  QList<QgsRasterPyramid> myPyramidList;
648  // if use existing, get pyramids from actual layer
649  // but that's not available yet
650  if ( mPyramidsUseExistingCheckBox->isChecked() )
651  {
652  myPyramidList = mDataProvider->buildPyramidList();
653  }
654  else
655  {
656  if ( ! mPyramidsOptionsWidget->overviewList().isEmpty() )
657  myPyramidList = mDataProvider->buildPyramidList( mPyramidsOptionsWidget->overviewList() );
658  }
659  QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
660  for ( myRasterPyramidIterator = myPyramidList.begin();
661  myRasterPyramidIterator != myPyramidList.end();
662  ++myRasterPyramidIterator )
663  {
664  if ( ! mPyramidsUseExistingCheckBox->isChecked() || myRasterPyramidIterator->exists )
665  {
666  text += QString::number( myRasterPyramidIterator->xDim ) + QString( "x" ) +
667  QString::number( myRasterPyramidIterator->yDim ) + " ";
668  }
669  }
670  }
671 
672  mPyramidResolutionsLineEdit->setText( text.trimmed() );
673 }
674 
675 void QgsRasterLayerSaveAsDialog::setNoDataToEdited( int row )
676 {
677  if ( row >= mNoDataToEdited.size() )
678  {
679  mNoDataToEdited.resize( row + 1 );
680  }
681  mNoDataToEdited[row] = true;
682 }
683 
684 double QgsRasterLayerSaveAsDialog::noDataCellValue( int row, int column ) const
685 {
686  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
687  if ( !lineEdit || lineEdit->text().isEmpty() )
688  {
689  std::numeric_limits<double>::quiet_NaN();
690  }
691  return lineEdit->text().toDouble();
692 }
693 
694 void QgsRasterLayerSaveAsDialog::adjustNoDataCellWidth( int row, int column )
695 {
696  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
697  if ( !lineEdit ) return;
698 
699  int width = qMax( lineEdit->fontMetrics().width( lineEdit->text() ) + 10, 100 );
700  width = qMax( width, mNoDataTableWidget->columnWidth( column ) );
701 
702  lineEdit->setFixedWidth( width );
703 }
704 
706 {
707  QgsRasterRangeList noDataList;
708  if ( ! mNoDataGroupBox->isChecked() )
709  return noDataList;
710 
711  for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
712  {
713  QgsRasterRange noData( noDataCellValue( r, 0 ), noDataCellValue( r, 1 ) );
714  noDataList.append( noData );
715 
716  }
717  return noDataList;
718 }
719 
721 {
722  return mPyramidsGroupBox->isChecked() ? mPyramidsOptionsWidget->overviewList() : QList<int>();
723 }
724 
726 {
727  if ( ! mPyramidsGroupBox->isChecked() )
729  else if ( mPyramidsUseExistingCheckBox->isChecked() )
731  else
733 }
734 
735 bool QgsRasterLayerSaveAsDialog::validate() const
736 {
737  if ( mCreateOptionsGroupBox->isChecked() )
738  {
739  QString message = mCreateOptionsWidget->validateOptions( true, false );
740  if ( !message.isNull() )
741  return false;
742  }
743  if ( mPyramidsGroupBox->isChecked() )
744  {
745  QString message = mPyramidsOptionsWidget->createOptionsWidget()->validateOptions( true, false );
746  if ( !message.isNull() )
747  return false;
748  }
749  return true;
750 }
751