QGIS API Documentation  2.0.1-Dufour
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsnewvectorlayerdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsnewvectorlayerdialog.cpp - description
3  -------------------
4  begin : October 2004
5  copyright : (C) 2004 by Marco Hugentobler
6  email : [email protected]
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgsapplication.h"
20 #include "qgis.h"
21 #include "qgslogger.h"
24 #include <QPushButton>
25 
26 #include <QLibrary>
27 #include <QSettings>
28 #include "qgsencodingfiledialog.h"
29 #include "qgsproviderregistry.h"
30 
31 
32 QgsNewVectorLayerDialog::QgsNewVectorLayerDialog( QWidget *parent, Qt::WFlags fl )
33  : QDialog( parent, fl )
34 {
35  setupUi( this );
36 
37  QSettings settings;
38  restoreGeometry( settings.value( "/Windows/NewVectorLayer/geometry" ).toByteArray() );
39 
40  mAddAttributeButton->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) );
41  mRemoveAttributeButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) );
42  mTypeBox->addItem( tr( "Text data" ), "String" );
43  mTypeBox->addItem( tr( "Whole number" ), "Integer" );
44  mTypeBox->addItem( tr( "Decimal number" ), "Real" );
45  mTypeBox->addItem( tr( "Date" ), "Date" );
46 
47  mWidth->setValidator( new QIntValidator( 1, 255, this ) );
48  mPrecision->setValidator( new QIntValidator( 0, 15, this ) );
49 
50  mPointRadioButton->setChecked( true );
51  mFileFormatComboBox->addItem( tr( "ESRI Shapefile" ), "ESRI Shapefile" );
52 #if 0
53  // Disabled until provider properly supports editing the created file formats
54  mFileFormatComboBox->addItem( tr( "Comma Separated Value" ), "Comma Separated Value" );
55  mFileFormatComboBox->addItem( tr( "GML" ), "GML" );
56  mFileFormatComboBox->addItem( tr( "Mapinfo File" ), "Mapinfo File" );
57 #endif
58  if ( mFileFormatComboBox->count() == 1 )
59  {
60  mFileFormatComboBox->setVisible( false );
61  mFileFormatLabel->setVisible( false );
62  }
63 
64  mOkButton = buttonBox->button( QDialogButtonBox::Ok );
65 
66  mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << "id" << "Integer" << "10" << "" ) );
67 
69 
70  srs.createFromOgcWmsCrs( settings.value( "/Projections/layerDefaultCrs", GEO_EPSG_CRS_AUTHID ).toString() );
71  srs.validate();
72 
73  mCrsId = srs.srsid();
74  leSpatialRefSys->setText( srs.authid() + " - " + srs.description() );
75 
76  connect( mNameEdit, SIGNAL( textChanged( QString ) ), this, SLOT( nameChanged( QString ) ) );
77  connect( mAttributeView, SIGNAL( itemSelectionChanged() ), this, SLOT( selectionChanged() ) );
78 
79  mAddAttributeButton->setEnabled( false );
80  mRemoveAttributeButton->setEnabled( false );
81 }
82 
84 {
85  QSettings settings;
86  settings.setValue( "/Windows/NewVectorLayer/geometry", saveGeometry() );
87 }
88 
90 {
91  // FIXME: sync with providers/ogr/qgsogrprovider.cpp
92  switch ( index )
93  {
94  case 0: // Text data
95  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
96  mWidth->setText( "80" );
97  mPrecision->setEnabled( false );
98  mWidth->setValidator( new QIntValidator( 1, 255, this ) );
99  break;
100 
101  case 1: // Whole number
102  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
103  mWidth->setText( "10" );
104  mPrecision->setEnabled( false );
105  mWidth->setValidator( new QIntValidator( 1, 10, this ) );
106  break;
107 
108  case 2: // Decimal number
109  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 20 )
110  mWidth->setText( "20" );
111  mPrecision->setEnabled( true );
112  mWidth->setValidator( new QIntValidator( 1, 20, this ) );
113  break;
114 
115  default:
116  QgsDebugMsg( "unexpected index" );
117  break;
118  }
119 }
120 
122 {
123  if ( mPointRadioButton->isChecked() )
124  {
125  return QGis::WKBPoint;
126  }
127  else if ( mLineRadioButton->isChecked() )
128  {
129  return QGis::WKBLineString;
130  }
131  else if ( mPolygonRadioButton->isChecked() )
132  {
133  return QGis::WKBPolygon;
134  }
135  return QGis::WKBUnknown;
136 }
137 
139 {
140  return mCrsId;
141 }
142 
144 {
145  QString myName = mNameEdit->text();
146  QString myWidth = mWidth->text();
147  QString myPrecision = mPrecision->isEnabled() ? mPrecision->text() : "";
148  //use userrole to avoid translated type string
149  QString myType = mTypeBox->itemData( mTypeBox->currentIndex(), Qt::UserRole ).toString();
150  mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << myName << myType << myWidth << myPrecision ) );
151  if ( mAttributeView->topLevelItemCount() > 0 )
152  {
153  mOkButton->setEnabled( true );
154  }
155  mNameEdit->clear();
156 }
157 
159 {
160  delete mAttributeView->currentItem();
161  if ( mAttributeView->topLevelItemCount() == 0 )
162  {
163  mOkButton->setEnabled( false );
164  }
165 }
166 
168 {
170  mySelector->setMessage();
171  mySelector->setSelectedCrsId( mCrsId );
172  if ( mySelector->exec() )
173  {
175  srs.createFromOgcWmsCrs( mySelector->selectedAuthId() );
176  mCrsId = srs.srsid();
177  leSpatialRefSys->setText( srs.authid() + " - " + srs.description() );
178  }
179  else
180  {
181  QApplication::restoreOverrideCursor();
182  }
183  delete mySelector;
184 }
185 
186 void QgsNewVectorLayerDialog::attributes( QList< QPair<QString, QString> >& at ) const
187 {
188  QTreeWidgetItemIterator it( mAttributeView );
189  while ( *it )
190  {
191  QTreeWidgetItem *item = *it;
192  QString type = QString( "%1;%2;%3" ).arg( item->text( 1 ) ).arg( item->text( 2 ) ).arg( item->text( 3 ) );
193  at.push_back( qMakePair( item->text( 0 ), type ) );
194  QgsDebugMsg( QString( "appending %1//%2" ).arg( item->text( 0 ) ).arg( type ) );
195  ++it;
196  }
197 }
198 
200 {
201  //use userrole to avoid translated type string
202  QString myType = mFileFormatComboBox->itemData( mFileFormatComboBox->currentIndex(), Qt::UserRole ).toString();
203  return myType;
204 }
205 
207 {
208  mAddAttributeButton->setDisabled( name.isEmpty() || mAttributeView->findItems( name, Qt::MatchExactly ).size() > 0 );
209 }
210 
212 {
213  mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().size() == 0 );
214 }
215 
216 
217 // this is static
218 QString QgsNewVectorLayerDialog::runAndCreateLayer( QWidget* parent, QString* pEnc )
219 {
220  QgsNewVectorLayerDialog geomDialog( parent );
221  if ( geomDialog.exec() == QDialog::Rejected )
222  {
223  return QString();
224  }
225 
226  QGis::WkbType geometrytype = geomDialog.selectedType();
227  QString fileformat = geomDialog.selectedFileFormat();
228  int crsId = geomDialog.selectedCrsId();
229  QgsDebugMsg( QString( "New file format will be: %1" ).arg( fileformat ) );
230 
231  QList< QPair<QString, QString> > attributes;
232  geomDialog.attributes( attributes );
233 
234  QString enc;
235  QString fileName;
236 
237  QSettings settings;
238  QString lastUsedDir = settings.value( "/UI/lastVectorFileFilterDir", "." ).toString();
239 
240  QgsDebugMsg( "Saving vector file dialog without filters: " );
241 
242  QgsEncodingFileDialog* openFileDialog =
243  new QgsEncodingFileDialog( parent, tr( "Save As" ), lastUsedDir, "", QString( "" ) );
244 
245  openFileDialog->setFileMode( QFileDialog::AnyFile );
246  openFileDialog->setAcceptMode( QFileDialog::AcceptSave );
247  openFileDialog->setConfirmOverwrite( true );
248 
249  if ( settings.contains( "/UI/lastVectorFileFilter" ) )
250  {
251  QString lastUsedFilter = settings.value( "/UI/lastVectorFileFilter", QVariant( QString::null ) ).toString();
252  openFileDialog->selectFilter( lastUsedFilter );
253  }
254 
255  if ( openFileDialog->exec() == QDialog::Rejected )
256  {
257  delete openFileDialog;
258  return QString();
259  }
260 
261  fileName = openFileDialog->selectedFiles().first();
262 
263  if ( fileformat == "ESRI Shapefile" && !fileName.endsWith( ".shp", Qt::CaseInsensitive ) )
264  fileName += ".shp";
265 
266  enc = openFileDialog->encoding();
267 
268  settings.setValue( "/UI/lastVectorFileFilter", openFileDialog->selectedFilter() );
269  settings.setValue( "/UI/lastVectorFileFilterDir", openFileDialog->directory().absolutePath() );
270 
271  delete openFileDialog;
272 
273  //try to create the new layer with OGRProvider instead of QgsVectorFileWriter
275  QString ogrlib = pReg->library( "ogr" );
276  // load the data provider
277  QLibrary* myLib = new QLibrary( ogrlib );
278  bool loaded = myLib->load();
279  if ( loaded )
280  {
281  QgsDebugMsg( "ogr provider loaded" );
282 
283  typedef bool ( *createEmptyDataSourceProc )( const QString&, const QString&, const QString&, QGis::WkbType,
284  const QList< QPair<QString, QString> >&, const QgsCoordinateReferenceSystem * );
285  createEmptyDataSourceProc createEmptyDataSource = ( createEmptyDataSourceProc ) cast_to_fptr( myLib->resolve( "createEmptyDataSource" ) );
286  if ( createEmptyDataSource )
287  {
288  if ( geometrytype != QGis::WKBUnknown )
289  {
291  if ( !createEmptyDataSource( fileName, fileformat, enc, geometrytype, attributes, &srs ) )
292  {
293  return QString();
294  }
295  }
296  else
297  {
298  QgsDebugMsg( "geometry type not recognised" );
299  return QString();
300  }
301  }
302  else
303  {
304  QgsDebugMsg( "Resolving newEmptyDataSource(...) failed" );
305  return QString();
306  }
307  }
308 
309  if ( pEnc )
310  *pEnc = enc;
311  return fileName;
312 }