Skip to content

Commit cb178a7

Browse files
committedSep 14, 2018
New class QgsWindowManagerInterface
With implementation in app. This allows GUI library classes to re-use standard dialogs which are created in app. The initial use-case is to allow the GUI library symbol list widget to focus/open an existing Style Manager dialog (created in app), instead of opening a new modal style manager dialog. Side benefit - moves some code out of the monolithic qgisapp.cpp file.
1 parent 9bcd21f commit cb178a7

13 files changed

+274
-20
lines changed
 

‎python/gui/auto_generated/qgsgui.sip.in

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,24 @@ Returns the global processing recent algorithm log, used for tracking recently u
8080
%Docstring
8181
Register the widget to allow its position to be automatically saved and restored when open and closed.
8282
Use this to avoid needing to call saveGeometry() and restoreGeometry() on your widget.
83+
%End
84+
85+
static QgsWindowManagerInterface *windowManager();
86+
%Docstring
87+
Returns the global window manager, if set.
88+
89+
.. seealso:: :py:func:`setWindowManager`
90+
91+
.. versionadded:: 3.4
92+
%End
93+
94+
static void setWindowManager( QgsWindowManagerInterface *manager /Transfer/ );
95+
%Docstring
96+
Sets the global window ``manager``. Ownership is transferred to the QgsGui instance.
97+
98+
.. seealso:: :py:func:`windowManager`
99+
100+
.. versionadded:: 3.4
83101
%End
84102

85103
~QgsGui();
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/gui/qgswindowmanagerinterface.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
class QgsWindowManagerInterface
13+
{
14+
%Docstring
15+
Interface for window manager.
16+
17+
An implementation of the window manager interface is usually retrieved from
18+
the QgsGui instance, via :py:func:`QgsGui.windowManager()`
19+
20+
.. note::
21+
22+
This is not considered stable API and may change in future QGIS versions.
23+
24+
.. versionadded:: 3.4
25+
%End
26+
27+
%TypeHeaderCode
28+
#include "qgswindowmanagerinterface.h"
29+
%End
30+
public:
31+
32+
enum StandardDialog
33+
{
34+
DialogStyleManager,
35+
};
36+
37+
virtual ~QgsWindowManagerInterface();
38+
39+
virtual QWidget *openStandardDialog( StandardDialog dialog ) = 0;
40+
%Docstring
41+
Opens an instance of a standard QGIS dialog. Depending on the window manager
42+
implementation, this may either open a new instance of the dialog or bring an
43+
existing instance to the foreground.
44+
45+
Returns the dialog if shown, or None if the dialog either could not be
46+
created or is not supported by the window manager implementation.
47+
%End
48+
49+
};
50+
51+
52+
/************************************************************************
53+
* This file has been generated automatically from *
54+
* *
55+
* src/gui/qgswindowmanagerinterface.h *
56+
* *
57+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
58+
************************************************************************/

‎python/gui/gui_auto.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
%Include auto_generated/qgsabstractdatasourcewidget.sip
2222
%Include auto_generated/qgssourceselectprovider.sip
2323
%Include auto_generated/qgssourceselectproviderregistry.sip
24+
%Include auto_generated/qgswindowmanagerinterface.sip
2425
%Include auto_generated/attributetable/qgsfeaturemodel.sip
2526
%Include auto_generated/auth/qgsauthauthoritieseditor.sip
2627
%Include auto_generated/auth/qgsauthcertificateinfo.sip

