diff --git a/python/core/auto_generated/qgspallabeling.sip.in b/python/core/auto_generated/qgspallabeling.sip.in index a6d7380e928..d739432f61f 100644 --- a/python/core/auto_generated/qgspallabeling.sip.in +++ b/python/core/auto_generated/qgspallabeling.sip.in @@ -159,6 +159,7 @@ class QgsPalLayerSettings // text formatting MultiLineWrapChar, + AutoWrapLength, MultiLineHeight, MultiLineAlignment, DirSymbDraw, @@ -283,6 +284,10 @@ Returns the QgsExpression for this label settings. May be None if isExpression i QString wrapChar; + int autoWrapLength; + + bool useMaxLineLengthForAutoWrap; + MultiLineAlign multilineAlign; bool addDirectionSymbol; @@ -559,15 +564,16 @@ Checks whether a geometry requires preparation before registration with PAL .. versionadded:: 2.9 %End - static QStringList splitToLines( const QString &text, const QString &wrapCharacter ); + static QStringList splitToLines( const QString &text, const QString &wrapCharacter, int autoWrapLength = 0, bool useMaxLineLengthWhenAutoWrapping = true ); %Docstring -Splits a text string to a list of separate lines, using a specified wrap character. +Splits a ``text`` string to a list of separate lines, using a specified wrap character (``wrapCharacter``). The text string will be split on either newline characters or the wrap character. -:param text: text string to split -:param wrapCharacter: additional character to wrap on - -:return: list of text split to lines +Since QGIS 3.4 the ``autoWrapLength`` argument can be used to specify an ideal length of line to automatically +wrap text to (automatic wrapping is disabled if ``autoWrapLength`` is 0). This automatic wrapping is performed +after processing wrapping using ``wrapCharacter``. When auto wrapping is enabled, the ``useMaxLineLengthWhenAutoWrapping`` +argument controls whether the lines should be wrapped to an ideal maximum of ``autoWrapLength`` characters, or +if false then the lines are wrapped to an ideal minimum length of ``autoWrapLength`` characters. .. versionadded:: 2.9 %End diff --git a/python/core/auto_generated/qgsstringutils.sip.in b/python/core/auto_generated/qgsstringutils.sip.in index a84c916e6f5..69f1b480e3f 100644 --- a/python/core/auto_generated/qgsstringutils.sip.in +++ b/python/core/auto_generated/qgsstringutils.sip.in @@ -264,7 +264,7 @@ links. static QString wordWrap( const QString &string, int length, bool useMaxLineLength = true, const QString &customDelimiter = QString() ); %Docstring -Automatically wraps a \string by inserting new line characters at appropriate locations in the string. +Automatically wraps a ``string`` by inserting new line characters at appropriate locations in the string. The ``length`` argument specifies either the minimum or maximum length of lines desired, depending on whether ``useMaxLineLength`` is true. If ``useMaxLineLength`` is true, then the string will be wrapped diff --git a/src/app/qgslabelinggui.cpp b/src/app/qgslabelinggui.cpp index 85a1e87ee41..54aabcd73a0 100644 --- a/src/app/qgslabelinggui.cpp +++ b/src/app/qgslabelinggui.cpp @@ -247,6 +247,8 @@ void QgsLabelingGui::setLayer( QgsMapLayer *mapLayer ) mMaxCharAngleOutDSpinBox->setValue( std::fabs( lyr.maxCurvedCharAngleOut ) ); wrapCharacterEdit->setText( lyr.wrapChar ); + mAutoWrapLengthSpinBox->setValue( lyr.autoWrapLength ); + mAutoWrapTypeComboBox->setCurrentIndex( lyr.useMaxLineLengthForAutoWrap ? 0 : 1 ); mFontMultiLineAlignComboBox->setCurrentIndex( ( unsigned int ) lyr.multilineAlign ); chkPreserveRotation->setChecked( lyr.preserveRotation ); @@ -435,6 +437,8 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings() lyr.fontMinPixelSize = mFontMinPixelSpinBox->value(); lyr.fontMaxPixelSize = mFontMaxPixelSpinBox->value(); lyr.wrapChar = wrapCharacterEdit->text(); + lyr.autoWrapLength = mAutoWrapLengthSpinBox->value(); + lyr.useMaxLineLengthForAutoWrap = mAutoWrapTypeComboBox->currentIndex() == 0; lyr.multilineAlign = ( QgsPalLayerSettings::MultiLineAlign ) mFontMultiLineAlignComboBox->currentIndex(); lyr.preserveRotation = chkPreserveRotation->isChecked(); @@ -465,6 +469,7 @@ void QgsLabelingGui::populateDataDefinedButtons() // text formatting registerDataDefinedButton( mWrapCharDDBtn, QgsPalLayerSettings::MultiLineWrapChar ); + registerDataDefinedButton( mAutoWrapLengthDDBtn, QgsPalLayerSettings::AutoWrapLength ); registerDataDefinedButton( mFontLineHeightDDBtn, QgsPalLayerSettings::MultiLineHeight ); registerDataDefinedButton( mFontMultiLineAlignDDBtn, QgsPalLayerSettings::MultiLineAlignment ); diff --git a/src/core/qgspallabeling.cpp b/src/core/qgspallabeling.cpp index 9d46e61f6e6..49f1037bed5 100644 --- a/src/core/qgspallabeling.cpp +++ b/src/core/qgspallabeling.cpp @@ -124,6 +124,7 @@ void QgsPalLayerSettings::initPropertyDefinitions() { QgsPalLayerSettings::FontWordSpacing, QgsPropertyDefinition( "FontWordSpacing", QObject::tr( "Word spacing" ), QgsPropertyDefinition::Double, origin ) }, { QgsPalLayerSettings::FontBlendMode, QgsPropertyDefinition( "FontBlendMode", QObject::tr( "Text blend mode" ), QgsPropertyDefinition::BlendMode, origin ) }, { QgsPalLayerSettings::MultiLineWrapChar, QgsPropertyDefinition( "MultiLineWrapChar", QObject::tr( "Wrap character" ), QgsPropertyDefinition::String, origin ) }, + { QgsPalLayerSettings::AutoWrapLength, QgsPropertyDefinition( "AutoWrapLength", QObject::tr( "Automatic word wrap line length" ), QgsPropertyDefinition::IntegerPositive, origin ) }, { QgsPalLayerSettings::MultiLineHeight, QgsPropertyDefinition( "MultiLineHeight", QObject::tr( "Line height" ), QgsPropertyDefinition::DoublePositive, origin ) }, { QgsPalLayerSettings::MultiLineAlignment, QgsPropertyDefinition( "MultiLineAlignment", QgsPropertyDefinition::DataTypeString, QObject::tr( "Line alignment" ), QObject::tr( "string " ) + "[Left|Center|Right|Follow]", origin ) }, { QgsPalLayerSettings::DirSymbDraw, QgsPropertyDefinition( "DirSymbDraw", QObject::tr( "Draw direction symbol" ), QgsPropertyDefinition::Boolean, origin ) }, @@ -321,6 +322,8 @@ QgsPalLayerSettings &QgsPalLayerSettings::operator=( const QgsPalLayerSettings & // text formatting wrapChar = s.wrapChar; + autoWrapLength = s.autoWrapLength; + useMaxLineLengthForAutoWrap = s.useMaxLineLengthForAutoWrap; multilineAlign = s.multilineAlign; addDirectionSymbol = s.addDirectionSymbol; leftDirectionSymbol = s.leftDirectionSymbol; @@ -532,6 +535,9 @@ void QgsPalLayerSettings::readFromLayerCustomProperties( QgsVectorLayer *layer ) // text formatting wrapChar = layer->customProperty( QStringLiteral( "labeling/wrapChar" ) ).toString(); + autoWrapLength = layer->customProperty( QStringLiteral( "labeling/autoWrapLength" ) ).toInt(); + useMaxLineLengthForAutoWrap = layer->customProperty( QStringLiteral( "labeling/useMaxLineLengthForAutoWrap" ), QStringLiteral( "1" ) ).toBool(); + multilineAlign = static_cast< MultiLineAlign >( layer->customProperty( QStringLiteral( "labeling/multilineAlign" ), QVariant( MultiFollowPlacement ) ).toUInt() ); addDirectionSymbol = layer->customProperty( QStringLiteral( "labeling/addDirectionSymbol" ) ).toBool(); leftDirectionSymbol = layer->customProperty( QStringLiteral( "labeling/leftDirectionSymbol" ), QVariant( "<" ) ).toString(); @@ -739,6 +745,8 @@ void QgsPalLayerSettings::readXml( QDomElement &elem, const QgsReadWriteContext // text formatting QDomElement textFormatElem = elem.firstChildElement( QStringLiteral( "text-format" ) ); wrapChar = textFormatElem.attribute( QStringLiteral( "wrapChar" ) ); + autoWrapLength = textFormatElem.attribute( QStringLiteral( "autoWrapLength" ), QStringLiteral( "0" ) ).toInt(); + useMaxLineLengthForAutoWrap = textFormatElem.attribute( QStringLiteral( "useMaxLineLengthForAutoWrap" ), QStringLiteral( "1" ) ).toInt(); multilineAlign = static_cast< MultiLineAlign >( textFormatElem.attribute( QStringLiteral( "multilineAlign" ), QString::number( MultiFollowPlacement ) ).toUInt() ); addDirectionSymbol = textFormatElem.attribute( QStringLiteral( "addDirectionSymbol" ) ).toInt(); leftDirectionSymbol = textFormatElem.attribute( QStringLiteral( "leftDirectionSymbol" ), QStringLiteral( "<" ) ); @@ -953,6 +961,8 @@ QDomElement QgsPalLayerSettings::writeXml( QDomDocument &doc, const QgsReadWrite // text formatting QDomElement textFormatElem = doc.createElement( QStringLiteral( "text-format" ) ); textFormatElem.setAttribute( QStringLiteral( "wrapChar" ), wrapChar ); + textFormatElem.setAttribute( QStringLiteral( "autoWrapLength" ), autoWrapLength ); + textFormatElem.setAttribute( QStringLiteral( "useMaxLineLengthForAutoWrap" ), useMaxLineLengthForAutoWrap ); textFormatElem.setAttribute( QStringLiteral( "multilineAlign" ), static_cast< unsigned int >( multilineAlign ) ); textFormatElem.setAttribute( QStringLiteral( "addDirectionSymbol" ), addDirectionSymbol ); textFormatElem.setAttribute( QStringLiteral( "leftDirectionSymbol" ), leftDirectionSymbol ); @@ -1046,6 +1056,7 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF *fm, QString t QgsRenderContext *rc = context ? context : scopedRc.get(); QString wrapchr = wrapChar; + int evalAutoWrapLength = autoWrapLength; double multilineH = mFormat.lineHeight(); bool addDirSymb = addDirectionSymbol; @@ -1060,6 +1071,11 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF *fm, QString t wrapchr = dataDefinedValues.value( QgsPalLayerSettings::MultiLineWrapChar ).toString(); } + if ( dataDefinedValues.contains( QgsPalLayerSettings::AutoWrapLength ) ) + { + evalAutoWrapLength = dataDefinedValues.value( QgsPalLayerSettings::AutoWrapLength, evalAutoWrapLength ).toInt(); + } + if ( dataDefinedValues.contains( QgsPalLayerSettings::MultiLineHeight ) ) { multilineH = dataDefinedValues.value( QgsPalLayerSettings::MultiLineHeight ).toDouble(); @@ -1095,6 +1111,9 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF *fm, QString t rc->expressionContext().setOriginalValueVariable( wrapChar ); wrapchr = mDataDefinedProperties.value( QgsPalLayerSettings::MultiLineWrapChar, rc->expressionContext(), wrapchr ).toString(); + rc->expressionContext().setOriginalValueVariable( evalAutoWrapLength ); + evalAutoWrapLength = mDataDefinedProperties.value( QgsPalLayerSettings::AutoWrapLength, rc->expressionContext(), evalAutoWrapLength ).toInt(); + rc->expressionContext().setOriginalValueVariable( multilineH ); multilineH = mDataDefinedProperties.valueAsDouble( QgsPalLayerSettings::MultiLineHeight, rc->expressionContext(), multilineH ); @@ -1140,7 +1159,7 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF *fm, QString t } double w = 0.0, h = 0.0; - QStringList multiLineSplit = QgsPalLabeling::splitToLines( text, wrapchr ); + QStringList multiLineSplit = QgsPalLabeling::splitToLines( text, wrapchr, evalAutoWrapLength, useMaxLineLengthForAutoWrap ); int lines = multiLineSplit.size(); double labelHeight = fm->ascent() + fm->descent(); // ignore +1 for baseline @@ -2422,6 +2441,12 @@ void QgsPalLayerSettings::parseTextFormatting( QgsRenderContext &context ) wrapchr = exprVal.toString(); } + int evalAutoWrapLength = autoWrapLength; + if ( dataDefinedValEval( DDInt, QgsPalLayerSettings::AutoWrapLength, exprVal, context.expressionContext(), evalAutoWrapLength ) ) + { + evalAutoWrapLength = exprVal.toInt(); + } + // data defined multiline height? dataDefinedValEval( DDDouble, QgsPalLayerSettings::MultiLineHeight, exprVal, context.expressionContext() ); @@ -2844,13 +2869,14 @@ bool QgsPalLabeling::geometryRequiresPreparation( const QgsGeometry &geometry, Q return false; } -QStringList QgsPalLabeling::splitToLines( const QString &text, const QString &wrapCharacter ) +QStringList QgsPalLabeling::splitToLines( const QString &text, const QString &wrapCharacter, const int autoWrapLength, const bool useMaxLineLengthWhenAutoWrapping ) { QStringList multiLineSplit; if ( !wrapCharacter.isEmpty() && wrapCharacter != QLatin1String( "\n" ) ) { //wrap on both the wrapchr and new line characters - Q_FOREACH ( const QString &line, text.split( wrapCharacter ) ) + const QStringList lines = text.split( wrapCharacter ); + for ( const QString &line : lines ) { multiLineSplit.append( line.split( '\n' ) ); } @@ -2860,6 +2886,17 @@ QStringList QgsPalLabeling::splitToLines( const QString &text, const QString &wr multiLineSplit = text.split( '\n' ); } + // apply auto wrapping to each manually created line + if ( autoWrapLength != 0 ) + { + QStringList autoWrappedLines; + autoWrappedLines.reserve( multiLineSplit.count() ); + for ( const QString &line : qgis::as_const( multiLineSplit ) ) + { + autoWrappedLines.append( QgsStringUtils::wordWrap( line, autoWrapLength, useMaxLineLengthWhenAutoWrapping ).split( '\n' ) ); + } + multiLineSplit = autoWrappedLines; + } return multiLineSplit; } @@ -3044,7 +3081,12 @@ void QgsPalLabeling::dataDefinedTextFormatting( QgsPalLayerSettings &tmpLyr, tmpLyr.wrapChar = ddValues.value( QgsPalLayerSettings::MultiLineWrapChar ).toString(); } - if ( !tmpLyr.wrapChar.isEmpty() || tmpLyr.getLabelExpression()->expression().contains( QLatin1String( "wordwrap" ) ) ) + if ( ddValues.contains( QgsPalLayerSettings::AutoWrapLength ) ) + { + tmpLyr.autoWrapLength = ddValues.value( QgsPalLayerSettings::AutoWrapLength ).toInt(); + } + + if ( !tmpLyr.wrapChar.isEmpty() || tmpLyr.getLabelExpression()->expression().contains( QLatin1String( "wordwrap" ) ) || tmpLyr.autoWrapLength > 0 ) { if ( ddValues.contains( QgsPalLayerSettings::MultiLineHeight ) ) diff --git a/src/core/qgspallabeling.h b/src/core/qgspallabeling.h index d47e6812dd2..ac5e0e31e33 100644 --- a/src/core/qgspallabeling.h +++ b/src/core/qgspallabeling.h @@ -269,6 +269,7 @@ class CORE_EXPORT QgsPalLayerSettings // text formatting MultiLineWrapChar = 31, + AutoWrapLength = 101, MultiLineHeight = 32, MultiLineAlignment = 33, DirSymbDraw = 34, @@ -417,6 +418,27 @@ class CORE_EXPORT QgsPalLayerSettings */ QString wrapChar; + /** + * If non-zero, indicates that label text should be automatically wrapped to (ideally) the specified + * number of characters. If zero, auto wrapping is disabled. + * + * \see useMaxLineLengthForAutoWrap + * \since QGIS 3.4 + */ + int autoWrapLength = 0; + + /** + * If true, indicates that when auto wrapping label text the autoWrapLength length indicates the maximum + * ideal length of text lines. If false, then autoWrapLength indicates the ideal minimum length of text + * lines. + * + * If autoWrapLength is 0 then this value has no effect. + * + * \see autoWrapLength + * \since QGIS 3.4 + */ + bool useMaxLineLengthForAutoWrap = true; + //! Horizontal alignment of multi-line labels. MultiLineAlign multilineAlign; @@ -986,14 +1008,18 @@ class CORE_EXPORT QgsPalLabeling static bool geometryRequiresPreparation( const QgsGeometry &geometry, QgsRenderContext &context, const QgsCoordinateTransform &ct, const QgsGeometry &clipGeometry = QgsGeometry() ); /** - * Splits a text string to a list of separate lines, using a specified wrap character. + * Splits a \a text string to a list of separate lines, using a specified wrap character (\a wrapCharacter). * The text string will be split on either newline characters or the wrap character. - * \param text text string to split - * \param wrapCharacter additional character to wrap on - * \returns list of text split to lines + * + * Since QGIS 3.4 the \a autoWrapLength argument can be used to specify an ideal length of line to automatically + * wrap text to (automatic wrapping is disabled if \a autoWrapLength is 0). This automatic wrapping is performed + * after processing wrapping using \a wrapCharacter. When auto wrapping is enabled, the \a useMaxLineLengthWhenAutoWrapping + * argument controls whether the lines should be wrapped to an ideal maximum of \a autoWrapLength characters, or + * if false then the lines are wrapped to an ideal minimum length of \a autoWrapLength characters. + * * \since QGIS 2.9 */ - static QStringList splitToLines( const QString &text, const QString &wrapCharacter ); + static QStringList splitToLines( const QString &text, const QString &wrapCharacter, int autoWrapLength = 0, bool useMaxLineLengthWhenAutoWrapping = true ); /** * Splits a text string to a list of graphemes, which are the smallest allowable character diff --git a/src/core/qgsstringutils.h b/src/core/qgsstringutils.h index 69c87e0346c..ad6964e15ea 100644 --- a/src/core/qgsstringutils.h +++ b/src/core/qgsstringutils.h @@ -262,7 +262,7 @@ class CORE_EXPORT QgsStringUtils static QString insertLinks( const QString &string, bool *foundLinks = nullptr ); /** - * Automatically wraps a \string by inserting new line characters at appropriate locations in the string. + * Automatically wraps a \a string by inserting new line characters at appropriate locations in the string. * * The \a length argument specifies either the minimum or maximum length of lines desired, depending * on whether \a useMaxLineLength is true. If \a useMaxLineLength is true, then the string will be wrapped diff --git a/src/core/qgsvectorlayerlabelprovider.cpp b/src/core/qgsvectorlayerlabelprovider.cpp index 63c3ac6d988..bd46488409c 100644 --- a/src/core/qgsvectorlayerlabelprovider.cpp +++ b/src/core/qgsvectorlayerlabelprovider.cpp @@ -612,7 +612,7 @@ void QgsVectorLayerLabelProvider::drawLabelPrivate( pal::LabelPosition *label, Q } //QgsDebugMsgLevel( "drawLabel " + txt, 4 ); - QStringList multiLineList = QgsPalLabeling::splitToLines( txt, tmpLyr.wrapChar ); + QStringList multiLineList = QgsPalLabeling::splitToLines( txt, tmpLyr.wrapChar, tmpLyr.autoWrapLength, tmpLyr.useMaxLineLengthForAutoWrap ); QgsTextRenderer::HAlignment hAlign = QgsTextRenderer::AlignLeft; if ( tmpLyr.multilineAlign == QgsPalLayerSettings::MultiCenter ) diff --git a/src/gui/qgstextformatwidget.cpp b/src/gui/qgstextformatwidget.cpp index 07adb9341d3..70ca5126ddc 100644 --- a/src/gui/qgstextformatwidget.cpp +++ b/src/gui/qgstextformatwidget.cpp @@ -456,10 +456,13 @@ void QgsTextFormatWidget::initWidget() << mShapeTypeDDBtn << mShowLabelDDBtn << mWrapCharDDBtn + << mAutoWrapLengthDDBtn << mZIndexDDBtn << mZIndexSpinBox << spinBufferSize << wrapCharacterEdit + << mAutoWrapLengthSpinBox + << mAutoWrapTypeComboBox << mCentroidRadioVisible << mCentroidRadioWhole << mDirectSymbRadioBtnAbove diff --git a/src/ui/qgstextformatwidgetbase.ui b/src/ui/qgstextformatwidgetbase.ui index ae1af6e92c4..c7bfd8fc52c 100644 --- a/src/ui/qgstextformatwidgetbase.ui +++ b/src/ui/qgstextformatwidgetbase.ui @@ -172,7 +172,7 @@ 0 0 - 482 + 486 300 @@ -651,7 +651,7 @@ - 6 + 1 @@ -680,8 +680,8 @@ 0 0 - 448 - 444 + 375 + 470 @@ -1460,8 +1460,8 @@ font-style: italic; 0 0 - 448 - 389 + 452 + 479 @@ -1507,27 +1507,10 @@ font-style: italic; 0 - - + + - - - - - - - - - 0 - 0 - - - - - - - - + Wrap lines to @@ -1544,7 +1527,7 @@ font-style: italic; - + @@ -1557,7 +1540,98 @@ font-style: italic; + + + + + + + + + + + true + + + Paragraph style alignment of multi-line text + + + Qt::LeftToRight + + + + Left + + + + + Center + + + + + Right + + + + + + + + + + + + + + true + + + If set, label text will automatically be wrapped to match the specified number of characters per line (if possible) + + + No automatic wrapping + + + characters + + + 999 + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Alignment + + + + + + + + + + + true @@ -1588,52 +1662,28 @@ font-style: italic; - - - - - 0 - 0 - - + + - Alignment + - - - true - + - Paragraph style alignment of multi-line text - - - Qt::LeftToRight + Controls whether lines are automatically wrapped using the maximum number of characters in a line, or the minimum - Left + Maximum line length - Center + Minimum line length - - - Right - - - - - - - - - @@ -2095,8 +2145,8 @@ font-style: italic; 0 0 - 464 - 366 + 466 + 365 @@ -2441,8 +2491,8 @@ font-style: italic; 0 0 - 462 - 738 + 464 + 776 @@ -3214,8 +3264,8 @@ font-style: italic; 0 0 - 448 - 441 + 452 + 470 @@ -3675,8 +3725,8 @@ font-style: italic; 0 0 - 448 - 917 + 452 + 977 @@ -5309,8 +5359,8 @@ font-style: italic; 0 0 - 448 - 795 + 452 + 877 @@ -6187,6 +6237,34 @@ font-style: italic; + + QgsDoubleSpinBox + QDoubleSpinBox +
qgsdoublespinbox.h
+
+ + QgsColorButton + QToolButton +
qgscolorbutton.h
+ 1 +
+ + QgsPropertyOverrideButton + QToolButton +
qgspropertyoverridebutton.h
+
+ + QgsUnitSelectionWidget + QWidget +
qgsunitselectionwidget.h
+ 1 +
+ + QgsOpacityWidget + QWidget +
qgsopacitywidget.h
+ 1 +
QgsScrollArea QScrollArea @@ -6209,28 +6287,6 @@ font-style: italic; QWidget
qgsscalewidget.h
- - QgsDoubleSpinBox - QDoubleSpinBox -
qgsdoublespinbox.h
-
- - QgsUnitSelectionWidget - QWidget -
qgsunitselectionwidget.h
- 1 -
- - QgsColorButton - QToolButton -
qgscolorbutton.h
- 1 -
- - QgsPropertyOverrideButton - QToolButton -
qgspropertyoverridebutton.h
-
QgsBlendModeComboBox QComboBox @@ -6258,12 +6314,6 @@ font-style: italic;
effects/qgseffectstackpropertieswidget.h
1
- - QgsOpacityWidget - QWidget -
qgsopacitywidget.h
- 1 -
mFieldExpressionWidget @@ -6307,6 +6357,9 @@ font-style: italic; scrollArea_5 wrapCharacterEdit mWrapCharDDBtn + mAutoWrapLengthSpinBox + mAutoWrapLengthDDBtn + mAutoWrapTypeComboBox mFontLineHeightSpinBox mFontLineHeightDDBtn mFontMultiLineAlignComboBox @@ -6536,6 +6589,12 @@ font-style: italic; + + + + + + diff --git a/tests/src/core/testqgspallabeling.cpp b/tests/src/core/testqgspallabeling.cpp index 92cea159353..081c3086532 100644 --- a/tests/src/core/testqgspallabeling.cpp +++ b/tests/src/core/testqgspallabeling.cpp @@ -61,6 +61,14 @@ void TestQgsPalLabeling::wrapChar() QCOMPARE( QgsPalLabeling::splitToLines( "mixed new line\nand char", QString( " " ) ), QStringList() << "mixed" << "new" << "line" << "and" << "char" ); QCOMPARE( QgsPalLabeling::splitToLines( "no matching chars", QString( "#" ) ), QStringList() << "no matching chars" ); QCOMPARE( QgsPalLabeling::splitToLines( "no\nmatching\nchars", QString( "#" ) ), QStringList() << "no" << "matching" << "chars" ); + + // with auto wrap + QCOMPARE( QgsPalLabeling::splitToLines( "with auto wrap", QString(), 12, true ), QStringList() << "with auto" << "wrap" ); + QCOMPARE( QgsPalLabeling::splitToLines( "with auto wrap", QString(), 6, false ), QStringList() << "with auto" << "wrap" ); + + // manual wrap character should take precedence + QCOMPARE( QgsPalLabeling::splitToLines( QStringLiteral( "with auto-wrap and manual-wrap" ), QStringLiteral( "-" ), 12, true ), QStringList() << "with auto" << "wrap and" << "manual" << "wrap" ); + QCOMPARE( QgsPalLabeling::splitToLines( QStringLiteral( "with auto-wrap and manual-wrap" ), QStringLiteral( "-" ), 6, false ), QStringList() << "with auto" << "wrap and" << "manual" << "wrap" ); } void TestQgsPalLabeling::graphemes()