Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Possibility to add/remove attributes also in attribute table. Small m…
…odification to attribute table such that adding / removing columns is visible

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@11862 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Oct 28, 2009
1 parent 912b9b8 commit e145380
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 53 deletions.
75 changes: 75 additions & 0 deletions src/app/attributetable/qgsattributetabledialog.cpp
Expand Up @@ -28,6 +28,8 @@
#include <qgssearchtreenode.h>

#include "qgisapp.h"
#include "qgsaddattrdialog.h"
#include "qgsdelattrdialog.h"
#include "qgssearchquerybuilder.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
Expand Down Expand Up @@ -88,11 +90,18 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
mInvertSelectionButton->setIcon( getThemeIcon( "/mActionInvertSelection.png" ) );
mToggleEditingButton->setIcon( getThemeIcon( "/mActionToggleEditing.png" ) );
mOpenFieldCalculator->setIcon( getThemeIcon( "/mActionCalculateField.png" ) );
mAddAttribute->setIcon( getThemeIcon( "/mActionNewAttribute.png" ) );
mRemoveAttribute->setIcon( getThemeIcon( "/mActionDeleteAttribute.png" ) );

// toggle editing
bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes;
bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes;
mToggleEditingButton->setCheckable( true );
mToggleEditingButton->setEnabled( canChangeAttributes );
mOpenFieldCalculator->setEnabled( canChangeAttributes && mLayer->isEditable() );
mAddAttribute->setEnabled( canAddAttributes && mLayer->isEditable() );
mRemoveAttribute->setEnabled( canDeleteAttributes && mLayer->isEditable() );

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

bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes;
bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes;
mOpenFieldCalculator->setEnabled( canChangeAttributes && mLayer->isEditable() );
mAddAttribute->setEnabled( canAddAttributes && mLayer->isEditable() );
mRemoveAttribute->setEnabled( canDeleteAttributes && mLayer->isEditable() );

// (probably reload data if user stopped editing - possible revert)
mModel->reload( mModel->index( 0, 0 ), mModel->index( mModel->rowCount(), mModel->columnCount() ) );
Expand Down Expand Up @@ -555,6 +568,68 @@ void QgsAttributeTableDialog::revert()
mModel->reload( mModel->index( 0, 0 ), mModel->index( mModel->rowCount(), mModel->columnCount() ) );
}

void QgsAttributeTableDialog::on_mAddAttribute_clicked()
{
if ( !mLayer )
{
return;
}

QgsAddAttrDialog dialog( mLayer->dataProvider(), this );
if ( dialog.exec() == QDialog::Accepted )
{
mLayer->beginEditCommand( tr( "Attribute added" ) );
if ( mLayer->addAttribute( dialog.field() ) )
{
mLayer->endEditCommand();
}
else
{
QMessageBox::critical( 0, tr( "Attribute Error" ), tr( "The attribute could not be added to the layer" ) );
mLayer->destroyEditCommand();
}
}
}

void QgsAttributeTableDialog::on_mRemoveAttribute_clicked()
{
if ( !mLayer )
{
return;
}

QgsDelAttrDialog dialog( mLayer );
if ( dialog.exec() == QDialog::Accepted )
{
QList<int> attributes = dialog.selectedAttributes();
if ( attributes.size() < 1 )
{
return;
}

mLayer->beginEditCommand( tr( "Deleted attribute" ) );
bool deleted = false;
QList<int>::const_iterator it = attributes.constBegin();
for ( ; it != attributes.constEnd(); ++it )
{
if ( mLayer->deleteAttribute( *it ) )
{
deleted = true;
}
}

if ( deleted )
{
mLayer->endEditCommand();
}
else
{
QMessageBox::critical( 0, tr( "Attribute Error" ), tr( "The attribute(s) could not be deleted" ) );
mLayer->destroyEditCommand();
}
}
}

void QgsAttributeTableDialog::on_mOpenFieldCalculator_clicked()
{
QgsFieldCalculator calc( mLayer );
Expand Down
4 changes: 4 additions & 0 deletions src/app/attributetable/qgsattributetabledialog.h
Expand Up @@ -132,6 +132,10 @@ class QgsAttributeTableDialog : public QDialog, private Ui::QgsAttributeTableDia
* Starts editing mode
*/
void startEditing();
/**Opens dialog to add new attribute*/
void on_mAddAttribute_clicked();
/**Opens dialog to remove attribute*/
void on_mRemoveAttribute_clicked();
/**
* Opens field calculator dialog
*/
Expand Down
78 changes: 56 additions & 22 deletions src/app/attributetable/qgsattributetablemodel.cpp
Expand Up @@ -34,29 +34,8 @@ QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayer *theLayer, QObjec
mLastRow = NULL;
mLayer = theLayer;
mFeatureCount = mLayer->pendingFeatureCount();
loadAttributes();

mFieldCount = 0;
mAttributes.clear();
mValueMaps.clear();

for ( QgsFieldMap::const_iterator it = theLayer->pendingFields().constBegin(); it != theLayer->pendingFields().end(); it++ )
{
switch ( mLayer->editType( it.key() ) )
{
case QgsVectorLayer::Hidden:
continue;

case QgsVectorLayer::ValueMap:
mValueMaps.insert( it.key(), &mLayer->valueMap( it.key() ) );
break;

default:
break;
}

mFieldCount++;
mAttributes << it.key();
}

connect( mLayer, SIGNAL( layerModified( bool ) ), this, SLOT( layerModified( bool ) ) );
//connect(mLayer, SIGNAL(attributeAdded(int)), this, SLOT( attributeAdded(int)));
Expand Down Expand Up @@ -168,11 +147,66 @@ void QgsAttributeTableModel::layerModified( bool onlyGeometry )
if ( onlyGeometry )
return;

loadAttributes();
loadLayer();
emit modelChanged();
emit headerDataChanged( Qt::Horizontal, 0, columnCount() - 1 );
}

