Skip to content

Commit

Permalink
[feature][layout] Add ""Convert to Static Text" option to dropdown
Browse files Browse the repository at this point in the history
menu next to "Insert/Edit Expression…" in layout label properties
widget

When selected any dynamic parts of the label's contents will be
evaluated and replaced with their current values.

Provides an easy way to convert a dynamic label to a static one,
so that the user can then manually tweak the resulting tweak
when needed.
  • Loading branch information
nyalldawson committed May 13, 2021
1 parent e3cb3e5 commit 5e98648
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 1 deletion.
8 changes: 8 additions & 0 deletions python/core/auto_generated/layout/qgslayoutitemlabel.sip.in
Expand Up @@ -232,6 +232,14 @@ Returns the label font color.
virtual void refresh(); virtual void refresh();




void convertToStaticText();
%Docstring
Converts the label's :py:func:`~QgsLayoutItemLabel.text` to a static string, by evaluating any expressions included in the text
and replacing them with their current values.

.. versionadded:: 3.20
%End

protected: protected:
virtual void draw( QgsLayoutItemRenderContext &context ); virtual void draw( QgsLayoutItemRenderContext &context );


Expand Down
9 changes: 9 additions & 0 deletions src/core/layout/qgslayoutitemlabel.cpp
Expand Up @@ -516,6 +516,15 @@ void QgsLayoutItemLabel::refresh()
refreshExpressionContext(); refreshExpressionContext();
} }


void QgsLayoutItemLabel::convertToStaticText()
{
const QString evaluated = currentText();
if ( evaluated == mText )
return; // no changes

setText( evaluated );
}

void QgsLayoutItemLabel::itemShiftAdjustSize( double newWidth, double newHeight, double &xShift, double &yShift ) const void QgsLayoutItemLabel::itemShiftAdjustSize( double newWidth, double newHeight, double &xShift, double &yShift ) const
{ {
//keep alignment point constant //keep alignment point constant
Expand Down
8 changes: 8 additions & 0 deletions src/core/layout/qgslayoutitemlabel.h
Expand Up @@ -218,6 +218,14 @@ class CORE_EXPORT QgsLayoutItemLabel: public QgsLayoutItem


void refresh() override; void refresh() override;


/**
* Converts the label's text() to a static string, by evaluating any expressions included in the text
* and replacing them with their current values.
*
* \since QGIS 3.20
*/
void convertToStaticText();

protected: protected:
void draw( QgsLayoutItemRenderContext &context ) override; void draw( QgsLayoutItemRenderContext &context ) override;
bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override; bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override;
Expand Down
5 changes: 5 additions & 0 deletions src/gui/layout/qgslayoutlabelwidget.cpp
Expand Up @@ -88,6 +88,11 @@ QgsLayoutLabelWidget::QgsLayoutLabelWidget( QgsLayoutItemLabel *label )
} }
} ); } );


QMenu *expressionMenu = new QMenu( this );
QAction *convertToStaticAction = new QAction( tr( "Convert to Static Text" ), this );
expressionMenu->addAction( convertToStaticAction );
connect( convertToStaticAction, &QAction::triggered, mLabel, &QgsLayoutItemLabel::convertToStaticText );
mInsertExpressionButton->setMenu( expressionMenu );
} }


void QgsLayoutLabelWidget::setMasterLayout( QgsMasterLayoutInterface *masterLayout ) void QgsLayoutLabelWidget::setMasterLayout( QgsMasterLayoutInterface *masterLayout )
Expand Down
11 changes: 10 additions & 1 deletion src/ui/layout/qgslayoutlabelwidgetbase.ui
Expand Up @@ -62,7 +62,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>358</width> <width>358</width>
<height>682</height> <height>680</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="mainLayout"> <layout class="QVBoxLayout" name="mainLayout">
Expand Down Expand Up @@ -111,6 +111,15 @@
<property name="text"> <property name="text">
<string>Insert/Edit Expression…</string> <string>Insert/Edit Expression…</string>
</property> </property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextOnly</enum>
</property>
<property name="arrowType">
<enum>Qt::DownArrow</enum>
</property>
</widget> </widget>
</item> </item>
<item row="1" column="0" colspan="2"> <item row="1" column="0" colspan="2">
Expand Down
28 changes: 28 additions & 0 deletions tests/src/python/test_qgslayoutlabel.py
Expand Up @@ -22,6 +22,7 @@
QgsLayoutItemPage, QgsLayoutItemPage,
QgsLayoutPoint) QgsLayoutPoint)
from utilities import unitTestDataPath from utilities import unitTestDataPath
from qgis.PyQt.QtTest import QSignalSpy


from test_qgslayoutitem import LayoutItemTestCase from test_qgslayoutitem import LayoutItemTestCase


Expand Down Expand Up @@ -95,6 +96,33 @@ def page_evaluation_test(self, layout, label, mVectorLayer):
label.attemptMove(QgsLayoutPoint(0, 320)) label.attemptMove(QgsLayoutPoint(0, 320))
self.assertEqual(label.currentText(), "2/2") self.assertEqual(label.currentText(), "2/2")


def test_convert_to_static(self):
layout = QgsPrintLayout(QgsProject.instance())
layout.initializeDefaults()

label = QgsLayoutItemLabel(layout)
layout.addLayoutItem(label)
layout.setName('my layout')

# no text yet
label.convertToStaticText()
self.assertFalse(label.text())

spy = QSignalSpy(label.changed)
label.setText('already static text')
self.assertEqual(len(spy), 1)
label.convertToStaticText()
self.assertEqual(label.text(), 'already static text')
self.assertEqual(len(spy), 1)

label.setText('with [% 1+2+3 %] some [% @layout_name %] dynamic bits')
self.assertEqual(len(spy), 2)
self.assertEqual(label.text(), 'with [% 1+2+3 %] some [% @layout_name %] dynamic bits')

label.convertToStaticText()
self.assertEqual(label.text(), 'with 6 some my layout dynamic bits')
self.assertEqual(len(spy), 3)



if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

0 comments on commit 5e98648

Please sign in to comment.