split 3dviewsmanager into 3dviews manager and dialog class

This commit is contained in:
NEDJIMAbelgacem 2022-01-02 17:25:50 +01:00 committed by Nyall Dawson
parent f62db169f3
commit 89c661b35d
15 changed files with 338 additions and 129 deletions

View File

@ -12,7 +12,10 @@ QgsProject.ReadFlag.FlagTrustLayerMetadata.__doc__ = "Trust layer metadata. Impr
QgsProject.FlagDontStoreOriginalStyles = QgsProject.ReadFlag.FlagDontStoreOriginalStyles QgsProject.FlagDontStoreOriginalStyles = QgsProject.ReadFlag.FlagDontStoreOriginalStyles
QgsProject.FlagDontStoreOriginalStyles.is_monkey_patched = True QgsProject.FlagDontStoreOriginalStyles.is_monkey_patched = True
QgsProject.ReadFlag.FlagDontStoreOriginalStyles.__doc__ = "Skip the initial XML style storage for layers. Useful for minimising project load times in non-interactive contexts." QgsProject.ReadFlag.FlagDontStoreOriginalStyles.__doc__ = "Skip the initial XML style storage for layers. Useful for minimising project load times in non-interactive contexts."
QgsProject.ReadFlag.__doc__ = 'Flags which control project read behavior.\n\n.. versionadded:: 3.10\n\n' + '* ``FlagDontResolveLayers``: ' + QgsProject.ReadFlag.FlagDontResolveLayers.__doc__ + '\n' + '* ``FlagDontLoadLayouts``: ' + QgsProject.ReadFlag.FlagDontLoadLayouts.__doc__ + '\n' + '* ``FlagTrustLayerMetadata``: ' + QgsProject.ReadFlag.FlagTrustLayerMetadata.__doc__ + '\n' + '* ``FlagDontStoreOriginalStyles``: ' + QgsProject.ReadFlag.FlagDontStoreOriginalStyles.__doc__ QgsProject.FlagDontLoad3DViews = QgsProject.ReadFlag.FlagDontLoad3DViews
QgsProject.FlagDontLoad3DViews.is_monkey_patched = True
QgsProject.ReadFlag.FlagDontLoad3DViews.__doc__ = ""
QgsProject.ReadFlag.__doc__ = 'Flags which control project read behavior.\n\n.. versionadded:: 3.10\n\n' + '* ``FlagDontResolveLayers``: ' + QgsProject.ReadFlag.FlagDontResolveLayers.__doc__ + '\n' + '* ``FlagDontLoadLayouts``: ' + QgsProject.ReadFlag.FlagDontLoadLayouts.__doc__ + '\n' + '* ``FlagTrustLayerMetadata``: ' + QgsProject.ReadFlag.FlagTrustLayerMetadata.__doc__ + '\n' + '* ``FlagDontStoreOriginalStyles``: ' + QgsProject.ReadFlag.FlagDontStoreOriginalStyles.__doc__ + '\n' + '* ``FlagDontLoad3DViews``: ' + QgsProject.ReadFlag.FlagDontLoad3DViews.__doc__
# -- # --
# monkey patching scoped based enum # monkey patching scoped based enum
QgsProject.FileFormat.Qgz.__doc__ = "Archive file format, supports auxiliary data" QgsProject.FileFormat.Qgz.__doc__ = "Archive file format, supports auxiliary data"

View File

@ -15,7 +15,6 @@
class QgsProject : QObject, QgsExpressionContextGenerator, QgsExpressionContextScopeGenerator, QgsProjectTranslator class QgsProject : QObject, QgsExpressionContextGenerator, QgsExpressionContextScopeGenerator, QgsProjectTranslator
{ {
%Docstring(signature="appended") %Docstring(signature="appended")
@ -43,6 +42,7 @@ open within the main QGIS application.
FlagDontLoadLayouts, FlagDontLoadLayouts,
FlagTrustLayerMetadata, FlagTrustLayerMetadata,
FlagDontStoreOriginalStyles, FlagDontStoreOriginalStyles,
FlagDontLoad3DViews,
}; };
typedef QFlags<QgsProject::ReadFlag> ReadFlags; typedef QFlags<QgsProject::ReadFlag> ReadFlags;
@ -745,6 +745,15 @@ the project.
%End %End
Qgs3DViewsManager *views3DManager();
%Docstring
Returns the project's 3D views manager, which manages 3D views
in the project.
.. versionadded:: 3.24
%End
QgsBookmarkManager *bookmarkManager(); QgsBookmarkManager *bookmarkManager();
%Docstring %Docstring
Returns the project's bookmark manager, which manages bookmarks within Returns the project's bookmark manager, which manages bookmarks within

View File

