Skip to content

Commit a1719bd

Browse files
author
timlinux
committedMay 30, 2008
Gui cleanups for attribute capture when digitising. Create a dynamically generated dialog rather than using a table widget.
git-svn-id: http://svn.osgeo.org/qgis/trunk@8556 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent bd5ec63 commit a1719bd

File tree

4 files changed

+169
-194
lines changed

4 files changed

+169
-194
lines changed
 

‎src/app/qgsattributedialog.cpp

Lines changed: 112 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -22,148 +22,142 @@
2222
#include <QTableWidgetItem>
2323
#include <QSettings>
2424
#include <QLineEdit>
25-
26-
QgsAttributeDialog::QgsAttributeDialog(const QgsFieldMap& fields, const QgsAttributeMap& attributes)
25+
#include <QSpinBox>
26+
#include <QLabel>
27+
#include <QDoubleSpinBox>
28+
#include <QFrame>
29+
#include <QScrollArea>
30+
31+
QgsAttributeDialog::QgsAttributeDialog(
32+
QgsFieldMap theFieldMap, QgsFeature * thepFeature)
2733
: QDialog(),
28-
_settingsPath("/Windows/AttributeDialog/"),
29-
mRowIsDirty(attributes.size(), FALSE)
34+
mSettingsPath("/Windows/AttributeDialog/"),
35+
mFieldMap(theFieldMap),
36+
mpFeature(thepFeature)
3037
{
31-
restorePositionAndColumnWidth();
32-
33-
setupUi(this);
34-
mTable->setRowCount(attributes.size());
3538

36-
int index=0;
37-
for (QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); ++it)
39+
setupUi(this);
40+
if (mpFeature==NULL) return;
41+
if (mFieldMap.isEmpty()) return;
42+
QgsAttributeMap myAttributes = mpFeature->attributeMap();
43+
//
44+
//Set up dynamic inside a scroll box
45+
//
46+
QVBoxLayout * mypOuterLayout = new QVBoxLayout();
47+
mypOuterLayout->setContentsMargins(0,0,0,0);
48+
//transfers layout ownership so no need to call delete
49+
mFrame->setLayout(mypOuterLayout);
50+
QScrollArea * mypScrollArea = new QScrollArea();
51+
//transfers scroll area ownership so no need to call delete
52+
mypOuterLayout->addWidget(mypScrollArea);
53+
QFrame * mypInnerFrame = new QFrame();
54+
mypInnerFrame->setFrameShape(QFrame::NoFrame);
55+
mypInnerFrame->setFrameShadow(QFrame::Plain);
56+
//transfers frame ownership so no need to call delete
57+
mypScrollArea->setWidget(mypInnerFrame);
58+
mypScrollArea->setWidgetResizable( true );
59+
QGridLayout * mypInnerLayout = new QGridLayout(mypInnerFrame);
60+
61+
int index=0;
62+
for (QgsAttributeMap::const_iterator it = myAttributes.begin();
63+
it != myAttributes.end();
64+
++it)
65+
{
66+
QString myFieldName = mFieldMap[it.key()].name();
67+
QLabel * mypLabel = new QLabel();
68+
mypInnerLayout->addWidget(mypLabel,index,0);
69+
QVariant myFieldValue = it.value();
70+
QLineEdit * mypLineEdit = new QLineEdit();
71+
//the provider may have provided a default value so use it
72+
mypLineEdit->setText(myFieldValue.toString());
73+
if( mFieldMap[it.key()].type()==QVariant::Int )
3874
{
39-
// set attribute name
40-
41-
QString fieldName = fields[it.key()].name();
42-
43-
QTableWidgetItem * myFieldItem = new QTableWidgetItem(fieldName);
44-
myFieldItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
45-
mTable->setItem(index, 0, myFieldItem);
46-
47-
#if QT_VERSION >= 0x040400
48-
// set attribute value
49-
QTableWidgetItem * myValueItem = new QTableWidgetItem((*it).toString());
50-
mTable->setItem(index, 1, myValueItem);
51-
#endif
52-
53-
QLineEdit *le = new QLineEdit();
54-
55-
le->setFrame(false);
56-
57-
if( fields[it.key()].type()==QVariant::Int )
58-
{
59-
le->setValidator( new QIntValidator(le) );
60-
}
61-
else if( fields[it.key()].type()==QVariant::Double )
62-
{
63-
le->setValidator( new QDoubleValidator(le) );
64-
}
65-
66-
#if QT_VERSION < 0x040400
67-
le->setText((*it).toString());
68-
#endif
69-
70-
mTable->setCellWidget(index, 1, le);
71-
72-
++index;
75+
mypLineEdit->setValidator( new QIntValidator(mypLineEdit) );
76+
mypLabel->setText(myFieldName + tr(" (int)"));
7377
}
74-
75-
// setup the mechanism to track edited attribute values
76-
// if we do it this way, only edited attributes will
77-
// be attempted to be saved when the editing session stops.
78-
connect(mTable, SIGNAL(cellChanged(int, int)),
79-
this, SLOT (setAttributeValueChanged(int, int)));
80-
81-
mTable->resizeColumnsToContents();
82-
}
83-
84-
QgsAttributeDialog::~QgsAttributeDialog()
85-
{
86-
78+
else if( mFieldMap[it.key()].type()==QVariant::Double )
79+
{
80+
mypLineEdit->setValidator( new QDoubleValidator(mypLineEdit) );
81+
mypLabel->setText(myFieldName + tr(" (dbl)"));
82+
}
83+
else //string
84+
{
85+
//any special behaviour for string goes here
86+
mypLabel->setText(myFieldName + tr(" (txt)"));
87+
}
88+
mypInnerLayout->addWidget(mypLineEdit,index,1);
89+
mpWidgets << mypLineEdit;
90+
++index;
91+
}
92+
restoreGeometry();
8793
}
8894

