161 changes: 158 additions & 3 deletions src/gui/qgsrasterlayersaveasdialog.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgscoordinatetransform.h"
#include "qgsrasterlayer.h"
#include "qgsrasterlayersaveasdialog.h"
#include "qgsrasterdataprovider.h"
#include "qgsrasterformatsaveoptionswidget.h"
Expand All @@ -9,7 +10,6 @@
#include <QFileDialog>
#include <QSettings>


// this widget class will go into its separate file

// #include <QMouseEvent>
Expand Down Expand Up @@ -112,11 +112,12 @@ void GroupBox::setCollapsed( bool collapse )
emit expanded( this );
}

QgsRasterLayerSaveAsDialog::QgsRasterLayerSaveAsDialog( QgsRasterDataProvider* sourceProvider, const QgsRectangle& currentExtent,
QgsRasterLayerSaveAsDialog::QgsRasterLayerSaveAsDialog( QgsRasterLayer* rasterLayer, QgsRasterDataProvider* sourceProvider, const QgsRectangle& currentExtent,
const QgsCoordinateReferenceSystem& layerCrs,
const QgsCoordinateReferenceSystem& currentCrs,
QWidget* parent, Qt::WindowFlags f ):
QDialog( parent, f )
, mRasterLayer( rasterLayer )
, mDataProvider( sourceProvider )
, mCurrentExtent( currentExtent )
, mLayerCrs( layerCrs )
Expand All @@ -129,7 +130,12 @@ QgsRasterLayerSaveAsDialog::QgsRasterLayerSaveAsDialog( QgsRasterDataProvider* s
mLoadTransparentNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionCopySelected.png" ) );
mRemoveSelectedNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) );
mRemoveAllNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionRemove.png" ) );
// mNoDataGroupBox->setEnabled( false ); // not yet implemented

mNoDataTableWidget->setColumnCount( 2 );
mNoDataTableWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( tr( "From" ) ) );
mNoDataTableWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( tr( "To" ) ) );

on_mRawModeRadioButton_toggled( true );

setValidators();
// Translated labels + EPSG are updated later
Expand Down Expand Up @@ -602,3 +608,152 @@ QgsRasterLayerSaveAsDialog::Mode QgsRasterLayerSaveAsDialog::mode() const
if ( mRenderedModeRadioButton->isChecked() ) return RenderedImageMode;
return RawDataMode;
}

void QgsRasterLayerSaveAsDialog::on_mRawModeRadioButton_toggled( bool checked )
{
mNoDataGroupBox->setEnabled( checked && mDataProvider->bandCount() == 1 );
}

void QgsRasterLayerSaveAsDialog::on_mAddNoDataManuallyToolButton_clicked()
{
addNoDataRow( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
}

void QgsRasterLayerSaveAsDialog::on_mLoadTransparentNoDataToolButton_clicked()
{
if ( !mRasterLayer->renderer() ) return;
const QgsRasterTransparency* rasterTransparency = mRasterLayer->renderer()->rasterTransparency();
if ( !rasterTransparency ) return;

foreach ( QgsRasterTransparency::TransparentSingleValuePixel transparencyPixel, rasterTransparency->transparentSingleValuePixelList() )
{
if ( transparencyPixel.percentTransparent == 100 )
{
addNoDataRow( transparencyPixel.min, transparencyPixel.max );
if ( transparencyPixel.min != transparencyPixel.max )
{
setNoDataToEdited( mNoDataTableWidget->rowCount() - 1 );
}
}
}
}

void QgsRasterLayerSaveAsDialog::on_mRemoveSelectedNoDataToolButton_clicked()
{
mNoDataTableWidget->removeRow( mNoDataTableWidget->currentRow() );
}

void QgsRasterLayerSaveAsDialog::on_mRemoveAllNoDataToolButton_clicked()
{
while ( mNoDataTableWidget->rowCount() > 0 )
{
mNoDataTableWidget->removeRow( 0 );
}
}

void QgsRasterLayerSaveAsDialog::addNoDataRow( double min, double max )
{
mNoDataTableWidget->insertRow( mNoDataTableWidget->rowCount() );
for ( int i = 0; i < 2; i++ )
{
double value = i == 0 ? min : max;
QLineEdit *lineEdit = new QLineEdit();
lineEdit->setFrame( false );
lineEdit->setContentsMargins( 1, 1, 1, 1 );
QString valueString;
switch ( mRasterLayer->dataProvider()->srcDataType( 1 ) )
{
case QgsRasterInterface::Float32:
case QgsRasterInterface::Float64:
lineEdit->setValidator( new QDoubleValidator( 0 ) );
if ( !qIsNaN( value ) )
{
valueString = QString::number( value, 'f' );
}
break;
default:
lineEdit->setValidator( new QIntValidator( 0 ) );
if ( !qIsNaN( value ) )
{
valueString = QString::number( static_cast<int>( value ) );
}
break;
}
lineEdit->setText( valueString );
mNoDataTableWidget->setCellWidget( mNoDataTableWidget->rowCount() - 1, i, lineEdit );

connect( lineEdit, SIGNAL( textEdited( const QString & ) ), this, SLOT( noDataCellTextEdited( const QString & ) ) );
}
mNoDataTableWidget->resizeColumnsToContents();
mNoDataTableWidget->resizeRowsToContents();
}

void QgsRasterLayerSaveAsDialog::noDataCellTextEdited( const QString & text )
{
QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( sender() );
if ( !lineEdit ) return;
int row = -1;
int column = -1;
for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
{
for ( int c = 0 ; c < mNoDataTableWidget->columnCount(); c++ )
{
if ( mNoDataTableWidget->cellWidget( r, c ) == sender() )
{
row = r;
column = c;
break;
}
}
if ( row != -1 ) break;
}
QgsDebugMsg( QString( "row = %1 column =%2" ).arg( row ).arg( column ) );

if ( column == 0 )
{
QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, 1 ) );
if ( !toLineEdit ) return;
bool toChanged = mNoDataToEdited.value( row );
QgsDebugMsg( QString( "toChanged = %1" ).arg( toChanged ) );
if ( !toChanged )
{
toLineEdit->setText( lineEdit->text() );
}
}
else if ( column == 1 )
{
setNoDataToEdited( row );
}
}

