1
0
mirror of https://github.com/qgis/QGIS.git synced 2025-04-17 00:04:02 -04:00

[composer] Cache features for attribute table, to reduce excessive cpu use and multiple queries to layer provider

This commit is contained in:
Nyall Dawson 2014-04-23 06:28:56 +10:00
parent bf3566de88
commit a386e898f0
8 changed files with 447 additions and 59 deletions

@ -35,16 +35,74 @@ class QgsComposerAttributeTable : QgsComposerTable
bool writeXML( QDomElement& elem, QDomDocument & doc ) const;
bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
void setVectorLayer( QgsVectorLayer* vl );
/**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;
/**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;
void setMaximumNumberOfFeatures( int nr );
/**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
@ -54,7 +112,10 @@ class QgsComposerAttributeTable : QgsComposerTable
* @see featureFilter
*/
bool filterFeatures() const;
/**Sets whether the feature filter is active for the attribute table
/**Sets whether the feature filter is active for the attribute table. 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 filter Set to true to enable the feature filter
* @note added in 2.3
* @see filterFeatures
@ -70,8 +131,11 @@ class QgsComposerAttributeTable : QgsComposerTable
* @see filterFeatures
*/
QString featureFilter() const;
/**Sets the expression used for filtering features in the table. The filter is only
* active if filterFeatures() is set to true.
* active if filterFeatures() is set to true. 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 expression filter to use for selecting which features to display in the table
* @note added in 2.3
* @see featureFilter
@ -79,13 +143,45 @@ class QgsComposerAttributeTable : QgsComposerTable
*/
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
* @see setDisplayAttributes
*/
QSet<int> displayAttributes() const;
/**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 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.
* @see setFieldAliasMap
*/
QMap<int, QString> fieldAliasMap() const;
/**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.
* @see fieldAliasMap
*/
void setFieldAliasMap( const QMap<int, QString>& map );
/**Adapts mMaximumNumberOfFeatures depending on the rectangle height*/
/**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

@ -35,10 +35,25 @@ class QgsComposerTable: QgsComposerItem
void setGridColor( const QColor& c );
QColor gridColor() const;
public slots:
/**Adapts the size of the frame to match the content. This is normally done in the paint method, but sometimes
it needs to be done before the first render*/
void adjustFrameToSize();
/**Refreshes the attributes shown in the table by querying the vector layer for new data.
* This also causes the column widths and size of the table to change to accomodate the
* new data.
* @note added in 2.3
* @see adjustFrameToSize
*/
virtual void refreshAttributes();
/**Adapts the size of the frame to match the content. First, the optimal width of the columns
* is recalculated by checking the maximum width of attributes shown in the table. Then, the
* table is resized to fit its contents. This slot utilises the table's attribute cache so
* that a re-query of the vector layer is not required.
* @note added in 2.3
* @see refreshAttributes
*/
virtual void adjustFrameToSize();
protected:
/**Retrieves feature attributes*/

@ -106,9 +106,14 @@ void QgsComposerTableWidget::on_mAttributesPushButton_clicked()
{
//change displayAttributes and aliases
mComposerTable->beginCommand( tr( "Table attribute settings" ) );
mComposerTable->setDisplayAttributes( d.enabledAttributes() );
mComposerTable->setFieldAliasMap( d.aliasMap() );
mComposerTable->setSortAttributes( d.attributeSorting() );
//call these methods with update=false to prevent multiple refreshing of table attributes
mComposerTable->setDisplayAttributes( d.enabledAttributes(), false );
mComposerTable->setFieldAliasMap( d.aliasMap(), false );
mComposerTable->setSortAttributes( d.attributeSorting(), false );
//finally, force a single refresh of the attributes
mComposerTable->refreshAttributes();
mComposerTable->update();
mComposerTable->endCommand();
}

