[FEATURE] Remember widths for attribute table columns

If you resize columns, the width will be restored when next
opening the attribute table for that layer.
This commit is contained in:
Nyall Dawson 2016-06-03 12:23:11 +10:00
parent 9d780bac1b
commit 4c1812a9f6
12 changed files with 146 additions and 39 deletions

View File

@ -17,6 +17,7 @@
/**
* This is a container for configuration of the attribute table.
* The configuration is specific for one vector layer.
* \note added in QGIS 2.16
*/
class QgsAttributeTableConfig
@ -39,9 +40,12 @@ class QgsAttributeTableConfig
*/
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
//! Constructor for ColumnConfig
ColumnConfig();
Type type; //!< The type of this column.
QString name; //!< The name of the attribute if this column represents a field
bool hidden; //!< Flag that controls if the column is hidden
int width; //!< Width of column, or -1 for default width
};
/**
@ -115,4 +119,16 @@ class QgsAttributeTableConfig
*/
void setSortExpression( const QString& sortExpression );
/** Returns the width of a column, or -1 if column should use default width.
* @param column column index
* @see setColumnWidth()
*/
int columnWidth( int column ) const;
/** Sets the width of a column.
* @param column column index
* @param width column width in pixels, or -1 if column should use default width
* @see columnWidth()
*/
void setColumnWidth( int column, int width );
};

View File

@ -28,6 +28,13 @@ class QgsAttributeTableView : QTableView
*/
virtual bool eventFilter( QObject* object, QEvent* event );
/**
* Set the attribute table config which should be used to control
* the appearance of the attribute table.
* @note added in QGIS 2.16
*/
void setAttributeTableConfig( const QgsAttributeTableConfig& config );
protected:
/**
* Called for mouse press events on a table cell.
@ -89,6 +96,13 @@ class QgsAttributeTableView : QTableView
void finished();
/** Emitted when a column in the view has been resized.
* @param column column index (starts at 0)
* @param width new width in pixel
* @note added in QGIS 2.16
*/
void columnResized( int column, int width );
public slots:
void repaintRequested( const QModelIndexList& indexes );
void repaintRequested();

View File

