00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "qgsnewvectorlayerdialog.h"
00019 #include "qgsapplication.h"
00020
00021 #include "qgis.h"
00022 #include "qgslogger.h"
00023 #include "qgscoordinatereferencesystem.h"
00024 #include "qgsgenericprojectionselector.h"
00025 #include <QPushButton>
00026
00027 #include <QLibrary>
00028 #include <QSettings>
00029 #include "qgsencodingfiledialog.h"
00030 #include "qgsproviderregistry.h"
00031
00032
00033 QgsNewVectorLayerDialog::QgsNewVectorLayerDialog( QWidget *parent, Qt::WFlags fl )
00034 : QDialog( parent, fl )
00035 {
00036 setupUi( this );
00037
00038 QSettings settings;
00039 restoreGeometry( settings.value( "/Windows/NewVectorLayer/geometry" ).toByteArray() );
00040
00041
00042
00043
00044 mTypeBox->addItem( tr( "Text data" ), "String" );
00045 mTypeBox->addItem( tr( "Whole number" ), "Integer" );
00046 mTypeBox->addItem( tr( "Decimal number" ), "Real" );
00047
00048 mWidth->setValidator( new QIntValidator( 1, 255, this ) );
00049 mPrecision->setValidator( new QIntValidator( 0, 15, this ) );
00050
00051 mPointRadioButton->setChecked( true );
00052 mFileFormatComboBox->addItem( tr( "ESRI Shapefile" ), "ESRI Shapefile" );
00053
00054
00055
00056
00057 if ( mFileFormatComboBox->count() == 1 )
00058 {
00059 mFileFormatComboBox->setVisible( false );
00060 mFileFormatLabel->setVisible( false );
00061 }
00062
00063 mOkButton = buttonBox->button( QDialogButtonBox::Ok );
00064
00065 mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << "id" << "Integer" << "10" << "" ) );
00066
00067 QgsCoordinateReferenceSystem srs;
00068 srs.createFromOgcWmsCrs( GEO_EPSG_CRS_AUTHID );
00069 srs.validate();
00070
00071 mCrsId = srs.srsid();
00072 leSpatialRefSys->setText( srs.authid() + " - " + srs.description() );
00073
00074 connect( mNameEdit, SIGNAL( textChanged( QString ) ), this, SLOT( nameChanged( QString ) ) );
00075 connect( mAttributeView, SIGNAL( itemSelectionChanged() ), this, SLOT( selectionChanged() ) );
00076
00077 mAddAttributeButton->setEnabled( false );
00078 mRemoveAttributeButton->setEnabled( false );
00079 }
00080
00081 QgsNewVectorLayerDialog::~QgsNewVectorLayerDialog()
00082 {
00083 QSettings settings;
00084 settings.setValue( "/Windows/NewVectorLayer/geometry", saveGeometry() );
00085 }
00086
00087 void QgsNewVectorLayerDialog::on_mTypeBox_currentIndexChanged( int index )
00088 {
00089
00090 switch ( index )
00091 {
00092 case 0:
00093 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
00094 mWidth->setText( "80" );
00095 mPrecision->setEnabled( false );
00096 mWidth->setValidator( new QIntValidator( 1, 255, this ) );
00097 break;
00098
00099 case 1:
00100 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
00101 mWidth->setText( "10" );
00102 mPrecision->setEnabled( false );
00103 mWidth->setValidator( new QIntValidator( 1, 10, this ) );
00104 break;
00105
00106 case 2:
00107 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 20 )
00108 mWidth->setText( "20" );
00109 mPrecision->setEnabled( true );
00110 mWidth->setValidator( new QIntValidator( 1, 20, this ) );
00111 break;
00112
00113 default:
00114 QgsDebugMsg( "unexpected index" );
00115 break;
00116 }
00117 }
00118
00119 QGis::WkbType QgsNewVectorLayerDialog::selectedType() const
00120 {
00121 if ( mPointRadioButton->isChecked() )
00122 {
00123 return QGis::WKBPoint;
00124 }
00125 else if ( mLineRadioButton->isChecked() )
00126 {
00127 return QGis::WKBLineString;
00128 }
00129 else if ( mPolygonRadioButton->isChecked() )
00130 {
00131 return QGis::WKBPolygon;
00132 }
00133 return QGis::WKBUnknown;
00134 }
00135
00136 int QgsNewVectorLayerDialog::selectedCrsId() const
00137 {
00138 return mCrsId;
00139 }
00140
00141 void QgsNewVectorLayerDialog::on_mAddAttributeButton_clicked()
00142 {
00143 QString myName = mNameEdit->text();
00144 QString myWidth = mWidth->text();
00145 QString myPrecision = mPrecision->isEnabled() ? mPrecision->text() : "";
00146
00147 QString myType = mTypeBox->itemData( mTypeBox->currentIndex(), Qt::UserRole ).toString();
00148 mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << myName << myType << myWidth << myPrecision ) );
00149 if ( mAttributeView->topLevelItemCount() > 0 )
00150 {
00151 mOkButton->setEnabled( true );
00152 }
00153 mNameEdit->clear();
00154 }
00155
00156 void QgsNewVectorLayerDialog::on_mRemoveAttributeButton_clicked()
00157 {
00158 delete mAttributeView->currentItem();
00159 if ( mAttributeView->topLevelItemCount() == 0 )
00160 {
00161 mOkButton->setEnabled( false );
00162 }
00163 }
00164
00165 void QgsNewVectorLayerDialog::on_pbnChangeSpatialRefSys_clicked()
00166 {
00167 QgsGenericProjectionSelector *mySelector = new QgsGenericProjectionSelector( this );
00168 mySelector->setMessage();
00169 mySelector->setSelectedCrsId( pbnChangeSpatialRefSys->text().toInt() );
00170 if ( mySelector->exec() )
00171 {
00172 QgsCoordinateReferenceSystem srs;
00173 srs.createFromOgcWmsCrs( mySelector->selectedAuthId() );
00174 mCrsId = srs.srsid();
00175 leSpatialRefSys->setText( srs.authid() + " - " + srs.description() );
00176 }
00177 else
00178 {
00179 QApplication::restoreOverrideCursor();
00180 }
00181 delete mySelector;
00182 }
00183
00184 void QgsNewVectorLayerDialog::attributes( std::list<std::pair<QString, QString> >& at ) const
00185 {
00186 QTreeWidgetItemIterator it( mAttributeView );
00187 while ( *it )
00188 {
00189 QTreeWidgetItem *item = *it;
00190 QString type = QString( "%1;%2;%3" ).arg( item->text( 1 ) ).arg( item->text( 2 ) ).arg( item->text( 3 ) );
00191 at.push_back( std::make_pair( item->text( 0 ), type ) );
00192 QgsDebugMsg( QString( "appending %1//%2" ).arg( item->text( 0 ) ).arg( type ) );
00193 ++it;
00194 }
00195 }
00196
00197 QString QgsNewVectorLayerDialog::selectedFileFormat() const
00198 {
00199
00200 QString myType = mFileFormatComboBox->itemData( mFileFormatComboBox->currentIndex(), Qt::UserRole ).toString();
00201 return myType;
00202 }
00203
00204 void QgsNewVectorLayerDialog::nameChanged( QString name )
00205 {
00206 mAddAttributeButton->setDisabled( name.isEmpty() || mAttributeView->findItems( name, Qt::MatchExactly ).size() > 0 );
00207 }
00208
00209 void QgsNewVectorLayerDialog::selectionChanged()
00210 {
00211 mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().size() == 0 );
00212 }
00213
00214
00215
00216 QString QgsNewVectorLayerDialog::runAndCreateLayer( QWidget* parent, QString* pEnc )
00217 {
00218 QgsNewVectorLayerDialog geomDialog( parent );
00219 if ( geomDialog.exec() == QDialog::Rejected )
00220 {
00221 return QString();
00222 }
00223
00224 QGis::WkbType geometrytype = geomDialog.selectedType();
00225 QString fileformat = geomDialog.selectedFileFormat();
00226 int crsId = geomDialog.selectedCrsId();
00227 QgsDebugMsg( QString( "New file format will be: %1" ).arg( fileformat ) );
00228
00229 std::list<std::pair<QString, QString> > attributes;
00230 geomDialog.attributes( attributes );
00231
00232 QString enc;
00233 QString fileName;
00234
00235 QSettings settings;
00236 QString lastUsedDir = settings.value( "/UI/lastVectorFileFilterDir", "." ).toString();
00237
00238 QgsDebugMsg( "Saving vector file dialog without filters: " );
00239
00240 QgsEncodingFileDialog* openFileDialog =
00241 new QgsEncodingFileDialog( parent, tr( "Save As" ), lastUsedDir, "", QString( "" ) );
00242
00243 openFileDialog->setFileMode( QFileDialog::AnyFile );
00244 openFileDialog->setAcceptMode( QFileDialog::AcceptSave );
00245 openFileDialog->setConfirmOverwrite( true );
00246
00247 if ( settings.contains( "/UI/lastVectorFileFilter" ) )
00248 {
00249 QString lastUsedFilter = settings.value( "/UI/lastVectorFileFilter", QVariant( QString::null ) ).toString();
00250 openFileDialog->selectFilter( lastUsedFilter );
00251 }
00252
00253 if ( openFileDialog->exec() == QDialog::Rejected )
00254 {
00255 delete openFileDialog;
00256 return QString();
00257 }
00258
00259 fileName = openFileDialog->selectedFiles().first();
00260
00261 if ( fileformat == "ESRI Shapefile" && !fileName.endsWith( ".shp", Qt::CaseInsensitive ) )
00262 fileName += ".shp";
00263
00264 enc = openFileDialog->encoding();
00265
00266 settings.setValue( "/UI/lastVectorFileFilter", openFileDialog->selectedFilter() );
00267 settings.setValue( "/UI/lastVectorFileFilterDir", openFileDialog->directory().absolutePath() );
00268
00269 delete openFileDialog;
00270
00271
00272 QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
00273 QString ogrlib = pReg->library( "ogr" );
00274
00275 QLibrary* myLib = new QLibrary( ogrlib );
00276 bool loaded = myLib->load();
00277 if ( loaded )
00278 {
00279 QgsDebugMsg( "ogr provider loaded" );
00280
00281 typedef bool ( *createEmptyDataSourceProc )( const QString&, const QString&, const QString&, QGis::WkbType,
00282 const std::list<std::pair<QString, QString> >&, const QgsCoordinateReferenceSystem * );
00283 createEmptyDataSourceProc createEmptyDataSource = ( createEmptyDataSourceProc ) cast_to_fptr( myLib->resolve( "createEmptyDataSource" ) );
00284 if ( createEmptyDataSource )
00285 {
00286 if ( geometrytype != QGis::WKBUnknown )
00287 {
00288 QgsCoordinateReferenceSystem srs( crsId, QgsCoordinateReferenceSystem::InternalCrsId );
00289 if ( !createEmptyDataSource( fileName, fileformat, enc, geometrytype, attributes, &srs ) )
00290 {
00291 return QString();
00292 }
00293 }
00294 else
00295 {
00296 QgsDebugMsg( "geometry type not recognised" );
00297 return QString();
00298 }
00299 }
00300 else
00301 {
00302 QgsDebugMsg( "Resolving newEmptyDataSource(...) failed" );
00303 return QString();
00304 }
00305 }
00306
00307 if ( pEnc )
00308 *pEnc = enc;
00309 return fileName;
00310 }