QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules 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 : marco.hugentobler@autoform.ch
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 "qgsproviderregistry.h"
25 #include "qgsvectordataprovider.h"
26 #include "qgsvectorfilewriter.h"
27 
28 #include <QPushButton>
29 #include <QComboBox>
30 #include <QLibrary>
31 #include <QSettings>
32 #include <QFileDialog>
33 
34 
35 QgsNewVectorLayerDialog::QgsNewVectorLayerDialog( QWidget *parent, Qt::WindowFlags fl )
36  : QDialog( parent, fl )
37 {
38  setupUi( this );
39 
40  QSettings settings;
41  restoreGeometry( settings.value( "/Windows/NewVectorLayer/geometry" ).toByteArray() );
42 
43  mAddAttributeButton->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) );
44  mRemoveAttributeButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) );
45  mTypeBox->addItem( tr( "Text data" ), "String" );
46  mTypeBox->addItem( tr( "Whole number" ), "Integer" );
47  mTypeBox->addItem( tr( "Decimal number" ), "Real" );
48  mTypeBox->addItem( tr( "Date" ), "Date" );
49 
50  mWidth->setValidator( new QIntValidator( 1, 255, this ) );
51  mPrecision->setValidator( new QIntValidator( 0, 15, this ) );
52 
53  mPointRadioButton->setChecked( true );
54  mFileFormatComboBox->addItem( tr( "ESRI Shapefile" ), "ESRI Shapefile" );
55 #if 0
56  // Disabled until provider properly supports editing the created file formats
57  mFileFormatComboBox->addItem( tr( "Comma Separated Value" ), "Comma Separated Value" );
58  mFileFormatComboBox->addItem( tr( "GML" ), "GML" );
59  mFileFormatComboBox->addItem( tr( "Mapinfo File" ), "Mapinfo File" );
60 #endif
61  if ( mFileFormatComboBox->count() == 1 )
62  {
63  mFileFormatComboBox->setVisible( false );
64  mFileFormatLabel->setVisible( false );
65  }
66 
67  mFileFormatComboBox->setCurrentIndex( 0 );
68 
69  mFileEncoding->addItems( QgsVectorDataProvider::availableEncodings() );
70 
71  // Use default encoding if none supplied
72  QString enc = QSettings().value( "/UI/encoding", "System" ).toString();
73 
74  // The specified decoding is added if not existing alread, and then set current.
75  // This should select it.
76  int encindex = mFileEncoding->findText( enc );
77  if ( encindex < 0 )
78  {
79  mFileEncoding->insertItem( 0, enc );
80  encindex = 0;
81  }
82  mFileEncoding->setCurrentIndex( encindex );
83 
84  mOkButton = buttonBox->button( QDialogButtonBox::Ok );
85 
86  mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << "id" << "Integer" << "10" << "" ) );
87 
89 
90  srs.createFromOgcWmsCrs( settings.value( "/Projections/layerDefaultCrs", GEO_EPSG_CRS_AUTHID ).toString() );
91  srs.validate();
92 
93  mCrsId = srs.srsid();
94  leSpatialRefSys->setText( srs.authid() + " - " + srs.description() );
95 
96  connect( mNameEdit, SIGNAL( textChanged( QString ) ), this, SLOT( nameChanged( QString ) ) );
97  connect( mAttributeView, SIGNAL( itemSelectionChanged() ), this, SLOT( selectionChanged() ) );
98 
99  mAddAttributeButton->setEnabled( false );
100  mRemoveAttributeButton->setEnabled( false );
101 }
102 
104 {
105  QSettings settings;
106  settings.setValue( "/Windows/NewVectorLayer/geometry", saveGeometry() );
107 }
108 
110 {
111  Q_UNUSED( index );
112  if ( mFileFormatComboBox->currentText() == tr( "ESRI Shapefile" ) )
113  mNameEdit->setMaxLength( 10 );
114  else
115  mNameEdit->setMaxLength( 32767 );
116 }
117 
119 {
120  // FIXME: sync with providers/ogr/qgsogrprovider.cpp
121  switch ( index )
122  {
123  case 0: // Text data
124  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
125  mWidth->setText( "80" );
126  mPrecision->setEnabled( false );
127  mWidth->setValidator( new QIntValidator( 1, 255, this ) );
128  break;
129 
130  case 1: // Whole number
131  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
132  mWidth->setText( "10" );
133  mPrecision->setEnabled( false );
134  mWidth->setValidator( new QIntValidator( 1, 10, this ) );
135  break;
136 
137  case 2: // Decimal number
138  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 20 )
139  mWidth->setText( "20" );
140  mPrecision->setEnabled( true );
141  mWidth->setValidator( new QIntValidator( 1, 20, this ) );
142  break;
143 
144  default:
145  QgsDebugMsg( "unexpected index" );
146  break;
147  }
148 }
149 
151 {
152  if ( mPointRadioButton->isChecked() )
153  {
154  return QGis::WKBPoint;
155  }
156  else if ( mLineRadioButton->isChecked() )
157  {
158  return QGis::WKBLineString;
159  }
160  else if ( mPolygonRadioButton->isChecked() )
161  {
162  return QGis::WKBPolygon;
163  }
164  return QGis::WKBUnknown;
165 }
166 
168 {
169  return mCrsId;
170 }
171 
173 {
174  QString myName = mNameEdit->text();
175  QString myWidth = mWidth->text();
176  QString myPrecision = mPrecision->isEnabled() ? mPrecision->text() : "";
177  //use userrole to avoid translated type string
178  QString myType = mTypeBox->itemData( mTypeBox->currentIndex(), Qt::UserRole ).toString();
179  mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << myName << myType << myWidth << myPrecision ) );
180  if ( mAttributeView->topLevelItemCount() > 0 )
181  {
182  mOkButton->setEnabled( true );
183  }
184  mNameEdit->clear();
185 }
186 
188 {
189  delete mAttributeView->currentItem();
190  if ( mAttributeView->topLevelItemCount() == 0 )
191  {
192  mOkButton->setEnabled( false );
193  }
194 }
195 
197 {
199  mySelector->setMessage();
200  mySelector->setSelectedCrsId( mCrsId );
201  if ( mySelector->exec() )
202  {
204  srs.createFromOgcWmsCrs( mySelector->selectedAuthId() );
205  mCrsId = srs.srsid();
206  leSpatialRefSys->setText( srs.authid() + " - " + srs.description() );
207  }
208  else
209  {
210  QApplication::restoreOverrideCursor();
211  }
212  delete mySelector;
213 }
214 
215 void QgsNewVectorLayerDialog::attributes( QList< QPair<QString, QString> >& at ) const
216 {
217  QTreeWidgetItemIterator it( mAttributeView );
218  while ( *it )
219  {
220  QTreeWidgetItem *item = *it;
221  QString type = QString( "%1;%2;%3" ).arg( item->text( 1 ) ).arg( item->text( 2 ) ).arg( item->text( 3 ) );
222  at.push_back( qMakePair( item->text( 0 ), type ) );
223  QgsDebugMsg( QString( "appending %1//%2" ).arg( item->text( 0 ) ).arg( type ) );
224  ++it;
225  }
226 }
227 
229 {
230  //use userrole to avoid translated type string
231  QString myType = mFileFormatComboBox->itemData( mFileFormatComboBox->currentIndex(), Qt::UserRole ).toString();
232  return myType;
233 }
234 
236 {
237  return mFileEncoding->currentText();
238 }
239 
241 {
242  mAddAttributeButton->setDisabled( name.isEmpty() || mAttributeView->findItems( name, Qt::MatchExactly ).size() > 0 );
243 }
244 
246 {
247  mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().size() == 0 );
248 }
249 
250 
251 // this is static
252 QString QgsNewVectorLayerDialog::runAndCreateLayer( QWidget* parent, QString* pEnc )
253 {
254  QgsNewVectorLayerDialog geomDialog( parent );
255  if ( geomDialog.exec() == QDialog::Rejected )
256  {
257  return "";
258  }
259 
260  QGis::WkbType geometrytype = geomDialog.selectedType();
261  QString fileformat = geomDialog.selectedFileFormat();
262  QString enc = geomDialog.selectedFileEncoding();
263  int crsId = geomDialog.selectedCrsId();
264  QgsDebugMsg( QString( "New file format will be: %1" ).arg( fileformat ) );
265 
266  QList< QPair<QString, QString> > attributes;
267  geomDialog.attributes( attributes );
268 
269  QSettings settings;
270  QString lastUsedDir = settings.value( "/UI/lastVectorFileFilterDir", "." ).toString();
271  QString filterString = QgsVectorFileWriter::filterForDriver( fileformat );
272  QString fileName = QFileDialog::getSaveFileName( 0, tr( "Save layer as..." ), lastUsedDir, filterString );
273  if ( fileName.isNull() )
274  {
275  return "";
276  }
277 
278  if ( fileformat == "ESRI Shapefile" && !fileName.endsWith( ".shp", Qt::CaseInsensitive ) )
279  fileName += ".shp";
280 
281  settings.setValue( "/UI/lastVectorFileFilterDir", QFileInfo( fileName ).absolutePath() );
282  settings.setValue( "/UI/encoding", enc );
283 
284  //try to create the new layer with OGRProvider instead of QgsVectorFileWriter
286  QString ogrlib = pReg->library( "ogr" );
287  // load the data provider
288  QLibrary* myLib = new QLibrary( ogrlib );
289  bool loaded = myLib->load();
290  if ( loaded )
291  {
292  QgsDebugMsg( "ogr provider loaded" );
293 
294  typedef bool ( *createEmptyDataSourceProc )( const QString&, const QString&, const QString&, QGis::WkbType,
295  const QList< QPair<QString, QString> >&, const QgsCoordinateReferenceSystem * );
296  createEmptyDataSourceProc createEmptyDataSource = ( createEmptyDataSourceProc ) cast_to_fptr( myLib->resolve( "createEmptyDataSource" ) );
297  if ( createEmptyDataSource )
298  {
299  if ( geometrytype != QGis::WKBUnknown )
300  {
302  if ( !createEmptyDataSource( fileName, fileformat, enc, geometrytype, attributes, &srs ) )
303  {
304  return QString::null;
305  }
306  }
307  else
308  {
309  QgsDebugMsg( "geometry type not recognised" );
310  return QString::null;
311  }
312  }
313  else
314  {
315  QgsDebugMsg( "Resolving newEmptyDataSource(...) failed" );
316  return QString::null;
317  }
318  }
319 
320  if ( pEnc )
321  *pEnc = enc;
322 
323  return fileName;
324 }
static unsigned index
QString selectedFileEncoding() const
Returns the file format for storage.
void on_mTypeBox_currentIndexChanged(int index)
static QgsProviderRegistry * instance(QString pluginPath=QString::null)
means of accessing canonical single instance
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
QString library(const QString &providerKey) const
Return path for the library of the provider.
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
A generic dialog to prompt the user for a Coordinate Reference System.
int selectedCrsId() const
Returns the selected crs id.
WkbType
Used for symbology operations.
Definition: qgis.h:53
QString selectedFileFormat() const
Returns the file format for storage.
static const QStringList & availableEncodings()
Returns a list of available encodings.
bool createFromOgcWmsCrs(QString theCrs)
Set up this CRS from the given OGC CRS.
static QString runAndCreateLayer(QWidget *parent=0, QString *enc=0)
void setMessage(QString theMessage="")
If no parameter is passed, the message will be a generic 'define the CRS for this layer'...
A registry / canonical manager of data providers.
QgsNewVectorLayerDialog(QWidget *parent=0, Qt::WindowFlags fl=QgisGui::ModalDialogFlags)
void attributes(QList< QPair< QString, QString > > &at) const
Appends the chosen attribute names and types to at.
QGis::WkbType selectedType() const
Returns the selected geometry type.
Class for storing a coordinate reference system (CRS)
void(*)() cast_to_fptr(void *p)
Definition: qgis.h:301
void on_mFileFormatComboBox_currentIndexChanged(int index)
static QString filterForDriver(const QString &driverName)
Creates a filter for an OGR driver key.
const CORE_EXPORT QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority.
Definition: qgis.cpp:71
#define tr(sourceText)