Skip to content

Commit 370edc3

Browse files
committed
Refactor ActiveProject to QML singleton
1 parent 1a91120 commit 370edc3

27 files changed

+165
-139
lines changed

app/activeproject.cpp

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,26 @@
2828
const QString ActiveProject::LOADING_FLAG_FILE_PATH = QString( "%1/.input_loading_project" ).arg( QStandardPaths::standardLocations( QStandardPaths::TempLocation ).first() );
2929
const int ActiveProject::LOADING_FLAG_FILE_EXPIRATION_MS = 5000;
3030

31-
ActiveProject::ActiveProject( AppSettings &appSettings
32-
, ActiveLayer &activeLayer
33-
, LocalProjectsManager &localProjectsManager
34-
, QObject *parent ) :
35-
36-
QObject( parent )
37-
, mAppSettings( appSettings )
38-
, mActiveLayer( activeLayer )
39-
, mLocalProjectsManager( localProjectsManager )
40-
, mProjectLoadingLog( "" )
31+
ActiveProject::ActiveProject( QObject *parent ) : QObject( parent )
4132
{
4233
// we used to have our own QgsProject instance, but unfortunately few pieces of qgis_core
4334
// still work with QgsProject::instance() singleton hardcoded (e.g. vector layer's feature
4435
// iterator uses it for virtual fields, causing minor bugs with expressions)
4536
// so for the time being let's just stick to using the singleton until qgis_core is completely fixed
4637
mQgsProject = QgsProject::instance();
38+
mProjectLoadingLog = QLatin1String();
39+
}
40+
41+
void ActiveProject::setup( AppSettings &appSettings, ActiveLayer &activeLayer,
42+
LocalProjectsManager &localProjectsManager )
43+
{
44+
mAppSettings = &appSettings;
45+
mActiveLayer = &activeLayer;
46+
mLocalProjectsManager = &localProjectsManager;
4747

4848
// listen to local project removal event to invalidate mProject
49-
QObject::connect(
50-
&mLocalProjectsManager,
49+
connect(
50+
mLocalProjectsManager,
5151
&LocalProjectsManager::aboutToRemoveLocalProject,
5252
this, [this]( const LocalProject & project )
5353
{
@@ -58,8 +58,8 @@ ActiveProject::ActiveProject( AppSettings &appSettings
5858
} );
5959

6060
// listen to metadata changes of opened LocalProject (e.g. local version update or namespace update)
61-
QObject::connect(
62-
&mLocalProjectsManager,
61+
connect(
62+
mLocalProjectsManager,
6363
&LocalProjectsManager::localProjectDataChanged,
6464
this, [this]( const LocalProject & project )
6565
{
@@ -70,13 +70,11 @@ ActiveProject::ActiveProject( AppSettings &appSettings
7070
}
7171
} );
7272

73-
setAutosyncEnabled( mAppSettings.autosyncAllowed() );
73+
setAutosyncEnabled( mAppSettings->autosyncAllowed() );
7474

75-
QObject::connect( &mAppSettings, &AppSettings::autosyncAllowedChanged, this, &ActiveProject::setAutosyncEnabled );
75+
connect( mAppSettings, &AppSettings::autosyncAllowedChanged, this, &ActiveProject::setAutosyncEnabled );
7676
}
7777

78-
ActiveProject::~ActiveProject() = default;
79-
8078
QgsProject *ActiveProject::qgsProject() const
8179
{
8280
return mQgsProject;
@@ -115,7 +113,7 @@ bool ActiveProject::forceLoad( const QString &filePath, bool force )
115113
{
116114
emit projectWillBeReloaded();
117115

118-
whileBlocking( &mActiveLayer )->resetActiveLayer();
116+
whileBlocking( mActiveLayer )->resetActiveLayer();
119117
mLocalProject = LocalProject();
120118
mQgsProject->clear();
121119

@@ -153,7 +151,7 @@ bool ActiveProject::forceLoad( const QString &filePath, bool force )
153151
if ( mQgsProject->fileName() != filePath || force )
154152
{
155153
emit projectWillBeReloaded();
156-
mActiveLayer.resetActiveLayer();
154+
mActiveLayer->resetActiveLayer();
157155

158156
res = mQgsProject->read( filePath );
159157
if ( !res )
@@ -176,7 +174,7 @@ bool ActiveProject::forceLoad( const QString &filePath, bool force )
176174
return res;
177175
}
178176

179-
mLocalProject = mLocalProjectsManager.projectFromProjectFilePath( filePath );
177+
mLocalProject = mLocalProjectsManager->projectFromProjectFilePath( filePath );
180178

181179
if ( !mLocalProject.isValid() )
182180
{
@@ -224,7 +222,7 @@ bool ActiveProject::forceLoad( const QString &filePath, bool force )
224222
}
225223
}
226224

227-
if ( mAppSettings.autosyncAllowed() )
225+
if ( mAppSettings->autosyncAllowed() )
228226
{
229227
setAutosyncEnabled( true );
230228
requestSync( SyncOptions::AutomaticRequest );
@@ -475,9 +473,9 @@ void ActiveProject::updateActiveLayer()
475473
return;
476474
}
477475

478-
if ( !visibleLayers.contains( mActiveLayer.layer() ) )
476+
if ( !visibleLayers.contains( mActiveLayer->layer() ) )
479477
{
480-
QgsMapLayer *defaultLayer = InputUtils::mapLayerFromName( mAppSettings.defaultLayer(), mQgsProject );
478+
QgsMapLayer *defaultLayer = InputUtils::mapLayerFromName( mAppSettings->defaultLayer(), mQgsProject );
481479

482480
if ( !recordingAllowed( defaultLayer ) )
483481
{
@@ -504,12 +502,12 @@ void ActiveProject::setActiveLayer( QgsMapLayer *layer ) const
504502
{
505503
if ( !layer || !layer->isValid() )
506504
{
507-
mActiveLayer.resetActiveLayer();
505+
mActiveLayer->resetActiveLayer();
508506
}
509507
else
510508
{
511-
mActiveLayer.setActiveLayer( layer );
512-
mAppSettings.setDefaultLayer( mActiveLayer.layerName() );
509+
mActiveLayer->setActiveLayer( layer );
510+
mAppSettings->setDefaultLayer( mActiveLayer->layerName() );
513511
}
514512
}
515513

app/activeproject.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
#include <QObject>
1515

1616
#include "qgsproject.h"
17+
#include "qgslayertreenode.h"
1718

1819
#include "appsettings.h"
1920
#include "activelayer.h"
2021
#include "recordinglayersproxymodel.h"
2122
#include "localprojectsmanager.h"
2223
#include "autosynccontroller.h"
2324
#include "inputmapsettings.h"
24-
#include "merginprojectmetadata.h"
2525
#include "synchronizationoptions.h"
2626

2727
/**
@@ -30,6 +30,9 @@
3030
class ActiveProject: public QObject
3131
{
3232
Q_OBJECT
33+
QML_ELEMENT
34+
QML_SINGLETON
35+
3336
Q_PROPERTY( LocalProject localProject READ localProject NOTIFY localProjectChanged ) // LocalProject instance of active project, changes when project is loaded
3437
Q_PROPERTY( QgsProject *qgsProject READ qgsProject NOTIFY qgsProjectChanged ) // QgsProject instance of active project, never changes
3538
Q_PROPERTY( AutosyncController *autosyncController READ autosyncController NOTIFY autosyncControllerChanged )
@@ -42,13 +45,12 @@ class ActiveProject: public QObject
4245
Q_PROPERTY( bool photoSketchingEnabled READ photoSketchingEnabled NOTIFY photoSketchingEnabledChanged )
4346

4447
public:
45-
explicit ActiveProject(
46-
AppSettings &appSettings
47-
, ActiveLayer &activeLayer
48-
, LocalProjectsManager &localProjectsManager
49-
, QObject *parent = nullptr );
48+
explicit ActiveProject( QObject *parent = nullptr );
49+
50+
~ActiveProject() override = default;
5051

51-
virtual ~ActiveProject();
52+
// Initialize values
53+
void setup( AppSettings &appSettings, ActiveLayer &activeLayer, LocalProjectsManager &localProjectsManager );
5254

5355
//! Returns active project's QgsProject instance to do QGIS API magic
5456
QgsProject *qgsProject() const;
@@ -215,9 +217,9 @@ class ActiveProject: public QObject
215217
QgsProject *mQgsProject = nullptr;
216218
LocalProject mLocalProject;
217219

218-
AppSettings &mAppSettings;
219-
ActiveLayer &mActiveLayer;
220-
LocalProjectsManager &mLocalProjectsManager;
220+
AppSettings *mAppSettings = nullptr;
221+
ActiveLayer *mActiveLayer = nullptr;
222+
LocalProjectsManager *mLocalProjectsManager = nullptr;
221223
InputMapSettings *mMapSettings = nullptr;
222224
std::unique_ptr<AutosyncController> mAutosyncController;
223225

app/main.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,9 @@ int main( int argc, char *argv[] )
533533
NotificationModel notificationModel;
534534

535535
ActiveLayer al;
536-
ActiveProject activeProject( *as, al, localProjectsManager );
536+
// ActiveProject activeProject( *as, al, localProjectsManager );
537+
ActiveProject *activeProject = engine.singletonInstance<ActiveProject *>( "MMInput", "ActiveProject" );
538+
activeProject->setup( *as, al, localProjectsManager );
537539
std::unique_ptr<VariablesManager> vm( new VariablesManager( ma.get() ) );
538540
vm->registerInputExpressionFunctions();
539541

@@ -558,11 +560,11 @@ int main( int argc, char *argv[] )
558560

559561
// the automatic sync request on cold start will fail on MerginApiStatus not being initialized yet, so we call it again
560562
// after server ping is done
561-
if ( activeProject.autosyncController() )
563+
if ( activeProject->autosyncController() )
562564
{
563565
QObject::connect( ma.get(), &MerginApi::pingMerginFinished, &lambdaContext, [&activeProject]
564566
{
565-
activeProject.requestSync( SyncOptions::AutomaticRequest );
567+
activeProject->requestSync( SyncOptions::AutomaticRequest );
566568
}, Qt::SingleShotConnection );
567569
}
568570

@@ -613,33 +615,33 @@ int main( int argc, char *argv[] )
613615
notificationModel.addError( message );
614616
} );
615617

616-
QObject::connect( &activeProject, &ActiveProject::syncActiveProject, &syncManager, [&syncManager]( const LocalProject & project, const SyncOptions::RequestOrigin requestOrigin )
618+
QObject::connect( activeProject, &ActiveProject::syncActiveProject, &syncManager, [&syncManager]( const LocalProject & project, const SyncOptions::RequestOrigin requestOrigin )
617619
{
618620
syncManager.syncProject( project, SyncOptions::Authorized, SyncOptions::Retry, requestOrigin );
619621
} );
620622

621-
QObject::connect( &activeProject, &ActiveProject::projectReloaded, &lambdaContext, [merginApi = ma.get(), &activeProject]()
623+
QObject::connect( activeProject, &ActiveProject::projectReloaded, &lambdaContext, [merginApi = ma.get(), &activeProject]()
622624
{
623-
merginApi->reloadProjectRole( activeProject.projectFullName() );
625+
merginApi->reloadProjectRole( activeProject->projectFullName() );
624626
} );
625627

626628
QObject::connect( ma.get(), &MerginApi::authChanged, &lambdaContext, [merginApi = ma.get(), &activeProject]()
627629
{
628-
if ( activeProject.isProjectLoaded() )
630+
if ( activeProject->isProjectLoaded() )
629631
{
630632
// if you are logged in or if you just logged out
631633
if ( merginApi->userAuth()->hasValidToken() || !merginApi->userAuth()->hasAuthData() )
632634
{
633-
merginApi->reloadProjectRole( activeProject.projectFullName() );
635+
merginApi->reloadProjectRole( activeProject->projectFullName() );
634636
}
635637
}
636638
} );
637639

638-
QObject::connect( ma.get(), &MerginApi::projectRoleUpdated, &activeProject, [&activeProject]( const QString & projectFullName, const QString & role )
640+
QObject::connect( ma.get(), &MerginApi::projectRoleUpdated, activeProject, [&activeProject]( const QString & projectFullName, const QString & role )
639641
{
640-
if ( projectFullName == activeProject.projectFullName() )
642+
if ( projectFullName == activeProject->projectFullName() )
641643
{
642-
activeProject.setProjectRole( role );
644+
activeProject->setProjectRole( role );
643645
}
644646
} );
645647

@@ -659,17 +661,17 @@ int main( int argc, char *argv[] )
659661
} );
660662
// Direct connections
661663
QObject::connect( &app, &QGuiApplication::applicationStateChanged, &pk, &PositionKit::appStateChanged );
662-
QObject::connect( &app, &QGuiApplication::applicationStateChanged, &activeProject, &ActiveProject::appStateChanged );
664+
QObject::connect( &app, &QGuiApplication::applicationStateChanged, activeProject, &ActiveProject::appStateChanged );
663665
QObject::connect( &pw, &ProjectWizard::projectCreated, &localProjectsManager, &LocalProjectsManager::addLocalProject );
664-
QObject::connect( &activeProject, &ActiveProject::projectReloaded, vm.get(), &VariablesManager::merginProjectChanged );
665-
QObject::connect( &activeProject, &ActiveProject::projectWillBeReloaded, &inputProjUtils, &InputProjUtils::resetHandlers );
666-
QObject::connect( &syncManager, &SynchronizationManager::syncFinished, &activeProject, [&activeProject]( const QString & projectFullName, bool successfully, int version, bool reloadNeeded )
666+
QObject::connect( activeProject, &ActiveProject::projectReloaded, vm.get(), &VariablesManager::merginProjectChanged );
667+
QObject::connect( activeProject, &ActiveProject::projectWillBeReloaded, &inputProjUtils, &InputProjUtils::resetHandlers );
668+
QObject::connect( &syncManager, &SynchronizationManager::syncFinished, activeProject, [&activeProject]( const QString & projectFullName, bool successfully, int version, bool reloadNeeded )
667669
{
668670
Q_UNUSED( successfully );
669671
Q_UNUSED( version );
670-
if ( reloadNeeded && activeProject.projectFullName() == projectFullName )
672+
if ( reloadNeeded && activeProject->projectFullName() == projectFullName )
671673
{
672-
activeProject.reloadProject( activeProject.qgsProject()->homePath() );
674+
activeProject->reloadProject( activeProject->qgsProject()->homePath() );
673675
}
674676
} );
675677
QObject::connect( QgsApplication::messageLog(),
@@ -725,7 +727,7 @@ int main( int argc, char *argv[] )
725727
engine.rootContext()->setContextProperty( "__inputUtils", &iu );
726728
engine.rootContext()->setContextProperty( "__inputProjUtils", &inputProjUtils );
727729
engine.rootContext()->setContextProperty( "__inputHelp", &help );
728-
engine.rootContext()->setContextProperty( "__activeProject", &activeProject );
730+
// engine.rootContext()->setContextProperty( "__activeProject", &activeProject );
729731
engine.rootContext()->setContextProperty( "__syncManager", &syncManager );
730732
engine.rootContext()->setContextProperty( "__merginApi", ma.get() );
731733
engine.rootContext()->setContextProperty( "__merginProjectStatusModel", &mpsm );

app/qml/form/MMFormController.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ Item {
187187

188188
rememberAttributesController: MM.RememberAttributesController {
189189
rememberValuesAllowed: AppSettings.reuseLastEnteredValues
190-
activeProjectId: __activeProject.localProject.id()
190+
activeProjectId: ActiveProject.localProject.id()
191191
}
192192
// NOTE: order matters, we want to init variables manager before
193193
// assigning FeatureLayerPair, as VariablesManager is required

app/qml/form/MMFormPage.qml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import QtQuick.Dialogs
1515

1616
import mm 1.0 as MM
1717
import qgs 1.0 as QGS
18+
import MMInput
1819

1920
import "../components" as MMComponents
2021
import "./components" as MMFormComponents
@@ -109,7 +110,7 @@ Page {
109110
if ( root.state === "add" ) return qsTr( "New feature" )
110111
else if ( root.state === "edit" ) return qsTr( "Edit feature" )
111112
else if ( root.state === "multiEdit" ) return qsTr( "Edit selected features" )
112-
return __inputUtils.featureTitle( root.controller.featureLayerPair, __activeProject.qgsProject )
113+
return __inputUtils.featureTitle( root.controller.featureLayerPair, ActiveProject.qgsProject )
113114
}
114115

115116
rightItemContent: MMComponents.MMRoundButton {
@@ -205,7 +206,7 @@ Page {
205206

206207
footer: MMComponents.MMToolbar {
207208

208-
visible: !root.layerIsReadOnly && __activeProject.projectRole !== "reader" && root.state !== "multiEdit"
209+
visible: !root.layerIsReadOnly && ActiveProject.projectRole !== "reader" && root.state !== "multiEdit"
209210

210211
ObjectModel {
211212
id: readStateButtons
@@ -235,7 +236,7 @@ Page {
235236
id: editGeometry
236237
text: qsTr( "Edit geometry" )
237238
iconSource: __style.editIcon
238-
visible: root.layerIsSpatial && __activeProject.projectRole !== "reader"
239+
visible: root.layerIsSpatial && ActiveProject.projectRole !== "reader"
239240
onClicked: root.editGeometryRequested( root.controller.featureLayerPair )
240241
}
241242
}

app/qml/form/MMPreviewDrawer.qml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import QtQuick.Dialogs
1414

1515
import mm 1.0 as MM
1616
import qgs 1.0 as QGS
17+
import MMInput
1718

1819
import "../components" as MMComponents
1920
import "./components" as MMFormComponents
@@ -279,8 +280,8 @@ Item {
279280
property bool isHTMLType: root.controller.type === MM.AttributePreviewController.HTML
280281
property bool isEmptyType: root.controller.type === MM.AttributePreviewController.Empty
281282

282-
property bool showEditButton: !root.layerIsReadOnly && __activeProject.projectRole !== "reader"
283-
property bool showSelectMoreButton: !root.layerIsReadOnly && __activeProject.projectRole !== "reader"
283+
property bool showEditButton: !root.layerIsReadOnly && ActiveProject.projectRole !== "reader"
284+
property bool showSelectMoreButton: !root.layerIsReadOnly && ActiveProject.projectRole !== "reader"
284285
property bool showStakeoutButton: __inputUtils.isPointLayerFeature( controller.featureLayerPair )
285286
property bool showButtons: true
286287

app/qml/form/components/MMFeaturesListPageDrawer.qml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import QtQuick
1111
import QtQuick.Controls
1212

13+
import MMInput
14+
1315
import "../../inputs" as MMInputs
1416
import "../../components" as MMComponents
1517

@@ -103,7 +105,7 @@ Drawer {
103105
}
104106

105107
text: qsTr( "Add feature" )
106-
visible: __activeProject.projectRole !== "reader"
108+
visible: ActiveProject.projectRole !== "reader"
107109

108110
onClicked: root.buttonClicked()
109111
}

app/qml/form/editors/MMFormGalleryEditor.qml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import QtQuick
1111
import QtQuick.Controls
1212

1313
import mm 1.0 as MM
14+
import MMInput
1415

1516
import "../../components" as MMComponents
1617
import "../../components/private" as MMPrivateComponents
@@ -67,7 +68,7 @@ MMPrivateComponents.MMBaseInput {
6768
}
6869
}
6970

70-
header: __activeProject.projectRole !== "reader" ? addFeatureComponent : null
71+
header: ActiveProject.projectRole !== "reader" ? addFeatureComponent : null
7172
}
7273

7374
Component {

0 commit comments

Comments
 (0)