25 #include <QInputDialog>
26 #include <QMessageBox>
28 #include <QMouseEvent>
32 QMap< QString, QStringList > QgsRasterFormatSaveOptionsWidget::mBuiltinProfiles;
36 : QWidget( parent ), mFormat( format ), mProvider( provider ), mRasterLayer( 0 ),
37 mRasterFileName( QString() ), mPyramids( false ),
38 mPyramidsFormat(
QgsRaster::PyramidsGTiff )
45 if ( mBuiltinProfiles.isEmpty() )
48 mBuiltinProfiles[
"z_adefault" ] = ( QStringList() <<
"" <<
tr(
"Default" ) <<
"" );
53 mBuiltinProfiles[
"z_gtiff_1big" ] =
54 ( QStringList() <<
"GTiff" <<
tr(
"No compression" )
55 <<
"COMPRESS=NONE BIGTIFF=IF_NEEDED" );
56 mBuiltinProfiles[
"z_gtiff_2medium" ] =
57 ( QStringList() <<
"GTiff" <<
tr(
"Low compression" )
58 <<
"COMPRESS=PACKBITS" );
59 mBuiltinProfiles[
"z_gtiff_3small" ] =
60 ( QStringList() <<
"GTiff" <<
tr(
"High compression" )
61 <<
"COMPRESS=DEFLATE PREDICTOR=2 ZLEVEL=9" );
62 mBuiltinProfiles[
"z_gtiff_4jpeg" ] =
63 ( QStringList() <<
"GTiff" <<
tr(
"JPEG compression" )
64 <<
"COMPRESS=JPEG JPEG_QUALITY=75" );
69 mBuiltinProfiles[
"z__pyramids_gtiff_1big" ] =
70 ( QStringList() <<
"_pyramids" <<
tr(
"No compression" )
71 <<
"COMPRESS_OVERVIEW=NONE BIGTIFF_OVERVIEW=IF_NEEDED" );
72 mBuiltinProfiles[
"z__pyramids_gtiff_2medium" ] =
73 ( QStringList() <<
"_pyramids" <<
tr(
"Low compression" )
74 <<
"COMPRESS_OVERVIEW=PACKBITS" );
75 mBuiltinProfiles[
"z__pyramids_gtiff_3small" ] =
76 ( QStringList() <<
"_pyramids" <<
tr(
"High compression" )
77 <<
"COMPRESS_OVERVIEW=DEFLATE PREDICTOR_OVERVIEW=2 ZLEVEL=9" );
78 mBuiltinProfiles[
"z__pyramids_gtiff_4jpeg" ] =
79 ( QStringList() <<
"_pyramids" <<
tr(
"JPEG compression" )
80 <<
"JPEG_QUALITY_OVERVIEW=75 COMPRESS_OVERVIEW=JPEG PHOTOMETRIC_OVERVIEW=YCBCR INTERLEAVE_OVERVIEW=PIXEL" );
83 connect( mProfileComboBox, SIGNAL( currentIndexChanged(
const QString & ) ),
84 this, SLOT( updateOptions() ) );
85 connect( mOptionsTable, SIGNAL( cellChanged(
int,
int ) ),
this, SLOT( optionsTableChanged() ) );
86 connect( mOptionsHelpButton, SIGNAL( clicked() ),
this, SLOT(
helpOptions() ) );
87 connect( mOptionsValidateButton, SIGNAL( clicked() ),
this, SLOT(
validateOptions() ) );
91 mOptionsLineEdit->installEventFilter(
this );
92 mOptionsStackedWidget->installEventFilter(
this );
113 mProvider = provider;
120 QList< QWidget* > widgets = this->findChildren<QWidget *>();
124 foreach ( QWidget* widget, widgets )
125 widget->setVisible(
false );
126 mOptionsStackedWidget->setVisible(
true );
127 foreach ( QWidget* widget, mOptionsStackedWidget->findChildren<QWidget *>() )
128 widget->setVisible(
true );
139 foreach ( QWidget* widget, widgets )
140 widget->setVisible(
true );
142 mProfileButtons->setVisible(
false );
153 QString format = mPyramids ?
"_pyramids" : mFormat;
154 QStringList profileKeys = profiles();
155 QMapIterator<QString, QStringList> it( mBuiltinProfiles );
156 while ( it.hasNext() )
159 QString profileKey = it.key();
160 if ( ! profileKeys.contains( profileKey ) && it.value().count() > 0 )
163 if ( it.value()[0] ==
"" || it.value()[0] == format )
165 profileKeys.insert( 0, profileKey );
169 qSort( profileKeys );
173 mProfileComboBox->blockSignals(
true );
174 mProfileComboBox->clear();
175 foreach ( QString profileKey, profileKeys )
177 QString profileName, profileOptions;
178 profileOptions = createOptions( profileKey );
179 if ( mBuiltinProfiles.contains( profileKey ) )
181 profileName = mBuiltinProfiles[ profileKey ][ 1 ];
182 if ( profileOptions.isEmpty() )
183 profileOptions = mBuiltinProfiles[ profileKey ][ 2 ];
187 profileName = profileKey;
189 mOptionsMap[ profileKey ] = profileOptions;
190 mProfileComboBox->addItem( profileName, profileKey );
194 mProfileComboBox->blockSignals(
false );
196 QSettings mySettings;
197 mProfileComboBox->setCurrentIndex( mProfileComboBox->findData( mySettings.value(
198 mProvider +
"/driverOptions/" + format.toLower() +
"/defaultProfile",
203 void QgsRasterFormatSaveOptionsWidget::updateOptions()
205 QString myOptions = mOptionsMap.value( currentProfileKey() );
206 QStringList myOptionsList = myOptions.trimmed().split(
" ", QString::SkipEmptyParts );
208 if ( mOptionsStackedWidget->currentIndex() == 0 )
210 mOptionsTable->setRowCount( 0 );
211 for (
int i = 0; i < myOptionsList.count(); i++ )
213 QStringList key_value = myOptionsList[i].split(
"=" );
214 if ( key_value.count() == 2 )
216 mOptionsTable->insertRow( i );
217 mOptionsTable->setItem( i, 0,
new QTableWidgetItem( key_value[0] ) );
218 mOptionsTable->setItem( i, 1,
new QTableWidgetItem( key_value[1] ) );
224 mOptionsLineEdit->setText( myOptions );
225 mOptionsLineEdit->setCursorPosition( 0 );
244 if ( mProvider ==
"gdal" && mFormat !=
"" && ! mPyramids )
252 if ( helpCreationOptionsFormat )
254 message = helpCreationOptionsFormat( mFormat );
258 message = library->fileName() +
" does not have helpCreationOptionsFormat";
262 message = QString(
"cannot load provider library %1" ).arg( mProvider );
265 if ( message.isEmpty() )
266 message =
tr(
"Cannot get create options for driver %1" ).arg( mFormat );
268 else if ( mProvider ==
"gdal" && mPyramids )
270 message =
tr(
"For details on pyramids options please see the following pages" );
271 message +=
"\n\nhttp://www.gdal.org/gdaladdo.html\n\nhttp://www.gdal.org/frmt_gtiff.html";
274 message =
tr(
"No help available" );
278 QTextEdit *textEdit =
new QTextEdit( dlg );
279 textEdit->setReadOnly(
true );
281 textEdit->setText( message );
282 dlg->
layout()->addWidget( textEdit );
283 dlg->resize( 600, 400 );
293 QStringList createOptions =
options();
296 QgsDebugMsg( QString(
"layer: [%1] file: [%2] format: [%3]" ).arg( mRasterLayer ? mRasterLayer->
id() :
"none" ).arg( mRasterFileName ).arg( mFormat ) );
300 bool tmpLayer =
false;
301 if ( !( mRasterLayer && rasterLayer->
dataProvider() ) && ! mRasterFileName.isNull() )
307 QString defaultProjectionOption = settings.value(
"/Projections/defaultBehaviour",
"prompt" ).toString();
308 if ( settings.value(
"/Projections/defaultBehaviour",
"prompt" ).toString() ==
"prompt" )
310 settings.setValue(
"/Projections/defaultBehaviour",
"useProject" );
313 rasterLayer =
new QgsRasterLayer( mRasterFileName, QFileInfo( mRasterFileName ).baseName(), QString(
"gdal" ) );
315 if ( defaultProjectionOption ==
"prompt" )
317 settings.setValue(
"/Projections/defaultBehaviour", defaultProjectionOption );
321 if ( mProvider ==
"gdal" && mPyramids )
323 if ( rasterLayer && rasterLayer->dataProvider() )
325 QgsDebugMsg(
"calling validate pyramids on layer's data provider" );
326 message = rasterLayer->dataProvider()->validatePyramidsConfigOptions( mPyramidsFormat, createOptions, mFormat );
330 message =
tr(
"cannot validate pyramid options" );
333 else if ( !createOptions.isEmpty() && mProvider ==
"gdal" && mFormat !=
"" )
335 if ( rasterLayer && rasterLayer->dataProvider() )
337 QgsDebugMsg(
"calling validate on layer's data provider" );
338 message = rasterLayer->dataProvider()->validateCreationOptions( createOptions, mFormat );
348 if ( validateCreationOptionsFormat )
350 message = validateCreationOptionsFormat( createOptions, mFormat );
354 message = library->fileName() +
" does not have validateCreationOptionsFormat";
358 message = QString(
"cannot load provider library %1" ).arg( mProvider );
361 else if ( ! createOptions.isEmpty() )
363 QMessageBox::information(
this,
"",
tr(
"Cannot validate creation options" ), QMessageBox::Close );
371 if ( message.isNull() )
374 QMessageBox::information(
this,
"",
tr(
"Valid" ), QMessageBox::Close );
378 QMessageBox::warning(
this,
"",
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" ) ).arg( message ), QMessageBox::Close );
388 void QgsRasterFormatSaveOptionsWidget::optionsTableChanged()
390 QTableWidgetItem *key, *value;
392 for (
int i = 0 ; i < mOptionsTable->rowCount(); i++ )
394 key = mOptionsTable->item( i, 0 );
395 if ( ! key || key->text().isEmpty() )
397 value = mOptionsTable->item( i, 1 );
398 if ( ! value || value->text().isEmpty() )
400 options += key->text() +
"=" + value->text() +
" ";
402 options = options.trimmed();
403 mOptionsMap[ currentProfileKey()] =
options;
404 mOptionsLineEdit->setText( options );
405 mOptionsLineEdit->setCursorPosition( 0 );
408 void QgsRasterFormatSaveOptionsWidget::on_mOptionsLineEdit_editingFinished()
410 mOptionsMap[ currentProfileKey()] = mOptionsLineEdit->text().trimmed();
413 void QgsRasterFormatSaveOptionsWidget::on_mProfileNewButton_clicked()
415 QString profileName = QInputDialog::getText(
this,
"",
tr(
"Profile name:" ) );
416 if ( ! profileName.isEmpty() )
418 profileName = profileName.trimmed();
419 mOptionsMap[ profileName ] =
"";
420 mProfileComboBox->addItem( profileName, profileName );
421 mProfileComboBox->setCurrentIndex( mProfileComboBox->count() - 1 );
425 void QgsRasterFormatSaveOptionsWidget::on_mProfileDeleteButton_clicked()
427 int index = mProfileComboBox->currentIndex();
428 QString profileKey = currentProfileKey();
429 if ( index != -1 && ! mBuiltinProfiles.contains( profileKey ) )
431 mOptionsMap.remove( profileKey );
432 mProfileComboBox->removeItem( index );
436 void QgsRasterFormatSaveOptionsWidget::on_mProfileResetButton_clicked()
438 QString profileKey = currentProfileKey();
439 if ( mBuiltinProfiles.contains( profileKey ) )
441 mOptionsMap[ profileKey ] = mBuiltinProfiles[ profileKey ][ 2 ];
445 mOptionsMap[ profileKey ] =
"";
447 mOptionsLineEdit->setText( mOptionsMap.value( currentProfileKey() ) );
448 mOptionsLineEdit->setCursorPosition( 0 );
452 void QgsRasterFormatSaveOptionsWidget::optionsTableEnableDeleteButton()
454 mOptionsDeleteButton->setEnabled( mOptionsTable->currentRow() >= 0 );
457 void QgsRasterFormatSaveOptionsWidget::on_mOptionsAddButton_clicked()
459 mOptionsTable->insertRow( mOptionsTable->rowCount() );
461 int newRow = mOptionsTable->rowCount() - 1;
462 QTableWidgetItem* item =
new QTableWidgetItem();
463 mOptionsTable->setItem( newRow, 0, item );
464 mOptionsTable->setCurrentItem( item );
467 void QgsRasterFormatSaveOptionsWidget::on_mOptionsDeleteButton_clicked()
469 if ( mOptionsTable->currentRow() >= 0 )
471 mOptionsTable->removeRow( mOptionsTable->currentRow() );
473 QTableWidgetItem* item = mOptionsTable->item( mOptionsTable->currentRow(), 0 );
474 mOptionsTable->setCurrentItem( item );
475 optionsTableChanged();
480 QString QgsRasterFormatSaveOptionsWidget::settingsKey( QString profileName )
const
482 if ( profileName !=
"" )
483 profileName =
"/profile_" + profileName;
485 profileName =
"/profile_default" + profileName;
486 return mProvider +
"/driverOptions/" + mFormat.toLower() + profileName +
"/create";
489 QString QgsRasterFormatSaveOptionsWidget::currentProfileKey()
const
491 return mProfileComboBox->itemData( mProfileComboBox->currentIndex() ).toString();
496 return mOptionsMap.value( currentProfileKey() ).trimmed().split(
" ", QString::SkipEmptyParts );
499 QString QgsRasterFormatSaveOptionsWidget::createOptions( QString profileName )
const
501 QSettings mySettings;
502 return mySettings.value( settingsKey( profileName ),
"" ).toString();
505 void QgsRasterFormatSaveOptionsWidget::deleteCreateOptions( QString profileName )
507 QSettings mySettings;
508 mySettings.remove( settingsKey( profileName ) );
511 void QgsRasterFormatSaveOptionsWidget::setCreateOptions()
513 QSettings mySettings;
515 QMap< QString, QString >::iterator i = mOptionsMap.begin();
516 while ( i != mOptionsMap.end() )
518 setCreateOptions( i.key(), i.value() );
519 myProfiles += i.key() + QString(
" " );
522 mySettings.setValue( mProvider +
"/driverOptions/" + mFormat.toLower() +
"/profiles",
523 myProfiles.trimmed() );
524 mySettings.setValue( mProvider +
"/driverOptions/" + mFormat.toLower() +
"/defaultProfile",
525 currentProfileKey().trimmed() );
528 void QgsRasterFormatSaveOptionsWidget::setCreateOptions( QString profileName, QString options )
530 QSettings mySettings;
531 mySettings.setValue( settingsKey( profileName ), options.trimmed() );
534 void QgsRasterFormatSaveOptionsWidget::setCreateOptions( QString profileName, QStringList list )
536 setCreateOptions( profileName, list.join(
" " ) );
539 QStringList QgsRasterFormatSaveOptionsWidget::profiles()
const
541 QSettings mySettings;
542 return mySettings.value( mProvider +
"/driverOptions/" + mFormat.toLower() +
"/profiles",
"" ).toString().trimmed().split(
" ", QString::SkipEmptyParts );
545 void QgsRasterFormatSaveOptionsWidget::swapOptionsUI(
int newIndex )
549 if ( newIndex == -1 )
551 oldIndex = mOptionsStackedWidget->currentIndex();
552 newIndex = ( oldIndex + 1 ) % 2;
556 oldIndex = ( newIndex + 1 ) % 2;
560 mOptionsStackedWidget->setCurrentIndex( newIndex );
561 mOptionsStackedWidget->widget( newIndex )->setSizePolicy(
562 QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) );
563 mOptionsStackedWidget->widget( oldIndex )->setSizePolicy(
564 QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ) );
565 layout()->activate();
570 void QgsRasterFormatSaveOptionsWidget::updateControls()
572 bool valid = mProvider ==
"gdal" && mFormat !=
"";
573 mOptionsValidateButton->setEnabled( valid );
574 mOptionsHelpButton->setEnabled( valid );
578 bool QgsRasterFormatSaveOptionsWidget::eventFilter( QObject *obj, QEvent *event )
580 if ( event->type() == QEvent::MouseButtonPress )
582 QMouseEvent *mouseEvent =
static_cast<QMouseEvent *
>( event );
583 if ( mouseEvent && ( mouseEvent->button() == Qt::RightButton ) )
587 if ( mOptionsStackedWidget->currentIndex() == 0 )
588 text =
tr(
"Use simple interface" );
590 text =
tr(
"Use table interface" );
591 if ( obj->objectName() ==
"mOptionsLineEdit" )
593 menu = mOptionsLineEdit->createStandardContextMenu();
594 menu->addSeparator();
597 menu =
new QMenu(
this );
598 QAction* action =
new QAction( text, menu );
599 menu->addAction( action );
600 connect( action, SIGNAL( triggered() ),
this, SLOT( swapOptionsUI() ) );
601 menu->exec( mouseEvent->globalPos() );
607 return QObject::eventFilter( obj, event );
613 mOptionsTable->horizontalHeader()->resizeSection( 0, mOptionsTable->width() - 115 );