Skip to content
Permalink
Browse files
QgsVectorLayerSaveAsDialog: add checkboxes to decide which fields sho…
…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.
@@ -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 )
{
@@ -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();
}

@@ -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() );
@@ -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 );
}
@@ -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;
}
@@ -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

@@ -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
@@ -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();
@@ -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();
@@ -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.