18 changes: 11 additions & 7 deletions python/core/qgsvectorfilewriter.sip
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class QgsVectorFileWriter
@param newFilename QString pointer which will contain the new file name created (in case it is different to fileName).
@param symbologyExport symbology to export
@param symbologyScale scale of symbology
@param filterExtent if not a null pointer, only features intersecting the extent will be saved
*/
static WriterError writeAsVectorFormat( QgsVectorLayer* layer,
const QString& fileName,
Expand All @@ -136,22 +137,25 @@ class QgsVectorFileWriter
bool skipAttributeCreation = false, // added in 1.6
QString *newFilename = 0, // added in 1.9
SymbologyExport symbologyExport = NoSymbology, //added in 2.0
double symbologyScale = 1.0 // added in 2.0
double symbologyScale = 1.0, // added in 2.0
const QgsRectangle* filterExtent = 0 // added in 2.4
);

//! @note added in v2.2
static WriterError writeAsVectorFormat( QgsVectorLayer* layer,
const QString& fileName,
const QString& fileEncoding,
const QgsCoordinateTransform* ct,
const QString& driverName = "ESRI Shapefile",
bool onlySelected = false,
QString *errorMessage = 0,
const QStringList &datasourceOptions = QStringList(), // added in 1.6
const QStringList &layerOptions = QStringList(), // added in 1.6
bool skipAttributeCreation = false, // added in 1.6
QString *newFilename = 0, // added in 1.9
SymbologyExport symbologyExport = NoSymbology, //added in 2.0
double symbologyScale = 1.0 // added in 2.0
const QStringList &datasourceOptions = QStringList(),
const QStringList &layerOptions = QStringList(),
bool skipAttributeCreation = false,
QString *newFilename = 0,
SymbologyExport symbologyExport = NoSymbology,
double symbologyScale = 1.0,
const QgsRectangle* filterExtent = 0 // added in 2.4
);

/** create shapefile and initialize it */
Expand Down
3 changes: 2 additions & 1 deletion python/gui/qgisinterface.sip
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,8 @@ class QgisInterface : QObject
/** @note added in 1.9 */
virtual QAction *actionCancelAllEdits() = 0;
virtual QAction *actionLayerSaveAs() = 0;
virtual QAction *actionLayerSelectionSaveAs() = 0;
/** @note deprecated in 2.4 - returns null pointer */
virtual QAction *actionLayerSelectionSaveAs() = 0 /Deprecated/;
virtual QAction *actionRemoveLayer() = 0;
/** @note added in 1.9 */
virtual QAction *actionDuplicateLayer() = 0;
Expand Down
7 changes: 0 additions & 7 deletions src/app/legend/qgslegendlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,13 +436,6 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu )
// save as vector file
theMenu.addAction( tr( "Save As..." ), QgisApp::instance(), SLOT( saveAsFile() ) );

// save selection as vector file
QAction* saveSelectionAsAction = theMenu.addAction( tr( "Save Selection As..." ), QgisApp::instance(), SLOT( saveSelectionAsVectorFile() ) );
if ( vlayer->selectedFeatureCount() == 0 )
{
saveSelectionAsAction->setEnabled( false );
}

if ( !vlayer->isEditable() && vlayer->dataProvider()->supportsSubsetString() && vlayer->vectorJoins().isEmpty() )
theMenu.addAction( tr( "&Filter..." ), QgisApp::instance(), SLOT( layerSubsetString() ) );

Expand Down
50 changes: 49 additions & 1 deletion src/app/ogr/qgsvectorlayersaveasdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, QWidget* par
setup();
}

QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, int options, QWidget* parent, Qt::WFlags fl )
QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, const QgsRectangle& layerExtent, bool layerHasSelectedFeatures, int options, QWidget* parent, Qt::WFlags fl )
: QDialog( parent, fl )
, mCRS( srsid )
, mLayerExtent( layerExtent )
{
setup();
if ( !( options & Symbology ) )
Expand All @@ -44,6 +45,8 @@ QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, int options,
mScaleLabel->hide();
mScaleSpinBox->hide();
}

mSelectedOnly->setEnabled( layerHasSelectedFeatures );
}

void QgsVectorLayerSaveAsDialog::setup()
Expand Down Expand Up @@ -87,6 +90,14 @@ void QgsVectorLayerSaveAsDialog::setup()
mSymbologyExportComboBox->addItem( tr( "Feature symbology" ), QgsVectorFileWriter::FeatureSymbology );
mSymbologyExportComboBox->addItem( tr( "Symbol layer symbology" ), QgsVectorFileWriter::SymbolLayerSymbology );
on_mSymbologyExportComboBox_currentIndexChanged( mSymbologyExportComboBox->currentText() );

