Skip to content

Commit 384a280

Browse files
committed
[FEATURE] Add hide column, set column width and autosize to
attribute table header right click menu
1 parent 5dc1c52 commit 384a280

File tree

8 files changed

+169
-6
lines changed

8 files changed

+169
-6
lines changed

python/core/qgsattributetableconfig.sip

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ class QgsAttributeTableConfig
6565
*/
6666
QVector<QgsAttributeTableConfig::ColumnConfig> columns() const;
6767

68+
/** Returns true if the configuration is empty, ie it contains no columns.
69+
*/
70+
bool isEmpty() const;
71+
72+
/** Maps a visible column index to its original column index.
73+
* @param visibleColumn index of visible column
74+
* @returns corresponding index when hidden columns are considered
75+
*/
76+
int mapVisibleColumnToIndex( int visibleColumn ) const;
77+
6878
/**
6979
* Set the list of columns visible in the attribute table.
7080
* The list order defines the order of appearance.
@@ -131,4 +141,17 @@ class QgsAttributeTableConfig
131141
* @see columnWidth()
132142
*/
133143
void setColumnWidth( int column, int width );
144+
145+
/** Returns true if the specified column is hidden.
146+
* @param column column index
147+
* @see setColumnHidden()
148+
*/
149+
bool columnHidden( int column ) const;
150+
151+
/** Sets whether the specified column should be hidden.
152+
* @param column column index
153+
* @param hidden set to true to hide column
154+
* @see columnHidden()
155+
*/
156+
void setColumnHidden( int column, bool hidden );
134157
};

src/app/qgsattributetabledialog.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,11 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
125125

126126
// Initialize dual view
127127
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, mEditorContext );
128-
mMainView->setAttributeTableConfig( mLayer->attributeTableConfig() );
128+
129+
QgsAttributeTableConfig config = mLayer->attributeTableConfig();
130+
if ( config.isEmpty() )
131+
config.update( mLayer->fields() );
132+
mMainView->setAttributeTableConfig( config );
129133

130134
// Initialize filter gui elements
131135
mFilterActionMapper = new QSignalMapper( this );

src/core/qgsattributetableconfig.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,26 @@ QVector<QgsAttributeTableConfig::ColumnConfig> QgsAttributeTableConfig::columns(
2828
return mColumns;
2929
}
3030

31+
bool QgsAttributeTableConfig::isEmpty() const
32+
{
33+
return mColumns.isEmpty();
34+
}
35+
36+
int QgsAttributeTableConfig::mapVisibleColumnToIndex( int visibleColumn ) const
37+
{
38+
for ( int i = 0; i < mColumns.size(); ++i )
39+
{
40+
if ( mColumns.at( i ).hidden )
41+
{
42+
visibleColumn++;
43+
continue;
44+
}
45+
if ( visibleColumn == i )
46+
return i;
47+
}
48+
return -1;
49+
}
50+
3151
void QgsAttributeTableConfig::setColumns( const QVector<ColumnConfig>& columns )
3252
{
3353
mColumns = columns;
@@ -198,6 +218,16 @@ void QgsAttributeTableConfig::setColumnWidth( int column, int width )
198218
mColumns[ column ].width = width;
199219
}
200220

