Skip to content

Commit

Permalink
Merge pull request #5577 from opengisch/project-variables
Browse files Browse the repository at this point in the history
Project variables
  • Loading branch information
nirvn authored Aug 25, 2024
2 parents 7fbc4eb + facb371 commit 9eb5430
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 32 deletions.
86 changes: 67 additions & 19 deletions src/core/expressionvariablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
***************************************************************************/

#include "expressionvariablemodel.h"
#include "utils/expressioncontextutils.h"

#include <QDebug>
#include <QSettings>
Expand All @@ -34,19 +35,42 @@ bool ExpressionVariableModel::setData( const QModelIndex &index, const QVariant
return QStandardItemModel::setData( index, value, role );
}

void ExpressionVariableModel::addCustomVariable( const QString &varName, const QString &varVal )
int ExpressionVariableModel::addVariable( VariableScope scope, const QString &name, const QString &value )
{
QStandardItem *nameItem = new QStandardItem( varName );
nameItem->setData( varName, VariableName );
nameItem->setData( varVal, VariableValue );
nameItem->setEditable( true );
int lastVariableInScope = rowCount();
for ( int i = 0; i < rowCount(); ++i )
{
if ( item( i )->data( VariableScopeRole ).value<VariableScope>() == scope )
{
lastVariableInScope = i;
}
}

QStandardItem *nameItem = new QStandardItem( name );
nameItem->setData( name, VariableName );
nameItem->setData( value, VariableValue );
nameItem->setData( QVariant::fromValue( scope ), VariableScopeRole );
nameItem->setData( scope == VariableScope::ApplicationScope, VariableEditable );

insertRow( lastVariableInScope + 1, QList<QStandardItem *>() << nameItem );

insertRow( rowCount(), QList<QStandardItem *>() << nameItem );
return lastVariableInScope + 1;
}

void ExpressionVariableModel::removeCustomVariable( int row )
void ExpressionVariableModel::removeVariable( VariableScope scope, const QString &name )
{
removeRow( row );
for ( int i = 0; i < rowCount(); ++i )
{
QStandardItem *rowItem = item( i );
QString variableName = rowItem->data( VariableName ).toString();
VariableScope variableScope = rowItem->data( VariableScopeRole ).value<VariableScope>();

if ( variableName == name && variableScope == scope )
{
removeRow( i );
return;
}
}
}

void ExpressionVariableModel::save()
Expand All @@ -72,7 +96,7 @@ void ExpressionVariableModel::reloadVariables()
QStringList variableNames = scope->variableNames();
variableNames.sort();

// First add readonly variables
// First add readonly app variables
for ( const QString &varName : variableNames )
{
if ( scope->isReadOnly( varName ) )
Expand All @@ -84,28 +108,36 @@ void ExpressionVariableModel::reloadVariables()

nameItem->setData( varName, VariableName );
nameItem->setData( varValue, VariableValue );
nameItem->setData( QVariant::fromValue( VariableScope::ApplicationScope ), VariableScopeRole );
nameItem->setData( false, VariableEditable );
nameItem->setEditable( false );

insertRow( rowCount(), QList<QStandardItem *>() << nameItem );
}
}

// Then add custom variables
// Second add custom variables
for ( const QString &varName : variableNames )
{
if ( !scope->isReadOnly( varName ) )
{
addCustomVariable( varName, scope->variable( varName ).toString() );
addVariable( VariableScope::ApplicationScope, varName, scope->variable( varName ).toString() );
}
}
}
// Finally add readonly project variables
QVariantMap projectVariables = ExpressionContextUtils::projectVariables( mCurrentProject );
for ( const QString &varName : projectVariables.keys() )
{
QStandardItem *nameItem = new QStandardItem( varName );
QVariant varValue = projectVariables.value( varName ).toString();

bool ExpressionVariableModel::isEditable( int row )
{
QStandardItem *rowItem = item( row );
if ( rowItem )
return rowItem->isEditable();
return false;
nameItem->setData( varName, VariableName );
nameItem->setData( varValue, VariableValue );
nameItem->setData( QVariant::fromValue( VariableScope::ProjectScope ), VariableScopeRole );
nameItem->setData( false, VariableEditable );
nameItem->setEditable( false );

insertRow( rowCount(), QList<QStandardItem *>() << nameItem );
}
}

void ExpressionVariableModel::setName( int row, const QString &name )
Expand Down Expand Up @@ -139,6 +171,8 @@ QHash<int, QByteArray> ExpressionVariableModel::roleNames() const
QHash<int, QByteArray> names = QStandardItemModel::roleNames();
names[VariableName] = "VariableName";
names[VariableValue] = "VariableValue";
names[VariableScopeRole] = "VariableScope";
names[VariableEditable] = "VariableEditable";
return names;
}

Expand All @@ -147,3 +181,17 @@ void ExpressionVariableModel::onDataChanged( const QModelIndex &topLeft, const Q
Q_UNUSED( bottomRight )
Q_UNUSED( roles )
}

