diff --git a/python/core/qgsvectordataprovider.sip b/python/core/qgsvectordataprovider.sip index cce0156eb98..c02a8e5c318 100644 --- a/python/core/qgsvectordataprovider.sip +++ b/python/core/qgsvectordataprovider.sip @@ -296,4 +296,7 @@ class QgsVectorDataProvider : QgsDataProvider (e.g. no multipolygon in a polygon layer) @note: added in version 1.4*/ bool doesStrictFeatureTypeCheck() const; + + /** Returns a list of available encodings */ + static const QStringList &availableEncodings(); }; diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index f72b00e4e20..ef2dbeb41d9 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -105,6 +105,7 @@ SET(QGIS_APP_SRCS ogr/qgsopenvectorlayerdialog.cpp ogr/qgsnewogrconnection.cpp ogr/qgsogrsublayersdialog.cpp + ogr/qgsvectorlayersaveasdialog.cpp attributetable/qgsattributetabledialog.cpp attributetable/qgsattributetablemodel.cpp @@ -199,6 +200,7 @@ SET (QGIS_APP_MOC_HDRS ogr/qgsopenvectorlayerdialog.h ogr/qgsnewogrconnection.h ogr/qgsogrsublayersdialog.h + ogr/qgsvectorlayersaveasdialog.h attributetable/qgsattributetableview.h attributetable/qgsattributetablemodel.h diff --git a/src/app/legend/qgslegendlayer.cpp b/src/app/legend/qgslegendlayer.cpp index d51938ca7a0..b0f2afb639b 100644 --- a/src/app/legend/qgslegendlayer.cpp +++ b/src/app/legend/qgslegendlayer.cpp @@ -36,7 +36,7 @@ #include "qgsvectorfilewriter.h" #include "qgsgenericprojectionselector.h" #include "qgsattributetabledialog.h" -#include "qgsencodingfiledialog.h" +#include "ogr/qgsvectorlayersaveasdialog.h" #include "qgsrendererv2.h" #include "qgssymbolv2.h" @@ -53,6 +53,7 @@ #include #include #include +#include QgsLegendLayer::QgsLegendLayer( QgsMapLayer* layer ) @@ -450,16 +451,6 @@ void QgsLegendLayer::table() // the dialog will be deleted by itself on close } -void QgsLegendLayer::saveAsShapefile() -{ - saveAsShapefileGeneral( FALSE ); -} - -void QgsLegendLayer::saveSelectionAsShapefile() -{ - saveAsShapefileGeneral( TRUE ); -} - void QgsLegendLayer::saveAsVectorFile() { saveAsVectorFileGeneral( false ); @@ -503,83 +494,6 @@ void QgsLegendLayer::showInOverview() } void QgsLegendLayer::saveAsVectorFileGeneral( bool saveOnlySelection ) -{ - if ( mLyr.layer()->type() != QgsMapLayer::VectorLayer ) - return; - - QgsVectorLayer* vlayer = qobject_cast( mLyr.layer() ); - - //get output name and format - QSettings settings; - QString filter = QString( "Shapefiles (*.shp)" ); - QString dirName = settings.value( "/UI/lastVectorfileDir", "." ).toString(); - QString filterString = QgsVectorFileWriter::fileFilterString(); - QString selectedFilter = settings.value( "/UI/lastVectorFilter", "[OGR] ESRI Shapefiles (*.shp *.SHP)" ).toString(); - QString outputFile = QFileDialog::getSaveFileName( 0, tr( "Save layer as..." ), dirName, filterString, &selectedFilter ); - if ( outputFile.isNull() ) - { - return; //cancelled - } - - settings.setValue( "/UI/lastVectorfileDir", QFileInfo( outputFile ).absolutePath() ); - settings.setValue( "/UI/lastVectorFilter", selectedFilter ); - - QMap< QString, QString> filterDriverMap = QgsVectorFileWriter::supportedFiltersAndFormats(); - QMap< QString, QString>::const_iterator it = filterDriverMap.find( selectedFilter + ";;" ); - if ( it == filterDriverMap.constEnd() ) - { - return; //unknown format - } - - QString driverKey = *it; - - //output CRS - QgsCoordinateReferenceSystem destCRS = vlayer->srs(); - // Find out if we have projections enabled or not - if ( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() ) - { - destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs(); - } - - QgsGenericProjectionSelector * mySelector = new QgsGenericProjectionSelector(); - mySelector->setSelectedCrsId( destCRS.srsid() ); - mySelector->setMessage( tr( "Select the coordinate reference system for the saved shapefile. " - "The data points will be transformed from the layer coordinate reference system." ) ); - - if ( mySelector->exec() ) - { - QgsCoordinateReferenceSystem srs( mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId ); - destCRS = srs; - // destCRS->createFromId(mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId) - } - else - { - // Aborted CS selection, don't save. - delete mySelector; - return; - } - delete mySelector; - - // overwrite the file - user will already have been prompted - // to verify they want to overwrite by the file dialog above - // might not even exists in the given case. - if ( driverKey == "ESRI Shapefile" ) - { - // add the extension if not present - if ( !outputFile.endsWith( ".shp", Qt::CaseInsensitive ) ) - { - outputFile += ".shp"; - } - QgsVectorFileWriter::deleteShapeFile( outputFile ); - } - - QString errorMessage; - QgsVectorFileWriter::WriterError error; - error = QgsVectorFileWriter::writeAsVectorFormat( vlayer, outputFile, "utf-8", &destCRS, driverKey, saveOnlySelection, &errorMessage ); -} - - -void QgsLegendLayer::saveAsShapefileGeneral( bool saveOnlySelection ) { QgsCoordinateReferenceSystem destCRS; @@ -588,93 +502,66 @@ void QgsLegendLayer::saveAsShapefileGeneral( bool saveOnlySelection ) QgsVectorLayer* vlayer = qobject_cast( mLyr.layer() ); - // get a name for the shapefile - // Get a file to process, starting at the current directory - QSettings settings; - QString filter = QString( "Shapefiles (*.shp)" ); - QString dirName = settings.value( "/UI/lastShapefileDir", "." ).toString(); + QgsVectorLayerSaveAsDialog *dialog = new QgsVectorLayerSaveAsDialog( QgisApp::instance() ); - QgsEncodingFileDialog* openFileDialog = new QgsEncodingFileDialog( 0, - tr( "Save layer as..." ), - dirName, - filter, - QString( "" ) ); - openFileDialog->setAcceptMode( QFileDialog::AcceptSave ); - - // allow for selection of more than one file - //openFileDialog->setMode(QFileDialog::AnyFile); - - if ( openFileDialog->exec() != QDialog::Accepted ) - return; - - - QString encoding = openFileDialog->encoding(); - QString shapefileName = openFileDialog->selectedFiles().first(); - settings.setValue( "/UI/lastShapefileDir", QFileInfo( shapefileName ).absolutePath() ); - - - if ( shapefileName.isNull() ) - return; - - // add the extension if not present - if ( !shapefileName.endsWith( ".shp", Qt::CaseInsensitive ) ) + if( dialog->exec() == QDialog::Accepted ) { - shapefileName += ".shp"; + QString encoding = dialog->encoding(); + QString vectorFilename = dialog->filename(); + QString format = dialog->format(); + + if( dialog->crs() < 0 ) + { + // Find out if we have projections enabled or not + if ( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() ) + { + destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs(); + } + else + { + destCRS = vlayer->srs(); + } + } + else + { + destCRS = QgsCoordinateReferenceSystem( dialog->crs(), QgsCoordinateReferenceSystem::InternalCrsId ); + } + + // overwrite the file - user will already have been prompted + // to verify they want to overwrite by the file dialog above + // might not even exists in the given case. + // add the extension if not present + if( format == "ESRI Shapefile" ) + { + if ( !vectorFilename.endsWith( ".shp", Qt::CaseInsensitive ) ) + { + vectorFilename += ".shp"; + } + QgsVectorFileWriter::deleteShapeFile( vectorFilename ); + } + + // ok if the file existed it should be deleted now so we can continue... + QApplication::setOverrideCursor( Qt::WaitCursor ); + + QgsVectorFileWriter::WriterError error; + QString errorMessage; + error = QgsVectorFileWriter::writeAsVectorFormat( vlayer, vectorFilename, encoding, &destCRS, format, saveOnlySelection, &errorMessage ); + + QApplication::restoreOverrideCursor(); + + if ( error == QgsVectorFileWriter::NoError ) + { + QMessageBox::information( 0, tr( "Saving done" ), tr( "Export to vector file has been completed" ) ); + } + else + { + QMessageBox::warning( 0, tr( "Save error" ), tr( "Export to vector file failed.\nError: %1").arg( errorMessage ) ); + } } - destCRS = vlayer->srs(); - // Find out if we have projections enabled or not - if ( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() ) - { - destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs(); - } - - QgsGenericProjectionSelector * mySelector = new QgsGenericProjectionSelector(); - mySelector->setSelectedCrsId( destCRS.srsid() ); - mySelector->setMessage( tr( "Select the coordinate reference system for the saved shapefile. " - "The data points will be transformed from the layer coordinate reference system." ) ); - - if ( mySelector->exec() ) - { - QgsCoordinateReferenceSystem srs( mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId ); - destCRS = srs; - // destCRS->createFromId(mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId) - } - else - { - // Aborted CS selection, don't save. - delete mySelector; - return; - } - - delete mySelector; - - // overwrite the file - user will already have been prompted - // to verify they want to overwrite by the file dialog above - // might not even exists in the given case. - QgsVectorFileWriter::deleteShapeFile( shapefileName ); - - // ok if the file existed it should be deleted now so we can continue... - QApplication::setOverrideCursor( Qt::WaitCursor ); - - QgsVectorFileWriter::WriterError error; - QString errorMessage; - error = QgsVectorFileWriter::writeAsShapefile( vlayer, shapefileName, encoding, &destCRS, saveOnlySelection, &errorMessage ); - - QApplication::restoreOverrideCursor(); - - if ( error == QgsVectorFileWriter::NoError ) - { - QMessageBox::information( 0, tr( "Saving done" ), tr( "Export to Shapefile has been completed" ) ); - } - else - { - QMessageBox::warning( 0, tr( "Save error" ), errorMessage ); - } + delete dialog; } - - QString QgsLegendLayer::nameFromLayer( QgsMapLayer* layer ) { QString sourcename = layer->publicSource(); //todo: move this duplicated code into a new function diff --git a/src/app/legend/qgslegendlayer.h b/src/app/legend/qgslegendlayer.h index 1075b040504..c67a882f55f 100644 --- a/src/app/legend/qgslegendlayer.h +++ b/src/app/legend/qgslegendlayer.h @@ -1,6 +1,6 @@ /*************************************************************************** - * Copyright (C) 2005 by Tim Sutton * - * aps02ts@macbuntu * + * Copyright (C) 2005 by Tim Sutton * + * aps02ts@macbuntu * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -84,9 +84,6 @@ class QgsLegendLayer : public QgsLegendItem /**Show layer attribute table*/ void table(); - void saveAsShapefile(); - void saveSelectionAsShapefile(); - void saveAsVectorFile(); void saveSelectionAsVectorFile(); @@ -111,9 +108,6 @@ class QgsLegendLayer : public QgsLegendItem QPixmap getOriginalPixmap(); - /**Save as shapefile (called from saveAsShapefile and saveSelectionAsShapefile)*/ - void saveAsShapefileGeneral( bool saveOnlySelection ); - void saveAsVectorFileGeneral( bool saveOnlySelection ); private: diff --git a/src/app/ogr/qgsopenvectorlayerdialog.cpp b/src/app/ogr/qgsopenvectorlayerdialog.cpp index 3b9b7a0908a..86f61852a85 100644 --- a/src/app/ogr/qgsopenvectorlayerdialog.cpp +++ b/src/app/ogr/qgsopenvectorlayerdialog.cpp @@ -22,9 +22,11 @@ #include #include #include + #include "qgslogger.h" -#include "qgsencodingfiledialog.h" #include "qgsopenvectorlayerdialog.h" +#include "qgsvectordataprovider.h" + #include #include "qgsproviderregistry.h" #include "qgsnewogrconnection.h" @@ -40,8 +42,10 @@ QgsOpenVectorLayerDialog::QgsOpenVectorLayerDialog( QWidget* parent, Qt::WFlags cmbConnections->blockSignals( true ); radioSrcFile->setChecked( true ); mDataSourceType = "file"; + //set encoding - // cmbEncodings->setItemText( cmbEncodings->currentIndex(), QString( QTextCodec::codecForLocale()->name() ) ); + cmbEncodings->addItems( QgsVectorDataProvider::availableEncodings() ); + QSettings settings; QString enc = settings.value( "/UI/encoding", QString( "System" ) ).toString(); diff --git a/src/app/ogr/qgsvectorlayersaveasdialog.cpp b/src/app/ogr/qgsvectorlayersaveasdialog.cpp new file mode 100644 index 00000000000..42f451ea859 --- /dev/null +++ b/src/app/ogr/qgsvectorlayersaveasdialog.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** + qgsvectorlayersaveasdialog.h + Dialog to select destination, type and crs for ogr layers + ------------------- + begin : Mon Mar 22 2010 + copyright : (C) 2010 by Juergen E. Fischer + email : jef at norbit dot de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +/* $Id:$ */ +#include "qgsvectorlayersaveasdialog.h" +#include "qgsgenericprojectionselector.h" +#include "qgsvectordataprovider.h" +#include "qgsvectorfilewriter.h" + +#include +#include +#include + +QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( QWidget* parent, Qt::WFlags fl ) + : QDialog( parent, fl ) + , mCRS( -1 ) +{ + setupUi( this ); + + QSettings settings; + QMap map = QgsVectorFileWriter::ogrDriverList(); + for ( QMap< QString, QString>::const_iterator it = map.constBegin(); it != map.constEnd(); ++it ) + { + mFormatComboBox->addItem( it.key(), it.value() ); + } + + QString format = settings.value( "/UI/lastVectorFormat", "ESRI Shapefile" ).toString(); + mFormatComboBox->setCurrentIndex( mFormatComboBox->findData( format ) ); + + + mEncodingComboBox->addItems( QgsVectorDataProvider::availableEncodings() ); + + QString enc = settings.value( "/UI/encoding", QString( "System" ) ).toString(); + int idx = mEncodingComboBox->findText( enc ); + if ( idx < 0 ) + { + mEncodingComboBox->insertItem( 0, enc ); + idx = 0; + } + + mEncodingComboBox->setCurrentIndex( idx ); + + leCRS->setText( tr("Original CRS") ); +} + +QgsVectorLayerSaveAsDialog::~QgsVectorLayerSaveAsDialog() +{ +} + +void QgsVectorLayerSaveAsDialog::accept() +{ + QSettings settings; + settings.setValue( "/UI/lastVectorFileFilterDir", QFileInfo( filename() ).absolutePath() ); + settings.setValue( "/UI/lastVectorFormat", format() ); + settings.setValue( "/UI/encoding", encoding() ); + QDialog::accept(); +} + +void QgsVectorLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( int idx ) +{ + browseFilename->setEnabled( true ); + leFilename->setEnabled( true ); +} + +void QgsVectorLayerSaveAsDialog::on_browseFilename_clicked() +{ + QSettings settings; + QString dirName = leFilename->text().isEmpty() ? settings.value( "/UI/lastVectorfileDir", "." ).toString() : leFilename->text(); + QString filterString = QgsVectorFileWriter::filterForDriver( format() ); + QString outputFile = QFileDialog::getSaveFileName( 0, tr( "Save layer as..." ), dirName, filterString ); + if ( !outputFile.isNull() ) + { + leFilename->setText( outputFile ); + } +} + +void QgsVectorLayerSaveAsDialog::on_browseCRS_clicked() +{ + QgsGenericProjectionSelector * mySelector = new QgsGenericProjectionSelector(); + if( mCRS >= 0 ) + mySelector->setSelectedCrsId( mCRS ); + mySelector->setMessage( tr( "Select the coordinate reference system for the vector file. " + "The data points will be transformed from the layer coordinate reference system." ) ); + + if ( mySelector->exec() ) + { + QgsCoordinateReferenceSystem srs( mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId ); + mCRS = srs.srsid(); + leCRS->setText( srs.description() ); + } + + delete mySelector; +} + +QString QgsVectorLayerSaveAsDialog::filename() const +{ + return leFilename->text(); +} + +QString QgsVectorLayerSaveAsDialog::encoding() const +{ + return mEncodingComboBox->currentText(); +} + +QString QgsVectorLayerSaveAsDialog::format() const +{ + return mFormatComboBox->itemData( mFormatComboBox->currentIndex() ).toString(); +} + +long QgsVectorLayerSaveAsDialog::crs() const +{ + return mCRS; +} diff --git a/src/app/ogr/qgsvectorlayersaveasdialog.h b/src/app/ogr/qgsvectorlayersaveasdialog.h new file mode 100644 index 00000000000..7d7175a4772 --- /dev/null +++ b/src/app/ogr/qgsvectorlayersaveasdialog.h @@ -0,0 +1,53 @@ +/*************************************************************************** + qgsvectorlayersaveasdialog.h + Dialog to select destination, type and crs to save as ogr layers + ------------------- + begin : Mon Mar 22 2010 + copyright : (C) 2010 by Juergen E. Fischer + email : jef at norbit dot de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +/* $Id:$ */ +#ifndef QGSVECTORLAYERSAVEASDIALOG_H +#define QGSVECTORLAYERSAVEASDIALOG_H + +#include +#include +#include "qgscontexthelp.h" + +/** + * Class to select destination file, type and CRS for ogr layrs + */ +class QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVectorLayerSaveAsDialogBase +{ + Q_OBJECT + + public: + QgsVectorLayerSaveAsDialog( QWidget* parent = 0, Qt::WFlags fl = 0 ); + ~QgsVectorLayerSaveAsDialog(); + + QString format() const; + QString encoding() const; + QString filename() const; + long crs() const; + + private slots: + void on_mFormatComboBox_currentIndexChanged( int idx ); + void on_browseFilename_clicked(); + void on_browseCRS_clicked(); + void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); } + void accept(); + + private: + long mCRS; +}; + +#endif // QGSVECTORLAYERSAVEASDIALOG_H diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 459acf16241..004c877cb74 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -965,16 +965,16 @@ void QgisApp::createActions() connect( mActionToggleEditing, SIGNAL( triggered() ), this, SLOT( toggleEditing() ) ); mActionToggleEditing->setEnabled( false ); - mActionLayerSaveAs = new QAction( tr( "Save as Shapefile..." ), this ); + mActionLayerSaveAs = new QAction( tr( "Save as..." ), this ); shortcuts->registerAction( mActionLayerSaveAs ); - mActionLayerSaveAs->setStatusTip( tr( "Save the current layer as a shapefile" ) ); - connect( mActionLayerSaveAs, SIGNAL( triggered() ), this, SLOT( saveAsShapefile() ) ); + mActionLayerSaveAs->setStatusTip( tr( "Save the current layer as a vector file" ) ); + connect( mActionLayerSaveAs, SIGNAL( triggered() ), this, SLOT( saveAsVectorFile() ) ); mActionLayerSaveAs->setEnabled( false ); - mActionLayerSelectionSaveAs = new QAction( tr( "Save Selection as Shapefile..." ), this ); + mActionLayerSelectionSaveAs = new QAction( tr( "Save Selection as vector file..." ), this ); shortcuts->registerAction( mActionLayerSelectionSaveAs ); - mActionLayerSelectionSaveAs->setStatusTip( tr( "Save the selection as a shapefile" ) ); - connect( mActionLayerSelectionSaveAs, SIGNAL( triggered() ), this, SLOT( saveSelectionAsShapefile() ) ); + mActionLayerSelectionSaveAs->setStatusTip( tr( "Save the selection as a vector file" ) ); + connect( mActionLayerSelectionSaveAs, SIGNAL( triggered() ), this, SLOT( saveSelectionAsVectorFile() ) ); mActionLayerSelectionSaveAs->setEnabled( false ); mActionRemoveLayer = new QAction( getThemeIcon( "mActionRemoveLayer.png" ), tr( "Remove Layer" ), this ); @@ -3657,14 +3657,14 @@ void QgisApp::attributeTable() // the dialog will be deleted by itself on close } -void QgisApp::saveAsShapefile() +void QgisApp::saveAsVectorFile() { - mMapLegend->currentLegendLayer()->saveAsShapefile(); + mMapLegend->currentLegendLayer()->saveAsVectorFile(); } -void QgisApp::saveSelectionAsShapefile() +void QgisApp::saveSelectionAsVectorFile() { - mMapLegend->currentLegendLayer()->saveSelectionAsShapefile(); + mMapLegend->currentLegendLayer()->saveSelectionAsVectorFile(); } void QgisApp::layerProperties() @@ -5669,9 +5669,9 @@ void QgisApp::addRasterLayer() // This is the method that does the actual work of adding a raster layer - the others // here simply create a raster layer object and delegate here. It is the responsibility // of the calling method to manage things such as the frozen state of the mapcanvas and -// using waitcursors etc. - this method wont and SHOULDNT do it +// using waitcursors etc. - this method won't and SHOULDN'T do it // -bool QgisApp::addRasterLayer( QgsRasterLayer * theRasterLayer ) +bool QgisApp::addRasterLayer( QgsRasterLayer *theRasterLayer ) { if ( mMapCanvas && mMapCanvas->isDrawing() ) { @@ -5697,16 +5697,12 @@ bool QgisApp::addRasterLayer( QgsRasterLayer * theRasterLayer ) QgsMapLayerRegistry::instance()->addMapLayer( theRasterLayer ); // connect up any request the raster may make to update the app progress - QObject::connect( theRasterLayer, - SIGNAL( drawingProgress( int, int ) ), - this, - SLOT( showProgress( int, int ) ) ); + QObject::connect( theRasterLayer, SIGNAL( drawingProgress( int, int ) ), + this, SLOT( showProgress( int, int ) ) ); // connect up any request the raster may make to update the statusbar message - QObject::connect( theRasterLayer, - SIGNAL( statusChanged( QString ) ), - this, - SLOT( showStatusMessage( QString ) ) ); + QObject::connect( theRasterLayer, SIGNAL( statusChanged( QString ) ), + this, SLOT( showStatusMessage( QString ) ) ); return true; } diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index 2afa07c3dc0..a9c0432c0d8 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -625,8 +625,8 @@ class QgisApp : public QMainWindow void toggleEditing( QgsMapLayer *layer ); //! save current vector layer - void saveAsShapefile(); - void saveSelectionAsShapefile(); + void saveAsVectorFile(); + void saveSelectionAsVectorFile(); //! open the properties dialog for the currently selected layer void layerProperties(); diff --git a/src/core/qgsproviderregistry.h b/src/core/qgsproviderregistry.h index 6ddaee4ce02..4c5a1da805f 100644 --- a/src/core/qgsproviderregistry.h +++ b/src/core/qgsproviderregistry.h @@ -99,7 +99,6 @@ class CORE_EXPORT QgsProviderRegistry */ virtual QString protocolDrivers() const; - /** open the given vector data source Similar to open(QString const &), except that the user specifies a data provider @@ -127,7 +126,6 @@ class CORE_EXPORT QgsProviderRegistry /** type for data provider metadata associative container */ typedef std::map Providers; - private: /** ctor private since instance() creates it */ diff --git a/src/core/qgsvectordataprovider.cpp b/src/core/qgsvectordataprovider.cpp index 23d9b26275d..5191d632434 100644 --- a/src/core/qgsvectordataprovider.cpp +++ b/src/core/qgsvectordataprovider.cpp @@ -417,3 +417,59 @@ QVariant QgsVectorDataProvider::convertValue( QVariant::Type type, QString value return v; } + +const QStringList &QgsVectorDataProvider::availableEncodings() +{ + if( smEncodings.isEmpty() ) + { + smEncodings << "BIG5"; + smEncodings << "BIG5-HKSCS"; + smEncodings << "EUCJP"; + smEncodings << "EUCKR"; + smEncodings << "GB2312"; + smEncodings << "GBK"; + smEncodings << "GB18030"; + smEncodings << "JIS7"; + smEncodings << "SHIFT-JIS"; + smEncodings << "TSCII"; + smEncodings << "UTF-8"; + smEncodings << "UTF-16"; + smEncodings << "KOI8-R"; + smEncodings << "KOI8-U"; + smEncodings << "ISO8859-1"; + smEncodings << "ISO8859-2"; + smEncodings << "ISO8859-3"; + smEncodings << "ISO8859-4"; + smEncodings << "ISO8859-5"; + smEncodings << "ISO8859-6"; + smEncodings << "ISO8859-7"; + smEncodings << "ISO8859-8"; + smEncodings << "ISO8859-8-I"; + smEncodings << "ISO8859-9"; + smEncodings << "ISO8859-10"; + smEncodings << "ISO8859-11"; + smEncodings << "ISO8859-12"; + smEncodings << "ISO8859-13"; + smEncodings << "ISO8859-14"; + smEncodings << "ISO8859-15"; + smEncodings << "IBM 850"; + smEncodings << "IBM 866"; + smEncodings << "CP874"; + smEncodings << "CP1250"; + smEncodings << "CP1251"; + smEncodings << "CP1252"; + smEncodings << "CP1253"; + smEncodings << "CP1254"; + smEncodings << "CP1255"; + smEncodings << "CP1256"; + smEncodings << "CP1257"; + smEncodings << "CP1258"; + smEncodings << "Apple Roman"; + smEncodings << "TIS-620"; + smEncodings << "System"; + } + + return smEncodings; +} + +QStringList QgsVectorDataProvider::smEncodings; diff --git a/src/core/qgsvectordataprovider.h b/src/core/qgsvectordataprovider.h index 7b8ee80d06d..009f6c5bd9a 100644 --- a/src/core/qgsvectordataprovider.h +++ b/src/core/qgsvectordataprovider.h @@ -348,6 +348,9 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider @note: added in version 1.4*/ virtual bool doesStrictFeatureTypeCheck() const { return true;} + + static const QStringList &availableEncodings(); + protected: QVariant convertValue( QVariant::Type type, QString value ); @@ -374,6 +377,8 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider private: /** old notation **/ QMap mOldTypeList; + + static QStringList smEncodings; }; #endif diff --git a/src/core/qgsvectorfilewriter.cpp b/src/core/qgsvectorfilewriter.cpp index bcded475276..6dce804109a 100644 --- a/src/core/qgsvectorfilewriter.cpp +++ b/src/core/qgsvectorfilewriter.cpp @@ -387,92 +387,6 @@ QgsVectorFileWriter::writeAsShapefile( QgsVectorLayer* layer, QString *errorMessage ) { return writeAsVectorFormat( layer, shapefileName, fileEncoding, destCRS, "ESRI Shapefile", onlySelected, errorMessage ); -#if 0 - const QgsCoordinateReferenceSystem* outputCRS; - QgsCoordinateTransform* ct = 0; - int shallTransform = false; - - if ( destCRS && destCRS->isValid() ) - { - // This means we should transform - outputCRS = destCRS; - shallTransform = true; - } - else - { - // This means we shouldn't transform, use source CRS as output (if defined) - outputCRS = &layer->srs(); - } - QgsVectorFileWriter* writer = - new QgsVectorFileWriter( shapefileName, fileEncoding, layer->pendingFields(), layer->wkbType(), outputCRS ); - - // check whether file creation was successful - WriterError err = writer->hasError(); - if ( err != NoError ) - { - if ( errorMessage ) - *errorMessage = writer->errorMessage(); - delete writer; - return err; - } - - QgsAttributeList allAttr = layer->pendingAllAttributesList(); - QgsFeature fet; - - layer->select( allAttr, QgsRectangle(), true ); - - const QgsFeatureIds& ids = layer->selectedFeaturesIds(); - - // Create our transform - if ( destCRS ) - { - ct = new QgsCoordinateTransform( layer->srs(), *destCRS ); - } - - // Check for failure - if ( ct == NULL ) - { - shallTransform = false; - } - - // write all features - while ( layer->nextFeature( fet ) ) - { - if ( onlySelected && !ids.contains( fet.id() ) ) - continue; - - if ( shallTransform ) - { - try - { - fet.geometry()->transform( *ct ); - } - catch ( QgsCsException &e ) - { - delete ct; - delete writer; - - QString msg = QObject::tr( "Failed to transform a point while drawing a feature of type '%1'. Writing stopped. (Exception: %2)" ) - .arg( fet.typeName() ).arg( e.what() ); - QgsLogger::warning( msg ); - if ( errorMessage ) - *errorMessage = msg; - - return ErrProjection; - } - } - writer->addFeature( fet ); - } - - delete writer; - - if ( shallTransform ) - { - delete ct; - } - - return NoError; -#endif //0 } QgsVectorFileWriter::WriterError @@ -603,22 +517,46 @@ QMap< QString, QString> QgsVectorFileWriter::supportedFiltersAndFormats() QgsApplication::registerOgrDrivers(); int const drvCount = OGRGetDriverCount(); - QString drvName; - QString filterString; for ( int i = 0; i < drvCount; ++i ) { OGRSFDriverH drv = OGRGetDriver( i ); if ( drv ) { - drvName = OGR_Dr_GetName( drv ); - if ( OGR_Dr_TestCapability( drv, ODrCCreateDataSource ) != 0 ) + QString drvName = OGR_Dr_GetName( drv ); + if ( OGR_Dr_TestCapability( drv, "CreateDataSource" ) != 0 ) { - //add driver name and filter to map - filterString = QgsVectorFileWriter::filterForDriver( drvName ); - if ( !filterString.isEmpty() ) - { - resultMap.insert( filterString, drvName ); - } + QString filterString = filterForDriver( drvName ); + if( filterString.isEmpty() ) + continue; + + resultMap.insert( filterString, drvName ); + } + } + } + + return resultMap; +} + +QMap QgsVectorFileWriter::ogrDriverList() +{ + QMap resultMap; + + QgsApplication::registerOgrDrivers(); + int const drvCount = OGRGetDriverCount(); + + for ( int i = 0; i < drvCount; ++i ) + { + OGRSFDriverH drv = OGRGetDriver( i ); + if ( drv ) + { + QString drvName = OGR_Dr_GetName( drv ); + if ( OGR_Dr_TestCapability( drv, "CreateDataSource" ) != 0 ) + { + QPair p = nameAndGlob( drvName ); + if( p.first.isEmpty() ) + continue; + + resultMap.insert( p.first, drvName ); } } } @@ -629,16 +567,29 @@ QMap< QString, QString> QgsVectorFileWriter::supportedFiltersAndFormats() QString QgsVectorFileWriter::fileFilterString() { QString filterString; - QMap< QString, QString> driverFormatMap = QgsVectorFileWriter::supportedFiltersAndFormats(); + QMap< QString, QString> driverFormatMap = supportedFiltersAndFormats(); QMap< QString, QString>::const_iterator it = driverFormatMap.constBegin(); for ( ; it != driverFormatMap.constEnd(); ++it ) { + if( filterString.isEmpty() ) + filterString += ";;"; + filterString += it.key(); } return filterString; } QString QgsVectorFileWriter::filterForDriver( const QString& driverName ) +{ + QPair p = nameAndGlob( driverName ); + + if( p.first.isEmpty() || p.second.isEmpty() ) + return ""; + + return "[OGR] " + p.first + " (" + p.second.toLower() + " " + p.second.toUpper() + ")"; +} + +QPair QgsVectorFileWriter::nameAndGlob( QString driverName ) { QString longName; QString glob; @@ -660,7 +611,7 @@ QString QgsVectorFileWriter::filterForDriver( const QString& driverName ) } else if ( driverName.startsWith( "ESRI" ) ) { - longName = "ESRI Shapefiles"; + longName = "ESRI Shapefile"; glob = "*.shp"; } else if ( driverName.startsWith( "FMEObjects Gateway" ) ) @@ -685,12 +636,12 @@ QString QgsVectorFileWriter::filterForDriver( const QString& driverName ) } else if ( driverName.startsWith( "GMT" ) ) { - longName = "GMT"; + longName = "Generic Mapping Tools"; glob = "*.gmt"; } else if ( driverName.startsWith( "GPX" ) ) { - longName = "GPX"; + longName = "GPS eXchange Format"; glob = "*.gpx"; } else if ( driverName.startsWith( "Interlis 1" ) ) @@ -705,7 +656,7 @@ QString QgsVectorFileWriter::filterForDriver( const QString& driverName ) } else if ( driverName.startsWith( "KML" ) ) { - longName = "KML"; + longName = "Keyhole Markup Language"; glob = "*.kml" ; } else if ( driverName.startsWith( "MapInfo File" ) ) @@ -733,19 +684,16 @@ QString QgsVectorFileWriter::filterForDriver( const QString& driverName ) longName = "SQLite"; glob = "*.sqlite"; } - else if ( driverName.startsWith( "VRT" ) ) + else if ( driverName.startsWith( "DXF" ) ) { - longName = "VRT - Virtual Datasource "; - glob = "*.vrt"; + longName = "AutoCAD DXF"; + glob = "*.dxf"; } - else if ( driverName.startsWith( "XPlane" ) ) + else if ( driverName.startsWith( "Geoconcept" ) ) { - longName = "X-Plane/Flighgear"; - glob = "apt.dat nav.dat fix.dat awy.dat"; + longName = "Geoconcept"; + glob = "*.gxt *.txt"; } - else - { - return QString(); - } - return "[OGR] " + longName + " (" + glob.toLower() + " " + glob.toUpper() + ");;"; + + return QPair( longName, glob ); } diff --git a/src/core/qgsvectorfilewriter.h b/src/core/qgsvectorfilewriter.h index c1effd4579d..dc95110fd36 100644 --- a/src/core/qgsvectorfilewriter.h +++ b/src/core/qgsvectorfilewriter.h @@ -23,6 +23,8 @@ #include "qgsvectorlayer.h" #include "qgsfield.h" +#include + typedef void *OGRDataSourceH; typedef void *OGRLayerH; typedef void *OGRGeometryH; @@ -83,6 +85,9 @@ class CORE_EXPORT QgsVectorFileWriter /**Returns map with format filter string as key and OGR format key as value*/ static QMap< QString, QString> supportedFiltersAndFormats(); + /**Returns driver list that can be used for dialogs*/ + static QMap< QString, QString> ogrDriverList(); + /**Returns filter string that can be used for dialogs*/ static QString fileFilterString(); @@ -108,6 +113,7 @@ class CORE_EXPORT QgsVectorFileWriter * @return bool true if the file was deleted successfully */ static bool deleteShapeFile( QString theFileName ); + protected: OGRGeometryH createEmptyGeometry( QGis::WkbType wkbType ); @@ -129,6 +135,9 @@ class CORE_EXPORT QgsVectorFileWriter /** map attribute indizes to OGR field indexes */ QMap mAttrIdxToOgrIdx; + + private: + static QPair nameAndGlob( QString driverName ); }; #endif diff --git a/src/gui/qgsencodingfiledialog.cpp b/src/gui/qgsencodingfiledialog.cpp index 3d2d4a3dc8b..0e2e27d800c 100644 --- a/src/gui/qgsencodingfiledialog.cpp +++ b/src/gui/qgsencodingfiledialog.cpp @@ -16,6 +16,8 @@ #include "qgsencodingfiledialog.h" #include "qgsproject.h" #include "qgslogger.h" +#include "qgsvectordataprovider.h" + #include #include #include @@ -23,7 +25,6 @@ #include #include - QgsEncodingFileDialog::QgsEncodingFileDialog( QWidget * parent, const QString & caption, const QString & directory, const QString & filter, const QString & encoding ) @@ -35,48 +36,8 @@ QgsEncodingFileDialog::QgsEncodingFileDialog( QWidget * parent, QLabel* l = new QLabel( tr( "Encoding:" ), this ); layout()->addWidget( l ); layout()->addWidget( mEncodingComboBox ); - mEncodingComboBox->addItem( "BIG5" ); - mEncodingComboBox->addItem( "BIG5-HKSCS" ); - mEncodingComboBox->addItem( "EUCJP" ); - mEncodingComboBox->addItem( "EUCKR" ); - mEncodingComboBox->addItem( "GB2312" ); - mEncodingComboBox->addItem( "GBK" ); - mEncodingComboBox->addItem( "GB18030" ); - mEncodingComboBox->addItem( "JIS7" ); - mEncodingComboBox->addItem( "SHIFT-JIS" ); - mEncodingComboBox->addItem( "TSCII" ); - mEncodingComboBox->addItem( "UTF-8" ); - mEncodingComboBox->addItem( "UTF-16" ); - mEncodingComboBox->addItem( "KOI8-R" ); - mEncodingComboBox->addItem( "KOI8-U" ); - mEncodingComboBox->addItem( "ISO8859-1" ); - mEncodingComboBox->addItem( "ISO8859-2" ); - mEncodingComboBox->addItem( "ISO8859-3" ); - mEncodingComboBox->addItem( "ISO8859-4" ); - mEncodingComboBox->addItem( "ISO8859-5" ); - mEncodingComboBox->addItem( "ISO8859-6" ); - mEncodingComboBox->addItem( "ISO8859-7" ); - mEncodingComboBox->addItem( "ISO8859-8" ); - mEncodingComboBox->addItem( "ISO8859-8-I" ); - mEncodingComboBox->addItem( "ISO8859-9" ); - mEncodingComboBox->addItem( "ISO8859-10" ); - mEncodingComboBox->addItem( "ISO8859-13" ); - mEncodingComboBox->addItem( "ISO8859-14" ); - mEncodingComboBox->addItem( "ISO8859-15" ); - mEncodingComboBox->addItem( "IBM 850" ); - mEncodingComboBox->addItem( "IBM 866" ); - mEncodingComboBox->addItem( "CP874" ); - mEncodingComboBox->addItem( "CP1250" ); - mEncodingComboBox->addItem( "CP1251" ); - mEncodingComboBox->addItem( "CP1252" ); - mEncodingComboBox->addItem( "CP1253" ); - mEncodingComboBox->addItem( "CP1254" ); - mEncodingComboBox->addItem( "CP1255" ); - mEncodingComboBox->addItem( "CP1256" ); - mEncodingComboBox->addItem( "CP1257" ); - mEncodingComboBox->addItem( "CP1258" ); - mEncodingComboBox->addItem( "Apple Roman" ); - mEncodingComboBox->addItem( "TIS-620" ); + + mEncodingComboBox->addItems( QgsVectorDataProvider::availableEncodings() ); // Use default encoding if none supplied QString enc = encoding; diff --git a/src/plugins/ogr_converter/format.cpp b/src/plugins/ogr_converter/format.cpp index 3a540cdd69c..a801bfe19c0 100644 --- a/src/plugins/ogr_converter/format.cpp +++ b/src/plugins/ogr_converter/format.cpp @@ -108,5 +108,5 @@ void FormatsRegistry::init() add( Format( "UK.NTF", "UK National Transfer Format", Format::eFile ) ); add( Format( "TIGER", "U.S. Census TIGER/Line", Format::eFile ) ); add( Format( "VRT", "Virtual Datasource", Format::eFile ) ); - add( Format( "XPLANE", "X-Plane/Flighgear Aeronautical Data", Format::eFile ) ); + add( Format( "XPLANE", "X-Plane/Flightgear Aeronautical Data", Format::eFile ) ); } diff --git a/src/providers/ogr/qgsogrprovider.cpp b/src/providers/ogr/qgsogrprovider.cpp index 16a0b6cd9d4..59029debfd7 100644 --- a/src/providers/ogr/qgsogrprovider.cpp +++ b/src/providers/ogr/qgsogrprovider.cpp @@ -1321,9 +1321,17 @@ QString createFilters( QString type ) } else if ( driverName.startsWith( "XPlane" ) ) { - myFileFilters += createFileFilter_( "X-Plane/Flighgear", + myFileFilters += createFileFilter_( "X-Plane/Flightgear", "apt.dat nav.dat fix.dat awy.dat" ); } + else if ( driverName.startsWith( "Geoconcept" ) ) + { + myFileFilters += createFileFilter_( "Geoconcept", "*.gxt *.txt" ); + } + else if ( driverName.startsWith( "DXF" ) ) + { + myFileFilters += createFileFilter_( "AutoCAD DXF", "*.dxf" ); + } else { // NOP, we don't know anything about the current driver diff --git a/src/ui/qgsopenvectorlayerdialogbase.ui b/src/ui/qgsopenvectorlayerdialogbase.ui index ecba06733e5..cc1364086d0 100644 --- a/src/ui/qgsopenvectorlayerdialogbase.ui +++ b/src/ui/qgsopenvectorlayerdialogbase.ui @@ -89,226 +89,6 @@ 0 - - - BIG5 - - - - - BIG5-HKSCS - - - - - EUCJP - - - - - EUCKR - - - - - GB2312 - - - - - GBK - - - - - GB18030 - - - - - JIS7 - - - - - SHIFT-JIS - - - - - TSCII - - - - - UTF-8 - - - - - UTF-16 - - - - - KOI8-R - - - - - KOI8-U - - - - - ISO8859-1 - - - - - ISO8859-2 - - - - - ISO8859-3 - - - - - ISO8859-4 - - - - - ISO8859-5 - - - - - ISO8859-6 - - - - - ISO8859-7 - - - - - ISO8859-8 - - - - - ISO8859-8-I - - - - - ISO8859-9 - - - - - ISO8859-10 - - - - - ISO8859-11 - - - - - ISO8859-12 - - - - - ISO8859-13 - - - - - ISO8859-14 - - - - - ISO8859-15 - - - - - IBM 850 - - - - - IBM 866 - - - - - CP874 - - - - - CP1250 - - - - - CP1251 - - - - - CP1252 - - - - - CP1253 - - - - - CP1254 - - - - - CP1255 - - - - - CP1256 - - - - - CP1257 - - - - - CP1258 - - - - - Apple Roman - - - - - TIS-620 - - diff --git a/src/ui/qgsvectorlayersaveasdialogbase.ui b/src/ui/qgsvectorlayersaveasdialogbase.ui new file mode 100644 index 00000000000..4442a73cf1f --- /dev/null +++ b/src/ui/qgsvectorlayersaveasdialogbase.ui @@ -0,0 +1,129 @@ + + + QgsVectorLayerSaveAsDialogBase + + + + 0 + 0 + 400 + 203 + + + + Save vector layer as... + + + + + + false + + + + + + + CRS + + + + + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok + + + + + + + Save as + + + + + + + false + + + Browse + + + + + + + Browse + + + + + + + + + + Encoding + + + + + + + Format + + + + + + + + + + + + buttonBox + accepted() + QgsVectorLayerSaveAsDialogBase + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + QgsVectorLayerSaveAsDialogBase + reject() + + + 316 + 260 + + + 286 + 274 + + + + +