221+
bool QgsAttributeTableConfig::columnHidden( int column ) const
222+
{
223+
return mColumns.at( column ).hidden;
224+
}
225+
226+
void QgsAttributeTableConfig::setColumnHidden( int column, bool hidden )
227+
{
228+
mColumns[ column ].hidden = hidden;
229+
}
230+
201231
void QgsAttributeTableConfig::writeXml( QDomNode& node ) const
202232
{
203233
QDomDocument doc( node.ownerDocument() );

src/core/qgsattributetableconfig.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ class CORE_EXPORT QgsAttributeTableConfig
7575
*/
7676
QVector<ColumnConfig> columns() const;
7777

78+
/** Returns true if the configuration is empty, ie it contains no columns.
79+
*/
80+
bool isEmpty() const;
81+
82+
/** Maps a visible column index to its original column index.
83+
* @param visibleColumn index of visible column
84+
* @returns corresponding index when hidden columns are considered
85+
*/
86+
int mapVisibleColumnToIndex( int visibleColumn ) const;
87+
7888
/**
7989
* Set the list of columns visible in the attribute table.
8090
* The list order defines the order of appearance.
@@ -142,6 +152,19 @@ class CORE_EXPORT QgsAttributeTableConfig
142152
*/
143153
void setColumnWidth( int column, int width );
144154

155+
/** Returns true if the specified column is hidden.
156+
* @param column column index
157+
* @see setColumnHidden()
158+
*/
159+
bool columnHidden( int column ) const;
160+
161+
/** Sets whether the specified column should be hidden.
162+
* @param column column index
163+
* @param hidden set to true to hide column
164+
* @see columnHidden()
165+
*/
166+
void setColumnHidden( int column, bool hidden );
167+
145168
private:
146169
QVector<ColumnConfig> mColumns;
147170
ActionWidgetStyle mActionWidgetStyle;

src/gui/attributetable/qgsattributetablefiltermodel.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,9 @@ void QgsAttributeTableFilterModel::onColumnsChanged()
358358
int QgsAttributeTableFilterModel::mapColumnToSource( int column ) const
359359
{
360360
if ( mColumnMapping.isEmpty() )
361-
return 0;
361+
return column;
362+
if ( column < 0 || column >= mColumnMapping.size() )
363+
return -1;
362364
else
363365
return mColumnMapping.at( column );
364366
}

src/gui/attributetable/qgsattributetableview.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ void QgsAttributeTableView::setAttributeTableConfig( const QgsAttributeTableConf
9898
int i = 0;
9999
Q_FOREACH ( const QgsAttributeTableConfig::ColumnConfig& columnConfig, config.columns() )
100100
{
101+
if ( columnConfig.hidden )
102+
continue;
103+
101104
if ( columnConfig.width >= 0 )
102105
{
103106
setColumnWidth( i, columnConfig.width );

src/gui/attributetable/qgsdualview.cpp

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <QProgressDialog>
3535
#include <QSettings>
3636
#include <QGroupBox>
37+
#include <QInputDialog>
3738

3839
QgsDualView::QgsDualView( QWidget* parent )
3940
: QStackedWidget( parent )
@@ -461,14 +462,32 @@ void QgsDualView::viewWillShowContextMenu( QMenu* menu, const QModelIndex& atInd
461462

462463
void QgsDualView::showViewHeaderMenu( QPoint point )
463464
{
465+
int col = mTableView->columnAt( point.x() );
466+
464467
delete mHorizontalHeaderMenu;
465468
mHorizontalHeaderMenu = new QMenu( this );
469+
470+
QAction* hide = new QAction( tr( "&Hide column" ), mHorizontalHeaderMenu );
471+
connect( hide, SIGNAL( triggered( bool ) ), this, SLOT( hideColumn() ) );
472+
hide->setData( col );
473+
mHorizontalHeaderMenu->addAction( hide );
474+
QAction* setWidth = new QAction( tr( "&Set width..." ), mHorizontalHeaderMenu );
475+
connect( setWidth, SIGNAL( triggered( bool ) ), this, SLOT( resizeColumn() ) );
476+
setWidth->setData( col );
477+
mHorizontalHeaderMenu->addAction( setWidth );
478+
QAction* optimizeWidth = new QAction( tr( "&Autosize" ), mHorizontalHeaderMenu );
479+
connect( optimizeWidth, SIGNAL( triggered( bool ) ), this, SLOT( autosizeColumn() ) );
480+
optimizeWidth->setData( col );
481+
mHorizontalHeaderMenu->addAction( optimizeWidth );
482+
483+
mHorizontalHeaderMenu->addSeparator();
466484
QAction* organize = new QAction( tr( "&Organize columns..." ), mHorizontalHeaderMenu );
467485
connect( organize, SIGNAL( triggered( bool ) ), this, SLOT( organizeColumns() ) );
468486
mHorizontalHeaderMenu->addAction( organize );
469487
QAction* sort = new QAction( tr( "&Sort..." ), mHorizontalHeaderMenu );
470488
connect( sort, SIGNAL( triggered( bool ) ), this, SLOT( modifySort() ) );
471489
mHorizontalHeaderMenu->addAction( sort );
490+
472491
mHorizontalHeaderMenu->popup( mTableView->horizontalHeader()->mapToGlobal( point ) );
473492
}
474493

@@ -490,9 +509,59 @@ void QgsDualView::organizeColumns()
490509

491510
void QgsDualView::tableColumnResized( int column, int width )
492511
{
493-
QgsAttributeTableConfig config = mLayerCache->layer()->attributeTableConfig();
494-
config.setColumnWidth( column, width );
495-
mLayerCache->layer()->setAttributeTableConfig( config );
512+
QgsAttributeTableConfig config = mConfig;
513+
int sourceCol = config.mapVisibleColumnToIndex( column );
514+
if ( sourceCol >= 0 )
515+
{
516+
config.setColumnWidth( sourceCol, width );
517+
mLayerCache->layer()->setAttributeTableConfig( config );
518+
mConfig = config;
519+
}
520+
}
521+
522+
void QgsDualView::hideColumn()
523+
{
524+
QAction* action = qobject_cast<QAction*>( sender() );
525+
int col = action->data().toInt();
526+
QgsAttributeTableConfig config = mConfig;
527+
int sourceCol = mConfig.mapVisibleColumnToIndex( col );
528+
if ( sourceCol >= 0 )
529+
{
530+
config.setColumnHidden( sourceCol, true );
531+
mLayerCache->layer()->setAttributeTableConfig( config );
532+
setAttributeTableConfig( config );
533+
}
534+
}
535+
536+
void QgsDualView::resizeColumn()
537+
{
538+
QAction* action = qobject_cast<QAction*>( sender() );
539+
int col = action->data().toInt();
540+
if ( col < 0 )
541+
return;
542+
543+
QgsAttributeTableConfig config = mConfig;
544+
int sourceCol = config.mapVisibleColumnToIndex( col );
545+
if ( sourceCol >= 0 )
546+
{
547+
bool ok = false;
548+
int width = QInputDialog::getInt( this, tr( "Set column width" ), tr( "Enter column width" ),
549+
mTableView->columnWidth( col ),
550+
0, 1000, 10, &ok );
551+
if ( ok )
552+
{
553+
config.setColumnWidth( sourceCol, width );
554+
mLayerCache->layer()->setAttributeTableConfig( config );
555+
setAttributeTableConfig( config );
556+
}
557+
}
558+
}
559+
560+
void QgsDualView::autosizeColumn()
561+
{
562+
QAction* action = qobject_cast<QAction*>( sender() );
563+
int col = action->data().toInt();
564+
mTableView->resizeColumnToContents( col );
496565
}
497566

498567
void QgsDualView::modifySort()
@@ -501,7 +570,7 @@ void QgsDualView::modifySort()
501570
if ( !layer )
502571
return;
503572

504-
QgsAttributeTableConfig config = layer->attributeTableConfig();
573+
QgsAttributeTableConfig config = mConfig;
505574

506575
QDialog orderByDlg;
507576
orderByDlg.setWindowTitle( tr( "Configure attribute table sort order" ) );
@@ -546,6 +615,7 @@ void QgsDualView::modifySort()
546615
}
547616

548617
layer->setAttributeTableConfig( config );
618+
mConfig = config;
549619
}
550620
}
551621

@@ -606,6 +676,7 @@ void QgsDualView::setAttributeTableConfig( const QgsAttributeTableConfig& config
606676
{
607677
mFilterModel->setAttributeTableConfig( config );
608678
mTableView->setAttributeTableConfig( config );
679+
mConfig = config;
609680
}
610681

611682
void QgsDualView::setSortExpression( const QString& sortExpression )

src/gui/attributetable/qgsdualview.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,12 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
279279

280280
void tableColumnResized( int column, int width );
281281

282+
void hideColumn();
283+
284+
void resizeColumn();
285+
286+
void autosizeColumn();
287+
282288
void modifySort();
283289

284290
void previewExpressionChanged( const QString& expression );
@@ -326,6 +332,7 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
326332
QgsIFeatureSelectionManager* mFeatureSelectionManager;
327333
QgsDistanceArea mDistanceArea;
328334
QString mDisplayExpression;
335+
QgsAttributeTableConfig mConfig;
329336

330337
friend class TestQgsDualView;
331338
};

0 commit comments

Comments
 (0)