Skip to content

Commit c3f6fb8

Browse files
author
wonder
committed
[FEATURE] Honour the edit widgets settings also in attribute table.
git-svn-id: http://svn.osgeo.org/qgis/trunk@11150 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 39520b1 commit c3f6fb8

File tree

3 files changed

+299
-11
lines changed

3 files changed

+299
-11
lines changed

src/app/attributetable/qgsattributetabledelegate.cpp

+281-10
Original file line numberDiff line numberDiff line change
@@ -15,38 +15,183 @@
1515

1616
#include <QItemDelegate>
1717
#include <QLineEdit>
18+
#include <QComboBox>
1819
#include <QPainter>
20+
#include <QCompleter>
21+
#include <QSpinBox>
22+
#include <QDoubleSpinBox>
1923

2024
#include "qgsattributetableview.h"
2125
#include "qgsattributetablemodel.h"
26+
#include "qgsattributetablefiltermodel.h"
2227
#include "qgsattributetabledelegate.h"
2328
#include "qgsvectordataprovider.h"
29+
#include "qgsvectorlayer.h"
30+
#include "qgsuniquevaluerenderer.h"
31+
#include "qgssymbol.h"
32+
2433

2534
QWidget * QgsAttributeTableDelegate::createEditor(
2635
QWidget *parent,
2736
const QStyleOptionViewItem &option,
2837
const QModelIndex &index ) const
2938
{
30-
QWidget *editor = QItemDelegate::createEditor( parent, option, index );
31-
32-
QLineEdit *le = dynamic_cast<QLineEdit*>( editor );
33-
if ( !le ) return editor;
39+
QWidget *editor;
3440

35-
const QgsAttributeTableModel* m = dynamic_cast<const QgsAttributeTableModel*>( index.model() );
36-
if ( !m ) return editor;
41+
const QgsAttributeTableFilterModel* fm = dynamic_cast<const QgsAttributeTableFilterModel*>( index.model() );
42+
if ( !fm )
43+
{
44+
return editor;
45+
}
46+
const QgsAttributeTableModel* m = dynamic_cast<const QgsAttributeTableModel*>( fm->sourceModel() );
47+
if ( !m )
48+
{
49+
return editor;
50+
}
3751

3852
int col = index.column();
3953
QVariant::Type type = m->layer()->dataProvider()->fields()[col].type();
54+
QgsVectorLayer::EditType editType = m->layer()->editType(col);
55+
56+
//need to created correct edit widget according to edit type of value
57+
//and fill with data from correct source
58+
if (editType == QgsVectorLayer::LineEdit ||
59+
editType == QgsVectorLayer::UniqueValuesEditable ||
60+
editType == QgsVectorLayer::FileName ||
61+
editType == QgsVectorLayer::Immutable)
62+
{ //these are all siple edits
63+
editor = new QLineEdit(parent);
64+
QLineEdit* le = dynamic_cast<QLineEdit*> ( editor );
65+
le-> setReadOnly ( false );
66+
67+
if ( editType == QgsVectorLayer::UniqueValuesEditable )
68+
{ //just this value has completer
69+
QList<QVariant> values;
70+
m->layer()->dataProvider()->uniqueValues( col, values );
71+
72+
QStringList svalues;
73+
for ( QList<QVariant>::const_iterator it = values.begin(); it != values.end(); it++ )
74+
svalues << it->toString();
75+
76+
QCompleter *c = new QCompleter( svalues );
77+
c->setCompletionMode( QCompleter::PopupCompletion );
78+
le->setCompleter( c );
79+
}
80+
if (editType == QgsVectorLayer::Immutable)
81+
{
82+
le->setReadOnly(true);
83+
}
84+
//validators if value needs it
85+
if ( type == QVariant::Int )
86+
{
87+
le->setValidator( new QIntValidator( le ) );
88+
}
89+
else if ( type == QVariant::Double )
90+
{
91+
le->setValidator( new QDoubleValidator( le ) );
92+
}
93+
}
94+
else if (editType == QgsVectorLayer::ValueMap)
95+
{ //simple combobox from data from vector layer
96+
editor = new QComboBox(parent);
97+
QComboBox* cb = dynamic_cast<QComboBox*>( editor );
98+
QMap<QString, QVariant> &map = m->layer()->valueMap(col);
99+
QMap<QString, QVariant>::iterator it = map.begin();
100+
for ( ; it != map.end(); it ++)
101+
{
102+
cb->addItem( it.key() ,it.value());
103+
}
104+
}
105+
else if (editType == QgsVectorLayer::SliderRange)
106+
{ //horizontal slider
107+
editor = new QSlider(Qt::Horizontal, parent);
108+
QSlider* s = dynamic_cast<QSlider*>(editor );
109+
QgsVectorLayer::RangeData &range = m->layer()->range(col);
110+
s->setMinimum( range.mMin.toInt() );
111+
s->setMaximum( range.mMax.toInt() );
112+
s->setPageStep( range.mStep.toInt() );
113+
}
114+
else if (editType == QgsVectorLayer::Classification)
115+
{
116+
// should be prepared probably to not change it always
117+
int classificationField = -1;
118+
QMap<QString, QString> classes;
119+
const QgsUniqueValueRenderer *uvr = dynamic_cast<const QgsUniqueValueRenderer *>( m->layer()->renderer() );
120+
if ( uvr )
121+
{
122+
classificationField = uvr->classificationField();
123+
const QList<QgsSymbol *> symbols = uvr->symbols();
124+
125+
for ( int i = 0; i < symbols.size(); i++ )
126+
{
127+
QString label = symbols[i]->label();
128+
QString name = symbols[i]->lowerValue();
129+
if ( label == "" )
130+
label = name;
131+
classes.insert( name, label );
132+
}
133+
}
134+
editor = new QComboBox(parent);
135+
QComboBox* cb = dynamic_cast<QComboBox*>( editor );
136+
for ( QMap<QString, QString>::const_iterator it = classes.begin(); it != classes.end(); it++ )
137+
{
138+
cb->addItem( it.value(), it.key() );
139+
}
140+
}
141+
else if (editType == QgsVectorLayer::UniqueValues)
142+
{
143+
QList<QVariant> values;
144+
m->layer()->dataProvider()->uniqueValues( col, values );
145+
146+
editor = new QComboBox(parent);
147+
QComboBox* cb = dynamic_cast<QComboBox*>( editor );
148+
cb->setEditable( true );
40149

41-
if ( type == QVariant::Int )
150+
for ( QList<QVariant>::iterator it = values.begin(); it != values.end(); it++ )
151+
cb->addItem( it->toString() );
152+
153+
}
154+
else if (editType == QgsVectorLayer::Enumeration)
42155
{
43-
le->setValidator( new QIntValidator( le ) );
156+
QStringList enumValues;
157+
m->layer()->dataProvider()->enumValues( col, enumValues );
158+
159+
editor = new QComboBox(parent);
160+
QComboBox* cb = dynamic_cast<QComboBox*>( editor );
161+
QStringList::const_iterator s_it = enumValues.constBegin();
162+
for ( ; s_it != enumValues.constEnd(); ++s_it )
163+
{
164+
cb->addItem( *s_it );
165+
}
44166
}
45-
else if ( type == QVariant::Double )
167+
else if (editType == QgsVectorLayer::EditRange)
46168
{
47-
le->setValidator( new QDoubleValidator( le ) );
169+
if ( type == QVariant::Int )
170+
{
171+
int min = m->layer()->range( col ).mMin.toInt();
172+
int max = m->layer()->range( col ).mMax.toInt();
173+
int step = m->layer()->range( col ).mStep.toInt();
174+
editor = new QSpinBox(parent);
175+
QSpinBox* sb = dynamic_cast<QSpinBox*>( editor );
176+
177+
sb->setRange( min, max );
178+
sb->setSingleStep( step );
179+
180+
}
181+
else if ( type == QVariant::Double )
182+
{
183+
double min = m->layer()->range( col ).mMin.toDouble();
184+
double max = m->layer()->range( col ).mMax.toDouble();
185+
double step = m->layer()->range( col ).mStep.toDouble();
186+
editor = new QDoubleSpinBox(parent);
187+
QDoubleSpinBox* dsb = dynamic_cast<QDoubleSpinBox*>( editor );
188+
189+
dsb->setRange( min, max );
190+
dsb->setSingleStep( step );
191+
}
48192
}
49193

194+
50195
return editor;
51196
}
52197

