Skip to content

Commit 1e051f0

Browse files
committed
[FEATURE] Add a button in attribute table toolbar to switch between
docked and window mode Previously you had to change an option in the settings dialog and open a new table in order to switch between docked/undocked, but that's painful if you decide after a table is already open that you'd like to dock/undock it...
1 parent a4a74a9 commit 1e051f0

File tree

4 files changed

+95
-21
lines changed

4 files changed

+95
-21
lines changed

src/app/qgsattributetabledialog.cpp

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,17 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
226226
// info from table to application
227227
connect( this, &QgsAttributeTableDialog::saveEdits, this, [ = ] { QgisApp::instance()->saveEdits(); } );
228228

229-
bool myDockFlag = settings.value( QStringLiteral( "qgis/dockAttributeTable" ), false ).toBool();
230-
if ( myDockFlag )
229+
const bool dockTable = settings.value( QStringLiteral( "qgis/dockAttributeTable" ), false ).toBool();
230+
if ( dockTable )
231231
{
232-
mDock = new QgsAttributeTableDock( tr( "%1 (%n Feature(s))", "feature count", mMainView->featureCount() ).arg( mLayer->name() ), QgisApp::instance() );
232+
mDock = new QgsAttributeTableDock( QString(), QgisApp::instance() );
233233
mDock->setWidget( this );
234234
connect( this, &QObject::destroyed, mDock, &QWidget::close );
235235
QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock );
236236
}
237+
mActionDockUndock->setChecked( dockTable );
238+
connect( mActionDockUndock, &QAction::toggled, this, &QgsAttributeTableDialog::toggleDockMode );
239+
installEventFilter( this );
237240

238241
columnBoxInit();
239242
updateTitle();
@@ -363,7 +366,9 @@ void QgsAttributeTableDialog::updateTitle()
363366
{
364367
return;
365368
}
366-
QWidget *w = mDock ? qobject_cast<QWidget *>( mDock ) : qobject_cast<QWidget *>( this );
369+
QWidget *w = mDock ? qobject_cast<QWidget *>( mDock )
370+
: mDialog ? qobject_cast<QWidget *>( mDialog )
371+
: qobject_cast<QWidget *>( this );
367372
w->setWindowTitle( tr( " %1 :: Features Total: %2, Filtered: %3, Selected: %4" )
368373
.arg( mLayer->name() )
369374
.arg( std::max( static_cast< long >( mMainView->featureCount() ), mLayer->featureCount() ) ) // layer count may be estimated, so use larger of the two
@@ -390,25 +395,28 @@ void QgsAttributeTableDialog::updateButtonStatus( const QString &fieldName, bool
390395
mRunFieldCalc->setEnabled( isValid );
391396
}
392397

393-
void QgsAttributeTableDialog::closeEvent( QCloseEvent *event )
398+
void QgsAttributeTableDialog::keyPressEvent( QKeyEvent *event )
394399
{
395-
QDialog::closeEvent( event );
400+
QDialog::keyPressEvent( event );
396401

397-
if ( !mDock )
402+
if ( ( event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete ) && mActionDeleteSelected->isEnabled() )
398403
{
399-
QgsSettings settings;
400-
settings.setValue( QStringLiteral( "Windows/BetterAttributeTable/geometry" ), saveGeometry() );
404+
QgisApp::instance()->deleteSelected( mLayer, this );
401405
}
402406
}
403407

404-
void QgsAttributeTableDialog::keyPressEvent( QKeyEvent *event )
408+
bool QgsAttributeTableDialog::eventFilter( QObject *object, QEvent *ev )
405409
{
406-
QDialog::keyPressEvent( event );
407-
408-
if ( ( event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete ) && mActionDeleteSelected->isEnabled() )
410+
if ( ev->type() == QEvent::Close && !mDock && ( !mDialog || mDialog == object ) )
409411
{
410-
QgisApp::instance()->deleteSelected( mLayer, this );
412+
if ( QWidget *w = qobject_cast< QWidget * >( object ) )
413+
{
414+
QgsSettings settings;
415+
settings.setValue( QStringLiteral( "Windows/BetterAttributeTable/geometry" ), w->saveGeometry() );
416+
}
411417
}
418+
419+
return QDialog::eventFilter( object, ev );
412420
}
413421

414422
void QgsAttributeTableDialog::columnBoxInit()
@@ -1094,6 +1102,56 @@ void QgsAttributeTableDialog::showContextMenu( QgsActionMenu *menu, const QgsFea
10941102
}
10951103
}
10961104

