QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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( addNullButton, SIGNAL( clicked() ), this, SLOT( addNullButtonPushed() ) );
33  connect( removeSelectedButton, SIGNAL( clicked() ), this, SLOT( removeSelectedButtonPushed() ) );
34  connect( loadFromLayerButton, SIGNAL( clicked() ), this, SLOT( loadFromLayerButtonPushed() ) );
35  connect( loadFromCSVButton, SIGNAL( clicked() ), this, SLOT( loadFromCSVButtonPushed() ) );
36  connect( tableWidget, SIGNAL( cellChanged( int, int ) ), this, SLOT( vCellChanged( int, int ) ) );
37 }
38 
40 {
42  QSettings settings;
43 
44  //store data to map
45  for ( int i = 0; i < tableWidget->rowCount() - 1; i++ )
46  {
47  QTableWidgetItem *ki = tableWidget->item( i, 0 );
48  QTableWidgetItem *vi = tableWidget->item( i, 1 );
49 
50  if ( !ki )
51  continue;
52 
53  QString ks = ki->text();
54  if (( ks == settings.value( "qgis/nullValue", "NULL" ).toString() ) && !( ki->flags() & Qt::ItemIsEditable ) )
55  ks = VALUEMAP_NULL_TEXT;
56 
57  if ( !vi || vi->text().isNull() )
58  {
59  cfg.insert( ks, ks );
60  }
61  else
62  {
63  cfg.insert( vi->text(), ks );
64  }
65  }
66 
67  return cfg;
68 }
69 
71 {
72  tableWidget->clearContents();
73  for ( int i = tableWidget->rowCount() - 1; i > 0; i-- )
74  {
75  tableWidget->removeRow( i );
76  }
77 
78  int row = 0;
79  for ( QgsEditorWidgetConfig::ConstIterator mit = config.begin(); mit != config.end(); mit++, row++ )
80  {
81  if ( mit.value().isNull() )
82  setRow( row, mit.key(), QString() );
83  else
84  setRow( row, mit.value().toString(), mit.key() );
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  emit changed();
97 }
98 
99 void QgsValueMapConfigDlg::removeSelectedButtonPushed()
100 {
101  QList<QTableWidgetItem *> list = tableWidget->selectedItems();
102  QSet<int> rowsToRemove;
103  int removed = 0;
104  int i;
105  for ( i = 0; i < list.size(); i++ )
106  {
107  if ( list[i]->column() == 0 )
108  {
109  int row = list[i]->row();
110  if ( !rowsToRemove.contains( row ) )
111  {
112  rowsToRemove.insert( row );
113  }
114  }
115  }
116  for ( i = 0; i < rowsToRemove.size(); i++ )
117  {
118  tableWidget->removeRow( rowsToRemove.values().at( i ) - removed );
119  removed++;
120  }
121  emit changed();
122 }
123 
124 void QgsValueMapConfigDlg::updateMap( const QMap<QString, QVariant> &map, bool insertNull )
125 {
126  tableWidget->clearContents();
127  for ( int i = tableWidget->rowCount() - 1; i > 0; i-- )
128  {
129  tableWidget->removeRow( i );
130  }
131  int row = 0;
132 
133  if ( insertNull )
134  {
135  setRow( row, VALUEMAP_NULL_TEXT, "<NULL>" );
136  ++row;
137  }
138 
139  for ( QMap<QString, QVariant>::const_iterator mit = map.begin(); mit != map.end(); ++mit, ++row )
140  {
141  if ( mit.value().isNull() )
142  setRow( row, mit.key(), QString() );
143  else
144  setRow( row, mit.key(), mit.value().toString() );
145  }
146 }
147 
148 void QgsValueMapConfigDlg::setRow( int row, const QString value, const QString description )
149 {
150  QSettings settings;
151  QTableWidgetItem* valueCell;
152  QTableWidgetItem* descriptionCell = new QTableWidgetItem( description );
153  tableWidget->insertRow( row );
154  if ( value == QString( VALUEMAP_NULL_TEXT ) )
155  {
156  QFont cellFont;
157  cellFont.setItalic( true );
158  valueCell = new QTableWidgetItem( settings.value( "qgis/nullValue", "NULL" ).toString() );
159  valueCell->setFont( cellFont );
160  valueCell->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
161  descriptionCell->setFont( cellFont );
162  }
163  else
164  {
165  valueCell = new QTableWidgetItem( value );
166  }
167  tableWidget->setItem( row, 0, valueCell );
168  tableWidget->setItem( row, 1, descriptionCell );
169 }
170 
171 void QgsValueMapConfigDlg::addNullButtonPushed()
172 {
173  setRow( tableWidget->rowCount() - 1, VALUEMAP_NULL_TEXT, "<NULL>" );
174 }
175 
176 void QgsValueMapConfigDlg::loadFromLayerButtonPushed()
177 {
178  QgsAttributeTypeLoadDialog layerDialog( layer() );
179  if ( !layerDialog.exec() )
180  return;
181 
182  updateMap( layerDialog.valueMap(), layerDialog.insertNull() );
183 }
184 
185 void QgsValueMapConfigDlg::loadFromCSVButtonPushed()
186 {
187  QSettings settings;
188 
189  QString fileName = QFileDialog::getOpenFileName( nullptr, tr( "Select a file" ), QDir::homePath() );
190  if ( fileName.isNull() )
191  return;
192 
193  QFile f( fileName );
194 
195  if ( !f.open( QIODevice::ReadOnly ) )
196  {
197  QMessageBox::information( nullptr,
198  tr( "Error" ),
199  tr( "Could not open file %1\nError was:%2" ).arg( fileName, f.errorString() ),
200  QMessageBox::Cancel );
201  return;
202  }
203 
204  QTextStream s( &f );
205  s.setAutoDetectUnicode( true );
206 
207  QRegExp re0( "^([^;]*);(.*)$" );
208  re0.setMinimal( true );
209  QRegExp re1( "^([^,]*),(.*)$" );
210  re1.setMinimal( true );
212 
213  s.readLine();
214 
215  while ( !s.atEnd() )
216  {
217  QString l = s.readLine().trimmed();
218 
219  QString key, val;
220  if ( re0.indexIn( l ) >= 0 && re0.captureCount() == 2 )
221  {
222  key = re0.cap( 1 ).trimmed();
223  val = re0.cap( 2 ).trimmed();
224  }
225  else if ( re1.indexIn( l ) >= 0 && re1.captureCount() == 2 )
226  {
227  key = re1.cap( 1 ).trimmed();
228  val = re1.cap( 2 ).trimmed();
229  }
230  else
231  continue;
232 
233  if (( key.startsWith( '\"' ) && key.endsWith( '\"' ) ) ||
234  ( key.startsWith( '\'' ) && key.endsWith( '\'' ) ) )
235  {
236  key = key.mid( 1, key.length() - 2 );
237  }
238 
239  if (( val.startsWith( '\"' ) && val.endsWith( '\"' ) ) ||
240  ( val.startsWith( '\'' ) && val.endsWith( '\'' ) ) )
241  {
242  val = val.mid( 1, val.length() - 2 );
243  }
244 
245  if ( key == settings.value( "qgis/nullValue", "NULL" ).toString() )
246  key = QString( VALUEMAP_NULL_TEXT );
247 
248  map[ key ] = val;
249  }
250 
251  updateMap( map, false );
252 }
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
QVariantMap QgsEditorWidgetConfig
Holds a set of configuration parameters for a editor widget wrapper.
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()
void changed()
Emitted when the configuration of the widget is changed.
QString text() const
void setItalic(bool enable)
bool contains(const T &value) const
QVariant value(const QString &key, const QVariant &defaultValue) const
void setFlags(QFlags< Qt::ItemFlag > flags)
QString mid(int position, int n) const
int length() const
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
Qt::ItemFlags flags() const
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
void setFont(const QFont &font)
#define VALUEMAP_NULL_TEXT