// extent group box
mExtentGroupBox->setOutputCrs( srs );
mExtentGroupBox->setOriginalExtent( mLayerExtent, srs );
mExtentGroupBox->setOutputExtentFromOriginal();
mExtentGroupBox->setCheckable( true );
mExtentGroupBox->setChecked( false );
mExtentGroupBox->setCollapsed( true );
}

QList<QPair<QLabel*, QWidget*> > QgsVectorLayerSaveAsDialog::createControls( const QMap<QString, QgsVectorFileWriter::Option*>& options )
Expand Down Expand Up @@ -175,6 +186,21 @@ void QgsVectorLayerSaveAsDialog::accept()
void QgsVectorLayerSaveAsDialog::on_mCRSSelection_currentIndexChanged( int idx )
{
leCRS->setEnabled( idx == 2 );

QgsCoordinateReferenceSystem crs;
if ( mCRSSelection->currentIndex() == 0 )
{
crs = mLayerCrs;
}
else if ( mCRSSelection->currentIndex() == 1 )
{
crs = mExtentGroupBox->currentCrs();
}
else // custom CRS
{
crs.createFromId( mCRS, QgsCoordinateReferenceSystem::InternalCrsId );
}
mExtentGroupBox->setOutputCrs( crs );
}

void QgsVectorLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( int idx )
Expand Down Expand Up @@ -284,6 +310,8 @@ void QgsVectorLayerSaveAsDialog::on_browseCRS_clicked()
mCRS = srs.srsid();
leCRS->setText( srs.description() );
mCRSSelection->setCurrentIndex( 2 );

mExtentGroupBox->setOutputCrs( srs );
}

delete mySelector;
Expand Down Expand Up @@ -441,6 +469,26 @@ double QgsVectorLayerSaveAsDialog::scaleDenominator() const
return mScaleSpinBox->value();
}

void QgsVectorLayerSaveAsDialog::setCanvasExtent( const QgsRectangle& canvasExtent, const QgsCoordinateReferenceSystem& canvasCrs )
{
mExtentGroupBox->setCurrentExtent( canvasExtent, canvasCrs );
}

bool QgsVectorLayerSaveAsDialog::hasFilterExtent() const
{
return mExtentGroupBox->isChecked();
}

QgsRectangle QgsVectorLayerSaveAsDialog::filterExtent() const
{
return mExtentGroupBox->outputExtent();
}

bool QgsVectorLayerSaveAsDialog::onlySelected() const
{
return mSelectedOnly->isChecked();
}

void QgsVectorLayerSaveAsDialog::on_mSymbologyExportComboBox_currentIndexChanged( const QString& text )
{
bool scaleEnabled = true;
Expand Down
13 changes: 12 additions & 1 deletion src/app/ogr/qgsvectorlayersaveasdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSav
};

QgsVectorLayerSaveAsDialog( long srsid, QWidget* parent = 0, Qt::WFlags fl = 0 );
QgsVectorLayerSaveAsDialog( long srsid, int options = AllOptions, QWidget* parent = 0, Qt::WFlags fl = 0 );
QgsVectorLayerSaveAsDialog( long srsid, const QgsRectangle& layerExtent, bool layerHasSelectedFeatures, int options = AllOptions, QWidget* parent = 0, Qt::WFlags fl = 0 );
~QgsVectorLayerSaveAsDialog();

QString format() const;
Expand All @@ -57,6 +57,14 @@ class QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSav
int symbologyExport() const;
double scaleDenominator() const;

//! setup canvas extent - for the use in extent group box
void setCanvasExtent( const QgsRectangle& canvasExtent, const QgsCoordinateReferenceSystem& canvasCrs );

bool hasFilterExtent() const;
QgsRectangle filterExtent() const;

bool onlySelected() const;

private slots:
void on_mFormatComboBox_currentIndexChanged( int idx );
void on_mCRSSelection_currentIndexChanged( int idx );
Expand All @@ -71,6 +79,9 @@ class QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSav
QList< QPair< QLabel*, QWidget* > > createControls( const QMap<QString, QgsVectorFileWriter::Option*>& options );

long mCRS;

QgsRectangle mLayerExtent;
QgsCoordinateReferenceSystem mLayerCrs;
};

