Skip to content

Commit

Permalink
Hiding tracking layer while recording (#3700)
Browse files Browse the repository at this point in the history
  • Loading branch information
VitorVieiraZ authored Jan 23, 2025
1 parent 6115084 commit 3e2f0bc
Show file tree
Hide file tree
Showing 13 changed files with 431 additions and 147 deletions.
72 changes: 33 additions & 39 deletions app/activeproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@ const QString ActiveProject::LOADING_FLAG_FILE_PATH = QString( "%1/.input_loadin

ActiveProject::ActiveProject( AppSettings &appSettings
, ActiveLayer &activeLayer
, LayersProxyModel &recordingLayerPM
, LocalProjectsManager &localProjectsManager
, QObject *parent ) :

QObject( parent )
, mAppSettings( appSettings )
, mActiveLayer( activeLayer )
, mRecordingLayerPM( recordingLayerPM )
, mLocalProjectsManager( localProjectsManager )
, mProjectLoadingLog( "" )
{
Expand Down Expand Up @@ -188,7 +186,6 @@ bool ActiveProject::forceLoad( const QString &filePath, bool force )
setProjectRole( role );

updateMapTheme();
updateRecordingLayers();
updateActiveLayer();
updateMapSettingsLayers();

Expand Down Expand Up @@ -391,30 +388,6 @@ AutosyncController *ActiveProject::autosyncController() const
return nullptr;
}

bool ActiveProject::layerVisible( QgsMapLayer *layer )
{
if ( !mQgsProject || !layer )
{
return false;
}

QgsLayerTree *root = mQgsProject->layerTreeRoot();

if ( !root )
{
return false;
}

QgsLayerTreeLayer *layerTree = root->findLayer( layer );

if ( !layerTree )
{
return false;
}

return layerTree->isVisible();
}

QString ActiveProject::projectLoadingLog() const
{
return mProjectLoadingLog;
Expand Down Expand Up @@ -486,29 +459,38 @@ void ActiveProject::setMapTheme( const QString &themeName )

emit mapThemeChanged( mMapTheme );

updateRecordingLayers(); // <- worth to decouple similar to map themes model decoupling
updateActiveLayer();
updateMapSettingsLayers();
}

void ActiveProject::updateActiveLayer()
{
if ( !layerVisible( mActiveLayer.layer() ) )
if ( !InputUtils::layerVisible( mActiveLayer.layer(), mQgsProject ) )
{
QgsMapLayer *defaultLayer = mRecordingLayerPM.layerFromLayerName( mAppSettings.defaultLayer() );
QgsMapLayer *defaultAppSettingsLayer = InputUtils::mapLayerFromName( mAppSettings.defaultLayer(), mQgsProject );

if ( !defaultLayer )
if ( InputUtils::recordingAllowed( defaultAppSettingsLayer, mQgsProject ) )
{
defaultLayer = mRecordingLayerPM.firstUsableLayer();
setActiveLayer( defaultAppSettingsLayer );
return;
}

setActiveLayer( defaultLayer );
}
}
// default layer from app settings has no recording allowed => let's try to search for a new one
QgsMapLayer *defaultLayer = nullptr;
const QMap<QString, QgsMapLayer *> layers = mQgsProject->mapLayers();
for ( auto it = layers.cbegin(); it != layers.cend(); ++it )
{
QgsMapLayer *layer = it.value();
if ( InputUtils::recordingAllowed( layer, mQgsProject ) )
{
defaultLayer = layer;
break;
}
}

void ActiveProject::updateRecordingLayers()
{
mRecordingLayerPM.refreshData();
if ( defaultLayer )
setActiveLayer( defaultLayer );
}
}

bool ActiveProject::isProjectLoaded() const
Expand Down Expand Up @@ -537,7 +519,6 @@ void ActiveProject::switchLayerTreeNodeVisibility( QgsLayerTreeNode *node )
node->setItemVisibilityChecked( !node->isVisible() );

updateMapTheme();
updateRecordingLayers(); // <- worth to decouple similar to map themes model decoupling
updateActiveLayer();
updateMapSettingsLayers();
}
Expand All @@ -557,6 +538,19 @@ bool ActiveProject::positionTrackingSupported() const
return mQgsProject->readBoolEntry( QStringLiteral( "Mergin" ), QStringLiteral( "PositionTracking/Enabled" ), false );
}