89-
QString QgsAttributeDialog::value(int row)
90-
{
91-
return static_cast<QLineEdit*>(mTable->cellWidget(row,1))->text();
92-
}
9395

94-
bool QgsAttributeDialog::isDirty(int row)
96+
QgsAttributeDialog::~QgsAttributeDialog()
9597
{
96-
return mRowIsDirty.at(row);
98+
saveGeometry();
9799
}
98-
99-
bool QgsAttributeDialog::queryAttributes(const QgsFieldMap& fields, QgsFeature& f)
100+
101+
void QgsAttributeDialog::accept()
100102
{
101-
QgsAttributeMap featureAttributes = f.attributeMap();
102-
QgsAttributeDialog attdialog(fields, featureAttributes);
103-
104-
if (attdialog.exec() == QDialog::Accepted)
103+
//write the new values back to the feature
104+
QgsAttributeMap myAttributes = mpFeature->attributeMap();
105+
int myIndex=0;
106+
for (QgsAttributeMap::const_iterator it = myAttributes.begin();
107+
it != myAttributes.end();
108+
++it)
105109
{
106-
int i=0;
107-
for (QgsAttributeMap::const_iterator it = featureAttributes.begin(); it != featureAttributes.end(); ++it, i++)
110+
//Q_ASSERT(myIndex <= mpWidgets.size());
111+
QString myFieldName = mFieldMap[it.key()].name();
112+
bool myFlag=false;
113+
QString myFieldValue =
114+
dynamic_cast<QLineEdit *>(mpWidgets.value(myIndex))->text();
115+
switch( mFieldMap[it.key()].type() )
108116
{
109-
QString value = attdialog.value(i);
110-
111-
if( attdialog.isDirty(i) )
112-
{
113-
switch( fields[it.key()].type() )
117+
case QVariant::Int:
114118
{
115-
case QVariant::Int:
116-
f.changeAttribute(it.key(), value=="" ? QVariant( QString::null ) : QVariant( value.toInt() ) );
117-
break;
118-
119-
case QVariant::Double:
120-
f.changeAttribute(it.key(), value=="" ? QVariant( QString::null ) : QVariant( value.toDouble() ) );
121-
break;
122-
123-
default:
124-
f.changeAttribute(it.key(), value=="NULL" ? QVariant(QString::null) : QVariant(value) );
125-
break;
119+
int myIntValue = myFieldValue.toInt(&myFlag);
120+
if (myFlag && ! myFieldValue.isEmpty())
121+
{
122+
mpFeature->changeAttribute( it.key(), QVariant(myIntValue) );
123+
}
124+
else
125+
{
126+
mpFeature->changeAttribute( it.key(), QVariant(QString::null) );
127+
}
128+
}
129+
break;
130+
case QVariant::Double:
131+
{
132+
double myDblValue = myFieldValue.toDouble(&myFlag);
133+
if (myFlag && ! myFieldValue.isEmpty())
134+
{
135+
mpFeature->changeAttribute( it.key(), QVariant(myDblValue) );
136+
}
137+
else
138+
{
139+
mpFeature->changeAttribute( it.key(), QVariant(QString::null) );
140+
}
126141
}
127-
} else {
128-
f.changeAttribute(it.key(), QVariant(value) );
129-
}
142+
break;
143+
default: //string
144+
mpFeature->changeAttribute(it.key(),QVariant( myFieldValue ) );
145+
break;
130146
}
131-
return true;
132-
}
133-
else
134-
{
135-
return false;
147+
++myIndex;
136148
}
149+
QDialog::accept();
137150
}
138151

