Skip to content

Commit

Permalink
[feature] New configuration options for attribute table
Browse files Browse the repository at this point in the history
 * Allow reordering the attribute table columns
 * Allow adding a new column to trigger an action to the attribute table
  • Loading branch information
m-kuhn committed May 2, 2016
1 parent aa9010e commit dd88fa9
Show file tree
Hide file tree
Showing 27 changed files with 738 additions and 105 deletions.
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -22,6 +22,7 @@
%Include qgsaction.sip
%Include qgsactionmanager.sip
%Include qgsattributeaction.sip
%Include qgsattributetableconfig.sip
%Include qgsbrowsermodel.sip
%Include qgsclipper.sip
%Include qgscolorscheme.sip
Expand Down
78 changes: 78 additions & 0 deletions python/core/qgsattributetableconfig.sip
@@ -0,0 +1,78 @@
/***************************************************************************
qgsattributetableconfig.h - QgsAttributeTableConfig

---------------------
begin : 27.4.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

/**
* This is a container for configuration of the attribute table.
* The configuration is specific for one vector layer.
*/

class QgsAttributeTableConfig
{
%TypeHeaderCode
#include <qgsattributetableconfig.h>
%End
public:
/**
* The type of an attribute table column.
*/
enum Type
{
Field, //!< This column represents a field
Action //!< This column represents an action widget
};

/**
* Defines the configuration of a column in the attribute table.
*/
struct ColumnConfig
{
QgsAttributeTableConfig::Type mType; //!< The type of this column.
QString mName; //!< The name of the attribute if this column represents a field
bool mHidden; //!< Flag that controls if the column is hidden
};

QgsAttributeTableConfig();

/**
* Get the list with all columns and their configuration.
* The list order defines the order of appearance.
*/
QVector<QgsAttributeTableConfig::ColumnConfig> columns() const;

/**
* Set the list of columns visible in the attribute table.
* The list order defines the order of appearance.
*/
void setColumns( const QVector<QgsAttributeTableConfig::ColumnConfig>& columns );

/**
* Update the configuration with the given fields.
* Any field which is present in the configuration but not present in the
* parameter fields will be removed. Any field which is in the parameter
* fields but not in the configuration will be appended.
*/
void update( const QgsFields& fields );

/**
* Serialize to XML on layer save
*/
void writeXml( QDomNode& node ) const;

/**
* Deserialize to XML on layer load
*/
void readXml( const QDomNode& node );
};
12 changes: 12 additions & 0 deletions python/core/qgsvectorlayer.sip
Expand Up @@ -1321,6 +1321,18 @@ class QgsVectorLayer : QgsMapLayer
*/
QgsConditionalLayerStyles *conditionalStyles() const;

/**
* Get the attribute table configuration object.
* This defines the appearance of the attribute table.
*/
QgsAttributeTableConfig attributeTableConfig() const;

/**
* Set the attribute table configuration object.
* This defines the appearance of the attribute table.
*/
void setAttributeTableConfig( const QgsAttributeTableConfig& attributeTableConfig );

public slots:
/**
* Select feature by its ID
Expand Down
31 changes: 31 additions & 0 deletions python/gui/attributetable/qgsattributetablefiltermodel.sip
Expand Up @@ -13,6 +13,18 @@ class QgsAttributeTableFilterModel: QSortFilterProxyModel, QgsFeatureModel
ShowEdited
};

enum ColumnType
{
ColumnTypeField, //!< This column shows a field
ColumnTypeActionButton //!< This column shows action buttons
};

enum Role
{
TypeRole = QgsAttributeTableModel::UserRole //!< The type of a given column
};


/**
*
* Make sure, the master model is already loaded, so the selection will get synchronized.
Expand Down Expand Up @@ -99,6 +111,25 @@ class QgsAttributeTableFilterModel: QSortFilterProxyModel, QgsFeatureModel
/** Returns the map canvas*/
QgsMapCanvas* mapCanvas() const;

virtual QVariant data( const QModelIndex& index, int role ) const;

QVariant headerData( int section, Qt::Orientation orientation, int role ) const;

/**
* Get the index of the first column that contains an action widget.
* Returns -1 if none is defined.
*/
int actionColumnIndex() const;

int columnCount( const QModelIndex &parent ) const;

/**
* Set the attribute table configuration to control which fields are shown,
* in which order they are shown as well as if and where an action column
* is shown.
*/
void setAttributeTableConfig( const QgsAttributeTableConfig& config );

