Skip to content

Commit 9c62eec

Browse files
committedAug 29, 2016
[FEATURE] Substitution list support for labeling
Adds the ability to specify a list of text substitutes to make which apply to label text. Eg abbrevating street types. Users can export and import lists of substitutes to make reuse and sharing easier. (cherry-picked from 46fba7c)
1 parent eef50ea commit 9c62eec

17 files changed

+1098
-3
lines changed
 

‎python/core/qgspallabeling.sip

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,11 @@ class QgsPalLayerSettings
388388
QPainter::CompositionMode blendMode;
389389
QColor previewBkgrdColor;
390390

391+
//! Substitution collection for automatic text substitution with labels
392+
QgsStringReplacementCollection substitutions;
393+
//! True if substitutions should be applied
394+
bool useSubstitutions;
395+
391396
//-- text formatting
392397

393398
QString wrapChar;

‎python/core/qgsstringutils.sip

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,115 @@
1+
2+
3+
/** \ingroup core
4+
* \class QgsStringReplacement
5+
* \brief A representation of a single string replacement.
6+
* \note Added in version 3.0
7+
*/
8+
9+
class QgsStringReplacement
10+
{
11+
%TypeHeaderCode
12+
#include <qgsstringutils.h>
13+
%End
14+
public:
15+
16+
/** Constructor for QgsStringReplacement.
17+
* @param match string to match
18+
* @param replacement string to replace match with
19+
* @param caseSensitive set to true for a case sensitive match
20+
* @param wholeWordOnly set to true to match complete words only, or false to allow partial word matches
21+
*/
22+
QgsStringReplacement( const QString& match,
23+
const QString& replacement,
24+
bool caseSensitive = false,
25+
bool wholeWordOnly = false );
26+
27+
//! Returns the string matched by this object
28+
QString match() const;
29+
30+
//! Returns the string to replace matches with
31+
QString replacement() const;
32+
33+
//! Returns true if match is case sensitive
34+
bool caseSensitive() const;
35+
36+
//! Returns true if match only applies to whole words, or false if partial word matches are permitted
37+
bool wholeWordOnly() const;
38+
39+
/** Processes a given input string, applying any valid replacements which should be made.
40+
* @param input input string
41+
* @returns input string with any matches replaced by replacement string
42+
*/
43+
QString process( const QString& input ) const;
44+
45+
bool operator==( const QgsStringReplacement& other );
46+
47+
/** Returns a map of the replacement properties.
48+
* @see fromProperties()
49+
*/
50+
QgsStringMap properties() const;
51+
52+
/** Creates a new QgsStringReplacement from an encoded properties map.
53+
* @see properties()
54+
*/
55+
static QgsStringReplacement fromProperties( const QgsStringMap& properties );
56+
57+
};
58+
59+
60+
/** \ingroup core
61+
* \class QgsStringReplacementCollection
62+
* \brief A collection of string replacements (specified using QgsStringReplacement objects).
63+
* \note Added in version 3.0
64+
*/
65+
66+
class QgsStringReplacementCollection
67+
{
68+
%TypeHeaderCode
69+
#include <qgsstringutils.h>
70+
%End
71+
public:
72+
73+
/** Constructor for QgsStringReplacementCollection
74+
* @param replacements initial list of string replacements
75+
*/
76+
QgsStringReplacementCollection( const QList< QgsStringReplacement >& replacements = QList< QgsStringReplacement >() );
77+
78+
/** Returns the list of string replacements in this collection.
79+
* @see setReplacements()
80+
*/
81+
QList< QgsStringReplacement > replacements() const;
82+
83+
/** Sets the list of string replacements in this collection.
84+
* @param replacements list of string replacements to apply. Replacements are applied in the
85+
* order they are specified here.
86+
* @see replacements()
87+
*/
88+
void setReplacements( const QList< QgsStringReplacement >& replacements );
89+
90+
/** Processes a given input string, applying any valid replacements which should be made
91+
* using QgsStringReplacement objects contained by this collection. Replacements
92+
* are made in order of the QgsStringReplacement objects contained in the collection.
93+
* @param input input string
94+
* @returns input string with any matches replaced by replacement string
95+
*/
96+
QString process( const QString& input ) const;
97+
98+
/** Writes the collection state to an XML element.
99+
* @param elem target DOM element
100+
* @param doc DOM document
101+
* @see readXml()
102+
*/
103+
void writeXml( QDomElement& elem, QDomDocument& doc ) const;
104+
105+
/** Reads the collection state from an XML element.
106+
* @param elem DOM element
107+
* @see writeXml()
108+
*/
109+
void readXml( const QDomElement& elem );
110+
};
111+
112+
1113
/** \ingroup core
2114
* \class QgsStringUtils
3115
* \brief Utility functions for working with strings.

‎src/app/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ SET(QGIS_APP_SRCS
115115
qgsrelationadddlg.cpp
116116
qgsselectbyformdialog.cpp
117117
qgsstatisticalsummarydockwidget.cpp
118+
qgssubstitutionlistwidget.cpp
118119
qgstextannotationdialog.cpp
119120
qgssnappingdialog.cpp
120121
qgssvgannotationdialog.cpp
@@ -292,6 +293,7 @@ SET (QGIS_APP_MOC_HDRS
292293
qgssnappingdialog.h
293294
qgssponsors.h
294295
qgsstatisticalsummarydockwidget.h
296+
qgssubstitutionlistwidget.h
295297
qgssvgannotationdialog.h
296298
qgstextannotationdialog.h
297299
qgstipgui.h

‎src/app/qgslabelinggui.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "qgssvgselectorwidget.h"
3636
#include "qgsvectorlayerlabeling.h"
3737
#include "qgslogger.h"
38+
#include "qgssubstitutionlistwidget.h"
3839

3940
#include <QCheckBox>
4041
#include <QSettings>
@@ -139,6 +140,7 @@ QgsLabelingGui::QgsLabelingGui( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas,
139140
connect( mShadowTranspSlider, SIGNAL( valueChanged( int ) ), mShadowTranspSpnBx, SLOT( setValue( int ) ) );
140141
connect( mShadowTranspSpnBx, SIGNAL( valueChanged( int ) ), mShadowTranspSlider, SLOT( setValue( int ) ) );
141142
connect( mLimitLabelChkBox, SIGNAL( toggled( bool ) ), mLimitLabelSpinBox, SLOT( setEnabled( bool ) ) );
143+
connect( mCheckBoxSubstituteText, SIGNAL( toggled( bool ) ), mToolButtonConfigureSubstitutes, SLOT( setEnabled( bool ) ) );
142144

143145
//connections to prevent users removing all line placement positions
144146
connect( chkLineAbove, SIGNAL( toggled( bool ) ), this, SLOT( updateLinePlacementOptions() ) );
@@ -468,7 +470,8 @@ QgsLabelingGui::QgsLabelingGui( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas,
468470
<< radPolygonPerimeter
469471
<< radPolygonPerimeterCurved
470472
<< radPredefinedOrder
471-
<< mFieldExpressionWidget;
473+
<< mFieldExpressionWidget
474+
<< mCheckBoxSubstituteText;
472475
connectValueChanged( widgets, SLOT( updatePreview() ) );
473476

474477
connect( mQuadrantBtnGrp, SIGNAL( buttonClicked( int ) ), this, SLOT( updatePreview() ) );
@@ -625,6 +628,8 @@ void QgsLabelingGui::init()
625628
// set the current field or add the current expression to the bottom of the list
626629
mFieldExpressionWidget->setRow( -1 );
627630
mFieldExpressionWidget->setField( lyr.fieldName );
631+
mCheckBoxSubstituteText->setChecked( lyr.useSubstitutions );
632+
mSubstitutions = lyr.substitutions;
628633

629634
// populate placement options
630635
mCentroidRadioWhole->setChecked( lyr.centroidWhole );
@@ -1015,6 +1020,8 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
10151020
lyr.scaleVisibility = mScaleBasedVisibilityChkBx->isChecked();
10161021
lyr.scaleMin = mScaleBasedVisibilityMinSpnBx->value();
10171022
lyr.scaleMax = mScaleBasedVisibilityMaxSpnBx->value();
1023+
lyr.useSubstitutions = mCheckBoxSubstituteText->isChecked();
1024+
lyr.substitutions = mSubstitutions;
10181025

10191026
// buffer
10201027
lyr.bufferDraw = mBufferDrawChkBx->isChecked();
@@ -1975,6 +1982,12 @@ void QgsLabelingGui::updateLinePlacementOptions()
19751982
}
19761983
}
19771984

1985+
void QgsLabelingGui::onSubstitutionsChanged( const QgsStringReplacementCollection& substitutions )
1986+
{
1987+
mSubstitutions = substitutions;
1988+
emit widgetChanged();
1989+
}
1990+
19781991
void QgsLabelingGui::updateSvgWidgets( const QString& svgPath )
19791992
{
19801993
if ( mShapeSVGPathLineEdit->text() != svgPath )
@@ -2101,6 +2114,28 @@ void QgsLabelingGui::on_mChkNoObstacle_toggled( bool active )
21012114
mObstaclePriorityFrame->setEnabled( active );
21022115
}
21032116

2117+
void QgsLabelingGui::on_mToolButtonConfigureSubstitutes_clicked()
2118+
{
2119+
QgsPanelWidget* panel = QgsPanelWidget::findParentPanel( this );
2120+
if ( panel && panel->dockMode() )
2121+
{
2122+
QgsSubstitutionListWidget* widget = new QgsSubstitutionListWidget( panel );
2123+
widget->setPanelTitle( tr( "Substitutions" ) );
2124+
widget->setSubstitutions( mSubstitutions );
2125+
connect( widget, SIGNAL( substitutionsChanged( QgsStringReplacementCollection ) ), this, SLOT( onSubstitutionsChanged( QgsStringReplacementCollection ) ) );
2126+
panel->openPanel( widget );
2127+
return;
2128+
}
2129+
2130+
QgsSubstitutionListDialog dlg( this );
2131+
dlg.setSubstitutions( mSubstitutions );
2132+
if ( dlg.exec() == QDialog::Accepted )
2133+
{
2134+
mSubstitutions = dlg.substitutions();
2135+
emit widgetChanged();
2136+
}
2137+
}
2138+
21042139
void QgsLabelingGui::showBackgroundRadius( bool show )
21052140
{
21062141
mShapeRadiusLabel->setVisible( show );

‎src/app/qgslabelinggui.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <QDialog>
2222
#include <QFontDatabase>
2323
#include <ui_qgslabelingguibase.h>
24+
#include "qgsstringutils.h"
2425

2526
class QgsVectorLayer;
2627
class QgsMapCanvas;
@@ -96,6 +97,8 @@ class APP_EXPORT QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase
9697
void on_mDirectSymbRightToolBtn_clicked();
9798
void on_mChkNoObstacle_toggled( bool active );
9899

100+
void on_mToolButtonConfigureSubstitutes_clicked();
101+
99102
protected:
100103
void blockInitSignals( bool block );
101104
void blockFontChangeSignals( bool blk );
@@ -135,6 +138,8 @@ class APP_EXPORT QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase
135138

136139
bool mLoadSvgParams;
137140

141+
QgsStringReplacementCollection mSubstitutions;
142+
138143
void enableDataDefinedAlignment( bool enable );
139144

140145
private slots:
@@ -143,6 +148,7 @@ class APP_EXPORT QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase
143148
void showBackgroundPenStyle( bool show );
144149
void on_mShapeSVGPathLineEdit_textChanged( const QString& text );
145150
void updateLinePlacementOptions();
151+
void onSubstitutionsChanged( const QgsStringReplacementCollection& substitutions );
146152
};
147153

148154
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.