‎src/app/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ SET(QGIS_APP_SRCS
1010
qgsalignrasterdialog.cpp
1111
qgsappbrowserproviders.cpp
1212
qgsapplayertreeviewmenuprovider.cpp
13+
qgsappwindowmanager.cpp
1314
qgsaddattrdialog.cpp
1415
qgsaddtaborgroup.cpp
1516
qgsjoindialog.cpp

‎src/app/qgisapp.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
319319
#include "qgsnewnamedialog.h"
320320
#include "qgsgui.h"
321321
#include "qgsdatasourcemanagerdialog.h"
322-
#include "qgsstylemanagerdialog.h"
322+
#include "qgsappwindowmanager.h"
323323

324324
#include "qgsuserprofilemanager.h"
325325
#include "qgsuserprofile.h"
@@ -1263,6 +1263,8 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
12631263
qApp->processEvents();
12641264
endProfile();
12651265

1266+
QgsGui::setWindowManager( new QgsAppWindowManager() );
1267+
12661268
mMapCanvas->freeze( false );
12671269
mMapCanvas->clearExtentHistory(); // reset zoomnext/zoomlast
12681270

@@ -1517,8 +1519,8 @@ QgisApp::~QgisApp()
15171519
delete mVectorLayerTools;
15181520
delete mWelcomePage;
15191521

1520-
if ( mStyleManagerDialog )
1521-
delete mStyleManagerDialog;
1522+
// Gracefully delete window manager now
1523+
QgsGui::setWindowManager( nullptr );
15221524

15231525
deleteLayoutDesigners();
15241526
removeAnnotationItems();
@@ -2269,18 +2271,9 @@ void QgisApp::createActions()
22692271

22702272
}
22712273

2272-
#include "qgsstyle.h"
2273-
#include "qgsstylemanagerdialog.h"
2274-
22752274
void QgisApp::showStyleManager()
22762275
{
2277-
if ( !mStyleManagerDialog )
2278-
{
2279-
mStyleManagerDialog = new QgsStyleManagerDialog( QgsStyle::defaultStyle(), this, Qt::Window );
2280-
mStyleManagerDialog->setAttribute( Qt::WA_DeleteOnClose );
2281-
}
2282-
mStyleManagerDialog->show();
2283-
mStyleManagerDialog->activate();
2276+
QgsGui::windowManager()->openStandardDialog( QgsWindowManagerInterface::DialogStyleManager );
22842277
}
22852278

22862279
void QgisApp::showPythonDialog()

‎src/app/qgisapp.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ class QgsLayoutCustomDropHandler;
6565
class QgsLayoutDesignerDialog;
6666
class QgsLayoutDesignerInterface;
6767
class QgsLayoutManagerDialog;
68-
class QgsStyleManagerDialog;
6968
class QgsMapCanvas;
7069
class QgsMapCanvasDockWidget;
7170
class QgsMapLayer;
@@ -2204,7 +2203,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
22042203
QgsLayerStylingWidget *mMapStyleWidget = nullptr;
22052204

22062205
QPointer< QgsLayoutManagerDialog > mLayoutManagerDialog;
2207-
QPointer< QgsStyleManagerDialog > mStyleManagerDialog;
22082206

22092207
//! Persistent tile scale slider
22102208
QgsTileScaleWidget *mpTileScaleWidget = nullptr;

‎src/app/qgsappwindowmanager.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/***************************************************************************
2+
qgswindowmanagerinterface.cpp
3+
-----------------------------
4+
Date : September 2018
5+
Copyright : (C) 2018 Nyall Dawson
6+
Email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsappwindowmanager.h"
17+
#include "qgsstylemanagerdialog.h"
18+
#include "qgsstyle.h"
19+
#include "qgisapp.h"
20+
21+
22+
QgsAppWindowManager::~QgsAppWindowManager()
23+
{
24+
if ( mStyleManagerDialog )
25+
delete mStyleManagerDialog;
26+
}
27+
28+
QWidget *QgsAppWindowManager::openStandardDialog( QgsWindowManagerInterface::StandardDialog dialog )
29+
{
30+
switch ( dialog )
31+
{
32+
case QgsWindowManagerInterface::DialogStyleManager:
33+
{
34+
if ( !mStyleManagerDialog )
35+
{
36+
mStyleManagerDialog = new QgsStyleManagerDialog( QgsStyle::defaultStyle(), QgisApp::instance(), Qt::Window );
37+
mStyleManagerDialog->setAttribute( Qt::WA_DeleteOnClose );
38+
}
39+
mStyleManagerDialog->show();
40+
mStyleManagerDialog->activate();
41+
return mStyleManagerDialog;
42+
}
43+
}
44+
return nullptr;
45+
}

‎src/app/qgsappwindowmanager.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/***************************************************************************
2+
qgswindowmanagerinterface.h
3+
---------------------------
4+
Date : September 2018
5+
Copyright : (C) 2018 Nyall Dawson
6+
Email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSAPPWINDOWMANAGER_H
17+
#define QGSAPPWINDOWMANAGER_H
18+
19+
#include "qgis.h"
20+
#include "qgswindowmanagerinterface.h"
21+
#include <QPointer>
22+
23+
class QgsStyleManagerDialog;
24+
25+
/**
26+
* \ingroup gui
27+
* \brief Implementation of QgsWindowManagerInterface for the QGIS application.
28+
*/
29+
class QgsAppWindowManager : public QgsWindowManagerInterface
30+
{
31+
public:
32+
33+
QgsAppWindowManager() = default;
34+
~QgsAppWindowManager();
35+
36+
QWidget *openStandardDialog( QgsWindowManagerInterface::StandardDialog dialog ) override;
37+
38+
private:
39+
QPointer< QgsStyleManagerDialog > mStyleManagerDialog;
40+
};
41+
42+
43+
#endif // QGSAPPWINDOWMANAGER_H

