Skip to content

Commit

Permalink
[FEATURE] Add a button in attribute table toolbar to switch between
Browse files Browse the repository at this point in the history
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...
  • Loading branch information
nyalldawson committed Aug 13, 2018
1 parent a4a74a9 commit 1e051f0
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 21 deletions.
86 changes: 72 additions & 14 deletions src/app/qgsattributetabledialog.cpp
Expand Up @@ -226,14 +226,17 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
// info from table to application
connect( this, &QgsAttributeTableDialog::saveEdits, this, [ = ] { QgisApp::instance()->saveEdits(); } );

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

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

void QgsAttributeTableDialog::closeEvent( QCloseEvent *event )
void QgsAttributeTableDialog::keyPressEvent( QKeyEvent *event )
{
QDialog::closeEvent( event );
QDialog::keyPressEvent( event );

if ( !mDock )
if ( ( event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete ) && mActionDeleteSelected->isEnabled() )
{
QgsSettings settings;
settings.setValue( QStringLiteral( "Windows/BetterAttributeTable/geometry" ), saveGeometry() );
QgisApp::instance()->deleteSelected( mLayer, this );
}
}

void QgsAttributeTableDialog::keyPressEvent( QKeyEvent *event )
bool QgsAttributeTableDialog::eventFilter( QObject *object, QEvent *ev )
{
QDialog::keyPressEvent( event );

if ( ( event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete ) && mActionDeleteSelected->isEnabled() )
if ( ev->type() == QEvent::Close && !mDock && ( !mDialog || mDialog == object ) )
{
QgisApp::instance()->deleteSelected( mLayer, this );
if ( QWidget *w = qobject_cast< QWidget * >( object ) )
{
QgsSettings settings;
settings.setValue( QStringLiteral( "Windows/BetterAttributeTable/geometry" ), w->saveGeometry() );
}
}

return QDialog::eventFilter( object, ev );
}

void QgsAttributeTableDialog::columnBoxInit()
Expand Down Expand Up @@ -1094,6 +1102,56 @@ void QgsAttributeTableDialog::showContextMenu( QgsActionMenu *menu, const QgsFea
}
}

void QgsAttributeTableDialog::toggleDockMode( bool docked )
{
if ( docked )
{
// going from window -> dock, so save current window geometry
QgsSettings().setValue( QStringLiteral( "Windows/BetterAttributeTable/geometry" ), mDialog ? mDialog->saveGeometry() : saveGeometry() );
if ( mDialog )
{
mDialog->removeEventFilter( this );
mDialog->setLayout( nullptr );
mDialog->deleteLater();
mDialog = nullptr;
}

mDock = new QgsAttributeTableDock( QString(), QgisApp::instance() );
mDock->setWidget( this );
connect( this, &QObject::destroyed, mDock, &QWidget::close );
QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock );
updateTitle();
}
else
{
// going from dock -> window

mDialog = new QDialog( QgisApp::instance(), Qt::Window );
mDialog->setAttribute( Qt::WA_DeleteOnClose );

QVBoxLayout *vl = new QVBoxLayout();
vl->setContentsMargins( 0, 0, 0, 0 );
vl->setMargin( 0 );
vl->addWidget( this );
mDialog->setLayout( vl );

if ( mDock )
{
mDock->setWidget( nullptr );
disconnect( this, &QObject::destroyed, mDock, &QWidget::close );
mDock->deleteLater();
mDock = nullptr;
}

// subscribe to close events, so that we can save window geometry
mDialog->installEventFilter( this );

updateTitle();
mDialog->restoreGeometry( QgsSettings().value( QStringLiteral( "Windows/BetterAttributeTable/geometry" ) ).toByteArray() );
mDialog->show();
}
}

//
// QgsAttributeTableDock
//
Expand Down
10 changes: 4 additions & 6 deletions src/app/qgsattributetabledialog.h
Expand Up @@ -200,18 +200,14 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib

protected:

/**
* Handle closing of the window
* \param event unused
*/
void closeEvent( QCloseEvent *event ) override;

/*
* Handle KeyPress event of the window
* \param event
*/
void keyPressEvent( QKeyEvent *event ) override;

bool eventFilter( QObject *object, QEvent *ev ) override;

private slots:

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

private:
QMenu *mMenuActions = nullptr;
QToolButton *mActionFeatureActions = nullptr;

QgsDockWidget *mDock = nullptr;
QDialog *mDialog = nullptr;
QgsDistanceArea *myDa = nullptr;


Expand Down
18 changes: 18 additions & 0 deletions src/ui/qgsattributetabledialog.ui
Expand Up @@ -260,6 +260,7 @@
<addaction name="separator"/>
<addaction name="mActionSetStyles"/>
<addaction name="separator"/>
<addaction name="mActionDockUndock"/>
</widget>
</item>
</layout>
Expand Down Expand Up @@ -633,6 +634,21 @@
<string>Conditional formatting</string>
</property>
</action>
<action name="mActionDockUndock">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../../python/plugins/db_manager/resources.qrc">
<normaloff>:/db_manager/icons/tables.xpm</normaloff>:/db_manager/icons/tables.xpm</iconset>
</property>
<property name="text">
<string>Dock Attribute Table</string>
</property>
<property name="toolTip">
<string>Dock Attribute Table</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
Expand Down Expand Up @@ -670,6 +686,8 @@
<tabstop>mTableViewButton</tabstop>
</tabstops>
<resources>
<include location="../../images/images.qrc"/>
<include location="../../python/plugins/db_manager/resources.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
Expand Down
2 changes: 1 addition & 1 deletion src/ui/qgsoptionsbase.ui
Expand Up @@ -1799,7 +1799,7 @@
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="cbxAttributeTableDocked">
<property name="text">
<string>Open attribute table in a dock window</string>
<string>Open new attribute tables as docked windows</string>
</property>
</widget>
</item>
Expand Down

0 comments on commit 1e051f0

Please sign in to comment.