1105+
void QgsAttributeTableDialog::toggleDockMode( bool docked )
1106+
{
1107+
if ( docked )
1108+
{
1109+
// going from window -> dock, so save current window geometry
1110+
QgsSettings().setValue( QStringLiteral( "Windows/BetterAttributeTable/geometry" ), mDialog ? mDialog->saveGeometry() : saveGeometry() );
1111+
if ( mDialog )
1112+
{
1113+
mDialog->removeEventFilter( this );
1114+
mDialog->setLayout( nullptr );
1115+
mDialog->deleteLater();
1116+
mDialog = nullptr;
1117+
}
1118+
1119+
mDock = new QgsAttributeTableDock( QString(), QgisApp::instance() );
1120+
mDock->setWidget( this );
1121+
connect( this, &QObject::destroyed, mDock, &QWidget::close );
1122+
QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock );
1123+
updateTitle();
1124+
}
1125+
else
1126+
{
1127+
// going from dock -> window
1128+
1129+
mDialog = new QDialog( QgisApp::instance(), Qt::Window );
1130+
mDialog->setAttribute( Qt::WA_DeleteOnClose );
1131+
1132+
QVBoxLayout *vl = new QVBoxLayout();
1133+
vl->setContentsMargins( 0, 0, 0, 0 );
1134+
vl->setMargin( 0 );
1135+
vl->addWidget( this );
1136+
mDialog->setLayout( vl );
1137+
1138+
if ( mDock )
1139+
{
1140+
mDock->setWidget( nullptr );
1141+
disconnect( this, &QObject::destroyed, mDock, &QWidget::close );
1142+
mDock->deleteLater();
1143+
mDock = nullptr;
1144+
}
1145+
1146+
// subscribe to close events, so that we can save window geometry
1147+
mDialog->installEventFilter( this );
1148+
1149+
updateTitle();
1150+
mDialog->restoreGeometry( QgsSettings().value( QStringLiteral( "Windows/BetterAttributeTable/geometry" ) ).toByteArray() );
1151+
mDialog->show();
1152+
}
1153+
}
1154+
10971155
//
10981156
// QgsAttributeTableDock
10991157
//

src/app/qgsattributetabledialog.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,18 +200,14 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
200200

201201
protected:
202202

203-
/**
204-
* Handle closing of the window
205-
* \param event unused
206-
*/
207-
void closeEvent( QCloseEvent *event ) override;
208-
209203
/*
210204
* Handle KeyPress event of the window
211205
* \param event
212206
*/
213207
void keyPressEvent( QKeyEvent *event ) override;
214208

209+
bool eventFilter( QObject *object, QEvent *ev ) override;
210+
215211
private slots:
216212

217213
/**
@@ -225,12 +221,14 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
225221
void viewModeChanged( QgsAttributeForm::Mode mode );
226222
void formFilterSet( const QString &filter, QgsAttributeForm::FilterType type );
227223
void showContextMenu( QgsActionMenu *menu, QgsFeatureId fid );
224+
void toggleDockMode( bool docked );
228225

229226
private:
230227
QMenu *mMenuActions = nullptr;
231228
QToolButton *mActionFeatureActions = nullptr;
232229

233230
QgsDockWidget *mDock = nullptr;
231+
QDialog *mDialog = nullptr;
234232
QgsDistanceArea *myDa = nullptr;
235233

236234

src/ui/qgsattributetabledialog.ui

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@
260260
<addaction name="separator"/>
261261
<addaction name="mActionSetStyles"/>
262262
<addaction name="separator"/>
263+
<addaction name="mActionDockUndock"/>
263264
</widget>
264265
</item>
265266
</layout>
@@ -633,6 +634,21 @@
633634
<string>Conditional formatting</string>
634635
</property>
635636
</action>
637+
<action name="mActionDockUndock">
638+
<property name="checkable">
639+
<bool>true</bool>
640+
</property>
641+
<property name="icon">
642+
<iconset resource="../../python/plugins/db_manager/resources.qrc">
643+
<normaloff>:/db_manager/icons/tables.xpm</normaloff>:/db_manager/icons/tables.xpm</iconset>
644+
</property>
645+
<property name="text">
646+
<string>Dock Attribute Table</string>
647+
</property>
648+
<property name="toolTip">
649+
<string>Dock Attribute Table</string>
650+
</property>
651+
</action>
636652
</widget>
637653
<customwidgets>
638654
<customwidget>
@@ -670,6 +686,8 @@
670686
<tabstop>mTableViewButton</tabstop>
671687
</tabstops>
672688
<resources>
689+
<include location="../../images/images.qrc"/>
690+
<include location="../../python/plugins/db_manager/resources.qrc"/>
673691
<include location="../../images/images.qrc"/>
674692
<include location="../../images/images.qrc"/>
675693
<include location="../../images/images.qrc"/>

src/ui/qgsoptionsbase.ui

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1799,7 +1799,7 @@
17991799
<item row="0" column="0" colspan="2">
18001800
<widget class="QCheckBox" name="cbxAttributeTableDocked">
18011801
<property name="text">
1802-
<string>Open attribute table in a dock window</string>
1802+
<string>Open new attribute tables as docked windows</string>
18031803
</property>
18041804
</widget>
18051805
</item>

0 commit comments

Comments
 (0)