QGIS API Documentation  2.14.0-Essen
qgsvaluemapconfigdlg.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvaluemapconfigdlg.cpp
3  --------------------------------------
4  Date : 5.1.2014
5  Copyright : (C) 2014 Matthias Kuhn
6  Email : matthias at opengis dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsvaluemapconfigdlg.h"
17 
19 
20 #include <QSettings>
21 #include <QFileDialog>
22 #include <QMessageBox>
23 #include <QTextStream>
24 
26  : QgsEditorConfigWidget( vl, fieldIdx, parent )
27 {
28  setupUi( this );
29 
30  tableWidget->insertRow( 0 );
31 
32  connect( removeSelectedButton, SIGNAL( clicked() ), this, SLOT( removeSelectedButtonPushed() ) );
33  connect( loadFromLayerButton, SIGNAL( clicked() ), this, SLOT( loadFromLayerButtonPushed() ) );
34  connect( loadFromCSVButton, SIGNAL( clicked() ), this, SLOT( loadFromCSVButtonPushed() ) );
35  connect( tableWidget, SIGNAL( cellChanged( int, int ) ), this, SLOT( vCellChanged( int, int ) ) );
36 }
37 
39 {
41 
42  //store data to map
43  for ( int i = 0; i < tableWidget->rowCount() - 1; i++ )
44  {
45  QTableWidgetItem *ki = tableWidget->item( i, 0 );
46  QTableWidgetItem *vi = tableWidget->item( i, 1 );
47 
48  if ( !ki )
49  continue;
50 
51  if ( !vi || vi->text().isNull() )
52  {
53  cfg.insert( ki->text(), ki->text() );
54  }
55  else
56  {
57  cfg.insert( vi->text(), ki->text() );
58  }
59  }
60 
61  return cfg;
62 }
63 
65 {
66  tableWidget->clearContents();
67  for ( int i = tableWidget->rowCount() - 1; i > 0; i-- )
68  {
69  tableWidget->removeRow( i );
70  }
71 
72  int row = 0;
73  for ( QgsEditorWidgetConfig::ConstIterator mit = config.begin(); mit != config.end(); mit++, row++ )
74  {
75  tableWidget->insertRow( row );
76  if ( mit.value().isNull() )
77  {
78  tableWidget->setItem( row, 0, new QTableWidgetItem( mit.key() ) );
79  }
80  else
81  {
82  tableWidget->setItem( row, 0, new QTableWidgetItem( mit.value().toString() ) );
83  tableWidget->setItem( row, 1, new QTableWidgetItem( mit.key() ) );
84  }
85  }
86 }
87 
88 void QgsValueMapConfigDlg::vCellChanged( int row, int column )
89 {
90  Q_UNUSED( column );
91  if ( row == tableWidget->rowCount() - 1 )
92  {
93  tableWidget->insertRow( row + 1 );
94  } //else check type
95 }
96 
97 void QgsValueMapConfigDlg::removeSelectedButtonPushed()
98 {
99  QList<QTableWidgetItem *> list = tableWidget->selectedItems();
100  QSet<int> rowsToRemove;
101  int removed = 0;
102  int i;
103  for ( i = 0; i < list.size(); i++ )
104  {
105  if ( list[i]->column() == 0 )
106  {
107  int row = list[i]->row();
108  if ( !rowsToRemove.contains( row ) )
109  {
110  rowsToRemove.insert( row );
111  }
112  }
113  }
114  for ( i = 0; i < rowsToRemove.size(); i++ )
115  {
116  tableWidget->removeRow( rowsToRemove.values().at( i ) - removed );
117  removed++;
118  }
119 }
120 
121 void QgsValueMapConfigDlg::updateMap( const QMap<QString, QVariant> &map, bool insertNull )
122 {
123  tableWidget->clearContents();
124  for ( int i = tableWidget->rowCount() - 1; i > 0; i-- )
125  {
126  tableWidget->removeRow( i );
127  }
128  int row = 0;
129 
130  if ( insertNull )
131  {
132  QSettings settings;
133  tableWidget->setItem( row, 0, new QTableWidgetItem( settings.value( "qgis/nullValue", "NULL" ).toString() ) );
134  tableWidget->setItem( row, 1, new QTableWidgetItem( "<NULL>" ) );
135  ++row;
136  }
137 
138  for ( QMap<QString, QVariant>::const_iterator mit = map.begin(); mit != map.end(); ++mit, ++row )
139  {
140  tableWidget->insertRow( row );
141  if ( mit.value().isNull() )
142  {
143  tableWidget->setItem( row, 0, new QTableWidgetItem( mit.key() ) );
144  }
145  else
146  {
147  tableWidget->setItem( row, 0, new QTableWidgetItem( mit.key() ) );
148  tableWidget->setItem( row, 1, new QTableWidgetItem( mit.value().toString() ) );
149  }
150  }
151 }
152 
153 void QgsValueMapConfigDlg::loadFromLayerButtonPushed()
154 {
155  QgsAttributeTypeLoadDialog layerDialog( layer() );
156  if ( !layerDialog.exec() )
157  return;
158 
159  updateMap( layerDialog.valueMap(), layerDialog.insertNull() );
160 }
161 
162 void QgsValueMapConfigDlg::loadFromCSVButtonPushed()
163 {
164  QString fileName = QFileDialog::getOpenFileName( nullptr, tr( "Select a file" ), QDir::homePath() );
165  if ( fileName.isNull() )
166  return;
167 
168  QFile f( fileName );
169 
170  if ( !f.open( QIODevice::ReadOnly ) )
171  {
172  QMessageBox::information( nullptr,
173  tr( "Error" ),
174  tr( "Could not open file %1\nError was:%2" ).arg( fileName, f.errorString() ),
175  QMessageBox::Cancel );
176  return;
177  }
178 
179  QTextStream s( &f );
180  s.setAutoDetectUnicode( true );
181 
182  QRegExp re0( "^([^;]*);(.*)$" );
183  re0.setMinimal( true );
184  QRegExp re1( "^([^,]*),(.*)$" );
185  re1.setMinimal( true );
187 
188  s.readLine();
189 
190  while ( !s.atEnd() )
191  {
192  QString l = s.readLine().trimmed();
193 
194  QString key, val;
195  if ( re0.indexIn( l ) >= 0 && re0.captureCount() == 2 )
196  {
197  key = re0.cap( 1 ).trimmed();
198  val = re0.cap( 2 ).trimmed();
199  }
200  else if ( re1.indexIn( l ) >= 0 && re1.captureCount() == 2 )
201  {
202  key = re1.cap( 1 ).trimmed();
203  val = re1.cap( 2 ).trimmed();
204  }
205  else
206  continue;
207 
208  if (( key.startsWith( '\"' ) && key.endsWith( '\"' ) ) ||
209  ( key.startsWith( '\'' ) && key.endsWith( '\'' ) ) )
210  {
211  key = key.mid( 1, key.length() - 2 );
212  }
213 
214  if (( val.startsWith( '\"' ) && val.endsWith( '\"' ) ) ||
215  ( val.startsWith( '\'' ) && val.endsWith( '\'' ) ) )
216  {
217  val = val.mid( 1, val.length() - 2 );
218  }
219 
220  map[ key ] = val;
221  }
222 
223  updateMap( map, false );
224 }
void updateMap(const QMap< QString, QVariant > &map, bool insertNull)
QgsVectorLayer * layer()
Returns the layer for which this configuration widget applies.
void setAutoDetectUnicode(bool enabled)
QString cap(int nth) const
void setupUi(QWidget *widget)
This class should be subclassed for every configurable editor widget type.
QString readLine(qint64 maxlen)
void setMinimal(bool minimal)
QString errorString() const
int size() const
const T & at(int i) const
QgsValueMapConfigDlg(QgsVectorLayer *vl, int fieldIdx, QWidget *parent)
int exec()
const_iterator insert(const T &value)
QString homePath()
QString tr(const char *sourceText, const char *disambiguation, int n)
StandardButton information(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
int size() const
bool isNull() const
QMap< QString, QVariant > & valueMap()
Getter to value map which is currently active.
int indexIn(const QString &str, int offset, CaretMode caretMode) const
bool atEnd() const
QList< T > values() const
int captureCount() const
virtual QgsEditorWidgetConfig config() override
Create a configuration from the current GUI state.
QString trimmed() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
bool insertNull()
Returns true if the "Add NULL value" checkbox has been checked.
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
iterator end()
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
virtual void setConfig(const QgsEditorWidgetConfig &config) override
Update the configuration widget to represent the given configuration.
iterator begin()
QString text() const
bool contains(const T &value) const
QVariant value(const QString &key, const QVariant &defaultValue) const
QString mid(int position, int n) const
int length() const
iterator insert(const Key &key, const T &value)
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
typedef ConstIterator
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
QString toString() const