Quantum GIS API Documentation  1.8
src/gui/qgsnewvectorlayerdialog.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                          qgsnewvectorlayerdialog.cpp  -  description
00003                              -------------------
00004     begin                : October 2004
00005     copyright            : (C) 2004 by Marco Hugentobler
00006     email                : marco.hugentobler@autoform.ch
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines