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.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.__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
QgsProject.FileFormat.Qgz.__doc__ = "Archive file format, supports auxiliary data"

View File

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

View File

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

View File

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

View File

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

View File

@ -136,7 +136,6 @@
#include "qgs3dapputils.h"
#include "qgs3doptions.h"
#include "qgs3dviewsmanager.h"
#include <QDomImplementation>
#endif
#ifdef HAVE_GEOREFERENCER
@ -9900,15 +9899,23 @@ Qgs3DMapCanvasDockWidget *QgisApp::open3DMapView( const QString &mapName )
QgsReadWriteContext readWriteContext;
readWriteContext.setPathResolver( QgsProject::instance()->pathResolver() );
QDomElement elem3DMap = QgsProject::instance()->views3DManager()->get3DViewSettings( mapName );
if ( elem3DMap.isNull() )
return nullptr;
Qgs3DMapCanvasDockWidget *mapCanvasDock3D = createNew3DMapCanvasDock( mapName );
if ( !mapCanvasDock3D )
return nullptr;
QDomElement elem3DMap = m3DMapViewsDom[ mapName ];
read3DMapViewSettings( mapCanvasDock3D, elem3DMap );
m3DMapViewsDom[ mapName ] = elem3DMap;
m3DMapViewsWidgets[ mapName ] = mapCanvasDock3D;
QgsProject::instance()->views3DManager()->viewOpened( mapName );
connect( mapCanvasDock3D, &Qgs3DMapCanvasDockWidget::closed, [ &, mapName]()
{
QgsProject::instance()->views3DManager()->viewClosed( mapName );
} );
return mapCanvasDock3D;
#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
// 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() );
mapCanvasDock3D->setMapSettings( map );
@ -9954,16 +9960,18 @@ Qgs3DMapCanvasDockWidget *QgisApp::duplicate3DMapView( const QString &existingVi
Qgs3DMapSettings *map = new Qgs3DMapSettings;
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;
elem3DMap = doc.createElement( QStringLiteral( "view" ) );
write3DMapViewSettings( mapCanvasDock3D, doc, elem3DMap );
m3DMapViewsDom[ newViewName ] = elem3DMap;
QgsProject::instance()->views3DManager()->register3DViewSettings( newViewName, elem3DMap );
QgsProject::instance()->views3DManager()->viewOpened( newViewName );
return mapCanvasDock3D;
#else
@ -10064,7 +10072,7 @@ void QgisApp::populate3DMapviewsMenu( QMenu *menu )
#ifdef HAVE_3D
menu->clear();
QList<QAction *> acts;
const QList< QString > views = m3DMapViewsDom.keys();
const QList< QString > views = QgsProject::instance()->views3DManager()->get3DViewsNames();
acts.reserve( views.size() );
for ( QString viewName : views )
{
@ -13618,11 +13626,7 @@ void QgisApp::showLayoutManager()
void QgisApp::show3DMapViewsManager()
{
#ifdef HAVE_3D
QWidget *dialog = static_cast< QgsAppWindowManager * >( QgsGui::windowManager() )->openApplicationDialog( QgsAppWindowManager::Dialog3DMapViewsManager );
Qgs3DViewsManager *manager = dynamic_cast< Qgs3DViewsManager *>( dialog );
manager->set3DMapViewsDom( m3DMapViewsDom );
manager->set3DMapViewsWidgets( m3DMapViewsWidgets );
manager->show();
static_cast< QgsAppWindowManager * >( QgsGui::windowManager() )->openApplicationDialog( QgsAppWindowManager::Dialog3DMapViewsManager );
#endif
}
@ -13931,17 +13935,12 @@ Qgs3DMapCanvasDockWidget *QgisApp::createNew3DMapCanvasDock( const QString &name
markDirty();
Qgs3DMapCanvasDockWidget *map3DWidget = new Qgs3DMapCanvasDockWidget( this );
map3DWidget->setObjectName( name + QStringLiteral( "ViewObject" ) );
map3DWidget->setAllowedAreas( Qt::AllDockWidgetAreas );
map3DWidget->setWindowTitle( name );
map3DWidget->mapCanvas3D()->setObjectName( name );
map3DWidget->setMainCanvas( mMapCanvas );
map3DWidget->mapCanvas3D()->setTemporalController( mTemporalControllerWidget->temporalController() );
m3DMapViewsWidgets[ name ] = map3DWidget;
connect( map3DWidget, &Qgs3DMapCanvasDockWidget::closed, [ &, name]()
{
m3DMapViewsWidgets.remove( name );
} );
return map3DWidget;
#else
@ -14052,8 +14051,14 @@ void QgisApp::new3DMapCanvas()
elem3DMap.setAttribute( QStringLiteral( "isOpen" ), 1 );
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
}
@ -16748,27 +16753,16 @@ void QgisApp::writeProject( QDomDocument &doc )
qgisNode.appendChild( mapViewNode );
#ifdef HAVE_3D
QgsReadWriteContext readWriteContext;
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() )
for ( Qgs3DMapCanvasDockWidget *widget : findChildren< Qgs3DMapCanvasDockWidget * >() )
{
if ( !m3DMapViewsWidgets.contains( viewName ) )
continue;
Qgs3DMapCanvasDockWidget *w = m3DMapViewsWidgets[ viewName ];
QString viewName = widget->mapCanvas3D()->objectName();
QDomElement elem3DMap = doc.createElement( QStringLiteral( "view" ) );
elem3DMap.setAttribute( QStringLiteral( "isOpen" ), 1 );
write3DMapViewSettings( w, doc, elem3DMap );
m3DMapViewsDom[ w->mapCanvas3D()->objectName() ] = elem3DMap;
write3DMapViewSettings( widget, doc, elem3DMap );
QgsProject::instance()->views3DManager()->register3DViewSettings( viewName, elem3DMap );
}
for ( QString viewName : m3DMapViewsDom.keys() )
{
QDomElement dom = m3DMapViewsDom[viewName];
elem3DMaps.appendChild( m3DMapViewsDom[viewName] );
}
qgisNode.appendChild( elem3DMaps );
// QDomElement elem3DMaps = QgsProject::instance()->views3DManager()->writeXml( doc );
// qgisNode.appendChild( elem3DMaps );
#endif
projectChanged( doc );
}
@ -16877,25 +16871,20 @@ void QgisApp::readProject( const QDomDocument &doc )
}
#ifdef HAVE_3D
QgsReadWriteContext readWriteContext;
readWriteContext.setPathResolver( QgsProject::instance()->pathResolver() );
QDomElement elem3DMaps = doc.documentElement().firstChildElement( QStringLiteral( "mapViewDocks3D" ) );
if ( !elem3DMaps.isNull() )
// Open 3D Views that were already open
for ( QDomElement viewConfig : QgsProject::instance()->views3DManager()->get3DViews() )
{
QDomElement elem3DMap = elem3DMaps.firstChildElement( QStringLiteral( "view" ) );
while ( !elem3DMap.isNull() )
QString viewName = viewConfig.attribute( QStringLiteral( "name" ) );
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" ) );
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" ) );
}
QgsProject::instance()->views3DManager()->viewClosed( viewName );
} );
}
#endif
@ -17618,7 +17607,6 @@ QgsFeature QgisApp::duplicateFeatureDigitized( QgsMapLayer *mlayer, const QgsFea
return QgsFeature();
}
void QgisApp::populateProjectStorageMenu( QMenu *menu, const bool saving )
{
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.
* If the 3D view named \a name was not already created in the project, nullptr will be returned
*/
Qgs3DMapCanvasDockWidget *open3DMapView( const QString &name );
@ -2735,10 +2736,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QMap< QString, QToolButton * > mAnnotationItemGroupToolButtons;
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
{

View File

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

View File

@ -22,7 +22,7 @@
class QgsStyleManagerDialog;
class QgsLayoutManagerDialog;
class Qgs3DViewsManager;
class Qgs3DViewsManagerDialog;
/**
* \ingroup gui
@ -57,7 +57,7 @@ class QgsAppWindowManager : public QgsWindowManagerInterface
private:
QPointer< QgsStyleManagerDialog > mStyleManagerDialog;
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/qgsabstract3dsymbol.cpp
3d/qgsabstract3drenderer.cpp
3d/qgs3dviewsmanager.cpp
fieldformatter/qgscheckboxfieldformatter.cpp
fieldformatter/qgsrangefieldformatter.cpp
@ -1165,6 +1166,7 @@ set(QGIS_CORE_HDRS
3d/qgs3dsymbolregistry.h
3d/qgsabstract3dsymbol.h
3d/qgsabstract3drenderer.h
3d/qgs3dviewsmanager.h
annotations/qgsannotation.h
annotations/qgsannotationitem.h

View File

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

View File

@ -82,7 +82,7 @@ class QgsProjectTimeSettings;
class QgsAnnotationLayer;
class QgsAttributeEditorContainer;
class QgsPropertyCollection;
class Qgs3DViewsManager;
/**
* \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).
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.
FlagDontLoad3DViews = 1 << 4, //!<
};
Q_DECLARE_FLAGS( ReadFlags, ReadFlag )
@ -755,6 +756,21 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
*/
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
* the project.
@ -2042,6 +2058,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
std::unique_ptr<QgsAnnotationManager> mAnnotationManager;
std::unique_ptr<QgsLayoutManager> mLayoutManager;
std::unique_ptr<Qgs3DViewsManager> m3DViewsManager;
QgsBookmarkManager *mBookmarkManager = nullptr;

View File

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