diff --git a/src/core/expressionvariablemodel.cpp b/src/core/expressionvariablemodel.cpp index 7eef0263bf..450b78ba61 100644 --- a/src/core/expressionvariablemodel.cpp +++ b/src/core/expressionvariablemodel.cpp @@ -15,6 +15,7 @@ ***************************************************************************/ #include "expressionvariablemodel.h" +#include "utils/expressioncontextutils.h" #include #include @@ -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() == 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() << nameItem ); - insertRow( rowCount(), QList() << 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(); + + if ( variableName == name && variableScope == scope ) + { + removeRow( i ); + return; + } + } } void ExpressionVariableModel::save() @@ -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 ) ) @@ -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() << 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() << nameItem ); + } } void ExpressionVariableModel::setName( int row, const QString &name ) @@ -139,6 +171,8 @@ QHash ExpressionVariableModel::roleNames() const QHash names = QStandardItemModel::roleNames(); names[VariableName] = "VariableName"; names[VariableValue] = "VariableValue"; + names[VariableScopeRole] = "VariableScope"; + names[VariableEditable] = "VariableEditable"; return names; } @@ -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(); +} diff --git a/src/core/expressionvariablemodel.h b/src/core/expressionvariablemodel.h index 615538daae..6fc4b52b9b 100644 --- a/src/core/expressionvariablemodel.h +++ b/src/core/expressionvariablemodel.h @@ -17,40 +17,65 @@ #define EXPRESSIONVARIABLEMODEL_H #include +#include 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 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 &roles ); + + private: + QgsProject *mCurrentProject = nullptr; }; #endif // EXPRESSIONVARIABLEMODEL_H diff --git a/src/qml/QFieldSettings.qml b/src/qml/QFieldSettings.qml index cecdb2aa61..a72e43e2b3 100644 --- a/src/qml/QFieldSettings.qml +++ b/src/qml/QFieldSettings.qml @@ -31,6 +31,10 @@ Page { } } + function reset() { + variableEditor.reset(); + } + Settings { id: registry property bool showScaleBar: true diff --git a/src/qml/VariableEditor.qml b/src/qml/VariableEditor.qml index fdaab91d18..f4f78ac55b 100644 --- a/src/qml/VariableEditor.qml +++ b/src/qml/VariableEditor.qml @@ -29,6 +29,7 @@ ColumnLayout { ListView { id: table model: ExpressionVariableModel { + currentProject: qgisProject } flickableDirection: Flickable.VerticalFlick boundsBehavior: Flickable.StopAtBounds @@ -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 @@ -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") : '' @@ -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") : '' @@ -137,7 +142,7 @@ ColumnLayout { bgcolor: "transparent" onClicked: { - table.model.removeCustomVariable(index); + table.model.removeVariable(VariableScope, variableNameText.text); } } } @@ -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(); } } } diff --git a/src/qml/qgismobileapp.qml b/src/qml/qgismobileapp.qml index 600aee5525..2b05c18870 100644 --- a/src/qml/qgismobileapp.qml +++ b/src/qml/qgismobileapp.qml @@ -2333,6 +2333,7 @@ ApplicationWindow { onTriggered: { dashBoard.close(); + qfieldSettings.reset(); qfieldSettings.visible = true; highlighted = false; }