Skip to content

Commit 43a7350

Browse files
author
mhugent
committed
Possibility to add/remove attributes also in attribute table. Small modification to attribute table such that adding / removing columns is visible
git-svn-id: http://svn.osgeo.org/qgis/trunk@11862 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent f130f10 commit 43a7350

7 files changed

+202
-53
lines changed

src/app/attributetable/qgsattributetabledialog.cpp

+75
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include <qgssearchtreenode.h>
2929

3030
#include "qgisapp.h"
31+
#include "qgsaddattrdialog.h"
32+
#include "qgsdelattrdialog.h"
3133
#include "qgssearchquerybuilder.h"
3234
#include "qgslogger.h"
3335
#include "qgsmapcanvas.h"
@@ -88,11 +90,18 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
8890
mInvertSelectionButton->setIcon( getThemeIcon( "/mActionInvertSelection.png" ) );
8991
mToggleEditingButton->setIcon( getThemeIcon( "/mActionToggleEditing.png" ) );
9092
mOpenFieldCalculator->setIcon( getThemeIcon( "/mActionCalculateField.png" ) );
93+
mAddAttribute->setIcon( getThemeIcon( "/mActionNewAttribute.png" ) );
94+
mRemoveAttribute->setIcon( getThemeIcon( "/mActionDeleteAttribute.png" ) );
95+
9196
// toggle editing
9297
bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
98+
bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes;
99+
bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes;
93100
mToggleEditingButton->setCheckable( true );
94101
mToggleEditingButton->setEnabled( canChangeAttributes );
95102
mOpenFieldCalculator->setEnabled( canChangeAttributes && mLayer->isEditable() );
103+
mAddAttribute->setEnabled( canAddAttributes && mLayer->isEditable() );
104+
mRemoveAttribute->setEnabled( canDeleteAttributes && mLayer->isEditable() );
96105

97106
// info from table to application
98107
connect( this, SIGNAL( editingToggled( QgsMapLayer * ) ), QgisApp::instance(), SLOT( toggleEditing( QgsMapLayer * ) ) );
@@ -526,7 +535,11 @@ void QgsAttributeTableDialog::editingToggled()
526535
mToggleEditingButton->blockSignals( false );
527536

528537
bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
538+
bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes;
539+
bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes;
529540
mOpenFieldCalculator->setEnabled( canChangeAttributes && mLayer->isEditable() );
541+
mAddAttribute->setEnabled( canAddAttributes && mLayer->isEditable() );
542+
mRemoveAttribute->setEnabled( canDeleteAttributes && mLayer->isEditable() );
530543

531544
// (probably reload data if user stopped editing - possible revert)
532545
mModel->reload( mModel->index( 0, 0 ), mModel->index( mModel->rowCount(), mModel->columnCount() ) );
@@ -555,6 +568,68 @@ void QgsAttributeTableDialog::revert()
555568
mModel->reload( mModel->index( 0, 0 ), mModel->index( mModel->rowCount(), mModel->columnCount() ) );
556569
}
557570