void QgsRasterLayerSaveAsDialog::setNoDataToEdited( int row )
{
if ( row >= mNoDataToEdited.size() )
{
mNoDataToEdited.resize( row + 1 );
}
mNoDataToEdited[row] = true;
}

double QgsRasterLayerSaveAsDialog::noDataCellValue( int row, int column ) const
{
QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
if ( !lineEdit || lineEdit->text().isEmpty() )
{
std::numeric_limits<double>::quiet_NaN();
}
return lineEdit->text().toDouble();
}

QList<QgsRasterNuller::NoData> QgsRasterLayerSaveAsDialog::noData() const
{
QList<QgsRasterNuller::NoData> noDataList;
for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
{
QgsRasterNuller::NoData noData;
noData.min = noDataCellValue( r, 0 );
noData.max = noDataCellValue( r, 1 );
noDataList.append( noData );
}
return noDataList;
}
17 changes: 16 additions & 1 deletion src/gui/qgsrasterlayersaveasdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include "ui_qgsrasterlayersaveasdialogbase.h"
#include "qgsrectangle.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsrasternuller.h"

class QgsRasterLayer;
class QgsRasterDataProvider;
class QgsRasterFormatOptionsWidget;

Expand Down Expand Up @@ -35,7 +37,7 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
UserResolution
};

QgsRasterLayerSaveAsDialog( QgsRasterDataProvider* sourceProvider, const QgsRectangle& currentExtent, const QgsCoordinateReferenceSystem& layerCrs, const QgsCoordinateReferenceSystem& currentCrs, QWidget* parent = 0, Qt::WindowFlags f = 0 );
QgsRasterLayerSaveAsDialog( QgsRasterLayer* rasterLayer, QgsRasterDataProvider* sourceProvider, const QgsRectangle& currentExtent, const QgsCoordinateReferenceSystem& layerCrs, const QgsCoordinateReferenceSystem& currentCrs, QWidget* parent = 0, Qt::WindowFlags f = 0 );
~QgsRasterLayerSaveAsDialog();

Mode mode() const;
Expand All @@ -51,11 +53,13 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
QgsCoordinateReferenceSystem outputCrs();
QStringList createOptions() const;
QgsRectangle outputRectangle() const;
QList<QgsRasterNuller::NoData> noData() const;

void hideFormat();
void hideOutput();

private slots:
void on_mRawModeRadioButton_toggled( bool );
void on_mBrowseButton_clicked();
void on_mSaveAsLineEdit_textChanged( const QString& text );
void on_mCurrentExtentButton_clicked();
Expand All @@ -80,8 +84,14 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
void on_mCrsComboBox_currentIndexChanged( int ) { crsChanged(); }

void groupBoxExpanded( QWidget * widget ) { mScrollArea->ensureWidgetVisible( widget ); }
void on_mAddNoDataManuallyToolButton_clicked();
void on_mLoadTransparentNoDataToolButton_clicked();
void on_mRemoveSelectedNoDataToolButton_clicked();
void on_mRemoveAllNoDataToolButton_clicked();
void noDataCellTextEdited( const QString & text );

private:
QgsRasterLayer* mRasterLayer;
QgsRasterDataProvider* mDataProvider;
QgsRectangle mCurrentExtent;
QgsCoordinateReferenceSystem mLayerCrs; // may differ from provider CRS
Expand All @@ -90,6 +100,7 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
QgsCoordinateReferenceSystem mPreviousCrs;
ExtentState mExtentState;
ResolutionState mResolutionState;
QVector<bool> mNoDataToEdited;

void setValidators();
void setOutputExtent( const QgsRectangle& r, const QgsCoordinateReferenceSystem& srcCrs, ExtentState state );
Expand All @@ -105,6 +116,10 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
void recalcResolutionSize();
void crsChanged();
void updateCrsGroup();

void addNoDataRow( double min, double max );
void setNoDataToEdited( int row );
double noDataCellValue( int row, int column ) const;
};


Expand Down
5 changes: 4 additions & 1 deletion src/ui/qgsrasterlayersaveasdialogbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@
<string>Additional no data values. The specified values will be set to no data in output raster.</string>
</property>
<property name="title">
<string>No data values (not yet implemented)</string>
<string>No data values</string>
</property>
<property name="checkable">
<bool>true</bool>
Expand Down Expand Up @@ -457,6 +457,9 @@
</item>
<item row="2" column="0">
<widget class="QToolButton" name="mLoadTransparentNoDataToolButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Load user defined fully transparent (100%) values </string>
</property>
Expand Down