@ -1,5 +1,5 @@
/*************************************************************************** /***************************************************************************
qgs3dviewsmanager.cpp qgs3dviewsmanagerdialog.cpp
-------------------------------------- --------------------------------------
Date : December 2021 Date : December 2021
Copyright : (C) 2021 by Belgacem Nedjima Copyright : (C) 2021 by Belgacem Nedjima
@ -13,14 +13,15 @@
* * * *
***************************************************************************/ ***************************************************************************/
#include "qgs3dviewsmanager.h" #include "qgs3dviewsmanagerdialog.h"
#include "qgisapp.h" #include "qgisapp.h"
#include "qgs3dmapcanvasdockwidget.h" #include "qgs3dmapcanvasdockwidget.h"
#include "qgsnewnamedialog.h" #include "qgsnewnamedialog.h"
#include "qgs3dmapcanvas.h" #include "qgs3dmapcanvas.h"
#include "qgs3dviewsmanager.h"
Qgs3DViewsManager::Qgs3DViewsManager( QWidget *parent, Qt::WindowFlags f ) Qgs3DViewsManagerDialog::Qgs3DViewsManagerDialog( QWidget *parent, Qt::WindowFlags f )
: QDialog( parent, f ) : QDialog( parent, f )
{ {
setupUi( this ); setupUi( this );
@ -31,19 +32,27 @@ Qgs3DViewsManager::Qgs3DViewsManager( QWidget *parent, Qt::WindowFlags f )
m3DViewsListView->setEditTriggers( QAbstractItemView::NoEditTriggers ); m3DViewsListView->setEditTriggers( QAbstractItemView::NoEditTriggers );
m3DViewsListView->setSelectionMode( QAbstractItemView::SingleSelection ); m3DViewsListView->setSelectionMode( QAbstractItemView::SingleSelection );
connect( mOpenButton, &QToolButton::clicked, this, &Qgs3DViewsManager::openClicked ); connect( mOpenButton, &QToolButton::clicked, this, &Qgs3DViewsManagerDialog::openClicked );
connect( mDuplicateButton, &QToolButton::clicked, this, &Qgs3DViewsManager::duplicateClicked ); connect( mDuplicateButton, &QToolButton::clicked, this, &Qgs3DViewsManagerDialog::duplicateClicked );
connect( mRemoveButton, &QToolButton::clicked, this, &Qgs3DViewsManager::removeClicked ); connect( mRemoveButton, &QToolButton::clicked, this, &Qgs3DViewsManagerDialog::removeClicked );
connect( mRenameButton, &QToolButton::clicked, this, &Qgs3DViewsManager::renameClicked ); connect( mRenameButton, &QToolButton::clicked, this, &Qgs3DViewsManagerDialog::renameClicked );
connect( QgsProject::instance()->views3DManager(), &Qgs3DViewsManager::viewsListChanged, this, &Qgs3DViewsManagerDialog::onViewsListChanged );
} }
void Qgs3DViewsManager::openClicked() void Qgs3DViewsManagerDialog::onViewsListChanged()
{
reload();
}
void Qgs3DViewsManagerDialog::openClicked()
{ {
if ( m3DViewsListView->selectionModel()->selectedRows().isEmpty() ) if ( m3DViewsListView->selectionModel()->selectedRows().isEmpty() )
return; return;
QString viewName = m3DViewsListView->selectionModel()->selectedRows().at( 0 ).data( Qt::DisplayRole ).toString(); QString viewName = m3DViewsListView->selectionModel()->selectedRows().at( 0 ).data( Qt::DisplayRole ).toString();
Qgs3DMapCanvasDockWidget *widget = m3DMapViewsWidgets->value( viewName, nullptr );
Qgs3DMapCanvasDockWidget *widget = QgisApp::instance()->findChild<Qgs3DMapCanvasDockWidget *>( viewName );
if ( !widget ) if ( !widget )
{ {
widget = QgisApp::instance()->open3DMapView( viewName ); widget = QgisApp::instance()->open3DMapView( viewName );
@ -56,7 +65,7 @@ void Qgs3DViewsManager::openClicked()
} }
} }
void Qgs3DViewsManager::duplicateClicked() void Qgs3DViewsManagerDialog::duplicateClicked()
{ {
if ( m3DViewsListView->selectionModel()->selectedRows().isEmpty() ) if ( m3DViewsListView->selectionModel()->selectedRows().isEmpty() )
return; return;
@ -65,25 +74,21 @@ void Qgs3DViewsManager::duplicateClicked()
QString newViewName = askUserForATitle( existingViewName, tr( "Duplicate" ), false ); QString newViewName = askUserForATitle( existingViewName, tr( "Duplicate" ), false );
QgisApp::instance()->duplicate3DMapView( existingViewName, newViewName ); QgisApp::instance()->duplicate3DMapView( existingViewName, newViewName );
reload();
} }
void Qgs3DViewsManager::removeClicked() void Qgs3DViewsManagerDialog::removeClicked()
{ {
if ( m3DViewsListView->selectionModel()->selectedRows().isEmpty() ) if ( m3DViewsListView->selectionModel()->selectedRows().isEmpty() )
return; return;
QString viewName = m3DViewsListView->selectionModel()->selectedRows().at( 0 ).data( Qt::DisplayRole ).toString(); QString viewName = m3DViewsListView->selectionModel()->selectedRows().at( 0 ).data( Qt::DisplayRole ).toString();
m3DMapViewsDom->remove( viewName );
if ( Qgs3DMapCanvasDockWidget *w = m3DMapViewsWidgets->value( viewName, nullptr ) ) QgsProject::instance()->views3DManager()->remove3DView( viewName );
{ if ( Qgs3DMapCanvasDockWidget *w = QgisApp::instance()->findChild<Qgs3DMapCanvasDockWidget *>( viewName + QStringLiteral( "ViewObject" ) ) )
m3DMapViewsWidgets->remove( viewName );
w->close(); w->close();
}
reload();
} }
void Qgs3DViewsManager::renameClicked() void Qgs3DViewsManagerDialog::renameClicked()
{ {
if ( m3DViewsListView->selectionModel()->selectedRows().isEmpty() ) if ( m3DViewsListView->selectionModel()->selectedRows().isEmpty() )
return; return;
@ -94,45 +99,25 @@ void Qgs3DViewsManager::renameClicked()
if ( newTitle.isEmpty() ) if ( newTitle.isEmpty() )
return; return;
QDomElement dom = m3DMapViewsDom->value( oldTitle ); QgsProject::instance()->views3DManager()->rename3DView( oldTitle, newTitle );
m3DMapViewsDom->remove( oldTitle ); if ( Qgs3DMapCanvasDockWidget *widget = QgisApp::instance()->findChild<Qgs3DMapCanvasDockWidget *>( oldTitle + QStringLiteral( "ViewObject" ) ) )
m3DMapViewsDom->insert( newTitle, dom );
if ( Qgs3DMapCanvasDockWidget *widget = m3DMapViewsWidgets->value( oldTitle, nullptr ) )
{ {
m3DMapViewsWidgets->remove( oldTitle );
m3DMapViewsWidgets->insert( newTitle, widget );
widget->setWindowTitle( newTitle ); widget->setWindowTitle( newTitle );
widget->mapCanvas3D()->setObjectName( newTitle ); widget->mapCanvas3D()->setObjectName( newTitle );
} }
reload();
} }
void Qgs3DViewsManager::reload() void Qgs3DViewsManagerDialog::reload()
{ {
if ( !m3DMapViewsDom || !m3DMapViewsWidgets ) QStringList names = QgsProject::instance()->views3DManager()->get3DViewsNames();
return; mListModel->setStringList( names );
mListModel->setStringList( m3DMapViewsDom->keys() );
} }
void Qgs3DViewsManager::set3DMapViewsDom( QMap<QString, QDomElement> &mapViews3DDom ) QString Qgs3DViewsManagerDialog::askUserForATitle( QString oldTitle, QString action, bool allowExistingTitle )
{
m3DMapViewsDom = &mapViews3DDom;
reload();
}
void Qgs3DViewsManager::set3DMapViewsWidgets( QMap<QString, Qgs3DMapCanvasDockWidget *> &mapViews3DWidgets )
{
m3DMapViewsWidgets = &mapViews3DWidgets;
reload();
}
QString Qgs3DViewsManager::askUserForATitle( QString oldTitle, QString action, bool allowExistingTitle )
{ {
QString newTitle = oldTitle; QString newTitle = oldTitle;
QStringList notAllowedTitles = m3DMapViewsDom->keys(); QStringList notAllowedTitles = mListModel->stringList();
if ( allowExistingTitle ) if ( allowExistingTitle )
notAllowedTitles.removeOne( oldTitle ); notAllowedTitles.removeOne( oldTitle );
QgsNewNameDialog dlg( tr( "3D view" ), newTitle, QStringList(), notAllowedTitles, Qt::CaseSensitive, this ); QgsNewNameDialog dlg( tr( "3D view" ), newTitle, QStringList(), notAllowedTitles, Qt::CaseSensitive, this );

View File

@ -13,10 +13,10 @@
* * * *
***************************************************************************/ ***************************************************************************/
#ifndef QGS3DVIEWSMANAGER_H #ifndef QGS3DVIEWSMANAGERDIALOG_H
#define QGS3DVIEWSMANAGER_H #define QGS3DVIEWSMANAGERDIALOG_H
#include "ui_qgs3dviewsmanager.h" #include "ui_qgs3dviewsmanagerdialog.h"
#include <QDialog> #include <QDialog>
#include <QStringListModel> #include <QStringListModel>
@ -24,28 +24,25 @@
class Qgs3DMapCanvasDockWidget; class Qgs3DMapCanvasDockWidget;
class Qgs3DViewsManager : public QDialog, private Ui::Qgs3DViewsManager class Qgs3DViewsManagerDialog : public QDialog, private Ui::Qgs3DViewsManagerDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit Qgs3DViewsManager( QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags() ); explicit Qgs3DViewsManagerDialog( QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags() );
void reload(); void reload();
void set3DMapViewsDom( QMap<QString, QDomElement> &mapViews3DDom );
void set3DMapViewsWidgets( QMap<QString, Qgs3DMapCanvasDockWidget *> &mapViews3DWidgets );
private slots: private slots:
void openClicked(); void openClicked();
void duplicateClicked(); void duplicateClicked();
void removeClicked(); void removeClicked();
void renameClicked(); void renameClicked();
void onViewsListChanged();
private: private:
QStringListModel *mListModel = nullptr; QStringListModel *mListModel = nullptr;
QMap<QString, QDomElement> *m3DMapViewsDom = nullptr;
QMap<QString, Qgs3DMapCanvasDockWidget *> *m3DMapViewsWidgets = nullptr;
QString askUserForATitle( QString oldTitle, QString action, bool allowExistingTitle ); QString askUserForATitle( QString oldTitle, QString action, bool allowExistingTitle );
}; };