@@ -68,3 +213,129 @@ void QgsAttributeTableDelegate::paint( QPainter * painter,
68213
}
69214
}
70215

216+
217+
void QgsAttributeTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
218+
{
219+
220+
221+
const QgsAttributeTableFilterModel* fm = dynamic_cast<const QgsAttributeTableFilterModel*>( index.model() );
222+
if ( !fm )
223+
{
224+
return;
225+
}
226+
const QgsAttributeTableModel* m = dynamic_cast<const QgsAttributeTableModel*>( fm->sourceModel() );
227+
if ( !m )
228+
{
229+
return;
230+
}
231+
int col = index.column();
232+
QVariant::Type type = m->layer()->dataProvider()->fields()[col].type();
233+
QgsVectorLayer::EditType editType = m->layer()->editType(col);
234+
if (editType == QgsVectorLayer::LineEdit ||
235+
editType == QgsVectorLayer::UniqueValuesEditable ||
236+
editType == QgsVectorLayer::FileName ||
237+
editType == QgsVectorLayer::Immutable)
238+
{
239+
QString qs = index.model()->data(index, Qt::DisplayRole).toString();
240+
241+
QLineEdit* le = dynamic_cast<QLineEdit*> ( editor );
242+
le->setText( qs );
243+
}
244+
else if (editType == QgsVectorLayer::ValueMap ||
245+
editType == QgsVectorLayer::Classification ||
246+
editType == QgsVectorLayer::UniqueValues ||
247+
editType == QgsVectorLayer::Enumeration)
248+
{
249+
QComboBox* cb = dynamic_cast<QComboBox*>( editor );
250+
QVariant qs = index.model()->data(index, Qt::EditRole);
251+
int cbIndex = cb->findData(qs);
252+
if (cbIndex > -1)
253+
{
254+
cb->setCurrentIndex(cbIndex);
255+
}
256+
}
257+
else if (editType == QgsVectorLayer::SliderRange)
258+
{
259+
int value = index.model()->data(index, Qt::EditRole).toInt();
260+
QSlider* s = dynamic_cast<QSlider*>( editor );
261+
s->setValue( value );
262+
}
263+
else if (editType == QgsVectorLayer::EditRange)
264+
{
265+
if ( type == QVariant::Int )
266+
{
267+
QSpinBox* sb = dynamic_cast<QSpinBox*>( editor );
268+
int value = index.model()->data(index, Qt::EditRole).toInt();
269+
sb->setValue( value );
270+
}
271+
else if ( type == QVariant::Double )
272+
{
273+
QDoubleSpinBox* sb = dynamic_cast<QDoubleSpinBox*>( editor );
274+
double value = index.model()->data(index, Qt::EditRole).toDouble();
275+
sb->setValue( value );
276+
}
277+
}
278+
}
279+
280+
281+
282+
void QgsAttributeTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
283+
{
284+
const QgsAttributeTableFilterModel* fm = dynamic_cast<const QgsAttributeTableFilterModel*>( index.model() );
285+
if ( !fm )
286+
{
287+
return;
288+
}
289+
const QgsAttributeTableModel* m = dynamic_cast<const QgsAttributeTableModel*>( fm->sourceModel() );
290+
if ( !m )
291+
{
292+
return;
293+
}
294+
295+
int col = index.column();
296+
QVariant::Type type = m->layer()->dataProvider()->fields()[col].type();
297+
QgsVectorLayer::EditType editType = m->layer()->editType(col);
298+
if (editType == QgsVectorLayer::LineEdit ||
299+
editType == QgsVectorLayer::UniqueValuesEditable ||
300+
editType == QgsVectorLayer::FileName ||
301+
editType == QgsVectorLayer::Immutable)
302+
{
303+
QLineEdit* le = dynamic_cast<QLineEdit*> ( editor );
304+
QString text = le->text();
305+
QVariant value = QVariant (text);
306+
model->setData( index, value );
307+
}
308+
else if (editType == QgsVectorLayer::ValueMap ||
309+
editType == QgsVectorLayer::Classification ||
310+
editType == QgsVectorLayer::UniqueValues ||
311+
editType == QgsVectorLayer::Enumeration)
312+
{
313+
QComboBox* cb = dynamic_cast<QComboBox*>( editor );
314+
model->setData(index, cb->itemData(cb->currentIndex()));
315+
}
316+
else if (editType == QgsVectorLayer::SliderRange)
317+
{
318+
QSlider* s = dynamic_cast<QSlider*>( editor );
319+
model->setData( index, s->value() );
320+
}
321+
else if (editType == QgsVectorLayer::EditRange)
322+
{
323+
if ( type == QVariant::Int )
324+
{
325+
QSpinBox* sb = dynamic_cast<QSpinBox*>( editor );
326+
model->setData( index, sb->value() );
327+
}
328+
else if ( type == QVariant::Double )
329+
{
330+
QDoubleSpinBox* sb = dynamic_cast<QDoubleSpinBox*>( editor );
331+
model->setData( index, sb->value() );
332+
}
333+
}
334+
}
335+
336+
337+
338+
339+
340+
341+

