Skip to content

Commit

Permalink
Fix a TODO, restore correct variable handling for layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jan 8, 2018
1 parent 886e7bf commit 2b8143a
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 6 deletions.
30 changes: 30 additions & 0 deletions python/core/qgsexpressioncontext.sip
Expand Up @@ -1026,9 +1026,39 @@ For instance, current page name and number.
Creates a new scope which contains variables and functions relating to a :py:class:`QgsLayoutItem`.
For instance, item size and position.

.. versionadded:: 3.0

.. seealso:: :py:func:`setLayoutItemVariable()`

.. seealso:: :py:func:`setLayoutItemVariables()`
%End

static void setLayoutItemVariable( QgsLayoutItem *item, const QString &name, const QVariant &value );
%Docstring
Sets a layout ``item`` context variable, with the given ``name`` and ``value``.
This variable will be contained within scopes retrieved via
layoutItemScope().

.. seealso:: :py:func:`setLayoutItemVariables()`

.. seealso:: :py:func:`layoutItemScope()`

.. versionadded:: 3.0
%End

static void setLayoutItemVariables( QgsLayoutItem *item, const QVariantMap &variables );
%Docstring
Sets all layout item context variables for an ``item``. Existing variables will be removed and replaced
with the ``variables`` specified.

.. seealso:: :py:func:`setLayoutItemVariable()`

.. seealso:: :py:func:`layoutItemScope()`

.. versionadded:: 3.0
%End



static QgsExpressionContext createFeatureBasedContext( const QgsFeature &feature, const QgsFields &fields );
%Docstring
Expand Down
22 changes: 22 additions & 0 deletions src/app/layout/qgslayoutpropertieswidget.cpp
Expand Up @@ -84,6 +84,13 @@ QgsLayoutPropertiesWidget::QgsLayoutPropertiesWidget( QWidget *parent, QgsLayout
mReferenceMapComboBox->setCurrentLayout( mLayout );

connect( mLayout, &QgsLayout::changed, this, &QgsLayoutPropertiesWidget::updateGui );

updateVariables();
connect( mVariableEditor, &QgsVariableEditorWidget::scopeChanged, this, &QgsLayoutPropertiesWidget::variablesChanged );
// listen out for variable edits
connect( QgsApplication::instance(), &QgsApplication::customVariablesChanged, this, &QgsLayoutPropertiesWidget::updateVariables );
connect( QgsProject::instance(), &QgsProject::customVariablesChanged, this, &QgsLayoutPropertiesWidget::updateVariables );

updateGui();
}

Expand Down Expand Up @@ -228,6 +235,21 @@ void QgsLayoutPropertiesWidget::forceVectorToggled()
mLayout->setCustomProperty( QStringLiteral( "forceVector" ), mForceVectorCheckBox->isChecked() );
}

void QgsLayoutPropertiesWidget::variablesChanged()
{
QgsExpressionContextUtils::setLayoutVariables( mLayout, mVariableEditor->variablesInActiveScope() );
}

void QgsLayoutPropertiesWidget::updateVariables()
{
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::layoutScope( mLayout );
mVariableEditor->setContext( &context );
mVariableEditor->setEditableScopeIndex( 2 );
}

