mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Fix style dock button not synced to dock state (fix #14862)
Add a new class QgsDockWidget which has finer control over setting and retrieving the dock visibility, to account for dock widgets which are open but hidden by other docks
This commit is contained in:
parent
a033e81add
commit
cb4dacfebc
@ -63,6 +63,7 @@
|
||||
%Include qgsdetaileditemwidget.sip
|
||||
%Include qgsdial.sip
|
||||
%Include qgsdialog.sip
|
||||
%Include qgsdockwidget.sip
|
||||
%Include qgsencodingfiledialog.sip
|
||||
%Include qgserrordialog.sip
|
||||
%Include qgsexpressionbuilderdialog.sip
|
||||
|
61
python/gui/qgsdockwidget.sip
Normal file
61
python/gui/qgsdockwidget.sip
Normal file
@ -0,0 +1,61 @@
|
||||
/** \ingroup gui
|
||||
* \class QgsDockWidget
|
||||
* QDockWidget subclass with more fine-grained control over how the widget is closed or opened.
|
||||
* \note added in 2.16
|
||||
*/
|
||||
|
||||
class QgsDockWidget : QDockWidget
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsdockwidget.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor for QgsDockWidget.
|
||||
* @param parent parent widget
|
||||
*/
|
||||
explicit QgsDockWidget( QWidget* parent /TransferThis/ = nullptr );
|
||||
|
||||
public slots:
|
||||
|
||||
/** Sets the dock widget as visible to a user, ie both shown and raised to the front.
|
||||
* @param visible set to true to show the dock to the user, or false to hide the dock.
|
||||
* When setting a dock as user visible, the dock will be opened (if it is not already
|
||||
* opened) and raised to the front.
|
||||
* When setting as hidden, the following logic is used:
|
||||
* - hiding a dock which is open but not raised (ie hidden by another tab) will have no
|
||||
* effect, and the dock will still be opened and hidden by the other tab
|
||||
* - hiding a dock which is open and raised (ie, user visible) will cause the dock to
|
||||
* be closed
|
||||
* - hiding a dock which is closed has no effect and raises no signals
|
||||
* @see isUserVisible()
|
||||
*/
|
||||
void setUserVisible( bool visible );
|
||||
|
||||
/** Returns true if the dock is both opened and raised to the front (ie not hidden by
|
||||
* any other tabs.
|
||||
* @see setUserVisible()
|
||||
*/
|
||||
bool isUserVisible() const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void closeEvent( QCloseEvent * );
|
||||
virtual void showEvent( QShowEvent* event );
|
||||
|
||||
signals:
|
||||
|
||||
/** Emitted when dock widget is closed (or opened).
|
||||
* @param wasClosed will be true if dock widget was closed, or false if dock widget was opened
|
||||
* @see opened()
|
||||
*/
|
||||
void closed( bool wasClosed );
|
||||
|
||||
/** Emitted when dock widget is opened (or closed).
|
||||
* @param wasOpened will be true if dock widget was opened, or false if dock widget was closed
|
||||
* @see closed()
|
||||
*/
|
||||
void opened( bool wasOpened );
|
||||
|
||||
};
|
@ -135,6 +135,7 @@
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgsdatumtransformdialog.h"
|
||||
#include "qgsdoublespinbox.h"
|
||||
#include "qgsdockwidget.h"
|
||||
#include "qgsdxfexport.h"
|
||||
#include "qgsdxfexportdialog.h"
|
||||
#include "qgsdecorationcopyright.h"
|
||||
@ -769,13 +770,13 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
|
||||
mUndoDock->hide();
|
||||
|
||||
startProfile( "Map Style dock" );
|
||||
mMapStylingDock = new QDockWidget( this );
|
||||
mMapStylingDock = new QgsDockWidget( this );
|
||||
mMapStylingDock->setWindowTitle( tr( "Map Styling" ) );
|
||||
mMapStylingDock->setObjectName( "MapStyling" );
|
||||
mMapStyleWidget = new QgsMapStylingWidget( mMapCanvas, mMapStylePanelFactories );
|
||||
mMapStylingDock->setWidget( mMapStyleWidget );
|
||||
connect( mMapStyleWidget, SIGNAL( styleChanged( QgsMapLayer* ) ), this, SLOT( updateLabelToolButtons() ) );
|
||||
// connect( mMapStylingDock, SIGNAL( visibilityChanged( bool ) ), mActionStyleDock, SLOT( setChecked( bool ) ) );
|
||||
connect( mMapStylingDock, SIGNAL( visibilityChanged( bool ) ), mActionStyleDock, SLOT( setChecked( bool ) ) );
|
||||
|
||||
addDockWidget( Qt::RightDockWidgetArea, mMapStylingDock );
|
||||
mMapStylingDock->hide();
|
||||
@ -5800,7 +5801,7 @@ void QgisApp::setMapStyleDockLayer( QgsMapLayer* layer )
|
||||
|
||||
void QgisApp::mapStyleDock( bool enabled )
|
||||
{
|
||||
mMapStylingDock->setVisible( enabled );
|
||||
mMapStylingDock->setUserVisible( enabled );
|
||||
setMapStyleDockLayer( activeLayer() );
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ class QgsStatusBarMagnifierWidget;
|
||||
class QgsStatusBarScaleWidget;
|
||||
class QgsContrastEnhancement;
|
||||
class QgsCustomLayerOrderWidget;
|
||||
class QgsDockWidget;
|
||||
class QgsDoubleSpinBox;
|
||||
class QgsFeature;
|
||||
class QgsGeometry;
|
||||
@ -1730,7 +1731,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
QgsSnappingDialog *mSnappingDialog;
|
||||
|
||||
QgsPluginManager *mPluginManager;
|
||||
QDockWidget *mMapStylingDock;
|
||||
QgsDockWidget *mMapStylingDock;
|
||||
QgsMapStylingWidget* mMapStyleWidget;
|
||||
|
||||
QgsComposerManager *mComposerManager;
|
||||
|
@ -204,6 +204,7 @@ SET(QGIS_GUI_SRCS
|
||||
qgsdetaileditemwidget.cpp
|
||||
qgsdial.cpp
|
||||
qgsdialog.cpp
|
||||
qgsdockwidget.cpp
|
||||
qgsencodingfiledialog.cpp
|
||||
qgserrordialog.cpp
|
||||
qgsexpressionbuilderdialog.cpp
|
||||
@ -360,6 +361,7 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
qgsdetaileditemwidget.h
|
||||
qgsdial.h
|
||||
qgsdialog.h
|
||||
qgsdockwidget.h
|
||||
qgsencodingfiledialog.h
|
||||
qgserrordialog.h
|
||||
qgsexpressionbuilderdialog.h
|
||||
|
71
src/gui/qgsdockwidget.cpp
Normal file
71
src/gui/qgsdockwidget.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/***************************************************************************
|
||||
qgsdockwidget.cpp
|
||||
-----------------
|
||||
begin : June 2016
|
||||
copyright : (C) 2016 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "qgsdockwidget.h"
|
||||
|
||||
|
||||
QgsDockWidget::QgsDockWidget( QWidget* parent )
|
||||
: QDockWidget( parent )
|
||||
, mVisibleAndActive( false )
|
||||
{
|
||||
connect( this, SIGNAL( visibilityChanged( bool ) ), this, SLOT( handleVisibilityChanged( bool ) ) );
|
||||
}
|
||||
|
||||
void QgsDockWidget::setUserVisible( bool visible )
|
||||
{
|
||||
if ( visible )
|
||||
{
|
||||
if ( mVisibleAndActive )
|
||||
return;
|
||||
|
||||
show();
|
||||
raise();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !mVisibleAndActive )
|
||||
return;
|
||||
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsDockWidget::isUserVisible() const
|
||||
{
|
||||
return mVisibleAndActive;
|
||||
}
|
||||
|
||||
void QgsDockWidget::closeEvent( QCloseEvent* e )
|
||||
{
|
||||
emit closed( true );
|
||||
emit opened( false );
|
||||
QDockWidget::closeEvent( e );
|
||||
}
|
||||
|
||||
void QgsDockWidget::showEvent( QShowEvent* e )
|
||||
{
|
||||
emit closed( false );
|
||||
emit opened( true );
|
||||
QDockWidget::showEvent( e );
|
||||
}
|
||||
|
||||
void QgsDockWidget::handleVisibilityChanged( bool visible )
|
||||
{
|
||||
mVisibleAndActive = visible;
|
||||
}
|
||||
|
86
src/gui/qgsdockwidget.h
Normal file
86
src/gui/qgsdockwidget.h
Normal file
@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
qgsdockwidget.h
|
||||
---------------
|
||||
begin : June 2016
|
||||
copyright : (C) 2016 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QDockWidget>
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsDockWidget
|
||||
* QDockWidget subclass with more fine-grained control over how the widget is closed or opened.
|
||||
* \note added in 2.16
|
||||
*/
|
||||
|
||||
class GUI_EXPORT QgsDockWidget : public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor for QgsDockWidget.
|
||||
* @param parent parent widget
|
||||
*/
|
||||
explicit QgsDockWidget( QWidget* parent = nullptr );
|
||||
|
||||
public slots:
|
||||
|
||||
/** Sets the dock widget as visible to a user, ie both shown and raised to the front.
|
||||
* @param visible set to true to show the dock to the user, or false to hide the dock.
|
||||
* When setting a dock as user visible, the dock will be opened (if it is not already
|
||||
* opened) and raised to the front.
|
||||
* When setting as hidden, the following logic is used:
|
||||
* - hiding a dock which is open but not raised (ie hidden by another tab) will have no
|
||||
* effect, and the dock will still be opened and hidden by the other tab
|
||||
* - hiding a dock which is open and raised (ie, user visible) will cause the dock to
|
||||
* be closed
|
||||
* - hiding a dock which is closed has no effect and raises no signals
|
||||
* @see isUserVisible()
|
||||
*/
|
||||
void setUserVisible( bool visible );
|
||||
|
||||
/** Returns true if the dock is both opened and raised to the front (ie not hidden by
|
||||
* any other tabs.
|
||||
* @see setUserVisible()
|
||||
*/
|
||||
bool isUserVisible() const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void closeEvent( QCloseEvent * ) override;
|
||||
virtual void showEvent( QShowEvent* event ) override;
|
||||
|
||||
signals:
|
||||
|
||||
/** Emitted when dock widget is closed (or opened).
|
||||
* @param wasClosed will be true if dock widget was closed, or false if dock widget was opened
|
||||
* @see opened()
|
||||
*/
|
||||
void closed( bool wasClosed );
|
||||
|
||||
/** Emitted when dock widget is opened (or closed).
|
||||
* @param wasOpened will be true if dock widget was opened, or false if dock widget was closed
|
||||
* @see closed()
|
||||
*/
|
||||
void opened( bool wasOpened );
|
||||
|
||||
private slots:
|
||||
|
||||
void handleVisibilityChanged( bool visible );
|
||||
|
||||
private:
|
||||
|
||||
bool mVisibleAndActive;
|
||||
|
||||
};
|
@ -129,6 +129,7 @@ ADD_QGIS_TEST(zoomtest testqgsmaptoolzoom.cpp)
|
||||
ADD_QGIS_TEST(doublespinbox testqgsdoublespinbox.cpp)
|
||||
ADD_QGIS_TEST(dualviewtest testqgsdualview.cpp)
|
||||
ADD_QGIS_TEST(attributeformtest testqgsattributeform.cpp)
|
||||
ADD_QGIS_TEST(dockwidget testqgsdockwidget.cpp)
|
||||
ADD_QGIS_TEST(fieldexpressionwidget testqgsfieldexpressionwidget.cpp)
|
||||
ADD_QGIS_TEST(filewidget testqgsfilewidget.cpp)
|
||||
ADD_QGIS_TEST(focuswatcher testqgsfocuswatcher.cpp)
|
||||
|
174
tests/src/gui/testqgsdockwidget.cpp
Normal file
174
tests/src/gui/testqgsdockwidget.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
/***************************************************************************
|
||||
testqgsdockwidget.cpp
|
||||
----------------------
|
||||
Date : June 2016
|
||||
Copyright : (C) 2016 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include "qgsdockwidget.h"
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
|
||||
class TestQgsDockWidget: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase(); // will be called before the first testfunction is executed.
|
||||
void cleanupTestCase(); // will be called after the last testfunction was executed.
|
||||
void init(); // will be called before each testfunction is executed.
|
||||
void cleanup(); // will be called after every testfunction.
|
||||
|
||||
void testSignals();
|
||||
void testUserVisible();
|
||||
void testSetUserVisible();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
void TestQgsDockWidget::initTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void TestQgsDockWidget::cleanupTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void TestQgsDockWidget::init()
|
||||
{
|
||||
}
|
||||
|
||||
void TestQgsDockWidget::cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
void TestQgsDockWidget::testSignals()
|
||||
{
|
||||
QWidget* w = new QWidget();
|
||||
QApplication::setActiveWindow( w ); //required for focus events
|
||||
QgsDockWidget* d = new QgsDockWidget( w );
|
||||
|
||||
QSignalSpy spyClosed( d, SIGNAL( closed( bool ) ) );
|
||||
QSignalSpy spyOpened( d, SIGNAL( opened( bool ) ) );
|
||||
|
||||
w->show();
|
||||
|
||||
d->show();
|
||||
QCOMPARE( spyClosed.count(), 1 );
|
||||
QCOMPARE( spyClosed.last().at( 0 ).toBool(), false );
|
||||
QCOMPARE( spyOpened.count(), 1 );
|
||||
QCOMPARE( spyOpened.last().at( 0 ).toBool(), true );
|
||||
|
||||
d->close();
|
||||
QCOMPARE( spyClosed.count(), 2 );
|
||||
QCOMPARE( spyClosed.last().at( 0 ).toBool(), true );
|
||||
QCOMPARE( spyOpened.count(), 2 );
|
||||
QCOMPARE( spyOpened.last().at( 0 ).toBool(), false );
|
||||
|
||||
delete w;
|
||||
}
|
||||
|
||||
void TestQgsDockWidget::testUserVisible()
|
||||
{
|
||||
QgsDockWidget* w = new QgsDockWidget();
|
||||
QVERIFY( !w->isUserVisible() );
|
||||
|
||||
w->show();
|
||||
QVERIFY( w->isUserVisible() );
|
||||
|
||||
w->hide();
|
||||
QVERIFY( !w->isUserVisible() );
|
||||
delete w;
|
||||
}
|
||||
|
||||
void TestQgsDockWidget::testSetUserVisible()
|
||||
{
|
||||
QMainWindow* w = new QMainWindow();
|
||||
QApplication::setActiveWindow( w ); //required for focus events
|
||||
QgsDockWidget* d1 = new QgsDockWidget( w );
|
||||
QgsDockWidget* d2 = new QgsDockWidget( w );
|
||||
w->addDockWidget( Qt::RightDockWidgetArea, d1 );
|
||||
w->addDockWidget( Qt::RightDockWidgetArea, d2 );
|
||||
w->tabifyDockWidget( d1, d2 );
|
||||
w->show();
|
||||
|
||||
QVERIFY( d2->isUserVisible() );
|
||||
QVERIFY( !d1->isUserVisible() );
|
||||
|
||||
// showing dock widgets
|
||||
|
||||
// already visible
|
||||
d2->setUserVisible( true );
|
||||
QVERIFY( d2->isUserVisible() );
|
||||
QVERIFY( d2->isVisible() );
|
||||
QVERIFY( !d1->isUserVisible() );
|
||||
QVERIFY( d1->isVisible() );
|
||||
|
||||
// visible, but hidden by other dock
|
||||
d1->setUserVisible( true );
|
||||
QVERIFY( !d2->isUserVisible() );
|
||||
QVERIFY( d2->isVisible() );
|
||||
QVERIFY( d1->isUserVisible() );
|
||||
QVERIFY( d1->isVisible() );
|
||||
|
||||
// hidden
|
||||
d2->hide();
|
||||
d2->setUserVisible( true );
|
||||
QVERIFY( d2->isUserVisible() );
|
||||
QVERIFY( d2->isVisible() );
|
||||
QVERIFY( !d1->isUserVisible() );
|
||||
QVERIFY( d1->isVisible() );
|
||||
|
||||
// hiding dock widgets
|
||||
|
||||
// already hidden by other tab
|
||||
d1->setUserVisible( false );
|
||||
QVERIFY( d2->isUserVisible() );
|
||||
QVERIFY( d2->isVisible() );
|
||||
QVERIFY( !d1->isUserVisible() );
|
||||
QVERIFY( d1->isVisible() );
|
||||
|
||||
// already hidden
|
||||
d2->hide();
|
||||
d1->raise(); //shouldn't be necessary outside of tests
|
||||
QVERIFY( !d2->isUserVisible() );
|
||||
QVERIFY( !d2->isVisible() );
|
||||
QVERIFY( d1->isUserVisible() );
|
||||
QVERIFY( d1->isVisible() );
|
||||
|
||||
d2->setUserVisible( false );
|
||||
QVERIFY( !d2->isUserVisible() );
|
||||
QVERIFY( !d2->isVisible() );
|
||||
QVERIFY( d1->isUserVisible() );
|
||||
QVERIFY( d1->isVisible() );
|
||||
|
||||
// setting active dock as not user visible should hide it
|
||||
d2->show();
|
||||
d1->raise();
|
||||
QVERIFY( !d2->isUserVisible() );
|
||||
QVERIFY( d2->isVisible() );
|
||||
QVERIFY( d1->isUserVisible() );
|
||||
QVERIFY( d1->isVisible() );
|
||||
|
||||
d1->setUserVisible( false );
|
||||
QVERIFY( d2->isVisible() );
|
||||
QVERIFY( !d1->isUserVisible() );
|
||||
QVERIFY( !d1->isVisible() );
|
||||
|
||||
delete w;
|
||||
|
||||
}
|
||||
|
||||
QTEST_MAIN( TestQgsDockWidget )
|
||||
#include "testqgsdockwidget.moc"
|
Loading…
x
Reference in New Issue
Block a user