Skip to content

Commit 7479bf3

Browse files
committed
Allow setting data defined placement order in GUI
Sponsored by Andreas Neumann
1 parent b589856 commit 7479bf3

File tree

4 files changed

+175
-18
lines changed

4 files changed

+175
-18
lines changed

src/app/qgslabelinggui.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,7 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
876876
// placement
877877
setDataDefinedProperty( mCentroidDDBtn, QgsPalLayerSettings::CentroidWhole, lyr );
878878
setDataDefinedProperty( mPointQuadOffsetDDBtn, QgsPalLayerSettings::OffsetQuad, lyr );
879+
setDataDefinedProperty( mPointPositionOrderDDBtn, QgsPalLayerSettings::PredefinedPositionOrder, lyr );
879880
setDataDefinedProperty( mPointOffsetDDBtn, QgsPalLayerSettings::OffsetXY, lyr );
880881
setDataDefinedProperty( mPointOffsetUnitsDDBtn, QgsPalLayerSettings::OffsetUnits, lyr );
881882
setDataDefinedProperty( mLineDistanceDDBtn, QgsPalLayerSettings::LabelDistance, lyr );
@@ -1107,6 +1108,14 @@ void QgsLabelingGui::populateDataDefinedButtons( QgsPalLayerSettings& s )
11071108
tr( "int<br>" ) + QLatin1String( "[<b>0</b>=Above Left|<b>1</b>=Above|<b>2</b>=Above Right|<br>"
11081109
"<b>3</b>=Left|<b>4</b>=Over|<b>5</b>=Right|<br>"
11091110
"<b>6</b>=Below Left|<b>7</b>=Below|<b>8</b>=Below Right]" ) );
1111+
mPointPositionOrderDDBtn->init( mLayer, s.dataDefinedProperty( QgsPalLayerSettings::PredefinedPositionOrder ),
1112+
QgsDataDefinedButton::String,
1113+
tr( "Comma seperated list of placements in order of priority<br>" )
1114+
+ QLatin1String( "[<b>TL</b>=Top left|<b>TSL</b>=Top, slightly left|<b>T</b>=Top middle|<br>"
1115+
"<b>TSR</b>=Top, slightly right|<b>TR</b>=Top right|<br>"
1116+
"<b>L</b>=Left|<b>R</b>=Right|<br>"
1117+
"<b>BL</b>=Bottom left|<b>BSL</b>=Bottom, slightly left|<b>B</b>=Bottom middle|<br>"
1118+
"<b>BSR</b>=Bottom, slightly right|<b>BR</b>=Bottom right]" ) );
11101119
mPointOffsetDDBtn->init( mLayer, s.dataDefinedProperty( QgsPalLayerSettings::OffsetXY ),
11111120
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleXYDesc() );
11121121
mPointOffsetUnitsDDBtn->init( mLayer, s.dataDefinedProperty( QgsPalLayerSettings::OffsetUnits ),
@@ -1358,6 +1367,7 @@ void QgsLabelingGui::updatePlacementWidgets()
13581367
bool showCentroidFrame = false;
13591368
bool showQuadrantFrame = false;
13601369
bool showFixedQuadrantFrame = false;
1370+
bool showPlacementPriorityFrame = false;
13611371
bool showOffsetFrame = false;
13621372
bool showDistanceFrame = false;
13631373
bool showRotationFrame = false;
@@ -1388,6 +1398,7 @@ void QgsLabelingGui::updatePlacementWidgets()
13881398
else if ( curWdgt == pagePoint && radPredefinedOrder->isChecked() )
13891399
{
13901400
showDistanceFrame = true;
1401+
showPlacementPriorityFrame = true;
13911402
}
13921403
else if (( curWdgt == pageLine && radLineParallel->isChecked() )
13931404
|| ( curWdgt == pagePolygon && radPolygonPerimeter->isChecked() )
@@ -1410,6 +1421,7 @@ void QgsLabelingGui::updatePlacementWidgets()
14101421
mPlacementCentroidFrame->setVisible( showCentroidFrame );
14111422
mPlacementQuadrantFrame->setVisible( showQuadrantFrame );
14121423
mPlacementFixedQuadrantFrame->setVisible( showFixedQuadrantFrame );
1424+
mPlacementCartographicFrame->setVisible( showPlacementPriorityFrame );
14131425
mPlacementOffsetFrame->setVisible( showOffsetFrame );
14141426
mPlacementDistanceFrame->setVisible( showDistanceFrame );
14151427
mPlacementRotationFrame->setVisible( showRotationFrame );

src/core/qgslabelingenginev2.cpp

+64-5
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,45 @@ QString QgsLabelingUtils::encodePredefinedPositionOrder( const QVector<QgsPalLay
403403
QStringList predefinedOrderString;
404404
Q_FOREACH ( QgsPalLayerSettings::PredefinedPointPosition position, positions )
405405
{
406-
predefinedOrderString << QString::number( static_cast< int >( position ) );
406+
switch ( position )
407+
{
408+
case QgsPalLayerSettings::TopLeft:
409+
predefinedOrderString << "TL";
410+
break;
411+
case QgsPalLayerSettings::TopSlightlyLeft:
412+
predefinedOrderString << "TSL";
413+
break;
414+
case QgsPalLayerSettings::TopMiddle:
415+
predefinedOrderString << "T";
416+
break;
417+
case QgsPalLayerSettings::TopSlightlyRight:
418+
predefinedOrderString << "TSR";
419+
break;
420+
case QgsPalLayerSettings::TopRight:
421+
predefinedOrderString << "TR";
422+
break;
423+
case QgsPalLayerSettings::MiddleLeft:
424+
predefinedOrderString << "L";
425+
break;
426+
case QgsPalLayerSettings::MiddleRight:
427+
predefinedOrderString << "R";
428+
break;
429+
case QgsPalLayerSettings::BottomLeft:
430+
predefinedOrderString << "BL";
431+
break;
432+
case QgsPalLayerSettings::BottomSlightlyLeft:
433+
predefinedOrderString << "BSL";
434+
break;
435+
case QgsPalLayerSettings::BottomMiddle:
436+
predefinedOrderString << "B";
437+
break;
438+
case QgsPalLayerSettings::BottomSlightlyRight:
439+
predefinedOrderString << "BSR";
440+
break;
441+
case QgsPalLayerSettings::BottomRight:
442+
predefinedOrderString << "BR";
443+
break;
444+
}
407445
}
408446
return predefinedOrderString.join( "," );
409447
}
@@ -414,10 +452,31 @@ QVector<QgsPalLayerSettings::PredefinedPointPosition> QgsLabelingUtils::decodePr
414452
QStringList predefinedOrderList = positionString.split( ',' );
415453
Q_FOREACH ( const QString& position, predefinedOrderList )
416454
{
417-
bool ok = false;
418-
int positionInt = position.toInt( &ok );
419-
if ( ok )
420-
result << static_cast< QgsPalLayerSettings::PredefinedPointPosition >( positionInt );
455+
QString cleaned = position.trimmed().toUpper();
456+
if ( cleaned == "TL" )
457+
result << QgsPalLayerSettings::TopLeft;
458+
else if ( cleaned == "TSL" )
459+
result << QgsPalLayerSettings::TopSlightlyLeft;
460+
else if ( cleaned == "T" )
461+
result << QgsPalLayerSettings::TopMiddle;
462+
else if ( cleaned == "TSR" )
463+
result << QgsPalLayerSettings::TopSlightlyRight;
464+
else if ( cleaned == "TR" )
465+
result << QgsPalLayerSettings::TopRight;
466+
else if ( cleaned == "L" )
467+
result << QgsPalLayerSettings::MiddleLeft;
468+
else if ( cleaned == "R" )
469+
result << QgsPalLayerSettings::MiddleRight;
470+
else if ( cleaned == "BL" )
471+
result << QgsPalLayerSettings::BottomLeft;
472+
else if ( cleaned == "BSL" )
473+
result << QgsPalLayerSettings::BottomSlightlyLeft;
474+
else if ( cleaned == "B" )
475+
result << QgsPalLayerSettings::BottomMiddle;
476+
else if ( cleaned == "BSR" )
477+
result << QgsPalLayerSettings::BottomSlightlyRight;
478+
else if ( cleaned == "BR" )
479+
result << QgsPalLayerSettings::BottomRight;
421480
}
422481
return result;
423482
}

src/ui/qgslabelingguibase.ui

+85-12
Original file line numberDiff line numberDiff line change
@@ -560,8 +560,8 @@
560560
<rect>
561561
<x>0</x>
562562
<y>0</y>
563-
<width>594</width>
564-
<height>398</height>
563+
<width>346</width>
564+
<height>388</height>
565565
</rect>
566566
</property>
567567
<layout class="QVBoxLayout" name="verticalLayout_2">
@@ -1316,8 +1316,8 @@ font-style: italic;</string>
13161316
<rect>
13171317
<x>0</x>
13181318
<y>0</y>
1319-
<width>594</width>
1320-
<height>398</height>
1319+
<width>383</width>
1320+
<height>389</height>
13211321
</rect>
13221322
</property>
13231323
<layout class="QVBoxLayout" name="verticalLayout_14">
@@ -1961,8 +1961,8 @@ font-style: italic;</string>
19611961
<rect>
19621962
<x>0</x>
19631963
<y>0</y>
1964-
<width>594</width>
1965-
<height>398</height>
1964+
<width>301</width>
1965+
<height>257</height>
19661966
</rect>
19671967
</property>
19681968
<layout class="QVBoxLayout" name="verticalLayout_12">
@@ -2340,7 +2340,7 @@ font-style: italic;</string>
23402340
<rect>
23412341
<x>0</x>
23422342
<y>0</y>
2343-
<width>578</width>
2343+
<width>454</width>
23442344
<height>697</height>
23452345
</rect>
23462346
</property>
@@ -3170,7 +3170,7 @@ font-style: italic;</string>
31703170
<rect>
31713171
<x>0</x>
31723172
<y>0</y>
3173-
<width>578</width>
3173+
<width>330</width>
31743174
<height>424</height>
31753175
</rect>
31763176
</property>
@@ -3659,9 +3659,9 @@ font-style: italic;</string>
36593659
<property name="geometry">
36603660
<rect>
36613661
<x>0</x>
3662-
<y>0</y>
3662+
<y>-114</y>
36633663
<width>578</width>
3664-
<height>829</height>
3664+
<height>866</height>
36653665
</rect>
36663666
</property>
36673667
<layout class="QVBoxLayout" name="verticalLayout_11">
@@ -3713,7 +3713,7 @@ font-style: italic;</string>
37133713
<enum>QFrame::Sunken</enum>
37143714
</property>
37153715
<property name="currentIndex">
3716-
<number>2</number>
3716+
<number>0</number>
37173717
</property>
37183718
<widget class="QWidget" name="pagePoint">
37193719
<layout class="QGridLayout" name="gridLayout_13" columnstretch="0,0,0,0">
@@ -4448,6 +4448,78 @@ font-style: italic;</string>
44484448
</layout>
44494449
</widget>
44504450
</item>
4451+
<item>
4452+
<widget class="QFrame" name="mPlacementCartographicFrame">
4453+
<layout class="QGridLayout" name="gridLayout_39">
4454+
<property name="leftMargin">
4455+
<number>0</number>
4456+
</property>
4457+
<property name="topMargin">
4458+
<number>0</number>
4459+
</property>
4460+
<property name="rightMargin">
4461+
<number>0</number>
4462+
</property>
4463+
<property name="bottomMargin">
4464+
<number>0</number>
4465+
</property>
4466+
<item row="0" column="2">
4467+
<widget class="QgsDataDefinedButton" name="mPointPositionOrderDDBtn">
4468+
<property name="text">
4469+
<string>...</string>
4470+
</property>
4471+
</widget>
4472+
</item>
4473+
<item row="0" column="1" rowspan="2">
4474+
<widget class="QFrame" name="mPlacementFixedQuadrantFrame_2">
4475+
<layout class="QGridLayout" name="gridLayout_11">
4476+
<property name="leftMargin">
4477+
<number>0</number>
4478+
</property>
4479+
<property name="topMargin">
4480+
<number>0</number>
4481+
</property>
4482+
<property name="rightMargin">
4483+
<number>0</number>
4484+
</property>
4485+
<property name="bottomMargin">
4486+
<number>0</number>
4487+
</property>
4488+
<property name="spacing">
4489+
<number>2</number>
4490+
</property>
4491+
</layout>
4492+
</widget>
4493+
</item>
4494+
<item row="0" column="3">
4495+
<spacer name="horizontalSpacer_27">
4496+
<property name="orientation">
4497+
<enum>Qt::Horizontal</enum>
4498+
</property>
4499+
<property name="sizeHint" stdset="0">
4500+
<size>
4501+
<width>0</width>
4502+
<height>12</height>
4503+
</size>
4504+
</property>
4505+
</spacer>
4506+
</item>
4507+
<item row="0" column="0">
4508+
<widget class="QLabel" name="label_20">
4509+
<property name="sizePolicy">
4510+
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
4511+
<horstretch>0</horstretch>
4512+
<verstretch>0</verstretch>
4513+
</sizepolicy>
4514+
</property>
4515+
<property name="text">
4516+
<string>Position priority</string>
4517+
</property>
4518+
</widget>
4519+
</item>
4520+
</layout>
4521+
</widget>
4522+
</item>
44514523
<item>
44524524
<widget class="QFrame" name="mPlacementOffsetFrame">
44534525
<property name="minimumSize">
@@ -5151,7 +5223,7 @@ font-style: italic;</string>
51515223
<rect>
51525224
<x>0</x>
51535225
<y>0</y>
5154-
<width>578</width>
5226+
<width>429</width>
51555227
<height>799</height>
51565228
</rect>
51575229
</property>
@@ -6369,6 +6441,7 @@ font-style: italic;</string>
63696441
<tabstop>mLineDistanceSpnBx</tabstop>
63706442
<tabstop>mLineDistanceDDBtn</tabstop>
63716443
<tabstop>mLineDistanceUnitDDBtn</tabstop>
6444+
<tabstop>mPointPositionOrderDDBtn</tabstop>
63726445
<tabstop>mPointAngleSpinBox</tabstop>
63736446
<tabstop>mPointAngleDDBtn</tabstop>
63746447
<tabstop>mRepeatDistanceSpinBox</tabstop>

tests/src/core/testqgslabelingenginev2.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -389,14 +389,27 @@ void TestQgsLabelingEngineV2::testEncodeDecodePositionOrder()
389389
{
390390
//create an ordered position list
391391
QVector< QgsPalLayerSettings::PredefinedPointPosition > original;
392-
original << QgsPalLayerSettings::TopLeft << QgsPalLayerSettings::BottomRight << QgsPalLayerSettings::MiddleRight;
392+
//make sure all placements are added here
393+
original << QgsPalLayerSettings::BottomLeft << QgsPalLayerSettings::BottomSlightlyLeft
394+
<< QgsPalLayerSettings::BottomMiddle << QgsPalLayerSettings::BottomSlightlyRight
395+
<< QgsPalLayerSettings::BottomRight << QgsPalLayerSettings::MiddleRight
396+
<< QgsPalLayerSettings::MiddleLeft << QgsPalLayerSettings::TopLeft
397+
<< QgsPalLayerSettings::TopSlightlyLeft << QgsPalLayerSettings::TopMiddle
398+
<< QgsPalLayerSettings::TopSlightlyRight << QgsPalLayerSettings::TopRight;
393399
//encode list
394400
QString encoded = QgsLabelingUtils::encodePredefinedPositionOrder( original );
395401
QVERIFY( !encoded.isEmpty() );
396402

397403
//decode
398404
QVector< QgsPalLayerSettings::PredefinedPointPosition > decoded = QgsLabelingUtils::decodePredefinedPositionOrder( encoded );
399405
QCOMPARE( decoded, original );
406+
407+
//test decoding with a messy string
408+
decoded = QgsLabelingUtils::decodePredefinedPositionOrder( ",tr,x,BSR, L, t,," );
409+
QVector< QgsPalLayerSettings::PredefinedPointPosition > expected;
410+
expected << QgsPalLayerSettings::TopRight << QgsPalLayerSettings::BottomSlightlyRight
411+
<< QgsPalLayerSettings::MiddleLeft << QgsPalLayerSettings::TopMiddle;
412+
QCOMPARE( decoded, expected );
400413
}
401414

402415
bool TestQgsLabelingEngineV2::imageCheck( const QString& testName, QImage &image, int mismatchCount )

0 commit comments

Comments
 (0)