void QgsLayoutPropertiesWidget::blockSignals( bool block )
{
mGridResolutionSpinBox->blockSignals( block );
Expand Down
2 changes: 2 additions & 0 deletions src/app/layout/qgslayoutpropertieswidget.h
Expand Up @@ -48,6 +48,8 @@ class QgsLayoutPropertiesWidget: public QgsPanelWidget, private Ui::QgsLayoutWid
void worldFileToggled();
void rasterizeToggled();
void forceVectorToggled();
void variablesChanged();
void updateVariables();

private:

Expand Down
35 changes: 35 additions & 0 deletions src/core/qgsexpressioncontext.cpp
Expand Up @@ -1339,6 +1339,41 @@ QgsExpressionContextScope *QgsExpressionContextUtils::layoutItemScope( const Qgs
return scope;
}

void QgsExpressionContextUtils::setLayoutItemVariable( QgsLayoutItem *item, const QString &name, const QVariant &value )
{
if ( !item )
return;

//write variable to composer item
QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();

variableNames << name;
variableValues << value.toString();

item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
}

void QgsExpressionContextUtils::setLayoutItemVariables( QgsLayoutItem *item, const QVariantMap &variables )
{
if ( !item )
return;

QStringList variableNames;
QStringList variableValues;

QVariantMap::const_iterator it = variables.constBegin();
for ( ; it != variables.constEnd(); ++it )
{
variableNames << it.key();
variableValues << it.value().toString();
}

item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
}

void QgsExpressionContextUtils::setComposerItemVariable( QgsComposerItem *composerItem, const QString &name, const QVariant &value )
{
if ( !composerItem )
Expand Down
22 changes: 22 additions & 0 deletions src/core/qgsexpressioncontext.h
Expand Up @@ -959,9 +959,31 @@ class CORE_EXPORT QgsExpressionContextUtils
* Creates a new scope which contains variables and functions relating to a QgsLayoutItem.
* For instance, item size and position.
* \since QGIS 3.0
* \see setLayoutItemVariable()
* \see setLayoutItemVariables()
*/
static QgsExpressionContextScope *layoutItemScope( const QgsLayoutItem *item ) SIP_FACTORY;

/**
* Sets a layout \a item context variable, with the given \a name and \a value.
* This variable will be contained within scopes retrieved via
* layoutItemScope().
* \see setLayoutItemVariables()
* \see layoutItemScope()
* \since QGIS 3.0
*/
static void setLayoutItemVariable( QgsLayoutItem *item, const QString &name, const QVariant &value );

/**
* Sets all layout item context variables for an \a item. Existing variables will be removed and replaced
* with the \a variables specified.
* \see setLayoutItemVariable()
* \see layoutItemScope()
* \since QGIS 3.0
*/
static void setLayoutItemVariables( QgsLayoutItem *item, const QVariantMap &variables );


#ifndef SIP_RUN

/**
Expand Down
4 changes: 1 addition & 3 deletions src/gui/layout/qgslayoutitemwidget.cpp
Expand Up @@ -356,9 +356,7 @@ void QgsLayoutItemPropertiesWidget::changeItemSize()

void QgsLayoutItemPropertiesWidget::variablesChanged()
{
#if 0 //TODO
QgsExpressionContextUtils::setComposerItemVariables( mItem, mVariableEditor->variablesInActiveScope() );
#endif
QgsExpressionContextUtils::setLayoutItemVariables( mItem, mVariableEditor->variablesInActiveScope() );
}

QgsLayoutItem::ReferencePoint QgsLayoutItemPropertiesWidget::positionMode() const
Expand Down
37 changes: 34 additions & 3 deletions src/ui/layout/qgslayoutwidgetbase.ui
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>311</width>
<height>494</height>
<height>357</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -53,9 +53,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-316</y>
<y>-627</y>
<width>297</width>
<height>810</height>
<height>1063</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
Expand Down Expand Up @@ -392,6 +392,25 @@
</layout>
</widget>
</item>
<item>
<widget class="QgsCollapsibleGroupBox" name="groupBox_2">
<property name="title">
<string>Variables</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QgsVariableEditorWidget" name="mVariableEditor" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
Expand All @@ -413,6 +432,12 @@
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>QgsCollapsibleGroupBox</class>
<extends>QGroupBox</extends>
<header>qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsScrollArea</class>
<extends>QScrollArea</extends>
Expand Down Expand Up @@ -445,6 +470,12 @@
<extends>QComboBox</extends>
<header>qgslayoutitemcombobox.h</header>
</customwidget>
<customwidget>
<class>QgsVariableEditorWidget</class>
<extends>QWidget</extends>
<header location="global">qgsvariableeditorwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>scrollArea</tabstop>
Expand Down
23 changes: 23 additions & 0 deletions tests/src/core/testqgslayoutitem.cpp
Expand Up @@ -169,6 +169,7 @@ class TestQgsLayoutItem: public QObject
void setSceneRect();
void page();
void itemVariablesFunction();
void variables();

private:

Expand Down Expand Up @@ -1422,6 +1423,28 @@ void TestQgsLayoutItem::itemVariablesFunction()
QCOMPARE( r.toString(), QString( "degrees" ) );
}

void TestQgsLayoutItem::variables()
{
QgsLayout l( QgsProject::instance() );

QgsLayoutItemMap *map = new QgsLayoutItemMap( &l );
std::unique_ptr< QgsExpressionContextScope > scope( QgsExpressionContextUtils::layoutItemScope( map ) );
int before = scope->variableCount();

QgsExpressionContextUtils::setLayoutItemVariable( map, QStringLiteral( "var" ), 5 );
scope.reset( QgsExpressionContextUtils::layoutItemScope( map ) );
QCOMPARE( scope->variableCount(), before + 1 );
QCOMPARE( scope->variable( QStringLiteral( "var" ) ).toInt(), 5 );

QVariantMap vars;
vars.insert( QStringLiteral( "var2" ), 7 );
QgsExpressionContextUtils::setLayoutItemVariables( map, vars );
scope.reset( QgsExpressionContextUtils::layoutItemScope( map ) );
QCOMPARE( scope->variableCount(), before + 1 );
QVERIFY( !scope->hasVariable( QStringLiteral( "var" ) ) );
QCOMPARE( scope->variable( QStringLiteral( "var2" ) ).toInt(), 7 );
}

void TestQgsLayoutItem::rotation()
{
QgsProject proj;
Expand Down

0 comments on commit 2b8143a

Please sign in to comment.