View File

@ -326,7 +326,7 @@ if (WITH_3D)
3d/qgsshadowrenderingsettingswidget.cpp 3d/qgsshadowrenderingsettingswidget.cpp
3d/qgspointcloud3dsymbolwidget.cpp 3d/qgspointcloud3dsymbolwidget.cpp
3d/qgspointcloudlayer3drendererwidget.cpp 3d/qgspointcloudlayer3drendererwidget.cpp
3d/qgs3dviewsmanager.cpp 3d/qgs3dviewsmanagerdialog.cpp
) )
endif() endif()

View File

@ -136,7 +136,6 @@
#include "qgs3dapputils.h" #include "qgs3dapputils.h"
#include "qgs3doptions.h" #include "qgs3doptions.h"
#include "qgs3dviewsmanager.h" #include "qgs3dviewsmanager.h"
#include <QDomImplementation>
#endif #endif
#ifdef HAVE_GEOREFERENCER #ifdef HAVE_GEOREFERENCER
@ -9900,15 +9899,23 @@ Qgs3DMapCanvasDockWidget *QgisApp::open3DMapView( const QString &mapName )
QgsReadWriteContext readWriteContext; QgsReadWriteContext readWriteContext;
readWriteContext.setPathResolver( QgsProject::instance()->pathResolver() ); readWriteContext.setPathResolver( QgsProject::instance()->pathResolver() );
QDomElement elem3DMap = QgsProject::instance()->views3DManager()->get3DViewSettings( mapName );
if ( elem3DMap.isNull() )
return nullptr;
Qgs3DMapCanvasDockWidget *mapCanvasDock3D = createNew3DMapCanvasDock( mapName ); Qgs3DMapCanvasDockWidget *mapCanvasDock3D = createNew3DMapCanvasDock( mapName );
if ( !mapCanvasDock3D ) if ( !mapCanvasDock3D )
return nullptr; return nullptr;
QDomElement elem3DMap = m3DMapViewsDom[ mapName ];
read3DMapViewSettings( mapCanvasDock3D, elem3DMap ); read3DMapViewSettings( mapCanvasDock3D, elem3DMap );
m3DMapViewsDom[ mapName ] = elem3DMap; QgsProject::instance()->views3DManager()->viewOpened( mapName );
m3DMapViewsWidgets[ mapName ] = mapCanvasDock3D;
connect( mapCanvasDock3D, &Qgs3DMapCanvasDockWidget::closed, [ &, mapName]()
{
QgsProject::instance()->views3DManager()->viewClosed( mapName );
} );
return mapCanvasDock3D; return mapCanvasDock3D;
#else #else
@ -9935,9 +9942,8 @@ Qgs3DMapCanvasDockWidget *QgisApp::duplicate3DMapView( const QString &existingVi
// If the 3D view is open, copy its configuration to the duplicate widget, otherwise just use the recorded // If the 3D view is open, copy its configuration to the duplicate widget, otherwise just use the recorded
// settings from m3DMapViewsWidgets // settings from m3DMapViewsWidgets
if ( Qgs3DMapCanvasDockWidget *w = m3DMapViewsWidgets.value( existingViewName, nullptr ) ) if ( Qgs3DMapCanvasDockWidget *w = findChild<Qgs3DMapCanvasDockWidget *>( existingViewName + QStringLiteral( "ViewObject" ) ) )
{ {
setupDockWidget( mapCanvasDock3D, true );
Qgs3DMapSettings *map = new Qgs3DMapSettings( *w->mapCanvas3D()->map() ); Qgs3DMapSettings *map = new Qgs3DMapSettings( *w->mapCanvas3D()->map() );
mapCanvasDock3D->setMapSettings( map ); mapCanvasDock3D->setMapSettings( map );
@ -9954,16 +9960,18 @@ Qgs3DMapCanvasDockWidget *QgisApp::duplicate3DMapView( const QString &existingVi
Qgs3DMapSettings *map = new Qgs3DMapSettings; Qgs3DMapSettings *map = new Qgs3DMapSettings;
mapCanvasDock3D->setMapSettings( map ); mapCanvasDock3D->setMapSettings( map );
read3DMapViewSettings( mapCanvasDock3D, m3DMapViewsDom[ existingViewName ] ); QDomElement elem = QgsProject::instance()->views3DManager()->get3DViewSettings( existingViewName );
read3DMapViewSettings( mapCanvasDock3D, elem );
} }
m3DMapViewsWidgets[ newViewName ] = mapCanvasDock3D; setupDockWidget( mapCanvasDock3D, true );
QDomElement elem3DMap; QDomElement elem3DMap;
elem3DMap = doc.createElement( QStringLiteral( "view" ) ); elem3DMap = doc.createElement( QStringLiteral( "view" ) );
write3DMapViewSettings( mapCanvasDock3D, doc, elem3DMap ); write3DMapViewSettings( mapCanvasDock3D, doc, elem3DMap );
m3DMapViewsDom[ newViewName ] = elem3DMap; QgsProject::instance()->views3DManager()->register3DViewSettings( newViewName, elem3DMap );
QgsProject::instance()->views3DManager()->viewOpened( newViewName );
return mapCanvasDock3D; return mapCanvasDock3D;
#else #else
@ -10064,7 +10072,7 @@ void QgisApp::populate3DMapviewsMenu( QMenu *menu )
#ifdef HAVE_3D #ifdef HAVE_3D
menu->clear(); menu->clear();
QList<QAction *> acts; QList<QAction *> acts;
const QList< QString > views = m3DMapViewsDom.keys(); const QList< QString > views = QgsProject::instance()->views3DManager()->get3DViewsNames();
acts.reserve( views.size() ); acts.reserve( views.size() );
for ( QString viewName : views ) for ( QString viewName : views )
{ {
@ -13618,11 +13626,7 @@ void QgisApp::showLayoutManager()
void QgisApp::show3DMapViewsManager() void QgisApp::show3DMapViewsManager()
{ {
#ifdef HAVE_3D #ifdef HAVE_3D
QWidget *dialog = static_cast< QgsAppWindowManager * >( QgsGui::windowManager() )->openApplicationDialog( QgsAppWindowManager::Dialog3DMapViewsManager ); static_cast< QgsAppWindowManager * >( QgsGui::windowManager() )->openApplicationDialog( QgsAppWindowManager::Dialog3DMapViewsManager );
Qgs3DViewsManager *manager = dynamic_cast< Qgs3DViewsManager *>( dialog );
manager->set3DMapViewsDom( m3DMapViewsDom );
manager->set3DMapViewsWidgets( m3DMapViewsWidgets );
manager->show();
#endif #endif
} }
@ -13931,17 +13935,12 @@ Qgs3DMapCanvasDockWidget *QgisApp::createNew3DMapCanvasDock( const QString &name
markDirty(); markDirty();
Qgs3DMapCanvasDockWidget *map3DWidget = new Qgs3DMapCanvasDockWidget( this ); Qgs3DMapCanvasDockWidget *map3DWidget = new Qgs3DMapCanvasDockWidget( this );
map3DWidget->setObjectName( name + QStringLiteral( "ViewObject" ) );
map3DWidget->setAllowedAreas( Qt::AllDockWidgetAreas ); map3DWidget->setAllowedAreas( Qt::AllDockWidgetAreas );
map3DWidget->setWindowTitle( name ); map3DWidget->setWindowTitle( name );
map3DWidget->mapCanvas3D()->setObjectName( name ); map3DWidget->mapCanvas3D()->setObjectName( name );
map3DWidget->setMainCanvas( mMapCanvas ); map3DWidget->setMainCanvas( mMapCanvas );
map3DWidget->mapCanvas3D()->setTemporalController( mTemporalControllerWidget->temporalController() ); map3DWidget->mapCanvas3D()->setTemporalController( mTemporalControllerWidget->temporalController() );
m3DMapViewsWidgets[ name ] = map3DWidget;
connect( map3DWidget, &Qgs3DMapCanvasDockWidget::closed, [ &, name]()
{
m3DMapViewsWidgets.remove( name );
} );
return map3DWidget; return map3DWidget;
#else #else
@ -14052,8 +14051,14 @@ void QgisApp::new3DMapCanvas()
elem3DMap.setAttribute( QStringLiteral( "isOpen" ), 1 ); elem3DMap.setAttribute( QStringLiteral( "isOpen" ), 1 );
write3DMapViewSettings( dock, doc, elem3DMap ); write3DMapViewSettings( dock, doc, elem3DMap );
m3DMapViewsDom[ name ] = elem3DMap;
m3DMapViewsWidgets[ name ] = dock; QgsProject::instance()->views3DManager()->register3DViewSettings( name, elem3DMap );
QgsProject::instance()->views3DManager()->viewOpened( name );
connect( dock, &Qgs3DMapCanvasDockWidget::closed, [ &, name]()
{
QgsProject::instance()->views3DManager()->viewClosed( name );
} );
} }
#endif #endif
} }
@ -16748,27 +16753,16 @@ void QgisApp::writeProject( QDomDocument &doc )
qgisNode.appendChild( mapViewNode ); qgisNode.appendChild( mapViewNode );
#ifdef HAVE_3D #ifdef HAVE_3D
QgsReadWriteContext readWriteContext; for ( Qgs3DMapCanvasDockWidget *widget : findChildren< Qgs3DMapCanvasDockWidget * >() )
readWriteContext.setPathResolver( QgsProject::instance()->pathResolver() );
QDomElement elem3DMaps = doc.createElement( QStringLiteral( "mapViewDocks3D" ) );
for ( QString viewName : m3DMapViewsDom.keys() )
m3DMapViewsDom[viewName].setAttribute( QStringLiteral( "isOpen" ), 0 );
for ( QString viewName : m3DMapViewsDom.keys() )
{ {
if ( !m3DMapViewsWidgets.contains( viewName ) ) QString viewName = widget->mapCanvas3D()->objectName();
continue;
Qgs3DMapCanvasDockWidget *w = m3DMapViewsWidgets[ viewName ];
QDomElement elem3DMap = doc.createElement( QStringLiteral( "view" ) ); QDomElement elem3DMap = doc.createElement( QStringLiteral( "view" ) );
elem3DMap.setAttribute( QStringLiteral( "isOpen" ), 1 ); elem3DMap.setAttribute( QStringLiteral( "isOpen" ), 1 );
write3DMapViewSettings( w, doc, elem3DMap ); write3DMapViewSettings( widget, doc, elem3DMap );
m3DMapViewsDom[ w->mapCanvas3D()->objectName() ] = elem3DMap; QgsProject::instance()->views3DManager()->register3DViewSettings( viewName, elem3DMap );
} }
for ( QString viewName : m3DMapViewsDom.keys() ) // QDomElement elem3DMaps = QgsProject::instance()->views3DManager()->writeXml( doc );
{ // qgisNode.appendChild( elem3DMaps );
QDomElement dom = m3DMapViewsDom[viewName];
elem3DMaps.appendChild( m3DMapViewsDom[viewName] );
}
qgisNode.appendChild( elem3DMaps );
#endif #endif
projectChanged( doc ); projectChanged( doc );
} }
@ -16877,25 +16871,20 @@ void QgisApp::readProject( const QDomDocument &doc )
} }
#ifdef HAVE_3D #ifdef HAVE_3D
QgsReadWriteContext readWriteContext; // Open 3D Views that were already open
readWriteContext.setPathResolver( QgsProject::instance()->pathResolver() ); for ( QDomElement viewConfig : QgsProject::instance()->views3DManager()->get3DViews() )
QDomElement elem3DMaps = doc.documentElement().firstChildElement( QStringLiteral( "mapViewDocks3D" ) );
if ( !elem3DMaps.isNull() )
{ {
QDomElement elem3DMap = elem3DMaps.firstChildElement( QStringLiteral( "view" ) ); QString viewName = viewConfig.attribute( QStringLiteral( "name" ) );
while ( !elem3DMap.isNull() ) bool isOpen = viewConfig.attribute( QStringLiteral( "isOpen" ), QStringLiteral( "1" ) ).toInt() == 1;
if ( !isOpen )
continue;
Qgs3DMapCanvasDockWidget *mapCanvasDock3D = createNew3DMapCanvasDock( viewName );
read3DMapViewSettings( mapCanvasDock3D, viewConfig );
connect( mapCanvasDock3D, &Qgs3DMapCanvasDockWidget::closed, [ &, viewName]()
{ {
QString mapName = elem3DMap.attribute( QStringLiteral( "name" ) ); QgsProject::instance()->views3DManager()->viewClosed( viewName );
m3DMapViewsDom.insert( mapName, elem3DMap ); } );
if ( elem3DMap.attribute( QStringLiteral( "isOpen" ), QStringLiteral( "1" ) ).toInt() == 1 )
{
Qgs3DMapCanvasDockWidget *mapCanvasDock3D = createNew3DMapCanvasDock( mapName );
read3DMapViewSettings( mapCanvasDock3D, elem3DMap );
}
elem3DMap = elem3DMap.nextSiblingElement( QStringLiteral( "view" ) );
}
} }
#endif #endif
@ -17618,7 +17607,6 @@ QgsFeature QgisApp::duplicateFeatureDigitized( QgsMapLayer *mlayer, const QgsFea
return QgsFeature(); return QgsFeature();
} }
void QgisApp::populateProjectStorageMenu( QMenu *menu, const bool saving ) void QgisApp::populateProjectStorageMenu( QMenu *menu, const bool saving )
{ {
menu->clear(); menu->clear();

View File

@ -430,6 +430,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
/** /**
* Opens a 3D view canvas for a 3D map view called \a name. * Opens a 3D view canvas for a 3D map view called \a name.
* If the 3D view named \a name was not already created in the project, nullptr will be returned
*/ */
Qgs3DMapCanvasDockWidget *open3DMapView( const QString &name ); Qgs3DMapCanvasDockWidget *open3DMapView( const QString &name );
@ -2735,10 +2736,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QMap< QString, QToolButton * > mAnnotationItemGroupToolButtons; QMap< QString, QToolButton * > mAnnotationItemGroupToolButtons;
QAction *mAnnotationsItemInsertBefore = nullptr; // Used to insert annotation items at the appropriate location in the annotations toolbar QAction *mAnnotationsItemInsertBefore = nullptr; // Used to insert annotation items at the appropriate location in the annotations toolbar
#ifdef HAVE_3D
QMap<QString, QDomElement> m3DMapViewsDom;
QMap<QString, Qgs3DMapCanvasDockWidget *> m3DMapViewsWidgets;
#endif
class QgsCanvasRefreshBlocker class QgsCanvasRefreshBlocker
{ {

View File

@ -21,7 +21,7 @@
#include "qgsrasterlayer.h" #include "qgsrasterlayer.h"
#ifdef HAVE_3D #ifdef HAVE_3D
#include "qgs3dviewsmanager.h" #include "qgs3dviewsmanagerdialog.h"
#endif #endif
QgsAppWindowManager::~QgsAppWindowManager() QgsAppWindowManager::~QgsAppWindowManager()
@ -71,7 +71,7 @@ QWidget *QgsAppWindowManager::openApplicationDialog( QgsAppWindowManager::Applic
#ifdef HAVE_3D #ifdef HAVE_3D
if ( !m3DMapViewsManagerDialog ) if ( !m3DMapViewsManagerDialog )
{ {
m3DMapViewsManagerDialog = new Qgs3DViewsManager( QgisApp::instance(), Qt::Window ); m3DMapViewsManagerDialog = new Qgs3DViewsManagerDialog( QgisApp::instance(), Qt::Window );
m3DMapViewsManagerDialog->setAttribute( Qt::WA_DeleteOnClose ); m3DMapViewsManagerDialog->setAttribute( Qt::WA_DeleteOnClose );
} }
m3DMapViewsManagerDialog->show(); m3DMapViewsManagerDialog->show();

View File

@ -22,7 +22,7 @@
class QgsStyleManagerDialog; class QgsStyleManagerDialog;
class QgsLayoutManagerDialog; class QgsLayoutManagerDialog;
class Qgs3DViewsManager; class Qgs3DViewsManagerDialog;
/** /**
* \ingroup gui * \ingroup gui
@ -57,7 +57,7 @@ class QgsAppWindowManager : public QgsWindowManagerInterface
private: private:
QPointer< QgsStyleManagerDialog > mStyleManagerDialog; QPointer< QgsStyleManagerDialog > mStyleManagerDialog;
QPointer< QgsLayoutManagerDialog > mLayoutManagerDialog; QPointer< QgsLayoutManagerDialog > mLayoutManagerDialog;
QPointer< Qgs3DViewsManager > m3DMapViewsManagerDialog; QPointer< Qgs3DViewsManagerDialog > m3DMapViewsManagerDialog;
}; };

View File

@ -0,0 +1,107 @@
/***************************************************************************
qgs3dviewsmanager.cpp
------------------
Date : December 2021
Copyright : (C) 2021 Belgacem Nedjima
Email : gb underscore nedjima at esi dot dz
***************************************************************************
* *
* 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 "qgs3dviewsmanager.h"
#include "qgsproject.h"
#include "qgsstyleentityvisitor.h"
Qgs3DViewsManager::Qgs3DViewsManager( QgsProject *project )
: QObject( project )
{
}
bool Qgs3DViewsManager::readXml( const QDomElement &element, const QDomDocument &doc )
{
clear();
QgsReadWriteContext readWriteContext;
readWriteContext.setPathResolver( QgsProject::instance()->pathResolver() );
QDomElement elem3DMaps = element.firstChildElement( QStringLiteral( "mapViewDocks3D" ) );
if ( !elem3DMaps.isNull() )
{
QDomElement elem3DMap = elem3DMaps.firstChildElement( QStringLiteral( "view" ) );
while ( !elem3DMap.isNull() )
{
QString mapName = elem3DMap.attribute( QStringLiteral( "name" ) );
m3DMapViewsDom.insert( mapName, elem3DMap );
elem3DMap = elem3DMap.nextSiblingElement( QStringLiteral( "view" ) );
}
}
return true;
}
QDomElement Qgs3DViewsManager::writeXml( QDomDocument &doc ) const
{
QDomElement dom = doc.createElement( "mapViewDocks3D" );
for ( QDomElement d : m3DMapViewsDom.values() )
dom.appendChild( d );
return dom;
}
void Qgs3DViewsManager::clear()
{
m3DMapViewsDom.clear();
emit viewsListChanged();
}
QDomElement Qgs3DViewsManager::get3DViewSettings( const QString &name )
{
return m3DMapViewsDom.value( name, QDomElement() );
}
QList<QDomElement> Qgs3DViewsManager::get3DViews()
{
return m3DMapViewsDom.values();
}
void Qgs3DViewsManager::register3DViewSettings( const QString &name, const QDomElement &dom )
{
m3DMapViewsDom.insert( name, dom );
emit viewsListChanged();
}
QStringList Qgs3DViewsManager::get3DViewsNames()
{
return m3DMapViewsDom.keys();
}
void Qgs3DViewsManager::remove3DView( const QString &name )
{
m3DMapViewsDom.remove( name );
emit viewsListChanged();
}
void Qgs3DViewsManager::rename3DView( const QString &oldTitle, const QString &newTitle )
{
QDomElement elem = m3DMapViewsDom.value( oldTitle );
m3DMapViewsDom.remove( oldTitle );
m3DMapViewsDom[ newTitle ] = elem;
emit viewsListChanged();
}
void Qgs3DViewsManager::viewClosed( const QString &name )
{
if ( m3DMapViewsDom.contains( name ) )
m3DMapViewsDom[ name ].setAttribute( "isOpen", 0 );
}
void Qgs3DViewsManager::viewOpened( const QString &name )
{
if ( m3DMapViewsDom.contains( name ) )
m3DMapViewsDom[ name ].setAttribute( "isOpen", 1 );
}

View File

@ -0,0 +1,80 @@
/***************************************************************************
qgs3dviewsmanager.h
------------------
Date : December 2021
Copyright : (C) 2021 Belgacem Nedjima
Email : gb underscore nedjima at esi dot dz
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#ifndef QGS3DVIEWSMANAGER_H
#define QGS3DVIEWSMANAGER_H
#include "qgis_core.h"
#include "qgis_sip.h"
#include <QObject>
#include <QDomDocument>
#include <QDomElement>
#include <QMap>
class QgsProject;
/**
* \ingroup core
* \class Qgs3DViewsManager
*
* \brief Manages storage of a set of 3D views.
*
* QgsLayoutManager handles the storage, serializing and deserializing
* of 3D views. Usually this class is not constructed directly, but
* rather accessed through a QgsProject via QgsProject::viewsManager3D().
*
* Qgs3DViewsManager retains ownership of all the 3d views contained
* in the manager.
* \since QGIS 3.24
*/
class CORE_EXPORT Qgs3DViewsManager : public QObject
{
Q_OBJECT
public:
/**
* Constructor for Qgs3DViewsManager. The project will become the parent object for this
* manager.
*/
explicit Qgs3DViewsManager( QgsProject *project );
bool readXml( const QDomElement &element, const QDomDocument &doc );
QDomElement writeXml( QDomDocument &doc ) const;
void clear();
QDomElement get3DViewSettings( const QString &name );
void register3DViewSettings( const QString &name, const QDomElement &dom );
QStringList get3DViewsNames();
QList<QDomElement> get3DViews();
void remove3DView( const QString &name );
void rename3DView( const QString &oldTitle, const QString &newTitle );
void viewOpened( const QString &name );
void viewClosed( const QString &name );
signals:
void viewsListChanged();
private:
QMap<QString, QDomElement> m3DMapViewsDom;
};
#endif // QGSLAYOUTMANAGER_H

View File

@ -779,6 +779,7 @@ set(QGIS_CORE_SRCS
3d/qgs3dsymbolregistry.cpp 3d/qgs3dsymbolregistry.cpp
3d/qgsabstract3dsymbol.cpp 3d/qgsabstract3dsymbol.cpp
3d/qgsabstract3drenderer.cpp 3d/qgsabstract3drenderer.cpp
3d/qgs3dviewsmanager.cpp
fieldformatter/qgscheckboxfieldformatter.cpp fieldformatter/qgscheckboxfieldformatter.cpp
fieldformatter/qgsrangefieldformatter.cpp fieldformatter/qgsrangefieldformatter.cpp
@ -1165,6 +1166,7 @@ set(QGIS_CORE_HDRS
3d/qgs3dsymbolregistry.h 3d/qgs3dsymbolregistry.h
3d/qgsabstract3dsymbol.h 3d/qgsabstract3dsymbol.h
3d/qgsabstract3drenderer.h 3d/qgsabstract3drenderer.h
3d/qgs3dviewsmanager.h
annotations/qgsannotation.h annotations/qgsannotation.h
annotations/qgsannotationitem.h annotations/qgsannotationitem.h

View File

@ -66,7 +66,9 @@
#include "qgspointcloudlayer.h" #include "qgspointcloudlayer.h"
#include "qgsattributeeditorcontainer.h" #include "qgsattributeeditorcontainer.h"
#include "qgsgrouplayer.h" #include "qgsgrouplayer.h"
#ifdef HAVE_3D
#include "qgs3dviewsmanager.h"
#endif
#include <algorithm> #include <algorithm>
#include <QApplication> #include <QApplication>
@ -370,6 +372,7 @@ QgsProject::QgsProject( QObject *parent )
, mRelationManager( new QgsRelationManager( this ) ) , mRelationManager( new QgsRelationManager( this ) )
, mAnnotationManager( new QgsAnnotationManager( this ) ) , mAnnotationManager( new QgsAnnotationManager( this ) )
, mLayoutManager( new QgsLayoutManager( this ) ) , mLayoutManager( new QgsLayoutManager( this ) )
, m3DViewsManager( new Qgs3DViewsManager( this ) )
, mBookmarkManager( QgsBookmarkManager::createProjectBasedManager( this ) ) , mBookmarkManager( QgsBookmarkManager::createProjectBasedManager( this ) )
, mViewSettings( new QgsProjectViewSettings( this ) ) , mViewSettings( new QgsProjectViewSettings( this ) )
, mTimeSettings( new QgsProjectTimeSettings( this ) ) , mTimeSettings( new QgsProjectTimeSettings( this ) )
@ -840,6 +843,7 @@ void QgsProject::clear()
mRelationManager->clear(); mRelationManager->clear();
mAnnotationManager->clear(); mAnnotationManager->clear();
mLayoutManager->clear(); mLayoutManager->clear();
m3DViewsManager->clear();
mBookmarkManager->clear(); mBookmarkManager->clear();
mViewSettings->reset(); mViewSettings->reset();
mTimeSettings->reset(); mTimeSettings->reset();
@ -1719,6 +1723,13 @@ bool QgsProject::readProjectFile( const QString &filename, QgsProject::ReadFlags
profile.switchTask( tr( "Loading layouts" ) ); profile.switchTask( tr( "Loading layouts" ) );
mLayoutManager->readXml( doc->documentElement(), *doc ); mLayoutManager->readXml( doc->documentElement(), *doc );
} }
if ( !( flags & QgsProject::ReadFlag::FlagDontLoad3DViews ) )
{
profile.switchTask( tr( "Loading 3D Views" ) );
m3DViewsManager->readXml( doc->documentElement(), *doc );
}
profile.switchTask( tr( "Loading bookmarks" ) ); profile.switchTask( tr( "Loading bookmarks" ) );
mBookmarkManager->readXml( doc->documentElement(), *doc ); mBookmarkManager->readXml( doc->documentElement(), *doc );
@ -2444,6 +2455,9 @@ bool QgsProject::writeProjectFile( const QString &filename )
const QDomElement layoutElem = mLayoutManager->writeXml( *doc ); const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
qgisNode.appendChild( layoutElem ); qgisNode.appendChild( layoutElem );
const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
qgisNode.appendChild( views3DElem );
const QDomElement bookmarkElem = mBookmarkManager->writeXml( *doc ); const QDomElement bookmarkElem = mBookmarkManager->writeXml( *doc );
qgisNode.appendChild( bookmarkElem ); qgisNode.appendChild( bookmarkElem );
@ -3160,6 +3174,16 @@ QgsLayoutManager *QgsProject::layoutManager()
return mLayoutManager.get(); return mLayoutManager.get();
} }
const Qgs3DViewsManager *QgsProject::views3DManager() const
{
return m3DViewsManager.get();
}
Qgs3DViewsManager *QgsProject::views3DManager()
{
return m3DViewsManager.get();
}
const QgsBookmarkManager *QgsProject::bookmarkManager() const const QgsBookmarkManager *QgsProject::bookmarkManager() const
{ {
return mBookmarkManager; return mBookmarkManager;

View File

@ -82,7 +82,7 @@ class QgsProjectTimeSettings;
class QgsAnnotationLayer; class QgsAnnotationLayer;
class QgsAttributeEditorContainer; class QgsAttributeEditorContainer;
class QgsPropertyCollection; class QgsPropertyCollection;
class Qgs3DViewsManager;
/** /**
* \ingroup core * \ingroup core
@ -128,6 +128,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
FlagDontLoadLayouts = 1 << 1, //!< Don't load print layouts. Improves project read time if layouts are not required, and allows projects to be safely read in background threads (since print layouts are not thread safe). FlagDontLoadLayouts = 1 << 1, //!< Don't load print layouts. Improves project read time if layouts are not required, and allows projects to be safely read in background threads (since print layouts are not thread safe).
FlagTrustLayerMetadata = 1 << 2, //!< Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during the project's use by QGIS and QGIS Server. FlagTrustLayerMetadata = 1 << 2, //!< Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during the project's use by QGIS and QGIS Server.
FlagDontStoreOriginalStyles = 1 << 3, //!< Skip the initial XML style storage for layers. Useful for minimising project load times in non-interactive contexts. FlagDontStoreOriginalStyles = 1 << 3, //!< Skip the initial XML style storage for layers. Useful for minimising project load times in non-interactive contexts.
FlagDontLoad3DViews = 1 << 4, //!<
}; };
Q_DECLARE_FLAGS( ReadFlags, ReadFlag ) Q_DECLARE_FLAGS( ReadFlags, ReadFlag )
@ -755,6 +756,21 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
*/ */
QgsLayoutManager *layoutManager(); QgsLayoutManager *layoutManager();
/**
* Returns the project's 3D views manager, which manages 3D views
* in the project.
* \note not available in Python bindings
* \since QGIS 3.24
*/
const Qgs3DViewsManager *views3DManager() const SIP_SKIP;
/**
* Returns the project's 3D views manager, which manages 3D views
* in the project.
* \since QGIS 3.24
*/
Qgs3DViewsManager *views3DManager();
/** /**
* Returns the project's bookmark manager, which manages bookmarks within * Returns the project's bookmark manager, which manages bookmarks within
* the project. * the project.
@ -2042,6 +2058,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
std::unique_ptr<QgsAnnotationManager> mAnnotationManager; std::unique_ptr<QgsAnnotationManager> mAnnotationManager;
std::unique_ptr<QgsLayoutManager> mLayoutManager; std::unique_ptr<QgsLayoutManager> mLayoutManager;
std::unique_ptr<Qgs3DViewsManager> m3DViewsManager;
QgsBookmarkManager *mBookmarkManager = nullptr; QgsBookmarkManager *mBookmarkManager = nullptr;

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>Qgs3DViewsManager</class> <class>Qgs3DViewsManagerDialog</class>
<widget class="QDialog" name="Qgs3DViewsManager"> <widget class="QDialog" name="Qgs3DViewsManagerDialog">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>