[feature] Support Small Caps style in labels/text renderer

Adds two new capitalization styles for labels and text symbols:

- Small Caps: Renders lowercase characters as small caps
- All Small Caps: Renders all characters as small caps (regardless
of their original case)

Requires Qt 6.3+, or Qt 5.15 using KDE's fork and the cmake
HAS_KDE_QT5_SMALL_CAPS_FIX switch defined during build.
This commit is contained in:
Nyall Dawson 2021-11-04 15:16:55 +10:00
parent a168bcad52
commit dae69acc76
33 changed files with 176 additions and 99 deletions

View File

@ -425,7 +425,8 @@ if(WITH_CORE)
else()
set(QT_MIN_VERSION 5.12.0)
set(QT_VERSION_BASE "Qt5")
set(WITH_QT5_KDE_FORK FALSE CACHE BOOL "Using KDE's Qt 5.15 fork")
set(HAS_KDE_QT5_PDF_TRANSFORM_FIX FALSE CACHE BOOL "Using KDE's Qt 5.15 fork with the PDF brush transform fix")
set(HAS_KDE_QT5_SMALL_CAPS_FIX FALSE CACHE BOOL "Using KDE's Qt 5.15 fork with the QFont::SmallCaps fix")
endif()
# Use Qt5SerialPort optionally for GPS

View File

@ -104,7 +104,8 @@
#cmakedefine ENABLE_TESTS
#cmakedefine WITH_QT5_KDE_FORK
#cmakedefine HAS_KDE_QT5_PDF_TRANSFORM_FIX
#cmakedefine HAS_KDE_QT5_SMALL_CAPS_FIX
#endif

View File

@ -1132,3 +1132,32 @@ Qgis.DashPatternSizeAdjustment.ScaleGapOnly.__doc__ = "Only gap lengths are adju
Qgis.DashPatternSizeAdjustment.__doc__ = 'Dash pattern size adjustment options.\n\n.. versionadded:: 3.24\n\n' + '* ``ScaleBothDashAndGap``: ' + Qgis.DashPatternSizeAdjustment.ScaleBothDashAndGap.__doc__ + '\n' + '* ``ScaleDashOnly``: ' + Qgis.DashPatternSizeAdjustment.ScaleDashOnly.__doc__ + '\n' + '* ``ScaleGapOnly``: ' + Qgis.DashPatternSizeAdjustment.ScaleGapOnly.__doc__
# --
Qgis.DashPatternSizeAdjustment.baseClass = Qgis
QgsStringUtils.Capitalization = Qgis.Capitalization
# monkey patching scoped based enum
QgsStringUtils.MixedCase = Qgis.Capitalization.MixedCase
QgsStringUtils.MixedCase.is_monkey_patched = True
QgsStringUtils.MixedCase.__doc__ = "Mixed case, ie no change"
QgsStringUtils.AllUppercase = Qgis.Capitalization.AllUppercase
QgsStringUtils.AllUppercase.is_monkey_patched = True
QgsStringUtils.AllUppercase.__doc__ = "Convert all characters to uppercase"
QgsStringUtils.AllLowercase = Qgis.Capitalization.AllLowercase
QgsStringUtils.AllLowercase.is_monkey_patched = True
QgsStringUtils.AllLowercase.__doc__ = "Convert all characters to lowercase"
QgsStringUtils.ForceFirstLetterToCapital = Qgis.Capitalization.ForceFirstLetterToCapital
QgsStringUtils.ForceFirstLetterToCapital.is_monkey_patched = True
QgsStringUtils.ForceFirstLetterToCapital.__doc__ = "Convert just the first letter of each word to uppercase, leave the rest untouched"
QgsStringUtils.SmallCaps = Qgis.Capitalization.SmallCaps
QgsStringUtils.SmallCaps.is_monkey_patched = True
QgsStringUtils.SmallCaps.__doc__ = "Mixed case small caps (since QGIS 3.24)"
QgsStringUtils.TitleCase = Qgis.Capitalization.TitleCase
QgsStringUtils.TitleCase.is_monkey_patched = True
QgsStringUtils.TitleCase.__doc__ = "Simple title case conversion - does not fully grammatically parse the text and uses simple rules only. Note that this method does not convert any characters to lowercase, it only uppercases required letters. Callers must ensure that input strings are already lowercased."
QgsStringUtils.UpperCamelCase = Qgis.Capitalization.UpperCamelCase
QgsStringUtils.UpperCamelCase.is_monkey_patched = True
QgsStringUtils.UpperCamelCase.__doc__ = "Convert the string to upper camel case. Note that this method does not unaccent characters."
QgsStringUtils.AllSmallCaps = Qgis.Capitalization.AllSmallCaps
QgsStringUtils.AllSmallCaps.is_monkey_patched = True
QgsStringUtils.AllSmallCaps.__doc__ = "Force all characters to small caps (since QGIS 3.24)"
Qgis.Capitalization.__doc__ = 'String capitalization options.\n\n.. note::\n\n Prior to QGIS 3.24 this was available as :py:class:`QgsStringUtils`.Capitalization\n\n.. versionadded:: 3.24\n\n' + '* ``MixedCase``: ' + Qgis.Capitalization.MixedCase.__doc__ + '\n' + '* ``AllUppercase``: ' + Qgis.Capitalization.AllUppercase.__doc__ + '\n' + '* ``AllLowercase``: ' + Qgis.Capitalization.AllLowercase.__doc__ + '\n' + '* ``ForceFirstLetterToCapital``: ' + Qgis.Capitalization.ForceFirstLetterToCapital.__doc__ + '\n' + '* ``SmallCaps``: ' + Qgis.Capitalization.SmallCaps.__doc__ + '\n' + '* ``TitleCase``: ' + Qgis.Capitalization.TitleCase.__doc__ + '\n' + '* ``UpperCamelCase``: ' + Qgis.Capitalization.UpperCamelCase.__doc__ + '\n' + '* ``AllSmallCaps``: ' + Qgis.Capitalization.AllSmallCaps.__doc__
# --
Qgis.Capitalization.baseClass = Qgis

