Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remember project state mode (browse or digitize) and active layer across sessions #4449

Merged
merged 4 commits into from
Jul 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 71 additions & 37 deletions src/core/projectinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

#include <QDateTime>
#include <QFileInfo>
#include <QSettings>
#include <QString>
#include <qgslayertree.h>
#include <qgslayertreemodel.h>
Expand Down Expand Up @@ -108,12 +107,11 @@ void ProjectInfo::saveExtent()
QFileInfo fi( mFilePath );
if ( fi.exists() )
{
QSettings settings;
const QgsRectangle extent = mMapSettings->extent();
settings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
settings.setValue( QStringLiteral( "filesize" ), fi.size() );
settings.setValue( QStringLiteral( "extent" ), QStringLiteral( "%1|%2|%3|%4" ).arg( qgsDoubleToString( extent.xMinimum() ), qgsDoubleToString( extent.xMaximum() ), qgsDoubleToString( extent.yMinimum() ), qgsDoubleToString( extent.yMaximum() ) ) );
settings.endGroup();
mSettings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
mSettings.setValue( QStringLiteral( "filesize" ), fi.size() );
mSettings.setValue( QStringLiteral( "extent" ), QStringLiteral( "%1|%2|%3|%4" ).arg( qgsDoubleToString( extent.xMinimum() ), qgsDoubleToString( extent.xMaximum() ), qgsDoubleToString( extent.yMinimum() ), qgsDoubleToString( extent.yMaximum() ) ) );
mSettings.endGroup();
}
}

Expand All @@ -130,11 +128,10 @@ void ProjectInfo::saveRotation()
QFileInfo fi( mFilePath );
if ( fi.exists() )
{
QSettings settings;
settings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
settings.setValue( QStringLiteral( "filesize" ), fi.size() );
settings.setValue( QStringLiteral( "rotation" ), mMapSettings->rotation() );
settings.endGroup();
mSettings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
mSettings.setValue( QStringLiteral( "filesize" ), fi.size() );
mSettings.setValue( QStringLiteral( "rotation" ), mMapSettings->rotation() );
mSettings.endGroup();
}
}

Expand All @@ -151,17 +148,16 @@ void ProjectInfo::saveTemporalState()
QFileInfo fi( mFilePath );
if ( fi.exists() )
{
QSettings settings;
settings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
settings.setValue( QStringLiteral( "filesize" ), fi.size() );
settings.setValue( QStringLiteral( "isTemporal" ), mMapSettings->isTemporal() );
settings.setValue( QStringLiteral( "StartDateTime" ), mMapSettings->temporalBegin().toTimeSpec( Qt::LocalTime ).toString( Qt::ISODateWithMs ) );
settings.setValue( QStringLiteral( "EndDateTime" ), mMapSettings->temporalEnd().toTimeSpec( Qt::LocalTime ).toString( Qt::ISODateWithMs ) );
settings.endGroup();
mSettings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
mSettings.setValue( QStringLiteral( "filesize" ), fi.size() );
mSettings.setValue( QStringLiteral( "isTemporal" ), mMapSettings->isTemporal() );
mSettings.setValue( QStringLiteral( "StartDateTime" ), mMapSettings->temporalBegin().toTimeSpec( Qt::LocalTime ).toString( Qt::ISODateWithMs ) );
mSettings.setValue( QStringLiteral( "EndDateTime" ), mMapSettings->temporalEnd().toTimeSpec( Qt::LocalTime ).toString( Qt::ISODateWithMs ) );
mSettings.endGroup();
}
}

void ProjectInfo::saveLayerStyle( QgsMapLayer *layer ) const
void ProjectInfo::saveLayerStyle( QgsMapLayer *layer )
{
if ( mFilePath.isEmpty() || !layer )
return;
Expand All @@ -185,14 +181,13 @@ void ProjectInfo::saveLayerStyle( QgsMapLayer *layer ) const
id += layer->id();
}

QSettings settings;
settings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1/layerstyles" ).arg( mFilePath ) );
settings.setValue( id, style.xmlData() );
settings.endGroup();
mSettings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1/layerstyles" ).arg( mFilePath ) );
mSettings.setValue( id, style.xmlData() );
mSettings.endGroup();
}
}