void QgsAttributeTableModel::loadAttributes()
{
if ( !mLayer )
{
return;
}

bool ins = false, rm = false;
int pendingFieldCount = mLayer->pendingFields().size();

if ( mFieldCount < pendingFieldCount )
{
ins = true;
beginInsertColumns( QModelIndex(), mFieldCount, pendingFieldCount - 1 );
}
else if ( pendingFieldCount < mFieldCount )
{
rm = true;
beginRemoveColumns( QModelIndex(), pendingFieldCount, mFieldCount - 1 );
}

mFieldCount = 0;
mAttributes.clear();
mValueMaps.clear();

for ( QgsFieldMap::const_iterator it = mLayer->pendingFields().constBegin(); it != mLayer->pendingFields().end(); it++ )
{
switch ( mLayer->editType( it.key() ) )
{
case QgsVectorLayer::Hidden:
continue;

case QgsVectorLayer::ValueMap:
mValueMaps.insert( it.key(), &mLayer->valueMap( it.key() ) );
break;

default:
break;
}

mFieldCount++;
mAttributes << it.key();
}

if ( ins )
{
endInsertColumns();
}
else if ( rm )
{
endRemoveColumns();
}
}

void QgsAttributeTableModel::loadLayer()
{
QgsDebugMsg( "entered." );
Expand Down
5 changes: 5 additions & 0 deletions src/app/attributetable/qgsattributetablemodel.h
Expand Up @@ -202,6 +202,11 @@ class QgsAttributeTableModel: public QAbstractTableModel
*/
virtual void loadLayer();

/**
* Gets mFieldCount, mAttributes and mValueMaps
*/
virtual void loadAttributes();

/**
* load feature fid into mFeat
* @param fid feature id
Expand Down
29 changes: 15 additions & 14 deletions src/app/qgsdelattrdialog.cpp
Expand Up @@ -17,31 +17,32 @@

#include "qgsdelattrdialog.h"
#include "qgsfield.h"
#include <QHeaderView>
#include "qgsvectorlayer.h"

QgsDelAttrDialog::QgsDelAttrDialog( QHeaderView* header ): QDialog()
QgsDelAttrDialog::QgsDelAttrDialog( const QgsVectorLayer* vl ): QDialog()
{
setupUi( this );

//insert attribute names into the QListView
if ( header )
if ( vl )
{
listBox2->clear();
QAbstractItemModel *model = header->model();
for ( int i = 1;i < header->count();++i )
const QgsFieldMap layerAttributes = vl->pendingFields();
QgsFieldMap::const_iterator attIt = layerAttributes.constBegin();
for ( ; attIt != layerAttributes.constEnd(); ++attIt )
{
listBox2->addItem( model->headerData( i, Qt::Horizontal ).toString() );
QListWidgetItem* item = new QListWidgetItem( attIt.value().name(), listBox2 );
item->setData( Qt::UserRole, attIt.key() );
}
}
}

const std::list<QString>* QgsDelAttrDialog::selectedAttributes()
QList<int> QgsDelAttrDialog::selectedAttributes()
{
mSelectedItems.clear();
QListIterator<QListWidgetItem *> selection( listBox2->selectedItems() );
while ( selection.hasNext() )
QList<int> selectionList;
QList<QListWidgetItem *> selection = listBox2->selectedItems();
QList<QListWidgetItem *>::const_iterator itemIter = selection.constBegin();
for ( ; itemIter != selection.constEnd(); ++itemIter )
{
mSelectedItems.push_back( selection.next()->text() );
selectionList.push_back(( *itemIter )->data( Qt::UserRole ).toInt() );
}
return &mSelectedItems;
return selectionList;
}
9 changes: 4 additions & 5 deletions src/app/qgsdelattrdialog.h
Expand Up @@ -22,16 +22,15 @@
#include <QDialog>
#include <list>

class QHeaderView;
class QgsVectorLayer;

class QgsDelAttrDialog: public QDialog, private Ui::QgsDelAttrDialogBase
{
Q_OBJECT
public:
QgsDelAttrDialog( QHeaderView* header );
const std::list<QString>* selectedAttributes();
protected:
std::list<QString> mSelectedItems;
QgsDelAttrDialog( const QgsVectorLayer* vl );
/**Returns the selected attribute indices*/
QList<int> selectedAttributes();
};

#endif
55 changes: 43 additions & 12 deletions src/ui/qgsattributetabledialog.ui
Expand Up @@ -6,23 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
<width>623</width>
<width>646</width>
<height>570</height>
</rect>
</property>
<property name="windowTitle">
<string>Attribute Table</string>
</property>
<layout class="QGridLayout">
<property name="horizontalSpacing">
<number>2</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QgsAttributeTableView" name="mView">
<property name="alternatingRowColors">
Expand All @@ -31,7 +22,7 @@
</widget>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="mRemoveSelectionButton">
<property name="toolTip">
Expand Down Expand Up @@ -179,6 +170,46 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mAddAttribute">
<property name="toolTip">
<string>New column</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>../../images/themes/default/mActionNewAttribute.png</normaloff>../../images/themes/default/mActionNewAttribute.png</iconset>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mRemoveAttribute">
<property name="toolTip">
<string>Delete column</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>../../images/themes/default/mActionDeleteAttribute.png</normaloff>../../images/themes/default/mActionDeleteAttribute.png</iconset>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mOpenFieldCalculator">
<property name="toolTip">
Expand Down

0 comments on commit e145380

Please sign in to comment.