View File

@ -732,6 +732,20 @@ The development version
ScaleGapOnly,
};
enum class Capitalization
{
MixedCase,
AllUppercase,
AllLowercase,
ForceFirstLetterToCapital,
SmallCaps,
TitleCase,
UpperCamelCase,
AllSmallCaps,
};
static const double DEFAULT_SEARCH_RADIUS_MM;
static const float DEFAULT_MAPTOPIXEL_THRESHOLD;

View File

@ -169,17 +169,7 @@ Utility functions for working with strings.
%End
public:
enum Capitalization
{
MixedCase,
AllUppercase,
AllLowercase,
ForceFirstLetterToCapital,
TitleCase,
UpperCamelCase,
};
static QString capitalize( const QString &string, Capitalization capitalization );
static QString capitalize( const QString &string, Qgis::Capitalization capitalization );
%Docstring
Converts a string by applying capitalization rules to the string.

View File

@ -64,7 +64,7 @@ Returns ``True`` if the block is empty.
Returns the number of fragments in the block.
%End
void applyCapitalization( QgsStringUtils::Capitalization capitalization );
void applyCapitalization( Qgis::Capitalization capitalization );
%Docstring
Applies a ``capitalization`` style to the block's text.

View File

@ -116,7 +116,7 @@ argument controls whether the lines should be wrapped to an ideal maximum of ``a
if ``False`` then the lines are wrapped to an ideal minimum length of ``autoWrapLength`` characters.
%End
void applyCapitalization( QgsStringUtils::Capitalization capitalization );
void applyCapitalization( Qgis::Capitalization capitalization );
%Docstring
Applies a ``capitalization`` style to the document's text.

View File

@ -402,7 +402,7 @@ Sets the ``orientation`` for the text.
.. versionadded:: 3.10
%End
QgsStringUtils::Capitalization capitalization() const;
Qgis::Capitalization capitalization() const;
%Docstring
Returns the text capitalization style.
@ -411,7 +411,7 @@ Returns the text capitalization style.
.. versionadded:: 3.16
%End
void setCapitalization( QgsStringUtils::Capitalization capitalization );
void setCapitalization( Qgis::Capitalization capitalization );
%Docstring
Sets the text ``capitalization`` style.

View File

@ -78,7 +78,7 @@ based on the resultant font metrics. Failure to do so will result in poor qualit
at small font sizes.
%End
void applyCapitalization( QgsStringUtils::Capitalization capitalization );
void applyCapitalization( Qgis::Capitalization capitalization );
%Docstring
Applies a ``capitalization`` style to the fragment's text.

View File

