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

Project variables #5577

Merged
merged 8 commits into from
Aug 25, 2024
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
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 )
mohsenD98 marked this conversation as resolved.
Show resolved Hide resolved
mohsenD98 marked this conversation as resolved.
Show resolved Hide resolved
{
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 );
nirvn marked this conversation as resolved.
Show resolved Hide resolved
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
Loading