139-
void QgsAttributeDialog::savePositionAndColumnWidth()
152+
void QgsAttributeDialog::saveGeometry()
140153
{
141154
QSettings settings;
142-
settings.setValue(_settingsPath+"geometry", saveGeometry());
155+
settings.setValue(mSettingsPath+"geometry", QDialog::saveGeometry());
143156
}
144157

145-
void QgsAttributeDialog::resizeEvent(QResizeEvent *event)
146-
{
147-
savePositionAndColumnWidth();
148-
QWidget::resizeEvent(event);
149-
}
150-
151-
void QgsAttributeDialog::moveEvent(QMoveEvent *event)
152-
{
153-
savePositionAndColumnWidth();
154-
QWidget::moveEvent(event);
155-
}
156-
157-
void QgsAttributeDialog::restorePositionAndColumnWidth()
158+
void QgsAttributeDialog::restoreGeometry()
158159
{
159160
QSettings settings;
160-
restoreGeometry(settings.value(_settingsPath+"geometry").toByteArray());
161+
QDialog::restoreGeometry(settings.value(mSettingsPath+"geometry").toByteArray());
161162
}
162163

163-
void QgsAttributeDialog::setAttributeValueChanged(int row, int column)
164-
{
165-
QgsDebugMsg("Entered with row " + QString::number(row) +
166-
", column " + QString::number(column) + ".");
167-
168-
mRowIsDirty.at(row) = TRUE;
169-
}

‎src/app/qgsattributedialog.h

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,49 +25,36 @@
2525

2626
class QDialog;
2727
class QgsFeature;
28-
28+
class QLayout;
2929
class QgsField;
3030
typedef QMap<int, QgsField> QgsFieldMap;
3131

3232
class QgsAttributeDialog: public QDialog, private Ui::QgsAttributeDialogBase
3333
{
34-
Q_OBJECT
34+
Q_OBJECT;
3535

3636
public:
37-
QgsAttributeDialog(const QgsFieldMap& fields, const QgsAttributeMap& attributes);
38-
39-
~QgsAttributeDialog();
40-
41-
/** Returns if the field value of a row was edited since this dialog opened */
42-
bool isDirty(int row);
43-
44-
/** Opens an attribute dialog and queries the attributes for a given feature. The
45-
attribute values are set to the feature if the dialog is accepted.
46-
\retval true if accepted
47-
\retval false if canceled */
48-
static bool queryAttributes(const QgsFieldMap& fields, QgsFeature& f);
49-
50-
// Saves and restores the size and position from the last time
51-
// this dialog box was used.
52-
void savePositionAndColumnWidth();
53-
54-
void restorePositionAndColumnWidth();
55-
56-
void resizeEvent(QResizeEvent *event);
57-
58-
void moveEvent(QMoveEvent *event);
59-
60-
public slots:
61-
//! Slot to be called when an attribute value is edited in the table.
62-
void setAttributeValueChanged(int row, int column);
37+
QgsAttributeDialog(const QgsFieldMap thepFieldMap, QgsFeature * thepFeature);
38+
~QgsAttributeDialog();
39+
40+
/** Overloaded accept method which will write the feature field
41+
* values, then delegate to QDialog::accept()
42+
*/
43+
void accept();
44+
/** Saves the size and position for the next time
45+
* this dialog box was used.
46+
*/
47+
void saveGeometry();
48+
/** Restores the size and position from the last time
49+
* this dialog box was used.
50+
*/
51+
void restoreGeometry();
6352

6453
private:
65-
QString _settingsPath;
66-
67-
/** Returns the field value of a row */
68-
QString value(int row);
69-
70-
std::vector<bool> mRowIsDirty;
54+
QString mSettingsPath;
55+
QList<QWidget *> mpWidgets;
56+
QgsFieldMap mFieldMap;
57+
QgsFeature * mpFeature;
7158
};
7259

7360
#endif