QgsProject *ExpressionVariableModel::currentProject() const
{
return mCurrentProject;
}

void ExpressionVariableModel::setCurrentProject( QgsProject *project )
{
if ( mCurrentProject == project )
return;
mCurrentProject = project;
reloadVariables();
emit currentProjectChanged();
}
35 changes: 30 additions & 5 deletions src/core/expressionvariablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,65 @@
#define EXPRESSIONVARIABLEMODEL_H

#include <QStandardItemModel>
#include <qgsproject.h>

class ExpressionVariableModel : public QStandardItemModel
{
Q_OBJECT

Q_PROPERTY( QgsProject *currentProject READ currentProject WRITE setCurrentProject NOTIFY currentProjectChanged )

public:
enum Roles
{
VariableName = Qt::UserRole,
VariableValue
VariableValue,
VariableScopeRole,
VariableEditable = Qt::EditRole
};

enum class VariableScope
{
ApplicationScope,
ProjectScope
};

explicit ExpressionVariableModel( QObject *parent = nullptr );

bool setData( const QModelIndex &index, const QVariant &value, int role ) override;

Q_INVOKABLE void addCustomVariable( const QString &varName, const QString &varVal );
Q_INVOKABLE int addVariable( VariableScope scope, const QString &name, const QString &value );

Q_INVOKABLE void removeCustomVariable( int row );
Q_INVOKABLE void removeVariable( VariableScope scope, const QString &name );

Q_INVOKABLE void save();

Q_INVOKABLE void reloadVariables();

Q_INVOKABLE bool isEditable( int row );

Q_INVOKABLE void setName( int row, const QString &name );

Q_INVOKABLE void setValue( int row, const QString &value );

QHash<int, QByteArray> roleNames() const override;

/**
* Returns the current project used to retrieve variables from.
*/
QgsProject *currentProject() const;

/**
* Sets the project used to retrieve variables from.
*/
void setCurrentProject( QgsProject *project );

signals:
void currentProjectChanged();

private slots:
void onDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles );

private:
QgsProject *mCurrentProject = nullptr;
};

#endif // EXPRESSIONVARIABLEMODEL_H
4 changes: 4 additions & 0 deletions src/qml/QFieldSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ Page {
}
}

function reset() {
variableEditor.reset();
}

Settings {
id: registry
property bool showScaleBar: true
Expand Down
21 changes: 13 additions & 8 deletions src/qml/VariableEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ColumnLayout {
ListView {
id: table
model: ExpressionVariableModel {
currentProject: qgisProject
}
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
Expand All @@ -45,7 +46,11 @@ ColumnLayout {
color: "transparent"

property var itemRow: index
property bool canDelete: table.model.isEditable(index)
property bool canDelete: VariableEditable

function forceFocusOnVariableName() {
variableNameText.forceActiveFocus();
}

Row {
id: line
Expand All @@ -67,7 +72,7 @@ ColumnLayout {
leftPadding: 1
rightPadding: 1
text: VariableName
enabled: table.model.isEditable(index)
enabled: VariableEditable
font: Theme.tipFont
horizontalAlignment: TextInput.AlignLeft
placeholderText: displayText === '' ? qsTr("Enter name") : ''
Expand Down Expand Up @@ -104,7 +109,7 @@ ColumnLayout {
leftPadding: 1
rightPadding: 1
text: VariableValue
enabled: table.model.isEditable(index)
enabled: VariableEditable
font: Theme.tipFont
horizontalAlignment: TextInput.AlignLeft
placeholderText: displayText === '' ? qsTr("Enter value") : ''
Expand Down Expand Up @@ -137,7 +142,7 @@ ColumnLayout {
bgcolor: "transparent"

onClicked: {
table.model.removeCustomVariable(index);
table.model.removeVariable(VariableScope, variableNameText.text);
}
}
}
Expand All @@ -151,10 +156,10 @@ ColumnLayout {
text: qsTr("Add a new variable")

onClicked: {
table.model.addCustomVariable("new_variable", "");
table.positionViewAtIndex(table.count - 1, ListView.visible);
// TODO: Use Qt 5.13 itemAtIndex( index )
table.children[0].children[table.count].children[0].children[0].forceActiveFocus();
let applicationScope = 0;
let insertionPosition = table.model.addVariable(applicationScope, "new_variable", "");
table.positionViewAtIndex(insertionPosition, ListView.Contain);
table.itemAtIndex(insertionPosition).forceFocusOnVariableName();
}
}
}
1 change: 1 addition & 0 deletions src/qml/qgismobileapp.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2333,6 +2333,7 @@ ApplicationWindow {

onTriggered: {
dashBoard.close();
qfieldSettings.reset();
qfieldSettings.visible = true;
highlighted = false;
}
Expand Down

1 comment on commit 9eb5430

@qfield-fairy
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.