void ProjectInfo::saveLayerTreeState() const
void ProjectInfo::saveLayerTreeState()
{
if ( mFilePath.isEmpty() || !mLayerTree )
return;
Expand All @@ -211,15 +206,55 @@ void ProjectInfo::saveLayerTreeState() const
document.appendChild( document.createElement( QStringLiteral( "qgis" ) ) );
mapCollection.writeXml( document );

QSettings settings;
settings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
settings.setValue( QStringLiteral( "filesize" ), fi.size() );
settings.setValue( QStringLiteral( "layertreestate" ), document.toString() );
settings.remove( QStringLiteral( "maptheme" ) );
settings.endGroup();
mSettings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
mSettings.setValue( QStringLiteral( "filesize" ), fi.size() );
mSettings.setValue( QStringLiteral( "layertreestate" ), document.toString() );
mSettings.remove( QStringLiteral( "maptheme" ) );
mSettings.endGroup();
}
}

void ProjectInfo::saveStateMode( const QString &mode )
{
if ( mFilePath.isEmpty() )
return;

QFileInfo fi( mFilePath );
if ( fi.exists() )
{
mSettings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
mSettings.setValue( QStringLiteral( "filesize" ), fi.size() );
mSettings.setValue( QStringLiteral( "stateMode" ), mode );
mSettings.endGroup();
}
}

QString ProjectInfo::getSavedStateMode() const
{
return mSettings.value( QStringLiteral( "/qgis/projectInfo/%1/stateMode" ).arg( mFilePath ), QStringLiteral( "browse" ) ).toString();
}

void ProjectInfo::saveActiveLayer( QgsMapLayer *layer )
{
if ( mFilePath.isEmpty() || !layer )
return;

QFileInfo fi( mFilePath );
if ( fi.exists() )
{
mSettings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
mSettings.setValue( QStringLiteral( "filesize" ), fi.size() );
mSettings.setValue( QStringLiteral( "activeLayer" ), layer->id() );
mSettings.endGroup();
}
}

QgsMapLayer *ProjectInfo::getSavedActiveLayer() const
{
const QString layerId = mSettings.value( QStringLiteral( "/qgis/projectInfo/%1/activeLayer" ).arg( mFilePath ) ).toString();
return !layerId.isEmpty() ? QgsProject::instance()->mapLayer( layerId ) : nullptr;
}

void ProjectInfo::mapThemeChanged()
{
if ( mFilePath.isEmpty() )
Expand All @@ -228,18 +263,17 @@ void ProjectInfo::mapThemeChanged()
QFileInfo fi( mFilePath );
if ( fi.exists() )
{
QSettings settings;
settings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
settings.setValue( QStringLiteral( "filesize" ), fi.size() );
mSettings.beginGroup( QStringLiteral( "/qgis/projectInfo/%1" ).arg( mFilePath ) );
mSettings.setValue( QStringLiteral( "filesize" ), fi.size() );
if ( !mLayerTree->mapTheme().isEmpty() )
{
settings.setValue( QStringLiteral( "maptheme" ), mLayerTree->mapTheme() );
settings.remove( QStringLiteral( "layertreestate" ) );
mSettings.setValue( QStringLiteral( "maptheme" ), mLayerTree->mapTheme() );
mSettings.remove( QStringLiteral( "layertreestate" ) );
}
else
{
settings.remove( QStringLiteral( "maptheme" ) );
mSettings.remove( QStringLiteral( "maptheme" ) );
}
settings.endGroup();
mSettings.endGroup();
}
}
27 changes: 25 additions & 2 deletions src/core/projectinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "qgsquickmapsettings.h"

#include <QObject>
#include <QSettings>
#include <QTimer>

/**
Expand Down Expand Up @@ -59,12 +60,33 @@ class ProjectInfo : public QObject
/**
* Saves the \a layer style to the current project information settings
*/
Q_INVOKABLE void saveLayerStyle( QgsMapLayer *layer ) const;
Q_INVOKABLE void saveLayerStyle( QgsMapLayer *layer );

/**
* Saves the current state (visibility and collapse status) of the layer tree
*/
Q_INVOKABLE void saveLayerTreeState() const;
Q_INVOKABLE void saveLayerTreeState();

/**
* Saves the state \a mode for the current project
*/
Q_INVOKABLE void saveStateMode( const QString &mode );

/**
* Returns the saved state mode for the current project
*/
Q_INVOKABLE QString getSavedStateMode() const;

/**
* Saves the active \a layer within the current project
*/
Q_INVOKABLE void saveActiveLayer( QgsMapLayer *layer );

/**
* Returns the saved active layer for the current project
* or nullptr if active layer was not saved or isn't present
*/
Q_INVOKABLE QgsMapLayer *getSavedActiveLayer() const;

signals:

Expand All @@ -89,6 +111,7 @@ class ProjectInfo : public QObject
void saveRotation();
void saveTemporalState();

