Skip to content

Commit

Permalink
Merge pull request #39527 from signedav/offlineindicator
Browse files Browse the repository at this point in the history
Indicator for offline layers
  • Loading branch information
signedav committed Nov 11, 2020
2 parents 928997d + ef0bd56 commit f360838
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 2 deletions.
1 change: 1 addition & 0 deletions images/images.qrc
Expand Up @@ -858,6 +858,7 @@
<file>themes/default/mIconModelInput.svg</file>
<file>themes/default/mIndicatorTemporal.svg</file>
<file>themes/default/mIndicatorTimeFromProject.svg</file>
<file>themes/default/mIndicatorOffline.svg</file>
<file>themes/default/temporal_navigation/back.svg</file>
<file>themes/default/temporal_navigation/forward.svg</file>
<file>themes/default/temporal_navigation/next.svg</file>
Expand Down
1 change: 1 addition & 0 deletions images/themes/default/mIndicatorOffline.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions python/core/auto_generated/qgsmaplayer.sip.in
Expand Up @@ -1598,6 +1598,12 @@ Emitted when the validity of this layer changed.
.. versionadded:: 3.16
%End

void customPropertyChanged( const QString &key );
%Docstring
Emitted when a custom property of the layer has been changed or removed.

.. versionadded:: 3.18
%End

protected:

Expand Down
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -52,6 +52,7 @@ SET(QGIS_APP_SRCS
qgslayertreeviewnonremovableindicator.cpp
qgslayertreeviewbadlayerindicator.cpp
qgslayertreeviewtemporalindicator.cpp
qgslayertreeviewofflineindicator.cpp
qgsmapcanvasdockwidget.cpp
qgsmapsavedialog.cpp
qgsprojectlistitemdelegate.cpp
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -249,6 +249,7 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
#include "qgslayertreeviewnonremovableindicator.h"
#include "qgslayertreeviewnocrsindicator.h"
#include "qgslayertreeviewtemporalindicator.h"
#include "qgslayertreeviewofflineindicator.h"
#include "qgslayout.h"
#include "qgslayoutatlas.h"
#include "qgslayoutcustomdrophandler.h"
Expand Down Expand Up @@ -4750,6 +4751,7 @@ void QgisApp::initLayerTreeView()
new QgsLayerTreeViewMemoryIndicatorProvider( mLayerTreeView ); // gets parented to the layer view
new QgsLayerTreeViewTemporalIndicatorProvider( mLayerTreeView ); // gets parented to the layer view
new QgsLayerTreeViewNoCrsIndicatorProvider( mLayerTreeView ); // gets parented to the layer view
new QgsLayerTreeViewOfflineIndicatorProvider( mLayerTreeView ); // gets parented to the layer view
QgsLayerTreeViewBadLayerIndicatorProvider *badLayerIndicatorProvider = new QgsLayerTreeViewBadLayerIndicatorProvider( mLayerTreeView ); // gets parented to the layer view
connect( badLayerIndicatorProvider, &QgsLayerTreeViewBadLayerIndicatorProvider::requestChangeDataSource, this, &QgisApp::changeDataSource );
new QgsLayerTreeViewNonRemovableIndicatorProvider( mLayerTreeView ); // gets parented to the layer view
Expand Down
68 changes: 68 additions & 0 deletions src/app/qgslayertreeviewofflineindicator.cpp
@@ -0,0 +1,68 @@
/***************************************************************************
qgslayertreeviewofflineindicator.cpp
--------------------------------------
Date : October 2020
Copyright : (C) 2020 by David Signer
Email : david at opengis dot ch
***************************************************************************
* *
* 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 "qgslayertreeviewofflineindicator.h"
#include "qgslayertreeview.h"
#include "qgslayertree.h"
#include "qgslayertreemodel.h"
#include "qgisapp.h"

QgsLayerTreeViewOfflineIndicatorProvider::QgsLayerTreeViewOfflineIndicatorProvider( QgsLayerTreeView *view )
: QgsLayerTreeViewIndicatorProvider( view )
{

}

void QgsLayerTreeViewOfflineIndicatorProvider::connectSignals( QgsMapLayer *layer )
{
if ( !layer )
return;

connect( layer, &QgsMapLayer::customPropertyChanged, this, &QgsLayerTreeViewOfflineIndicatorProvider::onLayerChanged );
}

void QgsLayerTreeViewOfflineIndicatorProvider::disconnectSignals( QgsMapLayer *layer )
{
if ( !layer )
return;

disconnect( layer, &QgsMapLayer::customPropertyChanged, this, &QgsLayerTreeViewOfflineIndicatorProvider::onLayerChanged );
}

bool QgsLayerTreeViewOfflineIndicatorProvider::acceptLayer( QgsMapLayer *layer )
{
return layer->customProperty( QStringLiteral( "isOfflineEditable" ), false ).toBool();
}

QString QgsLayerTreeViewOfflineIndicatorProvider::iconName( QgsMapLayer *layer )
{
Q_UNUSED( layer )
return QStringLiteral( "/mIndicatorOffline.svg" );
}

QString QgsLayerTreeViewOfflineIndicatorProvider::tooltipText( QgsMapLayer *layer )
{
Q_UNUSED( layer )
return tr( "<b>Offline layer</b>" );
}

void QgsLayerTreeViewOfflineIndicatorProvider::onLayerChanged()
{
QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
if ( !layer )
return;

updateLayerIndicator( layer );
}
47 changes: 47 additions & 0 deletions src/app/qgslayertreeviewofflineindicator.h
@@ -0,0 +1,47 @@
/***************************************************************************
qgslayertreeviewofflineindicator.h
--------------------------------------
Date : October 2020
Copyright : (C) 2020 by David Signer
Email : david at opengis dot ch
***************************************************************************
* *
* 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 QGSLAYERTREEVIEWOFFLINEINDICATOR_H
#define QGSLAYERTREEVIEWOFFLINEINDICATOR_H

#include "qgslayertreeviewindicatorprovider.h"

#include <QSet>
#include <memory>

class QgsLayerTreeNode;
class QgsLayerTreeView;

//! Adds indicators showing whether layers are offline.
class QgsLayerTreeViewOfflineIndicatorProvider : public QgsLayerTreeViewIndicatorProvider
{
Q_OBJECT
public:
explicit QgsLayerTreeViewOfflineIndicatorProvider( QgsLayerTreeView *view );

protected:
void connectSignals( QgsMapLayer *layer ) override;
void disconnectSignals( QgsMapLayer *layer ) override;

protected slots:
void onLayerChanged();

private:
bool acceptLayer( QgsMapLayer *layer ) override;
QString iconName( QgsMapLayer *layer ) override;
QString tooltipText( QgsMapLayer *layer ) override;
};

#endif // QGSLAYERTREEVIEWOFFLINEINDICATOR_H
13 changes: 11 additions & 2 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -1707,7 +1707,11 @@ QStringList QgsMapLayer::customPropertyKeys() const

void QgsMapLayer::setCustomProperty( const QString &key, const QVariant &value )
{
mCustomProperties.setValue( key, value );
if ( !mCustomProperties.contains( key ) || mCustomProperties.value( key ) != value )
{
mCustomProperties.setValue( key, value );
emit customPropertyChanged( key );
}
}

void QgsMapLayer::setCustomProperties( const QgsObjectCustomProperties &properties )
Expand All @@ -1727,7 +1731,12 @@ QVariant QgsMapLayer::customProperty( const QString &value, const QVariant &defa

void QgsMapLayer::removeCustomProperty( const QString &key )
{
mCustomProperties.remove( key );

if ( mCustomProperties.contains( key ) )
{
mCustomProperties.remove( key );
emit customPropertyChanged( key );
}
}

QgsError QgsMapLayer::error() const
Expand Down
6 changes: 6 additions & 0 deletions src/core/qgsmaplayer.h
Expand Up @@ -1429,6 +1429,12 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
void isValidChanged();

/**
* Emitted when a custom property of the layer has been changed or removed.
*
* \since QGIS 3.18
*/
void customPropertyChanged( const QString &key );

private slots:

Expand Down
40 changes: 40 additions & 0 deletions tests/src/python/test_qgsvectorlayer.py
Expand Up @@ -399,6 +399,46 @@ def testSetDataSourceInvalidToValid(self):
# should STILL have kept renderer!
self.assertEqual(layer.renderer(), r)

def testSetCustomProperty(self):
"""
Test setting a custom property of the layer
"""
layer = createLayerWithOnePoint()
layer.setCustomProperty('Key_0', 'Value_0')
layer.setCustomProperty('Key_1', 'Value_1')

spy = QSignalSpy(layer.customPropertyChanged)

# change nothing by setting the same value
layer.setCustomProperty('Key_0', 'Value_0')
layer.setCustomProperty('Key_1', 'Value_1')
self.assertEqual(len(spy), 0)

# change one
layer.setCustomProperty('Key_0', 'Value zero')
self.assertEqual(len(spy), 1)

# add one
layer.setCustomProperty('Key_2', 'Value two')
self.assertEqual(len(spy), 2)

# add a null one and an empty one
layer.setCustomProperty('Key_3', None)
layer.setCustomProperty('Key_4', '')
self.assertEqual(len(spy), 4)

# remove one
layer.removeCustomProperty('Key_0')
self.assertEqual(len(spy), 5)

self.assertEqual(layer.customProperty('Key_0', 'no value'), 'no value')
self.assertEqual(layer.customProperty('Key_1', 'no value'), 'Value_1')
self.assertEqual(layer.customProperty('Key_2', 'no value'), 'Value two')
self.assertEqual(layer.customProperty('Key_3', 'no value'), None)
self.assertEqual(layer.customProperty('Key_4', 'no value'), '')

self.assertEqual(len(spy), 5)

def testStoreWkbTypeInvalidLayers(self):
"""
Test that layer wkb types are restored for projects with invalid layer paths
Expand Down

0 comments on commit f360838

Please sign in to comment.