Quantum GIS API Documentation
1.8
|
00001 /*************************************************************************** 00002 qgsnewvectorlayerdialog.cpp - description 00003 ------------------- 00004 begin : October 2004 00005 copyright : (C) 2004 by Marco Hugentobler 00006 email : [email protected] 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include "qgsnewvectorlayerdialog.h" 00019 #include "qgsapplication.h" 00020 //#include "qgisapp.h" // <- for theme icons 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 // TODO: do it without QgisApp 00042 //mAddAttributeButton->setIcon( QgisApp::getThemeIcon( "/mActionNewAttribute.png" ) ); 00043 //mRemoveAttributeButton->setIcon( QgisApp::getThemeIcon( "/mActionDeleteAttribute.png" ) ); 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 /* Disabled until provider properly supports editing the created file formats */ 00054 //mFileFormatComboBox->addItem( tr( "Comma Separated Value" ), "Comma Separated Value" ); 00055 //mFileFormatComboBox->addItem(tr( "GML"), "GML" ); 00056 //mFileFormatComboBox->addItem(tr( "Mapinfo File" ), "Mapinfo File" ); 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 // FIXME: sync with providers/ogr/qgsogrprovider.cpp 00090 switch ( index ) 00091 { 00092 case 0: // Text data 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: // Whole number 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: // Decimal number 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 //use userrole to avoid translated type string 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 //use userrole to avoid translated type string 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 // this is static 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 //try to create the new layer with OGRProvider instead of QgsVectorFileWriter 00272 QgsProviderRegistry * pReg = QgsProviderRegistry::instance(); 00273 QString ogrlib = pReg->library( "ogr" ); 00274 // load the data provider 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 }