@ -74,8 +74,8 @@ void QgsAttributeActionDialog::init( const QgsActionManager& actions, const QgsA
updateButtons();
QgsAttributeTableConfig::ColumnConfig visibleActionWidgetConfig = QgsAttributeTableConfig::ColumnConfig();
visibleActionWidgetConfig.mType = QgsAttributeTableConfig::Action;
visibleActionWidgetConfig.mHidden = false;
visibleActionWidgetConfig.type = QgsAttributeTableConfig::Action;
visibleActionWidgetConfig.hidden = false;
mShowInAttributeTable->setChecked( attributeTableConfig.actionWidgetVisible() );
mAttributeTableWidgetType->setCurrentIndex( attributeTableConfig.actionWidgetStyle() );

View File

@ -586,9 +586,9 @@ void QgsVectorLayerProperties::apply()
for ( int i = 0; i < columns.size(); ++i )
{
if ( columns.at( i ).mType == QgsAttributeTableConfig::Action )
if ( columns.at( i ).type == QgsAttributeTableConfig::Action )
{
columns[i].mHidden = !mActionDialog->showWidgetInAttributeTable();
columns[i].hidden = !mActionDialog->showWidgetInAttributeTable();
}
}

View File

@ -42,18 +42,18 @@ void QgsAttributeTableConfig::update( const QgsFields& fields )
for ( int i = mColumns.count() - 1; i >= 0; --i )
{
const ColumnConfig& column = mColumns.at( i );
if ( column.mType == Field )
if ( column.type == Field )
{
if ( fields.fieldNameIndex( column.mName ) == -1 )
if ( fields.fieldNameIndex( column.name ) == -1 )
{
mColumns.remove( i );
}
else
{
columns.append( column.mName );
columns.append( column.name );
}
}
else if ( column.mType == Action )
else if ( column.type == Action )
{
containsActionColumn = true;
}
@ -64,9 +64,9 @@ void QgsAttributeTableConfig::update( const QgsFields& fields )
if ( !columns.contains( field.name() ) )
{
ColumnConfig newColumn;
newColumn.mHidden = false;
newColumn.mType = Field;
newColumn.mName = field.name();
newColumn.hidden = false;
newColumn.type = Field;
newColumn.name = field.name();
mColumns.append( newColumn );
}
@ -76,8 +76,8 @@ void QgsAttributeTableConfig::update( const QgsFields& fields )
{
ColumnConfig actionConfig;
actionConfig.mType = Action;
actionConfig.mHidden = true;
actionConfig.type = Action;
actionConfig.hidden = true;
mColumns.append( actionConfig );
}
@ -87,7 +87,7 @@ bool QgsAttributeTableConfig::actionWidgetVisible() const
{
Q_FOREACH ( const ColumnConfig& columnConfig, mColumns )
{
if ( columnConfig.mType == Action && columnConfig.mHidden == false )
if ( columnConfig.type == Action && columnConfig.hidden == false )
return true;
}
return false;
@ -97,9 +97,9 @@ void QgsAttributeTableConfig::setActionWidgetVisible( bool visible )
{
for ( int i = 0; i < mColumns.size(); ++i )
{
if ( mColumns.at( i ).mType == Action )
if ( mColumns.at( i ).type == Action )
{
mColumns[i].mHidden = !visible;
mColumns[i].hidden = !visible;
}
}
}
@ -134,15 +134,16 @@ void QgsAttributeTableConfig::readXml( const QDomNode& node )
if ( columnElement.attribute( "type" ) == "actions" )
{
column.mType = Action;
column.type = Action;
}
else
{
column.mType = Field;
column.mName = columnElement.attribute( "name" );
column.type = Field;
column.name = columnElement.attribute( "name" );
}
column.mHidden = columnElement.attribute( "hidden" ) == "1";
column.hidden = columnElement.attribute( "hidden" ) == "1";
column.width = columnElement.attribute( "width", "-1" ).toDouble();
mColumns.append( column );
}
@ -166,9 +167,9 @@ void QgsAttributeTableConfig::readXml( const QDomNode& node )
{
ColumnConfig column;
column.mName = editTypeElement.attribute( "name" );
column.mHidden = true;
column.mType = Field;
column.name = editTypeElement.attribute( "name" );
column.hidden = true;
column.type = Field;
mColumns.append( column );
}
}
@ -187,6 +188,16 @@ void QgsAttributeTableConfig::setSortExpression( const QString& sortExpression )
mSortExpression = sortExpression;
}
int QgsAttributeTableConfig::columnWidth( int column ) const
{
return mColumns.at( column ).width;
}
void QgsAttributeTableConfig::setColumnWidth( int column, int width )
{
mColumns[ column ].width = width;
}
void QgsAttributeTableConfig::writeXml( QDomNode& node ) const
{
QDomDocument doc( node.ownerDocument() );
@ -202,17 +213,18 @@ void QgsAttributeTableConfig::writeXml( QDomNode& node ) const
{
QDomElement columnElement = doc.createElement( "column" );
if ( column.mType == Action )
if ( column.type == Action )
{
columnElement.setAttribute( "type", "actions" );
}
else
{
columnElement.setAttribute( "type", "field" );
columnElement.setAttribute( "name", column.mName );
columnElement.setAttribute( "name", column.name );
}
columnElement.setAttribute( "hidden", column.mHidden );
columnElement.setAttribute( "hidden", column.hidden );
columnElement.setAttribute( "width", QString::number( column.width ) );
columnsElement.appendChild( columnElement );
}

View File

@ -25,6 +25,7 @@
/**
* This is a container for configuration of the attribute table.
* The configuration is specific for one vector layer.
* \note added in QGIS 2.16
*/
class CORE_EXPORT QgsAttributeTableConfig
@ -44,9 +45,17 @@ class CORE_EXPORT QgsAttributeTableConfig
*/
struct ColumnConfig
{
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
//! Constructor for ColumnConfig
ColumnConfig()
: type( Field )
, hidden( false )
, width( -1 )
{}
Type type; //!< The type of this column.
QString name; //!< The name of the attribute if this column represents a field
bool hidden; //!< Flag that controls if the column is hidden
int width; //!< Width of column, or -1 for default width
};
/**
@ -120,6 +129,19 @@ class CORE_EXPORT QgsAttributeTableConfig
*/
void setSortExpression( const QString& sortExpression );
/** Returns the width of a column, or -1 if column should use default width.
* @param column column index
* @see setColumnWidth()
*/
int columnWidth( int column ) const;
/** Sets the width of a column.
* @param column column index
* @param width column width in pixels, or -1 if column should use default width
* @see columnWidth()
*/
void setColumnWidth( int column, int width );
private:
QVector<ColumnConfig> mColumns;
ActionWidgetStyle mActionWidgetStyle;

View File

@ -119,11 +119,11 @@ void QgsAttributeTableFilterModel::setAttributeTableConfig( const QgsAttributeTa
Q_FOREACH ( const QgsAttributeTableConfig::ColumnConfig& columnConfig, mConfig.columns() )
{
// Hidden? Forget about this column
if ( columnConfig.mHidden )
if ( columnConfig.hidden )
continue;
// The new value for the mapping (field index or -1 for action column)
int newValue = ( columnConfig.mType == QgsAttributeTableConfig::Action ) ? -1 : layer()->fieldNameIndex( columnConfig.mName );
int newValue = ( columnConfig.type == QgsAttributeTableConfig::Action ) ? -1 : layer()->fieldNameIndex( columnConfig.name );
newColumnMapping << newValue;
}

View File

@ -93,6 +93,23 @@ bool QgsAttributeTableView::eventFilter( QObject *object, QEvent *event )
return false;
}
void QgsAttributeTableView::setAttributeTableConfig( const QgsAttributeTableConfig& config )
{
int i = 0;
Q_FOREACH ( const QgsAttributeTableConfig::ColumnConfig& columnConfig, config.columns() )
{
if ( columnConfig.width >= 0 )
{
setColumnWidth( i, columnConfig.width );
}
else
{
setColumnWidth( i, horizontalHeader()->defaultSectionSize() );
}
i++;
}
}
void QgsAttributeTableView::setModel( QgsAttributeTableFilterModel* filterModel )
{
if ( mFilterModel )
@ -385,6 +402,7 @@ void QgsAttributeTableView::columnSizeChanged( int index, int oldWidth, int newW
mActionWidget->resize( newWidth, mActionWidget->height() );
updateActionImage( mActionWidget );
}
emit columnResized( index, newWidth );
}
void QgsAttributeTableView::updateActionImage( QWidget* widget )

View File

@ -31,7 +31,7 @@ class QgsVectorLayer;
class QgsVectorLayerCache;
class QMenu;
class QProgressDialog;
class QgsAttributeTableConfig;
/**
* @brief
@ -68,6 +68,13 @@ class GUI_EXPORT QgsAttributeTableView : public QTableView
*/
virtual bool eventFilter( QObject* object, QEvent* event ) override;
/**
* Set the attribute table config which should be used to control
* the appearance of the attribute table.
* @note added in QGIS 2.16
*/
void setAttributeTableConfig( const QgsAttributeTableConfig& config );
protected:
/**
* Called for mouse press events on a table cell.
@ -127,6 +134,13 @@ class GUI_EXPORT QgsAttributeTableView : public QTableView
*/
void willShowContextMenu( QMenu* menu, const QModelIndex& atIndex );
/** Emitted when a column in the view has been resized.
* @param column column index (starts at 0)
* @param width new width in pixel
* @note added in QGIS 2.16
*/
void columnResized( int column, int width );
void finished();
public slots:

View File

@ -72,6 +72,7 @@ void QgsDualView::init( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, const Qg
connect( mTableView, SIGNAL( willShowContextMenu( QMenu*, QModelIndex ) ), this, SLOT( viewWillShowContextMenu( QMenu*, QModelIndex ) ) );
mTableView->horizontalHeader()->setContextMenuPolicy( Qt::CustomContextMenu );
connect( mTableView->horizontalHeader(), SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( showViewHeaderMenu( QPoint ) ) );
connect( mTableView, SIGNAL( columnResized( int, int ) ), this, SLOT( tableColumnResized( int, int ) ) );
initLayerCache( layer, !request.filterRect().isNull() );
initModels( mapCanvas, request );
@ -487,6 +488,13 @@ void QgsDualView::organizeColumns()
}
}
void QgsDualView::tableColumnResized( int column, int width )
{
QgsAttributeTableConfig config = mLayerCache->layer()->attributeTableConfig();
config.setColumnWidth( column, width );
mLayerCache->layer()->setAttributeTableConfig( config );
}
void QgsDualView::modifySort()
{
QgsVectorLayer* layer = mLayerCache->layer();
@ -597,6 +605,7 @@ void QgsDualView::setFeatureSelectionManager( QgsIFeatureSelectionManager* featu
void QgsDualView::setAttributeTableConfig( const QgsAttributeTableConfig& config )
{
mFilterModel->setAttributeTableConfig( config );
mTableView->setAttributeTableConfig( config );
}
void QgsDualView::setSortExpression( const QString& sortExpression )

View File

@ -277,6 +277,8 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
void organizeColumns();
void tableColumnResized( int column, int width );
void modifySort();
void previewExpressionChanged( const QString& expression );

View File

@ -59,14 +59,14 @@ QgsOrganizeTableColumnsDialog::QgsOrganizeTableColumnsDialog( const QgsVectorLay
Q_FOREACH ( const QgsAttributeTableConfig::ColumnConfig& columnConfig, mConfig.columns() )
{
QListWidgetItem* item;
if ( columnConfig.mType == QgsAttributeTableConfig::Action )
if ( columnConfig.type == QgsAttributeTableConfig::Action )
{
item = new QListWidgetItem( tr( "[Action Widget]" ), mFieldsList );
item->setIcon( QgsApplication::getThemeIcon( "/propertyicons/action.svg" ) );
}
else
{
int idx = vl->fieldNameIndex( columnConfig.mName );
int idx = vl->fieldNameIndex( columnConfig.name );
item = new QListWidgetItem( vl->attributeDisplayName( idx ), mFieldsList );
switch ( vl->fields().fieldOrigin( idx ) )
@ -85,7 +85,7 @@ QgsOrganizeTableColumnsDialog::QgsOrganizeTableColumnsDialog( const QgsVectorLay
}
}
item->setCheckState( columnConfig.mHidden ? Qt::Unchecked : Qt::Checked );
item->setCheckState( columnConfig.hidden ? Qt::Unchecked : Qt::Checked );
item->setData( Qt::UserRole, QVariant::fromValue( columnConfig ) );
}
}
@ -116,7 +116,7 @@ QgsAttributeTableConfig QgsOrganizeTableColumnsDialog::config() const
const QListWidgetItem* item = mFieldsList->item( i );
QgsAttributeTableConfig::ColumnConfig columnConfig = item->data( Qt::UserRole ).value<QgsAttributeTableConfig::ColumnConfig>();
columnConfig.mHidden = item->checkState() == Qt::Unchecked;
columnConfig.hidden = item->checkState() == Qt::Unchecked;
columns.append( columnConfig );
}