‎src/gui/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ SET(QGIS_GUI_HDRS
791791
qgswidgetstatehelper_p.h
792792
qgssourceselectprovider.h
793793
qgssourceselectproviderregistry.h
794+
qgswindowmanagerinterface.h
794795

795796
ogr/qgsogrhelperfunctions.h
796797
ogr/qgsnewogrconnection.h

‎src/gui/qgsgui.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "qgswidgetstatehelper_p.h"
3838
#include "qgslogger.h"
3939
#include "qgsprocessingrecentalgorithmlog.h"
40+
#include "qgswindowmanagerinterface.h"
4041

4142
QgsGui *QgsGui::instance()
4243
{
@@ -93,11 +94,21 @@ void QgsGui::enableAutoGeometryRestore( QWidget *widget, const QString &key )
9394
{
9495
if ( widget->objectName().isEmpty() )
9596
{
96-
QgsDebugMsg( "WARNING: No object name set. Best for it to be set objectName when using QgsGui::enableAutoGeometryRestore" );
97+
QgsDebugMsg( QStringLiteral( "WARNING: No object name set. Best for it to be set objectName when using QgsGui::enableAutoGeometryRestore" ) );
9798
}
9899
instance()->mWidgetStateHelper->registerWidget( widget, key );
99100
}
100101

102+
QgsWindowManagerInterface *QgsGui::windowManager()
103+
{
104+
return instance()->mWindowManager.get();
105+
}
106+
107+
void QgsGui::setWindowManager( QgsWindowManagerInterface *manager )
108+
{
109+
instance()->mWindowManager.reset( manager );
110+
}
111+
101112
QgsGui::~QgsGui()
102113
{
103114
delete mProcessingGuiRegistry;

‎src/gui/qgsgui.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "qgis_gui.h"
2222
#include "qgis_sip.h"
2323
#include <QWidget>
24+
#include <memory>
2425

2526
class QgsEditorWidgetRegistry;
2627
class QgsShortcutsManager;
@@ -32,6 +33,7 @@ class QgsLayoutItemGuiRegistry;
3233
class QgsWidgetStateHelper;
3334
class QgsProcessingGuiRegistry;
3435
class QgsProcessingRecentAlgorithmLog;
36+
class QgsWindowManagerInterface;
3537

3638
/**
3739
* \ingroup gui
@@ -109,6 +111,20 @@ class GUI_EXPORT QgsGui
109111
*/
110112
static void enableAutoGeometryRestore( QWidget *widget, const QString &key = QString() );
111113

114+
/**
115+
* Returns the global window manager, if set.
116+
* \see setWindowManager()
117+
* \since QGIS 3.4
118+
*/
119+
static QgsWindowManagerInterface *windowManager();
120+
121+
/**
122+
* Sets the global window \a manager. Ownership is transferred to the QgsGui instance.
123+
* \see windowManager()
124+
* \since QGIS 3.4
125+
*/
126+
static void setWindowManager( QgsWindowManagerInterface *manager SIP_TRANSFER );
127+
112128
~QgsGui();
113129

114130
private:
@@ -125,6 +141,7 @@ class GUI_EXPORT QgsGui
125141
QgsLayoutItemGuiRegistry *mLayoutItemGuiRegistry = nullptr;
126142
QgsProcessingGuiRegistry *mProcessingGuiRegistry = nullptr;
127143
QgsProcessingRecentAlgorithmLog *mProcessingRecentAlgorithmLog = nullptr;
144+
std::unique_ptr< QgsWindowManagerInterface > mWindowManager;
128145

129146
#ifdef SIP_RUN
130147
QgsGui( const QgsGui &other );

‎src/gui/qgswindowmanagerinterface.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/***************************************************************************
2+
qgswindowmanagerinterface.h
3+
---------------------------
4+
Date : September 2018
5+
Copyright : (C) 2018 Nyall Dawson
6+
Email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSWINDOWMANAGERINTERFACE_H
17+
#define QGSWINDOWMANAGERINTERFACE_H
18+
19+
#include "qgis.h"
20+
#include "qgis_gui.h"
21+
22+
///@cond NOT_STABLE
23+
24+
/**
25+
* \ingroup gui
26+
* \brief Interface for window manager.
27+
*
28+
* An implementation of the window manager interface is usually retrieved from
29+
* the QgsGui instance, via QgsGui::windowManager().
30+
*
31+
* \note This is not considered stable API and may change in future QGIS versions.
32+
* \since QGIS 3.4
33+
*/
34+
class GUI_EXPORT QgsWindowManagerInterface
35+
{
36+
public:
37+
38+
//! Standard QGIS dialogs
39+
enum StandardDialog
40+
{
41+
DialogStyleManager = 0, //!< Style manager dialog
42+
};
43+
44+
virtual ~QgsWindowManagerInterface() = default;
45+
46+
/**
47+
* Opens an instance of a standard QGIS dialog. Depending on the window manager
48+
* implementation, this may either open a new instance of the dialog or bring an
49+
* existing instance to the foreground.
50+
*
51+
* Returns the dialog if shown, or nullptr if the dialog either could not be
52+
* created or is not supported by the window manager implementation.
53+
*/
54+
virtual QWidget *openStandardDialog( StandardDialog dialog ) = 0;
55+
56+
};
57+
58+
///@endcond
59+
60+
#endif // QGSWINDOWMANAGERINTERFACE_H

‎src/gui/symbology/qgssymbolslistwidget.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include "qgsnewauxiliarylayerdialog.h"
3131
#include "qgsauxiliarystorage.h"
3232
#include "qgsstylemodel.h"
33+
#include "qgsgui.h"
34+
#include "qgswindowmanagerinterface.h"
3335

3436
#include <QAction>
3537
#include <QString>
@@ -134,7 +136,7 @@ QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbol *symbol, QgsStyle *style,
134136

135137
connect( mStyle, &QgsStyle::groupsModified, this, &QgsSymbolsListWidget::populateGroups );
136138

137-
connect( openStyleManagerButton, &QPushButton::pressed, this, &QgsSymbolsListWidget::openStyleManager );
139+
connect( openStyleManagerButton, &QToolButton::clicked, this, &QgsSymbolsListWidget::openStyleManager );
138140

139141
lblSymbolName->clear();
140142

@@ -394,10 +396,16 @@ void QgsSymbolsListWidget::updateModelFilters()
394396

395397
void QgsSymbolsListWidget::openStyleManager()
396398
{
397-
QgsStyleManagerDialog dlg( mStyle, this );
398-
dlg.exec();
399+
// prefer to use global window manager to open the style manager, if possible!
400+
// this allows reuse of an existing non-modal window instead of opening a new modal window
401+
if ( !QgsGui::windowManager() || !QgsGui::windowManager()->openStandardDialog( QgsWindowManagerInterface::DialogStyleManager ) )
402+
{
403+
// fallback to modal dialog
404+
QgsStyleManagerDialog dlg( mStyle, this );
405+
dlg.exec();
399406

400-
updateModelFilters(); // probably not needed -- the model should automatically update if any changes were made
407+
updateModelFilters(); // probably not needed -- the model should automatically update if any changes were made
408+
}
401409
}
402410

403411
void QgsSymbolsListWidget::clipFeaturesToggled( bool checked )

0 commit comments

Comments
 (0)
Please sign in to comment.