#endif // QGSVECTORLAYERSAVEASDIALOG_H
25 changes: 10 additions & 15 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,6 @@ void QgisApp::createActions()
connect( mActionCancelEdits, SIGNAL( triggered() ), this, SLOT( cancelEdits() ) );
connect( mActionCancelAllEdits, SIGNAL( triggered() ), this, SLOT( cancelAllEdits() ) );
connect( mActionLayerSaveAs, SIGNAL( triggered() ), this, SLOT( saveAsFile() ) );
connect( mActionLayerSelectionSaveAs, SIGNAL( triggered() ), this, SLOT( saveSelectionAsVectorFile() ) );
connect( mActionRemoveLayer, SIGNAL( triggered() ), this, SLOT( removeLayer() ) );
connect( mActionDuplicateLayer, SIGNAL( triggered() ), this, SLOT( duplicateLayers() ) );
connect( mActionSetLayerCRS, SIGNAL( triggered() ), this, SLOT( setLayerCRS() ) );
Expand Down Expand Up @@ -4571,16 +4570,11 @@ void QgisApp::saveAsFile()
}
else if ( layerType == QgsMapLayer::VectorLayer )
{
saveAsVectorFileGeneral( false );
saveAsVectorFileGeneral();
}
}

void QgisApp::saveSelectionAsVectorFile()
{
saveAsVectorFileGeneral( true );
}

