Skip to content

Commit 7ed4218

Browse files
committed
[needs-docs] Upgrade project level setting for Label as Outlines/text setting to use newer API
And replace labeling engine dialog "Draw text as outlines" checkbox with a combobox presenting the choice of always rendering as outlines OR text. (This will allow us to easily add additional methods in future, e.g. potentially a "Render as text wherever possible" setting, for defaulting to text objects whenever it doesn't impact the rendering quality to do so)
1 parent 12b3e15 commit 7ed4218

10 files changed

+196
-35
lines changed

python/core/auto_generated/qgslabelingenginesettings.sip.in

+20-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99

1010

11-
1211
class QgsLabelingEngineSettings
1312
{
1413
%Docstring
@@ -25,6 +24,7 @@ Stores global configuration for labeling engine
2524
{
2625
UseAllLabels,
2726
UsePartialCandidates,
27+
// TODO QGIS 4.0: remove
2828
RenderOutlineLabels,
2929
DrawLabelRectOnly,
3030
DrawCandidates,
@@ -92,6 +92,25 @@ Read configuration of the labeling engine from a project
9292
Write configuration of the labeling engine to a project
9393
%End
9494

95+
96+
QgsRenderContext::TextRenderFormat defaultTextRenderFormat() const;
97+
%Docstring
98+
Returns the default text rendering format for the labels.
99+
100+
.. seealso:: :py:func:`setDefaultTextRenderFormat`
101+
102+
.. versionadded:: 3.4.3
103+
%End
104+
105+
void setDefaultTextRenderFormat( QgsRenderContext::TextRenderFormat format );
106+
%Docstring
107+
Sets the default text rendering ``format`` for the labels.
108+
109+
.. seealso:: :py:func:`defaultTextRenderFormat`
110+
111+
.. versionadded:: 3.4.3
112+
%End
113+
95114
};
96115

97116
QFlags<QgsLabelingEngineSettings::Flag> operator|(QgsLabelingEngineSettings::Flag f1, QFlags<QgsLabelingEngineSettings::Flag> f2);

python/core/auto_generated/qgsmapsettings.sip.in

+17-2
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,11 @@ Returns the text render format, which dictates how text is rendered (e.g. as pat
296296
%Docstring
297297
Sets the text render ``format``, which dictates how text is rendered (e.g. as paths or real text objects).
298298

299+
.. warning::
300+
301+
Calling the setLabelingEngineSettings() method will reset the text render format to match the default
302+
text render format from the label engine settings.
303+
299304
.. seealso:: :py:func:`textRenderFormat`
300305

301306
.. versionadded:: 3.4.3
@@ -504,14 +509,24 @@ Gets segmentation tolerance type (maximum angle or maximum difference between cu
504509

505510
void setLabelingEngineSettings( const QgsLabelingEngineSettings &settings );
506511
%Docstring
507-
Sets global configuration of the labeling engine
512+
Sets the global configuration of the labeling engine.
513+
514+
.. note::
515+
516+
Calling this method will reset the textRenderFormat() to match the default
517+
text render format from the label engine ``settings``.
518+
519+
.. seealso:: :py:func:`labelingEngineSettings`
520+
508521

509522
.. versionadded:: 3.0
510523
%End
511524

512525
const QgsLabelingEngineSettings &labelingEngineSettings() const;
513526
%Docstring
514-
Returns global configuration of the labeling engine
527+
Returns the global configuration of the labeling engine.
528+
529+
.. seealso:: :py:func:`setLabelingEngineSettings`
515530

516531
.. versionadded:: 3.0
517532
%End

src/app/qgslabelengineconfigdialog.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ QgsLabelEngineConfigDialog::QgsLabelEngineConfigDialog( QWidget *parent )
3636
// search method
3737
cboSearchMethod->setCurrentIndex( engineSettings.searchMethod() );
3838

39+
mTextRenderFormatComboBox->addItem( tr( "Always Render Labels as Paths (Recommended)" ), QgsRenderContext::TextFormatAlwaysOutlines );
40+
mTextRenderFormatComboBox->addItem( tr( "Always Render Labels as Text" ), QgsRenderContext::TextFormatAlwaysText );
41+
3942
// candidate numbers
4043
int candPoint, candLine, candPolygon;
4144
engineSettings.numCandidatePositions( candPoint, candLine, candPolygon );
@@ -47,9 +50,9 @@ QgsLabelEngineConfigDialog::QgsLabelEngineConfigDialog( QWidget *parent )
4750
chkShowAllLabels->setChecked( engineSettings.testFlag( QgsLabelingEngineSettings::UseAllLabels ) );
4851

4952
chkShowPartialsLabels->setChecked( engineSettings.testFlag( QgsLabelingEngineSettings::UsePartialCandidates ) );
50-
mDrawOutlinesChkBox->setChecked( engineSettings.testFlag( QgsLabelingEngineSettings::RenderOutlineLabels ) );
51-
}
5253

54+
mTextRenderFormatComboBox->setCurrentIndex( mTextRenderFormatComboBox->findData( engineSettings.defaultTextRenderFormat() ) );
55+
}
5356

5457
void QgsLabelEngineConfigDialog::onOK()
5558
{
@@ -63,7 +66,8 @@ void QgsLabelEngineConfigDialog::onOK()
6366
engineSettings.setFlag( QgsLabelingEngineSettings::DrawCandidates, chkShowCandidates->isChecked() );
6467
engineSettings.setFlag( QgsLabelingEngineSettings::UseAllLabels, chkShowAllLabels->isChecked() );
6568
engineSettings.setFlag( QgsLabelingEngineSettings::UsePartialCandidates, chkShowPartialsLabels->isChecked() );
66-
engineSettings.setFlag( QgsLabelingEngineSettings::RenderOutlineLabels, mDrawOutlinesChkBox->isChecked() );
69+
70+
engineSettings.setDefaultTextRenderFormat( static_cast< QgsRenderContext::TextRenderFormat >( mTextRenderFormatComboBox->currentData().toInt() ) );
6771

6872
QgsProject::instance()->setLabelingEngineSettings( engineSettings );
6973

@@ -80,7 +84,7 @@ void QgsLabelEngineConfigDialog::setDefaults()
8084
chkShowCandidates->setChecked( false );
8185
chkShowAllLabels->setChecked( false );
8286
chkShowPartialsLabels->setChecked( p.getShowPartial() );
83-
mDrawOutlinesChkBox->setChecked( true );
87+
mTextRenderFormatComboBox->setCurrentIndex( mTextRenderFormatComboBox->findData( QgsRenderContext::TextFormatAlwaysOutlines ) );
8488
}
8589

8690
void QgsLabelEngineConfigDialog::showHelp()

src/core/layout/qgslayoutitemmap.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,7 @@ QgsMapSettings QgsLayoutItemMap::mapSettings( const QgsRectangle &extent, QSizeF
11181118
jobMapSettings.setPathResolver( mLayout->project()->pathResolver() );
11191119

11201120
jobMapSettings.setLabelingEngineSettings( mLayout->project()->labelingEngineSettings() );
1121+
// override the default text render format inherited from the labeling engine settings using the layout's render context setting
11211122
jobMapSettings.setTextRenderFormat( mLayout->renderContext().textRenderFormat() );
11221123

11231124
return jobMapSettings;

src/core/qgslabelingenginesettings.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020

2121
QgsLabelingEngineSettings::QgsLabelingEngineSettings()
22-
: mFlags( RenderOutlineLabels | UsePartialCandidates )
22+
: mFlags( UsePartialCandidates )
2323
{
2424
}
2525

@@ -41,7 +41,15 @@ void QgsLabelingEngineSettings::readSettingsFromProject( QgsProject *prj )
4141
if ( prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawRectOnly" ), false, &saved ) ) mFlags |= DrawLabelRectOnly;
4242
if ( prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/ShowingAllLabels" ), false, &saved ) ) mFlags |= UseAllLabels;
4343
if ( prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/ShowingPartialsLabels" ), true, &saved ) ) mFlags |= UsePartialCandidates;
44-
if ( prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawOutlineLabels" ), true, &saved ) ) mFlags |= RenderOutlineLabels;
44+
45+
mDefaultTextRenderFormat = QgsRenderContext::TextFormatAlwaysOutlines;
46+
// if users have disabled the older PAL "DrawOutlineLabels" setting, respect that
47+
if ( !prj->readBoolEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawOutlineLabels" ), true ) )
48+
mDefaultTextRenderFormat = QgsRenderContext::TextFormatAlwaysText;
49+
// otherwise, prefer the new setting
50+
const int projectTextFormat = prj->readNumEntry( QStringLiteral( "PAL" ), QStringLiteral( "/TextFormat" ), -1 );
51+
if ( projectTextFormat >= 0 )
52+
mDefaultTextRenderFormat = static_cast< QgsRenderContext::TextRenderFormat >( projectTextFormat );
4553
}
4654

4755
void QgsLabelingEngineSettings::writeSettingsToProject( QgsProject *project )
@@ -55,5 +63,8 @@ void QgsLabelingEngineSettings::writeSettingsToProject( QgsProject *project )
5563
project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawRectOnly" ), mFlags.testFlag( DrawLabelRectOnly ) );
5664
project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/ShowingAllLabels" ), mFlags.testFlag( UseAllLabels ) );
5765
project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/ShowingPartialsLabels" ), mFlags.testFlag( UsePartialCandidates ) );
58-
project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawOutlineLabels" ), mFlags.testFlag( RenderOutlineLabels ) );
66+
67+
project->writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/TextFormat" ), static_cast< int >( mDefaultTextRenderFormat ) );
5968
}
69+
70+

src/core/qgslabelingenginesettings.h

+31-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#define QGSLABELINGENGINESETTINGS_H
1717

1818
#include "qgis_core.h"
19-
19+
#include "qgsrendercontext.h"
2020
#include <QFlags>
2121

2222
class QgsProject;
@@ -34,7 +34,8 @@ class CORE_EXPORT QgsLabelingEngineSettings
3434
{
3535
UseAllLabels = 1 << 1, //!< Whether to draw all labels even if there would be collisions
3636
UsePartialCandidates = 1 << 2, //!< Whether to use also label candidates that are partially outside of the map view
37-
RenderOutlineLabels = 1 << 3, //!< Whether to render labels as text or outlines
37+
// TODO QGIS 4.0: remove
38+
RenderOutlineLabels = 1 << 3, //!< Whether to render labels as text or outlines. Deprecated and of QGIS 3.4.3 - use defaultTextRenderFormat() instead.
3839
DrawLabelRectOnly = 1 << 4, //!< Whether to only draw the label rect and not the actual label text (used for unit tests)
3940
DrawCandidates = 1 << 5, //!< Whether to draw rectangles of generated candidates (good for debugging)
4041
};
@@ -82,6 +83,32 @@ class CORE_EXPORT QgsLabelingEngineSettings
8283
//! Write configuration of the labeling engine to a project
8384
void writeSettingsToProject( QgsProject *project );
8485

86+
// TODO QGIS 4.0: In reality the text render format settings don't only apply to labels, but also
87+
// ANY text rendered using QgsTextRenderer (including some non-label text items in layouts).
88+
// These methods should possibly be moved out of here and into the general QgsProject settings.
89+
90+
/**
91+
* Returns the default text rendering format for the labels.
92+
*
93+
* \see setDefaultTextRenderFormat()
94+
* \since QGIS 3.4.3
95+
*/
96+
QgsRenderContext::TextRenderFormat defaultTextRenderFormat() const
97+
{
98+
return mDefaultTextRenderFormat;
99+
}
100+
101+
/**
102+
* Sets the default text rendering \a format for the labels.
103+
*
104+
* \see defaultTextRenderFormat()
105+
* \since QGIS 3.4.3
106+
*/
107+
void setDefaultTextRenderFormat( QgsRenderContext::TextRenderFormat format )
108+
{
109+
mDefaultTextRenderFormat = format;
110+
}
111+
85112
private:
86113
//! Flags
87114
Flags mFlags;
@@ -90,6 +117,8 @@ class CORE_EXPORT QgsLabelingEngineSettings
90117
//! Number of candedate positions that will be generated for features
91118
int mCandPoint = 16, mCandLine = 50, mCandPolygon = 30;
92119

120+
QgsRenderContext::TextRenderFormat mDefaultTextRenderFormat = QgsRenderContext::TextFormatAlwaysOutlines;
121+
93122
};
94123

95124
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsLabelingEngineSettings::Flags )

src/core/qgsmapsettings.h

+22-3
Original file line numberDiff line numberDiff line change
@@ -267,12 +267,18 @@ class CORE_EXPORT QgsMapSettings
267267
/**
268268
* Sets the text render \a format, which dictates how text is rendered (e.g. as paths or real text objects).
269269
*
270+
* \warning Calling the setLabelingEngineSettings() method will reset the text render format to match the default
271+
* text render format from the label engine settings.
272+
*
270273
* \see textRenderFormat()
271274
* \since QGIS 3.4.3
272275
*/
273276
void setTextRenderFormat( QgsRenderContext::TextRenderFormat format )
274277
{
275278
mTextRenderFormat = format;
279+
// ensure labeling engine setting is also kept in sync, just in case anyone accesses QgsMapSettings::labelingEngineSettings().defaultTextRenderFormat()
280+
// instead of correctly calling QgsMapSettings::textRenderFormat(). It can't hurt to be consistent!
281+
mLabelingEngineSettings.setDefaultTextRenderFormat( format );
276282
}
277283

278284
//! sets format of internal QImage
@@ -433,13 +439,26 @@ class CORE_EXPORT QgsMapSettings
433439
QgsAbstractGeometry::SegmentationToleranceType segmentationToleranceType() const { return mSegmentationToleranceType; }
434440

435441
/**
436-
* Sets global configuration of the labeling engine
442+
* Sets the global configuration of the labeling engine.
443+
*
444+
* \note Calling this method will reset the textRenderFormat() to match the default
445+
* text render format from the label engine \a settings.
446+
*
447+
* \see labelingEngineSettings()
448+
*
437449
* \since QGIS 3.0
438450
*/
439-
void setLabelingEngineSettings( const QgsLabelingEngineSettings &settings ) { mLabelingEngineSettings = settings; }
451+
void setLabelingEngineSettings( const QgsLabelingEngineSettings &settings )
452+
{
453+
mLabelingEngineSettings = settings;
454+
mTextRenderFormat = settings.defaultTextRenderFormat();
455+
}
440456

441457
/**
442-
* Returns global configuration of the labeling engine
458+
* Returns the global configuration of the labeling engine.
459+
*
460+
* \see setLabelingEngineSettings()
461+
*
443462
* \since QGIS 3.0
444463
*/
445464
const QgsLabelingEngineSettings &labelingEngineSettings() const { return mLabelingEngineSettings; }

src/ui/qgslabelengineconfigdialog.ui

+19-20
Original file line numberDiff line numberDiff line change
@@ -205,18 +205,25 @@
205205
</layout>
206206
</item>
207207
<item>
208-
<layout class="QGridLayout" name="gridLayout_2">
209-
<property name="verticalSpacing">
210-
<number>6</number>
211-
</property>
212-
<item row="3" column="0">
213-
<widget class="QCheckBox" name="chkShowCandidates">
208+
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1">
209+
<item row="0" column="0">
210+
<widget class="QLabel" name="label_5">
214211
<property name="text">
215-
<string>Show candidates (for debugging)</string>
212+
<string>Text rendering</string>
213+
</property>
214+
</widget>
215+
</item>
216+
<item row="0" column="1">
217+
<widget class="QComboBox" name="mTextRenderFormatComboBox"/>
218+
</item>
219+
<item row="1" column="0" colspan="2">
220+
<widget class="QCheckBox" name="chkShowPartialsLabels">
221+
<property name="text">
222+
<string>Allow truncated labels on edges of map</string>
216223
</property>
217224
</widget>
218225
</item>
219-
<item row="2" column="0">
226+
<item row="2" column="0" colspan="2">
220227
<widget class="QCheckBox" name="chkShowAllLabels">
221228
<property name="sizePolicy">
222229
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -232,17 +239,10 @@
232239
</property>
233240
</widget>
234241
</item>
235-
<item row="0" column="0">
236-
<widget class="QCheckBox" name="mDrawOutlinesChkBox">
237-
<property name="text">
238-
<string>Draw text as outlines (recommended)</string>
239-
</property>
240-
</widget>
241-
</item>
242-
<item row="1" column="0">
243-
<widget class="QCheckBox" name="chkShowPartialsLabels">
242+
<item row="3" column="0" colspan="2">
243+
<widget class="QCheckBox" name="chkShowCandidates">
244244
<property name="text">
245-
<string>Show partial labels</string>
245+
<string>Show candidates (for debugging)</string>
246246
</property>
247247
</widget>
248248
</item>
@@ -278,11 +278,10 @@
278278
<tabstop>spinCandPoint</tabstop>
279279
<tabstop>spinCandLine</tabstop>
280280
<tabstop>spinCandPolygon</tabstop>
281-
<tabstop>mDrawOutlinesChkBox</tabstop>
281+
<tabstop>mTextRenderFormatComboBox</tabstop>
282282
<tabstop>chkShowPartialsLabels</tabstop>
283283
<tabstop>chkShowAllLabels</tabstop>
284284
<tabstop>chkShowCandidates</tabstop>
285-
<tabstop>buttonBox</tabstop>
286285
</tabstops>
287286
<resources/>
288287
<connections>

tests/src/core/testqgslabelingengine.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class TestQgsLabelingEngine : public QObject
4040
void cleanupTestCase();
4141
void init();// will be called before each testfunction is executed.
4242
void cleanup();// will be called after every testfunction.
43+
void testEngineSettings();
4344
void testBasic();
4445
void testDiagrams();
4546
void testRuleBased();
@@ -99,6 +100,42 @@ void TestQgsLabelingEngine::cleanup()
99100
vl = nullptr;
100101
}
101102

103+
void TestQgsLabelingEngine::testEngineSettings()
104+
{
105+
// test labeling engine settings
106+
107+
// getters/setters
108+
QgsLabelingEngineSettings settings;
109+
settings.setDefaultTextRenderFormat( QgsRenderContext::TextFormatAlwaysText );
110+
QCOMPARE( settings.defaultTextRenderFormat(), QgsRenderContext::TextFormatAlwaysText );
111+
settings.setDefaultTextRenderFormat( QgsRenderContext::TextFormatAlwaysOutlines );
112+
QCOMPARE( settings.defaultTextRenderFormat(), QgsRenderContext::TextFormatAlwaysOutlines );
113+
114+
// reading from project
115+
QgsProject p;
116+
settings.setDefaultTextRenderFormat( QgsRenderContext::TextFormatAlwaysText );
117+
settings.writeSettingsToProject( &p );
118+
QgsLabelingEngineSettings settings2;
119+
settings2.readSettingsFromProject( &p );
120+
QCOMPARE( settings2.defaultTextRenderFormat(), QgsRenderContext::TextFormatAlwaysText );
121+
122+
settings.setDefaultTextRenderFormat( QgsRenderContext::TextFormatAlwaysOutlines );
123+
settings.writeSettingsToProject( &p );
124+
settings2.readSettingsFromProject( &p );
125+
QCOMPARE( settings2.defaultTextRenderFormat(), QgsRenderContext::TextFormatAlwaysOutlines );
126+
127+
// test that older setting is still respected as a fallback
128+
QgsProject p2;
129+
QgsLabelingEngineSettings settings3;
130+
p2.writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawOutlineLabels" ), false );
131+
settings3.readSettingsFromProject( &p2 );
132+
QCOMPARE( settings3.defaultTextRenderFormat(), QgsRenderContext::TextFormatAlwaysText );
133+
134+
p2.writeEntry( QStringLiteral( "PAL" ), QStringLiteral( "/DrawOutlineLabels" ), true );
135+
settings3.readSettingsFromProject( &p2 );
136+
QCOMPARE( settings3.defaultTextRenderFormat(), QgsRenderContext::TextFormatAlwaysOutlines );
137+
}
138+
102139
void TestQgsLabelingEngine::setDefaultLabelParams( QgsPalLayerSettings &settings )
103140
{
104141
QgsTextFormat format;

0 commit comments

Comments
 (0)