571+
void QgsAttributeTableDialog::on_mAddAttribute_clicked()
572+
{
573+
if ( !mLayer )
574+
{
575+
return;
576+
}
577+
578+
QgsAddAttrDialog dialog( mLayer->dataProvider(), this );
579+
if ( dialog.exec() == QDialog::Accepted )
580+
{
581+
mLayer->beginEditCommand( tr( "Attribute added" ) );
582+
if ( mLayer->addAttribute( dialog.field() ) )
583+
{
584+
mLayer->endEditCommand();
585+
}
586+
else
587+
{
588+
QMessageBox::critical( 0, tr( "Attribute Error" ), tr( "The attribute could not be added to the layer" ) );
589+
mLayer->destroyEditCommand();
590+
}
591+
}
592+
}
593+
594+
void QgsAttributeTableDialog::on_mRemoveAttribute_clicked()
595+
{
596+
if ( !mLayer )
597+
{
598+
return;
599+
}
600+
601+
QgsDelAttrDialog dialog( mLayer );
602+
if ( dialog.exec() == QDialog::Accepted )
603+
{
604+
QList<int> attributes = dialog.selectedAttributes();
605+
if ( attributes.size() < 1 )
606+
{
607+
return;
608+
}
609+
610+
mLayer->beginEditCommand( tr( "Deleted attribute" ) );
611+
bool deleted = false;
612+
QList<int>::const_iterator it = attributes.constBegin();
613+
for ( ; it != attributes.constEnd(); ++it )
614+
{
615+
if ( mLayer->deleteAttribute( *it ) )
616+
{
617+
deleted = true;
618+
}
619+
}
620+
621+
if ( deleted )
622+
{
623+
mLayer->endEditCommand();
624+
}
625+
else
626+
{
627+
QMessageBox::critical( 0, tr( "Attribute Error" ), tr( "The attribute(s) could not be deleted" ) );
628+
mLayer->destroyEditCommand();
629+
}
630+
}
631+
}
632+
558633
void QgsAttributeTableDialog::on_mOpenFieldCalculator_clicked()
559634
{
560635
QgsFieldCalculator calc( mLayer );

src/app/attributetable/qgsattributetabledialog.h

+4
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ class QgsAttributeTableDialog : public QDialog, private Ui::QgsAttributeTableDia
132132
* Starts editing mode
133133
*/
134134
void startEditing();
135+
/**Opens dialog to add new attribute*/
136+
void on_mAddAttribute_clicked();
137+
/**Opens dialog to remove attribute*/
138+
void on_mRemoveAttribute_clicked();
135139
/**
136140
* Opens field calculator dialog
137141
*/

src/app/attributetable/qgsattributetablemodel.cpp

+56-22
Original file line numberDiff line numberDiff line change
@@ -34,29 +34,8 @@ QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayer *theLayer, QObjec
3434
mLastRow = NULL;
3535
mLayer = theLayer;
3636
mFeatureCount = mLayer->pendingFeatureCount();
37+
loadAttributes();
3738

38-
mFieldCount = 0;
39-
mAttributes.clear();
40-
mValueMaps.clear();
41-
42-
for ( QgsFieldMap::const_iterator it = theLayer->pendingFields().constBegin(); it != theLayer->pendingFields().end(); it++ )
43-
{
44-
switch ( mLayer->editType( it.key() ) )
45-
{
46-
case QgsVectorLayer::Hidden:
47-
continue;
48-
49-
case QgsVectorLayer::ValueMap:
50-
mValueMaps.insert( it.key(), &mLayer->valueMap( it.key() ) );
51-
break;
52-
53-
default:
54-
break;
55-
}
56-
57-
mFieldCount++;
58-
mAttributes << it.key();
59-
}
6039

6140
connect( mLayer, SIGNAL( layerModified( bool ) ), this, SLOT( layerModified( bool ) ) );
6241
//connect(mLayer, SIGNAL(attributeAdded(int)), this, SLOT( attributeAdded(int)));
@@ -168,11 +147,66 @@ void QgsAttributeTableModel::layerModified( bool onlyGeometry )
168147
if ( onlyGeometry )
169148
return;
170149

150+
loadAttributes();
171151
loadLayer();
172152
emit modelChanged();
173153
emit headerDataChanged( Qt::Horizontal, 0, columnCount() - 1 );
174154
}
175155

156+
void QgsAttributeTableModel::loadAttributes()
157+
{
158+
if ( !mLayer )
159+
{
160+
return;
161+
}
162+
163+
bool ins = false, rm = false;
164+
int pendingFieldCount = mLayer->pendingFields().size();
165+
166+
if ( mFieldCount < pendingFieldCount )
167+
{
168+
ins = true;
169+
beginInsertColumns( QModelIndex(), mFieldCount, pendingFieldCount - 1 );
170+
}
171+
else if ( pendingFieldCount < mFieldCount )
172+
{
173+
rm = true;
174+
beginRemoveColumns( QModelIndex(), pendingFieldCount, mFieldCount - 1 );
175+
}
176+
177+
mFieldCount = 0;
178+
mAttributes.clear();
179+
mValueMaps.clear();
180+
181+
for ( QgsFieldMap::const_iterator it = mLayer->pendingFields().constBegin(); it != mLayer->pendingFields().end(); it++ )
182+
{
183+
switch ( mLayer->editType( it.key() ) )
184+
{
185+
case QgsVectorLayer::Hidden:
186+
continue;
187+
188+
case QgsVectorLayer::ValueMap:
189+
mValueMaps.insert( it.key(), &mLayer->valueMap( it.key() ) );
190+
break;
191+
192+
default:
193+
break;
194+
}
195+
196+
mFieldCount++;
197+
mAttributes << it.key();
198+
}
199+
200+
if ( ins )
201+
{
202+
endInsertColumns();
203+
}
204+
else if ( rm )
205+
{
206+
endRemoveColumns();
207+
}
208+
}
209+
176210
void QgsAttributeTableModel::loadLayer()
177211
{
178212
QgsDebugMsg( "entered." );

src/app/attributetable/qgsattributetablemodel.h

+5
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ class QgsAttributeTableModel: public QAbstractTableModel
202202
*/
203203
virtual void loadLayer();
204204

205+
/**
206+
* Gets mFieldCount, mAttributes and mValueMaps
207+
*/
208+
virtual void loadAttributes();
209+
205210
/**
206211
* load feature fid into mFeat
207212
* @param fid feature id

src/app/qgsdelattrdialog.cpp

+15-14
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,32 @@
1717

1818
#include "qgsdelattrdialog.h"
1919
#include "qgsfield.h"
20-
#include <QHeaderView>
20+
#include "qgsvectorlayer.h"
2121

22-
QgsDelAttrDialog::QgsDelAttrDialog( QHeaderView* header ): QDialog()
22+
QgsDelAttrDialog::QgsDelAttrDialog( const QgsVectorLayer* vl ): QDialog()
2323
{
2424
setupUi( this );
25-
26-
//insert attribute names into the QListView
27-
if ( header )
25+
if ( vl )
2826
{
2927
listBox2->clear();
30-
QAbstractItemModel *model = header->model();
31-
for ( int i = 1;i < header->count();++i )
28+
const QgsFieldMap layerAttributes = vl->pendingFields();
29+
QgsFieldMap::const_iterator attIt = layerAttributes.constBegin();
30+
for ( ; attIt != layerAttributes.constEnd(); ++attIt )
3231
{
33-
listBox2->addItem( model->headerData( i, Qt::Horizontal ).toString() );
32+
QListWidgetItem* item = new QListWidgetItem( attIt.value().name(), listBox2 );
33+
item->setData( Qt::UserRole, attIt.key() );
3434
}
3535
}
3636
}
3737

38-
const std::list<QString>* QgsDelAttrDialog::selectedAttributes()
38+
QList<int> QgsDelAttrDialog::selectedAttributes()
3939
{
40-
mSelectedItems.clear();
41-
QListIterator<QListWidgetItem *> selection( listBox2->selectedItems() );
42-
while ( selection.hasNext() )
40+
QList<int> selectionList;
41+
QList<QListWidgetItem *> selection = listBox2->selectedItems();
42+
QList<QListWidgetItem *>::const_iterator itemIter = selection.constBegin();
43+
for ( ; itemIter != selection.constEnd(); ++itemIter )
4344
{
44-
mSelectedItems.push_back( selection.next()->text() );
45+
selectionList.push_back(( *itemIter )->data( Qt::UserRole ).toInt() );
4546
}
46-
return &mSelectedItems;
47+
return selectionList;
4748
}

src/app/qgsdelattrdialog.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,15 @@
2222
#include <QDialog>
2323
#include <list>
2424

25-
class QHeaderView;
25+
class QgsVectorLayer;
2626

2727
class QgsDelAttrDialog: public QDialog, private Ui::QgsDelAttrDialogBase
2828
{
2929
Q_OBJECT
3030
public:
31-
QgsDelAttrDialog( QHeaderView* header );
32-
const std::list<QString>* selectedAttributes();
33-
protected:
34-
std::list<QString> mSelectedItems;
31+
QgsDelAttrDialog( const QgsVectorLayer* vl );
32+
/**Returns the selected attribute indices*/
33+
QList<int> selectedAttributes();
3534
};
3635

