Skip to content

Commit

Permalink
[FEATURE][composer] Rework attribute tables to make tables more flexi…
Browse files Browse the repository at this point in the history
…ble.

- Add support for reordering columns in a table (fix #5942)
- Add support for expression based columns
- Add support for setting column alignment (fix #2957)
- Add support for setting column header alignment
- Make sorting in tables correctly handle nulls, dates, times, locale aware string sorting
This work also paves the way for future expansion of attribute tables to allow for setting column widths, column colors, etc.
  • Loading branch information
nyalldawson committed May 15, 2014
1 parent fa0f0bd commit dc905ac
Show file tree
Hide file tree
Showing 24 changed files with 2,985 additions and 585 deletions.
87 changes: 53 additions & 34 deletions python/core/composer/qgscomposerattributetable.sip
Expand Up @@ -2,6 +2,7 @@
* Attribute table item for map composer.
*/

/**Helper class for sorting tables, takes into account sorting column and ascending / descending*/
class QgsComposerAttributeTableCompare
{
%TypeHeaderCode
Expand All @@ -11,7 +12,15 @@ class QgsComposerAttributeTableCompare
public:
QgsComposerAttributeTableCompare();
// bool operator()( const QgsAttributeMap& m1, const QgsAttributeMap& m2 );

/**Sets column number to sort by
* @param col column number for sorting
*/
void setSortColumn( int col );

/**Sets sort order for column sorting
* @param asc set to true to sort in ascending order, false to sort in descending order
*/
void setAscending( bool asc );
};

Expand All @@ -32,85 +41,94 @@ class QgsComposerAttributeTable : QgsComposerTable
/** \brief Reimplementation of QCanvasItem::paint*/
virtual void paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget );

/**Writes properties specific to attribute tables
* @param elem an existing QDomElement in which to store the attribute table's properties.
* @param doc QDomDocument for the destination xml.
* @see readXML
*/
bool writeXML( QDomElement& elem, QDomDocument & doc ) const;

/**Reads the properties specific to an attribute table from xml.
* @param itemElem a QDomElement holding the attribute table's desired properties.
* @param doc QDomDocument for the source xml.
* @see writeXML
*/
bool readXML( const QDomElement& itemElem, const QDomDocument& doc );

/**Sets the vector layer from which to display feature attributes
* @param layer Vector layer for attribute table
* @note added in 2.3
* @see vectorLayer
*/
*/
void setVectorLayer( QgsVectorLayer* layer );

/**Returns the vector layer the attribute table is currently using
* @returns attribute table's current vector layer
* @note added in 2.3
* @see setVectorLayer
*/
*/
QgsVectorLayer* vectorLayer() const;

/**Resets the attribute table's columns to match the vector layer's fields
* @note added in 2.3
* @see setVectorLayer
*/
void resetColumns();

/**Sets the composer map to use to limit the extent of features shown in the
* attribute table. This setting only has an effect if setDisplayOnlyVisibleFeatures is
* set to true. Changing the composer map forces the table to refetch features from its
* vector layer, and may result in the table changing size to accomodate the new displayed
* feature attributes.
* @param map QgsComposerMap which drives the extents of the table's features
* @note added in 2.3
* @see composerMap
* @see setDisplayOnlyVisibleFeatures
*/
*/
void setComposerMap( const QgsComposerMap* map /TransferThis/ );

/**Returns the composer map whose extents are controlling the features shown in the
* table. The extents of the map are only used if displayOnlyVisibleFeatures() is true.
* @returns composer map controlling the attribute table
* @note added in 2.3
* @see setComposerMap
* @see displayOnlyVisibleFeatures
*/
*/
const QgsComposerMap* composerMap() const;

/**Sets the maximum number of features shown by the table. Changing this setting may result
* in the attribute table changing its size to accomodate the new number of rows, and requires
* the table to refetch features from its vector layer.
* @param features maximum number of features to show in the table
* @note added in 2.3
* @see maximumNumberOfFeatures
*/
*/
void setMaximumNumberOfFeatures( int features );

/**Returns the maximum number of features to be shown by the table.
* @returns maximum number of features
* @note added in 2.3
* @see setMaximumNumberOfFeatures
*/
*/
int maximumNumberOfFeatures() const;

/**Sets attribute table to only show features which are visible in a composer map item. Changing
* this setting forces the table to refetch features from its vector layer, and may result in
* the table changing size to accomodate the new displayed feature attributes.
* @param visibleOnly set to true to show only visible features
* @note added in 2.3
* @see displayOnlyVisibleFeatures
* @see setComposerMap
*/
*/
void setDisplayOnlyVisibleFeatures( bool b );

/**Returns true if the table is set to show only features visible on a corresponding
* composer map item.
* @returns true if table only shows visible features
* @note added in 2.3
* @see composerMap
* @see setDisplayOnlyVisibleFeatures
*/
*/
bool displayOnlyVisibleFeatures() const;

/**Returns true if a feature filter is active on the attribute table
* @returns bool state of the feature filter
* @note added in 2.3
* @see setFilterFeatures
* @see featureFilter
*/
*/
bool filterFeatures() const;

/**Sets whether the feature filter is active for the attribute table. Changing
Expand All @@ -120,7 +138,7 @@ class QgsComposerAttributeTable : QgsComposerTable
* @note added in 2.3
* @see filterFeatures
* @see setFeatureFilter
*/
*/
void setFilterFeatures( bool filter );

/**Returns the current expression used to filter features for the table. The filter is only
Expand All @@ -129,7 +147,7 @@ class QgsComposerAttributeTable : QgsComposerTable
* @note added in 2.3
* @see setFeatureFilter
* @see filterFeatures
*/
*/
QString featureFilter() const;

/**Sets the expression used for filtering features in the table. The filter is only
Expand All @@ -140,50 +158,51 @@ class QgsComposerAttributeTable : QgsComposerTable
* @note added in 2.3
* @see featureFilter
* @see setFilterFeatures
*/
*/
void setFeatureFilter( const QString& expression );

/**Returns the attributes fields which are shown by the table.
* @returns a QSet of integers refering to the attributes in the vector layer. If
* result is an empty QSet than all feature attributes will be shown.
* @see setDisplayAttributes
*/
QSet<int> displayAttributes() const;
* @deprecated use QgsComposerTable::columns() instead
*/
QSet<int> displayAttributes() const /Deprecated/;

/**Sets the attributes to display in the table.
* @param attr QSet of integer values refering to the attributes from the vector layer to show
* @param attr QSet of integer values refering to the attributes from the vector layer to show.
* Set to an empty QSet to show all feature attributes.
* @param refresh set to true to force the table to refetch features from its vector layer
* and immediately update the display of the table. This may result in the table changing size
* to accomodate the new displayed feature attributes.
* @see displayAttributes
*/
*/
void setDisplayAttributes( const QSet<int>& attr );

/**Returns the attribute field aliases, which control how fields are named in the table's
* header row.
* @returns a QMap of integers to strings, where the string is the field's alias.
* @returns a QMap of integers to strings, where the string is the field's alias and the
* integer is the field index from the associated vector layer.
* @see setFieldAliasMap
*/
QMap<int, QString> fieldAliasMap() const;
* @deprecated use QgsComposerTable::columns() instead
*/
QMap<int, QString> fieldAliasMap() const /Deprecated/;

/**Sets the attribute field aliases, which control how fields are named in the table's
* header row.
* @param map QMap of integers to strings, where the string is the alias to use for the
* corresponding field.
* @param refresh set to true to force the table to refetch features from its vector layer
* and immediately update the display of the table. This may result in the table changing size
* to accomodate the new displayed feature attributes and field aliases.
* corresponding field, and the integer is the field index from the vector layer
* @see fieldAliasMap
*/
void setFieldAliasMap( const QMap<int, QString>& map );
* @deprecated use QgsComposerTable::columns() instead
*/
void setFieldAliasMap( const QMap<int, QString>& map ) /Deprecated/;

/**Adapts mMaximumNumberOfFeatures depending on the rectangle height. Calling this forces
* the table to refetch features from its vector layer and immediately updates the display
* of the table.
* @see maximumNumberOfFeatures
* @see setMaximumNumberOfFeatures
*/
*/
void setSceneRect( const QRectF& rectangle );

// @note not available in python bindings
Expand Down
156 changes: 156 additions & 0 deletions python/core/composer/qgscomposerattributetablemodel.sip
@@ -0,0 +1,156 @@
/**A model for displaying columns shown in a QgsComposerAttributeTable*/
class QgsComposerAttributeTableColumnModel: public QAbstractTableModel
{
%TypeHeaderCode
#include <qgscomposerattributetablemodel.h>
%End

public:

/*! Controls whether a row/column is shifted up or down
*/
enum ShiftDirection
{
ShiftUp, /*!< shift the row/column up */
ShiftDown /*!< shift the row/column down */
};

/**Constructor for QgsComposerAttributeTableColumnModel.
* @param composerTable QgsComposerAttributeTable the model is attached to
*/
QgsComposerAttributeTableColumnModel( QgsComposerAttributeTable *composerTable, QObject *parent = 0 );
virtual ~QgsComposerAttributeTableColumnModel();

virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
virtual QVariant data( const QModelIndex &index, int role ) const;
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
virtual bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );
Qt::ItemFlags flags( const QModelIndex &index ) const;
bool removeRows( int row, int count, const QModelIndex &parent = QModelIndex() );
bool insertRows( int row, int count, const QModelIndex &parent = QModelIndex() );
QModelIndex index( int row, int column, const QModelIndex &parent ) const;

/**Moves the specified row up or down in the model. Used for rearranging the attribute tables
* columns.
* @returns true if the move is allowed
* @param row row in model representing attribute table column to move
* @param direction direction to move the attribute table column
* @note added in 2.3
*/
bool moveRow( int row , ShiftDirection direction );

/**Resets the attribute table's columns to match the source layer's fields. Remove all existing
* attribute table columns and column customisations.
* @note added in 2.3
*/
void resetToLayer();

/**Returns the QgsComposerTableColumn corresponding to an index in the model.
* @returns QgsComposerTableColumn for specified index
* @param index a QModelIndex
* @note added in 2.3
* @see indexFromColumn
*/
QgsComposerTableColumn* columnFromIndex( const QModelIndex & index ) const;

/**Returns a QModelIndex corresponding to a QgsComposerTableColumn in the model.
* @returns QModelIndex for specified QgsComposerTableColumn
* @param column a QgsComposerTableColumn
* @note added in 2.3
* @see columnFromIndex
*/
QModelIndex indexFromColumn( QgsComposerTableColumn *column );

/**Sets a specified column as a sorted column in the QgsComposerAttributeTable. The column will be
* added to the end of the sort rank list, ie it will take the next largest available sort rank.
* @param column a QgsComposerTableColumn
* @param order sort order for column
* @note added in 2.3
* @see removeColumnFromSort
* @see moveColumnInSortRank
*/
void setColumnAsSorted( QgsComposerTableColumn *column, Qt::SortOrder order );

/**Sets a specified column as an unsorted column in the QgsComposerAttributeTable. The column will be
* removed from the sort rank list.
* @param column a QgsComposerTableColumn
* @note added in 2.3
* @see setColumnAsSorted
*/
void setColumnAsUnsorted( QgsComposerTableColumn * column );

/**Moves a column up or down in the sort rank for the QgsComposerAttributeTable.
* @param column a QgsComposerTableColumn
* @param direction direction to move the column in the sort rank list
* @note added in 2.3
* @see setColumnAsSorted
*/
bool moveColumnInSortRank( QgsComposerTableColumn * column, ShiftDirection direction );

};

