Skip to content

Commit

Permalink
QgsVectorLayerSaveAsDialog: add checkboxes to decide which fields sho…
Browse files Browse the repository at this point in the history
…uld be exported with their displayed values, and bind it in QgisApp with QgsVectorFileWriter
  • Loading branch information
rouault committed May 14, 2016
1 parent 038b3b7 commit 90cc0ed
Show file tree
Hide file tree
Showing 6 changed files with 415 additions and 16 deletions.
210 changes: 200 additions & 10 deletions src/app/ogr/qgsvectorlayersaveasdialog.cpp
Expand Up @@ -20,22 +20,32 @@
#include "qgsgenericprojectionselector.h"
#include "qgsvectordataprovider.h"
#include "qgscoordinatereferencesystem.h"
#include "qgseditorwidgetfactory.h"
#include "qgseditorwidgetregistry.h"

#include <QSettings>
#include <QFileDialog>
#include <QTextCodec>

static const int COLUMN_IDX_NAME = 0;
static const int COLUMN_IDX_TYPE = 1;
static const int COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE = 2;

QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, QWidget* parent, Qt::WindowFlags fl )
: QDialog( parent, fl )
, mCRS( srsid )
, mLayer( 0 )
, mAttributeTableItemChangedSlotEnabled( true )
, mReplaceRawFieldValuesStateChangedSlotEnabled( true )
{
setup();
}

QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( QgsVectorLayer *layer, int options, QWidget* parent, Qt::WindowFlags fl )
: QDialog( parent, fl )
, mLayer( layer )
, mAttributeTableItemChangedSlotEnabled( true )
, mReplaceRawFieldValuesStateChangedSlotEnabled( true )
{
if ( layer )
{
Expand Down Expand Up @@ -234,23 +244,70 @@ void QgsVectorLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( int idx
if ( mLayer )
{
mAttributeTable->setRowCount( mLayer->fields().count() );
mAttributeTable->setColumnCount( 2 );
mAttributeTable->setHorizontalHeaderLabels( QStringList() << tr( "Name" ) << tr( "Type" ) );

int i = 0;
Q_FOREACH ( const QgsField &fld, mLayer->fields() )
bool foundFieldThatCanBeExportedAsDisplayedValue = false;
for ( int i = 0; i < mLayer->fields().size(); ++i )
{
QgsEditorWidgetFactory *factory;
if ( mLayer->editFormConfig()->widgetType( i ) != "TextEdit" &&
( factory = QgsEditorWidgetRegistry::instance()->factory( mLayer->editFormConfig()->widgetType( i ) ) ) )
{
foundFieldThatCanBeExportedAsDisplayedValue = true;
break;
}
}
if ( foundFieldThatCanBeExportedAsDisplayedValue )
{
mAttributeTable->setColumnCount( 3 );
mAttributeTable->setHorizontalHeaderLabels( QStringList() << tr( "Name" ) << tr( "Type" ) << tr( "Replace with displayed values" ) );
}
else
{
mAttributeTable->setColumnCount( 2 );
mAttributeTable->setHorizontalHeaderLabels( QStringList() << tr( "Name" ) << tr( "Type" ) );
mReplaceRawFieldValues->setVisible( false );
}

mAttributeTableItemChangedSlotEnabled = false;

for ( int i = 0; i < mLayer->fields().size(); ++i )
{
const QgsField &fld = mLayer->fields().at( i );
Qt::ItemFlags flags = mLayer->providerType() != "oracle" || !fld.typeName().contains( "SDO_GEOMETRY" ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
QTableWidgetItem *item;
item = new QTableWidgetItem( fld.name() );
item->setFlags( flags | Qt::ItemIsUserCheckable );
item->setCheckState( Qt::Unchecked );
mAttributeTable->setItem( i, 0, item );
mAttributeTable->setItem( i, COLUMN_IDX_NAME, item );

item = new QTableWidgetItem( fld.typeName() );
item->setFlags( flags );
mAttributeTable->setItem( i++, 1, item );
mAttributeTable->setItem( i, COLUMN_IDX_TYPE, item );

if ( foundFieldThatCanBeExportedAsDisplayedValue )
{
QgsEditorWidgetFactory *factory;
if ( mLayer->editFormConfig()->widgetType( i ) != "TextEdit" &&
( factory = QgsEditorWidgetRegistry::instance()->factory( mLayer->editFormConfig()->widgetType( i ) ) ) )
{
item = new QTableWidgetItem( tr( "Use %1" ).arg( factory->name() ) );
item->setFlags( Qt::ItemIsUserCheckable );
item->setCheckState( Qt::Unchecked );
mAttributeTable->setItem( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE, item );
}
else
{
item = new QTableWidgetItem();
item->setFlags( Qt::NoItemFlags );
mAttributeTable->setItem( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE, item );
}
}
}

mAttributeTableItemChangedSlotEnabled = true;

mReplaceRawFieldValues->setEnabled( false );

mAttributeTable->resizeColumnsToContents();
}

Expand Down Expand Up @@ -311,6 +368,92 @@ void QgsVectorLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( int idx
}
}

void QgsVectorLayerSaveAsDialog::on_mReplaceRawFieldValues_stateChanged( int )
{
if ( !mReplaceRawFieldValuesStateChangedSlotEnabled )
return;
if ( mAttributeTable->columnCount() != 3 )
return;
mReplaceRawFieldValuesStateChangedSlotEnabled = false;
mAttributeTableItemChangedSlotEnabled = false;
if ( mReplaceRawFieldValues->checkState() != Qt::PartiallyChecked )
{
for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
{
if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->checkState() == Qt::Checked &&
mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsEnabled )
{
mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setCheckState( mReplaceRawFieldValues->checkState() );
}
}
}
mReplaceRawFieldValues->setTristate( false );
mAttributeTableItemChangedSlotEnabled = true;
mReplaceRawFieldValuesStateChangedSlotEnabled = true;
}

void QgsVectorLayerSaveAsDialog::on_mAttributeTable_itemChanged( QTableWidgetItem * item )
{
if ( !mAttributeTableItemChangedSlotEnabled )
return;
mReplaceRawFieldValuesStateChangedSlotEnabled = false;
mAttributeTableItemChangedSlotEnabled = false;
int row = item->row();
int column = item->column();
if ( column == COLUMN_IDX_NAME &&
mAttributeTable->item( row, column )->checkState() == Qt::Unchecked &&
mAttributeTable->columnCount() == 3 &&
mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
( mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
{
mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setCheckState( Qt::Unchecked );
mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable );
bool checkBoxEnabled = false;
for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
{
if ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsEnabled )
{
checkBoxEnabled = true;
break;
}
}
mReplaceRawFieldValues->setEnabled( checkBoxEnabled );
if ( !checkBoxEnabled )
mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
}
else if ( column == COLUMN_IDX_NAME &&
mAttributeTable->item( row, column )->checkState() == Qt::Checked &&
mAttributeTable->columnCount() == 3 &&
mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
( mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
{
mAttributeTable->item( row, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
mReplaceRawFieldValues->setEnabled( true );
}
else if ( column == COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE &&
( mAttributeTable->item( row, column )->flags() & Qt::ItemIsUserCheckable ) )
{
bool allChecked = true;
bool allUnchecked = true;
for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
{
if ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE ) &&
mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsEnabled )
{
if ( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->checkState() == Qt::Unchecked )
allChecked = false;
else
allUnchecked = false;
}
}
mReplaceRawFieldValues->setCheckState(( !allChecked && !allUnchecked ) ? Qt::PartiallyChecked : ( allChecked ) ? Qt::Checked : Qt::Unchecked );
}
mAttributeTableItemChangedSlotEnabled = true;
mReplaceRawFieldValuesStateChangedSlotEnabled = true;
}

void QgsVectorLayerSaveAsDialog::on_leFilename_textChanged( const QString& text )
{
buttonBox->button( QDialogButtonBox::Ok )->setEnabled( QFileInfo( text ).absoluteDir().exists() );
Expand Down Expand Up @@ -469,7 +612,24 @@ QgsAttributeList QgsVectorLayerSaveAsDialog::selectedAttributes() const

for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
{
if ( mAttributeTable->item( i, 0 )->checkState() == Qt::Checked )
if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->checkState() == Qt::Checked )
{
attributes.append( i );
}
}

return attributes;
}

QgsAttributeList QgsVectorLayerSaveAsDialog::attributesAsDisplayedValues() const
{
QgsAttributeList attributes;

for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
{
if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->checkState() == Qt::Checked &&
mAttributeTable->columnCount() == 3 &&
mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->checkState() == Qt::Checked )
{
attributes.append( i );
}
Expand Down Expand Up @@ -572,17 +732,47 @@ void QgsVectorLayerSaveAsDialog::on_mGeometryTypeComboBox_currentIndexChanged( i

void QgsVectorLayerSaveAsDialog::on_mSelectAllAttributes_clicked()
{
mAttributeTableItemChangedSlotEnabled = false;
mReplaceRawFieldValuesStateChangedSlotEnabled = false;
for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
{
if ( mAttributeTable->item( i, 0 )->flags() & Qt::ItemIsEnabled )
mAttributeTable->item( i, 0 )->setCheckState( Qt::Checked );
if ( mAttributeTable->item( i, COLUMN_IDX_NAME )->flags() & Qt::ItemIsEnabled )
{
if ( mAttributeTable->columnCount() == 3 &&
( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
{
mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
}
mAttributeTable->item( i, COLUMN_IDX_NAME )->setCheckState( Qt::Checked );
}
}
if ( mAttributeTable->columnCount() == 3 )
{
mReplaceRawFieldValues->setEnabled( true );
}
mAttributeTableItemChangedSlotEnabled = true;
mReplaceRawFieldValuesStateChangedSlotEnabled = true;
}

void QgsVectorLayerSaveAsDialog::on_mDeselectAllAttributes_clicked()
{
mAttributeTableItemChangedSlotEnabled = false;
mReplaceRawFieldValuesStateChangedSlotEnabled = false;
for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
{
mAttributeTable->item( i, 0 )->setCheckState( Qt::Unchecked );
mAttributeTable->item( i, COLUMN_IDX_NAME )->setCheckState( Qt::Unchecked );
if ( mAttributeTable->columnCount() == 3 &&
( mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->flags() & Qt::ItemIsUserCheckable ) )
{
mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setFlags( Qt::ItemIsUserCheckable );
mAttributeTable->item( i, COLUMN_IDX_EXPORT_AS_DISPLAYED_VALUE )->setCheckState( Qt::Unchecked );
}
}
if ( mAttributeTable->columnCount() == 3 )
{
mReplaceRawFieldValues->setCheckState( Qt::Unchecked );
mReplaceRawFieldValues->setEnabled( false );
}
mAttributeTableItemChangedSlotEnabled = true;
mReplaceRawFieldValuesStateChangedSlotEnabled = true;
}
11 changes: 9 additions & 2 deletions src/app/ogr/qgsvectorlayersaveasdialog.h
Expand Up @@ -24,9 +24,9 @@
#include "qgsvectorfilewriter.h"

/**
* Class to select destination file, type and CRS for ogr layrs
* Class to select destination file, type and CRS for ogr layers
*/
class QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSaveAsDialogBase
class APP_EXPORT QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSaveAsDialogBase
{
Q_OBJECT

Expand All @@ -50,6 +50,8 @@ class QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSav
long crs() const;
bool attributeSelection() const;
QgsAttributeList selectedAttributes() const;
/** Return selected attributes that must be exported with their displayed values instead of their raw values. Added in QGIS 2.16 */
QgsAttributeList attributesAsDisplayedValues() const;
bool addToCanvas() const;
/** Returns type of symbology export.
0: No symbology
Expand Down Expand Up @@ -97,6 +99,7 @@ class QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSav
void setIncludeZ( bool checked );

private slots:

void on_mFormatComboBox_currentIndexChanged( int idx );
void on_leFilename_textChanged( const QString& text );
void on_browseFilename_clicked();
Expand All @@ -107,6 +110,8 @@ class QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSav
void accept() override;
void on_mSelectAllAttributes_clicked();
void on_mDeselectAllAttributes_clicked();
void on_mReplaceRawFieldValues_stateChanged( int state );
void on_mAttributeTable_itemChanged( QTableWidgetItem * item );

private:
void setup();
Expand All @@ -117,6 +122,8 @@ class QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSav
QgsRectangle mLayerExtent;
QgsCoordinateReferenceSystem mLayerCrs;
QgsVectorLayer *mLayer;
bool mAttributeTableItemChangedSlotEnabled;
bool mReplaceRawFieldValuesStateChangedSlotEnabled;
};

#endif // QGSVECTORLAYERSAVEASDIALOG_H

0 comments on commit 90cc0ed

Please sign in to comment.