Skip to content

Commit

Permalink
Allow setting data defined placement order in GUI
Browse files Browse the repository at this point in the history
Sponsored by Andreas Neumann
  • Loading branch information
nyalldawson committed Jan 11, 2016
1 parent b589856 commit 7479bf3
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 18 deletions.
12 changes: 12 additions & 0 deletions src/app/qgslabelinggui.cpp
Expand Up @@ -876,6 +876,7 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
// placement
setDataDefinedProperty( mCentroidDDBtn, QgsPalLayerSettings::CentroidWhole, lyr );
setDataDefinedProperty( mPointQuadOffsetDDBtn, QgsPalLayerSettings::OffsetQuad, lyr );
setDataDefinedProperty( mPointPositionOrderDDBtn, QgsPalLayerSettings::PredefinedPositionOrder, lyr );
setDataDefinedProperty( mPointOffsetDDBtn, QgsPalLayerSettings::OffsetXY, lyr );
setDataDefinedProperty( mPointOffsetUnitsDDBtn, QgsPalLayerSettings::OffsetUnits, lyr );
setDataDefinedProperty( mLineDistanceDDBtn, QgsPalLayerSettings::LabelDistance, lyr );
Expand Down Expand Up @@ -1107,6 +1108,14 @@ void QgsLabelingGui::populateDataDefinedButtons( QgsPalLayerSettings& s )
tr( "int<br>" ) + QLatin1String( "[<b>0</b>=Above Left|<b>1</b>=Above|<b>2</b>=Above Right|<br>"
"<b>3</b>=Left|<b>4</b>=Over|<b>5</b>=Right|<br>"
"<b>6</b>=Below Left|<b>7</b>=Below|<b>8</b>=Below Right]" ) );
mPointPositionOrderDDBtn->init( mLayer, s.dataDefinedProperty( QgsPalLayerSettings::PredefinedPositionOrder ),
QgsDataDefinedButton::String,
tr( "Comma seperated list of placements in order of priority<br>" )
+ QLatin1String( "[<b>TL</b>=Top left|<b>TSL</b>=Top, slightly left|<b>T</b>=Top middle|<br>"
"<b>TSR</b>=Top, slightly right|<b>TR</b>=Top right|<br>"
"<b>L</b>=Left|<b>R</b>=Right|<br>"
"<b>BL</b>=Bottom left|<b>BSL</b>=Bottom, slightly left|<b>B</b>=Bottom middle|<br>"
"<b>BSR</b>=Bottom, slightly right|<b>BR</b>=Bottom right]" ) );
mPointOffsetDDBtn->init( mLayer, s.dataDefinedProperty( QgsPalLayerSettings::OffsetXY ),
QgsDataDefinedButton::AnyType, QgsDataDefinedButton::doubleXYDesc() );
mPointOffsetUnitsDDBtn->init( mLayer, s.dataDefinedProperty( QgsPalLayerSettings::OffsetUnits ),
Expand Down Expand Up @@ -1358,6 +1367,7 @@ void QgsLabelingGui::updatePlacementWidgets()
bool showCentroidFrame = false;
bool showQuadrantFrame = false;
bool showFixedQuadrantFrame = false;
bool showPlacementPriorityFrame = false;
bool showOffsetFrame = false;
bool showDistanceFrame = false;
bool showRotationFrame = false;
Expand Down Expand Up @@ -1388,6 +1398,7 @@ void QgsLabelingGui::updatePlacementWidgets()
else if ( curWdgt == pagePoint && radPredefinedOrder->isChecked() )
{
showDistanceFrame = true;
showPlacementPriorityFrame = true;
}
else if (( curWdgt == pageLine && radLineParallel->isChecked() )
|| ( curWdgt == pagePolygon && radPolygonPerimeter->isChecked() )
Expand All @@ -1410,6 +1421,7 @@ void QgsLabelingGui::updatePlacementWidgets()
mPlacementCentroidFrame->setVisible( showCentroidFrame );
mPlacementQuadrantFrame->setVisible( showQuadrantFrame );
mPlacementFixedQuadrantFrame->setVisible( showFixedQuadrantFrame );
mPlacementCartographicFrame->setVisible( showPlacementPriorityFrame );
mPlacementOffsetFrame->setVisible( showOffsetFrame );
mPlacementDistanceFrame->setVisible( showDistanceFrame );
mPlacementRotationFrame->setVisible( showRotationFrame );
Expand Down
69 changes: 64 additions & 5 deletions src/core/qgslabelingenginev2.cpp
Expand Up @@ -403,7 +403,45 @@ QString QgsLabelingUtils::encodePredefinedPositionOrder( const QVector<QgsPalLay
QStringList predefinedOrderString;
Q_FOREACH ( QgsPalLayerSettings::PredefinedPointPosition position, positions )
{
predefinedOrderString << QString::number( static_cast< int >( position ) );
switch ( position )
{
case QgsPalLayerSettings::TopLeft:
predefinedOrderString << "TL";
break;
case QgsPalLayerSettings::TopSlightlyLeft:
predefinedOrderString << "TSL";
break;
case QgsPalLayerSettings::TopMiddle:
predefinedOrderString << "T";
break;
case QgsPalLayerSettings::TopSlightlyRight:
predefinedOrderString << "TSR";
break;
case QgsPalLayerSettings::TopRight:
predefinedOrderString << "TR";
break;
case QgsPalLayerSettings::MiddleLeft:
predefinedOrderString << "L";
break;
case QgsPalLayerSettings::MiddleRight:
predefinedOrderString << "R";
break;
case QgsPalLayerSettings::BottomLeft:
predefinedOrderString << "BL";
break;
case QgsPalLayerSettings::BottomSlightlyLeft:
predefinedOrderString << "BSL";
break;
case QgsPalLayerSettings::BottomMiddle:
predefinedOrderString << "B";
break;
case QgsPalLayerSettings::BottomSlightlyRight:
predefinedOrderString << "BSR";
break;
case QgsPalLayerSettings::BottomRight:
predefinedOrderString << "BR";
break;
}
}
return predefinedOrderString.join( "," );
}
Expand All @@ -414,10 +452,31 @@ QVector<QgsPalLayerSettings::PredefinedPointPosition> QgsLabelingUtils::decodePr
QStringList predefinedOrderList = positionString.split( ',' );
Q_FOREACH ( const QString& position, predefinedOrderList )
{
bool ok = false;
int positionInt = position.toInt( &ok );
if ( ok )
result << static_cast< QgsPalLayerSettings::PredefinedPointPosition >( positionInt );
QString cleaned = position.trimmed().toUpper();
if ( cleaned == "TL" )
result << QgsPalLayerSettings::TopLeft;
else if ( cleaned == "TSL" )
result << QgsPalLayerSettings::TopSlightlyLeft;
else if ( cleaned == "T" )
result << QgsPalLayerSettings::TopMiddle;
else if ( cleaned == "TSR" )
result << QgsPalLayerSettings::TopSlightlyRight;
else if ( cleaned == "TR" )
result << QgsPalLayerSettings::TopRight;
else if ( cleaned == "L" )
result << QgsPalLayerSettings::MiddleLeft;
else if ( cleaned == "R" )
result << QgsPalLayerSettings::MiddleRight;
else if ( cleaned == "BL" )
result << QgsPalLayerSettings::BottomLeft;
else if ( cleaned == "BSL" )
result << QgsPalLayerSettings::BottomSlightlyLeft;
else if ( cleaned == "B" )
result << QgsPalLayerSettings::BottomMiddle;
else if ( cleaned == "BSR" )
result << QgsPalLayerSettings::BottomSlightlyRight;
else if ( cleaned == "BR" )
result << QgsPalLayerSettings::BottomRight;
}
return result;
}
97 changes: 85 additions & 12 deletions src/ui/qgslabelingguibase.ui
Expand Up @@ -560,8 +560,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>594</width>
<height>398</height>
<width>346</width>
<height>388</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
Expand Down Expand Up @@ -1316,8 +1316,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>594</width>
<height>398</height>
<width>383</width>
<height>389</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_14">
Expand Down Expand Up @@ -1961,8 +1961,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>594</width>
<height>398</height>
<width>301</width>
<height>257</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
Expand Down Expand Up @@ -2340,7 +2340,7 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>578</width>
<width>454</width>
<height>697</height>
</rect>
</property>
Expand Down Expand Up @@ -3170,7 +3170,7 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>578</width>
<width>330</width>
<height>424</height>
</rect>
</property>
Expand Down Expand Up @@ -3659,9 +3659,9 @@ font-style: italic;</string>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<y>-114</y>
<width>578</width>
<height>829</height>
<height>866</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
Expand Down Expand Up @@ -3713,7 +3713,7 @@ font-style: italic;</string>
<enum>QFrame::Sunken</enum>
</property>
<property name="currentIndex">
<number>2</number>
<number>0</number>
</property>
<widget class="QWidget" name="pagePoint">
<layout class="QGridLayout" name="gridLayout_13" columnstretch="0,0,0,0">
Expand Down Expand Up @@ -4448,6 +4448,78 @@ font-style: italic;</string>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="mPlacementCartographicFrame">
<layout class="QGridLayout" name="gridLayout_39">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="2">
<widget class="QgsDataDefinedButton" name="mPointPositionOrderDDBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QFrame" name="mPlacementFixedQuadrantFrame_2">
<layout class="QGridLayout" name="gridLayout_11">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
</layout>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer_27">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>12</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_20">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Position priority</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="mPlacementOffsetFrame">
<property name="minimumSize">
Expand Down Expand Up @@ -5151,7 +5223,7 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>578</width>
<width>429</width>
<height>799</height>
</rect>
</property>
Expand Down Expand Up @@ -6369,6 +6441,7 @@ font-style: italic;</string>
<tabstop>mLineDistanceSpnBx</tabstop>
<tabstop>mLineDistanceDDBtn</tabstop>
<tabstop>mLineDistanceUnitDDBtn</tabstop>
<tabstop>mPointPositionOrderDDBtn</tabstop>
<tabstop>mPointAngleSpinBox</tabstop>
<tabstop>mPointAngleDDBtn</tabstop>
<tabstop>mRepeatDistanceSpinBox</tabstop>
Expand Down
15 changes: 14 additions & 1 deletion tests/src/core/testqgslabelingenginev2.cpp
Expand Up @@ -389,14 +389,27 @@ void TestQgsLabelingEngineV2::testEncodeDecodePositionOrder()
{
//create an ordered position list
QVector< QgsPalLayerSettings::PredefinedPointPosition > original;
original << QgsPalLayerSettings::TopLeft << QgsPalLayerSettings::BottomRight << QgsPalLayerSettings::MiddleRight;
//make sure all placements are added here
original << QgsPalLayerSettings::BottomLeft << QgsPalLayerSettings::BottomSlightlyLeft
<< QgsPalLayerSettings::BottomMiddle << QgsPalLayerSettings::BottomSlightlyRight
<< QgsPalLayerSettings::BottomRight << QgsPalLayerSettings::MiddleRight
<< QgsPalLayerSettings::MiddleLeft << QgsPalLayerSettings::TopLeft
<< QgsPalLayerSettings::TopSlightlyLeft << QgsPalLayerSettings::TopMiddle
<< QgsPalLayerSettings::TopSlightlyRight << QgsPalLayerSettings::TopRight;
//encode list
QString encoded = QgsLabelingUtils::encodePredefinedPositionOrder( original );
QVERIFY( !encoded.isEmpty() );

//decode
QVector< QgsPalLayerSettings::PredefinedPointPosition > decoded = QgsLabelingUtils::decodePredefinedPositionOrder( encoded );
QCOMPARE( decoded, original );

//test decoding with a messy string
decoded = QgsLabelingUtils::decodePredefinedPositionOrder( ",tr,x,BSR, L, t,," );
QVector< QgsPalLayerSettings::PredefinedPointPosition > expected;
expected << QgsPalLayerSettings::TopRight << QgsPalLayerSettings::BottomSlightlyRight
<< QgsPalLayerSettings::MiddleLeft << QgsPalLayerSettings::TopMiddle;
QCOMPARE( decoded, expected );
}

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

0 comments on commit 7479bf3

Please sign in to comment.