@ -352,6 +352,7 @@ SET(QGIS_CORE_MOC_HDRS
composer/qgscomposerlabel.h
composer/qgscomposershape.h
composer/qgscomposerattributetable.h
composer/qgscomposertable.h
composer/qgscomposerhtml.h
composer/qgscomposermultiframe.h
composer/qgscomposereffect.h

@ -98,26 +98,111 @@ void QgsComposerAttributeTable::initializeAliasMap()
}
}
void QgsComposerAttributeTable::setVectorLayer( QgsVectorLayer* vl )
void QgsComposerAttributeTable::setVectorLayer( QgsVectorLayer* layer )
{
if ( vl != mVectorLayer )
if ( layer == mVectorLayer )
{
mDisplayAttributes.clear();
mVectorLayer = vl;
initializeAliasMap();
return;
}
mDisplayAttributes.clear();
if ( mVectorLayer )
{
//disconnect from previous layer
QObject::disconnect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) );
}
mVectorLayer = layer;
initializeAliasMap();
refreshAttributes();
//listen for modifications to layer and refresh table when they occur
QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) );
}
void QgsComposerAttributeTable::setComposerMap( const QgsComposerMap* map )
{
if ( map == mComposerMap )
{
return;
}
if ( mComposerMap )
{
QObject::disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( repaint() ) );
//disconnect from previous map
QObject::disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( refreshAttributes() ) );
}
mComposerMap = map;
if ( mComposerMap )
{
QObject::connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( repaint() ) );
//listen out for extent changes in linked map
QObject::connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( refreshAttributes() ) );
}
refreshAttributes();
}
void QgsComposerAttributeTable::setMaximumNumberOfFeatures( int features )
{
if ( features == mMaximumNumberOfFeatures )
{
return;
}
mMaximumNumberOfFeatures = features;
refreshAttributes();
}
void QgsComposerAttributeTable::setDisplayOnlyVisibleFeatures( bool visibleOnly )
{
if ( visibleOnly == mShowOnlyVisibleFeatures )
{
return;
}
mShowOnlyVisibleFeatures = visibleOnly;
refreshAttributes();
}
void QgsComposerAttributeTable::setFilterFeatures( bool filter )
{
if ( filter == mFilterFeatures )
{
return;
}
mFilterFeatures = filter;
refreshAttributes();
}
void QgsComposerAttributeTable::setFeatureFilter( const QString& expression )
{
if ( expression == mFeatureFilter )
{
return;
}
mFeatureFilter = expression;
refreshAttributes();
}
void QgsComposerAttributeTable::setDisplayAttributes( const QSet<int>& attr, bool refresh )
{
mDisplayAttributes = attr;
if ( refresh )
{
refreshAttributes();
}
}
void QgsComposerAttributeTable::setFieldAliasMap( const QMap<int, QString>& map, bool refresh )
{
mFieldAliasMap = map;
if ( refresh )
{
refreshAttributes();
}
}
@ -259,9 +344,23 @@ void QgsComposerAttributeTable::setSceneRect( const QRectF& rectangle )
mMaximumNumberOfFeatures = 0;
}
QgsComposerItem::setSceneRect( rectangle );
//refresh table attributes, since number of features has likely changed
refreshAttributes();
emit maximumNumberOfFeaturesChanged( mMaximumNumberOfFeatures );
}
void QgsComposerAttributeTable::setSortAttributes( const QList<QPair<int, bool> > att, bool refresh )
{
mSortInformation = att;
if ( refresh )
{
refreshAttributes();
}
}
bool QgsComposerAttributeTable::writeXML( QDomElement& elem, QDomDocument & doc ) const
{
QDomElement composerTableElem = doc.createElement( "ComposerAttributeTable" );
@ -349,6 +448,12 @@ bool QgsComposerAttributeTable::readXML( const QDomElement& itemElem, const QDom
mComposerMap = 0;
}
if ( mComposerMap )
{
//if we have found a valid map item, listen out to extent changes on it and refresh the table
QObject::connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( refreshAttributes() ) );
}
//vector layer
QString layerId = itemElem.attribute( "vectorLayer", "not_existing" );
if ( layerId == "not_existing" )
@ -361,6 +466,11 @@ bool QgsComposerAttributeTable::readXML( const QDomElement& itemElem, const QDom
if ( ml )
{
mVectorLayer = dynamic_cast<QgsVectorLayer*>( ml );
if ( mVectorLayer )
{
//if we have found a valid vector layer, listen for modifications on it and refresh the table
QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) );
}
}
}
@ -417,6 +527,8 @@ bool QgsComposerAttributeTable::readXML( const QDomElement& itemElem, const QDom
//must be done here because tableReadXML->setSceneRect changes mMaximumNumberOfFeatures
mMaximumNumberOfFeatures = itemElem.attribute( "maxFeatures", "5" ).toInt();
refreshAttributes();
emit itemChanged();
return success;
}

