QGIS API Documentation  2.8.2-Wien
 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"
23 #include "qgsproviderregistry.h"
24 #include "qgsvectordataprovider.h"
25 #include "qgsvectorfilewriter.h"
26 
27 #include <QPushButton>
28 #include <QComboBox>
29 #include <QLibrary>
30 #include <QSettings>
31 #include <QFileDialog>
32 
33 
34 QgsNewVectorLayerDialog::QgsNewVectorLayerDialog( QWidget *parent, Qt::WindowFlags fl )
35  : QDialog( parent, fl )
36 {
37  setupUi( this );
38 
39  QSettings settings;
40  restoreGeometry( settings.value( "/Windows/NewVectorLayer/geometry" ).toByteArray() );
41 
42  mAddAttributeButton->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) );
43  mRemoveAttributeButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) );
44  mTypeBox->addItem( tr( "Text data" ), "String" );
45  mTypeBox->addItem( tr( "Whole number" ), "Integer" );
46  mTypeBox->addItem( tr( "Decimal number" ), "Real" );
47  mTypeBox->addItem( tr( "Date" ), "Date" );
48 
49  mWidth->setValidator( new QIntValidator( 1, 255, this ) );
50  mPrecision->setValidator( new QIntValidator( 0, 15, this ) );
51 
52  mPointRadioButton->setChecked( true );
53  mFileFormatComboBox->addItem( tr( "ESRI Shapefile" ), "ESRI Shapefile" );
54 #if 0
55  // Disabled until provider properly supports editing the created file formats
56  mFileFormatComboBox->addItem( tr( "Comma Separated Value" ), "Comma Separated Value" );
57  mFileFormatComboBox->addItem( tr( "GML" ), "GML" );
58  mFileFormatComboBox->addItem( tr( "Mapinfo File" ), "Mapinfo File" );
59 #endif
60  if ( mFileFormatComboBox->count() == 1 )
61  {
62  mFileFormatComboBox->setVisible( false );
63  mFileFormatLabel->setVisible( false );
64  }
65 
66  mFileFormatComboBox->setCurrentIndex( 0 );
67 
68  mFileEncoding->addItems( QgsVectorDataProvider::availableEncodings() );
69 
70  // Use default encoding if none supplied
71  QString enc = QSettings().value( "/UI/encoding", "System" ).toString();
72 
73  // The specified decoding is added if not existing alread, and then set current.
74  // This should select it.
75  int encindex = mFileEncoding->findText( enc );
76  if ( encindex < 0 )
77  {
78  mFileEncoding->insertItem( 0, enc );
79  encindex = 0;
80  }
81  mFileEncoding->setCurrentIndex( encindex );
82 
83  mOkButton = buttonBox->button( QDialogButtonBox::Ok );
84 
85  mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << "id" << "Integer" << "10" << "" ) );
86 
88  defaultCrs.createFromOgcWmsCrs( settings.value( "/Projections/layerDefaultCrs", GEO_EPSG_CRS_AUTHID ).toString() );
89  defaultCrs.validate();
90  mCrsSelector->setCrs( defaultCrs );
91 
92  connect( mNameEdit, SIGNAL( textChanged( QString ) ), this, SLOT( nameChanged( QString ) ) );
93  connect( mAttributeView, SIGNAL( itemSelectionChanged() ), this, SLOT( selectionChanged() ) );
94 
95  mAddAttributeButton->setEnabled( false );
96  mRemoveAttributeButton->setEnabled( false );
97 }
98 
100 {
101  QSettings settings;
102  settings.setValue( "/Windows/NewVectorLayer/geometry", saveGeometry() );
103 }
104 
106 {
107  Q_UNUSED( index );
108  if ( mFileFormatComboBox->currentText() == tr( "ESRI Shapefile" ) )
109  mNameEdit->setMaxLength( 10 );
110  else
111  mNameEdit->setMaxLength( 32767 );
112 }
113 
115 {
116  // FIXME: sync with providers/ogr/qgsogrprovider.cpp
117  switch ( index )
118  {
119  case 0: // Text data
120  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
121  mWidth->setText( "80" );
122  mPrecision->setEnabled( false );
123  mWidth->setValidator( new QIntValidator( 1, 255, this ) );
124  break;
125 
126  case 1: // Whole number
127  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
128  mWidth->setText( "10" );
129  mPrecision->setEnabled( false );
130  mWidth->setValidator( new QIntValidator( 1, 10, this ) );
131  break;
132 
133  case 2: // Decimal number
134  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 20 )
135  mWidth->setText( "20" );
136  mPrecision->setEnabled( true );
137  mWidth->setValidator( new QIntValidator( 1, 20, this ) );
138  break;
139 
140  default:
141  QgsDebugMsg( "unexpected index" );
142  break;
143  }
144 }
145 
147 {
148  if ( mPointRadioButton->isChecked() )
149  {
150  return QGis::WKBPoint;
151  }
152  else if ( mLineRadioButton->isChecked() )
153  {
154  return QGis::WKBLineString;
155  }
156  else if ( mPolygonRadioButton->isChecked() )
157  {
158  return QGis::WKBPolygon;
159  }
160  return QGis::WKBUnknown;
161 }
162 
164 {
165  return mCrsSelector->crs().srsid();
166 }
167 
169 {
170  QString myName = mNameEdit->text();
171  QString myWidth = mWidth->text();
172  QString myPrecision = mPrecision->isEnabled() ? mPrecision->text() : "";
173  //use userrole to avoid translated type string
174  QString myType = mTypeBox->itemData( mTypeBox->currentIndex(), Qt::UserRole ).toString();
175  mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << myName << myType << myWidth << myPrecision ) );
176  if ( mAttributeView->topLevelItemCount() > 0 )
177  {
178  mOkButton->setEnabled( true );
179  }
180  mNameEdit->clear();
181 }
182 
184 {
185  delete mAttributeView->currentItem();
186  if ( mAttributeView->topLevelItemCount() == 0 )
187  {
188  mOkButton->setEnabled( false );
189  }
190 }
191 
192 void QgsNewVectorLayerDialog::attributes( QList< QPair<QString, QString> >& at ) const
193 {
194  QTreeWidgetItemIterator it( mAttributeView );
195  while ( *it )
196  {
197  QTreeWidgetItem *item = *it;
198  QString type = QString( "%1;%2;%3" ).arg( item->text( 1 ) ).arg( item->text( 2 ) ).arg( item->text( 3 ) );
199  at.push_back( qMakePair( item->text( 0 ), type ) );
200  QgsDebugMsg( QString( "appending %1//%2" ).arg( item->text( 0 ) ).arg( type ) );
201  ++it;
202  }
203 }
204 
206 {
207  //use userrole to avoid translated type string
208  QString myType = mFileFormatComboBox->itemData( mFileFormatComboBox->currentIndex(), Qt::UserRole ).toString();
209  return myType;
210 }
211 
213 {
214  return mFileEncoding->currentText();
215 }
216 
218 {
219  mAddAttributeButton->setDisabled( name.isEmpty() || mAttributeView->findItems( name, Qt::MatchExactly ).size() > 0 );
220 }
221 
223 {
224  mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().size() == 0 );
225 }
226 
227 
228 // this is static
229 QString QgsNewVectorLayerDialog::runAndCreateLayer( QWidget* parent, QString* pEnc )
230 {
231  QgsNewVectorLayerDialog geomDialog( parent );
232  if ( geomDialog.exec() == QDialog::Rejected )
233  {
234  return "";
235  }
236 
237  QGis::WkbType geometrytype = geomDialog.selectedType();
238  QString fileformat = geomDialog.selectedFileFormat();
239  QString enc = geomDialog.selectedFileEncoding();
240  int crsId = geomDialog.selectedCrsId();
241  QgsDebugMsg( QString( "New file format will be: %1" ).arg( fileformat ) );
242 
243  QList< QPair<QString, QString> > attributes;
244  geomDialog.attributes( attributes );
245 
246  QSettings settings;
247  QString lastUsedDir = settings.value( "/UI/lastVectorFileFilterDir", "." ).toString();
248  QString filterString = QgsVectorFileWriter::filterForDriver( fileformat );
249  QString fileName = QFileDialog::getSaveFileName( 0, tr( "Save layer as..." ), lastUsedDir, filterString );
250  if ( fileName.isNull() )
251  {
252  return "";
253  }
254 
255  if ( fileformat == "ESRI Shapefile" && !fileName.endsWith( ".shp", Qt::CaseInsensitive ) )
256  fileName += ".shp";
257 
258  settings.setValue( "/UI/lastVectorFileFilterDir", QFileInfo( fileName ).absolutePath() );
259  settings.setValue( "/UI/encoding", enc );
260 
261  //try to create the new layer with OGRProvider instead of QgsVectorFileWriter
263  QString ogrlib = pReg->library( "ogr" );
264  // load the data provider
265  QLibrary* myLib = new QLibrary( ogrlib );
266  bool loaded = myLib->load();
267  if ( loaded )
268  {
269  QgsDebugMsg( "ogr provider loaded" );
270 
271  typedef bool ( *createEmptyDataSourceProc )( const QString&, const QString&, const QString&, QGis::WkbType,
272  const QList< QPair<QString, QString> >&, const QgsCoordinateReferenceSystem * );
273  createEmptyDataSourceProc createEmptyDataSource = ( createEmptyDataSourceProc ) cast_to_fptr( myLib->resolve( "createEmptyDataSource" ) );
274  if ( createEmptyDataSource )
275  {
276  if ( geometrytype != QGis::WKBUnknown )
277  {
279  if ( !createEmptyDataSource( fileName, fileformat, enc, geometrytype, attributes, &srs ) )
280  {
281  return QString::null;
282  }
283  }
284  else
285  {
286  QgsDebugMsg( "geometry type not recognised" );
287  return QString::null;
288  }
289  }
290  else
291  {
292  QgsDebugMsg( "Resolving newEmptyDataSource(...) failed" );
293  return QString::null;
294  }
295  }
296 
297  if ( pEnc )
298  *pEnc = enc;
299 
300  return fileName;
301 }