3736
#endif

src/ui/qgsattributetabledialog.ui

+43-12
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,14 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>623</width>
9+
<width>646</width>
1010
<height>570</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
1414
<string>Attribute Table</string>
1515
</property>
16-
<layout class="QGridLayout">
17-
<property name="horizontalSpacing">
18-
<number>2</number>
19-
</property>
20-
<property name="verticalSpacing">
21-
<number>0</number>
22-
</property>
23-
<property name="margin">
24-
<number>0</number>
25-
</property>
16+
<layout class="QGridLayout" name="gridLayout">
2617
<item row="0" column="0">
2718
<widget class="QgsAttributeTableView" name="mView">
2819
<property name="alternatingRowColors">
@@ -31,7 +22,7 @@
3122
</widget>
3223
</item>
3324
<item row="1" column="0">
34-
<layout class="QHBoxLayout">
25+
<layout class="QHBoxLayout" name="horizontalLayout">
3526
<item>
3627
<widget class="QToolButton" name="mRemoveSelectionButton">
3728
<property name="toolTip">
@@ -179,6 +170,46 @@
179170
</property>
180171
</widget>
181172
</item>
173+
<item>
174+
<widget class="QToolButton" name="mAddAttribute">
175+
<property name="toolTip">
176+
<string>New column</string>
177+
</property>
178+
<property name="text">
179+
<string/>
180+
</property>
181+
<property name="icon">
182+
<iconset>
183+
<normaloff>../../images/themes/default/mActionNewAttribute.png</normaloff>../../images/themes/default/mActionNewAttribute.png</iconset>
184+
</property>
185+
<property name="iconSize">
186+
<size>
187+
<width>18</width>
188+
<height>18</height>
189+
</size>
190+
</property>
191+
</widget>
192+
</item>
193+
<item>
194+
<widget class="QToolButton" name="mRemoveAttribute">
195+
<property name="toolTip">
196+
<string>Delete column</string>
197+
</property>
198+
<property name="text">
199+
<string/>
200+
</property>
201+
<property name="icon">
202+
<iconset>
203+
<normaloff>../../images/themes/default/mActionDeleteAttribute.png</normaloff>../../images/themes/default/mActionDeleteAttribute.png</iconset>
204+
</property>
205+
<property name="iconSize">
206+
<size>
207+
<width>18</width>
208+
<height>18</height>
209+
</size>
210+
</property>
211+
</widget>
212+
</item>
182213
<item>
183214
<widget class="QToolButton" name="mOpenFieldCalculator">
184215
<property name="toolTip">

0 commit comments

Comments
 (0)