‎src/app/qgsmaptooladdfeature.cpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,23 @@ void QgsMapToolAddFeature::canvasReleaseEvent(QMouseEvent * e)
170170
// add the fields to the QgsFeature
171171
const QgsFieldMap fields=provider->fields();
172172
for(QgsFieldMap::const_iterator it = fields.constBegin(); it != fields.constEnd(); ++it)
173-
{
174-
f->addAttribute(it.key(), provider->getDefaultValue(it.key()) );
175-
}
173+
{
174+
f->addAttribute(it.key(), provider->getDefaultValue(it.key()) );
175+
}
176176

177177
// show the dialog to enter attribute values
178-
if (QgsAttributeDialog::queryAttributes(fields, *f))
178+
QgsAttributeDialog * mypDialog = new QgsAttributeDialog(fields,f );
179+
if (mypDialog->exec())
180+
{
181+
qDebug("Adding feature to layer");
179182
vlayer->addFeature(*f);
183+
}
180184
else
185+
{
186+
qDebug("Adding feature to layer failed");
181187
delete f;
182-
188+
}
189+
delete mypDialog;
183190
mCanvas->refresh();
184191
}
185192

@@ -429,19 +436,21 @@ void QgsMapToolAddFeature::canvasReleaseEvent(QMouseEvent * e)
429436
f->addAttribute(it.key(), provider->getDefaultValue(it.key()));
430437
}
431438

432-
if (QgsAttributeDialog::queryAttributes(fields, *f))
433-
{
434-
if(vlayer->addFeature(*f))
435-
{
436-
//add points to other features to keep topology up-to-date
437-
int topologicalEditing = QgsProject::instance()->readNumEntry("Digitizing", "/TopologicalEditing", 0);
438-
if(topologicalEditing)
439-
{
440-
vlayer->addTopologicalPoints(f->geometry());
441-
}
442-
}
443-
}
439+
QgsAttributeDialog * mypDialog = new QgsAttributeDialog(fields,f );
440+
if (mypDialog->exec())
441+
{
442+
if(vlayer->addFeature(*f))
443+
{
444+
//add points to other features to keep topology up-to-date
445+
int topologicalEditing = QgsProject::instance()->readNumEntry("Digitizing", "/TopologicalEditing", 0);
446+
if(topologicalEditing)
447+
{
448+
vlayer->addTopologicalPoints(f->geometry());
449+
}
450+
}
451+
}
444452
delete f;
453+
delete mypDialog;
445454

446455
// delete the elements of mCaptureList
447456
mCaptureList.clear();

‎src/ui/qgsattributedialogbase.ui

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,25 @@
55
<rect>
66
<x>0</x>
77
<y>0</y>
8-
<width>329</width>
9-
<height>330</height>
8+
<width>447</width>
9+
<height>343</height>
1010
</rect>
1111
</property>
1212
<property name="windowTitle" >
1313
<string>Enter Attribute Values</string>
1414
</property>
1515
<layout class="QGridLayout" >
1616
<item row="0" column="0" >
17-
<widget class="QTableWidget" name="mTable" >
18-
<property name="columnCount" >
19-
<number>2</number>
17+
<widget class="QFrame" name="mFrame" >
18+
<property name="frameShape" >
19+
<enum>QFrame::StyledPanel</enum>
20+
</property>
21+
<property name="frameShadow" >
22+
<enum>QFrame::Raised</enum>
2023
</property>
21-
<row>
22-
<property name="text" >
23-
<string>1</string>
24-
</property>
25-
</row>
26-
<column>
27-
<property name="text" >
28-
<string>Attribute</string>
29-
</property>
30-
</column>
31-
<column>
32-
<property name="text" >
33-
<string>Value</string>
34-
</property>
35-
</column>
3624
</widget>
3725
</item>
38-
<item row="1" column="0" >
26+
<item row="2" column="0" >
3927
<widget class="QDialogButtonBox" name="buttonBox" >
4028
<property name="standardButtons" >
4129
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
@@ -45,9 +33,6 @@
4533
</layout>
4634
</widget>
4735
<layoutdefault spacing="6" margin="11" />
48-
<tabstops>
49-
<tabstop>mTable</tabstop>
50-
</tabstops>
5136
<resources/>
5237
<connections>
5338
<connection>
@@ -58,7 +43,7 @@
5843
<hints>
5944
<hint type="sourcelabel" >
6045
<x>277</x>
61-
<y>305</y>
46+
<y>318</y>
6247
</hint>
6348
<hint type="destinationlabel" >
6449
<x>325</x>

0 commit comments

Comments
 (0)
Please sign in to comment.