/**Allows for filtering QgsComposerAttributeTable columns by columns which are sorted or unsorted*/
class QgsComposerTableSortColumnsProxyModel : public QSortFilterProxyModel
{
%TypeHeaderCode
#include <qgscomposerattributetablemodel.h>
%End

public:
/*! Controls whether the proxy model shows sorted or unsorted columns
*/
enum ColumnFilterType
{
ShowSortedColumns, /*!< show only sorted columns */
ShowUnsortedColumns/*!< show only unsorted columns */
};

/**Constructor for QgsComposerTableSortColumnsProxyModel.
* @param composerTable QgsComposerAttributeTable the model is attached to
* @param filterType filter for columns, controls whether sorted or unsorted columns are shown
*/
QgsComposerTableSortColumnsProxyModel( QgsComposerAttributeTable *composerTable, ColumnFilterType filterType, QObject *parent = 0 );

virtual ~QgsComposerTableSortColumnsProxyModel();

bool lessThan( const QModelIndex &left, const QModelIndex &right ) const;
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
virtual QVariant data( const QModelIndex &index, int role ) const;
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
Qt::ItemFlags flags( const QModelIndex &index ) const;
virtual bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );

/**Returns the QgsComposerTableColumn corresponding to a row in the proxy model.
* @returns QgsComposerTableColumn for specified row
* @param row a row number
* @note added in 2.3
* @see columnFromIndex
*/
QgsComposerTableColumn* columnFromRow( int row );

/**Returns the QgsComposerTableColumn corresponding to an index in the proxy model.
* @returns QgsComposerTableColumn for specified index
* @param index a QModelIndex
* @note added in 2.3
* @see columnFromRow
* @see columnFromSourceIndex
*/
QgsComposerTableColumn* columnFromIndex( const QModelIndex & index ) const;


/**Returns the QgsComposerTableColumn corresponding to an index from the source
* QgsComposerAttributeTableColumnModel model.
* @returns QgsComposerTableColumn for specified index from QgsComposerAttributeTableColumnModel
* @param index a QModelIndex
* @note added in 2.3
* @see columnFromRow
* @see columnFromIndex
*/
QgsComposerTableColumn* columnFromSourceIndex( const QModelIndex& sourceIndex ) const;

protected:

bool filterAcceptsRow( int source_row, const QModelIndex & source_parent ) const;

};

0 comments on commit dc905ac

Please sign in to comment.