@ -53,16 +53,70 @@ class CORE_EXPORT QgsComposerAttributeTable: public QgsComposerTable
bool writeXML( QDomElement& elem, QDomDocument & doc ) const;
bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
void setVectorLayer( QgsVectorLayer* vl );
/**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 { return mVectorLayer; }
/**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 );
/*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 { return mComposerMap; }
void setMaximumNumberOfFeatures( int nr ) { mMaximumNumberOfFeatures = nr; }
/**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 { return mMaximumNumberOfFeatures; }
void setDisplayOnlyVisibleFeatures( bool b ) { mShowOnlyVisibleFeatures = b; }
/**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 visibleOnly );
/*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 { return mShowOnlyVisibleFeatures; }
/*Returns true if a feature filter is active on the attribute table
@ -72,13 +126,15 @@ class CORE_EXPORT QgsComposerAttributeTable: public QgsComposerTable
* @see featureFilter
*/
bool filterFeatures() const { return mFilterFeatures; }
/**Sets whether the feature filter is active for the attribute table
/**Sets whether the feature filter is active for the attribute table. 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 filter Set to true to enable the feature filter
* @note added in 2.3
* @see filterFeatures
* @see setFeatureFilter
*/
void setFilterFeatures( bool filter ) { mFilterFeatures = filter; }
void setFilterFeatures( bool filter );
/*Returns the current expression used to filter features for the table. The filter is only
* active if filterFeatures() is true.
@ -89,27 +145,77 @@ class CORE_EXPORT QgsComposerAttributeTable: public QgsComposerTable
*/
QString featureFilter() const { return mFeatureFilter; }
/**Sets the expression used for filtering features in the table. The filter is only
* active if filterFeatures() is set to true.
* active if filterFeatures() is set to true. 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 expression filter to use for selecting which features to display in the table
* @note added in 2.3
* @see featureFilter
* @see setFilterFeatures
*/
void setFeatureFilter( const QString& expression ) { mFeatureFilter = expression; }
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
* @see setDisplayAttributes
*/
QSet<int> displayAttributes() const { return mDisplayAttributes; }
void setDisplayAttributes( const QSet<int>& attr ) { mDisplayAttributes = attr; }
/**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 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, bool refresh = true );
/*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.
* @see setFieldAliasMap
*/
QMap<int, QString> fieldAliasMap() const { return mFieldAliasMap; }
void setFieldAliasMap( const QMap<int, QString>& map ) { mFieldAliasMap = map; }
/**Adapts mMaximumNumberOfFeatures depending on the rectangle height*/
/**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.
* @see fieldAliasMap
*/
void setFieldAliasMap( const QMap<int, QString>& map, bool refresh = true );
/**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
void setSortAttributes( const QList<QPair<int, bool> > att ) { mSortInformation = att; }
/**Sets the attributes to use to sort the table's features.
* @param att QList integers/bool pairs, where the integer refers to the attribute index and
* the bool sets the sort order for the attribute. If true the attribute is sorted ascending,
* if false, the attribute is sorted in descending order. Note that features are sorted
* after the maximum number of displayed features have been fetched from the vector layer's
* provider.
* @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.l
* @see sortAttributes
* @note not available in python bindings
*/
void setSortAttributes( const QList<QPair<int, bool> > att, bool refresh = true );
// @note not available in python bindings
/*Returns the attributes used to sort the table's features.
* @returns a QList of integer/bool pairs, where the integer refers to the attribute index and
* the bool to the sort order for the attribute. If true the attribute is sorted ascending,
* if false, the attribute is sorted in descending order.
* @see setSortAttributes
* @note not available in python bindings
*/
QList<QPair<int, bool> > sortAttributes() const { return mSortInformation; }
protected:
@ -147,7 +253,14 @@ class CORE_EXPORT QgsComposerAttributeTable: public QgsComposerTable
/**Inserts aliases from vector layer as starting configuration to the alias map*/
void initializeAliasMap();
/**Returns the attribute name to display in the item (attribute name or an alias if present)*/
/**Returns the attribute name to display in the table's header row for a specified attribute.
* @param attributeIndex attribute index
* @param name default name to use for the attribute
* @returns the aliases for the attribute if set. If an alias is not set then the
* default name will be returned.
* @see setFieldAliasMap
*/
QString attributeDisplayName( int attributeIndex, const QString& name ) const;
private slots:

@ -42,6 +42,23 @@ QgsComposerTable::~QgsComposerTable()
}
void QgsComposerTable::refreshAttributes()
{
mMaxColumnWidthMap.clear();
mAttributeMaps.clear();
//getFeatureAttributes
if ( !getFeatureAttributes( mAttributeMaps ) )
{
return;
}
//since attributes have changed, we also need to recalculate the column widths
//and size of table
adjustFrameToSize();
}
void QgsComposerTable::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
{
Q_UNUSED( itemStyle );
@ -51,19 +68,14 @@ void QgsComposerTable::paint( QPainter* painter, const QStyleOptionGraphicsItem*
return;
}
//getFeatureAttributes
QList<QgsAttributeMap> attributeMaps;
if ( !getFeatureAttributes( attributeMaps ) )
if ( mComposition->plotStyle() == QgsComposition::Print ||
mComposition->plotStyle() == QgsComposition::Postscript )
{
return;
//exporting composition, so force an attribute refresh
//we do this in case vector layer has changed via an external source (eg, another database user)
refreshAttributes();
}
QMap<int, double> maxColumnWidthMap;
//check how much space each column needs
calculateMaxColumnWidths( maxColumnWidthMap, attributeMaps );
//adapt item frame to max width / height
adaptItemFrame( maxColumnWidthMap, attributeMaps );
drawBackground( painter );
painter->setPen( Qt::SolidLine );
@ -86,8 +98,8 @@ void QgsComposerTable::paint( QPainter* painter, const QStyleOptionGraphicsItem*
currentY += mGridStrokeWidth;
//draw the attribute values
QList<QgsAttributeMap>::const_iterator attIt = attributeMaps.begin();
for ( ; attIt != attributeMaps.end(); ++attIt )
QList<QgsAttributeMap>::const_iterator attIt = mAttributeMaps.begin();
for ( ; attIt != mAttributeMaps.end(); ++attIt )
{
currentY += fontAscentMillimeters( mContentFont );
currentY += mLineTextDistance;
@ -99,7 +111,7 @@ void QgsComposerTable::paint( QPainter* painter, const QStyleOptionGraphicsItem*
currentY += mGridStrokeWidth;
}
currentX += maxColumnWidthMap[columnIt.key()];
currentX += mMaxColumnWidthMap[columnIt.key()];
currentX += mLineTextDistance;
currentX += mGridStrokeWidth;
}
@ -112,8 +124,8 @@ void QgsComposerTable::paint( QPainter* painter, const QStyleOptionGraphicsItem*
gridPen.setColor( mGridColor );
gridPen.setJoinStyle( Qt::MiterJoin );
painter->setPen( gridPen );
drawHorizontalGridLines( painter, attributeMaps.size() );
drawVerticalGridLines( painter, maxColumnWidthMap );
drawHorizontalGridLines( painter, mAttributeMaps.size() );
drawVerticalGridLines( painter, mMaxColumnWidthMap );
}
//draw frame and selection boxes if necessary
@ -124,17 +136,31 @@ void QgsComposerTable::paint( QPainter* painter, const QStyleOptionGraphicsItem*
}
}
void QgsComposerTable::setHeaderFont( const QFont& f )
{
mHeaderFont = f;
//since font attributes have changed, we need to recalculate the table size
adjustFrameToSize();
}
void QgsComposerTable::setContentFont( const QFont& f )
{
mContentFont = f;
//since font attributes have changed, we need to recalculate the table size
adjustFrameToSize();
}
void QgsComposerTable::adjustFrameToSize()
{
QList<QgsAttributeMap> attributes;
if ( !getFeatureAttributes( attributes ) )
//check how much space each column needs
if ( !calculateMaxColumnWidths( mMaxColumnWidthMap, mAttributeMaps ) )
{
return;
}
//adapt item frame to max width / height
adaptItemFrame( mMaxColumnWidthMap, mAttributeMaps );
QMap<int, double> maxWidthMap;
if ( !calculateMaxColumnWidths( maxWidthMap, attributes ) )
return;
adaptItemFrame( maxWidthMap, attributes );
repaint();
}
bool QgsComposerTable::tableWriteXML( QDomElement& elem, QDomDocument & doc ) const

@ -28,6 +28,8 @@
/**A class to display feature attributes in the print composer*/
class CORE_EXPORT QgsComposerTable: public QgsComposerItem
{
Q_OBJECT
public:
QgsComposerTable( QgsComposition* composition );
virtual ~QgsComposerTable();
@ -44,10 +46,10 @@ class CORE_EXPORT QgsComposerTable: public QgsComposerItem
void setLineTextDistance( double d ) { mLineTextDistance = d; }
double lineTextDistance() const { return mLineTextDistance; }
void setHeaderFont( const QFont& f ) { mHeaderFont = f;}
void setHeaderFont( const QFont& f );
QFont headerFont() const { return mHeaderFont; }
void setContentFont( const QFont& f ) { mContentFont = f; }
void setContentFont( const QFont& f );
QFont contentFont() const { return mContentFont; }
void setShowGrid( bool show ) { mShowGrid = show;}
@ -59,9 +61,24 @@ class CORE_EXPORT QgsComposerTable: public QgsComposerItem
void setGridColor( const QColor& c ) { mGridColor = c; }
QColor gridColor() const { return mGridColor; }
/**Adapts the size of the frame to match the content. This is normally done in the paint method, but sometimes
it needs to be done before the first render*/
void adjustFrameToSize();
public slots:
/**Refreshes the attributes shown in the table by querying the vector layer for new data.
* This also causes the column widths and size of the table to change to accomodate the
* new data.
* @note added in 2.3
* @see adjustFrameToSize
*/
virtual void refreshAttributes();
/**Adapts the size of the frame to match the content. First, the optimal width of the columns
* is recalculated by checking the maximum width of attributes shown in the table. Then, the
* table is resized to fit its contents. This slot utilises the table's attribute cache so
* that a re-query of the vector layer is not required.
* @note added in 2.3
* @see refreshAttributes
*/
virtual void adjustFrameToSize();
protected:
/**Distance between table lines and text*/
@ -74,6 +91,9 @@ class CORE_EXPORT QgsComposerTable: public QgsComposerItem
double mGridStrokeWidth;
QColor mGridColor;
QList<QgsAttributeMap> mAttributeMaps;
QMap<int, double> mMaxColumnWidthMap;
/**Retrieves feature attributes*/
//! @note not available in python bindings
virtual bool getFeatureAttributes( QList<QgsAttributeMap>& attributeMaps ) { Q_UNUSED( attributeMaps ); return false; }