bool ActiveProject::projectHasRecordingLayers() const
{
if ( !mQgsProject )
return false;

const QMap<QString, QgsMapLayer *> layers = mQgsProject->mapLayers();
for ( auto it = layers.constBegin(); it != layers.constEnd(); ++it )
{
if ( InputUtils::recordingAllowed( it.value(), mQgsProject ) )
return true;
}

return false;
QString ActiveProject::projectRole() const
{
return mProjectRole;
Expand Down
9 changes: 2 additions & 7 deletions app/activeproject.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class ActiveProject: public QObject
explicit ActiveProject(
AppSettings &appSettings
, ActiveLayer &activeLayer
, LayersProxyModel &recordingLayerPM
, LocalProjectsManager &localProjectsManager
, QObject *parent = nullptr );

Expand Down Expand Up @@ -103,11 +102,6 @@ class ActiveProject: public QObject
*/
void updateMapSettingsLayers() const;

/**
* layerVisible returns boolean if input layer is visible within current project
*/
bool layerVisible( QgsMapLayer *layer );

/**
* Return the QGIS log recorded during the loading phase of the project
*/
Expand All @@ -120,6 +114,8 @@ class ActiveProject: public QObject

bool positionTrackingSupported() const;

//! Returns true if the project has at least one layer that allows recording
Q_INVOKABLE bool projectHasRecordingLayers() const;
/**
* Returns role/permission level of current user for this project
*/
Expand Down Expand Up @@ -189,7 +185,6 @@ class ActiveProject: public QObject

AppSettings &mAppSettings;
ActiveLayer &mActiveLayer;
LayersProxyModel &mRecordingLayerPM;
LocalProjectsManager &mLocalProjectsManager;
InputMapSettings *mMapSettings = nullptr;
std::unique_ptr<AutosyncController> mAutosyncController;
Expand Down
62 changes: 62 additions & 0 deletions app/inpututils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2222,3 +2222,65 @@ double InputUtils::pixelDistanceBetween( const QPointF &p1, const QPointF &p2 )
{
return std::hypot( p1.x() - p2.x(), p1.y() - p2.y() );
}

bool InputUtils::layerHasGeometry( const QgsVectorLayer *layer )
{
if ( !layer || !layer->isValid() )
return false;
return layer->wkbType() != Qgis::WkbType::NoGeometry && layer->wkbType() != Qgis::WkbType::Unknown;
}

bool InputUtils::layerVisible( QgsMapLayer *layer, QgsProject *project )
{
if ( !layer || !layer->isValid() || !project )
return false;

QgsLayerTree *root = project->layerTreeRoot();

if ( !root )
return false;

QgsLayerTreeLayer *layerTree = root->findLayer( layer );

if ( layerTree )
return layerTree->isVisible();

return false;
}

bool InputUtils::isPositionTrackingLayer( QgsMapLayer *layer, QgsProject *project )
{
if ( !layer || !project )
return false;

QString trackingLayerId = project->readEntry( QStringLiteral( "Mergin" ), QStringLiteral( "PositionTracking/TrackingLayer" ), QString() );
return layer->id() == trackingLayerId;
}

bool InputUtils::recordingAllowed( QgsMapLayer *layer, QgsProject *project )
{
if ( !layer || !layer->isValid() || !project )
return false;

QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );

return ( vectorLayer &&
!vectorLayer->readOnly() &&
layerHasGeometry( vectorLayer ) &&
layerVisible( layer, project ) &&
!isPositionTrackingLayer( layer, project ) );
}

QgsMapLayer *InputUtils::mapLayerFromName( const QString &layerName, QgsProject *project )
{
if ( !project || layerName.isEmpty() )
return nullptr;

QList<QgsMapLayer *> layersByName = project->mapLayersByName( layerName );
if ( !layersByName.isEmpty() )
{
return layersByName.first();
}

return nullptr;
}
26 changes: 26 additions & 0 deletions app/inpututils.h
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,32 @@ class InputUtils: public QObject
*/
static double pixelDistanceBetween( const QPointF &p1, const QPointF &p2 );

/**
* filters if input layer is visible in current map theme
*/
static bool layerVisible( QgsMapLayer *layer, QgsProject *project );

/**
* Returns if layer is not NoGeo and not Unknown
*/
static bool layerHasGeometry( const QgsVectorLayer *layer );

/**
* Returns true if the layer is the position tracking layer
*/
Q_INVOKABLE static bool isPositionTrackingLayer( QgsMapLayer *layer, QgsProject *project );

/**
* Returns true if the layer allows recording
*/
static bool recordingAllowed( QgsMapLayer *layer, QgsProject *project );

/**
* Returns QgsMapLayer pointer for given layer name and project.
* If layer with given name does not exist or there is no project, returns nullptr.
*/
static QgsMapLayer *mapLayerFromName( const QString &layerName, QgsProject *project );

public slots:
void onQgsLogMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level );

Expand Down
Loading

0 comments on commit 3e2f0bc

Please sign in to comment.