@ -9660,7 +9660,7 @@ bool QgisApp::uniqueLayoutTitle( QWidget *parent, QString &title, bool acceptEmp
layoutNames << l->name();
}
const QString windowTitle = tr( "Create %1" ).arg( QgsGui::higFlags() & QgsGui::HigDialogTitleIsTitleCase ? QgsStringUtils::capitalize( typeString, QgsStringUtils::TitleCase )
const QString windowTitle = tr( "Create %1" ).arg( QgsGui::higFlags() & QgsGui::HigDialogTitleIsTitleCase ? QgsStringUtils::capitalize( typeString, Qgis::Capitalization::TitleCase )
: typeString );
while ( !titleValid )

View File

@ -1897,11 +1897,11 @@ std::unique_ptr<QgsLabelFeature> QgsPalLayerSettings::registerFeatureWithDetails
}
// apply capitalization
QgsStringUtils::Capitalization capitalization = mFormat.capitalization();
Qgis::Capitalization capitalization = mFormat.capitalization();
// maintain API - capitalization may have been set in textFont
if ( capitalization == QgsStringUtils::MixedCase && mFormat.font().capitalization() != QFont::MixedCase )
if ( capitalization == Qgis::Capitalization::MixedCase && mFormat.font().capitalization() != QFont::MixedCase )
{
capitalization = static_cast< QgsStringUtils::Capitalization >( mFormat.font().capitalization() );
capitalization = static_cast< Qgis::Capitalization >( mFormat.font().capitalization() );
}
// data defined font capitalization?
if ( mDataDefinedProperties.isActive( QgsPalLayerSettings::FontCase ) )
@ -1916,24 +1916,34 @@ std::unique_ptr<QgsLabelFeature> QgsPalLayerSettings::registerFeatureWithDetails
{
if ( fcase.compare( QLatin1String( "NoChange" ), Qt::CaseInsensitive ) == 0 )
{
capitalization = QgsStringUtils::MixedCase;
capitalization = Qgis::Capitalization::MixedCase;
}
else if ( fcase.compare( QLatin1String( "Upper" ), Qt::CaseInsensitive ) == 0 )
{
capitalization = QgsStringUtils::AllUppercase;
capitalization = Qgis::Capitalization::AllUppercase;
}
else if ( fcase.compare( QLatin1String( "Lower" ), Qt::CaseInsensitive ) == 0 )
{
capitalization = QgsStringUtils::AllLowercase;
capitalization = Qgis::Capitalization::AllLowercase;
}
else if ( fcase.compare( QLatin1String( "Capitalize" ), Qt::CaseInsensitive ) == 0 )
{
capitalization = QgsStringUtils::ForceFirstLetterToCapital;
capitalization = Qgis::Capitalization::ForceFirstLetterToCapital;
}
else if ( fcase.compare( QLatin1String( "Title" ), Qt::CaseInsensitive ) == 0 )
{
capitalization = QgsStringUtils::TitleCase;
capitalization = Qgis::Capitalization::TitleCase;
}
#if defined(HAS_KDE_QT5_SMALL_CAPS_FIX) || QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
else if ( fcase.compare( QLatin1String( "SmallCaps" ), Qt::CaseInsensitive ) == 0 )
{
capitalization = Qgis::Capitalization::SmallCaps;
}
else if ( fcase.compare( QLatin1String( "AllSmallCaps" ), Qt::CaseInsensitive ) == 0 )
{
capitalization = Qgis::Capitalization::AllSmallCaps;
}
#endif
}
}
}

View File