src/app/attributetable/qgsattributetabledelegate.h

+17
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define QGSATTRIBUTETABLEDELEGATE_H
1818

1919
#include <QItemDelegate>
20+
#include "qgsvectorlayer.h"
2021
class QPainter;
2122
/** \ingroup app
2223
* A delegate item class for QgsAttributeTable (see Qt documentation for
@@ -43,6 +44,22 @@ class QgsAttributeTableDelegate : public QItemDelegate
4344
QPainter * painter,
4445
const QStyleOptionViewItem & option,
4546
const QModelIndex & index ) const;
47+
48+
/**
49+
* Sets data to editor widget. Overloads default metod
50+
* @param editor editor which was created by create editor function in this class
51+
* @param index index of field which is to be modified
52+
*/
53+
void setEditorData(QWidget *editor, const QModelIndex &index) const;
54+
55+
/**
56+
* Sets data from editor backk to model. Overloads default metod
57+
* @param editor editor which was created by create editor function in this class
58+
* @param model model where data should be updated
59+
* @param index index of field which is to be modified
60+
*/
61+
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
62+
4663
};
4764

4865
#endif //QGSATTRIBUTETABLEDELEGATE_H

src/app/attributetable/qgsattributetablemodel.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ void QgsAttributeTableModel::layerModified( bool onlyGeometry )
144144

145145
loadLayer();
146146
emit modelChanged();
147-
emit headerDataChanged( Qt::Horizontal, 0, columnCount() );
147+
emit headerDataChanged ( Qt::Horizontal, 0, columnCount() - 1);
148148
}
149149

150150
void QgsAttributeTableModel::loadLayer()

0 commit comments

Comments
 (0)