protected:
/**
* Returns true if the source row will be accepted
Expand Down
2 changes: 1 addition & 1 deletion python/gui/attributetable/qgsattributetableview.sip
Expand Up @@ -19,7 +19,7 @@ class QgsAttributeTableView : QTableView
/**
* This event filter is installed on the verticalHeader to intercept mouse press and release
* events. These are used to disable / enable live synchronisation with the map canvas selection
* which can be slow due to recurring canvas repaints. Updating the
* which can be slow due to recurring canvas repaints.
*
* @param object The object which is the target of the event.
* @param event The intercepted event
Expand Down
13 changes: 13 additions & 0 deletions python/gui/attributetable/qgsdualview.sip
Expand Up @@ -65,6 +65,11 @@ class QgsDualView : QStackedWidget
*/
void setFilterMode( QgsAttributeTableFilterModel::FilterMode filterMode );

/**
* Get the filter mode
*
* @return the filter mode
*/
QgsAttributeTableFilterModel::FilterMode filterMode();

/**
Expand Down Expand Up @@ -98,6 +103,9 @@ class QgsDualView : QStackedWidget
*/
void setFilteredFeatures( const QgsFeatureIds& filteredFeatures );

/**
* Get a list of currently visible feature ids.
*/
QgsFeatureIds filteredFeatures();

/**
Expand All @@ -112,6 +120,11 @@ class QgsDualView : QStackedWidget
void setFeatureSelectionManager( QgsIFeatureSelectionManager* featureSelectionManager );

QgsAttributeTableView* tableView();
/**
* Set the attribute table config which should be used to control
* the appearance of the attribute table.
*/
void setAttributeTableConfig( const QgsAttributeTableConfig& config );

protected:
/**
Expand Down
13 changes: 8 additions & 5 deletions python/gui/attributetable/qgsorganizetablecolumnsdialog.sip
Expand Up @@ -8,16 +8,19 @@ class QgsOrganizeTableColumnsDialog : QDialog
/**
* Constructor
* @param vl The concerned vector layer
* @param visible the cuurent list of visible fields name
* @param visible the current list of visible fields name
* @param parent parent object
* @param flags window flags
*/
QgsOrganizeTableColumnsDialog( const QgsVectorLayer* vl, QStringList visible, QWidget *parent /TransferThis/ = nullptr, Qt::WindowFlags flags = Qt::Window );
QgsOrganizeTableColumnsDialog(const QgsVectorLayer* vl, QWidget* parent = nullptr, Qt::WindowFlags flags = Qt::Window );

/**
* Destructor
*/
~QgsOrganizeTableColumnsDialog();

/**
* Get the selected fields name
* @return The selected fields name
* Get the updated configuration
*/
QStringList selectedFields();
QgsAttributeTableConfig config() const;
};
14 changes: 5 additions & 9 deletions src/app/qgsattributetabledialog.cpp
Expand Up @@ -125,6 +125,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid

// Initialize dual view
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, context );
mMainView->setAttributeTableConfig( mLayer->attributeTableConfig() );

// Initialize filter gui elements
mFilterActionMapper = new QSignalMapper( this );
Expand Down Expand Up @@ -776,17 +777,12 @@ void QgsAttributeTableDialog::on_mFilterTableFields_clicked()
return;
}

QgsOrganizeTableColumnsDialog dialog( mLayer, mVisibleFields );
QgsOrganizeTableColumnsDialog dialog( mLayer );
if ( dialog.exec() == QDialog::Accepted )
{
mVisibleFields = dialog.selectedFields();

const QgsFields layerAttributes = mLayer->fields();
for ( int idx = 0; idx < layerAttributes.count(); ++idx )
{
mMainView->tableView()->setColumnHidden(
idx, !mVisibleFields.contains( layerAttributes[idx].name() ) );
}
QgsAttributeTableConfig config = dialog.config();
mLayer->setAttributeTableConfig( config );
mMainView->setAttributeTableConfig( config );
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/core/CMakeLists.txt
Expand Up @@ -79,6 +79,7 @@ SET(QGIS_CORE_SRCS
qgsapplication.cpp
qgsaction.cpp
qgsactionmanager.cpp
qgsattributetableconfig.cpp
qgsbrowsermodel.cpp
qgscachedfeatureiterator.cpp
qgscacheindex.cpp
Expand Down Expand Up @@ -591,7 +592,7 @@ SET(QGIS_CORE_HDRS

qgis.h
qgsaction.h
qgsactionmanager.h
qgsattributetableconfig.h
qgsattributeaction.h
qgscachedfeatureiterator.h
qgscacheindex.h
Expand Down
1 change: 0 additions & 1 deletion src/core/geometry/qgsabstractgeometryv2.h
Expand Up @@ -23,7 +23,6 @@ email : marco.hugentobler at sourcepole dot com

#include <QString>

class QgsCoordinateTransform;
class QgsMapToPixel;
class QgsCurveV2;
class QgsMultiCurveV2;
Expand Down

0 comments on commit dd88fa9

Please sign in to comment.