@ -294,18 +294,18 @@ void QgsAbstractVectorLayerLabeling::writeTextSymbolizer( QDomNode &parent, QgsP
}
else
{
QgsStringUtils::Capitalization capitalization = format.capitalization();
if ( capitalization == QgsStringUtils::MixedCase && font.capitalization() != QFont::MixedCase )
capitalization = static_cast< QgsStringUtils::Capitalization >( font.capitalization() );
if ( capitalization == QgsStringUtils::AllUppercase )
Qgis::Capitalization capitalization = format.capitalization();
if ( capitalization == Qgis::Capitalization::MixedCase && font.capitalization() != QFont::MixedCase )
capitalization = static_cast< Qgis::Capitalization >( font.capitalization() );
if ( capitalization == Qgis::Capitalization::AllUppercase )
{
appendSimpleFunction( doc, labelElement, QStringLiteral( "strToUpperCase" ), settings.fieldName );
}
else if ( capitalization == QgsStringUtils::AllLowercase )
else if ( capitalization == Qgis::Capitalization::AllLowercase )
{
appendSimpleFunction( doc, labelElement, QStringLiteral( "strToLowerCase" ), settings.fieldName );
}
else if ( capitalization == QgsStringUtils::ForceFirstLetterToCapital )
else if ( capitalization == Qgis::Capitalization::ForceFirstLetterToCapital )
{
appendSimpleFunction( doc, labelElement, QStringLiteral( "strCapitalize" ), settings.fieldName );
}

View File

@ -1219,7 +1219,7 @@ void QgsLayoutExporter::preparePrintAsPdf( QgsLayout *layout, QPrinter &printer,
// May not work on Windows or non-X11 Linux. Works fine on Mac using QPrinter::NativeFormat
//printer.setFontEmbeddingEnabled( true );
#if defined(WITH_QT5_KDE_FORK) || QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
#if defined(HAS_KDE_QT5_PDF_TRANSFORM_FIX) || QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
// paint engine hack not required, fixed upstream
#else
QgsPaintEngineHack::fixEngineFlags( printer.paintEngine() );

View File

@ -488,7 +488,7 @@ QStringList QgsProcessingModelAlgorithm::asPythonCode( const QgsProcessing::Pyth
n.replace( rx2, QString() );
if ( !capitalize )
n = n.replace( ' ', '_' );
return capitalize ? QgsStringUtils::capitalize( n, QgsStringUtils::UpperCamelCase ) : n;
return capitalize ? QgsStringUtils::capitalize( n, Qgis::Capitalization::UpperCamelCase ) : n;
};
auto uniqueSafeName = [ &safeName ]( const QString & name, bool capitalize, const QMap< QString, QString > &friendlyNames )->QString

View File

@ -1196,6 +1196,29 @@ class CORE_EXPORT Qgis
};
Q_ENUM( DashPatternSizeAdjustment )
// NOTE -- the hardcoded numbers here must match QFont::Capitalization!
/**
* String capitalization options.
*
* \note Prior to QGIS 3.24 this was available as QgsStringUtils::Capitalization
*
* \since QGIS 3.24
*/
enum class Capitalization SIP_MONKEYPATCH_SCOPEENUM_UNNEST( QgsStringUtils, Capitalization ) : int
{
MixedCase = 0, //!< Mixed case, ie no change
AllUppercase = 1, //!< Convert all characters to uppercase
AllLowercase = 2, //!< Convert all characters to lowercase
ForceFirstLetterToCapital = 4, //!< Convert just the first letter of each word to uppercase, leave the rest untouched
SmallCaps = 5, //!< Mixed case small caps (since QGIS 3.24)
TitleCase = 1004, //!< Simple title case conversion - does not fully grammatically parse the text and uses simple rules only. Note that this method does not convert any characters to lowercase, it only uppercases required letters. Callers must ensure that input strings are already lowercased.
UpperCamelCase = 1005, //!< Convert the string to upper camel case. Note that this method does not unaccent characters.
AllSmallCaps = 1006, //!< Force all characters to small caps (since QGIS 3.24)
};
Q_ENUM( Capitalization )
/**
* Identify search radius in mm
* \since QGIS 2.3

View File

@ -953,7 +953,7 @@ QString QgsMapLayer::formatLayerName( const QString &name )
{
QString layerName( name );
layerName.replace( '_', ' ' );
layerName = QgsStringUtils::capitalize( layerName, QgsStringUtils::ForceFirstLetterToCapital );
layerName = QgsStringUtils::capitalize( layerName, Qgis::Capitalization::ForceFirstLetterToCapital );
return layerName;
}

View File

@ -21,7 +21,7 @@
// Hack to workaround Qt #5114 by disabling PatternTransform
void QgsPaintEngineHack::fixFlags()
{
#if defined(WITH_QT5_KDE_FORK) || QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
#if defined(HAS_KDE_QT5_PDF_TRANSFORM_FIX) || QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
// not required, fixed upstream
#else
gccaps = PaintEngineFeatures();
@ -50,7 +50,7 @@ void QgsPaintEngineHack::fixFlags()
void QgsPaintEngineHack::fixEngineFlags( QPaintEngine *engine )
{
#if defined(WITH_QT5_KDE_FORK) || QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
#if defined(HAS_KDE_QT5_PDF_TRANSFORM_FIX) || QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
// not required, fixed upstream
( void )engine;
#else

View File

@ -21,23 +21,25 @@
#include <QRegularExpression>
#include <cstdlib> // for std::abs
QString QgsStringUtils::capitalize( const QString &string, QgsStringUtils::Capitalization capitalization )
QString QgsStringUtils::capitalize( const QString &string, Qgis::Capitalization capitalization )
{
if ( string.isEmpty() )
return QString();
switch ( capitalization )
{
case MixedCase:
case Qgis::Capitalization::MixedCase:
case Qgis::Capitalization::SmallCaps:
return string;
case AllUppercase:
case Qgis::Capitalization::AllUppercase:
return string.toUpper();
case AllLowercase:
case Qgis::Capitalization::AllLowercase:
case Qgis::Capitalization::AllSmallCaps:
return string.toLower();
case ForceFirstLetterToCapital:
case Qgis::Capitalization::ForceFirstLetterToCapital:
{
QString temp = string;
@ -58,7 +60,7 @@ QString QgsStringUtils::capitalize( const QString &string, QgsStringUtils::Capit
return temp;
}
case TitleCase:
case Qgis::Capitalization::TitleCase:
{
// yes, this is MASSIVELY simplifying the problem!!
@ -103,8 +105,8 @@ QString QgsStringUtils::capitalize( const QString &string, QgsStringUtils::Capit
return result;
}
case UpperCamelCase:
QString result = QgsStringUtils::capitalize( string.toLower(), QgsStringUtils::ForceFirstLetterToCapital ).simplified();
case Qgis::Capitalization::UpperCamelCase:
QString result = QgsStringUtils::capitalize( string.toLower(), Qgis::Capitalization::ForceFirstLetterToCapital ).simplified();
result.remove( ' ' );
return result;
}
@ -669,7 +671,7 @@ QString QgsStringUtils::wordWrap( const QString &string, const int length, const
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 2)
newstr.append( line.midRef( strCurrent ) );
#else
newstr.append( QStringView {line}.mid( strCurrent ) );
newstr.append( QStringView {line} .mid( strCurrent ) );
#endif
strCurrent = strLength;
}

View File

@ -20,7 +20,6 @@
#include <QRegularExpression>
#include <QList>
#include <QDomDocument>
#include <QFont> // for enum values
#ifndef QGSSTRINGUTILS_H
#define QGSSTRINGUTILS_H
@ -185,17 +184,6 @@ class CORE_EXPORT QgsStringUtils
{
public:
//! Capitalization options
enum Capitalization
{
MixedCase = QFont::MixedCase, //!< Mixed case, ie no change
AllUppercase = QFont::AllUppercase, //!< Convert all characters to uppercase
AllLowercase = QFont::AllLowercase, //!< Convert all characters to lowercase
ForceFirstLetterToCapital = QFont::Capitalize, //!< Convert just the first letter of each word to uppercase, leave the rest untouched
TitleCase = QFont::Capitalize + 1000, //!< Simple title case conversion - does not fully grammatically parse the text and uses simple rules only. Note that this method does not convert any characters to lowercase, it only uppercases required letters. Callers must ensure that input strings are already lowercased.
UpperCamelCase = QFont::Capitalize + 1001, //!< Convert the string to upper camel case. Note that this method does not unaccent characters.
};
/**
* Converts a string by applying capitalization rules to the string.
* \param string input string
@ -203,7 +191,7 @@ class CORE_EXPORT QgsStringUtils
* \returns capitalized string
* \since QGIS 3.0
*/
static QString capitalize( const QString &string, Capitalization capitalization );
static QString capitalize( const QString &string, Qgis::Capitalization capitalization );
/**
* Makes a raw string safe for inclusion as a HTML/XML string literal.

View File

@ -56,7 +56,7 @@ int QgsTextBlock::size() const
return mFragments.size();
}
void QgsTextBlock::applyCapitalization( QgsStringUtils::Capitalization capitalization )
void QgsTextBlock::applyCapitalization( Qgis::Capitalization capitalization )
{
for ( QgsTextFragment &fragment : mFragments )
{

View File

@ -84,7 +84,7 @@ class CORE_EXPORT QgsTextBlock
*
* \since QGIS 3.16
*/
void applyCapitalization( QgsStringUtils::Capitalization capitalization );
void applyCapitalization( Qgis::Capitalization capitalization );
#ifdef SIP_RUN
int __len__() const;

View File

@ -187,7 +187,7 @@ void QgsTextDocument::splitLines( const QString &wrapCharacter, int autoWrapLeng
}
}
void QgsTextDocument::applyCapitalization( QgsStringUtils::Capitalization capitalization )
void QgsTextDocument::applyCapitalization( Qgis::Capitalization capitalization )
{
for ( QgsTextBlock &block : mBlocks )
{

View File

@ -152,7 +152,7 @@ class CORE_EXPORT QgsTextDocument
*
* \since QGIS 3.16
*/
void applyCapitalization( QgsStringUtils::Capitalization capitalization );
void applyCapitalization( Qgis::Capitalization capitalization );
#ifndef SIP_RUN
///@cond PRIVATE

View File

@ -22,6 +22,7 @@
#include "qgspainting.h"
#include "qgstextrendererutils.h"
#include "qgspallabeling.h"
#include "qgsconfig.h"
#include <QFontDatabase>
#include <QMimeData>
#include <QWidget>
@ -194,6 +195,10 @@ QFont QgsTextFormat::scaledFont( const QgsRenderContext &context, double scaleFa
font.setLetterSpacing( QFont::AbsoluteSpacing, context.convertToPainterUnits( d->textFont.letterSpacing(), d->fontSizeUnits, d->fontSizeMapUnitScale ) * scaleFactor );
font.setWordSpacing( context.convertToPainterUnits( d->textFont.wordSpacing(), d->fontSizeUnits, d->fontSizeMapUnitScale ) * scaleFactor * scaleFactor );
if ( d->capitalization == Qgis::Capitalization::SmallCaps
|| d->capitalization == Qgis::Capitalization::AllSmallCaps )
font.setCapitalization( QFont::SmallCaps );
return font;
}
@ -318,17 +323,23 @@ void QgsTextFormat::setOrientation( TextOrientation orientation )
d->orientation = orientation;
}
QgsStringUtils::Capitalization QgsTextFormat::capitalization() const
Qgis::Capitalization QgsTextFormat::capitalization() const
{
// bit of complexity here to maintain API..
return d->capitalization == QgsStringUtils::MixedCase && d->textFont.capitalization() != QFont::MixedCase ? static_cast< QgsStringUtils::Capitalization >( d->textFont.capitalization() ) : d->capitalization ;
return d->capitalization == Qgis::Capitalization::MixedCase && d->textFont.capitalization() != QFont::MixedCase
? static_cast< Qgis::Capitalization >( d->textFont.capitalization() )
: d->capitalization ;
}
void QgsTextFormat::setCapitalization( QgsStringUtils::Capitalization capitalization )
void QgsTextFormat::setCapitalization( Qgis::Capitalization capitalization )
{
d->isValid = true;
d->capitalization = capitalization;
#if defined(HAS_KDE_QT5_SMALL_CAPS_FIX) || QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
d->textFont.setCapitalization( capitalization == Qgis::Capitalization::SmallCaps || capitalization == Qgis::Capitalization::AllSmallCaps ? QFont::SmallCaps : QFont::MixedCase );
#else
d->textFont.setCapitalization( QFont::MixedCase );
#endif
}
bool QgsTextFormat::allowHtmlFormatting() const
@ -413,7 +424,7 @@ void QgsTextFormat::readFromLayer( QgsVectorLayer *layer )
d->textFont = QFont( fontFamily, d->fontSize, fontWeight, fontItalic );
d->textNamedStyle = QgsFontUtils::translateNamedStyle( layer->customProperty( QStringLiteral( "labeling/namedStyle" ), QVariant( "" ) ).toString() );
QgsFontUtils::updateFontViaStyle( d->textFont, d->textNamedStyle ); // must come after textFont.setPointSizeF()
d->capitalization = static_cast< QgsStringUtils::Capitalization >( layer->customProperty( QStringLiteral( "labeling/fontCapitals" ), QVariant( 0 ) ).toUInt() );
d->capitalization = static_cast< Qgis::Capitalization >( layer->customProperty( QStringLiteral( "labeling/fontCapitals" ), QVariant( 0 ) ).toUInt() );
d->textFont.setUnderline( layer->customProperty( QStringLiteral( "labeling/fontUnderline" ) ).toBool() );
d->textFont.setStrikeOut( layer->customProperty( QStringLiteral( "labeling/fontStrikeout" ) ).toBool() );
d->textFont.setLetterSpacing( QFont::AbsoluteSpacing, layer->customProperty( QStringLiteral( "labeling/fontLetterSpacing" ), QVariant( 0.0 ) ).toDouble() );
@ -557,9 +568,12 @@ void QgsTextFormat::readXml( const QDomElement &elem, const QgsReadWriteContext
}
if ( textStyleElem.hasAttribute( QStringLiteral( "capitalization" ) ) )
d->capitalization = static_cast< QgsStringUtils::Capitalization >( textStyleElem.attribute( QStringLiteral( "capitalization" ), QString::number( QgsStringUtils::MixedCase ) ).toInt() );
d->capitalization = static_cast< Qgis::Capitalization >( textStyleElem.attribute( QStringLiteral( "capitalization" ), QString::number( static_cast< int >( Qgis::Capitalization::MixedCase ) ) ).toInt() );
else
d->capitalization = static_cast< QgsStringUtils::Capitalization >( textStyleElem.attribute( QStringLiteral( "fontCapitals" ), QStringLiteral( "0" ) ).toUInt() );
d->capitalization = static_cast< Qgis::Capitalization >( textStyleElem.attribute( QStringLiteral( "fontCapitals" ), QStringLiteral( "0" ) ).toUInt() );
if ( d->capitalization == Qgis::Capitalization::SmallCaps || d->capitalization == Qgis::Capitalization::AllSmallCaps )
d->textFont.setCapitalization( QFont::SmallCaps );
d->allowHtmlFormatting = textStyleElem.attribute( QStringLiteral( "allowHtml" ), QStringLiteral( "0" ) ).toInt();

View File

@ -374,7 +374,7 @@ class CORE_EXPORT QgsTextFormat
* \see setCapitalization()
* \since QGIS 3.16
*/
QgsStringUtils::Capitalization capitalization() const;
Qgis::Capitalization capitalization() const;
/**
* Sets the text \a capitalization style.
@ -382,7 +382,7 @@ class CORE_EXPORT QgsTextFormat
* \see capitalization()
* \since QGIS 3.16
*/
void setCapitalization( QgsStringUtils::Capitalization capitalization );
void setCapitalization( Qgis::Capitalization capitalization );
/**
* Returns TRUE if text should be treated as a HTML document and HTML tags should be used for formatting

View File

@ -16,6 +16,7 @@
#include "qgstextfragment.h"
#include <QFontMetricsF>
#include <QTextFragment>
#include "qgsstringutils.h"
QgsTextFragment::QgsTextFragment( const QString &text, const QgsTextCharacterFormat &format )
: mText( text )
@ -60,7 +61,7 @@ double QgsTextFragment::horizontalAdvance( const QFont &font, bool fontHasBeenUp
}
}
void QgsTextFragment::applyCapitalization( QgsStringUtils::Capitalization capitalization )
void QgsTextFragment::applyCapitalization( Qgis::Capitalization capitalization )
{
mText = QgsStringUtils::capitalize( mText, capitalization );
}

View File

@ -19,7 +19,7 @@
#include "qgis_sip.h"
#include "qgis_core.h"
#include "qgstextcharacterformat.h"
#include "qgsstringutils.h"
#include "qgis.h"
class QTextFragment;
@ -93,7 +93,7 @@ class CORE_EXPORT QgsTextFragment
*
* \since QGIS 3.16
*/
void applyCapitalization( QgsStringUtils::Capitalization capitalization );
void applyCapitalization( Qgis::Capitalization capitalization );
private:

View File

@ -298,7 +298,7 @@ class QgsTextSettingsPrivate : public QSharedData
QgsTextFormat::TextOrientation orientation = QgsTextFormat::HorizontalOrientation;
QColor previewBackgroundColor = Qt::white;
bool allowHtmlFormatting = false;
QgsStringUtils::Capitalization capitalization = QgsStringUtils::MixedCase;
Qgis::Capitalization capitalization = Qgis::Capitalization::MixedCase;
//! Property collection for data defined settings
QgsPropertyCollection mDataDefinedProperties;

View File

@ -152,7 +152,7 @@ void QgsProcessingAlgorithmDialogBase::setAlgorithm( QgsProcessingAlgorithm *alg
QString title;
if ( ( QgsGui::higFlags() & QgsGui::HigDialogTitleIsTitleCase ) && !( algorithm->flags() & QgsProcessingAlgorithm::FlagDisplayNameIsLiteral ) )
{
title = QgsStringUtils::capitalize( mAlgorithm->displayName(), QgsStringUtils::TitleCase );
title = QgsStringUtils::capitalize( mAlgorithm->displayName(), Qgis::Capitalization::TitleCase );
}
else
{

View File

@ -39,6 +39,7 @@
#include "qgsfillsymbol.h"
#include "qgsiconutils.h"
#include "qgssymbollayerreference.h"
#include "qgsconfig.h"
#include <QButtonGroup>
#include <QMessageBox>
@ -895,7 +896,7 @@ void QgsTextFormatWidget::updateWidgetForFormat( const QgsTextFormat &format )
mFontLetterSpacingSpinBox->setValue( format.font().letterSpacing() );
whileBlocking( mKerningCheckBox )->setChecked( format.font().kerning() );
whileBlocking( mFontCapitalsComboBox )->setCurrentIndex( mFontCapitalsComboBox->findData( format.capitalization() ) );
whileBlocking( mFontCapitalsComboBox )->setCurrentIndex( mFontCapitalsComboBox->findData( static_cast< int >( format.capitalization() ) ) );
QgsFontUtils::updateFontViaStyle( mRefFont, format.namedStyle() );
updateFont( mRefFont );
@ -1031,7 +1032,7 @@ QgsTextFormat QgsTextFormatWidget::format( bool includeDataDefinedProperties ) c
format.setPreviewBackgroundColor( mPreviewBackgroundColor );
format.setOrientation( static_cast< QgsTextFormat::TextOrientation >( mTextOrientationComboBox->currentData().toInt() ) );
format.setAllowHtmlFormatting( mHtmlFormattingCheckBox->isChecked( ) );
format.setCapitalization( static_cast< QgsStringUtils::Capitalization >( mFontCapitalsComboBox->currentData().toInt() ) );
format.setCapitalization( static_cast< Qgis::Capitalization >( mFontCapitalsComboBox->currentData().toInt() ) );
// buffer
QgsTextBufferSettings buffer;
@ -1422,14 +1423,17 @@ void QgsTextFormatWidget::updatePlacementWidgets()
void QgsTextFormatWidget::populateFontCapitalsComboBox()
{
mFontCapitalsComboBox->addItem( tr( "No Change" ), QgsStringUtils::MixedCase );
mFontCapitalsComboBox->addItem( tr( "All Uppercase" ), QgsStringUtils::AllUppercase );
mFontCapitalsComboBox->addItem( tr( "All Lowercase" ), QgsStringUtils::AllLowercase );
// Small caps doesn't work right with QPainterPath::addText()
mFontCapitalsComboBox->addItem( tr( "No Change" ), static_cast< int >( Qgis::Capitalization::MixedCase ) );
mFontCapitalsComboBox->addItem( tr( "All Uppercase" ), static_cast< int >( Qgis::Capitalization::AllUppercase ) );
mFontCapitalsComboBox->addItem( tr( "All Lowercase" ), static_cast< int >( Qgis::Capitalization::AllLowercase ) );
#if defined(HAS_KDE_QT5_SMALL_CAPS_FIX) || QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
// Requires new enough build due to
// https://bugreports.qt.io/browse/QTBUG-13965
// mFontCapitalsComboBox->addItem( tr( "Small Caps" ), QVariant( 3 ) );
mFontCapitalsComboBox->addItem( tr( "Title Case" ), QgsStringUtils::TitleCase );
mFontCapitalsComboBox->addItem( tr( "Force First Letter to Capital" ), QgsStringUtils::ForceFirstLetterToCapital );
mFontCapitalsComboBox->addItem( tr( "Small Caps" ), static_cast< int >( Qgis::Capitalization::SmallCaps ) );
mFontCapitalsComboBox->addItem( tr( "All Small Caps" ), static_cast< int >( Qgis::Capitalization::AllSmallCaps ) );
#endif
mFontCapitalsComboBox->addItem( tr( "Title Case" ), static_cast< int >( Qgis::Capitalization::TitleCase ) );
mFontCapitalsComboBox->addItem( tr( "Force First Letter to Capital" ), static_cast< int >( Qgis::Capitalization::ForceFirstLetterToCapital ) );
}
void QgsTextFormatWidget::populateFontStyleComboBox()

View File

@ -77,7 +77,7 @@ QgsVectorLayerTemporalPropertiesWidget::QgsVectorLayerTemporalPropertiesWidget(
QgsUnitTypes::TemporalCenturies
} )
{
const QString title = ( QgsGui::higFlags() & QgsGui::HigDialogTitleIsTitleCase ) ? QgsStringUtils::capitalize( QgsUnitTypes::toString( u ), QgsStringUtils::TitleCase )
const QString title = ( QgsGui::higFlags() & QgsGui::HigDialogTitleIsTitleCase ) ? QgsStringUtils::capitalize( QgsUnitTypes::toString( u ), Qgis::Capitalization::TitleCase )
: QgsUnitTypes::toString( u );
mDurationUnitsComboBox->addItem( title, u );
mFixedDurationUnitsComboBox->addItem( title, u );

View File

@ -694,7 +694,7 @@ void TestQgsLabelingEngine::testCapitalization()
QCOMPARE( provider2->mLabels.at( 0 )->labelText(), QString( "A TEST LABEL" ) );
font.setCapitalization( QFont::MixedCase );
format.setCapitalization( QgsStringUtils::AllUppercase );
format.setCapitalization( Qgis::Capitalization::AllUppercase );
format.setFont( font );
settings.setFormat( format );
QgsVectorLayerLabelProvider *provider2b = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test2" ), true, &settings );
@ -705,7 +705,7 @@ void TestQgsLabelingEngine::testCapitalization()
//lowercase
font.setCapitalization( QFont::AllLowercase );
format.setCapitalization( QgsStringUtils::MixedCase );
format.setCapitalization( Qgis::Capitalization::MixedCase );
format.setFont( font );
settings.setFormat( format );
QgsVectorLayerLabelProvider *provider3 = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test3" ), true, &settings );
@ -715,7 +715,7 @@ void TestQgsLabelingEngine::testCapitalization()
QCOMPARE( provider3->mLabels.at( 0 )->labelText(), QString( "a test label" ) );
font.setCapitalization( QFont::MixedCase );
format.setCapitalization( QgsStringUtils::AllLowercase );
format.setCapitalization( Qgis::Capitalization::AllLowercase );
format.setFont( font );
settings.setFormat( format );
QgsVectorLayerLabelProvider *provider3b = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test3" ), true, &settings );
@ -726,7 +726,7 @@ void TestQgsLabelingEngine::testCapitalization()
//first letter uppercase
font.setCapitalization( QFont::Capitalize );
format.setCapitalization( QgsStringUtils::MixedCase );
format.setCapitalization( Qgis::Capitalization::MixedCase );
format.setFont( font );
settings.setFormat( format );
QgsVectorLayerLabelProvider *provider4 = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test4" ), true, &settings );
@ -736,7 +736,7 @@ void TestQgsLabelingEngine::testCapitalization()
QCOMPARE( provider4->mLabels.at( 0 )->labelText(), QString( "A TeSt LABEL" ) );
font.setCapitalization( QFont::MixedCase );
format.setCapitalization( QgsStringUtils::ForceFirstLetterToCapital );
format.setCapitalization( Qgis::Capitalization::ForceFirstLetterToCapital );
format.setFont( font );
settings.setFormat( format );
QgsVectorLayerLabelProvider *provider4b = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test4" ), true, &settings );
@ -746,7 +746,7 @@ void TestQgsLabelingEngine::testCapitalization()
QCOMPARE( provider4b->mLabels.at( 0 )->labelText(), QString( "A TeSt LABEL" ) );
settings.fieldName = QStringLiteral( "'A TEST LABEL'" );
format.setCapitalization( QgsStringUtils::TitleCase );
format.setCapitalization( Qgis::Capitalization::TitleCase );
format.setFont( font );
settings.setFormat( format );
QgsVectorLayerLabelProvider *provider5 = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test4" ), true, &settings );

View File

@ -192,16 +192,16 @@ void TestQgsStringUtils::titleCase()
{
QFETCH( QString, input );
QFETCH( QString, expected );
QCOMPARE( QgsStringUtils::capitalize( input, QgsStringUtils::TitleCase ), expected );
QCOMPARE( QgsStringUtils::capitalize( input, Qgis::Capitalization::TitleCase ), expected );
}
void TestQgsStringUtils::camelCase()
{
QCOMPARE( QgsStringUtils::capitalize( QString(), QgsStringUtils::UpperCamelCase ), QString() );
QCOMPARE( QgsStringUtils::capitalize( QString( " abc def" ), QgsStringUtils::UpperCamelCase ), QString( "AbcDef" ) );
QCOMPARE( QgsStringUtils::capitalize( QString( "ABC DEF" ), QgsStringUtils::UpperCamelCase ), QString( "AbcDef" ) );
QCOMPARE( QgsStringUtils::capitalize( QString( "àbc def" ), QgsStringUtils::UpperCamelCase ), QString( "ÀbcDef" ) );
QCOMPARE( QgsStringUtils::capitalize( QString( "àbc dÉf" ), QgsStringUtils::UpperCamelCase ), QString( "ÀbcDéf" ) );
QCOMPARE( QgsStringUtils::capitalize( QString(), Qgis::Capitalization::UpperCamelCase ), QString() );
QCOMPARE( QgsStringUtils::capitalize( QString( " abc def" ), Qgis::Capitalization::UpperCamelCase ), QString( "AbcDef" ) );
QCOMPARE( QgsStringUtils::capitalize( QString( "ABC DEF" ), Qgis::Capitalization::UpperCamelCase ), QString( "AbcDef" ) );
QCOMPARE( QgsStringUtils::capitalize( QString( "àbc def" ), Qgis::Capitalization::UpperCamelCase ), QString( "ÀbcDef" ) );
QCOMPARE( QgsStringUtils::capitalize( QString( "àbc dÉf" ), Qgis::Capitalization::UpperCamelCase ), QString( "ÀbcDéf" ) );
}
void TestQgsStringUtils::htmlToMarkdown()