void QgisApp::saveAsVectorFileGeneral( bool saveOnlySelection, QgsVectorLayer* vlayer, bool symbologyOption )
void QgisApp::saveAsVectorFileGeneral( QgsVectorLayer* vlayer, bool symbologyOption )
{
if ( !mMapLegend )
return;
Expand All @@ -4601,7 +4595,9 @@ void QgisApp::saveAsVectorFileGeneral( bool saveOnlySelection, QgsVectorLayer* v
options &= ~QgsVectorLayerSaveAsDialog::Symbology;
}

QgsVectorLayerSaveAsDialog *dialog = new QgsVectorLayerSaveAsDialog( vlayer->crs().srsid(), options, this );
QgsVectorLayerSaveAsDialog *dialog = new QgsVectorLayerSaveAsDialog( vlayer->crs().srsid(), vlayer->extent(), vlayer->selectedFeatureCount() != 0, options, this );

dialog->setCanvasExtent( mMapCanvas->mapSettings().visibleExtent(), mMapCanvas->mapSettings().destinationCrs() );

if ( dialog->exec() == QDialog::Accepted )
{
Expand Down Expand Up @@ -4659,15 +4655,17 @@ void QgisApp::saveAsVectorFileGeneral( bool saveOnlySelection, QgsVectorLayer* v
QgsVectorFileWriter::WriterError error;
QString errorMessage;
QString newFilename;
QgsRectangle filterExtent = dialog->filterExtent();
error = QgsVectorFileWriter::writeAsVectorFormat(
vlayer, vectorFilename, encoding, ct, format,
saveOnlySelection,
dialog->onlySelected(),
&errorMessage,
datasourceOptions, dialog->layerOptions(),
dialog->skipAttributeCreation(),
&newFilename,
( QgsVectorFileWriter::SymbologyExport )( dialog->symbologyExport() ),
dialog->scaleDenominator() );
dialog->scaleDenominator(),
dialog->hasFilterExtent() ? &filterExtent : 0 );

delete ct;

Expand Down Expand Up @@ -5677,7 +5675,7 @@ void QgisApp::pasteAsNewVector()
if ( !layer )
return;

saveAsVectorFileGeneral( false, layer, false );
saveAsVectorFileGeneral( layer, false );

delete layer;
}
Expand Down Expand Up @@ -8301,7 +8299,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionToggleEditing->setChecked( false );
mActionSaveLayerEdits->setEnabled( false );
mActionLayerSaveAs->setEnabled( false );
mActionLayerSelectionSaveAs->setEnabled( false );
mActionLayerProperties->setEnabled( false );
mActionLayerSubsetString->setEnabled( false );
mActionAddToOverview->setEnabled( false );
Expand Down Expand Up @@ -8398,7 +8395,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionSelectByExpression->setEnabled( true );
mActionOpenTable->setEnabled( true );
mActionLayerSaveAs->setEnabled( true );
mActionLayerSelectionSaveAs->setEnabled( true );
mActionCopyFeatures->setEnabled( layerHasSelection );
mActionFeatureAction->setEnabled( layerHasActions );

Expand Down Expand Up @@ -8567,7 +8563,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionUndo->setEnabled( false );
mActionRedo->setEnabled( false );
mActionLayerSaveAs->setEnabled( true );
mActionLayerSelectionSaveAs->setEnabled( false );
mActionAddFeature->setEnabled( false );
mActionDeleteSelected->setEnabled( false );
mActionAddRing->setEnabled( false );
Expand Down
4 changes: 1 addition & 3 deletions src/app/qgisapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
/** @note added in 1.9 */
QAction *actionCancelAllEdits() { return mActionCancelAllEdits; }
QAction *actionLayerSaveAs() { return mActionLayerSaveAs; }
QAction *actionLayerSelectionSaveAs() { return mActionLayerSelectionSaveAs; }
QAction *actionRemoveLayer() { return mActionRemoveLayer; }
/** @note added in 1.9 */
QAction *actionDuplicateLayer() { return mActionDuplicateLayer; }
Expand Down Expand Up @@ -1085,7 +1084,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow

//! save current vector layer
void saveAsFile();
void saveSelectionAsVectorFile();

//! save current raster layer
void saveAsRasterFile();
Expand Down Expand Up @@ -1258,7 +1256,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
/**Deletes all the composer objects and clears mPrintComposers*/
void deletePrintComposers();

void saveAsVectorFileGeneral( bool saveOnlySelection, QgsVectorLayer* vlayer = 0, bool symbologyOption = true );
void saveAsVectorFileGeneral( QgsVectorLayer* vlayer = 0, bool symbologyOption = true );

/** Paste features from clipboard into a new memory layer.
* If no features are in clipboard an empty layer is returned.
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgisappinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ QAction *QgisAppInterface::actionRollbackAllEdits() { return qgis->actionRollbac
QAction *QgisAppInterface::actionCancelEdits() { return qgis->actionCancelEdits(); }
QAction *QgisAppInterface::actionCancelAllEdits() { return qgis->actionCancelAllEdits(); }
QAction *QgisAppInterface::actionLayerSaveAs() { return qgis->actionLayerSaveAs(); }
QAction *QgisAppInterface::actionLayerSelectionSaveAs() { return qgis->actionLayerSelectionSaveAs(); }
QAction *QgisAppInterface::actionLayerSelectionSaveAs() { return 0; }
QAction *QgisAppInterface::actionRemoveLayer() { return qgis->actionRemoveLayer(); }
QAction *QgisAppInterface::actionDuplicateLayer() { return qgis->actionDuplicateLayer(); }
QAction *QgisAppInterface::actionLayerProperties() { return qgis->actionLayerProperties(); }
Expand Down
23 changes: 14 additions & 9 deletions src/core/qgsvectorfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1791,7 +1791,8 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
bool skipAttributeCreation,
QString *newFilename,
SymbologyExport symbologyExport,
double symbologyScale )
double symbologyScale,
const QgsRectangle* filterExtent )
{
QgsCoordinateTransform* ct = 0;
if ( destCRS && layer )
Expand All @@ -1800,7 +1801,7 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
}

QgsVectorFileWriter::WriterError error = writeAsVectorFormat( layer, fileName, fileEncoding, ct, driverName, onlySelected,
errorMessage, datasourceOptions, layerOptions, skipAttributeCreation, newFilename, symbologyExport, symbologyScale );
errorMessage, datasourceOptions, layerOptions, skipAttributeCreation, newFilename, symbologyExport, symbologyScale, filterExtent );
delete ct;
return error;
}
Expand All @@ -1812,13 +1813,13 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::writeAsVectorFormat( QgsVe
const QString& driverName,
bool onlySelected,
QString *errorMessage,
const QStringList &datasourceOptions, // added in 1.6
const QStringList &layerOptions, // added in 1.6
bool skipAttributeCreation, // added in 1.6
QString *newFilename, // added in 1.9
SymbologyExport symbologyExport, //added in 2.0
double symbologyScale // added in 2.0
)
const QStringList &datasourceOptions,
const QStringList &layerOptions,
bool skipAttributeCreation,
QString *newFilename,
SymbologyExport symbologyExport,
double symbologyScale,
const QgsRectangle* filterExtent )
{
if ( !layer )
{
Expand Down Expand Up @@ -1960,6 +1961,10 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::writeAsVectorFormat( QgsVe
return ErrProjection;
}
}

if ( fet.geometry() && filterExtent && !fet.geometry()->intersects( *filterExtent ) )
continue;

if ( allAttr.size() < 1 && skipAttributeCreation )
{
fet.initAttributes( 0 );
Expand Down
Loading