QSettings mSettings;
QString mFilePath;

QgsQuickMapSettings *mMapSettings = nullptr;
Expand Down
29 changes: 21 additions & 8 deletions src/qml/DashBoard.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Drawer {
signal showCloudMenu

property alias allowLayerChange: legend.enabled
property alias currentLayer: legend.currentLayer
property alias activeLayer: legend.activeLayer
property alias layerTree: legend.model
property MapSettings mapSettings

Expand All @@ -41,9 +41,21 @@ Drawer {
onShowMenu: mainMenu.popup(settingsButton.x + 2, mainWindow.sceneTopMargin + settingsButton.y + 2)
onShowCloudMenu: cloudPopup.show()

onCurrentLayerChanged: {
if ( currentLayer && currentLayer.readOnly && stateMachine.state == "digitize" )
displayToast( qsTr( "The layer %1 is read only." ).arg( currentLayer.name ) )
onActiveLayerChanged: {
if (activeLayer && activeLayer.readOnly && stateMachine.state == "digitize")
displayToast(qsTr("The layer %1 is read only.").arg(activeLayer.name))
}

Connections {
target: stateMachine

function onStateChanged() {
if (stateMachine.state === "measure") {
return
}

modeSwitch.checked = stateMachine.state === "digitize"
}
}

ColumnLayout {
Expand Down Expand Up @@ -146,7 +158,7 @@ Drawer {


Switch {
id: modeswitch
id: modeSwitch
visible: projectInfo.insertRights
height: 56
width: ( 56 + 36 )
Expand All @@ -155,7 +167,7 @@ Drawer {
indicator: Rectangle {
implicitHeight: 36
implicitWidth: 36 * 2
x: modeswitch.leftPadding
x: modeSwitch.leftPadding
radius: 4
color: "#66212121"
border.color: "#44FFFFFF"
Expand Down Expand Up @@ -183,7 +195,7 @@ Drawer {
opacity: 0.4
}
Rectangle {
x: modeswitch.checked ? parent.width - width : 0
x: modeSwitch.checked ? parent.width - width : 0
width: 36
height: 36
radius: 4
Expand All @@ -193,7 +205,7 @@ Drawer {
width: 28
height: 28
anchors.centerIn: parent
source: modeswitch.checked ? Theme.getThemeVectorIcon( 'ic_create_white_24dp' ) : Theme.getThemeVectorIcon( 'ic_map_white_24dp' )
source: modeSwitch.checked ? Theme.getThemeVectorIcon( 'ic_create_white_24dp' ) : Theme.getThemeVectorIcon( 'ic_map_white_24dp' )
sourceSize.width: parent.height * screen.devicePixelRatio
sourceSize.height: parent.width * screen.devicePixelRatio
}
Expand All @@ -205,6 +217,7 @@ Drawer {
}
}
}

onPositionChanged: {
if ( checked ) {
changeMode( "digitize" )
Expand Down
9 changes: 5 additions & 4 deletions src/qml/Legend.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ ListView {
id: legend

property bool isVisible: false
property VectorLayer currentLayer
property VectorLayer activeLayer

model: flatLayerTree
flickableDirection: Flickable.VerticalFlick
Expand All @@ -28,7 +28,7 @@ ListView {
property int itemPadding: 5 + ( 5 + 24 ) * TreeLevel
property string itemType: Type
property string layerType: LayerType
property bool isSelectedLayer: ( itemType === "layer" && vectorLayer != null && vectorLayer == currentLayer )
property bool isSelectedLayer: ( itemType === "layer" && vectorLayer != null && vectorLayer == activeLayer )
property bool isPressed: false

id: rectangle
Expand Down Expand Up @@ -141,7 +141,7 @@ ListView {
text: Name
horizontalAlignment: Text.AlignLeft
font.pointSize: Theme.tipFont.pointSize
font.bold: itemType === "group" || (itemType === "layer" && vectorLayer != null && vectorLayer == currentLayer) ? true : false
font.bold: itemType === "group" || (itemType === "layer" && vectorLayer != null && vectorLayer == activeLayer) ? true : false
color: {
if ( isSelectedLayer )
return Theme.light;
Expand Down Expand Up @@ -233,7 +233,8 @@ ListView {

if (item) {
if (item.vectorLayer && item.vectorLayer.isValid) {
currentLayer = item.vectorLayer
activeLayer = item.vectorLayer
projectInfo.saveActiveLayer(activeLayer)
}
}
}
Expand Down
Loading
Loading