From ad29f280335da15bc074646a21874abc2aa60d72 Mon Sep 17 00:00:00 2001 From: Damiano Date: Wed, 10 Mar 2021 20:21:16 +0100 Subject: [PATCH 001/377] SettingsEntry new methods exists and remove --- src/app/locator/qgslocatoroptionswidget.cpp | 10 +- src/app/options/qgsoptions.cpp | 3 +- src/core/CMakeLists.txt | 9 + src/core/layout/qgslayout.h | 9 + src/core/locator/qgslocator.cpp | 13 +- src/core/locator/qgslocator.h | 17 + src/core/qgsapplication.cpp | 14 +- src/core/qgsapplication.h | 8 + src/core/settings/qgssettingsentry.cpp | 382 +++++++++++++++ src/core/settings/qgssettingsentry.h | 461 ++++++++++++++++++ src/core/settings/qgssettingsregistrycore.cpp | 36 ++ src/core/settings/qgssettingsregistrycore.h | 50 ++ 12 files changed, 997 insertions(+), 15 deletions(-) create mode 100644 src/core/settings/qgssettingsentry.cpp create mode 100644 src/core/settings/qgssettingsentry.h create mode 100644 src/core/settings/qgssettingsregistrycore.cpp create mode 100644 src/core/settings/qgssettingsregistrycore.h diff --git a/src/app/locator/qgslocatoroptionswidget.cpp b/src/app/locator/qgslocatoroptionswidget.cpp index 35c1bb73e6b8..66a079732f8d 100644 --- a/src/app/locator/qgslocatoroptionswidget.cpp +++ b/src/app/locator/qgslocatoroptionswidget.cpp @@ -322,8 +322,6 @@ QVariant QgsLocatorFiltersModel::headerData( int section, Qt::Orientation orient void QgsLocatorFiltersModel::commitChanges() { - QgsSettings settings; - QHash< QgsLocatorFilter *, QString >::const_iterator itp = mPrefixes.constBegin(); for ( ; itp != mPrefixes.constEnd(); ++itp ) { @@ -332,26 +330,26 @@ void QgsLocatorFiltersModel::commitChanges() if ( !activePrefix.isEmpty() && activePrefix != filter->prefix() ) { filter->setActivePrefix( activePrefix ); - settings.setValue( QStringLiteral( "locator_filters/prefix_%1" ).arg( filter->name() ), activePrefix, QgsSettings::Section::Gui ); + QgsLocator::Settings::LocatorFilterPrefix().setValue( activePrefix, filter->name() ); } else { filter->setActivePrefix( QString() ); - settings.remove( QStringLiteral( "locator_filters/prefix_%1" ).arg( filter->name() ), QgsSettings::Section::Gui ); + QgsLocator::Settings::LocatorFilterPrefix().remove( filter->name() ); } } QHash< QgsLocatorFilter *, bool >::const_iterator it = mEnabledChanges.constBegin(); for ( ; it != mEnabledChanges.constEnd(); ++it ) { QgsLocatorFilter *filter = it.key(); - settings.setValue( QStringLiteral( "locator_filters/enabled_%1" ).arg( filter->name() ), it.value(), QgsSettings::Section::Gui ); + QgsLocator::Settings::LocatorFilterEnabled().setValue( it.value(), filter->name() ); filter->setEnabled( it.value() ); } it = mDefaultChanges.constBegin(); for ( ; it != mDefaultChanges.constEnd(); ++it ) { QgsLocatorFilter *filter = it.key(); - settings.setValue( QStringLiteral( "locator_filters/default_%1" ).arg( filter->name() ), it.value(), QgsSettings::Section::Gui ); + QgsLocator::Settings::LocatorFilterDefault().setValue( it.value(), filter->name() ); filter->setUseWithoutPrefix( it.value() ); } } diff --git a/src/app/options/qgsoptions.cpp b/src/app/options/qgsoptions.cpp index 9072f7567e07..b9e7550d4a08 100644 --- a/src/app/options/qgsoptions.cpp +++ b/src/app/options/qgsoptions.cpp @@ -62,6 +62,7 @@ #include "qgsbearingnumericformat.h" #include "qgssublayersdialog.h" #include "options/qgsadvancedoptions.h" +#include "qgslayout.h" #ifdef HAVE_OPENCL #include "qgsopenclutils.h" @@ -1480,7 +1481,7 @@ void QgsOptions::saveOptions() { pathsList << mListComposerTemplatePaths->item( i )->text(); } - mSettings->setValue( QStringLiteral( "Layout/searchPathsForTemplates" ), pathsList, QgsSettings::Core ); + QgsLayout::Settings::SearchPathForTemplates().setValue( pathsList ); pathsList.clear(); for ( int r = 0; r < mLocalizedDataPathListWidget->count(); r++ ) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 5497a2d52ccb..ef3c6915bf91 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -714,6 +714,10 @@ set(QGIS_CORE_SRCS geocms/geonode/qgsgeonodeconnection.cpp geocms/geonode/qgsgeonoderequest.cpp + settings/qgssettingsentry.cpp + settings/qgssettingsregistry.cpp + settings/qgssettingsregistrycore.cpp + validity/qgsabstractvaliditycheck.cpp validity/qgsvaliditycheckcontext.cpp validity/qgsvaliditycheckregistry.cpp @@ -1552,6 +1556,10 @@ set(QGIS_CORE_HDRS textrenderer/qgstextrendererutils.h textrenderer/qgstextshadowsettings.h + settings/qgssettingsentry.h + settings/qgssettingsregistry.h + settings/qgssettingsregistrycore.h + validity/qgsabstractvaliditycheck.h validity/qgsvaliditycheckcontext.h validity/qgsvaliditycheckregistry.h @@ -1792,6 +1800,7 @@ target_include_directories(qgis_core PUBLIC raster renderer scalebar + settings symbology textrenderer validity diff --git a/src/core/layout/qgslayout.h b/src/core/layout/qgslayout.h index 12c2da188578..b49c31f28f82 100644 --- a/src/core/layout/qgslayout.h +++ b/src/core/layout/qgslayout.h @@ -24,6 +24,7 @@ #include "qgslayoutguidecollection.h" #include "qgslayoutexporter.h" #include "qgsmasterlayoutinterface.h" +#include "qgssettingsentry.h" class QgsLayoutItemMap; class QgsLayoutModel; @@ -657,6 +658,14 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext */ bool accept( QgsStyleEntityVisitorInterface *visitor ) const; + struct Settings + { + struct SearchPathForTemplates : public QgsSettingsEntryStringList + { + SearchPathForTemplates() : QgsSettingsEntryStringList( "Layout/searchPathsForTemplates", QgsSettings::Core, QStringList(), QObject::tr( "Search path for templates" ) ) {} + }; + }; + public slots: /** diff --git a/src/core/locator/qgslocator.cpp b/src/core/locator/qgslocator.cpp index 51e1a307babf..5596ba29bd2f 100644 --- a/src/core/locator/qgslocator.cpp +++ b/src/core/locator/qgslocator.cpp @@ -94,10 +94,15 @@ void QgsLocator::registerFilter( QgsLocatorFilter *filter ) filter->setParent( this ); // restore settings - QgsSettings settings; - bool enabled = settings.value( QStringLiteral( "locator_filters/enabled_%1" ).arg( filter->name() ), true, QgsSettings::Section::Gui ).toBool(); - bool byDefault = settings.value( QStringLiteral( "locator_filters/default_%1" ).arg( filter->name() ), filter->useWithoutPrefix(), QgsSettings::Section::Gui ).toBool(); - QString prefix = settings.value( QStringLiteral( "locator_filters/prefix_%1" ).arg( filter->name() ), filter->prefix(), QgsSettings::Section::Gui ).toString(); + bool enabled = true; + if ( QgsLocator::Settings::LocatorFilterEnabled().exists( filter->name() ) ) + enabled = QgsLocator::Settings::LocatorFilterEnabled().value( filter->name() ); + bool byDefault = filter->useWithoutPrefix(); + if ( QgsLocator::Settings::LocatorFilterDefault().exists( filter->name() ) ) + byDefault = QgsLocator::Settings::LocatorFilterDefault().value( filter->name() ); + QString prefix = filter->prefix(); + if ( QgsLocator::Settings::LocatorFilterPrefix().exists( filter->name() ) ) + prefix = QgsLocator::Settings::LocatorFilterPrefix().value( filter->name() ); if ( prefix.isEmpty() ) { prefix = filter->prefix(); diff --git a/src/core/locator/qgslocator.h b/src/core/locator/qgslocator.h index e554436f9dfa..8ccf5522779e 100644 --- a/src/core/locator/qgslocator.h +++ b/src/core/locator/qgslocator.h @@ -29,6 +29,7 @@ #include "qgslocatorfilter.h" #include "qgsfeedback.h" #include "qgslocatorcontext.h" +#include "qgssettingsentry.h" /** @@ -152,6 +153,22 @@ class CORE_EXPORT QgsLocator : public QObject */ QStringList completionList() const {return mAutocompletionList;} + struct Settings + { + struct LocatorFilterEnabled : public QgsSettingsEntryBool + { + LocatorFilterEnabled() : QgsSettingsEntryBool( "locator_filters/enabled_%1", QgsSettings::Gui, true, QObject::tr( "Enabled" ) ) {} + }; + struct LocatorFilterDefault : public QgsSettingsEntryBool + { + LocatorFilterDefault() : QgsSettingsEntryBool( "locator_filters/default_%1", QgsSettings::Gui, false, QObject::tr( "Default value" ) ) {} + }; + struct LocatorFilterPrefix : public QgsSettingsEntryString + { + LocatorFilterPrefix() : QgsSettingsEntryString( "locator_filters/prefix_%1", QgsSettings::Gui, QString(), QObject::tr( "Locator filter prefix" ) ) {} + }; + }; + signals: /** diff --git a/src/core/qgsapplication.cpp b/src/core/qgsapplication.cpp index 341a09e5314c..a8a7dec3c606 100644 --- a/src/core/qgsapplication.cpp +++ b/src/core/qgsapplication.cpp @@ -20,6 +20,7 @@ #include "qgsexception.h" #include "qgsgeometry.h" #include "qgsannotationitemregistry.h" +#include "qgslayout.h" #include "qgslayoutitemregistry.h" #include "qgslogger.h" #include "qgsproject.h" @@ -52,6 +53,7 @@ #include "qgsmessagelog.h" #include "qgsannotationregistry.h" #include "qgssettings.h" +#include "qgssettingsregistrycore.h" #include "qgstiledownloadmanager.h" #include "qgsunittypes.h" #include "qgsuserprofile.h" @@ -1097,10 +1099,7 @@ QStringList QgsApplication::layoutTemplatePaths() { //local directories to search when looking for an template with a given basename //defined by user in options dialog - QgsSettings settings; - QStringList pathList = settings.value( QStringLiteral( "Layout/searchPathsForTemplates" ), QVariant(), QgsSettings::Core ).toStringList(); - - return pathList; + return QgsLayout::Settings::SearchPathForTemplates().value(); } QMap QgsApplication::systemEnvVars() @@ -2160,6 +2159,11 @@ QgsTaskManager *QgsApplication::taskManager() return members()->mTaskManager; } +QgsSettingsRegistryCore *QgsApplication::settingsRegistryCore() +{ + return members()->mSettingsRegistryCore; +} + QgsColorSchemeRegistry *QgsApplication::colorSchemeRegistry() { return members()->mColorSchemeRegistry; @@ -2349,6 +2353,7 @@ QgsApplication::ApplicationMembers::ApplicationMembers() { // don't use initializer lists or scoped pointers - as more objects are added here we // will need to be careful with the order of creation/destruction + mSettingsRegistryCore = new QgsSettingsRegistryCore(); mLocalizedDataPathRegistry = new QgsLocalizedDataPathRegistry(); mMessageLog = new QgsMessageLog(); QgsRuntimeProfiler *profiler = QgsRuntimeProfiler::threadLocalInstance(); @@ -2550,6 +2555,7 @@ QgsApplication::ApplicationMembers::~ApplicationMembers() delete mConnectionRegistry; delete mLocalizedDataPathRegistry; delete mCrsRegistry; + delete mSettingsRegistryCore; } QgsApplication::ApplicationMembers *QgsApplication::members() diff --git a/src/core/qgsapplication.h b/src/core/qgsapplication.h index fee2c3eb1199..2ea07b19e720 100644 --- a/src/core/qgsapplication.h +++ b/src/core/qgsapplication.h @@ -25,6 +25,7 @@ #include "qgsconfig.h" #include "qgstranslationcontext.h" +class QgsSettingsRegistryCore; class Qgs3DRendererRegistry; class QgsActionScopeRegistry; class QgsAnnotationItemRegistry; @@ -617,6 +618,12 @@ class CORE_EXPORT QgsApplication : public QApplication */ static QgsTaskManager *taskManager(); + /** + * Returns the application's settings registry, used for managing application settings. + * \since QGIS 3.20 + */ + static QgsSettingsRegistryCore *settingsRegistryCore() SIP_KEEPREFERENCE; + /** * Returns the application's color scheme registry, used for managing color schemes. * \since QGIS 3.0 @@ -994,6 +1001,7 @@ class CORE_EXPORT QgsApplication : public QApplication struct ApplicationMembers { + QgsSettingsRegistryCore *mSettingsRegistryCore = nullptr; QgsCoordinateReferenceSystemRegistry *mCrsRegistry = nullptr; Qgs3DRendererRegistry *m3DRendererRegistry = nullptr; Qgs3DSymbolRegistry *m3DSymbolRegistry = nullptr; diff --git a/src/core/settings/qgssettingsentry.cpp b/src/core/settings/qgssettingsentry.cpp new file mode 100644 index 000000000000..dc36173d4263 --- /dev/null +++ b/src/core/settings/qgssettingsentry.cpp @@ -0,0 +1,382 @@ +/*************************************************************************** + qgssettingsentry.cpp + -------------------------------------- + Date : February 2021 + Copyright : (C) 2021 by Damiano Lombardi + Email : damiano at opengis dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgssettingsentry.h" + +#include "qgslogger.h" + +QgsSettingsEntry::QgsSettingsEntry( QString key, + QgsSettings::Section section, + QVariant defaultValue, + QString description ) + : mKey( key ) + , mDefaultValue( defaultValue ) + , mSection( section ) + , mDescription( description ) +{ +} + +QgsSettingsEntry::~QgsSettingsEntry() +{ +} + +QString QgsSettingsEntry::key( const QString &dynamicKeyPart ) const +{ + if ( dynamicKeyPart.isEmpty() == false ) + { + if ( hasDynamicKey() == false ) + { + QgsLogger::warning( QStringLiteral( "Settings '%1' don't have a dynamic key, the provided dynamic key part will be ignored" ).arg( mKey ) ); + return mKey; + } + + QString completeKey = mKey; + return completeKey.replace( '%', dynamicKeyPart ); + } + else + { + if ( hasDynamicKey() == true ) + QgsLogger::warning( QStringLiteral( "Settings '%1' have a dynamic key but the dynamic key part was not provided" ).arg( mKey ) ); + + return mKey; + } +} + +bool QgsSettingsEntry::hasDynamicKey() const +{ + return mKey.contains( '%' ); +} + +bool QgsSettingsEntry::exists( const QString &dynamicKeyPart ) const +{ + return QgsSettings().contains( key( dynamicKeyPart ), section() ); +} + +void QgsSettingsEntry::remove( const QString &dynamicKeyPart ) const +{ + QgsSettings().remove( key( dynamicKeyPart ), section() ); +} + +QgsSettings::Section QgsSettingsEntry::section() const +{ + return mSection; +} + +bool QgsSettingsEntry::setValue( const QVariant &value, const QString &dynamicKeyPart ) +{ + QgsSettings().setValue( key( dynamicKeyPart ), + value, + section() ); + return true; +} + +QgsSettingsEntry::SettingsType QgsSettingsEntry::settingsType() const +{ + return QgsSettingsEntry::Variant; +} + +QVariant QgsSettingsEntry::valueFromPython() const +{ + return value(); +} + +QVariant QgsSettingsEntry::defaultValueFromPython() const +{ + return defaultValue(); +} + +QString QgsSettingsEntry::description() const +{ + return mDescription; +} + +QgsSettingsEntryString::QgsSettingsEntryString( const QString &key, + QgsSettings::Section section, + const QString &defaultValue, + const QString &description, + int minLength, + int maxLength ) + : QgsSettingsEntry( key, + section, + defaultValue, + description ) + , mMinLength( minLength ) + , mMaxLength( maxLength ) +{ + +} + +bool QgsSettingsEntryString::setValue( const QVariant &value, const QString &dynamicKeyPart ) +{ + if ( value.canConvert() == false ) + { + QgsDebugMsg( QObject::tr( "Can't convert value '%1' to string for settings with key '%2'" ) + .arg( value.toString() ) + .arg( QgsSettingsEntry::key() ) ); + return false; + } + + QString valueString = value.toString(); + if ( valueString.length() < mMinLength ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. String length '%2' is shorter than minimum length '%3'." ) + .arg( QgsSettingsEntry::key() ) + .arg( valueString.length() ) + .arg( mMinLength ) ); + return false; + } + + if ( mMaxLength >= 0 + && valueString.length() > mMaxLength ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. String length '%2' is longer than maximum length '%3'." ) + .arg( QgsSettingsEntry::key() ) + .arg( valueString.length() ) + .arg( mMinLength ) ); + return false; + } + + QgsSettingsEntry::setValue( value, dynamicKeyPart ); + return true; +} + +QgsSettingsEntry::SettingsType QgsSettingsEntryString::settingsType() const +{ + return QgsSettingsEntry::String; +} + +int QgsSettingsEntryString::minLength() +{ + return mMinLength; +} + +int QgsSettingsEntryString::maxLength() +{ + return mMaxLength; +} + +QgsSettingsEntryStringList::QgsSettingsEntryStringList( const QString &key, + QgsSettings::Section section, + const QStringList &defaultValue, + const QString &description ) + : QgsSettingsEntry( key, + section, + defaultValue, + description ) +{ + +} + +bool QgsSettingsEntryStringList::setValue( const QVariant &value, const QString &dynamicKeyPart ) +{ + if ( value.canConvert() == false ) + { + QgsDebugMsg( QObject::tr( "Can't convert value '%1' to string list for settings with key '%2'" ) + .arg( value.toString() ) + .arg( QgsSettingsEntry::key() ) ); + return false; + } + + QgsSettingsEntry::setValue( value, dynamicKeyPart ); + return true; +} + +QgsSettingsEntry::SettingsType QgsSettingsEntryStringList::settingsType() const +{ + return QgsSettingsEntry::StringList; +} + +QgsSettingsEntryBool::QgsSettingsEntryBool( const QString &key, + QgsSettings::Section section, + bool defaultValue, + const QString &description ) + : QgsSettingsEntry( key, + section, + defaultValue, + description ) +{ + +} + +bool QgsSettingsEntryBool::setValue( const QVariant &value, const QString &dynamicKeyPart ) +{ + if ( value.canConvert() == false ) + { + QgsDebugMsg( QObject::tr( "Can't convert value '%1' to bool for settings with key '%2'" ) + .arg( value.toString() ) + .arg( QgsSettingsEntry::key() ) ); + return false; + } + + QgsSettingsEntry::setValue( value, dynamicKeyPart ); + return true; +} + +QgsSettingsEntry::SettingsType QgsSettingsEntryBool::settingsType() const +{ + return QgsSettingsEntry::Bool; +} + +QgsSettingsEntryInteger::QgsSettingsEntryInteger( const QString &key, + QgsSettings::Section section, + qlonglong defaultValue, + const QString &description, + qlonglong minValue, + qlonglong maxValue ) + : QgsSettingsEntry( key, + section, + defaultValue, + description ) + , mMinValue( minValue ) + , mMaxValue( maxValue ) +{ + +} + +bool QgsSettingsEntryInteger::setValue( const QVariant &value, const QString &dynamicKeyPart ) +{ + if ( value.canConvert() == false ) + { + QgsDebugMsg( QObject::tr( "Can't convert value '%1' to qlonglong for settings with key '%2'" ) + .arg( value.toString() ) + .arg( QgsSettingsEntry::key() ) ); + return false; + } + + qlonglong valueLongLong = value.toLongLong(); + if ( valueLongLong < mMinValue ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. Value '%2' is less than minimum value '%3'." ) + .arg( QgsSettingsEntry::key() ) + .arg( valueLongLong ) + .arg( mMinValue ) ); + return false; + } + + if ( valueLongLong > mMaxValue ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. Value '%2' is greather than maximum value '%3'." ) + .arg( QgsSettingsEntry::key() ) + .arg( valueLongLong ) + .arg( mMinValue ) ); + return false; + } + + QgsSettingsEntry::setValue( value, dynamicKeyPart ); + return true; +} + +QgsSettingsEntry::SettingsType QgsSettingsEntryInteger::settingsType() const +{ + return QgsSettingsEntry::Integer; +} + +qlonglong QgsSettingsEntryInteger::minValue() +{ + return mMinValue; +} + +qlonglong QgsSettingsEntryInteger::maxValue() +{ + return mMaxValue; +} + +QgsSettingsEntryDouble::QgsSettingsEntryDouble( const QString &key, + QgsSettings::Section section, + double defaultValue, + const QString &description, + double minValue, + double maxValue, + double displayDecimals ) + : QgsSettingsEntry( key, + section, + defaultValue, + description ) + , mMinValue( minValue ) + , mMaxValue( maxValue ) + , mDisplayHintDecimals( displayDecimals ) +{ + +} + +bool QgsSettingsEntryDouble::setValue( const QVariant &value, const QString &dynamicKeyPart ) +{ + if ( value.canConvert() == false ) + { + QgsDebugMsg( QObject::tr( "Can't convert value '%1' to double for settings with key '%2'" ) + .arg( value.toString() ) + .arg( QgsSettingsEntry::key() ) ); + return false; + } + + double valueDouble = value.toDouble(); + if ( valueDouble < mMinValue ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. Value '%2' is less than minimum value '%3'." ) + .arg( QgsSettingsEntry::key() ) + .arg( valueDouble ) + .arg( mMinValue ) ); + return false; + } + + if ( valueDouble > mMaxValue ) + { + QgsDebugMsg( QObject::tr( "Can't set value for settings with key '%1'. Value '%2' is greather than maximum value '%3'." ) + .arg( QgsSettingsEntry::key() ) + .arg( valueDouble ) + .arg( mMinValue ) ); + return false; + } + + QgsSettingsEntry::setValue( value, dynamicKeyPart ); + return true; +} + +QgsSettingsEntry::SettingsType QgsSettingsEntryDouble::settingsType() const +{ + return QgsSettingsEntry::Double; +} + +double QgsSettingsEntryDouble::minValue() const +{ + return mMinValue; +} + +double QgsSettingsEntryDouble::maxValue() const +{ + return mMaxValue; +} + +int QgsSettingsEntryDouble::displayHintDecimals() const +{ + return mDisplayHintDecimals; +} + +bool QgsSettingsEntryEnum::setValue( const QVariant &value, const QString &dynamicKeyPart ) +{ + if ( mMetaEnum.isValid() == false ) + { + QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) ); + return false; + } + + QgsSettingsEntry::setValue( mMetaEnum.valueToKey( value.toInt() ), dynamicKeyPart ); + return true; +} + +QgsSettingsEntry::SettingsType QgsSettingsEntryEnum::settingsType() const +{ + return QgsSettingsEntry::Enum; +} diff --git a/src/core/settings/qgssettingsentry.h b/src/core/settings/qgssettingsentry.h new file mode 100644 index 000000000000..900ff76234bb --- /dev/null +++ b/src/core/settings/qgssettingsentry.h @@ -0,0 +1,461 @@ +/*************************************************************************** + qgssettingsentry.h + -------------------------------------- + Date : February 2021 + Copyright : (C) 2021 by Damiano Lombardi + Email : damiano at opengis dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSSETTINGSENTRY_H +#define QGSSETTINGSENTRY_H + +#include +#include + +#include "qgis_core.h" +#include "qgis_sip.h" +#include "qgssettings.h" + +/** + * \ingroup core + * \class QgsSettingsEntry + * + * Represent settings entry and provides methods for reading and writing settings values. + * Different subclasses are provided for differents settings types with metainformations + * to validate set values and provide more accurate settings description for the gui. + * + * \since QGIS 3.18 + */ +class CORE_EXPORT QgsSettingsEntry +{ + +#ifdef SIP_RUN + SIP_CONVERT_TO_SUBCLASS_CODE + if ( dynamic_cast< QgsSettingsEntryString * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryString; + if ( dynamic_cast< QgsSettingsEntryStringList * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryStringList; + else if ( dynamic_cast< QgsSettingsEntryInteger * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryInteger; + else if ( dynamic_cast< QgsSettingsEntryDouble * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryDouble; + else + sipType = NULL; + SIP_END +#endif + + public: + + enum SettingsType + { + Variant, + String, + StringList, + Bool, + Integer, + Double, + Enum + }; + + /** + * Constructor for QgsSettingsEntry. + * + * The \a key argument specifies the key of the settings. + * The \a section argument specifies the section of the settings. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntry( QString key, + QgsSettings::Section section, + QVariant defaultValue = QVariant(), + QString description = QString() ); + + /** + * Destructor for QgsSettingsEntry. + */ + virtual ~QgsSettingsEntry(); + + /** + * Get settings entry key. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + QString key( const QString &dynamicKeyPart = QString() ) const; + + /** + * Returns true if a part of the settings key is built dynamically. + */ + bool hasDynamicKey() const; + + /** + * Returns true if the settings is contained in the underlying QSettings. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + bool exists( const QString &dynamicKeyPart = QString() ) const; + + /** + * Removes the settings from the underlying QSettings. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + void remove( const QString &dynamicKeyPart = QString() ) const; + + /** + * Get settings section. The settings section of the parent group is returned if available. + */ + QgsSettings::Section section() const; + + /** + * Set settings value. + * + * The \a dynamicKeyPart argument specifies the dynamic part of the settings key. + */ + virtual bool setValue( const QVariant &value, const QString &dynamicKeyPart = QString() ); + + /** + * Get settings value. + */ + QVariant valueFromPython() const SIP_PYNAME( value ); + +#ifndef SIP_RUN + template + T value( const QString &dynamicKeyPart = QString() ) const + { + QVariant variantValue = QgsSettings().value( key( dynamicKeyPart ), + mDefaultValue, + mSection ); + if ( variantValue.canConvert() == false ) + QgsDebugMsg( QObject::tr( "Can't convert setting '%1' to type '%2'" ) + .arg( key( dynamicKeyPart ) ) + .arg( typeid( T ).name() ) ); + + return variantValue.value(); + } +#endif + + /** + * Get settings default value. + */ + QVariant defaultValueFromPython() const SIP_PYNAME( defaultValue ); + +#ifndef SIP_RUN + template + T defaultValue() const + { + if ( mDefaultValue.canConvert() == false ) + QgsDebugMsg( QObject::tr( "Can't convert default value of setting '%1' to type '%2'" ) + .arg( mKey ) + .arg( typeid( T ).name() ) ); + + return mDefaultValue.value(); + } +#endif + + /** + * Get the settings entry type. + */ + virtual SettingsType settingsType() const; + + /** + * Get the settings entry description. + */ + QString description() const; + + private: + + QString mKey; + QVariant mDefaultValue; + QgsSettings::Section mSection; + QString mDescription; + +}; + +/** + * \class QgsSettingsEntryString + * \ingroup core + * A string settings entry. + * \since QGIS 3.18 + */ +class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntry +{ + public: + + /** + * Constructor for QgsSettingsEntryString. + * + * The \a key argument specifies the final part of the settings key. + * The \a parentGroup argument specifies a parent group which is used to rebuild + * the entiere settings key and to determine the settings section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + * The \a minLength argument specifies the minimal length of the string value. + * The \a maxLength argument specifies the maximal lenght of the string value. + * By -1 the there is no limit + */ + QgsSettingsEntryString( const QString &key, + QgsSettings::Section section, + const QString &defaultValue = QString(), + const QString &description = QString(), + int minLength = 0, + int maxLength = -1 ); + + //! \copydoc QgsSettingsEntry::setValue + bool setValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) override; + + //! \copydoc QgsSettingsEntry::settingsType + virtual SettingsType settingsType() const override; + + /** + * Returns the string minimum length. + */ + int minLength(); + + /** + * Returns the string maximum length. By -1 there is no limitation. + */ + int maxLength(); + + private: + + int mMinLength; + int mMaxLength; + +}; + +/** + * \class QgsSettingsEntryStringList + * \ingroup core + * A string list settings entry. + * \since QGIS 3.18 + */ +class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntry +{ + public: + + /** + * Constructor for QgsSettingsEntryStringList. + * + * The \a key argument specifies the final part of the settings key. + * The \a parentGroup argument specifies a parent group which is used to rebuild + * the entiere settings key and to determine the settings section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryStringList( const QString &key, + QgsSettings::Section section, + const QStringList &defaultValue = QStringList(), + const QString &description = QString() ); + + //! \copydoc QgsSettingsEntry::setValue + bool setValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) override; + + //! \copydoc QgsSettingsEntry::settingsType + virtual SettingsType settingsType() const override; + +}; + +/** + * \class QgsSettingsEntryBool + * \ingroup core + * A boolean settings entry. + * \since QGIS 3.18 + */ +class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntry +{ + public: + + /** + * Constructor for QgsSettingsEntryBool. + * + * The \a key argument specifies the final part of the settings key. + * The \a parentGroup argument specifies a parent group which is used to rebuild + * the entiere settings key and to determine the settings section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + QgsSettingsEntryBool( const QString &key, + QgsSettings::Section section, + bool defaultValue = false, + const QString &description = QString() ); + + //! \copydoc QgsSettingsEntry::setValue + bool setValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) override; + + //! \copydoc QgsSettingsEntry::settingsType + virtual SettingsType settingsType() const override; + +}; + +/** + * \class QgsSettingsEntryInteger + * \ingroup core + * An integer settings entry. + * \since QGIS 3.18 + */ +class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntry +{ + public: + + /** + * Constructor for QgsSettingsEntryInteger. + * + * The \a key argument specifies the final part of the settings key. + * The \a parentGroup argument specifies a parent group which is used to rebuild + * the entiere settings key and to determine the settings section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + * The \a minValue argument specifies the minimal value. + * The \a maxValue argument specifies the maximal value. + */ + QgsSettingsEntryInteger( const QString &key, + QgsSettings::Section section, + qlonglong defaultValue = 0, + const QString &description = QString(), + qlonglong minValue = -__LONG_LONG_MAX__ + 1, + qlonglong maxValue = __LONG_LONG_MAX__ ); + + //! \copydoc QgsSettingsEntry::setValue + bool setValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) override; + + //! \copydoc QgsSettingsEntry::settingsType + virtual SettingsType settingsType() const override; + + /** + * Returns the minimum value. + */ + qlonglong minValue(); + + /** + * Returns the maximum value. + */ + qlonglong maxValue(); + + private: + + qlonglong mMinValue; + qlonglong mMaxValue; + +}; + +/** + * \class QgsSettingsEntryDouble + * \ingroup core + * A double settings entry. + * \since QGIS 3.18 + */ +class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntry +{ + public: + + /** + * Constructor for QgsSettingsEntryDouble. + * + * The \a key argument specifies the final part of the settings key. + * The \a parentGroup argument specifies a parent group which is used to rebuild + * the entiere settings key and to determine the settings section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + * The \a minValue argument specifies the minimal value. + * The \a maxValue argument specifies the maximal value. + */ + QgsSettingsEntryDouble( const QString &key, + QgsSettings::Section section, + double defaultValue = 0.0, + const QString &description = QString(), + double minValue = __DBL_MIN__, + double maxValue = __DBL_MAX__, + double displayDecimals = 1 ); + + //! \copydoc QgsSettingsEntry::setValue + bool setValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) override; + + //! \copydoc QgsSettingsEntry::settingsType + virtual SettingsType settingsType() const override; + + /** + * Returns the minimum value. + */ + double minValue() const; + + /** + * Returns the maximum value. + */ + double maxValue() const; + + /** + * Returns how much decimals should be shown in the Gui. + */ + int displayHintDecimals() const; + + private: + + double mMinValue; + double mMaxValue; + + int mDisplayHintDecimals; + +}; + +#ifndef SIP_RUN + +/** + * \class QgsSettingsEntryEnum + * \ingroup core + * An enum settings entry. + * \since QGIS 3.18 + */ +class CORE_EXPORT QgsSettingsEntryEnum : public QgsSettingsEntry +{ + public: + + /** + * Constructor for QgsSettingsEntryEnum. + * + * The \a key argument specifies the final part of the settings key. + * The \a parentGroup argument specifies a parent group which is used to rebuild + * the entiere settings key and to determine the settings section. + * The \a default value argument specifies the default value for the settings entry. + * The \a description argument specifies a description for the settings entry. + */ + template + QgsSettingsEntryEnum( const QString &key, + QgsSettings::Section *section, + const T &defaultValue, + const QString &description = QString() ) + : QgsSettingsEntry( key, + section, + defaultValue, + description ) + { + mMetaEnum = QMetaEnum::fromType(); + Q_ASSERT( mMetaEnum.isValid() ); + if ( !mMetaEnum.isValid() ) + { + QgsDebugMsg( QStringLiteral( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ) ); + } + } + + //! \copydoc QgsSettingsEntry::setValue + bool setValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) override; + + //! \copydoc QgsSettingsEntry::settingsType + virtual SettingsType settingsType() const override; + + private: + + QMetaEnum mMetaEnum; + +}; +#endif + + + +#endif // QGSSETTINGSENTRY_H diff --git a/src/core/settings/qgssettingsregistrycore.cpp b/src/core/settings/qgssettingsregistrycore.cpp new file mode 100644 index 000000000000..d874212c9827 --- /dev/null +++ b/src/core/settings/qgssettingsregistrycore.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** + qgssettingsregistrycore.cpp + -------------------------------------- + Date : February 2021 + Copyright : (C) 2021 by Damiano Lombardi + Email : damiano at opengis dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgssettingsregistrycore.h" + +#include "qgslayout.h" +#include "qgslocator.h" + +QgsSettingsRegistryCore::QgsSettingsRegistryCore() + : mSettingsEntries() +{ + mSettingsEntries.append( new QgsLayout::Settings::SearchPathForTemplates() ); + + mSettingsEntries.append( new QgsLocator::Settings::LocatorFilterEnabled() ); + mSettingsEntries.append( new QgsLocator::Settings::LocatorFilterDefault() ); + mSettingsEntries.append( new QgsLocator::Settings::LocatorFilterPrefix() ); +} + +QgsSettingsRegistryCore::~QgsSettingsRegistryCore() +{ + qDeleteAll( mSettingsEntries ); +} + + diff --git a/src/core/settings/qgssettingsregistrycore.h b/src/core/settings/qgssettingsregistrycore.h new file mode 100644 index 000000000000..7bc8bdf23c96 --- /dev/null +++ b/src/core/settings/qgssettingsregistrycore.h @@ -0,0 +1,50 @@ +/*************************************************************************** + qgssettingsregistrycore.h + -------------------------------------- + Date : February 2021 + Copyright : (C) 2021 by Damiano Lombardi + Email : damiano at opengis dot ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#ifndef QGSSETTINGSREGISTRYCORE_H +#define QGSSETTINGSREGISTRYCORE_H + +#include "qgis_core.h" +#include "qgis_sip.h" +#include "qgssettingsentry.h" + +#include "qgslayout.h" +#include "qgslocator.h" + +#include + +class QgsSettingsEntryStringList; + +/** + * \ingroup core + * \class QgsSettingsRegistryCore + * + * \since QGIS 3.18 + */ +class CORE_EXPORT QgsSettingsRegistryCore +{ + public: + + QgsSettingsRegistryCore(); + ~QgsSettingsRegistryCore(); + + private: + + QList mSettingsEntries; + +}; + +#endif // QGSSETTINGSREGISTRYCORE_H From 784675dd3ee2c97e2a010c885bf301b72e54ae24 Mon Sep 17 00:00:00 2001 From: Damiano Date: Wed, 10 Mar 2021 22:08:26 +0100 Subject: [PATCH 002/377] Corrected keys placeholders --- src/core/locator/qgslocator.h | 6 +++--- src/core/settings/qgssettingsentry.h | 14 +++++++------- src/core/settings/qgssettingsregistrycore.h | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/locator/qgslocator.h b/src/core/locator/qgslocator.h index 8ccf5522779e..815d1b0f84b4 100644 --- a/src/core/locator/qgslocator.h +++ b/src/core/locator/qgslocator.h @@ -157,15 +157,15 @@ class CORE_EXPORT QgsLocator : public QObject { struct LocatorFilterEnabled : public QgsSettingsEntryBool { - LocatorFilterEnabled() : QgsSettingsEntryBool( "locator_filters/enabled_%1", QgsSettings::Gui, true, QObject::tr( "Enabled" ) ) {} + LocatorFilterEnabled() : QgsSettingsEntryBool( "locator_filters/enabled_%", QgsSettings::Gui, true, QObject::tr( "Enabled" ) ) {} }; struct LocatorFilterDefault : public QgsSettingsEntryBool { - LocatorFilterDefault() : QgsSettingsEntryBool( "locator_filters/default_%1", QgsSettings::Gui, false, QObject::tr( "Default value" ) ) {} + LocatorFilterDefault() : QgsSettingsEntryBool( "locator_filters/default_%", QgsSettings::Gui, false, QObject::tr( "Default value" ) ) {} }; struct LocatorFilterPrefix : public QgsSettingsEntryString { - LocatorFilterPrefix() : QgsSettingsEntryString( "locator_filters/prefix_%1", QgsSettings::Gui, QString(), QObject::tr( "Locator filter prefix" ) ) {} + LocatorFilterPrefix() : QgsSettingsEntryString( "locator_filters/prefix_%", QgsSettings::Gui, QString(), QObject::tr( "Locator filter prefix" ) ) {} }; }; diff --git a/src/core/settings/qgssettingsentry.h b/src/core/settings/qgssettingsentry.h index 900ff76234bb..71c1c77828d4 100644 --- a/src/core/settings/qgssettingsentry.h +++ b/src/core/settings/qgssettingsentry.h @@ -31,7 +31,7 @@ * Different subclasses are provided for differents settings types with metainformations * to validate set values and provide more accurate settings description for the gui. * - * \since QGIS 3.18 + * \since QGIS 3.20 */ class CORE_EXPORT QgsSettingsEntry { @@ -182,7 +182,7 @@ class CORE_EXPORT QgsSettingsEntry * \class QgsSettingsEntryString * \ingroup core * A string settings entry. - * \since QGIS 3.18 + * \since QGIS 3.20 */ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntry { @@ -234,7 +234,7 @@ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntry * \class QgsSettingsEntryStringList * \ingroup core * A string list settings entry. - * \since QGIS 3.18 + * \since QGIS 3.20 */ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntry { @@ -266,7 +266,7 @@ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntry * \class QgsSettingsEntryBool * \ingroup core * A boolean settings entry. - * \since QGIS 3.18 + * \since QGIS 3.20 */ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntry { @@ -298,7 +298,7 @@ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntry * \class QgsSettingsEntryInteger * \ingroup core * An integer settings entry. - * \since QGIS 3.18 + * \since QGIS 3.20 */ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntry { @@ -349,7 +349,7 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntry * \class QgsSettingsEntryDouble * \ingroup core * A double settings entry. - * \since QGIS 3.18 + * \since QGIS 3.20 */ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntry { @@ -410,7 +410,7 @@ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntry * \class QgsSettingsEntryEnum * \ingroup core * An enum settings entry. - * \since QGIS 3.18 + * \since QGIS 3.20 */ class CORE_EXPORT QgsSettingsEntryEnum : public QgsSettingsEntry { diff --git a/src/core/settings/qgssettingsregistrycore.h b/src/core/settings/qgssettingsregistrycore.h index 7bc8bdf23c96..d8e35cd18a12 100644 --- a/src/core/settings/qgssettingsregistrycore.h +++ b/src/core/settings/qgssettingsregistrycore.h @@ -32,7 +32,7 @@ class QgsSettingsEntryStringList; * \ingroup core * \class QgsSettingsRegistryCore * - * \since QGIS 3.18 + * \since QGIS 3.20 */ class CORE_EXPORT QgsSettingsRegistryCore { From 4a5e23fac72c4d1e5a3b5092566e019a25abb3a1 Mon Sep 17 00:00:00 2001 From: Damiano Lombardi Date: Fri, 12 Mar 2021 07:41:25 +0100 Subject: [PATCH 003/377] Added macros for settings definition --- src/core/CMakeLists.txt | 2 -- src/core/layout/qgslayout.h | 5 +---- src/core/locator/qgslocator.h | 15 +++------------ src/core/settings/qgssettingsentry.h | 26 ++++++++++++++++++++++++++ 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ef3c6915bf91..6cf31b34b7fa 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -715,7 +715,6 @@ set(QGIS_CORE_SRCS geocms/geonode/qgsgeonoderequest.cpp settings/qgssettingsentry.cpp - settings/qgssettingsregistry.cpp settings/qgssettingsregistrycore.cpp validity/qgsabstractvaliditycheck.cpp @@ -1557,7 +1556,6 @@ set(QGIS_CORE_HDRS textrenderer/qgstextshadowsettings.h settings/qgssettingsentry.h - settings/qgssettingsregistry.h settings/qgssettingsregistrycore.h validity/qgsabstractvaliditycheck.h diff --git a/src/core/layout/qgslayout.h b/src/core/layout/qgslayout.h index b49c31f28f82..b71668a80733 100644 --- a/src/core/layout/qgslayout.h +++ b/src/core/layout/qgslayout.h @@ -660,10 +660,7 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext struct Settings { - struct SearchPathForTemplates : public QgsSettingsEntryStringList - { - SearchPathForTemplates() : QgsSettingsEntryStringList( "Layout/searchPathsForTemplates", QgsSettings::Core, QStringList(), QObject::tr( "Search path for templates" ) ) {} - }; + QGS_SETTING_ENTRY_STRINGLIST( SearchPathForTemplates, "Layout/searchPathsForTemplates", QgsSettings::Core, QStringList(), "Search path for templates" ) }; public slots: diff --git a/src/core/locator/qgslocator.h b/src/core/locator/qgslocator.h index 815d1b0f84b4..c5c1b92e343e 100644 --- a/src/core/locator/qgslocator.h +++ b/src/core/locator/qgslocator.h @@ -155,18 +155,9 @@ class CORE_EXPORT QgsLocator : public QObject struct Settings { - struct LocatorFilterEnabled : public QgsSettingsEntryBool - { - LocatorFilterEnabled() : QgsSettingsEntryBool( "locator_filters/enabled_%", QgsSettings::Gui, true, QObject::tr( "Enabled" ) ) {} - }; - struct LocatorFilterDefault : public QgsSettingsEntryBool - { - LocatorFilterDefault() : QgsSettingsEntryBool( "locator_filters/default_%", QgsSettings::Gui, false, QObject::tr( "Default value" ) ) {} - }; - struct LocatorFilterPrefix : public QgsSettingsEntryString - { - LocatorFilterPrefix() : QgsSettingsEntryString( "locator_filters/prefix_%", QgsSettings::Gui, QString(), QObject::tr( "Locator filter prefix" ) ) {} - }; + QGS_SETTING_ENTRY_BOOL( LocatorFilterEnabled, "locator_filters/enabled_%", QgsSettings::Gui, true, "Enabled" ) + QGS_SETTING_ENTRY_BOOL( LocatorFilterDefault, "locator_filters/default_%", QgsSettings::Gui, false, "Default value" ) + QGS_SETTING_ENTRY_STRING( LocatorFilterPrefix, "locator_filters/prefix_%", QgsSettings::Gui, QString(), "Locator filter prefix", 0, -1 ) }; signals: diff --git a/src/core/settings/qgssettingsentry.h b/src/core/settings/qgssettingsentry.h index 71c1c77828d4..3a7f961f82a2 100644 --- a/src/core/settings/qgssettingsentry.h +++ b/src/core/settings/qgssettingsentry.h @@ -23,6 +23,30 @@ #include "qgis_sip.h" #include "qgssettings.h" +# define QGS_SETTING_ENTRY_STRING(name, path, section, defaultValue, description, minLength, maxLength) \ + struct name : public QgsSettingsEntryString \ + { name() : QgsSettingsEntryString( path, section, defaultValue, QObject::tr( description ), minLength, maxLength ) {} }; + +# define QGS_SETTING_ENTRY_STRINGLIST(name, path, section, defaultValue, description) \ + struct name : public QgsSettingsEntryStringList \ + { name() : QgsSettingsEntryStringList( path, section, defaultValue, QObject::tr( description ) ) {} }; + +# define QGS_SETTING_ENTRY_BOOL(name, path, section, defaultValue, description) \ + struct name : public QgsSettingsEntryBool \ + { name() : QgsSettingsEntryBool( path, section, defaultValue, QObject::tr( description ) ) {} }; + +# define QGS_SETTING_ENTRY_INTEGER(name, path, section, defaultValue, description, minValue, maxValue) \ + struct name : public QgsSettingsEntryInteger \ + { name() : QgsSettingsEntryInteger( path, section, defaultValue, QObject::tr( description ), minValue, maxValue ) {} }; + +# define QGS_SETTING_ENTRY_DOUBLE(name, path, section, defaultValue, description, minValue, maxValue, displayDecimals) \ + struct name : public QgsSettingsEntryDouble \ + { name() : QgsSettingsEntryDouble( path, section, defaultValue, QObject::tr( description ), minValue, maxValue, displayDecimals ) {} }; + +# define QGS_SETTING_ENTRY_ENUM(name, path, section, defaultValue, description) \ + struct name : public QgsSettingsEntryEnum \ + { name() : QgsSettingsEntryEnum( path, section, defaultValue, QObject::tr( description ) ) {} }; + /** * \ingroup core * \class QgsSettingsEntry @@ -42,6 +66,8 @@ class CORE_EXPORT QgsSettingsEntry sipType = sipType_QgsSettingsEntryString; if ( dynamic_cast< QgsSettingsEntryStringList * >( sipCpp ) ) sipType = sipType_QgsSettingsEntryStringList; + else if ( dynamic_cast< QgsSettingsEntryBool * >( sipCpp ) ) + sipType = sipType_QgsSettingsEntryBool; else if ( dynamic_cast< QgsSettingsEntryInteger * >( sipCpp ) ) sipType = sipType_QgsSettingsEntryInteger; else if ( dynamic_cast< QgsSettingsEntryDouble * >( sipCpp ) ) From 5796a5ff672a647f0ae522cf9add4aa4ec7c8068 Mon Sep 17 00:00:00 2001 From: Damiano Lombardi Date: Sun, 14 Mar 2021 20:17:38 +0100 Subject: [PATCH 004/377] QgsSettingsEntry macros with variable/default arguments --- src/core/layout/qgslayout.h | 2 +- src/core/locator/qgslocator.h | 6 +-- src/core/settings/qgssettingsentry.h | 56 +++++++++++++++------------- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/core/layout/qgslayout.h b/src/core/layout/qgslayout.h index b71668a80733..d0b2e7661254 100644 --- a/src/core/layout/qgslayout.h +++ b/src/core/layout/qgslayout.h @@ -660,7 +660,7 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext struct Settings { - QGS_SETTING_ENTRY_STRINGLIST( SearchPathForTemplates, "Layout/searchPathsForTemplates", QgsSettings::Core, QStringList(), "Search path for templates" ) + QGS_SETTING_ENTRY_STRINGLIST( SearchPathForTemplates, QStringLiteral( "Layout/searchPathsForTemplates" ), QgsSettings::Core, QStringList(), tr( "Search path for templates" ) ) }; public slots: diff --git a/src/core/locator/qgslocator.h b/src/core/locator/qgslocator.h index c5c1b92e343e..640906fd5c5b 100644 --- a/src/core/locator/qgslocator.h +++ b/src/core/locator/qgslocator.h @@ -155,9 +155,9 @@ class CORE_EXPORT QgsLocator : public QObject struct Settings { - QGS_SETTING_ENTRY_BOOL( LocatorFilterEnabled, "locator_filters/enabled_%", QgsSettings::Gui, true, "Enabled" ) - QGS_SETTING_ENTRY_BOOL( LocatorFilterDefault, "locator_filters/default_%", QgsSettings::Gui, false, "Default value" ) - QGS_SETTING_ENTRY_STRING( LocatorFilterPrefix, "locator_filters/prefix_%", QgsSettings::Gui, QString(), "Locator filter prefix", 0, -1 ) + QGS_SETTING_ENTRY_BOOL( LocatorFilterEnabled, QStringLiteral( "locator_filters/enabled_%" ), QgsSettings::Gui, true, tr( "Enabled" ) ) + QGS_SETTING_ENTRY_BOOL( LocatorFilterDefault, QStringLiteral( "locator_filters/default_%" ), QgsSettings::Gui, false, tr( "Default value" ) ) + QGS_SETTING_ENTRY_STRING( LocatorFilterPrefix, QStringLiteral( "locator_filters/prefix_%" ), QgsSettings::Gui, QString(), tr( "Locator filter prefix" ) ) }; signals: diff --git a/src/core/settings/qgssettingsentry.h b/src/core/settings/qgssettingsentry.h index 3a7f961f82a2..64cddcd4cb45 100644 --- a/src/core/settings/qgssettingsentry.h +++ b/src/core/settings/qgssettingsentry.h @@ -23,30 +23,6 @@ #include "qgis_sip.h" #include "qgssettings.h" -# define QGS_SETTING_ENTRY_STRING(name, path, section, defaultValue, description, minLength, maxLength) \ - struct name : public QgsSettingsEntryString \ - { name() : QgsSettingsEntryString( path, section, defaultValue, QObject::tr( description ), minLength, maxLength ) {} }; - -# define QGS_SETTING_ENTRY_STRINGLIST(name, path, section, defaultValue, description) \ - struct name : public QgsSettingsEntryStringList \ - { name() : QgsSettingsEntryStringList( path, section, defaultValue, QObject::tr( description ) ) {} }; - -# define QGS_SETTING_ENTRY_BOOL(name, path, section, defaultValue, description) \ - struct name : public QgsSettingsEntryBool \ - { name() : QgsSettingsEntryBool( path, section, defaultValue, QObject::tr( description ) ) {} }; - -# define QGS_SETTING_ENTRY_INTEGER(name, path, section, defaultValue, description, minValue, maxValue) \ - struct name : public QgsSettingsEntryInteger \ - { name() : QgsSettingsEntryInteger( path, section, defaultValue, QObject::tr( description ), minValue, maxValue ) {} }; - -# define QGS_SETTING_ENTRY_DOUBLE(name, path, section, defaultValue, description, minValue, maxValue, displayDecimals) \ - struct name : public QgsSettingsEntryDouble \ - { name() : QgsSettingsEntryDouble( path, section, defaultValue, QObject::tr( description ), minValue, maxValue, displayDecimals ) {} }; - -# define QGS_SETTING_ENTRY_ENUM(name, path, section, defaultValue, description) \ - struct name : public QgsSettingsEntryEnum \ - { name() : QgsSettingsEntryEnum( path, section, defaultValue, QObject::tr( description ) ) {} }; - /** * \ingroup core * \class QgsSettingsEntry @@ -204,6 +180,11 @@ class CORE_EXPORT QgsSettingsEntry }; + +#define QGS_SETTING_ENTRY_STRING(name, path, section, defaultValue, ...) \ + struct name : public QgsSettingsEntryString \ + { name() : QgsSettingsEntryString( path, section, defaultValue, ##__VA_ARGS__ ) {} }; + /** * \class QgsSettingsEntryString * \ingroup core @@ -256,6 +237,11 @@ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntry }; + +# define QGS_SETTING_ENTRY_STRINGLIST(name, path, section, defaultValue, ...) \ + struct name : public QgsSettingsEntryStringList \ + { name() : QgsSettingsEntryStringList( path, section, defaultValue, ##__VA_ARGS__ ) {} }; + /** * \class QgsSettingsEntryStringList * \ingroup core @@ -288,6 +274,11 @@ class CORE_EXPORT QgsSettingsEntryStringList : public QgsSettingsEntry }; + +# define QGS_SETTING_ENTRY_BOOL(name, path, section, defaultValue, ...) \ + struct name : public QgsSettingsEntryBool \ + { name() : QgsSettingsEntryBool( path, section, defaultValue, ##__VA_ARGS__ ) {} }; + /** * \class QgsSettingsEntryBool * \ingroup core @@ -320,6 +311,11 @@ class CORE_EXPORT QgsSettingsEntryBool : public QgsSettingsEntry }; + +# define QGS_SETTING_ENTRY_INTEGER(name, path, section, defaultValue, ...) \ + struct name : public QgsSettingsEntryInteger \ + { name() : QgsSettingsEntryInteger( path, section, defaultValue, ##__VA_ARGS__ ) {} }; + /** * \class QgsSettingsEntryInteger * \ingroup core @@ -371,6 +367,11 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntry }; + +# define QGS_SETTING_ENTRY_DOUBLE(name, path, section, defaultValue, ...) \ + struct name : public QgsSettingsEntryDouble \ + { name() : QgsSettingsEntryDouble( path, section, defaultValue, ##__VA_ARGS__ ) {} }; + /** * \class QgsSettingsEntryDouble * \ingroup core @@ -430,8 +431,13 @@ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntry }; + #ifndef SIP_RUN +# define QGS_SETTING_ENTRY_ENUM(name, path, section, defaultValue, ...) \ + struct name : public QgsSettingsEntryEnum \ + { name() : QgsSettingsEntryEnum( path, section, defaultValue, ##__VA_ARGS__ ) {} }; + /** * \class QgsSettingsEntryEnum * \ingroup core @@ -453,7 +459,7 @@ class CORE_EXPORT QgsSettingsEntryEnum : public QgsSettingsEntry */ template QgsSettingsEntryEnum( const QString &key, - QgsSettings::Section *section, + QgsSettings::Section section, const T &defaultValue, const QString &description = QString() ) : QgsSettingsEntry( key, From da9715048586f1115f11c04ae90aa36505d4076c Mon Sep 17 00:00:00 2001 From: Damiano Date: Mon, 15 Mar 2021 10:31:58 +0100 Subject: [PATCH 005/377] Fixes typos and banned keywords --- src/core/settings/qgssettingsentry.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/core/settings/qgssettingsentry.h b/src/core/settings/qgssettingsentry.h index 64cddcd4cb45..99ff91edf430 100644 --- a/src/core/settings/qgssettingsentry.h +++ b/src/core/settings/qgssettingsentry.h @@ -23,12 +23,16 @@ #include "qgis_sip.h" #include "qgssettings.h" +#define QGS_SETTING_ENTRY_VARIANT(name, path, section, defaultValue, ...) \ + struct name : public QgsSettingsEntry\ + { name() : QgsSettingsEntry( path, section, defaultValue, ##__VA_ARGS__ ) {} }; + /** * \ingroup core * \class QgsSettingsEntry * * Represent settings entry and provides methods for reading and writing settings values. - * Different subclasses are provided for differents settings types with metainformations + * Different subclasses are provided for different settings types with metainformations * to validate set values and provide more accurate settings description for the gui. * * \since QGIS 3.20 @@ -204,7 +208,7 @@ class CORE_EXPORT QgsSettingsEntryString : public QgsSettingsEntry * The \a default value argument specifies the default value for the settings entry. * The \a description argument specifies a description for the settings entry. * The \a minLength argument specifies the minimal length of the string value. - * The \a maxLength argument specifies the maximal lenght of the string value. + * The \a maxLength argument specifies the maximal length of the string value. * By -1 the there is no limit */ QgsSettingsEntryString( const QString &key, @@ -341,8 +345,8 @@ class CORE_EXPORT QgsSettingsEntryInteger : public QgsSettingsEntry QgsSettings::Section section, qlonglong defaultValue = 0, const QString &description = QString(), - qlonglong minValue = -__LONG_LONG_MAX__ + 1, - qlonglong maxValue = __LONG_LONG_MAX__ ); + qlonglong minValue = std::numeric_limits::min(), + qlonglong maxValue = std::numeric_limits::max() ); //! \copydoc QgsSettingsEntry::setValue bool setValue( const QVariant &value, const QString &dynamicKeyPart = QString() ) override; @@ -397,8 +401,8 @@ class CORE_EXPORT QgsSettingsEntryDouble : public QgsSettingsEntry QgsSettings::Section section, double defaultValue = 0.0, const QString &description = QString(), - double minValue = __DBL_MIN__, - double maxValue = __DBL_MAX__, + double minValue = std::numeric_limits::min(), + double maxValue = std::numeric_limits::max(), double displayDecimals = 1 ); //! \copydoc QgsSettingsEntry::setValue From ccc7889e0a7a47e82706e49dc0f054642475b5e7 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 10 Mar 2021 13:23:35 +1000 Subject: [PATCH 006/377] Allow point clouds, mesh, vector tiles to be exported to qlr and qml files through layer tree menu, and ensure that the styles can be reapplied to the layer Fixes #42111 Fixes #42112 --- src/app/qgisapp.cpp | 4 +- src/app/qgsapplayertreeviewmenuprovider.cpp | 127 ++++++++++++-------- src/core/qgslayerdefinition.cpp | 62 +++++++--- 3 files changed, 125 insertions(+), 68 deletions(-) diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 2f317ba1920e..09eae4882831 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -8916,6 +8916,8 @@ void QgisApp::saveStyleFile( QgsMapLayer *layer ) case QgsMapLayerType::RasterLayer: case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::PointCloudLayer: + case QgsMapLayerType::VectorTileLayer: { QgsSettings settings; QString lastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString(); @@ -8938,10 +8940,8 @@ void QgisApp::saveStyleFile( QgsMapLayer *layer ) break; } - case QgsMapLayerType::VectorTileLayer: case QgsMapLayerType::AnnotationLayer: case QgsMapLayerType::PluginLayer: - case QgsMapLayerType::PointCloudLayer: break; } diff --git a/src/app/qgsapplayertreeviewmenuprovider.cpp b/src/app/qgsapplayertreeviewmenuprovider.cpp index c167ded93808..47b82a72a74c 100644 --- a/src/app/qgsapplayertreeviewmenuprovider.cpp +++ b/src/app/qgsapplayertreeviewmenuprovider.cpp @@ -432,58 +432,91 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu() menu->addSeparator(); - if ( vlayer ) + // export menu + if ( layer ) { - if ( vlayer->isTemporary() ) - { - QAction *actionMakePermanent = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "mActionFileSave.svg" ) ), tr( "Make Permanent…" ), menu ); - connect( actionMakePermanent, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->makeMemoryLayerPermanent( vlayer ); } ); - menu->addAction( actionMakePermanent ); - } - // save as vector file - QMenu *menuExportVector = new QMenu( tr( "E&xport" ), menu ); - QAction *actionSaveAs = new QAction( tr( "Save Features &As…" ), menuExportVector ); - connect( actionSaveAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile(); } ); - actionSaveAs->setEnabled( vlayer->isValid() ); - menuExportVector->addAction( actionSaveAs ); - QAction *actionSaveSelectedFeaturesAs = new QAction( tr( "Save &Selected Features As…" ), menuExportVector ); - connect( actionSaveSelectedFeaturesAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile( nullptr, true ); } ); - actionSaveSelectedFeaturesAs->setEnabled( vlayer->isValid() && vlayer->selectedFeatureCount() > 0 ); - menuExportVector->addAction( actionSaveSelectedFeaturesAs ); - QAction *actionSaveAsDefinitionLayer = new QAction( tr( "Save as Layer &Definition File…" ), menuExportVector ); - connect( actionSaveAsDefinitionLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition ); - menuExportVector->addAction( actionSaveAsDefinitionLayer ); - if ( vlayer->isSpatial() ) + switch ( layer->type() ) { - QAction *actionSaveStyle = new QAction( tr( "Save as &QGIS Layer Style File…" ), menuExportVector ); - connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } ); - menuExportVector->addAction( actionSaveStyle ); + case QgsMapLayerType::VectorLayer: + if ( vlayer ) + { + if ( vlayer->isTemporary() ) + { + QAction *actionMakePermanent = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "mActionFileSave.svg" ) ), tr( "Make Permanent…" ), menu ); + connect( actionMakePermanent, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->makeMemoryLayerPermanent( vlayer ); } ); + menu->addAction( actionMakePermanent ); + } + // save as vector file + QMenu *menuExportVector = new QMenu( tr( "E&xport" ), menu ); + QAction *actionSaveAs = new QAction( tr( "Save Features &As…" ), menuExportVector ); + connect( actionSaveAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile(); } ); + actionSaveAs->setEnabled( vlayer->isValid() ); + menuExportVector->addAction( actionSaveAs ); + QAction *actionSaveSelectedFeaturesAs = new QAction( tr( "Save &Selected Features As…" ), menuExportVector ); + connect( actionSaveSelectedFeaturesAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile( nullptr, true ); } ); + actionSaveSelectedFeaturesAs->setEnabled( vlayer->isValid() && vlayer->selectedFeatureCount() > 0 ); + menuExportVector->addAction( actionSaveSelectedFeaturesAs ); + QAction *actionSaveAsDefinitionLayer = new QAction( tr( "Save as Layer &Definition File…" ), menuExportVector ); + connect( actionSaveAsDefinitionLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition ); + menuExportVector->addAction( actionSaveAsDefinitionLayer ); + if ( vlayer->isSpatial() ) + { + QAction *actionSaveStyle = new QAction( tr( "Save as &QGIS Layer Style File…" ), menuExportVector ); + connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } ); + menuExportVector->addAction( actionSaveStyle ); + } + menu->addMenu( menuExportVector ); + } + break; + + case QgsMapLayerType::RasterLayer: + if ( rlayer ) + { + QMenu *menuExportRaster = new QMenu( tr( "E&xport" ), menu ); + QAction *actionSaveAs = new QAction( tr( "Save &As…" ), menuExportRaster ); + QAction *actionSaveAsDefinitionLayer = new QAction( tr( "Save as Layer &Definition File…" ), menuExportRaster ); + QAction *actionSaveStyle = new QAction( tr( "Save as &QGIS Layer Style File…" ), menuExportRaster ); + connect( actionSaveAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile(); } ); + menuExportRaster->addAction( actionSaveAs ); + actionSaveAs->setEnabled( rlayer->isValid() ); + connect( actionSaveAsDefinitionLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition ); + menuExportRaster->addAction( actionSaveAsDefinitionLayer ); + connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } ); + menuExportRaster->addAction( actionSaveStyle ); + menu->addMenu( menuExportRaster ); + } + break; + + case QgsMapLayerType::MeshLayer: + case QgsMapLayerType::VectorTileLayer: + case QgsMapLayerType::PointCloudLayer: + { + QMenu *menuExportRaster = new QMenu( tr( "E&xport" ), menu ); + QAction *actionSaveAsDefinitionLayer = new QAction( tr( "Save as Layer &Definition File…" ), menuExportRaster ); + QAction *actionSaveStyle = new QAction( tr( "Save as &QGIS Layer Style File…" ), menuExportRaster ); + connect( actionSaveAsDefinitionLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition ); + menuExportRaster->addAction( actionSaveAsDefinitionLayer ); + connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } ); + menuExportRaster->addAction( actionSaveStyle ); + menu->addMenu( menuExportRaster ); + } + break; + + case QgsMapLayerType::AnnotationLayer: + break; + + case QgsMapLayerType::PluginLayer: + if ( mView->selectedLayerNodes().count() == 1 ) + { + // disable duplication of plugin layers + duplicateLayersAction->setEnabled( false ); + } + break; + } - menu->addMenu( menuExportVector ); - } - else if ( rlayer ) - { - QMenu *menuExportRaster = new QMenu( tr( "E&xport" ), menu ); - QAction *actionSaveAs = new QAction( tr( "Save &As…" ), menuExportRaster ); - QAction *actionSaveAsDefinitionLayer = new QAction( tr( "Save as Layer &Definition File…" ), menuExportRaster ); - QAction *actionSaveStyle = new QAction( tr( "Save as &QGIS Layer Style File…" ), menuExportRaster ); - connect( actionSaveAs, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveAsFile(); } ); - menuExportRaster->addAction( actionSaveAs ); - actionSaveAs->setEnabled( rlayer->isValid() ); - connect( actionSaveAsDefinitionLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition ); - menuExportRaster->addAction( actionSaveAsDefinitionLayer ); - connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } ); - menuExportRaster->addAction( actionSaveStyle ); - menu->addMenu( menuExportRaster ); - } - else if ( layer && layer->type() == QgsMapLayerType::PluginLayer && mView->selectedLayerNodes().count() == 1 ) - { - // disable duplication of plugin layers - duplicateLayersAction->setEnabled( false ); + menu->addSeparator(); } - menu->addSeparator(); - // style-related actions if ( layer && mView->selectedLayerNodes().count() == 1 ) { diff --git a/src/core/qgslayerdefinition.cpp b/src/core/qgslayerdefinition.cpp index 2205c20f451e..616a70aa9543 100644 --- a/src/core/qgslayerdefinition.cpp +++ b/src/core/qgslayerdefinition.cpp @@ -30,6 +30,10 @@ #include "qgsvectorlayer.h" #include "qgsvectortilelayer.h" #include "qgsapplication.h" +#include "qgsmaplayerfactory.h" +#include "qgsmeshlayer.h" +#include "qgspointcloudlayer.h" +#include "qgsannotationlayer.h" bool QgsLayerDefinition::loadLayerDefinition( const QString &path, QgsProject *project, QgsLayerTreeGroup *rootGroup, QString &errorMessage ) { @@ -294,26 +298,42 @@ QList QgsLayerDefinition::loadLayerDefinitionLayersInternal( QDom const QString type = layerElem.attribute( QStringLiteral( "type" ) ); QgsMapLayer *layer = nullptr; - if ( type == QLatin1String( "vector" ) ) + bool ok = false; + const QgsMapLayerType layerType = QgsMapLayerFactory::typeFromString( type, ok ); + if ( ok ) { - layer = new QgsVectorLayer( ); - } - else if ( type == QLatin1String( "raster" ) ) - { - layer = new QgsRasterLayer; - } - else if ( type == QLatin1String( "vector-tile" ) ) - { - layer = new QgsVectorTileLayer; - } - else if ( type == QLatin1String( "plugin" ) ) - { - QString typeName = layerElem.attribute( QStringLiteral( "name" ) ); - layer = QgsApplication::pluginLayerRegistry()->createLayer( typeName ); - } - else - { - errorMessage = QObject::tr( "Unsupported layer type: %1" ).arg( type ); + switch ( layerType ) + { + case QgsMapLayerType::VectorLayer: + layer = new QgsVectorLayer(); + break; + + case QgsMapLayerType::RasterLayer: + layer = new QgsRasterLayer(); + break; + + case QgsMapLayerType::PluginLayer: + { + QString typeName = layerElem.attribute( QStringLiteral( "name" ) ); + layer = QgsApplication::pluginLayerRegistry()->createLayer( typeName ); + break; + } + + case QgsMapLayerType::MeshLayer: + layer = new QgsMeshLayer(); + break; + + case QgsMapLayerType::VectorTileLayer: + layer = new QgsVectorTileLayer; + break; + + case QgsMapLayerType::PointCloudLayer: + layer = new QgsPointCloudLayer(); + break; + + case QgsMapLayerType::AnnotationLayer: + break; + } } if ( layer ) @@ -323,6 +343,10 @@ QList QgsLayerDefinition::loadLayerDefinitionLayersInternal( QDom layer->readLayerXml( layerElem, context ); layers << layer; } + else + { + errorMessage = QObject::tr( "Unsupported layer type: %1" ).arg( type ); + } layerElem = layerElem.nextSiblingElement( QStringLiteral( "maplayer" ) ); } return layers; From 85607aefb4ec59eeba7498e89671a6a685ad8f4e Mon Sep 17 00:00:00 2001 From: Harrissou Sant-anna Date: Wed, 10 Mar 2021 12:37:35 +0100 Subject: [PATCH 007/377] Updating the Readme file --- README.md | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d34bab29aa85..d5d088222c69 100644 --- a/README.md +++ b/README.md @@ -5,17 +5,35 @@ [![Build Status](https://dev.azure.com/qgis/QGIS/_apis/build/status/qgis.QGIS?branchName=master)](https://dev.azure.com/qgis/QGIS/_build/latest?definitionId=1&branchName=master) [![Windows cross build](https://github.com/qgis/QGIS/workflows/MingW64%20Windows%2064bit%20Build/badge.svg)](https://github.com/qgis/QGIS/actions/workflows/mingw64.yml?query=branch%3Amaster+event%3Apush) -# About QGIS - QGIS is a full-featured, user-friendly, free-and-open-source (FOSS) geographical information system (GIS) that runs on Unix platforms, Windows, and MacOS. + + + * [Features](#features) + * [1. Flexible and powerful spatial data management](#1-flexible-and-powerful-spatial-data-management) + * [2. Beautiful cartography](#2-beautiful-cartography) + * [3. Advanced and robust geospatial analysis](#3-advanced-and-robust-geospatial-analysis) + * [4. Powerful customization and extensibility](#4-powerful-customization-and-extensibility) + * [5. QGIS Server](#5-qgis-server) + * [Under the hood](#under-the-hood) + * [Versions and release cycle](#versions-and-release-cycle) + * [Free and Open Source](#free-and-open-source) + * [Installing and using QGIS](#installing-and-using-qgis) + * [Documentation](#documentation) + * [Help and support channels](#help-and-support-channels) + * [Get involved with the community](#get-involved-with-the-community) + * [Bug reporting and bug fixing](#bug-reporting-and-bug-fixing) + * [New features and enhancements](#new-features-and-enhancements) + * [Translations](#translations) + * [Other ways to contribute](#other-ways-to-contribute) + ## Features ### 1. Flexible and powerful spatial data management - Supports raster, vector, mesh, and point cloud data in a range of industry-standard formats - - *Raster formats include:* GeoPackage, GeoTIFF, GRASS, ArcInfo binary and ASCII grids, ERDAS Imagine SDTS, WMS, WCS, PostgreSQL/PostGIS, and [other GDAL supported formats](https://gdal.org/drivers/raster/index.html). - - *Vector formats include:* GeoPackage, ESRI Shapefiles, GRASS, SpatiaLite, PostgreSQL/PostGIS, MSSQL, Oracle, WFS, Vector Tiles and [other OGR supported formats](http://www.gdal.org/ogr_formats.html). + - *Raster formats include*: GeoPackage, GeoTIFF, GRASS, ArcInfo binary and ASCII grids, ERDAS Imagine SDTS, WMS, WCS, PostgreSQL/PostGIS, and [other GDAL supported formats](https://gdal.org/drivers/raster/index.html). + - *Vector formats include*: GeoPackage, ESRI Shapefiles, GRASS, SpatiaLite, PostgreSQL/PostGIS, MSSQL, Oracle, WFS, Vector Tiles and [other OGR supported formats](http://www.gdal.org/ogr_formats.html). - *Mesh formats include*: NetCDF, GRIB, 2DM, and [other MDAL supported formats](https://github.com/lutraconsulting/MDAL#supported-formats). - *Point-cloud format*: LAS/LAZ and EPT datasets. - Access and display local files, spatial databases (PostGIS, SpatiaLite, SQL Server, Oracle, SAP HANA), web services (WMS, WCS, WFS, ArcGIS REST services), tile services, etc. @@ -72,7 +90,7 @@ For more maps created with QGIS, visit the [QGIS Map Showcase Flickr Group](http - Broad and varied [plugin ecosystem](https://plugins.qgis.org/) that includes data connectors, digitizing aids, advanced analysis and charting tools, in-the-field data capture, etc. - Style manager for creating, storing, and managing styles - [QGIS style hub](https://plugins.qgis.org/styles/) for easy sharing of styles -- Python and C++ [API](https://qgis.org/api/) for standalone (headless) applications as well as in-application comprehensive scripting (PyQGIS) +- Python and C++ API for standalone (headless) applications as well as in-application comprehensive scripting (PyQGIS) *Example: Style manager* @@ -138,27 +156,28 @@ For installation of QGIS Server, see its [getting started documentation](https:/ ### Documentation -A range of -[documentation](https://qgis.org/en/docs/index.html) is available. This includes: +A range of [documentation](https://qgis.org/en/docs/index.html) is available. This includes: - [Training Manual](https://docs.qgis.org/latest/en/docs/training_manual/index.html) - [QGIS User Guide](https://docs.qgis.org/latest/en/docs/user_manual/index.html) - [QGIS Server Guide](https://docs.qgis.org/latest/en/docs/server_manual/index.html) +- [Visual Changelog](https://qgis.org/en/site/forusers/visualchangelogs.html) - [Documentation Guidelines](https://docs.qgis.org/latest/en/docs/documentation_guidelines/index.html) -- [PyQGIS Cookbook](https://docs.qgis.org/latest/en/docs/pyqgis_developer_cookbook/index.html) +- [QGIS Python (PyQGIS) Cookbook](https://docs.qgis.org/latest/en/docs/pyqgis_developer_cookbook/index.html) +- [QGIS Python (PyQGIS) API](https://qgis.org/pyqgis/) +- [QGIS C++ API](https://qgis.org/api/) - [Developers Guide](https://docs.qgis.org/latest/en/docs/developers_guide/index.html) -- [Visual Changelog](https://qgis.org/en/site/forusers/visualchangelogs.html) ### Help and support channels There are several channels where you can find help and support for QGIS: -- Using the [QGIS community site](https://qgis.org](https://qgis.org) +- Using the [QGIS community site](https://qgis.org) - Joining the [qgis-users mailing list](https://lists.osgeo.org/mailman/listinfo/qgis-user) - Chatting with other users real-time. *Please wait around for a response to your question as many folks on the channel are doing other things and it may take a while for them to notice your question. The following paths all take you to the same chat room:* - Using an IRC client and joining the [#qgis](http://webchat.freenode.net/?channels=#qgis) channel on irc.freenode.net. - Using a Matrix client and joining the [#qgis:matrix.org](http://matrix.to/#/#qgis:matrix.org) room. - - Using [Gitter](https://gitter.im/qgis/QGIS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) chat. + - Using [Gitter](https://gitter.im/qgis/QGIS) chat. - At the [GIS stackexchange](https://gis.stackexchange.com/) or [r/QGIS reddit](https://www.reddit.com/r/QGIS/), which are not maintained by the QGIS team, but where the QGIS and broader GIS community provides lots of advice - [Other support channels](https://qgis.org/en/site/forusers/support.html) @@ -187,7 +206,7 @@ For large-scale changes, you can open a [QEP (QGIS Enhancement Proposal)](https: Please help translate QGIS to your language. At this moment about forty languages are already available in the Desktop user interface and about eighty languages are available in transifex ready to be translated. -The [translation](https://qgis.org/en/site/getinvolved/translate.html) process is managed by the [Translation Team](https://qgis.org/en/site/getinvolved/governance/governance.html#gui-translation) and all the activities are done under the [Transifex](https://www.transifex.com/) platform. +The [translation](https://qgis.org/en/site/getinvolved/translate.html) process is managed by the [Translation Team](https://qgis.org/en/site/getinvolved/governance/governance.html#gui-translation) and all the activities are done under the [Transifex](https://www.transifex.com/qgis/) platform. ### Other ways to contribute From 1acf6750494f503ac103562adebaf5be3e6f93c5 Mon Sep 17 00:00:00 2001 From: uclaros Date: Wed, 10 Mar 2021 20:47:39 +0200 Subject: [PATCH 008/377] Add 'NULL' to autocomplete list in expression editor --- src/gui/codeeditors/qgscodeeditorexpression.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/codeeditors/qgscodeeditorexpression.cpp b/src/gui/codeeditors/qgscodeeditorexpression.cpp index cb44b2ea8f63..41d72cacbfd6 100644 --- a/src/gui/codeeditors/qgscodeeditorexpression.cpp +++ b/src/gui/codeeditors/qgscodeeditorexpression.cpp @@ -157,6 +157,7 @@ void QgsCodeEditorExpression::updateApis() mApis->add( fieldName ); } + mApis->add( QString( "NULL" ) ); mApis->prepare(); mSqlLexer->setAPIs( mApis ); } From 7a2e17b63e4c86dfca47cfc25771d0725c9c9368 Mon Sep 17 00:00:00 2001 From: Harrissou Sant-anna Date: Wed, 10 Mar 2021 11:10:26 +0100 Subject: [PATCH 009/377] Alias json_to_map and map_to_json functions --- src/core/expression/qgsexpressionfunction.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index 5d1826bc004d..bf63f20195b0 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -7278,10 +7278,8 @@ const QList &QgsExpression::Functions() << new QgsStaticExpressionFunction( QStringLiteral( "generate_series" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "start" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "stop" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "step" ), true, 1.0 ), fcnGenerateSeries, QStringLiteral( "Arrays" ) ) //functions for maps - << new QgsStaticExpressionFunction( QStringLiteral( "json_to_map" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnLoadJson, QStringLiteral( "Maps" ) ) - << new QgsStaticExpressionFunction( QStringLiteral( "from_json" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "value" ) ), fcnLoadJson, QStringLiteral( "Maps" ) ) - << new QgsStaticExpressionFunction( QStringLiteral( "map_to_json" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "map" ) ), fcnWriteJson, QStringLiteral( "Maps" ) ) - << new QgsStaticExpressionFunction( QStringLiteral( "to_json" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "json_string" ) ), fcnWriteJson, QStringLiteral( "Maps" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "from_json" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "value" ) ), fcnLoadJson, QStringLiteral( "Maps" ), QString(), false, QSet(), false, QStringList() << QStringLiteral( "json_to_map" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "to_json" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "json_string" ) ), fcnWriteJson, QStringLiteral( "Maps" ), QString(), false, QSet(), false, QStringList() << QStringLiteral( "map_to_json" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "hstore_to_map" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnHstoreToMap, QStringLiteral( "Maps" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "map_to_hstore" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "map" ) ), fcnMapToHstore, QStringLiteral( "Maps" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "map" ), -1, fcnMap, QStringLiteral( "Maps" ) ) From fc028c2208e5c015a30f5794d79a27ebfcaba509 Mon Sep 17 00:00:00 2001 From: Harrissou Sant-anna Date: Wed, 10 Mar 2021 11:10:35 +0100 Subject: [PATCH 010/377] Delete map_to_json function --- resources/function_help/json/map_to_json | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 resources/function_help/json/map_to_json diff --git a/resources/function_help/json/map_to_json b/resources/function_help/json/map_to_json deleted file mode 100644 index b2d4e7b0b045..000000000000 --- a/resources/function_help/json/map_to_json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "map_to_json", - "type": "function", - "groups": ["Maps"], - "description": "Merge map elements into a json-formatted string.", - "arguments": [ - {"arg":"map", "description":"the input map"}], - "examples": [ { "expression":"map_to_json(map('qgis','rocks'))", "returns":"{\"qgis\":\"rocks\"}"} - ] -} From f4a70e79a9fe783b378cd39fdeac40697fde346d Mon Sep 17 00:00:00 2001 From: Harrissou Sant-anna Date: Wed, 10 Mar 2021 11:12:02 +0100 Subject: [PATCH 011/377] Delete json_to_map function --- resources/function_help/json/json_to_map | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 resources/function_help/json/json_to_map diff --git a/resources/function_help/json/json_to_map b/resources/function_help/json/json_to_map deleted file mode 100644 index eea2a087f8ae..000000000000 --- a/resources/function_help/json/json_to_map +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "json_to_map", - "type": "function", - "groups": ["Maps"], - "description": "Creates a map from a json-formatted string.", - "arguments": [ - {"arg":"string", "description":"the input string"}], - "examples": [ { "expression":"json_to_map('{\"qgis\":\"rocks\"}')", "returns":"{ 'qgis': 'rocks' }"} - ] -} From 7a39484947d7c9a83c6fb42bd4ca394b349c3b66 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 3 Mar 2021 12:10:19 +1000 Subject: [PATCH 012/377] [feature] Add streaming digitizing mode When active, points are automatically added following the mouse cursor movement. Refs Natural resources Canada Contract: 3000720707 --- .../auto_generated/qgsmaptoolcapture.sip.in | 8 ++++++ src/app/qgisapp.cpp | 28 +++++++++++++++++-- src/app/qgisapp.h | 6 ++++ src/gui/qgsmaptoolcapture.cpp | 22 ++++++++++++--- src/gui/qgsmaptoolcapture.h | 13 +++++++++ src/ui/qgisapp.ui | 19 +++++++++++++ 6 files changed, 90 insertions(+), 6 deletions(-) diff --git a/python/gui/auto_generated/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in index 2a1846c08a48..c51dd0d8feb8 100644 --- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in +++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in @@ -33,6 +33,7 @@ class QgsMapToolCapture : QgsMapToolAdvancedDigitizing { StraightSegments, CircularString, + Streaming, }; enum Capability @@ -135,6 +136,13 @@ transfers ownership to the caller. void setCircularDigitizingEnabled( bool enable ); %Docstring Enable the digitizing with curve +%End + + void setStreamDigitizingEnabled( bool enable ); +%Docstring +Toggles the stream digitizing mode. + +.. versionadded:: 3.20 %End protected: diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 09eae4882831..14082be2e221 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -2562,6 +2562,9 @@ void QgisApp::createActions() connect( mActionRegularPolygonCenterPoint, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::RegularPolygonCenterPoint ), true ); } ); connect( mActionRegularPolygonCenterCorner, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::RegularPolygonCenterCorner ), true ); } ); connect( mActionDigitizeWithCurve, &QAction::triggered, this, &QgisApp::enableDigitizeWithCurve ); + connect( mActionStreamDigitize, &QAction::triggered, this, &QgisApp::enableStreamDigitizing ); + mActionStreamDigitize->setShortcut( tr( "R", "Keyboard shortcut: toggle stream digitizing" ) ); + connect( mActionMoveFeature, &QAction::triggered, this, &QgisApp::moveFeature ); connect( mActionMoveFeatureCopy, &QAction::triggered, this, &QgisApp::moveFeatureCopy ); connect( mActionRotateFeature, &QAction::triggered, this, &QgisApp::rotateFeature ); @@ -10121,6 +10124,18 @@ void QgisApp::enableDigitizeWithCurve( bool enable ) settings.setValue( QStringLiteral( "UI/digitizeWithCurve" ), enable ? 1 : 0 ); } +void QgisApp::enableStreamDigitizing( bool enable ) +{ + const QList< QgsMapToolCapture * > captureTools = mMapTools->captureTools(); + for ( QgsMapToolCapture *tool : captureTools ) + { + if ( tool->supportsTechnique( QgsMapToolCapture::Streaming ) ) + tool->setStreamDigitizingEnabled( enable ); + } + QgsSettings settings; + settings.setValue( QStringLiteral( "UI/digitizeWithStream" ), enable ? 1 : 0 ); +} + void QgisApp::enableDigitizeTechniqueActions( bool enable, QAction *triggeredFromToolAction ) { QgsSettings settings; @@ -10132,8 +10147,11 @@ void QgisApp::enableDigitizeTechniqueActions( bool enable, QAction *triggeredFro { if ( triggeredFromToolAction == tool->action() || ( !triggeredFromToolAction && mMapCanvas->mapTool() == tool ) ) { - if ( tool->supportsTechnique( QgsMapToolCapture::CircularString ) ) - supportedTechniques.insert( QgsMapToolCapture::CircularString ); + for ( QgsMapToolCapture::CaptureTechnique technique : { QgsMapToolCapture::CircularString, QgsMapToolCapture::Streaming } ) + { + if ( tool->supportsTechnique( technique ) ) + supportedTechniques.insert( technique ); + } break; } } @@ -10142,10 +10160,16 @@ void QgisApp::enableDigitizeTechniqueActions( bool enable, QAction *triggeredFro const bool curveIsChecked = settings.value( QStringLiteral( "UI/digitizeWithCurve" ) ).toInt(); mActionDigitizeWithCurve->setChecked( curveIsChecked && mActionDigitizeWithCurve->isEnabled() ); + mActionStreamDigitize->setEnabled( enable && supportedTechniques.contains( QgsMapToolCapture::Streaming ) ); + const bool streamIsChecked = settings.value( QStringLiteral( "UI/digitizeWithStream" ) ).toInt(); + mActionStreamDigitize->setChecked( streamIsChecked && mActionStreamDigitize->isEnabled() ); + for ( QgsMapToolCapture *tool : captureTools ) { if ( tool->supportsTechnique( QgsMapToolCapture::CircularString ) ) tool->setCircularDigitizingEnabled( mActionDigitizeWithCurve->isChecked() ); + if ( tool->supportsTechnique( QgsMapToolCapture::Streaming ) ) + tool->setStreamDigitizingEnabled( mActionStreamDigitize->isChecked() ); } } diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index 2e83085d3c3d..f02064999dc0 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -1962,6 +1962,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow */ void enableDigitizeWithCurve( bool enable ); + /** + * Enables or disables stream digitizing + * \since QGIS 3.20 + */ + void enableStreamDigitizing( bool enable ); + /** * Enables the action that toggles digitizing with curve */ diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index c6426e6337ff..501ab8491c7e 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -364,6 +364,11 @@ void QgsMapToolCapture::setCircularDigitizingEnabled( bool enable ) mTempRubberBand->setStringType( mDigitizingType ); } +void QgsMapToolCapture::setStreamDigitizingEnabled( bool enable ) +{ + mStreamingEnabled = enable; + mStartNewCurve = true; +} void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) { @@ -378,8 +383,13 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) { bool hasTrace = false; - - if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 ) + if ( mStreamingEnabled ) + { + mAllowAddingStreamingPoints = true; + addVertex( mapPoint ); + mAllowAddingStreamingPoints = false; + } + else if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 ) { // Store the intermediate point for circular string to retrieve after tracing mouse move if // the digitizing type is circular and the temp rubber band is effectivly circular and if this point is existing @@ -407,7 +417,7 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) } } - if ( !hasTrace ) + if ( !mStreamingEnabled && !hasTrace ) { if ( mCaptureCurve.numPoints() > 0 ) { @@ -536,6 +546,9 @@ int QgsMapToolCapture::addVertex( const QgsPointXY &point, const QgsPointLocator return 2; } + if ( mCapturing && mStreamingEnabled && !mAllowAddingStreamingPoints ) + return 0; + int res; QgsPoint layerPoint; res = fetchLayerPoint( match, layerPoint ); @@ -670,7 +683,8 @@ int QgsMapToolCapture::addCurve( QgsCurve *c ) // we set the extendPrevious option to true to avoid creating compound curves with many 2 vertex linestrings -- instead we prefer // to extend linestring curves so that they continue the previous linestring wherever possible... - mCaptureCurve.addCurve( c, true ); + mCaptureCurve.addCurve( c, !mStartNewCurve ); + mStartNewCurve = false; int countAfter = mCaptureCurve.vertexCount(); int addedPoint = countAfter - countBefore; diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index 31863dbe1648..4030f0ddec00 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -143,6 +143,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing { StraightSegments, //!< Default capture mode - capture occurs with straight line segments CircularString, //!< Capture in circular strings + Streaming, //!< Streaming points digitizing mode (points are automatically added as the mouse cursor moves) }; //! Specific capabilities of the tool @@ -233,6 +234,12 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing //! Enable the digitizing with curve void setCircularDigitizingEnabled( bool enable ); + /** + * Toggles the stream digitizing mode. + * \since QGIS 3.20 + */ + void setStreamDigitizingEnabled( bool enable ); + private slots: void addError( const QgsGeometry::Error &error ); void currentLayerChanged( QgsMapLayer *layer ); @@ -454,6 +461,12 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing //! Used to store the state of digitizing type (linear or circular) QgsWkbTypes::Type mDigitizingType = QgsWkbTypes::LineString; + + bool mStreamingEnabled = false; + bool mAllowAddingStreamingPoints = false; + bool mStartNewCurve = false; + + }; Q_DECLARE_OPERATORS_FOR_FLAGS( QgsMapToolCapture::Capabilities ) diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui index 6e036c3d9814..301efdc76846 100644 --- a/src/ui/qgisapp.ui +++ b/src/ui/qgisapp.ui @@ -521,6 +521,7 @@ false + @@ -3486,6 +3487,24 @@ Shows placeholders for labels which could not be placed, e.g. due to overlaps wi Add Point Cloud Layer... + + + true + + + true + + + + :/images/themes/default/mIconSnappingSelf.svg:/images/themes/default/mIconSnappingSelf.svg + + + Stream Digitizing + + + Toggles stream digitizing mode + + From 2ef5b5cfccdccbcee198f3dd7dd261e5aa957ea9 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 4 Mar 2021 17:00:28 +1000 Subject: [PATCH 013/377] Many tools support streaming mode --- src/app/qgsmaptooladdpart.cpp | 14 ++++++++++++++ src/app/qgsmaptooladdpart.h | 1 + src/app/qgsmaptooladdring.cpp | 14 ++++++++++++++ src/app/qgsmaptooladdring.h | 1 + src/app/qgsmaptoolfillring.cpp | 14 ++++++++++++++ src/app/qgsmaptoolfillring.h | 1 + src/app/qgsmaptoolreshape.cpp | 1 + src/app/qgsmaptoolsplitfeatures.cpp | 1 + src/app/qgsmaptoolsplitparts.cpp | 14 ++++++++++++++ src/app/qgsmaptoolsplitparts.h | 1 + src/gui/qgsmaptooldigitizefeature.cpp | 1 + 11 files changed, 63 insertions(+) diff --git a/src/app/qgsmaptooladdpart.cpp b/src/app/qgsmaptooladdpart.cpp index 2d7a2e843523..180659a582e0 100644 --- a/src/app/qgsmaptooladdpart.cpp +++ b/src/app/qgsmaptooladdpart.cpp @@ -40,6 +40,20 @@ QgsMapToolCapture::Capabilities QgsMapToolAddPart::capabilities() const return QgsMapToolCapture::SupportsCurves; } +bool QgsMapToolAddPart::supportsTechnique( QgsMapToolCapture::CaptureTechnique technique ) const +{ + switch ( technique ) + { + case QgsMapToolCapture::StraightSegments: + case QgsMapToolCapture::Streaming: + return true; + + case QgsMapToolCapture::CircularString: + return false; + } + return false; +} + void QgsMapToolAddPart::canvasReleaseEvent( QgsMapMouseEvent *e ) { if ( checkSelection() ) diff --git a/src/app/qgsmaptooladdpart.h b/src/app/qgsmaptooladdpart.h index 681d70fa2f68..cf9e4b1cc326 100644 --- a/src/app/qgsmaptooladdpart.h +++ b/src/app/qgsmaptooladdpart.h @@ -24,6 +24,7 @@ class APP_EXPORT QgsMapToolAddPart : public QgsMapToolCapture QgsMapToolAddPart( QgsMapCanvas *canvas ); QgsMapToolCapture::Capabilities capabilities() const override; + bool supportsTechnique( CaptureTechnique technique ) const override; void canvasReleaseEvent( QgsMapMouseEvent *e ) override; void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; diff --git a/src/app/qgsmaptooladdring.cpp b/src/app/qgsmaptooladdring.cpp index da7222401f9a..ff1dbf0df64a 100644 --- a/src/app/qgsmaptooladdring.cpp +++ b/src/app/qgsmaptooladdring.cpp @@ -33,6 +33,20 @@ QgsMapToolAddRing::QgsMapToolAddRing( QgsMapCanvas *canvas ) connect( QgisApp::instance(), &QgisApp::projectRead, this, &QgsMapToolAddRing::stopCapturing ); } +bool QgsMapToolAddRing::supportsTechnique( QgsMapToolCapture::CaptureTechnique technique ) const +{ + switch ( technique ) + { + case QgsMapToolCapture::StraightSegments: + case QgsMapToolCapture::Streaming: + return true; + + case QgsMapToolCapture::CircularString: + return false; + } + return false; +} + void QgsMapToolAddRing::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) { diff --git a/src/app/qgsmaptooladdring.h b/src/app/qgsmaptooladdring.h index 172d5bea6004..7cff202a656a 100644 --- a/src/app/qgsmaptooladdring.h +++ b/src/app/qgsmaptooladdring.h @@ -22,5 +22,6 @@ class APP_EXPORT QgsMapToolAddRing: public QgsMapToolCapture Q_OBJECT public: QgsMapToolAddRing( QgsMapCanvas *canvas ); + bool supportsTechnique( CaptureTechnique technique ) const override; void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; }; diff --git a/src/app/qgsmaptoolfillring.cpp b/src/app/qgsmaptoolfillring.cpp index 718fb271adc4..5b61b8f4e280 100644 --- a/src/app/qgsmaptoolfillring.cpp +++ b/src/app/qgsmaptoolfillring.cpp @@ -33,6 +33,20 @@ QgsMapToolFillRing::QgsMapToolFillRing( QgsMapCanvas *canvas ) mToolName = tr( "Fill ring" ); } +bool QgsMapToolFillRing::supportsTechnique( QgsMapToolCapture::CaptureTechnique technique ) const +{ + switch ( technique ) + { + case QgsMapToolCapture::StraightSegments: + case QgsMapToolCapture::Streaming: + return true; + + case QgsMapToolCapture::CircularString: + return false; + } + return false; +} + void QgsMapToolFillRing::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) { //check if we operate on a vector layer diff --git a/src/app/qgsmaptoolfillring.h b/src/app/qgsmaptoolfillring.h index 978c30918e70..f914a8e3939e 100644 --- a/src/app/qgsmaptoolfillring.h +++ b/src/app/qgsmaptoolfillring.h @@ -26,6 +26,7 @@ class APP_EXPORT QgsMapToolFillRing: public QgsMapToolCapture Q_OBJECT public: QgsMapToolFillRing( QgsMapCanvas *canvas ); + bool supportsTechnique( CaptureTechnique technique ) const override; void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; private: diff --git a/src/app/qgsmaptoolreshape.cpp b/src/app/qgsmaptoolreshape.cpp index 5ed8174df57f..dee006d1023f 100644 --- a/src/app/qgsmaptoolreshape.cpp +++ b/src/app/qgsmaptoolreshape.cpp @@ -87,6 +87,7 @@ bool QgsMapToolReshape::supportsTechnique( QgsMapToolCapture::CaptureTechnique t { case QgsMapToolCapture::StraightSegments: case QgsMapToolCapture::CircularString: + case QgsMapToolCapture::Streaming: return true; } return false; diff --git a/src/app/qgsmaptoolsplitfeatures.cpp b/src/app/qgsmaptoolsplitfeatures.cpp index bfab5c55f08c..90b1e62389a5 100644 --- a/src/app/qgsmaptoolsplitfeatures.cpp +++ b/src/app/qgsmaptoolsplitfeatures.cpp @@ -36,6 +36,7 @@ bool QgsMapToolSplitFeatures::supportsTechnique( QgsMapToolCapture::CaptureTechn { case QgsMapToolCapture::StraightSegments: case QgsMapToolCapture::CircularString: + case QgsMapToolCapture::Streaming: return true; } return false; diff --git a/src/app/qgsmaptoolsplitparts.cpp b/src/app/qgsmaptoolsplitparts.cpp index cb916da72a55..49b6af6fde9b 100644 --- a/src/app/qgsmaptoolsplitparts.cpp +++ b/src/app/qgsmaptoolsplitparts.cpp @@ -30,6 +30,20 @@ QgsMapToolSplitParts::QgsMapToolSplitParts( QgsMapCanvas *canvas ) setSnapToLayerGridEnabled( false ); } +bool QgsMapToolSplitParts::supportsTechnique( QgsMapToolCapture::CaptureTechnique technique ) const +{ + switch ( technique ) + { + case QgsMapToolCapture::StraightSegments: + case QgsMapToolCapture::Streaming: + return true; + + case QgsMapToolCapture::CircularString: + return false; + } + return false; +} + void QgsMapToolSplitParts::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) { //check if we operate on a vector layer diff --git a/src/app/qgsmaptoolsplitparts.h b/src/app/qgsmaptoolsplitparts.h index b8926db564a2..b67ce93f55fd 100644 --- a/src/app/qgsmaptoolsplitparts.h +++ b/src/app/qgsmaptoolsplitparts.h @@ -24,6 +24,7 @@ class APP_EXPORT QgsMapToolSplitParts: public QgsMapToolCapture Q_OBJECT public: QgsMapToolSplitParts( QgsMapCanvas *canvas ); + bool supportsTechnique( CaptureTechnique technique ) const override; void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; }; diff --git a/src/gui/qgsmaptooldigitizefeature.cpp b/src/gui/qgsmaptooldigitizefeature.cpp index 32604cdbed98..beca24bb1a0b 100644 --- a/src/gui/qgsmaptooldigitizefeature.cpp +++ b/src/gui/qgsmaptooldigitizefeature.cpp @@ -55,6 +55,7 @@ bool QgsMapToolDigitizeFeature::supportsTechnique( QgsMapToolCapture::CaptureTec case QgsMapToolCapture::StraightSegments: return true; case QgsMapToolCapture::CircularString: + case QgsMapToolCapture::Streaming: return mode() != QgsMapToolCapture::CapturePoint; } return false; From 3e32678fa465c6f5bcba7b983e67ef02403d1111 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 5 Mar 2021 12:43:27 +1000 Subject: [PATCH 014/377] Add test for streaming mode --- .../src/app/testqgsmaptooladdfeatureline.cpp | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/src/app/testqgsmaptooladdfeatureline.cpp b/tests/src/app/testqgsmaptooladdfeatureline.cpp index a2bd25f18ae0..b8a847b4a041 100644 --- a/tests/src/app/testqgsmaptooladdfeatureline.cpp +++ b/tests/src/app/testqgsmaptooladdfeatureline.cpp @@ -75,6 +75,7 @@ class TestQgsMapToolAddFeatureLine : public QObject void testSelfSnapping(); void testLineString(); void testCompoundCurve(); + void testStream(); private: QgisApp *mQgisApp = nullptr; @@ -855,5 +856,52 @@ void TestQgsMapToolAddFeatureLine::testCompoundCurve() mLayerLineCurved->undoStack()->undo(); } +void TestQgsMapToolAddFeatureLine::testStream() +{ + // test streaming mode digitizing + TestQgsMapToolAdvancedDigitizingUtils utils( mCaptureTool ); + + mCanvas->setCurrentLayer( mLayerLine ); + + QSet oldFids = utils.existingFeatureIds(); + + QgsSnappingConfig cfg = mCanvas->snappingUtils()->config(); + cfg.setEnabled( false ); + mCanvas->snappingUtils()->setConfig( cfg ); + + oldFids = utils.existingFeatureIds(); + utils.mouseClick( 5, 6.5, Qt::LeftButton ); + utils.mouseClick( 6.25, 6.5, Qt::LeftButton ); + utils.mouseClick( 6.75, 6.5, Qt::LeftButton ); + + mCaptureTool->setStreamDigitizingEnabled( true ); + utils.mouseMove( 7.0, 6.6 ); + utils.mouseMove( 7.1, 6.7 ); + utils.mouseMove( 7.2, 6.6 ); + utils.mouseMove( 7.3, 6.5 ); + utils.mouseMove( 7.5, 6.9 ); + utils.mouseMove( 7.6, 6.3 ); + utils.mouseClick( 7.75, 6.5, Qt::LeftButton ); + mCaptureTool->setStreamDigitizingEnabled( false ); + utils.mouseClick( 7.5, 5.0, Qt::LeftButton ); + mCaptureTool->setStreamDigitizingEnabled( true ); + utils.mouseMove( 7.4, 5.0 ); + utils.mouseMove( 7.3, 5.1 ); + utils.mouseMove( 7.2, 5.0 ); + utils.mouseMove( 7.1, 4.9 ); + + // check capture curve initially -- the streamed sections MUST become their own curve in the geometry, and not be compined with the straight line segments! + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5),(7.5 5, 7.41 5, 7.3 5.09, 7.2 5, 7.09 4.91))" ) ); + utils.mouseClick( 7.0, 5.0, Qt::RightButton ); + mCaptureTool->setStreamDigitizingEnabled( false ); + + QgsFeatureId newFid = utils.newFeatureId( oldFids ); + + QString wkt = "LineString (5 6.5, 6.25 6.5, 6.75 6.5, 7 6.59375, 7.09375 6.703125, 7.203125 6.59375, 7.296875 6.5, 7.5 6.90625, 7.59375 6.296875, 7.5 5, 7.40625 5, 7.296875 5.09375, 7.203125 5, 7.09375 4.90625)"; + QCOMPARE( mLayerLine->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( wkt ) ); + + mLayerLine->undoStack()->undo(); +} + QGSTEST_MAIN( TestQgsMapToolAddFeatureLine ) #include "testqgsmaptooladdfeatureline.moc" From 424934e9cd030760b5708fb7b9f9876a16a80bb5 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 5 Mar 2021 13:12:28 +1000 Subject: [PATCH 015/377] Implement undo logic for streamed digitizing mode When the backspace key is held down, points will be repeatedly removed from streamed digitized sections, right up till the start of the streaming section. Then the point removal will temporarily pause until the user releases and re-holds down the backspace key. This allows users to selectively remove portions of the geometry captured with the streaming mode by holding down the undo key, without risking accidental undo of non-streamed portions. --- .../auto_generated/qgsmaptoolcapture.sip.in | 7 +- src/gui/qgsmaptoolcapture.cpp | 18 +++- src/gui/qgsmaptoolcapture.h | 10 ++- .../src/app/testqgsmaptooladdfeatureline.cpp | 86 +++++++++++++++++++ tests/src/app/testqgsmaptoolutils.h | 6 +- 5 files changed, 118 insertions(+), 9 deletions(-) diff --git a/python/gui/auto_generated/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in index c51dd0d8feb8..418f65698cad 100644 --- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in +++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in @@ -232,9 +232,12 @@ Variant to supply more information in the case of snapping .. versionadded:: 2.14 %End - void undo(); + void undo( bool isAutoRepeat = false ); %Docstring -Removes the last vertex from mRubberBand and mCaptureList +Removes the last vertex from mRubberBand and mCaptureList. + +Since QGIS 3.20, if ``isAutoRepeat`` is set to ``True`` then the undo operation will be treated +as a auto repeated undo as if the user has held down the undo key for an extended period of time. %End void startCapturing(); diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 501ab8491c7e..ec411d344140 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -710,7 +710,7 @@ QList QgsMapToolCapture::snappingMatches() const return mSnappingMatches; } -void QgsMapToolCapture::undo() +void QgsMapToolCapture::undo( bool isAutoRepeat ) { mTracingStartPoint = QgsPointXY(); @@ -719,6 +719,10 @@ void QgsMapToolCapture::undo() if ( size() <= 1 && mTempRubberBand->pointsCount() != 0 ) return; + if ( isAutoRepeat && mIgnoreSubsequentAutoRepeatUndo ) + return; + mIgnoreSubsequentAutoRepeatUndo = false; + QgsPoint lastPoint = mTempRubberBand->lastPoint(); if ( mTempRubberBand->stringType() == QgsWkbTypes::CircularString && mTempRubberBand->pointsCount() > 2 ) @@ -742,12 +746,22 @@ void QgsMapToolCapture::undo() } else { + const int curvesBefore = mCaptureCurve.nCurves(); + const bool lastCurveIsLineString = qgsgeometry_cast< QgsLineString * >( mCaptureCurve.curveAt( curvesBefore - 1 ) ); + int pointsCountBefore = mCaptureCurve.numPoints(); mCaptureCurve.deleteVertex( vertexToRemove ); int pointsCountAfter = mCaptureCurve.numPoints(); for ( ; pointsCountAfter < pointsCountBefore; pointsCountAfter++ ) if ( !mSnappingMatches.empty() ) mSnappingMatches.removeLast(); + + // if we have removed the last point in a linestring curve, then we "stick" here and ignore subsequent + // autorepeat undo actions until the user releases the undo key and holds it down again. This allows + // users to selectively remove portions of the geometry captured with the streaming mode by holding down + // the undo key, without risking accidental undo of non-streamed portions. + if ( mCaptureCurve.nCurves() < curvesBefore && lastCurveIsLineString ) + mIgnoreSubsequentAutoRepeatUndo = true; } updateExtraSnapLayer(); @@ -773,7 +787,7 @@ void QgsMapToolCapture::keyPressEvent( QKeyEvent *e ) { if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ) { - undo(); + undo( e->isAutoRepeat() ); // Override default shortcut management in MapCanvas e->ignore(); diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index 4030f0ddec00..d61f95378fcf 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -326,8 +326,13 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing */ int addVertex( const QgsPointXY &mapPoint, const QgsPointLocator::Match &match ); - //! Removes the last vertex from mRubberBand and mCaptureList - void undo(); + /** + * Removes the last vertex from mRubberBand and mCaptureList. + * + * Since QGIS 3.20, if \a isAutoRepeat is set to TRUE then the undo operation will be treated + * as a auto repeated undo as if the user has held down the undo key for an extended period of time. + */ + void undo( bool isAutoRepeat = false ); /** * Start capturing @@ -466,6 +471,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing bool mAllowAddingStreamingPoints = false; bool mStartNewCurve = false; + bool mIgnoreSubsequentAutoRepeatUndo = false; }; diff --git a/tests/src/app/testqgsmaptooladdfeatureline.cpp b/tests/src/app/testqgsmaptooladdfeatureline.cpp index b8a847b4a041..cfd863a5d9ce 100644 --- a/tests/src/app/testqgsmaptooladdfeatureline.cpp +++ b/tests/src/app/testqgsmaptooladdfeatureline.cpp @@ -76,6 +76,7 @@ class TestQgsMapToolAddFeatureLine : public QObject void testLineString(); void testCompoundCurve(); void testStream(); + void testUndo(); private: QgisApp *mQgisApp = nullptr; @@ -903,5 +904,90 @@ void TestQgsMapToolAddFeatureLine::testStream() mLayerLine->undoStack()->undo(); } +void TestQgsMapToolAddFeatureLine::testUndo() +{ + // test undo logic + TestQgsMapToolAdvancedDigitizingUtils utils( mCaptureTool ); + + mCanvas->setCurrentLayer( mLayerLine ); + + QSet oldFids = utils.existingFeatureIds(); + + QgsSnappingConfig cfg = mCanvas->snappingUtils()->config(); + cfg.setEnabled( false ); + mCanvas->snappingUtils()->setConfig( cfg ); + + oldFids = utils.existingFeatureIds(); + utils.mouseClick( 5, 6.5, Qt::LeftButton ); + utils.mouseClick( 6.25, 6.5, Qt::LeftButton ); + utils.mouseClick( 6.75, 6.5, Qt::LeftButton ); + + mCaptureTool->setStreamDigitizingEnabled( true ); + utils.mouseMove( 7.0, 6.6 ); + utils.mouseMove( 7.1, 6.7 ); + utils.mouseMove( 7.2, 6.6 ); + utils.mouseMove( 7.3, 6.5 ); + utils.mouseMove( 7.5, 6.9 ); + utils.mouseMove( 7.6, 6.3 ); + utils.mouseClick( 7.75, 6.5, Qt::LeftButton ); + mCaptureTool->setStreamDigitizingEnabled( false ); + utils.mouseClick( 7.5, 5.0, Qt::LeftButton ); + mCaptureTool->setStreamDigitizingEnabled( true ); + utils.mouseMove( 7.4, 5.0 ); + utils.mouseMove( 7.3, 5.1 ); + utils.mouseMove( 7.2, 5.0 ); + utils.mouseMove( 7.1, 4.9 ); + + // check capture curve initially -- the streamed sections MUST become their own curve in the geometry, and not be compined with the straight line segments! + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5),(7.5 5, 7.41 5, 7.3 5.09, 7.2 5, 7.09 4.91))" ) ); + + // now lets try undoing... + utils.keyClick( Qt::Key_Backspace ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5),(7.5 5, 7.41 5, 7.3 5.09, 7.2 5))" ) ); + // simulate auto repeating undo from a held-down backspace key + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5),(7.5 5, 7.41 5, 7.3 5.09))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5),(7.5 5, 7.41 5))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + // we've now finished undoing the streamed digitizing section, so undo should pause until the user releases the backspace key and then re-presses it + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), false ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91, 7.59 6.3))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), false ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91))" ) ); + // simulate holding down another key + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + // should get "stuck" here again + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5))" ) ); + // release and repress + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), false ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5))" ) ); + utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true ); + + utils.mouseClick( 7.0, 5.0, Qt::RightButton ); + mCaptureTool->setStreamDigitizingEnabled( false ); +} + QGSTEST_MAIN( TestQgsMapToolAddFeatureLine ) #include "testqgsmaptooladdfeatureline.moc" diff --git a/tests/src/app/testqgsmaptoolutils.h b/tests/src/app/testqgsmaptoolutils.h index 503e323774ef..ec55d3b24de1 100644 --- a/tests/src/app/testqgsmaptoolutils.h +++ b/tests/src/app/testqgsmaptoolutils.h @@ -97,12 +97,12 @@ class TestQgsMapToolAdvancedDigitizingUtils mouseRelease( mapX, mapY, button, stateKey, snap ); } - void keyClick( int key, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers() ) + void keyClick( int key, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), bool autoRepeat = false ) { - QKeyEvent e1( QEvent::KeyPress, key, stateKey ); + QKeyEvent e1( QEvent::KeyPress, key, stateKey, QString(), autoRepeat ); mMapTool->keyPressEvent( &e1 ); - QKeyEvent e2( QEvent::KeyRelease, key, stateKey ); + QKeyEvent e2( QEvent::KeyRelease, key, stateKey, QString(), autoRepeat ); mMapTool->keyReleaseEvent( &e2 ); } From d20178c645ac9b99570fbf3fff72feadc49cd831 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 5 Mar 2021 13:48:21 +1000 Subject: [PATCH 016/377] Add option to control the tolerance of streamed digitizing --- src/app/CMakeLists.txt | 1 + src/app/maptools/qgsappmaptools.cpp | 51 ++++++++++++++++++ src/app/maptools/qgsappmaptools.h | 23 ++++++++ src/app/qgisapp.cpp | 34 +++++++++--- src/app/qgisapp.h | 2 +- src/gui/qgsmaptoolcapture.cpp | 9 ++++ src/ui/qgisapp.ui | 1 - .../src/app/testqgsmaptooladdfeatureline.cpp | 53 +++++++++++++++++++ 8 files changed, 166 insertions(+), 8 deletions(-) diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 5fb0e20a9e3d..8bed5854d72f 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -472,6 +472,7 @@ target_include_directories(qgis_app PUBLIC ${CMAKE_SOURCE_DIR}/src/app/pluginmanager ${CMAKE_SOURCE_DIR}/src/app/gps ${CMAKE_SOURCE_DIR}/src/app/dwg + ${CMAKE_SOURCE_DIR}/src/app/maptools ${CMAKE_SOURCE_DIR}/src/app/mesh ${CMAKE_SOURCE_DIR}/src/app/locator ${CMAKE_SOURCE_DIR}/src/app/pointcloud diff --git a/src/app/maptools/qgsappmaptools.cpp b/src/app/maptools/qgsappmaptools.cpp index afca5c7283ca..4afd39f66260 100644 --- a/src/app/maptools/qgsappmaptools.cpp +++ b/src/app/maptools/qgsappmaptools.cpp @@ -68,6 +68,50 @@ #include "qgsmaptoolchangelabelproperties.h" #include "qgsmaptoolpinlabels.h" #include "qgsmaptooloffsetpointsymbol.h" +#include "qgsspinbox.h" + +// +// QgsStreamDigitizingSettingsAction +// + +QgsStreamDigitizingSettingsAction::QgsStreamDigitizingSettingsAction( QWidget *parent ) + : QWidgetAction( parent ) +{ + QGridLayout *gLayout = new QGridLayout(); + gLayout->setContentsMargins( 3, 2, 3, 2 ); + + QgsSettings settings; + int defaultTolerance = settings.value( QStringLiteral( "/qgis/digitizing/stream_tolerance" ), 2 ).toInt(); + + mStreamToleranceSpinBox = new QgsSpinBox(); + mStreamToleranceSpinBox->setSuffix( tr( "px" ) ); + mStreamToleranceSpinBox->setKeyboardTracking( false ); + mStreamToleranceSpinBox->setRange( 1, 200 ); + mStreamToleranceSpinBox->setWrapping( false ); + mStreamToleranceSpinBox->setSingleStep( 1 ); + mStreamToleranceSpinBox->setClearValue( 2 ); + mStreamToleranceSpinBox->setValue( defaultTolerance ); + + QLabel *label = new QLabel( tr( "Tolerance" ) ); + gLayout->addWidget( label, 1, 0 ); + gLayout->addWidget( mStreamToleranceSpinBox, 1, 1 ); + connect( mStreamToleranceSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), this, [ = ]( int value ) + { + QgsSettings settings; + settings.setValue( QStringLiteral( "/qgis/digitizing/stream_tolerance" ), value ); + } ); + + QWidget *w = new QWidget(); + w->setLayout( gLayout ); + setDefaultWidget( w ); +} + +QgsStreamDigitizingSettingsAction::~QgsStreamDigitizingSettingsAction() = default; + + +// +// QgsAppMapTools +// QgsAppMapTools::QgsAppMapTools( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDock ) { @@ -133,6 +177,8 @@ QgsAppMapTools::QgsAppMapTools( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockW mTools.insert( Tool::MoveLabel, new QgsMapToolMoveLabel( canvas, cadDock ) ); mTools.insert( Tool::RotateLabel, new QgsMapToolRotateLabel( canvas, cadDock ) ); mTools.insert( Tool::ChangeLabelProperties, new QgsMapToolChangeLabelProperties( canvas, cadDock ) ); + + mStreamDigitizingSettingsAction = new QgsStreamDigitizingSettingsAction(); } QgsAppMapTools::~QgsAppMapTools() @@ -160,3 +206,8 @@ QList QgsAppMapTools::captureTools() const return res; } +QWidgetAction *QgsAppMapTools::streamDigitizingSettingsAction() +{ + return mStreamDigitizingSettingsAction; +} + diff --git a/src/app/maptools/qgsappmaptools.h b/src/app/maptools/qgsappmaptools.h index 9e89bff7b0d5..abfe1c05c3c2 100644 --- a/src/app/maptools/qgsappmaptools.h +++ b/src/app/maptools/qgsappmaptools.h @@ -19,12 +19,29 @@ #include #include #include +#include + class QgsMapTool; class QgsMapToolCapture; class QgsMapCanvas; class QgsAdvancedDigitizingDockWidget; +class QgsSpinBox; + +class QgsStreamDigitizingSettingsAction: public QWidgetAction +{ + Q_OBJECT + + public: + + QgsStreamDigitizingSettingsAction( QWidget *parent = nullptr ); + ~QgsStreamDigitizingSettingsAction() override; + + private: + QgsSpinBox *mStreamToleranceSpinBox = nullptr; +}; + class QgsAppMapTools { @@ -119,9 +136,15 @@ class QgsAppMapTools */ QList< QgsMapToolCapture * > captureTools() const; + /** + * Returns the stream digitizing settings action; + */ + QWidgetAction *streamDigitizingSettingsAction(); + private: QHash< Tool, QPointer< QgsMapTool > > mTools; + QgsStreamDigitizingSettingsAction *mStreamDigitizingSettingsAction = nullptr; }; diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 14082be2e221..65130b3cad4d 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -1049,9 +1049,13 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh functionProfile( &QgisApp::createMenus, this, QStringLiteral( "Create menus" ) ); functionProfile( &QgisApp::createActions, this, QStringLiteral( "Create actions" ) ); functionProfile( &QgisApp::createActionGroups, this, QStringLiteral( "Create action group" ) ); + + // create tools + mMapTools = std::make_unique< QgsAppMapTools >( mMapCanvas, mAdvancedDigitizingDockWidget ); + functionProfile( &QgisApp::createToolBars, this, QStringLiteral( "Toolbars" ) ); functionProfile( &QgisApp::createStatusBar, this, QStringLiteral( "Status bar" ) ); - functionProfile( &QgisApp::createCanvasTools, this, QStringLiteral( "Create canvas tools" ) ); + functionProfile( &QgisApp::setupCanvasTools, this, QStringLiteral( "Create canvas tools" ) ); const QList< QgsMapToolCapture * > captureTools = mMapTools->captureTools(); for ( QgsMapToolCapture *tool : captureTools ) { @@ -1718,6 +1722,8 @@ QgisApp::~QgisApp() delete mQgisInterface; delete mStyleSheetBuilder; + if ( QgsMapTool *tool = mMapCanvas->mapTool() ) + mMapCanvas->unsetMapTool( tool ); mMapTools.reset(); delete mpMaptip; @@ -3203,6 +3209,13 @@ void QgisApp::createToolBars() static_cast< void ( QgsDoubleSpinBox::* )( double ) >( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( double v ) { mTracer->setOffset( v ); } ); + QToolButton *bt = new QToolButton(); + bt->setPopupMode( QToolButton::MenuButtonPopup ); + bt->addAction( mActionStreamDigitize ); + bt->addAction( mMapTools->streamDigitizingSettingsAction() ); + bt->setDefaultAction( mActionStreamDigitize ); + mAdvancedDigitizeToolBar->insertWidget( mAdvancedDigitizeToolBar->actions().at( 0 ), bt ); + QList toolbarMenuActions; // Set action names so that they can be used in customization const auto constToolbarMenuToolBars = toolbarMenuToolBars; @@ -3218,7 +3231,7 @@ void QgisApp::createToolBars() mToolbarMenu->addActions( toolbarMenuActions ); // advanced selection tool button - QToolButton *bt = new QToolButton( mSelectionToolBar ); + bt = new QToolButton( mSelectionToolBar ); bt->setPopupMode( QToolButton::MenuButtonPopup ); bt->addAction( mActionSelectByForm ); bt->addAction( mActionSelectByExpression ); @@ -4226,11 +4239,8 @@ void QgisApp::setupConnections() connect( mLayoutsMenu, &QMenu::aboutToShow, this, &QgisApp::layoutsMenuAboutToShow ); } -void QgisApp::createCanvasTools() +void QgisApp::setupCanvasTools() { - // create tools - mMapTools = std::make_unique< QgsAppMapTools >( mMapCanvas, mAdvancedDigitizingDockWidget ); - mMapTools->mapTool( QgsAppMapTools::ZoomIn )->setAction( mActionZoomIn ); mMapTools->mapTool( QgsAppMapTools::ZoomOut )->setAction( mActionZoomOut ); connect( mMapTools->mapTool< QgsMapToolPan >( QgsAppMapTools::Pan ), &QgsMapToolPan::panDistanceBearingChanged, this, &QgisApp::showPanMessage ); @@ -10114,6 +10124,12 @@ void QgisApp::snappingOptions() void QgisApp::enableDigitizeWithCurve( bool enable ) { + if ( enable && mActionStreamDigitize->isChecked() ) + { + mActionStreamDigitize->setChecked( false ); + enableStreamDigitizing( false ); + } + const QList< QgsMapToolCapture * > captureTools = mMapTools->captureTools(); for ( QgsMapToolCapture *tool : captureTools ) { @@ -10126,6 +10142,12 @@ void QgisApp::enableDigitizeWithCurve( bool enable ) void QgisApp::enableStreamDigitizing( bool enable ) { + if ( enable && mActionDigitizeWithCurve->isChecked() ) + { + mActionDigitizeWithCurve->setChecked( false ); + enableDigitizeWithCurve( false ); + } + const QList< QgsMapToolCapture * > captureTools = mMapTools->captureTools(); for ( QgsMapToolCapture *tool : captureTools ) { diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index f02064999dc0..cf6008266487 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -2235,7 +2235,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow void setupConnections(); void initLayerTreeView(); void createOverview(); - void createCanvasTools(); + void setupCanvasTools(); void createMapTips(); void createDecorations(); void init3D(); diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index ec411d344140..f14bf3e1d8d2 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -385,6 +385,15 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) if ( mStreamingEnabled ) { + if ( ! mCaptureCurve.isEmpty() ) + { + QgsSettings settings; + const int tolerance = settings.value( QStringLiteral( "/qgis/digitizing/stream_tolerance" ), 2 ).toInt(); + QgsPoint prevPoint = mCaptureCurve.curveAt( mCaptureCurve.nCurves() - 1 )->endPoint(); + if ( QgsPointXY( toCanvasCoordinates( toMapCoordinates( mCanvas->currentLayer(), prevPoint ) ) ).distance( e->pos() ) < tolerance ) + return; + } + mAllowAddingStreamingPoints = true; addVertex( mapPoint ); mAllowAddingStreamingPoints = false; diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui index 301efdc76846..a4bcabac1ec9 100644 --- a/src/ui/qgisapp.ui +++ b/src/ui/qgisapp.ui @@ -521,7 +521,6 @@ false - diff --git a/tests/src/app/testqgsmaptooladdfeatureline.cpp b/tests/src/app/testqgsmaptooladdfeatureline.cpp index cfd863a5d9ce..606fa2105aac 100644 --- a/tests/src/app/testqgsmaptooladdfeatureline.cpp +++ b/tests/src/app/testqgsmaptooladdfeatureline.cpp @@ -77,6 +77,7 @@ class TestQgsMapToolAddFeatureLine : public QObject void testCompoundCurve(); void testStream(); void testUndo(); + void testStreamTolerance(); private: QgisApp *mQgisApp = nullptr; @@ -112,6 +113,8 @@ void TestQgsMapToolAddFeatureLine::initTestCase() QCoreApplication::setOrganizationName( QStringLiteral( "QGIS" ) ); QCoreApplication::setOrganizationDomain( QStringLiteral( "qgis.org" ) ); QCoreApplication::setApplicationName( QStringLiteral( "QGIS-TEST" ) ); + QgsSettings settings; + settings.clear(); mQgisApp = new QgisApp(); @@ -989,5 +992,55 @@ void TestQgsMapToolAddFeatureLine::testUndo() mCaptureTool->setStreamDigitizingEnabled( false ); } +void TestQgsMapToolAddFeatureLine::testStreamTolerance() +{ + // test streaming mode digitizing with tolerance + QgsSettings settings; + settings.setValue( QStringLiteral( "/qgis/digitizing/stream_tolerance" ), 10 ); + + TestQgsMapToolAdvancedDigitizingUtils utils( mCaptureTool ); + + mCanvas->setCurrentLayer( mLayerLine ); + + QSet oldFids = utils.existingFeatureIds(); + + QgsSnappingConfig cfg = mCanvas->snappingUtils()->config(); + cfg.setEnabled( false ); + mCanvas->snappingUtils()->setConfig( cfg ); + + oldFids = utils.existingFeatureIds(); + utils.mouseClick( 5, 6.5, Qt::LeftButton ); + utils.mouseClick( 6.25, 6.5, Qt::LeftButton ); + utils.mouseClick( 6.75, 6.5, Qt::LeftButton ); + + mCaptureTool->setStreamDigitizingEnabled( true ); + utils.mouseMove( 7.0, 6.6 ); + utils.mouseMove( 7.1, 6.7 ); + utils.mouseMove( 7.2, 6.6 ); + utils.mouseMove( 7.3, 6.5 ); + utils.mouseMove( 7.5, 6.9 ); + utils.mouseMove( 7.6, 6.3 ); + utils.mouseClick( 7.75, 6.5, Qt::LeftButton ); + mCaptureTool->setStreamDigitizingEnabled( false ); + utils.mouseClick( 7.5, 5.0, Qt::LeftButton ); + mCaptureTool->setStreamDigitizingEnabled( true ); + utils.mouseMove( 7.4, 5.0 ); + utils.mouseMove( 7.3, 5.1 ); + utils.mouseMove( 7.2, 5.0 ); + utils.mouseMove( 7.1, 4.9 ); + + // check capture curve initially -- the streamed sections MUST become their own curve in the geometry, and not be compined with the straight line segments! + QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.2 6.59, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5),(7.5 5, 7.3 5.09, 7.09 4.91))" ) ); + utils.mouseClick( 7.0, 5.0, Qt::RightButton ); + mCaptureTool->setStreamDigitizingEnabled( false ); + + QgsFeatureId newFid = utils.newFeatureId( oldFids ); + + QString wkt = "LineString (5 6.5, 6.25 6.5, 6.75 6.5, 7 6.59375, 7.203125 6.59375, 7.5 6.90625, 7.59375 6.296875, 7.5 5, 7.296875 5.09375, 7.09375 4.90625)"; + QCOMPARE( mLayerLine->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( wkt ) ); + + mLayerLine->undoStack()->undo(); +} + QGSTEST_MAIN( TestQgsMapToolAddFeatureLine ) #include "testqgsmaptooladdfeatureline.moc" From 800dbb8d2df96987128c3c15ef517ff2909caebc Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 8 Mar 2021 10:35:22 +1000 Subject: [PATCH 017/377] [needs-docs] Make the Digitize with Curve and Streaming Digitize actions sit in the same drop down group --- src/app/maptools/qgsappmaptools.cpp | 2 +- src/app/qgisapp.cpp | 39 +++++++++++++++++++++++------ src/app/qgisapp.h | 2 ++ src/ui/qgisapp.ui | 3 +-- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/app/maptools/qgsappmaptools.cpp b/src/app/maptools/qgsappmaptools.cpp index 4afd39f66260..60bf77512410 100644 --- a/src/app/maptools/qgsappmaptools.cpp +++ b/src/app/maptools/qgsappmaptools.cpp @@ -92,7 +92,7 @@ QgsStreamDigitizingSettingsAction::QgsStreamDigitizingSettingsAction( QWidget *p mStreamToleranceSpinBox->setClearValue( 2 ); mStreamToleranceSpinBox->setValue( defaultTolerance ); - QLabel *label = new QLabel( tr( "Tolerance" ) ); + QLabel *label = new QLabel( tr( "Streaming Tolerance" ) ); gLayout->addWidget( label, 1, 0 ); gLayout->addWidget( mStreamToleranceSpinBox, 1, 1 ); connect( mStreamToleranceSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), this, [ = ]( int value ) diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 65130b3cad4d..74bbbe68ef4f 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -3209,12 +3209,25 @@ void QgisApp::createToolBars() static_cast< void ( QgsDoubleSpinBox::* )( double ) >( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( double v ) { mTracer->setOffset( v ); } ); - QToolButton *bt = new QToolButton(); - bt->setPopupMode( QToolButton::MenuButtonPopup ); - bt->addAction( mActionStreamDigitize ); - bt->addAction( mMapTools->streamDigitizingSettingsAction() ); - bt->setDefaultAction( mActionStreamDigitize ); - mAdvancedDigitizeToolBar->insertWidget( mAdvancedDigitizeToolBar->actions().at( 0 ), bt ); + mDigitizeModeToolButton = new QToolButton(); + mDigitizeModeToolButton->setPopupMode( QToolButton::MenuButtonPopup ); + QMenu *digitizeMenu = new QMenu(); + digitizeMenu->addAction( mActionDigitizeWithCurve ); + digitizeMenu->addAction( mActionStreamDigitize ); + digitizeMenu->addSeparator(); + digitizeMenu->addAction( mMapTools->streamDigitizingSettingsAction() ); + mDigitizeModeToolButton->setMenu( digitizeMenu ); + + switch ( settings.value( QStringLiteral( "UI/digitizeTechnique" ), 0 ).toInt() ) + { + case 0: + mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithCurve ); + break; + case 1: + mDigitizeModeToolButton->setDefaultAction( mActionStreamDigitize ); + break; + } + mAdvancedDigitizeToolBar->insertWidget( mAdvancedDigitizeToolBar->actions().at( 0 ), mDigitizeModeToolButton ); QList toolbarMenuActions; // Set action names so that they can be used in customization @@ -3231,7 +3244,7 @@ void QgisApp::createToolBars() mToolbarMenu->addActions( toolbarMenuActions ); // advanced selection tool button - bt = new QToolButton( mSelectionToolBar ); + QToolButton *bt = new QToolButton( mSelectionToolBar ); bt->setPopupMode( QToolButton::MenuButtonPopup ); bt->addAction( mActionSelectByForm ); bt->addAction( mActionSelectByExpression ); @@ -10130,6 +10143,12 @@ void QgisApp::enableDigitizeWithCurve( bool enable ) enableStreamDigitizing( false ); } + if ( enable ) + { + mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithCurve ); + QgsSettings().setValue( QStringLiteral( "UI/digitizeTechnique" ), 0 ); + } + const QList< QgsMapToolCapture * > captureTools = mMapTools->captureTools(); for ( QgsMapToolCapture *tool : captureTools ) { @@ -10148,6 +10167,12 @@ void QgisApp::enableStreamDigitizing( bool enable ) enableDigitizeWithCurve( false ); } + if ( enable ) + { + mDigitizeModeToolButton->setDefaultAction( mActionStreamDigitize ); + QgsSettings().setValue( QStringLiteral( "UI/digitizeTechnique" ), 1 ); + } + const QList< QgsMapToolCapture * > captureTools = mMapTools->captureTools(); for ( QgsMapToolCapture *tool : captureTools ) { diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index cf6008266487..e36acc02be8d 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -2531,6 +2531,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow QgsDockWidget *mDevToolsDock = nullptr; QgsDevToolsPanelWidget *mDevToolsWidget = nullptr; + QToolButton *mDigitizeModeToolButton = nullptr; + //! Persistent tile scale slider QgsTileScaleWidget *mpTileScaleWidget = nullptr; diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui index a4bcabac1ec9..67f5cd1cc06b 100644 --- a/src/ui/qgisapp.ui +++ b/src/ui/qgisapp.ui @@ -521,7 +521,6 @@ false - @@ -3468,7 +3467,7 @@ Shows placeholders for labels which could not be placed, e.g. due to overlaps wi :/images/themes/default/mActionDigitizeWithCurve.svg:/images/themes/default/mActionDigitizeWithCurve.svg - Digitize with curve + Digitize with Curve Digitize with curve From 422f5300ad407ed76fe93489a379ee3634fde088 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 8 Mar 2021 10:43:35 +1000 Subject: [PATCH 018/377] Proper icon for streaming digitize mode --- images/images.qrc | 1 + images/themes/default/mActionStreamingDigitize.svg | 1 + src/ui/qgisapp.ui | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 images/themes/default/mActionStreamingDigitize.svg diff --git a/images/images.qrc b/images/images.qrc index dc98a9973d25..89923684e280 100644 --- a/images/images.qrc +++ b/images/images.qrc @@ -910,6 +910,7 @@ themes/default/mIconCodeEditor.svg themes/default/console/iconSyntaxErrorConsoleParams.svg themes/default/mIconSnappingEndpoint.svg + themes/default/mActionStreamingDigitize.svg qgis_tips/symbol_levels.png diff --git a/images/themes/default/mActionStreamingDigitize.svg b/images/themes/default/mActionStreamingDigitize.svg new file mode 100644 index 000000000000..acf7ef3c20d7 --- /dev/null +++ b/images/themes/default/mActionStreamingDigitize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui index 67f5cd1cc06b..4ecee3c61c3e 100644 --- a/src/ui/qgisapp.ui +++ b/src/ui/qgisapp.ui @@ -3494,7 +3494,7 @@ Shows placeholders for labels which could not be placed, e.g. due to overlaps wi - :/images/themes/default/mIconSnappingSelf.svg:/images/themes/default/mIconSnappingSelf.svg + :/images/themes/default/mActionStreamingDigitize.svg:/images/themes/default/mActionStreamingDigitize.svg Stream Digitizing From 2f1d3d916a2efd5f0424c06c3a7d5d4441d6cffc Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 8 Mar 2021 11:01:09 +1000 Subject: [PATCH 019/377] Fix tolerance handling with snapped points --- src/gui/qgsmaptoolcapture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index f14bf3e1d8d2..3043fc694075 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -390,7 +390,7 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) QgsSettings settings; const int tolerance = settings.value( QStringLiteral( "/qgis/digitizing/stream_tolerance" ), 2 ).toInt(); QgsPoint prevPoint = mCaptureCurve.curveAt( mCaptureCurve.nCurves() - 1 )->endPoint(); - if ( QgsPointXY( toCanvasCoordinates( toMapCoordinates( mCanvas->currentLayer(), prevPoint ) ) ).distance( e->pos() ) < tolerance ) + if ( QgsPointXY( toCanvasCoordinates( toMapCoordinates( mCanvas->currentLayer(), prevPoint ) ) ).distance( toCanvasCoordinates( point ) ) < tolerance ) return; } From b7e8cd541eae43d0c71f43ed4d2a18aee97cc6fd Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 11 Mar 2021 17:26:41 +1000 Subject: [PATCH 020/377] Only retrieve streaming tolerance once per operation, not with every mouse move --- src/gui/qgsmaptoolcapture.cpp | 11 +++++++---- src/gui/qgsmaptoolcapture.h | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 3043fc694075..56a53ed54f1d 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -368,6 +368,11 @@ void QgsMapToolCapture::setStreamDigitizingEnabled( bool enable ) { mStreamingEnabled = enable; mStartNewCurve = true; + if ( enable ) + { + QgsSettings settings; + mStreamingToleranceInPixels = settings.value( QStringLiteral( "/qgis/digitizing/stream_tolerance" ), 2 ).toInt(); + } } void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) @@ -385,12 +390,10 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) if ( mStreamingEnabled ) { - if ( ! mCaptureCurve.isEmpty() ) + if ( !mCaptureCurve.isEmpty() ) { - QgsSettings settings; - const int tolerance = settings.value( QStringLiteral( "/qgis/digitizing/stream_tolerance" ), 2 ).toInt(); QgsPoint prevPoint = mCaptureCurve.curveAt( mCaptureCurve.nCurves() - 1 )->endPoint(); - if ( QgsPointXY( toCanvasCoordinates( toMapCoordinates( mCanvas->currentLayer(), prevPoint ) ) ).distance( toCanvasCoordinates( point ) ) < tolerance ) + if ( QgsPointXY( toCanvasCoordinates( toMapCoordinates( mCanvas->currentLayer(), prevPoint ) ) ).distance( toCanvasCoordinates( point ) ) < mStreamingToleranceInPixels ) return; } diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index d61f95378fcf..7a51611876e2 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -469,6 +469,8 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing bool mStreamingEnabled = false; bool mAllowAddingStreamingPoints = false; + int mStreamingToleranceInPixels = 1; + bool mStartNewCurve = false; bool mIgnoreSubsequentAutoRepeatUndo = false; From 6ce99826e3fb0bc02af00755e1ced949768ec3e7 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 11 Mar 2021 17:27:14 +1000 Subject: [PATCH 021/377] Dox++ --- src/gui/qgsmaptoolcapture.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index 7a51611876e2..bccf6b913afe 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -143,7 +143,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing { StraightSegments, //!< Default capture mode - capture occurs with straight line segments CircularString, //!< Capture in circular strings - Streaming, //!< Streaming points digitizing mode (points are automatically added as the mouse cursor moves) + Streaming, //!< Streaming points digitizing mode (points are automatically added as the mouse cursor moves). Since QGIS 3.20. }; //! Specific capabilities of the tool From 71f1bba266dcbcf95aa0141feb502be4616efe75 Mon Sep 17 00:00:00 2001 From: nirvn Date: Thu, 11 Mar 2021 09:35:15 +0700 Subject: [PATCH 022/377] [ogr] Fix absence of proper feature ID when adding features to CSV, ODS, and XLSX datasets --- src/core/providers/ogr/qgsogrprovider.cpp | 43 ++++++++++++++++++----- src/core/providers/ogr/qgsogrprovider.h | 6 ++-- tests/src/core/testqgsogrprovider.cpp | 32 +++++++++++++++++ 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/src/core/providers/ogr/qgsogrprovider.cpp b/src/core/providers/ogr/qgsogrprovider.cpp index ce3444665439..da6b713f2c09 100644 --- a/src/core/providers/ogr/qgsogrprovider.cpp +++ b/src/core/providers/ogr/qgsogrprovider.cpp @@ -1669,7 +1669,7 @@ QString QgsOgrProvider::jsonStringValue( const QVariant &value ) const return stringValue; } -bool QgsOgrProvider::addFeaturePrivate( QgsFeature &f, Flags flags ) +bool QgsOgrProvider::addFeaturePrivate( QgsFeature &f, Flags flags, QgsFeatureId incrementalFeatureId ) { bool returnValue = true; QgsOgrFeatureDefn &featureDefinition = mOgrLayer->GetLayerDefn(); @@ -1860,16 +1860,23 @@ bool QgsOgrProvider::addFeaturePrivate( QgsFeature &f, Flags flags ) pushError( tr( "OGR error creating feature %1: %2" ).arg( f.id() ).arg( CPLGetLastErrorMsg() ) ); returnValue = false; } - else if ( !( flags & QgsFeatureSink::FastInsert ) ) + else { - QgsFeatureId id = static_cast( OGR_F_GetFID( feature.get() ) ); - if ( id >= 0 ) + if ( !( flags & QgsFeatureSink::FastInsert ) ) { - f.setId( id ); + QgsFeatureId id = static_cast( OGR_F_GetFID( feature.get() ) ); + if ( id >= 0 ) + { + f.setId( id ); - if ( mFirstFieldIsFid && attributes.count() > 0 ) + if ( mFirstFieldIsFid && attributes.count() > 0 ) + { + f.setAttribute( 0, id ); + } + } + else if ( incrementalFeatureId >= 0 ) { - f.setAttribute( 0, id ); + f.setId( incrementalFeatureId ); } } } @@ -1890,13 +1897,33 @@ bool QgsOgrProvider::addFeatures( QgsFeatureList &flist, Flags flags ) const bool inTransaction = startTransaction(); + QgsFeatureId incrementalFeatureId = -1; + OGRGeometryH filter; + if ( !( flags & QgsFeatureSink::FastInsert ) && + ( mGDALDriverName == QLatin1String( "CSV" ) || mGDALDriverName == QLatin1String( "XLSX" ) || mGDALDriverName == QLatin1String( "ODS" ) ) ) + { + filter = mOgrLayer->GetSpatialFilter(); + if ( filter ) + { + filter = OGR_G_Clone( filter ); + mOgrLayer->SetSpatialFilter( nullptr ); + } + + incrementalFeatureId = static_cast< QgsFeatureId >( mOgrLayer->GetFeatureCount() ) + 1; + + if ( filter ) + mOgrLayer->SetSpatialFilter( filter ); + } + bool returnvalue = true; for ( QgsFeatureList::iterator it = flist.begin(); it != flist.end(); ++it ) { - if ( !addFeaturePrivate( *it, flags ) ) + if ( !addFeaturePrivate( *it, flags, incrementalFeatureId ) ) { returnvalue = false; } + if ( incrementalFeatureId >= 0 ) + incrementalFeatureId++; } if ( inTransaction ) diff --git a/src/core/providers/ogr/qgsogrprovider.h b/src/core/providers/ogr/qgsogrprovider.h index 827e3927862b..d8cd7968804a 100644 --- a/src/core/providers/ogr/qgsogrprovider.h +++ b/src/core/providers/ogr/qgsogrprovider.h @@ -310,10 +310,12 @@ class QgsOgrProvider final: public QgsVectorDataProvider mutable QStringList mSubLayerList; - //! converts \a value from json QVariant to QString + //! Converts \a value from json QVariant to QString QString jsonStringValue( const QVariant &value ) const; - bool addFeaturePrivate( QgsFeature &f, QgsFeatureSink::Flags flags ); + //! The \a incrementalFeatureId will generally be -1, except for a few OGR drivers where QGIS will pass on a value when OGR doesn't set it + bool addFeaturePrivate( QgsFeature &f, QgsFeatureSink::Flags flags, QgsFeatureId incrementalFeatureId = -1 ); + //! Deletes one feature bool deleteFeature( QgsFeatureId id ); diff --git a/tests/src/core/testqgsogrprovider.cpp b/tests/src/core/testqgsogrprovider.cpp index d63df9ef600e..f2c8869df412 100644 --- a/tests/src/core/testqgsogrprovider.cpp +++ b/tests/src/core/testqgsogrprovider.cpp @@ -49,6 +49,7 @@ class TestQgsOgrProvider : public QObject void decodeUri(); void encodeUri(); void testThread(); + void testCsvFeatureAddition(); private: QString mTestDataDir; @@ -352,6 +353,37 @@ void TestQgsOgrProvider::testThread() } +void TestQgsOgrProvider::testCsvFeatureAddition() +{ + QString csvFilename = QDir::tempPath() + "/csvfeatureadditiontest.csv"; + QFile csvFile( csvFilename ); + if ( csvFile.open( QIODevice::WriteOnly | QIODevice::Append ) ) + { + QTextStream textStream( &csvFile ); + textStream << QLatin1String( "col1,col2\n1,2\n" ); + csvFile.close(); + } + + QgsVectorLayer *csvLayer = new QgsVectorLayer( csvFilename, QStringLiteral( "csv" ) ); + QVERIFY( csvLayer->isValid() ); + QCOMPARE( csvLayer->featureCount(), 1 ); + + + QgsFeature feature( csvLayer->fields() ); + feature.setAttribute( 0, 1 ); + feature.setAttribute( 1, 1 ); + feature.setAttribute( 2, QLatin1String( "csv" ) ); + + QgsFeatureList features; + features << feature << feature; + csvLayer->dataProvider()->addFeatures( features ); + QCOMPARE( features.at( 0 ).id(), 2 ); + QCOMPARE( features.at( 1 ).id(), 3 ); + + delete csvLayer; + QFile::remove( csvFilename ); +} + QGSTEST_MAIN( TestQgsOgrProvider ) #include "testqgsogrprovider.moc" From 6750566b3fae59395e5d42ba9c3862669d1076bc Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 11 Mar 2021 17:17:04 +1000 Subject: [PATCH 023/377] [pal] Fix crash in labeling polygons in some rare circumstance which I can only reproduce on a single project But this code is so totally unreadable that it's not suprising that there's all kinds of nasty here. In this case the crash is caused when the polygon part calculated by "splitPolygons" (which does... something... to a polygon) results in a zero area polygon (because... reasons). So add a safeguard in to avoid this situation. Also rename class to something saner --- src/core/pal/feature.cpp | 9 +++++--- src/core/pal/pointset.cpp | 47 +++++++++++++++++---------------------- src/core/pal/pointset.h | 10 +++++---- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/core/pal/feature.cpp b/src/core/pal/feature.cpp index d9c0b29f1462..7ac03dc5332b 100644 --- a/src/core/pal/feature.cpp +++ b/src/core/pal/feature.cpp @@ -1654,14 +1654,17 @@ std::size_t FeaturePart::createCandidatesForPolygon( std::vector< std::unique_pt double beta; double diago = std::sqrt( labelWidth * labelWidth / 4.0 + labelHeight * labelHeight / 4 ); double rx, ry; - std::vector< CHullBox > boxes; + std::vector< OrientedConvexHullBoundingBox > boxes; boxes.reserve( shapes_final.size() ); // Compute bounding box foreach finalShape while ( !shapes_final.isEmpty() ) { PointSet *shape = shapes_final.takeFirst(); - boxes.emplace_back( shape->compute_chull_bbox() ); + bool ok = false; + OrientedConvexHullBoundingBox box = shape->computeConvexHullOrientedBoundingBox( ok ); + if ( ok ) + boxes.emplace_back( box ); if ( shape->parent ) delete shape; @@ -1682,7 +1685,7 @@ std::size_t FeaturePart::createCandidatesForPolygon( std::vector< std::unique_pt do { - for ( CHullBox &box : boxes ) + for ( OrientedConvexHullBoundingBox &box : boxes ) { // there is two possibilities here: // 1. no maximum candidates for polygon setting is in effect (i.e. maxPolygonCandidates == 0). In that case, diff --git a/src/core/pal/pointset.cpp b/src/core/pal/pointset.cpp index d0475fabf6c9..d3d67745d2d0 100644 --- a/src/core/pal/pointset.cpp +++ b/src/core/pal/pointset.cpp @@ -649,11 +649,9 @@ void PointSet::extendLineByDistance( double startDistance, double endDistance, d invalidateGeos(); } -CHullBox PointSet::compute_chull_bbox() +OrientedConvexHullBoundingBox PointSet::computeConvexHullOrientedBoundingBox( bool &ok ) { - int i; - int j; - + ok = false; double bbox[4]; // xmin, ymin, xmax, ymax double alpha; @@ -661,19 +659,10 @@ CHullBox PointSet::compute_chull_bbox() double alpha_seg; - double dref; double d1, d2; double bb[16]; // {ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, gx, gy, hx, hy}} - double cp; - double best_cp; - double distNearestPoint; - - double area; - double width; - double length; - double best_area = std::numeric_limits::max(); double best_alpha = -1; double best_bb[16]; @@ -686,7 +675,7 @@ CHullBox PointSet::compute_chull_bbox() bbox[2] = std::numeric_limits::lowest(); bbox[3] = std::numeric_limits::lowest(); - for ( i = 0; i < cHullSize; i++ ) + for ( int i = 0; i < cHullSize; i++ ) { if ( x[cHull[i]] < bbox[0] ) bbox[0] = x[cHull[i]]; @@ -701,8 +690,14 @@ CHullBox PointSet::compute_chull_bbox() bbox[3] = y[cHull[i]]; } + OrientedConvexHullBoundingBox finalBb; - dref = bbox[2] - bbox[0]; + const double dref = bbox[2] - bbox[0]; + if ( qgsDoubleNear( dref, 0 ) ) + { + ok = false; + return finalBb; + } for ( alpha_d = 0; alpha_d < 90; alpha_d++ ) { @@ -733,22 +728,22 @@ CHullBox PointSet::compute_chull_bbox() bb[15] = bb[13] - d1; // hx, hy // adjust all points - for ( i = 0; i < 16; i += 4 ) + for ( int i = 0; i < 16; i += 4 ) { alpha_seg = ( ( i / 4 > 0 ? ( i / 4 ) - 1 : 3 ) ) * M_PI_2 + alpha; - best_cp = std::numeric_limits::max(); - for ( j = 0; j < nbPoints; j++ ) + double best_cp = std::numeric_limits::max(); + for ( int j = 0; j < nbPoints; j++ ) { - cp = GeomFunction::cross_product( bb[i + 2], bb[i + 3], bb[i], bb[i + 1], x[cHull[j]], y[cHull[j]] ); + const double cp = GeomFunction::cross_product( bb[i + 2], bb[i + 3], bb[i], bb[i + 1], x[cHull[j]], y[cHull[j]] ); if ( cp < best_cp ) { best_cp = cp; } } - distNearestPoint = best_cp / dref; + const double distNearestPoint = best_cp / dref; d1 = std::cos( alpha_seg ) * distNearestPoint; d2 = std::sin( alpha_seg ) * distNearestPoint; @@ -760,10 +755,10 @@ CHullBox PointSet::compute_chull_bbox() } // compute and compare AREA - width = GeomFunction::cross_product( bb[6], bb[7], bb[4], bb[5], bb[12], bb[13] ) / dref; - length = GeomFunction::cross_product( bb[2], bb[3], bb[0], bb[1], bb[8], bb[9] ) / dref; + const double width = GeomFunction::cross_product( bb[6], bb[7], bb[4], bb[5], bb[12], bb[13] ) / dref; + const double length = GeomFunction::cross_product( bb[2], bb[3], bb[0], bb[1], bb[8], bb[9] ) / dref; - area = width * length; + double area = width * length; if ( area < 0 ) area *= -1; @@ -780,10 +775,7 @@ CHullBox PointSet::compute_chull_bbox() } // best bbox is defined - - CHullBox finalBb; - - for ( i = 0; i < 16; i = i + 4 ) + for ( int i = 0; i < 16; i = i + 4 ) { GeomFunction::computeLineIntersection( best_bb[i], best_bb[i + 1], best_bb[i + 2], best_bb[i + 3], best_bb[( i + 4 ) % 16], best_bb[( i + 5 ) % 16], best_bb[( i + 6 ) % 16], best_bb[( i + 7 ) % 16], @@ -794,6 +786,7 @@ CHullBox PointSet::compute_chull_bbox() finalBb.width = best_width; finalBb.length = best_length; + ok = true; return finalBb; } diff --git a/src/core/pal/pointset.h b/src/core/pal/pointset.h index 14b9d3f45b57..70ca0924ce6a 100644 --- a/src/core/pal/pointset.h +++ b/src/core/pal/pointset.h @@ -52,7 +52,10 @@ namespace pal class PointSet; - struct CHullBox + /** + * Represents the minimum area, oriented bounding box surrounding a convex hull. + */ + struct OrientedConvexHullBoundingBox { double x[4]; double y[4]; @@ -112,10 +115,9 @@ namespace pal bool containsLabelCandidate( double x, double y, double width, double height, double alpha = 0 ) const; /** - * Computes a con???? hull. Maybe convex, maybe concave. The person who wrote this - * had no care for anyone else ever reading their code. + * Computes an oriented bounding box for the shape's convex hull. */ - CHullBox compute_chull_bbox(); + OrientedConvexHullBoundingBox computeConvexHullOrientedBoundingBox( bool &ok ); /** * Split a concave shape into several convex shapes. From 079ae7d37a7b2d54ae2c4c9c5a818c4268025edd Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 10 Mar 2021 14:20:21 +1000 Subject: [PATCH 024/377] Optimise two heavily used methods in QgsLineString --- src/core/geometry/qgslinestring.cpp | 36 ++++++++++++++++------------- src/core/geometry/qgslinestring.h | 1 + 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/core/geometry/qgslinestring.cpp b/src/core/geometry/qgslinestring.cpp index f3581eab7cc6..e5a2af5d2fb6 100644 --- a/src/core/geometry/qgslinestring.cpp +++ b/src/core/geometry/qgslinestring.cpp @@ -375,6 +375,18 @@ bool QgsLineString::removeDuplicateNodes( double epsilon, bool useZValues ) return result; } +bool QgsLineString::isClosed() const +{ + if ( mX.empty() ) + return false; + + bool closed = qgsDoubleNear( mX.first(), mX.last() ) && + qgsDoubleNear( mY.first(), mY.last() ); + if ( is3D() && closed ) + closed &= qgsDoubleNear( mZ.first(), mZ.last() ) || ( std::isnan( mZ.first() ) && std::isnan( mZ.last() ) ); + return closed; +} + QVector< QgsVertexId > QgsLineString::collectDuplicateNodes( double epsilon, bool useZValues ) const { QVector< QgsVertexId > res; @@ -448,23 +460,15 @@ bool QgsLineString::fromWkb( QgsConstWkbPtr &wkbPtr ) QgsRectangle QgsLineString::calculateBoundingBox() const { - double xmin = std::numeric_limits::max(); - double ymin = std::numeric_limits::max(); - double xmax = -std::numeric_limits::max(); - double ymax = -std::numeric_limits::max(); + if ( mX.empty() ) + return QgsRectangle(); - const int nb = mX.size(); - const double *x = mX.constData(); - const double *y = mY.constData(); - for ( int i = 0; i < nb; ++i ) - { - const double px = *x++; - xmin = std::min( xmin, px ); - xmax = std::max( xmax, px ); - const double py = *y++; - ymin = std::min( ymin, py ); - ymax = std::max( ymax, py ); - } + auto result = std::minmax_element( mX.begin(), mX.end() ); + const double xmin = *result.first; + const double xmax = *result.second; + result = std::minmax_element( mY.begin(), mY.end() ); + const double ymin = *result.first; + const double ymax = *result.second; return QgsRectangle( xmin, ymin, xmax, ymax, false ); } diff --git a/src/core/geometry/qgslinestring.h b/src/core/geometry/qgslinestring.h index 7975b8e1b9de..d04bd3767700 100644 --- a/src/core/geometry/qgslinestring.h +++ b/src/core/geometry/qgslinestring.h @@ -590,6 +590,7 @@ class CORE_EXPORT QgsLineString: public QgsCurve bool isValid( QString &error SIP_OUT, int flags = 0 ) const override; QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY; bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits::epsilon(), bool useZValues = false ) override; + bool isClosed() const override SIP_HOLDGIL; /** * Returns a list of any duplicate nodes contained in the geometry, within the specified tolerance. From f98558f06cb0764cbbd66f50e2ac01c0432ae21d Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 10 Mar 2021 14:20:43 +1000 Subject: [PATCH 025/377] Add optimised conversion methods for ogr (multi)polygons to QgsGeometry Avoids conversion back and forth from wkb to transfer these geometries from ogr to qgis --- src/core/qgsogrutils.cpp | 49 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/core/qgsogrutils.cpp b/src/core/qgsogrutils.cpp index b4672c0b4905..9c4e80da7502 100644 --- a/src/core/qgsogrutils.cpp +++ b/src/core/qgsogrutils.cpp @@ -23,6 +23,9 @@ #include "qgsmultilinestring.h" #include "qgsogrprovider.h" #include "qgslinesymbollayer.h" +#include "qgspolygon.h" +#include "qgsmultipolygon.h" + #include #include #include @@ -427,6 +430,38 @@ std::unique_ptr< QgsMultiLineString > ogrGeometryToQgsMultiLineString( OGRGeomet return mp; } +std::unique_ptr< QgsPolygon > ogrGeometryToQgsPolygon( OGRGeometryH geom ) +{ + std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >(); + + const int count = OGR_G_GetGeometryCount( geom ); + if ( count >= 1 ) + { + polygon->setExteriorRing( ogrGeometryToQgsLineString( OGR_G_GetGeometryRef( geom, 0 ) ).release() ); + } + + for ( int i = 1; i < count; ++i ) + { + polygon->addInteriorRing( ogrGeometryToQgsLineString( OGR_G_GetGeometryRef( geom, i ) ).release() ); + } + + return polygon; +} + +std::unique_ptr< QgsMultiPolygon > ogrGeometryToQgsMultiPolygon( OGRGeometryH geom ) +{ + std::unique_ptr< QgsMultiPolygon > polygon = std::make_unique< QgsMultiPolygon >(); + + const int count = OGR_G_GetGeometryCount( geom ); + polygon->reserve( count ); + for ( int i = 0; i < count; ++i ) + { + polygon->addGeometry( ogrGeometryToQgsPolygon( OGR_G_GetGeometryRef( geom, i ) ).release() ); + } + + return polygon; +} + QgsWkbTypes::Type QgsOgrUtils::ogrGeometryTypeToQgsWkbType( OGRwkbGeometryType ogrGeomType ) { switch ( ogrGeomType ) @@ -537,19 +572,27 @@ QgsGeometry QgsOgrUtils::ogrGeometryToQgsGeometry( OGRGeometryH geom ) case QgsWkbTypes::LineString: { - // optimised case for line -- avoid wkb conversion return QgsGeometry( ogrGeometryToQgsLineString( geom ) ); } case QgsWkbTypes::MultiLineString: { - // optimised case for line -- avoid wkb conversion return QgsGeometry( ogrGeometryToQgsMultiLineString( geom ) ); } + case QgsWkbTypes::Polygon: + { + return QgsGeometry( ogrGeometryToQgsPolygon( geom ) ); + } + + case QgsWkbTypes::MultiPolygon: + { + return QgsGeometry( ogrGeometryToQgsMultiPolygon( geom ) ); + } + default: break; - }; + } // Fallback to inefficient WKB conversions From 509025ad5f226aeca50a51cf5a6d895f29bfb0c3 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 10 Mar 2021 14:30:17 +1000 Subject: [PATCH 026/377] Cleanups --- src/core/providers/ogr/qgsogrfeatureiterator.cpp | 7 ++++--- src/core/providers/ogr/qgsogrfeatureiterator.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/providers/ogr/qgsogrfeatureiterator.cpp b/src/core/providers/ogr/qgsogrfeatureiterator.cpp index dd9db8588504..3660e778dfef 100644 --- a/src/core/providers/ogr/qgsogrfeatureiterator.cpp +++ b/src/core/providers/ogr/qgsogrfeatureiterator.cpp @@ -61,7 +61,7 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource *source, bool && mRequest.filterType() != QgsFeatureRequest::FilterType::FilterFids ); QgsCPLHTTPFetchOverrider oCPLHTTPFetcher( mAuthCfg ); - QgsSetCPLHTTPFetchOverriderInitiatorClass( oCPLHTTPFetcher, QStringLiteral( "QgsOgrFeatureIterator" ) ); + QgsSetCPLHTTPFetchOverriderInitiatorClass( oCPLHTTPFetcher, QStringLiteral( "QgsOgrFeatureIterator" ) ) for ( const auto &id : mRequest.filterFids() ) { @@ -155,6 +155,7 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource *source, bool { QSet attributeIndexes; const auto usedAttributeIndices = mRequest.orderBy().usedAttributeIndices( mSource->mFields ); + attributeIndexes.reserve( usedAttributeIndices.size() ); for ( int attrIdx : usedAttributeIndices ) { attributeIndexes << attrIdx; @@ -347,7 +348,7 @@ bool QgsOgrFeatureIterator::fetchFeature( QgsFeature &feature ) QMutexLocker locker( mSharedDS ? &mSharedDS->mutex() : nullptr ); QgsCPLHTTPFetchOverrider oCPLHTTPFetcher( mAuthCfg, mInterruptionChecker ); - QgsSetCPLHTTPFetchOverriderInitiatorClass( oCPLHTTPFetcher, QStringLiteral( "QgsOgrFeatureIterator" ) ); + QgsSetCPLHTTPFetchOverriderInitiatorClass( oCPLHTTPFetcher, QStringLiteral( "QgsOgrFeatureIterator" ) ) feature.setValid( false ); @@ -501,7 +502,7 @@ void QgsOgrFeatureIterator::getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature f.setAttribute( attindex, value ); } -bool QgsOgrFeatureIterator::readFeature( gdal::ogr_feature_unique_ptr fet, QgsFeature &feature ) const +bool QgsOgrFeatureIterator::readFeature( const gdal::ogr_feature_unique_ptr &fet, QgsFeature &feature ) const { feature.setId( OGR_F_GetFID( fet.get() ) ); feature.initAttributes( mSource->mFields.count() ); diff --git a/src/core/providers/ogr/qgsogrfeatureiterator.h b/src/core/providers/ogr/qgsogrfeatureiterator.h index a6140017e93f..c0ceb53c6909 100644 --- a/src/core/providers/ogr/qgsogrfeatureiterator.h +++ b/src/core/providers/ogr/qgsogrfeatureiterator.h @@ -82,7 +82,7 @@ class QgsOgrFeatureIterator final: public QgsAbstractFeatureIteratorFromSource Date: Wed, 10 Mar 2021 14:30:56 +1000 Subject: [PATCH 027/377] Move trivial check before expensive check --- src/core/providers/ogr/qgsogrfeatureiterator.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/providers/ogr/qgsogrfeatureiterator.cpp b/src/core/providers/ogr/qgsogrfeatureiterator.cpp index 3660e778dfef..52c2c7ba2199 100644 --- a/src/core/providers/ogr/qgsogrfeatureiterator.cpp +++ b/src/core/providers/ogr/qgsogrfeatureiterator.cpp @@ -534,12 +534,12 @@ bool QgsOgrFeatureIterator::readFeature( const gdal::ogr_feature_unique_ptr &fet { // OK } - else if ( ( useIntersect && ( !feature.hasGeometry() - || ( mRequest.flags() & QgsFeatureRequest::ExactIntersect && !feature.geometry().intersects( mFilterRect ) ) - || ( !( mRequest.flags() & QgsFeatureRequest::ExactIntersect ) && !feature.geometry().boundingBoxIntersects( mFilterRect ) ) - ) - ) - || ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten( ( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) ) + else if ( ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten( ( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) + || ( useIntersect && ( !feature.hasGeometry() + || ( mRequest.flags() & QgsFeatureRequest::ExactIntersect && !feature.geometry().intersects( mFilterRect ) ) + || ( !( mRequest.flags() & QgsFeatureRequest::ExactIntersect ) && !feature.geometry().boundingBoxIntersects( mFilterRect ) ) + ) + ) ) { return false; } From 922ae90b5bd05aa0b2474487b11ca290e1df76c2 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 10 Mar 2021 14:48:22 +1000 Subject: [PATCH 028/377] Sipify --- python/core/auto_generated/geometry/qgslinestring.sip.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/core/auto_generated/geometry/qgslinestring.sip.in b/python/core/auto_generated/geometry/qgslinestring.sip.in index 3b050591220d..898d08d93735 100644 --- a/python/core/auto_generated/geometry/qgslinestring.sip.in +++ b/python/core/auto_generated/geometry/qgslinestring.sip.in @@ -422,6 +422,8 @@ segment in the line. virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false ); + virtual bool isClosed() const /HoldGIL/; + QVector< QgsVertexId > collectDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false ) const; %Docstring From d7351fd5d121c17eb96872c23e897a5f41b1fc51 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 11 Mar 2021 09:04:00 +1000 Subject: [PATCH 029/377] Add QgsRectangle::contains overload which doesn't require QgsPoint/QgsPointXY objects --- .../auto_generated/geometry/qgsrectangle.sip.in | 13 ++++++++++--- src/core/geometry/qgsbox3d.cpp | 2 +- src/core/geometry/qgsrectangle.h | 17 ++++++++++++++--- .../qgspointcloudattributebyramprenderer.cpp | 2 +- .../qgspointcloudclassifiedrenderer.cpp | 2 +- .../pointcloud/qgspointcloudrgbrenderer.cpp | 2 +- src/core/qgsgeometryvalidator.cpp | 2 +- src/core/raster/qgsrasterprojector.cpp | 4 ++-- src/providers/gpx/qgsgpxfeatureiterator.cpp | 2 +- 9 files changed, 32 insertions(+), 14 deletions(-) diff --git a/python/core/auto_generated/geometry/qgsrectangle.sip.in b/python/core/auto_generated/geometry/qgsrectangle.sip.in index 8150d5c761d3..b8ebdb857794 100644 --- a/python/core/auto_generated/geometry/qgsrectangle.sip.in +++ b/python/core/auto_generated/geometry/qgsrectangle.sip.in @@ -234,19 +234,26 @@ Gets rectangle enlarged by buffer. Returns the intersection with the given rectangle. %End - bool intersects( const QgsRectangle &rect ) const; + bool intersects( const QgsRectangle &rect ) const /HoldGIL/; %Docstring Returns ``True`` when rectangle intersects with other rectangle. %End - bool contains( const QgsRectangle &rect ) const; + bool contains( const QgsRectangle &rect ) const /HoldGIL/; %Docstring Returns ``True`` when rectangle contains other rectangle. %End - bool contains( const QgsPointXY &p ) const; + bool contains( const QgsPointXY &p ) const /HoldGIL/; %Docstring Returns ``True`` when rectangle contains a point. +%End + + bool contains( double x, double y ) const /HoldGIL/; +%Docstring +Returns ``True`` when rectangle contains the point at (``x``, ``y``). + +.. versionadded:: 3.20 %End void combineExtentWith( const QgsRectangle &rect ); diff --git a/src/core/geometry/qgsbox3d.cpp b/src/core/geometry/qgsbox3d.cpp index b787d06dd081..be7c9ea7e2de 100644 --- a/src/core/geometry/qgsbox3d.cpp +++ b/src/core/geometry/qgsbox3d.cpp @@ -109,7 +109,7 @@ bool QgsBox3d::contains( const QgsBox3d &other ) const bool QgsBox3d::contains( const QgsPoint &p ) const { - if ( !mBounds2d.contains( QgsPointXY( p.x(), p.y() ) ) ) + if ( !mBounds2d.contains( p.x(), p.y() ) ) return false; if ( p.is3D() ) diff --git a/src/core/geometry/qgsrectangle.h b/src/core/geometry/qgsrectangle.h index ffb197b2cd53..ca527e7f0e56 100644 --- a/src/core/geometry/qgsrectangle.h +++ b/src/core/geometry/qgsrectangle.h @@ -346,7 +346,7 @@ class CORE_EXPORT QgsRectangle /** * Returns TRUE when rectangle intersects with other rectangle. */ - bool intersects( const QgsRectangle &rect ) const + bool intersects( const QgsRectangle &rect ) const SIP_HOLDGIL { double x1 = ( mXmin > rect.mXmin ? mXmin : rect.mXmin ); double x2 = ( mXmax < rect.mXmax ? mXmax : rect.mXmax ); @@ -360,7 +360,7 @@ class CORE_EXPORT QgsRectangle /** * Returns TRUE when rectangle contains other rectangle. */ - bool contains( const QgsRectangle &rect ) const + bool contains( const QgsRectangle &rect ) const SIP_HOLDGIL { return ( rect.mXmin >= mXmin && rect.mXmax <= mXmax && rect.mYmin >= mYmin && rect.mYmax <= mYmax ); } @@ -368,12 +368,23 @@ class CORE_EXPORT QgsRectangle /** * Returns TRUE when rectangle contains a point. */ - bool contains( const QgsPointXY &p ) const + bool contains( const QgsPointXY &p ) const SIP_HOLDGIL { return mXmin <= p.x() && p.x() <= mXmax && mYmin <= p.y() && p.y() <= mYmax; } + /** + * Returns TRUE when rectangle contains the point at (\a x, \a y). + * + * \since QGIS 3.20 + */ + bool contains( double x, double y ) const SIP_HOLDGIL + { + return mXmin <= x && x <= mXmax && + mYmin <= y && y <= mYmax; + } + /** * Expands the rectangle so that it covers both the original rectangle and the given rectangle. */ diff --git a/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp b/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp index 432df83458f6..2db080c85178 100644 --- a/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp +++ b/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp @@ -95,7 +95,7 @@ void QgsPointCloudAttributeByRampRenderer::renderBlock( const QgsPointCloudBlock } pointXY( context, ptr, i, x, y ); - if ( visibleExtent.contains( QgsPointXY( x, y ) ) ) + if ( visibleExtent.contains( x, y ) ) { if ( reproject ) { diff --git a/src/core/pointcloud/qgspointcloudclassifiedrenderer.cpp b/src/core/pointcloud/qgspointcloudclassifiedrenderer.cpp index 39fff3c1888e..098324dae04a 100644 --- a/src/core/pointcloud/qgspointcloudclassifiedrenderer.cpp +++ b/src/core/pointcloud/qgspointcloudclassifiedrenderer.cpp @@ -113,7 +113,7 @@ void QgsPointCloudClassifiedRenderer::renderBlock( const QgsPointCloudBlock *blo continue; pointXY( context, ptr, i, x, y ); - if ( visibleExtent.contains( QgsPointXY( x, y ) ) ) + if ( visibleExtent.contains( x, y ) ) { if ( reproject ) { diff --git a/src/core/pointcloud/qgspointcloudrgbrenderer.cpp b/src/core/pointcloud/qgspointcloudrgbrenderer.cpp index 895643ae779b..b1b7eaef2c3f 100644 --- a/src/core/pointcloud/qgspointcloudrgbrenderer.cpp +++ b/src/core/pointcloud/qgspointcloudrgbrenderer.cpp @@ -110,7 +110,7 @@ void QgsPointCloudRgbRenderer::renderBlock( const QgsPointCloudBlock *block, Qgs } pointXY( context, ptr, i, x, y ); - if ( visibleExtent.contains( QgsPointXY( x, y ) ) ) + if ( visibleExtent.contains( x, y ) ) { if ( reproject ) { diff --git a/src/core/qgsgeometryvalidator.cpp b/src/core/qgsgeometryvalidator.cpp index f848ae7f7ff9..7bab74c20e16 100644 --- a/src/core/qgsgeometryvalidator.cpp +++ b/src/core/qgsgeometryvalidator.cpp @@ -429,7 +429,7 @@ bool QgsGeometryValidator::intersectLines( double px, double py, QgsVector v, do bool QgsGeometryValidator::pointInRing( const QgsLineString *ring, double pX, double pY ) { - if ( !ring->boundingBox().contains( QgsPointXY( pX, pY ) ) ) + if ( !ring->boundingBox().contains( pX, pY ) ) return false; bool inside = false; diff --git a/src/core/raster/qgsrasterprojector.cpp b/src/core/raster/qgsrasterprojector.cpp index 57e5b8c6794f..a4f76e1cccef 100644 --- a/src/core/raster/qgsrasterprojector.cpp +++ b/src/core/raster/qgsrasterprojector.cpp @@ -498,7 +498,7 @@ bool ProjectorData::preciseSrcRowCol( int destRow, int destCol, int *srcRow, int QgsDebugMsgLevel( QStringLiteral( "x = %1 y = %2" ).arg( x ).arg( y ), 5 ); #endif - if ( !mExtent.contains( QgsPointXY( x, y ) ) ) + if ( !mExtent.contains( x, y ) ) { return false; } @@ -558,7 +558,7 @@ bool ProjectorData::approximateSrcRowCol( int destRow, int destCol, int *srcRow, double mySrcX = bx + ( tx - bx ) * yfrac; double mySrcY = by + ( ty - by ) * yfrac; - if ( !mExtent.contains( QgsPointXY( mySrcX, mySrcY ) ) ) + if ( !mExtent.contains( mySrcX, mySrcY ) ) { return false; } diff --git a/src/providers/gpx/qgsgpxfeatureiterator.cpp b/src/providers/gpx/qgsgpxfeatureiterator.cpp index 06b4fbf625af..9e5b68071236 100644 --- a/src/providers/gpx/qgsgpxfeatureiterator.cpp +++ b/src/providers/gpx/qgsgpxfeatureiterator.cpp @@ -199,7 +199,7 @@ bool QgsGPXFeatureIterator::readWaypoint( const QgsWaypoint &wpt, QgsFeature &fe { if ( !mFilterRect.isNull() ) { - if ( ! mFilterRect.contains( QgsPointXY( wpt.lon, wpt.lat ) ) ) + if ( ! mFilterRect.contains( wpt.lon, wpt.lat ) ) return false; } From f43382caa8cd2a1d578fd5f497405bb8b2fa431d Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 11 Mar 2021 09:04:13 +1000 Subject: [PATCH 030/377] Modernize test --- tests/src/python/test_qgsrectangle.py | 179 ++++++-------------------- 1 file changed, 38 insertions(+), 141 deletions(-) diff --git a/tests/src/python/test_qgsrectangle.py b/tests/src/python/test_qgsrectangle.py index 797c714b3d54..9f2020f090d1 100644 --- a/tests/src/python/test_qgsrectangle.py +++ b/tests/src/python/test_qgsrectangle.py @@ -24,46 +24,20 @@ class TestQgsRectangle(unittest.TestCase): def testCtor(self): rect = QgsRectangle(5.0, 5.0, 10.0, 10.0) - myMessage = ('Expected: %s\nGot: %s\n' % - (5.0, rect.xMinimum())) - assert rect.xMinimum() == 5.0, myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (5.0, rect.yMinimum())) - assert rect.yMinimum() == 5.0, myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (10.0, rect.xMaximum())) - assert rect.xMaximum() == 10.0, myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (10.0, rect.yMaximum())) - assert rect.yMaximum() == 10.0, myMessage + self.assertEqual(rect.xMinimum(), 5.0) + self.assertEqual(rect.yMinimum(), 5.0) + self.assertEqual(rect.xMaximum(), 10.0) + self.assertEqual(rect.yMaximum(), 10.0) def testDimensions(self): - rect = QgsRectangle(0.0, 0.0, 10.0, 10.0) - - myMessage = ('Expected: %s\nGot: %s\n' % - (10.0, rect.width())) - assert rect.width() == 10.0, myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (10.0, rect.height())) - assert rect.height() == 10.0, myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - ("5.0, 5.0", rect.center().toString())) - assert rect.center() == QgsPointXY(5.0, 5.0), myMessage + rect = QgsRectangle(0.0, 0.0, 10.0, 20.0) + self.assertEqual(rect.width(), 10.0) + self.assertEqual(rect.height(), 20.0) + self.assertEqual(rect.center(), QgsPointXY(5.0, 10.0)) rect.scale(2.0) - - myMessage = ('Expected: %s\nGot: %s\n' % - (20.0, rect.width())) - assert rect.width() == 20.0, myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (20.0, rect.height())) - assert rect.height() == 20.0, myMessage + self.assertEqual(rect.width(), 20.0) + self.assertEqual(rect.height(), 40.0) def testCalculations(self): rect = QgsRectangle(0.0, 1.0, 20.0, 10.0) @@ -74,20 +48,12 @@ def testIntersection(self): rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) rect2 = QgsRectangle(2.0, 2.0, 7.0, 7.0) - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect1.intersects(rect2))) - assert rect1.intersects(rect2), myMessage + self.assertTrue(rect1.intersects(rect2)) rect3 = rect1.intersect(rect2) self.assertFalse(rect3.isEmpty(), "Empty rectangle returned") - - myMessage = ('Expected: %s\nGot: %s\n' % - (3.0, rect3.width())) - assert rect3.width() == 3.0, myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (3.0, rect3.height())) - assert rect3.height() == 3.0, myMessage + self.assertEqual(rect3.width(), 3.0) + self.assertEqual(rect3.height(), 3.0) def testContains(self): rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) @@ -96,43 +62,17 @@ def testContains(self): pnt2 = QgsPointXY(6.0, 2.0) rect3 = rect1.intersect(rect2) - - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect1.contains(rect3))) - assert rect1.contains(rect3), myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect2.contains(rect3))) - assert rect2.contains(rect3), myMessage + self.assertTrue(rect1.contains(rect3)) + self.assertTrue(rect2.contains(rect3)) # test for point - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect1.contains(pnt1))) - assert rect1.contains(pnt1), myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect2.contains(pnt1))) - assert rect2.contains(pnt1), myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect3.contains(pnt1))) - assert rect3.contains(pnt1), myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (False, rect1.contains(pnt2))) - self.assertFalse(rect1.contains(pnt2), myMessage) - - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect2.contains(pnt2))) - assert rect2.contains(pnt2), myMessage - - myMessage = ('Expected: %s\nGot: %s\n' % - (False, rect3.contains(pnt2))) - self.assertFalse(rect3.contains(pnt2), myMessage) - - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect3.contains(pnt1))) - self.assertTrue(rect3.contains(pnt1), myMessage) + self.assertTrue(rect1.contains(pnt1)) + self.assertTrue(rect2.contains(pnt1)) + self.assertTrue(rect3.contains(pnt1)) + self.assertFalse(rect1.contains(pnt2)) + self.assertTrue(rect2.contains(pnt2)) + self.assertFalse(rect3.contains(pnt2)) + self.assertTrue(rect3.contains(pnt1)) def testUnion(self): rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) @@ -140,33 +80,21 @@ def testUnion(self): pnt1 = QgsPointXY(6.0, 2.0) rect1.combineExtentWith(rect2) - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect1.contains(rect2))) - assert rect1.contains(rect2), myMessage + self.assertTrue(rect1.contains(rect2)) - print((rect1.toString())) - assert rect1 == QgsRectangle( - 0.0, 0.0, 7.0, 7.0), 'Wrong combine with rectangle result' + self.assertEqual(rect1, QgsRectangle(0.0, 0.0, 7.0, 7.0)) rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) rect1.combineExtentWith(6.0, 2.0) - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect1.contains(pnt1))) - assert rect1.contains(pnt1), myMessage + self.assertTrue(rect1.contains(pnt1)) - myExpectedResult = QgsRectangle(0.0, 0.0, 6.0, 5.0).toString() - myResult = rect1.toString() - myMessage = ('Expected: %s\nGot: %s\n' % - (myExpectedResult, myResult)) - self.assertEqual(myResult, myExpectedResult, myMessage) + self.assertEqual(rect1.toString(), QgsRectangle(0.0, 0.0, 6.0, 5.0).toString()) rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) rect1.combineExtentWith(rect2) - myMessage = ('Expected: %s\nGot: %s\n' % - (True, rect1.contains(rect2))) - assert rect1.contains(rect2), myMessage + self.assertTrue(rect1.contains(rect2)) - assert rect1 == QgsRectangle(0.0, 0.0, 7.0, 7.0), "Wrong union result" + self.assertEqual(rect1, QgsRectangle(0.0, 0.0, 7.0, 7.0)) def testAsWktCoordinates(self): """Test that we can get a proper wkt representation fo the rect""" @@ -176,7 +104,7 @@ def testAsWktCoordinates(self): myWkt = rect1.asWktCoordinates() myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedWkt, myWkt)) - assert compareWkt(myWkt, myExpectedWkt), myMessage + self.assertTrue(compareWkt(myWkt, myExpectedWkt), myMessage) def testAsWktPolygon(self): """Test that we can get a proper rect wkt polygon representation for rect""" @@ -189,56 +117,25 @@ def testAsWktPolygon(self): myWkt = rect1.asWktPolygon() myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedWkt, myWkt)) - assert compareWkt(myWkt, myExpectedWkt), myMessage + self.assertTrue(compareWkt(myWkt, myExpectedWkt), myMessage) def testToString(self): """Test the different string representations""" self.assertEqual(QgsRectangle().toString(), 'Empty') rect = QgsRectangle(0, 0.1, 0.2, 0.3) - myExpectedString = '0.0000000000000000,0.1000000000000000 : 0.2000000000000000,0.3000000000000000' - myString = rect.toString() - myMessage = ('Expected: %s\nGot: %s\n' % - (myExpectedString, myString)) - assert myString == myExpectedString, myMessage + self.assertEqual(rect.toString(), '0.0000000000000000,0.1000000000000000 : 0.2000000000000000,0.3000000000000000') # can't test the actual result here, because floating point inaccuracies mean the result is unpredictable # at this precision self.assertEqual(len(rect.toString(20)), 93) - myMessage = ('Expected: %s\nGot: %s\n' % - (myExpectedString, myString)) - assert myString == myExpectedString, myMessage - - myExpectedString = '0,0 : 0,0' - myString = rect.toString(0) - myMessage = ('Expected: %s\nGot: %s\n' % - (myExpectedString, myString)) - assert myString == myExpectedString, myMessage - - myExpectedString = '0.00,0.10 : 0.20,0.30' - myString = rect.toString(2) - myMessage = ('Expected: %s\nGot: %s\n' % - (myExpectedString, myString)) - assert myString == myExpectedString, myMessage - - myExpectedString = '0.0,0.1 : 0.2,0.3' - myString = rect.toString(1) - myMessage = ('Expected: %s\nGot: %s\n' % - (myExpectedString, myString)) - assert myString == myExpectedString, myMessage - - myExpectedString = '0.00,0.10 : 0.20,0.30' - myString = rect.toString(-1) - myMessage = ('Expected: %s\nGot: %s\n' % - (myExpectedString, myString)) - assert myString == myExpectedString, myMessage + self.assertEqual(rect.toString(0), '0,0 : 0,0') + self.assertEqual(rect.toString(2), '0.00,0.10 : 0.20,0.30') + self.assertEqual(rect.toString(1), '0.0,0.1 : 0.2,0.3') + self.assertEqual(rect.toString(-1), '0.00,0.10 : 0.20,0.30') rect = QgsRectangle(5000000.01111, -0.3, 5000000.44111, 99.8) - myExpectedString = '5000000.01,-0.30 : 5000000.44,99.80' - myString = rect.toString(-1) - myMessage = ('Expected: %s\nGot: %s\n' % - (myExpectedString, myString)) - assert myString == myExpectedString, myMessage + self.assertEqual(rect.toString(-1), '5000000.01,-0.30 : 5000000.44,99.80') def testAsPolygon(self): """Test string representation as polygon""" @@ -258,11 +155,11 @@ def testToBox3d(self): def testOperators(self): rect1 = QgsRectangle(10, 20, 40, 40) rect2 = rect1 + QgsVector(3, 5.5) - assert rect2 == QgsRectangle(13, 25.5, 43, 45.5), "QgsRectangle + operator does no work" + self.assertEqual(rect2, QgsRectangle(13, 25.5, 43, 45.5)) # Subtracting the center point, so it becomes zero. rect1 -= rect1.center() - QgsPointXY(0, 0) - assert rect1.center() == QgsPointXY(0, 0) + self.assertEqual(rect1.center(), QgsPointXY(0, 0)) def testInvert(self): rect = QgsRectangle(0, 0.1, 0.2, 0.3) From 5db42dae7944c011b41a44d82e25183d946c8a25 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 11 Mar 2021 09:20:17 +1000 Subject: [PATCH 031/377] Add unit tests for QgsRectangle::contains( double, double) --- tests/src/python/test_qgsrectangle.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/src/python/test_qgsrectangle.py b/tests/src/python/test_qgsrectangle.py index 9f2020f090d1..32c641d8d760 100644 --- a/tests/src/python/test_qgsrectangle.py +++ b/tests/src/python/test_qgsrectangle.py @@ -67,12 +67,19 @@ def testContains(self): # test for point self.assertTrue(rect1.contains(pnt1)) + self.assertTrue(rect1.contains(pnt1.x(), pnt1.y())) self.assertTrue(rect2.contains(pnt1)) + self.assertTrue(rect2.contains(pnt1.x(), pnt1.y())) self.assertTrue(rect3.contains(pnt1)) + self.assertTrue(rect3.contains(pnt1.x(), pnt1.y())) self.assertFalse(rect1.contains(pnt2)) + self.assertFalse(rect1.contains(pnt2.x(), pnt2.y())) self.assertTrue(rect2.contains(pnt2)) + self.assertTrue(rect2.contains(pnt2.x(), pnt2.y())) self.assertFalse(rect3.contains(pnt2)) + self.assertFalse(rect3.contains(pnt2.x(), pnt2.y())) self.assertTrue(rect3.contains(pnt1)) + self.assertTrue(rect3.contains(pnt1.x(), pnt1.y())) def testUnion(self): rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0) From 1e40d385e8d30403f41849d0cb7695f82abd24dd Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 11 Mar 2021 09:52:06 +1000 Subject: [PATCH 032/377] Super-optimised version of geometry bounding box intersects test Apply some fancy logic to make this test as cheap as possible to run --- .../geometry/qgsabstractgeometry.sip.in | 10 +++ .../geometry/qgscompoundcurve.sip.in | 2 + .../auto_generated/geometry/qgscurve.sip.in | 1 + .../geometry/qgscurvepolygon.sip.in | 2 + .../geometry/qgsgeometrycollection.sip.in | 2 + .../geometry/qgslinestring.sip.in | 2 + .../auto_generated/geometry/qgspoint.sip.in | 2 + src/core/geometry/qgsabstractgeometry.cpp | 5 ++ src/core/geometry/qgsabstractgeometry.h | 10 +++ src/core/geometry/qgscompoundcurve.cpp | 29 +++++++ src/core/geometry/qgscompoundcurve.h | 1 + src/core/geometry/qgscurve.h | 7 +- src/core/geometry/qgscurvepolygon.cpp | 33 ++++++++ src/core/geometry/qgscurvepolygon.h | 1 + src/core/geometry/qgsgeometry.cpp | 11 +-- src/core/geometry/qgsgeometrycollection.cpp | 29 +++++++ src/core/geometry/qgsgeometrycollection.h | 1 + src/core/geometry/qgslinestring.cpp | 78 +++++++++++++++++++ src/core/geometry/qgslinestring.h | 1 + src/core/geometry/qgspoint.cpp | 5 ++ src/core/geometry/qgspoint.h | 1 + tests/src/core/testqgsgeometry.cpp | 22 ++++++ 22 files changed, 244 insertions(+), 11 deletions(-) diff --git a/python/core/auto_generated/geometry/qgsabstractgeometry.sip.in b/python/core/auto_generated/geometry/qgsabstractgeometry.sip.in index b34dca4b442b..cf33d9006880 100644 --- a/python/core/auto_generated/geometry/qgsabstractgeometry.sip.in +++ b/python/core/auto_generated/geometry/qgsabstractgeometry.sip.in @@ -521,6 +521,16 @@ Returns ``True`` if the geometry is empty virtual bool hasCurvedSegments() const; %Docstring Returns ``True`` if the geometry contains curved segments +%End + + virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/; +%Docstring +Returns ``True`` if the bounding box of this geometry intersects with a ``rectangle``. + +Since this test only considers the bounding box of the geometry, is is very fast to +calculate and handles invalid geometries. + +.. versionadded:: 3.20 %End virtual QgsAbstractGeometry *segmentize( double tolerance = M_PI / 180., SegmentationToleranceType toleranceType = MaximumAngle ) const /Factory/; diff --git a/python/core/auto_generated/geometry/qgscompoundcurve.sip.in b/python/core/auto_generated/geometry/qgscompoundcurve.sip.in index 6bc71c9968cd..4362c2f53177 100644 --- a/python/core/auto_generated/geometry/qgscompoundcurve.sip.in +++ b/python/core/auto_generated/geometry/qgscompoundcurve.sip.in @@ -82,6 +82,8 @@ of the curve. virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false ); + virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/; + int nCurves() const /HoldGIL/; %Docstring diff --git a/python/core/auto_generated/geometry/qgscurve.sip.in b/python/core/auto_generated/geometry/qgscurve.sip.in index 1d8985ae63ee..abec8f3a345d 100644 --- a/python/core/auto_generated/geometry/qgscurve.sip.in +++ b/python/core/auto_generated/geometry/qgscurve.sip.in @@ -280,6 +280,7 @@ Returns the curve's orientation, e.g. clockwise or counter-clockwise. + }; /************************************************************************ diff --git a/python/core/auto_generated/geometry/qgscurvepolygon.sip.in b/python/core/auto_generated/geometry/qgscurvepolygon.sip.in index e1cf2db7e549..f3c8c3e71a75 100644 --- a/python/core/auto_generated/geometry/qgscurvepolygon.sip.in +++ b/python/core/auto_generated/geometry/qgscurvepolygon.sip.in @@ -71,6 +71,8 @@ Curve polygon geometry type virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false ); + virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/; + int numInteriorRings() const /HoldGIL/; diff --git a/python/core/auto_generated/geometry/qgsgeometrycollection.sip.in b/python/core/auto_generated/geometry/qgsgeometrycollection.sip.in index 0ad0f6281a24..369b0827da2b 100644 --- a/python/core/auto_generated/geometry/qgsgeometrycollection.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometrycollection.sip.in @@ -102,6 +102,8 @@ Returns a geometry from within the collection. virtual int vertexNumberFromVertexId( QgsVertexId id ) const; + virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/; + void reserve( int size ) /HoldGIL/; %Docstring diff --git a/python/core/auto_generated/geometry/qgslinestring.sip.in b/python/core/auto_generated/geometry/qgslinestring.sip.in index 898d08d93735..11a0c665181b 100644 --- a/python/core/auto_generated/geometry/qgslinestring.sip.in +++ b/python/core/auto_generated/geometry/qgslinestring.sip.in @@ -424,6 +424,8 @@ segment in the line. virtual bool isClosed() const /HoldGIL/; + virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/; + QVector< QgsVertexId > collectDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false ) const; %Docstring diff --git a/python/core/auto_generated/geometry/qgspoint.sip.in b/python/core/auto_generated/geometry/qgspoint.sip.in index eca6d9211eea..b6db95384e6a 100644 --- a/python/core/auto_generated/geometry/qgspoint.sip.in +++ b/python/core/auto_generated/geometry/qgspoint.sip.in @@ -436,6 +436,8 @@ Angle undefined. Always returns 0.0 virtual double segmentLength( QgsVertexId startVertex ) const; + virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/; + virtual bool addZValue( double zValue = 0 ); diff --git a/src/core/geometry/qgsabstractgeometry.cpp b/src/core/geometry/qgsabstractgeometry.cpp index 3d7f0f0364a6..1ce3cc3556ac 100644 --- a/src/core/geometry/qgsabstractgeometry.cpp +++ b/src/core/geometry/qgsabstractgeometry.cpp @@ -307,6 +307,11 @@ bool QgsAbstractGeometry::hasCurvedSegments() const return false; } +bool QgsAbstractGeometry::boundingBoxIntersects( const QgsRectangle &rectangle ) const +{ + return boundingBox().intersects( rectangle ); +} + QgsAbstractGeometry *QgsAbstractGeometry::segmentize( double tolerance, SegmentationToleranceType toleranceType ) const { Q_UNUSED( tolerance ) diff --git a/src/core/geometry/qgsabstractgeometry.h b/src/core/geometry/qgsabstractgeometry.h index 4ea2310c3b66..20ffd82d63db 100644 --- a/src/core/geometry/qgsabstractgeometry.h +++ b/src/core/geometry/qgsabstractgeometry.h @@ -537,6 +537,16 @@ class CORE_EXPORT QgsAbstractGeometry */ virtual bool hasCurvedSegments() const; + /** + * Returns TRUE if the bounding box of this geometry intersects with a \a rectangle. + * + * Since this test only considers the bounding box of the geometry, is is very fast to + * calculate and handles invalid geometries. + * + * \since QGIS 3.20 + */ + virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const SIP_HOLDGIL; + /** * Returns a version of the geometry without curves. Caller takes ownership of * the returned geometry. diff --git a/src/core/geometry/qgscompoundcurve.cpp b/src/core/geometry/qgscompoundcurve.cpp index 4e2d9ab91214..5ce3849677f6 100644 --- a/src/core/geometry/qgscompoundcurve.cpp +++ b/src/core/geometry/qgscompoundcurve.cpp @@ -465,6 +465,35 @@ bool QgsCompoundCurve::removeDuplicateNodes( double epsilon, bool useZValues ) return result; } +bool QgsCompoundCurve::boundingBoxIntersects( const QgsRectangle &rectangle ) const +{ + if ( mCurves.empty() ) + return false; + + // if we already have the bounding box calculated, then this check is trivial! + if ( !mBoundingBox.isNull() ) + { + return mBoundingBox.intersects( rectangle ); + } + + // otherwise loop through each member curve and test the bounding box intersection. + // This gives us a chance to use optimisations which may be present on the individual + // curve subclasses, and at worst it will cause a calculation of the bounding box + // of each individual member curve which we would have to do anyway... (and these + // bounding boxes are cached, so would be reused without additional expense) + for ( const QgsCurve *curve : mCurves ) + { + if ( curve->boundingBoxIntersects( rectangle ) ) + return true; + } + + // even if we don't intersect the bounding box of any member curves, we may still intersect the + // bounding box of the overall compound curve. + // so here we fall back to the non-optimised base class check which has to first calculate + // the overall bounding box of the compound curve.. + return QgsAbstractGeometry::boundingBoxIntersects( rectangle ); +} + const QgsCurve *QgsCompoundCurve::curveAt( int i ) const { if ( i < 0 || i >= mCurves.size() ) diff --git a/src/core/geometry/qgscompoundcurve.h b/src/core/geometry/qgscompoundcurve.h index b1ddcb0a3e6f..d2c75b4eba8c 100644 --- a/src/core/geometry/qgscompoundcurve.h +++ b/src/core/geometry/qgscompoundcurve.h @@ -72,6 +72,7 @@ class CORE_EXPORT QgsCompoundCurve: public QgsCurve QgsCompoundCurve *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY; bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits::epsilon(), bool useZValues = false ) override; + bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL; /** * Returns the number of curves in the geometry. diff --git a/src/core/geometry/qgscurve.h b/src/core/geometry/qgscurve.h index 317d919497ed..03307554e177 100644 --- a/src/core/geometry/qgscurve.h +++ b/src/core/geometry/qgscurve.h @@ -292,10 +292,13 @@ class CORE_EXPORT QgsCurve: public QgsAbstractGeometry QVector &outX, QVector &outY, QVector &outZ, QVector &outM ) const; #endif - private: - + /** + * Cached bounding box. + */ mutable QgsRectangle mBoundingBox; + private: + mutable bool mHasCachedValidity = false; mutable QString mValidityFailureReason; }; diff --git a/src/core/geometry/qgscurvepolygon.cpp b/src/core/geometry/qgscurvepolygon.cpp index 51878d1317cf..060884fb20b5 100644 --- a/src/core/geometry/qgscurvepolygon.cpp +++ b/src/core/geometry/qgscurvepolygon.cpp @@ -612,6 +612,39 @@ bool QgsCurvePolygon::removeDuplicateNodes( double epsilon, bool useZValues ) return result; } +bool QgsCurvePolygon::boundingBoxIntersects( const QgsRectangle &rectangle ) const +{ + if ( !mExteriorRing && mInteriorRings.empty() ) + return false; + + // if we already have the bounding box calculated, then this check is trivial! + if ( !mBoundingBox.isNull() ) + { + return mBoundingBox.intersects( rectangle ); + } + + // loop through each ring and test the bounding box intersection. + // This gives us a chance to use optimisations which may be present on the individual + // ring geometry subclasses, and at worst it will cause a calculation of the bounding box + // of each individual ring geometry which we would have to do anyway... (and these + // bounding boxes are cached, so would be reused without additional expense) + if ( mExteriorRing && mExteriorRing->boundingBoxIntersects( rectangle ) ) + return true; + + for ( const QgsCurve *ring : mInteriorRings ) + { + if ( ring->boundingBoxIntersects( rectangle ) ) + return true; + } + + // even if we don't intersect the bounding box of any rings, we may still intersect the + // bounding box of the overall polygon (we are considering worst case scenario here and + // the polygon is invalid, with rings outside the exterior ring!) + // so here we fall back to the non-optimised base class check which has to first calculate + // the overall bounding box of the polygon.. + return QgsSurface::boundingBoxIntersects( rectangle ); +} + QgsPolygon *QgsCurvePolygon::toPolygon( double tolerance, SegmentationToleranceType toleranceType ) const { std::unique_ptr< QgsPolygon > poly( new QgsPolygon() ); diff --git a/src/core/geometry/qgscurvepolygon.h b/src/core/geometry/qgscurvepolygon.h index 78a401e1fc6d..f58fe533d3bc 100644 --- a/src/core/geometry/qgscurvepolygon.h +++ b/src/core/geometry/qgscurvepolygon.h @@ -66,6 +66,7 @@ class CORE_EXPORT QgsCurvePolygon: public QgsSurface QgsAbstractGeometry *boundary() const override SIP_FACTORY; QgsCurvePolygon *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY; bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits::epsilon(), bool useZValues = false ) override; + bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL; //curve polygon interface diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 3b4c86f92984..2a8311be9867 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -1160,14 +1160,7 @@ bool QgsGeometry::boundingBoxIntersects( const QgsRectangle &rectangle ) const return false; } - // optimise trivial case for point intersections - if ( QgsWkbTypes::flatType( d->geometry->wkbType() ) == QgsWkbTypes::Point ) - { - const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( d->geometry.get() ); - return rectangle.contains( QgsPointXY( point->x(), point->y() ) ); - } - - return d->geometry->boundingBox().intersects( rectangle ); + return d->geometry->boundingBoxIntersects( rectangle ); } bool QgsGeometry::boundingBoxIntersects( const QgsGeometry &geometry ) const @@ -1177,7 +1170,7 @@ bool QgsGeometry::boundingBoxIntersects( const QgsGeometry &geometry ) const return false; } - return d->geometry->boundingBox().intersects( geometry.constGet()->boundingBox() ); + return d->geometry->boundingBoxIntersects( geometry.constGet()->boundingBox() ); } bool QgsGeometry::contains( const QgsPointXY *p ) const diff --git a/src/core/geometry/qgsgeometrycollection.cpp b/src/core/geometry/qgsgeometrycollection.cpp index 4242cf394da7..8d903d5d3f26 100644 --- a/src/core/geometry/qgsgeometrycollection.cpp +++ b/src/core/geometry/qgsgeometrycollection.cpp @@ -200,6 +200,35 @@ int QgsGeometryCollection::vertexNumberFromVertexId( QgsVertexId id ) const return -1; // should not happen } +bool QgsGeometryCollection::boundingBoxIntersects( const QgsRectangle &rectangle ) const +{ + if ( mGeometries.empty() ) + return false; + + // if we already have the bounding box calculated, then this check is trivial! + if ( !mBoundingBox.isNull() ) + { + return mBoundingBox.intersects( rectangle ); + } + + // otherwise loop through each member geometry and test the bounding box intersection. + // This gives us a chance to use optimisations which may be present on the individual + // geometry subclasses, and at worst it will cause a calculation of the bounding box + // of each individual member geometry which we would have to do anyway... (and these + // bounding boxes are cached, so would be reused without additional expense) + for ( const QgsAbstractGeometry *geometry : mGeometries ) + { + if ( geometry->boundingBoxIntersects( rectangle ) ) + return true; + } + + // even if we don't intersect the bounding box of any member geometries, we may still intersect the + // bounding box of the overall collection. + // so here we fall back to the non-optimised base class check which has to first calculate + // the overall bounding box of the collection.. + return QgsAbstractGeometry::boundingBoxIntersects( rectangle ); +} + void QgsGeometryCollection::reserve( int size ) { mGeometries.reserve( size ); diff --git a/src/core/geometry/qgsgeometrycollection.h b/src/core/geometry/qgsgeometrycollection.h index 01d34758c11f..9052d14f0105 100644 --- a/src/core/geometry/qgsgeometrycollection.h +++ b/src/core/geometry/qgsgeometrycollection.h @@ -125,6 +125,7 @@ class CORE_EXPORT QgsGeometryCollection: public QgsAbstractGeometry QgsAbstractGeometry *boundary() const override SIP_FACTORY; void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override; int vertexNumberFromVertexId( QgsVertexId id ) const override; + bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL; /** * Attempts to allocate memory for at least \a size geometries. diff --git a/src/core/geometry/qgslinestring.cpp b/src/core/geometry/qgslinestring.cpp index e5a2af5d2fb6..bf0370c4b519 100644 --- a/src/core/geometry/qgslinestring.cpp +++ b/src/core/geometry/qgslinestring.cpp @@ -387,6 +387,84 @@ bool QgsLineString::isClosed() const return closed; } +bool QgsLineString::boundingBoxIntersects( const QgsRectangle &rectangle ) const +{ + if ( mX.empty() ) + return false; + + if ( !mBoundingBox.isNull() ) + { + return mBoundingBox.intersects( rectangle ); + } + const int nb = mX.size(); + + // We are a little fancy here! + if ( nb > 40 ) + { + // if a large number of vertices, take some sample vertices at 1/5th increments through the linestring + // and test whether any are inside the rectangle. Maybe we can shortcut a lot of iterations by doing this! + // (why 1/5th? it's picked so that it works nicely for polygon rings which are almost rectangles, so the vertex extremities + // will fall on approximately these vertex indices) + if ( rectangle.contains( mX.at( 0 ), mY.at( 0 ) ) || + rectangle.contains( mX.at( static_cast< int >( nb * 0.2 ) ), mY.at( static_cast< int >( nb * 0.2 ) ) ) || + rectangle.contains( mX.at( static_cast< int >( nb * 0.4 ) ), mY.at( static_cast< int >( nb * 0.4 ) ) ) || + rectangle.contains( mX.at( static_cast< int >( nb * 0.6 ) ), mY.at( static_cast< int >( nb * 0.6 ) ) ) || + rectangle.contains( mX.at( static_cast< int >( nb * 0.8 ) ), mY.at( static_cast< int >( nb * 0.8 ) ) ) || + rectangle.contains( mX.at( nb - 1 ), mY.at( nb - 1 ) ) ) + return true; + } + + // Be even MORE fancy! Given that bounding box calculation is non-free, cached, and we don't + // already have it, we start performing the bounding box calculation while we are testing whether + // each point falls inside the rectangle. That way if we end up testing the majority of the points + // anyway, we can update the cached bounding box with the results we've calculated along the way + // and save future calls to calculate the bounding box! + double xmin = std::numeric_limits::max(); + double ymin = std::numeric_limits::max(); + double xmax = -std::numeric_limits::max(); + double ymax = -std::numeric_limits::max(); + + const double *x = mX.constData(); + const double *y = mY.constData(); + bool foundPointInRectangle = false; + for ( int i = 0; i < nb; ++i ) + { + const double px = *x++; + xmin = std::min( xmin, px ); + xmax = std::max( xmax, px ); + const double py = *y++; + ymin = std::min( ymin, py ); + ymax = std::max( ymax, py ); + + if ( !foundPointInRectangle && rectangle.contains( px, py ) ) + { + foundPointInRectangle = true; + + // now... we have a choice to make. If we've already looped through the majority of the points + // in this linestring then let's just continue to iterate through the remainder so that we can + // complete the overall bounding box calculation we've already mostly done. If however we're only + // just at the start of iterating the vertices, we shortcut out early and leave the bounding box + // uncalculated + if ( i < nb * 0.5 ) + return true; + } + } + + // at this stage we now know the overall bounding box of the linestring, so let's cache + // it so we don't ever have to calculate this again. We've done all the hard work anyway! + mBoundingBox = QgsRectangle( xmin, ymin, xmax, ymax, false ); + + if ( foundPointInRectangle ) + return true; + + // NOTE: if none of the points in the line actually fell inside the rectangle, it doesn't + // exclude that the OVERALL bounding box of the linestring itself intersects the rectangle!! + // So we fall back to the parent class method which compares the overall bounding box against + // the rectangle... and this will be very cheap now that we've already calculated and cached + // the linestring's bounding box! + return QgsCurve::boundingBoxIntersects( rectangle ); +} + QVector< QgsVertexId > QgsLineString::collectDuplicateNodes( double epsilon, bool useZValues ) const { QVector< QgsVertexId > res; diff --git a/src/core/geometry/qgslinestring.h b/src/core/geometry/qgslinestring.h index d04bd3767700..5c4aa3210b91 100644 --- a/src/core/geometry/qgslinestring.h +++ b/src/core/geometry/qgslinestring.h @@ -591,6 +591,7 @@ class CORE_EXPORT QgsLineString: public QgsCurve QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY; bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits::epsilon(), bool useZValues = false ) override; bool isClosed() const override SIP_HOLDGIL; + bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL; /** * Returns a list of any duplicate nodes contained in the geometry, within the specified tolerance. diff --git a/src/core/geometry/qgspoint.cpp b/src/core/geometry/qgspoint.cpp index acf7e8bbbbd9..3d376cfa5fce 100644 --- a/src/core/geometry/qgspoint.cpp +++ b/src/core/geometry/qgspoint.cpp @@ -537,6 +537,11 @@ double QgsPoint::segmentLength( QgsVertexId ) const return 0.0; } +bool QgsPoint::boundingBoxIntersects( const QgsRectangle &rectangle ) const +{ + return rectangle.contains( mX, mY ); +} + /*************************************************************************** * This class is considered CRITICAL and any change MUST be accompanied with * full unit tests. diff --git a/src/core/geometry/qgspoint.h b/src/core/geometry/qgspoint.h index cc73fd32f50a..756d1dec38b3 100644 --- a/src/core/geometry/qgspoint.h +++ b/src/core/geometry/qgspoint.h @@ -529,6 +529,7 @@ class CORE_EXPORT QgsPoint: public QgsAbstractGeometry QgsPoint vertexAt( QgsVertexId /*id*/ ) const override; QgsPoint *toCurveType() const override SIP_FACTORY; double segmentLength( QgsVertexId startVertex ) const override; + bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL; bool addZValue( double zValue = 0 ) override; bool addMValue( double mValue = 0 ) override; diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp index f2195686f7ed..63dba1ecaa10 100644 --- a/tests/src/core/testqgsgeometry.cpp +++ b/tests/src/core/testqgsgeometry.cpp @@ -1388,6 +1388,11 @@ void TestQgsGeometry::point() TestFailTransformer failTransformer; QVERIFY( !p.transform( &failTransformer ) ); + + // test bounding box intersects + QVERIFY( QgsPoint( 1, 2 ).boundingBoxIntersects( QgsRectangle( 0, 0.5, 1.5, 3 ) ) ); + QVERIFY( !QgsPoint( 1, 2 ).boundingBoxIntersects( QgsRectangle( 3, 0.5, 3.5, 3 ) ) ); + QVERIFY( !QgsPoint().boundingBoxIntersects( QgsRectangle( 0, 0.5, 3.5, 3 ) ) ); } void TestQgsGeometry::circularString() @@ -5175,6 +5180,23 @@ void TestQgsGeometry::lineString() QCOMPARE( orientation.orientation(), QgsCurve::Clockwise ); orientation.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 1 ) << QgsPoint( 0, 0 ) ); QCOMPARE( orientation.orientation(), QgsCurve::CounterClockwise ); + + // test bounding box intersects + QgsLineString bb; + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + bb.setPoints( QgsPointSequence() << QgsPoint( 11, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 13, -10 ) ); + QVERIFY( bb.boundingBoxIntersects( QgsRectangle( 12, 3, 16, 9 ) ) ); + // double test because of cache + QVERIFY( bb.boundingBoxIntersects( QgsRectangle( 12, 3, 16, 9 ) ) ); + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + QCOMPARE( bb.boundingBox(), QgsRectangle( 11, -10, 13, 12 ) ); + // clear cache + bb.setPoints( QgsPointSequence() << QgsPoint( 11, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 13, -10 ) ); + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + QCOMPARE( bb.boundingBox(), QgsRectangle( 11, -10, 13, 12 ) ); + QVERIFY( bb.boundingBoxIntersects( QgsRectangle( 12, 3, 16, 9 ) ) ); } void TestQgsGeometry::polygon() From f9ddb047e7389359c5889fa199cdd9b42c0f2091 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 12 Mar 2021 08:26:17 +1000 Subject: [PATCH 033/377] [processing] Fix output from Snap Geometries algorithms cannot be plugged into algorithm inputs requiring a point or line geometry type Fixes #42200 --- src/analysis/processing/qgsalgorithmsnapgeometries.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analysis/processing/qgsalgorithmsnapgeometries.cpp b/src/analysis/processing/qgsalgorithmsnapgeometries.cpp index 086f695f868f..c1141e63e90d 100644 --- a/src/analysis/processing/qgsalgorithmsnapgeometries.cpp +++ b/src/analysis/processing/qgsalgorithmsnapgeometries.cpp @@ -99,7 +99,7 @@ void QgsSnapGeometriesAlgorithm::initAlgorithm( const QVariantMap & ) << QObject::tr( "Snap to anchor nodes (single layer only)" ); addParameter( new QgsProcessingParameterEnum( QStringLiteral( "BEHAVIOR" ), QObject::tr( "Behavior" ), options, false, QVariantList() << 0 ) ); addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), - QObject::tr( "Snapped geometry" ), QgsProcessing::TypeVectorPolygon ) ); + QObject::tr( "Snapped geometry" ), QgsProcessing::TypeVectorAnyGeometry ) ); } QgsSnapGeometriesAlgorithm *QgsSnapGeometriesAlgorithm::createInstance() const From aa3049c31a3a3e0939d76672b5b195eace145dd3 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 12 Mar 2021 08:09:35 +1000 Subject: [PATCH 034/377] Add more tests for QgsAbstractGeometry::boundingBoxIntersects --- tests/src/core/testqgsgeometry.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp index 63dba1ecaa10..22b940f0440c 100644 --- a/tests/src/core/testqgsgeometry.cpp +++ b/tests/src/core/testqgsgeometry.cpp @@ -7063,6 +7063,35 @@ void TestQgsGeometry::polygon() rhr.fromWkt( QStringLiteral( "PolygonZM ((0 0 3 4, 0 100 13 14, 100 100 13 14, 100 0 23 24, 0 0 3 4),(10 10 1 2, 10 20 3 4, 20 10 6 8, 10 10 1 2))" ) ); rhr.forceRHR(); QCOMPARE( rhr.asWkt( 2 ), QStringLiteral( "PolygonZM ((0 0 3 4, 0 100 13 14, 100 100 13 14, 100 0 23 24, 0 0 3 4),(10 10 1 2, 20 10 6 8, 10 20 3 4, 10 10 1 2))" ) ); + + // test bounding box intersects + QgsPolygon bb; + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + QgsLineString bbR; + bbR.setPoints( QgsPointSequence() << QgsPoint( 0, 2 ) << QgsPoint( 4, 2 ) << QgsPoint( 4, 4 ) << QgsPoint( 0, 2 ) ); + bb.setExteriorRing( bbR.clone() ); + QVERIFY( bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + // double test because of cache + QVERIFY( bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 11, 3, 6, 9 ) ) ); + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 11, 3, 6, 9 ) ) ); + QCOMPARE( bb.boundingBox(), QgsRectangle( 0, 2, 4, 4 ) ); + // clear cache + bbR.setPoints( QgsPointSequence() << QgsPoint( 10, 2 ) << QgsPoint( 14, 2 ) << QgsPoint( 15, 4 ) << QgsPoint( 10, 2 ) ); + bb.setExteriorRing( bbR.clone() ); + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + QCOMPARE( bb.boundingBox(), QgsRectangle( 10, 2, 15, 4 ) ); + QVERIFY( bb.boundingBoxIntersects( QgsRectangle( 11, 3, 16, 9 ) ) ); + // technically invalid -- the interior ring is outside the exterior, but we want boundingBoxIntersects to be tolerant to + // cases like this! + bbR.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 4, 2 ) << QgsPoint( 5, 4 ) << QgsPoint( 1, 2 ) ); + bb.addInteriorRing( bbR.clone() ); + QVERIFY( bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + QVERIFY( bb.boundingBoxIntersects( QgsRectangle( 1, 3, 6, 9 ) ) ); + QVERIFY( bb.boundingBoxIntersects( QgsRectangle( 11, 3, 16, 9 ) ) ); + QVERIFY( !bb.boundingBoxIntersects( QgsRectangle( 21, 3, 26, 9 ) ) ); + QCOMPARE( bb.boundingBox(), QgsRectangle( 10, 2, 15, 4 ) ); } void TestQgsGeometry::triangle() From 8f3fdf7ec91df03e6352728b85bfe19dfa5f6e3d Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 12 Mar 2021 09:16:53 +1000 Subject: [PATCH 035/377] Simplify use of aux field for callout properties Instead of prompting users for an aux field name and type, just immediately create the field when the option is selected (like we do for other label properties) --- src/gui/callouts/qgscalloutwidget.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/gui/callouts/qgscalloutwidget.cpp b/src/gui/callouts/qgscalloutwidget.cpp index 70e7f3b9200a..7054046122ee 100644 --- a/src/gui/callouts/qgscalloutwidget.cpp +++ b/src/gui/callouts/qgscalloutwidget.cpp @@ -97,15 +97,9 @@ void QgsCalloutWidget::createAuxiliaryField() // create property in auxiliary storage if necessary if ( !mVectorLayer->auxiliaryLayer()->exists( def ) ) { - QgsNewAuxiliaryFieldDialog dlg( def, mVectorLayer, true, this ); - if ( dlg.exec() == QDialog::Accepted ) - def = dlg.propertyDefinition(); + mVectorLayer->auxiliaryLayer()->addAuxiliaryField( def ); } - // return if still not exist - if ( !mVectorLayer->auxiliaryLayer()->exists( def ) ) - return; - // update property with join field name from auxiliary storage QgsProperty property = button->toProperty(); property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) ); From a8ea72598446a08710264f28544e2b2631fab10b Mon Sep 17 00:00:00 2001 From: nirvn Date: Wed, 10 Mar 2021 14:06:56 +0700 Subject: [PATCH 036/377] [ui] Add map layer icons in th expression builder's tree view --- src/gui/qgsexpressiontreeview.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/qgsexpressiontreeview.cpp b/src/gui/qgsexpressiontreeview.cpp index 698ff6ab6ef3..7f37462c1337 100644 --- a/src/gui/qgsexpressiontreeview.cpp +++ b/src/gui/qgsexpressiontreeview.cpp @@ -25,6 +25,7 @@ #include "qgssettings.h" #include "qgsrelationmanager.h" #include "qgsapplication.h" +#include "qgsmaplayermodel.h" //! Returns a HTML formatted string for use as a \a relation item help. @@ -411,7 +412,8 @@ void QgsExpressionTreeView::loadLayers() QMap::const_iterator layerIt = layers.constBegin(); for ( ; layerIt != layers.constEnd(); ++layerIt ) { - registerItemForAllGroups( QStringList() << tr( "Map Layers" ), layerIt.value()->name(), QStringLiteral( "'%1'" ).arg( layerIt.key() ), formatLayerHelp( layerIt.value() ) ); + QIcon icon = QgsMapLayerModel::iconForLayer( layerIt.value() ); + registerItem( QStringLiteral( "Map Layers" ), layerIt.value()->name(), QStringLiteral( "'%1'" ).arg( layerIt.key() ), formatLayerHelp( layerIt.value() ), QgsExpressionItem::ExpressionNode, false, 1, icon ); } } From 5a8446092e866180b8c2567e421b3b33f6d76a12 Mon Sep 17 00:00:00 2001 From: nirvn Date: Wed, 10 Mar 2021 14:13:59 +0700 Subject: [PATCH 037/377] [ui] Display map layer functions above list of map layers --- src/gui/qgsexpressiontreeview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qgsexpressiontreeview.cpp b/src/gui/qgsexpressiontreeview.cpp index 7f37462c1337..788e5bd7a149 100644 --- a/src/gui/qgsexpressiontreeview.cpp +++ b/src/gui/qgsexpressiontreeview.cpp @@ -413,7 +413,7 @@ void QgsExpressionTreeView::loadLayers() for ( ; layerIt != layers.constEnd(); ++layerIt ) { QIcon icon = QgsMapLayerModel::iconForLayer( layerIt.value() ); - registerItem( QStringLiteral( "Map Layers" ), layerIt.value()->name(), QStringLiteral( "'%1'" ).arg( layerIt.key() ), formatLayerHelp( layerIt.value() ), QgsExpressionItem::ExpressionNode, false, 1, icon ); + registerItem( QStringLiteral( "Map Layers" ), layerIt.value()->name(), QStringLiteral( "'%1'" ).arg( layerIt.key() ), formatLayerHelp( layerIt.value() ), QgsExpressionItem::ExpressionNode, false, 99, icon ); } } From 2adad295d87ad13b9e42ed731df61cf84802f049 Mon Sep 17 00:00:00 2001 From: nirvn Date: Wed, 10 Mar 2021 14:14:49 +0700 Subject: [PATCH 038/377] [ui] Move layer_property() function from General to Map Layers group for ease of discoverability --- resources/function_help/json/layer_property | 2 +- src/core/expression/qgsexpressionfunction.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/function_help/json/layer_property b/resources/function_help/json/layer_property index 58bd08d84aa5..7336d74a5895 100644 --- a/resources/function_help/json/layer_property +++ b/resources/function_help/json/layer_property @@ -1,7 +1,7 @@ { "name": "layer_property", "type": "function", - "groups": ["General"], + "groups": ["Map Layers"], "description": "Returns a matching layer property or metadata value.", "arguments": [ {"arg":"layer", "description":"a string, representing either a layer name or layer ID"}, diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index bf63f20195b0..cb196443db78 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -7146,7 +7146,7 @@ const QList &QgsExpression::Functions() functions << new QgsStaticExpressionFunction( QStringLiteral( "layer_property" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "layer" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "property" ) ), - fcnGetLayerProperty, QStringLiteral( "General" ) ) + fcnGetLayerProperty, QStringLiteral( "Map Layers" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "decode_uri" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "layer" ) ) From 807a0540e06c729fba57c74a1886ec63a9c720cb Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Thu, 11 Mar 2021 10:43:16 +0100 Subject: [PATCH 039/377] Add option to use the old legend style --- .../qgscolorramplegendnodesettings.sip.in | 20 +++++ .../qgscolorramplegendnodewidget.sip.in | 18 ++++ .../qgscolorramplegendnodesettings.cpp | 16 +++- .../qgscolorramplegendnodesettings.h | 20 +++++ .../qgspointcloudattributebyramprenderer.cpp | 18 ++-- .../qgssinglebandpseudocolorrenderer.cpp | 18 ++-- src/gui/qgscolorramplegendnodewidget.cpp | 19 ++++ src/gui/qgscolorramplegendnodewidget.h | 18 ++++ .../qgssinglebandgrayrendererwidget.cpp | 2 + src/ui/qgscolorramplegendnodewidgetbase.ui | 86 +++++++++++-------- 10 files changed, 182 insertions(+), 53 deletions(-) diff --git a/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in b/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in index da60690f11c4..d3258b929c2f 100644 --- a/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in +++ b/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in @@ -197,6 +197,26 @@ Sets the ramp ``orientation`` (i.e. horizontal or vertical). .. seealso:: :py:func:`orientation` .. seealso:: :py:func:`setDirection` +%End + + bool useContinuousLegend() const; +%Docstring +Returns the ``True`` if the flag to use continuous legend is set. + +.. seealso:: :py:func:`setUseContinuousLegend` +%End + + void setUseContinuousLegend( bool useContinuousLegend ); +%Docstring +Sets the flag to use a continuos legend to ``useContinuousLegend``. + +When this flag is set the legend will be rendered using a single color ramp with +min and max values, when it is not set the legend will be rendered using separate +items for each item entry. + +.. seealso:: :py:func:`setOrientation` + +.. seealso:: :py:func:`direction` %End }; diff --git a/python/gui/auto_generated/qgscolorramplegendnodewidget.sip.in b/python/gui/auto_generated/qgscolorramplegendnodewidget.sip.in index 92284b0de791..81e6aa168680 100644 --- a/python/gui/auto_generated/qgscolorramplegendnodewidget.sip.in +++ b/python/gui/auto_generated/qgscolorramplegendnodewidget.sip.in @@ -47,6 +47,15 @@ Returns the legend node settings as defined by the widget. Sets the settings to show in the widget. .. seealso:: :py:func:`settings` +%End + + void setUseContinuousRampCheckBoxVisibility( bool visible ); +%Docstring +Sets visibility for the "Use Continuous Legend" checkbox to ``visible``. + +This widget is visible and checked by default but in a few cases it does not +need to be visible because disabling it would not make sense (for instance +when using single band gray renderer). %End }; @@ -77,6 +86,15 @@ Returns the legend node settings as defined by the dialog. QDialogButtonBox *buttonBox() const; %Docstring Returns a reference to the dialog's button box. +%End + + void setUseContinuousRampCheckBoxVisibility( bool visible ); +%Docstring +Sets visibility for the "Use Continuous Legend" checkbox in the legend settings dialog to ``visible``. + +This widget is visible and checked by default but in a few cases it does not +need to be visible because disabling it would not make sense (for instance +when using single band gray renderer). %End }; diff --git a/src/core/layertree/qgscolorramplegendnodesettings.cpp b/src/core/layertree/qgscolorramplegendnodesettings.cpp index 98dea0b45df8..1dd891e4d44a 100644 --- a/src/core/layertree/qgscolorramplegendnodesettings.cpp +++ b/src/core/layertree/qgscolorramplegendnodesettings.cpp @@ -26,7 +26,8 @@ QgsColorRampLegendNodeSettings::QgsColorRampLegendNodeSettings() } QgsColorRampLegendNodeSettings::QgsColorRampLegendNodeSettings( const QgsColorRampLegendNodeSettings &other ) - : mMinimumLabel( other.mMinimumLabel ) + : mUseContinuousLegend( other.mUseContinuousLegend ) + , mMinimumLabel( other.mMinimumLabel ) , mMaximumLabel( other.mMaximumLabel ) , mPrefix( other.mPrefix ) , mSuffix( other.mSuffix ) @@ -40,6 +41,7 @@ QgsColorRampLegendNodeSettings::QgsColorRampLegendNodeSettings( const QgsColorRa QgsColorRampLegendNodeSettings &QgsColorRampLegendNodeSettings::operator=( const QgsColorRampLegendNodeSettings &other ) { + mUseContinuousLegend = other.mUseContinuousLegend; mMinimumLabel = other.mMinimumLabel; mMaximumLabel = other.mMaximumLabel; mPrefix = other.mPrefix; @@ -97,6 +99,7 @@ void QgsColorRampLegendNodeSettings::writeXml( QDomDocument &doc, QDomElement &e { QDomElement settingsElement = doc.createElement( QStringLiteral( "rampLegendSettings" ) ); + settingsElement.setAttribute( QStringLiteral( "useContinuousLegend" ), mUseContinuousLegend ); settingsElement.setAttribute( QStringLiteral( "minimumLabel" ), mMinimumLabel ); settingsElement.setAttribute( QStringLiteral( "maximumLabel" ), mMaximumLabel ); settingsElement.setAttribute( QStringLiteral( "prefix" ), mPrefix ); @@ -121,6 +124,7 @@ void QgsColorRampLegendNodeSettings::readXml( const QDomElement &element, const const QDomElement settingsElement = element.firstChildElement( QStringLiteral( "rampLegendSettings" ) ); if ( !settingsElement.isNull() ) { + mUseContinuousLegend = settingsElement.attribute( QStringLiteral( "useContinuousLegend" ), QStringLiteral( "1" ) ).toInt( ); mMinimumLabel = settingsElement.attribute( QStringLiteral( "minimumLabel" ) ); mMaximumLabel = settingsElement.attribute( QStringLiteral( "maximumLabel" ) ); mPrefix = settingsElement.attribute( QStringLiteral( "prefix" ) ); @@ -185,3 +189,13 @@ void QgsColorRampLegendNodeSettings::setOrientation( Qt::Orientation orientation { mOrientation = orientation; } + +bool QgsColorRampLegendNodeSettings::useContinuousLegend() const +{ + return mUseContinuousLegend; +} + +void QgsColorRampLegendNodeSettings::setUseContinuousLegend( bool useContinuousLegend ) +{ + mUseContinuousLegend = useContinuousLegend; +} diff --git a/src/core/layertree/qgscolorramplegendnodesettings.h b/src/core/layertree/qgscolorramplegendnodesettings.h index d60a5d3becf6..a372f8a625ac 100644 --- a/src/core/layertree/qgscolorramplegendnodesettings.h +++ b/src/core/layertree/qgscolorramplegendnodesettings.h @@ -202,7 +202,27 @@ class CORE_EXPORT QgsColorRampLegendNodeSettings */ void setOrientation( Qt::Orientation orientation ); + /** + * Returns the TRUE if the flag to use continuous legend is set. + * + * \see setUseContinuousLegend() + */ + bool useContinuousLegend() const; + + /** + * Sets the flag to use a continuos legend to \a useContinuousLegend. + * + * When this flag is set the legend will be rendered using a single color ramp with + * min and max values, when it is not set the legend will be rendered using separate + * items for each item entry. + * + * \see setOrientation() + * \see direction() + */ + void setUseContinuousLegend( bool useContinuousLegend ); + private: + bool mUseContinuousLegend = true; QString mMinimumLabel; QString mMaximumLabel; QString mPrefix; diff --git a/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp b/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp index 2db080c85178..c432c8029d22 100644 --- a/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp +++ b/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp @@ -179,13 +179,17 @@ QList QgsPointCloudAttributeByRampRenderer::creat switch ( mColorRampShader.colorRampType() ) { case QgsColorRampShader::Interpolated: - // for interpolated shaders we use a ramp legend node - res << new QgsColorRampLegendNode( nodeLayer, mColorRampShader.sourceColorRamp()->clone(), - mColorRampShader.legendSettings() ? *mColorRampShader.legendSettings() : QgsColorRampLegendNodeSettings(), - mColorRampShader.minimumValue(), - mColorRampShader.maximumValue() ); - break; - + // for interpolated shaders we use a ramp legend node unless the settings flag + // to use the continuous legend is not set, in that case we fall through + if ( ! mColorRampShader.legendSettings() || mColorRampShader.legendSettings()->useContinuousLegend() ) + { + res << new QgsColorRampLegendNode( nodeLayer, mColorRampShader.sourceColorRamp()->clone(), + mColorRampShader.legendSettings() ? *mColorRampShader.legendSettings() : QgsColorRampLegendNodeSettings(), + mColorRampShader.minimumValue(), + mColorRampShader.maximumValue() ); + break; + } + Q_FALLTHROUGH(); case QgsColorRampShader::Discrete: case QgsColorRampShader::Exact: { diff --git a/src/core/raster/qgssinglebandpseudocolorrenderer.cpp b/src/core/raster/qgssinglebandpseudocolorrenderer.cpp index 733a85c04ab3..5667e8092465 100644 --- a/src/core/raster/qgssinglebandpseudocolorrenderer.cpp +++ b/src/core/raster/qgssinglebandpseudocolorrenderer.cpp @@ -444,15 +444,19 @@ QList QgsSingleBandPseudoColorRenderer::createLeg switch ( rampShader->colorRampType() ) { case QgsColorRampShader::Interpolated: - // for interpolated shaders we use a ramp legend node - if ( !rampShader->colorRampItemList().isEmpty() ) + // for interpolated shaders we use a ramp legend node unless the settings flag + // to use the continuous legend is not set, in that case we fall through + if ( ! rampShader->legendSettings() || rampShader->legendSettings()->useContinuousLegend() ) { - res << new QgsColorRampLegendNode( nodeLayer, rampShader->createColorRamp(), - rampShader->legendSettings() ? *rampShader->legendSettings() : QgsColorRampLegendNodeSettings(), - rampShader->minimumValue(), rampShader->maximumValue() ); + if ( !rampShader->colorRampItemList().isEmpty() ) + { + res << new QgsColorRampLegendNode( nodeLayer, rampShader->createColorRamp(), + rampShader->legendSettings() ? *rampShader->legendSettings() : QgsColorRampLegendNodeSettings(), + rampShader->minimumValue(), rampShader->maximumValue() ); + } + break; } - break; - + Q_FALLTHROUGH(); case QgsColorRampShader::Discrete: case QgsColorRampShader::Exact: { diff --git a/src/gui/qgscolorramplegendnodewidget.cpp b/src/gui/qgscolorramplegendnodewidget.cpp index cf42d31ced3b..6a155e06be9e 100644 --- a/src/gui/qgscolorramplegendnodewidget.cpp +++ b/src/gui/qgscolorramplegendnodewidget.cpp @@ -38,6 +38,13 @@ QgsColorRampLegendNodeWidget::QgsColorRampLegendNodeWidget( QWidget *parent ) mFontButton->setShowNullFormat( true ); mFontButton->setNoFormatString( tr( "Default" ) ); + connect( mUseContinuousLegendCheckBox, &QCheckBox::stateChanged, this, [ = ]( bool checked ) + { + mLayoutGroup->setEnabled( checked ); + mLabelsGroup->setEnabled( checked ); + onChanged(); + } ); + connect( mMinLabelLineEdit, &QLineEdit::textChanged, this, &QgsColorRampLegendNodeWidget::onChanged ); connect( mMaxLabelLineEdit, &QLineEdit::textChanged, this, &QgsColorRampLegendNodeWidget::onChanged ); connect( mPrefixLineEdit, &QLineEdit::textChanged, this, &QgsColorRampLegendNodeWidget::onChanged ); @@ -51,6 +58,7 @@ QgsColorRampLegendNodeWidget::QgsColorRampLegendNodeWidget( QWidget *parent ) QgsColorRampLegendNodeSettings QgsColorRampLegendNodeWidget::settings() const { QgsColorRampLegendNodeSettings settings; + settings.setUseContinuousLegend( mUseContinuousLegendCheckBox->isChecked() ); settings.setDirection( static_cast< QgsColorRampLegendNodeSettings::Direction >( mDirectionComboBox->currentData().toInt() ) ); settings.setOrientation( static_cast< Qt::Orientation >( mOrientationComboBox->currentData().toInt() ) ); settings.setMinimumLabel( mMinLabelLineEdit->text() ); @@ -67,6 +75,7 @@ void QgsColorRampLegendNodeWidget::setSettings( const QgsColorRampLegendNodeSett mBlockSignals = true; mSettings = settings; + mUseContinuousLegendCheckBox->setChecked( settings.useContinuousLegend() ); mMinLabelLineEdit->setText( settings.minimumLabel() ); mMaxLabelLineEdit->setText( settings.maximumLabel() ); mPrefixLineEdit->setText( settings.prefix() ); @@ -78,6 +87,11 @@ void QgsColorRampLegendNodeWidget::setSettings( const QgsColorRampLegendNodeSett mBlockSignals = false; } +void QgsColorRampLegendNodeWidget::setUseContinuousRampCheckBoxVisibility( bool visible ) +{ + mUseContinuousLegendCheckBox->setVisible( visible ); +} + void QgsColorRampLegendNodeWidget::changeNumberFormat() { QgsNumericFormatSelectorWidget *widget = new QgsNumericFormatSelectorWidget( this ); @@ -148,3 +162,8 @@ QDialogButtonBox *QgsColorRampLegendNodeDialog::buttonBox() const { return mButtonBox; } + +void QgsColorRampLegendNodeDialog::setUseContinuousRampCheckBoxVisibility( bool visible ) +{ + mWidget->setUseContinuousRampCheckBoxVisibility( visible ); +} diff --git a/src/gui/qgscolorramplegendnodewidget.h b/src/gui/qgscolorramplegendnodewidget.h index cd04c7306aef..c3bdcdf52413 100644 --- a/src/gui/qgscolorramplegendnodewidget.h +++ b/src/gui/qgscolorramplegendnodewidget.h @@ -63,6 +63,15 @@ class GUI_EXPORT QgsColorRampLegendNodeWidget: public QgsPanelWidget, private Ui */ void setSettings( const QgsColorRampLegendNodeSettings &settings ); + /** + * Sets visibility for the "Use Continuous Legend" checkbox to \a visible. + * + * This widget is visible and checked by default but in a few cases it does not + * need to be visible because disabling it would not make sense (for instance + * when using single band gray renderer). + */ + void setUseContinuousRampCheckBoxVisibility( bool visible ); + private slots: void onChanged(); @@ -102,6 +111,15 @@ class GUI_EXPORT QgsColorRampLegendNodeDialog : public QDialog */ QDialogButtonBox *buttonBox() const; + /** + * Sets visibility for the "Use Continuous Legend" checkbox in the legend settings dialog to \a visible. + * + * This widget is visible and checked by default but in a few cases it does not + * need to be visible because disabling it would not make sense (for instance + * when using single band gray renderer). + */ + void setUseContinuousRampCheckBoxVisibility( bool visible ); + private: QgsColorRampLegendNodeWidget *mWidget = nullptr; diff --git a/src/gui/raster/qgssinglebandgrayrendererwidget.cpp b/src/gui/raster/qgssinglebandgrayrendererwidget.cpp index 45111ac06ebb..71ac7c361944 100644 --- a/src/gui/raster/qgssinglebandgrayrendererwidget.cpp +++ b/src/gui/raster/qgssinglebandgrayrendererwidget.cpp @@ -229,6 +229,7 @@ void QgsSingleBandGrayRendererWidget::showLegendSettings() if ( panel && panel->dockMode() ) { QgsColorRampLegendNodeWidget *legendPanel = new QgsColorRampLegendNodeWidget(); + legendPanel->setUseContinuousRampCheckBoxVisibility( false ); legendPanel->setPanelTitle( tr( "Legend Settings" ) ); legendPanel->setSettings( mLegendSettings ); connect( legendPanel, &QgsColorRampLegendNodeWidget::widgetChanged, this, [ = ] @@ -241,6 +242,7 @@ void QgsSingleBandGrayRendererWidget::showLegendSettings() else { QgsColorRampLegendNodeDialog dialog( mLegendSettings, this ); + dialog.setUseContinuousRampCheckBoxVisibility( false ); dialog.setWindowTitle( tr( "Legend Settings" ) ); if ( dialog.exec() ) { diff --git a/src/ui/qgscolorramplegendnodewidgetbase.ui b/src/ui/qgscolorramplegendnodewidgetbase.ui index f73257629c44..b3eff07544c4 100644 --- a/src/ui/qgscolorramplegendnodewidgetbase.ui +++ b/src/ui/qgscolorramplegendnodewidgetbase.ui @@ -33,22 +33,25 @@ 0 - + + + Use continuous legend + + + true + + + + + Labels - - - - Prefix - - - - + - + @@ -61,21 +64,48 @@ + + + + Text format + + + + + + + + + - + - Suffix + Prefix - + Minimum + + + + Suffix + + + + + + Maximum + + + + Number format @@ -85,17 +115,14 @@ - - - - - + + - Text format + <html><head/><body><p><span style=" font-style:italic;">(Applies to print layout legends only)</span></p></body></html> - + Customize @@ -103,30 +130,13 @@ - - - - - - - Maximum - - - - - - - <html><head/><body><p><span style=" font-style:italic;">(Applies to print layout legends only)</span></p></body></html> - - - - + Layout From edc6029ff107f3079f859fc4f94e2c71dde9caf2 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Thu, 11 Mar 2021 10:53:23 +0100 Subject: [PATCH 040/377] Update python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in Co-authored-by: Nyall Dawson --- .../layertree/qgscolorramplegendnodesettings.sip.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in b/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in index d3258b929c2f..a8ee7275789d 100644 --- a/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in +++ b/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in @@ -201,7 +201,7 @@ Sets the ramp ``orientation`` (i.e. horizontal or vertical). bool useContinuousLegend() const; %Docstring -Returns the ``True`` if the flag to use continuous legend is set. +Returns ``True`` if a continuous gradient legend will be used. .. seealso:: :py:func:`setUseContinuousLegend` %End From ac7cd421a0a22b3a0b86d08eedd3f91e72080534 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Thu, 11 Mar 2021 10:55:26 +0100 Subject: [PATCH 041/377] Sync header after PR review --- src/core/layertree/qgscolorramplegendnodesettings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/layertree/qgscolorramplegendnodesettings.h b/src/core/layertree/qgscolorramplegendnodesettings.h index a372f8a625ac..1c17310d7f21 100644 --- a/src/core/layertree/qgscolorramplegendnodesettings.h +++ b/src/core/layertree/qgscolorramplegendnodesettings.h @@ -203,7 +203,7 @@ class CORE_EXPORT QgsColorRampLegendNodeSettings void setOrientation( Qt::Orientation orientation ); /** - * Returns the TRUE if the flag to use continuous legend is set. + * Returns TRUE if a continuous gradient legend will be used. * * \see setUseContinuousLegend() */ From 6eff08778e407bfcb38a57dd195ae74d3ddea462 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Thu, 11 Mar 2021 11:38:40 +0100 Subject: [PATCH 042/377] Doxy --- .../layertree/qgscolorramplegendnodesettings.sip.in | 6 +++--- src/core/layertree/qgscolorramplegendnodesettings.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in b/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in index a8ee7275789d..84f98fc6f64f 100644 --- a/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in +++ b/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in @@ -208,11 +208,11 @@ Returns ``True`` if a continuous gradient legend will be used. void setUseContinuousLegend( bool useContinuousLegend ); %Docstring -Sets the flag to use a continuos legend to ``useContinuousLegend``. +Sets the flag to use a continuos gradient legend to ``useContinuousLegend``. -When this flag is set the legend will be rendered using a single color ramp with +When this flag is set the legend will be rendered using a continuous color ramp with min and max values, when it is not set the legend will be rendered using separate -items for each item entry. +items for each entry. .. seealso:: :py:func:`setOrientation` diff --git a/src/core/layertree/qgscolorramplegendnodesettings.h b/src/core/layertree/qgscolorramplegendnodesettings.h index 1c17310d7f21..bf3d816b7ad2 100644 --- a/src/core/layertree/qgscolorramplegendnodesettings.h +++ b/src/core/layertree/qgscolorramplegendnodesettings.h @@ -210,11 +210,11 @@ class CORE_EXPORT QgsColorRampLegendNodeSettings bool useContinuousLegend() const; /** - * Sets the flag to use a continuos legend to \a useContinuousLegend. + * Sets the flag to use a continuos gradient legend to \a useContinuousLegend. * - * When this flag is set the legend will be rendered using a single color ramp with + * When this flag is set the legend will be rendered using a continuous color ramp with * min and max values, when it is not set the legend will be rendered using separate - * items for each item entry. + * items for each entry. * * \see setOrientation() * \see direction() From 7afb0fd5d133ac3c7ad47afd87ca32a8470139cd Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Fri, 12 Mar 2021 16:49:53 +0100 Subject: [PATCH 043/377] Add tests for useContinuousLegend flag --- tests/src/python/test_qgscolorramplegendnode.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/src/python/test_qgscolorramplegendnode.py b/tests/src/python/test_qgscolorramplegendnode.py index aba262674ea2..b99f24bdede3 100644 --- a/tests/src/python/test_qgscolorramplegendnode.py +++ b/tests/src/python/test_qgscolorramplegendnode.py @@ -77,6 +77,10 @@ def test_settings(self): self.assertEqual(settings.orientation(), Qt.Vertical) settings.setOrientation(Qt.Horizontal) self.assertEqual(settings.orientation(), Qt.Horizontal) + # Test default + self.assertTrue(settings.useContinuousLegend()) + settings.setUseContinuousLegend(False) + self.assertFalse(settings.useContinuousLegend()) self.assertFalse(settings.textFormat().isValid()) tf = QgsTextFormat() @@ -116,6 +120,7 @@ def test_settings(self): self.assertEqual(settings3.suffix(), 'suff') self.assertEqual(settings3.textFormat().size(), 13) self.assertEqual(settings3.orientation(), Qt.Horizontal) + self.assertFalse(settings3.useContinuousLegend()) # no text format elem = doc.createElement('test2') From 7d9d42c2aec2a1acd613b5696b6a917c264f6196 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Fri, 30 Oct 2020 10:49:55 +0100 Subject: [PATCH 044/377] Threaded standalone server --- src/server/qgis_mapserver.cpp | 636 +++++++++++++++++++--------------- 1 file changed, 360 insertions(+), 276 deletions(-) diff --git a/src/server/qgis_mapserver.cpp b/src/server/qgis_mapserver.cpp index f413c964aced..19017be7154b 100644 --- a/src/server/qgis_mapserver.cpp +++ b/src/server/qgis_mapserver.cpp @@ -41,6 +41,7 @@ while QGIS server internal logging is printed to stderr. #include #include #include +#include #ifndef Q_OS_WIN @@ -55,6 +56,46 @@ while QGIS server internal logging is printed to stderr. // For the signal exit handler QAtomicInt IS_RUNNING = 1; +// Request sync +QWaitCondition SERVER_WAIT_CONDITION; +QMutex SERVER_QUEUE_MUTEX; +// Server sync +QWaitCondition REQUEST_WAIT_CONDITION; +QMutex REQUEST_QUEUE_MUTEX; + +QString ipAddress; +QString serverPort; + +struct Request +{ + QString httpHeader; + QgsBufferServerRequest request; + QgsBufferServerResponse response; + QTcpSocket *clientConnection; + std::chrono::steady_clock::time_point startTime; +}; + +QQueue REQUEST_QUEUE; +QQueue SERVER_QUEUE; + +const QMap knownStatuses +{ + { 200, QStringLiteral( "OK" ) }, + { 201, QStringLiteral( "Created" ) }, + { 202, QStringLiteral( "Accepted" ) }, + { 204, QStringLiteral( "No Content" ) }, + { 301, QStringLiteral( "Moved Permanently" ) }, + { 302, QStringLiteral( "Moved Temporarily" ) }, + { 304, QStringLiteral( "Not Modified" ) }, + { 400, QStringLiteral( "Bad Request" ) }, + { 401, QStringLiteral( "Unauthorized" ) }, + { 403, QStringLiteral( "Forbidden" ) }, + { 404, QStringLiteral( "Not Found" ) }, + { 500, QStringLiteral( "Internal Server Error" ) }, + { 501, QStringLiteral( "Not Implemented" ) }, + { 502, QStringLiteral( "Bad Gateway" ) }, + { 503, QStringLiteral( "Service Unavailable" ) } +}; /** * The HttpException class represents an HTTP parsing exception. @@ -86,6 +127,285 @@ class HttpException: public std::exception }; + +class ServerWorker: public QThread +{ + Q_OBJECT + + public: + + ServerWorker( ) = default; + + void run( ) + { + QgsServer server; + +#ifdef HAVE_SERVER_PYTHON_PLUGINS + server.initPython(); +#endif + while ( IS_RUNNING ) + { + + SERVER_QUEUE_MUTEX.lock(); + + while ( SERVER_QUEUE.size() == 0 ) + { + SERVER_WAIT_CONDITION.wait( &SERVER_QUEUE_MUTEX ); + } + + auto request = SERVER_QUEUE.dequeue(); + + SERVER_QUEUE_MUTEX.unlock(); + + request->response.clear(); + + server.handleRequest( request->request, request->response ); + + emit responseReady( request ); + } + }; + + signals: + + void responseReady( Request *request ); +}; + + +class HttpHandlerWorker: public QThread +{ + Q_OBJECT + + public: + + HttpHandlerWorker( ) = default; + + void run( ) + { + + while ( IS_RUNNING ) + { + + REQUEST_QUEUE_MUTEX.lock(); + + while ( REQUEST_QUEUE.size() == 0 ) + { + REQUEST_WAIT_CONDITION.wait( &REQUEST_QUEUE_MUTEX ); + } + + auto clientConnection = REQUEST_QUEUE.dequeue(); + + REQUEST_QUEUE_MUTEX.unlock(); + + // Process request + QString incomingData; + + while ( IS_RUNNING && clientConnection->state() == QAbstractSocket::SocketState::ConnectedState ) + { + + auto start = std::chrono::steady_clock::now(); + + if ( ! clientConnection->bytesAvailable() ) + { + qApp->processEvents(); + continue; + } + + // Read all incoming data + while ( IS_RUNNING && clientConnection->bytesAvailable() > 0 ) + { + incomingData.append( clientConnection->readAll() ); + } + + try + { + // Parse protocol and URL GET /path HTTP/1.1 + int firstLinePos { incomingData.indexOf( "\r\n" ) }; + if ( firstLinePos == -1 ) + { + throw HttpException( QStringLiteral( "HTTP error finding protocol header" ) ); + } + + const QString firstLine { incomingData.left( firstLinePos ) }; + const QStringList firstLinePieces { firstLine.split( ' ' ) }; + if ( firstLinePieces.size() != 3 ) + { + throw HttpException( QStringLiteral( "HTTP error splitting protocol header" ) ); + } + + const QString methodString { firstLinePieces.at( 0 ) }; + + QgsServerRequest::Method method; + if ( methodString == "GET" ) + { + method = QgsServerRequest::Method::GetMethod; + } + else if ( methodString == "POST" ) + { + method = QgsServerRequest::Method::PostMethod; + } + else if ( methodString == "HEAD" ) + { + method = QgsServerRequest::Method::HeadMethod; + } + else if ( methodString == "PUT" ) + { + method = QgsServerRequest::Method::PutMethod; + } + else if ( methodString == "PATCH" ) + { + method = QgsServerRequest::Method::PatchMethod; + } + else if ( methodString == "DELETE" ) + { + method = QgsServerRequest::Method::DeleteMethod; + } + else + { + throw HttpException( QStringLiteral( "HTTP error unsupported method: %1" ).arg( methodString ) ); + } + + const QString protocol { firstLinePieces.at( 2 )}; + if ( protocol != QLatin1String( "HTTP/1.0" ) && protocol != QLatin1String( "HTTP/1.1" ) ) + { + throw HttpException( QStringLiteral( "HTTP error unsupported protocol: %1" ).arg( protocol ) ); + } + + // Headers + QgsBufferServerRequest::Headers headers; + int endHeadersPos { incomingData.indexOf( "\r\n\r\n" ) }; + + if ( endHeadersPos == -1 ) + { + throw HttpException( QStringLiteral( "HTTP error finding headers" ) ); + } + + const QStringList httpHeaders { incomingData.mid( firstLinePos + 2, endHeadersPos - firstLinePos ).split( "\r\n" ) }; + + for ( const auto &headerLine : httpHeaders ) + { + const int headerColonPos { headerLine.indexOf( ':' ) }; + if ( headerColonPos > 0 ) + { + headers.insert( headerLine.left( headerColonPos ), headerLine.mid( headerColonPos + 2 ) ); + } + } + + const int headersSize { endHeadersPos + 4 }; + + // Check for content length and if we have got all data + if ( headers.contains( QStringLiteral( "Content-Length" ) ) ) + { + bool ok; + const int contentLength { headers.value( QStringLiteral( "Content-Length" ) ).toInt( &ok ) }; + if ( ok && contentLength > incomingData.length() - headersSize ) + { + break; + } + } + + // At this point we should have read all data: + + // Build URL from env ... + QString url { qgetenv( "REQUEST_URI" ) }; + // ... or from server ip/port and request path + if ( url.isEmpty() ) + { + const QString path { firstLinePieces.at( 1 )}; + // Take Host header if defined + if ( headers.contains( QStringLiteral( "Host" ) ) ) + { + url = QStringLiteral( "http://%1%2" ).arg( headers.value( QStringLiteral( "Host" ) ) ).arg( path ); + } + else + { + url = QStringLiteral( "http://%1:%2%3" ).arg( ipAddress ).arg( serverPort ).arg( path ); + } + } + + // Inefficient copy :( + QByteArray data { incomingData.mid( headersSize ).toUtf8() }; + + auto request = new Request + { + firstLinePieces.join( ' ' ), + { url, method, headers, &data }, + {}, + clientConnection, + start + } ; + + // Send it to the queue + SERVER_QUEUE_MUTEX.lock(); + SERVER_QUEUE.enqueue( request ); + SERVER_QUEUE_MUTEX.unlock(); + SERVER_WAIT_CONDITION.wakeOne(); + + } + catch ( HttpException &ex ) + { + + if ( clientConnection->state() != QAbstractSocket::SocketState::ConnectedState ) + { + break; + } + + // Output stream: send error + clientConnection->write( QStringLiteral( "HTTP/1.0 %1 %2\r\n" ).arg( 500 ).arg( knownStatuses.value( 500 ) ).toUtf8() ); + clientConnection->write( QStringLiteral( "Server: QGIS\r\n" ).toUtf8() ); + clientConnection->write( "\r\n" ); + clientConnection->write( ex.message().toUtf8() ); + + std::cout << QStringLiteral( "%1 [%2] \"%3\" - - 500" ) + .arg( clientConnection->peerAddress().toString() ) + .arg( QDateTime::currentDateTime().toString() ) + .arg( ex.message() ).toStdString() << std::endl; + + clientConnection->disconnectFromHost(); + clientConnection->deleteLater(); + } + } + }; + + } +}; + + +void responseHandler( Request *requestPtr ) +{ + + std::unique_ptr request { requestPtr }; + auto elapsedTime { std::chrono::steady_clock::now() - request->startTime }; + + const auto &response { request->response }; + const auto &clientConnection { request->clientConnection }; + + // Output stream + clientConnection->write( QStringLiteral( "HTTP/1.0 %1 %2\r\n" ).arg( response.statusCode() ).arg( knownStatuses.value( response.statusCode(), QStringLiteral( "Unknown response code" ) ) ).toUtf8() ); + clientConnection->write( QStringLiteral( "Server: QGIS\r\n" ).toUtf8() ); + const auto responseHeaders { response.headers() }; + for ( auto it = responseHeaders.constBegin(); it != responseHeaders.constEnd(); ++it ) + { + clientConnection->write( QStringLiteral( "%1: %2\r\n" ).arg( it.key(), it.value() ).toUtf8() ); + } + clientConnection->write( "\r\n" ); + const QByteArray body { response.body() }; + clientConnection->write( body ); + + // 10.185.248.71 [09/Jan/2015:19:12:06 +0000] 808840 @@ -57,7 +60,53 @@ - + + + + + + Take all attributes from the Polygon with the largest area or Line with the longest length + + + + 0 + 0 + + + + + + + false + + + + + + + Take attributes from largest geometry + + + mFromLargestPushButton + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + @@ -91,7 +140,7 @@ - + Qt::Horizontal @@ -101,7 +150,7 @@ - + @@ -115,6 +164,9 @@ :/images/themes/default/mActionSelectPan.svg:/images/themes/default/mActionSelectPan.svg + + false + @@ -147,6 +199,7 @@ mTableWidget mFromSelectedPushButton + mFromLargestPushButton mSkipAllButton mRemoveFeatureFromSelectionButton buttonBox From 47ebeb47026eb1758593b9c7c39b4c58c34cef92 Mon Sep 17 00:00:00 2001 From: uclaros Date: Fri, 12 Mar 2021 00:56:56 +0200 Subject: [PATCH 074/377] Fix label wording --- src/ui/qgsmergeattributesdialogbase.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/qgsmergeattributesdialogbase.ui b/src/ui/qgsmergeattributesdialogbase.ui index 976793f1f55d..044bb770166b 100644 --- a/src/ui/qgsmergeattributesdialogbase.ui +++ b/src/ui/qgsmergeattributesdialogbase.ui @@ -84,7 +84,7 @@ - Take attributes from largest geometry + Take attributes from feature with the largest geometry mFromLargestPushButton From db47b371faa8f0be4b3592476ebfef4c6ae0eb11 Mon Sep 17 00:00:00 2001 From: uclaros Date: Fri, 12 Mar 2021 11:22:03 +0200 Subject: [PATCH 075/377] Updated icon --- images/themes/default/mActionFromLargestFeature.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/themes/default/mActionFromLargestFeature.svg b/images/themes/default/mActionFromLargestFeature.svg index 318d631f1075..a115deffb216 100644 --- a/images/themes/default/mActionFromLargestFeature.svg +++ b/images/themes/default/mActionFromLargestFeature.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 830947c4050b033435b0b413dc8a4dcfe28ed6a7 Mon Sep 17 00:00:00 2001 From: uclaros Date: Fri, 12 Mar 2021 12:12:19 +0200 Subject: [PATCH 076/377] Also support MultiPoints --- src/app/qgsmergeattributesdialog.cpp | 18 +++++++++++++++++- src/ui/qgsmergeattributesdialogbase.ui | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/app/qgsmergeattributesdialog.cpp b/src/app/qgsmergeattributesdialog.cpp index fb08225f4ee5..bc8f5279d232 100644 --- a/src/app/qgsmergeattributesdialog.cpp +++ b/src/app/qgsmergeattributesdialog.cpp @@ -79,7 +79,8 @@ QgsMergeAttributesDialog::QgsMergeAttributesDialog( const QgsFeatureList &featur mFromLargestPushButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionFromLargestFeature.svg" ) ) ); mRemoveFeatureFromSelectionButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionRemoveSelectedFeature.svg" ) ) ); - mFromLargestPushButton->setEnabled( mVectorLayer->geometryType() == QgsWkbTypes::LineGeometry || + mFromLargestPushButton->setEnabled( mVectorLayer->geometryType() == QgsWkbTypes::PointGeometry || + mVectorLayer->geometryType() == QgsWkbTypes::LineGeometry || mVectorLayer->geometryType() == QgsWkbTypes::PolygonGeometry ); mTakeLargestAttributesLabel->setEnabled( mFromLargestPushButton->isEnabled() ); @@ -494,6 +495,21 @@ void QgsMergeAttributesDialog::mFromLargestPushButton_clicked() switch ( mVectorLayer->geometryType() ) { + case QgsWkbTypes::PointGeometry: + { + QgsFeatureList::const_iterator f_it = mFeatureList.constBegin(); + for ( ; f_it != mFeatureList.constEnd(); ++f_it ) + { + const QgsAbstractGeometry *geom = f_it->geometry().constGet(); + int partCount = geom ? geom->partCount() : 0; + if ( partCount > maxValue ) + { + featureId = f_it->id(); + maxValue = partCount; + } + } + break; + } case QgsWkbTypes::LineGeometry: { QgsFeatureList::const_iterator f_it = mFeatureList.constBegin(); diff --git a/src/ui/qgsmergeattributesdialogbase.ui b/src/ui/qgsmergeattributesdialogbase.ui index 044bb770166b..9ea89b0fd1c0 100644 --- a/src/ui/qgsmergeattributesdialogbase.ui +++ b/src/ui/qgsmergeattributesdialogbase.ui @@ -65,7 +65,7 @@ - Take all attributes from the Polygon with the largest area or Line with the longest length + Take all attributes from the Polygon with the largest area, Line with the longest length or MultiPoint with the most parts From b49896dcd1732a4169ef313282768bf2bdae2776 Mon Sep 17 00:00:00 2001 From: uclaros Date: Fri, 12 Mar 2021 13:00:47 +0200 Subject: [PATCH 077/377] Also select row with largest feature so it gets highlighted --- src/app/qgsmergeattributesdialog.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/app/qgsmergeattributesdialog.cpp b/src/app/qgsmergeattributesdialog.cpp index bc8f5279d232..b7eb0f3d3af7 100644 --- a/src/app/qgsmergeattributesdialog.cpp +++ b/src/app/qgsmergeattributesdialog.cpp @@ -541,8 +541,20 @@ void QgsMergeAttributesDialog::mFromLargestPushButton_clicked() default: return; } + // Only proceed if we do have a largest geometry if ( maxValue > 0 ) + { setAllAttributesFromFeature( featureId ); + // Also select the appropriate row so the feature gets highlighted + for ( int row = mTableWidget->rowCount() - 1; row >= 0; --row ) + { + if ( mTableWidget->verticalHeaderItem( row )->text() == FID_TO_STRING( featureId ) ) + { + mTableWidget->selectRow( row ); + return; + } + } + } } void QgsMergeAttributesDialog::mRemoveFeatureFromSelectionButton_clicked() From 991627e54cafd1b6287b4a2e45d116bb09c6c646 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 16 Mar 2021 08:57:00 +1000 Subject: [PATCH 078/377] Tweak the labeling of the new merge "from largest" button depending on the layer's actual geometry type, and disable the option for single-point layers --- src/app/qgsmergeattributesdialog.cpp | 32 ++++++++++++++++++++++---- src/ui/qgsmergeattributesdialogbase.ui | 3 --- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/app/qgsmergeattributesdialog.cpp b/src/app/qgsmergeattributesdialog.cpp index b7eb0f3d3af7..e9326c1f172b 100644 --- a/src/app/qgsmergeattributesdialog.cpp +++ b/src/app/qgsmergeattributesdialog.cpp @@ -79,10 +79,34 @@ QgsMergeAttributesDialog::QgsMergeAttributesDialog( const QgsFeatureList &featur mFromLargestPushButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionFromLargestFeature.svg" ) ) ); mRemoveFeatureFromSelectionButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionRemoveSelectedFeature.svg" ) ) ); - mFromLargestPushButton->setEnabled( mVectorLayer->geometryType() == QgsWkbTypes::PointGeometry || - mVectorLayer->geometryType() == QgsWkbTypes::LineGeometry || - mVectorLayer->geometryType() == QgsWkbTypes::PolygonGeometry ); - mTakeLargestAttributesLabel->setEnabled( mFromLargestPushButton->isEnabled() ); + switch ( mVectorLayer->geometryType() ) + { + case QgsWkbTypes::PointGeometry: + mTakeLargestAttributesLabel->setText( tr( "Take attributes from feature with the most points" ) ); + mFromLargestPushButton->setToolTip( tr( "Take all attributes from the MultiPoint feature with the most parts" ) ); + if ( !QgsWkbTypes::isMultiType( mVectorLayer->wkbType() ) ) + { + mTakeLargestAttributesLabel->setEnabled( false ); + mFromLargestPushButton->setEnabled( false ); + } + break; + + case QgsWkbTypes::LineGeometry: + mTakeLargestAttributesLabel->setText( tr( "Take attributes from feature with the longest length" ) ); + mFromLargestPushButton->setToolTip( tr( "Take all attributes from the Line feature with the longest length" ) ); + break; + + case QgsWkbTypes::PolygonGeometry: + mTakeLargestAttributesLabel->setText( tr( "Take attributes from feature with the largest area" ) ); + mFromLargestPushButton->setToolTip( tr( "Take all attributes from the Polygon feature with the largest area" ) ); + break; + + case QgsWkbTypes::UnknownGeometry: + case QgsWkbTypes::NullGeometry: + mTakeLargestAttributesLabel->setEnabled( false ); + mFromLargestPushButton->setEnabled( false ); + break; + } connect( mSkipAllButton, &QAbstractButton::clicked, this, &QgsMergeAttributesDialog::setAllToSkip ); connect( mTableWidget, &QTableWidget::cellChanged, this, &QgsMergeAttributesDialog::tableWidgetCellChanged ); diff --git a/src/ui/qgsmergeattributesdialogbase.ui b/src/ui/qgsmergeattributesdialogbase.ui index 9ea89b0fd1c0..fa9c2723c4b3 100644 --- a/src/ui/qgsmergeattributesdialogbase.ui +++ b/src/ui/qgsmergeattributesdialogbase.ui @@ -64,9 +64,6 @@ - - Take all attributes from the Polygon with the largest area, Line with the longest length or MultiPoint with the most parts - 0 From 4cdc0b2f4e2baee257ef50b358f427efe534f4b3 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 16 Mar 2021 09:00:14 +1000 Subject: [PATCH 079/377] Use correct title for Merge Features dialog Fixes #32206 --- src/app/qgisapp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 72e059591b5e..2c4e36c98e6b 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -10036,6 +10036,7 @@ void QgisApp::mergeSelectedFeatures() //merge the attributes together QgsMergeAttributesDialog d( featureList, vl, mapCanvas() ); + d.setWindowTitle( tr( "Merge Features" ) ); if ( d.exec() == QDialog::Rejected ) { return; From bab63dd050b701828d52e731795a24fceb911f61 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 16 Mar 2021 09:15:05 +1000 Subject: [PATCH 080/377] [processing] Fix misleading "cancel" label shown for "close" button This button isn't a cancel button - it just closes the dialog, and doesn't abort any changes which have already been made as a result of running the algorithm through the dialog. --- python/plugins/processing/gui/AlgorithmDialog.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/plugins/processing/gui/AlgorithmDialog.py b/python/plugins/processing/gui/AlgorithmDialog.py index f29bfe29113a..1b22fc821807 100644 --- a/python/plugins/processing/gui/AlgorithmDialog.py +++ b/python/plugins/processing/gui/AlgorithmDialog.py @@ -83,8 +83,6 @@ def __init__(self, alg, in_place=False, parent=None): self.buttonBox().button(QDialogButtonBox.Ok).setText( QCoreApplication.translate("AlgorithmDialog", "Modify Selected Features") if has_selection else QCoreApplication.translate("AlgorithmDialog", "Modify All Features")) - self.buttonBox().button(QDialogButtonBox.Close).setText( - QCoreApplication.translate("AlgorithmDialog", "Cancel")) self.setWindowTitle(self.windowTitle() + ' | ' + self.active_layer.name()) self.updateRunButtonVisibility() From 82d120b5059353c5c3d5e69f096da06444099196 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 16 Mar 2021 08:48:03 +1000 Subject: [PATCH 081/377] [processing] When an algorithm is run in place through the 'ef' locator filter, ensure the progress bar is removed when the algorithm finishes Otherwise it hangs around in the message bar until it's manually dismissed, unlike the behavior when you run an in-place operation through the toolbox. --- python/plugins/processing/gui/AlgorithmLocatorFilter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/plugins/processing/gui/AlgorithmLocatorFilter.py b/python/plugins/processing/gui/AlgorithmLocatorFilter.py index ddaa1001224b..7a43c10e58e6 100644 --- a/python/plugins/processing/gui/AlgorithmLocatorFilter.py +++ b/python/plugins/processing/gui/AlgorithmLocatorFilter.py @@ -227,3 +227,4 @@ def triggerResult(self, result): feedback = MessageBarProgress(algname=alg.displayName()) parameters = {} execute_in_place(alg, parameters, feedback=feedback) + feedback.close() From 1f00f6ea2f37cb8f14b1023e4dadedd03da2915c Mon Sep 17 00:00:00 2001 From: Andrea Giudiceandrea Date: Mon, 15 Mar 2021 23:44:20 +0100 Subject: [PATCH 082/377] [processing][gdal] Fix parsing of creation options for Roughness alg --- python/plugins/processing/algs/gdal/roughness.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/python/plugins/processing/algs/gdal/roughness.py b/python/plugins/processing/algs/gdal/roughness.py index 304e86f5255a..747d489fe857 100644 --- a/python/plugins/processing/algs/gdal/roughness.py +++ b/python/plugins/processing/algs/gdal/roughness.py @@ -108,7 +108,6 @@ def getConsoleCommands(self, parameters, context, feedback, executing=True): options = self.parameterAsString(parameters, self.OPTIONS, context) if options: - arguments.append('-co') - arguments.append(options) + arguments.extend(GdalUtils.parseCreationOptions(options)) return [self.commandName(), GdalUtils.escapeAndJoin(arguments)] From 5db41d1edfd1d4d8216fdc15394657efbd8f009d Mon Sep 17 00:00:00 2001 From: Harrissou Sant-anna Date: Tue, 16 Mar 2021 04:49:35 +0100 Subject: [PATCH 083/377] Use correct spelling for qgsProcessingException class Fix typo --- .../auto_generated/processing/qgsprocessingalgorithm.sip.in | 2 +- python/plugins/processing/tests/GdalAlgorithmsGeneralTest.py | 2 +- src/core/processing/qgsprocessingalgorithm.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in b/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in index 26befaab62c2..3cd42bdf443b 100644 --- a/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in @@ -350,7 +350,7 @@ Algorithm progress should be reported using the supplied ``feedback`` object. If specified, ``ok`` will be set to ``True`` if algorithm was successfully run. -If ``catchExceptions`` is set to ``False``, then :py:class:`QgsProcessingExceptions` raised during +If ``catchExceptions`` is set to ``False``, then :py:class:`QgsProcessingException` raised during the algorithm run will not be automatically caught and will be raised instead. :return: A map of algorithm outputs. These may be output layer references, or calculated diff --git a/python/plugins/processing/tests/GdalAlgorithmsGeneralTest.py b/python/plugins/processing/tests/GdalAlgorithmsGeneralTest.py index 135907be6c71..ae87dc55e5c0 100644 --- a/python/plugins/processing/tests/GdalAlgorithmsGeneralTest.py +++ b/python/plugins/processing/tests/GdalAlgorithmsGeneralTest.py @@ -82,7 +82,7 @@ def testCommandNameInTags(self): self.assertTrue(a.commandName() in a.tags(), 'Algorithm {} commandName not found in tags!'.format(a.id())) def testNoParameters(self): - # Test that algorithms throw QgsProcessingExceptions and not base Python + # Test that algorithms throw QgsProcessingException and not base Python # exceptions when no parameters specified p = QgsApplication.processingRegistry().providerById('gdal') context = QgsProcessingContext() diff --git a/src/core/processing/qgsprocessingalgorithm.h b/src/core/processing/qgsprocessingalgorithm.h index 769dbef64a0c..7462f5410f7b 100644 --- a/src/core/processing/qgsprocessingalgorithm.h +++ b/src/core/processing/qgsprocessingalgorithm.h @@ -378,7 +378,7 @@ class CORE_EXPORT QgsProcessingAlgorithm * * If specified, \a ok will be set to TRUE if algorithm was successfully run. * - * If \a catchExceptions is set to FALSE, then QgsProcessingExceptions raised during + * If \a catchExceptions is set to FALSE, then QgsProcessingException raised during * the algorithm run will not be automatically caught and will be raised instead. * * \returns A map of algorithm outputs. These may be output layer references, or calculated From ba8e125ab1fa0eaceea4b132de82de7a437bab34 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Wed, 10 Mar 2021 23:38:22 +0100 Subject: [PATCH 084/377] Fix wrong list of layers in Rasterize alg (Convert map to raster) When not using a map theme nor explicit list of layers, the list of layers is taken from the project. However the algorithm took a list of all layers in the project, including the ones that were not visible, and the rendering order was rather arbitrary (sorted by layer IDs I think). It seems this has been broken since the port from Python to C++ in QGIS 3.12 --- src/analysis/processing/qgsalgorithmrasterize.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/analysis/processing/qgsalgorithmrasterize.cpp b/src/analysis/processing/qgsalgorithmrasterize.cpp index 7bee31890156..8e3f7d80765d 100644 --- a/src/analysis/processing/qgsalgorithmrasterize.cpp +++ b/src/analysis/processing/qgsalgorithmrasterize.cpp @@ -29,6 +29,7 @@ #include "qgsmaprenderercustompainterjob.h" #include "gdal.h" #include "qgsgdalutils.h" +#include "qgslayertree.h" #include @@ -333,8 +334,16 @@ bool QgsRasterizeAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, Qgs // Still no layers? Get them all from the project if ( mMapLayers.size() == 0 ) { - const auto constLayers { context.project()->mapLayers().values() }; - for ( const QgsMapLayer *ml : constLayers ) + QList layers; + QgsLayerTree *root = context.project()->layerTreeRoot(); + for ( QgsLayerTreeLayer *nodeLayer : root->findLayers() ) + { + QgsMapLayer *layer = nodeLayer->layer(); + if ( nodeLayer->isVisible() && root->layerOrder().contains( layer ) ) + layers << layer; + } + + for ( const QgsMapLayer *ml : qgis::as_const( layers ) ) { mMapLayers.push_back( std::unique_ptr( ml->clone( ) ) ); } From 4e46aa4c49f07b9f076f0daa7e84e8454aac6080 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Sun, 14 Mar 2021 13:16:06 +0100 Subject: [PATCH 085/377] Added a test for "rasterize" (convert map to raster) algorithm --- .../auto_generated/qgsrenderchecker.sip.in | 9 +++- src/core/qgsrenderchecker.cpp | 2 +- src/core/qgsrenderchecker.h | 9 +++- tests/src/analysis/testqgsprocessingalgs.cpp | 50 ++++++++++++++++++ .../expected_rasterize/expected_rasterize.tif | Bin 0 -> 307694 bytes 5 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 tests/testdata/control_images/processing_algorithm/expected_rasterize/expected_rasterize.tif diff --git a/python/core/auto_generated/qgsrenderchecker.sip.in b/python/core/auto_generated/qgsrenderchecker.sip.in index 48b48cdaa428..63d6b9e76dec 100644 --- a/python/core/auto_generated/qgsrenderchecker.sip.in +++ b/python/core/auto_generated/qgsrenderchecker.sip.in @@ -82,7 +82,14 @@ Sets the base directory ``name`` for the control image (with control image path suffixed). The path to the image will be constructed like this: -:py:func:`~QgsRenderChecker.controlImagePath` + '/' + control name + '/' + control name + '.png' +:py:func:`~QgsRenderChecker.controlImagePath` + '/' + control name + '/' + control name + '.' + extension ('png' by default) +%End + + void setControlExtension( const QString &extension ); +%Docstring +Sets file extension for the control image. By defailt it is "png" + +.. versionadded:: 3.20 %End void setControlPathPrefix( const QString &name ); diff --git a/src/core/qgsrenderchecker.cpp b/src/core/qgsrenderchecker.cpp index 92ebe68f7d9b..d67b96241f65 100644 --- a/src/core/qgsrenderchecker.cpp +++ b/src/core/qgsrenderchecker.cpp @@ -46,7 +46,7 @@ void QgsRenderChecker::setControlImagePath( const QString &path ) void QgsRenderChecker::setControlName( const QString &name ) { mControlName = name; - mExpectedImageFile = controlImagePath() + name + '/' + mControlPathSuffix + name + ".png"; + mExpectedImageFile = controlImagePath() + name + '/' + mControlPathSuffix + name + "." + mControlExtension; } void QgsRenderChecker::setControlPathSuffix( const QString &name ) diff --git a/src/core/qgsrenderchecker.h b/src/core/qgsrenderchecker.h index ffec638d8503..e49456df5d30 100644 --- a/src/core/qgsrenderchecker.h +++ b/src/core/qgsrenderchecker.h @@ -98,10 +98,16 @@ class CORE_EXPORT QgsRenderChecker * suffixed). * * The path to the image will be constructed like this: - * controlImagePath() + '/' + control name + '/' + control name + '.png' + * controlImagePath() + '/' + control name + '/' + control name + '.' + extension ('png' by default) */ void setControlName( const QString &name ); + /** + * Sets file extension for the control image. By defailt it is "png" + * \since QGIS 3.20 + */ + void setControlExtension( const QString &extension ) { mControlExtension = extension; } + /** * Sets the path prefix where the control images are kept. * This will be appended to controlImagePath(). @@ -237,6 +243,7 @@ class CORE_EXPORT QgsRenderChecker int mMaxSizeDifferenceY = 0; int mElapsedTimeTarget = 0; QgsMapSettings mMapSettings; + QString mControlExtension = QStringLiteral( "png" ); QString mControlPathPrefix; QString mControlPathSuffix; QVector mDashMessages; diff --git a/tests/src/analysis/testqgsprocessingalgs.cpp b/tests/src/analysis/testqgsprocessingalgs.cpp index f7e4694ef9ad..d1a912486cda 100644 --- a/tests/src/analysis/testqgsprocessingalgs.cpp +++ b/tests/src/analysis/testqgsprocessingalgs.cpp @@ -39,6 +39,7 @@ #include "qgsreclassifyutils.h" #include "qgsalgorithmrasterlogicalop.h" #include "qgsprintlayout.h" +#include "qgslayertree.h" #include "qgslayoutmanager.h" #include "qgslayoutitemmap.h" #include "qgsmarkersymbollayer.h" @@ -178,6 +179,8 @@ class TestQgsProcessingAlgs: public QObject void fileDownloader(); + void rasterize(); + private: bool imageCheck( const QString &testName, const QString &renderedImage ); @@ -6511,6 +6514,53 @@ void TestQgsProcessingAlgs::fileDownloader() QVERIFY( results.value( QStringLiteral( "OUTPUT" ) ).toString().endsWith( QLatin1String( ".txt" ) ) ); } +void TestQgsProcessingAlgs::rasterize() +{ + std::unique_ptr< QgsProcessingAlgorithm > alg( QgsApplication::processingRegistry()->createAlgorithmById( QStringLiteral( "native:rasterize" ) ) ); + QVERIFY( alg != nullptr ); + + QString outputTif = QDir::tempPath() + "/rasterize_output.tif"; + if ( QFile::exists( outputTif ) ) + QFile::remove( outputTif ); + + QVariantMap parameters; + parameters.insert( QStringLiteral( "EXTENT" ), QStringLiteral( "-120,-80,15,55" ) ); + parameters.insert( QStringLiteral( "TILE_SIZE" ), 320 ); + parameters.insert( QStringLiteral( "MAP_UNITS_PER_PIXEL" ), 0.125 ); + parameters.insert( QStringLiteral( "OUTPUT" ), outputTif ); + + // create a temporary project with three layers, but only two are visible + // (to test that the algorithm in the default setup without defined LAYERS or MAP_THEME uses only vsisible + // layers that and in the correct order) + QgsProject project; + QString dataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt + QgsVectorLayer *pointsLayer = new QgsVectorLayer( dataDir + "/points.shp", QStringLiteral( "points" ), QStringLiteral( "ogr" ) ); + QgsVectorLayer *linesLayer = new QgsVectorLayer( dataDir + "/lines.shp", QStringLiteral( "lines" ), QStringLiteral( "ogr" ) ); + QgsVectorLayer *polygonLayer = new QgsVectorLayer( dataDir + "/polys.shp", QStringLiteral( "polygons" ), QStringLiteral( "ogr" ) ); + QVERIFY( pointsLayer->isValid() && linesLayer->isValid() && polygonLayer->isValid() ); + project.addMapLayers( QList() << pointsLayer << linesLayer << polygonLayer ); + QgsLayerTreeLayer *nodePolygons = project.layerTreeRoot()->findLayer( polygonLayer ); + QVERIFY( nodePolygons ); + nodePolygons->setItemVisibilityChecked( false ); + + std::unique_ptr< QgsProcessingContext > context = qgis::make_unique< QgsProcessingContext >(); + context->setProject( &project ); + QgsProcessingFeedback feedback; + QVariantMap results; + bool ok = false; + + results = alg->run( parameters, *context, &feedback, &ok ); + QVERIFY( ok ); + QVERIFY( QFile::exists( outputTif ) ); + + QgsRenderChecker checker; + checker.setControlPathPrefix( QStringLiteral( "processing_algorithm" ) ); + checker.setControlExtension( "tif" ); + checker.setControlName( "expected_rasterize" ); + checker.setRenderedImage( outputTif ); + QVERIFY( checker.compareImages( "rasterize", 500 ) ); +} + void TestQgsProcessingAlgs::exportMeshTimeSeries() { std::unique_ptr< QgsProcessingAlgorithm > alg( QgsApplication::processingRegistry()->createAlgorithmById( QStringLiteral( "native:meshexporttimeseries" ) ) ); diff --git a/tests/testdata/control_images/processing_algorithm/expected_rasterize/expected_rasterize.tif b/tests/testdata/control_images/processing_algorithm/expected_rasterize/expected_rasterize.tif new file mode 100644 index 0000000000000000000000000000000000000000..3a7605fc2c97e474e45a58b595e5c2a96f381c5b GIT binary patch literal 307694 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 literal 0 HcmV?d00001 From fb683e9a0fd6072567f6445bea8942999cdb6f5c Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Sun, 14 Mar 2021 13:27:00 +0100 Subject: [PATCH 086/377] Fix spelling --- python/core/auto_generated/qgsrenderchecker.sip.in | 2 +- src/core/qgsrenderchecker.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/core/auto_generated/qgsrenderchecker.sip.in b/python/core/auto_generated/qgsrenderchecker.sip.in index 63d6b9e76dec..162180b6fef1 100644 --- a/python/core/auto_generated/qgsrenderchecker.sip.in +++ b/python/core/auto_generated/qgsrenderchecker.sip.in @@ -87,7 +87,7 @@ The path to the image will be constructed like this: void setControlExtension( const QString &extension ); %Docstring -Sets file extension for the control image. By defailt it is "png" +Sets file extension for the control image. By default it is "png" .. versionadded:: 3.20 %End diff --git a/src/core/qgsrenderchecker.h b/src/core/qgsrenderchecker.h index e49456df5d30..1a47ba6092b3 100644 --- a/src/core/qgsrenderchecker.h +++ b/src/core/qgsrenderchecker.h @@ -103,7 +103,7 @@ class CORE_EXPORT QgsRenderChecker void setControlName( const QString &name ); /** - * Sets file extension for the control image. By defailt it is "png" + * Sets file extension for the control image. By default it is "png" * \since QGIS 3.20 */ void setControlExtension( const QString &extension ) { mControlExtension = extension; } From ea25d07ddb0b20a25c3501c2bdc35a4a3e730fa5 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Sun, 14 Mar 2021 15:05:00 +0100 Subject: [PATCH 087/377] qgis::make_unique -> std::make_unique --- tests/src/analysis/testqgsprocessingalgs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/analysis/testqgsprocessingalgs.cpp b/tests/src/analysis/testqgsprocessingalgs.cpp index d1a912486cda..d23e4e16bb91 100644 --- a/tests/src/analysis/testqgsprocessingalgs.cpp +++ b/tests/src/analysis/testqgsprocessingalgs.cpp @@ -6543,7 +6543,7 @@ void TestQgsProcessingAlgs::rasterize() QVERIFY( nodePolygons ); nodePolygons->setItemVisibilityChecked( false ); - std::unique_ptr< QgsProcessingContext > context = qgis::make_unique< QgsProcessingContext >(); + std::unique_ptr< QgsProcessingContext > context = std::make_unique< QgsProcessingContext >(); context->setProject( &project ); QgsProcessingFeedback feedback; QVariantMap results; From d5616ee950def0900dca49461dd8d03bd40a5dd3 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Mon, 15 Mar 2021 10:06:37 +0100 Subject: [PATCH 088/377] Add qt5-image-formats-plugins to build deps to support TIF for QImage --- .docker/qgis3-build-deps.dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/.docker/qgis3-build-deps.dockerfile b/.docker/qgis3-build-deps.dockerfile index 9e8476e82bdd..776a57def10a 100644 --- a/.docker/qgis3-build-deps.dockerfile +++ b/.docker/qgis3-build-deps.dockerfile @@ -98,6 +98,7 @@ RUN apt-get update \ qt3d-defaultgeometryloader-plugin \ qt3d-gltfsceneio-plugin \ qt3d-scene2d-plugin \ + qt5-image-formats-plugins \ qt5keychain-dev \ qtbase5-dev \ qtdeclarative5-dev-tools \ From dbe5aba5e9ffa4429b0fa11cd9c6cabb137ab30b Mon Sep 17 00:00:00 2001 From: nirvn Date: Mon, 15 Mar 2021 11:01:16 +0700 Subject: [PATCH 089/377] [ogr][gdal] Proper vsi{zip,tar,gzip} uri decoding/encoding --- .../providers/gdal/qgsgdalproviderbase.cpp | 35 ++++++++++++++----- src/core/providers/ogr/qgsogrconnpool.h | 8 +++-- src/core/providers/ogr/qgsogrprovider.cpp | 34 ++++++++++++++++-- tests/src/core/testqgsgdalprovider.cpp | 6 ++-- tests/src/python/test_provider_gdal.py | 9 +++++ tests/src/python/test_provider_ogr.py | 27 ++++++++++++++ 6 files changed, 103 insertions(+), 16 deletions(-) diff --git a/src/core/providers/gdal/qgsgdalproviderbase.cpp b/src/core/providers/gdal/qgsgdalproviderbase.cpp index fdf06b7e5c29..915414a83afa 100644 --- a/src/core/providers/gdal/qgsgdalproviderbase.cpp +++ b/src/core/providers/gdal/qgsgdalproviderbase.cpp @@ -260,7 +260,6 @@ QgsRectangle QgsGdalProviderBase::extent( GDALDatasetH gdalDataset )const GDALDatasetH QgsGdalProviderBase::gdalOpen( const QString &uri, unsigned int nOpenFlags ) { QVariantMap parts = decodeGdalUri( uri ); - QString filePath = parts.value( QStringLiteral( "path" ) ).toString(); const QStringList openOptions = parts.value( QStringLiteral( "openOptions" ) ).toStringList(); parts.remove( QStringLiteral( "openOptions" ) ); @@ -329,8 +328,25 @@ QVariantMap QgsGdalProviderBase::decodeGdalUri( const QString &uri ) QStringList openOptions; QString vsiPrefix = qgsVsiPrefix( path ); - if ( !path.isEmpty() ) + QString vsiSuffix; + if ( path.startsWith( vsiPrefix, Qt::CaseInsensitive ) ) + { path = path.mid( vsiPrefix.count() ); + if ( vsiPrefix == QLatin1String( "/vsizip/" ) ) + { + const QRegularExpression vsiRegex( QStringLiteral( "(?:\\.zip|\\.tar|\\.gz|\\.tar\\.gz|\\.tgz)([^|]*)" ) ); + QRegularExpressionMatch match = vsiRegex.match( path ); + if ( match.hasMatch() ) + { + vsiSuffix = match.captured( 1 ); + path = path.remove( match.capturedStart( 1 ), match.capturedLength( 1 ) ); + } + } + } + else + { + vsiPrefix.clear(); + } if ( path.indexOf( ':' ) != -1 ) { @@ -373,22 +389,23 @@ QVariantMap QgsGdalProviderBase::decodeGdalUri( const QString &uri ) uriComponents.insert( QStringLiteral( "openOptions" ), openOptions ); if ( !vsiPrefix.isEmpty() ) uriComponents.insert( QStringLiteral( "vsiPrefix" ), vsiPrefix ); + if ( !vsiSuffix.isEmpty() ) + uriComponents.insert( QStringLiteral( "vsiSuffix" ), vsiSuffix ); return uriComponents; } QString QgsGdalProviderBase::encodeGdalUri( const QVariantMap &parts ) { const QString vsiPrefix = parts.value( QStringLiteral( "vsiPrefix" ) ).toString(); + const QString vsiSuffix = parts.value( QStringLiteral( "vsiSuffix" ) ).toString(); const QString path = parts.value( QStringLiteral( "path" ) ).toString(); const QString layerName = parts.value( QStringLiteral( "layerName" ) ).toString(); - QString uri; - if ( !layerName.isEmpty() && path.endsWith( QLatin1String( "gpkg" ) ) ) - uri = QStringLiteral( "GPKG:%1:%2" ).arg( path, layerName ); + QString uri = vsiPrefix + path + vsiSuffix; + if ( !layerName.isEmpty() && uri.endsWith( QLatin1String( "gpkg" ) ) ) + uri = QStringLiteral( "GPKG:%1:%2" ).arg( uri, layerName ); else if ( !layerName.isEmpty() ) - uri = path + QStringLiteral( "|%1" ).arg( layerName ); - else - uri = path; + uri = uri + QStringLiteral( "|%1" ).arg( layerName ); const QStringList openOptions = parts.value( QStringLiteral( "openOptions" ) ).toStringList(); @@ -398,7 +415,7 @@ QString QgsGdalProviderBase::encodeGdalUri( const QVariantMap &parts ) uri += openOption; } - return !vsiPrefix.isEmpty() ? vsiPrefix + uri : uri; + return uri; } ///@endcond diff --git a/src/core/providers/ogr/qgsogrconnpool.h b/src/core/providers/ogr/qgsogrconnpool.h index c67595c9ce9b..a22d572cf6cd 100644 --- a/src/core/providers/ogr/qgsogrconnpool.h +++ b/src/core/providers/ogr/qgsogrconnpool.h @@ -40,8 +40,10 @@ inline void qgsConnectionPool_ConnectionCreate( const QString &connInfo, QgsOgrC { c = new QgsOgrConn; - QVariantMap parts = QgsOgrProviderMetadata().decodeUri( connInfo ); - QString filePath = parts.value( QStringLiteral( "path" ) ).toString(); + const QVariantMap parts = QgsOgrProviderMetadata().decodeUri( connInfo ); + const QString fullPath = parts.value( QStringLiteral( "vsiPrefix" ) ).toString() + + parts.value( QStringLiteral( "path" ) ).toString() + + parts.value( QStringLiteral( "vsiSuffix" ) ).toString(); const QStringList openOptions = parts.value( QStringLiteral( "openOptions" ) ).toStringList(); char **papszOpenOptions = nullptr; for ( const QString &option : openOptions ) @@ -49,7 +51,7 @@ inline void qgsConnectionPool_ConnectionCreate( const QString &connInfo, QgsOgrC papszOpenOptions = CSLAddString( papszOpenOptions, option.toUtf8().constData() ); } - c->ds = QgsOgrProviderUtils::GDALOpenWrapper( filePath.toUtf8().constData(), false, papszOpenOptions, nullptr ); + c->ds = QgsOgrProviderUtils::GDALOpenWrapper( fullPath.toUtf8().constData(), false, papszOpenOptions, nullptr ); CSLDestroy( papszOpenOptions ); c->path = connInfo; c->valid = true; diff --git a/src/core/providers/ogr/qgsogrprovider.cpp b/src/core/providers/ogr/qgsogrprovider.cpp index da6b713f2c09..34d37bffd7c5 100644 --- a/src/core/providers/ogr/qgsogrprovider.cpp +++ b/src/core/providers/ogr/qgsogrprovider.cpp @@ -319,7 +319,10 @@ static QString AnalyzeURI( QString const &uri, openOptions = parts.value( QStringLiteral( "openOptions" ) ).toStringList(); } - return parts.value( QStringLiteral( "path" ) ).toString(); + const QString fullPath = parts.value( QStringLiteral( "vsiPrefix" ) ).toString() + + parts.value( QStringLiteral( "path" ) ).toString() + + parts.value( QStringLiteral( "vsiSuffix" ) ).toString(); + return fullPath; } QgsVectorLayerExporter::ExportError QgsOgrProvider::createEmptyLayer( const QString &uri, @@ -3572,6 +3575,27 @@ QVariantMap QgsOgrProviderMetadata::decodeUri( const QString &uri ) const int layerId = -1; + QString vsiPrefix = qgsVsiPrefix( path ); + QString vsiSuffix; + if ( path.startsWith( vsiPrefix, Qt::CaseInsensitive ) ) + { + path = path.mid( vsiPrefix.count() ); + if ( vsiPrefix == QLatin1String( "/vsizip/" ) ) + { + const QRegularExpression vsiRegex( QStringLiteral( "(?:\\.zip|\\.tar|\\.gz|\\.tar\\.gz|\\.tgz)([^|]*)" ) ); + QRegularExpressionMatch match = vsiRegex.match( path ); + if ( match.hasMatch() ) + { + vsiSuffix = match.captured( 1 ); + path = path.remove( match.capturedStart( 1 ), match.capturedLength( 1 ) ); + } + } + } + else + { + vsiPrefix.clear(); + } + if ( path.contains( '|' ) ) { const QRegularExpression geometryTypeRegex( QStringLiteral( "\\|geometrytype=([a-zA-Z0-9]*)" ), QRegularExpression::PatternOption::CaseInsensitiveOption ); @@ -3667,18 +3691,24 @@ QVariantMap QgsOgrProviderMetadata::decodeUri( const QString &uri ) const uriComponents.insert( QStringLiteral( "databaseName" ), databaseName ); if ( !openOptions.isEmpty() ) uriComponents.insert( QStringLiteral( "openOptions" ), openOptions ); + if ( !vsiPrefix.isEmpty() ) + uriComponents.insert( QStringLiteral( "vsiPrefix" ), vsiPrefix ); + if ( !vsiSuffix.isEmpty() ) + uriComponents.insert( QStringLiteral( "vsiSuffix" ), vsiSuffix ); return uriComponents; } QString QgsOgrProviderMetadata::encodeUri( const QVariantMap &parts ) const { + const QString vsiPrefix = parts.value( QStringLiteral( "vsiPrefix" ) ).toString(); + const QString vsiSuffix = parts.value( QStringLiteral( "vsiSuffix" ) ).toString(); const QString path = parts.value( QStringLiteral( "path" ) ).toString(); const QString layerName = parts.value( QStringLiteral( "layerName" ) ).toString(); const QString layerId = parts.value( QStringLiteral( "layerId" ) ).toString(); const QString subset = parts.value( QStringLiteral( "subset" ) ).toString(); const QString geometryType = parts.value( QStringLiteral( "geometryType" ) ).toString(); const QStringList openOptions = parts.value( QStringLiteral( "openOptions" ) ).toStringList(); - QString uri = path + QString uri = vsiPrefix + path + vsiSuffix + ( !layerName.isEmpty() ? QStringLiteral( "|layername=%1" ).arg( layerName ) : !layerId.isEmpty() ? QStringLiteral( "|layerid=%1" ).arg( layerId ) : QString() ) + ( !geometryType.isEmpty() ? QStringLiteral( "|geometrytype=%1" ).arg( geometryType ) : QString() ); for ( const QString &openOption : openOptions ) diff --git a/tests/src/core/testqgsgdalprovider.cpp b/tests/src/core/testqgsgdalprovider.cpp index 856f08c95699..a0d392375931 100644 --- a/tests/src/core/testqgsgdalprovider.cpp +++ b/tests/src/core/testqgsgdalprovider.cpp @@ -105,8 +105,9 @@ void TestQgsGdalProvider::decodeUri() uri = QStringLiteral( "/vsizip//home/to/path/file.zip/my.tif" ); components = QgsProviderRegistry::instance()->decodeUri( QStringLiteral( "gdal" ), uri ); - QCOMPARE( components[QStringLiteral( "path" )].toString(), QStringLiteral( "/home/to/path/file.zip/my.tif" ) ); + QCOMPARE( components[QStringLiteral( "path" )].toString(), QStringLiteral( "/home/to/path/file.zip" ) ); QCOMPARE( components[QStringLiteral( "vsiPrefix" )].toString(), QStringLiteral( "/vsizip/" ) ); + QCOMPARE( components[QStringLiteral( "vsiSuffix" )].toString(), QStringLiteral( "/my.tif" ) ); //test windows path uri = QStringLiteral( "gpkg:c:/home/to/path/my_file.gpkg:layer_name" ); @@ -125,8 +126,9 @@ void TestQgsGdalProvider::encodeUri() QCOMPARE( QgsProviderRegistry::instance()->encodeUri( QStringLiteral( "gdal" ), parts ), QStringLiteral( "GPKG:/home/user/test.gpkg:layername" ) ); parts.clear(); - parts.insert( QStringLiteral( "path" ), QStringLiteral( "/home/user/test.zip/my.tif" ) ); + parts.insert( QStringLiteral( "path" ), QStringLiteral( "/home/user/test.zip" ) ); parts.insert( QStringLiteral( "vsiPrefix" ), QStringLiteral( "/vsizip/" ) ); + parts.insert( QStringLiteral( "vsiSuffix" ), QStringLiteral( "/my.tif" ) ); QCOMPARE( QgsProviderRegistry::instance()->encodeUri( QStringLiteral( "gdal" ), parts ), QStringLiteral( "/vsizip//home/user/test.zip/my.tif" ) ); } diff --git a/tests/src/python/test_provider_gdal.py b/tests/src/python/test_provider_gdal.py index 74ba81d62e4f..fb7b82ae9f15 100644 --- a/tests/src/python/test_provider_gdal.py +++ b/tests/src/python/test_provider_gdal.py @@ -111,6 +111,15 @@ def testDecodeEncodeUriOptions(self): encodedUri = QgsProviderRegistry.instance().encodeUri('gdal', parts) self.assertEqual(encodedUri, uri) + def testDecodeEncodeUriVsizip(self): + """Test decodeUri/encodeUri for /vsizip/ prefixed URIs""" + + uri = '/vsizip//my/file.zip/image.tif' + parts = QgsProviderRegistry.instance().decodeUri('gdal', uri) + self.assertEqual(parts, {'path': '/my/file.zip', 'layerName': None, 'vsiPrefix': '/vsizip/', 'vsiSuffix': '/image.tif'}) + encodedUri = QgsProviderRegistry.instance().encodeUri('gdal', parts) + self.assertEqual(encodedUri, uri) + if __name__ == '__main__': unittest.main() diff --git a/tests/src/python/test_provider_ogr.py b/tests/src/python/test_provider_ogr.py index 6d9c722a2e34..232ad51d509d 100644 --- a/tests/src/python/test_provider_ogr.py +++ b/tests/src/python/test_provider_ogr.py @@ -928,6 +928,33 @@ def testEmbeddedSymbolsKml(self): self.assertCountEqual([s.color().alpha() for s in symbols if s is not None], [127, 135, 255, 127]) self.assertEqual(len([s for s in symbols if s is None]), 2) + def testDecodeEncodeUriVsizip(self): + """Test decodeUri/encodeUri for /vsizip/ prefixed URIs""" + + uri = '/vsizip//my/file.zip/shapefile.shp' + parts = QgsProviderRegistry.instance().decodeUri('ogr', uri) + self.assertEqual(parts, {'path': '/my/file.zip', 'layerName': None, 'layerId': None, 'vsiPrefix': '/vsizip/', 'vsiSuffix': '/shapefile.shp'}) + encodedUri = QgsProviderRegistry.instance().encodeUri('ogr', parts) + self.assertEqual(encodedUri, uri) + + uri = '/my/file.zip' + parts = QgsProviderRegistry.instance().decodeUri('ogr', uri) + self.assertEqual(parts, {'path': '/my/file.zip', 'layerName': None, 'layerId': None}) + encodedUri = QgsProviderRegistry.instance().encodeUri('ogr', parts) + self.assertEqual(encodedUri, uri) + + uri = '/vsizip//my/file.zip|layername=shapefile' + parts = QgsProviderRegistry.instance().decodeUri('ogr', uri) + self.assertEqual(parts, {'path': '/my/file.zip', 'layerName': 'shapefile', 'layerId': None, 'vsiPrefix': '/vsizip/'}) + encodedUri = QgsProviderRegistry.instance().encodeUri('ogr', parts) + self.assertEqual(encodedUri, uri) + + uri = '/vsizip//my/file.zip|layername=shapefile|subset="field"=\'value\'' + parts = QgsProviderRegistry.instance().decodeUri('ogr', uri) + self.assertEqual(parts, {'path': '/my/file.zip', 'layerName': 'shapefile', 'layerId': None, 'subset': '"field"=\'value\'', 'vsiPrefix': '/vsizip/'}) + encodedUri = QgsProviderRegistry.instance().encodeUri('ogr', parts) + self.assertEqual(encodedUri, uri) + if __name__ == '__main__': unittest.main() From 366fa999b4a78280bb6892d3b8ff6525d7039d07 Mon Sep 17 00:00:00 2001 From: nirvn Date: Fri, 12 Mar 2021 10:20:47 +0700 Subject: [PATCH 090/377] Follow up a1e57a7 : fix handling of filtered layers --- src/core/providers/ogr/qgsogrprovider.cpp | 19 ++++++++-------- tests/src/core/testqgsogrprovider.cpp | 27 ++++++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/core/providers/ogr/qgsogrprovider.cpp b/src/core/providers/ogr/qgsogrprovider.cpp index 34d37bffd7c5..186fba5f65d4 100644 --- a/src/core/providers/ogr/qgsogrprovider.cpp +++ b/src/core/providers/ogr/qgsogrprovider.cpp @@ -1901,21 +1901,22 @@ bool QgsOgrProvider::addFeatures( QgsFeatureList &flist, Flags flags ) const bool inTransaction = startTransaction(); QgsFeatureId incrementalFeatureId = -1; - OGRGeometryH filter; if ( !( flags & QgsFeatureSink::FastInsert ) && ( mGDALDriverName == QLatin1String( "CSV" ) || mGDALDriverName == QLatin1String( "XLSX" ) || mGDALDriverName == QLatin1String( "ODS" ) ) ) { - filter = mOgrLayer->GetSpatialFilter(); - if ( filter ) + QMutex *mutex = nullptr; + OGRLayerH layer = mOgrOrigLayer->getHandleAndMutex( mutex ); { - filter = OGR_G_Clone( filter ); - mOgrLayer->SetSpatialFilter( nullptr ); - } + QMutexLocker locker( mutex ); - incrementalFeatureId = static_cast< QgsFeatureId >( mOgrLayer->GetFeatureCount() ) + 1; + if ( !mSubsetString.isEmpty() ) + OGR_L_SetAttributeFilter( layer, nullptr ); + + incrementalFeatureId = static_cast< QgsFeatureId >( OGR_L_GetFeatureCount( layer, false ) ) + 1; - if ( filter ) - mOgrLayer->SetSpatialFilter( filter ); + if ( !mSubsetString.isEmpty() ) + OGR_L_SetAttributeFilter( layer, textEncoding()->fromUnicode( mSubsetString ).constData() ); + } } bool returnvalue = true; diff --git a/tests/src/core/testqgsogrprovider.cpp b/tests/src/core/testqgsogrprovider.cpp index f2c8869df412..76523e583827 100644 --- a/tests/src/core/testqgsogrprovider.cpp +++ b/tests/src/core/testqgsogrprovider.cpp @@ -357,10 +357,10 @@ void TestQgsOgrProvider::testCsvFeatureAddition() { QString csvFilename = QDir::tempPath() + "/csvfeatureadditiontest.csv"; QFile csvFile( csvFilename ); - if ( csvFile.open( QIODevice::WriteOnly | QIODevice::Append ) ) + if ( csvFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) { QTextStream textStream( &csvFile ); - textStream << QLatin1String( "col1,col2\n1,2\n" ); + textStream << QLatin1String( "col1,col2,col3\n0,0,\"csv0\"\n" ); csvFile.close(); } @@ -368,18 +368,29 @@ void TestQgsOgrProvider::testCsvFeatureAddition() QVERIFY( csvLayer->isValid() ); QCOMPARE( csvLayer->featureCount(), 1 ); - - QgsFeature feature( csvLayer->fields() ); - feature.setAttribute( 0, 1 ); - feature.setAttribute( 1, 1 ); - feature.setAttribute( 2, QLatin1String( "csv" ) ); + QgsFeature f1( csvLayer->fields() ); + f1.setAttribute( 0, 1 ); + f1.setAttribute( 1, 1 ); + f1.setAttribute( 2, QLatin1String( "csv1" ) ); + QgsFeature f2( csvLayer->fields() ); + f2.setAttribute( 0, 2 ); + f2.setAttribute( 1, 2 ); + f2.setAttribute( 2, QLatin1String( "csv2" ) ); QgsFeatureList features; - features << feature << feature; + features << f1 << f2; csvLayer->dataProvider()->addFeatures( features ); QCOMPARE( features.at( 0 ).id(), 2 ); QCOMPARE( features.at( 1 ).id(), 3 ); + csvLayer->setSubsetString( QStringLiteral( "col1 = '2'" ) ); + QCOMPARE( csvLayer->featureCount(), 1 ); + + features.clear(); + features << f1; + csvLayer->dataProvider()->addFeatures( features ); + QCOMPARE( features.at( 0 ).id(), 4 ); + delete csvLayer; QFile::remove( csvFilename ); } From 12698e94ebbd2e1d3138811fbc119c7ba0ee02a9 Mon Sep 17 00:00:00 2001 From: Marco Bernasocchi Date: Tue, 16 Mar 2021 15:58:55 +0100 Subject: [PATCH 091/377] Allow loading GPKG layers with GEOMETRY type (#42253) --- python/plugins/db_manager/db_plugins/gpkg/plugin.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/python/plugins/db_manager/db_plugins/gpkg/plugin.py b/python/plugins/db_manager/db_plugins/gpkg/plugin.py index d96775d0d3b2..2c0ff61a0949 100644 --- a/python/plugins/db_manager/db_plugins/gpkg/plugin.py +++ b/python/plugins/db_manager/db_plugins/gpkg/plugin.py @@ -209,12 +209,21 @@ def mimeUri(self): # QGIS has no provider to load Geopackage vectors, let's use OGR return u"vector:ogr:%s:%s" % (self.name, self.ogrUri()) - def toMapLayer(self): + def toMapLayer(self, geometryType=None, crs=None): from qgis.core import QgsVectorLayer provider = "ogr" uri = self.ogrUri() + if geometryType: + geom_mapping = { + 'POINT': 'Point', + 'LINESTRING': 'LineString', + 'POLYGON': 'Polygon', + } + geometryType = geom_mapping[geometryType] + uri = "{}|geometrytype={}".format(uri, geometryType) + return QgsVectorLayer(uri, self.name, provider) def tableFieldsFactory(self, row, table): From 881256fd17edda9f14d0a03aa5a00de405d2dedb Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 16 Mar 2021 06:51:12 +1000 Subject: [PATCH 092/377] Restore attribute table column sizes in the Merge Attributes dialog Otherwise the columns all get set to a minimal default width, which quickly gets very frustrating if you're merging a lot of features and have to keep manually resizing columns to see cell content... --- src/app/qgsmergeattributesdialog.cpp | 26 ++++++++++++++++++++++++++ src/app/qgsmergeattributesdialog.h | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/src/app/qgsmergeattributesdialog.cpp b/src/app/qgsmergeattributesdialog.cpp index e9326c1f172b..8a547866fa7b 100644 --- a/src/app/qgsmergeattributesdialog.cpp +++ b/src/app/qgsmergeattributesdialog.cpp @@ -110,6 +110,8 @@ QgsMergeAttributesDialog::QgsMergeAttributesDialog( const QgsFeatureList &featur connect( mSkipAllButton, &QAbstractButton::clicked, this, &QgsMergeAttributesDialog::setAllToSkip ); connect( mTableWidget, &QTableWidget::cellChanged, this, &QgsMergeAttributesDialog::tableWidgetCellChanged ); + + setAttributeTableConfig( mVectorLayer->attributeTableConfig() ); } QgsMergeAttributesDialog::QgsMergeAttributesDialog() @@ -126,6 +128,29 @@ QgsMergeAttributesDialog::~QgsMergeAttributesDialog() delete mSelectionRubberBand; } +void QgsMergeAttributesDialog::setAttributeTableConfig( const QgsAttributeTableConfig &config ) +{ + const QVector< QgsAttributeTableConfig::ColumnConfig > columns = config.columns(); + for ( const QgsAttributeTableConfig::ColumnConfig &columnConfig : columns ) + { + if ( columnConfig.hidden ) + continue; + + const int col = mFieldToColumnMap.value( columnConfig.name, -1 ); + if ( col < 0 ) + continue; + + if ( columnConfig.width >= 0 ) + { + mTableWidget->setColumnWidth( col, columnConfig.width ); + } + else + { + mTableWidget->setColumnWidth( col, mTableWidget->horizontalHeader()->defaultSectionSize() ); + } + } +} + void QgsMergeAttributesDialog::createTableWidgetContents() { //get information about attributes from vector layer @@ -152,6 +177,7 @@ void QgsMergeAttributesDialog::createTableWidgetContents() } mTableWidget->setColumnCount( col + 1 ); + mFieldToColumnMap[ mFields.at( idx ).name() ] = col; QComboBox *cb = createMergeComboBox( mFields.at( idx ).type() ); if ( mFields.at( idx ).constraints().constraints() & QgsFieldConstraints::ConstraintUnique ) diff --git a/src/app/qgsmergeattributesdialog.h b/src/app/qgsmergeattributesdialog.h index e207f63ff8c8..4fce199b5499 100644 --- a/src/app/qgsmergeattributesdialog.h +++ b/src/app/qgsmergeattributesdialog.h @@ -29,6 +29,7 @@ class QgsMapCanvas; class QgsRubberBand; class QgsVectorLayer; class QComboBox; +class QgsAttributeTableConfig; //! A dialog to insert the merge behavior for attributes (e.g. for the union features editing tool) @@ -72,6 +73,8 @@ class APP_EXPORT QgsMergeAttributesDialog: public QDialog, private Ui::QgsMergeA private: QgsMergeAttributesDialog(); //default constructor forbidden void createTableWidgetContents(); + void setAttributeTableConfig( const QgsAttributeTableConfig &config ); + //! Create new combo box with the options for featureXX / mean / min / max QComboBox *createMergeComboBox( QVariant::Type columnType ) const; @@ -106,6 +109,7 @@ class APP_EXPORT QgsMergeAttributesDialog: public QDialog, private Ui::QgsMergeA QgsFields mFields; QSet mHiddenAttributes; + QMap< QString, int > mFieldToColumnMap; bool mUpdating = false; static const QList< QgsStatisticalSummary::Statistic > DISPLAY_STATS; From 3d7437e9aabaff3f1866c23c8d46e339c1f7c937 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 16 Mar 2021 06:31:55 +1000 Subject: [PATCH 093/377] When merging features, ensure that fields with "apply default value on update" are correctly evaluated and the default value used for the merged feature result --- src/app/qgisapp.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 2c4e36c98e6b..b86d88b09d88 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -10072,13 +10072,8 @@ void QgisApp::mergeSelectedFeatures() } } - vl->beginEditCommand( tr( "Merged features" ) ); - - //create new feature - QgsFeature newFeature; - newFeature.setGeometry( unionGeom ); - QgsAttributes attrs = d.mergedAttributes(); + QgsAttributeMap newAttributes; QString errorMessage; for ( int i = 0; i < attrs.count(); ++i ) { @@ -10095,9 +10090,13 @@ void QgisApp::mergeSelectedFeatures() tr( "Could not store value '%1' in field of type %2: %3" ).arg( attrs.at( i ).toString(), vl->fields().at( i ).typeName(), errorMessage ), Qgis::Warning ); } - attrs[i] = val; + newAttributes[ i ] = val; } - newFeature.setAttributes( attrs ); + + vl->beginEditCommand( tr( "Merged features" ) ); + + //create new feature + QgsFeature newFeature = QgsVectorLayerUtils::createFeature( vl, unionGeom, newAttributes ); QgsFeatureIds::const_iterator feature_it = featureIdsAfter.constBegin(); for ( ; feature_it != featureIdsAfter.constEnd(); ++feature_it ) From 6f0c47539ea7f366f429cc6e5374cc1dfe2e7860 Mon Sep 17 00:00:00 2001 From: Werner Macho Date: Tue, 16 Mar 2021 09:26:26 +0100 Subject: [PATCH 094/377] Update README.md Use the more common term of "any later version" instead of "above" for GPL license --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5d088222c69..00b0558ae6d6 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ Every month, there is a **Point Release** that provides bug-fixes to the LTR and ### Free and Open Source -QGIS is released under the GNU Public License (GPL) Version 2 or above. +QGIS is released under the GNU Public License (GPL) Version 2 or any later version. Developing QGIS under this license means that you can (if you want to) inspect and modify the source code and guarantees that you, our happy user will always have access to a GIS program that is free of cost and can be freely From 0ca61fd2052714f8fd3908f44231971585195386 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Tue, 16 Mar 2021 15:41:46 +0100 Subject: [PATCH 095/377] Fix wfs3 template with string fids Fixes #42275 --- src/server/qgsserverogcapihandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/qgsserverogcapihandler.cpp b/src/server/qgsserverogcapihandler.cpp index 4346a1686179..30b3f71775a0 100644 --- a/src/server/qgsserverogcapihandler.cpp +++ b/src/server/qgsserverogcapihandler.cpp @@ -313,7 +313,7 @@ void QgsServerOgcApiHandler::htmlDump( const json &data, const QgsServerApiConte { fName.chop( 1 ); } - fName += '/' + QString::number( args.at( 0 )->get( ) ); + fName += '/' + QString::fromStdString( args.at( 0 )->get( ) ); if ( !suffix.isEmpty() ) { fName += '.' + suffix; From 7913bd22171e1780839d4254bf1ba7c5d877369a Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Tue, 16 Mar 2021 17:08:20 +0100 Subject: [PATCH 096/377] Test for issue 42275 --- tests/src/python/test_qgsserver_api.py | 9 + ...ons_items_testlayer_\303\250\303\251.html" | 175 ++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 "tests/testdata/qgis_server/api/test_wfs3_collections_items_testlayer_\303\250\303\251.html" diff --git a/tests/src/python/test_qgsserver_api.py b/tests/src/python/test_qgsserver_api.py index 3adb2a5aae41..69fdc700f669 100644 --- a/tests/src/python/test_qgsserver_api.py +++ b/tests/src/python/test_qgsserver_api.py @@ -527,6 +527,15 @@ def test_wfs3_collection_items(self): self.compareApi(request, project, 'test_wfs3_collections_items_testlayer_èé.json') + def test_wfs3_collection_items_html(self): + """Test WFS3 API items""" + project = QgsProject() + project.read(unitTestDataPath('qgis_server') + '/test_project_api.qgs') + request = QgsBufferServerRequest( + 'http://server.qgis.org/wfs3/collections/testlayer%20èé/items.html') + self.compareApi(request, project, + 'test_wfs3_collections_items_testlayer_èé.html') + def test_wfs3_collection_items_crs(self): """Test WFS3 API items with CRS""" project = QgsProject() diff --git "a/tests/testdata/qgis_server/api/test_wfs3_collections_items_testlayer_\303\250\303\251.html" "b/tests/testdata/qgis_server/api/test_wfs3_collections_items_testlayer_\303\250\303\251.html" new file mode 100644 index 000000000000..9f99d1521003 --- /dev/null +++ "b/tests/testdata/qgis_server/api/test_wfs3_collections_items_testlayer_\303\250\303\251.html" @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Features in layer A test vector layer èé + + + +
+ + + +
+ +
+ +
+
+

Features in layer A test vector layer èé

+ + +

A test vector layer èé 0

+
+ +
id
+
1
+ +
name
+
one
+ +
utf8nameè
+
one èé
+ +
+ +

A test vector layer èé 1

+
+ +
id
+
2
+ +
name
+
two
+ +
utf8nameè
+
two àò
+ +
+ +

A test vector layer èé 2

+
+ +
id
+
3
+ +
name
+
three
+ +
utf8nameè
+
three èé↓
+ +
+ +
+ + +
+
+ + +
+ + +
+ + +
+ + + + + + + + + + + + + From dc665e2105f267e0d04cdd6308de0a455d568532 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 17 Mar 2021 11:04:43 +1000 Subject: [PATCH 097/377] [feature] Allow pen cap style to be set for simple marker symbol layers This is useful for the stroke-only symbols like the cross and arrowhead markers, where it's sometimes nice to have round caps instead of square caps. --- .../symbology/qgsmarkersymbollayer.sip.in | 34 +++++++++++++ src/core/symbology/qgsmarkersymbollayer.cpp | 18 +++++++ src/core/symbology/qgsmarkersymbollayer.h | 24 ++++++++++ src/gui/symbology/qgssymbollayerwidget.cpp | 11 +++++ src/gui/symbology/qgssymbollayerwidget.h | 1 + src/ui/symbollayer/widget_simplemarker.ui | 45 ++++++++++++++---- tests/src/core/testqgssimplemarker.cpp | 14 ++++++ .../expected_simplemarker_roundcap.png | Bin 0 -> 641520 bytes 8 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 tests/testdata/control_images/symbol_simplemarker/expected_simplemarker_roundcap/expected_simplemarker_roundcap.png diff --git a/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in b/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in index a00347839630..8e010355b0c4 100644 --- a/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in @@ -333,6 +333,8 @@ Returns the marker's stroke join style (e.g., miter, bevel, etc). .. seealso:: :py:func:`setPenJoinStyle` +.. seealso:: :py:func:`penCapStyle` + .. seealso:: :py:func:`strokeColor` .. seealso:: :py:func:`strokeStyle` @@ -348,11 +350,43 @@ Sets the marker's stroke join style (e.g., miter, bevel, etc). .. seealso:: :py:func:`penJoinStyle` +.. seealso:: :py:func:`setPenCapStyle` + .. seealso:: :py:func:`setStrokeColor` .. seealso:: :py:func:`setStrokeStyle` .. versionadded:: 2.16 +%End + + Qt::PenCapStyle penCapStyle() const; +%Docstring +Returns the marker's stroke cap style (e.g., flat, round, etc). + +.. seealso:: :py:func:`setPenCapStyle` + +.. seealso:: :py:func:`penJoinStyle` + +.. seealso:: :py:func:`strokeColor` + +.. seealso:: :py:func:`strokeStyle` + +.. versionadded:: 3.20 +%End + + void setPenCapStyle( Qt::PenCapStyle style ); +%Docstring +Sets the marker's stroke cap ``style`` (e.g., flat, round, etc). + +.. seealso:: :py:func:`penCapStyle` + +.. seealso:: :py:func:`penJoinStyle` + +.. seealso:: :py:func:`setStrokeColor` + +.. seealso:: :py:func:`setStrokeStyle` + +.. versionadded:: 3.20 %End double strokeWidth() const; diff --git a/src/core/symbology/qgsmarkersymbollayer.cpp b/src/core/symbology/qgsmarkersymbollayer.cpp index 572869e5a0c2..8670a52aa32d 100644 --- a/src/core/symbology/qgsmarkersymbollayer.cpp +++ b/src/core/symbology/qgsmarkersymbollayer.cpp @@ -894,6 +894,11 @@ QgsSymbolLayer *QgsSimpleMarkerSymbolLayer::create( const QVariantMap &props ) m->setVerticalAnchorPoint( QgsMarkerSymbolLayer::VerticalAnchorPoint( props[ QStringLiteral( "vertical_anchor_point" )].toInt() ) ); } + if ( props.contains( QStringLiteral( "cap_style" ) ) ) + { + m->setPenCapStyle( QgsSymbolLayerUtils::decodePenCapStyle( props[QStringLiteral( "cap_style" )].toString() ) ); + } + m->restoreOldDataDefinedProperties( props ); return m; @@ -918,6 +923,7 @@ void QgsSimpleMarkerSymbolLayer::startRender( QgsSymbolRenderContext &context ) mBrush = QBrush( brushColor ); mPen = QPen( penColor ); mPen.setStyle( mStrokeStyle ); + mPen.setCapStyle( mPenCapStyle ); mPen.setJoinStyle( mPenJoinStyle ); mPen.setWidthF( context.renderContext().convertToPainterUnits( mStrokeWidth, mStrokeWidthUnit, mStrokeWidthMapUnitScale ) ); @@ -1113,6 +1119,16 @@ void QgsSimpleMarkerSymbolLayer::draw( QgsSymbolRenderContext &context, QgsSimpl mSelPen.setJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( style ) ); } } + if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyCapStyle ) ) + { + context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePenCapStyle( mPenCapStyle ) ); + QString style = mDataDefinedProperties.valueAsString( QgsSymbolLayer::PropertyCapStyle, context.renderContext().expressionContext(), QString(), &ok ); + if ( ok ) + { + mPen.setCapStyle( QgsSymbolLayerUtils::decodePenCapStyle( style ) ); + mSelPen.setCapStyle( QgsSymbolLayerUtils::decodePenCapStyle( style ) ); + } + } if ( shapeIsFilled( shape ) ) { @@ -1183,6 +1199,7 @@ QVariantMap QgsSimpleMarkerSymbolLayer::properties() const map[QStringLiteral( "outline_width_unit" )] = QgsUnitTypes::encodeUnit( mStrokeWidthUnit ); map[QStringLiteral( "outline_width_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mStrokeWidthMapUnitScale ); map[QStringLiteral( "joinstyle" )] = QgsSymbolLayerUtils::encodePenJoinStyle( mPenJoinStyle ); + map[QStringLiteral( "cap_style" )] = QgsSymbolLayerUtils::encodePenCapStyle( mPenCapStyle ); map[QStringLiteral( "horizontal_anchor_point" )] = QString::number( mHorizontalAnchorPoint ); map[QStringLiteral( "vertical_anchor_point" )] = QString::number( mVerticalAnchorPoint ); return map; @@ -1202,6 +1219,7 @@ QgsSimpleMarkerSymbolLayer *QgsSimpleMarkerSymbolLayer::clone() const m->setStrokeWidthMapUnitScale( mStrokeWidthMapUnitScale ); m->setHorizontalAnchorPoint( mHorizontalAnchorPoint ); m->setVerticalAnchorPoint( mVerticalAnchorPoint ); + m->setPenCapStyle( mPenCapStyle ); copyDataDefinedProperties( m ); copyPaintEffect( m ); return m; diff --git a/src/core/symbology/qgsmarkersymbollayer.h b/src/core/symbology/qgsmarkersymbollayer.h index 901c76ac1428..d0643b8f5b91 100644 --- a/src/core/symbology/qgsmarkersymbollayer.h +++ b/src/core/symbology/qgsmarkersymbollayer.h @@ -299,6 +299,7 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayer : public QgsSimpleMarkerSymbolLayer /** * Returns the marker's stroke join style (e.g., miter, bevel, etc). * \see setPenJoinStyle() + * \see penCapStyle() * \see strokeColor() * \see strokeStyle() * \since QGIS 2.16 @@ -309,12 +310,33 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayer : public QgsSimpleMarkerSymbolLayer * Sets the marker's stroke join style (e.g., miter, bevel, etc). * \param style join style * \see penJoinStyle() + * \see setPenCapStyle() * \see setStrokeColor() * \see setStrokeStyle() * \since QGIS 2.16 */ void setPenJoinStyle( Qt::PenJoinStyle style ) { mPenJoinStyle = style; } + /** + * Returns the marker's stroke cap style (e.g., flat, round, etc). + * \see setPenCapStyle() + * \see penJoinStyle() + * \see strokeColor() + * \see strokeStyle() + * \since QGIS 3.20 + */ + Qt::PenCapStyle penCapStyle() const { return mPenCapStyle; } + + /** + * Sets the marker's stroke cap \a style (e.g., flat, round, etc). + * \see penCapStyle() + * \see penJoinStyle() + * \see setStrokeColor() + * \see setStrokeStyle() + * \since QGIS 3.20 + */ + void setPenCapStyle( Qt::PenCapStyle style ) { mPenCapStyle = style; } + /** * Returns the width of the marker's stroke. * \see setStrokeWidth() @@ -394,6 +416,8 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayer : public QgsSimpleMarkerSymbolLayer QgsMapUnitScale mStrokeWidthMapUnitScale; //! Stroke pen join style Qt::PenJoinStyle mPenJoinStyle; + //! Stroke pen cap style + Qt::PenCapStyle mPenCapStyle = Qt::SquareCap; //! QPen corresponding to marker's stroke style QPen mPen; //! QBrush corresponding to marker's fill style diff --git a/src/gui/symbology/qgssymbollayerwidget.cpp b/src/gui/symbology/qgssymbollayerwidget.cpp index 261495b2361e..8c2595bffab6 100644 --- a/src/gui/symbology/qgssymbollayerwidget.cpp +++ b/src/gui/symbology/qgssymbollayerwidget.cpp @@ -651,6 +651,7 @@ QgsSimpleMarkerSymbolLayerWidget::QgsSimpleMarkerSymbolLayerWidget( QgsVectorLay connect( btnChangeColorStroke, &QgsColorButton::colorChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setColorStroke ); connect( btnChangeColorFill, &QgsColorButton::colorChanged, this, &QgsSimpleMarkerSymbolLayerWidget::setColorFill ); connect( cboJoinStyle, static_cast( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged ); + connect( cboCapStyle, static_cast( &QComboBox::currentIndexChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::penCapStyleChanged ); connect( spinSize, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setSize ); connect( spinAngle, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setAngle ); connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleMarkerSymbolLayerWidget::setOffset ); @@ -698,6 +699,9 @@ void QgsSimpleMarkerSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer ) cboJoinStyle->blockSignals( true ); cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() ); cboJoinStyle->blockSignals( false ); + cboCapStyle->blockSignals( true ); + cboCapStyle->setPenCapStyle( mLayer->penCapStyle() ); + cboCapStyle->blockSignals( false ); // without blocking signals the value gets changed because of slot setOffset() spinOffsetX->blockSignals( true ); @@ -734,6 +738,7 @@ void QgsSimpleMarkerSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer ) registerDataDefinedButton( mStrokeWidthDDBtn, QgsSymbolLayer::PropertyStrokeWidth ); registerDataDefinedButton( mStrokeStyleDDBtn, QgsSymbolLayer::PropertyStrokeStyle ); registerDataDefinedButton( mJoinStyleDDBtn, QgsSymbolLayer::PropertyJoinStyle ); + registerDataDefinedButton( mCapStyleDDBtn, QgsSymbolLayer::PropertyCapStyle ); registerDataDefinedButton( mSizeDDBtn, QgsSymbolLayer::PropertySize ); registerDataDefinedButton( mAngleDDBtn, QgsSymbolLayer::PropertyAngle ); registerDataDefinedButton( mOffsetDDBtn, QgsSymbolLayer::PropertyOffset ); @@ -773,6 +778,12 @@ void QgsSimpleMarkerSymbolLayerWidget::penJoinStyleChanged() emit changed(); } +void QgsSimpleMarkerSymbolLayerWidget::penCapStyleChanged() +{ + mLayer->setPenCapStyle( cboCapStyle->penCapStyle() ); + emit changed(); +} + void QgsSimpleMarkerSymbolLayerWidget::setSize() { mLayer->setSize( spinSize->value() ); diff --git a/src/gui/symbology/qgssymbollayerwidget.h b/src/gui/symbology/qgssymbollayerwidget.h index b45cc8e4c351..8ef5cd54cb44 100644 --- a/src/gui/symbology/qgssymbollayerwidget.h +++ b/src/gui/symbology/qgssymbollayerwidget.h @@ -233,6 +233,7 @@ class GUI_EXPORT QgsSimpleMarkerSymbolLayerWidget : public QgsSymbolLayerWidget, void setShape(); void updateAssistantSymbol(); void penJoinStyleChanged(); + void penCapStyleChanged(); private: diff --git a/src/ui/symbollayer/widget_simplemarker.ui b/src/ui/symbollayer/widget_simplemarker.ui index 76b452d6559c..de01ecc678b4 100644 --- a/src/ui/symbollayer/widget_simplemarker.ui +++ b/src/ui/symbollayer/widget_simplemarker.ui @@ -503,31 +503,51 @@
+ + + + Cap style + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + +
- QgsColorButton - QToolButton -
qgscolorbutton.h
- 1 + QgsDoubleSpinBox + QDoubleSpinBox +
qgsdoublespinbox.h
QgsPropertyOverrideButton QToolButton
qgspropertyoverridebutton.h
- - QgsDoubleSpinBox - QDoubleSpinBox -
qgsdoublespinbox.h
-
QgsUnitSelectionWidget QWidget
qgsunitselectionwidget.h
1
+ + QgsColorButton + QToolButton +
qgscolorbutton.h
+ 1 +
QgsPenJoinStyleComboBox QComboBox @@ -538,6 +558,11 @@ QComboBox
qgspenstylecombobox.h
+ + QgsPenCapStyleComboBox + QComboBox +
qgspenstylecombobox.h
+
spinSize @@ -554,6 +579,8 @@ mStrokeWidthDDBtn cboJoinStyle mJoinStyleDDBtn + cboCapStyle + mCapStyleDDBtn spinAngle mAngleDDBtn spinOffsetX diff --git a/tests/src/core/testqgssimplemarker.cpp b/tests/src/core/testqgssimplemarker.cpp index 171d07ddcca6..54bfb7d56517 100644 --- a/tests/src/core/testqgssimplemarker.cpp +++ b/tests/src/core/testqgssimplemarker.cpp @@ -78,6 +78,7 @@ class TestQgsSimpleMarkerSymbol : public QObject void simpleMarkerSymbolBevelJoin(); void simpleMarkerSymbolMiterJoin(); void simpleMarkerSymbolRoundJoin(); + void simpleMarkerSymbolCapStyle(); void simpleMarkerOctagon(); void simpleMarkerSquareWithCorners(); void simpleMarkerAsterisk(); @@ -308,6 +309,19 @@ void TestQgsSimpleMarkerSymbol::simpleMarkerSymbolRoundJoin() QVERIFY( imageCheck( "simplemarker_roundjoin" ) ); } +void TestQgsSimpleMarkerSymbol::simpleMarkerSymbolCapStyle() +{ + mReport += QLatin1String( "

Cap style

\n" ); + + mSimpleMarkerLayer->setColor( Qt::blue ); + mSimpleMarkerLayer->setStrokeColor( Qt::black ); + mSimpleMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::ArrowHead ); + mSimpleMarkerLayer->setSize( 25 ); + mSimpleMarkerLayer->setStrokeWidth( 3 ); + mSimpleMarkerLayer->setPenCapStyle( Qt::RoundCap ); + QVERIFY( imageCheck( "simplemarker_roundcap" ) ); +} + void TestQgsSimpleMarkerSymbol::simpleMarkerOctagon() { mReport += QLatin1String( "

Simple marker octagon

\n" ); diff --git a/tests/testdata/control_images/symbol_simplemarker/expected_simplemarker_roundcap/expected_simplemarker_roundcap.png b/tests/testdata/control_images/symbol_simplemarker/expected_simplemarker_roundcap/expected_simplemarker_roundcap.png new file mode 100644 index 0000000000000000000000000000000000000000..372adc6e3b41a2c5d9ea18c0e2a0e9b6f10e8ad9 GIT binary patch literal 641520 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 Y|K!kRXa8X!72frwamOz>ZqkhZ4_vtQ4gdfE literal 0 HcmV?d00001 From acc59e2d1f3e04f262fe7a4d13e9daafc8e27626 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 17 Mar 2021 12:22:12 +1000 Subject: [PATCH 098/377] Update test --- tests/src/python/test_qgsmapboxglconverter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/src/python/test_qgsmapboxglconverter.py b/tests/src/python/test_qgsmapboxglconverter.py index 2b452ac1a595..0516966f6b62 100644 --- a/tests/src/python/test_qgsmapboxglconverter.py +++ b/tests/src/python/test_qgsmapboxglconverter.py @@ -570,6 +570,7 @@ def testCircleLayer(self): properties = rendererStyle.symbol().symbolLayers()[0].properties() expected_properties = { 'angle': '0', + 'cap_style': 'square', 'color': '22,22,22,153', 'horizontal_anchor_point': '1', 'joinstyle': 'bevel', From c1065e8219b56fd0ba4226ea0c579acaf3ec5acf Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Wed, 17 Mar 2021 15:22:49 +0700 Subject: [PATCH 099/377] [feature][symbology] Allow pen cap style to be set for ellipse marker symbol layers (#42289) --- .../symbology/qgsellipsesymbollayer.sip.in | 30 ++++++++++ src/core/symbology/qgsellipsesymbollayer.cpp | 56 ++++++++++++++---- src/core/symbology/qgsellipsesymbollayer.h | 21 +++++++ .../symbology/qgsellipsesymbollayerwidget.cpp | 10 ++++ .../symbology/qgsellipsesymbollayerwidget.h | 1 + src/ui/symbollayer/widget_ellipse.ui | 27 +++++++++ tests/src/core/testqgsellipsemarker.cpp | 21 ++++++- .../expected_ellipsemarker_roundcap.png | Bin 0 -> 641520 bytes 8 files changed, 150 insertions(+), 16 deletions(-) create mode 100644 tests/testdata/control_images/symbol_ellipsemarker/expected_ellipsemarker_roundcap/expected_ellipsemarker_roundcap.png diff --git a/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in b/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in index 42c512acc540..bf5b79062865 100644 --- a/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in @@ -75,6 +75,36 @@ Gets stroke join style. Set stroke join style. .. versionadded:: 2.16 +%End + + Qt::PenCapStyle penCapStyle() const; +%Docstring +Returns the marker's stroke cap style (e.g., flat, round, etc). + +.. seealso:: :py:func:`setPenCapStyle` + +.. seealso:: :py:func:`penJoinStyle` + +.. seealso:: :py:func:`strokeColor` + +.. seealso:: :py:func:`strokeStyle` + +.. versionadded:: 3.20 +%End + + void setPenCapStyle( Qt::PenCapStyle style ); +%Docstring +Sets the marker's stroke cap ``style`` (e.g., flat, round, etc). + +.. seealso:: :py:func:`penCapStyle` + +.. seealso:: :py:func:`penJoinStyle` + +.. seealso:: :py:func:`setStrokeColor` + +.. seealso:: :py:func:`setStrokeStyle` + +.. versionadded:: 3.20 %End void setStrokeWidth( double w ); diff --git a/src/core/symbology/qgsellipsesymbollayer.cpp b/src/core/symbology/qgsellipsesymbollayer.cpp index d13183727e19..357f87054e80 100644 --- a/src/core/symbology/qgsellipsesymbollayer.cpp +++ b/src/core/symbology/qgsellipsesymbollayer.cpp @@ -102,6 +102,10 @@ QgsSymbolLayer *QgsEllipseSymbolLayer::create( const QVariantMap &properties ) { layer->setPenJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( properties[QStringLiteral( "joinstyle" )].toString() ) ); } + if ( properties.contains( QStringLiteral( "cap_style" ) ) ) + { + layer->setPenCapStyle( QgsSymbolLayerUtils::decodePenCapStyle( properties[QStringLiteral( "cap_style" )].toString() ) ); + } if ( properties.contains( QStringLiteral( "outline_width" ) ) ) { layer->setStrokeWidth( properties[QStringLiteral( "outline_width" )].toDouble() ); @@ -179,9 +183,9 @@ void QgsEllipseSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContext & penColor.setAlphaF( penColor.alphaF() * context.opacity() ); mPen.setColor( penColor ); - if ( mDataDefinedProperties.hasActiveProperties() ) + bool ok; + if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyStrokeWidth ) ) { - bool ok; context.setOriginalValueVariable( mStrokeWidth ); QVariant exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyStrokeWidth, context.renderContext().expressionContext() ); if ( exprVal.isValid() ) @@ -194,44 +198,67 @@ void QgsEllipseSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContext & mSelPen.setWidthF( width ); } } + } + if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyStrokeStyle ) ) + { context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePenStyle( mStrokeStyle ) ); - exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyStrokeStyle, context.renderContext().expressionContext() ); + QVariant exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyStrokeStyle, context.renderContext().expressionContext() ); if ( exprVal.isValid() ) { mPen.setStyle( QgsSymbolLayerUtils::decodePenStyle( exprVal.toString() ) ); mSelPen.setStyle( mPen.style() ); } + } + if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyJoinStyle ) ) + { context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePenJoinStyle( mPenJoinStyle ) ); - exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyJoinStyle, context.renderContext().expressionContext() ); + QVariant exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyJoinStyle, context.renderContext().expressionContext() ); if ( exprVal.isValid() ) { mPen.setJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( exprVal.toString() ) ); mSelPen.setJoinStyle( mPen.joinStyle() ); } + } + + if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyCapStyle ) ) + { + context.setOriginalValueVariable( QgsSymbolLayerUtils::encodePenCapStyle( mPenCapStyle ) ); + QString style = mDataDefinedProperties.valueAsString( QgsSymbolLayer::PropertyCapStyle, context.renderContext().expressionContext(), QString(), &ok ); + if ( ok ) + { + mPen.setCapStyle( QgsSymbolLayerUtils::decodePenCapStyle( style ) ); + mSelPen.setCapStyle( QgsSymbolLayerUtils::decodePenCapStyle( style ) ); + } + } + if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyFillColor ) ) + { context.setOriginalValueVariable( QgsSymbolLayerUtils::encodeColor( mColor ) ); QColor brushColor = mDataDefinedProperties.valueAsColor( QgsSymbolLayer::PropertyFillColor, context.renderContext().expressionContext(), mColor ); brushColor.setAlphaF( brushColor.alphaF() * context.opacity() ); mBrush.setColor( brushColor ); + } + if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyStrokeColor ) ) + { context.setOriginalValueVariable( QgsSymbolLayerUtils::encodeColor( mStrokeColor ) ); QColor penColor = mDataDefinedProperties.valueAsColor( QgsSymbolLayer::PropertyStrokeColor, context.renderContext().expressionContext(), mStrokeColor ); penColor.setAlphaF( penColor.alphaF() * context.opacity() ); mPen.setColor( penColor ); + } - if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyWidth ) || mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyHeight ) || mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyName ) ) + if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyWidth ) || mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyHeight ) || mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyName ) ) + { + QString symbolName = mSymbolName; + context.setOriginalValueVariable( mSymbolName ); + QVariant exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyName, context.renderContext().expressionContext() ); + if ( exprVal.isValid() ) { - QString symbolName = mSymbolName; - context.setOriginalValueVariable( mSymbolName ); - exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyName, context.renderContext().expressionContext() ); - if ( exprVal.isValid() ) - { - symbolName = exprVal.toString(); - } - preparePath( symbolName, context, &scaledWidth, &scaledHeight, context.feature() ); + symbolName = exprVal.toString(); } + preparePath( symbolName, context, &scaledWidth, &scaledHeight, context.feature() ); } //offset and rotation @@ -321,6 +348,7 @@ void QgsEllipseSymbolLayer::startRender( QgsSymbolRenderContext &context ) mPen.setColor( mStrokeColor ); mPen.setStyle( mStrokeStyle ); mPen.setJoinStyle( mPenJoinStyle ); + mPen.setCapStyle( mPenCapStyle ); mPen.setWidthF( context.renderContext().convertToPainterUnits( mStrokeWidth, mStrokeWidthUnit, mStrokeWidthMapUnitScale ) ); mBrush.setColor( mColor ); @@ -353,6 +381,7 @@ QgsEllipseSymbolLayer *QgsEllipseSymbolLayer::clone() const m->setOffsetMapUnitScale( mOffsetMapUnitScale ); m->setStrokeStyle( mStrokeStyle ); m->setPenJoinStyle( mPenJoinStyle ); + m->setPenCapStyle( mPenCapStyle ); m->setStrokeWidth( mStrokeWidth ); m->setColor( color() ); m->setStrokeColor( mStrokeColor ); @@ -513,6 +542,7 @@ QVariantMap QgsEllipseSymbolLayer::properties() const map[QStringLiteral( "outline_width_unit" )] = QgsUnitTypes::encodeUnit( mStrokeWidthUnit ); map[QStringLiteral( "outline_width_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mStrokeWidthMapUnitScale ); map[QStringLiteral( "joinstyle" )] = QgsSymbolLayerUtils::encodePenJoinStyle( mPenJoinStyle ); + map[QStringLiteral( "cap_style" )] = QgsSymbolLayerUtils::encodePenCapStyle( mPenCapStyle ); map[QStringLiteral( "color" )] = QgsSymbolLayerUtils::encodeColor( mColor ); map[QStringLiteral( "outline_color" )] = QgsSymbolLayerUtils::encodeColor( mStrokeColor ); map[QStringLiteral( "offset" )] = QgsSymbolLayerUtils::encodePoint( mOffset ); diff --git a/src/core/symbology/qgsellipsesymbollayer.h b/src/core/symbology/qgsellipsesymbollayer.h index 0de6a3d23dde..da4ce933eea1 100644 --- a/src/core/symbology/qgsellipsesymbollayer.h +++ b/src/core/symbology/qgsellipsesymbollayer.h @@ -75,6 +75,26 @@ class CORE_EXPORT QgsEllipseSymbolLayer: public QgsMarkerSymbolLayer */ void setPenJoinStyle( Qt::PenJoinStyle style ) { mPenJoinStyle = style; } + /** + * Returns the marker's stroke cap style (e.g., flat, round, etc). + * \see setPenCapStyle() + * \see penJoinStyle() + * \see strokeColor() + * \see strokeStyle() + * \since QGIS 3.20 + */ + Qt::PenCapStyle penCapStyle() const { return mPenCapStyle; } + + /** + * Sets the marker's stroke cap \a style (e.g., flat, round, etc). + * \see penCapStyle() + * \see penJoinStyle() + * \see setStrokeColor() + * \see setStrokeStyle() + * \since QGIS 3.20 + */ + void setPenCapStyle( Qt::PenCapStyle style ) { mPenCapStyle = style; } + void setStrokeWidth( double w ) { mStrokeWidth = w; } double strokeWidth() const { return mStrokeWidth; } @@ -156,6 +176,7 @@ class CORE_EXPORT QgsEllipseSymbolLayer: public QgsMarkerSymbolLayer QColor mStrokeColor; Qt::PenStyle mStrokeStyle = Qt::SolidLine; Qt::PenJoinStyle mPenJoinStyle = DEFAULT_ELLIPSE_JOINSTYLE; + Qt::PenCapStyle mPenCapStyle = Qt::SquareCap; double mStrokeWidth = 0; QgsUnitTypes::RenderUnit mStrokeWidthUnit = QgsUnitTypes::RenderMillimeters; QgsMapUnitScale mStrokeWidthMapUnitScale; diff --git a/src/gui/symbology/qgsellipsesymbollayerwidget.cpp b/src/gui/symbology/qgsellipsesymbollayerwidget.cpp index eaceb846ab74..9a549854c45a 100644 --- a/src/gui/symbology/qgsellipsesymbollayerwidget.cpp +++ b/src/gui/symbology/qgsellipsesymbollayerwidget.cpp @@ -97,6 +97,7 @@ QgsEllipseSymbolLayerWidget::QgsEllipseSymbolLayerWidget( QgsVectorLayer *vl, QW connect( spinOffsetX, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsEllipseSymbolLayerWidget::setOffset ); connect( spinOffsetY, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsEllipseSymbolLayerWidget::setOffset ); connect( cboJoinStyle, static_cast( &QComboBox::currentIndexChanged ), this, &QgsEllipseSymbolLayerWidget::penJoinStyleChanged ); + connect( cboCapStyle, static_cast( &QComboBox::currentIndexChanged ), this, &QgsEllipseSymbolLayerWidget::penCapStyleChanged ); } void QgsEllipseSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer ) @@ -137,6 +138,7 @@ void QgsEllipseSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer ) mHorizontalAnchorComboBox->setCurrentIndex( mLayer->horizontalAnchorPoint() ); mVerticalAnchorComboBox->setCurrentIndex( mLayer->verticalAnchorPoint() ); cboJoinStyle->setPenJoinStyle( mLayer->penJoinStyle() ); + cboCapStyle->setPenCapStyle( mLayer->penCapStyle() ); blockComboSignals( false ); registerDataDefinedButton( mSymbolWidthDDBtn, QgsSymbolLayer::PropertyWidth ); @@ -147,6 +149,7 @@ void QgsEllipseSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer ) registerDataDefinedButton( mStrokeColorDDBtn, QgsSymbolLayer::PropertyStrokeColor ); registerDataDefinedButton( mStrokeStyleDDBtn, QgsSymbolLayer::PropertyStrokeStyle ); registerDataDefinedButton( mJoinStyleDDBtn, QgsSymbolLayer::PropertyJoinStyle ); + registerDataDefinedButton( mCapStyleDDBtn, QgsSymbolLayer::PropertyCapStyle ); registerDataDefinedButton( mShapeDDBtn, QgsSymbolLayer::PropertyName ); registerDataDefinedButton( mOffsetDDBtn, QgsSymbolLayer::PropertyOffset ); registerDataDefinedButton( mHorizontalAnchorDDBtn, QgsSymbolLayer::PropertyHorizontalAnchor ); @@ -287,6 +290,12 @@ void QgsEllipseSymbolLayerWidget::penJoinStyleChanged() emit changed(); } +void QgsEllipseSymbolLayerWidget::penCapStyleChanged() +{ + mLayer->setPenCapStyle( cboCapStyle->penCapStyle() ); + emit changed(); +} + void QgsEllipseSymbolLayerWidget::blockComboSignals( bool block ) { mSymbolWidthUnitWidget->blockSignals( block ); @@ -299,6 +308,7 @@ void QgsEllipseSymbolLayerWidget::blockComboSignals( bool block ) mSymbolHeightUnitWidget->blockSignals( block ); mOffsetUnitWidget->blockSignals( block ); cboJoinStyle->blockSignals( block ); + cboCapStyle->blockSignals( block ); } void QgsEllipseSymbolLayerWidget::mHorizontalAnchorComboBox_currentIndexChanged( int index ) diff --git a/src/gui/symbology/qgsellipsesymbollayerwidget.h b/src/gui/symbology/qgsellipsesymbollayerwidget.h index b9d11e023163..86952cd169e3 100644 --- a/src/gui/symbology/qgsellipsesymbollayerwidget.h +++ b/src/gui/symbology/qgsellipsesymbollayerwidget.h @@ -73,6 +73,7 @@ class GUI_EXPORT QgsEllipseSymbolLayerWidget: public QgsSymbolLayerWidget, priva void mVerticalAnchorComboBox_currentIndexChanged( int index ); void penJoinStyleChanged(); + void penCapStyleChanged(); void setOffset(); }; diff --git a/src/ui/symbollayer/widget_ellipse.ui b/src/ui/symbollayer/widget_ellipse.ui index 7e810151b9e6..69ecec9b0eab 100644 --- a/src/ui/symbollayer/widget_ellipse.ui +++ b/src/ui/symbollayer/widget_ellipse.ui @@ -219,6 +219,26 @@
+ + + + Cap style + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + + @@ -591,6 +611,11 @@ QComboBox
qgspenstylecombobox.h
+ + QgsPenCapStyleComboBox + QComboBox +
qgspenstylecombobox.h
+
QgsPenStyleComboBox QComboBox @@ -614,6 +639,8 @@ mStrokeWidthDDBtn cboJoinStyle mJoinStyleDDBtn + cboCapStyle + mCapStyleDDBtn mRotationSpinBox mRotationDDBtn spinOffsetX diff --git a/tests/src/core/testqgsellipsemarker.cpp b/tests/src/core/testqgsellipsemarker.cpp index c863689ebd6a..911bdd485b63 100644 --- a/tests/src/core/testqgsellipsemarker.cpp +++ b/tests/src/core/testqgsellipsemarker.cpp @@ -58,6 +58,7 @@ class TestQgsEllipseMarkerSymbol : public QObject void ellipseMarkerSymbolBevelJoin(); void ellipseMarkerSymbolMiterJoin(); void ellipseMarkerSymbolRoundJoin(); + void ellipseMarkerSymbolCapStyle(); void selected(); void bounds(); void opacityWithDataDefinedColor(); @@ -158,7 +159,7 @@ void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolSize() void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolBevelJoin() { - mReport += QLatin1String( "

Ellipse marker symbol layer test

\n" ); + mReport += QLatin1String( "

Ellipse marker bevel join style

\n" ); mEllipseMarkerLayer->setFillColor( Qt::blue ); mEllipseMarkerLayer->setStrokeColor( Qt::black ); @@ -172,7 +173,7 @@ void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolBevelJoin() void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolMiterJoin() { - mReport += QLatin1String( "

Ellipse marker symbol layer test

\n" ); + mReport += QLatin1String( "

Ellipse marker miter join style

\n" ); mEllipseMarkerLayer->setFillColor( Qt::blue ); mEllipseMarkerLayer->setStrokeColor( Qt::black ); @@ -186,7 +187,7 @@ void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolMiterJoin() void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolRoundJoin() { - mReport += QLatin1String( "

Ellipse marker symbol layer test

\n" ); + mReport += QLatin1String( "

Ellipse marker round join style

\n" ); mEllipseMarkerLayer->setFillColor( Qt::blue ); mEllipseMarkerLayer->setStrokeColor( Qt::black ); @@ -198,6 +199,20 @@ void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolRoundJoin() QVERIFY( imageCheck( "ellipsemarker_roundjoin" ) ); } +void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolCapStyle() +{ + mReport += QLatin1String( "

Ellipse marker round cap style

\n" ); + + mEllipseMarkerLayer->setColor( Qt::blue ); + mEllipseMarkerLayer->setStrokeColor( Qt::black ); + mEllipseMarkerLayer->setSymbolName( QStringLiteral( "cross" ) ); + mEllipseMarkerLayer->setSymbolWidth( 35 ); + mEllipseMarkerLayer->setSymbolHeight( 15 ); + mEllipseMarkerLayer->setStrokeWidth( 3 ); + mEllipseMarkerLayer->setPenCapStyle( Qt::RoundCap ); + QVERIFY( imageCheck( "ellipsemarker_roundcap" ) ); +} + void TestQgsEllipseMarkerSymbol::selected() { mEllipseMarkerLayer->setFillColor( Qt::blue ); diff --git a/tests/testdata/control_images/symbol_ellipsemarker/expected_ellipsemarker_roundcap/expected_ellipsemarker_roundcap.png b/tests/testdata/control_images/symbol_ellipsemarker/expected_ellipsemarker_roundcap/expected_ellipsemarker_roundcap.png new file mode 100644 index 0000000000000000000000000000000000000000..31c4f5551f4439e685e9eb284c82ff5df05954e5 GIT binary patch literal 641520 zcmeI52YeJ&*N0C?sG;{JRjO1)MFbTD6hw*=#NN?Yu@^)`5iBT*<+UId5LA$22N9)+ z0;2SeH0ix3AtCLXo9`u(x-+{oJMFpr^2_ebnRCy1&XE7^%$<8*>Dm3N62+<(6Oj^K zuI_l9NW`1!r$`}f%h0(OEzy1zee~)ZpAaeeyZVWE_q>wTL~2Qwj_rFt6Cp9fC&xyN z-jtNC8PXsC0SG_<0)_|_Fl3D}1Rwwb2teR}1P~BT1qeU@0uTs_00I&eHV%RS1Rwwb z1cY+{0uX=z1cD;qMgh6B&wJX)f&U*15LD6}1OW&@00QO`aHE)*O8{>WfB*y_5EKCf zBq(eg1OW&@00IaI=KusC009UDMF0T_3L6JO00Izz00I)$bD-q%7CRXW5LV=L1_20! zg#cm_7R+=40SG|Adjt>=@70uyAOHafgoOYC5*EyK0s#m>zL1RwwbYX~49)^Nou z1Rwwb&l5mEJYQlGga8B}U=0BT#2T)6br6Bozb!1zSO5nVgiyRmAZGaFSQN#ZwIwSE zKmY=k6F@*LM@$D0fB*!%NdN)yW?jh&0uX?J6CV|uR3QKX2$)F#0Wp&%z90Yr2>6Hq0^*}$lPUxt00A=zARuPa z#1{l000AEni1JacqzVBDSVSN_JzaKhTrIoSuaflM->qzNW-NfVy?Vo@QoT`giHL}> zsCV2tfdFFSgenjN1YAtu;Et^_{+WKV>960iWKpMOYq@R27^z&RL6+^j@eYBA(VLRe zy^{`^KmY>aB(QV+N*Q^>6>|DiLayCL6)G%`e>O{$n9#gOfcqidt0@^lAS?t@l26OH zr|-^FJX8=Vr<3H<0ryC9;;FF2L?_`TfPjRTH@!i?GX$3Z^tJ5XusUEq`?qb9#otW~ zXorFO2p}Nts~HhPz!3ztEYlvL*V(o%U#!#8Ub7ApIxjmj7Qo&}+}Ar|;=Y;@F$5ez zAnwQ^-EqVpJFMFlL-!CsK-^O+B8311AmAth2#BM~K`;=200i7a00D7Nt%wu?5P*QA z2p}MiDhI(p00IyQiooYjUeVmvu>gokP<7)V2tWV=5RjPRlVed4P6P-*00IyQiU0x< z6gCcm00bZa0R)6|00Izz00e>}fPe&rje{Tn0SG`KWC7WA{mr-7Iu?K$LI45~fPn1; zLKYL-Gavv6KmY;|u!R5uVheUUg#ZK~;C=!Ki2G|u1`vP%1Z*LIfY^eaP9XpR2)Lhs zp9N(5TXV)S7Qp@IFd0Aq0uCVHXEAXAenNl%1R&sE0tkqEYe(b|fB*z+C4hj~il5FQ z009WNmjD9d-r5m41RwwbTL~Z_w&D-A^TbBi_G2tSu=F?%0uV5t0AgZ3Q#?Wd0ub;8 zfhb>ONs9GR9X%{Y>~%YKuwlU>MWt}jXa`3adT0@& zHzlQq?gkGK@E?JcmOj);dKoK2w0xsBw355AHLHR?D!P=nEN55yoa%tIvb z=wBn(duS{`dRm%{8*n#565?s$r^EMdUN4_KafhU(rg|!E#KcqOB$;p!_-p!P*|=z4 zIJ%+_4-we5VzDfkGS)*GX{p2vpB#&dc&nyl69xh+fB8NPz0idh39Op^gQwC$Ks;4W zk_iU^bwh*(fnW$6JFqvH!yJ1I0^-=x5SUX56faxesi6^EKTyWF0br2CdtN?88Y85ECa=gIHWapk1H4q;j1Gu85T&okO5p zwVKlYwg;ROkO`3>ASOV>g}(@>$B*wA`H2)O<*iE-{;Fblvn>)`LhgL+6H&jt)DRFa zRg+x8Mxa)+Rx;$r71E+}4~d9~2wT5&p2j##&o8)v-Vt!_x+xO8Uw@Cc4!@BZP6Gq)Xda5p4uNW09R9Gt3swXAOSM*9s zIr3np#T-c300CnJN|dW0>c^RFU&XrGR4lcmOUL%Tt&6bHr5$9+^eMVJXsFpXVjzMp zR&Fxla+aH_MXV5j00bOF00D7OF$e_$5P*Q22p}MCsur9@xAOHdH5_pG5Va=h$s-3PDIw0g6(chUKmY;`A>fH8)Dz=Q$hU6{k;UJ9Aqgjr zWuUFrpow&QC{|it)ypBM2?GKU@C$*z{} zfPhHM@X4{RR*|_A-j_X_)&;EPH?PI&o?bMdGYlXA0SG`KgMh0AWaTg4>ndZiHXrwf zg>!Y;VgvyQKmY>z2)J56j_u#AFH6np$ex|LZ83xZ1R&r)0*9M592)#s09T7iT3V{^ zdZ(tQ=(fcW0uX=z1OgLqwSWXp4+{uD00I!OiU0y)64gDj1G1Jm1GTjhpMvv3kR1x@|FZ4*|Y`xTjV`s)K-HpDpQmSH= z9L6QeRgnANnZyqZ%a+lZ>!fQcKQh2Q00>G{NPDO9xB*}Hu6`q+WJ^6tGoCE>)e zTyx&Jer3k~LDQE?k?0b++OW|%1Q?y=oLUfx2M8p_osf|?T%JQb&ZIWy(|2UdLw$Wa zym->khw~JVGmO-|D)lT6&G`fn5a-v32wg;A+A9MCu9msx*PrB%uP3-DD|13s-#S)m zBjNP4#otcUJ-SYhKWr=_5HoyoEGl9VT-^GPfcgruP`jwFr~UHDTYAhqWpi-*7TwB_ zaQvvmA3x%${JoeA0^-H0l9Me2_H0@wsVT|2`rh;RS}`(=OqWxK8>u;HjI`t=X2>+c z%MM!v#188884`g$@h!(VeJsGKlP7fNsD^MQ#>eTl#}EQeB!HMWu`0v_0SG|A1q7l- z_HFNiFmn&_$nG7v@5p8AH?PIY>bWy=+2h?!MN5>F8jV{@TW!AcvejyMH&HT!00e9y z5Vd9LLR&hvqfFfKm{cJE0V@e0AXd_KpzpofGYm8cKmY<}5I{i8py(nWk%gF3 z+ePIfR0uel00QFZ@|Yi7&GXJT-zgp;00CbTKtOy{_6jxXNV6-u`6y#jHIG1ivOLaM z0P}cy&l6(ey_)8lk$NuVwh?1|yI@7GP}m3o2!uoc0SO78I}WZ`>s)zq;vA`WVLNvO zOq39SfGY?@U2)6(t_U=@Am@EHI=9VvZqt)%QhdBDGO(yat84m5@iJxe?9{eO#+s|3tuU{}bV{!U+eeaPQhrT5RBF$g++XcGuh<8ahH`qdRm&y9{1mj z1*nZK^pn+-f8H4pA1kPATr}4Tw*h^s^Q8T44@j>kUu1wqKw8c=Q0MSpKYST5$nW18 zmhmB?eDzuZZH*XkL){212iwjW|E^4Z`DsBs99$#^g*JEmd!jzM(%em8+03tWC7@Q; zT%~gndtDCyXM}(lq2*B9Lp!(0H?I$JXmo_-R04~>8lUf_52waWT>la{yz8HT-voGN z#5RDde|N_WpB#&d{L90&uNF-kFUg6gTpK@u+ecvjL~Ti7nrjK9rljbOU40cXyCEQE z6ScwL?oDfL=#?(LKw$UAHC{-=i#hb4y7?McjRoMYx(80f0tF&HkOe8&LEzNMUQJ{d7C|5xmw7x| z-xGWNMnH{A{^7qbI5O=8Q^qb=$v!lCB1K# zq9sZ>CmJ$m=(Cl$7MtA^EZTU{z>8etd64xVj6f9|R;QY|cBVb+23G-nTxN=+fn!7aS2m00Kb~_~qj_9sRIZ?)N~N z?=Gv&f>2AkbZp-{sI)oAZUPr{?JW&1xk6hk{cBO9Zjut>!xB=;=_FY)eTt}=-)Ink zfO!OxPQ}Zrph@kik46z;2r`^ zF27n^n5evC14cj`TN?KSR_~&=3@LU`xro#y1k^D7n})sP=x9ABAWz*=>KJ1I>^tWQ z7mb!av9H+|06jy%V+7Rv?EOFdM#@yF?&!=yx}mNXt62Q)7qa5#Z{^6Iof2KDjMTsQ z@{C0Z)EcZb{}5>1>sHyhZl%om)Y+e&{8JJ4XR1Dp`*Vtu_R`_@2Oa-(x;n#x77!&E zc(H6*w>|5hi>xy+rwnrip7$a zn(Ezz$;@&BgJ&%Fm4H|d)PfFz5)d_Y@caMit$pHLk!wgwT;9F6rwp3DRLY-IJ69Vv zdXqrIHtj|Iq@|`v!U^rlVi?=kBcGE6Q^x7)u~zd7GcFP6GS+FdcK$3G`{bQEtwo0a zvQCPY^v~2Z|EyXf@7&WvHy;e0Par4(nf2kQJjLTo%Iaa53D4dqk4>0$W)r`CM4&)q zRMXPVEca){w5p$ zm?tL>AI$Nz@sjEK9w6KJ$FK6q6L(m4E$`Hc5`|YaP)8+84?RgvgZ_mLUn*-XM zZSeWv{!+8a1!r#x_VtXO+b?m|SO9g|s<`$?@Z1aAN~1O%L`_pog8&5lNg#)qoH)2& zK8yX2teP|36e53qH_;S7p*q>Re37Uhv)hg}%S8S7v8l^ex4kq*%2uo4$Mne=0=_4Z z<>O;gLY%yM!{w%lhwtfn9KeQ!b7e&DOC|2;A&+NDdJup>ZUnLj$XBmECx>=!%gv5$ z5XhCli9-iu;?PHO-N!}ED0)_~DbJwO1vW*4UyI=8XHVJ)P5QCV@-=QCs>B zdCT-icQbq9g(nH9X?kxP@u4SkBPr(+m^`|!^{af(zzF~{?}wZTrdq?M^2}EY zWbrqj%f>}&&XWU@uKhdH)cq1Qmx1|9 z@bBLww?yp4ICBVyN;0ZoA-Oc>&WxYzNhc>I%0o@`Pc_=(@#m#!`>xsDg#Eo*&Hj~` z%W{Z^3Pg?U*t==HG;4p2+&t`E8Pu_{?)V=4^hZrVOqn!Gcb^zS!0!aAoZCqDZ`GZPs-09y%DgoYP#aNpS>T@ z&PsztUyYYZLmw42Z~mE|KVL6_@w**Vl`+o!$iF&5yg;`ANzrgXaJF;Qy~ z(Ci`Li*F+d$B*fzo0RbHw*cJ-nP8~C2`M27^njN#@l zBZEaPXP95Ru-gsN=+Z0mGhv?#2&h%Zt{*T$F1)6X{G}~ybZEymQTILl)K<^?(NMZg zujpdPK9I351SAjyC+y$1WrOVbd#$cemS__kA|Sb=>U8&`8LN%WpExF0gYz!ytUU)6 z_|j&s2eZ+U1Zp%nU(}Bu+o+p6iQaj#uDIp?jAsDNPfk03M5Rjm- znSYRxuiol1S9*Gy_H>3XZf6ArTP>@oerV1iP#`kWP%wNzGK9+(WBvl!f}Ktw;6DPT zD^=5y{^iv!zZn|~poFJ*8D~70?7yn%&loY$&k9Qjz^k@qD$!NwC?$BGL~4-Wt`1Ojox!( zQ$uh24t_IW=xTYN`y0Yo^@E~1wXN>+?wM5>z zw}(91vVuI=C|U+x*+{;B^La^5Jaxvz6~EOzDmCmnucl@hP|tcOF{U}6K-A0+j46GJ zHb<6`ru^^LIaJk%Un91AH?KEhZpc=x0=9nPoGiygmnto_TU;#F8Z>3}PZl!Xf74le z$Zhr98M0;R!aS4haC?7g(E9Q`_h;Xsrn^x;XRj=(M(|C4_a#{}V~X7O&X=zGgL_T? z=cL|6?PSUePs+~qD>Kqn-%ieL)mCm8Jc=0@vY!A>ejhV@a;$o$)16<6olN$Bv9;*b zT^nQiuBiF+1GQx{zmhQz-5AI$bN_oA;zf;Nr8$p)8e%s?d-`+c2d`%N%U`TyX}Mw0 zD7mP|O}al_teEw!jDE0BzDZWq#wJ1lWWk7WEGQPW;KwcUT) zCHET}3lRQHct|At%){2BniX!_ia#axhb2;?Y=yA(OGow+P}jD)KQ>g_-~OO%Ua~;q zj~imjCp%?BBXEkG*V$K<)$%?b??6j$F1HSuHJ>!`TFZpa>u!L18m~(6*I- z89#_4d`%!VC0Td=Mr?IE#Sj7k2p}K<0GYKrImun)FU`suKM;U`tpqx!oNg4Bu>gok znCi@`M_~d@HxPh8*a#pXVL+|scc^z^+c5M*7Z88|1j0vv2Mof%`t}hYxpM4&7|_rK z1R&r-0%`?3_4GIbVqx(L7b~9e*e&yqTL>A~5P(3~2prwJOC~&bzpVT1=Zrq1D%7ZB zsPklPo|9wy_ZT|HXdi~0>o86_6)z_a?$=>?#zg;v`{kn4|9C2M}28PHx$j5T1&{D5{CKmY>%Ah2cGA{qb8y|RDXrYs46Ju+7M4t-Nv zX^XzA3Bugg)bR07wY<(25|slt)N`q%nsYkP)5IC;tv>&DE=RKo0ub;cfo&@m%WK-F z_3YxISi~PcA|F3?oBaOeN3KM({HJeZ$J*sNVvjO*nMWk~w6SS>6HXj6cqu7Ij3IA0 zacG|*ABBoVXDnPW<;ADubYen|W7Wb2J)RgYr7Bc0EjPu95~&O)Ki@HZ^kHVb;d6 zPu^*ktFZYQ*e?HjL@CLqW!i`V89!kQDqBa-w9P-pY~}&q7A#yu8nx{x*AEyWm1@@u zXpaE|An-2%b;*1Gw!i<~kjE=^Z}#^uKb9Vk56i>C*yaLJS?|T>cXTK-e4jj=`&?~Y z!pe`hkM^lgP^+|?fG=FzO8)rzGaqG6st^dBz|OTRbUWF(PQPs+r)4Tv4`hW!~uZ}0*Ub_b(1(1r{6Y^)8-w!i&_aUP*azxn{_aMU=v~zh`bN?r=_Ke znq}CDO|AWU$#u6%%yX}alLXF*tcc0`1e$leHeJ!&ncXZWO2TZXu4ElzE?F7{D;9FlDEw!6plxHkz-I{I>#pby`lpP32DD*hi zHUisMFO{Fhylz|nbPNHf5GYxpl05b0T)A$*%Tlq{xf#!#s7t;z&TA=my*^I*y)((O zDVDf|<&?94I1Ce*^XY%(>ieEzD6(O49N;wqYP417dmhjDQQyoXA_|1(|3%F3$+3J5 z@zm)Ql|1bee~tw>dHA3l*B+LkK>z~(5>Va=YA?}l7n?c2IhCJuc#;3PA-9Lgr25>UfWx<5M9 zr`eM>1e`%2s{X~78Hz+bx@@FXYtTdj^`Z8cuU<>W5A0`nQ4%AuVC!H4W7gDM8pK$D z5@johT9|(9Q+GKyxzIy1@}%dflgH(Q{(VF5)I}a5qoSm2)f&?L%5GBkf;KLS+&iH< zW{hv+cAaGKjO7{6>~CHEhr}N{Y#Qa0M-GWvK}BzCaLE;6pWJ`L!nu0G%do3|(Pd&} z#x+CE9bz1R?1=2$yg^b(aW{Ez(C#T~Mlw z)!pI$ECP-Z5EYY}x8lk>9?JMRE5?vt8eMtnk+IXmew}^U%&%n3LpSQq_0jP^hCN2z z!I@zA_n-4+)Xkkt@PrFL5KuFP9@_bjJn{L@VH?is2d;r~k zybEwV7{pkBY+iV4Hh}~GY!>xxmKGiYh)H-j(+dP35H14R zRJOG65HKttM(18pvwzVbV1z)m22G8aV+(;y0_wRTwWc#IJOm8?b&o1o$k2*EYEEJr z1dI?kPaED{p++4ehhPhV3<4c)>ko-A5-=z-X}-*?eFMd()J$1tidNfnH_g^wa?&%3aowE-#jMii7c$=UEL}hhR_ZziKRn6p!ArFgsu;)xu z^Ily)@D)*u_tNqvFmcF3h)3RdGWQfIUQ*iiy+_(*Zu$QgNeOW>q;ud)r3bcemb*uN zDm9v%pUs2w-_D;nM!p#Qkgh=0^!N8^>z&%&65~$D{%xBiDIxzW6=uennw%_uFP?9v z%PhXslsezPIZXC#-H>HFZ$yF?5Cu7L1NRIE{D@C;_O3GBJ9`^aA+*ZgF zhYrZfU%q!+*p7;K^_&^HCg)5~OOpjt-6Kn(Xn>)&J?UEwRUj%|0k>xK$ z=4X34z(54^d-R^i(}@YXlL|EOL$@Oga}Y?=mK|1uLc%W|Q+o{3R;#EbT{^b!og*wZ z*g+s>_~cj=#SZfH2?37~So-5s*|uV_N3tOeqXZBTqr|X>00c4#tY0uE^EEI0M*sow zU(LxF0;Um&(}pb3{7V1<@o(+P90DN|C{ww5$Ubo3UIGY+duvDJ5U`zqda946pTNg! z_8s@?SOCOC|9OBV1R#)&fSO96Mdu#bw({051biVNMWRdSuBV#uFQP!CZhH(N;Aa96 z+9Dk{J^zl>YViX z_db#Fqb4y+iVxpJS!ab|+snx>J|Rn{Ptn!CnyL1wN%M5sI>l(bHhuP*c|Ya|#}@*k zvW|Ifq^w`?OTLpUwd&T#71N!Ts#rz$H>w;JX9EN*CQ!IoaZx{hY9-6-UtzCgh05Z# z75TK~Ad78TpO)`f0AF0rQYUpWZAQoeQ-7BxmtU3R94`PtF+l(VJ|p0pZzHO%Whz&b2S5BaV~*&*|ClEUCy!~<44)${I(8Se0J9sKy7t`t zu_0~=4L7krNP67x(00IyQiU0x<6gCcm zfb|3-qYCQo#E7kKrx-#Y009If03dclz%ByitJl`ub=hh)blYMG0ka4oAZC%w!_VUb z>m6V$Kpt?|teZgH3oa4$K&hT~L6__Gm|+6}a|y%@pB!uJ7~f<2_sG`ee@NWXL*{1Y zaBr*U%rF$;{4YL~!qL$=j!91!IeuV|9NV`?l20e**zeX25d{iJu@a@ELe09OP1ciZ z8j6YDwqwmQnLlxiUUNs;wdmMG=1CG}J= zwg^aK{7IQM;u-mE(np?xX;m`QUU|kU*S_)l#o&iLo9poddu7tF$8ycDY}Iq*)|baf zqc$CK-Ook{ghC+f*R&GjPRPr>E0O%hH8_hX4d@BCur{|Nm@4@7Zp{Dj@1cIt>C4 zu!n%U7fFMFnFPWrAQfuVH8Xa6K>z{<2=M>U04z*(5eTb*oZISBDWxqUOoIRf!cU;p zHGRV0DLs0EfLgpLw-#0bQ4fgS^5Xls#lbcRm_y*I$idpejzf~M`eO3bq(MLj`Fg8&4qC!oaRo;N2*fk<1PC$>I8 z2lP;^R2kh-L>sWx?bKq!3%lJQx#eif8Fl5I4@={Aoic_Ps!>|;$B$Z^zO&q)I(ghs zKm{TrrEsz0IgUw9NtV>)(~_2&rtQ<_J8@V`S97rFY&llf(pKA2Q*)>f8aei9K8-Rg zs!f^VrxsPPkd&`cM=rXyZ^kzd#KYR^*J;^WcLzpnbvw1#P)*o&!=OD1SHrqhT|Y$Hi5WKzcLoUY^e75Q!`8tp1w>b4D2WC z7tYBNMCCdS1<+M(*#qHSe$w>2)h8;)VbOAOL}^ z1Q3v{Ja`8I2tWV=Itd^kIzeFu0SM$tVB^pw+S0tt3y>!uKkPtE{7_|bga8B}Uto01$ux1cD=gfCR^lqaXkQ2>6}=0^<8q z000nx00e>~fPe(YjiVp{0SMSepjiKj&pT}_0Aga>=|IO2fB*#CO#lILcm0SS0uX?J zZ3I|2Bn;?Nl21$Akwc;uB33Q#=wU;>9^1c13Kfkubd24`NB8YE6v8phzId7Px{pbW zkJD|dR{t>?k8bBd8mh%5ikB%TQH2Tz>4C!_U_XI~(VLR~|F4?;v3M?mZ7UYbSFb)N zo0l$-^t3e3!}x{-i7T#bH>pSuz>&qViEM2qhFP8-xz{$Sj5*$ zZk3R9`Oh=b{js55N{d{4Kp=>FAlni?E9tbc0M4z{`USJ)o7V>+B+f07qast6IcL20 zvaI~&dq>4ZFc1htAP6xD37pVGga!e(5I{go zu2hL~6-@SsJ3kSKE?w47>5{9<3HVDuX0|=CJ&a=ks?~2ICCgWI`6)v9b`U69qLkEZ zdVw8X( z*uHm=F6=$5RE5fh0;t=njhxe{xuIh)h5!WYCBVlZd->Bl1Rwwb*AhTLTw6Kf5kNr9 zV~Hm(5jb^w(Q=Fh@KQy|#bN@8iN%0%4*>{3z^eoh5U*C2ydVGp2v|%20kIe`?jZmH z2zZqM0^-%mk{1LZ00D~$ARrb4#yteWO<-A<{e2h<5N_)9hnR2 zdWoc*PLhhX>&y99_0s)q=WJiRhJYyq+9Y(jpRoXfn3!@l;Uq5tNeOW>ZNxyCKXFVB zlQ!4iE-}xI6utLCwypeAK7INg*|&9L7GH&nM$7dBM@YNA_lo)!M1ueX!b1Q72@hxA z_p)>SN?AL9mYh6%K#G?sFOA!Fl$uR1(9K01|8lQ3l9rm1=P^AVA0}P?Ga%3X?0^6S z%q4(;n9CDy77$2HNzM?DT^m;A>s?(Ed+xhGrE0y#`P#7)0uV5V05{al;fNOt32gl1 zR|zB@s(U3gxm_x=Ff?34z}Ey25MP(y9m(%pw?cQIJJ+q$ZHplU{7&GxzZZ8lYb*d_ z;`g)31^Fk&pVS@YsT0R^+hPa-2!uue0SS#CM?(Mt5b!Ml1jM(cCvgZs00N;AKtMv{ z$I%dg00ewX00HrB=}8;{5P(2v1Z)(LO%eC~WY$=K&>(O$1Rwwb2!uw!MllI3aE^um z1RwwbdkG*Q_VTB92tWV=?j;a2d~z%*;@;fR6|uAU-NK zsX_n(5HOPf0%9gjd_e#L5bzNJ1jI+hCRGSP00L$bKtRl-i7$%?%qaKwJ&Xmg2rh0R zUlFlVed4o8ar|wsfVcdd#qa zKn?YCot{jukzSjo~pr9j%@CV+s1n|O%*rJPQZ#Q2jTdU4m`-;Nq8zi9%hrhuW#2tdFC1P~Ap6p<7l009WtK>z`{300O!QoDqWP&5P$## zEFy45Oe}JbTL?e^0ub;j0R+UWl_f6-KmY<36F@*L28??MKmY=sB@i=wax5z1+47PY z1RwwbYYDhpKo+;Y^#{fRSbK)x9Rd)5fDQug784x_VgdmOKmY>P5I{hz;fhxXKmY=s zCxC!>zQiO50SG|A8UhH2HC*uu0SG|A^8^qOn@ar1<9|HNSOAORM?_fM0q!9HfinaU zlQSgv?N|cQrON7#t$3Mox@|Fp00crKfPjR?kE6pt;M`ViboWyC0{ynSoni<92;@ot z0m&5$8=XX;X46*E^olM4LsH*V+TZ$MKsyW|00DCdARy*&#EXRlBDDJ&H^1sWx&m8#0%8O!DTtFOz!yHf4? z^3<2}SV0H}0uX?JTL>T^ZmAS;LI45~a2Npu#9;*?90))F0&XFIfVibn#0dciK)_)H z5DnG0SG`KlK=veiGmjpfB*y_V1xhyVuTj9 z5P$##AdpD_0m($c3kW~}0uV4l00A*V3tI?400K@Yu zN&o?IXkiEo0uX?J(+MCTPOlL0K>z{}a3}!;#G!>DEC@gV0!}A@fH=KE#0LQgK)|5{ zBH9<4lVqZb6usi1Jt759cj?%^w?k7VEC@gV0uZo-K;8X+40-?eQI9C+T{?B|_*I8H GhW#HYyaQ_h literal 0 HcmV?d00001 From 15a1c5a349f33a4f1e99f1ff96684775ccd1b1c8 Mon Sep 17 00:00:00 2001 From: nirvn Date: Wed, 17 Mar 2021 14:33:25 +0700 Subject: [PATCH 100/377] [symbology] Add a 1/2, 1/3, 1/4 arc signs to simple markers --- .../symbology/qgsmarkersymbollayer.sip.in | 3 ++ src/core/symbology/qgsmarkersymbollayer.cpp | 36 +++++++++++++++++++ src/core/symbology/qgsmarkersymbollayer.h | 3 ++ 3 files changed, 42 insertions(+) diff --git a/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in b/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in index 8e010355b0c4..cc7112fb9b68 100644 --- a/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in @@ -52,6 +52,9 @@ leaves the actual drawing of the symbols to subclasses. Octagon, SquareWithCorners, AsteriskFill, + SemiArc, + ThirdArc, + QuarterArc, }; static QList< QgsSimpleMarkerSymbolLayerBase::Shape > availableShapes(); diff --git a/src/core/symbology/qgsmarkersymbollayer.cpp b/src/core/symbology/qgsmarkersymbollayer.cpp index 8670a52aa32d..5ead3abb5963 100644 --- a/src/core/symbology/qgsmarkersymbollayer.cpp +++ b/src/core/symbology/qgsmarkersymbollayer.cpp @@ -75,6 +75,9 @@ QList QgsSimpleMarkerSymbolLayerBase::ava << CrossFill << Cross2 << Line + << SemiArc + << ThirdArc + << QuarterArc << ArrowHead << ArrowHeadFilled << SemiCircle @@ -133,6 +136,9 @@ bool QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( QgsSimpleMarkerSymbolLayerBa case Cross2: case Line: case ArrowHead: + case SemiArc: + case ThirdArc: + case QuarterArc: return false; } return true; @@ -356,6 +362,12 @@ QgsSimpleMarkerSymbolLayerBase::Shape QgsSimpleMarkerSymbolLayerBase::decodeShap return LeftHalfTriangle; else if ( cleaned == QLatin1String( "asterisk_fill" ) ) return AsteriskFill; + else if ( cleaned == QLatin1String( "semi_arc" ) ) + return SemiArc; + else if ( cleaned == QLatin1String( "third_arc" ) ) + return ThirdArc; + else if ( cleaned == QLatin1String( "quarter_arc" ) ) + return QuarterArc; if ( ok ) *ok = false; @@ -418,6 +430,12 @@ QString QgsSimpleMarkerSymbolLayerBase::encodeShape( QgsSimpleMarkerSymbolLayerB return QStringLiteral( "quarter_circle" ); case AsteriskFill: return QStringLiteral( "asterisk_fill" ); + case SemiArc: + return QStringLiteral( "semi_arc" ); + case ThirdArc: + return QStringLiteral( "third_arc" ); + case QuarterArc: + return QStringLiteral( "quarter_arc" ); } return QString(); } @@ -635,6 +653,9 @@ bool QgsSimpleMarkerSymbolLayerBase::shapeToPolygon( QgsSimpleMarkerSymbolLayerB case SemiCircle: case ThirdCircle: case QuarterCircle: + case SemiArc: + case ThirdArc: + case QuarterArc: return false; } @@ -667,6 +688,21 @@ bool QgsSimpleMarkerSymbolLayerBase::prepareMarkerPath( QgsSimpleMarkerSymbolLay mPath.lineTo( 0, 0 ); return true; + case SemiArc: + mPath.moveTo( 1, 0 ); + mPath.arcTo( -1, -1, 2, 2, 0, 180 ); + return true; + + case ThirdArc: + mPath.moveTo( 0, -1 ); + mPath.arcTo( -1, -1, 2, 2, 90, 120 ); + return true; + + case QuarterArc: + mPath.moveTo( 0, -1 ); + mPath.arcTo( -1, -1, 2, 2, 90, 90 ); + return true; + case Cross: mPath.moveTo( -1, 0 ); mPath.lineTo( 1, 0 ); // horizontal diff --git a/src/core/symbology/qgsmarkersymbollayer.h b/src/core/symbology/qgsmarkersymbollayer.h index d0643b8f5b91..b0f55acaec44 100644 --- a/src/core/symbology/qgsmarkersymbollayer.h +++ b/src/core/symbology/qgsmarkersymbollayer.h @@ -74,6 +74,9 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerBase : public QgsMarkerSymbolLayer Octagon, //!< Octagon (since QGIS 3.18) SquareWithCorners, //!< A square with diagonal corners (since QGIS 3.18) AsteriskFill, //!< A filled asterisk shape (since QGIS 3.18) + SemiArc, //!< A line-only semi arc (since QGIS 3.20) + ThirdArc, //!< A line-only one third arc (since QGIS 3.20) + QuarterArc, //!< A line-only quarter arc (since QGIS 3.20) }; //! Returns a list of all available shape types. From c8b4541a42556ccd6ab33b9f9a519eb0d9958370 Mon Sep 17 00:00:00 2001 From: nirvn Date: Wed, 17 Mar 2021 15:18:08 +0700 Subject: [PATCH 101/377] [symbology] Add a semi arc and arrow sign to ellipse markers --- .../symbology/qgsellipsesymbollayer.sip.in | 11 ++++++++ src/core/symbology/qgsellipsesymbollayer.cpp | 28 +++++++++++++++++-- src/core/symbology/qgsellipsesymbollayer.h | 8 ++++++ .../symbology/qgsellipsesymbollayerwidget.cpp | 2 +- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in b/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in index bf5b79062865..ea8092620595 100644 --- a/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in @@ -51,6 +51,17 @@ Creates the symbol layer void setSymbolName( const QString &name ); QString symbolName() const; + bool shapeIsFilled( const QString &symbolName ) const; +%Docstring +Returns ``True`` if a shape has a fill. + +:param symbolName: name of shape to test + +:return: ``True`` if shape uses a fill, or ``False`` if shape uses lines only + +.. versionadded:: 3.20 +%End + virtual void setSize( double size ); diff --git a/src/core/symbology/qgsellipsesymbollayer.cpp b/src/core/symbology/qgsellipsesymbollayer.cpp index 357f87054e80..7f699512f953 100644 --- a/src/core/symbology/qgsellipsesymbollayer.cpp +++ b/src/core/symbology/qgsellipsesymbollayer.cpp @@ -280,8 +280,16 @@ void QgsEllipseSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContext & transform.rotate( angle ); } - p->setPen( context.selected() ? mSelPen : mPen ); - p->setBrush( context.selected() ? mSelBrush : mBrush ); + if ( shapeIsFilled( mSymbolName ) ) + { + p->setPen( context.selected() ? mSelPen : mPen ); + p->setBrush( context.selected() ? mSelBrush : mBrush ); + } + else + { + p->setPen( context.selected() ? mSelPen : mPen ); + p->setBrush( QBrush() ); + } p->drawPath( transform.map( mPainterPath ) ); } @@ -627,6 +635,17 @@ void QgsEllipseSymbolLayer::preparePath( const QString &symbolName, QgsSymbolRen mPainterPath.moveTo( -size.width() / 2.0, 0 ); mPainterPath.lineTo( size.width() / 2.0, 0 ); } + else if ( symbolName == QLatin1String( "arrow" ) ) + { + mPainterPath.moveTo( -size.width() / 2.0, size.height() / 2.0 ); + mPainterPath.lineTo( 0, -size.height() / 2.0 ); + mPainterPath.lineTo( size.width() / 2.0, size.height() / 2.0 ); + } + else if ( symbolName == QLatin1String( "semi_arc" ) ) + { + mPainterPath.moveTo( size.width() / 2.0, 0 ); + mPainterPath.arcTo( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height(), 0, 180 ); + } else if ( symbolName == QLatin1String( "triangle" ) ) { mPainterPath.moveTo( 0, -size.height() / 2.0 ); @@ -650,6 +669,11 @@ void QgsEllipseSymbolLayer::preparePath( const QString &symbolName, QgsSymbolRen } } +bool QgsEllipseSymbolLayer::shapeIsFilled( const QString &symbolName ) const +{ + return symbolName == QLatin1String( "cross" ) || symbolName == QLatin1String( "arrow" ) || symbolName == QLatin1String( "semi_arc" ) ? false : true; +} + void QgsEllipseSymbolLayer::setSize( double size ) { if ( mSymbolWidth >= mSymbolHeight ) diff --git a/src/core/symbology/qgsellipsesymbollayer.h b/src/core/symbology/qgsellipsesymbollayer.h index da4ce933eea1..9a8f93305dea 100644 --- a/src/core/symbology/qgsellipsesymbollayer.h +++ b/src/core/symbology/qgsellipsesymbollayer.h @@ -52,6 +52,14 @@ class CORE_EXPORT QgsEllipseSymbolLayer: public QgsMarkerSymbolLayer void setSymbolName( const QString &name ) { mSymbolName = name; } QString symbolName() const { return mSymbolName; } + /** + * Returns TRUE if a shape has a fill. + * \param symbolName name of shape to test + * \returns TRUE if shape uses a fill, or FALSE if shape uses lines only + * \since QGIS 3.20 + */ + bool shapeIsFilled( const QString &symbolName ) const; + void setSize( double size ) override; void setSymbolWidth( double w ); diff --git a/src/gui/symbology/qgsellipsesymbollayerwidget.cpp b/src/gui/symbology/qgsellipsesymbollayerwidget.cpp index 9a549854c45a..a49908a2fd98 100644 --- a/src/gui/symbology/qgsellipsesymbollayerwidget.cpp +++ b/src/gui/symbology/qgsellipsesymbollayerwidget.cpp @@ -66,7 +66,7 @@ QgsEllipseSymbolLayerWidget::QgsEllipseSymbolLayerWidget( QgsVectorLayer *vl, QW mRotationSpinBox->setClearValue( 0.0 ); QStringList names; - names << QStringLiteral( "circle" ) << QStringLiteral( "rectangle" ) << QStringLiteral( "diamond" ) << QStringLiteral( "cross" ) << QStringLiteral( "triangle" ) << QStringLiteral( "right_half_triangle" ) << QStringLiteral( "left_half_triangle" ) << QStringLiteral( "semi_circle" ); + names << QStringLiteral( "circle" ) << QStringLiteral( "rectangle" ) << QStringLiteral( "diamond" ) << QStringLiteral( "cross" ) << QStringLiteral( "arrow" ) << QStringLiteral( "semi_arc" ) << QStringLiteral( "triangle" ) << QStringLiteral( "right_half_triangle" ) << QStringLiteral( "left_half_triangle" ) << QStringLiteral( "semi_circle" ); int size = mShapeListWidget->iconSize().width(); size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) ); From b56ea9a8b066d84723806cd4043b0e6a3fcc78a5 Mon Sep 17 00:00:00 2001 From: nirvn Date: Wed, 17 Mar 2021 16:08:23 +0700 Subject: [PATCH 102/377] Address review --- .../symbology/qgsmarkersymbollayer.sip.in | 2 +- src/core/symbology/qgsellipsesymbollayer.cpp | 4 ++-- src/core/symbology/qgsmarkersymbollayer.cpp | 16 ++++++++-------- src/core/symbology/qgsmarkersymbollayer.h | 4 ++-- .../symbology/qgsellipsesymbollayerwidget.cpp | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in b/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in index cc7112fb9b68..5e9a34a052ac 100644 --- a/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgsmarkersymbollayer.sip.in @@ -52,7 +52,7 @@ leaves the actual drawing of the symbols to subclasses. Octagon, SquareWithCorners, AsteriskFill, - SemiArc, + HalfArc, ThirdArc, QuarterArc, }; diff --git a/src/core/symbology/qgsellipsesymbollayer.cpp b/src/core/symbology/qgsellipsesymbollayer.cpp index 7f699512f953..1fc9993a4235 100644 --- a/src/core/symbology/qgsellipsesymbollayer.cpp +++ b/src/core/symbology/qgsellipsesymbollayer.cpp @@ -641,7 +641,7 @@ void QgsEllipseSymbolLayer::preparePath( const QString &symbolName, QgsSymbolRen mPainterPath.lineTo( 0, -size.height() / 2.0 ); mPainterPath.lineTo( size.width() / 2.0, size.height() / 2.0 ); } - else if ( symbolName == QLatin1String( "semi_arc" ) ) + else if ( symbolName == QLatin1String( "half_arc" ) ) { mPainterPath.moveTo( size.width() / 2.0, 0 ); mPainterPath.arcTo( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height(), 0, 180 ); @@ -671,7 +671,7 @@ void QgsEllipseSymbolLayer::preparePath( const QString &symbolName, QgsSymbolRen bool QgsEllipseSymbolLayer::shapeIsFilled( const QString &symbolName ) const { - return symbolName == QLatin1String( "cross" ) || symbolName == QLatin1String( "arrow" ) || symbolName == QLatin1String( "semi_arc" ) ? false : true; + return symbolName == QLatin1String( "cross" ) || symbolName == QLatin1String( "arrow" ) || symbolName == QLatin1String( "half_arc" ) ? false : true; } void QgsEllipseSymbolLayer::setSize( double size ) diff --git a/src/core/symbology/qgsmarkersymbollayer.cpp b/src/core/symbology/qgsmarkersymbollayer.cpp index 5ead3abb5963..72b0fb4d361c 100644 --- a/src/core/symbology/qgsmarkersymbollayer.cpp +++ b/src/core/symbology/qgsmarkersymbollayer.cpp @@ -75,7 +75,7 @@ QList QgsSimpleMarkerSymbolLayerBase::ava << CrossFill << Cross2 << Line - << SemiArc + << HalfArc << ThirdArc << QuarterArc << ArrowHead @@ -136,7 +136,7 @@ bool QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( QgsSimpleMarkerSymbolLayerBa case Cross2: case Line: case ArrowHead: - case SemiArc: + case HalfArc: case ThirdArc: case QuarterArc: return false; @@ -362,8 +362,8 @@ QgsSimpleMarkerSymbolLayerBase::Shape QgsSimpleMarkerSymbolLayerBase::decodeShap return LeftHalfTriangle; else if ( cleaned == QLatin1String( "asterisk_fill" ) ) return AsteriskFill; - else if ( cleaned == QLatin1String( "semi_arc" ) ) - return SemiArc; + else if ( cleaned == QLatin1String( "half_arc" ) ) + return HalfArc; else if ( cleaned == QLatin1String( "third_arc" ) ) return ThirdArc; else if ( cleaned == QLatin1String( "quarter_arc" ) ) @@ -430,8 +430,8 @@ QString QgsSimpleMarkerSymbolLayerBase::encodeShape( QgsSimpleMarkerSymbolLayerB return QStringLiteral( "quarter_circle" ); case AsteriskFill: return QStringLiteral( "asterisk_fill" ); - case SemiArc: - return QStringLiteral( "semi_arc" ); + case HalfArc: + return QStringLiteral( "half_arc" ); case ThirdArc: return QStringLiteral( "third_arc" ); case QuarterArc: @@ -653,7 +653,7 @@ bool QgsSimpleMarkerSymbolLayerBase::shapeToPolygon( QgsSimpleMarkerSymbolLayerB case SemiCircle: case ThirdCircle: case QuarterCircle: - case SemiArc: + case HalfArc: case ThirdArc: case QuarterArc: return false; @@ -688,7 +688,7 @@ bool QgsSimpleMarkerSymbolLayerBase::prepareMarkerPath( QgsSimpleMarkerSymbolLay mPath.lineTo( 0, 0 ); return true; - case SemiArc: + case HalfArc: mPath.moveTo( 1, 0 ); mPath.arcTo( -1, -1, 2, 2, 0, 180 ); return true; diff --git a/src/core/symbology/qgsmarkersymbollayer.h b/src/core/symbology/qgsmarkersymbollayer.h index b0f55acaec44..de7d9bb9a3e6 100644 --- a/src/core/symbology/qgsmarkersymbollayer.h +++ b/src/core/symbology/qgsmarkersymbollayer.h @@ -74,9 +74,9 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerBase : public QgsMarkerSymbolLayer Octagon, //!< Octagon (since QGIS 3.18) SquareWithCorners, //!< A square with diagonal corners (since QGIS 3.18) AsteriskFill, //!< A filled asterisk shape (since QGIS 3.18) - SemiArc, //!< A line-only semi arc (since QGIS 3.20) + HalfArc, //!< A line-only half arc (since QGIS 3.20) ThirdArc, //!< A line-only one third arc (since QGIS 3.20) - QuarterArc, //!< A line-only quarter arc (since QGIS 3.20) + QuarterArc, //!< A line-only one quarter arc (since QGIS 3.20) }; //! Returns a list of all available shape types. diff --git a/src/gui/symbology/qgsellipsesymbollayerwidget.cpp b/src/gui/symbology/qgsellipsesymbollayerwidget.cpp index a49908a2fd98..10c7b2f5a966 100644 --- a/src/gui/symbology/qgsellipsesymbollayerwidget.cpp +++ b/src/gui/symbology/qgsellipsesymbollayerwidget.cpp @@ -66,7 +66,7 @@ QgsEllipseSymbolLayerWidget::QgsEllipseSymbolLayerWidget( QgsVectorLayer *vl, QW mRotationSpinBox->setClearValue( 0.0 ); QStringList names; - names << QStringLiteral( "circle" ) << QStringLiteral( "rectangle" ) << QStringLiteral( "diamond" ) << QStringLiteral( "cross" ) << QStringLiteral( "arrow" ) << QStringLiteral( "semi_arc" ) << QStringLiteral( "triangle" ) << QStringLiteral( "right_half_triangle" ) << QStringLiteral( "left_half_triangle" ) << QStringLiteral( "semi_circle" ); + names << QStringLiteral( "circle" ) << QStringLiteral( "rectangle" ) << QStringLiteral( "diamond" ) << QStringLiteral( "cross" ) << QStringLiteral( "arrow" ) << QStringLiteral( "half_arc" ) << QStringLiteral( "triangle" ) << QStringLiteral( "right_half_triangle" ) << QStringLiteral( "left_half_triangle" ) << QStringLiteral( "semi_circle" ); int size = mShapeListWidget->iconSize().width(); size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) ); From 64cfd0e4b2706e4c5815563cc6f21e35b86f3bb4 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 17 Mar 2021 12:18:59 +1000 Subject: [PATCH 103/377] Fix UI hang when selecting vertices from complex features when releasing the mouse button after a drag operation For large geometries the total vertex count was being calculated once per vertex, resulting in a lot of unnecessary extra work --- src/app/vertextool/qgsvertextool.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/vertextool/qgsvertextool.cpp b/src/app/vertextool/qgsvertextool.cpp index fa4a2170697d..a538c2943987 100644 --- a/src/app/vertextool/qgsvertextool.cpp +++ b/src/app/vertextool/qgsvertextool.cpp @@ -601,9 +601,10 @@ void QgsVertexTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) bool isFeatureSelected = vlayer->selectedFeatureIds().contains( f.id() ); QgsGeometry g = f.geometry(); - for ( int i = 0; i < g.constGet()->nCoordinates(); ++i ) + int i = 0; + for ( auto it = g.constGet()->vertices_begin(); it != g.constGet()->vertices_end(); ++it ) { - QgsPoint pt = g.vertexAt( i ); + QgsPoint pt = *it; if ( layerRubberBandEngine->contains( &pt ) ) { // we don't want to select invisible features, @@ -618,6 +619,7 @@ void QgsVertexTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) if ( isFeatureSelected ) selectedVertices << Vertex( vlayer, f.id(), i ); } + i++; } } if ( r ) From 7fed9107345550b82a4f9fffdcfad914f0a1b3bc Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 18 Mar 2021 08:57:33 +1000 Subject: [PATCH 104/377] Fix possible crash when rendering callouts (master only) --- src/core/callouts/qgscallout.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/callouts/qgscallout.cpp b/src/core/callouts/qgscallout.cpp index 9655938cc79e..662440107e81 100644 --- a/src/core/callouts/qgscallout.cpp +++ b/src/core/callouts/qgscallout.cpp @@ -652,6 +652,9 @@ void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const d const QPolygonF points = line.asQPolygonF(); + if ( points.empty() ) + return; + QgsCalloutPosition position; position.setOrigin( context.mapToPixel().toMapCoordinates( points.at( 0 ).x(), points.at( 0 ).y() ).toQPointF() ); position.setDestination( context.mapToPixel().toMapCoordinates( points.constLast().x(), points.constLast().y() ).toQPointF() ); @@ -771,6 +774,9 @@ void QgsManhattanLineCallout::draw( QgsRenderContext &context, QRectF rect, cons const QPolygonF points = line.asQPolygonF(); + if ( points.empty() ) + return; + QgsCalloutPosition position; position.setOrigin( context.mapToPixel().toMapCoordinates( points.at( 0 ).x(), points.at( 0 ).y() ).toQPointF() ); position.setDestination( context.mapToPixel().toMapCoordinates( points.constLast().x(), points.constLast().y() ).toQPointF() ); From 72391d42390ed9e0a0dcdcaf63650ceaf2adda42 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 18 Mar 2021 08:29:53 +1000 Subject: [PATCH 105/377] Add method to calculate total length of a QPolygonF line --- .../symbology/qgssymbollayerutils.sip.in | 7 +++++++ src/core/symbology/qgssymbollayerutils.cpp | 18 ++++++++++++++++++ src/core/symbology/qgssymbollayerutils.h | 7 +++++++ tests/src/python/test_qgssymbollayerutils.py | 11 +++++++++++ 4 files changed, 43 insertions(+) diff --git a/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in b/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in index 5c5e695ccefc..c82cefd94e07 100644 --- a/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in +++ b/python/core/auto_generated/symbology/qgssymbollayerutils.sip.in @@ -732,6 +732,13 @@ Calculate a point on the surface of a QPolygonF static bool pointInPolygon( const QPolygonF &points, QPointF point ); %Docstring Calculate whether a point is within of a QPolygonF +%End + + static double polylineLength( const QPolygonF &polyline ); +%Docstring +Returns the total length of a ``polyline``. + +.. versionadded:: 3.20 %End static QPolygonF polylineSubstring( const QPolygonF &polyline, double startOffset, double endOffset ); diff --git a/src/core/symbology/qgssymbollayerutils.cpp b/src/core/symbology/qgssymbollayerutils.cpp index 4e73ac729733..3bb076082ddd 100644 --- a/src/core/symbology/qgssymbollayerutils.cpp +++ b/src/core/symbology/qgssymbollayerutils.cpp @@ -4189,6 +4189,24 @@ bool QgsSymbolLayerUtils::pointInPolygon( const QPolygonF &points, QPointF point return inside; } +double QgsSymbolLayerUtils::polylineLength( const QPolygonF &polyline ) +{ + if ( polyline.size() < 2 ) + return 0; + + double totalLength = 0; + auto it = polyline.begin(); + QPointF p1 = *it++; + for ( ; it != polyline.end(); ++it ) + { + QPointF p2 = *it; + const double segmentLength = std::sqrt( std::pow( p1.x() - p2.x(), 2.0 ) + std::pow( p1.y() - p2.y(), 2.0 ) ); + totalLength += segmentLength; + p1 = p2; + } + return totalLength; +} + QPolygonF QgsSymbolLayerUtils::polylineSubstring( const QPolygonF &polyline, double startOffset, double endOffset ) { if ( polyline.size() < 2 ) diff --git a/src/core/symbology/qgssymbollayerutils.h b/src/core/symbology/qgssymbollayerutils.h index 5929abd11482..89675ca8619d 100644 --- a/src/core/symbology/qgssymbollayerutils.h +++ b/src/core/symbology/qgssymbollayerutils.h @@ -657,6 +657,13 @@ class CORE_EXPORT QgsSymbolLayerUtils //! Calculate whether a point is within of a QPolygonF static bool pointInPolygon( const QPolygonF &points, QPointF point ); + /** + * Returns the total length of a \a polyline. + * + * \since QGIS 3.20 + */ + static double polylineLength( const QPolygonF &polyline ); + /** * Returns the substring of a \a polyline which starts at \a startOffset from the beginning of the line * and ends at \a endOffset from the start of the line. diff --git a/tests/src/python/test_qgssymbollayerutils.py b/tests/src/python/test_qgssymbollayerutils.py index fb8ef086cd9e..d3291bf4b3d2 100644 --- a/tests/src/python/test_qgssymbollayerutils.py +++ b/tests/src/python/test_qgssymbollayerutils.py @@ -270,6 +270,17 @@ def testDecodeSldUom(self): decode = QgsSymbolLayerUtils.decodeSldUom("http://www.opengeospatial.org/se/units/pixel") self.assertEqual(decode, (QgsUnitTypes.RenderPixels, 1.0)) + def testPolylineLength(self): + """ + Test QgsSymbolLayerUtils.polylineLength + """ + self.assertEqual(QgsSymbolLayerUtils.polylineLength(QPolygonF()), 0.0) + self.assertEqual( + QgsSymbolLayerUtils.polylineLength(QPolygonF([QPointF(11, 12), QPointF(11, 12)])), 0.0) + self.assertEqual( + QgsSymbolLayerUtils.polylineLength(QPolygonF([QPointF(11, 2), QPointF(11, 12), QPointF(11, 12)])), 10.0) + self.assertEqual(QgsSymbolLayerUtils.polylineLength(QPolygonF([QPointF(11, 2), QPointF(11, 12), QPointF(111, 12)])), 110.0) + def testPolylineSubstring(self): res = QgsSymbolLayerUtils.polylineSubstring(QPolygonF(), 1, 2) # no crash self.assertFalse(res) From ac94c0445980c8833c7aab7435770e5d803035a3 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 18 Mar 2021 08:30:26 +1000 Subject: [PATCH 106/377] [feature] Add option to trim the start and end of simple line symbol layers by a preset amount This allows for the line rendering to trim off the first x mm and last y mm from the actual line string when drawing the line. It can be used eg when creating complex symbols where a line layer should not overlap marker symbol layers placed at the start and end of the line. The start/end trim distance supports a range of units, including percentage of the overall line length, and can be data defined for extra control. --- .../symbology/qgslinesymbollayer.sip.in | 194 +++++++- .../symbology/qgssymbollayer.sip.in | 2 + src/core/symbology/qgslinesymbollayer.cpp | 72 ++- src/core/symbology/qgslinesymbollayer.h | 166 ++++++- src/core/symbology/qgssymbollayer.cpp | 2 + src/core/symbology/qgssymbollayer.h | 4 +- src/gui/symbology/qgssymbollayerwidget.cpp | 54 +++ src/ui/symbollayer/widget_simpleline.ui | 451 +++++++++++------- .../python/test_qgssimplelinesymbollayer.py | 82 ++++ ...ed_simpleline_trim_distance_percentage.png | Bin 0 -> 433 bytes ...xpected_simpleline_trim_distance_units.png | Bin 0 -> 527 bytes 11 files changed, 858 insertions(+), 169 deletions(-) create mode 100644 tests/testdata/control_images/symbol_simpleline/expected_simpleline_trim_distance_percentage/expected_simpleline_trim_distance_percentage.png create mode 100644 tests/testdata/control_images/symbol_simpleline/expected_simpleline_trim_distance_units/expected_simpleline_trim_distance_units.png diff --git a/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in b/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in index 5bedfdbe2d01..e1c3cc70cc14 100644 --- a/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in @@ -271,7 +271,7 @@ Returns the units for the dash pattern offset. const QgsMapUnitScale &dashPatternOffsetMapUnitScale() const; %Docstring -Returns the map unit scale the dash pattern offset value. +Returns the map unit scale for the dash pattern offset value. .. seealso:: :py:func:`setDashPatternOffsetMapUnitScale` @@ -293,6 +293,198 @@ Sets the map unit ``scale`` for the dash pattern offset. .. seealso:: :py:func:`setDashPatternOffsetUnit` .. versionadded:: 3.16 +%End + + double trimDistanceStart() const; +%Docstring +Returns the trim distance for the start of the line, which dictates a length +from the start of the line at which the actual rendering should start. + +Trim units can be retrieved by calling :py:func:`~QgsSimpleLineSymbolLayer.trimDistanceStartUnit`. + +.. seealso:: :py:func:`setTrimDistanceStart` + +.. seealso:: :py:func:`trimDistanceEnd` + +.. seealso:: :py:func:`trimDistanceStartUnit` + +.. seealso:: :py:func:`trimDistanceStartMapUnitScale` + +.. versionadded:: 3.20 +%End + + void setTrimDistanceStart( double distance ); +%Docstring +Sets the trim ``distance`` for the start of the line, which dictates a length +from the start of the line at which the actual rendering should start. + +Trim units can be set by calling :py:func:`~QgsSimpleLineSymbolLayer.setTrimDistanceStartUnit`. + +.. seealso:: :py:func:`trimDistanceStart` + +.. seealso:: :py:func:`setTrimDistanceEnd` + +.. seealso:: :py:func:`setTrimDistanceStartUnit` + +.. seealso:: :py:func:`setTrimDistanceStartMapUnitScale` + +.. versionadded:: 3.20 +%End + + void setTrimDistanceStartUnit( QgsUnitTypes::RenderUnit unit ); +%Docstring +Sets the ``unit`` for the trim distance for the start of the line. + +.. seealso:: :py:func:`trimDistanceStartUnit` + +.. seealso:: :py:func:`setTrimDistanceEndUnit` + +.. seealso:: :py:func:`setTrimDistanceStart` + +.. seealso:: :py:func:`setTrimDistanceStartMapUnitScale` + +.. versionadded:: 3.20 +%End + + QgsUnitTypes::RenderUnit trimDistanceStartUnit() const; +%Docstring +Returns the unit for the trim distance for the start of the line. + +.. seealso:: :py:func:`setTrimDistanceStartUnit` + +.. seealso:: :py:func:`trimDistanceEndUnit` + +.. seealso:: :py:func:`trimDistanceStart` + +.. seealso:: :py:func:`trimDistanceStartMapUnitScale` + +.. versionadded:: 3.20 +%End + + const QgsMapUnitScale &trimDistanceStartMapUnitScale() const; +%Docstring +Returns the map unit scale for the trim distance for the start of the line. + +.. seealso:: :py:func:`setTrimDistanceStartMapUnitScale` + +.. seealso:: :py:func:`trimDistanceEndMapUnitUnit` + +.. seealso:: :py:func:`trimDistanceStart` + +.. seealso:: :py:func:`trimDistanceStartUnit` + +.. versionadded:: 3.20 +%End + + void setTrimDistanceStartMapUnitScale( const QgsMapUnitScale &scale ); +%Docstring +Sets the map unit ``scale`` for the trim distance for the start of the line. + +.. seealso:: :py:func:`trimDistanceStartMapUnitScale` + +.. seealso:: :py:func:`setTrimDistanceEndMapUnitUnit` + +.. seealso:: :py:func:`setTrimDistanceStart` + +.. seealso:: :py:func:`setTrimDistanceStartUnit` + +.. versionadded:: 3.20 +%End + + double trimDistanceEnd() const; +%Docstring +Returns the trim distance for the end of the line, which dictates a length +from the end of the line at which the actual rendering should end. + +Trim units can be retrieved by calling :py:func:`~QgsSimpleLineSymbolLayer.trimDistanceEndUnit`. + +.. seealso:: :py:func:`setTrimDistanceEnd` + +.. seealso:: :py:func:`trimDistanceStart` + +.. seealso:: :py:func:`trimDistanceEndUnit` + +.. seealso:: :py:func:`trimDistanceEndMapUnitScale` + +.. versionadded:: 3.20 +%End + + void setTrimDistanceEnd( double distance ); +%Docstring +Sets the trim ``distance`` for the end of the line, which dictates a length +from the end of the line at which the actual rendering should end. + +Trim units can be set by calling :py:func:`~QgsSimpleLineSymbolLayer.setTrimDistanceEndUnit`. + +.. seealso:: :py:func:`trimDistanceEnd` + +.. seealso:: :py:func:`setTrimDistanceStart` + +.. seealso:: :py:func:`setTrimDistanceEndUnit` + +.. seealso:: :py:func:`setTrimDistanceEndMapUnitScale` + +.. versionadded:: 3.20 +%End + + void setTrimDistanceEndUnit( QgsUnitTypes::RenderUnit unit ); +%Docstring +Sets the ``unit`` for the trim distance for the end of the line. + +.. seealso:: :py:func:`trimDistanceEndUnit` + +.. seealso:: :py:func:`setTrimDistanceStartUnit` + +.. seealso:: :py:func:`setTrimDistanceEnd` + +.. seealso:: :py:func:`setTrimDistanceEndMapUnitScale` + +.. versionadded:: 3.20 +%End + + QgsUnitTypes::RenderUnit trimDistanceEndUnit() const; +%Docstring +Returns the unit for the trim distance for the end of the line. + +.. seealso:: :py:func:`setTrimDistanceEndUnit` + +.. seealso:: :py:func:`trimDistanceStartUnit` + +.. seealso:: :py:func:`trimDistanceEnd` + +.. seealso:: :py:func:`trimDistanceEndMapUnitScale` + +.. versionadded:: 3.20 +%End + + const QgsMapUnitScale &trimDistanceEndMapUnitScale() const; +%Docstring +Returns the map unit scale for the trim distance for the end of the line. + +.. seealso:: :py:func:`setTrimDistanceEndMapUnitScale` + +.. seealso:: :py:func:`trimDistanceStartMapUnitUnit` + +.. seealso:: :py:func:`trimDistanceEnd` + +.. seealso:: :py:func:`trimDistanceEndUnit` + +.. versionadded:: 3.20 +%End + + void setTrimDistanceEndMapUnitScale( const QgsMapUnitScale &scale ); +%Docstring +Sets the map unit ``scale`` for the trim distance for the end of the line. + +.. seealso:: :py:func:`trimDistanceEndMapUnitScale` + +.. seealso:: :py:func:`setTrimDistanceStartMapUnitUnit` + +.. seealso:: :py:func:`setTrimDistanceEnd` + +.. seealso:: :py:func:`setTrimDistanceEndUnit` + +.. versionadded:: 3.20 %End bool drawInsidePolygon() const; diff --git a/python/core/auto_generated/symbology/qgssymbollayer.sip.in b/python/core/auto_generated/symbology/qgssymbollayer.sip.in index 57aa0f9e2751..903e81481c69 100644 --- a/python/core/auto_generated/symbology/qgssymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgssymbollayer.sip.in @@ -146,6 +146,8 @@ class QgsSymbolLayer PropertyFontFamily, PropertyFontStyle, PropertyDashPatternOffset, + PropertyTrimStart, + PropertyTrimEnd, }; static const QgsPropertiesDefinition &propertyDefinitions(); diff --git a/src/core/symbology/qgslinesymbollayer.cpp b/src/core/symbology/qgslinesymbollayer.cpp index af8af81cab9f..4ffda1dd3145 100644 --- a/src/core/symbology/qgslinesymbollayer.cpp +++ b/src/core/symbology/qgslinesymbollayer.cpp @@ -191,6 +191,19 @@ QgsSymbolLayer *QgsSimpleLineSymbolLayer::create( const QVariantMap &props ) if ( props.contains( QStringLiteral( "dash_pattern_offset_map_unit_scale" ) ) ) l->setDashPatternOffsetMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( props[QStringLiteral( "dash_pattern_offset_map_unit_scale" )].toString() ) ); + if ( props.contains( QStringLiteral( "trim_distance_start" ) ) ) + l->setTrimDistanceStart( props[QStringLiteral( "trim_distance_start" )].toDouble() ); + if ( props.contains( QStringLiteral( "trim_distance_start_unit" ) ) ) + l->setTrimDistanceStartUnit( QgsUnitTypes::decodeRenderUnit( props[QStringLiteral( "trim_distance_start_unit" )].toString() ) ); + if ( props.contains( QStringLiteral( "trim_distance_start_map_unit_scale" ) ) ) + l->setTrimDistanceStartMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( props[QStringLiteral( "trim_distance_start_map_unit_scale" )].toString() ) ); + if ( props.contains( QStringLiteral( "trim_distance_end" ) ) ) + l->setTrimDistanceEnd( props[QStringLiteral( "trim_distance_end" )].toDouble() ); + if ( props.contains( QStringLiteral( "trim_distance_end_unit" ) ) ) + l->setTrimDistanceEndUnit( QgsUnitTypes::decodeRenderUnit( props[QStringLiteral( "trim_distance_end_unit" )].toString() ) ); + if ( props.contains( QStringLiteral( "trim_distance_end_map_unit_scale" ) ) ) + l->setTrimDistanceEndMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( props[QStringLiteral( "trim_distance_end_map_unit_scale" )].toString() ) ); + if ( props.contains( QStringLiteral( "align_dash_pattern" ) ) ) l->setAlignDashPattern( props[ QStringLiteral( "align_dash_pattern" )].toInt() ); @@ -202,7 +215,6 @@ QgsSymbolLayer *QgsSimpleLineSymbolLayer::create( const QVariantMap &props ) return l; } - QString QgsSimpleLineSymbolLayer::layerType() const { return QStringLiteral( "SimpleLine" ); @@ -329,7 +341,7 @@ void QgsSimpleLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, con } -void QgsSimpleLineSymbolLayer::renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) +void QgsSimpleLineSymbolLayer::renderPolyline( const QPolygonF &pts, QgsSymbolRenderContext &context ) { QPainter *p = context.renderContext().painter(); if ( !p ) @@ -337,6 +349,46 @@ void QgsSimpleLineSymbolLayer::renderPolyline( const QPolygonF &points, QgsSymbo return; } + QPolygonF points = pts; + + double startTrim = mTrimDistanceStart; + if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyTrimStart ) ) + { + context.setOriginalValueVariable( startTrim ); + startTrim = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyTrimStart, context.renderContext().expressionContext(), mTrimDistanceStart ); + } + double endTrim = mTrimDistanceEnd; + if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyTrimEnd ) ) + { + context.setOriginalValueVariable( endTrim ); + endTrim = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyTrimEnd, context.renderContext().expressionContext(), mTrimDistanceEnd ); + } + + double totalLength = -1; + if ( mTrimDistanceStartUnit == QgsUnitTypes::RenderPercentage ) + { + totalLength = QgsSymbolLayerUtils::polylineLength( points ); + startTrim = startTrim * 0.01 * totalLength; + } + else + { + startTrim = context.renderContext().convertToPainterUnits( startTrim, mTrimDistanceStartUnit, mTrimDistanceStartMapUnitScale ); + } + if ( mTrimDistanceEndUnit == QgsUnitTypes::RenderPercentage ) + { + if ( totalLength < 0 ) // only recalculate if we didn't already work this out for the start distance! + totalLength = QgsSymbolLayerUtils::polylineLength( points ); + endTrim = endTrim * 0.01 * totalLength; + } + else + { + endTrim = context.renderContext().convertToPainterUnits( endTrim, mTrimDistanceEndUnit, mTrimDistanceEndMapUnitScale ); + } + if ( !qgsDoubleNear( startTrim, 0 ) || !qgsDoubleNear( endTrim, 0 ) ) + { + points = QgsSymbolLayerUtils::polylineSubstring( points, startTrim, -endTrim ); + } + QColor penColor = mColor; penColor.setAlphaF( mColor.alphaF() * context.opacity() ); mPen.setColor( penColor ); @@ -424,6 +476,12 @@ QVariantMap QgsSimpleLineSymbolLayer::properties() const map[QStringLiteral( "dash_pattern_offset" )] = QString::number( mDashPatternOffset ); map[QStringLiteral( "dash_pattern_offset_unit" )] = QgsUnitTypes::encodeUnit( mDashPatternOffsetUnit ); map[QStringLiteral( "dash_pattern_offset_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mDashPatternOffsetMapUnitScale ); + map[QStringLiteral( "trim_distance_start" )] = QString::number( mTrimDistanceStart ); + map[QStringLiteral( "trim_distance_start_unit" )] = QgsUnitTypes::encodeUnit( mTrimDistanceStartUnit ); + map[QStringLiteral( "trim_distance_start_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mTrimDistanceStartMapUnitScale ); + map[QStringLiteral( "trim_distance_end" )] = QString::number( mTrimDistanceEnd ); + map[QStringLiteral( "trim_distance_end_unit" )] = QgsUnitTypes::encodeUnit( mTrimDistanceEndUnit ); + map[QStringLiteral( "trim_distance_end_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mTrimDistanceEndMapUnitScale ); map[QStringLiteral( "draw_inside_polygon" )] = ( mDrawInsidePolygon ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ); map[QStringLiteral( "ring_filter" )] = QString::number( static_cast< int >( mRingFilter ) ); map[QStringLiteral( "align_dash_pattern" )] = mAlignDashPattern ? QStringLiteral( "1" ) : QStringLiteral( "0" ); @@ -450,6 +508,12 @@ QgsSimpleLineSymbolLayer *QgsSimpleLineSymbolLayer::clone() const l->setDashPatternOffset( mDashPatternOffset ); l->setDashPatternOffsetUnit( mDashPatternOffsetUnit ); l->setDashPatternOffsetMapUnitScale( mDashPatternOffsetMapUnitScale ); + l->setTrimDistanceStart( mTrimDistanceStart ); + l->setTrimDistanceStartUnit( mTrimDistanceStartUnit ); + l->setTrimDistanceStartMapUnitScale( mTrimDistanceStartMapUnitScale ); + l->setTrimDistanceEnd( mTrimDistanceEnd ); + l->setTrimDistanceEndUnit( mTrimDistanceEndUnit ); + l->setTrimDistanceEndMapUnitScale( mTrimDistanceEndMapUnitScale ); l->setAlignDashPattern( mAlignDashPattern ); l->setTweakDashPatternOnCorners( mPatternCartographicTweakOnSharpCorners ); @@ -612,7 +676,7 @@ void QgsSimpleLineSymbolLayer::applyDataDefinedSymbology( QgsSymbolRenderContext //re-scale pattern vector after data defined pen width was applied QVector scaledVector; - for ( double v : mCustomDashVector ) + for ( double v : qgis::as_const( mCustomDashVector ) ) { //the dash is specified in terms of pen widths, therefore the division scaledVector << context.renderContext().convertToPainterUnits( v, mCustomDashPatternUnit, mCustomDashPatternMapUnitScale ) / dashWidthDiv; @@ -624,7 +688,7 @@ void QgsSimpleLineSymbolLayer::applyDataDefinedSymbology( QgsSymbolRenderContext double patternOffset = mDashPatternOffset; if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyDashPatternOffset ) && pen.style() != Qt::SolidLine ) { - context.setOriginalValueVariable( mDashPatternOffset ); + context.setOriginalValueVariable( patternOffset ); patternOffset = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyDashPatternOffset, context.renderContext().expressionContext(), mDashPatternOffset ); pen.setDashOffset( context.renderContext().convertToPainterUnits( patternOffset, mDashPatternOffsetUnit, mDashPatternOffsetMapUnitScale ) / dashWidthDiv ); } diff --git a/src/core/symbology/qgslinesymbollayer.h b/src/core/symbology/qgslinesymbollayer.h index 0a287d2b61b4..c3c570f9e941 100644 --- a/src/core/symbology/qgslinesymbollayer.h +++ b/src/core/symbology/qgslinesymbollayer.h @@ -247,7 +247,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer QgsUnitTypes::RenderUnit dashPatternOffsetUnit() const { return mDashPatternOffsetUnit; } /** - * Returns the map unit scale the dash pattern offset value. + * Returns the map unit scale for the dash pattern offset value. * * \see setDashPatternOffsetMapUnitScale() * \see dashPatternOffsetUnit() @@ -268,6 +268,162 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer */ void setDashPatternOffsetMapUnitScale( const QgsMapUnitScale &scale ) { mDashPatternOffsetMapUnitScale = scale; } + /** + * Returns the trim distance for the start of the line, which dictates a length + * from the start of the line at which the actual rendering should start. + * + * Trim units can be retrieved by calling trimDistanceStartUnit(). + * + * \see setTrimDistanceStart() + * \see trimDistanceEnd() + * \see trimDistanceStartUnit() + * \see trimDistanceStartMapUnitScale() + * + * \since QGIS 3.20 + */ + double trimDistanceStart() const { return mTrimDistanceStart; } + + /** + * Sets the trim \a distance for the start of the line, which dictates a length + * from the start of the line at which the actual rendering should start. + * + * Trim units can be set by calling setTrimDistanceStartUnit(). + * + * \see trimDistanceStart() + * \see setTrimDistanceEnd() + * \see setTrimDistanceStartUnit() + * \see setTrimDistanceStartMapUnitScale() + * + * \since QGIS 3.20 + */ + void setTrimDistanceStart( double distance ) { mTrimDistanceStart = distance; } + + /** + * Sets the \a unit for the trim distance for the start of the line. + * + * \see trimDistanceStartUnit() + * \see setTrimDistanceEndUnit() + * \see setTrimDistanceStart() + * \see setTrimDistanceStartMapUnitScale() + * + * \since QGIS 3.20 + */ + void setTrimDistanceStartUnit( QgsUnitTypes::RenderUnit unit ) { mTrimDistanceStartUnit = unit; } + + /** + * Returns the unit for the trim distance for the start of the line. + * + * \see setTrimDistanceStartUnit() + * \see trimDistanceEndUnit() + * \see trimDistanceStart() + * \see trimDistanceStartMapUnitScale() + * + * \since QGIS 3.20 + */ + QgsUnitTypes::RenderUnit trimDistanceStartUnit() const { return mTrimDistanceStartUnit; } + + /** + * Returns the map unit scale for the trim distance for the start of the line. + * + * \see setTrimDistanceStartMapUnitScale() + * \see trimDistanceEndMapUnitUnit() + * \see trimDistanceStart() + * \see trimDistanceStartUnit() + * + * \since QGIS 3.20 + */ + const QgsMapUnitScale &trimDistanceStartMapUnitScale() const { return mTrimDistanceStartMapUnitScale; } + + /** + * Sets the map unit \a scale for the trim distance for the start of the line. + * + * \see trimDistanceStartMapUnitScale() + * \see setTrimDistanceEndMapUnitUnit() + * \see setTrimDistanceStart() + * \see setTrimDistanceStartUnit() + * + * \since QGIS 3.20 + */ + void setTrimDistanceStartMapUnitScale( const QgsMapUnitScale &scale ) { mTrimDistanceStartMapUnitScale = scale; } + + /** + * Returns the trim distance for the end of the line, which dictates a length + * from the end of the line at which the actual rendering should end. + * + * Trim units can be retrieved by calling trimDistanceEndUnit(). + * + * \see setTrimDistanceEnd() + * \see trimDistanceStart() + * \see trimDistanceEndUnit() + * \see trimDistanceEndMapUnitScale() + * + * \since QGIS 3.20 + */ + double trimDistanceEnd() const { return mTrimDistanceEnd; } + + /** + * Sets the trim \a distance for the end of the line, which dictates a length + * from the end of the line at which the actual rendering should end. + * + * Trim units can be set by calling setTrimDistanceEndUnit(). + * + * \see trimDistanceEnd() + * \see setTrimDistanceStart() + * \see setTrimDistanceEndUnit() + * \see setTrimDistanceEndMapUnitScale() + * + * \since QGIS 3.20 + */ + void setTrimDistanceEnd( double distance ) { mTrimDistanceEnd = distance; } + + /** + * Sets the \a unit for the trim distance for the end of the line. + * + * \see trimDistanceEndUnit() + * \see setTrimDistanceStartUnit() + * \see setTrimDistanceEnd() + * \see setTrimDistanceEndMapUnitScale() + * + * \since QGIS 3.20 + */ + void setTrimDistanceEndUnit( QgsUnitTypes::RenderUnit unit ) { mTrimDistanceEndUnit = unit; } + + /** + * Returns the unit for the trim distance for the end of the line. + * + * \see setTrimDistanceEndUnit() + * \see trimDistanceStartUnit() + * \see trimDistanceEnd() + * \see trimDistanceEndMapUnitScale() + * + * \since QGIS 3.20 + */ + QgsUnitTypes::RenderUnit trimDistanceEndUnit() const { return mTrimDistanceEndUnit; } + + /** + * Returns the map unit scale for the trim distance for the end of the line. + * + * \see setTrimDistanceEndMapUnitScale() + * \see trimDistanceStartMapUnitUnit() + * \see trimDistanceEnd() + * \see trimDistanceEndUnit() + * + * \since QGIS 3.20 + */ + const QgsMapUnitScale &trimDistanceEndMapUnitScale() const { return mTrimDistanceEndMapUnitScale; } + + /** + * Sets the map unit \a scale for the trim distance for the end of the line. + * + * \see trimDistanceEndMapUnitScale() + * \see setTrimDistanceStartMapUnitUnit() + * \see setTrimDistanceEnd() + * \see setTrimDistanceEndUnit() + * + * \since QGIS 3.20 + */ + void setTrimDistanceEndMapUnitScale( const QgsMapUnitScale &scale ) { mTrimDistanceEndMapUnitScale = scale; } + /** * Returns TRUE if the line should only be drawn inside polygons, and any portion * of the line which falls outside the polygon should be clipped away. @@ -352,6 +508,14 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer QgsUnitTypes::RenderUnit mDashPatternOffsetUnit = QgsUnitTypes::RenderMillimeters; QgsMapUnitScale mDashPatternOffsetMapUnitScale; + double mTrimDistanceStart = 0; + QgsUnitTypes::RenderUnit mTrimDistanceStartUnit = QgsUnitTypes::RenderMillimeters; + QgsMapUnitScale mTrimDistanceStartMapUnitScale; + + double mTrimDistanceEnd = 0; + QgsUnitTypes::RenderUnit mTrimDistanceEndUnit = QgsUnitTypes::RenderMillimeters; + QgsMapUnitScale mTrimDistanceEndMapUnitScale; + //! Vector with an even number of entries for the QVector mCustomDashVector; diff --git a/src/core/symbology/qgssymbollayer.cpp b/src/core/symbology/qgssymbollayer.cpp index 620d74f43498..33adb39132a9 100644 --- a/src/core/symbology/qgssymbollayer.cpp +++ b/src/core/symbology/qgssymbollayer.cpp @@ -107,6 +107,8 @@ void QgsSymbolLayer::initPropertyDefinitions() { QgsSymbolLayer::PropertyClipPoints, QgsPropertyDefinition( "clipPoints", QObject::tr( "Clip markers" ), QgsPropertyDefinition::Boolean, origin )}, { QgsSymbolLayer::PropertyClipPoints, QgsPropertyDefinition( "densityArea", QObject::tr( "Density area" ), QgsPropertyDefinition::DoublePositive, origin )}, { QgsSymbolLayer::PropertyDashPatternOffset, QgsPropertyDefinition( "dashPatternOffset", QObject::tr( "Dash pattern offset" ), QgsPropertyDefinition::DoublePositive, origin )}, + { QgsSymbolLayer::PropertyTrimStart, QgsPropertyDefinition( "trimStart", QObject::tr( "Start trim distance" ), QgsPropertyDefinition::DoublePositive, origin )}, + { QgsSymbolLayer::PropertyTrimEnd, QgsPropertyDefinition( "trimEnd", QObject::tr( "End trim distance" ), QgsPropertyDefinition::DoublePositive, origin )}, }; } diff --git a/src/core/symbology/qgssymbollayer.h b/src/core/symbology/qgssymbollayer.h index 89e23f5efe20..6e1ea147adc6 100644 --- a/src/core/symbology/qgssymbollayer.h +++ b/src/core/symbology/qgssymbollayer.h @@ -188,7 +188,9 @@ class CORE_EXPORT QgsSymbolLayer PropertyDensityArea, //!< Density area PropertyFontFamily, //!< Font family PropertyFontStyle, //!< Font style - PropertyDashPatternOffset, //!< Dash pattern offset + PropertyDashPatternOffset, //!< Dash pattern offset, + PropertyTrimStart, //!< Trim distance from start of line (since QGIS 3.20) + PropertyTrimEnd, //!< Trim distance from end of line (since QGIS 3.20) }; /** diff --git a/src/gui/symbology/qgssymbollayerwidget.cpp b/src/gui/symbology/qgssymbollayerwidget.cpp index 8c2595bffab6..5826b4e479a3 100644 --- a/src/gui/symbology/qgssymbollayerwidget.cpp +++ b/src/gui/symbology/qgssymbollayerwidget.cpp @@ -232,6 +232,10 @@ QgsSimpleLineSymbolLayerWidget::QgsSimpleLineSymbolLayerWidget( QgsVectorLayer * << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); mPatternOffsetUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); + mTrimDistanceStartUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels + << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches << QgsUnitTypes::RenderPercentage ); + mTrimDistanceEndUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels + << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches << QgsUnitTypes::RenderPercentage ); btnChangeColor->setAllowOpacity( true ); btnChangeColor->setColorDialogTitle( tr( "Select Line Color" ) ); @@ -254,6 +258,9 @@ QgsSimpleLineSymbolLayerWidget::QgsSimpleLineSymbolLayerWidget( QgsVectorLayer * spinOffset->setClearValue( 0.0 ); spinPatternOffset->setClearValue( 0.0 ); + mTrimStartDistanceSpin->setClearValue( 0.0 ); + mTrimDistanceEndSpin->setClearValue( 0.0 ); + //make a temporary symbol for the size assistant preview mAssistantPreviewSymbol.reset( new QgsLineSymbol() ); @@ -268,6 +275,42 @@ QgsSimpleLineSymbolLayerWidget::QgsSimpleLineSymbolLayerWidget( QgsVectorLayer * connect( cboJoinStyle, static_cast( &QComboBox::currentIndexChanged ), this, &QgsSimpleLineSymbolLayerWidget::penStyleChanged ); connect( spinPatternOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimpleLineSymbolLayerWidget::patternOffsetChanged ); + connect( mTrimStartDistanceSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value ) + { + if ( !mLayer ) + return; + + mLayer->setTrimDistanceStart( value ); + emit changed(); + } ); + connect( mTrimDistanceStartUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ] + { + if ( !mLayer ) + return; + + mLayer->setTrimDistanceStartUnit( mTrimDistanceStartUnitWidget->unit() ); + mLayer->setTrimDistanceStartMapUnitScale( mTrimDistanceStartUnitWidget->getMapUnitScale() ); + emit changed(); + } ); + connect( mTrimDistanceEndSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value ) + { + if ( !mLayer ) + return; + + mLayer->setTrimDistanceEnd( value ); + emit changed(); + } ); + connect( mTrimDistanceEndUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ] + { + if ( !mLayer ) + return; + + mLayer->setTrimDistanceEndUnit( mTrimDistanceEndUnitWidget->unit() ); + mLayer->setTrimDistanceEndMapUnitScale( mTrimDistanceEndUnitWidget->getMapUnitScale() ); + emit changed(); + } ); + + updatePatternIcon(); connect( this, &QgsSymbolLayerWidget::changed, this, &QgsSimpleLineSymbolLayerWidget::updateAssistantSymbol ); @@ -310,6 +353,10 @@ void QgsSimpleLineSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer ) whileBlocking( mPatternOffsetUnitWidget )->setUnit( mLayer->dashPatternOffsetUnit() ); whileBlocking( mPatternOffsetUnitWidget )->setMapUnitScale( mLayer->dashPatternOffsetMapUnitScale() ); + whileBlocking( mTrimDistanceStartUnitWidget )->setUnit( mLayer->trimDistanceStartUnit() ); + whileBlocking( mTrimDistanceStartUnitWidget )->setMapUnitScale( mLayer->trimDistanceStartMapUnitScale() ); + whileBlocking( mTrimDistanceEndUnitWidget )->setUnit( mLayer->trimDistanceEndUnit() ); + whileBlocking( mTrimDistanceEndUnitWidget )->setMapUnitScale( mLayer->trimDistanceEndMapUnitScale() ); // set values spinWidth->blockSignals( true ); @@ -331,6 +378,8 @@ void QgsSimpleLineSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer ) cboJoinStyle->blockSignals( false ); cboCapStyle->blockSignals( false ); whileBlocking( spinPatternOffset )->setValue( mLayer->dashPatternOffset() ); + whileBlocking( mTrimStartDistanceSpin )->setValue( mLayer->trimDistanceStart() ); + whileBlocking( mTrimDistanceEndSpin )->setValue( mLayer->trimDistanceEnd() ); //use a custom dash pattern? bool useCustomDashPattern = mLayer->useCustomDashPattern(); @@ -366,6 +415,8 @@ void QgsSimpleLineSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer ) registerDataDefinedButton( mJoinStyleDDBtn, QgsSymbolLayer::PropertyJoinStyle ); registerDataDefinedButton( mCapStyleDDBtn, QgsSymbolLayer::PropertyCapStyle ); registerDataDefinedButton( mPatternOffsetDDBtn, QgsSymbolLayer::PropertyDashPatternOffset ); + registerDataDefinedButton( mTrimDistanceStartDDBtn, QgsSymbolLayer::PropertyTrimStart ); + registerDataDefinedButton( mTrimDistanceEndDDBtn, QgsSymbolLayer::PropertyTrimEnd ); updateAssistantSymbol(); } @@ -390,6 +441,9 @@ void QgsSimpleLineSymbolLayerWidget::setContext( const QgsSymbolWidgetContext &c break; case QgsSymbol::Fill: + mTrimGroupBox->hide(); + break; + case QgsSymbol::Hybrid: break; } diff --git a/src/ui/symbollayer/widget_simpleline.ui b/src/ui/symbollayer/widget_simpleline.ui index 9d459e2c81c4..d3844a683426 100644 --- a/src/ui/symbollayer/widget_simpleline.ui +++ b/src/ui/symbollayer/widget_simpleline.ui @@ -6,23 +6,79 @@ 0 0 - 325 - 449 + 432 + 563
Form - - + + - Pattern offset + - - + + + + + + + 1 + 0 + + + + Hairline + + + 6 + + + 100000.000000000000000 + + + 0.200000000000000 + + + 1.000000000000000 + + + true + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + + + + + + Stroke style + + + + + + + Join style + + @@ -31,6 +87,47 @@ + + + + Color + + + + + + + + + + Use custom dash pattern + + + + + + + Stroke width + + + + + + + Cap style + + + + + + + If enabled, the dash pattern for the line will be dynamically refined over sharp corners + + + Tweak dash pattern at sharp corners + + + @@ -71,26 +168,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - @@ -116,38 +193,19 @@ - - - - - - - - - - - - - + + - - - - Rings - - + + - - - - Stroke width - - + + - - + + - + 1 @@ -172,7 +230,7 @@ - + 0 @@ -186,27 +244,10 @@ - - - - - - - - - - - - - - - - - - - + + - + 1 @@ -231,58 +272,7 @@ - - - - 0 - 0 - - - - Qt::StrongFocus - - - - - - - - - - - - - - - - - - 1 - 0 - - - - Hairline - - - 6 - - - 100000.000000000000000 - - - 0.200000000000000 - - - 1.000000000000000 - - - true - - - - - + 0 @@ -303,80 +293,211 @@ - - - - If enabled, the dash pattern sizes will be dynamically tweaked to ensure that the end of the line is represented by a complete dash element + + + + Pattern offset + + + + - Align dash pattern to line length + Rings - - + + - Join style + - - + + - Cap style + Draw line only inside polygon - - + + - Color + - - + + - Use custom dash pattern + - - + + - Offset + - - + + + + If enabled, the dash pattern sizes will be dynamically tweaked to ensure that the end of the line is represented by a complete dash element + - Draw line only inside polygon + Align dash pattern to line length - - + + - Stroke style + Offset - - + + - - - - If enabled, the dash pattern for the line will be dynamically refined over sharp corners + + + + Qt::Vertical - - Tweak dash pattern at sharp corners + + + 20 + 40 + + + + + + + + Trim Lines + + + + + + + + + + + + + + + 1 + 0 + + + + 6 + + + 100000.000000000000000 + + + 0.200000000000000 + + + 0.000000000000000 + + + true + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + + + + + + + + + 1 + 0 + + + + 6 + + + 100000.000000000000000 + + + 0.200000000000000 + + + 0.000000000000000 + + + true + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + + + + + + Start + + + + + + + End + + + + + + + + + + + @@ -419,6 +540,12 @@ QComboBox
qgspenstylecombobox.h
+ + QgsCollapsibleGroupBoxBasic + QGroupBox +
qgscollapsiblegroupbox.h
+ 1 +
btnChangeColor diff --git a/tests/src/python/test_qgssimplelinesymbollayer.py b/tests/src/python/test_qgssimplelinesymbollayer.py index 30d41fd4fc09..dfe22517da4b 100644 --- a/tests/src/python/test_qgssimplelinesymbollayer.py +++ b/tests/src/python/test_qgssimplelinesymbollayer.py @@ -83,6 +83,88 @@ def testDashPatternWithDataDefinedWidth(self): rendered_image = self.renderGeometry(s, g) assert self.imageCheck('simpleline_dashpattern_datadefined_width', 'simpleline_dashpattern_datadefined_width', rendered_image) + def testTrimDistance(self): + s = QgsLineSymbol.createSimple({'outline_color': '#ff0000', 'outline_width': '0.6'}) + + s.symbolLayer(0).setTrimDistanceStart(1.2) + s.symbolLayer(0).setTrimDistanceStartUnit(QgsUnitTypes.RenderPoints) + s.symbolLayer(0).setTrimDistanceStartMapUnitScale(QgsMapUnitScale(5, 10)) + s.symbolLayer(0).setTrimDistanceEnd(3.2) + s.symbolLayer(0).setTrimDistanceEndUnit(QgsUnitTypes.RenderPercentage) + s.symbolLayer(0).setTrimDistanceEndMapUnitScale(QgsMapUnitScale(15, 20)) + + s2 = s.clone() + self.assertEqual(s2.symbolLayer(0).trimDistanceStart(), 1.2) + self.assertEqual(s2.symbolLayer(0).trimDistanceStartUnit(), QgsUnitTypes.RenderPoints) + self.assertEqual(s2.symbolLayer(0).trimDistanceStartMapUnitScale().minScale, 5) + self.assertEqual(s2.symbolLayer(0).trimDistanceStartMapUnitScale().maxScale, 10) + self.assertEqual(s2.symbolLayer(0).trimDistanceEnd(), 3.2) + self.assertEqual(s2.symbolLayer(0).trimDistanceEndUnit(), QgsUnitTypes.RenderPercentage) + self.assertEqual(s2.symbolLayer(0).trimDistanceEndMapUnitScale().minScale, 15) + self.assertEqual(s2.symbolLayer(0).trimDistanceEndMapUnitScale().maxScale, 20) + + doc = QDomDocument() + context = QgsReadWriteContext() + element = QgsSymbolLayerUtils.saveSymbol('test', s, doc, context) + + s2 = QgsSymbolLayerUtils.loadSymbol(element, context) + self.assertEqual(s2.symbolLayer(0).trimDistanceStart(), 1.2) + self.assertEqual(s2.symbolLayer(0).trimDistanceStartUnit(), QgsUnitTypes.RenderPoints) + self.assertEqual(s2.symbolLayer(0).trimDistanceStartMapUnitScale().minScale, 5) + self.assertEqual(s2.symbolLayer(0).trimDistanceStartMapUnitScale().maxScale, 10) + self.assertEqual(s2.symbolLayer(0).trimDistanceEnd(), 3.2) + self.assertEqual(s2.symbolLayer(0).trimDistanceEndUnit(), QgsUnitTypes.RenderPercentage) + self.assertEqual(s2.symbolLayer(0).trimDistanceEndMapUnitScale().minScale, 15) + self.assertEqual(s2.symbolLayer(0).trimDistanceEndMapUnitScale().maxScale, 20) + + def testTrimDistanceRender(self): + """ + Rendering test of trim distances + """ + s = QgsLineSymbol.createSimple({'outline_color': '#ff0000', 'outline_width': '2'}) + + s.symbolLayer(0).setTrimDistanceStart(150) + s.symbolLayer(0).setTrimDistanceStartUnit(QgsUnitTypes.RenderPoints) + s.symbolLayer(0).setTrimDistanceEnd(9) + s.symbolLayer(0).setTrimDistanceEndUnit(QgsUnitTypes.RenderMillimeters) + + g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)') + rendered_image = self.renderGeometry(s, g) + assert self.imageCheck('simpleline_trim_distance_units', 'simpleline_trim_distance_units', rendered_image) + + def testTrimDistanceRenderPercentage(self): + """ + Rendering test of trim distances using percentage + """ + s = QgsLineSymbol.createSimple({'outline_color': '#ff0000', 'outline_width': '2'}) + + s.symbolLayer(0).setTrimDistanceStart(10) + s.symbolLayer(0).setTrimDistanceStartUnit(QgsUnitTypes.RenderPercentage) + s.symbolLayer(0).setTrimDistanceEnd(50) + s.symbolLayer(0).setTrimDistanceEndUnit(QgsUnitTypes.RenderPercentage) + + g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)') + rendered_image = self.renderGeometry(s, g) + assert self.imageCheck('simpleline_trim_distance_percentage', 'simpleline_trim_distance_percentage', rendered_image) + + def testTrimDistanceRenderDataDefined(self): + """ + Rendering test of trim distances using data defined lengths + """ + s = QgsLineSymbol.createSimple({'outline_color': '#ff0000', 'outline_width': '2'}) + + s.symbolLayer(0).setTrimDistanceStart(1) + s.symbolLayer(0).setTrimDistanceStartUnit(QgsUnitTypes.RenderPercentage) + s.symbolLayer(0).setTrimDistanceEnd(5) + s.symbolLayer(0).setTrimDistanceEndUnit(QgsUnitTypes.RenderPercentage) + + s.symbolLayer(0).setDataDefinedProperty(QgsSymbolLayer.PropertyTrimStart, QgsProperty.fromExpression('5*2')) + s.symbolLayer(0).setDataDefinedProperty(QgsSymbolLayer.PropertyTrimEnd, QgsProperty.fromExpression('60-10')) + + g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)') + rendered_image = self.renderGeometry(s, g) + assert self.imageCheck('simpleline_trim_distance_percentage', 'simpleline_trim_distance_percentage', rendered_image) + def testDashPatternOffset(self): s = QgsLineSymbol.createSimple({'outline_color': '#ff0000', 'outline_width': '0.6'}) diff --git a/tests/testdata/control_images/symbol_simpleline/expected_simpleline_trim_distance_percentage/expected_simpleline_trim_distance_percentage.png b/tests/testdata/control_images/symbol_simpleline/expected_simpleline_trim_distance_percentage/expected_simpleline_trim_distance_percentage.png new file mode 100644 index 0000000000000000000000000000000000000000..cb5c59343a2ebe5f5bd7008941d87d9385de8abd GIT binary patch literal 433 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k2}mkgS)K$^oCO|{#S9F5M?jcysy3fA0|R5S zr;B4q#hkZS4EdT3L|7e#pZ*JP(~_OolaSgq^V8|0+F^3cK)vLEiru+i8SZ7ieD4UA7FVYTm2bcD614mER~<~c0~G-aj}jDx1|$NolHPY8 WGqQ Date: Thu, 18 Mar 2021 08:59:11 +1000 Subject: [PATCH 107/377] Fix see also links --- .../auto_generated/symbology/qgslinesymbollayer.sip.in | 8 ++++---- src/core/symbology/qgslinesymbollayer.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in b/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in index e1c3cc70cc14..c6ec7917a69f 100644 --- a/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in @@ -367,7 +367,7 @@ Returns the map unit scale for the trim distance for the start of the line. .. seealso:: :py:func:`setTrimDistanceStartMapUnitScale` -.. seealso:: :py:func:`trimDistanceEndMapUnitUnit` +.. seealso:: :py:func:`trimDistanceEndMapUnit` .. seealso:: :py:func:`trimDistanceStart` @@ -382,7 +382,7 @@ Sets the map unit ``scale`` for the trim distance for the start of the line. .. seealso:: :py:func:`trimDistanceStartMapUnitScale` -.. seealso:: :py:func:`setTrimDistanceEndMapUnitUnit` +.. seealso:: :py:func:`setTrimDistanceEndMapUnit` .. seealso:: :py:func:`setTrimDistanceStart` @@ -463,7 +463,7 @@ Returns the map unit scale for the trim distance for the end of the line. .. seealso:: :py:func:`setTrimDistanceEndMapUnitScale` -.. seealso:: :py:func:`trimDistanceStartMapUnitUnit` +.. seealso:: :py:func:`trimDistanceStartMapUnit` .. seealso:: :py:func:`trimDistanceEnd` @@ -478,7 +478,7 @@ Sets the map unit ``scale`` for the trim distance for the end of the line. .. seealso:: :py:func:`trimDistanceEndMapUnitScale` -.. seealso:: :py:func:`setTrimDistanceStartMapUnitUnit` +.. seealso:: :py:func:`setTrimDistanceStartMapUnit` .. seealso:: :py:func:`setTrimDistanceEnd` diff --git a/src/core/symbology/qgslinesymbollayer.h b/src/core/symbology/qgslinesymbollayer.h index c3c570f9e941..2e8b5bf3b1fd 100644 --- a/src/core/symbology/qgslinesymbollayer.h +++ b/src/core/symbology/qgslinesymbollayer.h @@ -326,7 +326,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer * Returns the map unit scale for the trim distance for the start of the line. * * \see setTrimDistanceStartMapUnitScale() - * \see trimDistanceEndMapUnitUnit() + * \see trimDistanceEndMapUnit() * \see trimDistanceStart() * \see trimDistanceStartUnit() * @@ -338,7 +338,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer * Sets the map unit \a scale for the trim distance for the start of the line. * * \see trimDistanceStartMapUnitScale() - * \see setTrimDistanceEndMapUnitUnit() + * \see setTrimDistanceEndMapUnit() * \see setTrimDistanceStart() * \see setTrimDistanceStartUnit() * @@ -404,7 +404,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer * Returns the map unit scale for the trim distance for the end of the line. * * \see setTrimDistanceEndMapUnitScale() - * \see trimDistanceStartMapUnitUnit() + * \see trimDistanceStartMapUnit() * \see trimDistanceEnd() * \see trimDistanceEndUnit() * @@ -416,7 +416,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer * Sets the map unit \a scale for the trim distance for the end of the line. * * \see trimDistanceEndMapUnitScale() - * \see setTrimDistanceStartMapUnitUnit() + * \see setTrimDistanceStartMapUnit() * \see setTrimDistanceEnd() * \see setTrimDistanceEndUnit() * From 56e2ac8aaf9b825e49ea4a93934d185ea7737ed4 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 18 Mar 2021 09:18:00 +1000 Subject: [PATCH 108/377] Don't hide trim option for polygon outlines --- src/gui/symbology/qgssymbollayerwidget.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/gui/symbology/qgssymbollayerwidget.cpp b/src/gui/symbology/qgssymbollayerwidget.cpp index 5826b4e479a3..ae9c23a75628 100644 --- a/src/gui/symbology/qgssymbollayerwidget.cpp +++ b/src/gui/symbology/qgssymbollayerwidget.cpp @@ -441,9 +441,6 @@ void QgsSimpleLineSymbolLayerWidget::setContext( const QgsSymbolWidgetContext &c break; case QgsSymbol::Fill: - mTrimGroupBox->hide(); - break; - case QgsSymbol::Hybrid: break; } From 34581efb74b82a56fa8ae85d7750b9bfc0d94317 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 18 Mar 2021 09:19:58 +1000 Subject: [PATCH 109/377] More see also fixes --- .../auto_generated/symbology/qgslinesymbollayer.sip.in | 8 ++++---- src/core/symbology/qgslinesymbollayer.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in b/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in index c6ec7917a69f..9f3973f9bfaa 100644 --- a/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgslinesymbollayer.sip.in @@ -367,7 +367,7 @@ Returns the map unit scale for the trim distance for the start of the line. .. seealso:: :py:func:`setTrimDistanceStartMapUnitScale` -.. seealso:: :py:func:`trimDistanceEndMapUnit` +.. seealso:: :py:func:`trimDistanceEndMapUnitScale` .. seealso:: :py:func:`trimDistanceStart` @@ -382,7 +382,7 @@ Sets the map unit ``scale`` for the trim distance for the start of the line. .. seealso:: :py:func:`trimDistanceStartMapUnitScale` -.. seealso:: :py:func:`setTrimDistanceEndMapUnit` +.. seealso:: :py:func:`setTrimDistanceEndMapUnitScale` .. seealso:: :py:func:`setTrimDistanceStart` @@ -463,7 +463,7 @@ Returns the map unit scale for the trim distance for the end of the line. .. seealso:: :py:func:`setTrimDistanceEndMapUnitScale` -.. seealso:: :py:func:`trimDistanceStartMapUnit` +.. seealso:: :py:func:`trimDistanceStartMapUnitScale` .. seealso:: :py:func:`trimDistanceEnd` @@ -478,7 +478,7 @@ Sets the map unit ``scale`` for the trim distance for the end of the line. .. seealso:: :py:func:`trimDistanceEndMapUnitScale` -.. seealso:: :py:func:`setTrimDistanceStartMapUnit` +.. seealso:: :py:func:`setTrimDistanceStartMapUnitScale` .. seealso:: :py:func:`setTrimDistanceEnd` diff --git a/src/core/symbology/qgslinesymbollayer.h b/src/core/symbology/qgslinesymbollayer.h index 2e8b5bf3b1fd..5f51cb9eb816 100644 --- a/src/core/symbology/qgslinesymbollayer.h +++ b/src/core/symbology/qgslinesymbollayer.h @@ -326,7 +326,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer * Returns the map unit scale for the trim distance for the start of the line. * * \see setTrimDistanceStartMapUnitScale() - * \see trimDistanceEndMapUnit() + * \see trimDistanceEndMapUnitScale() * \see trimDistanceStart() * \see trimDistanceStartUnit() * @@ -338,7 +338,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer * Sets the map unit \a scale for the trim distance for the start of the line. * * \see trimDistanceStartMapUnitScale() - * \see setTrimDistanceEndMapUnit() + * \see setTrimDistanceEndMapUnitScale() * \see setTrimDistanceStart() * \see setTrimDistanceStartUnit() * @@ -404,7 +404,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer * Returns the map unit scale for the trim distance for the end of the line. * * \see setTrimDistanceEndMapUnitScale() - * \see trimDistanceStartMapUnit() + * \see trimDistanceStartMapUnitScale() * \see trimDistanceEnd() * \see trimDistanceEndUnit() * @@ -416,7 +416,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer * Sets the map unit \a scale for the trim distance for the end of the line. * * \see trimDistanceEndMapUnitScale() - * \see setTrimDistanceStartMapUnit() + * \see setTrimDistanceStartMapUnitScale() * \see setTrimDistanceEnd() * \see setTrimDistanceEndUnit() * From 9ae8f2c3dd96e2b7c3312c0889299824fae92c4c Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 18 Mar 2021 09:47:52 +1000 Subject: [PATCH 110/377] [FEATURE] When the "show pinned labels" option is enabled, also highlight any pinned callout start or end points This allows users to immediately see which callouts points have been manually placed vs are automatically placed. --- .../auto_generated/callouts/qgscallout.sip.in | 8 ++- .../labeling/qgscalloutposition.sip.in | 44 ++++++++++++ src/app/labeling/qgsmaptoolpinlabels.cpp | 52 +++++++++++--- src/app/labeling/qgsmaptoolpinlabels.h | 5 ++ src/core/callouts/qgscallout.cpp | 29 +++++--- src/core/callouts/qgscallout.h | 9 ++- src/core/labeling/qgscalloutposition.h | 43 ++++++++++++ tests/src/core/testqgslabelingengine.cpp | 68 +++++++++++++++---- 8 files changed, 223 insertions(+), 35 deletions(-) diff --git a/python/core/auto_generated/callouts/qgscallout.sip.in b/python/core/auto_generated/callouts/qgscallout.sip.in index b21058bc56b1..5fab9268bcbc 100644 --- a/python/core/auto_generated/callouts/qgscallout.sip.in +++ b/python/core/auto_generated/callouts/qgscallout.sip.in @@ -409,20 +409,24 @@ Returns the anchor point geometry for a label with the given bounding box and `` QGIS 3.20 use :py:func:`~QgsCallout.calloutLabelPoint` instead %End - QgsGeometry calloutLabelPoint( QRectF bodyBoundingBox, double angle, LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCalloutContext &calloutContext ) const; + QgsGeometry calloutLabelPoint( QRectF bodyBoundingBox, double angle, LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCalloutContext &calloutContext, bool &pinned ) const; %Docstring Returns the anchor point geometry for a label with the given bounding box and ``anchor`` point mode. +The ``pinned`` argument will be set to ``True`` if the callout label point is pinned (manually placed). + .. versionadded:: 3.20 %End - QgsGeometry calloutLineToPart( const QgsGeometry &labelGeometry, const QgsAbstractGeometry *partGeometry, QgsRenderContext &context, const QgsCalloutContext &calloutContext ) const; + QgsGeometry calloutLineToPart( const QgsGeometry &labelGeometry, const QgsAbstractGeometry *partGeometry, QgsRenderContext &context, const QgsCalloutContext &calloutContext, bool &pinned ) const; %Docstring Calculates the direct line from a label geometry to an anchor geometry part, respecting the various callout settings which influence how the callout end should be placed in the anchor geometry. Returns a null geometry if the callout line cannot be calculated. +The ``pinned`` argument will be set to ``True`` if the callout anchor point is pinned (manually placed). + .. versionadded:: 3.20 %End diff --git a/python/core/auto_generated/labeling/qgscalloutposition.sip.in b/python/core/auto_generated/labeling/qgscalloutposition.sip.in index 18ff59897425..ca12469c04d0 100644 --- a/python/core/auto_generated/labeling/qgscalloutposition.sip.in +++ b/python/core/auto_generated/labeling/qgscalloutposition.sip.in @@ -85,6 +85,50 @@ The destination of the callout line is the line point associated with the featur .. seealso:: :py:func:`destination` .. seealso:: :py:func:`setOrigin` +%End + + bool originIsPinned() const; +%Docstring +Returns ``True`` if the origin of the callout has pinned (manually placed). + +The origin of the callout line is the line point associated with the label text. + +.. seealso:: :py:func:`destinationIsPinned` + +.. seealso:: :py:func:`setOriginIsPinned` +%End + + void setOriginIsPinned( bool pinned ); +%Docstring +Sets whether the origin of the callout has pinned (manually placed). + +The origin of the callout line is the line point associated with the label text. + +.. seealso:: :py:func:`setDestinationIsPinned` + +.. seealso:: :py:func:`originIsPinned` +%End + + bool destinationIsPinned() const; +%Docstring +Returns ``True`` if the destination of the callout has pinned (manually placed). + +The destination of the callout line is the line point associated with the feature's geometry. + +.. seealso:: :py:func:`originIsPinned` + +.. seealso:: :py:func:`setDestinationIsPinned` +%End + + void setDestinationIsPinned( bool pinned ); +%Docstring +Sets whether the destination of the callout has pinned (manually placed). + +The destination of the callout line is the line point associated with the feature's geometry. + +.. seealso:: :py:func:`setOriginIsPinned` + +.. seealso:: :py:func:`destinationIsPinned` %End }; diff --git a/src/app/labeling/qgsmaptoolpinlabels.cpp b/src/app/labeling/qgsmaptoolpinlabels.cpp index c35e52a73641..37f1195412c7 100644 --- a/src/app/labeling/qgsmaptoolpinlabels.cpp +++ b/src/app/labeling/qgsmaptoolpinlabels.cpp @@ -154,6 +154,20 @@ void QgsMapToolPinLabels::highlightLabel( const QgsLabelPosition &labelpos, mHighlights.insert( id, rb ); } +void QgsMapToolPinLabels::highlightCallout( bool isOrigin, const QgsCalloutPosition &calloutPosition, const QString &id, const QColor &color ) +{ + double scaleFactor = mCanvas->fontMetrics().xHeight(); + + QgsRubberBand *rb = new QgsRubberBand( mCanvas, QgsWkbTypes::PointGeometry ); + rb->setWidth( 2 ); + rb->setSecondaryStrokeColor( QColor( 255, 255, 255, 100 ) ); + rb->setColor( color ); + rb->setIcon( QgsRubberBand::ICON_X ); + rb->setIconSize( scaleFactor ); + rb->addPoint( isOrigin ? calloutPosition.origin() : calloutPosition.destination() ); + mHighlights.insert( id, rb ); +} + // public slot to render highlight rectangles around pinned labels void QgsMapToolPinLabels::highlightPinnedLabels() { @@ -164,7 +178,7 @@ void QgsMapToolPinLabels::highlightPinnedLabels() return; } - QgsDebugMsg( QStringLiteral( "Highlighting pinned labels" ) ); + QgsDebugMsgLevel( QStringLiteral( "Highlighting pinned labels" ), 2 ); // get list of all drawn labels from all layers within given extent const QgsLabelingResults *labelingResults = mCanvas->labelingResults( false ); @@ -174,16 +188,14 @@ void QgsMapToolPinLabels::highlightPinnedLabels() } QgsRectangle ext = mCanvas->extent(); - QgsDebugMsg( QStringLiteral( "Getting labels from canvas extent" ) ); + QgsDebugMsgLevel( QStringLiteral( "Getting labels from canvas extent" ), 2 ); - QList labelPosList = labelingResults->labelsWithinRect( ext ); + const QList labelPosList = labelingResults->labelsWithinRect( ext ); QApplication::setOverrideCursor( Qt::WaitCursor ); QList::const_iterator it; - for ( it = labelPosList.constBegin() ; it != labelPosList.constEnd(); ++it ) + for ( const QgsLabelPosition &pos : labelPosList ) { - const QgsLabelPosition &pos = *it; - mCurrentLabel = LabelDetails( pos ); if ( isPinned() ) @@ -216,14 +228,38 @@ void QgsMapToolPinLabels::highlightPinnedLabels() highlightLabel( pos, labelStringID, lblcolor ); } } + + // highlight pinned callouts + const QList calloutPosList = labelingResults->calloutsWithinRectangle( ext ); + const QColor calloutColor = QColor( 54, 129, 255, 160 ); + for ( const QgsCalloutPosition &callout : calloutPosList ) + { + if ( callout.originIsPinned() ) + { + QString calloutStringID = QStringLiteral( "callout|%1|%2|origin" ).arg( callout.layerID, QString::number( callout.featureId ) ); + // don't highlight again + if ( mHighlights.contains( calloutStringID ) ) + continue; + + highlightCallout( true, callout, calloutStringID, calloutColor ); + } + if ( callout.destinationIsPinned() ) + { + QString calloutStringID = QStringLiteral( "callout|%1|%2|destination" ).arg( callout.layerID, QString::number( callout.featureId ) ); + // don't highlight again + if ( mHighlights.contains( calloutStringID ) ) + continue; + + highlightCallout( false, callout, calloutStringID, calloutColor ); + } + } QApplication::restoreOverrideCursor(); } void QgsMapToolPinLabels::removePinnedHighlights() { QApplication::setOverrideCursor( Qt::BusyCursor ); - const auto constMHighlights = mHighlights; - for ( QgsRubberBand *rb : constMHighlights ) + for ( QgsRubberBand *rb : qgis::as_const( mHighlights ) ) { delete rb; } diff --git a/src/app/labeling/qgsmaptoolpinlabels.h b/src/app/labeling/qgsmaptoolpinlabels.h index fe633fcb4ed9..3354d67de8b9 100644 --- a/src/app/labeling/qgsmaptoolpinlabels.h +++ b/src/app/labeling/qgsmaptoolpinlabels.h @@ -82,6 +82,11 @@ class APP_EXPORT QgsMapToolPinLabels: public QgsMapToolLabel const QString &id, const QColor &color ); + //! Highlights a given callout relative to whether its pinned and editable + void highlightCallout( bool isOrigin, const QgsCalloutPosition &labelpos, + const QString &id, + const QColor &color ); + //! Select valid labels to pin or unpin void pinUnpinLabels( const QgsRectangle &ext, QMouseEvent *e ); diff --git a/src/core/callouts/qgscallout.cpp b/src/core/callouts/qgscallout.cpp index 662440107e81..021584a5fe25 100644 --- a/src/core/callouts/qgscallout.cpp +++ b/src/core/callouts/qgscallout.cpp @@ -309,8 +309,9 @@ QgsGeometry QgsCallout::labelAnchorGeometry( QRectF rect, const double angle, La return label; } -QgsGeometry QgsCallout::calloutLabelPoint( QRectF rect, const double angle, QgsCallout::LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCallout::QgsCalloutContext &calloutContext ) const +QgsGeometry QgsCallout::calloutLabelPoint( QRectF rect, const double angle, QgsCallout::LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCallout::QgsCalloutContext &calloutContext, bool &pinned ) const { + pinned = false; if ( dataDefinedProperties().isActive( QgsCallout::OriginX ) && dataDefinedProperties().isActive( QgsCallout::OriginY ) ) { bool ok = false; @@ -320,6 +321,7 @@ QgsGeometry QgsCallout::calloutLabelPoint( QRectF rect, const double angle, QgsC const double y = dataDefinedProperties().valueAsDouble( QgsCallout::OriginY, context.expressionContext(), 0, &ok ); if ( ok ) { + pinned = true; // data defined label point, use it directly QgsGeometry labelPoint = QgsGeometry::fromPointXY( QgsPointXY( x, y ) ); try @@ -384,8 +386,9 @@ QgsGeometry QgsCallout::calloutLabelPoint( QRectF rect, const double angle, QgsC return label; } -QgsGeometry QgsCallout::calloutLineToPart( const QgsGeometry &labelGeometry, const QgsAbstractGeometry *partGeometry, QgsRenderContext &context, const QgsCalloutContext &calloutContext ) const +QgsGeometry QgsCallout::calloutLineToPart( const QgsGeometry &labelGeometry, const QgsAbstractGeometry *partGeometry, QgsRenderContext &context, const QgsCalloutContext &calloutContext, bool &pinned ) const { + pinned = false; AnchorPoint anchor = anchorPoint(); const QgsAbstractGeometry *evaluatedPartAnchor = partGeometry; std::unique_ptr< QgsAbstractGeometry > tempPartAnchor; @@ -399,6 +402,7 @@ QgsGeometry QgsCallout::calloutLineToPart( const QgsGeometry &labelGeometry, con const double y = dataDefinedProperties().valueAsDouble( QgsCallout::DestinationY, context.expressionContext(), 0, &ok ); if ( ok ) { + pinned = true; tempPartAnchor = std::make_unique< QgsPoint >( QgsWkbTypes::Point, x, y ); evaluatedPartAnchor = tempPartAnchor.get(); try @@ -603,13 +607,16 @@ void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const d context.expressionContext().setOriginalValueVariable( encodedAnchor ); labelAnchor = decodeLabelAnchorPoint( dataDefinedProperties().valueAsString( QgsCallout::LabelAnchorPointPosition, context.expressionContext(), encodedAnchor ) ); } - const QgsGeometry label = calloutLabelPoint( rect, angle, labelAnchor, context, calloutContext ); + + bool originPinned = false; + const QgsGeometry label = calloutLabelPoint( rect, angle, labelAnchor, context, calloutContext, originPinned ); if ( label.isNull() ) return; - auto drawCalloutLine = [this, &context, &calloutContext, &label]( const QgsAbstractGeometry * partAnchor ) + auto drawCalloutLine = [this, &context, &calloutContext, &label, originPinned]( const QgsAbstractGeometry * partAnchor ) { - QgsGeometry line = calloutLineToPart( label, partAnchor, context, calloutContext ); + bool destinationPinned = false; + QgsGeometry line = calloutLineToPart( label, partAnchor, context, calloutContext, destinationPinned ); if ( line.isEmpty() ) return; @@ -657,7 +664,9 @@ void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const d QgsCalloutPosition position; position.setOrigin( context.mapToPixel().toMapCoordinates( points.at( 0 ).x(), points.at( 0 ).y() ).toQPointF() ); + position.setOriginIsPinned( originPinned ); position.setDestination( context.mapToPixel().toMapCoordinates( points.constLast().x(), points.constLast().y() ).toQPointF() ); + position.setDestinationIsPinned( destinationPinned ); calloutContext.addCalloutPosition( position ); mLineSymbol->renderPolyline( points, nullptr, context ); @@ -722,13 +731,15 @@ void QgsManhattanLineCallout::draw( QgsRenderContext &context, QRectF rect, cons context.expressionContext().setOriginalValueVariable( encodedAnchor ); labelAnchor = decodeLabelAnchorPoint( dataDefinedProperties().valueAsString( QgsCallout::LabelAnchorPointPosition, context.expressionContext(), encodedAnchor ) ); } - const QgsGeometry label = calloutLabelPoint( rect, angle, labelAnchor, context, calloutContext ); + bool originPinned = false; + const QgsGeometry label = calloutLabelPoint( rect, angle, labelAnchor, context, calloutContext, originPinned ); if ( label.isNull() ) return; - auto drawCalloutLine = [this, &context, &calloutContext, &label]( const QgsAbstractGeometry * partAnchor ) + auto drawCalloutLine = [this, &context, &calloutContext, &label, originPinned]( const QgsAbstractGeometry * partAnchor ) { - QgsGeometry line = calloutLineToPart( label, partAnchor, context, calloutContext ); + bool destinationPinned = false; + QgsGeometry line = calloutLineToPart( label, partAnchor, context, calloutContext, destinationPinned ); if ( line.isEmpty() ) return; @@ -779,7 +790,9 @@ void QgsManhattanLineCallout::draw( QgsRenderContext &context, QRectF rect, cons QgsCalloutPosition position; position.setOrigin( context.mapToPixel().toMapCoordinates( points.at( 0 ).x(), points.at( 0 ).y() ).toQPointF() ); + position.setOriginIsPinned( originPinned ); position.setDestination( context.mapToPixel().toMapCoordinates( points.constLast().x(), points.constLast().y() ).toQPointF() ); + position.setDestinationIsPinned( destinationPinned ); calloutContext.addCalloutPosition( position ); lineSymbol()->renderPolyline( points, nullptr, context ); diff --git a/src/core/callouts/qgscallout.h b/src/core/callouts/qgscallout.h index 9953cd4c1438..bc1e1a5f95aa 100644 --- a/src/core/callouts/qgscallout.h +++ b/src/core/callouts/qgscallout.h @@ -424,9 +424,12 @@ class CORE_EXPORT QgsCallout /** * Returns the anchor point geometry for a label with the given bounding box and \a anchor point mode. + * + * The \a pinned argument will be set to TRUE if the callout label point is pinned (manually placed). + * * \since QGIS 3.20 */ - QgsGeometry calloutLabelPoint( QRectF bodyBoundingBox, double angle, LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCalloutContext &calloutContext ) const; + QgsGeometry calloutLabelPoint( QRectF bodyBoundingBox, double angle, LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCalloutContext &calloutContext, bool &pinned ) const; /** * Calculates the direct line from a label geometry to an anchor geometry part, respecting the various @@ -434,9 +437,11 @@ class CORE_EXPORT QgsCallout * * Returns a null geometry if the callout line cannot be calculated. * + * The \a pinned argument will be set to TRUE if the callout anchor point is pinned (manually placed). + * * \since QGIS 3.20 */ - QgsGeometry calloutLineToPart( const QgsGeometry &labelGeometry, const QgsAbstractGeometry *partGeometry, QgsRenderContext &context, const QgsCalloutContext &calloutContext ) const; + QgsGeometry calloutLineToPart( const QgsGeometry &labelGeometry, const QgsAbstractGeometry *partGeometry, QgsRenderContext &context, const QgsCalloutContext &calloutContext, bool &pinned ) const; private: diff --git a/src/core/labeling/qgscalloutposition.h b/src/core/labeling/qgscalloutposition.h index 30b34e1cd7a4..4f9fae2c3f52 100644 --- a/src/core/labeling/qgscalloutposition.h +++ b/src/core/labeling/qgscalloutposition.h @@ -103,11 +103,54 @@ class CORE_EXPORT QgsCalloutPosition */ void setDestination( const QPointF &destination ) { mDestination = destination; } + /** + * Returns TRUE if the origin of the callout has pinned (manually placed). + * + * The origin of the callout line is the line point associated with the label text. + * + * \see destinationIsPinned() + * \see setOriginIsPinned() + */ + bool originIsPinned() const { return mOriginIsPinned; } + + /** + * Sets whether the origin of the callout has pinned (manually placed). + * + * The origin of the callout line is the line point associated with the label text. + * + * \see setDestinationIsPinned() + * \see originIsPinned() + */ + void setOriginIsPinned( bool pinned ) { mOriginIsPinned = pinned; } + + /** + * Returns TRUE if the destination of the callout has pinned (manually placed). + * + * The destination of the callout line is the line point associated with the feature's geometry. + * + * \see originIsPinned() + * \see setDestinationIsPinned() + */ + bool destinationIsPinned() const { return mDestinationIsPinned; } + + /** + * Sets whether the destination of the callout has pinned (manually placed). + * + * The destination of the callout line is the line point associated with the feature's geometry. + * + * \see setOriginIsPinned() + * \see destinationIsPinned() + */ + void setDestinationIsPinned( bool pinned ) { mDestinationIsPinned = pinned; } + private: QPointF mOrigin; QPointF mDestination; + + bool mOriginIsPinned = false; + bool mDestinationIsPinned = false; }; #endif // QGSCALLOUTPOSITION_H diff --git a/tests/src/core/testqgslabelingengine.cpp b/tests/src/core/testqgslabelingengine.cpp index b53a6814e629..aee609936972 100644 --- a/tests/src/core/testqgslabelingengine.cpp +++ b/tests/src/core/testqgslabelingengine.cpp @@ -2039,6 +2039,11 @@ void TestQgsLabelingEngine::labelingResultsWithCallouts() f.setAttributes( QgsAttributes() << 2 << -3424024 << 7849709 << -2713442 << 7628322 << -2567040 << 6974872 ); f.setGeometry( QgsGeometry::fromPointXY( QgsPointXY( -2995532, 7242679 ) ) ); QVERIFY( vl3->dataProvider()->addFeature( f ) ); + + f.setAttributes( QgsAttributes() << 3 << -4024024 << 7849709 << QVariant() << QVariant() << QVariant() << QVariant() ); + f.setGeometry( QgsGeometry::fromPointXY( QgsPointXY( -2995532, 7242679 ) ) ); + QVERIFY( vl3->dataProvider()->addFeature( f ) ); + vl3->updateExtents(); vl3->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! @@ -2081,6 +2086,8 @@ void TestQgsLabelingEngine::labelingResultsWithCallouts() QGSCOMPARENEAR( callouts.at( 0 ).origin().y(), 7628322.0, 10 ); QGSCOMPARENEAR( callouts.at( 0 ).destination().x(), -2567040.0, 10 ); QGSCOMPARENEAR( callouts.at( 0 ).destination().y(), 6974872.0, 10 ); + QVERIFY( callouts.at( 0 ).originIsPinned() ); + QVERIFY( callouts.at( 0 ).destinationIsPinned() ); callouts = results->calloutsWithinRectangle( QgsRectangle( -2567340, 6974572, -2566740, 6975172 ) ); QCOMPARE( callouts.count(), 1 ); @@ -2090,6 +2097,8 @@ void TestQgsLabelingEngine::labelingResultsWithCallouts() QGSCOMPARENEAR( callouts.at( 0 ).origin().y(), 7628322.0, 10 ); QGSCOMPARENEAR( callouts.at( 0 ).destination().x(), -2567040.0, 10 ); QGSCOMPARENEAR( callouts.at( 0 ).destination().y(), 6974872.0, 10 ); + QVERIFY( callouts.at( 0 ).originIsPinned() ); + QVERIFY( callouts.at( 0 ).destinationIsPinned() ); callouts = results->calloutsWithinRectangle( QgsRectangle( -1242625, 7967227, -1242025, 7967827 ) ); QCOMPARE( callouts.count(), 1 ); @@ -2099,6 +2108,8 @@ void TestQgsLabelingEngine::labelingResultsWithCallouts() QGSCOMPARENEAR( callouts.at( 0 ).origin().y(), 7967527.0, 10 ); QGSCOMPARENEAR( callouts.at( 0 ).destination().x(), -424572.0, 10 ); QGSCOMPARENEAR( callouts.at( 0 ).destination().y(), 7567578.0, 10 ); + QVERIFY( callouts.at( 0 ).originIsPinned() ); + QVERIFY( callouts.at( 0 ).destinationIsPinned() ); callouts = results->calloutsWithinRectangle( QgsRectangle( -424872, 7567278, -424272, 7567878 ) ); QCOMPARE( callouts.count(), 1 ); @@ -2108,22 +2119,49 @@ void TestQgsLabelingEngine::labelingResultsWithCallouts() QGSCOMPARENEAR( callouts.at( 0 ).origin().y(), 7967527.0, 10 ); QGSCOMPARENEAR( callouts.at( 0 ).destination().x(), -424572.0, 10 ); QGSCOMPARENEAR( callouts.at( 0 ).destination().y(), 7567578.0, 10 ); + QVERIFY( callouts.at( 0 ).originIsPinned() ); + QVERIFY( callouts.at( 0 ).destinationIsPinned() ); + + callouts = results->calloutsWithinRectangle( QgsRectangle( -4104024, 7609709, -3804024, 8249709 ) ); + QCOMPARE( callouts.count(), 1 ); + QCOMPARE( callouts.at( 0 ).featureId, 2 ); + QCOMPARE( callouts.at( 0 ).layerID, vl3->id() ); + QGSCOMPARENEAR( callouts.at( 0 ).origin().x(), -3856062.0, 10 ); + QGSCOMPARENEAR( callouts.at( 0 ).origin().y(), 7849709.0, 10 ); + QGSCOMPARENEAR( callouts.at( 0 ).destination().x(), -2995532.0, 10 ); + QGSCOMPARENEAR( callouts.at( 0 ).destination().y(), 7242679.0, 10 ); + QVERIFY( !callouts.at( 0 ).originIsPinned() ); + QVERIFY( !callouts.at( 0 ).destinationIsPinned() ); callouts = results->calloutsWithinRectangle( mapSettings.visibleExtent() ); - QCOMPARE( callouts.count(), 2 ); - bool callout1IsFirstLayer = callouts.at( 0 ).layerID == vl2->id(); - QCOMPARE( callouts.at( callout1IsFirstLayer ? 0 : 1 ).featureId, 1 ); - QCOMPARE( callouts.at( callout1IsFirstLayer ? 0 : 1 ).layerID, vl2->id() ); - QGSCOMPARENEAR( callouts.at( callout1IsFirstLayer ? 0 : 1 ).origin().x(), -1242325.0, 10 ); - QGSCOMPARENEAR( callouts.at( callout1IsFirstLayer ? 0 : 1 ).origin().y(), 7967527.0, 10 ); - QGSCOMPARENEAR( callouts.at( callout1IsFirstLayer ? 0 : 1 ).destination().x(), -424572.0, 10 ); - QGSCOMPARENEAR( callouts.at( callout1IsFirstLayer ? 0 : 1 ).destination().y(), 7567578.0, 10 ); - QCOMPARE( callouts.at( callout1IsFirstLayer ? 1 : 0 ).featureId, 1 ); - QCOMPARE( callouts.at( callout1IsFirstLayer ? 1 : 0 ).layerID, vl3->id() ); - QGSCOMPARENEAR( callouts.at( callout1IsFirstLayer ? 1 : 0 ).origin().x(), -2713442.0, 10 ); - QGSCOMPARENEAR( callouts.at( callout1IsFirstLayer ? 1 : 0 ).origin().y(), 7628322.0, 10 ); - QGSCOMPARENEAR( callouts.at( callout1IsFirstLayer ? 1 : 0 ).destination().x(), -2567040.0, 10 ); - QGSCOMPARENEAR( callouts.at( callout1IsFirstLayer ? 1 : 0 ).destination().y(), 6974872.0, 10 ); + QCOMPARE( callouts.count(), 3 ); + int callout1Index = callouts.at( 0 ).layerID == vl2->id() ? 0 : callouts.at( 1 ).layerID == vl2->id() ? 1 : 2; + int callout2Index = callouts.at( 0 ).layerID == vl3->id() && callouts.at( 0 ).featureId == 1 ? 0 : callouts.at( 1 ).layerID == vl3->id() && callouts.at( 1 ).featureId == 1 ? 1 : 2; + int callout3Index = callouts.at( 0 ).layerID == vl3->id() && callouts.at( 0 ).featureId == 2 ? 0 : callouts.at( 1 ).layerID == vl3->id() && callouts.at( 1 ).featureId == 2 ? 1 : 2; + QCOMPARE( callouts.at( callout1Index ).featureId, 1 ); + QCOMPARE( callouts.at( callout1Index ).layerID, vl2->id() ); + QGSCOMPARENEAR( callouts.at( callout1Index ).origin().x(), -1242325.0, 10 ); + QGSCOMPARENEAR( callouts.at( callout1Index ).origin().y(), 7967527.0, 10 ); + QGSCOMPARENEAR( callouts.at( callout1Index ).destination().x(), -424572.0, 10 ); + QGSCOMPARENEAR( callouts.at( callout1Index ).destination().y(), 7567578.0, 10 ); + QVERIFY( callouts.at( callout1Index ).originIsPinned() ); + QVERIFY( callouts.at( callout1Index ).destinationIsPinned() ); + QCOMPARE( callouts.at( callout2Index ).featureId, 1 ); + QCOMPARE( callouts.at( callout2Index ).layerID, vl3->id() ); + QGSCOMPARENEAR( callouts.at( callout2Index ).origin().x(), -2713442.0, 10 ); + QGSCOMPARENEAR( callouts.at( callout2Index ).origin().y(), 7628322.0, 10 ); + QGSCOMPARENEAR( callouts.at( callout2Index ).destination().x(), -2567040.0, 10 ); + QGSCOMPARENEAR( callouts.at( callout2Index ).destination().y(), 6974872.0, 10 ); + QVERIFY( callouts.at( callout2Index ).originIsPinned() ); + QVERIFY( callouts.at( callout2Index ).destinationIsPinned() ); + QCOMPARE( callouts.at( callout3Index ).featureId, 2 ); + QCOMPARE( callouts.at( callout3Index ).layerID, vl3->id() ); + QGSCOMPARENEAR( callouts.at( callout3Index ).origin().x(), -3856062.0, 10 ); + QGSCOMPARENEAR( callouts.at( callout3Index ).origin().y(), 7849709.0, 10 ); + QGSCOMPARENEAR( callouts.at( callout3Index ).destination().x(), -2995532.0, 10 ); + QGSCOMPARENEAR( callouts.at( callout3Index ).destination().y(), 7242679.0, 10 ); + QVERIFY( !callouts.at( callout3Index ).originIsPinned() ); + QVERIFY( !callouts.at( callout3Index ).destinationIsPinned() ); // with rotation mapSettings.setRotation( 60 ); @@ -2172,7 +2210,7 @@ void TestQgsLabelingEngine::labelingResultsWithCallouts() callouts = results->calloutsWithinRectangle( mapSettings.visibleExtent() ); QCOMPARE( callouts.count(), 2 ); - callout1IsFirstLayer = callouts.at( 0 ).layerID == vl2->id(); + bool callout1IsFirstLayer = callouts.at( 0 ).layerID == vl2->id(); QCOMPARE( callouts.at( callout1IsFirstLayer ? 0 : 1 ).featureId, 1 ); QCOMPARE( callouts.at( callout1IsFirstLayer ? 0 : 1 ).layerID, vl2->id() ); QGSCOMPARENEAR( callouts.at( callout1IsFirstLayer ? 0 : 1 ).origin().x(), -1242325.0, 10 ); From 4713abe0c4420893e82af970477444d51be42fb5 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 18 Mar 2021 10:27:30 +1000 Subject: [PATCH 111/377] Update action text and tooltip --- src/ui/qgisapp.ui | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui index 4ecee3c61c3e..2442d904f920 100644 --- a/src/ui/qgisapp.ui +++ b/src/ui/qgisapp.ui @@ -1678,7 +1678,7 @@ F6 - + @@ -2317,11 +2317,11 @@ Acts on all layers. :/images/themes/default/mActionShowPinnedLabels.svg:/images/themes/default/mActionShowPinnedLabels.svg - Highlight Pinned Labels and Diagrams + Highlight Pinned Labels, Diagrams and Callouts - Highlight Pinned Labels and Diagrams -Shows highlight rectangles around labels and diagrams which are fixed in place, e.g. due to manual placement. + Highlight Pinned Labels, Diagrams and Callouts +Shows highlight rectangles around labels, diagrams and callout points which are fixed in place, e.g. due to manual placement. From d9361086ab388992701114f5cbd75309ba958ba6 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 18 Mar 2021 12:18:09 +1000 Subject: [PATCH 112/377] Cleanup callout code to remove a lot of duplicated code between simple line and manhattan line callout classes --- .../auto_generated/callouts/qgscallout.sip.in | 21 ++- src/core/callouts/qgscallout.cpp | 142 ++++-------------- src/core/callouts/qgscallout.h | 21 ++- tests/src/core/testqgscallout.cpp | 2 +- tests/src/core/testqgscalloutregistry.cpp | 2 +- 5 files changed, 64 insertions(+), 124 deletions(-) diff --git a/python/core/auto_generated/callouts/qgscallout.sip.in b/python/core/auto_generated/callouts/qgscallout.sip.in index 5fab9268bcbc..35dd91d1c0df 100644 --- a/python/core/auto_generated/callouts/qgscallout.sip.in +++ b/python/core/auto_generated/callouts/qgscallout.sip.in @@ -235,7 +235,7 @@ Returns the list of rendered callout positions. }; - void render( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ); + void render( QgsRenderContext &context, const QRectF &rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ); %Docstring Renders the callout onto the specified render ``context``. @@ -381,7 +381,7 @@ anchor point. protected: - virtual void draw( QgsRenderContext &context, QRectF bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) = 0; + virtual void draw( QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) = 0; %Docstring Performs the actual rendering of the callout implementation onto the specified render ``context``. @@ -401,7 +401,7 @@ The ``calloutContext`` argument is used to specify additional contextual informa how a callout is being rendered. %End - QgsGeometry labelAnchorGeometry( QRectF bodyBoundingBox, const double angle, LabelAnchorPoint anchor ) const /Deprecated/; + QgsGeometry labelAnchorGeometry( const QRectF &bodyBoundingBox, const double angle, LabelAnchorPoint anchor ) const /Deprecated/; %Docstring Returns the anchor point geometry for a label with the given bounding box and ``anchor`` point mode. @@ -409,7 +409,7 @@ Returns the anchor point geometry for a label with the given bounding box and `` QGIS 3.20 use :py:func:`~QgsCallout.calloutLabelPoint` instead %End - QgsGeometry calloutLabelPoint( QRectF bodyBoundingBox, double angle, LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCalloutContext &calloutContext, bool &pinned ) const; + QgsGeometry calloutLabelPoint( const QRectF &bodyBoundingBox, double angle, LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCalloutContext &calloutContext, bool &pinned ) const; %Docstring Returns the anchor point geometry for a label with the given bounding box and ``anchor`` point mode. @@ -678,9 +678,18 @@ Sets whether callout lines should be drawn to all feature parts. %End protected: - virtual void draw( QgsRenderContext &context, QRectF bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ); + virtual void draw( QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ); + virtual QgsCurve *createCalloutLine( const QgsPoint &start, const QgsPoint &end, QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ) const /Factory/; +%Docstring +Creates a callout line between ``start`` and ``end`` in the desired style. + +The base class method returns a straight line. + +.. versionadded:: 3.20 +%End + private: QgsSimpleLineCallout( const QgsSimpleLineCallout &other ); QgsSimpleLineCallout &operator=( const QgsSimpleLineCallout & ); @@ -716,7 +725,7 @@ serialized in the ``properties`` map (corresponding to the output from protected: - virtual void draw( QgsRenderContext &context, QRectF bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ); + virtual QgsCurve *createCalloutLine( const QgsPoint &start, const QgsPoint &end, QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ) const /Factory/; private: diff --git a/src/core/callouts/qgscallout.cpp b/src/core/callouts/qgscallout.cpp index 021584a5fe25..94737837a999 100644 --- a/src/core/callouts/qgscallout.cpp +++ b/src/core/callouts/qgscallout.cpp @@ -120,7 +120,7 @@ QgsCallout::DrawOrder QgsCallout::drawOrder() const return OrderBelowAllLabels; } -void QgsCallout::render( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) +void QgsCallout::render( QgsRenderContext &context, const QRectF &rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) { if ( !mEnabled ) return; @@ -259,7 +259,7 @@ QgsCallout::LabelAnchorPoint QgsCallout::decodeLabelAnchorPoint( const QString & return LabelPointOnExterior; } -QgsGeometry QgsCallout::labelAnchorGeometry( QRectF rect, const double angle, LabelAnchorPoint anchor ) const +QgsGeometry QgsCallout::labelAnchorGeometry( const QRectF &rect, const double angle, LabelAnchorPoint anchor ) const { QgsGeometry label; switch ( anchor ) @@ -309,7 +309,7 @@ QgsGeometry QgsCallout::labelAnchorGeometry( QRectF rect, const double angle, La return label; } -QgsGeometry QgsCallout::calloutLabelPoint( QRectF rect, const double angle, QgsCallout::LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCallout::QgsCalloutContext &calloutContext, bool &pinned ) const +QgsGeometry QgsCallout::calloutLabelPoint( const QRectF &rect, const double angle, QgsCallout::LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCallout::QgsCalloutContext &calloutContext, bool &pinned ) const { pinned = false; if ( dataDefinedProperties().isActive( QgsCallout::OriginX ) && dataDefinedProperties().isActive( QgsCallout::OriginY ) ) @@ -470,6 +470,21 @@ QgsGeometry QgsCallout::calloutLineToPart( const QgsGeometry &labelGeometry, con return line; } +// +// QgsCallout::QgsCalloutContext +// + +QgsCoordinateTransform QgsCallout::QgsCalloutContext::originalFeatureToMapTransform( const QgsRenderContext &renderContext ) const +{ + if ( !mOriginalFeatureToMapTransform.isValid() ) + { + // lazy initialization, only create if needed... + mOriginalFeatureToMapTransform = QgsCoordinateTransform( originalFeatureCrs, renderContext.coordinateTransform().destinationCrs(), renderContext.transformContext() ); + } + return mOriginalFeatureToMapTransform; +} + + // // QgsSimpleLineCallout // @@ -598,7 +613,7 @@ void QgsSimpleLineCallout::setLineSymbol( QgsLineSymbol *symbol ) mLineSymbol.reset( symbol ); } -void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) +void QgsSimpleLineCallout::draw( QgsRenderContext &context, const QRectF &rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) { LabelAnchorPoint labelAnchor = labelAnchorPoint(); if ( dataDefinedProperties().isActive( QgsCallout::LabelAnchorPointPosition ) ) @@ -613,7 +628,7 @@ void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const d if ( label.isNull() ) return; - auto drawCalloutLine = [this, &context, &calloutContext, &label, originPinned]( const QgsAbstractGeometry * partAnchor ) + auto drawCalloutLine = [this, &context, &calloutContext, &label, &rect, angle, &anchor, originPinned]( const QgsAbstractGeometry * partAnchor ) { bool destinationPinned = false; QgsGeometry line = calloutLineToPart( label, partAnchor, context, calloutContext, destinationPinned ); @@ -634,6 +649,9 @@ void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const d if ( minLengthPixels > 0 && lineLength < minLengthPixels ) return; // too small! + std::unique_ptr< QgsCurve > calloutCurve( createCalloutLine( qgsgeometry_cast< const QgsLineString * >( line.constGet() )->startPoint(), + qgsgeometry_cast< const QgsLineString * >( line.constGet() )->endPoint(), context, rect, angle, anchor, calloutContext ) ); + double offsetFromAnchor = mOffsetFromAnchorDistance; if ( dataDefinedProperties().isActive( QgsCallout::OffsetFromAnchor ) ) { @@ -651,13 +669,10 @@ void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const d const double offsetFromLabelPixels = context.convertToPainterUnits( offsetFromLabel, mOffsetFromLabelUnit, mOffsetFromLabelScale ); if ( offsetFromAnchorPixels > 0 || offsetFromLabelPixels > 0 ) { - if ( const QgsLineString *ls = qgsgeometry_cast< const QgsLineString * >( line.constGet() ) ) - { - line = QgsGeometry( ls->curveSubstring( offsetFromLabelPixels, ls->length() - offsetFromAnchorPixels ) ); - } + calloutCurve.reset( calloutCurve->curveSubstring( offsetFromLabelPixels, calloutCurve->length() - offsetFromAnchorPixels ) ); } - const QPolygonF points = line.asQPolygonF(); + const QPolygonF points = calloutCurve->asQPolygonF(); if ( points.empty() ) return; @@ -688,7 +703,10 @@ void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const d } } - +QgsCurve *QgsSimpleLineCallout::createCalloutLine( const QgsPoint &start, const QgsPoint &end, QgsRenderContext &, const QRectF &, const double, const QgsGeometry &, QgsCallout::QgsCalloutContext & ) const +{ + return new QgsLineString( start, end ); +} // // QgsManhattanLineCallout @@ -722,104 +740,8 @@ QgsManhattanLineCallout *QgsManhattanLineCallout::clone() const return new QgsManhattanLineCallout( *this ); } -void QgsManhattanLineCallout::draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) -{ - LabelAnchorPoint labelAnchor = labelAnchorPoint(); - if ( dataDefinedProperties().isActive( QgsCallout::LabelAnchorPointPosition ) ) - { - QString encodedAnchor = encodeLabelAnchorPoint( labelAnchor ); - context.expressionContext().setOriginalValueVariable( encodedAnchor ); - labelAnchor = decodeLabelAnchorPoint( dataDefinedProperties().valueAsString( QgsCallout::LabelAnchorPointPosition, context.expressionContext(), encodedAnchor ) ); - } - bool originPinned = false; - const QgsGeometry label = calloutLabelPoint( rect, angle, labelAnchor, context, calloutContext, originPinned ); - if ( label.isNull() ) - return; - - auto drawCalloutLine = [this, &context, &calloutContext, &label, originPinned]( const QgsAbstractGeometry * partAnchor ) - { - bool destinationPinned = false; - QgsGeometry line = calloutLineToPart( label, partAnchor, context, calloutContext, destinationPinned ); - if ( line.isEmpty() ) - return; - - const double lineLength = line.length(); - if ( qgsDoubleNear( lineLength, 0 ) ) - return; - - double minLength = minimumLength(); - if ( dataDefinedProperties().isActive( QgsCallout::MinimumCalloutLength ) ) - { - minLength = dataDefinedProperties().valueAsDouble( QgsCallout::MinimumCalloutLength, context.expressionContext(), minLength ); - } - double minLengthPixels = context.convertToPainterUnits( minLength, minimumLengthUnit(), minimumLengthMapUnitScale() ); - if ( minLengthPixels > 0 && lineLength < minLengthPixels ) - return; // too small! - - const QgsPoint start = qgsgeometry_cast< const QgsLineString * >( line.constGet() )->startPoint(); - const QgsPoint end = qgsgeometry_cast< const QgsLineString * >( line.constGet() )->endPoint(); - QgsPoint mid1 = QgsPoint( start.x(), end.y() ); - - line = QgsGeometry::fromPolyline( QgsPolyline() << start << mid1 << end ); - double offsetFromAnchorDist = offsetFromAnchor(); - if ( dataDefinedProperties().isActive( QgsCallout::OffsetFromAnchor ) ) - { - offsetFromAnchorDist = dataDefinedProperties().valueAsDouble( QgsCallout::OffsetFromAnchor, context.expressionContext(), offsetFromAnchorDist ); - } - const double offsetFromAnchorPixels = context.convertToPainterUnits( offsetFromAnchorDist, offsetFromAnchorUnit(), offsetFromAnchorMapUnitScale() ); - - double offsetFromLabelDist = offsetFromLabel(); - if ( dataDefinedProperties().isActive( QgsCallout::OffsetFromLabel ) ) - { - offsetFromLabelDist = dataDefinedProperties().valueAsDouble( QgsCallout::OffsetFromLabel, context.expressionContext(), offsetFromLabelDist ); - } - const double offsetFromLabelPixels = context.convertToPainterUnits( offsetFromLabelDist, offsetFromAnchorUnit(), offsetFromAnchorMapUnitScale() ); - - if ( offsetFromAnchorPixels > 0 || offsetFromLabelPixels > 0 ) - { - if ( QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( line.get() ) ) - { - line = QgsGeometry( ls->curveSubstring( offsetFromLabelPixels, ls->length() - offsetFromAnchorPixels ) ); - } - } - - const QPolygonF points = line.asQPolygonF(); - - if ( points.empty() ) - return; - - QgsCalloutPosition position; - position.setOrigin( context.mapToPixel().toMapCoordinates( points.at( 0 ).x(), points.at( 0 ).y() ).toQPointF() ); - position.setOriginIsPinned( originPinned ); - position.setDestination( context.mapToPixel().toMapCoordinates( points.constLast().x(), points.constLast().y() ).toQPointF() ); - position.setDestinationIsPinned( destinationPinned ); - calloutContext.addCalloutPosition( position ); - - lineSymbol()->renderPolyline( points, nullptr, context ); - }; - - bool toAllParts = drawCalloutToAllParts(); - if ( dataDefinedProperties().isActive( QgsCallout::DrawCalloutToAllParts ) ) - { - context.expressionContext().setOriginalValueVariable( toAllParts ); - toAllParts = dataDefinedProperties().valueAsBool( QgsCallout::DrawCalloutToAllParts, context.expressionContext(), toAllParts ); - } - - if ( calloutContext.allFeaturePartsLabeled || !toAllParts ) - drawCalloutLine( anchor.constGet() ); - else - { - for ( auto it = anchor.const_parts_begin(); it != anchor.const_parts_end(); ++it ) - drawCalloutLine( *it ); - } -} - -QgsCoordinateTransform QgsCallout::QgsCalloutContext::originalFeatureToMapTransform( const QgsRenderContext &renderContext ) const +QgsCurve *QgsManhattanLineCallout::createCalloutLine( const QgsPoint &start, const QgsPoint &end, QgsRenderContext &, const QRectF &, const double, const QgsGeometry &, QgsCallout::QgsCalloutContext & ) const { - if ( !mOriginalFeatureToMapTransform.isValid() ) - { - // lazy initialization, only create if needed... - mOriginalFeatureToMapTransform = QgsCoordinateTransform( originalFeatureCrs, renderContext.coordinateTransform().destinationCrs(), renderContext.transformContext() ); - } - return mOriginalFeatureToMapTransform; + QgsPoint mid1 = QgsPoint( start.x(), end.y() ); + return new QgsLineString( QVector< QgsPoint >() << start << mid1 << end ); } diff --git a/src/core/callouts/qgscallout.h b/src/core/callouts/qgscallout.h index bc1e1a5f95aa..a6c295ae0ab7 100644 --- a/src/core/callouts/qgscallout.h +++ b/src/core/callouts/qgscallout.h @@ -284,7 +284,7 @@ class CORE_EXPORT QgsCallout * \warning A prior call to startRender() must have been made before calling this method, and * after all render() operations are complete a call to stopRender() must be made. */ - void render( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ); + void render( QgsRenderContext &context, const QRectF &rect, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ); /** * Returns TRUE if the the callout is enabled. @@ -414,13 +414,13 @@ class CORE_EXPORT QgsCallout * The \a calloutContext argument is used to specify additional contextual information about * how a callout is being rendered. */ - virtual void draw( QgsRenderContext &context, QRectF bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) = 0; + virtual void draw( QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) = 0; /** * Returns the anchor point geometry for a label with the given bounding box and \a anchor point mode. * \deprecated QGIS 3.20 use calloutLabelPoint() instead */ - Q_DECL_DEPRECATED QgsGeometry labelAnchorGeometry( QRectF bodyBoundingBox, const double angle, LabelAnchorPoint anchor ) const SIP_DEPRECATED; + Q_DECL_DEPRECATED QgsGeometry labelAnchorGeometry( const QRectF &bodyBoundingBox, const double angle, LabelAnchorPoint anchor ) const SIP_DEPRECATED; /** * Returns the anchor point geometry for a label with the given bounding box and \a anchor point mode. @@ -429,7 +429,7 @@ class CORE_EXPORT QgsCallout * * \since QGIS 3.20 */ - QgsGeometry calloutLabelPoint( QRectF bodyBoundingBox, double angle, LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCalloutContext &calloutContext, bool &pinned ) const; + QgsGeometry calloutLabelPoint( const QRectF &bodyBoundingBox, double angle, LabelAnchorPoint anchor, QgsRenderContext &context, const QgsCalloutContext &calloutContext, bool &pinned ) const; /** * Calculates the direct line from a label geometry to an anchor geometry part, respecting the various @@ -661,7 +661,16 @@ class CORE_EXPORT QgsSimpleLineCallout : public QgsCallout void setDrawCalloutToAllParts( bool drawToAllParts ) { mDrawCalloutToAllParts = drawToAllParts; } protected: - void draw( QgsRenderContext &context, QRectF bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ) override; + void draw( QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ) override; + + /** + * Creates a callout line between \a start and \a end in the desired style. + * + * The base class method returns a straight line. + * + * \since QGIS 3.20 + */ + virtual QgsCurve *createCalloutLine( const QgsPoint &start, const QgsPoint &end, QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ) const SIP_FACTORY; private: @@ -720,7 +729,7 @@ class CORE_EXPORT QgsManhattanLineCallout : public QgsSimpleLineCallout QgsManhattanLineCallout *clone() const override; protected: - void draw( QgsRenderContext &context, QRectF bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ) override; + QgsCurve *createCalloutLine( const QgsPoint &start, const QgsPoint &end, QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ) const override SIP_FACTORY; private: #ifdef SIP_RUN diff --git a/tests/src/core/testqgscallout.cpp b/tests/src/core/testqgscallout.cpp index 426949be83c7..db7a2e0e54fb 100644 --- a/tests/src/core/testqgscallout.cpp +++ b/tests/src/core/testqgscallout.cpp @@ -77,7 +77,7 @@ class DummyCallout : public QgsCallout protected: - void draw( QgsRenderContext &, QRectF, const double, const QgsGeometry &, QgsCallout::QgsCalloutContext & ) override { } + void draw( QgsRenderContext &, const QRectF &, const double, const QgsGeometry &, QgsCallout::QgsCalloutContext & ) override { } private: QString mProp1; diff --git a/tests/src/core/testqgscalloutregistry.cpp b/tests/src/core/testqgscalloutregistry.cpp index eb8b8003f918..bee917b880b2 100644 --- a/tests/src/core/testqgscalloutregistry.cpp +++ b/tests/src/core/testqgscalloutregistry.cpp @@ -31,7 +31,7 @@ class DummyCallout : public QgsCallout QgsCallout *clone() const override { return new DummyCallout(); } static QgsCallout *create( const QVariantMap &, const QgsReadWriteContext & ) { return new DummyCallout(); } protected: - void draw( QgsRenderContext &, QRectF, const double, const QgsGeometry &, QgsCallout::QgsCalloutContext & ) override {} + void draw( QgsRenderContext &, const QRectF &, const double, const QgsGeometry &, QgsCallout::QgsCalloutContext & ) override {} }; From 8a9720861768e4224ec85b3be2dbbf4191853a08 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Wed, 17 Mar 2021 10:45:37 +0100 Subject: [PATCH 113/377] Fix WMS DPI scale rounding error --- src/server/services/wms/qgswmsrendercontext.cpp | 2 +- src/server/services/wms/qgswmsrenderer.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server/services/wms/qgswmsrendercontext.cpp b/src/server/services/wms/qgswmsrendercontext.cpp index aa9d57651e82..f2f8dbfd487f 100644 --- a/src/server/services/wms/qgswmsrendercontext.cpp +++ b/src/server/services/wms/qgswmsrendercontext.cpp @@ -172,7 +172,7 @@ qreal QgsWmsRenderContext::dotsPerMm() const // Apply DPI parameter if present. This is an extension of QGIS Server // compared to WMS 1.3. // Because of backwards compatibility, this parameter is optional - int dpm = 1 / OGC_PX_M; + qreal dpm = 1 / OGC_PX_M; if ( !mParameters.dpi().isEmpty() ) { diff --git a/src/server/services/wms/qgswmsrenderer.cpp b/src/server/services/wms/qgswmsrenderer.cpp index 7a8daee721d4..62e824f6d4e5 100644 --- a/src/server/services/wms/qgswmsrenderer.cpp +++ b/src/server/services/wms/qgswmsrenderer.cpp @@ -1096,7 +1096,9 @@ namespace QgsWms } mapSettings.setOutputSize( QSize( paintDevice->width(), paintDevice->height() ) ); - mapSettings.setOutputDpi( paintDevice->logicalDpiX() ); + // Recalculate from input DPI: do not take the (integer) value from paint device + // because it loose precision! + mapSettings.setOutputDpi( mContext.dotsPerMm() * 25.4 ); //map extent QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle(); From bc6e2b305d06f033adab9849f7970177844566fd Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Wed, 17 Mar 2021 14:19:58 +0100 Subject: [PATCH 114/377] Update test mask images --- .docker/docker-qgis-test.sh | 26 +----------------- ...mbol_DefaultMapUnitsPerMillimeter_mask.png | Bin 5534 -> 5521 bytes ...ol_DefaultMapUnitsPerMillimeter_result.png | Bin 5513 -> 0 bytes ...hic_ScaleSymbol_DefaultScale_2056_mask.png | Bin 8670 -> 8840 bytes .../WMS_GetMap_Annotations_mask.png | Bin 10911 -> 18058 bytes .../WMS_GetMap_Background_mask.png | Bin 4139 -> 10361 bytes .../WMS_GetMap_Background_Hex_mask.png | Bin 4139 -> 10361 bytes .../WMS_GetMap_Basic_mask.png | Bin 4065 -> 9962 bytes .../WMS_GetMap_Basic2_mask.png | Bin 4582 -> 9191 bytes .../WMS_GetMap_Basic3_mask.png | Bin 4582 -> 9201 bytes .../WMS_GetMap_Basic4_mask.png | Bin 4582 -> 9302 bytes .../WMS_GetMap_Basic5_mask.png | Bin 4503 -> 9785 bytes .../WMS_GetMap_ContextRendering_mask.png | Bin 4440 -> 13107 bytes .../WMS_GetMap_Diagrams_mask.png | Bin 21079 -> 34273 bytes .../WMS_GetMap_Dimension_All_NoValue_mask.png | Bin 21069 -> 37095 bytes ...Map_Dimension_Elevation_MixValues_mask.png | Bin 20479 -> 31630 bytes ...p_Dimension_Elevation_MultiValues_mask.png | Bin 20965 -> 32161 bytes ...ap_Dimension_Elevation_RangeValue_mask.png | Bin 20479 -> 31630 bytes ...nsion_Elevation_RangeValue_Filter_mask.png | Bin 20917 -> 31939 bytes ..._GetMap_Dimension_Elevation_Value_mask.png | Bin 20917 -> 31939 bytes .../WMS_GetMap_Filter_mask.png | Bin 5305 -> 12185 bytes .../WMS_GetMap_Filter2_mask.png | Bin 6211 -> 10096 bytes .../WMS_GetMap_Filter3_mask.png | Bin 7532 -> 14474 bytes .../WMS_GetMap_Filter4_mask.png | Bin 4451 -> 7672 bytes .../WMS_GetMap_Filter_OGC_mask.png | Bin 5305 -> 12185 bytes .../WMS_GetMap_Filter_OGC2_mask.png | Bin 0 -> 15062 bytes .../WMS_GetMap_Filter_OGC3_mask.png | Bin 0 -> 9965 bytes .../WMS_GetMap_Filter_OGC_V2_mask.png | Bin 6413 -> 10312 bytes .../WMS_GetMap_Highlight_mask.png | Bin 17119 -> 21533 bytes .../WMS_GetMap_Highlight_Line_mask.png | Bin 4460 -> 8863 bytes .../WMS_GetMap_Highlight_Point_mask.png | Bin 5578 -> 12126 bytes .../WMS_GetMap_LabelingSettings.png | Bin 30545 -> 39409 bytes .../WMS_GetMap_LabelingSettings_mask.png | Bin 32511 -> 32926 bytes .../WMS_GetMap_Labeling_Complex_mask.png | Bin 0 -> 5354 bytes .../WMS_GetMap_LayerOrder_mask.png | Bin 5848 -> 13778 bytes .../WMS_GetMap_Opacities_mask.png | Bin 15669 -> 21378 bytes .../WMS_GetMap_Opacities2_mask.png | Bin 0 -> 12508 bytes .../WMS_GetMap_Opacities3_mask.png | Bin 0 -> 11190 bytes .../WMS_GetMap_SLDRestored_mask.png | Bin 4767 -> 9390 bytes .../WMS_GetMap_SRS/WMS_GetMap_SRS_mask.png | Bin 6031 -> 15471 bytes .../WMS_GetMap_Selection_mask.png | Bin 7855 -> 16662 bytes .../WMS_GetMap_StyleCustom_mask.png | Bin 25874 -> 48819 bytes .../WMS_GetMap_StyleDefault_mask.png | Bin 12872 -> 17563 bytes .../WMS_GetMap_StyleMixed_mask.png | Bin 28977 -> 54611 bytes .../WMS_GetMap_StyleMixed_LayerOrder_mask.png | Bin 27996 -> 51957 bytes .../WMS_GetMap_Transparent.png | Bin 33108 -> 33099 bytes .../WMS_GetMap/WMS_GetMap_mask.png | Bin 10929 -> 15605 bytes .../WMS_GetMap_projectsubstring_mask.png | Bin 3851 -> 4917 bytes 48 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ScaleSymbol_DefaultMapUnitsPerMillimeter/WMS_GetLegendGraphic_ScaleSymbol_DefaultMapUnitsPerMillimeter_result.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC2/WMS_GetMap_Filter_OGC2_mask.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC3/WMS_GetMap_Filter_OGC3_mask.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetMap_Labeling_Complex/WMS_GetMap_Labeling_Complex_mask.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetMap_Opacities2/WMS_GetMap_Opacities2_mask.png create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetMap_Opacities3/WMS_GetMap_Opacities3_mask.png diff --git a/.docker/docker-qgis-test.sh b/.docker/docker-qgis-test.sh index b6735b832d0f..b7f7f627fd34 100755 --- a/.docker/docker-qgis-test.sh +++ b/.docker/docker-qgis-test.sh @@ -62,30 +62,6 @@ popd > /dev/null # /root/QGIS # Restore Oracle test data ############################## -echo "${bold}Load Oracle database...🙏${endbold}" - -export ORACLE_HOST="oracle" -export QGIS_ORACLETEST_DBNAME="${ORACLE_HOST}/XEPDB1" -export QGIS_ORACLETEST_DB="host=${QGIS_ORACLETEST_DBNAME} port=1521 user='QGIS' password='qgis'" - -echo "Wait a moment while loading Oracle database." -COUNT=0 -while ! echo exit | sqlplus -L SYSTEM/adminpass@$QGIS_ORACLETEST_DBNAME &> /dev/null -do - printf "🙏" - sleep 5 - if [[ $(( COUNT++ )) -eq 200 ]]; then - break - fi -done -if [[ ${COUNT} -eq 201 ]]; then - echo "timeout, no oracle, no 🙏" -else - echo " done 👀" - pushd /root/QGIS > /dev/null - /root/QGIS/tests/testdata/provider/testdata_oracle.sh $ORACLE_HOST - popd > /dev/null # /root/QGIS -fi ############################## # Restore SQL Server test data @@ -128,5 +104,5 @@ else echo "Flaky tests are run!" fi echo "List of skipped tests: $EXCLUDE_TESTS" -python3 /root/QGIS/.ci/ctest2ci.py xvfb-run ctest -V -E "${EXCLUDE_TESTS}" -S /root/QGIS/.ci/config.ctest --output-on-failure +python3 /root/QGIS/.ci/ctest2ci.py xvfb-run ctest -R 'PyQgsServerWMSGetMap$' -V -E "${EXCLUDE_TESTS}" -S /root/QGIS/.ci/config.ctest --output-on-failure diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ScaleSymbol_DefaultMapUnitsPerMillimeter/WMS_GetLegendGraphic_ScaleSymbol_DefaultMapUnitsPerMillimeter_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_ScaleSymbol_DefaultMapUnitsPerMillimeter/WMS_GetLegendGraphic_ScaleSymbol_DefaultMapUnitsPerMillimeter_mask.png index 5dfec844a8d0907f2acb40c845764424fa3829f5..206c87a1c65b8c33195f8466d062346db35eb9d4 100644 GIT binary patch literal 5521 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 literal 8670 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 wiu+xCuNN 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 UizmB-*Z=?k07*qoM6N<$f|Q?rA^-pY literal 10911 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Background/WMS_GetMap_Background_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Background/WMS_GetMap_Background_mask.png index 2805829a2f0ba1b7c484a105c891650dd1ea588a..d076be657da15834a9b026377bbef6bf26d1044f 100644 GIT binary patch literal 10361 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Background_Hex/WMS_GetMap_Background_Hex_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Background_Hex/WMS_GetMap_Background_Hex_mask.png index 68fc395f34eb9eaaa8d799db09a1bb9935a26b58..d076be657da15834a9b026377bbef6bf26d1044f 100644 GIT binary patch literal 10361 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 ZrLi2UqHoKJUIb)4W2UT diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Basic/WMS_GetMap_Basic_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Basic/WMS_GetMap_Basic_mask.png index 3548470832d8c80d0c0ac0ec5147ac85fb458507..1f7079e3505f6af8262c9a3e7497ee4c4e0dffbe 100644 GIT binary patch literal 9962 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 literal 4065 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 literal 4582 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 p1W53e52}&>?CFa9C;UM3r9wL=))2{T~w)KaKzZ literal 4582 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 literal 4582 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 ZId#9|KKJ=K&+~K6+xvQ2oa`srAqe8s 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 literal 4440 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 literal 21079 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Dimension_All_NoValue/WMS_GetMap_Dimension_All_NoValue_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Dimension_All_NoValue/WMS_GetMap_Dimension_All_NoValue_mask.png index 78aa41a1137b8f1cc14e7243dd21aec744fded12..febc7f00706a5a543f9826742de6ed7177ef9bb2 100644 GIT binary patch literal 37095 zcmZsCc|6o#^mnBwOOkc0MWK+4Ez1xwQ;3GrAQQ$uBx{T&N%moqeP1R~jAd+DMwT-6 zv5pXueI477{h7Ys@ALcp@jQRbYi91}bM86!oOACz_uTghe_#k$yjVc%83(~PTbScdgzynvxZS-%@AU7dl{mb-YvZc-ux$&eN^n;Y5za;3r(H<_RsHf+Pv;%i*U3ubiDG z-@Bk*L3xIMAj!oX+;nGZX8aWWhxVk3yGABerYZXYBk}Jelgl9ohlj)p%E*FOP2R20 z#!uWc@P9~}aiUw=*$*TOqx%;I;PCe8!tlkhe;PtIcYhk@nbeLwTcMNA?{Gu^?W;eV zZD++t>Q4R1_AFjHFKg9jRjK>6H%07vSc0{)ZwkGar_<*)PD?S-=$AqCuy+%+g_sLJojbyzb?AgH#YiiBz= zxL!EI2j6A;mul#>*>-JzHBmPm${|Km!#B*~W{gV8bf3U=V z?>gcSJ2M}@J^GS=_8-Ci=fR&7k$pya{iHcVmVMoS`@Na{6rq+$UO^GZ&2ruZdsNc} z$X+`c-c9o0{@p)v$XaD9;?s!e%e@&mg zcKUxu0r?3nf{mHA7e6w9{tgqbpOw#@D-??gWiAtoR8ic-}TJOu=z-%!zk|C_F|)M!-|w@3U1WQ+q5?Qi4*o|k&o8x}ch{}b6#2(Y zO@R+W4*dQz$J?CYOx_BUCx1m|t+=$R@~;yKo|cu(-N*#cyjbuRnZo`v6z1SLFd9g! zrqitjj;@#rzsz3yCYg6w4ISA(aVy<$WoBk(sw#BvgH86@LH@z6XAaMIkQ^Ki*AOpK z4nzhT(3^ez{G8}|P@Kr*kHVNqfZ5+ zFzUqDs)<+oEB$g??a5W$;xGL+gPS(9W;Z=?tb3f3G+Kpa@sO;PS+67Rq}z(;YMuB? z`asl$BaG0e(hT#q5BGPrr%3G1ouGMkg)Kgh?B9Q98cCSW#`AXH^NQQsrO&IYP6XS1 zdGbo5=`Sb!w_O_(F}?ONs(oH_o4d{KxB7TfBZ{O2&nR|_aMGo|Ss!pbUNnUC_xDHQ z4}nD+sFD5seTn9R%PsdX%KQPA@b)$`4Rz?XQs!pb$aAsMwDuXdFcZ+H%q7MC7c({} zqDSO{>UFo3O&cY-fnKC@7~QpeG%`n5eDq}!`Y+5)4hJrO=UA;?6MVOuCRAp6>A?@> z_AE_4y0$2<4*skMpV!PJi^Rw`$#?QO$)}8^40s&GunOEbtuvpWI+pm|i;LO+`+^rL zU&Wjcg7*lx(5g16UF=}`0r?pwuE2k(I73F%O$PgMw`fR8W;6v&e((GRUc5rr<>8<8 zDX|IJ(UHadn2izlQVJW4;JZQZ?gY?75uQn3MMX|b)T5DKkB|0A$7YBOvtJYz>r;iE z@}C^#Dpg;|u3Sp(F@K3&Rs?la_Z~V7e$Vla9KPW2TXG@1>8L?)1i1RwA=O&wOIBY0 zg4lJpuFSXaakW|}4Bu6IuOw|4;ie&kBv}xhPZQOwV+t|wit?veP!}LAW210olxdB@ zHA<5?pWIKoWf9K!I}_J#BzEMb`TCR!bYLxp%t+EW?2Nypa{;ER$57yjP|VU^iLm`k zv#-AtU9zpXawDHevJ{xev;83D-eN&o$8mg?+fB+pi*|UIFZh&AfL2nLQ8{#ew%UPD z>=Oys0y2|Ey$m;qNlOk(Z*vxE_P@o_k|c1C0{lXQo8w^ppKzP@sFg;KG`*1JER zFRjy@|KzwNeoffof^LEKf2EFmQl6{>hPZI=Lr#BEdFu^efG(&cvP2HRaF_q4BvgGXwDkauq_>tKDfWJ zv0;Z}w(kUd?_}kv<(0B)u+_8ps=g7YpAd1 zc%xH=nzWb(Sa7)N++%qFHP1Hm`niIYooG8oKedzCMNVX&PGrbzR**#8kw5nX$h2ox5{c&&J}{b+gG$ zv<~hDD);%5f$KYL?yBkaIy3nv@JoCZQFd!zAQOmMI57zVzAo!o2;otW-Vqth9*t1y z@1fTCyUruVXH}O`1sSmTcKd`q<{J!0)`1=ctwp5cmNhVx{ zN&1lFRird(l+`*@p$Mi{(GG@$?g)+18i4VS+)Y( zFh|F^pRcR2K#H*N`CF?no3~(^-;hKd?pXl}TIWl*^R;jJx^Lx*q!3d6Kc%Qoc z-W9#_ZXPW#Sdi>itqVj-Ev@O@cCVc=HVG!(aaWMKldtjee!y2YvVm0Duw{^uPmZIQ03d-xdtI=XmRGPjM3efN_G)BzT}uYOt+g+;2M{2 zw(~U#Y*>!!1jx`eGQ;Ti@4k|m1D~iTN$GQ2zKou1&D|L)p3m#tr8lEiw(^J6xr7C{ zvx~#7LRI8P5`I^4Wr0I%$lzP%j0Nz+uaI0+%o*Hm5C)uyE3r*r|5m=O$ljeJweo8o zz387YgYkFj61hY4MWbEa+}tunJ32vfW?OPy?`#Ec7aQTJ>{)dwO&aNjPbptJ=VdAN zVD?&D*Rbifh^6bWuUy+vz@p95F5Vz1a4Yawd*Gw-8xA5}1K?pNgE0F+&9e96#(HxigU>w!Gu0 z1L~M;RJBN*dhJZYRTR50v#_dLUiu0sgZ|)c&oT<(Hrp|1S^i+J2h=yiSv%s%4fgM% z8suGzIO0)BGVJ{L;g8hIysj%P zOND~T9sm^xiE9*T!y@r{4L}p#I~|rMv#X8wvabrdjp{Og^46+0N4IB&DD#xa1}m>i zK3aEd5N?%UUu*!LLTkFX;~;myPE3bYgZ18H(mcAacdV}2&FW0v`Zo7ds$htn^5Vqv zSFq*&)<0T~;?43ceejQ#pOA6piR@|%J~LDoqNG31d-E6(_a8G3reAqq#%Vo0OZ){s z5|Nwj)F+*5*udP4v6-H4jQo(Zad*yarz5)TY!#C*!~6K4iquCa{Wwl}RYyVfPM?bq z4AYY50%v8gXGyxK;?CL@@ZlP@B#4xWpCGU$hxeJZ z)VM7L6h}#_&VMT4H67Fch1Y`NKrDX>>t4l)*q<(&z+gq&J2xX7t=OdzkGAD-5SA?RY|RqMlB0(PA$?O9CpxK$+en=Kcg z@nY5J%G4tz*I(;Gk18F5CwC?SjM@q%E*k>fnIBl&;p97FtT~5r0QimM?OqkaQDqTH z`6L0Y$xP1o13T&G1|t~b%WmWaz(9Xq*uGV#v^tNzDRgbD`B6sNUROrW9UdO`*8pa3 z$tQb9u#n59I$z&V#3WINfWM+cI>Q{&&UxkJEZJM%pPP(%5Le4U#c?EL6Qa#%OVn_O z9b@5af_HK*HOoQLmiqIexyLnp*qpiCqapdqb@72kYL!p{#FMLC+c-7+y-P0H4@~BM@DpR@OzKxYhZo>WR$)n_SKr% zbu3oY9rsp(s)w8Ouf;HD2qq$Q%^WcY0aqAWk5Z%-a;~H^`;9 zDv#U^jbgI=dawf01SG2J#sv!(Bv>ONp7I2@V`*2lvJ?E%WQz@^zszqYJV|m$e9<5_ zFLxm~kN`xMys8;{^-FihjWnXFvQCLX#64G1Ji7BoaVbQl${dh$?|pfk zhq1W_$~Y=%ce1>M9P{Y~Bcjm>|khv?Y)ZU0$_3K<6aQdd9 z7d=?~cpTyZ;TRez$*?fm;sWGcwOa0euZnV{V(v5_b+-nA``YpZ?CqL;#V?gH8V->h;YNl$jW*TrJNYvaf;{9lLK0U@AOP9%d~vU5p{=uv zm0*~o%vfbVr(j>2g$-%XK4weNtHSIVk2p(pzLOV-B1`s1x}@_EJK|QQRX_}ltZ}rj zRs9oTg|~`IEe{w~YU?Z3y|3o=4+TFN`II&zS?2Z*Ck?{1be3LJkxNG6OQnyotF^*o zv36;R-KmP+&g6my@|%dBV@9m$Q*Fy4Hp~G5?zDBU*}yh#{f#%5sJGe1{C1A2d_z7n zj$f7_KwC}b*q$zHx0(QoxiqShawK+LT~(V#5)d1lx}op&zgNYISC1uk3Ir-QGADsHdZb;@sgV)sz458oCw)Q!q$fJ+z)vBj|V zYGu9oK;QOcNvn=ml_UM+pCdSa+yVgc?LEmRqFiewDg`V`$Uts+!$&uE_@8dIV}`~b z(R$bCpPY89C%9kggcPffWOqbc+A?kzaSk2n{S=1MUG~)(m|UtnO+5*qzfD#VJpTNXiy__8L9=L&w5cVxYjpUzPY7N8|> zVpLRFam$?sW`L;Zuij=Wj)c3K%~>VuQ(8N7<59a%D5Fq=QbJ7lO@A`gjAkeCSf?Kx z(o%C{Y0STO&e&Fv75dhrm@pZZd&^=<3WN6n-0yx~J2rpbwnk=K{R8{)y2x=U`uJ$9 za5T2JhB4}z{-Z7Jou#Fvg5gk)CzuX%|0VwrnVJ^WxhMcj3?dM5Ud(2!Xk3+_BKT{ z&Jk$gBx(=XZ9Nfwv0uevH&s^%`VIf0uKZ>*8f$*N<8*tFY+Of+~i-mToqR; z%Co(DmlA!I#gl*d*dT#ozTffm=zWbFxz#a93MsgzYWnmc<7lfDqu5OkyyAJ$`Hdv! zFyr$-LXP+mJb!44_8*AHprEcIyS3RP>A8}$5REvkV}Zi_R9!uKzNR3+ql}mGww(1^ zYEJ?aR_`tq;Hq+gZ*nKA>LCBO)kNs_^loCnZsPXJs4^-8aJpl%ca2L5XLTlEx8rI3 z6NiecwI@-9%$~o0B-z-3<209K?+fg_ZX4vxMXF3^Y*_#bpW^Q-Irp<%teXPBGGTT* zR;6NqWc6VOxo2;#8a8sI2bvT-TE#0qd$;9g3GOfSx72k4Y-ODLt#U>NU17{Wa1RZ<|;{t4KJt;>QEk)Y<7vDP|?lZAzG4{>*6|g{~e~D^9mvg40UP zHaq2Ae&?3~$1_ft4R6T<{G>!Tp8yTjJr~WMTAKbF*7#Kc6T9HMGn(7x$319?)8!#gLcjQ9ok<=&&xt33*` z6f#DfpUH=qC#|z!trH6niz(eHs=!2hA1|wJ|18rJjEa6Hztp;L^nM*fv)ennFEVPq zVnGJjwX62avqpSBYvwxTxs~HD?Vyr|i}W1|>t@kt&yvXIZITNv=5Dyo46^!18ntev#s^c0%s6ZRv0m*jqNf3CB!zf zDyp8^OS+Y?>Z8_>Iz8l5&CLd%OP2=?Jl+MCr$k|2b46;kgrsDpj$s@SP4tq%| zHK112kYKquE$WF;EmrQ6h6fcyX!hlG|Cx>Joqg!E3eKP*U&es~{}3oddi_A2P_j?G zmWh`Ko-(^D0^vX-Gd(|=O--h|tqgs!rAo^~F4ZJTtNm_EsumV<=c#a*4xbH~Q7=Ii zx?2--8&`!UydB709yO&JA9rBGok@0k=aS!XSh_zHrzfl>o@Y&F^^d-e_ATL1&#gV3 zF}ZE4l?()r7rao=juMq9hND;LVb$EG3avDWgY+TPa!quV@>_v1vM(yy5d-+~j;JuB}RI=&APF73t_NsP*!;doJX6s{;v>&m0RYij}`QTNtyt47O z8U3_)BH@LUT0=I|{@$MIz(W`MHbJd*iw2IC^>EL<#Qmx?umtmMu z!PKCaC1$zIzylr^a*kR&0O%NZbxQPW88mQX8T%GEpWbjUJmL-DO>ZE%X#a3$VhpJ5 zX)o5uF$^H{U&W6W^l=ehF*Y&Us8MWks+h!2xphpdIB6IX-<}O||G3 zB+f?BD@xWmce@IPR968W2cz;7X+7H>Z=Lqh_t*B+#jhKKJr|dTdCK=#oDDQAyK6}E z8YM1R?Xs5Ox%?=wR0hK&Kt=&9y#I!l9q91R^I|XR{A-6V36~;%mLV(_H=^YkTLeO5 z5NXy#QHl=3ggn;k6u*VF1W+V7ykS$J*{rkRM0%jo42t+}Te;p%>)i z5*YGEw=pIyeAx&-%T$#YwPPCSoG(noAy{-0H@+LQ{LRUVyzE7IQQuEkM9$C#Bpt1Q ztrPi~Ymq@4oGNPOugv`4e{W5resBGO@=7x=z&}lV15M7j7_<4s4QO}~eYo5R7~CZv zACOl9j^+Z4Y2^u->VnINm)!!nduf7hc()}Bbmyor&rIaro6BlE;FeDQDVNg; z>#6RVM4I$M?0EHLg%l=a=5$nves2=ZwqF(Lbfqrg6>`NFOcdQZS#np`zYCK?$iH#` z{{pG9n^}+vnmhVK(yTl_oH#!8iiV;v3ADwE{73g=#5S#<_4)IqSOuDJTZ5JEPCj36 z>DorK%ai%D=f$3jtJNC$1SH&XnjCLQ)9vo93!_Iq8m=W*&;@`P)_&lrj?10K2QG!J z+usXs9RBn-E03Y3>OXYD-~R$RN;zW)q2Ft=ybC`N)orVPrf>>sygWKZgz9apA4L~M zC7r#70BmP`E!!E`EX=8~4=TOD!!XccaMw}{cy2mK0dy!A8{DdmRYoo^NO~_Mh3zT# zAA^>oD3@WykJwrCPz|%Mw&8`q7pk-R)pTokREln zefYNi#I3BWq+DDll&UCjNWhl*hMbd7svji|FbG?pMsd{f|1WmW3sJ;$Xk| zvnT$ZRiXC?m?d-asU^FerV)xuCdt?~O`x#f^N;r-Yl8f-b8UV5CGb$LlJ#t% zvBFN_N{qN%@PPR~P!=V~sijc0HX{AJ&Kw~Q&76AEgyNtD*g6l3)ySd1KzmQbQz-}xh^UK8zN)0;sgEd30r zHmN&Qn08zI$Gm9L`21D+wUgt$#7y1N?75Y;Z_^F_8@4>YkuRCC3|PO#Pq>N$3lZqB zfj^Y_b5;HLK1Ib=_P$kxgq6VAuCP}SulwJeI}_G>A8_oQ=!yJ3|8o=LF8{V;Mw_T7 z6zrQJh58EnO5)OC5SD;U9|FZXx-E9zq~^eStGMxEbwk7UCCtJ5Co)sHPuc*G!e>$G zUhMQVSgc&;cPkoSer{t>xx|iK`^GuxvFTiuHC3a;#Z5^1C_PPoHbKmJq@05ZfI;H0;GyC1xUiKnu6_x%#44Kj2TIB=!cD@%#;#WdIQlB=&TbDBOx>RQD#mM^wN zs|W>}uhFwIm)~M>BH|CX48dBK=?j9Ku*Y?szGFm@DR}r=Bl(RfU;?p7*H> zyS;iJ!UaiR#-4CXGmDzRO?#SYP^7WL*MIi|ot5jiO`1~|{z%XtPBo6y_l_+!{=kijgoO5<6>V*3M!1W|;a zp_E$}rg&)eeVdam-`)}S)~?7Ijww%i0;eDrSwXffi7wlU?nGCTYreOvoRPL`N%K9h zP?OUi8MLbDR1M&Y)5<)X{GqtGcuUIJj9D_Lg1(Lm15Pp`J=*DcLEf1H89&glbcpC@ zNQVf`k5Ve>66u)c>tcdE*@h7-6ftpx@ut4;WhIyGijk_Jl{{ zJa$$yiCHLXQQM|^BC(>XN_lABK5$%Cz8gN!9d|nQN`}d=z(MYrqdFg%t1I!nJ8$)J zS!swjGe#VpS?%r$m&R|E%`&OU9+$}#9aE$Dl1=^wXgsCkYQ|JH9R=xXu@;75P$VF3 z&N5%uJ@VHzp^ghte0-GiCc>D{Lv!{OVk33LkB_Vr48B8kbWYceiJcV?q zmfE-!44iC z7C&+6TRKNEUrt7zS-NjXP4j-5F{!cf?G@v%@n8Cxmj!s=2;a$&<0ppv{ET#EP!!F3 zM0RZWrD6qg^*z}IeGs>=1B-k2BIBf{YF05xJ>xZ?oYgh?BvMM=jBjPdZzRP%%$Bx+ ztmzUnT!e%ue#EcK#AF{tk=FPNIZ4d1OvM$`8>>wH+NyH}fU2<7%#&`bn1MkP_VFs6 zEor73r1Cn7xQ1wRZ@&w7wowZ|{P$g<1P57#%TlA90E?k2o;haRS<8+EIo6E2GA>hV zHB5;Tk(Ag8(v-@LrHltf5t-wE2i;pvtN5Lh#nP>E~+m3OYc!{Kv zqI9!498Pj4+$y#rk#Qs6Ug>sOaggo2PXWfqK-&4iQ?lgo=I-*UpUe=9Izy0=TQ{%! zxc0@09Me0qcf3T?BYpfhd1k!n%jT{D$&^u)*LWpgKpiY){?NWFm$hhUDd(^^Sd=uS zFPGCCZC@xa8KiN}aURU-$aPM3{f)e^W`W3r|BmgKvE{>=88HR(41zb`FbsSqvJ^R6nJZ#@BTBWXkFrCZ(2OS5*PkD(-~u5p zBt^Hzsa>SsE}uw+;kIfX&&^kW#;N(dKVy0O?eLOe&^X_5lQ8aFO^u%F@88{w!6FU~ zQyb5!qDPWVKC#KQU(}@%*n<;A8}@B>ibs>Vvw;%3D=RW+V%1HyV>q+WT^-E*u3g}~ z$<0M>;MK-%+Q9cZl#b6YG1ssaCsp+hL#t^anx!oF&=iboJ232%^NRfD8xC3Uc*5^Q zcWD*dmRXpSe4#AxQY*i;pFx|M=Y4YgFk+8{6?r<{)-d|>dJvpPUM&ZT@V z=Pio2ymS2LNik-FGcbm6`9f240@U7a`b(=-1#jEsTYKNoj3xPsOAWM}5M+q~rGi4k zT&#p$Ej|RP6ygZ5J!_@tyI&u_)i{TPdx`VTLc`~Km$ak@_(qRGqX~&i{eBQOkeS)H z$ zy~J-!%oF|gI|RDQY3)ZIzfxZL$nMzTn%+ZWkEq-_)M|LI-Iw7Y2@Bam|Lz_te8SI; zWrv|VG9&Jxy-`SpO2k|p5?7ssmzDB-2)~IuZ@;fFnh2sT0mZsUVjiq^>$Uo(Cx5@{ z_*#aVaNh>wwf==y%Xedb!h9Eq6VPok9e5wiJyY5`=2-{};HqTO$fKjyu#Xlvz#6^R zTyMxE<~BkEor?`4$HD|tg>{^Y!npfqMA4jW&lMQP{!UdbfwSO2-D(N^H&N%l>&>iO zhN9rdOEu~d@`$tkTnT7?fzu4vIpW}% z*7c|Znt763Vn2(`ZElar2%_&o9Dw)?tpd#s$sv1D?zCUR-)B^~_srck%**SG`Xlv# z(YKBG8AfR%Rx9x~!|XRz9Xd^@o7$#Q9)%pH0QK&cJb2pYsAu+uFd)KTS~XMUW8!QH z{zT5~nBd<%NI{a0R6{(@qiC?tI$p+T+@MX)viDwT;NCLjihzUoXC&X0sBcPAKQ5pO z4A_$xfH~zX`xU##3({xiX2GuwsD&D{e#cV`7E?U-oLXt1pfYXKDh_>FFjM(O+1 zOC4wfw!*_$Lo-^3!#M!`l1;?1XHVf4h~Co{=iC5yma3jHPy=;WKvo8~l{TWM`_;T3 zm6vGhIDIH=w%2VTA};Q{CEq$VBDbK}!}EQ$Ep+JuILo`0j!C?3aUJoMDQPQ#K?^lO6}U8uBodn<;t3$pdl~6_Dt!UtcXp0_b{fx zcG6%n*dfM!HPx1)vUYRe-SQ52WcnFA(taQ}fcJ05Iyx~~6%8FZ4P~xv6BlJ*9FcQY zS*1fUCxrVW6GRoAe};sOa*mJLX_wsC6ghF%mYL#kvPx!(>J)p%yede&`XQZ}A=3tiprg$H=QV z?sNOk8EbjsFIoKPmmk)RW-Ws<9=Kb9q`Z2h%{9vEn><*(cbCs&L7mt~d5QK7Y3hB` z{=yT5$It+-y$7JGQ-$Yj{VE(AfSflu15xc*fZK|n7_kjgL<2xDowWT%m&9x2UTbeu zXUNg${;Xnw*whKG?URQG&(qr7kq*kcqc)v&+vfW<=EN7Bz6cG(0CCs8jYx`nKX_bm z`@n%*8ujS*1+CNjjUuj4RERYWcJ%%epw`9&V z5o&F${h?+{FfQ&ANw{s5sF>{;_2duiGG;O3%a6wWKZ>&`Ns9#|&WJstmVKhATX~wQ zr6&O`fFDcPI+DR5Y{ho8@zg%Bko{Oe9I>hn`_=?mk+^TL#b-1dUX@@GoN;E=&DD|$ z(2)+E6HA7T#R$d}nqPA$Djm7dd4O@9e8rdBV6k6!Q)aKFsn4fu>fvk8mVN*oJKM3p z?;r6JH0*tX@Q@;=x-hd>7$&UuGp7OHNS&EfxcRp)c-Z`=7OWS3jvwLwM?S6tnHZF{u)@H+^`Tw@I2u zF$7N{`M?ayhz91QNuRH4jU0dmEq}g3k}oGX)Df3{%w592%&7oLAZ1Sx&Kaz7%t%^| zAH%sUv)SQAux|elC66r_F-9zkQSj4|iv{an{M3-SSHP7i;l@5^56!=5%;O{Kas3mM z&E0>HTfEu8cIlk;@{=|2;)TYDSaqqY*VoQ~qtXrY*ipq2L-Dy=6|C>ELlKI&I-JH0 zbrIkgW_=KH_GgITszPXs;w<(;PNehwT*OX$Y#f~4m0Bn*@c{Z4L zPzSAaXOdsu0>2#gN;&H4bN1D!38mB*1;-$V3!dH*xpI}FM#2046y38_mBp$ScVrb~ zFrsTk710)3m3h($hB`h()At-R>0>vw)ijqi6Z_>H``qqZACjKeh4F#jcxhb zN+kV0c~p$-Y{V>cmWZtolsbB-?5dwDFiCNd4HR=*JFAwTo+bG0Qr2#HnYf2tUoq}EiQI>vWQNlv^imCfeth_|2ZEdfVm?EFooYm zD4{aORXGEF!V=pD)Epcz_mD^SJGl86yCsz?m@yh^Ecc~9y_iGFit^^XC2t4W&(#ka zl&D`W>dpePgM2-jUTJg13zf99L@V{~Fhl#KQ*>c5Esr%>IDPeDmWS+aW%umU^<&lcJ}< z8xIT5*TMVkRo%oHh9W%b+Mc!f)~|A+zb%j2`!H zJeU)}p}^4ye`Jp6E;@VYWCu85SP7)3X+e4qtdT|zMHD&MOvAw$qo7hIKqXjrULZ?3 zr(&^3Q`*>`S!y%NjpvMo!mUWFt?Ev6=k_9TiFPRB{$@g;j3T@BB#7fGycp+v$QjjK zXtLbJQ7Fr4DJxW#ppGHFdqEj~(st{_UiwZ1rHYOYX0w_ZMJ<)&zXXR*zKuiwBKnjH z|18&*()0;1u%~9|W}hWuBjeQpwBwAN-RxcVG9a=? z?Q8O#o6Z;3RXdz|Skn$#=_n}I4(QVEGkJZ5c2>68$`oQ_XgsiP^T(IJCUZIhJR`qvwA{5nDA`}Myb^Lg z(4Gy|BIB9!1Ed?RI?m}YpH-q6r!{eb=X(N?C%~c|V&uGS=^(CuC6U|7-%uy+PE}D= z^p3PDK{RY!*Era&VO@3cVd;7@Ae5&d7n|+gj3Pd%lDI=XGzUh15b#3t6wJywCQP}s z5#FXtcHVKSQnL=pE4YSa6ABiS4t+ht2TGRNyVy~x3Zui1M#f(exb%JYhnrsdwp`P9 zMOY>vIxwGftB~z!u8Ph84a^_!)Yh|GR_6wzJ*5z@ABwg)2(iKu-&`)A}tAAsnTG=?1DDHHkUDcmCqaPvbUkdR&0T1clUZ7Y7^`2xQNz z>YR5!akI~A2+|#vTaL>|Uz65#o;l4jdbpF_R)$(=KT%GbBks zD|uuF`}MS(+A+8wog0O75B0p0<6SvE4P|?XJ>TfR)BaoKXK{{Vz*u8~@ARB<1ha|H z3H?B`R0! zRz$C|ddkS>L1UifBs*LA5O{M9dxxVu*L=Y2L=%c| z8w;Z+NtF<93&f*_mRP$r8HpR_@m-W6+vi3QIp@>`CL_0b)tKJfQ&EQ&n@9_KHkGMI z&-ETW@qTN@y>=dE-67qQ)w~y%?;F8oO|W@!%uBCTOrXQ_NnnK+F!*pRPJ$gYRbvM0 z6HXN|9qUDptA(Pe+tfgh^i|dmrB%S$KdR9>cckCY12Vk}o1PwNgE8LB3H+Ws_pC&? z4(o-1EkD~w7nf$Jtda5eWX<9{yl$}QQxxC1b}TxO!&nF{bq#&XA}=LzQ4 zDV~&J=8OjxOhnYo)O5_)7|;Cq>izTmU=VlmBMr2`y!++uIHgKHfS%vBu&@13LS>yC z@8FpED-%($1LPg5)QErpb`&}70ukdWkpLccp_!DYOZ1$KP$MJpal+wBW2#rO&rI6U zn~McZ+}OuEqoboFm5!twlLoHecc+`<-fL_h9l>|&+io+JRXoM8SXhOFhem5)M^*I` zGBaC8OnZBh+~0d*N3>MTi1Q`BsXu*P?b5hIT2-{gWo(SVBiHHkxmfK@?_;Qr>wQT} ztZpQ|0yN-&6i^=UCo~{yAdlv)sQ)ZZ#^n4==YtYffL&tv^_z>IclzcU_3%36Xuuto zc|I$lnzW-Rgk`hmA}YD*Alplc#Y-bG849+c{L*DoD zx+0B;?(M{c0{~nuIG>m$h|-(QK6x?5;EI^x#=@cS(I5_fxf(nzml@m+HZ-}yAi$~b zt`h{0+fUEJnJcZK7<1w^)##;ZDB`P^ES6Ql5ACq)+Iz-D5EZ@|zWdL>_lxAN0hR*y z-5zV81$kVhVH;^OpMQRigdV-gP!@XLS$GorEYZ{DNsdO$1Rr-95*F}V&a_2-R+43r zv6?B((_(8~9;ZM_f7f;rQsNW5i4jkgHh{vazjxXq{7ld{A_1JEk=;pe`t0h2or7)`rp)Cx8=Ku4iLuW7(}xYNY35Pbj@w zs$t&BzJLI*jGF7++~&d;J&n_|{ewS8ZR3s?IaB+z;7BGZ5O)dp0mS$=_l~Gu)m+*m zhbx;r2+_q_4oI0p24O3XNuRP@)oV6#wYiC_o?bN={Z6Q%v(=oY+pF(0#U@2{g1RQC z!$My?>G)#nfeby9&O3X-@8QeFP)QqE?bxHJK6SHP;V1{Nl>bx$v@3yAoihXB8ov@~ zZ{Q_#cgf*LT)t6G8tPkLr`1htSl>gn+xER-jE3Lx)1EQ0mBWR|j`s`Tk?$P_(jG~e z9M#m_R+ITtQN=24*JW!n6M>p5X?eP(j(_-Idl=?jmL}&Z{lm9J@LgC$y@b~dRsKxJ z4*=Tg8K#>1h1mGgy>QpGAk>>NBcpFcLUFiB-xqZzTYRiY8^XQU0g#Z94FXX;N#mo0 z1Gp5a+vam7^(00Q_SPo;>75LRQ#k!I%Y3UBBxVZpdm?9(8oM!mg%id{F{NLXznz7& zme?m)+qt4p9~Jj2`ui8Q+MLz|XE62FJ2^oSAW#9G9-T7H3;Cip%s5pe(h4OMzYg@YyPs0p)>JqSb`03K9)9BS-kRd0|&vt}Pn8b<`@}>z;PPIgaE^u4@2U`^OvW9d9iOe`}0N zyWE2DGfbXK(%G=>(2&+f$L{t%RKvY86WDu6x!3X0NFgdS+<7M&6BHEy8FI?HjO~*#U3`1!mb=PF z#3E*UGx`naamzK)2<4pC(zFao=&F0m+uON+fzog|{&BKwa9(-F$%Kt zw@4QHKM{a-qoR})zLO<=EE$h08@6l!&!gvh^w?Rk+5>Qf8{!cjk87TIxron1)8^Yk zq5WZ=*<3ZT27j~vMOw@Arr}ek_-YV3xEOdFivbYTMTwGJV;Amcu zA113ub)C>R@{98WkGD2XFl?6c3hIlkT;K?vhbG{4%|n#`FBU*%!b`Wx`cTu{i0T*B z39`euvx`DbjoOehPUioCU0RegNL$3GEop z8^pchI>Vu>1OM8p^5mY7ob2$+%7Zb)6+)|ycLsxK06779T0RF^JT4vC!m5TW4rRlL z?)&c?3ey=d!2B%GM|2i1ho00&C$wD^i;C(g4l|3j`KX0hegg()FA*rtK8MgyxSu>% zt#_I$ckNZ0#>K1VVaBqskQrUG5t9EZkWzZzQe-sF*2hZ#Amn8T&XkKqQ#K<r#Xza0jBd`3gy{ZOdb?HQqfQQIlK(RCf|GYuQ zPx%8gt6Eb{U~X9@bZF`{?pyMT^GAuPB)hb0l*fN`USLB0L=0d#mZX`)^^u5oH*M(f)1XJit9gz;tu1ghGsAQx-)TLe zo=N@)>7Ms{sI)B5bW3g;=F~M5amrg$?Pfd77O)KzBkQcp{oU)n_ij}^`*#16R8>~ zlWlLvXpNCms=(X+o;WX%O08&4fTvmzXWB67Q0O!b&az-qa@H?RO&J33+2hPj)b+CP z`Nd0b<5?lNPNc&>k%GhBTv?}mIGk1PlB?3;zfY0uSa89&cDmOt(BFq@gr-HP-Ud!l z$Fh`w>Z-9{U-HLW-VW42pDZ5&;=dEfv{~0rKc^x+W!@EH+S|LCb7}HBpWmKmo(Er- zFMLW)O4qWRD)_;yW{#L^b|lHEn`@gCaRMz#EyFUa@RxZrCYo45WkvE3TbeK)^SlKh2eI$3#&vgf*ZZE%Krs2oZvlF&_$eQLW0>X*#xJm=I(H$eJReU+Nk zL}M65(&!X%4BUU3t@CO5){2)}jPLN5_E%wz^8rMB1!rOcg<^KwklA<^U+#Ajp4l`D z^i6uwrLW4mx~lm7m6X93Zxh2p#y)PDz6{PQ)uADt+6|wH-*B<|2gKw*RWso zW#BqPN*;XQ|L&}Ke`oY`0Hjf@^ zT?If#5(oIl%sHRl+^bwx$@z1FE9F9&z5a>f_RX|;C0}QRSa#qHenvmHXc$2xDr6~~ z5+c4@R3mr9-!Gv)IwVtO-K=me{(dnO8oVcBH1Y&gIq%Gqy&o#M5l%hW2Ugt(FapDRNDB!%?{k(4#%l1NBg(6GOs`c9Dtn<{= z9*ut?HoDx&hIISRZ8d#OwM?&cJ|g<-2{h%e6V6~`PybnQ4sp&%jEsd0&ffZB#viuu z0d2=nA2{1Zy{$~zi#e^X3!K5Yf9aUu%bWZYmK|GaPVnwpWcICoG#Xr`9eLH+DzAb} zz9`!9wD(VRWObptMT=ho&P;TTF#cJ~yww9?Bjo_^n`=et_p=r`+);H z(AgESY}@n-zKFZJqFSYk;h*@S`x;2E6s_-$PX5|S#KHYwKfvw?a!`VJX`F=GF3&uz zV>O75cSkK(jnfr6Q#MwM#AqRm$1e;O>B`%;IX?f~5S2G={1eYDuY#!4EM66NV3yX^ zGJ0jDv#8H$v5)phk0OFYXXQ*$!REiMerInrm-2${>+MWRy!#P02yb{DTD7-pd$es^ zKx_&GF3oA-y>q+mjO1QlD|S?hF9|fSkL-atjXQPJNOnrweV^;Pc`n5xmtTid+>$v| zGaBBYfkU=|S3<~7%6;4qBAdnN2B(}q$UDs`CB)XD3ajOGJHBSHI6IA6q_89N1Qpz@ z5J~*}`{c}|HJ9_UkvZOJ7FF9ko?r6Ak9L3;139YtxWu%+>|A!HO&aZ%q9P}l61?qL zRxzDA5}%TzrJN;T{uB9Y09lsq5HGH3N@&cWW_{GpIxIKcB;G!>VW@2l6oQTEL?WB@ z*RT1Sx*e}T=_w72qrJ>yix(R`9}54RoT${0Uu8ByQdiMqDhnV$UDe%x$BGMrFu9DV zz+$R(xh;(f7Ne+${(f}-0Jb%(EsS(~#eEL@OZfsW97hxFuwTNA@U&k7DSp!4KI$w8<0Qsi4X>Z7ze&cgNaG1lNIWl-90))`!r1pfr*jlMz@NA<(bNtL+OGc=} z(pMy^3<9)3V(c(Yx^d_MlHfvh&YD zk4&desFP4B)h|g&*6;H>Pd^aV-NB8qSl_JTaX9aUV!P zm0z=61@V8N>&{3dRT*jBp4ZLg)(b30w!)v<Zzlk-4qL>+(6UkY;gg-A6t06MM@+n^Vpx1;Lh2Xq<}zf5Y^RM#^>?N&P)Jy+kia zn`=JI{02GnlPI;dgXxl8tmT2xC8z)sb;xk&vx-LTJo%#b$ zkP4APf7#3N^$?v%-nd%43Ze||6DJmqx0$d#+{`dsREu;4X-w?^A5WN#1SVM2MYE(U zpGFv6E}nru!d0|8+Jk4S7@1eeo`hXXRfL1@!#c?F%dYyYO?a*>=tn(ZkuP8qQpk%P zZBzumN*B7<5xI@-cv``fQe<1?=Fhc6Rp5a$Du-;OGk-)-tz<@M<5aV@3*tV~$P&s- zIqTwKMs&2VH@fqtAvX(LDGnX8CxKnrSF$WPbjYrbSj*iH@gvPT*DO6O9>)asrFz|D z_&QqBn6)k6k0B^9j^rD~&T1mBwU(WH-&BaNWH$>f9#{ETCB7be+z#=yb@a0+aP`L@ zicAiU#y#@n>O>wic`khd;Wdb{a*@4jKk|@ckP3>uh|bb2<(rYi9~04v&=br=_u5E- z?jJS^+90G)7w!mYYs8hMHXhnFnym6;iBDl6T|jR^T&1T$9mI;s?(zPcYe7 zt*BPdOOE*2(~UvL>1R8hJ7)*64|DzxOJi#{y~S6yUhWzX5=l_mNLOHXQ?(-p(#_2XUY=0d*i>X2TNvYpqAps zX%RKP?-pP7_>>O>0jj6`%?Wa5!rqInz^jt!$z6y!YEw;oe_-6o?+hE+GP5KkrJTlT z-fn*lX+3<1QiKI3ggGX0HuhoXYJO2-M)zL5TcfS`_I%R=+0~2p+Fj$%clnqFa(tJr z)NcMdAWm+?AGRegVQHugXzN2meF={SsMOqnZPPn_&F0D8kBm$O;t+^r+I;DgP|dbp``Ke zfy+4-h`!X*&03-9C6yNMx-{)N+Q>@kmt%x{8? z$fI8QR}JcV&{bE*88+ul>4#P24cbD=wRg3*9%=Dgs(I#fj&dZX+iOP#0izWMvgeSs z!G64AW&wXam4ON58U4c$VPgLc>#LVd45MnA3{i?w*elj2^Mx;wDhjyJ++H{DmtJ^!YX?d@%%0=tiu%(^NcQ1T|1 z?VJd^=_~c+zlYZyZ;8rmR>1xjKwIjXi`ZzKDg%4EP2yHbl+Efphi6+e7&5GKe%PZPaB#4~kY z&OQ(D>pWz>oc%^aF346;>pGsJ*2HFc%N3)S$-e3@NWN#Jl>0X_4*!-N?UgbAZCgAc zkX3=>PW^XJ4OSq2cB%hx?bKx{$RDjRaAy@&`YbE=yK4MxC1Q(xVZIAo+>f~tyZ24rVcOSD<*HAiq{|zf338M3 zwoacGIXKOihyNuwo3zLT?5J5P8hc@C_<%b=N&ci=>Et)b8wz|iFp4?u1a@Pz2Bzq1 z@VTsVM`^Rj{L>BHpE^AdFttH#zH7XlTDGI?Fq6o9ouP|fcIx{%eopm$_-e`xOU3rE zipsIWs?sg?Fq7QVxUGN2$iscQ_4Y5`T7sf#;GKV4#guDVf==bfTdKqEEa*8de~fbB zH7Q;j*aV$yWN}tfG7Wd8`!9t;S*BjN=)p1g#h!Xj(Nym+x}0!%sFY}TzF-GxEww?d zKvb3K!W_T?pbhSblY4$Dq2qt;Zz^1mplc?)rCqE6B8{%rWYl75XAiF$~ zpcmdDKg!k%66FWq2|H3DAP9=zgb4m)OmaiN!9V`2SadCkqVM1AlwcU=3 zk7@<8+Y7zcg+@D4V9KOSQTgw4BNU;LST~@ZDhH+7UKl&0GUR#FVraW!rwu7$W-WtN zDsjD+ixxRfZw5Od_Z$sis}+kcAd&7S)r13Qz#-z1qU;-D(36y$fieiS3ae6{(KNRfwuO`5DPXjEA?e>Zp%s!5@ zwCS?vWJ!3Lx4$%2ebdLv8R)OiH?uT}tI?Y5LsPJhAH`(K_GjdS#Er@SA(JAS(S?SY z0s{&>`-D;Kec}J@;A&-@?9$RtCm^Z{!IF0`4_tRCuF^&M7&h`@%benR$Q>q6IFx0) z6lL?JNSR&muFT*OBMG1qx+rqPbWxwDi1k4M6Qz?-sf#dE)f?kVGJ{gk)Q1P1ZpFY1 zpFS$H(tBYl<}Oc($~Im*d2_Eu7rh4+`|;-N{1)MuYIFJ;0+99Ea!%W=C@cfJq`!@r zY8cB=oya{y;LL_-3(y-%O&bXYI^l}rn!!+1u-C4;Nt^nn2t|kG*;?rLCkX!+_5H3( zU>rtRBkb#HpJ_6Fdz;#liqlt-}eM`eVGZQA~$ev`DfUY=5hItZ56AcMcEc~3U@jLwKfK%#OCe{uXA~!pHAPuR(AH_mZhWW zlcnw%A5UheIY;tN9hBtIbK`Mr;OYaRP(Ry!+(u7#IRW!CMKgW@N!}RbXmIKoZ^ z8XRAYcC%4-*P={B7HTwsbpdk>w;cEvPDKRqqA0uJv6{LT2+{5KoL@f0`@Tih6*G_3 zPuc|MhknZZ*ciFX`A&I#3ihB*@+R8`LZBUU)$UGwZ>5jvCn3<7IqBTkSu)uOsCa8R zF3ATpQzYoXbf07dJLd_V!j@-WH}xzV#^~1c2?)y%6u-oR#}-E;JCFBPw*`!)(nKP! zK#1(teU6UDU;SWc@3_7tHG4#WVc;dYrMCYRQhk~q5KZ0>@L@oCOm|n1&0{2|K9iNI z8NBVuKTUIPLAdOn(>wABpmh=PfXO%4eAOfX+2ZJ{Z#AfpGHh>Y#lrPzU9V3NzAhv| zpv-<-H?7`NqDte{NMO~|*Z)rEZ@+HL8!vnWLiGPzqv{G z^E8dYI~dCzI@e!%{PX3<1(UViDO-e0wIcrWn}wG%{ja*ngbAc<7yk37)Czn8sq_J4 zpS|by-djI7!Gh=a<-S9WRI4RP}Vv_*!X@IGG}k zeC0r7zda16Q$PKfi6hyrM$O*qDYa4s+@W*ReSm_Y-p1b|xueACx)Iz`Qm5e&|LqTS zYBEIHk*`3zHwN}Y+-J_iY<>MVXc_uw<@`Uy7;f>)K=GeEfgE-ODb|U5JAD+Zk9;jF zvw7EdjyI~U0;TEJ!YrbAn3v}n=PWu2|F+-R5-%5dSWIF}?{o4F+4o)$JX-}eMYJKA zLKAjf%lUF5F+H@)GC4-#k%#M@PrO#X{ta7*d%5%aV8fl`Q?cF4jIWTJH@8l01=Fn4ku_(Roui|%RTP4|r{G2o1$M(1$ zmkpOUl5*968$Yyv#$@4=B)+9&-=%~J#u=u6bGlP(M%ecZygr0&w}^dF;WVahpXPV- zMdILXNQZf-XtjFdg|hHbfC)MtuAQc-apu3x;p^+Z{(~BB?r%7)?_!gTvP48bp_kln z*4t{qn5mD|{qHS>6uy?s3w$213S3Z2mEc>Hd^VSuL7`CAOX4Hg+2*_LIV z#UYOCV@J3H{X5}zI+6j!>Z7lVKbI44vnl>3bIhX?7Z{0+zL);1{})M*>fB(YTl`%wf(}ZC#K#JA1c{YTr+Mv`ve}!`?wKq+0DkW%*gIXR z5SH85cKJ1qe-XXfWTSejupc+l{q&0G#KgFZXt+v_y3YK#oShFc>E-aw-ro2RC2FTk zJOd2(hAuC0zJ%LWF)cr5<^!orCd7rwX-s&$P#Mh4gQOW4aof*V$^sJ;5UR zwKW3K^)Q-oc}itsX$ab(4PG+YWuP3WI|)$ zq!Xc&-F>%7$jRM3E^pGT)%4`**it9{-q7^4Zw*-*=D*w`U;oG;-(r_?qjN!#;_7nU zt4R#iqf=Yj*63xW`f*5L?+C-pTA4mFLbw)T7e`9MVW(^X{{y%A7eAgC_q;Bcw3_x! zHpIN$5baSB6R@ zyE$LTY9;D+KamlsDh%YQmp@%vM(jVRB0RldfcU;aTe=|gjm%kMCS%i{_X1z1;WpzV z4spK4wm{|C0~Sw_(U&W|Zc-7F@9OKojxoPMoVR2R&VvC+iWRd?{WEQVq+gYsS?_S47K@E0jL*pQ112F7e9g z97J$6SQXRaljO4`zf9y&Y=KTnwniSd)}_2UUMP}m!G0XNh-Vpsr+&guzjV0XV*3Y$ zxPU*2H@cf{JIm%mUcALd(@aa;zST|MQ;cq#r5@Av_uK$r1H$t{DQ*vkgB@i9UP}cy zB09U#w8fv033E~pafkwo1$aa!Q6{o8nQiZkdUrz(D^>gqgG^;6;2OBaRh?12A$fdX z{@dIu<(-evq3AxeNIMP{9VSa=*&jZ4yUE1~P}^~4?g}J;mbE~BtoYpdDwfL6^LQV~ zDm8n~hWl5QzBawyIT4$|$`J9Q9kGuH8I_wJa3*j`Sy(K0uKKIdLA-vQGbbP%Sd~-h z@c31X2stR!};>Em89cS@w z*#Kf_c|?+IMw_2NkF<>U?LEL{P- zm#T`A-1tN><%?KDfb-f7`e1-=;cU-0MdjDE(viQ@+lMi!3d`z61-g;E1rz}Jm=_^0d)Qc`l_=ko07PoG&uRU4grxA3=c-@rjoC0{|fz`#pO z5;>s8Uj(n^D@vX{8ucQe$$W*oF+;x_{(0-!pVK^NsEY%s@fF!pkQm6K zfod%|$jM{4!+cW-r@6x-6Bej+5_-)X59!p{-z;22vW4^0AN2 zB_-}6-c3>mK5_-JGk65<|9>rjxJFh{`;v$sF~ zlN2}9(rO3~99^Z(r73Hb?8c<(bc6UVZ%tBNWfyNYTp>_{`~c0zT0!}FK#bqrgHRt( zBIBO7b^Jn{Jd# zJ|^cR@Ui0_eJWGFy(S-(Vq6ogmM)i={IDGc?b%NzTzbv2RSbdpJ#55XzzcHkC|wac zFTeMnj6YY1K#~vTVs|Hz7Pkq={EO$jqZ-Dm3ku=Hx8JYTS4 zP$Ejyc{2I;aPcr?mb7-Ofr65AAq8EJPo<5?1B#oYO1>5U80yZE4|zGwyNXGiA4In)<$YE!aKF@&b9U z`^l~|ndBR`z$$SCMhJW;4QVW2;=Hy~n^CQ)$lAl>(5q+zp*|;e7uWGfn4}|jcyMRe zL1n;$=UW~yJ&`w;rA0lh?<4I4Ws~dvz`xGE|K`ED^AFt6g86PJCP|!uIe`lo{^7lB z1WReplA3vEFu#*-8SnC*71@efd8P5_bm_#+{bgFW6ReGzB?7eal& zkr=gDk9jP%wf*s%5+d!CdM+NqDrHNO4nnw_FOF?b=k;+ii`GN>XYY}*Kb1{wWQnn} z%R8_B{rAsffCUT?{zjcNkRZhet)X>c*C`e=unl$gq2h}YD&gwd>>?*Ekq*{w`8QlZ zzjd>!koQ20)5$y6y)P%<*Zjae5$gj-p+h90gm*g%w~b;6lcD#u3tBsk$F0lY*yxF;X{#)X9Jsr_ z{jGYTSpH$cnI9B;d@ zTpp0VtQoAc?Nc9;Qn1bq03Lpw#|@PEaAPh!FhWT5V9R!U{VoBdl4<^h)@@dI4=ul5 z$cLqMjEkGjj=Q(40|5g6bTr}B5?UQdSD%vq2OTha6D?IS5>$L9RK1qW4e&_Yy&Ypf zOIsKh&-qI16y zUEyWsn1qW8m~NdK!NP6!)g^m~9rsr)RkwRYBGak=^^^EgS$@gi>jd-a$ZXSE(O~1< z7Q&uPxq4!D8M0i^6!X4o&Ep(AQP@qtd@o(;u2Hj4uBM!xQ-7mT{nod4RFI|V*uchf zP!V`pU~IV4hM_|^JK!YA(}~^mwiiR%S_`8;(8%nqLYc`BAe%*O9ny2(-oWm=I(Q+S z_m3{AsH}ca4J?k714D`g1Z*)wou~$#w`ip}5w^ko^i(5yL58OAH=CO;e$_`1(r!ud za3&@he*WZ-N5`fNYeli^)fMRYn1;RAr0e$kqJ5-FF_cg=y?kf5ggy@<%v=1U+dy7+ zi>e8&<==w|4UH?fIcpzCp7TvK$zmi%X12k`?=$4o~-!oZ4Yp#qrd(UT^CEw$;{cTxFK#EPg>QlR_IoJ@LEqJxw~n29|}AoZb+X zAd=NvkRBk75DvG64HxX9G8t&{1&3Ml)4N4n}< z3R{T+cNR*<_a@p!+o(prRfD>G z(*vj_`SY*qcC*Sva4U4zcm6kfUn=Tu7~*{S=>;xlyF>|n!64{J-XymAVru)NKsiTa zeiCpO&W%0Xb&tI9PLdSRaz;?@0oQLS#EaFf%=Nr@)a=zo$ylqD%KN7?pJhUn#z$SH zY|L7_wL?jzIR=Tdtgt*e9_95+F#s6(&YeShE6+thmwlvawx31N)|a|{BKNqyCXr@r zn&oo(Dc#1T)a;XGu0Y2vhx}~#{cQw%tpuKjE3h$BgLKi7JVCS z%A6s;VcXU6-wI)~$leOb(39S%KvD{pGXA%)g3=bhJP1ZWRcV=${&pfA9}9#ub=Fw# zQb9pni$bjIPtEiLx-QRtE3TQhn1D(C7_UscjWY)?sfCy<#&UKos8ammb!k0)TbMn_ zO)=jRPh^~tZRGQw;Wom=gQMU@92n`#TlejwFBJq+&c^fJkn8`a2iTRApxi)x2Y4*7 zUrpTU{Vs0z)2yr4<=$KVShc`z8kx(`<9sZ^w8HSjLyBL~U%@F7Pm(pG=M?#O3E3T9 zN@JFG>^p{jCnWXQ9;{R<`zw|*lpN|k$~Xd~Q%&D&e5RiyIxceC6i>ML?!*$BfI7qu z&xhpK`iRetQHqrQlT&#?bpRR5&nUBJqf`4FKIIHXON(=0%_mWJm39by0nUSE$ev9Z znEt)HgOU$z84b)*k?$xEhnc4xH@*#qA`_ntUr70@w;%~;oeMWDYt|?>Q0rq%Z_b&aB+iN=o{iwCq2z=T*WgHJ0SwV_7V)w@l5tsAQM*(Rm=%v>z!u zjkOEi25L({LX17ew%9r}Nr#9hJxj~jE}_PL>v@uGKAT-+=(xJ->v&=)4puYFVC)${@g?Dg>Yz+UWd|qW4-L-%$OK| zbQQbwkZ*%$eFs)LY6z$S9Ust6ZY#J_QscZ>Vh+*qyb+L)rVQdm}4mUm0lcpo3*0n5Tm=j=8k z@|lT&mJFq462Om)ymwB36(sE%=cDTI-MnuhB(zzXJYejsoNq!iY zHdI)3Stl7cjq{Cg$}7A`_m0y73@%H{2h_2%|6!QgRLCMk_Jxh`4xzDtf9>I-%N*Qa z7pYWD5L^aRHGqoRvFUqc25HIf-1%3g50uOqQR*io;fashj3qG+)_iTwnCB*}x4rbp zg&3ot)jY7%LFrKv`zvmUbJ6mR6kp~ZPP3y@Z=BJM7~;VOGxIxk&Be0=`v z%I*6AD)q%s!p#)t7AxtS`C-+rA-9}^7L7h>(9C<{ualD=sKs25PdhbMh*Cag^C_dP zb87RQ1Jk~mg(Z0)lk1dY>+((- zKJM1ye?K4HDfJ$9wZe7~q0#W*r7RWQy+$!`M}V{1jDqMTM|Os{J0+ph+cT)T;m`vV zLO)75bLaLIxf>WO8&KA4=Q@=MGm+H1N63P2YV+4n%N|>B}${OS|%sjRXIs9ng^p-gLlyG z@jujIJFzR#@*5`)e&@2Z3Zd7KKttQ1FJtbj0s+xKVAd^H{%K>?glZJSxNi;P% zdO1$>_u7x)vdx1L%bVkNKBaF-z08ESd~Gerrm8Dg5@lcL^MCGxg&-=^?#Y-a%@Z~HOJ@j}XX6z!u`%!=o*Cy-*O1H2JG&%vZ z8~(Z-_vG^ma;<~7^ZTgh7;GNgPjOr5+2=1KO=DfEVcik=SLVKE6Q8b&tNLDKbogh6 zkReVmIm4NX(|+uTZ0-?Hz#|Y-&ISJ^fe?{8u()vhFMh}mnMzvrrTO==Z%ePEL_9~| z*z3WP>R%^n0&Ka?t8gmb#M1EG@f>ym8VoI#aCj7=ZrqOMZ0Qi8j_i-Q1Oi&OCBHq_ zT+J5W=DUl5UWN3JUhJPhJD+-XqVze8_Y7NvI`bk+WH;3y?*b&obSE}Zk7I=DMDEfN z7a%G8@(U@x4)e+Q;RrJ`6IRuZIXYf=(h$gr3mtp(jQG2z7>#8gQ;<`7UD80Cm5{q_ zHOX5!1iN-YPt)8_3Nv#Kn}&OqAwJ>SLAoF|96oszUYzGBpEdcD?^FB-J?pjLeKB1D%Q zh@E|ij&MD#Tna|7opd6V%QQ$S&%8e(&r1Yiw4&n!U(O{~a#{ZpgUuCUPYLFqlWiCo z=wlDYb#|q;MRNZ@xSyIBlXQ?#3yQzIZ!^HgzP zFp_GM4qX}xe!U7~*D=w6{!G_;1KI+d=-Wunn!pwj)<%x=2nGr~&&z0D6Qu|P2T=N% zEZLe-xRoZ7Gflh}W9TStbhWdg=L04y^%p1$V`$awZAiv7!3e1*H7xEJnGOuGQi*ybW z_ASc z3GO7QNN{AcI<}+?UrC(&R-*#Uv0sSsD56M-$8syub3?5#{f= zqVtD+Ph}-A4N1t3|1jTql~~EG)ctPdl#mYc&egDG| zIRAi=?eFIRNv&I%^Vr48jCyRZ*dZ`PVms?Fu&96@3;1L zAa?MvC`;9%i}k92$xWkoql#t-IcL7aNhkdE5^ zj&-Nf+XqC^X`r?qaS1TuYbfqeDqJQ-*QarODgLEXCJNKDsi6|ZnQ&P-Qj}!8R~BgH zyih5bhMU|4117oSA}aJkYN*$$`bI9`8{u_`Pom&D*wDjn#YS#()+5%CZT`7L8uTK9O;6BRhl5}A?lM`}zey&0) z)cU5uQ)mc~ZbLsNj~&pxrwBHGT5t?Z_I zGBJ(cGW|?F;1_Nz~wy>Yu=r`}n`I z2QCsHE)Cv;zfZhc-q+)4?vr!qF(R>h9~XF5P3w}*YUd@G(G4O$_IG%cH-R_Nrhedz zJbW>c^SpDR8cQqOrChR@wXDs%HA$`~j9i&XY0!}JC3p|+Y@M0)At}`$JUs3OEksQD z8e%s4!~@ENt9+oS{Za-OUW{ALko!0jlI+qMkUP}Khj?rkW7^?1Dp0|G?dkdek}Chw_skLV z!_IE_oOgp5Fnl;M1Id>C%GM^w(l>UN9l|Z0o;-Zv)U&xiTKm}^9{}zE0^!PNu)Zkn z=MK_uyAFZa2fam4|5Ih>@2W(YP8op`^6gXZgyDM{Sgl{*CHH5Iw2U>`CDEytBBFL% zutUns^DESYzv#TJ+IyiFLS6bV?+%FK&SZ*iuTi>Fm)$CG>II3ie3}ww>Vrp;h$=4H zU=vkdUWFaQNs#e z)=EX(WoeS3>dbm-qstpymaxS6P0k$3*PMjB$-r0_R1-`Hgs#}%76}l1PLvzFt|M_x zVkav_FYE}2_mcJf^|bW$D^hw}*~^O9o&+Ib?)zm`g-CFDQt0$~O zvD~Z_P?BFD7pL{K!55{*aE$YjVNf7f^!)fOtq~4Y$-Lwnrptx;$WbQM*l1aULLShA)^e`H1qb#ERNM zv<#toLe_@E!Vl(YNM~P(hAX$|%8Kdk;#c~JooC?`?ge1aC^(xExO?e^foOaT$lrA! zcJqBr0U-uZt~B==RL6*%C@;wcbEOA-2b$A@JRlINt_~7+<|2h(q}Po zaYWUjr({!d2eoRkIIvscGpRyv9)Wf27Uw8>uenW^00ndj`vtQop&!Y0%x)eQw{RsL@^No{$dDVrXN;hFFy5y>d0SpP;uwrhJr%vUoWNXG`Zp7SWg z^koH)kAA?tVZ=Q@c9l9yzNfVa!EKw~;?*Y!zfHgQ#N~^v+9VxHLZTge{Ts4E2P`11Y}X?J|~km-{mGC1|4}c+DN(Kek@(}g^3qPMCOEx8&6Xh zdince^3>IvNY6xq(uVHS~{rC>sar;%c<$3{7`Wcz6BdK7M{LrbgECBmLJ+-BcG5xDQPVGZCKmK zvAdghxVX6j_jy6VuceZ*YC+50AOBOeUzvSE@3G$;uJzM@|F}fQl$1$}zL~a_H{&rY z$Q=Ek7OW4{sKL}!s5iIGX5Z(6T?`jRiFyd<5IPjbJAWR4f56vV;q3qFL^zeCQ5>4? zRXgsoefCDKfwg)4U-l-(hrU!9^D9qatbjKD820ka%#22JkyIz&H*=#w_D(TQ1?br8 zGo~h0cSKZGaD~OMO-JsO=w^s+3#?jRg?CuO-la%HPFuD3A5dW(%o6`IJTO~}zOxC_ zSjJ`eGiXlCHg0djS7Fr#}(XX%^i2a)Bt@}zUlvi<+rX+ZB3 ze|}yf*DB)wDG*Oh9vP#df?C76(&}1W-OC_NWIp24D=a55qCfVeFR!`?DERf9+i5QX z*g=8Ek&D%fk-SyDgYxC+`mX){{D0)QWtP_+r{Lk9aqcZneU|f5T16yUh}?d^9#m1Y zOcNs~G>S(JFHW%*CoEk~;J)vD?AXQU54AN-OxLKhf5(hGM{-(kzCC35`c~fgtJ!sx z296I`E+sM+W+6X*}+xlsV^V`a9!a;Pz6x8IgaUbsQ%7&fMDCb0*h@WDB zIisihx$^BVVd}$|@t2dqLmfI<=E`t7UFsK}09L(JUKl9zI-|E9>Nh`-?0*yAOg8bD zlZ3H+b@{99RMSR@$$tBMmG;{DqB~sFy5&YBh5~_e&_=c-X0w+UWe3B4$^Fv@2eI&d zy!(9=&fqO^#H>2PSgd)jFzwI>!7{F**z>1|5pX{Vr)@9mB#^$f*UkIG!iM&hw3#3c zJ|#sgc$7uNM_{Ar2aDrkT-`v@qJBlCPQ8W<;0-_Hd`uMXD0S!3WCFMrwfoM8>I&4e zb(9ZJC77D`Sse9!lArUs<7^s59blNw5!usj2!mC7s9=N&pIhdud(7T1uaymgY<8YG z#%^R)__G1A_IDp)r_SQ5Gn_{0zdVQ;xfV3IVEVWCM>s|7>|2eaczs*h_UkODRUg9O zb(Kv5>7@nXV(xns_nc%0!9ln`tKVs?INQiXs{bG*%g_?+6dej|h6#4V<`cu0TmOhT~sKtCI5t)&h-!Y=(`ec`ZPl*ZJindGc!&*QY2Y*yGN2>l0f-a~58W zvafA_BFEdqAGMgS)r@%FymL8N|^I^e6Hlv4luRb{h88tEKZcn)pov@kNw9m{P?Xd%}Pg7BZ9MP#i1~zcd8QZ?(QgR zZtuW2%F?kOU#ddAAZYeix+?$2;o`dj3)Cj+g6;QxR_A?+?hI-gS$M!*;e{r1hfIn!|QgS(?+Ju948YuGcNdpHjG?r4t@M zy`MGv3qz1&RRJ4bf*UP({HimCr}jrt&G;=(HphSnemQBC&Gi7vpa&|fAjpegIF~Z@ z`#;K8a!?Z2kPxz=;6|r**}!&5qN>MuQT1~2VG@r5V#gsdIMk*c+4pY_XLBxFy%Cx) z+dFvD=16xos0bCk_>bnNr52zVXMURhcNV&IW!+R_8nEDEYNs_s8xyZk(9L)j${ za^4)~nrP(S@ny#HRw=QQH@+L}!gW-O5lz5I6&U1=#a>%ymyN7TYHf6(XKzdIE&06w zuKAqcXAe+7&0g{P;NO|Od}NgNQ9A=dAa_4Q1V8Z@t?F(G+)4)qi}L=1grBaDJpHV- z`~fS(d4rL7ih_`?6Vn7zvy<*urccR zbUF>S_5a&Dvn0257>d$E_4~*cvi~)vk~n@}NYH421Vzf$a86aK9b2L(+0w;CGCCK% zY_C_GCaGup{An22jv7R~~CpVg&h$VwO zs4}z2MX&V($PP90LU*-?gC~+(5c5+0P5m0p9_I8b{?C)>M zHTF^og1w)t=dORBI(p+p61+LtJwsgHvndL@uV+9<5joq}>@~4%jTmKcED-bw$W3J@ z)oA7K^tO6?*~iP9dHY3+yvSdD!+V~Iw_mNlTM=_XKNwpcdTkv2o@qsNdc`#|@FEY< zilr6K-s>FYu(fwB*j&2pyY7>{PGa0e;%v`J*8q4#hLydy?e<=DA-V=S<#CkXFU$c! zAH<5nQjzdHqME4JJPL1Ywhr_4^f7u^ZV4He?inh!zgE!qP~q-{lr^@3yCuR)Mco=r zwcmv&P(9QlEg|%hz z+wgnMBhkmO?a05{Dpt{Pwj7?8@4*uS{r^3NC-qRLO!}jhdWgPLZ+-5JfMx`3$!|y6 zz2EQQ@xA_O1H}8MiO$Cp)K)smYddp)MIL$0klUhR4e#et7>E86Y|c%GiM4kb-KgSu z*9586PV|1p+TTNXy7&COaqC+r^F4S`BQF}!`<+HcYjk|w{!))}?cbdjb%>&0BW*_8 zd7pdty1k}*xF6y5;GwTf#=36h<>WId0E>!amWJTGS*yHU;vT5w6-TDm-7>B3%I2J9 zyCuWOB16erAmjQh{)1o>PUkCsCYLRSpicGlMklO&Wz7o+5KbzK#{qga!`1pH#XxL>{h0A3h zlW(+sGnt3FCrC1!(#tv9zgkGVoU|A6wSpZPu)W6R%Oax>%5e?;+}cv|M>C4egCLL4@~PBZM90cx4ja% zM(spKfV90N?4Efq!%UC8W)wwf2{DwS?>I`O>DNoo0nPz}z5?2Nxm+&gzyJRG``PHt z*b@r3IlHry}5Jp-@Z1)Wq1fY5T1W04;ppWGvBnXT8@~ zkvX21hmX#~Ga|k3u=N_i13_O%wy5a&e17thXV80NpDjcuBJzrq$1KE9^8{3%ht7NV zEVQG;p^243Qp>TlcZnW^3OWWZP_c_?hEG`z;aC+Ho$I z%a=JEMhvi??+C!-oK;g3*s!^(DfdmnXRw) z^FHtS4s{#e_3QnfTE{!1@eN}j=x`dM5VrSvRvJYY-$lpw^0Y# zBWk0^SgYNrC{A8Sbu;?^+NkpSWQ#IwTVg!cemejb1RV~|7ABCf-dx5@tW`YgHoWa> zg>XweQr*5K6K2-P_u&~TqaqyjC;B{lOwafkX|I&>C5qyGk6ZZd!oFY}I-Cy4b-xOE zID0wd+CIAW!G7lL?|IhJjtz;oxZm$z_Ve1S_0MAS&AR?z6x$zd$VC0JMvB)D@yI>l z_V&Nu?_K9(g@orjS&zbaiw>{qU8h!3<(-S56f7JFG{jPoIGa>-l zyts(^uV25Kebs#yqc5s|0BC`r!y(BQlf7!#VXY5QxOj%>jTD<@3*@3AyjnWp9fGyi zaiex+o&s+U2t91l%b#Db*Ig_o1lxj;I~)=T>DJaqFXi7n=X!-UFN{2+Khn1Mnb$|{ z@kae=y>G?1_q_CVwCzcokw+O7AZCi?ge6m+%Jz2O+INs`*9+%IDGV9D*ow~R)PopD zh&e0)L5D*kq0FpD_IN!0&i_8ki<4ZvH{@waTi$zKp;ql2bRNBx!U2S|x+pQ^ty?nby7880tpA^Bt5C}RPk|hsDc`$p6 zYb+spK(|8go;bDk$!x2O^SnYYA@auUac!>OizxI&1(xiij~$&)6e;kI?@ir1ntQJm zzRfrWfPkRGA(8N9?}JiAScg$Zz3N(3xfL&+)6ay9y?*KRfh7~Qu+{6|zI`j-zkmNC zMzv6~{VVNx>(X0lxp%#v7Xi`7k$?JJ^lu_l#MkOW=2~Wq1Do~%SOP_H00EJJ^%@D; z3Tdy9&+Ee)#dAWf@;}p;3`?)0*VpJeZFO})84kGB{=vRM&;c4m%jITSQe|($w6&1? zsKJr#t9&l=)h}&h4Wa_L7PGelcqa%tKmugx#+=u-(M4_1ge@a|to6yh27vv6hYrw*H>;Wq<7$Q5dxw_w7S6SX z$LYT5+1^@1(EwokAm{)kH&v(zU~OfwR<1ibMs53=NUybAC;;pa1RYL=tY&5BAs?Y- z49uMP#mlpM!`7lc&CK}&z_vip;Z)S-37;W!-q`craCXMaubo4*kKXUq6VU*``XK0V zI-==TXSP{05SGjiS4y9V*V>8N0)Tx(l{=h{o^{f*h?r-`e`_)m)wKG1zu(h+M9cw> z2_8DYAle(h-EQUg@898erSw<0lkWzA3`0zzBHg z01ay6%ssNpv+8Z|(g9!;Jam8rk(X}Yw-dt1&^52(UH11r2LR{=K?mp{ni=kTy_U!0 zQ7wdHIaB~x69gS#0alc2Ync$%V43hD{rJ|im zb^url1RY=kt>U(5=o$dPEC{&+OduMjX2+V#djJ5l!9xcC05|}6=l}o!2LM3_001}u z2s!`&zyUze0RR9F0D=zi05(Y^=HlXQsB8QEeOe3?X-bl@TF-KA)ciJX%r};Ed?- fx}J;)V>i$Loi=T3!lIJS00000NkvXXu0mjfdz#(I literal 21069 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Dimension_Elevation_MixValues/WMS_GetMap_Dimension_Elevation_MixValues_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Dimension_Elevation_MixValues/WMS_GetMap_Dimension_Elevation_MixValues_mask.png index c254de9fc404cb2b12868fd5d29feb4a17972e45..82512fab316cb43c33aaf2618aa693504d731203 100644 GIT binary patch literal 31630 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 HFGK$atPZH5 literal 20965 zcmeEuhdWzu+AR!0#V;b6w{;S5A`WJm;Lx=XvhWecw+K9zHN+y(n-I006KW8|hgB z05qikHYNt@ks&AqG6bq~13Mk@pW{9q6r zrvU(b0sr^r|L(#6Ck`m9osRWO2Z(%!O8`LjC0fer>FKGUwzhV^zhF0W$hIE<@bNkm zi7}NfY;^0u`(ii%@Lh!N__I+gglh*$qyadC9Q*xm1;*vsH!}jF_jQYi+4E1e#KJij z0f3XZ0m?64sdsP;k_H$a}RnJ2H_lr&$xETlUCEjcHi~9&{GWmpJh`_DA z?||(h_1OWRW}O4NuPDainc|ycwrBt$3^9=wviDRh9~vGlVbFnhd)D@=k;PKyUQaZd zwEzHwPLUHw%CofiAF}3(3JVa(kz!_4E3XO)(V+GD8x{ai)G6|NQ2)*bY9JzA`WO)Q zA{eAP8lc(00f=T|dNX%r`*JJcfZ5dfeNfcdmb9}5QrhY|bYAOMuR)>M zd-aA(=`A0O?OOIUcM5{`oLk4%6y3z?p&cvA#{ay@==CJ+^@)F_C_3v>G+1N%h{izY z{wv}*9dhl&qOhT&+Bj@COnG-Pz|djRs>^NqTU+`a7$zJLeM#VWAcJ5OPYj_m_cC0a zYX|2Io7U*m!Bf0WHqJFPtAQnS<|!2gT{7nj2_y~WA$9@vXf}akR+Yf3ka&>Vx!k=D zC(f{U{TGbjSz}`KD#(iP>Q3uFGKPLh8m9OA?*XhCSt)b~r6j@u781;2N;-Hw)=Uaq zJ174#_WbfeR4CG_rDm0F9KGep7rk=gHPZ65!^m1kX8hS5rofLknMhwVXx#D4g9?qN zyr*?&n`iuGI@-n`4?Y6Rz7CvF?qC9Q*4FVV z)lczSyxRu2`D-W`WEgU#aA10fUF%j`;g_oFcHXiO!7vy<@1)0(oz`v1z}ClM3*~Z< znCF`hLSR)j$kVmF=HS~}4=?>m=UYQbqjar$% zHomD+P$^^_G3{y#wGABgo#AnR-Jqw@#;(OocPxQ0cSR|Qn8Pk3`}!Me!&pAn2y6@bl9)=I<1dv$pYOkLvg}6 zvM5M8-eBYWMpTvcYqU}|{)cutUz#U4bLsY(z`ix!kJ2q z;Ik->^_XFN5%!+9wMkE=(aLWA@?dsch5^dKfR7Qm=M`z1Qe@|z1kD_3ztOn7VmqAV zmD^frzIggo(=#orb>^+Nt;#fA@z-G+2CV~U;|_h{ z3GGRxO$QAxT}aw9WLNs8^;PZCh;ZcBr}p)_ggd9YmlE{4xSXvH;}g4dp*a)){-SyJ7^^-uvNdl55bTc`DcRuNm-Q0A&m$^ z3Yqy_%gco3;RBP>qa8i-tJ3Gl9n?AUA1?X40f~!CfdNL*?%ptUy#I0m?5f+J=JotK$D6 zo$N-fm7nZL*3SevTOPf&yjpfn+-?15r#DBWQ6j}Unp<}G-DP#XqdXK}K|fqoS^y}> zM5Z)_Ln5Y>h+wA{s7Ykvx%0m=joDvb*rAdfk zQW}24pV0;dG^2dV*R+6s_2UVmgT2m;weNjc*BgtljsZW)4d>n;3cfd6XPHjSDW|)wN zNLk#g3)zf~Pm9rEPNQIY)NYmZuBQG}6pBK(mZokp&Hph@c!kI7kim zoRqoZy;47NL3qDGZ~L_;NX_$YGtZg#*glCg*Ab(0w_(VQUIELU=+>u^oPD>(nER>i z=z8R1nNV{kjM7*RB??Ty1cec1@(ke%{$D=&%l@TpCit}mg$#H~-D*>Zm+*V?f)$_E zj7}C&4z{wqSBFRDFwA#yv?mYJ;EPsws^7yuJxnYh*}>N;7I6A$Sz~ECbv6zv{S$W* zU_`sE@>R>Gwu48Ep5wT1bl={4xR3YO=OgvD2qf& zlO)bN%P_4j3}xZ6XCaC5m?>QO9@0JU=T_EWvq?i4BJFV7ZfF9R2AhhU`K2|eF?1)D zS9+y+*~d|CRrc*@ggEk|X`Ws`)SlC9hc@kqq{6Yj**BZ~&Heh&Hq3m(@%$N#EpOova$I_Za1kj02((9+Ens4ubqsKqab!%G!G6a0 zX$2MKb?ft+=7tuu=znf;p4iiXJR0IFz-69pc!DB5lWG>jF<%Ssnr~s;!{DxfK`oiD z7SEx!ak3k*h^fIzx)2sRM9fr9K#U$EZo+Idw`i*2_$ua9Gd&)oX+^*%DAlu!kfhs$ zyxlRD6@_F6pW9+N2pH5bQ+e$CQrQdhgah?@W_8dI><~#XRpV726UVhbs+h2Rt|7;> z`aP0kou1%kC{<&1F^Ld=H?8GMy;FDc(m(Q3uPwUTqnFAoNtLHZU+nP4$3Q2+jEZNb zj%gf&yQpnc7H%(>WJQ=D9LTbm`w57j?cpP^fr(SR80>FlRxFSB6HG(70%cA6oU@xu z+7NCi5F3B&Eo1&q$oPlJ*(||xyJMu)wtGMN zgj@UbMQ`{<=fcUx0ul8gl@8)S4#XyU24o}i3M^b5j&(mgtOjcx?JuA24sR+XPx(F4 zYM!)B4W0VFJ<`3_t{(GJD;nK2qCR0|oxrtNBsbvpJD-=06g@GsirU0!+%0nzS^t?{Yhbr zL^eWL=jJ)q&-^_&2tGZSaaxV!3l{s4sdJzG-o@~CTy%m?n8(mXbrTlTl^d9@ob$!+wK`oo6ki4P%%UJ3fQ z7r?x-a-*4mCM{Ef;2QM7=+H&wCBW z?U0Adj1Pn32(q;Yc=6|x=gQ}+OnCjckd*6F-ef!JB?vAQ=Lz~94c;l(%Zys1XdLKo z07@WjgI{C7^#ngfK3Lj$$DIeTK>kx^+6a!J0psZ*u!A~gNsuGZN4@Z& zwd^A<3!h?)-_VRoZejnWdgzc$e~O2B`k>^K+fr+A3@*iHI0OG0e4fdxVW|qi%YZ~6 zQ0AUxw$JZ`$0UWNNt8y{QgA!pl$x9t}V=px#j zZ_Ev-P1GOuXR)--x>sZF&(0XwUxFhn7YX|&kY=R8*e(Hsr-$#VgcFdMCDB14UMp{B z$0S(??UDigvfJDvbn{jqPn^|Do)zB}&RK1Q`Rt;GH$~D($)<22&q*(*bl*ip&Fph& zqkRmM$S?o(3PWH6Xi}kMc*j%0g;p4=HKzThK%v&_YE7T&2jJQUDrC;6SA*howF4Q@ zqJ&@pX5F{l;rF1Z$Lg?`&78s+EV?Ek2*+lh2ixv9kBH^O@z1_K0U^J?`W|q`@P-yU zT*XvP#G6drQ>kqE^RCYzG6H0lr0;ylFqC=Tx@n;>XDF*ucac`}9Z!sKDk4SyKfxGgMv5LBvUw!%%ok z)f)ORAL3Mlbvcq29Z#~Kkg!eE5WX$nVit}(v9mERhv>ZHNih!LL!1_HO;Bc+0vDgi z+WxwYK;tt;bG&kE=@VO`z@7RdP2{6+;kL)XwOP=vs1rXT!raqhQpW(pnF7X_3T0Fn zOLrIO>ziKL5%uB%%Jj`rOkM8wT(>wZwu~mzeYWMJ^_()CDxr=>hI;L$=P7?kab6tj z4>W|1p8jk|oE?*KwoCu{twiExz|qsXy-O1j&t7`m0OGB*`A6gz3Ws}|`^#EHN0nzd zpS+(jedLUCH-qp>Qj5t}PwlWX%?pRcM2->7Tc3R%K8O|;f!Y>8+MMdO$J|@B#&{Ma zZ@nt$D$;*g*`3~yLASymQ7`xkuQPRemKGik+c3=3ly}Xs&SjK6iljo4{l%A+(K?~G zaPUx$o6SSc#@(y?$P&-7Iz^lNHM_$*?AYGH_8at9k;mvh6^%yVtu|1}-H+GBoRVf& zJxt%nJYvrU6K~d&@;q`o-Xt6++YDEuT9V)D%-~W!`bp8?=GK5q-Vzi6ckS`j#QaUT z6cu4FYt=T>#zVMW-GpNJ8Mv*{8`}A%O5fyI zF6uCcP%pJmgZ_Gxig5n^^Wo+^s}N2vEj!Y?7?dJC>|*J&uvC4azMJ*Xy<)5d2@=a^ zK2ypXf8#%SbyDZ|+e@?y3H|kVemPB^4yp%@3;(q5z+e4?KL$45cj!5=!9;)0?08!& z)gp8~R0_#f;$U^04fD_+c-85G=@b~T-ciPg^b>O*ne57jGS>FvS_ngt5}ixGwnLrTyUzUp){|HvSyk@CAl;Je)M? zFfi#L-F9N#x{{+Q<sFc2Av4z_anBNCH9fpu0ierw8sZ5 z(n(TPxZ;USk#6cNb)Wjh{{unld;E5pbJlNA^s#ivvYBj5H8M=2o18|=Q~sB-d^_bB z*YolsPji9nV5{vF!Qk_`OAPlvh&7d&jWFq z7!nt>qkJWjrQpPnGFCIbS^~*?`ziadrv;;LG__loZE#2tIJ@2&|OazsTi>&|Z9G9ITXCdkY$kp)XMWhcjgjx^7B@X@9uP^5uNg3=NBBMyNwX2g&W`G2w-Kt7>#5ctD z#lT$$l(}L*$ziLOK>%^94GA~!#G&!X9HQ%SGhLZ2klDE7=1}E|h1{(WyrVOamz)}E z51DrbZ;!iByd6TRy?;q~|EH|IDOyM5)0RjwDWdWmlTgId;|sKd*H1t4%U8h|+XyUU z;a=p=nvEAn!2&3MS6e~53*S2Zl|v=(4rJBo`grzQ@!jXjp6BC$f+0@`qfq^xu#rD) zroW)8x4yGTf3)KIv~p$qI5^qUkj1sv09GgM>RDh@$V6h9SYi}8_}RL{Pr>q?Zjir- z115!PYa~DoHvXIuCR;7q{<%%Mu>Ujf(5DhoK9>sy~EDhc6(} zkVH$@nQ#m$5`6gAVr#}<^m{QYttJ3klrL?AVCZ^W)M9pyT$3BgMxmttn0fcsdOm?v zROZYEnxCp1w-^|+%sIvkX9HyDzWNN#%*;?}x`p8S7NLHwOH%qAYq_m0e2)kO@LUT+ zgQ5jRDZrC?X`r8bi-A@1%2pc=hYqf_`cSUHLpx&2gJ*8mxAGN^ClGxq0Oq>EqM4*}9| zp0N`M|D?qn4q4Y|v#O-ssqE`cZlfDz6gd|2I11EQZB13M3I8J#4u(7S#|&`xRUcJg z{&ATKh|j=xjAJ8T2LBoSasL&RbmGdjpv?`;XkXBP>fcvJqe27#gEvjiAM@u7h)%mF+j$ml}L18w0L- zfrn;qK=#!{W|(uXGHU4^Uj()%UncGz_P0&NV~xMF6XSdhVqU||YOQs9uvH3fz94o8 zr)~P~p^Q$|pr)hXJ^PM^nz8=dvuyuusj0;onWN?m3P&+&esP7z~T{aLB` zFscY`1k=e$dE8*a?Q)jKoA0FP>Mf9&krI>yE`U74O@a@s%lfB$vGw@S&JJU5P7*E@ z_2RydZfR0|>NmtkUM3Q=4P)tDbCASSlpyK^1!>Rl+a_oLx5}V7r`{`#(SU9_!o9{$ zgWg|#jj{{|;d^*=?aX9WAuDYJts?Cwlb+4#%VhyxQET@WY9>hIVNvx*7}CJ?L10XS zyyZiW8j4-lKfH?)$Wsy*`}HbQBJ%7Km6Wzoj@fHnYUrMFS4w*fxjc3KRjL=$AuF4WOrNkiMe?7T_F6A;Cjz{WrZrafGX@loZ1+dw zetSdG+$W|68Dk=SWFhG5ZortQ5baj)Lu>~0^!Q-tvDR}oCX#c=>wB07DyUD5LgV58 zAZ1NoFROl*q&*pjyq}KT!qAP3pDLdnZ`FGv(l9CXTZ+yi$9fv8%LP4mT;C;Utf=&v zWh@5a4uJdE%cqY{F3ouM`KBzb^L-ItF(%_c5gLtM9P5dx=z)oKvf^%`evPk2`g{HL z3sc`t=KM)Xv$iauDdpS7lyl>;+)vBGX24sLknDOf1<{e*2QXN!p=;xVm(N5Ha~O=W zc_5ALI`b`z?_;1i1#?n=i>RYb?LYd{<=s2nph!FueEUqmQipH@KQP!X#9UO?N*v~T zj@1g;z2c?c{~4=WBrnSMMp0>>voQ4dgc5naA9d{ea^R+upiL>x3JV3N@Dk|Adg=4& zRkm;q+B@yUgCc3BqmSdOyu4q=XkxT-EWL*DfLc5J-d0rPSwyON(PhJd~Vw4yp zqTKemdENG*>5{X1ca1F>O|O7NdER?CuLovyg_mvu!&>dm)?Rxy(NTVLjj+R1N?iEzhBl2inKE(ycQP2LVqU232lx`?R@2)f8BKp0QmbR|{!*W56(pTRzbi-;G z1!M00(A_+@=H#-LmiiK-<1{==yE6P3rpk|;Xgg|AjW#M<5b;dWkM_#e0Z%*Mzug2aFmDF7JMZ9%g!^a^ZNP z+sIXI?ZE-*ONilpr{Nr3WmE)qC3pfdJR8T7w2ZI;sxJ~lf3wI8O0;43qJSe2ojqby zQ^5c80`w!|qNq>kOTaPVCPZeR-*YVM%zrCq$Kn|RPw_f1-X=HmWpSxz7~6eO^sS?z zrAUk}p5fFvlm8rrSIA!05S^-jF|99=%KI)2ZhJD9*Y9h?H-Pn=*lkz`2+Gv#}<7JD`XtF+Z{Wv_NgpLNcMUlN)twd#FJ&-WB(j-Nk3OMckt$p{e1|Ci4=qU zu)SO`uzrA`?8hQ!)4%hlyQ;P+9{mRKzpr+fJT@0_1v~wHOa~t@I`@ShDc@yS+O+3b zm$G6gIX!)gC2IUk_!HhuEa?mA?}4iF@~x(mkB~p!9XFO!Amm+y(%wbyv9*c4p%-Hd zTRx#2>sKFM9Dj}dj{JlKM_LQLZ!7w^-|}82ozW?Y?nx3uj#iuY)I2}I#Z+B2AoGM{ zQ*`{U7(}s!t*>K(5b_Ec$yNY#Yg_qHt{-N$2b#^BM;M@l2X`^_R=`hxMtQpysG4;K z{!8#$Plc@*m;3uq`CBehvb1HLi(J{6EKx%{N$M@FhWCA^;b&1f6^H8A$y7zgPe<#M zNz~!*)1B8}xf+My08lwkP=$UYj12819y`=r>R93*(`2C_%T3$KCI_K>|6TsYnX2aD z-46+*5+96eG7PJ`wfWW{B?ZlWc0jDoXP&_Q8-kl!a_u-qQ8|ZKhPMKAn7^d9-aq;! zxZTbVC-QFvCQrRuaSY$s(k&|d_8X9fEc^|f3g6gJ9M-+)JA|@uO!psq-nba(PNTFG z%{Q=Ou?n4KV5Exjg+_A2sMrN{o5Jwebp5T*%8f6LS`FfFfhxroQQM`PvmY)!kM-LH zRIu{jpDE8?KGi!_P6gbMpd7NAC(@H+7g=u9VZcj@FrT|)DpQ1xipg1G1O7Wdp` z)(CDi(?kF$7{r*l6G8BvEtM|9^e?GutR5hQ&X2~TrqF}>zCeW&>I<3sPZqIdeDRif zl-2o`PElce$d&tIF77#d?~>CZ2!j~UD24Qg+PqI>prO#Y)u{6mBC%`i#XVSk5K!Ly z<8K9FgJXNWsO{M^@Z{7O9#_b4oy?jI75I?P6f8&<@xpUAqIV0uS`x)(%1XD!y#utx zi83pbad!-qdXfhsgs77I_}qqsPbo&>P;lL!aWJ9(YS})T`5G5!VT7<^p}0k^P|d4h zE+N>vEXW~R;cK$g@S6zy^Yt5E$wxV2rswf784bIIB~QAJ)|sCwE4G(kg3P~u>}*mO zH%sZUYnk?XHTKq~Wk+MTmM*4?2D|FFyIj3}4Y<4D|7_%D3i#FUOWCHV$Z~qBmh!mS zB(vj+_r|hO#j?ZkXa1FO0#NJ+7}mN-5_7yCp1`Zc~?iwoLCQn34l#aWQ^p_9bs{c4w?y7uIPF? zUH`oCrMvs{lkFj)-3}XUuVriQK4W`IeWHJimGygO#A*W#XfXxjXA@)3!3`xDhunmE zDq7(dQ(6hYIGC<^&zS^FuI;!-2;@T1lEa!5jq>xO@R!3xB)tx_q?;BPO8B6Gozd&B zv9BKSh}I!q@^gj&y{hnSu%0KN+gK^|F`jn0?xD8Kz{oFfCpX+Tggg~BGQT*u#r*bd z)W#w%eDOm+xbuytuv!0+Rt{B52Dl+grhv5e;xk4e`NN~*xG=h2tG`~D@@I$hp~`g? z+hcMtkWx6R(7Ek|FMR##&)F`;U;9`BU3%clG4|89|LQ`2+^nmTxkcE)M*fvKXuUzT z4!qSj9k4F4{Ng7zgYd2}1_hn^l5&^5H=vv!QQ;wVm6;g_S+p}HAriG8)=pJRl)4lt z-;t5n*wlYTkjolW=9J=wPWb%GYFMfx+~UW(!S_zP@cU-Qv67vyP zA~6sXCTSU6tK?*ee1iN#n)0cBLLSWo(Z+P~m$xhuEFbTORlatHeK~pj8h3^!)gqG! zm{3D*E-LTq64cQG0G8r0`c^@jb|v+t@qc+vzSVllvxikrCr!yK4N06*0Ts7IbJ)nd zM8xibSX$+Zu_vR!@N*OiGM9@!`E*CuPRf6XjGdado9LQZ??OlpBFqvsM+96jW~&;g z2QcawSxTzTipnCicwQaNkFb~+D-*g}4c(C03|b3;>0is5`Q6UZgaqEy5>2&dmvLnP zyF^?cirq;*;HIaZdyl840*H*YH7(W4eOMpsz9KAi5GmMo-@=2XN(OB=!fMG7wvXH+KO@2cY5D~EPf*%_#NqMWsH*{VC%@Iw?RQeBo8 z^_NQ$`63hq!IcERLhL=68pY%-PrMzNWu7wu|-Z@mbkbjv-pTVhZM`QxoiO z1gj)f05g@*CtneHvsxNklyz(vzbH zAIdU#yL;Qxd-vowe}7`JjXFuoWzF{LPFUx*#JS+l-i0DcufPm&Z&VNXXK{${)h$-;Fl>o9db?HXoz*fEHw@i4a4h z$S~-8p7p!;U<$Yp6(e$(83C_$b4v*q)b&|UkU#3Sz&sciaP*va2p(pb8K@-Mda5Dt zmfzvr`U16$(scY|we4Eta~0C#D71V8eOeKoE>z1OOWcj3{U9r^TD_8=ReX7V<-jrr z1+V`zo5I1R_-Qni{<|e3MR4&3>vVQ4D#Ci=skBT}|ZTKE& z^~UGGlmw zKP?~Nc(R0Q;7<2{mwPxD4# zaV@y=sjzQH;>A#DHk zjXCcp0{nDRoT`ylZL*bXn&u}h(E}7cM9HJcH9gWN^uMf9>m$#+KFD?VT{8B_E^6z* zmb`3LF)`SDSDu=e?-#}-2GzPYo9oSpY9OKh{dg^bi{u}0E z0v=0JkD=zOf>GHW-LbO6zDhzg3K}d7e((`TTOEwO?j}AGgEwCIweNVl7#d?ITzGmB z%+RdQp~)-8o3A-TR)AUT(^0|3IM-&gR0+OVw16h0!Vi}lVtV1hOa|1;mwkxhs8opQ zC#lptO~?q1G|6u@lexa#tb7OLGyr^J5zNi=sAA+oGhy7dt*H+-Plfj{_1IQ<>t}|- zd$S%FZEF-s%;;`ISX12ZouCe0qHt(Apn`0$!=k#_JY?rhGha|mytzDYV1Rdhm0GG} zyOrD}&F4US@#U4;B)b&jvr+1#QLMC8cX?AYBhKU1dI$?f-?-Y{gxgVCP&u&9JvMdF za@F>MhjQ!d)w=4oOPxkXYli0t+`teRX9YH9+PT%%dVH_V%kGKApFW@Wy0ZoNuUqL< zb}in`TYZT#t}JowdyV;X#;qGiWtmy3Q3J;2acS4*2!X8y(g8Spyw0)QwojokY5#pr zRFW+X%=0K&ljXJ2OG|#t5!5YaydzsZS(EpfXKxFJ)t2Yhqanj%bA?H$z^m!92t45T zfVvBAJp6}va4M|bbIMb%EA7rIrvj+(oApmF~)JV&=r`tcDw+!4HesOwD~2Q_^$IUw%$^1=urjCR%xfJ$c|o%#BJ+Sf(&n2 zoc4i@A##ZRXsP(z`pC;5A;W(cqA17zEBbdYSmARpY(T9;3u0LBuOX*uW`}ER;%T{8 zVSW3UzNi|JWp|%U|Da2CdtZq(bjR0g*TYNUwSqR9t2-0nb~9_SHq9S~--laQa5w(j zlAhs~`YE8e^%+;U;+LCQ6`JZ)QHcIK;rT!yDxQABM06aa!^J@O^ybRA1v0v-DTDjV z&F$IyHKVonG}`35y1TPjWMCase_$A&kh<%Hb16z5A0YHfi#)Y6SH2j?_fU+oZR<5p zPc40IMkY`&vAxC$#m%K1&gBilQWeXLLW*K7Cns;r>j4K`0Aka_ko!c=9@UxfpUL7u za$cj6Uxaq9?>4!n#q=^0iN5wQ6Xve+d0s1z$K%IhnAqu@CJWtwgFlk@N)NxgMzbS0 zdv=o8|AhR4jFeZq?%`oSFnw(>f`(J8*b%|U-S+Uc%_W;NIeLpo^J7hY;@Wvhqegv( zA3WvGtj+lG+mI+|`L}bZd-d&7$FMznA4ww{Sx@l|Shw9Tm697L*_Z;!Lc{~mX`-in z*;e6AG_0ujb5oJr)+Pe1TKm=;-~8)ZS$pGZ;EVR%1Ld(nKkzYf%}ftglm@O_nKbF= z&f|PMgKXOz=oOBMboE}vEC%h2){O~l6n2+XTZR=ZeOweK@f_5yr25sM=cPuj^;^^j zN?$>>p6|>{h0?`D>h2}f-lUthm?-JOpV|2Pjn`5oPl{14fp88!i1%CSD>C@rZIXbm4PKb9-^VT)Q#4VW-AzXEN z;rHtL9V+}bbAQBZiv?Jkf>v#jo?H* zSmnvUa@)(qPX7vh(LLLywIenT$>`m#y<@vAGL!6+Gm%I`iv|dtEW+v)pxj)p7E;f~KyUa+1T%EGbmMUdq2^!#ym^ zzi}yx;~tL(Y8Fr!Hh{{T&e>SM@0Q#4;8W<3>exM&lP4&5@{b?^~3udfZ ztE|h;(Mhoz7R(=Wcdd!+vT-N?wu4}p_BvYFNltPxyDFUw&wz}DY?*l9T)__e zM8)ZJOJgXFW*HpDG9?hT^d1+nh+YY*56y33N%Dgn*4=0O_Xgaz+UcMIewSnYZuxvD zr0xw?-h;;Ixm1ub>@-|!HE2inJLbM~=P-va4vTaq;zKoaF-lJG!M)2&Z#r%hkZiO@ zMOk|~rKz7xkBgHOx1<$z7w<=`ONBg~yxtf$Yp7^`TV)5dxWlBM6TxBTo(NGyf+{grr&b2AVwKI+F$(U&spapE`bAv%9ST z1~(tKg^iWImaA;NBvV4#rTy=hA)hKA6og6^mT4D``So_ZXA0D{pR0c#K40LIvgn!= zDkS2mQ1f6a-y`#YIg%`I;i7i!sagjh^ui>^bLrAZ<)~nO2gk*`0<5(Q@;Q^Jxr{Q6AD}^> z3gp)QN$vKIPY0x(;NtAof4>deau-_}t5XP=lP!7?{Of}`+FkqVcHqiA7rd5}w1`;I z$$}u##~IrV_3CZSB3!vKHu>Cz*wCv*(pi7{@cyQV1p$NX$_$8tOK7gVsm<#6h00rR zf4f*J2Q>4F5}~GGv@Iu>rCVD?{><^n?{CYHqA9N^k9&@Z%8n(K4&_}}c_@p=R|%ry z7iPb%eU5d}mQ8<@(yee_$Ft%{O)IVMUnb?pgzsDTK|(p_`aOn~Cs+ohs80Xo-#+}% zro$cO7jT=oUao;T+#b+9wWTdHYDTO8JI=l~uAmQFV@KCvmh+ZoX+2+jwWrDfq9K0| zeuU1mCxXT4Ut)086E!PF6D0AsxuA`HHOCnfJqJAPT|@Ifg#B^G-=gD;-^{bs>HI~9 z$zqo32fnN(5yig?QG2$-XV0`y4m7A2kECyfk$Vj9oeMBhEgCz`XfLqLVA`3-!{493 zwbWPXlun$%4WfF@{O&iM+Mq+A1r4(Qz+dd2AO8AWC^|0V)m8b8^1hUVvt3@DxdM5o z>%MKyaKBMvYwp9{{8A;EGE%`_4pO=*PN#nSDyFN1`|zoGZ17tKDHDN=){(#@pydU- zuf8j@{5~>eAxZS8v8fCu;IrntAlmQy}AM%0eic$*5(@ZQhQ@T`RM3TTxTVGlqn*h%@uZq#v zqN>KFS;gDUxl@18ImbtROR-<*;-SA(64&5$MrqJ9V zJ7jvvWk4pbw#|K%X`Zxfe4gC%>m2{C1r0qJBkqz#2K8kYOFIkhq$~yh2|#MUjH_sD+F6j;R8h4PX0p!xR z{5d{^y))gzEiVkS^tw~|XSiTXv;}X&-{k}O>BcFo4!JWOs#*U+jjGp6<^;AVc1Vm~ zo9)@~9dfR#-A0lBcAVQPK74`qKaa#7tvVBlVG+d#^ciM3D~B}%s$&K#=#`-sNBB+z zTC>Hq?@0o-n!XmpTLLF=`d+`nnBLKAOTf)S1V|S9G^VSg7Ex}OmD8i*o$}7YwcMR# z=2R@Uy0LPXVL74MFJPSThxEufB%Lj|IQ~_^ta%R2F_@`Hl258F9UV&?*hyj03k0` zH*<=LLm#qT@>zlOn(&5r_H_l?fP9jhL=P^YKp7n|V#OlIIz{Y1wx8C%dlD+vTG=B^ zVzM_jo;dz8Hn!^*5Z28pjrhwM3`cU+cF_!JHGq0l?sh_PEE85Q)bJV>AnWvf5$w}x_B5W;(;!d98Zo6l=E5# zup25s6{MZ=rXo|%o=T6`O^q8mc}>%@V%cc1+}AZevPf4YM69b>qta*hr#^@d*5J>* zIo9*Xdw%$iR|eOiqqW72T89y07`@$7;8^VwYp*_rpD>zOMgmp(5PH9w9~r9pe;ai@4$gf#!cn^(vs}1Vo7F zdr9K^Z`_-87a4~DI_WhAS9Txn2n{+*W**#h?=n%fj(N!jxM@A55SaE%ZC|xc;+erv zds6}DYSiA=Z(6{oE_-9UNgMz5fy^z#k~Mf|Z)dnNY{bo1b>NRT{sn(g@dX|3mZpu2 zvn83C)XMyFn1mDJtPf3HBRO}waYg!t04^BBLs0%xd;y?R4UHj0{wAMbgMT0mKl@<6 zRa%=KuI5M0;Pwgu0&0Nh3+6=jz0p!DSU}(BKc4a*milYN`H5-&Bpo!mctNl3 zw|MfsnmFMnS~U;CQd}|z(}rh{_NNDHSA3+??>b)4J(Fh&a@Ns!w@7vid^1n9iT$Vn z9k~*>*wWN>ak|Nd-$Cd3rkj-Mw^`9~kz|jHaVLA!g`nM3UA=J35tu(<<(bteuD?J& z#+b(Bu$&QkAHE5hIo-yL0e8?t&X@nAR{hWN(wv2GbB&#EFD7(wS+u6Eyc;*$B>1fa zaDKh}PzVakCTL z&)fLUJ*Ci^lT6WZKO>*ao2cxcsvJ|RrG_eo&<%@iH|g%{ZieA21A_HA=XTHox&=)t z&0_v-#0K|67UUW0sZhEd3K1p!v$Xos9nV|5U?seZ!TLPL>qa`8nasHC2up4wrS}hU zdtYI?!60f0B`)zK=? z7KG5SQe4V(E$wtCfA*N5D-)ddV=%#aIfr@E z4o@cjSy2>Qr*(^*-Uht;-QM(yGC^mi<$t(i(VfOW1-Vo6&_wEktr-#N<5WP@;H5*M zI*lR`pteE!$3Oo0n>1N5mUs4}MGM-5p~>%yWq2 za|%U{igIOuY-0>DU7RZ&vD{4l*)QDKMo+R^Mj9)GTCT6GGs7hYXSsQH8(+fvyp|8q zxp3|7xF!gw)eg@mfJD7;McetUzS z2P`H)#_SthiI z!C%}x*V3^xJ#1v!y(jPdbs>VGTB90^&S&R>cPP(YO9lWqqyGC}0Nc8O^H-|Q0gTbw zHa`oe%*f&%i;JgWd(HF2y~kP5L!|sg;25|z1v66OBK2B6P4~Xj7de>#K$88|HY*y3 zOOMPlBNKQffn3B=3&gv@T*K6?l^HRV-D=1N+3n2H9nty_AL{q4T)(DuG3C}dH{G$= zADW(>sna4XxixZzmu5wiK&SON-ob9%D>2!KCOxm)dhDvU_MYRP(@^=`I}tMuOrEhi zjM3L>X?)9hYmV?RsCU_kcW>2WEtHw&hTg54fUqNKxpReq1rJcUobONNgd5VOS&Q@( zFPM6``{W^mqDIObFS^u#S~|6bItYoLx~Y5T$H$waprNhWqn`G;zK%rEU-0qKIni;x zIMG)^6XDYdr{R0ZdIyEPHCj9WJ%z3?dJ|&cmpOgyo7J={D$`mj6?}W zK~%&_2xF0FGBGbBX`i-5=Z}ja!<4@Z`|$cSP1G zOmEqqvW;adl_Fs>p-_mtG1Fj(hCvGoqwGr&#u_8b%!diz+kf!= z@jhO6IrrT2IQN|A>pY*Ho}TT@$8jlXzTpZ8o0%Qgl+0nOy(^T+J7e1Y>r`rpu*jy6 zU`5L@3K%*Al0Ws%H%rr2q&~5BXfav~n*u$#CNiJz8vPI4tN>hIQN?70Wt(DEblkcn zwfveUbnjbr8T#=JS%7)kw>S6Np;M}SE1ey~i{f=Od~mjUqlgg`E7J8qcK;3S-Kgb+=D@dBw?&ODxivMPz2>e;Ln(%U#-5h`c-Q0s)gP^5GdKeaz@J+Kr} zRhM0OKRedruscadwSuqBbf4bFBd@(MIrI)oJ*hP`WjLuy-X`$Wn%)#DH>~@12QJkl zwApKA6b3g2#z{`0Temy>WM%?pZ5Vb8_b&q~2N7i>`A5CPe=W7nG|S}NgUou#IF8<~ zTEIORzp0h`xN165H4CG8aT~9CVPz-o8Jl~=^u63a!eEJjQr8tdS^azg8M3i-MNGg@ z6tvlUKxox))TwMC9;rkQ^Ega5NSxVG^JsT1K=aP?g~ULoODD9Uo;priJI z7WoXl`frryd(xSn!RZdISzE`0L1soIW1=0TMcy&ByHT;#iAV^maLZL#AMxnzHJm%1 zuTb%!##S=69PD554ocV{*RDQ03hI2DiTRUbg6nGqrsr)h416N93?H+N|4rrQ>C7{W zc62dZaJJ(3=e7{=G2*j?2h5T-Na-)8u>dC`ZxFT|?lB z|BB6vrQewvvn5E}c}L3p7&zk6z%XH`?Vb0rGQn+1;XF0CkK8lte}Jr0^kC-6-X+F; zH?et1YOquJ?K?_+Lc6&QkB5X>kyN*OZChxU1n%Xli)(QVOWwdkWFYk*ZOTDwchz4@ znoz;K;R+-)6TYU)QMKJ{&zWS^sXv-L&{N)8B6;8X%@g%hnlzz+v+%VA&vV$7V?}Pd zm7|%*_;@VtN(Y(Mr~?0ZHLWJLJ2MS=F2JXY%Z>ild@+CJbXb0LU(NO-zdAg^pY1Td z*+3SM-BvE@YIKz`(yU$o#vOWA=cg&&pNRpvVw3{Hn^8`s&g9L5jwnw}MqY)_T=SK& zy8zb0l5xlta{$b}W(!Z_x#ObTWP@~zu^XuG1)!1!G%(@BkITO<*H?ERoOp$nF-!CqeEpzxm?S-tt*8#c(*}CX$MgV8_J)CxA@m(y`gE`pb5?9Eyp?L)~ z#~p`GIG-^Rg>OT(+%M8CjNhG4t7^#^X}h?-Ffd#t5>cvlRuyuKlg!YF?@Zg-+}v!B zxPihv>ZrnldpV43rg8&Uo5BXCFis9Wn6>wO_H-1vI)dCAT|nC#$ClK`u#i*E8U4u- zIFt_)CtDGIVrJ)G!R3v`%L|RNm{zP(z+BZwx2=4&w=x&;NuoROO5}fnt}Td~ zil`Ng_#@pMKtY81hWl~;qSyq$SZ z=Rckgj%JU5Ix$1-{uz1U=dWwO*c=^qR?fDTE!*JX6H%TW^OF;g(C}Y9%zG{;R1o*j z(1zLR{O<}bR&Tfhn_;-!cV)XJdc-UEapsz2;q=&Ne7 zuN6=akGj;vH2C7q#+nu1xOrCib&OK)LyI@0h`GB4X_gnpZPRi}nERDA*4zGx_&2&f z_3sD)#{^#&SY-fV%ccb$(1yPTe_@9Lpi94BJ@ut$6A6Z1ey(JfA5#5)$Rr+}B#TAm z-8lSQpCKOIHKb4E2^o4Y&t0F)>;0y#(>P&R=y8TC>V6!SPo6S#d`=T+)XD0t5-g&7 zrVUarC)I0Zykg@&r47|%1`Ds-akT>JaXZYpKKhXr2s9RUCedY0&^w#3IPj@wGB_bc zb2Zqy=70CFLv=;0DWGTjkoOqV|&px1(xvz7FuDVBtL? ziZMb_6B{wQ4UmPjr(iDczzTouD2p>C;uZ zDyY^FXBzuK!f43yOZC9BGWA~Q>>)VWRr7>OyZdypoF|EHni_ok4G}3KsJ8)p z7Q~kN%30%NBBW*?WYz)sM}mg8-&q+)kx4&5V#aayJUL)qJR!I}A>$shw-=Toq39I1 zh!%6)W<<17c~%!mIPThtL-*Y$dnAtQTU+U_oY&o z2i3h+DDuP+C5e}>9>a~%b;Z_sOvxh_KTHP2W)=UIvo)?mAVBlGw(ddn3V#knc3ZGg zuHS!b(xSRIvaW1kMP?zjf=9h1N`v`oJ(t%K=7K3!S=V)@lB4vnqq)|SG44HX8y81W z7=KqN49sMfD)>GMik)C&c5PQ=lW#5w#UCj!`XC;GpmLLGXCYES)<)^g zcOO1+Xt>JWiF>ystO$i0x2T5qHM%^R+h5V&!Kszmiuz{j!BRald>C$wQXf6CFrC7U z3Q>Li`1Lh6Ps$K(%&vI!CCky~jisnS7(uA%esY(Q$A@zPClpStMd)i*37SROEz7bD z&EKv3Yy?3DxTLkICi9@1QU;B$BYQjD`hrcsYWvAL`STj;qsALx@1iYMej8t>vRv|U z`4UNIZ@PD)Sd7(Ie`3Eci?0`&AhK#s)_%ZwZpSHEChA^0q+I+5f!vr@^o7RUa+Yh^ zb2}MDa&ND7jYuyLaY0M2AzYj>tWJMc#3=4Z$eDs@7ZSw}pHK71<50e1PuVp4mRn?4 zg3-Hb)YE?n5yh1o_R*iNC%Z=}K5P#W3m8ogmrs*JNoJaZ#2xV2z7DUm>P&Sh*@-{x z5<99>j6xZ^*^3e!7}3PE;PUS0KYG+BxbFTjY{7}{hMFr%e~LQCP&|ahvW(tE-e*n{ zkAS-0u9Ax^R=*T5)x*7y<$478us1872B`jEN4TM7#qZqgZVxp_8*dO${KwvYzWyIy zb+_F_mQA@g`itrnTVx^gg1a00{OKmc4qPpxHc=W3)(!g8Zzcy zB$dC6D4aRRF=ZTO5ANww8$(y~E#U%T08BHvap)=K>Rucp-Xz{MF>?~Z3>_dZ>jyC< zNVFnG5Ll3R5rx zx{_WP0sO^d52GEWuvEKs&H8a$_3u}2A3oe7kFw-95)_ew5YG1YLY`asr{o1Rh40KO z>5Uo~E?{cC2umRF)obC{@|^XSdBi-jaYFV^Q^=S!Pzg&A5&N(oGE$R`h{nqS9x(eA z0Als*b?D161!=jMI!R$-NO)w_L1}8)86rBXu?SEDu4=(S(`s7C{9YfHrb+2U z1T(rFCjvNuaOHjR!cFv1F4!jX(d2EZSN-SdmYACH^0d C+h;QX diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Dimension_Elevation_RangeValue/WMS_GetMap_Dimension_Elevation_RangeValue_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Dimension_Elevation_RangeValue/WMS_GetMap_Dimension_Elevation_RangeValue_mask.png index c254de9fc404cb2b12868fd5d29feb4a17972e45..82512fab316cb43c33aaf2618aa693504d731203 100644 GIT binary patch literal 31630 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 literal 20917 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 literal 20917 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 S*fO5T2rx6TyjWp$BjG<9=6)*x diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter2/WMS_GetMap_Filter2_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter2/WMS_GetMap_Filter2_mask.png index fe5866957bc9771d7dfbec36b696f90f46da0126..c0c7b7b44174610aceb6f2bd187b176c655eac57 100644 GIT binary patch literal 10096 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 Z|M?%t3172c@)SA+CkNNFSo^E@{|}u#>*4?a literal 6211 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 DW;bKW diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter3/WMS_GetMap_Filter3_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter3/WMS_GetMap_Filter3_mask.png index b4cade6c05850044fc20d8458a58f6f5623819cc..e8ae8e7176424f3723e6d12aad20f7f9ab5df52c 100644 GIT binary patch literal 14474 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 WNi!pANDlxPf{gE&->%Ykiu->j863s{ literal 7532 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

ueJ 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter4/WMS_GetMap_Filter4_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter4/WMS_GetMap_Filter4_mask.png index e840d114fd36e20578c2dbd6c620f6c8fe79affd..fbbc09207bbbef809628b839b5cd1b4560495847 100644 GIT binary patch literal 7672 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 literal 4451 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 S*fO5T2rx6TyjWp$BjG<9=6)*x diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC2/WMS_GetMap_Filter_OGC2_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC2/WMS_GetMap_Filter_OGC2_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..cd6a5fb7f8ea366da3b3f48d5fb3306d418c7bcf GIT binary patch literal 15062 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 W^O~CC6@aJ;divz~;}SKikpBbL=7-4u literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC3/WMS_GetMap_Filter_OGC3_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC3/WMS_GetMap_Filter_OGC3_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c4a5a27a25161c6472cc71223a239a0e880cbbb9 GIT binary patch literal 9965 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 literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC_V2/WMS_GetMap_Filter_OGC_V2_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Filter_OGC_V2/WMS_GetMap_Filter_OGC_V2_mask.png index 693d564859c4e1204e178606eecf45093ea9163f..20d0dd22bbf88fe6582a2f9a52de44159d820003 100644 GIT binary patch literal 10312 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 literal 6413 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

e31x1q2T-fY4YB)mF#>@n`!YJ?TQ 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 literal 17119 zcmY*>2Rzno`~EGY6k19OPlJpiA$vp%DY7CXDYKBhNy(F0A|WAUg%%lENkXzmWi{-X zk?j9*)!Xm?zMs$QdAaZJeSfd-b)DC79>;N>S2tBp9%G0ODU^RGiiZzrINu-XaM9DaxV-#hW^I5scbqr< zJ^wYi=lPS2Osta3a?Ygcn9OA_e6)!ASg6reaN>FX$cKhYPY*P1u2vcw&av7z!)do= zMt_~?x+6!r=N7+2Y~;STX1|cBL2bo1sW&>c@9&F`&FZx}WPZDKfrdhnifU};!+# z_H#4hb8+%?-qnYf#oO2aei2`dw^ZZFJ!vE;l!J0{|M^vK<~e)LLjG%lQ>R}`*Zckb0O!L>w$VU2 z@_|+MWW4|NtJ)}eT4o7~-U{5bL+$r){%;B*yt$lmC8OHOH1XO~a%nXBZJhoNwuF-m zB!P*IvUI)dOSe?Njobfy(3@dhzZ})nofYF6e=n!qKfc;Kd1u|#^K}abKesdbv5HuH zA8gL0$WC>yUS%K0LgPB1eEhg-*$oC}W@b*si61}Iq7PnfDsZyilBHvGY0Wqdjf868 zt5;G(){gy237(5{pI*5<|Mb#YV4&S?>05}bMP(=_zkyK6BdV=obY|Ni5qCXMonigbLXMQdhEnr1o|2M0&b_wU^Q{1f-y zaLe;IrRu-(U1=$&PTN$Bj!4ca_%ZTuaUH#S^=fEhnIBViSC`?(j~_!5ZF{QBKin4& zO^h(~)H(aos@bkqI@w{UMKRQKenfP7uvuA0N9R+a+e@u1gMEfwvW|*3Z{Ca&vAny2 znmS{C_)~WJTEj2moeNvbp5tk>-+gwP5)>5Fa#rr^4DneOIP+Bd@fo%0q1M))BcBCk ze`I}^@fJ;xr^^g|sWliaYJE2=E9+#eOa>mnV4Qu^c8y%SzLWcOo*iDjdbRJ$SLA^X z9B4?JSo0~*F8Sc)Pl-o^Sj}fAdXi@3m#)9`EE<=hk+2D$aQZpxG1U2NG9)NS)0duE zBVL}Ce2I*VOjS+IzKNWy!k&fQeueA*|IPsM5twPZN_9M&P%%yc-#I*xT_NH`2` z%CGfj=Cj8umbk#8<#D7%b6V2(?-wq&J&E6Iz}|g@rH3(Wzx7t(zM-LXEWctO@5rxT z&Pk6R@d^l>5*HVj@Lb3h8CaL#tez|6xqUWbJD#vr+?K>8Q=NWY0o?jzx9gs_*=Dv(AaCAZ;<{X_W zYrg`Wo_CQ0g)>NwPVZm5a@x!mzZ|j~4XUMmaQ!zZ0dv~dh41jLJ`zW5^{|I`148QweVycka@{6#6s!4ht# z|3<&KRcrmPCGYr)jvv0+h=~cVk@^n=RuPQEaQ^!XCjpUC>pgx0E+FW?An?AQjJ@;D zx!>Of;Q5VN-Yd+k`~V>T!R-G5VqkLjveSF}K}835cGTr09`+j=#4XP)}=#Ii3o>C;zD&u^1Ax0^obsJOA3;+>oz z;RoC;GtQlB6_DCy#8|Ma?u%gC4(jnuncQ;thMc3-jC!Taw5zT%mgE5A{rOf-Zs;Fp z8NPpovp?-BAB%C7`{!MC9V}EU^~8^6mwmQrW2JoF@%~E?$#2|8E;fHs`kOqSFu#3J za&~?HIQQ`5D}qxoWzonSm#*#i6U9x{+Kdv!UUZgx#`|K!xoVp{hf6;T{%7I*D&pmj z$>h*>GyMU1tXGJAGTs&EzOuwQYxIvF*BIz5|6;SQwABq=Y$y66?|QAgb1a&q1s)jqPX*d=B^9Y5Qj_4j2AIqYk7%006reAn-V zM()YoPTlRDehhCNnS3n0pTfw!6+_VTxq03@^iNjYufE;;z!5KTRS7(CnE31M+%CAH ziY8oKH9w`!=xm^m6BF&V`}^sXm=fBJ+yWo1>}J60ZnH)w%Na{Ptg?4zNSk_A7P2R9 z7}KG&Nq@VyW!>NO$-Q3qIdvxX5A8Z7?O+qfl58X^%F#E5GM#)S(zvYKfB!EA8v!yc zFTdM}nNj7h)#xwbe7IBEPyD0Wr(c=+TTgyiaoj&7M0@_{Nb?gT1zI|~AwLe!y1rO1 z&(f2arxbZ#`oV^zfGA<}hq~Do=GAxiv5H#VZ)j}HvS6!<5Xd@fm3KrX`k-cvgu@HV zR{o%Eq9@JG&9$dbqtOue7v&US3{)ZT8vG+$XWP2;Imf#;&D z%6&04Y1b*$3l|da?$vpyZQydm?dNb_|Iqa0q&jl?CN{PVl9XEY>{Q~1oJQMIuV1IR zXkuc}GJod2&zQB9)#$|$u@0X19`5dsr+EhLZkS$4zFd7rEk5A{4J~b|c9ub!Zg$$j z;v)0*?T?Z3hH6B+no`x1zmJV&iFP_Gyll4(XlQ5%i-<^`nzGL@DAZMs;BOxPQWhQ^ zoqp)r%2ecN!i&t`=f$G`}pyHH*DCj3AgX=KG%VS$|~#mYQ>5b8c9mbL2Qy*Sm`^v zF-Zz!9zZg1vHkMmOuEZtFIbD+)3M50+2zMt8M@|kQv-vI$swoJ)j1V0vFc`KDW6`L zCnP5BR*9AA$d7Ft(7>vP-MSUG%__Ha?&*)E`LUtT*2VjN3b9Dor>tb$o-#K*WC=oo zbqnuw>0=xD`25(}oJ%|hSvpcJ2utBoiAwCPiLM^7=M@#zR=&Hp-kXa0#l`B)9WH$_ zgk%J>Npcwn2D3}2eSB_eiLqxIIOtuMymZ#l=*$@~E?zVV6numTZRsg0Dl(~w67glX2Kg{SwryFKwC`8#zaq0R zUbd#isQ%#*uKoM#E`81!@fivfG(pPe5*2M_F@BE)JQ2>T8Ms?L;V8p%_gUM?f#lfD zx?M*CHb)8?zrA<={&wR)LD_|Ig{NcHcTUNe2MYF9aCix4oPBvP^u(Dn_jI0JxEU$! zmQz_(b>MT(Wg#qj_NaQHtHY2(mO zck0>Ii0~VF-F+PZbT7F4zH!UZyo4rBPR@bb$Jq0_C&a{UmrR@9YVWiTS-N7`7d38hP23xq2hlnGiwSKj74-C8(9fq!a{q~JBX2_Ch_3GQZXXob9K>IA( zbD!qh4?INBYH@h}ipM3>oo-|12-+x7>j%3BrUn|1WOiZQroZ1gm4+1ubhq9Yx3eF~ zZq;p_>91F~{OLvg&5e7=BaUXIzXkkM6$dMzdUdu~qXJ2M+-g_plCF87eD0Yg% z;)u1Ex}M(s(9qCLTeqenJ}m3v4h=S^M*#Lj90oPWjYA*LTmWXwVVs+=a#-V3fB=M5 z*zQ#Q0>`KW7ySbT(@rP(<6D{@sca*|0a0#2*u1#>`Cv_?&@n8XCa^=Z!11!;>7z$) zn0&aO8Wy&RP1;pMQBl#NBR?DWbLf4)b)R0Y>YB}aRh^x4U8e_=09`x>4xBy~yuBXq zIMowj$ji-rTun`_s;a61ytk>y!>u_}|155)iH{7nW_i_*yzlBNZX3eK9S&_-tMTY+ z)bg&|>jb1}B$Q%eW4n%I$%15qAzLmkC&zj=DXYq{{} z@W%vTF6NDA*Di&Q0;h<^fu{O|W7+17T$evSE2sBToSW}j=2vuGoNm?3&=n!Vj#b+A z1yC{>%dZ&P={~8Fed*(A1W~q+VAsno&vbARDbzxFRp>Uu zi~Br%`qWk;M(O0q7A!%4yZ%hOT}YyxrVEz7>8bIt*|`VvRs5JC0aR z{P@9o@Y20cIhWJlyg5up;`%K}l%C-|-!GY&u`WZh*9*pq`25O@q#cnNr?By{UP_^f zk00+{T$rq#`{Kv(!nlHwC<>xKM>`6bw{1)BEObj(3g;bcO1)Dw+q;cT-1cx!Rk-@O zb8#!zvczErOHaNRsscc~FmHTeR=?8&xrct$DpjDO2vWa8f88NNuf=Ta`04s%96Y;s zA3hes-V7jm{2@lN`iqTOMKBv-AjnEszx5pslw1gZEsYD4sb<`sHufTDHKcC2@)`lcyhl%f%vicEN?~%5r3fn}j znn>EjM-?%1du^pB7Uzbt=+~@iOi@c9+eF4=PH#$_FeU^KID*B2w`T9}32NQ*`uWk6 zRoLv7yu7^quW_S`rlx0S&KA067tN1KO3x2JC;P7@%h0;;6ll<3S8=iK3$ysm`*h#6 zwrUF$PK7@3T5?hBlL-Kh2XV+2wUs)Pm3A8|Oa@L233$y0AiPY2esUnt9109QXM0X{ zRVce;sZFe!e0C(REa|+l@$~C80{y;Q47h(DEMAxhz%^SSA9aZyW;7l8_&j-cDl#X* zphqWT(u7Pum;plOW{Q_Hpe#vL(+C!T``wRm`V zpop9M>l2Wm?1>z%2;pc2EG1LZF>WgGM6@>}uURWLB!tMMVVQ^Sp0%n6%4Th|ex(NP zRv#j}l)|f-){l_Wf@RWUBNhfPWaRTpOT-!SIWl$r{AfY8+l&?M%9UhSV6Nu6uQ5$w z5vnUHjuF1(Fb`lP_QZDZ$ z#=#D!u6_0{0h{-c?XU0D;Xt@{@B7FE1ZE1X7YW<%|Mu3#W~n6{HUIIooR|haK0ce) zt&79XmR??%MAU+C#t2_(+YddE4ufW}J?}Xx&T}AoG?he=v(o=N`X&R}aOUR*ofN^B!7fS%q zG{a&~B}GN@*(PLf!W9U$)?BUJpd#8~Uq6$rmuK73<>KO^q@tn;3W3d#9Bq}a2&0I= zN2llfWmqVKfKouG*5Sj~2^Ga20*yI>;BoDb_ajmS*Hpo_GBPrn8%)n4scg>!XL%6& zR`4FM7bgU_;)GN)9c$JPHf8zKP;PdLBReK7ixWm3tMM+7i0ls5ql5#|v z+svr$E9a+`NSwPwW{xc@jJz4Ytb#N=cniBBZSfzg67EocW4^VpZ0K7Hw#`6xT_ZWo4IA0SYa z5*POmoIiDIq9WkYp^d<=eomt`n7eGHMHv&-{afTZC$*66VK>4HJ$AH5e|>X~R5QdSWk(Jozz=^=N5IQ7b!s0BmNTeKhuH9r=51*)prpM8awG z60u>i8?7M#<@9m*{DaQwjX*z%(6Mpjmfj9Nrf4bs;Mu*vtiSH3+qHZpV@ z5rMtSJ~`VL8x4g!^Ou}t&yqsakxFN@zv7YP>V+ho1}^7+`yhY4<1+r3UYCBmP3C?j=eHwOD?cz z<|X&L6BT8Fp`O6vn>VM03--1@UD$K-{{G6!O5e`OE8pJg)T$M^yG$Z?Z#53wDtP|- zv>t*;^exK}%QRqOo1#g}W1Y7w#+}aJ7>0iA+_^JwcVnXBM#!gFucf@o>T01_&$(2= zxA$n*Y`%v*c`whdFN*vQOLX$1X>4RM_~+5kyqQk7Ai=kRY?3V)BlNS1hDMk;kS$Wu zDN|8dS%@I?w0nrmTndC^h|7=iEj56EpxD^h+ZW!3a9Bg3fzcd99E$u-4zb8;n+iO7 zydYs54N~g9Y`(E}>-l|PS0n+;{OYC#vRCV}drYZ$Ec~eOox8pb8P40AQaIZitrdP> z_IL*P_{7YN_WASYZ`XdzI4g?0rt+4>QlbgO%o5_#|KER~9DUKpG3W5qb81o=qO--d z`LT{V=8j-8;oLB-v+BB^xdVX+>P<{cXb_ROE*7kuY`nSQ=e3*GuUEUo$qFc1TAUw> zwl1pQcuFcBq0Y_2Gw^KXb%&8p&8+tKfDr7`u4YwXJaZG(0@7A1LaeXv@h+if0z>!d4v$}t_8f$=c6U;*TUY=_$o?4vgvK(kgirR1F zgSv*HnSPpfRwf(_g8WE;4cHsT`di?hkdzGrXt1N;C33S}eOU_(3pIx6*U%aMWTW5bV;Q6!;-MY&|U2}eUj8Lq`UT+UBy^?%zG@UClHDZyF&wb>F=%&DpmY=rZl>zc=@eD-|UPDjYRuV z3yU;Fq5u8woDvfG@8-YPRvL_tKS5?z>@x{j!^HHGFYQ_>o5dVPo50+T%6YK02B2O2xuhI1KG#|rV{o+odT0|B0kTD@(`P( zV-umP$q!tW)E}Lwk2`ejajh|29gD_CL7g5m`Zck#h62S4&%i%3A*c8R1hVSpr92m$ ziMRl_I1N{h)_40IBY zxWUS&#xM)QalCC7 z@!uwwydZ zI!uJs)u~PoG#;Dj@+u|{XCY`Jil+61d?ER3L4`ki6kgcC)<81x)++y~T?TZVhmb=8RD|P^Vj&c~CYWqZjHEWXC+KuyN(whTgJTlxHja_CT?!8;2#SXP9@${x<&4JiFSKB z#wRDA^HyE{oMR68tNY~KRRqxVd!br0@FLeQzFX`kzAF-GM5rP2`t|WpEoS|7@$?J~ znt8T8VXz{J=7h8gU1BNakFk7MTUq&Z&V5akghLuEXS2mFmIM?ScsMza96EHUrH8l) z*o+PfzpjvE3(48^>|*s4`j zo~!j*N`T+MBPn?nL(hIob^ZEvB8B)T1PKX-nTeNGN=r*ydSG`nf+l8Rz5ywwq*Nb{ zWQ^kL?5|(Q(Tatx(+xhfYv^kjx=?c2XIP{M7TXGDCW6#U+yv2fn`@*BOd^exb&;)l zKg6WNIH(%1PrF!s7uJ9DqZ5%2ow_`B)kJD=(ei%lUhMneZj!*SMqSu4w!4`?_#_sw}~;aj1xv9W-2 zFd{1obJu*~;>AdeeG=uBNRaL*%t9n&=H^c=nFXT~Lg(MCBKzzfGVWGIt{po{j~{?> z(jxd7JN?;cW4d;hd_}bK0cKu}{pe08>YiBOl#wZVH%)5m*#^*OCcnnN^ul}C52f&= z^A0H`=w`u8iU!ng$umI67Y=-WnH33!{}CCGFvPd_XzXf)G`T*_knA;wPzT>!3ZNH7QR6h+;$ka!j{OTUas5x@>n+6d)4BprGoO)JB~ z!1)X9Bvw5dAhmg30>jW-k{oFZJ05824%vB`xeRivXC1i@y zY%Cu&^IG_E?Ay0*#xO%qz-tTK{cUW_8g6_bYGzyE(m8zQRK9x;HJ$(&c#1D_l3~V1 z^Xuo|LoG%KLDPs<6d|b9=a5o%gH1f-_g$4lXiN>Y*1E2hm6e6UyZn2AC?D12Oa1dt zNf@8@hqYS|ydh8j2!@m|zkpTDXwkft5Io$;CiPR1NH+ICSE9j6fB&F8fH`W4Yxya$ zfj4g7eu+3sMIcY==zaLs*JnzG+&CZ%fH{adg%`|v4|?ecv|FrRwQ4`oF<94db}6g(*zjN;`&(U`P=V3J&~wjL32dHD_y;I?F;r|kgHzgQ4qKng3!67u|&wz z(~}F!y7$bJ66l7p;$nxVZO3pq2}_r*93f{?4h?L-7}V%jag!vxC~ z5Yr>bL5Mz-sn4}*n#GQk7>;z!2<^l2s;j+ zA(cBkG|{=lMg*|xSb>54L_rjY_DHY^Ii_HcGB z0Bl6TzxG{|!S78{DXI8~xYWR(oFXVU-1d|(QbZQ21*v+#LYPvHsc?y+q+FgoeE6^l zU?qa$3<9(Pno1M(M9>g@Vt&9Kb*Pn|F$46$0Z;=g0{2e`bRL{H2s1c_$#EG*$-dnQ?Xa^*RNkUZQPhZJW6QomT&VY@c_B$ z>FFDwLo>!y5EdCOyC(`l0tK~1bxJeS)4y!K$~Yeo6x0mN&seR^$RYEXNBvPh3W+bQ zHX;*(L8N0j;P#W2A5sp%X!?=GUvhbU1e_uxoHi?(@PU2J2}k}o$_EAHOOTw(%gcGN z6vVeeK|Sutll{bo#b%g8d4z~NJ{axjZ&L>!{Qm7*0%;^et@jg3jdn`S@y}G8iqJ>O@$utwTkCLgHy}f<> zjM>a+M~g9ud@^6i5TlwVCXZmMXTvVhM+uhjE2IcsM6#unGRPi6 zgOD6pi*Un^qV5Jv*MRPP{rYuSR8$&x!#@3d4K&X+g9DQ?D@fJ=Bx4;WX&R=P`DlAy ziwlFig2FVsUUS4e;o-zkAxep`Kh&Mzy`E#(Tgb|99eU0vuRRGkTYfN$)%ZQ?bv3Ae zoPZ~K`-4b=?9VpiE$zMVYxX^Lh?4Qhhr9e_`WNnA7#Ex0?JE7N`x=tw5*V4z(77c%J(7{MBE*Cgt0gHO6jT=$e5z#voZk*|GxqbV#R;wYPpXB>UwEW!+ z2oQqOJ%FaQ{m|d!lVJjeoiucGTP$o(oj4&JdIDYmtmHr!pxgZr0i~tNo12&?u=#lu**~54H1H&V*zb8vw=z1W@EYa@TTeMxALrKii>eY{< z$iZV1t+q>F?Imi!i31pdL4$;@d_8Oj))7UlDTw{f#H6H1R1u;ek|H5Y8sMnq9d1p< z{K0Y;@@=t17bT%MT!Mo2z`bg8i9~|JN0T&s!NepAxl(s*K56ghM4=g+;aM0w??G@+ zz+#69Muv<^a4G9Ory|s`3VL$hoL}ZdlftiGzs}6RCQk$ZmBq_zS(af6ttxhtHKJ!j zno(@{P0C=VlXgP##F4X;ebGoT&yC7fLXmAlUgxlb>SQ%E>{>Hdhh$+5mRy5JvO)>^ zyt}*md*s#k=o|ermnJ-goFEOKyxAE2L|z~8s#7oh3{bs?=EW%TL%bYRZd-P9acyRO z(Q~qzLA3o`Ow41kSyP&HR8Jx^8o{gdEZ`#ak8T)l$cyPg&F(#%s58Su`Y)|wME<>1 zUKAjCIf6D~p)>*>zIwcBmR3eoDvHFZh&Ggsb8cV2(_YBT>t*Gu8)`~5hLdb0-SWz1 z@;z>Uaqj1cCA?f~J7GtSD0xp}?~u7adsW8hHO*ux9mhR*LeVJH zZbPP?tm4bMhlb2EFY}_xclFx#B0~#aEB`ne7!-Ok zd2G~okg2vvH0l6hNNW++9WNAEXi~);#?ItHmVyohPixt_1%VC|O(W0tBARIokS|-H zNHT;LL0}%&-QJ1uzAJv}|C;MRl@K+A{U zz8#MWvjzAP@x-vXu>JXm4r-TuTcN+RNm(9HhMl(wb@Xo)A(lXP5^JOloM=DL4vF-@U|sPNg)&}8&sHLihQSFJ_c-+!wEbU0OFo6P zt>*kW1;8##+Ae<|4p>7Y(fvitp27Ptx+n4e?^e!r{oX2dQ;g1{|8pYY$@-`csBB@bWbTf+w^VxkXxkK3 zXq52gJLJolyL#m-s$ABo{~RswUQ@5l7?(({rPK^jlvuAah6%1Lq~d1ya|QmJ6zFM7 zxp3YOxzb;v zd9HgK#pzHSbwp}+oapQA-UV?uoq)FE-~UAqwQT7LYl;+=M}NtY{rwEy$>>M+FNrs! zNa4)JeZREr-h0l6VUkH7^a97qBC7EVe@`zwl%VULMWd+n(HGQDsDl;g4&S5p>b1~) z`pYw%;b>l2x>^i%5}((jax{KuXZeqyg;w{vxXoIhaUS1HiLlubX8hQPQe@5!x{1C&6w4CHH|Mz7yRdy433p@G(K38$=!%I{EDRF zF6h`az0~ zdAqdOnu9|HLlOq7SC*IlWVu8gma$N2+TJ`nWE$Z?!z^*Brh|``GFr+wPyZoj<>$%o z0^Huu)HKRR&F2}(VG-^U_2_S_r}(-RIrdYWd9_C^ClxyGypEA8UU6UKot?Apovq%o zxkEFp`ZLQkbIkdl1{l@meqEx>+xU&ym8NyDwe-2u%xT)R8ir8LiH;uZE07#rUOkom zJ(z=+(#AaB{&ju-lYK?MychG7%SRbkO>KB{qete~UdmVr(~Ru8e$Iax)=;{6XVW(^3Pow7%4qH- z&X0-utTp2}KQw-n#&zqL;Y&yOg0$A?%2S+oMWM_*;WfPO9mQrA^{#_ro*b0S?acWB zszGZlQm zIl0w%RaHQ@9}PwCUpXiB>n-KXGfU%$RIRD_0v^c+ZArW9iy0}t>-(+VZw#(>?8#TV zNnOIR%AV<5;O)lBW13+;@h9yhDb`0h^8I$apiqv)4^PUCHqnfo99lu?45aT+$Wu=m z{r!hO{&0EiEl!d9xT8+`zU21KUdAB`r4ysv7C*3!@@flneod}I((vzBZ_sz#NNJ)f znOBYf99E!FIr@y9a?Xi#MgKluM4J0QZ#UgdO&OEBBdOtYL z>77dL%WcAyJDBE;8K(P)@Iq0U*L`@z2XlMK9ycUNH(^TVqNJ9qt zPqt+Ag!70UpH<2covXW|spPh&;^d~$*DSk|8!HbE$Rp{a0|M1-E!2|zAD^*=%}8q6 z=#Aw+Q&w%aq;{0HLP%fH66emi1vx)Tot)%qXZ~z55D*Zc4l{eVB56~BNx-QH-qea5 zN;;d7Xy8m%u_S;Ara^n@!dA~L{Hcph&l6j>Zawgpd&iDL#N>og0@_4HIt1(M>;Kc> z`v{qc8+I+)5i{K@IbSb&y)H5S&eRmwwaxKvaZKNGP^k8kRCkoGN%sIbH-l7b2^mJ3 z%pkPL2`b!)TSSC-#-xoKx`LZ{=Fr%U3aB(8@5e~FoW?1f7Gh@)4_`vwJxO}@PTm)b zCq-Peo4C%8yv#<8W=qi^disM;|1eDuq&ijMsP77bgA-81j7I+Ido5figOcS4iKM;%QskXXLBVT1Q%Y$nhVHmncHrmZ9NfUu|*s z1l)PlxlTd5+(HZDE=6?LsiXM#!1?QH($0gn$J0=xGPB<|qGWWpMVVKKMxyF)sZ#HG z$wR#C&Y_d0x^J3EAqpgetR{RgR6B)zp9}i{0 zgV*5GHOMZ{o(f?(JY%}bJ}l2CoWWz1LXQ&2)1PbBuV0TUb_28Y2Z&Bh6tc-&?9+Xr z3Wi4x6hNVq5*}ug^o@`XAtsq$an}ufE!Xwi-1MpWK_f237VcUp?lJcQ?F@ZZbdkuVId)> zZc6(}{yAj%=j7r4a2y-;zR6Du;JNG_dQTK`$xp9f0MC>4eeUUe&NTG(+sj+#Ai-ILgb+B>z(UcC!iY~*5< zp0Ow9!4*lM6PJAaKX^_kygH}6HdbgNrg$F);7#|?b;jz5$0&`&Iicb1!j0-xt|4EG zz9C;6ERz!-yAa4DC0F$&F0!+lT)l;xWl-bCgQ4^LY`{L8BYkQng`3@OD9_$sWnZ$U zE-P5p&hxp{=YaX#rZIu5jLz$Q*dqMZrbfTmc6$Aus&jS4bv$i55#6Tz)lUS6i$aUljr@WFj1Im|*Jj%n)}T*r`#WqQ#3ZKjn{4rYg-$eY>A^q-pb)EySI72{BvpybD6uzW8lg2 zXYDzuq3Dg349#GC`3Nyx;?(RCl#?#39lo!o0( zuUsV-G)z3|)0fLtU+MP#K5UBzuF}wn-Nib-nMT6<`&ZE8+SyoNU<;W$qjs9J%-mdYT(z2+fzR2+AGGj;^X5X_``AjPZKTR zXy+P0ZwxC=W59Alg<}s+6&}L=)&f3|BPO?Qt@D6`L-GfKD_EZ}c5F#)Cf$&noRX*0 zdxxqs9TWSj?g{iDkj7@xV7xmOmICZmEo`o7bY%{blP52&I*4}&mnt2{RxTC}QrZKv z(zPk$CbKnlNIb=hKck;Ld$u$sGrMRl=``8|{X=Txfd8;TSA%_Acc_#&m?gU9(Stx* z!%_Ao&EF8h@AEUeOCo)|x*+gK-Ierq0a`uAOX-M(9+^4Qv-ADc*Gk6cwv*2z3p6gw zPWE6hq%a55G1MOY_xfIo(`W>_y&J7*L-1Hb6M-B9q^A^xKoOYiq+th|Tobxk|EC21 zjlu2Qk6#pRgv^m=U==2Zh7#>|7+_vG_v{&hdE9(Y(3rG9lgcyvDOI5KZpGrIxpa2d z{vDWmp1pfd5QK!V*PA`S@4ugJNi|B=W@`^)E`dNa1LJ@&B@Z?`54uZGa8UbCVd1G1jEyA)PqaS4x`fH6Kw2~LhKPNCo${a;UAIJ1hi=cUH?^iXPrjYN*zZH*zYidW z@%Gx#Rjs_r7}tcujH-@gt0>*$(|z>&ms{z&kM5mWN%7ur%P_nkE&Ap+M0KuGCZpX= zIXYE;mQ8eFY~+w*uF|NDGZ(%@Lp6r_VgPm;CDW&1!I=~9J)!!Gf^w-g5+4gomfDT> z>&X;dp(y!EPVuZrs)@<5TfruG(=OtWyqq~s;GR2sUHp}=q;DR!PPy$%f%HB9y#I2! z-Q2AY$JIG~_S5MFK!0jp@w;=H0-V*OO|y08a~clah2I5VZ@1z2E7d6c0g?wrR$Rnk z_S~Ks92>V$WLa3bP|8+Jhh3!nHCS>##fuqQtFwa5}PYk{lSM zbX&E%2)kW@KCa9% zuX=~k!V`)r^izrNDmx0NFU}!fuQaBF?OwrVL-l&QoTBkxHJwZG==&}8@lPK7?>~H? zdSg2y-6GzkB|ZS7CbcT-pLBER${*#RdbD4XPBrSUI*40~Eke#g|KD-pztJkkld!y9 zPUp`V;}o2we$zfesiOaTurzFEnjPh$?|=CpOR_n~YDTHoGdmy(DT+r<9?q0M=kxyn Df#W%B}-=PTT@v|s7S~#vXd=_#$G-l%gi8T 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 DZo71= diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Highlight_Point/WMS_GetMap_Highlight_Point_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Highlight_Point/WMS_GetMap_Highlight_Point_mask.png index 7153a0a37a3edda938e24d3403409820450b0817..bd01c396bd2e934429572eca3d9e73916dc67e4f 100644 GIT binary patch literal 12126 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 literal 5578 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

3-WAlGTYgWO8 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 SI?8y0fa~!i7_?s9I{bepOmEHr literal 30545 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̐zD3 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 literal 32511 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 Ox_{T`PWkPp5&r|~@?+@$ literal 5848 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Opacities/WMS_GetMap_Opacities_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Opacities/WMS_GetMap_Opacities_mask.png index 8ed917a596a2571831b24082e5668d25738f2e37..4c1430e2bae4335754e306f7c590364840ea8a65 100644 GIT binary patch literal 21378 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Opacities2/WMS_GetMap_Opacities2_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Opacities2/WMS_GetMap_Opacities2_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..c54ef3dc20e73d1e4408c6b1810386c4c820646e GIT binary patch literal 12508 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 literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Opacities3/WMS_GetMap_Opacities3_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Opacities3/WMS_GetMap_Opacities3_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..59432c3c0106eb05c29073fc1f9b9f13591fb5b0 GIT binary patch literal 11190 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 literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_SLDRestored/WMS_GetMap_SLDRestored_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_SLDRestored/WMS_GetMap_SLDRestored_mask.png index 321c90978dcd9a77e9951e9fd333b5533c997b62..e31085bf6827586618132e187cfb4c824f87bcbc 100644 GIT binary patch literal 9390 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_SRS/WMS_GetMap_SRS_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_SRS/WMS_GetMap_SRS_mask.png index 7381f4136c44e230324b9d9d116fdb85e62535ca..246cad1a519cb7ec16a84e0ae234686af31d4d0d 100644 GIT binary patch literal 15471 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 QH$H41`&@S~aFJ2r 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Selection/WMS_GetMap_Selection_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Selection/WMS_GetMap_Selection_mask.png index 25d9ff13eb4eeda224f79fca36f68b368ece9115..0217a07bd89db7f12680f14442c252f94cdae3be 100644 GIT binary patch literal 16662 zcmXwhcU%(A|37XkN9J2|qGo2UT$vL!EiGrcSDK+%YHm}(ZE5Ao%9*Rw%z-mhR2-S& z#tFI01x{2za{uV_ef<95!QFA=b+3Ef-RoYj*ONC7%naGj3!Dc40POeg-LU`w=*a&* ztjx5M0qnwC+SfV1d-j0<09)?A58a2$;rJpA)H{HaJyT2>`#*6EmLkI@gl{e(wf*-{r-qG6n(EuA9C5 zaK_RqTFAikZ3Jh~FP#5CfbO?wHUx(XE^PFmb!hPOuhg=g#&0@M5TNPxV-9m#UjUQn zXb!;TQT+r-#-QI zqMWN!3>l6MbXm*_Z5wW62Sl|m6wm(QkhlbhK38KY1jxPfl^Hmy&l3IN7g`v|HA45B z{+i(rS`UESpD)!y@02leTp3mbo7|oGo6QevFl%%Zv(qT0HZIpH3KXi#850 z)ev1ow@3Sd9u;^;W5o;^ZOa%W8e=3Vs`!h4DPE%25LH+^*YS;3TUQ~WSTK~vLl4FvU9s-B|J_QD3Gp^!1Mt^{ zM7EEg#rS@F0O%EUj7z&n<4-j8$TT{^tMMXzeKa5@dwXONqMuaMr40Sokzp}xsTx-? zo(4eE>Waq13mfRuX2jMr_-{nO)!sju)T5!VN`9%)9IVCmY5G&qA^!#)di!5LQ>%C( z13gONjuwk>kys(ac^*~0Lc^3@T1R3wi~izVq8SVV(4CZMj;rC?1yPO>mwt7!g(T4= zW3$ks0f+*Nw)}Kuq%lJO>w-=JCny+DMPogC0S51)kb2g0{ItXM&i|z62+_Jg^lP`Y z{-I+e<@aOj#RcloiJ@=aZ*39vcryj`_3LFF_v^l7E^PuvxaowO?rArPGsYfPF7Dm! z(4^ORpqoecixjYn=FOt z|HK+1E;-b_OHs4T$)C6LX%w7kd%{QKp$glB(XAIpweniG=Tsw-vo6Oxd>6nXZCvt) zu0ud7q>v67;mun78}tG9vgfjao-T{P7zUdH3i*3Qq_@k=pN~m`hoF1IAAG^y#qHXw z9^QXdG}1u2`OB-8P9=b(X#4GGhE228gw4=pf#Bn6OjOI|woJO$)6HHj~!s4{$9!?AJjg#==6Q)V|4`Mv`?f(fuw4M#4I8BJ7 ze~4QuUZFK-ye9G_oH6JzfH9{b6bLe)Z5U=m5I{z$pt1MSTP~VB-5xQnHct7h156z@WXSzDWTzTblT2$( zuMxe{7k{Z!sE9^yoal-(C!R-{CJFzNEO?&!f62lGXO>Q(e@Q!D_N#+5F0jQ;)W9bW zu3m^u``7zL@6F<2@uNm?P>90`z~)0a=^vTb*tURFiDl_lnr(E8Fx$74$lH-35ZBm`&%5KVHw5aA8l!oYbHM+f1N$7RneaN2s=$XWd}ir!@hCC4SPT}sf~Gs4jIC?8_eA_nzu zH!nopv|*Lrd8rh}!TsmBPKdMmS#j-)dfE(`y4iz*DkCRs; z^F(U9e}j$Oo#URdF9odY=w)ErUZ~b}g2Y5Wt4|hd!5Oe>x>OiP>$5v@oPy7TIU|4sr*9c(=@jp`6XY(aFLDb zxz%@`J2fWoc6%uP{qU9k%I$Pq|9w;7u}ZtF$-I91;hmBRwWIls)NO*(tFie%le@~$ zk_AX5AH2A~?# zEKB8=)X3FdSjvn1*2QDtu4_u#p}BW#jD_Zr4wy&6k-2pVKBKU{A*{|`zN7LEtX%Q_ z!-7(HJRQnN^XBU@a+vFtT#?x`^iS`xbXa%}5IV%aX4r#CWjrd<@%=+^II%ziZnT%4 z-3XJHUe)OhIL;Wj{tz-UFa^8WQ(Zyb-=PDk-0qmh@Hor0J zK*w9xw`9f6-BZb&wOu5-em%L9@6cQ(lSxWtf)s9n2&;vv&rPF$Lit5XPNV0U0#-iV zUUCWtKXE#ocQaITvAI!T;W_p-c=gGzyhTqRlS0Yqv}RJAvqtg69gAx}4mw*ib;!l* zM<>oDirU_~?ahdJuDZ#f7x9|wj;MflHqU=AYm-O^xsjKZk_@r-{;`jf1B{BNYdv4B z@!;siiUorUFbUo{;t1&HBF|bRFCFN1>8#YdHa}2g(Pv9luLP1!{#3qYg$K}|WwTKC zM~k)eFx+5ZY1eL1C@Hp?d+cd(9MwZPJiW8!!L@Y4N|BBP#Mcyea;95o&@vyl*^epE4j5>8*W}(y%k_TXH>gD(}+T~;!ne6z9AU|QuuEb;=IqT=0llvzRlu4 zK+?dpSe?>bh|GISjxTp>zSaQ6I&8jCkMl_FGSQOL^Rfu#k zlbc?aFhdDoJ_$d>%^z*s$PM21Qwn8r&+n_mhT_S+r=ZGjadkHg4^@7T%f0O2xwQQL zTh?^R#UuS{(V?UFZL_=G)uZ<`4fBn|d>nJp6R?eTN8t;nd>VzgZ><(gqk&9FY57k{ zb|2X{Fe5VG(A2@9pcG{+1y?+e8!v(%ej|rJ-%2kyJRDsx6xsX_|6q{Ku6@p97!kX*{oOG^s$(dz<9NJ zvES{lx++jhq6ox$b^82)QG3@D_ zzKDG;+-2HMOR3iDRsgV<72GQ>wA9Z^h|MpaFiut>%)Z9kF@6&#KD4aZ@R{-=DJ)NR zU1!gFm=b8M&q5Zs9ny2Y19HP+7U4h(zxkR|DT$&NQ6 z+F76YA0HF#c`*UUA7BG-d0G(=(6ut$cTa%g>>u;Q9_A&|3Tm9yTufy$AFiq| zHyl+e665Ncc{6-6mQwl(AHyrUUp9SoSnAF4YEgcvJSTyQQBmsaWh|}BJjI|dY3t}?haDT=Wn$3(taF5b?^`K z)a5v@0j1F=pQdCQr0oZKO0{~dmE2|%!)oW>IxYrO?X!!F$i)?GcJFV?O-i@g0@apE zK93vCN|<3@SD!4anB(nj3d;;3*k5?(TUuqUIPrqq>yn9eeK`LvmY@N4xn(bkGmB#d zAP~Gc&aM$Q?8)ftn{MO73u9d{e^nvuXM2t?DERlQWOqsb!aDvbX2jgFzPKPN_Kv{Um?>*JNevl5x+ zd8v?8H;v78)Bk&rW$va;LA48}*i7NsO{j#h0G!o+jsx>A>sTZXGbIkbBPy>NuG=Ub z+DzSpqGsp4J+>%=4kE_k*uUSF?FzcRUX4`IPrAFxpn%nr>0y^k&<#eMs2==8@;2P7 zHP}h6o0@nORlJ^nrS`w>>5YQe>HK%4%|=Kv_sy}ljMYbkz5L{R9)}CCvXH4APwTMt zNj^1s<}Ryvsau1K3yM1f%+WyT_ul@zTGfy@&0aGjbaUe-ewgL3^^>XP&D}Knl!Ae% zMh(@n4k?+f387eC^vy+^rg;KDPSCx!Gb@K2*1m8S;c_PI(%3Eil7BtHIo=G3Yu%~; z8Vse57-s*6ds}tY@uQ}F%mC1i?Ki3)wfz~BAz@tRFTW}PcEnK$Dw+Hx^<7Mc{rk=* zHT@3;t-Ekl8JBSbUwKtzCS>R)_d=lsj=n)mlS*0r@h=mGG?$Tue?sOaB^o`dPo@fV zEE-ZXZpT8WcS4fgQ^$={XB}M;&JC+uq(|<%>Os}tDabTb5NGRb9DL$$t8H~jf}|pl z|AhlQDOZukc+b88y}fYlmi?<De?beF#&nblk~0kv8?nyv1tM&S}IZg7P#mSw}fR_IE$?3z*vAo_0GwaZg+1&}FjPCrDbeBnz&+-GJ?f6z<2MDz8dvgb_tf7|XM zUfh+Q3=B-ob*P`Mu3{(<1Hg*$zMB zdFp^U=Hg!B0R>leYSOA(hxbKZe(_Aq2VuC&k2t?R8R%~R(5|=~v}0id`EKO?9J#Fx z(TCgi60$dT=O?GMD=;;g+4ohh?HGyQ7|na<6h!y(DMZ%b;Uy|lkqp7t{a^Zg^fZD?zd}CIenC8 zV^)&sD4R#Rq|jioS(eVNp`t#JTm>W4xqfOk16Dnfks*&5-awZfj(V<5_u@+=FN1>a zr+mnrdR+L^`OoNWhbU9#=W|^XpC~lR31oE>|B7|{FtO|8uHsr<%yr9g12h?Z-}L0R2JwN+9mmu?u??3*m=ZR*es)0)d4V8CHtqDCa!e=?SQ?5jRb?~Cp4wjFLw!7V zA>h$-&#ojZKNqnYOi;4pQ;?O^!g%>E#*Hs+cR4jzyR=lKgwd1#>*#$*e`x=#jWF@eB)c0`oZ|#8;n1!ds)s$yk ztkk-%B})s6#@&7cD*6-5wUe1MNstUt>%{G;&eHlA?;a!b{5af(N<>&XUEOysa2{gn z{B&9MBhaZ;b>ypaX)0{NjlF%Bpb&)=q{hBcYFS%7KD1}5qr#_dX}5m$8U%PSg(}Fj zSjo~j$@w$vVAA(4R%aOO9`jup=h;)+W34*1>zpZ^U6?!LNWayTyV7PT&wU}L5Fwdg zS^*;jMs8?+3MfEa=EiiL=RSkrQJ*W?RRG!Sw!nt(HiYwq(G-e{1a+Y6 z0f1HhNd^S#yv|kcWc)YyT9#u5nqRP7uF_HPM$ePv3e|ek^NGfzHeVa<4Rk=&UH$Bo zOP0ARi9>8QiUYD#`|5*ro+%^Jlh!%QlFEHfyOl$n!g6twKr1hB|;=$QG_x61}ndt7fFtCblZoeqCAL`{Q(_Ugm619kMQbzDb`!>(nedgVl?Jl|cF zy^nOXRx4w{R+{M)t_%`~?(C1)!WJFYP87x&V30#uIj#{N-_)&7Dk~`k%T0f>13_R< zXgaW&5?r4Z^`|5RNEIbS2o>4Gn9X8KK`-GBWp#^o5xkTnNX|Xg4L3BG9b;hFmQj^B zWkO|~JmTS*XP{EYRDzd67>o3O+;-6(54Kz5s@3?L&OCo0A{7`&i^I`JtJhpPucua z-40~fAMbKi*55QLz&vZ{|7PSuw2}}1-kc0wZ+$jw*VipS_p3{D?y+k|i##+%|5>-D zdvj!Jdwe%=C&$f@p@`t3EJkl}hm+a{r8J9+7x~3${u%c8lbwpeQ z#g^ik6YVo4lMTPWR&{=u8${OrdY-^*b3NKNjs?C2bxZ9jPjEi0;ovmTIdxbr zZp_Lff4|c4C1HDwloTsfe4#lf1rd3PJ3Uyy5fWL%b?~Wl0&1#ky6yc+`76!Lyq3`) z8vgjl)Y3grhZ`}}Vu9Mk+_;?c(=h4li#LLZMZBv@SiQ=x$6n>pJ`aC+pj_Q9wodPD zh51+{zeg?Ik62jR|K<^w5uP=&K{-sz$#q@27#2Y&Ik~wPjCz8=IC_>>J-shrd*dJr zelg5p_{s`)D1XZydY~n-eD%vLp7vlmgG8Wp@o@hqw=>48tE;7Sz;7l5NNKhz%Y&zO z8v;*HPbDr44;s7c?I=q5RO}(gz^FY*=I$&60aPWjplJsAfZF;c$oa=yAvLu#eId2l z6~$Pk0(vQmd8I91M_0uVt<5<TXTZYBS{20ysFD!>n_vz<`J zn~v+t%lXM9;|6QA`GePv9+!Ae+6X_k*U8=bOccgBi)!yV!%#;k>NG4*ne2CI-;{eq zzoumhVoX}@;fX17dm(um^{U5r_~?Wq6 zTxfjJ<@^Jk#(?|hj6B(R)bvv~Px9z3Dw z2LH#O?^~M&rZ~Ju1IwMSWgWJk9$c)NgjaBGICbV_E0P?@**cEr=qDAezU$bhf6CVU zPokdcp)HU7THaYHosGdSZTr8>fSh_u*yQv*dO|sGQ~IeoKNbFwA}!;yukbT)*otnh z-l5X$fpC1)1g@3lH)OTLwF>jLfx*lA;X#aWV&P zXGb9x5%r|Ma2b;N)31Y_t4XeuIr3v-T92 z>Id##8cj}nFXv-?t!JpMX#QdC6&!oJ6&Ah3Eao9B ztRN0qo@^)O@VpdgBAOJgo#+!@ao<$&(;taA*R`kOQj_1(I!$aRkY^(47had0;a6XM zRBJ9aiX1MAL1Dw*oi#$#t17B5gL`!PDy8;E^)G8JnADX5e_*U!Dz)4{(>#@Dt6aSY zjC;@QZM%VQ!WZDXy483qjcJAnfq#iKcxdh~S9yk1V2t@FXGtLkDt<3)PGS|3uh>iP?D_~Zg{Rj1Dho{O`| zp_PZ{+(A_<&W|(B7F^Q?^O6urzeBIdH>!lSzYn! z3xrEP=_8gz>fr3=4x_>`6G-i`8BK;zIZt8G`IGcKwP708Uq`(C3zh` ztSjYfVBu_b>kG>KpMCaYfz6Ak#^?a0mUjZANu4FvY;1Nw_W5X!*jJ}{6DHg9cySLI z{j2qoj`j?oiHix9%U)>QubGX-L4OhTQY7uju5>K0)OgQD^2@_;WLG9db6i*K$V^Ed zzQ_DFTbR8jgAT+v1IQ8Beof>W2raM8I6B83@!p?R?4oR0rgPo+K)q=3+ARs2fmW3{Y0mh1vL!cxcSSG)LICB0j zTk(8hO#Hywrja&03 z77Q$oHt&sgYmAiAM@g>~X!y=!@_3*GmJ!d~uF?K$Hh|h6l=t(w$!*okVb~bCV9@e{ zxX+wm!L-W|67{nm#d>{p^#+)aB#0<%vw2izCKtTHfe`>of)u0Ft zTpLa5W6MsT-LELxX>O16VN3bNI;*d%^SYK?n^z{3>g1ItoxV2zP-cWf|;D-22y>P zz%E07crJg;KyBN5McYA_&omL{@$!wENyBl2N*rnuHjvc$?bG}qXob@+c9){#iBSSd z=+{Bje|@o4A%_zG5_@4`Z&?YKN8-A89GBi)SM3jz$P(esq)?iwkcE*D@xp0~;B#~* z^bMTC3^Vr+En#D6)D2Sw9m89(FlR^M-;}17<8h&okPClv+VHJd8y+Tc6P ze!RW)tNMMm34c(~(ur+pTPk6Zi`z&Vgs!1 zB^<)6TB9;<E=TbB>SGC_e|4+~BHuTO5TpCN{I1PA!|BTg2*jRftn$u|WeDERzh=nEAK;$eiF zA1w@Fj80;bTcvuI8*l&h8D-UQ&!e(IW#4Ao5?vJMUp1QU8Qw=s*g0z67B&uA5h}UX z%{9WV7&n#r-s@pSfGL7tYe@>+knLUCz0N_X!(VIXjr%ib%w?>Tsb%=9RPYiEFE^!j zjxorRJP~pI904KyWg1k+_5E;`7et;Uy8GH!JtQcS-VenEy-TewZ5L6L8qPvbA=Ij0 za7IkNty(?#EQ1>Jo_dSB_ny1C;abc}rNia^UCNlpxnjteVHqYp2X*%s{(YmMV@UgbdeT5zMs(8XL&kE&(H2L9np$pVa| zRsr5dy*iTJ!Od&!v#J#=+l_hT4FibG0Wn5xu!~q|ioMzi^Xa`N9JLmy1k_{l`qDGE+NOrl(&{;Np=3M0%dtX1- zsb5d?ZhNZRlQ%XhreN^jMlak~WYI?_H}e0qNv6|@6)t_u8vgEZY1yCN0j?M{@EMR8 z$XgAr(4ASgCy2eI`K;c$VD>_TbteL)0~Q8OT-sl3d&uR<1+-<@9LsiJf9_WSE+fYbSt_yevrR8rS>qqIb?pZwWLbkvHgX@VdY8= z+LvnrE?wuq1KkYs6<)$(2>)%Q19A_;5$FjoszZ=3B51~T0|;e}66gvDrwPYP+(!DK z)mj2dsIRwI*N4Ktys-?_uBXCmDqY4subZe=IRqP#Vca8{yJLc=a>xVuh^;Zf@)vi5 zt`>>}Q|ebEt051F_M?c?6F6=T`ptMdBDfqB;@vp2gcmmLm`4mfhBt1{72*F|ZY$mRFrAw4+8e>X^EZGMJy;N2XK2@nDe*AgTqHFfH5 z$_}5riNZb2{qDq^)BpA0nU9?JPeqE2TyWTuFzTU^?>7hBZJQ({Sc^2j7d(7C?`-q{ z!X+zHYU6Hj>wR_IU}&$`L_kC>=}^2(%JfB{zIGvF-}G%y_%N z0o;uU;TV^_*1d8qC+}p=qS=fVD|Ht?-c{pJW(CfV-k!K_p0w_tr1TA!`_ugds`Psq zlI0SykkiG;JC$XVJfUXbpwWej$5P2@=dwIPvoA_|?7_y0ZcGRRL~L2xlg1p0!QM)} zcGOc(SVg4RszY0CM;a>Z2;Ckh@dPJLpoJZX?9m5S-{o;YpwdGcU0Rh;= ztEA7ItLtNMUM-;y&Zi!uiQncn%&pgLh+)P4fh#B@j90}Ueol9b_uxuUtm`udy#kDK z%y;ZgW_O*=Kzw?slA*3hw9o+ADpYT$_RjUHG=zi2_>=H0+%Marb1D)sNH=dJWXe>| zL;7LG+Z!fVkBwgz!4$zsNC*DFu0Ub6Qi}S<~{Buq%(#?;C72w-7b!>{AXEE z&pggE(drWbGd{_;X^9VWSG4g};nc?v`B0faO>X#tt%$x zHa@m!8`cI?tJ_!FVE**K@0`|*w@=rp=%`37!)26ZtTYApgMuFgF5&mIHTH-yE8R=w zOt&(!lQPc*!b9$t!y)~kmn8G5<~?Ub)tgOzp@;%Wdmimzh*7Y)j zYK{qL`^&$+2f-B}o-3T36|Ugyb75Huk{%T1-O^iAcO7}69d|0u@S=Qp<`8;rN^}HGI7b(8rPda!`3-}0Y%CPifX5p@k+2g- z$h*Ldw^RsNd`(a7ez;L~dVO--)H>iG%=1={@n6j=|Lu-g7JP1;f06-9+-(d!^+Ms& zZhoa$w%@cLHi8wa2-p|RGmMVL&kP0;X9tYLAxQbc)xT>Gi>O#H^TqNLpjf!=Pr07M zhKBg$6@Q+xWJ9QVe%)gbGwAJvSuij*jI~nV#b8Tuq6jUT3NC*8xcI-_c^HEAt0U1> z@!=MmeERbV*xYv}U;KATOtLcl;m^fOx$~+;^RHbQ5s(7v$d$tWB$NK@I8;w)I5BTX z7CIS_MId-lszPL!tJRHo#x3)k~K z2C+}QLr*HPPvjrn$o6`;E!*EX$$WKp0f;SdoTqwJt(dT9U)(Hs`!oi4xY)|XgSjn? z>&>Ph7?2!=5^hk~$I~DTfq(N;FbM zK*E@J1M}`9VH-pF5`u4?1ttGiwejdfW8wDNY?3rHB`5u}&(%jLND1m_0tORYY+m=o zekM1=n$KFDjFD2-p51J85&r%rgIz;QD{6XtV7+lb6+31t^tX2;p1;TYE5B8iB=~5{AV*dPrTTF1flr`p zwSGmiyW4N0lQbRivlN%c!8&_4zu{KfW5>w&zuAwM$P(9laYFSu&Pn@$bL1GkQGVZcF1)n%A9{Bx1jZ)|e*Eb&C6N80eUSjl;d<8h6q z4I3%HJAHi36#vkid+vy?sce$loUYN9O(|@+?(}`k*cXoaLEt)gJVuiW+{0Vo#?9Zv z8G~TkjFbXC`oE^O6Sf0ygEc0*vML}CBZo~m>ZPl9o%(e%F3i@7Nq8(dV(m);3M>gH?!DSdgPdugJJ4GDfzeV0=>^E&~Ark^i*LT>gRvV50y|Cze6Y42Xo z7yt0pz_0;}pNBu!r;CAiz8l`U5rlDsT(+p6vJC2qj!rQSYBr7?p)<9hvQnPguX=i3?Zs0oh=vs%juIB^jBK7d_bH>KBT9=Tm)opUnymCsoQjwfOExm5N) z;gaProwL%P9!J1Y8J{kCr))jVwv%Y#78Xvai8QCza4LI5*H4~!=nO%Yj&1p;`fbF& z(>B}{N_wCO%YM1?d2re8h7{;WAXuT!=X=Ai0{stEk26icw@pvK{fnYk^L(lmTWrjm z-bBGFb60jVaxV-p8+$H}m20W`e0Lx{bRb!S>3WPLHN&{ax86_sf4yb6t9D-j-@j|0 zRIous%s%epMtZLFdXTW9!^pbN1M?f{J{p0vxL$Cs|L@qb+R=HQJ)34wIsYK#D72zb zuBS~dGRiC2kErC<4FgwMCGX8W(JS*&``fHfCk~W`8N=#l;0%_YSwBd2(EHu?hvZ5) z|L}ZlbGJ&adq#^5c-~~|et@@Z+?xH6!@d<)!aK9ZgvTvQ*2f|1Dj>{pJJd-cJ@iJj zV_Sks;=x5jL0xBU5`PA_se5%hs%~8X3W*^W7dWodly6Bs-j@WtWqMT2};%h&Xe=)QKn3T9* zW4?hbd!5S;M1OKG%rqDOxRBXi-7eq$wee)4{lgJ=SpJ1Sw}u12t-}m=w#X)N3Jk6W%e1wJXq>>s4$oT=cS7l%`*gROv zA?zn@9n(9tMSCE&I#+uu$UU+M3Q9tRC}g5?xzNXk5+SQIN61k@V-@UIN6PVvR}HPn zdhg~w{3Cu!_tVVU=IeZ(1`}bIJi>}Up`)Hh&`d>#IN9^VCXRNZNF}`!n5j?qF+bUy z4?X1Z&?XV+{K-H!c|+&|Fod_Y++gmKq=~b-p(FJ~$V14ug2&3i_8x3)|D%=p$@)Rl z*!b3*acWig>ZssVI2>B#`SAnaN9uk?udumKh#tMh@1N;IZUJl5qEAsyrj41WW@YfH z1w(k2UW0-q@#vd?ySvxGZ=ndxIy1$=mPzfiJCS7496=26Ix!oVk?p z?}48!WS6`wJGnx})_r^`TI62S{N4xG9tDvZo6TRcotP!BvR2Gt9;5a3F*%e&|AS^R zA+N{lBmwlFGxz<$RF0?Lu%^5&E$K3A`x9P5pjDZct`+jV&iJ9)Wub-4u-mh;3=29c-3X&E!_7;B4>xwt zXeNX(dky{JKO_3gWq^XCh!f)9sHv=}^>ky#phD%1prcXhg-)F1xPuX8Sie`5qd|I1 zoc(S6R9yXn=BL}Q7c`G@Y$ZkeDPwi`JOOziJne?y%Tb#ejz4&0X4jLlKMDsVn2*@Y z+F{_uY4Wfal_Thtr~3V^-lOyzN7G}Av-ZMN8=@hE7FREi(=UXx!K+ zu;|#H|E~ettfQMeD4p*9kWngLoH-EH4hu&qvxn0rKk1p&f`t{+ACe9#vHF=P@q>Jo zTk&NP&t(~$)^GDy<2G<%Zep_Hq=}jnEFMSE&IQOKi|tAxE0=m;~OBL7LZ};P=B=}3%bee4M5?t zz(c&ZN`{;ui7|++)Yk7CPnJ)keTwqO{fLz2&MJDYJ>7y6+df#7K2;>*`}PjG118`Hnjca1$@yvA)0hWy0x( zkuJK1bzOS|=8~EF_|0>cc9jP9v7lkzAA=^Nwj1;`oe68AQVyKcDh z@Cn-2`6|9f>&T7VWFASX`o#(e{Op>6El)7hMSo=d?{qSJ{lDKavr@H87TbWF5gx&T z$g+l8c9 zf1lNQ6P@yG)R-Fg8^yehY@jc1dbF?ac4^ zNXP?Q?;@EHejcvp$YV!faeh&&JRw6}G?`U2lICKWPl$fogxhn_irC`S`+fc~)C9Yh zdca0n(w^ZRI6FG23XmVsM_*#Sw$(=(GEnLeQ4!Rdbp;Ie*|1S&3!l?Jzasr#Vu3$F0P zfgO6CI`Ti&wTP$~6cGZjv`1N>HDH{*JzmxK{b>FEO?+&X@@TQf$fjorf0YLDyG_ur z@2fox2g#@`F5}5{3wmeb03p}e#-vDZX$5hVQqO=9KfOlb#n&|JdQQT5jxG3vF=r>v zlY@q~x`Oo3q2`M+P81F_mj;;WvV5F`@|9S0{g>O07|P8Xr7(bKI5B6Ru~G8u;U(?C z@GVPyV`u0Zjb_(XVEikmSEdSvtQ&5~)=6$!SzO1*j8CJ+3g}G>_l2$iL@y={Fg!~P z36a~G59mCOZ08=_?Mgxgon!-36Dl-fOW}0C(qY?y$2p~MZtKc9V?W_X^jVa&7MkR` zjl5;D7-V+ZF!Xf7y`m4Er)G}Jptwpw? zFhMt#T3eSBK&Kg**XOGy&M`0;q|+UYpWkMH5_ErGc9M)){CP-(yoS@mf24m(E{?Izt3aJ)~{#Q3b?D@ zp)Etw$R+vObcp0T2A%FB*O%Tj8Mf=S0lU8hvOX~Op?5l-{|AOt((~MTYxPPZ?k_9o zVqv_KLX;Lzf0BuY^URi8$#;z8roS!pJj`3xmojMBqVwyJC(G`}yVMM$pH8heb1c#R z?F)~#$0HdxM(8???}A-7>T9mDgTe@97zIdGS^&$-?AWk=JV`98sO4zRh46+t_^nfm zk>)}j=v56W&MfH0{2cbRd*nH_%JzTdT_#f0*V&sL4S%n8j?z$yS+9NGC23!Ktxka& zKz-I$mv)~*g%Gs0dzt3A)?Ak(k<4m$-!%5qGcy{8FB-5%mgUnt0x#4LSf9!TyF_Uh z?1XD~ZBW+z?gaZaGH}1`j95-$Sj9eBo5pt8oE{O|%l>B}VmZxr*K?}6#L!w6jCnrC zKtoQ`Y^kpG{*E*dWmGaBpb;2zzVhitSq$x$St9irk)~(u;Mi0TXh#8&3d^~#-N6;` z407Wg`kY^V$rMeIQMe94fP+ew2z#CSNVZSMhl8{kVm~ujX1jyrYCOD-K`9>+cJTQ- zH6h^_$RjcB27>xH!QNgYwk*@lWM2@6TI3^0g-x?$)(Xe5O1~_1*7A!DA?C3ej5d2iiR&F?4-zIkN5x38uQ|>P8BIf;wuQ4%6Op)W7AP zZ-oqM(crid2f@Qg7?7UM|N8uJ?V zh$4$eEB!BjUK0_+)+y8h+zW{oFMB);4Fnj{ZiO)|)7Qqr7dD3IgzoCnaxA1@G9D=P zXmM78oij0LA4?j7i3mpf*VM9QtV*o_Ys1*0WoWA>ToSv#v@4p$pq3n+QbO6x^G*K5 z&|yy-3T_LS6HxWIBor+}n<*IS56drPE@Y$~sq1Mzn3AcrY=-N!q3T+bY-t$c5alhp zq=e`ccLWE)5u?fyZSk)Q4_$YZI^dsf$q=g!@X~tD{`8K{-Q>p{9hX2svSpNvYNb## z6>=;TO%sWX|5W{--Bty%E(1Jiu+sDr0ZyuBBM?CIz%#HD?)#C)=eV}^Q^^1a}?5GwGU#PVP-@j-RCrl>4E9z3sq=j-SJ~m zpuy-ftODae*5 z>i)xhkX14;J{QmWJFM_Ki}JX zwy@!xG*=|%={Jn<@F;uzYW=E=vVpe15q8Oe%FD+APHtK)mjHlz6AXtPHT3zH(@8zI z`+M2?3mT zVu?GVq|K_@&q?9gq}ZbP?>#)Wu8S~}U{y!6GC~kDv3!;kIBP7?eBm^q{eFKdcu+Va#^$aEi+P%Rj|lv zFPhIG;S_C*`ma(ju3ulbLW2b$^E`hv+aJpEjq5@9nLmBciDWql#ET;=PgJj_kpcL_LhospKA)pv#ilK%zEA$JzTnNAO!&{(piWH;#RWdBKUM zDR+PUcm;)@!soN)^N*gz=cibe91g%7oWSREOpHf;;)I}1e~vOYYS7Ua`S_v8LG;OA z+p&p>u_Jj<+`ShJ-xKZ5wAlE1`C!}3`UDN5b$OpFH=Ju(d?lAampucOnuenn! zX&DXw&$9o=p!*Bh&Y$pAG;x2OS?TVLE$VHN7|_0YrPHjR|2xEc1rKzuD$APxajd72 zFs{${_;Q3AV*V__Z%H3eP?lW*`<4HXgM8o19a{eR;Bv6fLA!nXMdcyxzc|=lDGy)f zB_pkOFWm0n2e@o|^xMDXs2ZM2`LM2v+AmS3`ih*>Vw0-XDV=t7K0g{|gwy`F?-gO( zA#v^s06mBUP1-dI%%}!9xprowy)|x~^?Qq)migky%Ee!nJ3pejY4sHOIb&G;Rlz}W z{F`{qZU1i^i$5M@#vF#*10*gntEL@KwH{w$m-M}F^lY*^s>A_sy6;eV@_i}0!spE|TCxiQEN+dpma9P7|K`3W_Km@M_ z>un&~d=%w_YIA*dSxU0z6DKMN*Z_4URv((!L1hXoy*{Nvb%vce*2Dv%XXAyOLfgj&x7kFaV0)bgf?s_*`676si{4Ym0K1|A(dTi_#_+|rCK#{; z5YisO8XPy!H{ERK{)isa5;HiBTJsC~*k9uJfRZ;W4)~rZ6-zRnblMHrGtXbpsa>c&T{JE@su0hhlmODrA;<3Y7PufdMD4w^YE ze+>3C>tRXqcem-`ZntJA(RxfR1teKT}6Ie;$=9zw}2%CYXB>BA$f8NX~;pCMj*n^~H@ z<2Z6DqOxvCzb!o{MZN0+l{?IOHKz}0zc{E&S#{bJdQakniz~P+)mG~VO@l)*7I}jV z$C^j-!N`jXo}6BH9qGJUi-WgVZ^O@h^MW;lTZEZ$V%md8p=jq{unK>^u$ZLhBnL9c z58Bu4Vv)Z;~eWVR}?S<08UD9}t{%xDjh+#ARN-`#- zF0sadU_Rp3^FBDlV|3VUQ792Mm(l=k@NG|(PsSmjm2P!dy~!k@8c6r3*=3fP?#Q?R zOzL#58{=YA%d4AHPcHP+&UXLcJ4sZ96wKz>QVETbD#3JB53AZj>L&C`J@OZl%R_^?)Ad>eId2*({Ju>tIpp>kt}&jG`q7VbcVv^}7@tF4 z1V`-l#zdG)EK|ds3@-LRgBH~0l@LB4;Y6rP-YJN|!0^gg+Lju6-KfdZq@ zYtpBx%c|jXmDPM+V8;p7Jl~4pFO~i!LiC=IubAdf9XA)~HT+i2;r1J_h(x!7fK{`) z(mDr|1k!ymE}K4lIe1M+WJctJUe0Uuy#Ud7cJ8-gX`82gpkv4L9Wd3rBqfO#_fhtX zyYAdooS)6AB&0}hXN}1p%@5+rP;(Ot^*^ec)H1e9q%%W>0jDzJMLv{sov9mfc zVZ=q&w)S?}6Op8*(NY&|3tE!RkxWVTOrE0o&lgSCB~4dp+GP68z432t0RzT^Yj^|> zC!7k!R1{-x{tUD3H_c45hj#u_0TPlZ9@-8%d#*n2JycK&`auI%lG;c`x&!^CN!!^S z?l96wyl?A9t?HLJFw>oi{4{jCp0)q)X$m+jg0X8E`6?7!`1bs6%nRSSBdb)`eqh|~ zULgpXrz~^y@OPC^jCd9Y)oNR)H~Ug3W+XK^* z*mkIl1);B6QGtirr;V+F}c5k3TEPF%sa zs%dqfUos!kmI?vcℑ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 RfFc3>vERh9DPaD3>VKNP_E`V` literal 25874 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 P$O*;51SZ#Q4(I<5j1IFD diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_StyleDefault/WMS_GetMap_StyleDefault_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_StyleDefault/WMS_GetMap_StyleDefault_mask.png index 7079671f7cba86c1068ea76114d9d8a2bbfa5795..60665066f9c1680366301970c7166d369037195a 100644 GIT binary patch literal 17563 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�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 literal 28977 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 VFEAnp??9v|9#@f1Ic9MEe*n-sVq*XR diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_StyleMixed_LayerOrder/WMS_GetMap_StyleMixed_LayerOrder_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_StyleMixed_LayerOrder/WMS_GetMap_StyleMixed_LayerOrder_mask.png index fe91234036d74786ebeb9616db79f9e757f53816..7677b028880c22b2796903583f0f194936a152e4 100644 GIT binary patch literal 51957 zcmXtgbzD~4^Yx>mqJn^g2ndLDNQb0INJ_VWbV@e@iqa+BARyf!T`DDlba#n#m*hL= ze&638_jB(>e4c&wo;|bHnl&dt{^bkI+eEifC={logs374b!8v<2mJ>8q;q&C5dL+` zMnc0Lg~CWe{<#tv7L$NNk)tFX2H+^th zLgBmjJMR(SNedqaF5dKcl_D4XM~Y%N!e>|e-O*NL1MiVvx%%jnj)X*6&lZ-a`(}!O ziB?&Mapd1~H-X~Cu6TBKlkRnX_8yKasP}qt^pDZ6`X8GN%44HlK|K>a+lc4&`89p( zHKDI9$9{D6%kS*L4SGJ^EJN?yO)#c;p2m*RtnS|!KUGrI&2s3A&)ckgrRe8_C)Z@OKfwR6 z$l&*xR~){)+U#HQ+yp*6&JD%j0RN)@VeFjs1o`NKj|{frH;e6Fuik_2&AM$PHoZL? zVi;F@7x_iPJ9Dx|akUum-=+69GdX22}J6*pb}lQiAiwU7?&)<9Prv-R;aG6 zo$sJYjjArzD8JF#+RB+Cm~~=1>~4toV_V%yOAUO*p3yt{dU~ZYXu>7#MC$98 z8!GfFA?-(lN^;?<`JD70ZeXT=xQQh-*`4$>LtXs3@aLo?lE^uMljV%BMx6u!TIS~F zh4lPs1=dZ(Mir%T8^=`e)aM5%TUM=pLaAe%IxZyYxe7_ zves2rRShhA`_IlV@oeOiUL;?$Iy$qGc{O3TO>xN3-HnMVZnv%7Kb?epP6aK6Wo7qf zJdTpnFZrA|C5+37pNm#|p7TylPUgj^XT3zih_R)QT9}nn=i+3BEP#`C{S>nLqIN_x}|4^S{kW;4q`GUFfht zj$eciJpiob$~4j`Rg(v5bc^@P2X2n^R%?Ikh8F03knL_ zI5~+63txGn+ZbF@!UE5jUSCf_6mmmHM~C*w6LBl6Cv0qNB_=(juj*a;s71)0JbAJ_ zkd38pV1PqFaKp>X3y*+c{_NkLe`u(0YARV-dHK$Wu2-65BsDq)Mhk3Rcx};A^$2DJA!SU(oV{&qom6a7OE$z1uVs7jQ4{jBz22D=BLOpx-4E0J|TR~p_ zomQ3AT$s?sw=@wy2)@TzJ%b;s0|RekkO{t;uQVT`kBW{~;nOYn-r9QoA)k}zMCBVC zY-|)PD`&_YRz|_VaOeH|_cr$SBA%XtQqt0`r($Aa)%Jhyb|>@sJ$?~7dvdT=k+6C4 z-}afKg@}K+N$P^ScJpqF2$ldPE6z-vGgi~(1z)B0Oeh@j!q4!>z2+6BQ?;CJp$~)l zGF~+I^vDq`{ppO|nRefr^CR<=S6+vxZdv-BNM+@Iv?;bV-Ed`chSF&9XE+L_rl$5K zE9-fo>SIPm43y3KC@b2{n~ym-l$HjxW?9)q^v@5_A|eH9jJaGj*i zOpJ{5=6?8$Hn?*OUY^-IY>eZ>1GM<#JT}a-o4xp0d4777QC&?4-~LgvFlLgBer)%}bn-}7(puPqN35~F5&(?rThFRx+oznk&8)F$vH zM<--6L{IU$aNXaWB8EVSKsHUi((-|#qN2_5wq8qHn?5`aA*VSW#8X;a(L#HeK}Q6Y zdYR!ZDJdzubCwu`qY8UQMn?^ojhchqjj9<%SJ$U>JKcO+pEL`({=I$un*4l!KrXNc z7pL%5jp9yS{l&?ecq$}94)Z};3JQ99`t%VU_Yk+EO<7UV`1p7Z&oh_6;9%vqhpR*R zQAtTM$UXNwKT&XVtDV=}?2Kg|DDM%JE-ES#@9dA16Ew3EI8NZSpd9f!KZq4`CB?@# zVtZv!=DKIxanKrcAAis3=ch*wyNi;oED*9Qg;moOA>sxc9uTRSySsK7D{;Jzc~hNl z1hDI9-uYy{yu;wICYq_JAT0boUB9cRhXxA^D`?N7H4tAMf1lX8{*ilI)Fm9iz;uKA z3X~Z<92{YkDeTEt$2C<29D&18gTS5?e%A;BW*wP~7hzdjO_w@Z!JAWcFZPyxKbDh| zE8jYpwC{;mE}^2LidZ|EcJE0)BVyGTjmC2m6Z7dfh6}N>*CV9%wz8}&!t;3U=Iz_J z*%BMSe4&h7fy-CvKIZ6vWTm)wa%$x%{{HA0#xtB2!>@PdTYF78s@;#Cyi66u#nZS1nM#Kh#o&j0 z1n_WvRaM-+n8dyj5%&tT>j>Zoo?BWnCM72$SN;(%FAK|^zsKKk~RD_3%Ia9hS*;bZZ@Mt*oppj})gaFD)*9{F~zbvYredpK5x*yrSCf&u!GVk&*kcPqeSv z%+wcUC}qDi9mopld)vpofQu8utouaA-PKjEGlnVMRVNh|&40RH?jID?ob=Qln~=~S z&Uv!N{^rxCPfdsN@a^pF6?Ak$-@QXg@_SwUqtVyb7p;nl!h`!tB>ULlsgt!zNy(tf z+%yFAazT09A#@uOD{YP9Uouf zS52l6QUOg2gWbgrJTfx5nYVkGDyph*dGE<4aCDe5SAPEd%&x&~fI4#K$H>SCy~Ve~ zjfqy1x=Q=IpheM3QgJK#uNI3 z&8b8*VR8r&A|9L1IW5tPeJ{wU3RM}DezxH`R#{E8nAACKm@Drv>oz9EFlwZ`SVLmR zyLT@=j`aTh`{UKNkD1g<-bF-4nn83s%(vX?H?MGj#FST15Jgvk&!GCLxVV_H0M1gg z-i6hSgXkXGd(yYt!sb)86)r-L9=%5s{;ZO(s$u!W>ujf8)-$Nl<5bhglT5(vtNLNn z@%$Yzp^;);HIh3skZi@o#eenB&dmuAWXom0OyolmLv?`j`4;lIh^gSF-`UsryWthP&J0*Y6O>!@>Vf5lBQH zV5L9PVP{^f*6koKz0Cbjv|8Tz#r-F*N+kY4#DA)*tLrG4c3Wc#igxw%Y~<0{$&A%e z+*eXo{<3_LdU@uDWt&U<_O_vfv0b*D`0m}mZxY@F5HIld*woa+Ld}YZ ze~&1t>*_iup(I<_;YPl{b~7E$2lWLrxU7tA%$UB;d8;k>0Xw5q`BO%fZ-2X!o1t*a zp6nbRid$M1h|Ot3o@qKiBu>xB*!jg!{BskIPU|oc$uMmp#O=T8?|$zbCKSI?^u^K- zFb=FZJTA_kS~lU^#02r?=4Q3S%DwIsfuQwu%Z`Ywt}Yoy^%B&#%NSjxwq?aZHZj?` z{P+=#hfhm2nTm#HVK7&T`dlW7N8wDjii!b87)}LG3pR*aChoIKql=3C_-@75ugZs; zZQTMRG_0(B^S&zpErms0F8=+c8b*I8r5XU`5%c=>>jXYMgQQMXr{yJsRC7DuR;48* z&>Q|OB|4lP+uC-WKsnlP#uDlU+)|h@G?^t!+{(HQDL2ql$7Sw%P}?K}Jw4^Zrquk# zhOCj1(L6h!)B0z~Gf>xY3U!-w*gVf50gQ6YK=F9vR8W_m{$sh|t;fH=LYHPc$F43e zJXe0xcP*dlBn*00?bprXwk^&!BvPol0JXpEi)7^N($bCDizONeN+yV* z$5!6@n73}-VnZ@)`NChI2xYRbJz=9>HMk8KzQqze{#?!NE+%%}YNio$)^luoX9wpz zIyQD;=JKNI53~LasJ~Fi6z5enG;Tq%4M@zj?>SId-H80bS^~-Axtkj=f=x`*)y9>) zV1335CgxB2;_?d!%+1g1 z4>J~UWHlOg-0P@_cz(3MA64V=?@uiC!qs<=M11`(V`F0` zqSc(PP^&72ZVSPRX?~;;)lAy8gX!B*yP|Z(j*)ZwGg>cRz6_N~OXab>dV07~PKznC z@dMZZ#;i{5fx~j|6{y8NO-)V9PLLE3_|@0f7svI6C?X=Fx8BwM`1trW)H5ENSrig* zKy7T#>a1rPk9)i>9^Z0bXbXv0L#nezxp=*kt*yf3xU$*3SgJsYrdS!#pTB>Ll^g$_ zU0-J$>mQELSQ`HPYo5^3exj?b zuoy`%DUq+Y8Y{~*ogN7j;^znC4lFC9b8sIb0OwLISJ`wh2S=G6Uzt9dr&)lTdt|9W zSp?VB%BrX!O@F24uT+CaW``qu^W(svpeqtHT7H}A8Xm*Ny4GBtZGzinoW6Q_t&n3W zjh%o&z%sUY-1c*Fy2{JSdNW>Ny**jU7LR_4vdxVPh0q@RH|I-jl9{scZ||>>)rnsy zp$Ik_!0@1v=;-L5-Q5IRD{YGake)m>Y$YIUY)2}gJ&Lj7HtnB|09+bFtCP8vCT`SZ zgS#5n!a3AjAL?gLz=62f2+B+g?WPPJQeIjRd zzK@6Z8qWTnkXo@$bQ0x_pV6_Z`O!(QZ%pc57Gh& zD`?(i{Tjjz^JIXDP-PwV_bV>``6JoY0CCg|>EXApQFU6!{>ngKz8Z5tV#L^_d|LLG zFF%K6wRpq3Y?$1E0>b^dHtV?{cBB)_tXoOTFC7pTcHd<9+Bcs&_j}7t zx*~&vF~%r`n@eq)oz>i4Xf<&gXo3C_Ov?YLn-?SYDU)s^iO0!)c(n%{34sqgfchOb zDDB5*dp$;h9leX|fbuHeOh`>)L_6EsvJMw%-!U;U!64!3HRJ_=Ml}N0ZN7}t!^f0I zP+J=#Hos7(L9=o%`9hpGOMZ2u81n5>j}7{B?ysL0enm6TGBd|kkDW9;m_Y7W9R0vo zGo_A$Je7P(>NO~g<;I%u>5Q+c<=4|7v8KB0cF?2^nNwvg0N7pV&yJHRPnEegMh--56=L zUJJ|}5F4b*@83V%r0T39^*q)qpHu(fnL)|Uj%(7L6h6uQs@?i_Ge5{GCG)*Lk9-Xd zk$UU}P`=D1NIUEB|F33iNW1av1Go>ze`0l8^n!l=l*lmF1orwCQeYg5-qm-f#1;GN zW4MsGw|93VXsMek{_pSh3KMx8N|T}LMt zJqN6o93Opr^Z@elc%D@+FKumwfy@vu`$4mifV;)k&JJNCKwua>Z)UBIdR%G{5D>IS z0b&bqPl4Fia?t&18on&(x@$OQKUL?PE#h|<2d57%rdjW2;r%vZYiyLAvoj5f!{fxE zW9*OA&enK^^uGO{U-*F`A<^qo7a&jhdpd7T%R=5Vo{`MxlZU&3kB{F6v|obVxQkpE zI|r7F;5l2NJy0^-)=S$Bd-$F{?VGtcj!_M@o`qS>-o*C2!4wG(@T9Bgt z{Qav0FlR$YXRQwX@{-I~??Q;5wc8HTFp@S9k_dDrLT7Y)u6buQznB8V8jF#l*0FMv z@WjL*y=LDu>DVVcw)1GJ1?unZ|90#BilUQ{loSSdWxF*kAd|=iXKjfsI{|m8y-2%` z()Nz`JJ=Ij?h23)XMgzIQLiwMUZ!DVyJu!*CZDVP^XJcJz!Q1$6 ziP**6ePJO?s0~Q_-0EszcB&^4oSPT`aX`_CRPu<5>bk3|EBfu*&w)AgR=&|fcqd$> z<>>}KfPL3cqxG)rH?T+38A29-1wcq`9VD6y=uM~WE{BN zpQ55Di!hE?vQxJKA~bh&+=A`h-rh#pc-c*bKIAJg?W16=hs}h((C;Ed}XmC za=-PyZZGg^QF!olK)v@+zkdECr%2!5chIoLuAccYq@bZ886F?_hzI>8;^uU z=KJ^Wc=-5YUYDmcOrA8+Qeq%fJ_J;X5Q5){++iFn5V)ZX?+G*Cmnc$|443bu5stlO|rM-Cq12=83at4 z$}0`rmZRjp>~O8>Vh3(eILV>zNGIc{E~!L9^y1PuCHi_`?{9rdm~9Vzs8#3;S2i2qJhFNyFG-bFQ&ONN zR?=e#2?+roqy%iuZ9UBq&rKg4xYUy>2PpTe%Z|Ps9QK35i}O?Du>hp}?C1zU^#TnN zrE=RC=Y+3y*q#;c+c-a(;Z8Ib#x{kRbbz=~yuOEaqGf;cxc`RPNB1snXNbvVJ{+%F3 z6ykdWgOHqlDJO@vwPf1s(j#DZ*p$QJ{KOHIFgm(N6`I-`Y^X`0FzpeG-@ksP?<}+@ z^7l*)4MkrZRyFnA*L^DtGV>R>7kyE5O0?9}ZRsw6fu%szPlr6*4{&f97Z`_^f=KqGxO<*7Y2(B)c>)5>K692~u!Q|I;3aL<2#?%OhY z!Ud-$=I|z$hj23mdHt(F`(0l5L&o3n?0%rvygn)$lmFNbObz`c+i@qZ)(A9MevtV< zzafL{V|%i12Fi;#|Kt~7qW)oFFQlYyUu<1o$nl$PK$(dNUOU{HA%iDDLnZM#O0ixh za#~Q2Wxh-W7T0<{St!gM`y3k$-TNIVBY;A>*w`58*}kAM zkAF4$@cA?Ot7@Ao#N1XbaKL#Fa+UCY9EUIl6ZUBFsouBtUK6ZgSISW4=1w2u)ms&~+ z#KHhATIxDQUM1Vn_VzPKv~vJuzI}V<;^OkTqy!tb?76tOcp(=7unQbKJT%}hz*&*( zf*pdOtqna43=9B56ciP`;U16OHOP{XkrB-h522iB2HDRqj?E}g#jK3# z1o!cEVeDwLNNQQ^|4H7Uh0lSUP0PrLSLJ6!=#F3>nb$5^l~4cVE9L@dK@-N7mzPHY zMn-sXmpKH2!%F{kR#sMYOw3kDN7jei_o(XY>t|P1=$!7ixRyOhSMR%l`}Gc#l3 zz}jv1mSlI(UjpT#q@wEJ!dFO#MhU{Bawdy(8UhgtTvte#QYshLAG=xs>qfe;!2A%UO|eAaF9gv?z& z<~*3DvA_ z^XTomiE|Bg60xYZA#H7Kv%wq%JW|q^pn{e1%77RJieV-w9O3!-`6@l2fyJI2Z86)P zwhLW6${L!Qnp%JL4$x>q{Y4X(L7yIW2rA(98rtZ`|MQWL5%|L1m8)#CTIc(qEy6l;1>iN80h@(Y660L!S@< z9;()9BM`Jc`AV{?Ob`hTPWD$^R&%qrq4ep4#7~e~F;!~t0)eVaq}bT+fa7)CHIxz+ z6N~3p<$$&x;J&i*uL}zceX!J^{^hy3M|{@=n3!ap{DUe$qG9me`J3t`H5nNZQDQUq zJZK@v-~Ss!alJRB&TG||4M6*8`3k%6%qxhn__vYenD4M-zK89k4_RQ3`L7H4j9XIb z(i*ZZ{t^1o&d&R$CZV&lvstLhaMMgVh@h(cca9$2&@pj$SRK68!@q|CA{UcX7$}sW zS5uBaV-K1@*_N-kxwuqGgqq-1f%4A`y!Pi^{wteg_(b^lK7)hGt!-kessu=LYY8f| zk7|A^l&03bW=9NCesw!vSAZ_IEB#amI)G|W?Xr{J;w2&B-xr|G3#sTGDD1zw#X-;G zxJxF;XnP4qvI87LdROumDBwF1eb72c16pb)1YIyl-+u5cAltS)@&j5B6%!+M)}6?W z<%dO9xjd@wTZ+%`+s&dPI--;cR2+E74wR?n=H_dE{`?`QP*zs(D2F(Ei@u-k$yz))D#V105pB z>w5lc)xSL9hc1J9ol{}UoA2J&<9KY-$4q8GJ2W&joITxYdI8N$o)20XeXl_mt_Hnv z%;6~?Uq*WRRnQz-fn&6KEXJQME-l$%HTag+O{My@Du`jDooqK_bwF|a@#9B<8<(J9 z$`hS>TCMU1NdD$fr;tMyL%a7f_b|~AY{Cw3_(P059laUrz+$sdq>Pr{ht@$tJM^5yb!40 zmnS1lrtl?rczA{iXQZU0gH2vu(9#Xdf$p&rQz9d#;(7{-fWVJnikjm@f2I7fc<^Va zYm$=)*oHP4$LadxFn)c9flxql^lyR}Aj8?;fpu}c86T9GMijG%HQ?+0AjIe6#Q;Kt zcB0HYmq8nb+e&7vj3Bq|yeO~RJ}qonkQHRi{VlJ{L`WAsi5R6k!P`5z7)r7Z7DERk zOvF!|+1r?#&b*&!*Gh02`(-!{_og;fPiYJjfA1KiK)p+O6gM6H;4ex zUFXA7D%)6683pE*1E9W*EehD1d~SzE8$ej3rOcy7PDzQDuU6a!t1Pkq`%>V6L%i5LW zr=_KpX%A{vm;-}JCDXY}&Z&CX9(S+GpWiu7ia&mqelDvHRGH?f4gY(e(RLwfR=x1yGjg++TloTsR z^_cz|dz1L91ZdyW7i5`kF>`Sds1?0pt+mhwl+p|B^)rwZai)-H2Hv9w8lk=$V?`xP zaKoID1%}c!4y#G^$?H#qgvg-CBhBX6*!xMzmq+FKIXT}z+@C$9wUR z?W{nnW5_@u-GSYob~kdI2<#XuP85PAFr|wLwpu7xjTfs3lfOuhCv~JNWI$T z5s3XX3U6Tp5w8YBK&kbNVEG){_3L`jEROJ)o2at3J{$v_umD=|J#M6Fd$W`lx_plk zk5z|2o&zsHlFJR$#l?k+pwcUBG=PcZP=g)VM_2+wL)$=bY+VDL!?Z&4RpZ+lDYMsc zwW!3&2W?W2r9u!c3)k1deeXAS>jyQ)sj4$zSS|2%SI&xQ;^N~$e0&*4QnvwIESg)F zl@gRx;~0qLa>>zQ`Q)8FXh#LGaoHJ#M2iNTLNz_g&oNHF3;P(vA0nZytMy&0VGjoR6_)En3d zPSeFnehyl4QWA^%p(Uu?-}7u>g*Hc<+LO>}aX_#Lg5z-cQ9*bzfC6pym;3VSL+2mN za88L>1Mp&O005|>Lme9x^$`TLz>yFlPH%Gb2=OpML`n;=;>{1d*!H`tx(r_{013() zNVq=K(0NBter(rknkrHjno(8PcQAUpfE)pAjQ|m)S*==<6 zoIZ_B2mv0~-7hVL)z#I%<{muJSOXCyl;o-YpqH5$-Q?61l@+K|;x;xVEg`ZS!5IiV zVx)xpytA`&43JH<3UdF?HtXMg&~O2sfyr$(`Kg+ip8EWnt^@5uo%zK@&uU;jMeUL|D9{R7+lX(XB1RYoL zYMr;9*mibxi2|6jkcoc~dc0H%SRk zN@!;ZMMKg*Hk>%RH~9mD3veVr9AR-l6>o?UrLFH@CGlyP+kd0PA7*O7M1S}cpgE5Z<4zC3-zmE2kd0= zQ_l}$bv=bs1wAOO)<%l`q%yt5GfH_pL1npe?Z!_obbUhi|IAdPCRuNgX3in(J_RsA zke;5w7viPjqFsT!0<4gr-Rau3YgC?)^$q#5S9;^8Rp_H-tE7iOA9+tI;3hE{N-6*r z6AVP+Ec;4ykCZeNvKFf8Z1)aQCwqJ4BQLC{YN=|dDL`zSgZ76gXkC2;8tiCjXc8?p zU0Qy6*8E_m1C6>&{KKQ#uSB3Hr#{Q*^T(t$7!HGrkBDNBhkpPR550v;JsbXll=T5k z^B@O*Cj`(UkXn$D+d**?`vcY?ZG@Zwy=Vr3cW14*X&!nF5^{2g3uAY8_ft%aFI<|y zg-Hbkg*f2tke{i1-$=2p8Ee0I@nQjLTEwKqaKQse^lF7i@Cf*bo(88X+JCAGLiWof zp7+4gzC#Za*7O|UHn?tPL8FB{0(czZw}|J*xGU~GROF6s9&S;yt8?LxUmzvIkJJqv zFa(6-r}Y9v38Fom2Y^G>U~9kR^icF8^x$8EMM%BeIAn2pC|_-EWhDT#pwB?>wvUbg zic-Dx@aTh%7LwlKZjaVEGb0^I0MoBwSIfk4nn$nw=kxPCS)uvW-JJy-V@v>2u9S?- z7XXt=pk~pru*fgb(9;KcfB3MHU)&f`&8+#=AO0t#jRE~?$OCp?%}Pr;Td#v5wKuyu z(2~oBesU=IRq(g?`1q7$WH2B*Bm=G%gE(JYSa`h04b`gL_Lldv>FH_JOzZ!+owcN425MQqQUF<#TBv!!YY576NNQE;6+K>*`DtRb1bmZjE>@K0>nFZF8-R8 zO5nT$kb|w3P70{BW|dV4{9yo1fFqPsptm?ZQ{etLFUMJ9$t|B}ZN={CEpi6LE+Xn}&$VzrU zR)8MEzx(qsq2OB{WX+&j=)qB`wsx>^zJGU`0H#w0`TQZIYXMHuP)I8XU_nYe+#*mq z0^qPfZ@PUGi?jvlo2<2@zTK7Vpr(c%AeXyh0y(-1WCReO>1#8yvh?BkxV*T9v3tRn zhw+dX53$=xWj+UcVOd$(XT{vvjSZ$0iX*t<`T$2pYwWYf0!-Vs_xDBDh6{0UaIQc+ z0X7_qC`Bw_T=925{WVfmjhUyvDh)2=($Z4X@vn3c!*c)_L2dpqHueDS2M9F(2~vOp zK(qk$9rGACXny_1ljcz(DC|nI5Z2IOxd~eaHI*3J2wXEyl+Espj)P|A;_CVch%U4$ zXu(qoAJ@Q7^D4Hdwh1ye*fc+qqa#1}^z@A8{;n67fOwR7P>0IPn77W~F7ca?V3LZM z5aJ>(#I8x1bMgG4z~;x^UnYt9tr^a zb5KCB2?&f;2rb3*)^EuL8W27PrD-T0w+cYK#eT5elHke0U*23PLVnzo(wm6IM0i$X zgfnOk!x@z{6D;yQyO1^b+P7axdW7~!vAy}MYV4MhyUn#gTMmHC7z48kY*p<4tNtV? zu9^`>%PV@T*N_jo^4bS}u{pq2`G3DS*LF{d3~`0uy?WGdL2%CM&~4I&gEZUjUJc6_ zA$|Mp_QHSm@2v05m{eJUNKGR_gO4OhDwgp;ww4Fo(ysUck8b?QRoDVs>}o$9_7XOe z)jRNYzGfvh*8+0o{#)dG+2%?yI-#dw4_=73GAaAoVvH_Y@kQ+_WX@k;E{vk1{Ch5p z;JDmBResnj^VA|o;C32rVu@wN zXdWfI&{oBwGMdJwKRx-_7|NDiydUlA0rHzvXu&8fL&D~vnltOjovOu&m9s(TKTlX| zh!0uq2 z*xFfSw7oks4@zu#I+^8M1J6CwN>1T?OgrdV1GKh{HL-g zv|?=}mP=*X@u7i$OEXr6(9?`3Z%cgNu~K!s-bM`AJ_Vv;ozSMA;V8CID% z$RphySu&MLYW|oN^%5pH<@IY7b;nh2-b`1_9hJ$uc_jGTpr_(@*QKe1QAO>ag4#X5 zYCo$-p|8k8=!~W+=z=S57jj0c9liLSW!y&OV$5fN<&Yef*FBJ9^>2~1HY7({z$H`1 zS=K5!2QQ3iVP2<}WYd=Dg`}KBY1B-5rc=n2rem7eKPs>{j`@HW; z!^S_k&0#2MA9E`@n=XgQdKl>>;&P~PVTG4IsO8+o{O6Yzrkej}M_#}sU0>t?i6 zEAAX&oq=UoWJ2D6MjE>#Y4W`OpH^DE0&hblJ_EUZ;>p^FFD%CG0N~rwj%w}*5!Gra z`9(a9B=$P|(D~=GcSh{xrL`>b$AqITj6QqK#{|Wbd?rK`{B)sugnq64_>W~azBSlC zt%xU^6fq&WT~w0EF{o2p>bw+SBO?Ntc0ry)`Ffj#!s@~H4Yorc_rHgJ$PaCN(lEH~ zsx4W-ncg<{`VUoR+Pcc?)jDV${eUOWIFnn*4+FaiiB2x7EMU%rC z%myka4<)9UtA>eD6}RdVh5-pwm*zn_hv6Gk>~-LdVzBpRg%s2_mt)W56G=_|kQ(H{yEoM+4{!~#vv!<{ z9Ai)P@$;Cs=NN;VKeJbqcW6I2KeOcsrn6UF#4vb@Y}E}BqfABH9Y;f%WUcOo-P*9n zTqJ9J^>^VUT$pOjNCb2p*vDLVwSK?uF3Z%l3f6EZ8M-}){W_9wp~R+@q8(?qIVv3+ z?R~T>XK#-d)t@(`gj{C?zL>_%EF@`fISs+4#)BahjjzU{xa#(}J&DbPz3z|t_(Y{q ze9qdR{Iq5Phc-PH%7k1Cdq{tGCXhRoW9hzjlSF*ZT>b?4%!8Tx1`hrcN`2J`5cSWAMIb|$L= zQhX-y`CqE7aOq7z%7-r-B{AH|K^0!^O}hrp zfZ2tGYp@y67+L^12>tF|aUf8LGcrUR`8fcy^sis>;BO*b%A!{_-g|$0GQNCiS>+fU zWOQ~faI7+S2g!w34wqr|7HNF{?Blah|nNrl+cGDGcq7W8*YXP91eLem@v-1{d&uDg_A>-L6zbXPLpeIONOJm4$e`OQ5u zi}*!BiK03J?^lp&p=JQmGI{}CwbnI|@jnCjoks>ZSYd%0B;dV8tU!jpcT)u1d$Z-p zc51(TK?D3Ze*nWD+rUY#RTr~>#b|rfAS?|W-!9;f#(wya>14>fViauTo@YBR-U2;@ znI8Xu0AVn6AZi9;Y=U_N`1E;pXz_rVkQU5_VZdq0L7SUzD5a+%^oiN!6r2 z$-kxa=tM?4#d5ee$`xADs>M1X(3WDD)~&L72&Ue5-riSBE$gbQ-}$#Re?$hnz#xGQ zge*Glwb{@d^fd^1(pFg|##8P3eta&{PUZ zaDj8Cm}aJ>{S3NbKS&1w{xHs?wGTrik}|dkV}wpRA*MA@EVx9JC*Y?`1Mgp?F*O+N zYdrrZJLAnDBNNokHO^ZpU10Y0M0*D$Vx?k4C*#MD=R4ED#*hh?sN`f>&|b3PFygyj zfCmim-ykN z4n{!v2x)AF#|v2YywkP$;FqF1z#5nq`Dywn0h~hM3?6_egVuL2syCWJ%@h=MFgV~f zufwdGin1~x<{tEG>Xxg3pHSbi1>4@DX8w>OY%$(~2h!j1b%gPO4o5KJ~@%(wu1q=6Br5TK;oO}w6 zV8qz~89=?kt)eBkxCca}Qn0z8SS*Zd!N(5MEG=u$(n3_7K+l8UGAMZs4Z5+U*6oWj zqfT=4tBA(~gOKGJfesjBkS>f)gPR`M54ZRBn&EW%N)2AXJY6~%?w~D+_@%@%guyBd z?aHet9*+|aFkC$Lt$<;t{PuS9+hy;^rUqr4rbfLSWq+RNjTqTGc(mzcIi3H*{Ze&S znl-QswxR{dmoYVJ%F5p$i5v5#@;N_&89IT!bwTi`fehuBuJlTrLIJdIl3BAS;4+u?#v;IvD=%g*(Lj0m0o2nBzV63M$~D z0XyKt{~O`Hq*(=a3bvCcpnjIqKLq)V1DboS?wWozH5r!2u56YD@xi4cHWw~oF zV@~i1R16VwM}a`3uHv<(tgBaPmb$OMTuQ*ezXX zII#gJE{m(HQlJ(S2<^=WF%uP9!ZAHZ`ud=3fkZu+CUSE}2WIeU>gu%i1@@aqQZ3|h z6^CvQM8!`L%n^5DsV-Nf#*E8^)g14~vJQ(*`ij_P#c`NLbZk$%EMNvTkAtP|U~6VZ z{}SZ)#kDmHj!jV313dM%p0_C0m4W50^|_L|x&#>W0)5Pmx97@ioYqJ6Y~S5czL2*ObYZ%jf%f!;m2{BaUL{Qgx{|S zCp(O(&FZq?6I41CUglmlr+5Pu;cNAiQP_qt4lrj;&2Klt@D4m|MC(OJp}heP;OABR0oOTcya+-G`1d-AT)5^yh_=`wMKUjShqsGUI{J zVun_&=Hd}dO*TWg=?$m$*V-FcPSxT=>MZ|RoLli11#^6XU}4%xFsb1t55}i}tTdK% z9R-eBA5iN?P1OOtRPaoL&l6ShGL0E_Z85Btp6OL4S#m^#1;|)P_cuITk3&XFjb|z9 zjjVyBm{wx;cg~g+3&%$d8uM8Nw7wS(R-Etkj(vBQt;t2jx$xMI1c%vNwqJ`KanHQj}2P+LG5plP6Jy3APgqAHD;Q zY1V=Pg-D<1Osfu1O^vRLuRMDX)|G_9Wytn#6yCqRJU?nRk=dZl?g1Z?OydjCv>0#u z`I~|%VBQ{TeAE;aC32|A<}ktN0sZ8tl$4iH1?JCT3P}@MnwVghDJu;v#H$sEF^|t* z#-yQA`J+uj#k|f`sk(eJ1E^2(Om~EZow2H-uq*mkO6JTIf!V>%j>0Q?J}_G*HhR5& z{aN1wnIpVBZWm(AtMj}(cP`(t9RDi0i;*}fj14C>0r%&%d z*E4|50WxBZGz99mf82qx-U5E+_b}zV0D?HQ7%O-lw)OUyD7ji$NPG`AGhHf@#jVpz z_}MLjT_G&nn0iq);9-zi>X2zCuib??Gidyjn-Zq1W3~WeHDSG?lkgN%$bfbe7z_f-| zmtd6W01pJUes$BwQjdiL)~Z7il$faK&y)p?O-!`RX;%e>@UAzIwv59BRLt?|-}L0o z{7??mrAvWEOrn72VE-*!DW*w)V8~oAOwzSM`=NC~UP)1r1xlO7D9j&zLk2?1jHG4a z*{%aV2W1+3vxG2F4t}a&niQ8G>HD<8Hv|;&{^;-Dum~txQf?-~#NQv3Vq-Qdi2L&F3LG5RUtnof zW6l9VK^ah7`(YYs86H5?!7FG2{#y~?G*zL6Fg7hY`8&h|3?&Ac@&+%jvZCU1u+6KS zJn9p8)|R%Y%a&>K1;tu5Ru;QgnHJN&?+U;nq^&($w`FmIV%P$WNIsZzy|RY>*d zkuU*#aGjwQbN#mWSjj$jRNwmq2@dJ0NKm0A4|g0-E7o8%FhWe|S@XgbOek`i;HK;_ zi8_X6Ue|>>L<^HUG(2^eka?*5J!Ew$o+oCSbxur(58B@!M$^q;WPcw<<%2LkLf-8I zPj>5LT&P41;F*9`OO;1%XshPY^LI`Ox*F$i=baSLvDa1T4LXQyBA(hoTtGEWNe-ax zhqOYYCaiNc4+eIBPJ$W6iY;k$RDFycdM!qg?jqlN7d>FsVT>{uW*Fj=(ec4{J@FYn z#54Tg0Jrn$>1k(5M^{&rKsf;0@~kFk0ZJ@oeckb{xkV)f0R1N7BPVrVXKiV3Hvmo# zEsqu@IRPJl<1ht-4_FEryF}*A0iFf+tXgk=W2p!z>>5(`d4#ezc9L!`p>ABY`P==l z!%;_v6z1C)Y{Ap;uH622*L}6|$zQ!pOiY;ImgRa7I!F2lx-)Hw){Px}t(<88zn2&= z0Yj2T7g3WK3Pg9f&*pS$9VC;+ZlU0TVb$>VkN63=kFsqWOH01C3vH5<;7&C(laiBb z2eKyXYZMCO2}r;rW)+@c#PsP6FpR6B1Xn0EFd&B{J0*cWOGLG73cm(H3{}hx>9HoSrY~t3eWqX% zeg`q%vDlEuMV{BskXKB&HbBHge(B^{k7HG*Cj^?FPoT2rB88H5f|-DuDvt zDgsOY-0$&Bn|h_iCM13CM83J{-QeI4sfNwhqaUW4yoA8$`q;L7Q1lJYowt8}MMIwp zzc@f*cz}CSD8=8<=MeBxVELva*uMzDmK0qLg9@F8uWmAybHH5F)&xudgHD4?hYq-} z4${F(N=l{l){dlzYwfBI+?IX)nRa`|?Q&*VN`2V4@x>jRiwg=`F3)E!B`1Li`N8H( zbWI|K4bSf=%5<`t6>;K#Tbu%P4oFMQFc?l5sOC5K=n3S%V~~TW8umf95EU1fI=kil zPEE)4I$~}al^?BqLkxq#t!@5ARz;<^P$%<0BRxp8Rf}HH#q;m1m-i?_>T`M1F>ap> z*iDi;ijb5zr|Iw&4Ky(;Tja#WZ=8cc^oRzsjU^b0-~bOSP&=k*vGkkB4SCAUFgqizsQZxD!5`Ht&D=m4Kj{uL$1o~I z1>SZdUhuiVANg-?S=In%y$$Eu4Cs;*M&)2A<$Stg8bs)<9_m$S6j@gr|HT1}pZ#NGdf6EDSF;5bPJd z$RMg0Xf+)6OERVW$mH_9ZVzl1%od&G)&>` z1qsWQ$cs95lrw{gRoe=BEleuywZq4i8;5;!FPWmw2(4%=7+B9XId?oy{_+Ajm51nV zb%)Zy;k2%P0_STA(fbvw)ox(hHU-4T@%kIeZ7JTw6viev%=#&bpm_c}J;g;{Nl;2? z3|0VOUkr^C@csx}*BF3*vmgAzts5nJ$9fpiwR06|%XMp~j&^qUj&O&YthdPIMUZ+iR_p;< zPFcf8XuF#!sKZ_T#D4_jupf{-tqyUKz=&j%=Q(8$0GnX&?kodjy>|qj@jIKfsrWc>#r>n7yE8wXWZ}@le1m3Y-GVa7j3fe&NA8S99viqM~Ss+XRIKg&9~^!EjGAmSha?c8G8RrO`zPyzJl{G)o6axC!7^fU6R)GW6zZI0$fXEF1}H!?b3q%fIwEJ|gg> zfqGXa_tki9*LX7j6Yn-qe&9Uaax?5Wn`NLpEyc@un{|%(Y?P=>`Ub z{;v8l5l$ZvR1;fufUX3or?A$J_VyS3r&~a2`b@yL!(gTkzJJN3cJ6{1AK zz#DvHCcKWO7hW?&eybe#cEmQ!w70keQdX0Rh4BEf7cY=~gtu)VHW$k5ypMowEU^^y_+^iy_b*)G!5eb9yj<^uyZ|5Z5`pgy?OP{oy59(f_0AJHWYa+y12` zGAfc;C?O(ymMB6=R5DA+-XklO%!;ByWn_e8mOTp**(6&wMP@=8|Ic;5&;K~y=RJ=5 zzRUQ1zt?%4=VzU+ew%XTt78R?OE1V9VJ@;*Eo*M}h z2!k3-0$PuAxX$6`caM`NgIn!W&!-VtF|i}Q`?DhmG|5#bkEelwo53CUW42&A=2tM_ zNrM~EzobNt_3=;d&-qr?H$G$DI02AL6`ys{Tm$yeCak<*+#R^-SE`F$8P&1-g z6c&N;wXei2OWkDM#{)-PR(Yl8PTCv1FlsT_m#Cd;YV9($BmdXuUqheHuD1HaFl1U^ zW3$?C%Vd16y#<1PNSwK#-9R)Lid8kPNC(*Dz(rHtrhpm{*b^6;Jftl#)5 zK5pn(3I($%zX@gQ+Z$1b+C#?xEo z-S||-lXuA@_Qu1^ubHoqA5}2$s$ife2<7+LAEUybh9_KIB>)=SLsJ}&shmV+5%Xv; zj$7_y9<&JrSNl8v;3i3wfupVpg}V6~Cow}2F$$2z%d=tnUVn*z4>40p4>%R(FnL~q zUW|xW;8*mlkpWwN?%jIQg>|f@a|!N0F6NkUS-5wEm-;^Wu(F%St9O6z8>4Jdv}@QTz{8R|f(a}<0Wa7t2tfiLU^ z=B|iXj^3RFX@P=&TZU1A-v@D*gD11-=l(qC>c`x*83O1%e%YMOlZI_Ucz~i{G(c08> zFYcOFWPY&AyE6biK1!z0vC*xiu0QTtP5!)M{}f&I9=yKh&9T)WmyiQ>(8CDwxtX{B zZV+kNg<=U>$6?{|p`m|DGle5`1XxHHr4Y|o zLy_NRR4;T7?9{@wE2gr7xTGjrUS2w;s+yRYsoBOA0W^{kX>B{983hRFs}%nZr8Zsm zQ`^*1%hb}#SFe<8Z8NG|`vC6aO;U1j5NUdTkDxh z)_b0g3>P^)@WV(eQMxl+4@b8SJ=Y1m3e$Iw@bLu^cLo;(uM zTPxo{PEAvD+~X=*k}5z2(>I79@Mu=&V(b`H)aSjoib0%52tb@Nq7i(Rmgb1I7J7XW zhoB`8jvrGMIRm#;X4UX7h%WEkxo{)plTEigG|h|dxo)c5b|7>7o9!3>MDfUpTtBe8 zxMsIOO$>wOm*iCLgZOK^fOZ1{3dVbrfTFTfL6kD&dl&k+Zf6wJPoFfNs(B=Zz4Rks=uv=O-t5uTc#|jelmM-UviH7(?D06C}+q(q|8 z0FcC&my`27)PED8fF#uI8(=?pkBkCR38LEH;x=pcHgR_^RBmo7_x4Ihl$3&QT8BHV z?{hF4>orz+FZTxmvJupK^L~1X_t6$u@0tC<*_$Ai5($>?P-4Gn4R|xzuWX9mBKBvf zzS*|XjvIFjvExYE4+#F^MByq?(;^3$o137~aKxgSxP(4V8o{7mfAGmVj@E7?!EQvP zDU=Kq{0EIJ3{k{cR_(^Ml<6YNAtzB28XJ2bX!U$0$`0V_#Qy6wDk3<;~aOD0Viqs>LS7#Vk2jC@ghBR-NnVS zXLWT)U|vo54c-uh;hbcg=m-3BSaftSy7XA)0n8p-SwuGwMi-<#$}m`PM;LL4TNi{T zpO8>B91V(8M`0MnPm%35Yn-FAA3aC-2liq{Lu+;Wm23m(&tG5pF#Hd8>8@;&{4`s- zNC(G~Bcdis(z(Lb_n|8ZxcO)5qNL^hN@H96e(XCZksb7qvXkT`5QVRY^TnTS;K(0G zM)sPva5LlV?(eCtJ6G#*qrcmE^49Oz)~6RdReURM;YHnzCbbf1O84CV9MRDKR*)ep z(H#|=V1|%*inz@flHkT^d-9zRfwkMae}7bmldCKT$rHud%kM7&mKPQt?hlV&OXfr! zUQNiZQO28%7i)PQkbsk&Qy&Rg=`^N3Fxw}IW|$6weLjBvZ7iQ&ofUAI`b-Po%|u=l z@=Sqk+}2FN@rHo>>LV3O+D*Qvu1OG=saaEW9Zi(HhbXz5qa>?_7ci?Yj@}CeR!Mnl z>v)(T$G{siZ&+zf5%y7Cy7)wT8Y1)e=0=LBSJ3jITAHYSbU=~EA_XAfOpaR^(Ms5$T~srWMgO%RyZGM2_8 zzQ!H(70kafPFH3uT%3g?yqAlsV%QtzDb}wL7YN7VJ$ncq0q^XK9^Dy7;NGhZ@ljP4 z;%|0lRW3bnN0w~{s~PpmoYae5?iWlZyswBt*@)&!b#-@J8e=mQ#^H$1Qc(FNmlndI*RwEqVtlR z9^dmiYjL+V4!lK}nW#;d$WQsbd;O++3!3B2qZGU(XXSZ#l-rc|E)(d`z>! z+4+|Mzw`y&l|e#a9q5+|8UttxloM(4*%24Sjk|$M-F=&3$|k4EzGtd&j#)-P89QW` zfUA)}JltUJLrNob{7=Hy8L|uU#AtqC+lTKUTJo96B63Z%2h3XkJI97fn_*0K9&)@c)~WyByFS(Pqm(5 z^R0L%R}cYX86&&2!!73XhK4rF0viqL>g%g;9}k_QSri# zeFdEQX7%Z=CrS2w6Erk5IRY(UQI6BS>dCjA3JuE?Yn@suT?D9qul^rS%rTF@5EixK zc8(l<@HMFJ2AvVL3fq|Hlf}It<`dL+<3;a9UAJ!#wFyuDnSXUT2HtMPi&nKWDbs!FX2S+@l%hVT3rL<;xkEdeVB%U&-Y2 za-hSi0}goi8Ag7X==@;rFz$l>1(z};fkDVV!o^c#S^j%*VPS5jWY#l9(fks7i+fKH zFVgrhIE?zk8~8DOk9eR;;x?hxH&?s#SEkV~(b?`o{sb56_M8`g0s{i>vIdgz3`I$@ z$R|mh_9BzJ)8vbiC;*Q{UgJxD_)--hSYmy~j5Q3XgSlUsiew&OvZF3Det?MX1auVX zl6pw$!1Q(r)6KL3ri0RL5(g`nCKMANr2?_+`6G|-Ax|qIBh$^bUl(9C_j8W>ZRiU6 z&>y`_O|8Jy{2G{A;D{B%YpWY$>DZ-j;nlrYd5U+(t5>fGcwlO7jx0sxtj-b4L39OA zQJn%RF1h8rg@4F%uk7tv6qGtkr0`YXjNf>u8j5Nas5 z`8mU6?C&`_*KdB9VdpAI&{N)mI+sML?L9^Nj{|)X*<-$k-RJh;86VTxh=I|lAhp9P z?D=#0M|FNZJ^IMFsTff?IB-8D<*A{+u-kb*k!DCX195+A&<*kK-+yoGn?hjZ+0@4Y zWgryOU${&7o=ZFbp-#%c|IP9;3YA3OJNDBh2k?gJXbcQox5;&c-Em0mDs3R=~UJD5HS zLwIlNb??iUxk*QNZ}~f+#2+Qg2{0D*#25V?zb{NvI{qSleMmDK z8ygK?3hPOXtM^G3SBTVrqJ_oF(J~YSz*nF`_xO?21)vmW?L;_%%l!bgE*~SFTA)Ry zJg{l06#E0<*a_j&?VP7?+ddgRX9UI85O~gODb4?-N+PhLG@ImJ;;AAxDxfj*;*Rax z-6v35x%V|~$LL&%3o9P|0%i|zw@1@Dh)NeNl~h_N(w|sit~-9}R7m&zaAc1`i+0GQ zas$O--WG-UJW_(7gf(lfs;smb(DJ``wu%X;&!VO&4J>4INzajmucv0q-;4tVB#>Yi zxNNqq>h5%c;X6NZJ3v9J2ENbRe#tL0J$n?;gxh8_MXCKBTutbsF(%6=N^(_tzU!}R z;Pm`4S+VvPGXy@;>1Xv<@z~_Ypt{z`?Y_&vPkVUZzUo)ktnTB63}awNqzaO??Q{*= zVHFN*UcxbpouxJ4@*BjbXY--%lE@%Z-u)2Rf`Mi4mwtRW^XPdl0}X!YXol<(Q_NZ!~d&dapz^2@Fg>f z1mRReSUIHNm)&Bc#Iz4y@?JMoBUt{!W*p|@O%$;vLOC5NX(m0yJ+~nK1E+WdB;vJ# zeW=5w9J|+j<#Oi&LQH->cau|&OBvd!?p4E3p5v%)o<7gc={d<|(^nYAoZM;=E!wDu zm^mn%29fdi4!{H&3HQvLb#cgA1VUgIvks(_3AqC;)-z3>f@a$|SJmCvI953}9NJD> zN25f>;0hLI)gy>qs+WU*mD&5!XOX8TiA|hPDc4wseKvExgQ`yiL2@}&KG2_scL;It zH*Ox{oGYgjJ69cZzq8-;poS<3WYOC2;UT#(Z8NJi*yoqxprW?R`Pr_OC7pYY6U&%JomJGbJ&T^BuYuhcFt~pzmn`CXs8^ zq3$BYwE+h+C^*M3fVkmLexDh;7wPX}I%@MR+iSjEe{xp;XC})=);x=uUpjG)H$FVw zWKDDe=pW8pxDbTND(D6X;1^Xhbi*3A`y*qkSsQXhC57=iT)o+wV@{9p9C};ZoVfgy z>B63(ic6t}zpU&xmp~kyVAQvDlW%p|o`x`(Frhr`^4?8RcR#4CeqG>JmfKKFw=$Fo zwQs%;42+}@8vg~te+NNUCs^nF0|H2|P@WcF5(T($F1-c0e;jWZGQorny*SN~=U=J=U~OKtNqw{pf4jnN7O}G@V(@%r9+C0uLL4a`Jk14xIy` zok`#k_=#@D$fD)hi3xMZN#l&2y(-TYymlfY?R8-oO(X`P%XniFt~Eq78vXDrdzpdm z(fLH$rWfDocU37HAYN3;^XD}G!n4g6&gbGXj2cb8hGCf~dm%CI%End<#oW7h<1rxu zu^1csu-`z-P25KNMl*-&d-PQ%9n@#brF{*#Q})*EkUTjD&}^Wi|pD8cf#G#>}(;)Z=IN%h^& z4|w58EHnT;v>UH2uSZA{-2_1D`Q^9&I0y|oy;pA-<5e|W*KllW_c|7SUI*nJa1it<2KYCq_N>Yk8#smn~9=}0|xJ~nh5#~jHK->UTQ2CP3 zNuK@tKcs(7@0@ByxbBZ{9W)A_KPb31c$RSj2)NQKz+XQPDL-*<rOCV`h?&GNobNN`I_Us&)& z&s8#0OoJ)88pz&VOtqKbc&1=gJ%?*B5Ips>r6l3pp>JKU6YVpU-S%rc^WQ&c&Tw9& z%-FuYh45e&A*L8+9RRncEhCJ970vQPIetJrcY=@Z!s~Mgm;($Wky7HOG(e${xcUx_ zvd1diCn?_-xK0mM8Qq)yP8l|JAz6liw!cwicS$?!As8p%O?p2D60L^xD}+5B1=b^i z{Nd00CIKJ#0LdfWB9i*>g*Vf&53a^v^2^M-_7xyr4Kl~w1}yq9LxYM90SV8p5h3W) zYHF8uu5D3S~@!Gv4RF5{hjjz7xYgz8a8>G`f@2)F)3jQQ28+mf^`m&!3s+^s}1h$ab@eCquddi&6Q8WEu% zIK6@?_F#fauqNj^$MW#%=pzy~X-d#E@Odxr$R)#FfuibxqUlCO+CoonUWHjz9iI-& zP<|h#LZx;$$T_%{73`yLy1vt(e7!xv)Uq0Y&U#>0s6~OQMF{!CWAo=I0;||Wb#NTYzAL}XVs@@B99XjQd2EiNO&LXbI>F|&gF(?dKi;v)xGGqdCa87osC zqOlwyG%#wLBZ^%jF0~ctQrH(#>_m38AZMx}TBexP=f(YyqWZH*7N*PufizXw1 ztgYwHom+t@C-mXN;TFl);GEqdu{i{B%yp!oxWi*3c>fi~e=;#F+d$e-t}r_DD&W+| zSr6cIP(+xz86u}FVb#iD5p$tRFgBQ&hODAX8peS;1`-qCxR!yzJ$y=Y?8otyOul_e zMaYfJ>;M8wpe^p)9>Z`Oe!QF+mMd4T5MO~`U|^2d8?aA=P-N8mM}pTOr(A)Y@(_fs zQL&MipN@}OrGM?DM;WdI3* zU?*DH7&^=pWa|yO%-`Y0Jz!v00IC-v9?L}ZDZ~N(P;4+07J4LCoR-j|;Qq*Zj1#9$ zRRiI9jVL)n{Q|u`4qeuo_peo~)8MAWe^N!!LjJHHQpeKu^QiG}3hLsU(KffB1vU0a z!6GXk71#c$ua$pZ(DN-&uJ!a3+TK1MAQnUrR%Jb!onr>`!soNOQPnBa(Ndq@O%ru1NSkwUYB^Veqdw8)a$Z5-?okq;nQ ztd%s+h}Z@x3Hp+jmKL=7J8;>K$Q&k@E8;k_d-*Tm0;wImPwldqFwR=q+LdgVQ4{2> zsZ8i^uJwL#pBD-5{`~zoXgp$^+7+Tgj`(y9AG(uWpexA3BU}!0yZxcZKqED)3<_Mt z*kg<-XG{`j6Q&ssXxoVu^4jcxZC(X3kub-h+Z$XLyz3ApfNBL}ukR8BV@NiC(M6{_ zl}Kqc&}Cp8`|ahK(#_AACvPntA)5U}bcWMK7!#1qG24=#M4nZN%z6q`yMUC{UiB>F zGEz4D{QR=lLafDE$#0Jbk0y%HO!KJmbK`v}r=n_l83r+AKT+_?@A!cZE8($=?^{w`ISyc#Mzs5f#bp4uhJJZk6#;4z@Y#;G8z38@>Y>@ad5?{N{ zdMW(%+2v2{Z{`e47TVd%g{|8;o3?)|*EVKc9TYo%;zw1S`+B8QJ$(`l7f-YJZCM=G zXfjGSNfmNbm8;6&VZ5ub@+q_=??GdC)m8jM7f+r?a;4}SYa;B6v)9buU zR>8Pzy5-E5r!rN?%s-rp@49!|ax(uqRqoM*LK^3#;BCX|N!k%rQ;fZi0VdI({xRO= zS$Q0w8DG26`Pt4+w%7t{r&mX1=}q+7-Xw`{eBRb#Ngp|^Ca9O~d{gY{N#g?z>wd*- zQC*Eb!`WDNlD{cl&ua2hPt5R1L77WK`k7u%EYHN^zcl`HFq2cN4{tkrT|F*pN=Cz* z4#k>-g~J)X@gF@xg+EaQidjQmdFA8YNae>5zQKdZ4?nm_)+=f(*})$H+8 zCo|bzO5fEALL0R@q(f;m`Ks-i*|CWXzMqvw<@=V{7CU<-oHV+I&7NLn%cV__-tk=Y z?g;l-oU-)uI@(07bd&ne$+wpEvwGJvjfY5IDU6QTSFMNN_MqQX^23tujVhn%Xv4)@+T!n-0q#ngELg@gZD5WG|HLiW6h^NVGEzdRyCwWjW zTG;DX##^SYjQ;(jR%T!)BV%=hYk4BsefQb8f6TueCG2gsjelmfb#`>9@?X2tD|=lq z`1C91ch%ul&G)Y#(2m(`QeL=rPlGGTl4fI?%=a(ns^(m3W4QOfRQxCWW5lZbM44A| zyqRBc%2a^DlFmy@8acXgKW<-%3IW##h78mfGMS|`#x7~D7(_k1^zmcZ^^bX5`3Gp2 zCja^0xYWqZ|2?erg?GhrvDo}R4Ofk>9!@PE&9EJ3n&DAUmJ-29In$xZ)?q$ z`OaLS`V3$Go_!4*9mQyUs~_RdTIN$t1hF(m)8*(G(snfQXWpWAq5GMso8&G$J|Nc7 zz@J$Y)w4@=@!P59Nsa&h{0Tit9lmmEG0N(t)Jrq6<5`L7_w&U0GJQPnCW_1XZBlco z;#7C8c&4*EUU|7=ae0$`=E=?3|JJq@cO-pz?i_!9hVi-T ztD!gzM*i|!Emr+Tlx;l`Z$8gl*?J~bqSQH_wV1_XwpA()d3H|KJ-jmceY0OBU!_*f zYJdLGx8lb}`*ba&jjE%iQBgwriyyV~-RMjCtrDGI#RCof^mG;!sfN4*8=BldZ;)G# zHqfkWy*vK$j}C1=rPHbfUz2aS&RxUoYQ=_V#fJtQcHctZ9tatG_NZ(t)1;Y&X81c@ z%e(7Y1Xjvu>~mwyzVS%C)vmcbpv@f9Vb+syPUHJId)rx0d;Sl}ijf&ledvn3q{h>G zzHb}Xp8e9vw!!W442J}Bq3fBC`_c-waLq8d>nt=(U*j9gqYKU4-`5njuQRXw;2`d_ z_3-6-v&`zp+~^yQ6jP{?5W$z^kvrGe$hA(MPhvBjUuCYqrhG*0aOkM*|17*b~dip zr=WavJeY?z>A-+khFnOYzJue&Annv2)IOS10p=mB8LpD0U;817lbailHE>p1xj(t~ zka@;^_kc)W(M9EnR(?7e=j~!EjqffI7Zsqa#QtE?RSnke&O<R^e(=*$+WHoWZwtpizVmOp9=hhH=3nGZC1G}Ye4U7JZ4qnP{;543EgXK1*D18( zx%QXFSNsT&_vCS!wP;_SkyeVIx#RSB!ImqWd1ygx=1*pT)#RyLH=-AmnqogRc>iFW zsB~pTH4w3vRXU}&LR&W$HT?N#{0=rSua=A`NPZ~hUY4=rw{euc{9rCl zdbe}CjrLSs(uVT9w}#PrHyck?NnHId$26%~soxwrtRG$Wx37CP%<50(hwiJ^sb})W z3u}9250>A~lf9%iD0hHXHSCp+_BG0gYr!ulV}_ljl^u$eq%Z8CEWe-TAFVZYIscQ( z~Qot!KM+5;cBm@@V_am_7+OR`|YxIonkF@(in6h@rIepQ5xpOHu|j zo&^g@FT_r2pPzmIEPFX(S$$(M&85#T*VL>+tp2KDBmn<>a_i-@W?7-*a$l z-#NPAeQ)IEBUGMW-tFZ5T>CpC)8xTQHriVaCboKk=uz(Ev^gIyFA6E+nO{?%XbBe? zs|pVF5T!>s*_L1L#~{#RbVry~Nv20_=-|e6qy2M50uPjwnGHtVem-P5J@j$*sMX(6 zeuI=AgXXe7{aU3vUd5NNT-^5Ue$yE-S{}ERcDC^shB3lkBNLehu4V&$dQwJDBXZt~ zd8u}d>ObIbr1|!%95$>UrQQ+?} z=U>eKo?~&M{DK|hEP6DlOLnK?rP@E4Z;QAi7P(pC++fkLf{ZmkhqJWC%e9AQmX>)N z{oB~%DEm)IYp^YeH#HqeRFgQDE$tlJ%~AC||Ak3vdW_H~%QD6f=C=Hggk1yp%GWVX z+W9$7&NkleXA0R>aPpbHWD|pCrn^+7Q;r0!8#UO|p}R`K6!T-)!8_e_+BsOlcjyzEEG1n$wQy`%V3_a`g9iHFn>YW3QLiDeM-T_&%9a zmqAy&U4w)2)vC@Yt{vmsVx=#OC{If{WQq(f_#F)wTeN%78l^BVxzWw_ue{N2e#X;E z8;h9-)opWAYvb23u{PGVE~N=YtT^#$SWDN7#fS|p-fz_S|5|_=p%i;xB}b{VabDY; ztaC>tt=_p@kB&c8OzGCxSlp(ld4E$>Q^TXAF~5P9p#*XJmx{}xyKK*$1w=+z-&2G*i zqocQEBHuBpJKv^u*{yW&@8DSI<{~cko!252M`d}PuIcB?DmX3W-ahcVNr!I$@6_SD zDQx@fvxBbfSK9q!=45Bbd~chN^O%^k+}5ValhpMM2H)BF8tDaEycuM+=*Sdj=55qv zb1agj<-Oq+UXtW?(x1zJm=izonbF+R6Pbs<3Ju*~wRIcJ%oR);v7^;JxD@-}XT2uv zv^~M;>Bur;>~`^)$-YDLQO>keLbHZeg)vI=JMje^M_*=$>&7=pXg(V8a@;gNkRfFg zqn@&rZ-9QT1#g9&aku-!*!>=CxJ?i%vPt(Zw+%6HmQtKbUK_q=;0*MI3&|3 z^k}hWc{;=+*_{s18{(M(UvWeI4A{i8Y+!nc&<#MYqoX#b)To3>IPLg$OMY=w;90%1 zC{^U6B35%dhpOLS`Uak6_yq)zC1!bfc`q|F1L{mK(+2>58wR@PV0oBuXiyEmo`449 zJpj+?HgSIdM#In?et`LH8wUq1g|yoYJ7Sdg73U*l3OGE)El5)UXzYPLUP=^zhG;2J zH@bYzLk27VDLT;2fGSnl= z@8jjgTCf*$l~|QL{CR=!aZtkYeuf8R7mK9LuI@Ki?{!!MQtx>z?@|7+rOG)lnpN-_ z^B38^eJw@v2g21;%A5sSR#ky#f8Q<%AILS!8^tbPxv4=9zU=+TgT2sa&z;j_Yy!qz ziftFiGS2Uyc#)g?X?O{Un9Iv1en#r;SXw?A>LnH^mp*wgaDV=2b$czp@Bp==@1bN7 zTGjT%oih=2SR#r69<~*M)ek3su^NAFKwiY)Ui_w|YH_oh1&Tqj?ca9& z*ikLs*c(zmvj4_LFEydC9fpgH=#tz`Zm!l}3<9yB`o#-82W&AW51^Va7WxD2{ZpoK zsB-!oKX4GiWub2ZM|9Kv|GVWODEHU$B$JMsS>d%#42c(U+L|H3LL$Cu~WCIN}q7{(A$Uo+3 zZigK!=ivQymteW6ZEl|MFZu<&~~IZ z=gPZQR3w?KWFZr@?V4y~M|X1aI`QU(Sp;h#wxE(GXK%x^^?=Ex)_M`Ba|k9g<1VOT z<`7T3-XdKYAk?dyo02mfdoS1(MJ>)NX7uszJfu4m^p3iZW#@wS`7u9+fz5*l`(k1< zwCcSMH?cRqKAV5i+um*rtGNR3X8j~fs7a2(X6L;j;JvUr4Z^$&=0bq%U#6ugLuUw+ z#uK1+0EY9S2h#Ll5rPy5UfjVt&NR3$y?{SH~lR*KH!NK-Ea0m zLyxx+E2{i{{qh6?d^Ghek)3ow3y}6l$4B!ujmbzIhv=}?)X(c85i@55!sTamW-8k? zRvNepey?o*{4wIIVUJTr8k8(lTec9^6hU{DRaNnD+;7|F16?G5Md&18fc`JC*%7#M z$uQP-Ldd?pWhEG4Eu~+O)D}$igrIC5E<1m&+C| z*bhJ)BUUCs6bQaQEczgNMc_4t=M)0L#NuLBEV_#vK=hU4kI6Fx+6NayFkO=HMNC_W z?|X;9kJq-nl3-CF1Y`$6>Dy`nkP7;>^~Trdj~oAr5dVR4IKQD7{}SXCiDd=`ybimI zj)Hf@-kS%|+rmd;h#wZB*kfnUGG4xNg(x-%q)bHGW@fwwys)}}AxjY7f9jdvlP6F9 z8EMdaijRqybJ(XHiup8q%INlJu=#>Z(X;wTatq@^HHh+bDwsIz7I_M~G)p`mwUa0J zBC$%ce+L7DBGJpgL8uv7B@;E{@n@+M#vvYvPxc}?V{*x}RRRv9KSu7T$)Q;AG@p6; z#EHRb7W_?!fV;n7m+J}0+0-;N#G#YR? z)xGxA*90+2ehf;8W;g-6oE{=Q2+tYRYOxmu7$2q2$r#yie1IT0PkAUtE(`Tgs}HQk~vuPiw~PvpMIIE_-NojBnjeIGix zH&~M-digz7T4z&~RF>LmV`C#z#`3-vnPoZM^&q+_i@;^Tf z;7(8n5?=>CTSesoXCw6-e(^_09eRU%Fo!aRu1F`ET1>u);|3OP+1YWb#cLJXLNIwW zypJ~SS+8LxW0R-q{m1(ptD-%T_JR1$XX55amI(RZ;ts6z;=Zx=U8-)12!-Dk0j>uz z()rC5lqGmuV(;m&{_`6I{t%cYaj)+nIv#*9Cf2Qe`}UDkbIlauxPhPhwRPvgzEY1J z;L$~}dx8q;UA!K57V_~fu^+y^3+zE8`|ze)*kqh5dmmNy^|2R8QK`ED z5%qdRbMh}mv&%a}p-+p8i?0F0|1?bNprnATGp=(AEx|@G|4=sJ<&A?F4snzfkYfC3l%Yh z5jqsYC1R&UV^IZd$SrW~i-w;mLk^mL2w@9E$tQVph1XX_*9?vxT}MJS@NyAx=`JZd zcCtnammFCog7a`CO99JApaKnsDt>-=H~s*{I}35BMPCnfbaY_%g(|4QLonHsOekn6 zh&&nu4S4%?N!oYdj2wn=p&BWrbJ$Atzle@2BaUCQw<%0kC|uY~^$#MpfRY3BKgT;C zRWU&^eZ?Mix)lA=4pX7$;Qm%yqOk=sIXrd4+KZK1R=CUBH74bZcGP^qH zOJ9qWo#U~6NUS>wkGhSz0dxm2VTUv0<&oab&TixU_o<1i-LB4lOXzXx5a_6eir+YX z)Iy9` ze`HTMq+~l>)1MJNyTfV{mm96ynAoAOb?4&bti|I~oA-a9Bf$mO_&c=a6JjUA2v08A ze*|pfb~d(pnjGCY4VL%o_TUBYm_HFn{G$h!()=9UFWPl)L_0nA}o5M*}t|TD2)Gr%ws4WSWuWC2Y45N z!`(AICUp2PC(>T7HZOT9fLxsZ==(`-esNLx)G1orA=7v79lelG^bxM#3?HlSBPk}O zIG_~oa@4Zl<9Qu3iD3WeaOmmD3vW#C@Rh=fZWc0)TW{Y83*rwXZMrBP)oln-;Sp%Z z2nD6nx|P|rJpMq&yUfZPZag%4O1BvK^_T;_`TJ&xU8C2yqkTjU4=vWx+Lez!Ry8l1 zO~yODZ$WFE58`1Gw`jC{!rK`Kl>38NKKHpy+|crg5?mwz2+M!EoQT|=KLfU?dzCLX z$QE2@A--)0H@aMoTq<9`f>LIJ4zyInBruq50?p#faJlM&`Nt9b;mK!t>`xCgY@s$+ zNR*&8nqe*B@vwe1n3wBW#W9xDVMTb;RFAX{tAU3Fu)h;t+A12XC=n(4yH0m)0}Y)g za}i6;3o!u*pN!X%PJg;y5$jAyu7_g)iYsK-#3KxCJC3`xLM)t`sGdYGKtXifQEff1 zuLSa)RNv#A@rh-p;DtRbDKb6>&uvCYtM_t4meetr<6r93yw}5R1!XXZiFu<@-divH z5|iZBX$z#p#e;@j0wnqNl^TWJ7jvvxv;F3*=Nb5UAWH$gAdzchVJD=Xq&!>Yq5YOf z^H`p2^^Lryug^+$^rTr5Q8Bu*gdbB=Q?^a^WI-~Yp|p{yFh1!ngu=oXOG>}|j}~R( zb3>IP(lIzvVfZD+QWz@9T++iqxKZFy%Sk~pqH#2{C*U!wfNzzA`Xn`R3wP`q_Fgau$ z$iDT_bfa)*oVtbKRm*+1a<;xsujVQcb^ZKC)m-mGRK2p!@M$$QE~tNx{kS0pj^_7w3*yw0b<+R=cuPc1Cq2{q30g%#cSE91Cu(%ZR0lHAl0qr6N$wTr4I4KOVbVRH zCAMoT;D-P1=6w@>-;buW-%*L2#-g_!G&=#J-3|k`Xng)a!?*g0LW< z3NjmPqvg-=sJ_dTAd)&otp6zR#$8zRBZ4Ht>sSZ80*xcQAP=DaB54lrRcC+IJMw!@ zd7uaz3(d@uEnJdtgCk6UxY?)J1F2o^Hgl=^T%lJQva>5R3X=27F!V3ppS<2LhRU4w zE&cAp>~Khsy}zTg*!xLx7%>)X+rFI=0#CeNaHjoyhM%GoqvLe6D^e05crlZ(O_d*? zm{<(B$$^xRh9S)g+=_R|h8t5ZvLx&ZR__w+3wh=wNdzYVYF1Pb%uVid6`Q;5UqYJ$ zPzSA56{eeYin-Q?-rfqZR|pEK>Nnz4?`Rs{<*8z^#EH0P6LUGfAi*{n=Q7QHJcyd^21wi zKX|W4hS|WcxFpv_CL(9Q+^)U_hQG}Ug(ganqLQ`irN6$V*<8SMMWPe%Q6`j@_Kp9B z((&SpGZUkugTMuIJ?&95j>W7qw}}`%5rcx_Yax|OS*_I-8G+L^(uyM%dT1a$I@2${{ZHB5`E4_nP2vcwz_)n_ z9aLCAv&-K?5{W{(am1auTmMZ`(M1PbS}kZJg-=20Pq7c;78` ze<{JIafbL{y~)Hh8_iJJtIlM>IEU-vNOKT9g*`_Zf=YIrmakaz#$)B?DuJl_#uw> zHnWDPfM;j4zrD>c!p~A?Lq^83r@p(Bs%f;0=#XY%;z6wSeTNaF`wPyMi02QBIujEO z03UckIpiyFT?8Pb;zF4&?!2wS-z9={AigUGzQg{ejd^CR%wy3kjH?IZ!(KW0zBB$_ zGew(GFs3~)f5$@Ee8wP`p2qbvuXy9uEv&(GXeSL17aNl{~Lg=r9a?3HamE=xAf*GbV zJGnOWD}M7Ww*ikpw;TV{w?ACQd0cUtlKfw$TUhsOcx03GYxpPbqBzl-&;;keDEy-z{P(3UxOpm)r8ZZM} zvKAj%V}ZX!5#n0=<;!klvL=93Wpgh!xhC~l+||t@ec%;KJrTyjL=hnMp&!YyBxd4V zIhiUEh{mJ8jcaW66g7W^{p=d;)~$@RH|3~xEsWpZFfv_Fz@?loe}Jcwh!0$1kjLJk zeU3PIlDU)Ws(~lig8ccPBp@=u3m8=06xGHJ8%UPDjSN-RKMaG%V!{zJMp~buiP#Z; z_#eqwTDpx+i7G1?Fu^6!r|AIdV37_2vjAfYoMSQR)e7063*QgQ_ll^RK+u%*4b8tKxj_hLpsr?-cIK zh+td?)FFMN3`J~~GZzHE6&Q-{VNcs@6NCU&ki^NO@mh0!HsnqtsRXA1VC$XQWx@En z&+7q)+$Px27sD9PQ zgec8hHPF885=$qLRKN+kU%pTC^^KW$*VB}3LPqOf_Zz8>dW!ojDpP7-p_80LH|^utk9$`~(k@xUEKTqsaz z4}5-!DJo&;8U@IWf|u>#5L*K77s< zP+ojv4Tm+*M7eM$B+roToFwCn+1R2I176Xry(+D1beP z13~zTWJB@Ww{L5yW9qVa96B$E)#s2bd-C-FsFK};L==y{f$VWd0_+~x z9PeXMGCbUz09{G?6jF`u;FRq;t+2$14jkR}2Qe%7u@Q~SgY!cE^^HGEx(JiL^Cv{l ztI6U+L-_=W2d%yP2VeX>prhlP9FbDB-EtZg0A_7IC|v6dIEhnZ@TOOx7)J}XY|PIb zA;)h25~FJT3Wav&aa+gZ0$ZIKPg|8Z?UJ;o1~`oEw0k$vu?OwGvEn220k_{U3_zqQ zB7sYL;P@j+R;c=p;|(lO{DyKwoabXi@HOGGJPyAF0A(v0M3(s0J~K*b@6P=cLN@ow zk7OjjL4;-Lk2Vbi3SIJl0zEIVkVD9M*~%%u3%3@~T$_pHB&^{*_QvphWyu3;eh>E0V)U`Rrl4$Rm&qr1_;9(}m?&rt zB`Pk25%VJ9@>o{qBgmBX%j|K{6Fm97h4@2EIXjf72#JSw+O*-xq3I?w+#+u-lw&2% zUOxsW#IGc1@zr8f>-O3W&*{$|K%WnBB+js3ys^5^>kmx(ClCsRq28tomlg@4^FX>1 zfr|nCUYZ5|eX$Oi;Kyd|u;juNJ1hkci8otW`|^)2M$>$W6DS)l93X-?z+{asq7erhv#@|5%(Y4& zI&fk;E9=Ka6=slk?M*fjct@a8zaNT4F_%%~2_%ZInxVNK+n_I@R+9!8esfY5I7t6; zONC|$^HD2%p$vG`>K+LsZcz9!{4^dapCIAUa!i%SpPWaVYVZ?+dH1n!U6NUd(vVPC z_#}@F`g$0*Dll#w`(g%TIJ!0zpeMrt_x`^YARE1=F)JjF!+EvUFV*ZWuv#%2Ze?`!+P%D=bT__d)FxJQ` z;^o1_LW2$o{}rgfC2*sFYs}>|k>T@!lt8j`9VHNB@zpP6%L^zi;75D(8^H~AyTMA`}mAwCOxK_L!XXXe~W_V5!?Xl=H_h&qJH?f`xz0wbU*5XUK0$D)) zzqCU9lqg_)s0}#U$75>*D>61m*a#L<#`X?{X|N#LfS}Q^T@?aTCapALqySiv9oJ-i z7J>6&54uO^K`;=c?GZhIfB-cxV))5PU>@!zGPdDK4Wru8u|=Dini5a?F-+(rj1yNF zNuNX-*#}_R^T7V}gL@6TX}*L_9tM^Zzam~)bF?d4PAA(#DNc^t{l&+3hU^isb$#|u z-vuegQ`qpMu0^hf408&0@S98+y3mrgg5Swbd@Mlb-ZcZ(Evju!OJ0^%tPRc@mg!1@ zw9UPuF80lHF! z&h|dN()w&Qxr}z-rJOqf+9ZHwNN{@>GZ7*CV!{5q@zB!v4Rid;Xa?|qcvq3Qs8I#G zNr!n-mnteG*cp z%tRO7-YDx{c}c#yA%F0*^?fG#_QI;>Ti=3lZ9TlGl<{P>e`kfAW$Go8H=(SoH)TCT zb!T6_xAjD&eAllip?X#ymHmQn-f~N&Fs`BGf!VDB;Ezx?k9tN--XO6cmvFzT0M`n( z9ho3o*K8z-Rkr%T{57sos^G|%Ab$w9hRY9(AmI|QY5{+x1+OexgFR^1k&lAUiOlsR zR|U~&(Qe{i%`G+Fd*%yz2y_Pz=*pys%M^$u zS*4Kh1-}s9M)pi-xphh(j_++jmMbx&{$9$uc^n+;YysvBWan)lH|@UyxAE39XS;X* zJMZ?$UvMwSn^1=BJE(jp^i10s5_q>gKF)IXamCRMjAt0H%5P@kxLqGK7#tVpti{No z=(jEbeG4VG+&VoTIxdFWejB#G5$`UUou!}t>*}iOCaWR*wfMR7jM^{Pb7ik||6fU0 z0!`)GMo$_D(IAnbq8ZnaIg-kdsVikxamq}ljHOZ?LZl=aGKK5PlzFajROZYaDl!%- zB1--Hz5iY7u4`S+cfRla-r;$ky`Q};X3S&uV67GiBPthg&vtaYaw%*q}O<+=B4G0N9r=&eaK&prD0r z%_5RfjM!Uqv=B|0`A&Dl_UzG^Tg2}7abn^)h1iW@tKCz27Dob6ghOxS&e_v@xmJ;% z#!>&{o`uql*OKxj=1qOPyN$!FvlV)4az!^~8mX>B-F?T~0ARo;!6n~dIDlg3Zgf0lDjtIBQeM^JVDND{=~ z*67>WWqdpYKF<@}^xY##x%L$Fg0)!b0*z9o3@ha_`e!%XGerJcho&wo_0SyG!)8(ak#O|I-OF)VqZK zbM8VJYP@n`Fa-fgaCmq+^czA3zNVp99{I}Me=a0dbAsY!Xf~GSiNf2)Ro98}+Uptd zvsF4M&Lx;}eKa{3qs)@^>yL zUuiXL8t0CWbxBa99q1InvxmU8~{~)b#+>kI4K%S!^J+NJ0?0>6PVXd z7ADg2jMQh`H2%ujflhCwfsr?F7Pq{icX7Md2Y*D#^V!~iz!^wx0V~S9{973$8_jl& z1Ln%}ev0f+Na(Gt^rz?Hmb~3W0P({u=ZXOaGteJYUP$UPp+ABJW6ge;Eo!q<2)S?sa?guO? zeILAOXqZ3%@}JW^suEYQ4p&_xVCem5i1@cSdnF7s{rIi<@YZ&gHR-w@24p)!`Kuuz%ASGK1E(+zGv5i?uTTkQyiVcje z6>sBRY&1HH61{@mKbo!$j*_$F>Aq!}cki^#VS85^)@Dp943tU+Tnka3avJQ4dFTy_ z2T-DL?rrY$v@#ejoxMA77 z1I>I+QJzp!1(`zalq$NDhq29+e9A8G+vy3XO~ir4cKxU(fwc2xXhBTZ=zuk9fmnJJ z3egl!w)3Ena`7+pFDDmZT9L9>$@eZZlO78mFTYY}&gT7WyRO~hXnA0%xc&;m#S6?t z7R;DUsWOm&K)*5xvL`1eal30Nv_Vy6>vnvl2hz_fZe_S_zu0ksz#kFkH3O+NxCW|;X6g7dP zXn!4h zSD%IP=NxK5Z?RuZAfQjj3p@!$4qM;&?JSWoF#=L~o{C|vF;KB1%Ygdoz8!r0lDj+syLMl4k8 zpPH+4?CkBOwDYAG7(F_(g|%$r73Vywu`+C51gs`317J!JKh%Iy2iL}pLXWxuzUhGq zB#0^BDLVKQH!C(>KPvB@Zj)Cz@;soK-lguI9(-*5s-=drzmFgRO~Vnep{+?_kTj)( zaB;$I8x+*ZF$F;hy`4`Wh=Pzst^YU31+uqu3rokIHzkS{wK5o@tY54Y3&+s2nvDGo zM~4t@1g{zSy*SdH$n#YoOc_2kR>eybvJ~I9F9~U^;_~m;y^INk&q2@5soGE-Zj@5h zgjkqR-fDv!^Ee8O#Nz?`9G0fKc;(ziERmkiWe~wRLLdv(N-%ePyuH^`V59kjPN#FL zm86!AQEZU{TmOV_Xuk9^!#(5YdB#1+%cVlSq7^y~>Od5PvkbMNnUe&SC9UjlvIwSN z&?Kb)4h}YEzqu7dTzf+rUc5-2{>5fPrRFywjI={uJ_py>zY+6q*nkDzhIAMfuYy8w z^ z@?85I8veJwe9gUia~sG#npk8qt3DH$ttp@l?4tIG1+6f8(z&LFnjbkU8yB}U(dk{j zY_JyrVi0UvOPm9Uu|vY4D~-p#BO}~Hk%s3&{*31|!!F8NOi#%r|K6LH7Pd}arAoF4?E6%c-DANh?eESzk2U4+?N zfzzc+g^yUET)H3@m6Nf@AKWV4M^bfgKiT~5iRqYD>a)&;!ra`}?FU9uJ^skUlV=VA zH2pU#Yjf%a8ymAmaajL#{Cm;S@d-eT^%R^Sv`=UPeZdg_ z!*?d7?Qf`(#rvQ5Xz%7T+IMm{V+1RiBgy9><+=l7A{`>8Edkzh~RS9thTmx3W~xto=~hw2EmRAR@T7) z^47iMZBg!K`vIB|GW#I1Sz*l7E?$E?<@o2jd!te?-drV$qhHnO2cm1;F67c1o6a~ zLmx$GvrXkOr4`k!bynD=JOi_pn|3>8|87*s)ZyPTULmMhBOd`xd%!4^!=R&r zkre^qJuJm@P-pS}oLBFH+x`Wn5mBeb`*dv(E8dP8m)E;1a;&VZM4jL=H2rKH9giW> zMU`W<>Ux)@IXj}4QB-6YIY#Js2wr#(X=rE=NjcJ>Poxxx1_4e`g7RWL!dLe;Q4m4s zMXFV}dLTqgfs3pmH7&UQLdMj#sPU6c!j;`ij7%eO%3&f!1o1c2a6VvTqQeW}3$}71 zSwoa6Nc|jjPT(mi$h2QIHXZ{)OcZa4`4sp#0K5@7)MIa^P*6sCiO&d>%}Y}`a&9~G zN^Lz+Y{RRtJay|%)8o-MVl-Q5pCZr98*G{6GbCnR)4D!>eCJ(hVu zD2j~DPpPe6r9a*cygIhBX|-x19_1kpdibfq>hb*m0d{L7zq_~GY4C@`X@T!|`##X7 zb>rmqzx@ER&m|zBi~n@s5mB_c?|5m?&YfhVMp(Rr-K)uWM^79z``1&2e*O+Euiv+x z<@L6km);`;yrA(ks)^sIp32gAiU&5de={)%69swi6H^5u#b zNzRZyp}8)hcK2<5o?D?GH{ba5bAsQr!V*}uDB%SmnRuJ_>C|4XImD3$sH0*V;0+kb zEv1!y%O7=gzv~`1D<1jZ2z}TKvb`P{Xldx7cnd|qajeKRWHXu6G2dC7XoMJyt^7FR z>;jL8ldK#ZMG7+j&K}?)*Ks)Fj7~e>a20Zg1pq~BD&~=_wZUZ7Vf_pN=-}8C6SMWG zDOBx}K7X%A9XAn_OX6LP;~+eBM?YzpEx#>y-fw8EeH&WTn|E$4-of7aTJO4k(9PXFl(^_ zXv08(c0kOfs;Y`)fl#}BP94!nS5w(DAozU)o1!qAsmM6y4W!?01qL!#R8|t61F6^{ zL;CBF)j5%+Eh`I6*AbtDjt-=!kYZ#sMq~@)Aw_GQ^=!OdJ$KVrSR1$UrU@8lI-*K^ zYX4^Ba6x(st^&FN>v)12?MVJSRZEIuCfSoUifkHQWAnH#aW@BC;02dJk$+&s(BY+$|5Kz2r95gd6)u@2vpvm4=oUyod0s!hkQs> zY-joM{kx1qX>k;G*CC`Z4zA_UfuTT=&EDt?!FLe(ISp2UrGhYz;(W&4#l@xkTk!*& z)p!f?JH^%6i(AF0rn2*UML0xjUa>A8MbI4#^4W1oP7V%r1Vj`Dd%)1APmpK5g^?sW zS=jod9QoF-Kj-dMEQtS2UXY=o71o06j90gXmnHOW)4XgjjwFWrznSuXrw*DE0D2e9oY2uE=% zZ|{apn{MDeqsU|uiJ6-Xt})1`jq{{l1VSAu^_;5fzaSVCl8{)B=$$*h5-AGaD`YF3 zG_e&NLy;BiZPU&p3uNSc)Ya6I;7C7oh!_V#(QUuhr|z6>K$*e-!uJ1?N;b@t1ZM$- zv*xrZgfvK`*!91VnF#~!_Nu8}s1llu>s>P&d#m{%L^*yq?ojq~`lzNKx)jugjnF)m zgsz3x3O!MvHNx_0c(1H%*QDpk;V~zH9614%ZRist7TQDe5Z`%fDdzTmbZFn7rS9r+ zr~^5jt^&4@iU;0$(9zFJ zLiEqt&dD`s)2bIbeIT z^4o>)PtW`3T~M_-e=8&XJ1A~pz+bIkw+sCBT;OPDM1ZsDadrVkE*vC9C0C&EYtjdB z=)=g!>TTN+I2871^MuHUCb#r;wp;hSZBU*F? z`^7OyW5%XNMzAbthF;pxl1{kJNNvTsb34;kiQJ)!K>dWk<&_Db@A1#Mu@ioCBj7_Bhs`z}DmrqAoQ& zxa`;k#S2aS{pGr2qB4K{;1Mb|oqjUoRegQ>X&+4SAgs?meupz>>GVId9=m;_`DgM| z9g4;}3b-2=Z@t8tF~C{hVQ``i82tp|sGT@1Vi$sQchvM&iMr{`m^@kKQ=~$}JVU448~rFtd-{M4g6| zpMfcOe~i$OK+^&d7=zq6@@wt|;u(Q(mT1RS6|P> zp2^?NfHQ4spW052=Rm_U_R!0 z(Gp`sDecWGPMeTY!E`UP+`Q5NUatfY2=4rbPm}>jGw`47b?gUH@D`LkF+mYgQJuNc zti0Gg$SS%jFE;$}ae$-HO z3@rj@Co2xeI?{fF_LohtpV)ZiD)4jQf+mc29{Y{W%7trcYSaei=A)Sm;4lp8`Hdjx zZvVBUm(m8hHGP!&XwAJ3+-1M+YIm2raz^GW_32uw+C;0|4Yu!MFhU_U&s#j;8QWVF zm6o^o<45%B$h9miw%-@AoQCiW$pxsW2U)dw?ZoSimT`#MD<&;naC){wS44r^V{ykr zzv#5!T?}eE?6UOeTx>A3?y>Mz053}PbTz!q)z+KSjc#9#DQD9 z8%Yvs!P|u(BF;t7X23|Mj>@b7L^KoQ9HUT1UZ{mfD$sdsD9HtoZG;YaLu094I6^_f zLh1f%(mbwnRQy(4vlWuLBl`$ASm3~^q-`OY>*0aZtsh*M}s=!CIbtLjdiw}QDT}V@{{Hw>P63bgiIX=G^w|G`}$ge zbL;j*m6VmSmvR!40@gml1h~_077)jy0!~Vn=}h$obM*^4fR09v zA^=4>o!Hr7PXH@i9k>CgmY}zNft@KI0`D~xLaQboJjVu>u;6QPy!@r$IfE@2(I^%4 z4vKS?2Vr1g4Fmv)M9>N_hP257tJx0T0=oQOy?XT==VUHA_###g0&XMDOb`k`#uYwj zIA=Be@8)ea1=((;h*r2~;}zU@`~Ui?aXe58Q)X^@fDiFH5LdzwUbn)2mFjaO^e*T=1)4%+5D$Eo z1HMBnckc<2;PZ8!zcLWjpy1#DaMTe3!eJ{IX(q5#!;b##EKKCkgOnyw!N*96oypuM zIvOfcY}FsqVIPp~k)=1YU_;G+NSr)n>+OrrW3E0SJv@*IbsU7RVIUf{Y>N(u$b14* z41EQy0D831okF~i+ZK?AmDF89OX@LT0~fn5A(xJW`k^lPlI|hHqg~voE}kyyWV

Aea@Iw`ix3Ntixb!q@3{^&cr*5v@u{gh*d5M+gd^`h$_~qCJNIZK z3ZeD?M)YNc%!)8!(3SK@)3=T-;2K=aNX8Yg{XfS?ob2dA299wZE2*t0ic}2%i6x%e zPvCn-}dkQUa4IQUZn?| z!?&}HBm4wUm;k5XnG%~v!rO-DTwLY4rY z1}l&hdwYBHFpYrB)K_u$W}&OA*VBSWVJ`;!`LZY3(*v=y@?;ukMp|SYp_;RKZStU+ z@A5B~RN{=c6n#GXPgeNDa?=a+lHJqa_>WrzW>!AUHQ*oi{O8oap7jS2Vkr}S>=P$i zI21FRS8pIrBWSxMbRl9EQZpy}IEvmATu%4&>a@95&fqN`{`mSnV#LJ!6E#jehc3$l zcg1nNhQg4tF}-upqq2O+EhEi^E#CDYhyl=Poc0tTelMC@T9b(fCY7L8NwQ3Y12k!z zmoRDBM(Md9A0gnoLvDGXJSKW2N@68P84u5(U0t*1rA(`H+F6ZUAg+!Q&>#->=K`Th;3lZI8+ z+qZu%NZKeel`0uD-%QVv3|-}x;cdEglZ~X!$Dl}?s=*D-4{(_BtTkVLF~uTkk+N&g zcA6bVku|nZFtfR}2Ahn;ZVwuBv9ia!R){74?MyxW`vLg&^EYK)SmP?89W&JjZYz+# zv-Y56zbHDF^^(cEA}&IFdiy8^w-WuqS?u(*mW}ypqsu0qTO^s~Px9B4$aHmyGnbrh zmS;Bdc~QV6O$$;S$$uf{L6dxWdVfq3|%jjn-7`vA{LzUZX?=nJqDxglIF*{J&@&8aMex)3&dC><#dG<+q?Mc{3uA7`+ zm0`AZ|9GSLUiNluLVBDQBkv_)<+6T5){w z9cQOLx8NTVJ#EE4Y~Sw&(AzowfZIzC&Bl}6Wna&hDsz4wA-^!GU}R-&tdoe3 zi1M!%yOhNjQWXPS1i;n`B(cQ4#LLvlKx<09in4x_%_={i}&G}nEhb#Z4+odWCe9&UZ; zQV^D#8<=Ely{L@)SlP{g6jPNaO$O^%*w46;m*&b$UYJ_m=v0FQJCzklp`UryrR;i- zW(DTEmOS*WqT`{TT?-9!PEmNd-D#GlWU`vGkRSWVUptt;-VtV`PvuEd&P_by+{dvgu80PrW3I%jAPMWNiTcG-bNo|C5#1qe(eT@M&72mk?TQZ&?a2S zpf$^X8@X=Dv-pxa&OS_;6LYJ~b!UsWj1HrjjfaZ5jy}s^nA-5r1#w5A0udW8Vk)sy zImwd^vFndad(tdFuf=1V#TCl4)kuUYli|88Om9v7_P$G@Mq-|f^yh0C(Vvc1K1;+$ z#mSd)L^mswS4bcH@3Qa5UD#{nF+l23xg}EU!_MUKYab7eq85V3pQqs(iacQh%@Uyp z$n^s&>$))VgH!kvEBTbX6-QahH!B|63S2#{#&QO?6}JM*(L*B5Vj7nSBTGt=hng;r ow_wS?8o%n`nH{%ARHKz1ROZ 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 diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Transparent/WMS_GetMap_Transparent.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Transparent/WMS_GetMap_Transparent.png index 6a426138297c58ba4e2abc7c1dbb5500fe0319c9..ae748b0586fcf8d247a3155b8a06f986b2adde84 100644 GIT binary patch literal 33099 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 BTfqPT literal 10929 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 diff --git a/tests/testdata/control_images/qgis_server_accesscontrol/WMS_GetMap_projectsubstring/WMS_GetMap_projectsubstring_mask.png b/tests/testdata/control_images/qgis_server_accesscontrol/WMS_GetMap_projectsubstring/WMS_GetMap_projectsubstring_mask.png index 5cb59f67310e115657d2076ad44e3a3a4f62f9fb..ea6cf6213a80a4335499042c1e79a0bc1c30efa6 100644 GIT binary patch delta 3228 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 delta 2150 zcmV-s2$}b_CW{`BD@zNB000Y#0XNCZtpETHy-7qtRCt{2-O+NJ$QnjbaLs!gy?8hm zGx%Ty*^=m{n~$}s{z~G=7NAtNKnRV)Fw6r0aB3f|7XSd*PqX0x{Q|N9Yyp3Oe_Ag9 z0GZ}_9&WeWkGGkoX&8oK7{~GJd&Y4bK0iOdZgacczWsUm9=;ogVVGMl1i)2H(=<%e z^jE;vmaon8{PjJz+ijTV`LFN){QUg(=fx7hwD>(*pJlsjZHr|)E|zV({&l(C`g`xc z?+j*Rj4|)cIF8?bou+9X$MJt_mcLtmfAp-EXPTyYnx?O1TK|51+x7Rf-oCBp{_(xv zET){58v;AKh+!`)7^gSnU1Jy&bYIxjZ%2t%vQ^{27fg#`H9` z_Og2VsLht!;fUqC|GTY^L2bSK6{h(D7-LLV(|gE{T!;J5On-KI4`z+Wxb-?a56~Td;yFxrkhEK`7rz& zt&;cIGJ-K+pjyYqdvM;>k(t*U)*MpacA8nx-m;+|PW~w0HMF_pbBS;r5=MBuvxP)$%Nw zzZu>bV|tjBi^}wH-!(2ov-MH3>yM*7@}p*ZyxN>SbO3)I>ghG&t&fsje;n3;-CtBit^*wxqY7csS@A*Q|0fv9yhEzK0J^bgt zcfH=-Lr;Iz^OG7u2N-fcBfI32lq+BQwb!?*tqD3nB|Y!Wyt_19`24LQT>=Zoea`DTBNF|DWNN1WE4k{|Wi^LCo1>1#?a zYmXn7x-rccz!+niPK`+Q6o8&1{Oq=TcOBM&zrZwK0Aq}4I;H=^?=c`pFH@~2G}APF z``OFym-QRRar3@Qt^dczNAt(>hiSe5#u(FddJM32{C7${G3e=tNwsbD-){g2Hjd*d z-b;Uduhepvyf{v;+tOL?z~%LHMtUtr2dKA8zm~oPZg1I&f*zGE?0~FMA$li@k+9CHvsi;rW)WvoY zbbx|-etq`y^K&M6A0nYbm*XS{!;8bbyN} zv4{Tbla{kSc_$i24{@EqH8i_LUw<;s^Hb~l&d)8qw=U=ayd?1hT7FXNTJNQwC?g%-DZNgmPmmLI;F1Kru9QRWi(3C)mhDvH=LN-BU{q8;c|9%5-Y4@*d{&eEj z)@z{a*HnM|EbZmC>(^7azUQ6KYyauB-A8|S|Mlh1_v@5)v6zy2*gk>|00F#h4YRQU cHv$&;AAp#O&o?c~ Date: Thu, 18 Mar 2021 08:22:55 +0100 Subject: [PATCH 115/377] Restore test script committed by mistake --- .docker/docker-qgis-test.sh | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/.docker/docker-qgis-test.sh b/.docker/docker-qgis-test.sh index b7f7f627fd34..b6735b832d0f 100755 --- a/.docker/docker-qgis-test.sh +++ b/.docker/docker-qgis-test.sh @@ -62,6 +62,30 @@ popd > /dev/null # /root/QGIS # Restore Oracle test data ############################## +echo "${bold}Load Oracle database...🙏${endbold}" + +export ORACLE_HOST="oracle" +export QGIS_ORACLETEST_DBNAME="${ORACLE_HOST}/XEPDB1" +export QGIS_ORACLETEST_DB="host=${QGIS_ORACLETEST_DBNAME} port=1521 user='QGIS' password='qgis'" + +echo "Wait a moment while loading Oracle database." +COUNT=0 +while ! echo exit | sqlplus -L SYSTEM/adminpass@$QGIS_ORACLETEST_DBNAME &> /dev/null +do + printf "🙏" + sleep 5 + if [[ $(( COUNT++ )) -eq 200 ]]; then + break + fi +done +if [[ ${COUNT} -eq 201 ]]; then + echo "timeout, no oracle, no 🙏" +else + echo " done 👀" + pushd /root/QGIS > /dev/null + /root/QGIS/tests/testdata/provider/testdata_oracle.sh $ORACLE_HOST + popd > /dev/null # /root/QGIS +fi ############################## # Restore SQL Server test data @@ -104,5 +128,5 @@ else echo "Flaky tests are run!" fi echo "List of skipped tests: $EXCLUDE_TESTS" -python3 /root/QGIS/.ci/ctest2ci.py xvfb-run ctest -R 'PyQgsServerWMSGetMap$' -V -E "${EXCLUDE_TESTS}" -S /root/QGIS/.ci/config.ctest --output-on-failure +python3 /root/QGIS/.ci/ctest2ci.py xvfb-run ctest -V -E "${EXCLUDE_TESTS}" -S /root/QGIS/.ci/config.ctest --output-on-failure From f126b0caf15ca5c530c03127687c3dca6d1f174f Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Thu, 18 Mar 2021 09:38:02 +0100 Subject: [PATCH 116/377] Fix WMS control images --- ...imension_RangeElevation_MixValues_mask.png | Bin 18288 -> 33850 bytes ...ension_RangeElevation_MultiValues_mask.png | Bin 18288 -> 33850 bytes ...mension_RangeElevation_RangeValue_mask.png | Bin 18288 -> 33850 bytes ...ap_Dimension_RangeElevation_Value_mask.png | Bin 18240 -> 33910 bytes .../Restricted_WMS_GetMap_mask.png | Bin 3215 -> 3949 bytes ...icted_WMS_GetMap_projectsubstring_mask.png | Bin 3036 -> 3784 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Dimension_RangeElevation_MixValues/WMS_GetMap_Dimension_RangeElevation_MixValues_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Dimension_RangeElevation_MixValues/WMS_GetMap_Dimension_RangeElevation_MixValues_mask.png index 9a2d045819e586443bba8eb1eebff6cf265ce5be..9e5860e69af4b4ba4eda91e97a56eba4e6118ac1 100644 GIT binary patch literal 33850 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 ZQ!n2w)X_8#{;-*Yd%L7+*_f6# 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

VM{S7gZ?M}Z}F>_AsvK+63CX&R`(OL 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 literal 18240 zcmbrmcT|(j*EWiR6h*3_fHY|$1Ox=6gr?FW_!y*ws&ojw_g+L0kdjCXAPI;NdJDZH zAOsN-2u(_)gGdQQ;LG!S-*e8p&ic+j-}xgeYu%H3X7=nod-m*oT}k*yU+d;|&g&Eu z6gPFWpMohUt{nXPp`|828OANVBY)9(XhXayC>Y=T`?>O2wZw^nf{#Mysrsvc-0i&S zw3W{_&oW<Bfr7$=f>x1&qVo#h8o7Zcg4__HWMySlTjs%S#W;*3KWw16!A(Iin*i_; zKe~8b_@6h~$?y2k+-Ot%_hldcTYLGuxm|7QV^=5&ZWO+?DI~?;`A@I^{qz6*K>wdJ z_&;vI?ki*Qc>Mn1p==B1>y^zwME-OpS%e6=D)Q7Q7%0?fC@3CNP?6<%$7H-fY5iY9 z$Nq2E;s1CR|5?&b;_v;>4xQMNtN*U_zw7ls*ZBWm-~XGgJf!}kGz$F?Aa-A-g@r8i z81?^qRC9W%18=^#|43`{f9v~y&ZQHT%H+>3*hgNh|4h0w_H|x9&42at|LD?#xruZdh)u$MyEn zQ51D)bbOph3hjTc(r({cW`S0bT@;@)s0_}WC|y0g@>8X1?2Va*RMNGB`cwy#A=F4n z)$Emm+q9>PRs;)TQoG`P~ zD55;vqBbU}Mkuv;Nn#nC@bz+}E&$&pD5l1eT8CbLye>ka-FfDHyJ=R^+K{yK<*;VS zQ}qq)V%;hwMQEpnYVOpMzFj(KG&96~WY$urT)75YPfGXNk4HoW=pan z-&*xgGtWWA%vT4V@CLKLGvE@7g@y9XP7b~``1lM_oY_n7j@kpYBAU)@)Z=}H{BISc zo$dEmY5C*AMA1?wrqc@DUAoeaPB#7Xn*-2^v}-~qS8%q^cB!6KE(iB#`qRrg_E3)N zxH)0?xR~bXqQdT{jc)OWp%a2wT3KeCyA?D9Rq|C^%tIK9V!sR=f+a4EBAv3dzp*p~ zKnic8=&Bn4{HG3)!)+ht=4{Gvmj}oa!~B-a$z6xTQ^<#yMugUmY;;?fhPy2>`E~uc zLyKX)!zg<>5Hii;Je}XUNhl)xcnc-2)#EkH-P|gpz#Jabw5MGrN?(j=ByTLqZN0L^%#glrzg08fu>h$MVy|{gCx5Qg-ph5{H#mmA4v)5|ZM-eKdNYez`aXcU zd=dq3nbE+8(sf_1R%8X0pl!Nzt=qem5Z9s@oF7RwXWVb_x!|cbT8}9qspU40evT1N zY%v1MZ=Vf9QnJ14@adLXrnsbio84!_V0Dn$TWsQ`e&)$Z$i?RpR6EbfU6IIwC%2c> zRWCa5;))XPsA)`{1TK>rfKN&xH8gn-8ZHLw(y2MIp!SSR=K^W zW6ptQKod-YV+GH`!b13jjIsp#G3jzog+WXRUO^${azynxsh7ilV~Pn=Kh zT7?+%8GpgPt3GG`=|y8K=r#e97SgtWE2VkyukOhEy}+gR?tn1N<26ux>g&Li`rsN% zgFh02c6fx-R$9emnO_@wUG*jhU50#AfxG^0@9oXba|RVOA*c$Q8$!)Qs< zm!0WgWIgYADQkWEd#PD%)^Z0Z-|6J!M8~ubv%>G%-)?^|^A<&Z#GD)=%Vv@jO5r0ursAr!Uk(6l=v5i zekG9_Pwys>3T(OI$)R+y_y3*&kI;?25eQ&FM=uPzaW;-gBYVh=MeZ+pzchiD0UEVK z!7tvdC$>BR-xcq9rvt`xm1$jtROFhT!02tALJyW+>SH!o8*LP{fbth0Xgh8BM;sc^67Ga&ZELM4L&;r0_nvf`QE(0F1o&Sqe> zSK;dT*o#s(CAyXC+fI*6*67@Fr$;^w)Ji1SFjOjP14tiSpW8&vjqLz;_5nqW{=)uk zRvlr$j_^yP%uD6K#M!ejqo2s&4^gp**Q=UUru1$0dycWj8iV8S(Mf5OFTcbK+9<+9 z%Y6?)`SEh?oK`mWExVadK4|378b1&)gcUzu4;{e&sLLlEKMt&V)lTKaB9cU@u9^g! zvT##-K&PQ!)$LvH`^Sp|K9phmcwo>5wJ+=2@J>y%$HaOOwZorz-vRyP#ymg$wl8Q` z{WR;@tsZaL)wT|!J1otM-V(>NBq^8*TYh8hn>sPt)61q%IY@RF-nx8G3heo{5Qw+= z`L&Ou2kUjH3t8P=9Y6MW?q(j)2iZ-Q|DJ6bpOE!UI<&weh%U%(TQoE!n7+2z;3^`g zQ&-$|@Tpq^T*N-s?-3`}d3Y=3kHPn9-tMM}qU?$6H`Jsff*6qsFOx+SOZUBShKWo8 zH+ZnQr^AOYXl~4PRt)mt9#@JO4Y&Fv$sOInKZ6?TmJ995{nppiB{nd;2G0K6lWFMv zT+eQ~qfpn*DhaZPjz88(8E#uW4s4hxmA#7(I{(q7v8%S5Rp@_WNo*sQTchLfqmW5ffde^2uXWl0F$Bre_|PD5^r`%vzEt2^4wOtr0aP9`<)fD&UBqF?Ts zat6Z?TwxB?0cJa9th}V4cGDXzg3|njc$AcUtD2!&v1aPzwSFZ z-b&;84X$n(=bM(M4e-B{@KyKe-?r6PB{2FsVkYaQB$x&?w11(VHdMK40NWtcuiCwt z-qIkC@tfN}Egj4il(76#cCcXSIK*vOGRYq|f5o+URj(KO!>TcZ_`QFjBj4dtcFXi_Vf4qTp-J0ngl1yqhhb`ljEE@uJlbvfm`PXBoIvqzO|dJd7o`d8*D8~#zsSe85(dLL4%wj`K9(h^N8%* zdhUe>VQxGKgu$5Ypjmr3LQd?lPnTJn8NxD;Cw-iC#_%T9TqKO@@$hqVZx@rs$KC|O z&w3-z2g&fFK0S9)0hI=JO_M8ESTSO(`}I`5 zl1Yw(fRn%FfJrGNY;hISf%a9NB$Uq?yIC6yb?miXB)l%>jSP0Ov{eLD8hJ|n1*=i6|^%SIv{=V({(sHb|=Zt=wr@$ z%Gc8j6Mg|2^ap&4=TWdrsTF^Zb<)qzb|6P>AKd>m@b~4 zD*FXWv`qY9HQ%|BNWM_8&%Ib?!)U9$6_lO)~WqQ&`(&D;rl{qg?=#T-OuHbZM_=mNtg|uQ+6EB|1 zpw?&m{Os(^%(b&OL?v7o&w%x#qCH*erGz=ya4X~h?3Pl#c6WsS3cD&QwGIpb85cMv z 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 literal 3215 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 Q^j!x|_yl`DI3At*4+PXR#Q*>R From 204621fff907b1693838ff25efbefa7dcc14fa85 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Thu, 18 Mar 2021 10:56:38 +0100 Subject: [PATCH 117/377] More masks --- ...on_Elevation_RangeElevation_Value_mask.png | Bin 17440 -> 25764 bytes ...d_WMS_GetMap_projectsubstring_OGC_mask.png | Bin 3036 -> 3784 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/testdata/control_images/qgis_server/WMS_GetMap_Dimension_Elevation_RangeElevation_Value/WMS_GetMap_Dimension_Elevation_RangeElevation_Value_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetMap_Dimension_Elevation_RangeElevation_Value/WMS_GetMap_Dimension_Elevation_RangeElevation_Value_mask.png index dbba6c50fa13a16daaeaa69d0d25b8ddc727676d..782223f287bf46f8c6d95a625fe58afe7b21db92 100644 GIT binary patch literal 25764 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 diff --git a/tests/testdata/control_images/qgis_server_accesscontrol/Restricted_WMS_GetMap_projectsubstring_OGC/Restricted_WMS_GetMap_projectsubstring_OGC_mask.png b/tests/testdata/control_images/qgis_server_accesscontrol/Restricted_WMS_GetMap_projectsubstring_OGC/Restricted_WMS_GetMap_projectsubstring_OGC_mask.png index 9cb756fd32783ca7ce8f91619e78d2317c42b8d6..4b6e0d1d2d968f3ddefb3522a13d04109772eb8e 100644 GIT binary patch literal 3784 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 Q^j!x|_yl`DI3At*4+PXR#Q*>R From 61ff5ca96578ea027ac31522df8f114ef1d420fb Mon Sep 17 00:00:00 2001 From: Damiano Date: Thu, 18 Mar 2021 18:54:15 +0100 Subject: [PATCH 118/377] Fix relation editor widget not visible if n:m relation name is empty (#42312) Check relations for equality by Id instead of name and check only if the relation in context is valid. --- src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp b/src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp index c31d014b0bad..1b05818fe53f 100644 --- a/src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp +++ b/src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp @@ -274,17 +274,16 @@ void QgsRelationWidgetWrapper::setNmRelationId( const QVariant &nmRelationId ) // If this widget is already embedded by the same relation, reduce functionality const QgsAttributeEditorContext *ctx = &context(); - do + while ( ctx && ctx->relation().isValid() ) { - if ( ( ctx->relation().name() == mRelation.name() && ctx->formMode() == QgsAttributeEditorContext::Embed ) - || ( mNmRelation.isValid() && ctx->relation().name() == mNmRelation.name() ) ) + if ( ( ctx->relation().id() == mRelation.id() && ctx->formMode() == QgsAttributeEditorContext::Embed ) + || ( mNmRelation.isValid() && ctx->relation().id() == mNmRelation.id() ) ) { mWidget->setVisible( false ); break; } ctx = ctx->parentContext(); } - while ( ctx ); mWidget->setRelations( mRelation, mNmRelation ); } From 026e636abec0e1aedd767cbbfa1f8eb96ba2b7a0 Mon Sep 17 00:00:00 2001 From: Damiano Date: Thu, 18 Mar 2021 17:11:11 +0100 Subject: [PATCH 119/377] Avoid misleading debug output "Invalid relation: no ID" Set the relation ID at first to avoid debug messages --- src/core/qgspolymorphicrelation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/qgspolymorphicrelation.cpp b/src/core/qgspolymorphicrelation.cpp index 86c8c904a0ad..fedc0628d1a2 100644 --- a/src/core/qgspolymorphicrelation.cpp +++ b/src/core/qgspolymorphicrelation.cpp @@ -389,10 +389,10 @@ QList QgsPolymorphicRelation::generateRelations() const QgsRelation relation; QString referencedLayerName = d->mReferencedLayersMap[referencedLayerId]->name(); + relation.setId( QStringLiteral( "%1_%2" ).arg( d->mRelationId, referencedLayerName ) ); relation.setReferencedLayer( referencedLayerId ); relation.setReferencingLayer( d->mReferencingLayerId ); relation.setName( QStringLiteral( "Generated for \"%1\"" ).arg( referencedLayerName ) ); - relation.setId( QStringLiteral( "%1_%2" ).arg( d->mRelationId, referencedLayerName ) ); relation.setPolymorphicRelationId( d->mRelationId ); relation.setStrength( d->mRelationStrength ); From a4a5f262f4dc54eb9a7a002fbeb0f113b04038e8 Mon Sep 17 00:00:00 2001 From: Damiano Date: Mon, 15 Mar 2021 22:31:13 +0100 Subject: [PATCH 120/377] Added missing calls to updateUi hook --- src/gui/qgsabstractrelationeditorwidget.cpp | 53 +++++++++++---------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/gui/qgsabstractrelationeditorwidget.cpp b/src/gui/qgsabstractrelationeditorwidget.cpp index e6064b0e2687..02072de8cd1f 100644 --- a/src/gui/qgsabstractrelationeditorwidget.cpp +++ b/src/gui/qgsabstractrelationeditorwidget.cpp @@ -216,34 +216,32 @@ void QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &geometry ) // n:m Relation: first let the user create a new feature on the other table // and autocreate a new linking feature. QgsFeature f; - if ( vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), geometry, &f ) ) - { - // Fields of the linking table - const QgsFields fields = mRelation.referencingLayer()->fields(); - - // Expression context for the linking table - QgsExpressionContext context = mRelation.referencingLayer()->createExpressionContext(); + if ( vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), geometry, &f ) == false ) + return; - QgsAttributeMap linkAttributes; - const auto constFieldPairs = mRelation.fieldPairs(); - for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs ) - { - int index = fields.indexOf( fieldPair.first ); - linkAttributes.insert( index, mFeature.attribute( fieldPair.second ) ); - } + // Fields of the linking table + const QgsFields fields = mRelation.referencingLayer()->fields(); - const auto constNmFieldPairs = mNmRelation.fieldPairs(); - for ( const QgsRelation::FieldPair &fieldPair : constNmFieldPairs ) - { - int index = fields.indexOf( fieldPair.first ); - linkAttributes.insert( index, f.attribute( fieldPair.second ) ); - } - QgsFeature linkFeature = QgsVectorLayerUtils::createFeature( mRelation.referencingLayer(), QgsGeometry(), linkAttributes, &context ); + // Expression context for the linking table + QgsExpressionContext context = mRelation.referencingLayer()->createExpressionContext(); - mRelation.referencingLayer()->addFeature( linkFeature ); + QgsAttributeMap linkAttributes; + const auto constFieldPairs = mRelation.fieldPairs(); + for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs ) + { + int index = fields.indexOf( fieldPair.first ); + linkAttributes.insert( index, mFeature.attribute( fieldPair.second ) ); + } - updateUi(); + const auto constNmFieldPairs = mNmRelation.fieldPairs(); + for ( const QgsRelation::FieldPair &fieldPair : constNmFieldPairs ) + { + int index = fields.indexOf( fieldPair.first ); + linkAttributes.insert( index, f.attribute( fieldPair.second ) ); } + QgsFeature linkFeature = QgsVectorLayerUtils::createFeature( mRelation.referencingLayer(), QgsGeometry(), linkAttributes, &context ); + + mRelation.referencingLayer()->addFeature( linkFeature ); } else { @@ -260,8 +258,11 @@ void QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &geometry ) keyAttrs.insert( fields.indexFromName( fieldPair.referencingField() ), mFeature.attribute( fieldPair.referencedField() ) ); } - vlTools->addFeature( mRelation.referencingLayer(), keyAttrs, geometry ); + if ( vlTools->addFeature( mRelation.referencingLayer(), keyAttrs, geometry ) == false ) + return; } + + updateUi(); } void QgsAbstractRelationEditorWidget::deleteFeature( const QgsFeatureId fid ) @@ -542,8 +543,6 @@ void QgsAbstractRelationEditorWidget::unlinkFeatures( const QgsFeatureIds &fids } mRelation.referencingLayer()->deleteFeatures( fids ); - - updateUi(); } else { @@ -584,6 +583,8 @@ void QgsAbstractRelationEditorWidget::unlinkFeatures( const QgsFeatureIds &fids } } } + + updateUi(); } void QgsAbstractRelationEditorWidget::updateUi() From 56939072a60e5b1ec24387a439a11ca78bb27272 Mon Sep 17 00:00:00 2001 From: Damiano Date: Tue, 16 Mar 2021 08:40:21 +0100 Subject: [PATCH 121/377] Apply suggestions from code review Co-authored-by: Ivan Ivanov --- src/gui/qgsabstractrelationeditorwidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/qgsabstractrelationeditorwidget.cpp b/src/gui/qgsabstractrelationeditorwidget.cpp index 02072de8cd1f..1732652570dd 100644 --- a/src/gui/qgsabstractrelationeditorwidget.cpp +++ b/src/gui/qgsabstractrelationeditorwidget.cpp @@ -216,7 +216,7 @@ void QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &geometry ) // n:m Relation: first let the user create a new feature on the other table // and autocreate a new linking feature. QgsFeature f; - if ( vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), geometry, &f ) == false ) + if ( !vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), geometry, &f ) ) return; // Fields of the linking table @@ -258,7 +258,7 @@ void QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &geometry ) keyAttrs.insert( fields.indexFromName( fieldPair.referencingField() ), mFeature.attribute( fieldPair.referencedField() ) ); } - if ( vlTools->addFeature( mRelation.referencingLayer(), keyAttrs, geometry ) == false ) + if ( !vlTools->addFeature( mRelation.referencingLayer(), keyAttrs, geometry ) ) return; } From 8c76da2df696a42f034a77a3f9c1ab42401877bc Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Wed, 3 Feb 2021 00:06:56 +0100 Subject: [PATCH 122/377] Merge pull request #41272 from qgis/backport-41215-to-release-3_16 [Backport release-3_16] Fix wrong attr values in joined fields --- .../vector/qgsvectorlayerfeatureiterator.cpp | 30 +++++------- .../src/core/testqgsvectorlayerjoinbuffer.cpp | 49 +++++++++++++++++++ 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/core/vector/qgsvectorlayerfeatureiterator.cpp b/src/core/vector/qgsvectorlayerfeatureiterator.cpp index 9e63a7e9a562..3ed35aa013ba 100644 --- a/src/core/vector/qgsvectorlayerfeatureiterator.cpp +++ b/src/core/vector/qgsvectorlayerfeatureiterator.cpp @@ -1078,15 +1078,24 @@ void QgsVectorLayerFeatureIterator::FetchJoinInfo::addJoinedAttributesDirect( Qg subsetString += '=' + v; } + QList joinedAttributeIndices; + // maybe user requested just a subset of layer's attributes // so we do not have to cache everything - QVector subsetIndices; if ( joinInfo->hasSubset() ) { const QStringList subsetNames = QgsVectorLayerJoinInfo::joinFieldNamesSubset( *joinInfo ); - subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, subsetNames ); + QVector subsetIndices = QgsVectorLayerJoinBuffer::joinSubsetIndices( joinLayer, subsetNames ); + joinedAttributeIndices = qgis::setToList( qgis::listToSet( attributes ).intersect( qgis::listToSet( subsetIndices.toList() ) ) ); + } + else + { + joinedAttributeIndices = attributes; } + // we don't need the join field, it is already present in the other table + joinedAttributeIndices.removeAll( joinField ); + // select (no geometry) QgsFeatureRequest request; request.setFlags( QgsFeatureRequest::NoGeometry ); @@ -1101,22 +1110,9 @@ void QgsVectorLayerFeatureIterator::FetchJoinInfo::addJoinedAttributesDirect( Qg { int index = indexOffset; QgsAttributes attr = fet.attributes(); - if ( joinInfo->hasSubset() ) - { - for ( int i = 0; i < subsetIndices.count(); ++i ) - f.setAttribute( index++, attr.at( subsetIndices.at( i ) ) ); - } - else - { - // use all fields except for the one used for join (has same value as exiting field in target layer) - for ( int i = 0; i < attr.count(); ++i ) - { - if ( i == joinField ) - continue; - f.setAttribute( index++, attr.at( i ) ); - } - } + for ( int i = 0; i < joinedAttributeIndices.count(); ++i ) + f.setAttribute( index++, attr.at( joinedAttributeIndices.at( i ) ) ); } else { diff --git a/tests/src/core/testqgsvectorlayerjoinbuffer.cpp b/tests/src/core/testqgsvectorlayerjoinbuffer.cpp index 576e03f2e3ba..f84cee80a162 100644 --- a/tests/src/core/testqgsvectorlayerjoinbuffer.cpp +++ b/tests/src/core/testqgsvectorlayerjoinbuffer.cpp @@ -68,6 +68,7 @@ class TestVectorLayerJoinBuffer : public QObject void testResolveReferences(); void testSignals(); void testChangeAttributeValues(); + void testCollidingNameColumn(); private: QgsProject mProject; @@ -841,6 +842,54 @@ void TestVectorLayerJoinBuffer::testChangeAttributeValues() } +// Check https://github.com/qgis/QGIS/issues/26652 +void TestVectorLayerJoinBuffer::testCollidingNameColumn() +{ + mProject.clear(); + QgsVectorLayer *vlA = new QgsVectorLayer( QStringLiteral( "Point?field=id_a:integer&field=name" ), QStringLiteral( "cacheA" ), QStringLiteral( "memory" ) ); + QVERIFY( vlA->isValid() ); + QgsVectorLayer *vlB = new QgsVectorLayer( QStringLiteral( "Point?field=id_b:integer&field=name&field=value_b" ), QStringLiteral( "cacheB" ), QStringLiteral( "memory" ) ); + QVERIFY( vlB->isValid() ); + mProject.addMapLayer( vlA ); + mProject.addMapLayer( vlB ); + + QgsFeature fA1( vlA->dataProvider()->fields(), 1 ); + fA1.setAttribute( QStringLiteral( "id_a" ), 1 ); + fA1.setAttribute( QStringLiteral( "name" ), QStringLiteral( "name_a" ) ); + + vlA->dataProvider()->addFeatures( QgsFeatureList() << fA1 ); + + QgsVectorLayerJoinInfo joinInfo; + joinInfo.setTargetFieldName( QStringLiteral( "id_a" ) ); + joinInfo.setJoinLayer( vlB ); + joinInfo.setJoinFieldName( QStringLiteral( "id_b" ) ); + joinInfo.setPrefix( QStringLiteral( "" ) ); + joinInfo.setEditable( true ); + joinInfo.setUpsertOnEdit( true ); + vlA->addJoin( joinInfo ); + + QgsFeatureIterator fi1 = vlA->getFeatures(); + fi1.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + QVERIFY( !fA1.attribute( "value_b" ).isValid() ); + + QgsFeature fB1( vlB->dataProvider()->fields(), 1 ); + fB1.setAttribute( QStringLiteral( "id_b" ), 1 ); + fB1.setAttribute( QStringLiteral( "name" ), QStringLiteral( "name_b" ) ); + fB1.setAttribute( QStringLiteral( "value_b" ), QStringLiteral( "value_b" ) ); + + vlB->dataProvider()->addFeatures( QgsFeatureList() << fB1 ); + + QgsFeatureIterator fi2 = vlA->getFeatures(); + fi2.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + QCOMPARE( fA1.attribute( "value_b" ).toString(), QStringLiteral( "value_b" ) ); + +} QGSTEST_MAIN( TestVectorLayerJoinBuffer ) #include "testqgsvectorlayerjoinbuffer.moc" From 04b33a506e250e5e87c383ebec185327e44ab559 Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Thu, 11 Feb 2021 10:45:08 +0200 Subject: [PATCH 123/377] Fix wrong attr values in joined fields Improved version of #41215 Fix #26652 If the joined layer has field names that collide with already existing fields, these fields from the joined layer are dropped. However, this situation was not handled in the code, as the real joined field attr index is not being used, but indices starting from 0, 1, 2 for each of the joined fields. For example: "joined" layer has fields "id", "name" and "descr"; "source" layer has fields "id", "name", "joined_id" Then "id" and "name" columns from "joined" will be discarded, but the the value for "descr" would not be taken from attribute index 2, but index 1. --- .../vector/qgsvectorlayerfeatureiterator.cpp | 20 ++++++++++---- .../vector/qgsvectorlayerfeatureiterator.h | 1 + .../src/core/testqgsvectorlayerjoinbuffer.cpp | 26 +++++++++++++++---- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/core/vector/qgsvectorlayerfeatureiterator.cpp b/src/core/vector/qgsvectorlayerfeatureiterator.cpp index 3ed35aa013ba..82ed571b88ea 100644 --- a/src/core/vector/qgsvectorlayerfeatureiterator.cpp +++ b/src/core/vector/qgsvectorlayerfeatureiterator.cpp @@ -719,6 +719,7 @@ void QgsVectorLayerFeatureIterator::prepareJoin( int fieldIdx ) // store field source index - we'll need it when fetching from provider mFetchJoinInfo[ joinInfo ].attributes.push_back( sourceLayerIndex ); + mFetchJoinInfo[ joinInfo ].attributesSourceToDestLayerMap[sourceLayerIndex] = fieldIdx; } @@ -786,7 +787,9 @@ void QgsVectorLayerFeatureIterator::prepareFields() mExpressionContext.reset(); - mFieldsToPrepare = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList(); + mFieldsToPrepare = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) + ? mRequest.subsetOfAttributes() + : mSource->mFields.allAttributesList(); while ( !mFieldsToPrepare.isEmpty() ) { @@ -1099,20 +1102,27 @@ void QgsVectorLayerFeatureIterator::FetchJoinInfo::addJoinedAttributesDirect( Qg // select (no geometry) QgsFeatureRequest request; request.setFlags( QgsFeatureRequest::NoGeometry ); - request.setSubsetOfAttributes( attributes ); + request.setSubsetOfAttributes( joinedAttributeIndices ); request.setFilterExpression( subsetString ); request.setLimit( 1 ); QgsFeatureIterator fi = joinLayer->getFeatures( request ); // get first feature + const QList sourceAttrIndexes = attributesSourceToDestLayerMap.keys(); QgsFeature fet; if ( fi.nextFeature( fet ) ) { - int index = indexOffset; QgsAttributes attr = fet.attributes(); - for ( int i = 0; i < joinedAttributeIndices.count(); ++i ) - f.setAttribute( index++, attr.at( joinedAttributeIndices.at( i ) ) ); + for ( const int sourceAttrIndex : sourceAttrIndexes ) + { + if ( sourceAttrIndex == joinField ) + continue; + + int destAttrIndex = attributesSourceToDestLayerMap.value( sourceAttrIndex ); + + f.setAttribute( destAttrIndex, attr.at( sourceAttrIndex ) ); + } } else { diff --git a/src/core/vector/qgsvectorlayerfeatureiterator.h b/src/core/vector/qgsvectorlayerfeatureiterator.h index a6206563d5fb..53829fd35758 100644 --- a/src/core/vector/qgsvectorlayerfeatureiterator.h +++ b/src/core/vector/qgsvectorlayerfeatureiterator.h @@ -148,6 +148,7 @@ class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureItera { const QgsVectorLayerJoinInfo *joinInfo;//!< Canonical source of information about the join QgsAttributeList attributes; //!< Attributes to fetch + QMap attributesSourceToDestLayerMap SIP_SKIP; //!< Mapping from original attribute index to the joined layer index int indexOffset; //!< At what position the joined fields start QgsVectorLayer *joinLayer; //!< Resolved pointer to the joined layer int targetField; //!< Index of field (of this layer) that drives the join diff --git a/tests/src/core/testqgsvectorlayerjoinbuffer.cpp b/tests/src/core/testqgsvectorlayerjoinbuffer.cpp index f84cee80a162..5f1a43861e44 100644 --- a/tests/src/core/testqgsvectorlayerjoinbuffer.cpp +++ b/tests/src/core/testqgsvectorlayerjoinbuffer.cpp @@ -848,7 +848,7 @@ void TestVectorLayerJoinBuffer::testCollidingNameColumn() mProject.clear(); QgsVectorLayer *vlA = new QgsVectorLayer( QStringLiteral( "Point?field=id_a:integer&field=name" ), QStringLiteral( "cacheA" ), QStringLiteral( "memory" ) ); QVERIFY( vlA->isValid() ); - QgsVectorLayer *vlB = new QgsVectorLayer( QStringLiteral( "Point?field=id_b:integer&field=name&field=value_b" ), QStringLiteral( "cacheB" ), QStringLiteral( "memory" ) ); + QgsVectorLayer *vlB = new QgsVectorLayer( QStringLiteral( "Point?field=id_b:integer&field=name&field=value_b&field=value_c" ), QStringLiteral( "cacheB" ), QStringLiteral( "memory" ) ); QVERIFY( vlB->isValid() ); mProject.addMapLayer( vlA ); mProject.addMapLayer( vlB ); @@ -870,28 +870,44 @@ void TestVectorLayerJoinBuffer::testCollidingNameColumn() QgsFeatureIterator fi1 = vlA->getFeatures(); fi1.nextFeature( fA1 ); - QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b"} ) ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b", "value_c"} ) ); QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); QVERIFY( !fA1.attribute( "value_b" ).isValid() ); + QVERIFY( !fA1.attribute( "value_c" ).isValid() ); QgsFeature fB1( vlB->dataProvider()->fields(), 1 ); fB1.setAttribute( QStringLiteral( "id_b" ), 1 ); fB1.setAttribute( QStringLiteral( "name" ), QStringLiteral( "name_b" ) ); fB1.setAttribute( QStringLiteral( "value_b" ), QStringLiteral( "value_b" ) ); + fB1.setAttribute( QStringLiteral( "value_c" ), QStringLiteral( "value_c" ) ); vlB->dataProvider()->addFeatures( QgsFeatureList() << fB1 ); QgsFeatureIterator fi2 = vlA->getFeatures(); fi2.nextFeature( fA1 ); - QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b"} ) ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b", "value_c"} ) ); QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); QCOMPARE( fA1.attribute( "value_b" ).toString(), QStringLiteral( "value_b" ) ); + QCOMPARE( fA1.attribute( "value_c" ).toString(), QStringLiteral( "value_c" ) ); + fi2 = vlA->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList( {0, 1, 2} ) ) ); + fi2.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b", "value_c"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + QCOMPARE( fA1.attribute( "value_b" ).toString(), QStringLiteral( "value_b" ) ); + QVERIFY( !fA1.attribute( "value_c" ).isValid() ); + + fi2 = vlA->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList( {0, 1, 3} ) ) ); + fi2.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b", "value_c"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + QVERIFY( !fA1.attribute( "value_b" ).isValid() ); + QCOMPARE( fA1.attribute( "value_c" ).toString(), QStringLiteral( "value_c" ) ); } QGSTEST_MAIN( TestVectorLayerJoinBuffer ) #include "testqgsvectorlayerjoinbuffer.moc" - - From 136a989015d3934dcf2296fc734f915c48b1474b Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Thu, 18 Mar 2021 00:37:23 +0200 Subject: [PATCH 124/377] Additional tests --- .../src/core/testqgsvectorlayerjoinbuffer.cpp | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/tests/src/core/testqgsvectorlayerjoinbuffer.cpp b/tests/src/core/testqgsvectorlayerjoinbuffer.cpp index 5f1a43861e44..d583b5d3a5e2 100644 --- a/tests/src/core/testqgsvectorlayerjoinbuffer.cpp +++ b/tests/src/core/testqgsvectorlayerjoinbuffer.cpp @@ -907,6 +907,75 @@ void TestVectorLayerJoinBuffer::testCollidingNameColumn() QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); QVERIFY( !fA1.attribute( "value_b" ).isValid() ); QCOMPARE( fA1.attribute( "value_c" ).toString(), QStringLiteral( "value_c" ) ); + + vlA->removeJoin( vlB->id() ); + joinInfo.setJoinFieldNamesSubset( new QStringList( {"name"} ) ); + vlA->addJoin( joinInfo ); + fi2 = vlA->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList( {0, 1, 2} ) ) ); + fi2.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + + vlA->removeJoin( vlB->id() ); + joinInfo.setJoinFieldNamesSubset( new QStringList( {"value_b"} ) ); + vlA->addJoin( joinInfo ); + fi2 = vlA->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList( {0, 1, 2} ) ) ); + fi2.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + QCOMPARE( fA1.attribute( "value_b" ).toString(), QStringLiteral( "value_b" ) ); + + vlA->removeJoin( vlB->id() ); + joinInfo.setJoinFieldNamesSubset( new QStringList( {"value_c"} ) ); + vlA->addJoin( joinInfo ); + fi2 = vlA->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList( {0, 1, 2} ) ) ); + fi2.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_c"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + QCOMPARE( fA1.attribute( "value_c" ).toString(), QStringLiteral( "value_c" ) ); + + vlA->removeJoin( vlB->id() ); + joinInfo.setJoinFieldNamesSubset( new QStringList( {"name", "value_c"} ) ); + vlA->addJoin( joinInfo ); + fi2 = vlA->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList( {0, 1, 2, 3} ) ) ); + fi2.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_c"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + QCOMPARE( fA1.attribute( "value_c" ).toString(), QStringLiteral( "value_c" ) ); + + vlA->removeJoin( vlB->id() ); + joinInfo.setJoinFieldNamesSubset( new QStringList( {"value_b", "value_c"} ) ); + vlA->addJoin( joinInfo ); + fi2 = vlA->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList( {0, 1, 2, 3} ) ) ); + fi2.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b", "value_c"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + QCOMPARE( fA1.attribute( "value_b" ).toString(), QStringLiteral( "value_b" ) ); + QCOMPARE( fA1.attribute( "value_c" ).toString(), QStringLiteral( "value_c" ) ); + + vlA->removeJoin( vlB->id() ); + joinInfo.setJoinFieldNamesSubset( nullptr ); + vlA->addJoin( joinInfo ); + fi2 = vlA->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList( {0, 1, 2} ) ) ); + fi2.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b", "value_c"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + QCOMPARE( fA1.attribute( "value_b" ).toString(), QStringLiteral( "value_b" ) ); + QVERIFY( !fA1.attribute( "value_c" ).isValid() ); + + fi2 = vlA->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList( {0, 1, 3} ) ) ); + fi2.nextFeature( fA1 ); + QCOMPARE( fA1.fields().names(), QStringList( {"id_a", "name", "value_b", "value_c"} ) ); + QCOMPARE( fA1.attribute( "id_a" ).toInt(), 1 ); + QCOMPARE( fA1.attribute( "name" ).toString(), QStringLiteral( "name_a" ) ); + QVERIFY( !fA1.attribute( "value_b" ).isValid() ); + QCOMPARE( fA1.attribute( "value_c" ).toString(), QStringLiteral( "value_c" ) ); } QGSTEST_MAIN( TestVectorLayerJoinBuffer ) From 36a1e58e7e722553abc6936ba7c55ba0f7234876 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 18 Mar 2021 20:37:09 +0100 Subject: [PATCH 125/377] fix open form button not always enabled in relation reference widget (#42144) * fix open form button not always enabled in relation reference widget when the underlying model has more feature than what the model fetches by default (100), the feature is not fetched yet when the combobox has its index changed the new signal allows to be aware when the feature is ready to be used --- .../core/auto_generated/qgsfeaturepickermodelbase.sip.in | 9 +++++++++ python/gui/auto_generated/qgsfeaturelistcombobox.sip.in | 7 +++++++ src/core/qgsfeaturepickermodelbase.cpp | 7 +++++++ src/core/qgsfeaturepickermodelbase.h | 8 ++++++++ src/gui/editorwidgets/qgsrelationreferencewidget.cpp | 5 ++--- src/gui/editorwidgets/qgsrelationreferencewidget.h | 2 +- src/gui/qgsfeaturelistcombobox.cpp | 2 ++ src/gui/qgsfeaturelistcombobox.h | 7 +++++++ 8 files changed, 43 insertions(+), 4 deletions(-) diff --git a/python/core/auto_generated/qgsfeaturepickermodelbase.sip.in b/python/core/auto_generated/qgsfeaturepickermodelbase.sip.in index 3fcd4b9b480c..c22a1155c490 100644 --- a/python/core/auto_generated/qgsfeaturepickermodelbase.sip.in +++ b/python/core/auto_generated/qgsfeaturepickermodelbase.sip.in @@ -154,6 +154,15 @@ If set to 0, no limit is applied when fetching signals: + void currentFeatureChanged(); +%Docstring +Emitted when the current feature in the model has changed +This emitted both when the extra value changes and when the extra value status changes. +It allows being notified when the feature is fetched after the extra value has been set. + +.. versionadded:: 3.16.5 +%End + void sourceLayerChanged(); %Docstring The source layer from which features will be fetched. diff --git a/python/gui/auto_generated/qgsfeaturelistcombobox.sip.in b/python/gui/auto_generated/qgsfeaturelistcombobox.sip.in index f1d2745cf303..dd2d654deb9c 100644 --- a/python/gui/auto_generated/qgsfeaturelistcombobox.sip.in +++ b/python/gui/auto_generated/qgsfeaturelistcombobox.sip.in @@ -221,6 +221,13 @@ Normally the primary key of the layer. void allowNullChanged(); %Docstring Determines if a NULL value should be available in the list. +%End + + void currentFeatureChanged(); +%Docstring +Emitted when the current feature changes + +.. versionadded:: 3.16.5 %End }; diff --git a/src/core/qgsfeaturepickermodelbase.cpp b/src/core/qgsfeaturepickermodelbase.cpp index 6384a76189ce..c33fbc81d12e 100644 --- a/src/core/qgsfeaturepickermodelbase.cpp +++ b/src/core/qgsfeaturepickermodelbase.cpp @@ -28,6 +28,11 @@ QgsFeaturePickerModelBase::QgsFeaturePickerModelBase( QObject *parent ) mReloadTimer.setInterval( 100 ); mReloadTimer.setSingleShot( true ); connect( &mReloadTimer, &QTimer::timeout, this, &QgsFeaturePickerModelBase::scheduledReload ); + + // The fact that the feature changed is a combination of the 2 signals: + // If the extra value is set to a feature currently not fetched, it will go through an intermediate step while the extra value does not exist (as it call reloadFeature) + connect( this, &QgsFeaturePickerModelBase::extraIdentifierValueChanged, this, &QgsFeaturePickerModelBase::currentFeatureChanged ); + connect( this, &QgsFeaturePickerModelBase::extraValueDoesNotExistChanged, this, &QgsFeaturePickerModelBase::currentFeatureChanged ); } @@ -513,11 +518,13 @@ void QgsFeaturePickerModelBase::setExtraIdentifierValueUnguarded( const QVariant if ( !isNull ) { mEntries.prepend( createEntry( identifierValue ) ); + setExtraValueDoesNotExist( true ); reloadCurrentFeature(); } else { mEntries.prepend( QgsFeatureExpressionValuesGatherer::nullEntry( mSourceLayer ) ); + setExtraValueDoesNotExist( false ); } endInsertRows(); diff --git a/src/core/qgsfeaturepickermodelbase.h b/src/core/qgsfeaturepickermodelbase.h index a2649336338e..348f8bd627be 100644 --- a/src/core/qgsfeaturepickermodelbase.h +++ b/src/core/qgsfeaturepickermodelbase.h @@ -178,6 +178,14 @@ class CORE_EXPORT QgsFeaturePickerModelBase : public QAbstractItemModel SIP_ABST signals: + /** + * Emitted when the current feature in the model has changed + * This emitted both when the extra value changes and when the extra value status changes. + * It allows being notified when the feature is fetched after the extra value has been set. + * \since QGIS 3.16.5 + */ + void currentFeatureChanged(); + /** * The source layer from which features will be fetched. */ diff --git a/src/gui/editorwidgets/qgsrelationreferencewidget.cpp b/src/gui/editorwidgets/qgsrelationreferencewidget.cpp index 08de839203f3..73360b6b473d 100644 --- a/src/gui/editorwidgets/qgsrelationreferencewidget.cpp +++ b/src/gui/editorwidgets/qgsrelationreferencewidget.cpp @@ -599,7 +599,7 @@ void QgsRelationReferenceWidget::init() } // Only connect after iterating, to have only one iterator on the referenced table at once - connect( mComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsRelationReferenceWidget::comboReferenceChanged ); + connect( mComboBox, &QgsFeatureListComboBox::currentFeatureChanged, this, &QgsRelationReferenceWidget::comboReferenceChanged ); QApplication::restoreOverrideCursor(); @@ -723,9 +723,8 @@ void QgsRelationReferenceWidget::mapIdentification() } } -void QgsRelationReferenceWidget::comboReferenceChanged( int index ) +void QgsRelationReferenceWidget::comboReferenceChanged() { - Q_UNUSED( index ) mReferencedLayer->getFeatures( mComboBox->currentFeatureRequest() ).nextFeature( mFeature ); highlightFeature( mFeature ); updateAttributeEditorFrame( mFeature ); diff --git a/src/gui/editorwidgets/qgsrelationreferencewidget.h b/src/gui/editorwidgets/qgsrelationreferencewidget.h index 1316414270d9..bdeff0a5cc7c 100644 --- a/src/gui/editorwidgets/qgsrelationreferencewidget.h +++ b/src/gui/editorwidgets/qgsrelationreferencewidget.h @@ -287,7 +287,7 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget private slots: void highlightActionTriggered( QAction *action ); void deleteHighlight(); - void comboReferenceChanged( int index ); + void comboReferenceChanged(); void featureIdentified( const QgsFeature &feature ); void setMapTool( QgsMapTool *mapTool ); void unsetMapTool(); diff --git a/src/gui/qgsfeaturelistcombobox.cpp b/src/gui/qgsfeaturelistcombobox.cpp index 2495bd0faffd..3ed397bd96c6 100644 --- a/src/gui/qgsfeaturelistcombobox.cpp +++ b/src/gui/qgsfeaturelistcombobox.cpp @@ -61,6 +61,8 @@ QgsFeatureListComboBox::QgsFeatureListComboBox( QWidget *parent ) connect( mLineEdit, &QgsFilterLineEdit::textEdited, this, &QgsFeatureListComboBox::onCurrentTextChanged ); + connect( mModel, &QgsFeatureFilterModel::currentFeatureChanged, this, &QgsFeatureListComboBox::currentFeatureChanged ); + setToolTip( tr( "Just start typing what you are looking for." ) ); } diff --git a/src/gui/qgsfeaturelistcombobox.h b/src/gui/qgsfeaturelistcombobox.h index 76eb2e94ae23..4c7b1330912a 100644 --- a/src/gui/qgsfeaturelistcombobox.h +++ b/src/gui/qgsfeaturelistcombobox.h @@ -234,6 +234,12 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox */ void allowNullChanged(); + /** + * Emitted when the current feature changes + * \since QGIS 3.16.5 + */ + void currentFeatureChanged(); + private slots: void onCurrentTextChanged( const QString &text ); void onFilterUpdateCompleted(); @@ -253,6 +259,7 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox bool mIsCurrentlyEdited = false; friend class TestQgsFeatureListComboBox; + friend class TestQgsRelationReferenceWidget; }; From b641f9045e01e332872efdc5a1a4a528024a4c7c Mon Sep 17 00:00:00 2001 From: nirvn Date: Thu, 18 Mar 2021 10:15:08 +0700 Subject: [PATCH 126/377] [ui] Disable fill color for stroke-only ellipse symbols --- .../core/auto_generated/symbology/qgsellipsesymbollayer.sip.in | 2 +- src/core/symbology/qgsellipsesymbollayer.cpp | 2 +- src/core/symbology/qgsellipsesymbollayer.h | 2 +- src/gui/symbology/qgsellipsesymbollayerwidget.cpp | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in b/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in index ea8092620595..c7ac36ad8f53 100644 --- a/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in @@ -51,7 +51,7 @@ Creates the symbol layer void setSymbolName( const QString &name ); QString symbolName() const; - bool shapeIsFilled( const QString &symbolName ) const; + static bool shapeIsFilled( const QString &symbolName ); %Docstring Returns ``True`` if a shape has a fill. diff --git a/src/core/symbology/qgsellipsesymbollayer.cpp b/src/core/symbology/qgsellipsesymbollayer.cpp index 1fc9993a4235..c722049bcfac 100644 --- a/src/core/symbology/qgsellipsesymbollayer.cpp +++ b/src/core/symbology/qgsellipsesymbollayer.cpp @@ -669,7 +669,7 @@ void QgsEllipseSymbolLayer::preparePath( const QString &symbolName, QgsSymbolRen } } -bool QgsEllipseSymbolLayer::shapeIsFilled( const QString &symbolName ) const +bool QgsEllipseSymbolLayer::shapeIsFilled( const QString &symbolName ) { return symbolName == QLatin1String( "cross" ) || symbolName == QLatin1String( "arrow" ) || symbolName == QLatin1String( "half_arc" ) ? false : true; } diff --git a/src/core/symbology/qgsellipsesymbollayer.h b/src/core/symbology/qgsellipsesymbollayer.h index 9a8f93305dea..c0b50ac04999 100644 --- a/src/core/symbology/qgsellipsesymbollayer.h +++ b/src/core/symbology/qgsellipsesymbollayer.h @@ -58,7 +58,7 @@ class CORE_EXPORT QgsEllipseSymbolLayer: public QgsMarkerSymbolLayer * \returns TRUE if shape uses a fill, or FALSE if shape uses lines only * \since QGIS 3.20 */ - bool shapeIsFilled( const QString &symbolName ) const; + static bool shapeIsFilled( const QString &symbolName ); void setSize( double size ) override; diff --git a/src/gui/symbology/qgsellipsesymbollayerwidget.cpp b/src/gui/symbology/qgsellipsesymbollayerwidget.cpp index 10c7b2f5a966..caa363c4827c 100644 --- a/src/gui/symbology/qgsellipsesymbollayerwidget.cpp +++ b/src/gui/symbology/qgsellipsesymbollayerwidget.cpp @@ -121,6 +121,7 @@ void QgsEllipseSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer ) { mShapeListWidget->setCurrentItem( symbolItemList.at( 0 ) ); } + btnChangeColorFill->setEnabled( QgsEllipseSymbolLayer::shapeIsFilled( mLayer->symbolName() ) ); //set combo entries to current values blockComboSignals( true ); @@ -170,6 +171,7 @@ void QgsEllipseSymbolLayerWidget::mShapeListWidget_itemSelectionChanged() if ( item ) { mLayer->setSymbolName( item->data( Qt::UserRole ).toString() ); + btnChangeColorFill->setEnabled( QgsEllipseSymbolLayer::shapeIsFilled( mLayer->symbolName() ) ); emit changed(); } } From d5ba0d0bb621b79cb16645bc00083938438872a5 Mon Sep 17 00:00:00 2001 From: nirvn Date: Thu, 18 Mar 2021 10:20:55 +0700 Subject: [PATCH 127/377] [symbology] Fix stroke-only ellipse markers not reflecting selected state --- src/core/symbology/qgsellipsesymbollayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/symbology/qgsellipsesymbollayer.cpp b/src/core/symbology/qgsellipsesymbollayer.cpp index c722049bcfac..09fc63364d21 100644 --- a/src/core/symbology/qgsellipsesymbollayer.cpp +++ b/src/core/symbology/qgsellipsesymbollayer.cpp @@ -368,7 +368,7 @@ void QgsEllipseSymbolLayer::startRender( QgsSymbolRenderContext &context ) selPenColor.setAlphaF( context.opacity() ); } mSelBrush = QBrush( selBrushColor ); - mSelPen = QPen( selPenColor ); + mSelPen = QPen( !shapeIsFilled( mSymbolName ) ? selBrushColor : selPenColor ); mSelPen.setStyle( mStrokeStyle ); mSelPen.setWidthF( context.renderContext().convertToPainterUnits( mStrokeWidth, mStrokeWidthUnit, mStrokeWidthMapUnitScale ) ); } From 15c00d71522c708b845b52b3fee041c03846c170 Mon Sep 17 00:00:00 2001 From: nirvn Date: Thu, 18 Mar 2021 11:24:27 +0700 Subject: [PATCH 128/377] [optimization][symbology] Rely on enum for ellipse marker symbol layer shapes --- .../symbology/qgsellipsesymbollayer.sip.in | 97 ++++- src/core/symbology/qgsellipsesymbollayer.cpp | 384 +++++++++++------- src/core/symbology/qgsellipsesymbollayer.h | 84 +++- .../symbology/qgsellipsesymbollayerwidget.cpp | 35 +- tests/src/core/testqgsellipsemarker.cpp | 20 +- 5 files changed, 438 insertions(+), 182 deletions(-) diff --git a/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in b/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in index c7ac36ad8f53..272ff09b46e7 100644 --- a/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in +++ b/python/core/auto_generated/symbology/qgsellipsesymbollayer.sip.in @@ -19,6 +19,35 @@ A symbol layer for rendering objects with major and minor axis (e.g. ellipse, re #include "qgsellipsesymbollayer.h" %End public: + + enum Shape + { + Circle, + Rectangle, + Diamond, + Cross, + Arrow, + HalfArc, + Triangle, + RightHalfTriangle, + LeftHalfTriangle, + SemiCircle, + }; + + static QList< QgsEllipseSymbolLayer::Shape > availableShapes(); +%Docstring +Returns a list of all available shape types. +%End + + static bool shapeIsFilled( const QgsEllipseSymbolLayer::Shape &shape ); +%Docstring +Returns ``True`` if a ``shape`` has a fill. + +:return: ``True`` if shape uses a fill, or ``False`` if shape uses lines only + +.. versionadded:: 3.20 +%End + QgsEllipseSymbolLayer(); static QgsSymbolLayer *create( const QVariantMap &properties = QVariantMap() ) /Factory/; @@ -48,16 +77,72 @@ Creates the symbol layer virtual bool writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift = QPointF( 0.0, 0.0 ) ) const; - void setSymbolName( const QString &name ); - QString symbolName() const; + void setSymbolName( const QString &name ) /Deprecated/; +%Docstring +Sets the rendered ellipse marker shape using a symbol ``name``. - static bool shapeIsFilled( const QString &symbolName ); +.. seealso:: :py:func:`setShape` + +.. seealso:: :py:func:`shape` + +.. deprecated:: QGIS 3.20 +%End + + QString symbolName() const /Deprecated/; %Docstring -Returns ``True`` if a shape has a fill. +Returns the shape name for the rendered ellipse marker symbol. -:param symbolName: name of shape to test +.. seealso:: :py:func:`shape` -:return: ``True`` if shape uses a fill, or ``False`` if shape uses lines only +.. seealso:: :py:func:`setShape` + +.. deprecated:: QGIS 3.20 +%End + + QgsEllipseSymbolLayer::Shape shape() const; +%Docstring +Returns the shape for the rendered ellipse marker symbol. + +.. seealso:: :py:func:`setShape` + +.. versionadded:: 3.20 +%End + + void setShape( QgsEllipseSymbolLayer::Shape shape ); +%Docstring +Sets the rendered ellipse marker shape. + +:param shape: new ellipse marker shape + +.. seealso:: :py:func:`shape` + +.. versionadded:: 3.20 +%End + + static QgsEllipseSymbolLayer::Shape decodeShape( const QString &name, bool *ok = 0 ); +%Docstring +Attempts to decode a string representation of a shape name to the corresponding +shape. + +:param name: encoded shape name +:param ok: if specified, will be set to ``True`` if shape was successfully decoded + +:return: decoded name + +.. seealso:: :py:func:`encodeShape` + +.. versionadded:: 3.20 +%End + + static QString encodeShape( QgsEllipseSymbolLayer::Shape shape ); +%Docstring +Encodes a shape to its string representation. + +:param shape: shape to encode + +:return: encoded string + +.. seealso:: :py:func:`decodeShape` .. versionadded:: 3.20 %End diff --git a/src/core/symbology/qgsellipsesymbollayer.cpp b/src/core/symbology/qgsellipsesymbollayer.cpp index 09fc63364d21..6bcf5dd2edca 100644 --- a/src/core/symbology/qgsellipsesymbollayer.cpp +++ b/src/core/symbology/qgsellipsesymbollayer.cpp @@ -29,8 +29,7 @@ #include QgsEllipseSymbolLayer::QgsEllipseSymbolLayer() - : mSymbolName( QStringLiteral( "circle" ) ) - , mStrokeColor( QColor( 35, 35, 35 ) ) + : mStrokeColor( QColor( 35, 35, 35 ) ) { mColor = Qt::white; mPen.setColor( mStrokeColor ); @@ -48,7 +47,7 @@ QgsSymbolLayer *QgsEllipseSymbolLayer::create( const QVariantMap &properties ) QgsEllipseSymbolLayer *layer = new QgsEllipseSymbolLayer(); if ( properties.contains( QStringLiteral( "symbol_name" ) ) ) { - layer->setSymbolName( properties[ QStringLiteral( "symbol_name" )].toString() ); + layer->setShape( decodeShape( properties[ QStringLiteral( "symbol_name" )].toString() ) ); } if ( properties.contains( QStringLiteral( "size" ) ) ) { @@ -249,16 +248,16 @@ void QgsEllipseSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContext & mPen.setColor( penColor ); } + QgsEllipseSymbolLayer::Shape shape = mShape; if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyWidth ) || mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyHeight ) || mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyName ) ) { - QString symbolName = mSymbolName; - context.setOriginalValueVariable( mSymbolName ); + context.setOriginalValueVariable( encodeShape( shape ) ); QVariant exprVal = mDataDefinedProperties.value( QgsSymbolLayer::PropertyName, context.renderContext().expressionContext() ); if ( exprVal.isValid() ) { - symbolName = exprVal.toString(); + shape = decodeShape( exprVal.toString() ); } - preparePath( symbolName, context, &scaledWidth, &scaledHeight, context.feature() ); + preparePath( shape, context, &scaledWidth, &scaledHeight, context.feature() ); } //offset and rotation @@ -280,7 +279,7 @@ void QgsEllipseSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContext & transform.rotate( angle ); } - if ( shapeIsFilled( mSymbolName ) ) + if ( shapeIsFilled( shape ) ) { p->setPen( context.selected() ? mSelPen : mPen ); p->setBrush( context.selected() ? mSelBrush : mBrush ); @@ -351,7 +350,7 @@ void QgsEllipseSymbolLayer::startRender( QgsSymbolRenderContext &context ) QgsMarkerSymbolLayer::startRender( context ); // get anchor point expressions if ( !context.feature() || !dataDefinedProperties().hasActiveProperties() ) { - preparePath( mSymbolName, context ); + preparePath( mShape, context ); } mPen.setColor( mStrokeColor ); mPen.setStyle( mStrokeStyle ); @@ -368,7 +367,7 @@ void QgsEllipseSymbolLayer::startRender( QgsSymbolRenderContext &context ) selPenColor.setAlphaF( context.opacity() ); } mSelBrush = QBrush( selBrushColor ); - mSelPen = QPen( !shapeIsFilled( mSymbolName ) ? selBrushColor : selPenColor ); + mSelPen = QPen( !shapeIsFilled( mShape ) ? selBrushColor : selPenColor ); mSelPen.setStyle( mStrokeStyle ); mSelPen.setWidthF( context.renderContext().convertToPainterUnits( mStrokeWidth, mStrokeWidthUnit, mStrokeWidthMapUnitScale ) ); } @@ -380,7 +379,7 @@ void QgsEllipseSymbolLayer::stopRender( QgsSymbolRenderContext & ) QgsEllipseSymbolLayer *QgsEllipseSymbolLayer::clone() const { QgsEllipseSymbolLayer *m = new QgsEllipseSymbolLayer(); - m->setSymbolName( mSymbolName ); + m->setShape( mShape ); m->setSymbolWidth( mSymbolWidth ); m->setSymbolHeight( mSymbolHeight ); m->setStrokeStyle( mStrokeStyle ); @@ -429,7 +428,7 @@ void QgsEllipseSymbolLayer::writeSldMarker( QDomDocument &doc, QDomElement &elem double strokeWidth = QgsSymbolLayerUtils::rescaleUom( mStrokeWidth, mStrokeWidthUnit, props ); double symbolWidth = QgsSymbolLayerUtils::rescaleUom( mSymbolWidth, mSymbolWidthUnit, props ); - QgsSymbolLayerUtils::wellKnownMarkerToSld( doc, graphicElem, mSymbolName, mColor, mStrokeColor, mStrokeStyle, strokeWidth, symbolWidth ); + QgsSymbolLayerUtils::wellKnownMarkerToSld( doc, graphicElem, encodeShape( mShape ), mColor, mStrokeColor, mStrokeStyle, strokeWidth, symbolWidth ); // QgsProperty ddRotation = mDataDefinedProperties.property( QgsSymbolLayer::PropertyAngle ); @@ -523,7 +522,7 @@ QgsSymbolLayer *QgsEllipseSymbolLayer::createFromSld( QDomElement &element ) QgsEllipseSymbolLayer *m = new QgsEllipseSymbolLayer(); m->setOutputUnit( QgsUnitTypes::RenderUnit::RenderPixels ); - m->setSymbolName( name ); + m->setShape( decodeShape( name ) ); m->setFillColor( fillColor ); m->setStrokeColor( strokeColor ); m->setStrokeStyle( strokeStyle ); @@ -537,7 +536,7 @@ QgsSymbolLayer *QgsEllipseSymbolLayer::createFromSld( QDomElement &element ) QVariantMap QgsEllipseSymbolLayer::properties() const { QVariantMap map; - map[QStringLiteral( "symbol_name" )] = mSymbolName; + map[QStringLiteral( "symbol_name" )] = encodeShape( mShape ); map[QStringLiteral( "symbol_width" )] = QString::number( mSymbolWidth ); map[QStringLiteral( "symbol_width_unit" )] = QgsUnitTypes::encodeUnit( mSymbolWidthUnit ); map[QStringLiteral( "symbol_width_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mSymbolWidthMapUnitScale ); @@ -601,77 +600,96 @@ QSizeF QgsEllipseSymbolLayer::calculateSize( QgsSymbolRenderContext &context, do return QSizeF( width, height ); } -void QgsEllipseSymbolLayer::preparePath( const QString &symbolName, QgsSymbolRenderContext &context, double *scaledWidth, double *scaledHeight, const QgsFeature * ) +void QgsEllipseSymbolLayer::preparePath( const QgsEllipseSymbolLayer::Shape &shape, QgsSymbolRenderContext &context, double *scaledWidth, double *scaledHeight, const QgsFeature * ) { mPainterPath = QPainterPath(); QSizeF size = calculateSize( context, scaledWidth, scaledHeight ); - if ( symbolName == QLatin1String( "circle" ) ) - { - mPainterPath.addEllipse( QRectF( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height() ) ); - } - else if ( symbolName == QLatin1String( "semi_circle" ) ) - { - mPainterPath.arcTo( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height(), 0, 180 ); - mPainterPath.lineTo( 0, 0 ); - } - else if ( symbolName == QLatin1String( "rectangle" ) ) - { - mPainterPath.addRect( QRectF( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height() ) ); - } - else if ( symbolName == QLatin1String( "diamond" ) ) - { - mPainterPath.moveTo( -size.width() / 2.0, 0 ); - mPainterPath.lineTo( 0, size.height() / 2.0 ); - mPainterPath.lineTo( size.width() / 2.0, 0 ); - mPainterPath.lineTo( 0, -size.height() / 2.0 ); - mPainterPath.lineTo( -size.width() / 2.0, 0 ); - } - else if ( symbolName == QLatin1String( "cross" ) ) - { - mPainterPath.moveTo( 0, -size.height() / 2.0 ); - mPainterPath.lineTo( 0, size.height() / 2.0 ); - mPainterPath.moveTo( -size.width() / 2.0, 0 ); - mPainterPath.lineTo( size.width() / 2.0, 0 ); - } - else if ( symbolName == QLatin1String( "arrow" ) ) - { - mPainterPath.moveTo( -size.width() / 2.0, size.height() / 2.0 ); - mPainterPath.lineTo( 0, -size.height() / 2.0 ); - mPainterPath.lineTo( size.width() / 2.0, size.height() / 2.0 ); - } - else if ( symbolName == QLatin1String( "half_arc" ) ) - { - mPainterPath.moveTo( size.width() / 2.0, 0 ); - mPainterPath.arcTo( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height(), 0, 180 ); - } - else if ( symbolName == QLatin1String( "triangle" ) ) - { - mPainterPath.moveTo( 0, -size.height() / 2.0 ); - mPainterPath.lineTo( -size.width() / 2.0, size.height() / 2.0 ); - mPainterPath.lineTo( size.width() / 2.0, size.height() / 2.0 ); - mPainterPath.lineTo( 0, -size.height() / 2.0 ); - } - else if ( symbolName == QLatin1String( "left_half_triangle" ) ) - { - mPainterPath.moveTo( 0, size.height() / 2.0 ); - mPainterPath.lineTo( size.width() / 2.0, size.height() / 2.0 ); - mPainterPath.lineTo( 0, -size.height() / 2.0 ); - mPainterPath.lineTo( 0, size.height() / 2.0 ); - } - else if ( symbolName == QLatin1String( "right_half_triangle" ) ) - { - mPainterPath.moveTo( -size.width() / 2.0, size.height() / 2.0 ); - mPainterPath.lineTo( 0, size.height() / 2.0 ); - mPainterPath.lineTo( 0, -size.height() / 2.0 ); - mPainterPath.lineTo( -size.width() / 2.0, size.height() / 2.0 ); + switch ( shape ) + { + case Circle: + mPainterPath.addEllipse( QRectF( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height() ) ); + return; + + case SemiCircle: + mPainterPath.arcTo( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height(), 0, 180 ); + mPainterPath.lineTo( 0, 0 ); + return; + + case Rectangle: + mPainterPath.addRect( QRectF( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height() ) ); + return; + + case Diamond: + mPainterPath.moveTo( -size.width() / 2.0, 0 ); + mPainterPath.lineTo( 0, size.height() / 2.0 ); + mPainterPath.lineTo( size.width() / 2.0, 0 ); + mPainterPath.lineTo( 0, -size.height() / 2.0 ); + mPainterPath.lineTo( -size.width() / 2.0, 0 ); + return; + + case Cross: + mPainterPath.moveTo( 0, -size.height() / 2.0 ); + mPainterPath.lineTo( 0, size.height() / 2.0 ); + mPainterPath.moveTo( -size.width() / 2.0, 0 ); + mPainterPath.lineTo( size.width() / 2.0, 0 ); + return; + + case Arrow: + mPainterPath.moveTo( -size.width() / 2.0, size.height() / 2.0 ); + mPainterPath.lineTo( 0, -size.height() / 2.0 ); + mPainterPath.lineTo( size.width() / 2.0, size.height() / 2.0 ); + return; + + case HalfArc: + mPainterPath.moveTo( size.width() / 2.0, 0 ); + mPainterPath.arcTo( -size.width() / 2.0, -size.height() / 2.0, size.width(), size.height(), 0, 180 ); + return; + + case Triangle: + mPainterPath.moveTo( 0, -size.height() / 2.0 ); + mPainterPath.lineTo( -size.width() / 2.0, size.height() / 2.0 ); + mPainterPath.lineTo( size.width() / 2.0, size.height() / 2.0 ); + mPainterPath.lineTo( 0, -size.height() / 2.0 ); + return; + + case LeftHalfTriangle: + mPainterPath.moveTo( 0, size.height() / 2.0 ); + mPainterPath.lineTo( size.width() / 2.0, size.height() / 2.0 ); + mPainterPath.lineTo( 0, -size.height() / 2.0 ); + mPainterPath.lineTo( 0, size.height() / 2.0 ); + return; + + case RightHalfTriangle: + mPainterPath.moveTo( -size.width() / 2.0, size.height() / 2.0 ); + mPainterPath.lineTo( 0, size.height() / 2.0 ); + mPainterPath.lineTo( 0, -size.height() / 2.0 ); + mPainterPath.lineTo( -size.width() / 2.0, size.height() / 2.0 ); + return; } } -bool QgsEllipseSymbolLayer::shapeIsFilled( const QString &symbolName ) +bool QgsEllipseSymbolLayer::shapeIsFilled( const QgsEllipseSymbolLayer::Shape &shape ) { - return symbolName == QLatin1String( "cross" ) || symbolName == QLatin1String( "arrow" ) || symbolName == QLatin1String( "half_arc" ) ? false : true; + switch ( shape ) + { + case Circle: + case Rectangle: + case Diamond: + case Triangle: + case RightHalfTriangle: + case LeftHalfTriangle: + case SemiCircle: + return true; + + case Cross: + case Arrow: + case HalfArc: + return false; + } + + return true; } void QgsEllipseSymbolLayer::setSize( double size ) @@ -865,11 +883,11 @@ bool QgsEllipseSymbolLayer::writeDxf( QgsDxfExport &e, double mmMapUnitScaleFact } //symbol name - QString symbolName = mSymbolName; + QgsEllipseSymbolLayer::Shape shape = mShape; if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyName ) ) { - context.setOriginalValueVariable( mSymbolName ); - symbolName = mDataDefinedProperties.valueAsString( QgsSymbolLayer::PropertyName, context.renderContext().expressionContext(), mSymbolName ); + context.setOriginalValueVariable( encodeShape( shape ) ); + shape = decodeShape( mDataDefinedProperties.valueAsString( QgsSymbolLayer::PropertyName, context.renderContext().expressionContext(), encodeShape( shape ) ) ); } //offset @@ -902,76 +920,168 @@ bool QgsEllipseSymbolLayer::writeDxf( QgsDxfExport &e, double mmMapUnitScaleFact double halfWidth = symbolWidth / 2.0; double halfHeight = symbolHeight / 2.0; - if ( symbolName == QLatin1String( "circle" ) ) + switch ( shape ) { - if ( qgsDoubleNear( halfWidth, halfHeight ) ) + case Circle: { - QgsPoint pt( t.map( QPointF( 0, 0 ) ) ); - e.writeFilledCircle( layerName, oc, pt, halfWidth ); + if ( qgsDoubleNear( halfWidth, halfHeight ) ) + { + QgsPoint pt( t.map( QPointF( 0, 0 ) ) ); + e.writeFilledCircle( layerName, oc, pt, halfWidth ); + } + else + { + QgsPointSequence line; + + double stepsize = 2 * M_PI / 40; + for ( int i = 0; i < 39; ++i ) + { + double angle = stepsize * i; + double x = halfWidth * std::cos( angle ); + double y = halfHeight * std::sin( angle ); + line << QgsPoint( t.map( QPointF( x, y ) ) ); + } + //close ellipse with first point + line << line.at( 0 ); + + if ( mBrush.style() != Qt::NoBrush ) + e.writePolygon( QgsRingSequence() << line, layerName, QStringLiteral( "SOLID" ), fc ); + if ( mPen.style() != Qt::NoPen ) + e.writePolyline( line, layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth ); + } + return true; } - else + + case Rectangle: { - QgsPointSequence line; + QgsPointSequence p; + p << QgsPoint( t.map( QPointF( -halfWidth, -halfHeight ) ) ) + << QgsPoint( t.map( QPointF( halfWidth, -halfHeight ) ) ) + << QgsPoint( t.map( QPointF( halfWidth, halfHeight ) ) ) + << QgsPoint( t.map( QPointF( -halfWidth, halfHeight ) ) ); + p << p[0]; - double stepsize = 2 * M_PI / 40; - for ( int i = 0; i < 39; ++i ) + if ( mBrush.style() != Qt::NoBrush ) + e.writePolygon( QgsRingSequence() << p, layerName, QStringLiteral( "SOLID" ), fc ); + if ( mPen.style() != Qt::NoPen ) + e.writePolyline( p, layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth ); + return true; + } + case Cross: + { + if ( mPen.style() != Qt::NoPen ) { - double angle = stepsize * i; - double x = halfWidth * std::cos( angle ); - double y = halfHeight * std::sin( angle ); - line << QgsPoint( t.map( QPointF( x, y ) ) ); + e.writePolyline( QgsPointSequence() + << QgsPoint( t.map( QPointF( -halfWidth, 0 ) ) ) + << QgsPoint( t.map( QPointF( halfWidth, 0 ) ) ), + layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth ); + e.writePolyline( QgsPointSequence() + << QgsPoint( t.map( QPointF( 0, halfHeight ) ) ) + << QgsPoint( t.map( QPointF( 0, -halfHeight ) ) ), + layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth ); + return true; } - //close ellipse with first point - line << line.at( 0 ); + break; + } + case Triangle: + { + QgsPointSequence p; + p << QgsPoint( t.map( QPointF( -halfWidth, -halfHeight ) ) ) + << QgsPoint( t.map( QPointF( halfWidth, -halfHeight ) ) ) + << QgsPoint( t.map( QPointF( 0, halfHeight ) ) ); + p << p[0]; if ( mBrush.style() != Qt::NoBrush ) - e.writePolygon( QgsRingSequence() << line, layerName, QStringLiteral( "SOLID" ), fc ); + e.writePolygon( QgsRingSequence() << p, layerName, QStringLiteral( "SOLID" ), fc ); if ( mPen.style() != Qt::NoPen ) - e.writePolyline( line, layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth ); + e.writePolyline( p, layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth ); + return true; } + + case Diamond: + case Arrow: + case HalfArc: + case RightHalfTriangle: + case LeftHalfTriangle: + case SemiCircle: + return false; } - else if ( symbolName == QLatin1String( "rectangle" ) ) - { - QgsPointSequence p; - p << QgsPoint( t.map( QPointF( -halfWidth, -halfHeight ) ) ) - << QgsPoint( t.map( QPointF( halfWidth, -halfHeight ) ) ) - << QgsPoint( t.map( QPointF( halfWidth, halfHeight ) ) ) - << QgsPoint( t.map( QPointF( -halfWidth, halfHeight ) ) ); - p << p[0]; - - if ( mBrush.style() != Qt::NoBrush ) - e.writePolygon( QgsRingSequence() << p, layerName, QStringLiteral( "SOLID" ), fc ); - if ( mPen.style() != Qt::NoPen ) - e.writePolyline( p, layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth ); - return true; - } - else if ( symbolName == QLatin1String( "cross" ) && mPen.style() != Qt::NoPen ) - { - e.writePolyline( QgsPointSequence() - << QgsPoint( t.map( QPointF( -halfWidth, 0 ) ) ) - << QgsPoint( t.map( QPointF( halfWidth, 0 ) ) ), - layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth ); - e.writePolyline( QgsPointSequence() - << QgsPoint( t.map( QPointF( 0, halfHeight ) ) ) - << QgsPoint( t.map( QPointF( 0, -halfHeight ) ) ), - layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth ); - return true; - } - else if ( symbolName == QLatin1String( "triangle" ) ) - { - QgsPointSequence p; - p << QgsPoint( t.map( QPointF( -halfWidth, -halfHeight ) ) ) - << QgsPoint( t.map( QPointF( halfWidth, -halfHeight ) ) ) - << QgsPoint( t.map( QPointF( 0, halfHeight ) ) ); - p << p[0]; - if ( mBrush.style() != Qt::NoBrush ) - e.writePolygon( QgsRingSequence() << p, layerName, QStringLiteral( "SOLID" ), fc ); - if ( mPen.style() != Qt::NoPen ) - e.writePolyline( p, layerName, QStringLiteral( "CONTINUOUS" ), oc, strokeWidth ); - return true; - } - - return false; //soon... + + return false; } +QgsEllipseSymbolLayer::Shape QgsEllipseSymbolLayer::decodeShape( const QString &name, bool *ok ) +{ + if ( ok ) + *ok = true; + QString cleaned = name.toLower().trimmed(); + + if ( cleaned == QLatin1String( "circle" ) ) + return Circle; + else if ( cleaned == QLatin1String( "square" ) || cleaned == QLatin1String( "rectangle" ) ) + return Rectangle; + else if ( cleaned == QLatin1String( "diamond" ) ) + return Diamond; + else if ( cleaned == QLatin1String( "cross" ) ) + return Cross; + else if ( cleaned == QLatin1String( "arrow" ) ) + return Arrow; + else if ( cleaned == QLatin1String( "half_arc" ) ) + return HalfArc; + else if ( cleaned == QLatin1String( "triangle" ) ) + return Triangle; + else if ( cleaned == QLatin1String( "right_half_triangle" ) ) + return RightHalfTriangle; + else if ( cleaned == QLatin1String( "left_half_triangle" ) ) + return LeftHalfTriangle; + else if ( cleaned == QLatin1String( "semi_circle" ) ) + return SemiCircle; + + if ( ok ) + *ok = false; + return Circle; +} +QString QgsEllipseSymbolLayer::encodeShape( QgsEllipseSymbolLayer::Shape shape ) +{ + switch ( shape ) + { + case Circle: + return QStringLiteral( "circle" ); + case Rectangle: + return QStringLiteral( "rectangle" ); + case Diamond: + return QStringLiteral( "diamond" ); + case Cross: + return QStringLiteral( "cross" ); + case Arrow: + return QStringLiteral( "arrow" ); + case HalfArc: + return QStringLiteral( "half_arc" ); + case Triangle: + return QStringLiteral( "triangle" ); + case RightHalfTriangle: + return QStringLiteral( "right_half_triangle" ); + case LeftHalfTriangle: + return QStringLiteral( "left_half_triangle" ); + case SemiCircle: + return QStringLiteral( "semi_circle" ); + } + return QString(); +} + +QList QgsEllipseSymbolLayer::availableShapes() +{ + QList< Shape > shapes; + shapes << Circle + << Rectangle + << Diamond + << Cross + << Arrow + << HalfArc + << Triangle + << LeftHalfTriangle + << RightHalfTriangle + << SemiCircle; + return shapes; +} diff --git a/src/core/symbology/qgsellipsesymbollayer.h b/src/core/symbology/qgsellipsesymbollayer.h index c0b50ac04999..f359d901e261 100644 --- a/src/core/symbology/qgsellipsesymbollayer.h +++ b/src/core/symbology/qgsellipsesymbollayer.h @@ -31,6 +31,32 @@ class QgsExpression; class CORE_EXPORT QgsEllipseSymbolLayer: public QgsMarkerSymbolLayer { public: + + //! Marker symbol shapes + enum Shape + { + Circle, //!< Circle + Rectangle, //!< Rectangle + Diamond, //!< Diamond + Cross, //!< Stroke-only cross + Arrow, //!< Stroke-only arrow (since QGIS 3.20) + HalfArc, //!< Stroke-only half arc (since QGIS 3.20) + Triangle, //!< Triangle + RightHalfTriangle, //!< Right half of a triangle + LeftHalfTriangle, //!< Left half of a triangle + SemiCircle, //!< Semi circle + }; + + //! Returns a list of all available shape types. + static QList< QgsEllipseSymbolLayer::Shape > availableShapes(); + + /** + * Returns TRUE if a \a shape has a fill. + * \returns TRUE if shape uses a fill, or FALSE if shape uses lines only + * \since QGIS 3.20 + */ + static bool shapeIsFilled( const QgsEllipseSymbolLayer::Shape &shape ); + QgsEllipseSymbolLayer(); //! Creates the symbol layer @@ -49,16 +75,56 @@ class CORE_EXPORT QgsEllipseSymbolLayer: public QgsMarkerSymbolLayer bool writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift = QPointF( 0.0, 0.0 ) ) const override; - void setSymbolName( const QString &name ) { mSymbolName = name; } - QString symbolName() const { return mSymbolName; } + /** + * Sets the rendered ellipse marker shape using a symbol \a name. + * \see setShape() + * \see shape() + * \deprecated since QGIS 3.20 + */ + Q_DECL_DEPRECATED void setSymbolName( const QString &name ) SIP_DEPRECATED { mShape = decodeShape( name ); } /** - * Returns TRUE if a shape has a fill. - * \param symbolName name of shape to test - * \returns TRUE if shape uses a fill, or FALSE if shape uses lines only + * Returns the shape name for the rendered ellipse marker symbol. + * \see shape() + * \see setShape() + * \deprecated since QGIS 3.20 + */ + Q_DECL_DEPRECATED QString symbolName() const SIP_DEPRECATED { return encodeShape( mShape ); } + + /** + * Returns the shape for the rendered ellipse marker symbol. + * \see setShape() + * \since QGIS 3.20 + */ + QgsEllipseSymbolLayer::Shape shape() const { return mShape; } + + /** + * Sets the rendered ellipse marker shape. + * \param shape new ellipse marker shape + * \see shape() + * \since QGIS 3.20 + */ + void setShape( QgsEllipseSymbolLayer::Shape shape ) { mShape = shape; } + + /** + * Attempts to decode a string representation of a shape name to the corresponding + * shape. + * \param name encoded shape name + * \param ok if specified, will be set to TRUE if shape was successfully decoded + * \returns decoded name + * \see encodeShape() + * \since QGIS 3.20 + */ + static QgsEllipseSymbolLayer::Shape decodeShape( const QString &name, bool *ok = nullptr ); + + /** + * Encodes a shape to its string representation. + * \param shape shape to encode + * \returns encoded string + * \see decodeShape() * \since QGIS 3.20 */ - static bool shapeIsFilled( const QString &symbolName ); + static QString encodeShape( QgsEllipseSymbolLayer::Shape shape ); void setSize( double size ) override; @@ -174,7 +240,7 @@ class CORE_EXPORT QgsEllipseSymbolLayer: public QgsMarkerSymbolLayer QRectF bounds( QPointF point, QgsSymbolRenderContext &context ) override; private: - QString mSymbolName; + Shape mShape = Circle; double mSymbolWidth = 4; QgsUnitTypes::RenderUnit mSymbolWidthUnit = QgsUnitTypes::RenderMillimeters; QgsMapUnitScale mSymbolWidthMapUnitScale; @@ -200,13 +266,13 @@ class CORE_EXPORT QgsEllipseSymbolLayer: public QgsMarkerSymbolLayer /** * Setup mPainterPath - * \param symbolName name of symbol + * \param shape name of symbol * \param context render context * \param scaledWidth optional width * \param scaledHeight optional height * \param f optional feature to render (0 if no data defined rendering) */ - void preparePath( const QString &symbolName, QgsSymbolRenderContext &context, double *scaledWidth = nullptr, double *scaledHeight = nullptr, const QgsFeature *f = nullptr ); + void preparePath( const QgsEllipseSymbolLayer::Shape &shape, QgsSymbolRenderContext &context, double *scaledWidth = nullptr, double *scaledHeight = nullptr, const QgsFeature *f = nullptr ); QSizeF calculateSize( QgsSymbolRenderContext &context, double *scaledWidth = nullptr, double *scaledHeight = nullptr ); void calculateOffsetAndRotation( QgsSymbolRenderContext &context, double scaledWidth, double scaledHeight, bool &hasDataDefinedRotation, QPointF &offset, double &angle ) const; }; diff --git a/src/gui/symbology/qgsellipsesymbollayerwidget.cpp b/src/gui/symbology/qgsellipsesymbollayerwidget.cpp index caa363c4827c..6caeda2c127f 100644 --- a/src/gui/symbology/qgsellipsesymbollayerwidget.cpp +++ b/src/gui/symbology/qgsellipsesymbollayerwidget.cpp @@ -65,30 +65,27 @@ QgsEllipseSymbolLayerWidget::QgsEllipseSymbolLayerWidget( QgsVectorLayer *vl, QW spinOffsetY->setClearValue( 0.0 ); mRotationSpinBox->setClearValue( 0.0 ); - QStringList names; - names << QStringLiteral( "circle" ) << QStringLiteral( "rectangle" ) << QStringLiteral( "diamond" ) << QStringLiteral( "cross" ) << QStringLiteral( "arrow" ) << QStringLiteral( "half_arc" ) << QStringLiteral( "triangle" ) << QStringLiteral( "right_half_triangle" ) << QStringLiteral( "left_half_triangle" ) << QStringLiteral( "semi_circle" ); - int size = mShapeListWidget->iconSize().width(); size = std::max( 30, static_cast< int >( std::round( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 3 ) ) ); mShapeListWidget->setGridSize( QSize( size * 1.2, size * 1.2 ) ); mShapeListWidget->setIconSize( QSize( size, size ) ); double markerSize = size * 0.8; - const auto constNames = names; - for ( const QString &name : constNames ) + const auto shapes = QgsEllipseSymbolLayer::availableShapes(); + for ( QgsEllipseSymbolLayer::Shape shape : shapes ) { QgsEllipseSymbolLayer *lyr = new QgsEllipseSymbolLayer(); lyr->setSymbolWidthUnit( QgsUnitTypes::RenderPixels ); lyr->setSymbolHeightUnit( QgsUnitTypes::RenderPixels ); - lyr->setSymbolName( name ); + lyr->setShape( shape ); lyr->setStrokeColor( QColor( 0, 0, 0 ) ); lyr->setFillColor( QColor( 200, 200, 200 ) ); lyr->setSymbolWidth( markerSize ); lyr->setSymbolHeight( markerSize * 0.75 ); QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( lyr, QgsUnitTypes::RenderPixels, QSize( size, size ) ); QListWidgetItem *item = new QListWidgetItem( icon, QString(), mShapeListWidget ); - item->setToolTip( name ); - item->setData( Qt::UserRole, name ); + item->setData( Qt::UserRole, static_cast< int >( shape ) ); + item->setToolTip( QgsEllipseSymbolLayer::encodeShape( shape ) ); delete lyr; } // show at least 2 rows (only 1 row is required, but looks too cramped) @@ -116,12 +113,16 @@ void QgsEllipseSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer ) btnChangeColorStroke->setColor( mLayer->strokeColor() ); btnChangeColorFill->setColor( mLayer->fillColor() ); - QList symbolItemList = mShapeListWidget->findItems( mLayer->symbolName(), Qt::MatchExactly ); - if ( !symbolItemList.isEmpty() ) + QgsEllipseSymbolLayer::Shape shape = mLayer->shape(); + for ( int i = 0; i < mShapeListWidget->count(); ++i ) { - mShapeListWidget->setCurrentItem( symbolItemList.at( 0 ) ); + if ( static_cast< QgsEllipseSymbolLayer::Shape >( mShapeListWidget->item( i )->data( Qt::UserRole ).toInt() ) == shape ) + { + mShapeListWidget->setCurrentRow( i ); + break; + } } - btnChangeColorFill->setEnabled( QgsEllipseSymbolLayer::shapeIsFilled( mLayer->symbolName() ) ); + btnChangeColorFill->setEnabled( QgsEllipseSymbolLayer::shapeIsFilled( mLayer->shape() ) ); //set combo entries to current values blockComboSignals( true ); @@ -167,13 +168,9 @@ void QgsEllipseSymbolLayerWidget::mShapeListWidget_itemSelectionChanged() { if ( mLayer ) { - QListWidgetItem *item = mShapeListWidget->currentItem(); - if ( item ) - { - mLayer->setSymbolName( item->data( Qt::UserRole ).toString() ); - btnChangeColorFill->setEnabled( QgsEllipseSymbolLayer::shapeIsFilled( mLayer->symbolName() ) ); - emit changed(); - } + mLayer->setShape( static_cast< QgsEllipseSymbolLayer::Shape>( mShapeListWidget->currentItem()->data( Qt::UserRole ).toInt() ) ); + btnChangeColorFill->setEnabled( QgsEllipseSymbolLayer::shapeIsFilled( mLayer->shape() ) ); + emit changed(); } } diff --git a/tests/src/core/testqgsellipsemarker.cpp b/tests/src/core/testqgsellipsemarker.cpp index 911bdd485b63..39c283a42447 100644 --- a/tests/src/core/testqgsellipsemarker.cpp +++ b/tests/src/core/testqgsellipsemarker.cpp @@ -135,7 +135,7 @@ void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbol() mEllipseMarkerLayer->setFillColor( Qt::blue ); mEllipseMarkerLayer->setStrokeColor( Qt::black ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "circle" ) ); + mEllipseMarkerLayer->setShape( QgsEllipseSymbolLayer::Circle ); mEllipseMarkerLayer->setSymbolHeight( 3 ); mEllipseMarkerLayer->setSymbolWidth( 6 ); mEllipseMarkerLayer->setStrokeWidth( 0.8 ); @@ -163,7 +163,7 @@ void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolBevelJoin() mEllipseMarkerLayer->setFillColor( Qt::blue ); mEllipseMarkerLayer->setStrokeColor( Qt::black ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "triangle" ) ); + mEllipseMarkerLayer->setShape( QgsEllipseSymbolLayer::Triangle ); mEllipseMarkerLayer->setSymbolHeight( 25 ); mEllipseMarkerLayer->setSymbolWidth( 20 ); mEllipseMarkerLayer->setStrokeWidth( 3 ); @@ -177,7 +177,7 @@ void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolMiterJoin() mEllipseMarkerLayer->setFillColor( Qt::blue ); mEllipseMarkerLayer->setStrokeColor( Qt::black ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "triangle" ) ); + mEllipseMarkerLayer->setShape( QgsEllipseSymbolLayer::Triangle ); mEllipseMarkerLayer->setSymbolHeight( 25 ); mEllipseMarkerLayer->setSymbolWidth( 20 ); mEllipseMarkerLayer->setStrokeWidth( 3 ); @@ -191,7 +191,7 @@ void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolRoundJoin() mEllipseMarkerLayer->setFillColor( Qt::blue ); mEllipseMarkerLayer->setStrokeColor( Qt::black ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "triangle" ) ); + mEllipseMarkerLayer->setShape( QgsEllipseSymbolLayer::Triangle ); mEllipseMarkerLayer->setSymbolHeight( 25 ); mEllipseMarkerLayer->setSymbolWidth( 20 ); mEllipseMarkerLayer->setStrokeWidth( 3 ); @@ -205,7 +205,7 @@ void TestQgsEllipseMarkerSymbol::ellipseMarkerSymbolCapStyle() mEllipseMarkerLayer->setColor( Qt::blue ); mEllipseMarkerLayer->setStrokeColor( Qt::black ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "cross" ) ); + mEllipseMarkerLayer->setShape( QgsEllipseSymbolLayer::Cross ); mEllipseMarkerLayer->setSymbolWidth( 35 ); mEllipseMarkerLayer->setSymbolHeight( 15 ); mEllipseMarkerLayer->setStrokeWidth( 3 ); @@ -217,7 +217,7 @@ void TestQgsEllipseMarkerSymbol::selected() { mEllipseMarkerLayer->setFillColor( Qt::blue ); mEllipseMarkerLayer->setStrokeColor( Qt::black ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "triangle" ) ); + mEllipseMarkerLayer->setShape( QgsEllipseSymbolLayer::Triangle ); mEllipseMarkerLayer->setSymbolHeight( 25 ); mEllipseMarkerLayer->setSymbolWidth( 20 ); mEllipseMarkerLayer->setStrokeWidth( 3 ); @@ -233,7 +233,7 @@ void TestQgsEllipseMarkerSymbol::bounds() { mEllipseMarkerLayer->setFillColor( Qt::blue ); mEllipseMarkerLayer->setStrokeColor( Qt::black ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "circle" ) ); + mEllipseMarkerLayer->setShape( QgsEllipseSymbolLayer::Circle ); mEllipseMarkerLayer->setSymbolHeight( 3 ); mEllipseMarkerLayer->setSymbolWidth( 6 ); mEllipseMarkerLayer->setDataDefinedProperty( QgsSymbolLayer::PropertySize, QgsProperty::fromExpression( QStringLiteral( "min(\"importance\" * 2, 6)" ) ) ); @@ -249,8 +249,7 @@ void TestQgsEllipseMarkerSymbol::opacityWithDataDefinedColor() { mEllipseMarkerLayer->setColor( QColor( 200, 200, 200 ) ); mEllipseMarkerLayer->setStrokeColor( QColor( 0, 0, 0 ) ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "circle" ) ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "circle" ) ); + mEllipseMarkerLayer->setShape( QgsEllipseSymbolLayer::Circle ); mEllipseMarkerLayer->setSymbolHeight( 3 ); mEllipseMarkerLayer->setSymbolWidth( 6 ); mEllipseMarkerLayer->setDataDefinedProperty( QgsSymbolLayer::PropertyFillColor, QgsProperty::fromExpression( QStringLiteral( "if(importance > 2, 'red', 'green')" ) ) ); @@ -269,8 +268,7 @@ void TestQgsEllipseMarkerSymbol::dataDefinedOpacity() { mEllipseMarkerLayer->setColor( QColor( 200, 200, 200 ) ); mEllipseMarkerLayer->setStrokeColor( QColor( 0, 0, 0 ) ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "circle" ) ); - mEllipseMarkerLayer->setSymbolName( QStringLiteral( "circle" ) ); + mEllipseMarkerLayer->setShape( QgsEllipseSymbolLayer::Circle ); mEllipseMarkerLayer->setSymbolHeight( 3 ); mEllipseMarkerLayer->setSymbolWidth( 6 ); mEllipseMarkerLayer->setDataDefinedProperty( QgsSymbolLayer::PropertyFillColor, QgsProperty::fromExpression( QStringLiteral( "if(importance > 2, 'red', 'green')" ) ) ); From 7f19211ad1e777125f3f20aba267fb7b2cfabdec Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Wed, 3 Mar 2021 07:07:16 +0100 Subject: [PATCH 129/377] Remove "stale" label when a comment is added This means, someone still cares. We will still need to take care of manually removing the "feedback" label --- .github/workflows/unstale.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/unstale.yml diff --git a/.github/workflows/unstale.yml b/.github/workflows/unstale.yml new file mode 100644 index 000000000000..922a9f0083bd --- /dev/null +++ b/.github/workflows/unstale.yml @@ -0,0 +1,16 @@ +name: Remove Labels + +on: [issue_comment] + +jobs: + remove_labels: + if: contains(github.event.issue.labels.*.name, 'stale') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-ecosystem/action-remove-labels@v1 + if: ${{ github.event.comment.user.url != 'https://github.com/apps/github-actions' }} + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + labels: | + stale From 12354dc329052158da99b747cc1d396392117581 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Wed, 3 Mar 2021 08:12:07 +0100 Subject: [PATCH 130/377] No need to checkout --- .github/workflows/unstale.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/unstale.yml b/.github/workflows/unstale.yml index 922a9f0083bd..5c9eaf26303e 100644 --- a/.github/workflows/unstale.yml +++ b/.github/workflows/unstale.yml @@ -7,7 +7,6 @@ jobs: if: contains(github.event.issue.labels.*.name, 'stale') runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - uses: actions-ecosystem/action-remove-labels@v1 if: ${{ github.event.comment.user.url != 'https://github.com/apps/github-actions' }} with: From f5968d1f4053369007ced04beaa99df3407e2167 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 19 Mar 2021 14:49:33 +1000 Subject: [PATCH 131/377] Move code for generating the annotation "balloon" style background shape out into a new class so that it can be reused elsewhere --- src/core/CMakeLists.txt | 2 + src/core/annotations/qgsannotation.cpp | 173 ++----------------------- src/core/annotations/qgsannotation.h | 15 --- src/core/qgsshapegenerator.cpp | 150 +++++++++++++++++++++ src/core/qgsshapegenerator.h | 53 ++++++++ 5 files changed, 217 insertions(+), 176 deletions(-) create mode 100644 src/core/qgsshapegenerator.cpp create mode 100644 src/core/qgsshapegenerator.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 6cf31b34b7fa..a77d19bbe46f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -426,6 +426,7 @@ set(QGIS_CORE_SRCS qgsruntimeprofiler.cpp qgsscalecalculator.cpp qgsscaleutils.cpp + qgsshapegenerator.cpp qgssimplifymethod.cpp qgssnappingutils.cpp qgsspatialindex.cpp @@ -1033,6 +1034,7 @@ set(QGIS_CORE_HDRS qgsscalecalculator.h qgsscaleutils.h qgssettings.h + qgsshapegenerator.h qgssimplifymethod.h qgssnappingconfig.h qgssnappingutils.h diff --git a/src/core/annotations/qgsannotation.cpp b/src/core/annotations/qgsannotation.cpp index bda6717be765..2fdd574095c6 100644 --- a/src/core/annotations/qgsannotation.cpp +++ b/src/core/annotations/qgsannotation.cpp @@ -21,6 +21,7 @@ #include "qgsproject.h" #include "qgsgeometryutils.h" #include "qgsstyleentityvisitor.h" +#include "qgsshapegenerator.h" #include #include @@ -56,7 +57,6 @@ void QgsAnnotation::setHasFixedMapPosition( bool fixed ) return; mHasFixedMapPosition = fixed; - updateBalloon(); emit moved(); } @@ -93,7 +93,6 @@ void QgsAnnotation::setFrameOffsetFromReferencePointMm( QPointF offset ) { mOffsetFromReferencePoint = offset; - updateBalloon(); emit moved(); emit appearanceChanged(); } @@ -113,7 +112,6 @@ void QgsAnnotation::setFrameSizeMm( QSizeF size ) { QSizeF frameSize = minimumFrameSize().expandedTo( size ); //don't allow frame sizes below minimum mFrameSize = frameSize; - updateBalloon(); emit moved(); emit appearanceChanged(); } @@ -214,169 +212,26 @@ QSizeF QgsAnnotation::minimumFrameSize() const return QSizeF( 0, 0 ); } -void QgsAnnotation::updateBalloon() +void QgsAnnotation::drawFrame( QgsRenderContext &context ) const { - //first test if the point is in the frame. In that case we don't need a balloon. - if ( !mHasFixedMapPosition || - ( mOffsetFromReferencePoint.x() < 0 && ( mOffsetFromReferencePoint.x() + mFrameSize.width() ) > 0 - && mOffsetFromReferencePoint.y() < 0 && ( mOffsetFromReferencePoint.y() + mFrameSize.height() ) > 0 ) ) - { - mBalloonSegment = -1; - return; - } - - //edge list - QList segmentList; - segmentList << segment( 0, nullptr ); - segmentList << segment( 1, nullptr ); - segmentList << segment( 2, nullptr ); - segmentList << segment( 3, nullptr ); - - //find closest edge / closest edge point - double minEdgeDist = std::numeric_limits::max(); - int minEdgeIndex = -1; - QLineF minEdge; - QgsPointXY minEdgePoint; - QgsPointXY origin( 0, 0 ); - - for ( int i = 0; i < 4; ++i ) - { - QLineF currentSegment = segmentList.at( i ); - QgsPointXY currentMinDistPoint; - double currentMinDist = origin.sqrDistToSegment( currentSegment.x1(), currentSegment.y1(), currentSegment.x2(), currentSegment.y2(), currentMinDistPoint ); - bool isPreferredSegment = false; - if ( qgsDoubleNear( currentMinDist, minEdgeDist ) ) - { - // two segments are close - work out which looks nicer - const double angle = fmod( origin.azimuth( currentMinDistPoint ) + 360.0, 360.0 ); - if ( angle < 45 || angle > 315 ) - isPreferredSegment = i == 0; - else if ( angle < 135 ) - isPreferredSegment = i == 3; - else if ( angle < 225 ) - isPreferredSegment = i == 2; - else - isPreferredSegment = i == 1; - } - else if ( currentMinDist < minEdgeDist ) - isPreferredSegment = true; - - if ( isPreferredSegment ) - { - minEdgeIndex = i; - minEdgePoint = currentMinDistPoint; - minEdgeDist = currentMinDist; - minEdge = currentSegment; - } - } - - if ( minEdgeIndex < 0 ) - { + if ( !mFillSymbol ) return; - } - - mBalloonSegment = minEdgeIndex; - QPointF minEdgeEnd = minEdge.p2(); - mBalloonSegmentPoint1 = QPointF( minEdgePoint.x(), minEdgePoint.y() ); - if ( std::sqrt( minEdgePoint.sqrDist( minEdgeEnd.x(), minEdgeEnd.y() ) ) < mSegmentPointWidthMm ) - { - double x = 0; - double y = 0; - QgsGeometryUtils::pointOnLineWithDistance( minEdge.p2().x(), minEdge.p2().y(), minEdge.p1().x(), minEdge.p1().y(), mSegmentPointWidthMm, x, y ); - mBalloonSegmentPoint1 = QPointF( x, y ); - } - - { - double x = 0; - double y = 0; - QgsGeometryUtils::pointOnLineWithDistance( mBalloonSegmentPoint1.x(), mBalloonSegmentPoint1.y(), minEdge.p2().x(), minEdge.p2().y(), mSegmentPointWidthMm, x, y ); - mBalloonSegmentPoint2 = QPointF( x, y ); - } - -} -QLineF QgsAnnotation::segment( int index, QgsRenderContext *context ) const -{ - auto scaleSize = [context]( double size )->double + auto scaleSize = [&context]( double size )->double { - return context ? context->convertToPainterUnits( size, QgsUnitTypes::RenderMillimeters ) : size; + return context.convertToPainterUnits( size, QgsUnitTypes::RenderMillimeters ); }; - if ( mHasFixedMapPosition ) - { - switch ( index ) - { - case 0: - return QLineF( scaleSize( mOffsetFromReferencePoint.x() ), - scaleSize( mOffsetFromReferencePoint.y() ), - scaleSize( mOffsetFromReferencePoint.x() ) + scaleSize( mFrameSize.width() ), - scaleSize( mOffsetFromReferencePoint.y() ) ); - case 1: - return QLineF( scaleSize( mOffsetFromReferencePoint.x() ) + scaleSize( mFrameSize.width() ), - scaleSize( mOffsetFromReferencePoint.y() ), - scaleSize( mOffsetFromReferencePoint.x() ) + scaleSize( mFrameSize.width() ), - scaleSize( mOffsetFromReferencePoint.y() ) + scaleSize( mFrameSize.height() ) ); - case 2: - return QLineF( scaleSize( mOffsetFromReferencePoint.x() ) + scaleSize( mFrameSize.width() ), - scaleSize( mOffsetFromReferencePoint.y() ) + scaleSize( mFrameSize.height() ), - scaleSize( mOffsetFromReferencePoint.x() ), - scaleSize( mOffsetFromReferencePoint.y() ) + scaleSize( mFrameSize.height() ) ); - case 3: - return QLineF( scaleSize( mOffsetFromReferencePoint.x() ), - scaleSize( mOffsetFromReferencePoint.y() ) + scaleSize( mFrameSize.height() ), - scaleSize( mOffsetFromReferencePoint.x() ), - scaleSize( mOffsetFromReferencePoint.y() ) ); - default: - return QLineF(); - } - } - else - { - switch ( index ) - { - case 0: - return QLineF( 0, 0, scaleSize( mFrameSize.width() ), 0 ); - case 1: - return QLineF( scaleSize( mFrameSize.width() ), 0, - scaleSize( mFrameSize.width() ), scaleSize( mFrameSize.height() ) ); - case 2: - return QLineF( scaleSize( mFrameSize.width() ), scaleSize( mFrameSize.height() ), - 0, scaleSize( mFrameSize.height() ) ); - case 3: - return QLineF( 0, scaleSize( mFrameSize.height() ), - 0, 0 ); - default: - return QLineF(); - } - } -} -void QgsAnnotation::drawFrame( QgsRenderContext &context ) const -{ - if ( !mFillSymbol ) - return; + const QRectF frameRect( mHasFixedMapPosition ? scaleSize( mOffsetFromReferencePoint.x() ) : 0, + mHasFixedMapPosition ? scaleSize( mOffsetFromReferencePoint.y() ) : 0, + scaleSize( mFrameSize.width() ), + scaleSize( mFrameSize.height() ) ); + const QgsPointXY origin = mHasFixedMapPosition ? QgsPointXY( 0, 0 ) : QgsPointXY( frameRect.center().x(), frameRect.center().y() ); - QPolygonF poly; - poly.reserve( 9 + ( mHasFixedMapPosition ? 3 : 0 ) ); - QVector rings; //empty list - for ( int i = 0; i < 4; ++i ) - { - QLineF currentSegment = segment( i, &context ); - poly << QPointF( currentSegment.p1().x(), - currentSegment.p1().y() ); - if ( i == mBalloonSegment && mHasFixedMapPosition ) - { - poly << QPointF( context.convertToPainterUnits( mBalloonSegmentPoint1.x(), QgsUnitTypes::RenderMillimeters ), - context.convertToPainterUnits( mBalloonSegmentPoint1.y(), QgsUnitTypes::RenderMillimeters ) ); - poly << QPointF( 0, 0 ); - poly << QPointF( context.convertToPainterUnits( mBalloonSegmentPoint2.x(), QgsUnitTypes::RenderMillimeters ), - context.convertToPainterUnits( mBalloonSegmentPoint2.y(), QgsUnitTypes::RenderMillimeters ) ); - } - poly << QPointF( currentSegment.p2().x(), currentSegment.p2().y() ); - } - if ( poly.at( 0 ) != poly.at( poly.count() - 1 ) ) - poly << poly.at( 0 ); + const QPolygonF poly = QgsShapeGenerator::createBalloon( origin, frameRect, context.convertToPainterUnits( mSegmentPointWidthMm, QgsUnitTypes::RenderMillimeters ) ); mFillSymbol->startRender( context ); + QVector rings; //empty list mFillSymbol->renderPolygon( poly, &rings, nullptr, context ); mFillSymbol->stopRender( context ); } @@ -539,7 +394,6 @@ void QgsAnnotation::_readXml( const QDomElement &annotationElem, const QgsReadWr mFillSymbol.reset( QgsFillSymbol::createSimple( props ) ); } - updateBalloon(); emit mapLayerChanged(); } @@ -555,9 +409,6 @@ void QgsAnnotation::copyCommonProperties( QgsAnnotation *target ) const target->mMarkerSymbol.reset( mMarkerSymbol ? mMarkerSymbol->clone() : nullptr ); target->mContentsMargins = mContentsMargins; target->mFillSymbol.reset( mFillSymbol ? mFillSymbol->clone() : nullptr ); - target->mBalloonSegment = mBalloonSegment; - target->mBalloonSegmentPoint1 = mBalloonSegmentPoint1; - target->mBalloonSegmentPoint2 = mBalloonSegmentPoint2; target->mSegmentPointWidthMm = mSegmentPointWidthMm; target->mMapLayer = mMapLayer; target->mFeature = mFeature; diff --git a/src/core/annotations/qgsannotation.h b/src/core/annotations/qgsannotation.h index 099f3af991c6..b90f48dd0675 100644 --- a/src/core/annotations/qgsannotation.h +++ b/src/core/annotations/qgsannotation.h @@ -375,12 +375,6 @@ class CORE_EXPORT QgsAnnotation : public QObject private: - //! Check where to attach the balloon connection between frame and map point - void updateBalloon(); - - //! Gets the frame line (0 is the top line, 1 right, 2 bottom, 3 left) - QLineF segment( int index, QgsRenderContext *context ) const; - //! Draws the annotation frame to a destination painter void drawFrame( QgsRenderContext &context ) const; @@ -415,15 +409,6 @@ class CORE_EXPORT QgsAnnotation : public QObject //! Fill symbol used for drawing annotation std::unique_ptr mFillSymbol; - //! Segment number where the connection to the map point is attached. -1 if no balloon needed (e.g. if point is contained in frame) - int mBalloonSegment = -1; - - //! First segment point for drawing the connection (ccw direction) (always in mm) - QPointF mBalloonSegmentPoint1; - - //! Second segment point for drawing the balloon connection (ccw direction) (always in mm) - QPointF mBalloonSegmentPoint2; - //! Associated layer (or NULLPTR if not attached to a layer) QgsWeakMapLayerPointer mMapLayer; diff --git a/src/core/qgsshapegenerator.cpp b/src/core/qgsshapegenerator.cpp new file mode 100644 index 000000000000..0672893f6d05 --- /dev/null +++ b/src/core/qgsshapegenerator.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + qgsshapegenerator.cpp + ---------------- + begin : March 2021 + copyright : (C) 2021 Nyall Dawson + email : nyall dot dawson at gmail dot com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsshapegenerator.h" +#include "qgsgeometryutils.h" +#include +#include + +QLineF segment( int index, QRectF rect ) +{ + switch ( index ) + { + case 0: + return QLineF( rect.left(), + rect.top(), + rect.right(), + rect.top() ); + case 1: + return QLineF( rect.right(), + rect.top(), + rect.right(), + rect.bottom() ); + case 2: + return QLineF( rect.right(), + rect.bottom(), + rect.left(), + rect.bottom() ); + case 3: + return QLineF( rect.left(), + rect.bottom(), + rect.left(), + rect.top() ); + default: + return QLineF(); + } +} + +QPolygonF QgsShapeGenerator::createBalloon( const QgsPointXY &origin, const QRectF &rect, double wedgeWidth ) +{ + int balloonSegment = -1; + QPointF balloonSegmentPoint1; + QPointF balloonSegmentPoint2; + + //first test if the point is in the frame. In that case we don't need a balloon and can just use a rect + if ( rect.contains( origin.toQPointF() ) ) + { + balloonSegment = -1; + } + else + { + //edge list + QList segmentList; + segmentList << segment( 0, rect ); + segmentList << segment( 1, rect ); + segmentList << segment( 2, rect ); + segmentList << segment( 3, rect ); + + // find closest edge / closest edge point + double minEdgeDist = std::numeric_limits::max(); + int minEdgeIndex = -1; + QLineF minEdge; + QgsPointXY minEdgePoint( 0, 0 ); + + for ( int i = 0; i < 4; ++i ) + { + QLineF currentSegment = segmentList.at( i ); + QgsPointXY currentMinDistPoint; + double currentMinDist = origin.sqrDistToSegment( currentSegment.x1(), currentSegment.y1(), currentSegment.x2(), currentSegment.y2(), currentMinDistPoint ); + bool isPreferredSegment = false; + if ( qgsDoubleNear( currentMinDist, minEdgeDist ) ) + { + // two segments are close - work out which looks nicer + const double angle = fmod( origin.azimuth( currentMinDistPoint ) + 360.0, 360.0 ); + if ( angle < 45 || angle > 315 ) + isPreferredSegment = i == 0; + else if ( angle < 135 ) + isPreferredSegment = i == 3; + else if ( angle < 225 ) + isPreferredSegment = i == 2; + else + isPreferredSegment = i == 1; + } + else if ( currentMinDist < minEdgeDist ) + isPreferredSegment = true; + + if ( isPreferredSegment ) + { + minEdgeIndex = i; + minEdgePoint = currentMinDistPoint; + minEdgeDist = currentMinDist; + minEdge = currentSegment; + } + } + + if ( minEdgeIndex >= 0 ) + { + balloonSegment = minEdgeIndex; + QPointF minEdgeEnd = minEdge.p2(); + balloonSegmentPoint1 = QPointF( minEdgePoint.x(), minEdgePoint.y() ); + if ( std::sqrt( minEdgePoint.sqrDist( minEdgeEnd.x(), minEdgeEnd.y() ) ) < wedgeWidth ) + { + double x = 0; + double y = 0; + QgsGeometryUtils::pointOnLineWithDistance( minEdge.p2().x(), minEdge.p2().y(), minEdge.p1().x(), minEdge.p1().y(), wedgeWidth, x, y ); + balloonSegmentPoint1 = QPointF( x, y ); + } + + { + double x = 0; + double y = 0; + QgsGeometryUtils::pointOnLineWithDistance( balloonSegmentPoint1.x(), balloonSegmentPoint1.y(), minEdge.p2().x(), minEdge.p2().y(), wedgeWidth, x, y ); + balloonSegmentPoint2 = QPointF( x, y ); + } + } + } + + QPolygonF poly; + poly.reserve( 12 ); + for ( int i = 0; i < 4; ++i ) + { + QLineF currentSegment = segment( i, rect ); + poly << currentSegment.p1(); + + if ( i == balloonSegment ) + { + poly << balloonSegmentPoint1; + poly << origin.toQPointF(); + poly << balloonSegmentPoint2; + } + + poly << currentSegment.p2(); + } + if ( poly.at( 0 ) != poly.at( poly.count() - 1 ) ) + poly << poly.at( 0 ); + return poly; +} diff --git a/src/core/qgsshapegenerator.h b/src/core/qgsshapegenerator.h new file mode 100644 index 000000000000..b335c36d0ce1 --- /dev/null +++ b/src/core/qgsshapegenerator.h @@ -0,0 +1,53 @@ +/*************************************************************************** + qgsshapegenerator.h + ---------------- + begin : March 2021 + copyright : (C) 2021 Nyall Dawson + email : nyall dot dawson at gmail dot com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSSHAPEGENERATOR_H +#define QGSSHAPEGENERATOR_H + +#define SIP_NO_FILE +#include "qgis_core.h" + +#include + +class QgsPointXY; + +/** + * \ingroup core + * \class QgsShapeGenerator + * \brief Contains utility functions for generating shapes. + * + * \note Not available in Python bindings + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsShapeGenerator +{ + public: + + /** + * Generates a "balloon"/"talking bubble" style shape. + * + * The \a origin point indicates the starting point for the pointing wedge portion of the balloon. + * + * The \a rect argument specifies the rectangular bounds of the main body of the balloon. + * + * The \a wedgeWidth argument gives the width of the pointing wedge portion of the balloon at the + * position where it joins with the balloon's main body. + */ + static QPolygonF createBalloon( const QgsPointXY &origin, const QRectF &rect, double wedgeWidth ); +}; + +#endif // QGSSHAPEGENERATOR_H From f2203ea7b70e33e7650cd0c42170c14b440e2d29 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 17 Mar 2021 10:14:06 +1000 Subject: [PATCH 132/377] Add geometry util to calculate a point along a segment offset in a perpendicular direction by a set offset amount --- .../geometry/qgsgeometryutils.sip.in | 31 +++++++++++++++++++ src/core/geometry/qgsgeometryutils.cpp | 17 ++++++++++ src/core/geometry/qgsgeometryutils.h | 29 +++++++++++++++++ tests/src/core/testqgsgeometryutils.cpp | 30 ++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/python/core/auto_generated/geometry/qgsgeometryutils.sip.in b/python/core/auto_generated/geometry/qgsgeometryutils.sip.in index 8fbee929fb0e..db455f2c88e7 100644 --- a/python/core/auto_generated/geometry/qgsgeometryutils.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometryutils.sip.in @@ -269,6 +269,37 @@ Returns a point a specified ``distance`` toward a second point. %End + static void perpendicularOffsetPointAlongSegment( double x1, double y1, double x2, double y2, double proportion, double offset, double *x /Out/, double *y /Out/ ); +%Docstring +Calculates a point a certain ``proportion`` of the way along the segment from (``x1``, ``y1``) to (``x2``, ``y2``), +offset from the segment by the specified ``offset`` amount. + +:param x1: x-coordinate of start of segment +:param y1: y-coordinate of start of segment +:param x2: x-coordinate of end of segment +:param y2: y-coordinate of end of segment +:param proportion: proportion of the segment's length at which to place the point (between 0.0 and 1.0) +:param offset: perpendicular offset from segment to apply to point. A negative ``offset`` shifts the point to the left of the segment, while a positive ``offset`` will shift it to the right of the segment. + +Example +------- + +.. code-block:: python + + # Offset point at center of segment by 2 units to the right + x, y = QgsGeometryUtils.perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, 2 ) + # (6.0, 3.0) + + # Offset point at center of segment by 2 units to the left + x, y = QgsGeometryUtils.perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, -2 ) + # (6.0, 7.0) + +:return: - x: calculated point x-coordinate + - y: calculated point y-coordinate + +.. versionadded:: 3.20 +%End + static QgsPoint interpolatePointOnArc( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance ) /HoldGIL/; %Docstring Interpolates a point on an arc defined by three points, ``pt1``, ``pt2`` and ``pt3``. The arc will be diff --git a/src/core/geometry/qgsgeometryutils.cpp b/src/core/geometry/qgsgeometryutils.cpp index 9ea1026c047a..40b4c4649a58 100644 --- a/src/core/geometry/qgsgeometryutils.cpp +++ b/src/core/geometry/qgsgeometryutils.cpp @@ -631,6 +631,23 @@ void QgsGeometryUtils::pointOnLineWithDistance( double x1, double y1, double x2, } } +void QgsGeometryUtils::perpendicularOffsetPointAlongSegment( double x1, double y1, double x2, double y2, double proportion, double offset, double *x, double *y ) +{ + // calculate point along segment + const double mX = x1 + ( x2 - x1 ) * proportion; + const double mY = y1 + ( y2 - y1 ) * proportion; + const double pX = x1 - x2; + const double pY = y1 - y2; + double normalX = -pY; + double normalY = pX; + const double normalLength = sqrt( ( normalX * normalX ) + ( normalY * normalY ) ); + normalX /= normalLength; + normalY /= normalLength; + + *x = mX + offset * normalX; + *y = mY + offset * normalY; +} + QgsPoint QgsGeometryUtils::interpolatePointOnArc( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance ) { double centerX, centerY, radius; diff --git a/src/core/geometry/qgsgeometryutils.h b/src/core/geometry/qgsgeometryutils.h index 651e14a16b18..a30d7569774a 100644 --- a/src/core/geometry/qgsgeometryutils.h +++ b/src/core/geometry/qgsgeometryutils.h @@ -301,6 +301,35 @@ class CORE_EXPORT QgsGeometryUtils double *z1 = nullptr, double *z2 = nullptr, double *z = nullptr, double *m1 = nullptr, double *m2 = nullptr, double *m = nullptr ) SIP_SKIP; + /** + * Calculates a point a certain \a proportion of the way along the segment from (\a x1, \a y1) to (\a x2, \a y2), + * offset from the segment by the specified \a offset amount. + * + * \param x1 x-coordinate of start of segment + * \param y1 y-coordinate of start of segment + * \param x2 x-coordinate of end of segment + * \param y2 y-coordinate of end of segment + * \param proportion proportion of the segment's length at which to place the point (between 0.0 and 1.0) + * \param offset perpendicular offset from segment to apply to point. A negative \a offset shifts the point to the left of the segment, while a positive \a offset will shift it to the right of the segment. + * \param x calculated point x-coordinate + * \param y calculated point y-coordinate + * + * ### Example + * + * \code{.py} + * # Offset point at center of segment by 2 units to the right + * x, y = QgsGeometryUtils.perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, 2 ) + * # (6.0, 3.0) + * + * # Offset point at center of segment by 2 units to the left + * x, y = QgsGeometryUtils.perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, -2 ) + * # (6.0, 7.0) + * \endcode + * + * \since QGIS 3.20 + */ + static void perpendicularOffsetPointAlongSegment( double x1, double y1, double x2, double y2, double proportion, double offset, double *x SIP_OUT, double *y SIP_OUT ); + /** * Interpolates a point on an arc defined by three points, \a pt1, \a pt2 and \a pt3. The arc will be * interpolated by the specified \a distance from \a pt1. diff --git a/tests/src/core/testqgsgeometryutils.cpp b/tests/src/core/testqgsgeometryutils.cpp index e2e57b65b186..80bca354fbf5 100644 --- a/tests/src/core/testqgsgeometryutils.cpp +++ b/tests/src/core/testqgsgeometryutils.cpp @@ -83,6 +83,7 @@ class TestQgsGeometryUtils: public QObject void testPointContinuesArc(); void testBisector(); void testAngleBisector(); + void testPerpendicularOffsetPoint(); }; @@ -1537,5 +1538,34 @@ void TestQgsGeometryUtils::testAngleBisector() QVERIFY( !QgsGeometryUtils::angleBisector( 0, 0, 5, 0, 6, 0, 10, 0, x, y, angle ) ); } +void TestQgsGeometryUtils::testPerpendicularOffsetPoint() +{ + double x, y; + QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, 2, &x, &y ); + QGSCOMPARENEAR( x, 6.0, 10e-3 ); + QGSCOMPARENEAR( y, 3.0, 10e-3 ); + QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.5, -2, &x, &y ); + QGSCOMPARENEAR( x, 6.0, 10e-3 ); + QGSCOMPARENEAR( y, 7.0, 10e-3 ); + QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.1, 2, &x, &y ); + QGSCOMPARENEAR( x, 2.0, 10e-3 ); + QGSCOMPARENEAR( y, 3.0, 10e-3 ); + QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.9, 2, &x, &y ); + QGSCOMPARENEAR( x, 10.0, 10e-3 ); + QGSCOMPARENEAR( y, 3.0, 10e-3 ); + QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 0.0, 2, &x, &y ); + QGSCOMPARENEAR( x, 1.0, 10e-3 ); + QGSCOMPARENEAR( y, 3.0, 10e-3 ); + QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 1, 5, 11, 5, 1.0, 2, &x, &y ); + QGSCOMPARENEAR( x, 11.0, 10e-3 ); + QGSCOMPARENEAR( y, 3.0, 10e-3 ); + QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 5, 1, 5, 11, 0.5, 2, &x, &y ); + QGSCOMPARENEAR( x, 7.0, 10e-3 ); + QGSCOMPARENEAR( y, 6.0, 10e-3 ); + QgsGeometryUtils::perpendicularOffsetPointAlongSegment( 5, 1, 5, 11, 0.5, -2, &x, &y ); + QGSCOMPARENEAR( x, 3.0, 10e-3 ); + QGSCOMPARENEAR( y, 6.0, 10e-3 ); +} + QGSTEST_MAIN( TestQgsGeometryUtils ) #include "testqgsgeometryutils.moc" From 87ba773ad22b47634afef59997fd7c8cd3941a5c Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 18 Mar 2021 16:01:23 +1000 Subject: [PATCH 133/377] Add method to determine closest side of rectangle to a point --- .../geometry/qgsgeometryutils.sip.in | 26 +++++++ src/core/geometry/qgsgeometryutils.cpp | 77 +++++++++++++++++++ src/core/geometry/qgsgeometryutils.h | 24 ++++++ tests/src/core/testqgsgeometryutils.cpp | 35 +++++++++ 4 files changed, 162 insertions(+) diff --git a/python/core/auto_generated/geometry/qgsgeometryutils.sip.in b/python/core/auto_generated/geometry/qgsgeometryutils.sip.in index db455f2c88e7..00cac788722c 100644 --- a/python/core/auto_generated/geometry/qgsgeometryutils.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometryutils.sip.in @@ -498,6 +498,32 @@ Averages two angles, correctly handling negative angles and ensuring the result + static int closestSideOfRectangle( double right, double bottom, double left, double top, double x, double y ); +%Docstring +Returns a number representing the closest side of a rectangle defined by /a right, +``bottom``, ``left``, ``top`` to the point at (``x``, ``y``), where +the point may be in ther interior of the rectangle or outside it. + +The returned value may be: + +1. Point is closest to top side of rectangle +2. Point is located on the top-right diagonal of rectangle, equally close to the top and right sides +3. Point is closest to right side of rectangle +4. Point is located on the bottom-right diagonal of rectangle, equally close to the bottom and right sides +5. Point is closest to bottom side of rectangle +6. Point is located on the bottom-left diagonal of rectangle, equally close to the bottom and left sides +7. Point is closest to left side of rectangle +8. Point is located on the top-left diagonal of rectangle, equally close to the top and left sides + +.. note:: + + This method effectively partitions the space outside of the rectangle into Voronoi cells, so a point + to the top left of the rectangle may be assigned to the left or top sides based on its position relative + to the diagonal line extended from the rectangle's top-left corner. + +.. versionadded:: 3.20 +%End + static QgsPoint midpoint( const QgsPoint &pt1, const QgsPoint &pt2 ) /HoldGIL/; %Docstring Returns a middle point between points pt1 and pt2. diff --git a/src/core/geometry/qgsgeometryutils.cpp b/src/core/geometry/qgsgeometryutils.cpp index 40b4c4649a58..ade16a1d3048 100644 --- a/src/core/geometry/qgsgeometryutils.cpp +++ b/src/core/geometry/qgsgeometryutils.cpp @@ -1402,6 +1402,83 @@ QStringList QgsGeometryUtils::wktGetChildBlocks( const QString &wkt, const QStri return blocks; } +int QgsGeometryUtils::closestSideOfRectangle( double right, double bottom, double left, double top, double x, double y ) +{ + // point outside rectangle + if ( x <= left && y <= bottom ) + { + const double dx = left - x; + const double dy = bottom - y; + if ( qgsDoubleNear( dx, dy ) ) + return 6; + else if ( dx < dy ) + return 5; + else + return 7; + } + else if ( x >= right && y >= top ) + { + const double dx = x - right; + const double dy = y - top; + if ( qgsDoubleNear( dx, dy ) ) + return 2; + else if ( dx < dy ) + return 1; + else + return 3; + } + else if ( x >= right && y <= bottom ) + { + const double dx = x - right; + const double dy = bottom - y; + if ( qgsDoubleNear( dx, dy ) ) + return 4; + else if ( dx < dy ) + return 5; + else + return 3; + } + else if ( x <= left && y >= top ) + { + const double dx = left - x; + const double dy = y - top; + if ( qgsDoubleNear( dx, dy ) ) + return 8; + else if ( dx < dy ) + return 1; + else + return 7; + } + else if ( x <= left ) + return 7; + else if ( x >= right ) + return 3; + else if ( y <= bottom ) + return 5; + else if ( y >= top ) + return 1; + + // point is inside rectangle + const double smallestX = std::min( right - x, x - left ); + const double smallestY = std::min( top - y, y - bottom ); + if ( smallestX < smallestY ) + { + // closer to left/right side + if ( right - x < x - left ) + return 3; // closest to right side + else + return 7; + } + else + { + // closer to top/bottom side + if ( top - y < y - bottom ) + return 1; // closest to top side + else + return 5; + } +} + QgsPoint QgsGeometryUtils::midpoint( const QgsPoint &pt1, const QgsPoint &pt2 ) { QgsWkbTypes::Type pType( QgsWkbTypes::Point ); diff --git a/src/core/geometry/qgsgeometryutils.h b/src/core/geometry/qgsgeometryutils.h index a30d7569774a..9713d9a55777 100644 --- a/src/core/geometry/qgsgeometryutils.h +++ b/src/core/geometry/qgsgeometryutils.h @@ -547,6 +547,30 @@ class CORE_EXPORT QgsGeometryUtils */ static QStringList wktGetChildBlocks( const QString &wkt, const QString &defaultType = QString() ) SIP_SKIP; + /** + * Returns a number representing the closest side of a rectangle defined by /a right, + * \a bottom, \a left, \a top to the point at (\a x, \a y), where + * the point may be in ther interior of the rectangle or outside it. + * + * The returned value may be: + * + * 1. Point is closest to top side of rectangle + * 2. Point is located on the top-right diagonal of rectangle, equally close to the top and right sides + * 3. Point is closest to right side of rectangle + * 4. Point is located on the bottom-right diagonal of rectangle, equally close to the bottom and right sides + * 5. Point is closest to bottom side of rectangle + * 6. Point is located on the bottom-left diagonal of rectangle, equally close to the bottom and left sides + * 7. Point is closest to left side of rectangle + * 8. Point is located on the top-left diagonal of rectangle, equally close to the top and left sides + * + * \note This method effectively partitions the space outside of the rectangle into Voronoi cells, so a point + * to the top left of the rectangle may be assigned to the left or top sides based on its position relative + * to the diagonal line extended from the rectangle's top-left corner. + * + * \since QGIS 3.20 + */ + static int closestSideOfRectangle( double right, double bottom, double left, double top, double x, double y ); + /** * Returns a middle point between points pt1 and pt2. * Z value is computed if one of this point have Z. diff --git a/tests/src/core/testqgsgeometryutils.cpp b/tests/src/core/testqgsgeometryutils.cpp index 80bca354fbf5..81fc861185a4 100644 --- a/tests/src/core/testqgsgeometryutils.cpp +++ b/tests/src/core/testqgsgeometryutils.cpp @@ -84,6 +84,7 @@ class TestQgsGeometryUtils: public QObject void testBisector(); void testAngleBisector(); void testPerpendicularOffsetPoint(); + void testClosestSideOfRectangle(); }; @@ -1567,5 +1568,39 @@ void TestQgsGeometryUtils::testPerpendicularOffsetPoint() QGSCOMPARENEAR( y, 6.0, 10e-3 ); } +void TestQgsGeometryUtils::testClosestSideOfRectangle() +{ + // outside rect + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 1, -19 ), 7 ); + + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 1, -17 ), 7 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 9, -17 ), 8 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 9, -1 ), 1 ); + + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 1, -21 ), 7 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 9, -21 ), 6 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 9, -22 ), 5 ); + + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 14, -1 ), 1 ); + + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 18, -1 ), 1 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 17, -17 ), 2 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 20, -17 ), 3 ); + + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 18, -19 ), 3 ); + + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 18, -21 ), 3 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 17, -21 ), 4 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 17, -25 ), 5 ); + + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 14, -21 ), 5 ); + + // inside rect + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 10.5, -19 ), 7 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 16.5, -19 ), 3 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 14, -18.5 ), 1 ); + QCOMPARE( QgsGeometryUtils::closestSideOfRectangle( 16, -20, 10, -18, 14, -19.5 ), 5 ); +} + QGSTEST_MAIN( TestQgsGeometryUtils ) #include "testqgsgeometryutils.moc" From 7d68b21def7db3282b7988b26c89b1d6eba10591 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 17 Mar 2021 10:46:55 +1000 Subject: [PATCH 134/377] [feature] New callout style for curved lines Renders a nice cartographically pleasing curved line between the labels and features. Options include selecting a specific curve orientation (clockwise or counterclockwise), or an automatic orientation option which determines optimal orientation for each individual label. Users also have control over the amount of curvature applied to the callout lines. --- .../auto_generated/callouts/qgscallout.sip.in | 84 ++ src/core/callouts/qgscallout.cpp | 248 ++++ src/core/callouts/qgscallout.h | 105 ++ src/core/callouts/qgscalloutsregistry.cpp | 1 + src/gui/callouts/qgscalloutwidget.cpp | 206 +++ src/gui/callouts/qgscalloutwidget.h | 43 + src/gui/labeling/qgslabelinggui.cpp | 1 + src/ui/callouts/widget_curvedlinecallout.ui | 555 ++++++++ tests/src/core/testqgscallout.cpp | 1253 +++++++++++++++++ .../expected_curved_auto_horizontal_lines.png | Bin 0 -> 13424 bytes ...d_curved_auto_leaving_labels_at_bottom.png | Bin 0 -> 68750 bytes ...ved_auto_leaving_labels_at_bottom_left.png | Bin 0 -> 62510 bytes ...ed_auto_leaving_labels_at_bottom_right.png | Bin 0 -> 62118 bytes ..._curved_auto_leaving_labels_at_corners.png | Bin 0 -> 57623 bytes ...ted_curved_auto_leaving_labels_at_left.png | Bin 0 -> 70340 bytes ...ed_curved_auto_leaving_labels_at_right.png | Bin 0 -> 68615 bytes ...cted_curved_auto_leaving_labels_at_top.png | Bin 0 -> 68083 bytes ...curved_auto_leaving_labels_at_top_left.png | Bin 0 -> 62079 bytes ...urved_auto_leaving_labels_at_top_right.png | Bin 0 -> 62021 bytes .../expected_curved_auto_vertical_lines.png | Bin 0 -> 13279 bytes .../expected_curved_clockwise.png | Bin 0 -> 60453 bytes .../expected_curved_counterclockwise.png | Bin 0 -> 60876 bytes .../expected_curved_curvature.png | Bin 0 -> 63752 bytes 23 files changed, 2496 insertions(+) create mode 100644 src/ui/callouts/widget_curvedlinecallout.ui create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_horizontal_lines/expected_curved_auto_horizontal_lines.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_bottom/expected_curved_auto_leaving_labels_at_bottom.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_bottom_left/expected_curved_auto_leaving_labels_at_bottom_left.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_bottom_right/expected_curved_auto_leaving_labels_at_bottom_right.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_corners/expected_curved_auto_leaving_labels_at_corners.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_left/expected_curved_auto_leaving_labels_at_left.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_right/expected_curved_auto_leaving_labels_at_right.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_top/expected_curved_auto_leaving_labels_at_top.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_top_left/expected_curved_auto_leaving_labels_at_top_left.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_top_right/expected_curved_auto_leaving_labels_at_top_right.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_auto_vertical_lines/expected_curved_auto_vertical_lines.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_clockwise/expected_curved_clockwise.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_counterclockwise/expected_curved_counterclockwise.png create mode 100644 tests/testdata/control_images/callouts/expected_curved_curvature/expected_curved_curvature.png diff --git a/python/core/auto_generated/callouts/qgscallout.sip.in b/python/core/auto_generated/callouts/qgscallout.sip.in index 35dd91d1c0df..69f5b1fdd086 100644 --- a/python/core/auto_generated/callouts/qgscallout.sip.in +++ b/python/core/auto_generated/callouts/qgscallout.sip.in @@ -34,6 +34,10 @@ relevant symbology elements to render them. { sipType = sipType_QgsManhattanLineCallout; } + else if ( sipCpp->type() == "curved" && dynamic_cast( sipCpp ) != NULL ) + { + sipType = sipType_QgsCurvedLineCallout; + } else { sipType = 0; @@ -53,6 +57,8 @@ relevant symbology elements to render them. OriginY, DestinationX, DestinationY, + Curvature, + Orientation, }; enum DrawOrder @@ -734,6 +740,84 @@ serialized in the ``properties`` map (corresponding to the output from }; +class QgsCurvedLineCallout : QgsSimpleLineCallout +{ +%Docstring +Draws curved lines as callouts. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgscallout.h" +%End + public: + + enum Orientation + { + Automatic, + Clockwise, + CounterClockwise, + }; + + QgsCurvedLineCallout(); + + + static QgsCallout *create( const QVariantMap &properties = QVariantMap(), const QgsReadWriteContext &context = QgsReadWriteContext() ) /Factory/; +%Docstring +Creates a new QgsCurvedLineCallout, using the settings +serialized in the ``properties`` map (corresponding to the output from +:py:func:`QgsCurvedLineCallout.properties()` ). +%End + + virtual QString type() const; + + virtual QgsCurvedLineCallout *clone() const; + + virtual QVariantMap properties( const QgsReadWriteContext &context ) const; + + + double curvature() const; +%Docstring +Returns the callout line's curvature. + +The curvature is a percentage value (with typical ranges between 0.0 and 1.0), representing the overall curvature of the line. + +.. seealso:: :py:func:`setCurvature` +%End + + void setCurvature( double curvature ); +%Docstring +Sets the callout line's ``curvature``. + +The ``curvature`` is a percentage value (with typical ranges between 0.0 and 1.0), representing the overall curvature of the line. + +.. seealso:: :py:func:`curvature` +%End + + Orientation orientation() const; +%Docstring +Returns the callout line's curve orientation. + +.. seealso:: :py:func:`setOrientation` +%End + + void setOrientation( Orientation orientation ); +%Docstring +Sets the callout line's curve ``orientation``. + +.. seealso:: :py:func:`orientation` +%End + + protected: + virtual QgsCurve *createCalloutLine( const QgsPoint &start, const QgsPoint &end, QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) const /Factory/; + + + private: + QgsCurvedLineCallout( const QgsCurvedLineCallout &other ); + QgsCurvedLineCallout &operator=( const QgsCurvedLineCallout & ); +}; + /************************************************************************ * This file has been generated automatically from * diff --git a/src/core/callouts/qgscallout.cpp b/src/core/callouts/qgscallout.cpp index 94737837a999..07b94cf92c3d 100644 --- a/src/core/callouts/qgscallout.cpp +++ b/src/core/callouts/qgscallout.cpp @@ -24,6 +24,8 @@ #include "qgslinestring.h" #include "qgslogger.h" #include "qgsgeos.h" +#include "qgsgeometryutils.h" +#include "qgscircularstring.h" #include #include @@ -51,6 +53,10 @@ void QgsCallout::initPropertyDefinitions() { QgsCallout::OriginY, QgsPropertyDefinition( "OriginY", QObject::tr( "Callout origin (Y)" ), QgsPropertyDefinition::Double, origin ) }, { QgsCallout::DestinationX, QgsPropertyDefinition( "DestinationX", QObject::tr( "Callout destination (X)" ), QgsPropertyDefinition::Double, origin ) }, { QgsCallout::DestinationY, QgsPropertyDefinition( "DestinationY", QObject::tr( "Callout destination (Y)" ), QgsPropertyDefinition::Double, origin ) }, + { QgsCallout::Curvature, QgsPropertyDefinition( "Curvature", QObject::tr( "Callout line curvature" ), QgsPropertyDefinition::Double, origin ) }, + { + QgsCallout::Orientation, QgsPropertyDefinition( "Orientation", QgsPropertyDefinition::DataTypeString, QObject::tr( "Callout curve orientation" ), QObject::tr( "string " ) + "[auto|clockwise|counterclockwise]", origin ) + }, }; } @@ -745,3 +751,245 @@ QgsCurve *QgsManhattanLineCallout::createCalloutLine( const QgsPoint &start, con QgsPoint mid1 = QgsPoint( start.x(), end.y() ); return new QgsLineString( QVector< QgsPoint >() << start << mid1 << end ); } + + +// +// QgsCurvedLineCallout +// + +QgsCurvedLineCallout::QgsCurvedLineCallout() +{ +} + +QgsCurvedLineCallout::QgsCurvedLineCallout( const QgsCurvedLineCallout &other ) + : QgsSimpleLineCallout( other ) + , mOrientation( other.mOrientation ) + , mCurvature( other.mCurvature ) +{ + +} + +QgsCallout *QgsCurvedLineCallout::create( const QVariantMap &properties, const QgsReadWriteContext &context ) +{ + std::unique_ptr< QgsCurvedLineCallout > callout = std::make_unique< QgsCurvedLineCallout >(); + callout->readProperties( properties, context ); + + callout->setCurvature( properties.value( QStringLiteral( "curvature" ), 0.1 ).toDouble() ); + callout->setOrientation( decodeOrientation( properties.value( QStringLiteral( "orientation" ), QStringLiteral( "auto" ) ).toString() ) ); + + return callout.release(); +} + +QString QgsCurvedLineCallout::type() const +{ + return QStringLiteral( "curved" ); +} + +QgsCurvedLineCallout *QgsCurvedLineCallout::clone() const +{ + return new QgsCurvedLineCallout( *this ); +} + +QVariantMap QgsCurvedLineCallout::properties( const QgsReadWriteContext &context ) const +{ + QVariantMap props = QgsSimpleLineCallout::properties( context ); + props.insert( QStringLiteral( "curvature" ), mCurvature ); + props.insert( QStringLiteral( "orientation" ), encodeOrientation( mOrientation ) ); + return props; +} + +QgsCurve *QgsCurvedLineCallout::createCalloutLine( const QgsPoint &start, const QgsPoint &end, QgsRenderContext &context, const QRectF &rect, const double, const QgsGeometry &, QgsCallout::QgsCalloutContext & ) const +{ + double curvature = mCurvature * 100; + if ( dataDefinedProperties().isActive( QgsCallout::Curvature ) ) + { + context.expressionContext().setOriginalValueVariable( curvature ); + curvature = dataDefinedProperties().valueAsDouble( QgsCallout::Curvature, context.expressionContext(), curvature ); + } + + Orientation orientation = mOrientation; + if ( dataDefinedProperties().isActive( QgsCallout::Orientation ) ) + { + bool ok = false; + const QString orientationString = dataDefinedProperties().property( QgsCallout::Orientation ).valueAsString( context.expressionContext(), QString(), &ok ); + if ( ok ) + { + orientation = decodeOrientation( orientationString ); + } + } + + if ( orientation == Automatic ) + { + // to calculate automatically the best curve orientation, we first check which side of the label bounding box + // the callout origin is nearest to + switch ( QgsGeometryUtils::closestSideOfRectangle( rect.right(), rect.bottom(), rect.left(), rect.top(), start.x(), start.y() ) ) + { + case 1: + // closest to bottom + if ( qgsDoubleNear( end.x(), start.x() ) ) + { + // if vertical line, we bend depending on whether the line sits towards the left or right side of the label + if ( start.x() < ( rect.left() + 0.5 * rect.width() ) ) + orientation = CounterClockwise; + else + orientation = Clockwise; + } + else if ( end.x() > start.x() ) + orientation = CounterClockwise; + else + orientation = Clockwise; + break; + + case 2: + // closest to bottom-right + if ( end.x() < start.x() ) + orientation = Clockwise; + else if ( end.y() < start.y() ) + orientation = CounterClockwise; + else if ( end.x() - start.x() < end.y() - start.y() ) + orientation = Clockwise; + else + orientation = CounterClockwise; + break; + + case 3: + // closest to right + if ( qgsDoubleNear( end.y(), start.y() ) ) + { + // if horizontal line, we bend depending on whether the line sits towards the top or bottom side of the label + if ( start.y() < ( rect.top() + 0.5 * rect.height() ) ) + orientation = Clockwise; + else + orientation = CounterClockwise; + } + else if ( end.y() < start.y() ) + orientation = CounterClockwise; + else + orientation = Clockwise; + break; + + case 4: + // closest to top-right + if ( end.x() < start.x() ) + orientation = CounterClockwise; + else if ( end.y() > start.y() ) + orientation = Clockwise; + else if ( end.x() - start.x() < start.y() - end.y() ) + orientation = CounterClockwise; + else + orientation = Clockwise; + break; + + case 5: + // closest to top + if ( qgsDoubleNear( end.x(), start.x() ) ) + { + // if vertical line, we bend depending on whether the line sits towards the left or right side of the label + if ( start.x() < ( rect.left() + 0.5 * rect.width() ) ) + orientation = Clockwise; + else + orientation = CounterClockwise; + } + else if ( end.x() < start.x() ) + orientation = CounterClockwise; + else + orientation = Clockwise; + break; + + case 6: + // closest to top-left + if ( end.x() > start.x() ) + orientation = Clockwise; + else if ( end.y() > start.y() ) + orientation = CounterClockwise; + else if ( start.x() - end.x() < start.y() - end.y() ) + orientation = Clockwise; + else + orientation = CounterClockwise; + break; + + case 7: + //closest to left + if ( qgsDoubleNear( end.y(), start.y() ) ) + { + // if horizontal line, we bend depending on whether the line sits towards the top or bottom side of the label + if ( start.y() < ( rect.top() + 0.5 * rect.height() ) ) + orientation = CounterClockwise; + else + orientation = Clockwise; + } + else if ( end.y() > start.y() ) + orientation = CounterClockwise; + else + orientation = Clockwise; + break; + + case 8: + //closest to bottom-left + if ( end.x() > start.x() ) + orientation = CounterClockwise; + else if ( end.y() < start.y() ) + orientation = Clockwise; + else if ( start.x() - end.x() < end.y() - start.y() ) + orientation = CounterClockwise; + else + orientation = Clockwise; + break; + } + } + + // turn the line into a curved line. We do this by creating a circular string from the callout line's + // start to end point, where the curve point is in the middle of the callout line and perpendicularly offset + // by a proportion of the overall callout line length + const double distance = ( orientation == Clockwise ? 1 : -1 ) * start.distance( end ) * curvature / 100.0; + double midX, midY; + QgsGeometryUtils::perpendicularOffsetPointAlongSegment( start.x(), start.y(), end.x(), end.y(), 0.5, distance, &midX, &midY ); + + return new QgsCircularString( start, QgsPoint( midX, midY ), end ); +} + +QgsCurvedLineCallout::Orientation QgsCurvedLineCallout::decodeOrientation( const QString &string ) +{ + const QString cleaned = string.toLower().trimmed(); + if ( cleaned == QLatin1String( "auto" ) ) + return Automatic; + if ( cleaned == QLatin1String( "clockwise" ) ) + return Clockwise; + if ( cleaned == QLatin1String( "counterclockwise" ) ) + return CounterClockwise; + return Automatic; +} + +QString QgsCurvedLineCallout::encodeOrientation( QgsCurvedLineCallout::Orientation orientation ) +{ + switch ( orientation ) + { + case QgsCurvedLineCallout::Automatic: + return QStringLiteral( "auto" ); + case QgsCurvedLineCallout::Clockwise: + return QStringLiteral( "clockwise" ); + case QgsCurvedLineCallout::CounterClockwise: + return QStringLiteral( "counterclockwise" ); + } + return QString(); +} + +QgsCurvedLineCallout::Orientation QgsCurvedLineCallout::orientation() const +{ + return mOrientation; +} + +void QgsCurvedLineCallout::setOrientation( Orientation orientation ) +{ + mOrientation = orientation; +} + +double QgsCurvedLineCallout::curvature() const +{ + return mCurvature; +} + +void QgsCurvedLineCallout::setCurvature( double curvature ) +{ + mCurvature = curvature; +} diff --git a/src/core/callouts/qgscallout.h b/src/core/callouts/qgscallout.h index a6c295ae0ab7..57f5692ac8ee 100644 --- a/src/core/callouts/qgscallout.h +++ b/src/core/callouts/qgscallout.h @@ -57,6 +57,10 @@ class CORE_EXPORT QgsCallout { sipType = sipType_QgsManhattanLineCallout; } + else if ( sipCpp->type() == "curved" && dynamic_cast( sipCpp ) != NULL ) + { + sipType = sipType_QgsCurvedLineCallout; + } else { sipType = 0; @@ -79,6 +83,8 @@ class CORE_EXPORT QgsCallout OriginY, //!< Y-coordinate of callout origin (label anchor) (since QGIS 3.20) DestinationX, //!< X-coordinate of callout destination (feature anchor) (since QGIS 3.20) DestinationY, //!< Y-coordinate of callout destination (feature anchor) (since QGIS 3.20) + Curvature, //!< Curvature of curved line callouts (since QGIS 3.20) + Orientation, //!< Orientation of curved line callouts (since QGIS 3.20) }; //! Options for draw order (stacking) of callouts @@ -739,5 +745,104 @@ class CORE_EXPORT QgsManhattanLineCallout : public QgsSimpleLineCallout }; +/** + * \ingroup core + * \brief Draws curved lines as callouts. + * + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsCurvedLineCallout : public QgsSimpleLineCallout +{ + public: + + /** + * Curve orientation + */ + enum Orientation + { + Automatic, //!< Automatically choose most cartographically pleasing orientation based on label and callout arrangement + Clockwise, //!< Curve lines in a clockwise direction + CounterClockwise, //!< Curve lines in a counter-clockwise direction + }; + + QgsCurvedLineCallout(); + +#ifndef SIP_RUN + + /** + * Copy constructor. + */ + QgsCurvedLineCallout( const QgsCurvedLineCallout &other ); + + QgsCurvedLineCallout &operator=( const QgsCurvedLineCallout & ) = delete; +#endif + + /** + * Creates a new QgsCurvedLineCallout, using the settings + * serialized in the \a properties map (corresponding to the output from + * QgsCurvedLineCallout::properties() ). + */ + static QgsCallout *create( const QVariantMap &properties = QVariantMap(), const QgsReadWriteContext &context = QgsReadWriteContext() ) SIP_FACTORY; + + QString type() const override; + QgsCurvedLineCallout *clone() const override; + QVariantMap properties( const QgsReadWriteContext &context ) const override; + + /** + * Returns the callout line's curvature. + * + * The curvature is a percentage value (with typical ranges between 0.0 and 1.0), representing the overall curvature of the line. + * + * \see setCurvature() + */ + double curvature() const; + + /** + * Sets the callout line's \a curvature. + * + * The \a curvature is a percentage value (with typical ranges between 0.0 and 1.0), representing the overall curvature of the line. + * + * \see curvature() + */ + void setCurvature( double curvature ); + + /** + * Returns the callout line's curve orientation. + * + * \see setOrientation() + */ + Orientation orientation() const; + + /** + * Sets the callout line's curve \a orientation. + * + * \see orientation() + */ + void setOrientation( Orientation orientation ); + + protected: + QgsCurve *createCalloutLine( const QgsPoint &start, const QgsPoint &end, QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) const override SIP_FACTORY; + + private: +#ifdef SIP_RUN + QgsCurvedLineCallout( const QgsCurvedLineCallout &other ); + QgsCurvedLineCallout &operator=( const QgsCurvedLineCallout & ); +#endif + + /** + * Decodes a string to an orientation value + */ + static Orientation decodeOrientation( const QString &string ); + + /** + * Encodes an orientation string + */ + static QString encodeOrientation( Orientation orientation ); + + + Orientation mOrientation = Automatic; + double mCurvature = 0.1; +}; + #endif // QGSCALLOUT_H diff --git a/src/core/callouts/qgscalloutsregistry.cpp b/src/core/callouts/qgscalloutsregistry.cpp index f803e8fe3303..1703d2744598 100644 --- a/src/core/callouts/qgscalloutsregistry.cpp +++ b/src/core/callouts/qgscalloutsregistry.cpp @@ -51,6 +51,7 @@ QgsCalloutRegistry::QgsCalloutRegistry() // init registry with known callouts addCalloutType( new QgsCalloutMetadata( QStringLiteral( "simple" ), QObject::tr( "Simple lines" ), QgsApplication::getThemeIcon( QStringLiteral( "labelingCalloutSimple.svg" ) ), QgsSimpleLineCallout::create ) ); addCalloutType( new QgsCalloutMetadata( QStringLiteral( "manhattan" ), QObject::tr( "Manhattan lines" ), QgsApplication::getThemeIcon( QStringLiteral( "labelingCalloutManhattan.svg" ) ), QgsManhattanLineCallout::create ) ); + addCalloutType( new QgsCalloutMetadata( QStringLiteral( "curved" ), QObject::tr( "Curved lines" ), QgsApplication::getThemeIcon( QStringLiteral( "labelingCalloutSimple.svg" ) ), QgsCurvedLineCallout::create ) ); } QgsCalloutRegistry::~QgsCalloutRegistry() diff --git a/src/gui/callouts/qgscalloutwidget.cpp b/src/gui/callouts/qgscalloutwidget.cpp index 7054046122ee..58bc8911a7e1 100644 --- a/src/gui/callouts/qgscalloutwidget.cpp +++ b/src/gui/callouts/qgscalloutwidget.cpp @@ -314,5 +314,211 @@ QgsManhattanLineCalloutWidget::QgsManhattanLineCalloutWidget( QgsVectorLayer *vl } +// +// QgsCurvedLineCalloutWidget +// + +QgsCurvedLineCalloutWidget::QgsCurvedLineCalloutWidget( QgsVectorLayer *vl, QWidget *parent ) + : QgsCalloutWidget( parent, vl ) +{ + setupUi( this ); + + // Callout options - to move to custom widgets when multiple callout styles exist + mCalloutLineStyleButton->setSymbolType( QgsSymbol::Line ); + mCalloutLineStyleButton->setDialogTitle( tr( "Callout Symbol" ) ); + mCalloutLineStyleButton->registerExpressionContextGenerator( this ); + + mCalloutLineStyleButton->setLayer( vl ); + mMinCalloutWidthUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels + << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); + mOffsetFromAnchorUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels + << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); + mOffsetFromLabelUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels + << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); + + connect( mMinCalloutWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsCurvedLineCalloutWidget::minimumLengthUnitWidgetChanged ); + connect( mMinCalloutLengthSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsCurvedLineCalloutWidget::minimumLengthChanged ); + + connect( mOffsetFromAnchorUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsCurvedLineCalloutWidget::offsetFromAnchorUnitWidgetChanged ); + connect( mOffsetFromAnchorSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsCurvedLineCalloutWidget::offsetFromAnchorChanged ); + connect( mOffsetFromLabelUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsCurvedLineCalloutWidget::offsetFromLabelUnitWidgetChanged ); + connect( mOffsetFromLabelSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsCurvedLineCalloutWidget::offsetFromLabelChanged ); + + connect( mDrawToAllPartsCheck, &QCheckBox::toggled, this, &QgsCurvedLineCalloutWidget::drawToAllPartsToggled ); + + mOrientationComboBox->addItem( tr( "Automatic" ), static_cast< int >( QgsCurvedLineCallout::Automatic ) ); + mOrientationComboBox->addItem( tr( "Clockwise" ), static_cast< int >( QgsCurvedLineCallout::Clockwise ) ); + mOrientationComboBox->addItem( tr( "Counter Clockwise" ), static_cast< int >( QgsCurvedLineCallout::CounterClockwise ) ); + connect( mOrientationComboBox, static_cast( &QComboBox::currentIndexChanged ), this, [ = ]( int index ) + { + mCallout->setOrientation( static_cast( mOrientationComboBox->itemData( index ).toInt() ) ); + emit changed(); + } ); + + // Anchor point options + mAnchorPointComboBox->addItem( tr( "Pole of Inaccessibility" ), static_cast< int >( QgsCallout::PoleOfInaccessibility ) ); + mAnchorPointComboBox->addItem( tr( "Point on Exterior" ), static_cast< int >( QgsCallout::PointOnExterior ) ); + mAnchorPointComboBox->addItem( tr( "Point on Surface" ), static_cast< int >( QgsCallout::PointOnSurface ) ); + mAnchorPointComboBox->addItem( tr( "Centroid" ), static_cast< int >( QgsCallout::Centroid ) ); + connect( mAnchorPointComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsCurvedLineCalloutWidget::mAnchorPointComboBox_currentIndexChanged ); + + mLabelAnchorPointComboBox->addItem( tr( "Closest Point" ), static_cast< int >( QgsCallout::LabelPointOnExterior ) ); + mLabelAnchorPointComboBox->addItem( tr( "Centroid" ), static_cast< int >( QgsCallout::LabelCentroid ) ); + mLabelAnchorPointComboBox->addItem( tr( "Top Left" ), static_cast< int >( QgsCallout::LabelTopLeft ) ); + mLabelAnchorPointComboBox->addItem( tr( "Top Center" ), static_cast< int >( QgsCallout::LabelTopMiddle ) ); + mLabelAnchorPointComboBox->addItem( tr( "Top Right" ), static_cast< int >( QgsCallout::LabelTopRight ) ); + mLabelAnchorPointComboBox->addItem( tr( "Left Middle" ), static_cast< int >( QgsCallout::LabelMiddleLeft ) ); + mLabelAnchorPointComboBox->addItem( tr( "Right Middle" ), static_cast< int >( QgsCallout::LabelMiddleRight ) ); + mLabelAnchorPointComboBox->addItem( tr( "Bottom Left" ), static_cast< int >( QgsCallout::LabelBottomLeft ) ); + mLabelAnchorPointComboBox->addItem( tr( "Bottom Center" ), static_cast< int >( QgsCallout::LabelBottomMiddle ) ); + mLabelAnchorPointComboBox->addItem( tr( "Bottom Right" ), static_cast< int >( QgsCallout::LabelBottomRight ) ); + connect( mLabelAnchorPointComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsCurvedLineCalloutWidget::mLabelAnchorPointComboBox_currentIndexChanged ); + + connect( mCalloutLineStyleButton, &QgsSymbolButton::changed, this, &QgsCurvedLineCalloutWidget::lineSymbolChanged ); + + connect( mCurvatureSlider, &QSlider::valueChanged, this, [ = ]( int value ) { mCurvatureSpinBox->setValue( value / 10.0 ); } ); + connect( mCurvatureSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( double value ) { whileBlocking( mCurvatureSlider )->setValue( value * 10 ); } ); + connect( mCurvatureSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( double value ) + { + mCallout->setCurvature( value / 100.0 ); + emit changed(); + } ); + +} + +void QgsCurvedLineCalloutWidget::setCallout( QgsCallout *callout ) +{ + if ( !callout ) + return; + + mCallout.reset( dynamic_cast( callout->clone() ) ); + if ( !mCallout ) + return; + + mMinCalloutWidthUnitWidget->blockSignals( true ); + mMinCalloutWidthUnitWidget->setUnit( mCallout->minimumLengthUnit() ); + mMinCalloutWidthUnitWidget->setMapUnitScale( mCallout->minimumLengthMapUnitScale() ); + mMinCalloutWidthUnitWidget->blockSignals( false ); + + whileBlocking( mMinCalloutLengthSpin )->setValue( mCallout->minimumLength() ); + + mOffsetFromAnchorUnitWidget->blockSignals( true ); + mOffsetFromAnchorUnitWidget->setUnit( mCallout->offsetFromAnchorUnit() ); + mOffsetFromAnchorUnitWidget->setMapUnitScale( mCallout->offsetFromAnchorMapUnitScale() ); + mOffsetFromAnchorUnitWidget->blockSignals( false ); + mOffsetFromLabelUnitWidget->blockSignals( true ); + mOffsetFromLabelUnitWidget->setUnit( mCallout->offsetFromLabelUnit() ); + mOffsetFromLabelUnitWidget->setMapUnitScale( mCallout->offsetFromLabelMapUnitScale() ); + mOffsetFromLabelUnitWidget->blockSignals( false ); + whileBlocking( mOffsetFromAnchorSpin )->setValue( mCallout->offsetFromAnchor() ); + whileBlocking( mOffsetFromLabelSpin )->setValue( mCallout->offsetFromLabel() ); + + whileBlocking( mCalloutLineStyleButton )->setSymbol( mCallout->lineSymbol()->clone() ); + + whileBlocking( mDrawToAllPartsCheck )->setChecked( mCallout->drawCalloutToAllParts() ); + + whileBlocking( mOrientationComboBox )->setCurrentIndex( mOrientationComboBox->findData( static_cast< int >( mCallout->orientation() ) ) ); + + whileBlocking( mAnchorPointComboBox )->setCurrentIndex( mAnchorPointComboBox->findData( static_cast< int >( callout->anchorPoint() ) ) ); + whileBlocking( mLabelAnchorPointComboBox )->setCurrentIndex( mLabelAnchorPointComboBox->findData( static_cast< int >( callout->labelAnchorPoint() ) ) ); + + whileBlocking( mCurvatureSpinBox )->setValue( mCallout->curvature() * 100.0 ); + whileBlocking( mCurvatureSlider )->setValue( mCallout->curvature() * 1000.0 ); + + registerDataDefinedButton( mMinCalloutLengthDDBtn, QgsCallout::MinimumCalloutLength ); + registerDataDefinedButton( mOffsetFromAnchorDDBtn, QgsCallout::OffsetFromAnchor ); + registerDataDefinedButton( mOffsetFromLabelDDBtn, QgsCallout::OffsetFromLabel ); + registerDataDefinedButton( mDrawToAllPartsDDBtn, QgsCallout::DrawCalloutToAllParts ); + registerDataDefinedButton( mAnchorPointDDBtn, QgsCallout::AnchorPointPosition ); + registerDataDefinedButton( mLabelAnchorPointDDBtn, QgsCallout::LabelAnchorPointPosition ); + registerDataDefinedButton( mCalloutCurvatureDDBtn, QgsCallout::Curvature ); + registerDataDefinedButton( mCalloutOrientationDDBtn, QgsCallout::Orientation ); + + registerDataDefinedButton( mOriginXDDBtn, QgsCallout::OriginX ); + registerDataDefinedButton( mOriginYDDBtn, QgsCallout::OriginY ); + registerDataDefinedButton( mDestXDDBtn, QgsCallout::DestinationX ); + registerDataDefinedButton( mDestYDDBtn, QgsCallout::DestinationY ); +} + +void QgsCurvedLineCalloutWidget::setGeometryType( QgsWkbTypes::GeometryType type ) +{ + bool isPolygon = type == QgsWkbTypes::PolygonGeometry; + mAnchorPointLbl->setEnabled( isPolygon ); + mAnchorPointLbl->setVisible( isPolygon ); + mAnchorPointComboBox->setEnabled( isPolygon ); + mAnchorPointComboBox->setVisible( isPolygon ); + mAnchorPointDDBtn->setEnabled( isPolygon ); + mAnchorPointDDBtn->setVisible( isPolygon ); +} + +QgsCallout *QgsCurvedLineCalloutWidget::callout() +{ + return mCallout.get(); +} + +void QgsCurvedLineCalloutWidget::minimumLengthChanged() +{ + mCallout->setMinimumLength( mMinCalloutLengthSpin->value() ); + emit changed(); +} + +void QgsCurvedLineCalloutWidget::minimumLengthUnitWidgetChanged() +{ + mCallout->setMinimumLengthUnit( mMinCalloutWidthUnitWidget->unit() ); + mCallout->setMinimumLengthMapUnitScale( mMinCalloutWidthUnitWidget->getMapUnitScale() ); + emit changed(); +} + +void QgsCurvedLineCalloutWidget::offsetFromAnchorUnitWidgetChanged() +{ + mCallout->setOffsetFromAnchorUnit( mOffsetFromAnchorUnitWidget->unit() ); + mCallout->setOffsetFromAnchorMapUnitScale( mOffsetFromAnchorUnitWidget->getMapUnitScale() ); + emit changed(); +} + +void QgsCurvedLineCalloutWidget::offsetFromAnchorChanged() +{ + mCallout->setOffsetFromAnchor( mOffsetFromAnchorSpin->value() ); + emit changed(); +} + +void QgsCurvedLineCalloutWidget::offsetFromLabelUnitWidgetChanged() +{ + mCallout->setOffsetFromLabelUnit( mOffsetFromLabelUnitWidget->unit() ); + mCallout->setOffsetFromLabelMapUnitScale( mOffsetFromLabelUnitWidget->getMapUnitScale() ); + emit changed(); +} + +void QgsCurvedLineCalloutWidget::offsetFromLabelChanged() +{ + mCallout->setOffsetFromLabel( mOffsetFromLabelSpin->value() ); + emit changed(); +} + +void QgsCurvedLineCalloutWidget::lineSymbolChanged() +{ + mCallout->setLineSymbol( mCalloutLineStyleButton->clonedSymbol< QgsLineSymbol >() ); + emit changed(); +} + +void QgsCurvedLineCalloutWidget::mAnchorPointComboBox_currentIndexChanged( int index ) +{ + mCallout->setAnchorPoint( static_cast( mAnchorPointComboBox->itemData( index ).toInt() ) ); + emit changed(); +} + +void QgsCurvedLineCalloutWidget::mLabelAnchorPointComboBox_currentIndexChanged( int index ) +{ + mCallout->setLabelAnchorPoint( static_cast( mLabelAnchorPointComboBox->itemData( index ).toInt() ) ); + emit changed(); +} + +void QgsCurvedLineCalloutWidget::drawToAllPartsToggled( bool active ) +{ + mCallout->setDrawCalloutToAllParts( active ); + emit changed(); +} + + ///@endcond diff --git a/src/gui/callouts/qgscalloutwidget.h b/src/gui/callouts/qgscalloutwidget.h index 9d84db688edf..73e10498e372 100644 --- a/src/gui/callouts/qgscalloutwidget.h +++ b/src/gui/callouts/qgscalloutwidget.h @@ -172,6 +172,49 @@ class GUI_EXPORT QgsManhattanLineCalloutWidget : public QgsSimpleLineCalloutWidg }; + +/////////// + +#include "ui_widget_curvedlinecallout.h" + +class QgsCurvedLineCallout; +///@cond PRIVATE + +class GUI_EXPORT QgsCurvedLineCalloutWidget : public QgsCalloutWidget, private Ui::WidgetCurvedLineCallout +{ + Q_OBJECT + + public: + + QgsCurvedLineCalloutWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr ); + + static QgsCalloutWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsCurvedLineCalloutWidget( vl ); } + + void setCallout( QgsCallout *callout ) override; + + QgsCallout *callout() override; + + void setGeometryType( QgsWkbTypes::GeometryType type ) override; + + private slots: + + void minimumLengthChanged(); + void minimumLengthUnitWidgetChanged(); + void offsetFromAnchorUnitWidgetChanged(); + void offsetFromAnchorChanged(); + void offsetFromLabelUnitWidgetChanged(); + void offsetFromLabelChanged(); + void lineSymbolChanged(); + void mAnchorPointComboBox_currentIndexChanged( int index ); + void mLabelAnchorPointComboBox_currentIndexChanged( int index ); + void drawToAllPartsToggled( bool active ); + + private: + std::unique_ptr< QgsCurvedLineCallout > mCallout; + +}; + + #endif ///@endcond diff --git a/src/gui/labeling/qgslabelinggui.cpp b/src/gui/labeling/qgslabelinggui.cpp index 6163774b0316..425af01a7dcb 100644 --- a/src/gui/labeling/qgslabelinggui.cpp +++ b/src/gui/labeling/qgslabelinggui.cpp @@ -84,6 +84,7 @@ void QgsLabelingGui::initCalloutWidgets() { _initCalloutWidgetFunction( QStringLiteral( "simple" ), QgsSimpleLineCalloutWidget::create ); _initCalloutWidgetFunction( QStringLiteral( "manhattan" ), QgsManhattanLineCalloutWidget::create ); + _initCalloutWidgetFunction( QStringLiteral( "curved" ), QgsCurvedLineCalloutWidget::create ); } void QgsLabelingGui::updateCalloutWidget( QgsCallout *callout ) diff --git a/src/ui/callouts/widget_curvedlinecallout.ui b/src/ui/callouts/widget_curvedlinecallout.ui new file mode 100644 index 000000000000..b2ab822adae9 --- /dev/null +++ b/src/ui/callouts/widget_curvedlinecallout.ui @@ -0,0 +1,555 @@ + + + WidgetCurvedLineCallout + + + + 0 + 0 + 385 + 429 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + + + + + + + + + + + + + + + + + Offset from feature + + + + + + + + + + + + + + + 10 + 0 + + + + Qt::StrongFocus + + + + + + + Label anchor point + + + + + + + + 1 + 0 + + + + 6 + + + 100000.000000000000000 + + + 0.200000000000000 + + + 0.000000000000000 + + + true + + + + + + + Line style + + + + + + + Draw lines to all feature parts + + + + + + + + + + + + + + Offset from label area + + + + + + + + + + + + + + + + + + + + + + 10 + 0 + + + + Qt::StrongFocus + + + + + + + + + 1000 + + + 10 + + + 100 + + + 100 + + + Qt::Horizontal + + + + + + + % + + + 1 + + + 100.000000000000000 + + + + + + + + + Minimum length + + + + + + + Curvature + + + + + + + + 1 + 0 + + + + 6 + + + 100000.000000000000000 + + + 0.200000000000000 + + + 0.000000000000000 + + + true + + + + + + + + + + + + + + + + + + + + + 10 + 0 + + + + Qt::StrongFocus + + + + + + + + 1 + 0 + + + + 6 + + + 100000.000000000000000 + + + 0.200000000000000 + + + 1.000000000000000 + + + true + + + + + + + Anchor point + + + + + + + + 0 + 0 + + + + Symbol… + + + + + + + Orientation + + + + + + + + + + + + + + + + + + + Data Defined Placement + + + false + + + labelplacementgroup + + + + 8 + + + 8 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 0 + + + + X + + + + + + + + + + + + + + + 0 + 0 + + + + Y + + + + + + + + + + + + + + Qt::Horizontal + + + + 0 + 20 + + + + + + + + + + + + + Origin + + + + + + + + + + 0 + 0 + + + + X + + + + + + + + + + + + + + + 0 + 0 + + + + Y + + + + + + + + + + + + + + Qt::Horizontal + + + + 0 + 20 + + + + + + + + + + Destination + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + QgsDoubleSpinBox + QDoubleSpinBox +

qgsdoublespinbox.h
+ + + QgsSymbolButton + QToolButton +
qgssymbolbutton.h
+
+ + QgsPropertyOverrideButton + QToolButton +
qgspropertyoverridebutton.h
+
+ + QgsUnitSelectionWidget + QWidget +
qgsunitselectionwidget.h
+ 1 +
+ + + mCalloutLineStyleButton + mMinCalloutLengthSpin + mMinCalloutWidthUnitWidget + mMinCalloutLengthDDBtn + mOffsetFromAnchorSpin + mOffsetFromAnchorUnitWidget + mOffsetFromAnchorDDBtn + mOffsetFromLabelSpin + mOffsetFromLabelUnitWidget + mOffsetFromLabelDDBtn + mDrawToAllPartsCheck + mDrawToAllPartsDDBtn + mAnchorPointComboBox + mAnchorPointDDBtn + mLabelAnchorPointComboBox + mLabelAnchorPointDDBtn + + + + diff --git a/tests/src/core/testqgscallout.cpp b/tests/src/core/testqgscallout.cpp index db7a2e0e54fb..e8dcc49f1760 100644 --- a/tests/src/core/testqgscallout.cpp +++ b/tests/src/core/testqgscallout.cpp @@ -159,6 +159,19 @@ class TestQgsCallout: public QObject void manhattanDataDefinedDrawToAllParts(); void manhattanDataDefinedDestination(); void manhattanDataDefinedOrigin(); + void curvedAutoLeavingLabelsAtBottomLeft(); + void curvedAutoLeavingLabelsAtBottomRight(); + void curvedAutoLeavingLabelsAtTopLeft(); + void curvedAutoLeavingLabelsAtTopRight(); + void curvedAutoLeavingLabelsAtTop(); + void curvedAutoLeavingLabelsAtBottom(); + void curvedAutoLeavingLabelsAtLeft(); + void curvedAutoLeavingLabelsAtRight(); + void curvedAutoHorizontalLines(); + void curvedAutoVerticalLines(); + void curvedClockwise(); + void curvedCounterClockwise(); + void curvedCurvature(); private: bool imageCheck( const QString &testName, QImage &image, unsigned int mismatchCount = 0 ); @@ -2633,6 +2646,1246 @@ void TestQgsCallout::manhattanDataDefinedOrigin() QVERIFY( imageCheck( "manhattan_data_defined_origin", img, 20 ) ); } + +void TestQgsCallout::curvedAutoLeavingLabelsAtBottomLeft() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'X'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setLabelAnchorPoint( QgsCallout::LabelBottomLeft ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_auto_leaving_labels_at_bottom_left", img, 20 ) ); +} + +void TestQgsCallout::curvedAutoLeavingLabelsAtBottomRight() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'X'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setLabelAnchorPoint( QgsCallout::LabelBottomRight ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_auto_leaving_labels_at_bottom_right", img, 20 ) ); +} + +void TestQgsCallout::curvedAutoLeavingLabelsAtTopLeft() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'X'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setLabelAnchorPoint( QgsCallout::LabelTopLeft ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_auto_leaving_labels_at_top_left", img, 20 ) ); +} + +void TestQgsCallout::curvedAutoLeavingLabelsAtTopRight() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'X'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setLabelAnchorPoint( QgsCallout::LabelTopRight ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_auto_leaving_labels_at_top_right", img, 20 ) ); +} + +void TestQgsCallout::curvedAutoLeavingLabelsAtTop() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'XXXX'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setLabelAnchorPoint( QgsCallout::LabelTopMiddle ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_auto_leaving_labels_at_top", img, 20 ) ); +} + +void TestQgsCallout::curvedAutoLeavingLabelsAtBottom() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'XXXX'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setLabelAnchorPoint( QgsCallout::LabelBottomMiddle ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_auto_leaving_labels_at_bottom", img, 20 ) ); +} + +void TestQgsCallout::curvedAutoLeavingLabelsAtLeft() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'XXXX'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setLabelAnchorPoint( QgsCallout::LabelMiddleLeft ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_auto_leaving_labels_at_left", img, 20 ) ); +} + +void TestQgsCallout::curvedAutoLeavingLabelsAtRight() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'XXXX'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setLabelAnchorPoint( QgsCallout::LabelMiddleRight ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_auto_leaving_labels_at_right", img, 20 ) ); +} + +void TestQgsCallout::curvedAutoHorizontalLines() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000148 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180180 << 5000148 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000167 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000170)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180180 << 5000167 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'XXXX'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 20 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_auto_horizontal_lines", img, 20 ) ); +} + +void TestQgsCallout::curvedAutoVerticalLines() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180110 << 5000180 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180120 5000160)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180110 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + f.setAttributes( QgsAttributes() << 1 << 180175 << 5000180 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180180 5000160)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180175 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'XXXX'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 20 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_auto_vertical_lines", img, 20 ) ); +} + +void TestQgsCallout::curvedClockwise() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'X'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setOrientation( QgsCurvedLineCallout::Clockwise ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_clockwise", img, 20 ) ); +} + +void TestQgsCallout::curvedCounterClockwise() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'X'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setOrientation( QgsCurvedLineCallout::CounterClockwise ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_counterclockwise", img, 20 ) ); +} + +void TestQgsCallout::curvedCurvature() +{ + std::unique_ptr< QgsVectorLayer> vl2( new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:3946&field=id:integer&field=labelx:integer&field=labely:integer" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) ); + vl2->setRenderer( new QgsNullSymbolRenderer() ); + + QgsFeature f; + f.setAttributes( QgsAttributes() << 1 << 180120 << 5000160 ); + f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "Point (180150 5000150)" ) ) ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 2 << 180120 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 3 << 180120 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 4 << 180130 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 5 << 180140 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 6 << 180160 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 7 << 180170 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 8 << 180180 << 5000180 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 9 << 180180 << 5000170 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 10 << 180180 << 5000160 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 11 << 180180 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 12 << 180180 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 13 << 180180 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 14 << 180170 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 15 << 180160 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 16 << 180140 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 17 << 180130 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 18 << 180120 << 5000120 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 19 << 180120 << 5000130 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + f.setAttributes( QgsAttributes() << 20 << 180120 << 5000140 ); + QVERIFY( vl2->dataProvider()->addFeature( f ) ); + + QSize size( 640, 640 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) ); + mapSettings.setExtent( QgsRectangle( 180100, 5000100, 180200, 5000200 ) ); + mapSettings.setLayers( QList() << vl2.get() ); + mapSettings.setOutputDpi( 96 ); + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + context.setCoordinateTransform( QgsCoordinateTransform( vl2->crs(), mapSettings.destinationCrs(), QgsProject::instance()->transformContext() ) ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "'X'" ); + settings.isExpression = true; + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionX, QgsProperty::fromField( QStringLiteral( "labelx" ) ) ); + settings.dataDefinedProperties().setProperty( QgsPalLayerSettings::PositionY, QgsProperty::fromField( QStringLiteral( "labely" ) ) ); + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsCurvedLineCallout *callout = new QgsCurvedLineCallout(); + callout->setEnabled( true ); + callout->lineSymbol()->setWidth( 1 ); + callout->setOrientation( QgsCurvedLineCallout::Clockwise ); + callout->setCurvature( 0.3 ); + settings.setCallout( callout ); + + vl2->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary! + vl2->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl2.get(), QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "curved_curvature", img, 20 ) ); +} + // // Private helper functions not called directly by CTest // diff --git a/tests/testdata/control_images/callouts/expected_curved_auto_horizontal_lines/expected_curved_auto_horizontal_lines.png b/tests/testdata/control_images/callouts/expected_curved_auto_horizontal_lines/expected_curved_auto_horizontal_lines.png new file mode 100644 index 0000000000000000000000000000000000000000..c816e4146668313ee65e3e8836817b48c38625a7 GIT binary patch literal 13424 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 F{{q9tO{4$- literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_bottom/expected_curved_auto_leaving_labels_at_bottom.png b/tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_bottom/expected_curved_auto_leaving_labels_at_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..55aef2536aa7fa1d13fd556d2059d7234e976c83 GIT binary patch literal 68750 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 literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_corners/expected_curved_auto_leaving_labels_at_corners.png b/tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_corners/expected_curved_auto_leaving_labels_at_corners.png new file mode 100644 index 0000000000000000000000000000000000000000..dcaf36c08ddb98d1aaa9b365002ff24c8262ffd7 GIT binary patch literal 57623 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 E0Jw`c;s5{u literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_left/expected_curved_auto_leaving_labels_at_left.png b/tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_left/expected_curved_auto_leaving_labels_at_left.png new file mode 100644 index 0000000000000000000000000000000000000000..9856ef893b09fd0febce20779ed7f68a20ceebc7 GIT binary patch literal 70340 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 literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_right/expected_curved_auto_leaving_labels_at_right.png b/tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_right/expected_curved_auto_leaving_labels_at_right.png new file mode 100644 index 0000000000000000000000000000000000000000..7ab63e4305cf7f4a48703e3df45c94bb029d9bd9 GIT binary patch literal 68615 zcmeFZWl&b_+b_I8F-TEFBm_aaK|n%4q(eGIO1dSbF%aqQ7LboSjKYDaZ(J5zrH2 z7mEc^M{9iXD^4x;R9(ZsqLWn4r6Ur%g?6`AagDmzBJj`4HB*9T!ndx9jr~A#u51(< zp04`QoN8O^wk7D*Z5ceih_SKW(^H49K!9=M;m2DBF`=u-Es+~(CpYe}iQIVDj3)aX z_4Dg&XjC6>iI9H38VJ9AgZ$rL{@+3PKY1lQuEI@iV02SabNF@xX^u8{ZSvZ#ZqM3m zJJSH^v;1P#H%(!q{6GOgj3c@~@@=vt5VZJ@jO$!MZhW`Q)tvGB>EDHk^sVM(&1O8G zV(`-SoX?X+`Zm+?FzNVouOjhk@#4>e+AK0EGpW_35#dhpPTSCjzY1Bl^Y|Sv&)7Y! zXVsl!y?MWmigLO+I=Pth-uS*Y(>`EWxQnzUx5tZf zXL@lrQBgTRXF+0Xg1w@ zy6%^B9Ujzm8Io~bw8AveL~QGpK5yqKo~^u?6!Hp889y2#!+mBiJ1A^eIfQ!^A;_r8 zppzy*LTADhlXY+r!VSW`6w!z+n%n$0kvY+M0%}4u;h7wflSrw!?|;n(vopWsuM4RXFbdyb4zB1c>Hjh<-I(Qh(ctdVP&eo5=gE4$wzc*T zs|C?pHZofR}u1bY>ns@l4D#SE4Nr!Sb)zQ92}gS zoUGh!Y*UUxackG=-g}QcXK-`5RiY-D848|cA9j6-apMk#8tpWe_z!- zC)P7a_<7%ssEizAcVp5ECeyyJXZH>UHACb9Ud`1%CO+rA!pI^xt+FMbjW!( zC@Bad{xXz8PQ3n7(@MfBiPcfiJ;?g{E5D}G-}gfvvoJHis?ZDxijDS`ST4|QCfcf@yW^h)YMcM>W7}MUQK@aLRoWqvcH-x5uzq^#OJ-+OODvt z*|p)@+uN51T&|6lI;iKUjE#=wsGmt^+BJQ`aZqQ7>X_e=_t%xvM_&j?ROK}a>5$}c z)MCiYK50mbCy*XzND#SyZp=@)d^1yiqo@6hY0KsnL8DtwkyzdFJE@knHF4qrqeV0XU@!Tfa<3zmw$+U=(_!F{d z6WzJ&#lni^w6!!3b}#J0qX^HaCCZ$o3KX=&YDT{{d_8>!xsc#V8} zMMg@xG%`0oPsZ=GCPY<8@^d-IWBO8`FsSRSc{S|7$fFZ^UH^IX; zEE@Ub{LD<%^P{1AG6ofe_DTYq`&7eaa5 zxBmY4*AgHknAnnXWE5hwzeN)(l+wsCKUr8=UG1{J_;2TtXOb0PkTgku;qrK;4cCW7 z`Lk((vroa(V`Hv=zrPy_(Jg?*rK4sVy%$UXGZIJ4PZB`lpHN_P4N<{};$x4xXbPQ* zHuf<@^Zp}ZdB^GsdXZl#KF{qd!p6eJ%jZg|Uj4Lnr(%^sl|yX(Z1=51ghIlmA{(&1 zc$^~dCWJ)ix8ESKkpK@u;)%NeOAvB(>O zZ_eUqx3TX2?3b4apbIN5esg-TK1Ao)NhgEcq8D>GgF;a#^c(LD;p5f}FKK1k40Me6 z==kms?tA7~Xu`Eo&@o+LjddhS-xB%o4JR4fT_ncd{?B^qZ}IDhXbq(lR(rxnp45-f zm~d!$x-dIBghKHEBXltdOnZD-Ivn<@pDiyD)pRfZvm}wev$qo|MKApBYm{+-?#mn0 zB1oUpAd8op&Pi(7j!~vCQ{QF|9wII-E_Al_Avt-f-tCY86XV?4#l@xZ{2)P;@{NN- zh7JDFeXsEfD=aK5av@LIMk#Z1b15mQ#hxUgx`LUPXCiWGEr*1Detvr)CWeOCB;5J9 zg@JQJi#7`SsRRtlI7f1eX99xQf%9Oq+x8&4!ce%dtV`OFgff z(r2%N0J&;__KG~Xt*Z+g3#-<7^TDnjJmC4+Syy+r3rV9=4ita-U0l19y=7=?iS6k*+rhyF+t@x%b`4yl)bn^JFTyEcK=_eUT_xS&*Oav_6(8-pCAHPrz>O#^lDI;@6_0 zS1Y%Ruv5^|FKGxceeuW}UbhBAR|+R(f@V@-8JCixtFQmix7g#O29r*WgIQ-Zb9-1( zQBeYqjUAB^*Z$`8bl2Le<%YSrIT%1Y5_u2dPo&8Ajt>7ONx>o5G*YLvn+?k8YYEZO z2je!4{Z{XU*(`>ctY`JfY4lWH1(EOs2L~rVb>p`8X=(|$_extE+F*;m9{IyCNwos4 zp$w@zHF*kjgseJeYonaj=_m3A#Yb5wo|Kc5wa)fLvQM}FwP4jeB*0{5X0FEhdJ-u; zzx+E(N}c)I+s}XgXmIe`efLH)#L+o_caz8iJx$?>aaSyS>Dc&q#D_xNMkick|Cd4H9)v{sgv<6>f3tyC_}+Cm>@L@vPZ1QXqZ&GE$)&CJXkY8BJP zQ_4O^zpS*LblqLRnY13SSkEHd`q#HUUI{fpy0W~i?5kYDFDrpW;JSiw1qJJ$a7e^M z9&`)DhK901$yj*uz)M3zW@d_)&dVq9MI|Q6Rt5zI{t71Rv=Y$%0gp4SuIo|mxH@dpaQums zo{B_%r}x?c0#$$Wu< zLLaoK|8ko2gpwRWy;1i%Wwnlqj{f$tGS~sIQ-1m`9trp0^;mDkAR;27kDorVXjdsH z@16(0mI!%}#BD`PU(iDic;xj9>#=s)_>p3lzC#!YL(v_e@n>FJ&G zgGR>2Rfg|skDid2k^2dSKq&x^3-ML5jC}s^-E1n_Lv(x znrdppu#6?0FV2qlv$p1Z+0fF*^erq%$jN)_uw&W{A3l7Tr&jQ9Xw5WDfrx-W)JZ0) zb3Wi6tFiUfP97@pK#KMA(?feAsaIl(1fy%6uy%EIQ^w!sE(1W!IB&ue%I@6JHGZ1% z;Hj&-(&$Rf^*e02T(|w2J3B4f!>PMwmYRI=YHMnC7@C%smOlFU+$SRHn|%Ks-Nwdd z>V^NtXeq7c^Zl)v=Nyh0L(vlx+9fuR?LEj+V9=BKorA5hd_)}MF5Op$3*epxtXwH+ zE4OWN;X91rwx-L>?%0!VZqK$Vf0eC%GkeWfQB~jC`T;Sq^a4>$R34it%ds*)2Vg#{>jP9Y@C~Y0(chJp?!vX>xU73pgoI!T=I1lvUU?nQWAh-+ zIA4VU*b-prYMf_>xWIXO8F&*4Aj4n1}oFJJ8YlmxjyM&4RlGF9(b z|Nbi1=y_fh2fKJe(|7gfz?GL+;$g@hoOlGF0ZB_!8IVC0G)t#H4@u@7Wtat-` z)j|5>HZ?V^0u<=t62_06sdOJ7zu0_;K~TjRSVz2&m*Db)C$`?ccMGoLl1g49=}qKq zYBES!`OF*L_eBf~mnsL>N8}Am^nlTeki`Oz(}S>Qp08ie!i?FI;1%kji?7{(Y}yyk zWzm+ahCFdU+WP5(6%Y`>8|V)lpewPW-k=4O<8=frJScQ&*~(0%Wgo12RY6(SlG4(Y zRu{B?Wnx(BUHAR1VYU-xb^jJ5CME(Ijrf+AmsdlOZ+x9buQ`{s;fPXDFu8j70BXHS zcYMon8PhxABGZ1#5_e6Sh~v{!brls`64kpOuH(_HN6^aK5lJOI`zjnDN_oMGZX7K_ z!ftT2Hzh-f;4VJCqK?iB=kan2U;DybXcT{ji}agd@0axAAsJa&y|L`GKR#S16~{pM z`1pSO_>mE)E-j5|->D>cbh295&e;eJXnubF4M|81BNNjjbx)wzU6|Gak%@`!ha0bI ztY9uki)ONR7khQR#>L*0MV7?e$B!SM9B#^2()<6!_`wBThiU-YG?#CfN^671siYfVet|~q zQ0dIDu&@k%&$A;Mxp-S5JRyB_@rheEt^!feDlxnn7pgYd4wq>sTaM192%+3&FKNyT?krs`at(_Aw*HQj1F8G|zwIYH5i} zNQgjfjDy|XS=+dviV7zMggvSa2kOdD!FODCLPgU4RNK=o2S0ck-=ue;Y-hLg?NzPh zNOyP8vG+|?09D&Qu!wMQjCxq4WMmR}?TuYs`DnLq_=pGz2`TYVaB@ZnQ8NI26&v$9 z+rIAnE}MP9r!z*^vt9oYIW$X`l4qZTf^g`6{d|t;L&?MxDEoJ5xL~|;+OyM2Qot9k z|5<^~!PyywXL!RC5>{7MPL8%;zxc<_#kIe`Pdy23Pq)@7C_*y#2moe#sF{HQWw3}B zga4N{Cklh&Dx=QmiC?=mbp8fY7l4F`f4+`^OJq}+Ug*Qbwd-AMvv2I zYtX#HD=o}zrs||B0!;rD=>rI_4qBud7#N6Er9~Bq315P9D%tO!L$2Wvm%)&iI6R|? zaC!SyyTLs!LT{lrMV`iNadA;XOzh2V@w-65Xx5vXMRBPVC7d@V9Ju_tP8g?1qk zMBFmoB7o^*0Km>LO$8_mjI4z9b0w@;Z+v-=-EN*d^+Mz5<*ohwdBdTgZ{NP9q>wKs z1E>LBzUHflQ5wAnWv_^`l~x}&d&?bd%MfQ+WpGy zYw>#7Xa98E#MaE>FMpb zp9sXx&vtu#amfsX!s9qi!VB*vV~ZXx^?xXPQBPV;H=Kt)d|rhk6$HJ(-2~7WAX26%D7(eZn>x`= zsn>@k4?%u3%)0l@9mXvq=w{W)#o4a>z{2{KzXdNV!z)TlIc?N`1G*2gT+S{i2>Q^Q za#e^v<63@xzJY;3YzsQva@^|qXn%#(OA`~50h9tqpV@qqk&#iUln<0rT3X*Gy}>rP zm}D)GD=29;N=iy?cL8`2+634Lz@h_jAOqHQN1cNB<;^>6N_aRV+<|_6W@BaaytnV& zYdxDaY3+*RY*&}Hw%!1|qk)@>xuCrSM9!ATuSS6(Y7SRJLc%vCfdYjlaLLRK4Vzyv zT}snLupiPd|0$mR`{P43j?_8~f_YPO^CLdKvEkupQooQ8lNT!b?A^@%tlww(Uq9fW{f$bsKgJw|uVZ z?)_a3pOo3&E;~Y@i=%Wuznf4W6D&r)u`i0azJ04V8q^D%IOqPAD<9h0Bo{nv0UveR zmn?KAWMySZR4OYgAFhwLE{w)~6nRLGtF5T`L$#ib%Wii;Zh$7iYD>b-j)Ok$OHK|i z46*g>v4oEg6dqRENs!`RcQ5vSfNPTj>x0V3W^e1@um?Za#QOgIyWYk`bw({zUQj2C zoemfpE>0{48UXdG>u3A?{P`0YNWYc6{VuAFVkN7Bn6@2nt`A5D;i1NQN0@Z;bk5sHcYlQ8nklm$d`;@VmP6 zV|Pd1QnIiFmq`Q?{b*|Mh2GfT-=D$nx@S7YlA#9WB#fAogTp^C@R3CXoj)d2`GQAc zfKTH%RYvkPm0`qta`Ny@s;AZ0}_Cnwhs<=p@z5GvSGMQ|`K-pGZTiptfi zS0iI$eoqoIYq2@wilv~zGPeN)3ze#(s3^5oI+KHf!n^#@WBs2W#e<0Z*Voo84=g_P z#YXtqJ{WFDmUQw4TETuRIKtK}3eg&93?vjusz}l>&zAXhb*T&gI=^otp z7$+xZfWJRw9>ttpHPk=;PJ8Ox?Lgurom+#+5(5!_UfwV=t4rAIN+f9P>?!!D_6VYd z1N0=NzW%m0Q!oUebELtVAqQ0I0D`n|Zc$qAr<+7W7$CdA%*}m8)o@qW@I1$;lZ6Bu zKF1Z&N=62T;cu@xe@f-u3TS!p;)O$PYUebMGH!Q3GXbL-4=+*H*uLiE*Ucc@OIE91gbfKHX+1a^7 zPth^Ipup>7nReh+sWHy!hwokVVumbul#*{G{*E5mo0-vy}cn0fD~#B+i$DJSPTyh8L_m3B4*-}B@!mN*K$v{Zyh!;h`QXpJ@&l3yoUY} zQBhGzNo1AVw}6zuNYYF~pWHI%1OzsbDH9WJ4FZpNFljq{3*M#^dX7!UgQ&YnjG&xn z{`oT+OUhdRQp-Ju2zi`fO1#I@HXeDM0P!9*Z8PRr#zscwTO{Hg9TYu7@%-*( zy6QKt%L{-OenCN*wLI1n8pQ@axy}~HGrr`wq)$S_!_g6_IdJpI0xl&hFAmcHw1y^G zZ%);BGASzchOKlUeLxE@1R4WFLTEe9p`v$qDh7nOUlKeb1W#(D=KG1?Ohiv1-|Fge z2q&3Dlp=bPbIJqH%Ry2ay*O9HteE|lZ_Z527~{r|ZA$V=iF0hA)Gp^IT%#E?&3<=` zjg6uDC{Nz^5lPF-TYZm#wPYAc6dog(3AW$;haeD;(V9O-J^9mSewp9WjNbHdL*%yH}vMwxpKhU#}kS|e#D>G zD#qR+-tP%w2*mu*5e@;4j^CYV-+xZNzlbosJtb;Di{_n}o%p4h5}^}NmApKV(UQ!M z(Y)e)QF*dp-;E|5&Ez(-i;fUr_z%+OAc#oOxH0V@zW<(R#Y;;xgig{?N>w@v3EfD3 zp3pC7NiwL>yWlQ&hMk}H8SAix1R6McFth_J45Dbxs@mKyX z)U2!_?!;iKW?0fz0=yk|AQgDaM!)pyYlzpSwxv7!5XD_2Kl-L5O$@E2oY>fDq6UlHl=p@*U-T z(LfV1eN*NW9YlDpcJg$8_i(;*cb*Mbk) zw+>1&s#?kRC~@K71VMjj@H{6*`~w02*yI)zbob;O1Dt%F!7&EXUfUNdYib&r@OC+% z$I$5JSGLaM`EO&Rpqij9AQ%)-tOc zxaO_?rcmiuCOrD1qH$~5LC;Ge$-;zWA72b4Qi#>7@8Fr38U~`_`jUI;%#-nUT5z9r z0@=A2my4*~)UW{3_h!J1^iQk{->T7Y_`+?Z&96r)E)*R>$9XsD#GmTzS-U4!Dc0NUrwvPIG~>fXN5(u!Z{F}1MZxBV+zQ=q~CLZqtmH$3p5$bZO4OB?JC z);S)mX$~y3lg{q!?0_vW;P~bZJ2&@5+p22N@%gUh8Yhx^b#Q~QmeD6lF8*;Et$fke zIaTBhs1i#X8#*QpUKe+0^mJ}Xe{>pOzeTrI&`M=V!ZDCONMy0Vx%6dYfuGe|NTo$ zN&<;(MO?87SWUimb-4QvsZ1r{&rvM6$$X9sX0$Xkf}Up@j*GePt3|I$q@htTG6uL` zL`O#p-1mARDM^vep{Aw=^5EAMV>#G(qvJE#av~p4^10* zP#lL5=4eH=b<@@V>5)&V`|{jB#*1+N_#cy8z2jHUFZ6CNB6jZk`xhqVWaW+xXTBv) zHDnIdxSR4O0s}-yn`ez(_1Q$VJp>H^SIJ09(lIcc%z5FZJT@ORZSlWr7-#w7MQ}(+ z$chsS2Pfz2jqv7tj%@R;t7pLLi=A|)PRaWWE-^~6BJN*O_QE|odFdrWb`p@Tc?Gb!z z-imh!#KO#eA$^rLy0{-60+VTL(FN(H20DY4KpDfd5LLKDpzQ-iqh=k)X(4)LCBjn{ z8kt3ACMJkKm~Ry-lEiwuq^;?X22isi!j?4LM?DB4{VmF{@a!eo>)dc@@Xu8h5Iw#r z0wj{dsH2%c`l6EQ|G`b~co4&`tL$3%n3L@e(j3%$?Hn6PJyLq(Y3b?ieg^Ob7M6-p zRt3l*z@Fq_0SxDBf-0p>M^Ju=pRIGaF=^5j`>Y0};R{fXRUBAAa$S(Kb$1uw&&;`s z{tQ^4b6DpIG0nijE#GG3wmg-&fr)oWCRceIlJ9C-UZ| zXQ|cj=pU=fI|+Vh6u*T^_kNt3OS8r_MqbckAQ8nhPUCBVz9d(K+xNrQQl=M|2Wm4l zpJ_rE;oi7aWvO2|8e()jeeoh2lfg&?Q&kF0xD=-w9DTD`Q$+Zy?$@>Ae5n39IyxvJ zYHRCg3u_fjc$sLX`%hi>P~O8ECoT@BwLd70*MZ0K&-Z)?i~|T|cCKEKm2F;fnWK zs-;td7Xc0dvgL7d2-ZE?_b*}rpr~mcXW4_2cvvD*n&F%Q^W8J}XH;WCVZzb_DicHY zpkI!ILG=H>UOmz`G(^T>*j8aRZt(gwkmtO#?aKGe0Ox=^IyyN815CPCpN;iS`0vcj zHY|#8DllId#>y2WBuxG_`(@Mu5_PhE56bn6G4u1m)K3JMEub?jRR~iojTDksZX@4e zINO3{zkdA+5H<1B?h7?jwb6PGq{_E7>t zA)M13fNI+A*c0EccCjy~48+LjqJ#fz{Cmmy1DkkLpe$`Xy7yl2W5&mMD>fCy*O1TM z&E5YJ&}OgkG13Jz7;q&Rig#3xHvjp|3^9(ok*cnhWpl1l!#hl{5(mos%F=XS3;g`! zkVub6+DPess`vUub?XMG)adBwfCc~l`=^wdtqepCV3EAgIRPQzSMey{7K1mYrrFii zypvJwhJu2E4Dm+5&)KNbo%avGPjWavaa2vr#9R=a2A{6jR@@Wn0I_EGK!b-H&?xI! zP<2KttVot2(6XcdTX#8Slfxp+xc_18a|DKX=JAMM(q;-UUT<&j)31j%36s~5)!VE3 zElpKNL{F%`zf!KE{(ouX(-}d0(JWp0peQi8GIRWydIqhlmp_4KO8~?i%LX$dRg7Lx zBc@#a10_SQUN!%Vjlc06kUVVVaX`ADQuPVsbzA&AbA|xQ5Lx)AcbUXt&F%hrc?&tLMWr)y4>bR$; z=Y%zdykcZXNG~XY%hrISfz=;vUC#ewy~k7V=PH7sg<ecqC)xmr7G-R7w#OJCm`-5PM;MQf@lfRfjvTvv9U3U zVA7cix<5eZ+HhZqq}hV4=N^j>2C#tJfo0sU`i`3WmLrHu%u^YRj|Uj z(_Pqj;krJ?Rr6HuJ7UeF2lfFJH^ZRrSoYUPTf!$`yzDM?Q{m|n^H`JOJ&`7K*Wx#xyKw*no<`SRi%;v$75 zu1Da}!+KM7T%V7>h3Ru~aS=q)$f&{?(SCMz)|Mn~)jvFZv7D768N+)=LM)b~2P_!v zp{&^iSh-wxF<)vmvuhKu2mJ`t{Y@Zf>!h3p>*#X(5)Nfk)^$471+(~$+21G*g5 zBuq>0zy6RK@R7{lrKQaPU0!Y=z_2{M&&)3? z*cct)d1K16ml%p*^Er%kbTF{7DLlIEahA2h2JY_g((0-_v}_Q=VJGTESE@2ZfxA!2 zW3BDr@EEUCn#W?eYkWMx;SxM~n8KkAdg8~XY;U*p2IM3qvnLM=MJU5UneRaya8>o0 zbdHL2h0tw3(TQLyP!cjSGWym59dsq|gf!`y!gUR;m7hWk4Vq%9z4?je6HSt@Sy`0^ zE&i@b+bh$cewNGX>Ux2*d>!ursF;CYztZsPXlhnFZ%#p+gZj~kKIN4vl#nZtKMA@sia{_fRREtbn^Kp zZ2bq|=>W$k1Mp7nb@n5V+7=XYn!GFmOfg|$;q|F}5)zV#<6cN&!d5CjS|B&*X>#5E z=Of+QLJn(~*Y2Z3Tskh3GD8#;WyAdayut>`T2XuIr%xwggX_d&AYdcmfQo0*4>1ztTe}_;`3BA3uI%7|#VRc655$8^`G@)Z!0KL{Bd@d8(EY zfmREuSmC71M=;4FYJ(s@n(Od5*~R8r2l=oIEXRx^b%55qXZ}JCOMRd$FI9k}u(vl? zu_pfP*}JSP6Dg^ilU$D=rH+EWFUW~oA!hN_k|5B>i8PbUu7-Iw|v4m=Qe zTf`uppxO$z``W-j(itXyE=+(HAP*tPdC8)t=H{P#e2NJNpcw$4k*tIU2&ojq#lbW1 zo{F3M``Lk6K7Kq1i6)mb;GLjHj8@u^lRNRQjg>Rnll-Wvsv4`8AcqoVMlSF+H1PT` z-vXKKQ>pJD$rxq{fgt)V`VvC3;6sJ|ScK}zo^`KCo+ak=^pul!idD1ZV|k_~tUx0c zKJ&?%{cviTsv5R`56>uWxdD0wEMH+WEojn1TEcW4$xvDba~sm1vf}Gc9>Z4L*?$z% z`QiP0^EXDQ8ZT8}UsorflwUP`pO`qDSC>_{;p`}2_0zQHX^?i`-uiesZGEWJ`Q{b<%Blz z4g?W%?V#L2sC%KAnOq}z>a5@w)SLr@d+K>sRWVhKsWc;#qXP0t?h=#0n~e!xC5?W- zIX`~9J12^iHiDpniwp0h6}a5HZ?2usvy0tg`>3*(AITsOUt4=wq4XC8Q_rlzJg#xUH(f@nARWy8bfS}>ui2-o7 z>QSQhHgqO8H@67tMv*kOCr>n(og`mFuCAFqP2mV4L!j+B119LgN9AngW7+gUiqMwp zK_xBXWSF9)!DY~TNuBu#`@YD7K8OK*gKW6kRE0k%@L^8I#$Op;{J3+tIZbOnFDoYp z$&PkUY#1U)qdc0t&uPp?`=xXZSOqGUU}0hcmL7-k8@{2i&iQxm-gS|o3QLXiX3x)@ zA$+(cELT@ota~hh0RgXv*}r9He+~#p08f_|Bj~?``)ZmhuS-v>sL;o3Y!q1O;Ge~n z2Uwt3tJ%o=oHsP5OlK7nzrfsO`pIIGwg9uA*(rS zgTl}j23QZ3^l@zyNp#(6qV|c_TENb|54OStb;!J>~R+SX}JOa?6RT;)(-B zJ=}-~ymq2@=i|G(yQOMzY5#)TqFwhk%v$DAI78IPpJG_CCG+aA3p7a9&J{q!$;zU& zUr~lIWt@Gg5`kEOX6XX(?77bn4*GcWj>ePn6Oh!8#GXHY4e3$vYhOpRhj-4yI3_~9 zJFWbgE*?Y~);7Nbj+qv{;bg8VBZnd#7>Amfg%xbRsgT@IUES=x)0NeDPG!SJw?y$=F3sEWprZ)Rap2trJ`$2G{XbWOZ1hKdI1kHw0MdzUZ_?tt3v z-oIZBX_bY(QRsCj)(?3M?#e@aOdo)_j{<>Rx3;#9bntU#8L-Fn4H81+sbrz#+Y}ng z>Sij1&q4ktAEU_q*lu7QE&=UbGx(h-hx3Lu$KAx_w-Y5sGEO}WP}EQssx^EAu#=*{ zzr23p-Pn#4ra0PeC5PPMRE{#OT~SGi-DHiU{X&<%{d)(n(ZG|Jtbw(b6ZQTfKmuwv zTHR_pA9u%LO1nE}C;JvURvwBkf$9ifd*li$a!2Hz|Ceaym*SW?@o{nNUh;q7tjyfT z#*2zSw=sR5J$sfP^;6JpP7?6OG9NFm&!=;};h3vZCK!y|w zK``g+0T%%L<&bbOMjbLLm;hN1Xg$jnN;v{fYZ^GyThHfabj8GcR2T~O4;R%S&|;4d zYvQ#gt{!|Yqb*W_Ztw8W#LDdoO^(XS%*-?H2iFiAn@vms@k1zJ6M~2!X96f60w39~2vTH#p6TeatEys?*aV(Fl_Ep&EAWK}&z{Deq7Dn> z5Bm8VDw&&yL(AjzsK3V?ps#B05uA8&R|%MSx}fV#xqS>1&KYXx{- zm*>t4U-bcAYL=VdwU-k*c>?LLr?CkM5I*RJ&$uw2oo+VPR#i>ZyT$k**f=<-IFK_; zGnY`|hYwfiagrh;?15_$H|XC56EEXc>up;xF%0{YyY?|ygb;V}^72xe{{yw6rNyTk zF}-{DF0jrnu}VF+r^7hz$f^zR^Ww#BZvrXJNcU_KyRO1;wn%RM`rZsFp0_6f?=AA(YfBBx7z z??~zC=roG-en1{Ym5+21$aYD3u2K#J==1dbSQaAVpdO6O73AvC{N=O1&J@!bcLfic zu%T7GnWknOJh;n-o{fzVlnSR8a(yk)QroP^5`?%QsW;l*FjA;{cyK_2*9g%bh$6<# zzwW1nyzyWx9H9^uZ3YXmO}$7d2W%|V$M(Hdet^l&^aLU&nm87sz?Q>g)f=FiF{>3A zSWD}gYuvgD&FLLcf1r~$r9ZVl!FQ5JWVfw1!OjRVkvU#5Mt}jTiFmBIlKwm9r_w*7; zD}sw;xGi+W5o5G|m;Ih!Frt*x(IIWzk_kMr*y+^mXiI;gqA!4u*}!FDziADcvhHxn zCNwK(m9e8d92~bxZE&D8IX;6Xfhylj=MfPRoEF3RV`TkC#7}G~G!Hcu6#)X|#;af) zZ`5u|o`U0AuBs;r%(ttjfaK;87+o1t${-qOxLuq;b{OIfp&Q_kX|V9Zvb}%n*7vRk zkCQ#ky0`57rG>po{FQIF4F+1=rpF+JGlUPPKv3x+mL@t@R=k@xHA{_y7@PtTWQ zKfPp>ht10g0z?Ab9qn%u^L{Au?MW8UBIUTH4RFnXw^a~Iq%D6^VKB14m!qYwrB&l` z>NH@qe!#=c9j!ul=f+i_{9PUoRD-@fZl5UFfw1Gt5<@@8L}8gs!_EQde60GIlk;V* zlND;ho;W^*K;6(Y$Tvb00{fPqH#{zm7bpk(@5qKx&HHx@>;ufGB2i^^t90VffPfaVq|=igOdtx`}{HaIzX4qJDw4Z2NP z`o7tJX93(jJT$9zQt8ZL$U#M=mVhHLK$vXnZPrm~02(-t(ATG6?4y&TQe)cx1r@X3 z@EfbJl38G5jOzIO`EzeWzu|E8*=&fA`NJnj$?QWUGAe4Q!>t6RO92PS;D7xKn=raw z5MuKvYK&508ZXb~hiIuWv9Q2xe<0{C8H`QFHwfj;XAN>@=@6JH?S^wJ;7$|`s}?lD zeK5fR4xuVNl6~CJ_nN6Uw_K&)zH)gOrMaDAma={MEH15;%Jr<5Nn9* zK|Fk}4FVAW#Cm_qdAYb$7Z$SGZzo4YC_6Yn%BMJ2{uL@(>zMN4LlZ1eIR4WX1`M}1 zfv1p==LRviB~cu)mV(08Xu@N*RX+BZBzNwGTV=8|dB-FrHlXHZTr@$zQs$eY%EvF+ zkeTH;V7zq$Fq($jL0ob&-1r&*5IaL~T43#)JUk_YGn2OZ094#X|kP_BDRiUoCEz$x35D4`mV zk)7YS8K`>m+Kx6UI$CWvQ#n39K0|JUY6wG2vFk(`(5D4(0O?-fsY58U6*@1g#hpSp z_9qBh>rSjN9RaMFw?L_w5>Eh|fKnhUBSR%|4fG@;qP7LQ#S_TyZ~-av1sh`d+u- z>{;PF`>a^cX$Lzzl_EUOkOPh}-7D?6FtGrhVE^3~6z`O<-B^s|Shohx2gdb}_NBi= zfV?ZAA0QFuVRW`5c-8w`TNFI0fHonV%FCZXh8l+_PhtmM2Zx3LMd)SqjDXYy_^d7Q zS(*Zn@cDoLe)bq$N0o|n$V5Y`s@G5_Pn!h~6LYN5%d30Z1%zx!Z#eK%QO&|iIUjT` zs;s1y5rkc@(d6MC=lp#|^`-^LT87g;P~t;C%XM62U}Z(M`QORF5TRCLDSOfTL*j?b zJ~rvwzU0BN!g7xD`qvvE)#eI3%}KG=N~!-X0v!0xEEXv^#$Z?ytCVwA_r~(Q%k_MJIeL{xpf-Thj7nqX)+~lWDh(1# zvKXnWawSDW@`GRLZYq_7)bL{yFKK zni6DT=>g@4bhPTtEYMH$*bk@ss}j*2;LC8_k>X-Eu^1_G{~Ay87i!9ma2fC&203g{ z5W1``j3F~Dk|a~ZG7iTZ+VLTd1)ovv<+$QKFrWm1%Y^}Rh-`uS1ji9X;F(qR(8c%T zGc%23WwGrSKf#%sp^U^w2n4YqQZg_Jn$>;jg0Hw_e4+CoR!w9}{WH{&&6Yt&(X{`V zUkY?8W;p)f>vINZ!^a$;H8Sws3yX5l9cH%6fI(avtZi#=k3*f;(`f1Me*?wD zP#(V-PQzq3aB_18`}yfdJHyEf+qZAu%GueXw%#ih7&nmdgqB+&4hxc~L?xWbh@-wK z1RZL4h|<*|(g77(wXn$hVh>>saWSzlYfvU&d8s_T{H(LvG_g|+W;+-kOe$j#NsR~D zV0REaPk>|`92`pfIsHPg@@|3HEFmt=VbVY<A zGf<>oR@pwJ7lAP6#N;Hz$TL^&R{qyXe1NZW(~P(MfE)q}{Se?$?UN!XvI#E|D9|W= z@3IOh&}GmZJq|p!AVk=<-U81KxjOapl=7k?2>WM^13d#dHRawFPPE-i+$Vf|HFb4~ z*8F^Yo|or`xld$tbf*66{LJzgwc># zIqo|vb+wjC1dKX1ZaDC=qS72=A6iUC4n{<{Fe^Fu_o>D4na6QdAspgu3=yPDU2?}q zOts92aXc>nO1Qq%vdg@RK>7&#dj0g1?1r>PLZE$87=h5g;Mfh&@7^kPHg0YZcIE*7 zEN{SO1n)R61*6tsS!7d3R&fycP3-Ao74lu&_13BH z%m1%0SZO#dY1?XRn+(N57OWRUnA0S6Be{8SkVm+;vua=LO-s!z|C|eJ-+NZtZXEf( zLnrE0vKnOb>Xx!c@pfy7RXq>AeyK*RQzX4uflNKcFS54r+ z=kDI#BYxW(K0l$$M6ooscXmR+#h?c%Dlf;u!=r5?$+ZUqz}p*H;Mgl{IAMV9!J8X0 zEj01-p=t2{j&z-BI~C9Vm$Wo|QqnGMY*%PUZEbD6Zd6@mc-fDUf4~jcF#ixwzoesa8SC7dVIwDbwo1PqnqR(&|L;_KLS1k@Q__ zZ~%M}4oRq*==y)Tefu_S%eYZzh!BG+nZF}T*63A5jfsst$M@;vMP5#HiH4?Kxu{~Q z0s)=y)%#c+h;VIY#rXrbcN&lum3wD>eX@?(1yM-UuoRd$TK=2mZ-8+lt)-t(i+ht{ zc;#@gcN*YcOpG>b|7Kgm6Ml71xuI_YmQkoD>?pr)gEt#}PF ztsJh9FS=*CZ};OwYw zH=4YhTsNT0Mwi`ds2pD7<;7|5pSXS4N07)$8=v+#B(pdj^9%>L%1Qg^^yug@AZjQ1 zG!=#qA3ng|kPViN;}FY~@r3hykZ_}ll5WR0FgL3yX4*wEW$F8Fl|7mIXZGVa$^$YshUj5US(!?X3cTxJI7R3agD9mU zV3dgPaGeHsDRP&szwaa;oec8T6B84IqF_j4@9K*3O$LDCiF8J*$ojC}CU@y=}ctXT_Xx&b}mk&)>TAvKQjG2%qkX28M>Ji`)km9Hx7k z4cKl{jpC^f|C5G18BeKKkT9*BWXZ9(P510V4HpTDc|2@Y=w`p$4Pv^A%X2te2K^1R zS1$9xwzEq($X2Sr<85zH{Dg_AtEp)gdd^-LJU;Yyua#d2sOBdS$yp+WL9~NIdgg+C z04tc|8eIX=1L5)tf*oSj$BH{c|tCx@^o@?dY-!| zoc}?o6&`4rJCz+DguxD{JNjc2#ixW%#jp|+|5`-A(?8}>8*a1IHrcj&NAPru!Gk4+ zcW>m8$1S=^4K@GcBO8tu{V+Dy(0n>_j6Xk%MaTR6d8)=@2{Vd%RI0dNg|mU{w+ah+ zCI>b)cDx+>!|!ByN5=v~kHVK1mrTcETy}Z)8LPCtlUt^?EIgIsW!^>m?B&eK0h1gi zrwp{bX!G22(md^K)wP?04p#+Es2dv>VZHz1k7$iLm$mN?Ph2;@E_XQH@&FsVOHC@T z>$<(zbPlTE_MJNg*EHXyDqRGdCwk>9i&URrP7^ zGivjwqLmLWsF??tf3NL$QY3ZEV$rTeMJofQ1$g_MJ!#lB@pD?$+}Z`EqQr^|E+6(e zB#2k^MP}tyl*9DHc)Oz`m+q!NEA-!sfeJ6ZE=v5Vf0?;-CW$O(&3{6nLBb`~ z^;pgE5^5MbwS0si0A}OxtK@k+%0(#_{mr{H+O~WQ)~u&Mwe^r)v}lpDv-9)$v?|KE zil?1ACCuy4+J2f@0L@KJiCyjKC_%Su0a?%Wrw==Fowu3!HfI6lwGX++TOn!xs) zOPkspzVvJQx(sIry^F(sj4}1kUzn#8x+`bb!j^?45?gOt9{n)RHPy9pcBS96anYq6 zYs9r=f8KrH{jlD^Oox->PxLuv;r+q;=JGA8n>yM|PZ>Kr@ktgF<&BAqcAB2L?y=MS zESZFJ%z$x(kz2yNDU zd?jKRx{KzeL3HuJ4lh5UNZBl1ITv;LK~+`IzzWewwa*OHq8zS2{DZolwA(G~h1RfP z4{qP?v~iTAh|&x4kf8_qLA%{IwVRz*I4M=(UE#XIwddQxA`zimu$(MQ$d?ftbIs)0 z&PkfGd(#h9?JtuO#RO?S^0>7p?ckJC$_DcUFe#cHMiH_ z-q}q}Oyppba_i6bf;*W@vg(%Bna|ofaPq9;naekqx?DUXDauQIkh=Sfc%8XfrTx+M z^8==h6`9q<}xchWZ7zq5Z|9~eoy9OO3S6!9VL^l2>ZXQ6yfpI)|N zg=hO6-92~lCh(aNCuhu_-KXJF(8PR#)fn$`$rJq~M3hww8hEs+n>78Ot5!vO_GX&G z-gvb*;tkQi;1!CX@9Nd6CF7X|aXd9O{}q~o&VbAB2uO^du=sSF?Vdg_BO<&m2;rI1 zGS;Q7D$~UF zBLz*Z&DTE$*g9-24p7z`Jh$8R0Y1wTUysNoeYb`@e5oU87aW;zI&Ai{$kSpXiy>P) z3l@oqOf}jEIsrGU4;H5GJ{_u4Q$8W{-N*M6Sx#$~)1$jv^3xe>PSiSFpW$P9xFKNn zv{BQXl!q-Cdt?0NJ|g|*Z=P3@?6w6?DmWq~3Qmbmxiz7)$n07B>19>RM8PG?w93*h zih>JUcJkCjBE4aH`#gJIX$)2+H^V#gnmlDnjVZ-_T(h=DG+p|K>6AfKfYz`%xO}e| zhnt*>#?y#ET`vHgVqN7eRQI43)(M@ zJ7F?F6r5+JIlcdwie;jaB?ljyY_4o-nE0%5?5Rd4_Y1BI8=LRMN2T4EKYe*>mTp$# zqjz6V*AI4emen-dtvhws!KeXm#YF1&)Lr|ze!lv7ubS+xt-Y7r|Fm{HZQxzH6c-nN ztgpwGKGgNv(}xeILE59inwcf0rFB_)d5W~8Icz6fA|xg|_F+-c$@KKP+S(op3Mw_9 zl_-i?q`!11Ub&f)l{HF7r=X(Z@ZAmT=gljtulF))n73d-`mtl*r_AjgZ-+xaGQfPy zs8Pd!QD(pMA!MsdCiL$8irUV)C>=HBJEIdCNB8dSjL!9AxWWCy>XoymI62Ws78f1; ztE)T&H^K`XU`$VM@6UO8W-u@N7jz+}t%7`r**sq)qMZ{hbLPw^A?@SrP zr_4QM;(vtOs0&@9+E94 z(p{}&88$Gh2R3ZU_3Pt1tWNlE{+$`?WANv67-qv`ncrew-o=5>%LPl@w1xQG_~`X7B(lg09`m5*Q)9$ ziZLNaj4Vyc&TipNin6;z5!Nt93?Kegb6Qhfg6UF&r3A9{0Z+%obOa5wnLYbg$(M<> zvLoDn{a8{P)>*%>uXt!8BbgRM7tzzbc(Hcnu)kY&?wpEk0xp9w2yV?!_Vg zHeZzHIh|{<+?5<%GH8%scfL@P(G?l1H(TT7DG?uQ?f2SAoWkexWx7h5Q}|cF4el1n zh!m8SyUEDJAsEVZ9-@!;z3{<>q0rzV$z&#GVa zm@wfwI&=SotM!shuN>w(|M7V?@%hznty9e3!uT`x>;7)TDo(Vpr_QCM)Z*I--?GJV z&6>Cgl{fg(7^YPp54{N)OZQk#z#sWsEPdCIuoQnyz8B1fqaID1^0;5We!021?5l`x z=d8u!Iz<`Wul6xQ%bPuWHddptW5-%qS%K58T{H32AA1vX4R$g3^+O2>(FHZYpNI`P z-Q*(~s)4UKJv}{gF7~74US3Vb4t+<&S3G^XCG&a1r%#sC=QsSY`0(Mw`Df3{%I>z# zir^Po>Vu;q%5Cn&(GIPwtZa0M7MD|};0vbhcU*-fYvSc6yZ7&3eDyE8;jyZZuF_Ke zkTl)*anKfk6^q9#t|HlZyYijwCLqmhCy!?a>U)2BJE`R#;DV#*J+Ft{? z#bO>&mR=*B_(yoi`6YOEp4S<8jwqv3xV+qH>Qrx)TpvmjK>Eb*#grPolOb?X+rcb+I|vM=h;p%zTe z5}zBM^_B?*nFK);dv;nclX0oS7*n{Wrl`+A!N&Icx5i_qWQGxeG&ruw%KP^2&B@8J zp0Z~d_Ob!Vjli{P*lX)SZz3P>+Ls0`)`enD%<@B@0T#Q z_w=k4!i@RyNt5mpL-GACY}gS@(Az2%SwP+-X}&Bg1H>w9yG0CqyzxX(dux1b>}vKP zd_TT;L`~CHQx`KcH%dcT6()Z2WFJ31mY)8o$(djP&}&?eR(SU8Fo`Ao+0l=)Vj*De z>P^8h$Cqoogs#ZMSHr4>#=uXS7c8zFV2Fc}kx}b=<5ROvr>B2~E{*MZr zmA_V8HPq3Om`5)jZ7{u&6;1xEg1O-g;yEozKLpRk5u%wdS^L#hOp4eIpoGk)zqxq+ zyb+y9G1s%Ato6kTRr+w);P0`Ou*azB2|s~te|t`XHAq)?Z+v`boAqE?OG``quN75-JBWB4Hj1WnVZz=098dn8 zR^{;(D^|pPJ$TpR+D2#ek0>=OrAa%?`So7@^(7){r%M9?Oqdo zkTp8Wophw!p2X-|tMY?rP`oe>0ws7L_4jN=W<(Z(8gqzt?%c^3z`g-%&d$$;YgfMz zM)M?=a-8h9s)sPSsVF9&xl}xppG)4bVx2mL6P`sP_GiP#k8t%Zjas$Sck5A(%e*XO6^aW|w`1H_LbZ?GZy`|KAI+o^>0I7bO=9NDz6DG*WXdP4VGCA1^nz zpPh#fPv={pCeWV=46fJM_4)H>M5L_Cm;W?2q7F4n+>J0&7uwHJXBzdwEy_?=cK>`e zfTFS};{%X+YgYMydShD_=6;3Jh$bPgc1B#J@y?xV>?(IzZAsBf5BCk*| zE!y`NHqIZ3+3Oc-qlr&-9-Lw1v_N_T=AL!3I&q!g30h0G3WSMf0K<+s3)JN=uX%S5 zmBubmHTY_xf%SL`3kwV`gdwN_&VcVhdYKQvy3r@VznVO0QrD$^aX=2n2(u}-rX#Pt ztf)ksx_#87943G4s=8aMRj#k=QbNVc#58zfyEC5!F zfZFl!>y6{b7o#ZFpK-#xk7am&tBbd{H>NXuj%G_#fc+G&9L%=%<`x0+>gzY6G7-Cq zj?qnZ;J^VSe*5SVo}GKh_8U3!C$50{jt$fe{LTzULLNG_LSI6N`HFm0vgIZOIVO&= zU7n1u=PQA4v7G;660+|~nPNp{44S8k@!XYu=4yCiAkY;UehfK*7#FaQOd z<6own%`cP_lJfDq8Xw-`ze(Xn>ez|oT+JR+0|4cE_b$%Q*V553v@}j7Xd9`^Pb#|i z@ZlT>hlWRrHo8izZ|re(&LGuZpvK*Tg6iU&-u;>KB2 zzoHG78FfBBJ}Nz*7!T?pG*I$u7{s)>90G#yo`)sIK_v&#&^Zavf($I zG!7m*6zdUp_vJz@2DjDccjLJHeV5l+D#!2J&1cVgo?57_Aj8w8DYUsVTaujR#)hyB zRKCxw1ib~KO!*|{u3fioUrdZy&@5-?08lI^i1F=-eY}Q>Mc)bV_t&mepg^W$sU+c} zGn1ued}Pv5N{#iZ7!&Qm`?jwy{N35#Eia)*HAzf;ynl}}tPSrIZ!3i+3Xo^QCY6oT zwfEd5uh{K3Hw?B&!g`G{pUfpbuZNP7$?7*-82zBI&Q};20``E9pYoz-Gd4KtjpSn& z))MIuRVnPrD@#0MckC#Jg{HSvCuLI0K=JNwQ5U*xvvk732%N!3tWRIyPaB+jgMVQXuD|NJQ_B{iQ2J+J2NTVd>RaG}&4tmrr@^>_`2u) z`^9)y`54CxiwOGIL)KDp(dE+hw$;3cpbdDJ&2a8#ghGlN^0i1N4R^<&3wK6x^8-n@;pgAKLY2)3;}?=CSSm1ZOt@a&W+X@6p+ zq@)O0=RM!o)iK`wr}03k%1IL5*M4<2Ntj}1w?g5MslC_8gP0%}9^7-+vv1#oeAV>? zcs5o2{vI3!LYME#s1RYW0b^oKI;-Mh$LyleJZon2+%p&u>Y?SZt3;J6u47D{*|Cvs{81A8V2^59p-*0-4aG431$yq{%Pp zn5!I$!wp6*e@08?9oKSi&E?S0JNb#AS0B+6jV{D(`SR?=57aa?j#k~6%rq#h#Ic?; zCQdA%8S3}u70+J0cvW70vpnzaT{N4ru}WoSWlLAClwUO+Yh=ju-lFP;hV5RCm|E>4 zLoj(lI>pv)%gt@W%PzJ0XmnpwNP6YU0tUgpeDdVShV2Vqy?Qkq+vJN6p@5jOvW;7% z%2_#A`~fB=2fv6d_wdM|ZUQOpU$A;0>|Dl;8$r{i$@|Z+wJqYu3!_vE*3I?kd|$k< zDL_j>29qI&y*y{5q0@3sZMB{g0PV(tk@t&>8RuwTJE#MJPv|tCAh&XW_$uHs{MMfd z5qAB%$jaV)#omglI;z+u&Q@2uN=^G-aWOShbVW2hbt9x!o8{0OKs5FG#SrN-Y;{34 zf$*IltEG~ zh&A4`XFsD-{xhMQ|Aa^Eua@4^Y?4dS&uVJjmoEL#*w|Q=6C^cq%oyHQTWbkgKlQcz zti@g<%ZY_FQ-q#@_8v243>39_m7|A;2mL3HkMxe=R?dN=^Sz9kAblxzvRFdere@l3Xm`Fr!CVV?x@u`7n+;M3F z6F*q2h3@Vb@NHC`y6DLB!ERWs@sI`#G7n|ViH}JFQHbXJvhUFY2j=owol~fV6vbeW z8>R;f71G`>a!U>8%Z6XXGiw=m*Yi6)deWz_lTUzy)E3rrD5aR?Cp|td&N|u3#)fs* zsLYlSxh-9KmBC#}DyN(wK(JI_Gq(oEJv?koS(ThRp^im_N>Ax+$Ve!KhV(U*{cw5IOD>iOXwg`VHI&HUOT zJ=Z-JD!$rEVV(w=iV>M#-Ha6^J4s0$v(fR}xbau~jRzv5cd}=%Q)WQhgw3gfctUif zB{BKgTsyl@Se*%yORoN<($pZG5u?JAWO#_jXD(n+ETCg3 zNoQtNlBm0zoSgrx*|VvB$B!FV((NPX0l>wtPn=>by#=NL-)KxFR+$uue&SBS3F8Bv zXU|afzqSyaDd>g8@*k`EcQX{mN07mb&h6Rrgl=1D-v|&*P_G?kEZy1QkVJ4ekS% zt83nAN=4!H{sXg#=r0nf?Ob2`&oP?ZyKXy!2EDxU)&>Q&HpTAVZ82b}SI~%SC0pfv z_x)gjrTr7`H#R&Q;=8w;1{AvEn$ssL{6ynMcKwNhM0bI+wEGHk1vFO`b#*)CtF)vs zFRbH%>ek#Ohf}N$AHlqC2cu^^zq2K1?Xa;jT_Q4baw-RieOMe2bJr7h8++b;*pWyz zu!jEMa54&IKk>Y(s;_GPlvD?yrzs|eX#)l&yYh|HA68ZdV)63%*a4oTqIl9zjy6^4 zUT&g1cIgL6mGOro^Xqke_chu-J;XfP(pRr~m(6x?P_w_21}z;F6y&>9keq-L)efAU z)6)(cnU9$o9~SmDA*lUAR@Nf#hVGK)Ome^GQzPy=#NKFABfa`^>uwsS)f;+s72%*_ zD)y7UD>d3*gf0^HzZ$E`5$91RWjDR~*3=V|6uBqyxQ~lV1;gB9_Ap|Xc4O7%%#4h+ zFtLr{TP@#^E$Z*Z;^2Dn_%ZhhDJov23ohY69EN0984mk!=gty^Q|~$CP+kxNqbt2+8QYAse!<0xV}otg(ca$d z^10;XjEz4Q`zDvf+OhTNa{St>9!i6A?f3&QTaCFe7}n4=mGzU(Y&<^?MJ7Eck7xrv_WB}d@zR%XEILnv=2daP+3hQDP8&g&ZvI*BXRNfkf z=rCZwfFVQDwA4zrmG+GjdARBCK-0nGO8llN3-kXE6^H_G&#`Lv?qUxx;$n_ zybPT`+Ebi@xcJhs5)7zv7n2f=3u-?+EtoPK`=YQSXNjj94o&hss8ZRutttg0QDtSH zNf-Jn$PldU3gf^-VB-&KZty*CFuW$@ngaG2D4EhSX2NO5UIA>d@vAScG7pHk-51wnLwY$F(@+Nq@{?fDh&l5VS ze6C!Sv|z7wa-RvCjK+*np2x|Yo{-Vc{|EV!(492JWvk^eptM=obyy7CnH;-g&MQ* zhVoSO323b3@cB7L^ai|{%JoHLz9R_C`}XxToWB5Uh4b}g($rK3V%}!PGrl~0^X)gV zFZnSvnubzmX0Cp>@|`E+s=QpqcXqclNtIAaAI+EE@^9nm)1}m=bNmgUacxriNxM_c1Lh>OQWPYOj@mDYkm7{Sc?% z4-PRR5mI-N#|BD7O2-?`hT&>&|W(24Hp$N=Bp=0A=OXK0ZScL-=45OUE93$Bt@h zYC^F1b;&<9CFObg0#m2&x7!B`XTwd5$>}7Zn=r15ro+N5I?Kx5V-`=wl5Sx!S{l(C z)~(1{_?i8n&Ate$Guq}`~X>@uzbC+XxFA@ba z9hBzrw^8#DwAdMZvSR^qqyj&G{}J(DpS*nO_wHU#Ux^VakktU9^Y?FX{tSI8Wz zZnFv(Ih+|8ps9+l3%pK-1jT@`ey_Z*J$UdndZV$W&oJ2fVYsA#v7Vc0$1+!d+fd+8 zWyf3-7jfMKg=f>>zazYCxDD$vC=zo*K{h}QqElCC5`{E%%e1AW<-vmng*?DSucsX= z6Oa?@?;@Gvq1@yxMtl5gNX3go`uFcekJpQyTXqR-0?i-9p(0t0=*UAGMtE$7k`%Nf zY6%i!{W@wj#I2z&S7Q3ryaw+<3uFAgak;~dN|5l&uxF2LA2*-;@aYq$^BV+SK;4^d z+qa){$`VW&vr?9IWC_PSe=@CqJ$v-Pdk)PrQlDmKR?XK<9NtC6wg1ntdi6wpPy%Fael~%Syd}5r9M`M@ z%T3nFR@Rz3IyU8nNZe0pr8k5-#pw6Vy?RwOcbcveGjj1OsdO>j^Yr<1VXO_w%~!me zNI^;I;^oT;=#wXle9(cIiD^!6dS!YSktQ77l;NXqc-4kw9lMq1Hok}KJ76i5U;S<7 z614w#WZI@03hLn^jxCodSs8ajA_P+lW$ADT(#k8VC4OHwF*epRDBiL~vUUd843u4? zay}-egeGL^4IR`YlztNnn^&)0ONKa@e>ndi(_!ixt0cemoBhuuJ_^O>3IJqs6d_9%+@wcB%gYk@z`@N910 z6yNi@RQ&g!Eg|{-jGP)~u_$))YBxH#>RLoZT4pVer|6<{A5Yu2L1Rr zUdEpRBfs)_$Y^P7Fip+PHJ`tKU!yCrJTXjLfv10IW#x9iQez_{fMUK`AZ!YU?T}y{ zP}(LObDD`i=q($r)VFUCw+m#>RX4Y?TEwZN3QpD@ z3rznCf(BUSo)si$X=&-950*U*>8vkRXzz~mn0}d>nh;+L+iBBYgLHVrr5=IqK1LO6 zY9f5)lP8#hnBT?qGf-e4wr#buxxqrVmz%G~a}tB1nDv2=awi{jy2%H_1rTy__%=(- zULU{C;!N=KNgt7Pbwl*;~m`)^;7HNNL31$4}q?C7OmSI%qg7zvTD4^|?YU z8t#0_4vJ+=`giF>`+)$?>nMh?$OAkEz8ss9uFPxEtZS62p-`gS9xG`b^e?Ap0s$CbeHe($ znm68KQEA5({85V*S#4+}z7WmDdV33!B-{>DG(fj5gJ-(9xHvmA47xl)q%;0}qhAh~ zHuy{TISX{tcI@2w;Kd6B`OAM|sqLxRAWv*sEO0Pmb*ikYneRXmiU;(^A&sZN z2S#)82ui0mge&&!>6+;k%dH7hc3+L?Arrc0?OJ601@NRTPfCBuhvcgWMO1|PIE@?Y zKF(29ji<=CIb_ygIH}9muBn~+5?=G>4Fe;DNh>)4m~iRxg{0ETIt~1R<+f73t0_*- zj#BSGV89)~WNRNrc(16s-skLf&Ww-oh(6#8J`J{3%i+QRBh-kttfeXT1M&56qCfWe z*t2_g=Uo3RPIY1zv;eZ!Hmp@UcYZ$N)=3lxJBx#YzJKe@n=;V|MvwjtNre3>*R*G^ zUh^SmX}7Sknyx3eSb!yOnU3;My>sVnwBBf?>ag$6rlp~UPdst!Jm+*+OvGvTS21C&qSe7t<=Qser)mFyOjN`mu~+^%`ltxQM5ncTX$ z|BJqfSFQ+G2C+L%9D3TtklO??xO0Dt#FSMU9&SNLR8)fGAw^-SKE2NEZ7`cE%3;9* zw7Q*p6K=jIqZ;M}(D2XL`OY#jdE)V`TzUESOTirAM|T#@4~8A0^K4sAcLkX(ppV~r z^N|wx}fxiCMUAv@2P^Bryj~}Zu_&F#KC*%DJyVa||5#(aUf>39K zPF)(f{>C92L+9qtwLylV2X@rx(O&`|vcL@I0)D1%$ml}BM}3q(X}BaY(~7nuxV7Bu z=^_y^e%rRYNE$>b8^6i=JFQ!gR=}oJIUB?F?o5i^yH~i*2D;o})sL4_;E*WOuH0|p z<8wYeeHEiYa~vEUg_}X}e5HK2g&`X)QCfNwY2}*ttI@R|5#$6pR&QtmF~#;&8YUH| zq!t~11-pCeUuKZefd}}n70HBxrx|AP;jcHB#4vgy`SR#lbLQX<8B4Am6lfh28#|AD zz~|Lmi0>y09OZ{?;cI78eU2c^6@0XgX+9Lh;QsyJ1MLFk*A%|}22IaadHVRVTC?Kv zs48jUJGcki>iTco$g*giDivx$>I@_*6l6(J9G+*k4Dd%xq#&6a)NzzLZE~u(h;Jqk zskO7tcY>$ik)rua&!^!5Wjuw?4omfImT%a#rN)n{KrpM{SaNB?UuS>_q8XI24EA%Qh}ws8m^TUyy(u$hBk2%RuWI-1VH(e(teHT` zeV)WgyN79cD!u>3(s6kggoapxeBKZs4=|yNoZJ?V&B7Rd%om@I*-e{wv~O}C+Bei`myhE^38*x#l+NkTpQ3mP z&Doz6lOQ{21Hj@XcFKdg2ty3njRkqJWUF#y0sbY>I@1QjzPTKCKarfQGicBU4lREk zxY(;;e#rwy1*?~$kV7HJUP@rH06Kg=!&IF&98^c z|G7Cn1V$&OXQ4PZmF(PWEGB|=Meb)hO|>vv9{0hu5h_UQfWM^aEf5g|e+JPco;$be zORL|w*PKIYeTm7YD@l+ozr9&bAfA7~d3Ssc1YS~S{Oa@FbSR~W(Ci6TD6m0KWClV4 ztRg1qRC(_*@cp;$_h~l=jX^Eu-+c1?Ik#bb`uf!r;RBM2Fp)oPv2Rf4l=NPrL~y;{ zx7a!V?*&Lr?WE@{E&^!LZ25bmmP{xViy}MzOyjq2G{EIgE~}{6#OM)-;lvvjnhGFN z1ZS>esoqDl#X3vgdR-uJe>Ac1wturjUPHAHAY0-)K5^pDiELJnVxAZOK&R|k#p~Bc ziB!x&+P(X6%K-_xTo#fU7A*?TD$NrKg9Rt6!!@U2^cS6SsCY0 zT@YiC$5}=TJs%0E{{b%D%A%dEtn24BQteuAWsw=Mn&u4VdL)*5L6{QNQ-@gK(IXOt zdpw>s_!sCOSd1Q7AGn4siv~e1h`!tTH)r_#7et0XOLV?BHuCitoI@YLPR~D|c!C`K zLwol=O?bpDn8n3iI)<`6befmsHx;LzZei^IbKteCq`iA*F@EplNw4+m*P}m-_$n3=9lZ*n zk2s1_&bUWnIGrL5gUDUa8x_bg0YB zm9i9Ub(Ib$^wZOumg-P*v6s61A3Ph^#FID+6vhQ%^6p$CM;|8oIA%BM#u91pBS;yB zi%`xZWdy0v+jQAI^3L0-F#4Z9#Z<2jqLZJU0e^Sm`0?Ld;T^ng1KXK0UT03)z#fxX z03s)W%5}QZNL;5yVASL;4A!Auc%>0_yy?8(J)X!RT$rN*G zk*2P$q^iW>e^UatIX)JN01_16CBH)R-hN{YNhCg0% zb#T1hXhTDw>QT&iE*rX-+mmEi7ycgFBdk?NMLX7rg`xan>I##CcAk9WDicaK87{*F z=B#ojuY<$QCe^J4HNr*U>>h3>Ja#P9INrcf=HDkeh&73;gC~St^i?Ks>=WDo{I45jHGXmK`87*J_$9R>Z#M?jrGGq#OVJ_ziwL+~);vouZY7L)1S5_5i zNC`9 zx^)sZ2TAc*BF#3yBQFvRLoMw3lc?5$=lCz7gcsju?b=Pu`ylg!)l!fjg+XrmG|{9nFPo0c$P=fiV1 z-IQ?Pn49MV`uIuK-!4u+L@&L!goool_V%e+aw(%5e&SLvU28l};}M)1v@#@4TVK|V ziqz-nehPGawmv=z+bqGc%-21yr}V8;M{1zfj2ia#(W4r&;TEY5G`*5RSW^xtFT^6c zAlNGq@MW)GKfLm(VS|E#0y8CVq7pJ)*a#mDUsy~mL~-BQo!`d%TU@VW+1an|7s)J~ zvCClW*cJ#3&<2U0xKBw9%hHMeHZ`I4aueR>jN6iu=F}3zReT$~rgn&R@#dX*VWer|lz47E6uO7>=#5wJ&m>W6Pxf)dZ!M$iuu_M2nuI6oY%KgTP!U9P?{UBSub_ z4NW9>P?OT@1WLOK)d34};DNOQT@8einm7H(!uO2|Rn-4&Gq)?~DacPW{{5j8&qw{S-_H+DyD1&RZUFQC_N8NI{K2xP2P-Uq?F8M!ttf-o#gB zW%FEITK~(d@7}*}zbG-fDZOtURS&25__QP2dyaM2|5x3`PIGoXgdf7mNiEES--VWK zkoW}CCJV^sAsArI;>ZxzcnPIez?fr-J$lT-n2Y#AdCbtrcklYtt6CcoPl+2oYl(lK z7DU8+^UEO&5GSE85L-vz7E2!UZ>_wD$d};l7p(UiJ#wUOtSuNkEc+f0nJovHsh*TO zYj76JFK)%%SR+(oRk=tMY{82nfXFR3U~aUkrVJnJUUT$<>*?S!+)H>*=Pp>Vz|ykz zQH5?{(Z9kkcFN|>*O~8Q_#^wwP#ag}a=n4t;?_WNLq9uzvXhg4Ly*kQtNy2{?XeI*8lWb@SdTE;9T{oEKyIK3GnR=@L7(Ie ztp7f6A2QI4b}xFMYP&ko_0Jd$CJ|dbD@|XO7{7j2C@7eA>a0gJ=tW z&CZ4nNlKfC4W9nCj>Z~^N@coMNFf7z+(UJ3>9S|sEeD+j6skaM zyKJrB#py-G#RZekoI5w6aPV@%F_JELh`h^B21V9yY&7&L3jfZBF9c37D=Sw}c2xJr#0Z`v zM%D_wxg?Qx-931mNP9Gna3xN2LK@UATY&9G^yS{~Zyu4hy3>xB%%}|AZyxszfs&Fg zf6pF?RRMl}_m7V6-L{lTtJ&FO%g^nLjWx#h#8aX|Co6q;csw!jJZu>}av+hDs)7Qz zEj1V;8Kpj9D;j;u%ycnJOu@h*ham@`tMtXpEIyzcgx*erj4SYE!-jpPvZID>>-4s> zWGE+{PYs$Ucy~1RStvJ3IPG$#6r02~Mv5u=ucj9YOpGK6C+yi+2?c0rZGH0<;1^!y z#Ms2k(+@>Q3m5Eirl67l?zunW!2xvf>JAz53O`?aTY%#>+8O*89ANZo-!TS#G+xH8kC6zuF!j6)WA(M0GDi0Z? zVfbIQ4=qMUO`07O7UqHNj)TVyC;9nF$B#?Rw;8;Z*spl!JMbU8Ta(0nt`=0fxq+83 zd2p_Hde(DrrofXBp8>LPCheFyecz1SG>l#;66MPil@#f5aZNC6l;RVDWbuCSEExXK z&BSls+_?v+Fb*F4TT>uiIMu59^gE_S6PUVvank9owsSvCL(E{ru->lpg{RJ_LHG>9 z@13}{?f+E6s2W{dAB?B*x|~70VEWzAVUWJLwAQ%#zf{AEY`_EL$r6LvR_Dg`*OuT>bke)F^^ zbU(qvkBt@P`~cUaD|ha;PVT9!ObL2D;E$fEX@dDY;j>WMT)6N}Wu}hfHl%U5zrTl4 zjo{7TiU_$E=FV;V^Y0KgmY`2_5$Cmv#n=ll4_+CZ$*5xn%h?{?1w7wvCfHF0&qfRH z2zIdXEytxxsCf|W#ZjVPE@l9o2))3Z*BJBY3XR25<3;1lsp~nEuokbVCtF0+d01Gfbs5(Y9n$_PsQ16!FF{6xxV5gc=2AysA>Y=~R8yuL8~L0$ zy;@I2L|F5`E4qCD_KmFy^3LyzV-tI7e$PCS2;c}~J>rTlot^Bu(gV*+ON}=*={vlC z_41{Pni|1%rpc3;sLf=2ZU)Fj+t;9?>eI*7-oB*8NmuDEWh6^O6?nhZNri?^;?f`d zskd%fO088SuQD1-kamrYuU<&GMQ$S&aCV4FUwUj`#Q2@v0smGz6sDE@zT4Aj$OI{gg7e?r8;?c48h zbrS87n{NynDQQl+jF`D!C9?oP#Z9O}W%TisaXIV+ZsRgCaLcES+wQ!rQOK)a^G3g2 zUw9m?#%$m>A3wHGQ2#u}+ramijv7sX!R}|New)B2T>g%Fm=nP0Pl07Oa8s8*fN5V- z0l!W}Trr27Xz#XZ0AWoq-z>OpIfuFkdqa)8oD4BbPzD2@Q(K*d%V6nqomKy{0E2RG zJX+tKDj&`P8@*WCGG~VGam5G%)QnlPo>mzEu{fGE4|ptffV)S`WrK3t@Yf$ZZNRzk z0c_Bhwzp#c)z3lV{~70)FX}tR0*#)$%L;Z6)Ri;`wGo&bnHP~mUlVsDRJ&4OuoLlr zT{(A7UX+I?8PZ9VM^;F8&6et$K~D-MH2t+xp!A@D^)B8lF7B- zUQd!p_VNAuv(nwE z$zis-Olx}(Z)k)6X6U|e*i*1G5E1b_{b}E8*WY>GJnmuhVw!kR`)mEpokLb%k&&Q0 zK6UaWGNRx2+Ri2tIQI;>CWXxQMHnrQ_dwz`j6Wl~kl(D-AF?>i%10DDFYU~EX1PQn z1mxbmyYwx<=I818vp5@Y10zIc-kNZg009LD5M%P6v0U^Wz8U8#^U|ebT^~@djobJ= z<=nZI45{)RHUfVVTZ{+>?FOnEJY+~|B_NSimw>&E> zNR2dC+1f^>avzi^L(nD_Xf2{CnbdOZko@kuwFEZK>x~V2Au`>O8&GeyYyd=ksIATP z|F!H^GHxUEk;NV!5?_}sT}n9OUdi(E#gC45?bu*FCVX)ORV12BZ9cc+LY~s%8PHb% zdz2a`9y_q4@@_zYwoZMR$_@kr2*vDj^@8Bp&(Kgp$Mc8pSvZtgUg55ta%VU=9E78x ztI_eGI@F;7vkv`$2T`vA#Ii#g;&M{_{If5hX&+hn4))>cMLl7ppAJH9%C-trcqOPu-zz{4>- zcGgFdJP1!G^c$o@$==uLuW1|KbadRt(2;2v@Stu;C%8;3hd!jM)9#2#)|D$N-$sA@@PQ@Df7R$R z-_IG~=i+j>xi`V4!zf&y)qi_*tX09(|Q)+z9KgvL3_#E3#G>5;&2tt+&y2RBP z|LcP*d-)RkMaldSjs?{v-w`_&2zXAs7j7ClRwy3;c+}e~yuDMGH$fnovYC7KWI&m- zcnJK&76Sz>R+kTpEAb%rG{)K@o>+C9rbjm8;zbRpSGr)y;p}+#oM$)wB?-sQlIGYJ z*KXKg<1{lLhPb(Uvtc?(?sYW}n}k6;TR`1Ik!w_m@kqC{gZ@d$(`N5pV#bs5y927kaQRTrX2vO66cVe*{J`P7DPnUqE$M z@|xAFSxX`c0!%&0px#&#egxo23AJL?sssD>ElOG|G%Wrz?3Xdyfq7CO_b#sAeaPb& zjYv~XZ|^Y4dt23~z9TH)q3Ich|LBche)jC1O64L!ug%-GhEkrlefhJ%T}<$8?VsV| zl0!UV+JW!dfzYc&Wg0Hx^9_$!CtuCZ))}7wbC8>pBO@v3Qq{UkM8Vgt{l&o{CL(0p zPTGwm2QyUT&CM@SYq^+i#Hdky>f3&N`=;8v_YE8>rPVOhJRnr42?DPqT*=9rK*}nl zf9DSpu1xx&=Y`yi>Oxu)T(c8Bd?i(%sR7JOv^F z-v_qKaOjED(80pcq%M*oO}G~=E%W*FkFM@3_m2TG#0&~1`TN&DGw2GymLJg8K6dWh zv^jJ3XB~A=mq%M$v}~Eszep1s(IWZPT5%C`4jB;UKDUF9_J!yQhsl@hd+t!{tGwOk_4POJ;PmsH@ex0H*94`0_t~?3s-`~f z?ue{97rB^y^p%For%o*;Tb-YIFf2@G@L<_#_UzwD)2Byv1O6zMZ>+Da-IBQ_YWsFI z-_)ryXYS#CglmtU(*8gVteRs@Cpb_T6(zatFh<$u&(|}M+3xrpax*n6C2GXVBWx-F zY<@n5HqT&F*_pT}c|my*8eT_R0{AiYg9Vb)GOWjv5-DeCa4?UIbRRit6qwHxUxxeD z3pZqGgUVCUrQ)G*#D6q(@?;Cs+ms~uL(gycI)CxwL}DSlT#SY?)B}FQ^AE>wYEn>r zvm7Dv=SQL8Zs-~&HSiI=W(*xX*urE6L89$q-#I}scWW`!Eb{bx`r<{w5VkZlkm*U^ZJca(^&X?Audnbs%R-^{ z>(}U}5HNL3-Gp&v%IAjRu0S2JN+91W-hH$?Hg?9$nZ18LVh+v9Wy>f{!;PMCh&g%G zQK~P6nQFvc%n5>&FJ8kJB$W}xK#BKzw8+ZHa3jxJ^gRv+pSs9oXn_#iyu9%CIcMn}?HTv}gZPVdl^kt^T5ckd_7HD#_RXPv%q!QifUPq3P>oK3|Bdu$d~a~Yg34I@=pE+7tpN1I{lZ?sirBKWNAL@7d*G4 zp$mi_8HQYe58`)pkxz*Dm^>pR*LOfT)G?HpmqrevU~H`f$0J8vFNfN~H&%c6(D}!% z{d%sl+}bE&vxOWoB_H}}&b7B^Ci$pL#%?Tea|_Nrj;Zu%9=mQpcu2O)zRC1r=9gDP z^e5c1nn-qp{54q-KI7M9+3;hjsn2eIPTsQR)_=}Nkb)z#Y#-?FxGg{%$bwK!fLQME zi%(TYM*6YE*oO-*I1=6*XY7FS#IqoD3{LfFkS;5L1wqznVPG>{oU|cRakrRg5LK?! z_%(Uwhn@HF+57<9NMd?@b#xV$TxK6&7SGP^x=>#Q(x@?x##>`OJ^6@ojuZ8X%CJ{v zN%q`yA<7ynm?jhyf-kvW>9rqn9sXP-vekWz8O>;6JT)W%5KJd+gD=i=<;vIl{yb;q z$(AkS{C~=fHR2!hgX{lnxV)!a}g>XDw54$(=S}>l$ zwLHAGLL>Ap+7BBD@h>xcM8RM%0uDE4gelK^Bhw_WB3&nJAsC$M>S~A>d8=wDdaw~F zl7D*5*>B&2#f&EaktVyU?G!GeJLB=26i+(;XD ztD>iroQgiw2-rQS`Fp3pA~Sb=6+jT_3{r^#v-WZ6(4E%3F;VcI(%cTsf$#czvAzmL zYz_}SEZ=_i?9bAZi-jl3fJI7FHpHVxk(b$9Jgd7a7obW$k^@w z+*N=~DZoJKZ}eZ(KqufUrP}*-|C=8h9;)UgbMf+numXnjG1+Z{#X(??7S#H3N4mj$C*PD{WNa za36`NupfQtq-89?CmeWK{;$+b6uhNb%bwBPDMx?grhvd7?{{(mL4^aZdExGWm&z$8 zP86u+LPYDg%2EevtP4@vc8jyWVSV6>XV18QQ{)Xb*FM7S^vA?I*HCnPejM1n`xs7+ zAL4QfpbN4e%X|O6o!@t)?1aOI$1T1e_oc85xJ;(qrE2&dJfuHYR>aVQ1DrTYYy9Wy zH=ES-;6g-5BAii-@B|+@{_5F(k8pt$J$J(Nk#2@V`}ZFWo`e&gJ!_U*n;9_)}`VP)$ZtVKRkUnpaou4bO~jEjUu!0=f68vaC$?Xf;ok zDd{O;89&*#`0mXPXlZN1*>qarGMyU{M_xlMEmZ3(w39b!H&ukdTEZ@ky&opZT~IL5ggP_Bp`V!CBhB<1#W-srV*D% zkf%#7KRIwKzEWys@WK@}okBwfDnf>13K?4~4$?b=0>pXbj@{a>#IU+QsSH}Bc0h=S z@@az&ij17W?%?7UeED35$3zDFkeln(>CD4saAbK2H8BRRWN#3-;Cbm7Lo*y4n%65h zD8_sJ7^zg>yGv017t>t8*Yb(dz^}Gn?LR2Ns zx_QpQ>B>2S7V@`O3Wm4$@*3)txz$WFC$Obgg9+9#&>CmN3{dy#u_~9o3K9Z?ETA4P zL_Pr<5frl5ecTTc-M)SD0#k#23Nq|gemOkAW-cCR{bdk;A3lM8k5$Bi@%!CcD)YMP zKU^g}xD|#1i2fQ*$<6h^K(Ycl93AFr?EMp-y%@BjrmQTTO|eXI+Gl=&n?4@8(oZ^~ zJet)^4lktpQlPoKnKIC5bLb(p$fgD?0>HWaM^Y8_w=Q6xw zZ8JMlxMX+zR-P`nEjcfjjadscJ>#pmjGSaK$NB)b7=&lT zx~1@ZD0a}67}#kNs#(NYL2t#0`_%AGSX>+j;R)7gT3=Css{N>4iDmSaP=s9l++Vo7 zo=OL4l5WonNzBSv$75r=lgb*TM-&52g@Jk_N4BCI{+7wXSx%}W_;H&14h&!2twQwn zXAr-cK0YN4jm`9O0|Vt3?GTChL(m7gQGdjU(A~<1g>m(`LuJ)Cos!bh8%E<=Kp)Tl z+(bi;>WI}OIp#w5daSq@z?UlWFh$dJ1 z6mG@kzwq5yA@RFhb#QS3u0QPBAsJ1EHyAZ)w!M8305-^FXs;m@#>U3;;7SALxd-+U zzPK~w_ZpxY#!CR{4Zm;4!h8)y!Pd!KUAO^L7~fymVuj~Uo;rn~pc;{8J9#p+@8-Gc zZvhqh{_~KkU%$Q{w$bf^BNct*A{Fk|d(?O8c7K=BODH8UYewHQHYpQBNLMEnAsw7t zUB_?yUi+o|65s89oB>X1|GLADY;IT!SlnIUMGxpM*8#*K6&oGe!xd8sw4eS0z+j z(>j&4;k`*befk==%OMVO7FDin(WHy%AuEFY2Z^%f+W8*g7R*NoML=J@+F-QYFd8rj z{Dc~YIez*WS#`J*wMCm)uN~YWzgD0Y&Y!1By6*Q)JfKNhm0BH101_Mp5uWI(ze3UC z3?{-<$Lopm`1&O!joHH=78j3QQ!7)>h4nuh8|zmn*+*)W15TM+!?coKii#oqRN;~6 z1$|kNkW`Fy<~lUyWakqnP7stgOj)cHZmG>B^7H1;7dUVIf#VSlfNdD!b7TE_bnlMy z0-?>H*lai3V)@9*>w(Vm=U?BkMmsmeu0Q5E!s+?k+&&Zbi-}m(Wy>0XH(1A7%v&3o z_6{A8oS4`MEM?hzxjthQXk@^EC2TT3pI(xWBnm$i2wFVI84%1~IWm2{7I6r$fo}ID ztn2w z1tE#1*TBH+M~c9(CwK676hW636>%fu9seF~d4{U0}e8X=htnT3#|$jTmNWmHs>GPAN}@0Ai+36+YH zG{_2->@t!S8A-@WWUtKM>$<>VTi|6HP&HER^wQ2xmY%0}-|_zsR;NKHVRJd~T1Ylfk1 zOnlO|E!^dhNnPiZ(5v``;pN>V)S$cEa@@JSII)O~ z_?US!$~LG?BunOE_1Z^DLi0-;A>0!8gCNov(zOn4uxxhUX;lr0X-T&f6oAMzS=E@_uEY92j>5z@6>>=f>riwk@SuE^+JDh>Ka zSm~t2+(vYO=*OI0zbwj%=e4=ow`q1ufu=+wiQsP)zU9jS_A{L-ywP2^J7*89>>z??M2?&HoiEqDXjAi+@tN%7|tLcRa3elpNS&_{ETNd+%dZ;+dI8ajc+^r8&k7#y}qk zlx+ZxCaCFx9@R&djzUMa`Fk2-AjTp|iNJNaDm!7I#6|05%=S1xRQEqQXp0 zw(i1qh1VIyWiiTlLt1ts4vpfYM`cjaLJ8#bVBhrYM*6x|&-v!1@bBBc+HB{@P4{@B zr0I_^%5K{{SB*&qeaV}qOM4YVHB{!=qgEgY{U>?x?eSNnz& zn{1sE6QOKzU$t@U{^EB}Uv}dv!(*Cy&o>ML^0bc-!Ou>fQFx`5#&qq@HA6|^6*pf$ zUAbc#RCgK7zUBRF3TUu1BjY_?{^ameVbz_yk+*iKq+aCME6I@0rkb{0(P5=!`8hKo z>fY0$($Tm3{I8u3QYAPZkV}Gd4c?9SIO*ZWg1Qd`xElmOI3A%nG!*__g6u-fLkxg^ z1ZfmUjvh^wc6|a?ocnCbi-@7+DXjDs{6^gTwhoB<-VlQ{{7UEayT4u z8DVmK$iAB&a4my^g0u%I457`((OY99;t*$*^AvV2Geao}e2rbw?ksBJH6avNaG3yA zf%)*)vccWjrM=su`Cjb*hqHm4Td-3|Y46$tHOoVR<=%$hM2X;!0$cwr1SrycxY$p1 zca!D-4No+ULSoa)%XxncgDJI&fS6s=*cvOZa9f!N+S{|Czr9;uUOtDo{~OU?wKMus zN^KN|FvsC#Zd<#HUa z0Endh_l^m|ypikO1n3eM&SLs`hzyi_2K)P`wd;q$ap6>Y?1%$?D#@|`AdEpk*RR*7 zp&FDF6Z;d*Pyl`u;wyjxbf2Wh+*eTg0;`n1{T@18^=NiU9P+p=0ajMcV3mO2z$%%Y zu)VxIJpgXWQcMP~_m!qCEmt{MG>)_PLDB~nob>m9n6#bbW|lZ3skWe+CnD5sqR*^PMsPR8^}OmKBd$KW zTD?S9TXy}CR!? z=EkZBg#8KiJ88o;`EJ)+&c~9eFiE9EbJHZ$gY9%iF$H(srX%X0oE#fbR(IJ_bh4<4 zz)iUsm%l!qp^use*_!IuOLpyoc=#$^{TtVC9V06qE!JaWgnkYVV%*KG)bdxTI?*+r z_CEq2M8Pr@ZBbP}dQ#Y#R~z`zpS-?U%-{%1qebF#AN7EMQaHwS_}LZxy+LSW$2RvZ zxOF)!!g>p$av(ZNlkff8w+QxlTiozTC;q_$PNa|Silrnl2!S-#{)7L7(4j+!KM$Ju zwZ+q=BA5*P1bmP~X^FoE*E4mWM}OB+qtP6?TPKz$MpOX)1VtkAnnvhuKb7HWTi@o+u#bEUpCw`zwlavd&e6S z+ncv`jZL%rvMYF9J-i$wB=g1V?uTN3Xms$YrI*A#wt{}OtYgBlj$iGQ82<5raqC-g zRyt^q4TpCVxrl>%-4zCC7^wUk1z@Azw%_mJyWKqwG1Dzwmlb9lC0J0lJrxyZP~(>S zZ#yb@@F0Mt&^-)5xk%bN#Xl%%KQ%WqawHX^_Xg?CP}A1Y*$K@XDPpjTBw#~Yo2jgn zG)+n)6bT#HYjPiXpr$2}jA1EPH+}|99_%eW5VT_>2VgZgSLDq|Pls)lDtBHhPU8_f zdF|Q8-vJ}*aGlXkrYovrN@Z#fHAUhl*Zxuyby;hRCg$|!%nxJw0*T)zzYEzDRvx!%^~QRTUr7hv5fr$aC-+Q=Lg(caPk1sT;v(=fpv0h>}FvZ z@P6aGGMs>2HeBF?Q$Mi2yol=^soMFX*w=55AKN9f9Ex5NkcasaE|WK*|m` z=phb&lv;Q;?le4;^e7Qg=}s_>o-;8)J~QjCU0by6T{!S+uuLIqa9`F3Xmr8Q@Bs!+ zAAKz#yjHp?tn`7C2mL6R@LXI~o4Pl=Y0AI4BSAh`*t$h;HJkVOlaVjQHh)I4MncA^ z6n$1GSM>a-615VcA4H9@t^|d+@eDmsx2mHsinLZ${n{_G(YLul?LmivyF@?dkuo>vi#>%q z__n`rvpW6=6$siox_x!%bby)o1=$H9_!oZ#BrwM{j#=-#j{^N(#KlpSv0t+`C^Fm$$iGXLwt3?i6pj;iI%*x$mxsyt5&o+VBHb~cx5 zywE7)E8`%LB6gSe$v*v{%sqrCue)mY6-P9`zMp&Gs<9Mn9krj=J_b!Y-}ZRTr}{6@ z>ijMTzbnD6YiMYQ$_l@ju7-G1B-8`*90eHLUk7lg{Nix2I9eX~LBsa6qbpeF)4JDa zjpOUdR~E3`D4vYxnbz>OfYy@6nhY?!KD(#dA`d@KOkBK`G+F`K8q)goAn_rg-nL5j zG%Jgfo&EESehJij2p+0>M4O-q`SL4(Wz%2Ht1ZQFU{8S-nJ`J!$^bw6+A!})?H+Hk zcbjy*ve2*!adX20`zi{R8iP~tKSn&ahj)7JbW;+i6><(b2|mhBY|OIQ{+u#9*+?{_ z^h-`wd*)7pyFkl&sBhm~@@VIS92C`ztcOQu7N(y5JLeW-!cg*1m+e?yTO(3s?@ACl0&P7# zkWJRQSOQsuJZ9<_7j}Obsk(1j#HoTz^PvAcT=N=sBpTx z`?Zi|aUL0=%cg6!fmiqWbfm={UT)%3Smd3`orLm>QwLTY)s5n@(|*2MGQcR@k{GY1$K#0JeQh9MU$5KmHGnX!MQ`nQ%_iBTi$S5y`L*$E0$tRB| z^X(vnOCDZcQ}36iz}dT8wzIUP+#(S45zGNp)Gb9&Uv=7Zz*0%~=n~l8)5k)a%R5xU zsBT6?ATf~hFXWFvB3&(0wYZs(+9`q|2NT`m?g)Ed0I&==YsC8k50ueRt-?W7G5->e z2fP%n1*mhTb>81r=7zEac5RI1*dq`D6)rUC;B5dadLHTBR=zpC`^T0>8`ddS$6bzS z$z2ZW4qr6neia|Sr!wM;QzmGlnYQb1c$%Q2k+hN^BWQM#7f)Gi{2wjA%TqVo*r>uV zyO1G6oFD)TfgAn(egQ&$D6%v%av%%C?g=t6jm0Sh#7QF-o_f+L6srTZ;yeF;V&4_7 z4n@ELvAeHM0fiLlrljYEP7S37!=p~noupwtb9!R;K0vexgV9Ojy#U%F*Fm&+F#R#e z_Ao-c7$a3`Ggtp<;eUr-JlgmsU}5AGg3b$Mix2J#THZz?c;Bl+ZUpG%#|Lr(9|8bP zM|RzAgm2^KO@l?o=JFZ$vIgJ>X2EZul?4jbIa>8dLPJe$M!ju08T2bK;40l7FmT|p zWbT%y!2UciKsH{n|hx8C4&xK4%x z)*C?Xv&Y>*8g}e?hNc`;vIx|xGU`LXfJf&FPSkP~s%kyZynp|`lI&dhl3Vw#=;LuW zG9veCVy+@(A42?Vlhgx|Csy>`Y>Ev!zO!d{x>xYhY~Q)l9iT45NirzlVxpp|X(M=P zNTI24{tuF~LOc)0(%N`VdG2FUP$}FD9|d0EgS;iHsrx^l~s6X(9z^q+CBtm6}M?okXkVTmOGr<@3=5?2a>%~Z{ZtSn z*uWSMGMr`i?rLUW+Nj$n56&oJAJyz_wSAMSZTeXBo(?PdApwDo-s6`Xl$i_)^_URG zdZT&Af6RvKBC|PoF-VNM9y|a`1IfhUhi}Km$1&{1EHw^;5l~kn{O9B4hRl~QL5LNj zmXQwS)&%N+9GI4;E}Z`pv?%cbg++c>ZWT9C0lFZ{=)55lC6J&HQbN90Mw}zsT!{zZ zxTYqrb6k`nlKh#N5KNPtyjwWtEFkZNwUNUhdg5Rw#hoh+Ne{r{YJLu3eo}W)bfryT zB4-S0Jizj~w~ja?wGC}Nvadb`)&i3O28sf?xgoKCZ97M1H&CGQ&CgJ|YS4n+-UQ-GA>R`e0DjGoi}k3Q!j zDF(3dozKBlgc*%6oG83K3-=2Ngzl`V8A<-;uV-d}$=#-=ogyRbHwLQ`++XhpA*0IoJ5Mt`^yj8I_Rsfe;)-k{eapFCnj#_*>Ob@+> zsH7*ga4r=qA&Txf>o#0!t0?1S6t_jIBlP{gv@0*?JD~aJ9YqP{C`t zgX-sV>51|vz!E43fZK%x2$z7AMZPFnC+`oeoHV3!7-%oT)|#3aQsQJG%!ZI+g5g;S zBqf;Pl;((|9wxHGWr$ziWlexQUDWwVYai_6ztUxlLj%{|^&%MiFnj2&Imu56w+eJF zlp45oD@yMQ?}Ro4!(MGGxFOIV>JJ%Hgn6M^r5CB;MRv5 zGZ(i2X|9Qrj%tQJvVG>~=le+)R37<(ABbv#hZ|L(McC9~B0n$CO^NYWt%+IKm4>g&T6OWmRB*p*vZU7en6)rzrNjKgwB{XuI} zvhfp<6kVhlE6psyk`=wWmqrw@)Ve<30(bNL<;!0+s%H;kiVRaqhX=;p;XrV^d{`K5 zq>iR0Nd&{GB7O(*?{^9w)EM&s8v<@cca4JX3HT>K`5?Z3kI2YTYAob(5jv{NDC4lb zTquw`{sy%yPQInD7Nq2Dm>Y931Nqr&=V#26A=DMByv*Zbe^~-vH+_Z^%dE)>reGOP;*4`EaS`3<|5bZYe(S^lDWaVx$0evXpM1N4HW1krDr!V^E(l z#!X3X4qqvpm|b>kIO}1_lbcegKpBX1jIQPfm1amu;OFC;mtoX0r6j$d-87+`GFL5e zDnTN_aM!j$tDn{sNgu}xA$Qf^zr)GR6+_1^ zAt)>R-iEfhZy2u>CuJ@MQMB}`K7(4O%F}rbdF2i~@(w3+`_r?tOF>w7(Qn%}X!kkm z)-4^}jahqtpcNPyLHtT{DI3&KyigHAj^pwa2qM1nk2s1|eh{Ge!G_s)*VgFxa%uj9L;o!xh2`a6H9#5#lA8c@u%*GG#y9E4#0efB1W z@7XG1{C;Oln(KE|c!M)q|6KuX%_NQhd5=hv;^f(W6X+FgmuZ$}X6XDD5$^v6d*Th^ z@FuS-T3K5k+nhsCNA3Y$1;Rc!uhuVs9Mu%A-!A06_g`1!XF;3-&e>%Z_;7)nRk^r3 zi9=C_yUr|~3F{R@jC@RG<8(+f=$w0s=xeT|laE0oQd^xb4IsdEMI5*^I5f#O5UjvV z1x*(e4W7ki>&-xN0gGNo`^kafx|1eDIQDZLEiAq^@S9Kdc744T5DwvyvKMk^Ko#>9 z+q7fG0$S4E{CqKZY#(jmMJ^4faf^LbkW)@gOnfQ0K?nn&#I^!$>H?+AKD@lp3!VA@ zlT&OBtL#G9Ac6>RByc`}{1Yh1dlTlzQ4q%BOWr*WIv?gc#z3h=J!RygiC6@1SgKOUx?ppIyt&dzj4Wc^GEY&^l|s_KC| z=QnN;zjDzD23Dc>?ZrrW>k^AW4JZGcTa}v$6-!<%66|J9_uisLpe8=l%JQ-@qrbiV zE5OV6pgu)ZG?-kMclkzQ;x0}UX5Alr+z>A^wY#kudb^WB!S$91n`%eNoKkk+@ZmC> z<~>+}4s6m*SEqg|+?7`4+Yap#9M+7l!%E*_K`%}4a$)$>^}l5$6jTJ-RAmuc6wN5e zd_)h#YtGNker;_H*@ye*1M}}-m?Feck8Vsdp-|om^XzDVgjk4jE>2l5uN#VdRAG5w z#v%8Z_U2!wBk7`iaAT}?ng*f#qAQs}2>{s>PRd_DKLFI>deE%UV^h%WkTqQe>6uKf zG?7~=7T`s?Aem^o?mR{B2cLTk^_;%o9Rx-JSWPnqG&D9=Kj_cdw)bpYIp za~Ymf_$fGIw(YfHrbJ+Azsjx`fpnxbBMQx@fIv-02i(j|43QBLZ%az3si~L5Vi!lT zr~3QNY=?X&{HX}iu-4b6__}D#_X&M`pXRss>nBt6ClJD!!R8Qov_u)-9E!uLQ#o*j zV!6mOP@q`DauxMwAP8t=T~VL-*VB-YX^1s)O*8RW@k!;?-rC?6$jq4~$?R~pcoWzr zr?j-7qE##&-$Z`@mWzd6IF}U`IW99U0urcwkyxE@g+024IaMm?ADZMeaVgZk{QTiZ z=P=v|DtMI_)4-2G3|Lqx`UGQ?J>FbiYaJNQE?m`%cS39c^FY&U-j)E5B?f2I4K_aw z3P#CLrlG4F9UI$>!wki6KayhKB31+W3XgLYmoW4)Ix;fU81BqH+D1ih-Y7p*;*GD1 zU$)u#R{bgu-{cXLH5FURz((x-nfdaZEa~Z;A=*5IVNq? z4ki-Bbp|f>9XrxtlGcDoEe{w<)-wCa^Q5(FO0E(ICO5~Z@a6Frizwp2{=n0GgF4*# zf^Y{wsmEW!k(C3G)7QTcRbOSmt;dgfGJlLXNO2q#Twp{wg9fM@WLXO)bF+yY4@F4? zR&HwvFlr!O55ic_tV#MN zlA!ZsDi4}agjb>f=xS>OhKADdFNW~G+Fxdfiv`x5R;ln~m{I*l_dqp7-<6B7()*UY z-J~9WFx0)j+7W&k&~y{{xet;R4e|aQd~PAz8O-ghgXhleH-{!C%j~`#l!oLGwTN|= zP=pO`A1LI^5(+^LxW3483c(9gM2Kc$dHE)~m%K^?FhnTKKJ7#?hGPOZ{+tLGTVZ+~pCk$I8#D9CKF~KZ;V<{$I5|U}fv(3i6%Z+0mQ2u) zpp?e%d*3r_Yi}PKAKxaf4CzU3c#m%dEWBoZ=*KyC{;4{+ytJP}hnop1Iidti$dFYw zoc4&zkD!l)B6jFPA(b$e4oUt(eHiEuU`G-IJ9YjT-*$YXm~(UpPWXZOV5Xdd0Sq`{ zXapUkR)Mo&RAFRnZ0*lMK7M{gnS%a=pQnCs0YmSO?YaaJFW9`FoHE#P@U-l9#1y%c z8JkbchM&CU32M|pj6DwgR!Z8seM?i9wEY*#;j zDnb$?_Zs;P0LM@@m3^ECLSQC-3g#y}GqaYIZTW^-Ab!n6x>8mBqDkdzkdgsnP zgm?bCwb(to%#G=HR80PdC6h2zk zvUdFmA)I;|r=MqKVK^}?DHEp`tibr=jD?75T=(r6XERY&Qi69e5QE4==R3u5g;AD% zgkJWKEBj1r1-n^RoOyZW=g+jhDyR)>R!cs>-g!0>_yq*uuwNX7<`JY+K*Y37g=ggU^x=`au4PuMk1lFcWTmAMYT8Vc16J>pAr1I7 zHN|-51Ashe9O`%bXcECdY`wju=`<}xS@A#y1Cn+|zIbt9(dGSr-6eA$bML6Z zB;bGH3m|D!#*gVCR;Y2D_QH9`5QG~8vFM~c8Zh#?t5j&P%ql}s*C7jLrZmDNFi^4R zXDfoPNwV|R2DJUOMajY!zH)HIPE}dtrO5%&di~7`_uVG7Qt8F z8XKccU0X@&zs1GtQl#-As72qZQFl zYnla}7Ar^Mm=BL6ChU^F+Rc}?H@v88c#Tza*g1SwvkREa|ifja|+?&ycx z-Xi3l3zPK_B7(v~q+yjA4OI=TBCxT`4HXO5Nl&D-6;!>9MY|ld_f$RTHAZW8hE_vD zI@0tost9Cw-st!TRovdMnp|NcGPJraa*JK^Wf=WW1jJxPFX!LIl0-5{)g-QJ3_LI^ z{nN*Wb>gx`_F*7WWze2rcu#eN=}yFzVk@FbfuaH5Xx2Vl=?Q!xs19@CZ7spn=9o*E z4!-qbbrUA}?o0kl*Fm_|*KFH~mjC)+SkC9ho8TO#-MfV#poi@;rJQ0@@O8Jf6_jVh ze@DlQ08(aC7Hm{b2i;+KKp;j{N%+HmeFcUx&t8D0uTws z{l7OAsUbg~_6L}w5kqE$X!Fx#^dd^rpYi3eB!AUe$;~0C>WvED_Ep!N5~_N7uK0Sk zDV1grTqKD!pgzVO2~UD@2>>`8gIzvJ^PCpLO%9!jf zxN$~BpN@*+73&A+8)GgNiPMBuhy(Yfc9X9?A&S6|;J>hJO^+9yOm9WK&~Jl5kY0!v zD$An8RlI|Rg(~ARY_AU;K4 zMfk20m6NFNyzO#4au6?-ct)EF;X3jX4*vybc-fWGuPrCG@JA^cDe)^m0<#j=0F?$2ks6Txv$T7tJw z1m>Gjsz8>3362YR^HZ`bK!0)5;uocgPI?q#1Q4HE@j4`gER#IvKacS^1%j@PPMwMk z+dV}{eI6+mtAGIv1oiJZ>X)8X^wG_)fw1C|hP@ZNl8k@{55p!&5!mJPU-Y1AWTT^6 zdj!EFj4OZt*`FFuFsPVYZI=DyK`+i>rZCZd?QBM}7MwpT!|R!;D0vi*bE#xUJhwgM zu!S-$K8weRkAX0g%>5}6*k`on5vRGYXsFOXa)XjETWdJowY2cs=$Fx~%%V797BR>4 zgejg+WuLHk+X7=}bh*}i&V<|`v$ccmQ*umj$Pm(rT@-43#3&XpEt1kCdT3T?g(EKC7 zoq)hAUSnp;dFPK^T+>s7p?EJelo&1tFYg;n&b$(cf)KJi3g{&vifNey`hcsaN+ngR zSyWQe(bg7@8{&HaFo>TYOB+NEISbhhuCLb~=)QR}6VBXQ9VZK#3X=T!FStL^oXZo~ ztGIh3q$KSh-HBUIZ>N#d5VC`s))G1@rUbGNIVtgV! zBL_h&6#r>;R?>YaC2uB8C|9XkL{u{o#J<#-*1>&5@VVN9Zw^pmdf;i9*T;79-2Qmt zbL|~6BAA}`(6)F1C~GG4Zz;ZK@ZdVA_-^osBWOrKR;U>fR|#adyL;txT^$OM5y(#A zwGy}f^7~>(^2toVblK<>|KjdNr|W7EwgTFuMJXpELlUAt29pos@D%4Z=8(s%SpZa` zpb~1)_5VLw0RLVkgmd78JL-Sw3*_Iq$ApkVvql?Gm49^@aY))-x<2=2-D}R2{RoP5 zj11@vfM{^{u0yvS5-ACJ&PCB1)2Vkp1u|YiNwQ{AJrxrd%Jek?@+oL^U&U)$0+s|O%Hl~o3a~?dOa<Uh)nrmgMw_BQ^5p+f9?CCQ1QA48Uh%4M&G?+iEe5cXv+Eq%syMU~ig$3X-F2YcFB zd70bF0t5jT1`iHZ8_WW@M1YXK0;b5&0H_-OMxO+;1}+b9r1C2tq&58fN=i!n5RLsE z);L^XB)`{#(36>$?YH7L+$4|eR*3`CIlt_NVhzpHub-F50qh}(0H-afGSNv@d>A{< zCgaPALV%JTCg&lX`Vdr3r;*TIB z4yqm8G}v4n7`%Z`74UohWinG>bGow%1tg;HWe)iq!ucfe4pL}kUfXAOk$={0gbeaa zpYlE>CzO+Tiq98Q5JU3A*Qfr)wlgavKC-{NEzUWIxs|2W|M7{PDIj06EaE z3mcdZPkuQbMjU7tK9;_tOu(6iBRlPsJRGp7|^od}?X$wP4klo5DMUCuP@wx4S; z4fJ!ABa{O(KTI2%^0lv{TJGMO*uSYBfbXt zN1eT6!mFDWIC}kX!EBFTxa2i8cU9SPb;x{l7kb>k3O&WV7q4(0#1KQk3pyemA%GY* znJdQLOVXz0S<*% z%5tIUeeR3zz{14DO>-q@C+(J3TP_|nTDh<+zGk|oFX(K?E5s#MPR9eI#~nPmE+2rx zZ5wT(dEy~wBeUX`qPWIC-m)#Xd-TheETnu{e^6twiDnKc#`hyuw7KD%{@1|B&8R^h!s@qK-KTtz3?NR$tP zX+qjoaKa_9YYTZK$&3zw11^RJlsC{m4))er)kTm|x;lZX@f`}AWyBfns1aI6j zVO~l7{LMk2#LSqiB$}RJwLJpam1tb3$Cio3&9#Sjs1uKtIzT~s_h_)N8WrI`zZ~)C z@bUWv_qDwe$qB)*1GfwK$Ose~LQCfWC;A{-7a>HXIXTcBfMH!p=v714(F5r5M<~o8 z7@K`{-&N8Wq|@6hkoF)iSOha9kfhe4yLSyYr_asbQrcLiC_)WaQJa`X$00>0RLKe% zP9w|UJ~%tT7uxX^%6xKzm*~#3DwS|-t5j4`=oDh%9))VJ`~i^YJDJ>4~(=*4A8_JE)ng%1Gixrbw+P zkruajLHw*YlSG@wxkbT^mK4Mti^Q|r&((=p63SyS`ubZBVCoCfp4TO5k$U2dw!UQr zo>x-7R?^{7?(XhxAUmo(fCG;9^x;(|CFOX@;+QPc=$U1P3hBU$99eOILtX8{fq4jW zd@BM@G&H?jP{}ZGa5UOdij8n_8hWRip-L4^w(Poj#iuPFED!o5sLSFsl;p9+{*z>O zko2moZ++9|w_o|p9r@LqpCIt5-@ay&{PO>nWL}vYw+;?$?F?LhB2;@I!KzLy=yTfW z5nYk{pTo*mVm_~ZZs}yaboBIRok+23Puw-PR+R6sE{~4f1YQkewwc!J+*}t;%{rW9 zGK$Qh+<C00kkKzcWLcKe$^t`CroGQ(5^2`KOz7j~K;^-N8DYJ7gdD zP3Kg4@)p=zpI1MRT;18)sVS1M=dCX{kv3*^#^Wvb zG(aL>3k-p8WzEZ~nMEjkG2CmKnFOkSyn>?&hwUkoW{TXURG!DC zdv_FA<(ty^l1;BNE>+G2|Dzk^O3!{mPbhPpR4cSTZ5S=wK5(3S$2G}otv2es(Spx5 z_XZtUXX7&GCW!bWyoY2C+5Wf&C&2CH;_XGZ$klslr3m6&%xCqkFIp(iZLh_}<+l`% zu^ZwI!&4a^{O8Q#en_Fv={@eJ3Q?Y3T1rK(!qE{#|KLIo^)-ix3t1WcHL4FGUJ3t0 z3+(Pr{J)dj5;EJSmVMgZ5Zr z7&*L)pyUQBpOT-{(u%~2_`U~)1tfw&one5z9YD(^q+>z}auoiR@X>^F0}lkqWt*(b zjh+J7-mHh-I@^ye(QT>bV)vkOF&wwIv8h!UU&U!af@nQS*z>bn>yy25-lvd`I@0)* zJO;4FoB7TU-++I>GJtzc5OPC9$q@`wV91dFNAo{^t7X|JKD^O->U-g~_vc*xM+P4f zW&!MG43;o#A1=;I3h~ikfb*MCuVdMa{=CFRvOYQfAkvYm290dRVT0vc<#6QEvb=nm zlM@>gGcta4BP=csQT|MH9PkrBiHcygZ9(V1nUY9_O`s>xab?j|;|pE`6h6Fhqv0q|1DYal_ACtg!2Xx({BQB4h+{eN$7GhhNz z<-R{yAx{QsL&HKsNGb_4Qf_i+QB@%EAHz!%dhPmk(yZ$kRyH;;)^6Vf5|fi5maLe> zI#p9G+o#;Dkjqhm^)`Fet`cd7l)h*70yX|rwHyO96#(J{W=AC^Z!=(-0N|b%D+0j~ zNkuZ~yRw&rG$1E>I}6M8Lm{Hb-UEskUvD|7``Nkx#kJW)BC=Z$PxbC-ub0opnv4TN z+hb}Awn+n?0}86%12Pd5T={q<{sZ#QfLwk5zKBGhz6JMSW$w37AHe+i{PAh1Vp^m^xkWGPC>uhCn5JTCKZ9`U&8eWx z!6{$abP#(ZBUB|=6fiRm;U&?NUQ!RdOTaPFN;Agb3?RW!)Et!vX`1jU0QmERe|mdX z+xDXsO5}c`BDPd_)zi(>^ENhCoed>bUGBmxfmd(71VLcv$f2ny($-)^z6^ll-1vK_ z)_}Xo=axZFhHajUHoYc!dJs}GL(60MO(cUX+5g@FO-FUu7XYo>?!UnlDCS!=z@Qb} ze=`Mj&KXNN{h-->lgbkQz8S9*{|f>+_uC!QW+^(zd+4lZe+50#UkbvJWL-ZyOpNOo7_fZ{YSrqH_J5pu#}qg zkt;1301>vVJ@jt=je-T4jw-6&VZ(YyWNp`X)_nf*Wv5FT1n;l>9WEo12o3DNB+E{w z3bP<^*`_|jhUE{@V$%rz^`KL;vRP3NIEAay7DB zySC}7Vn14^7h-3_N!(EUs0Rl;DNNUX@_V6n*(CjsU6i6-_Yks+YXZ||auJJh1c(D@tG^Li;9!S*sm;Du_unddaMfBFBn&4lP z+|*qiftZCgQqG{_Li?Gldr(^fr-@nU62V`UfQS%M%SOThkao`_ zP4S^5v{A@s`7WlkVlYcn`FgCeQeYo*ynm*!D{$`5n7%8E`Qj`6VT{WiZWq5!JuELT zZ+Eb>LpCC_!RRtQp4CyT029Bzl8ZWN`Y%|(Y)=$47a5YNrys$QBzc3LW3g^u?3=Dr z<%#madjprvV-mZf9x3>}fA{W0Evy8u5iobLIs0j}@C7&M>5m=asIo2m4)&?wF)9B8 zbwics39oHrbc^N?A^?0ezgTpo@OyiEd+i>-tWUJL-43`?CO$pJTpIvVQS0*;*8$gp z`uLiMDW(lM6;`oBr7bK`YG3YUF)GZr0BsfF0_*Awk&&}P`A2-mGFc5I$NKXa+A>gz zMl{(KK0}^_l~tZNNGMW@u;Q|rcGApnvgzm1*QB}VQ*!5h7!USQyRM2M9Kut$-`pPxZ+$ETp1a1pnnU6meF!Dhs zMJk(r+uLtgUhWtXI@Z zqo7EuI!z_a$eP^!70=#WfeD5=!0fX>dtse*6&`7Vc#%7ZjpV=vJK~a68`HnUqWUIi zbAz-^3=Hzc0iT>aaiVq1{m`Wofq@$+^bFk)w1gA$(533^p=~mcH~%>;U`_>BLFt1n zz`{S3O+ywjd+xlNIM_eL#CGUtYbP|f-!Kg&sPeiTil9e>6h8m3X@)*(!UsUfi`U#t ztgJHpYr}8s4SdUQqp*G(Gmtu5k#5-i>bywVLKhdRnj(8O3~9^N8yFc8=sURl(Ca6& z&m&S0LDxCJhp;gpxR}8ixRsoh5^}Y;2M>fdkEged{q!D;hK3?Zq{bo-S!WoZV`PW1 zNZ7=B*LoSSg}N5l#4Kr6QiCY|z2~1@c%vqc(4nHQq~P1|zoPqjAx;0+a}VVn_^o(* zHBX}aJ$EEpI*96V9TkYfW%ReWFUgCw=qa4XMf;-lU+8FQS&Yxm^7pM7mc7{_k?PNo zQb&f4d?y=Q{eAQdl!98>aie=pcSM z%z0tkNlCr}AP5oK(8XBegd8h@S-QQvUu`Auf-M^{-|FTXla4B&Bt}L?n?{g`k?%4n zy=ct(2N9`?gC7gl+y;RpKLeI}Aq#NJvcoIeTpLxoF!$}eDNG7OhRwP|vE>dgjx9SP zdFA6CA&^y{e)uG_Df&zM?eIsmVPzlXj#iV~xB>zG9GK-iXu?#{^7V`L9IzAU zXNJ?oN$&)-y64~TuEG;&zrZ?~HzE$BzLTXN$79Tbf}OpiN zc;fz@?a}Jun043j8G{^EvPK2y~gq z_s(=j6fNH@yUA^6HR}AD#4&rx`2EMcJ!Cw=kB28Pjsx{7`pAh}5^c$=VVFI235lmY zk9w=CFJpl4kKO)dH~kB~L9FJM_4M2Co?;O>mY|xKIKvP-c)<;HTc{G{4n0H`Dk}%O zJBZx_81ymc9Y20LKdjfK|3*@9u&bxXKSbo18BAS>)RtyZ-z@)y(RBCP+ifvv{lJ9Y zaVBWit5>)HhQsr9N1|mqd z&o1!XQ>(0d3fl1&5u;g4C`wA(EJQ8vgjtSsI8&AI^ETVHMOdtv^2fW>7QFKKD}DsIlFUn>)nWX-*vZUh1&Z; zt37?vENwb=g}xB%X6;)knJQbYRobX5=2PJg9ym3FLs4BrBWSMi=)^69SENZbu#Rw# z8zJ%c;E^Noy*Ckt=Lj3#p&%Fp-lOxTk z%^TlI2R?H9UVWR*{!_~Vs)O_cUMwE2 zi`fSMo+`#8d!a~4&t479U$lOG7&Vtb%?%}|$?fH~l zol1=b9SnT}G^vOptv7wFfRzW$?nGNAV{Mg_g;WaZ>?le-%>1dgHcCFz6GdxQ3R25& z(FcVq#rbn4)va#-sk*^LvcMK}f62Q$l7ifyoSYnYea-wYQW~*QwQ@QO z94TNTqU=iy*-B4uRj?Joj9dEB<1p3^Y8RWvX2n&VHOaaSc^b3jzo`46Gw_<|;!%=; zy%E(03>FdR&lU3@ddt(dg4B8obfcWwE9X-EXSb#VAVZTIlUd3Z-dG6NXBpTd?4Zx$ z{t0&D%KId-MDh_`NPLrW6v5~pTvRCU#NsX%WsgSfi*Xk5r$QhyLpr|^f)de))_!-g z$7`LfmyZRUjl+SG?RLOL^ z41C}=!0ol%QN4|vbuy;Wx(9#tHjxi5Z6g+6!=`Wv`0Vne#-|FJDqS)xfGT3P^{xdp zcUFUMFbTzP;m;>LuWS@^6J3Wpl5UgY*)P}TKU-rtfGP zkm|!ZXj^=tz<|i3?p3Z_1E#5BP--JoeXorQq2+QFejx)SsMgxeW1>s1tD(mZ?KCp{ zG;1N|ElfXu8+YI-`I&3(4ta(XwmCfE$4JKG$vyZZZ!jRCjK5G`a*BM?V?n9iw8t+x zLPC*!$;HdFY|{3jYk7PGr>x9d2Dj`lFZei^<2x-yGTIh;1fp8?3tvP=XsVc;`S7y* zxzmRhP1UAYS-Aywi_LTAH%IN-h6Q-9`g{o&cK>VI8Btf+`S@?a(LILtjGZ0+XO64J z1jaa-A1$w3A4zeBCJ&+4f=b;uwn0OBw7HiQ4H(gXqcPk>6Gpl-6x-l)#f%X|msRGJ zkJEHwspf9lVsVBpC2j8cb!l@yM%X-m^84lBx4l1tAjGz^m%3>hq^kNckE`}QYYCIy z!24rvckX4s7xrF*=q` zw6q)NbLY5ic=In6JP2HLKR&jQpp~7!VYxnBn0&MDtizwRkp=#Yre=lBK{=)E@#Zlq zW6#gNd*0M2uc7)~*|9lYA)_zhPwzLi%TZ4gOcF{RST3p=sa3zD(my@jS=q!Wwm-3%eZ7N8J~Zel z&SgIK``-n3A|Y%O$lKT0>BU7B7q4eZanhYiL&r23|Kt^Q8u8+2w}S`sbWpHYMf;N% zD@LV>S@sL|2rgB^&hmS=ft$}ysaI~GZ^wDc&I(Kczd)K1aEaqmwq@hG)KOX9_xC;( zlV>kBeK&dj{W-Z5Ra|JDx{biYymrHg-)leS=rib5+ZA7z&I`33C`^!2)>cgxJ8ZoA zhn@M{sDXB0pre;#?JlmHbym-#%%6os=%_u*zb3|;zvgh@<^djFef^4OL`H)CaMo;J z|0z|=^xG%+JB);w6KfK+ieLX7E%MsqvQ9>d&_+@p7{Kxa0jmq+#aJj{;$KW@ep$hk z%_QLqRbM;JL@lkYe|qlVY5n8eR<4WKQz2&zlxz&TpQmxmcr(Yp{Gi7H{wGM={C<9Y z#Yo}RX2L1Oy!7#$R$Ge{3uBH;87oKqi&e^=D8I@y%D3D)#Xji~^N=fB-Cj2^de|mv z*k;>{-)pZ%Z))y-I=-TEK3rWzm6keuBQRk2x)!fkpp|>9i_-d+D^ab-wEk>d@X}Dy z7%Trgte5<1)9su8w@YrhHCDOWYIfl>LD8y11r@dSUl*2L=iT0{IlPcDyj*5i#GY;W zcy6wFNBm*cPLGS{!;Q=fjllfv*uI@%kG$YsmVv*2AI8N^f7KRw_x5eXCDQ%?$y9T2 zX?7NU7S#5o#+Nq3`nW8klpt7WIO=MjP5Ex){^b3M#cqS}#0W^qx}(ndy(s_s?y7e2 zA%pM*0GV(Pm5e2y9a_oZGv;}seKNVov(K*R9#W7|@OZ}Fl0Ew)jG~#+Qu4y7c?G?o z{6`V(lXi3G3XWya)HAj!O`8gxc$gYgW^rx{^9zOc5g}{d*%R|)Z$G53iA(;I45!#u z?>i`dQsLpT4X!8dA6k3NvkL|lP;^RiLt-Yz?}x=N-1(*XD*5v=K-r%q}! z@UBxa^GW3IZoZT2s3WZ)sqkA|n4kah`Ll&~-`2qOhbz*$4`mY@k3W=gd**-pgpfeh z0^^31H181%(TRyb5IWS1S4P^kDr*vJM-0P{%8}&M>TqaXy^l#u3c8A^TXvP#|NK(!}O?2!( zw!Tufg3=5G<*r#>DrD8qy&4lbxel;TI6y&O9)WKQuM&$HcrR^AEfvo!EhQ_Gnnc*X zS6^<p zHhx6MM@|k*(%$HCZ}+}cGUMz~DVu3>vN%vZsN96Zd$9IhtVgF^;n8d|oHx+WC1GOx z1G+(zP0059ya(w!(h-@7yRdpBDZ;e8(K;cAW&5sO!@qxbeff2fY_c;o;=TJ=Rg=V~ zWG?rD*YB1PM#&sD<*CK~dW>!Og4c&8>!NQPB^~y+laKifD$f6kj5=Rr!oyoU z;52fu;G3o7M#Jwt1FvV^=PjP;&HMkh>(Pm%O_PpAKejorbK#POA8Qt$auqdEdtv|o z=Xqy-Ti{VdHTP@3o7VqYsqpoC=R4rKgj(QoY2bi;^TCAp>+#Q5a>vU6_q+cGt}g+0 z{Z5y6=6`kB@lQ*9>TTt`sI_J~Iy%4$QT6M8dVikoExhF40z*e&uN^p$^W$~=f6%Dt zt-D|O<-~zq&nv*?tiaafedYW0Jck~gzm}q1vth$G4_!glI*AuH7k>V}@P4+|Y!SY$ z3-6t7PWkp}=~HpBcm<{Yk8-j1-$$7&d-1A0ymQ6lu0A`?>$~$_^zmYm9s8gO_oM5i@_7Yg zBWfIfnMF&lNndpS#u+oEPx0^9e+#I#d9S#)f92ouw@0tMu62LveR}EnYQHZzzkQ;6 z9WOt9t9SkX&m+cMr(^%$6<<{sJ^AgrOW_B8b-uXg887td*W$Xkum9Wj+n4diUYK)L z?8-Ek=@WWoYGiiRUh`cUEHrUl`?`lQ&cG;N=Iy&=i5c^)IaR-=Y?%}N;G4tpdwwoU zF0I~jcWd~zSVirtPp)s7eP^A`%9vg1U#l*z{=4V(di&V69U-|ZH(iV9jhDXNmvcMd zR>8BQ#wp6|@$K*CmxX6dby>oF%~ZtvN^Si0l8v4V19#Zmx+B@LVt)1CZ|Cl^{fPbegHq#OD6yvsu}@uDH1L&6Sb;o6oapYs}^= za_dx;THO@a=C}WPyQr=@{rz?MuaAHKuT}saCc|KHz&e3}fq_o|*o}0!x=T>HyCp?Lx}>GMk(5>uX%LW-Qt9rlv-tkz z%$z%O=l%hA4l@oaFR=Hs*R$5Ao;OHQUJ@IV7!yGdY-y=y$_R4J_v#PEHTWO@GCe2w zbkj~s%Mn3vzF+-8iDkqgL68TC^s^_bZXegCTt)95p7L%j;<1nEyu-wNlu4&;pU(S< z?#+bu;Rt`BG6C%)%s1%|^3_7JoNY@+tgB1a?Q!kcP_-UCpcL(>pP^XXv<^N$QIc|a zk~XUEYT6+r$9gz7J?pN*DR*5A>o%>4Yk6}qw`5fPE|2_q9>i0w>suM562uJ{n=#N+hen73{WoW9wb#-;Ml5Ai! zAa~h%q6WTDBpyPjq@?7$v0GMH_`BM2wAt%4G%W0JV@hZ7pThI!0`5C=b&iV+jEoVa zd9DxIU8l)JyT_q)ox z)y2&DCijz3_t%FT)DsSMXFoHZwg%#gILy75r7?V5sPJsa$-{$xTuwnDjoVsVTbnrK zp;u|f)4=HU+4cw#_no(GFPj-SIhOGJ`1L`k?unY3+V=K# zJga_9b+z?a`NM|4UZmnmDFUv!<|lt!1AC%^gM&lvvDVkuYwPG#l1$JR>bH2?*x1O( zU{)qaM*b|*7h#F-wo%m=Ov-g#8~fzADDRM6%K2o7(`#e0E&%JEu+N3=@#nxm$!E{r zj&T2Fzz;q;IvV@$d{=C0YU-NAevpiej6?*vT zzTI$ndh+l5WVKAdW$i(OGxh1h{CtU4W$te`YDY&$AD>H`sd{tM6$VyT5qOSKl#&${ z6~bp4j*h$D=O@R<$68ui=E61gICt5)8Pe3_^jJ`lROWuGaw0yx?efeu2_j@`{piQ^ z58Ij+6k_CyLngK4=8JZ}Mp?b`N(Aw}*4-ILZTg&j(?qYyW8dR=U+`RTM}4O8JXfdN zW__ZTXVVbJfv!mz6FEck9P-PZ@DECX#I5oe559(p*yv2f*-iJVZ`tkMPv`jZ z^{Zd&Jli2fZ@d2Jayi+T(Qw=L{ul8&vFfP!oGpWsSA|WsHKFgMvv> zvG;P~;=4k-SJZy3ew-jedKh~zt&a1`$~JvbuFnMYu)A+4OHVUdrCN|5YA}i>Q<3I;SU9+ zUrPxCwZzi~|7`6lzCuTyYul-kHn#|CDJ}ZC=)*9FkMOoQn^dsQ1Z|f8K>1KgVPA1H z{7(Z(_v^p(`BAo6(BgA>;Tw+<@J$R^iXLjq`0m#}+q=$LEAD`GRJNMdc0^4b-5t-m zx%yclDhu&l-7m`{%0v0GERiRD_IhDG5!%Bx$L!_mX;J6VDnIGlHetUeQKj75Q}~@B z^E(E7b`KqGXpklDA!~>7n{DtD{;8Z;@6Vi_pdnqQaf#TEpRc4*vBq3S|ER!+MckC^ zWb~^yA2wUDl)8Oh=7hr3?-sLu_wOjaEyQQe?JGFQ+`>X?vrm1sp=FbkkXDqeQZB-0 z#L{sCnIf#0JK)K15^lIBL$*B;JDx+FchIx3toRQ>`1JTn2x|>II&OsB*fFT1)62Hr zCb@sVk<*L5<-uso@_6hxnY_^CoJmY@3nTKyC8K2i$kpFcmE7mWVO?5_VZp57Zu{Ld zdHk+`FMcL@$zE>f@BfKQOocg6I&_!D`Xz~6Mto=0WYi@6d<2tMSv$!%a(Kg80F&iMd_AYmrg~i%=}-};m63v}F_+*NOeFua(zZxT zOHycye5>%wlJwh*c+JxJp6WLdeiQzRM?`Ho+LKlpGaLH;GVJ$^7D_u&5i&Yq`u)Rc;4u2v+8+rdgI0oJ6=*mQI#&W%Kec%o~6zidm@va=pSE> z>%3p+N9jl7m#_QkJ#Qj()wa8_sgwNQLeZyP_9pX``S>(V6xkr6!V?O07hGG%m!@ZR z59?Mhb<1>TO7tZ}XfFCsE(!%M1_uXc(Ia$vs>^R{A)*2D0jaVPxl7nKBsymNG;n1GI~E8YKVGMTL}nt0ANWCeYs_P({!y79Xgw`MLb)DI+n zG)k1k>cuq4(QUMNbL^1pm_L5uk`?NXo%6I#&xwrP3nQ&xK}zanE<-21`#W#6-PgJg z)e%wudF-CRWJ|R(eg`r{Q8Cz>xh57vCOSGAhLfO>5FaT{Th^`LmzP84DrclP?Z10Z zzERvGj^|!rJVFp%GnX2omai=`PxA#Y>NkA6FCxf=v_IRus_?F`%qa5v<$G);vVAi8 zW%2UW+0Au4?i_37RQ!p0=T#zmj%*(pk;BuX=A#)vIjdzYrMh)H2Tc=1XhdXsuIax2 z=-rU5h+PqD!rGgdm@B`l8R_LUDo=6sE-C!HzWf#|3rqc}CFRl^c-}tWamS$tt%;(* zjC(Bf-=$Ei^6Edek}N+?hmmpL^@?TYfci zYKX*-U+nga_`i9RtxS(B)ehg|ZxTrvXXD5xQ)}B?S+U?<@)A*xvXAVh6;~JGVW!nXt>YG{^eiGUtZ@Q<5OrSuK9hLnGxaUuJN8d;X1u26ukKO z@#FjV?_agPBNKE}WFovS8t1LvY$NRc^}}@)i7;Zd5*DklO%aBO%MibtnmTjh^J>B+ zR1M}TgJ$mg(|%pwyFPZ1RwP&QOP-18u5(p|$|vtMN2|8Y1~-nmszh5^Sv`96=v!;6 zoSfWiqy2mht%$}ohqCT6cD*Oe`Sji~*J2)@JvKT#*vLh=ZM7?CDd<(EIi)zv$-;+@~rVbkrKtI+FQ>ROSyUV!vMo ze5ElfQA|`!6ci+y`%*baDp46z zD_yIuRjGci&(dCoXOZWvGs{xZU^Zv= ze-p+cWMbpyMkDa@vApX8pc@{Zlamu*$?6P|=3dXHve*7%>xUFvUKh^ygi$IZ;sy&0 zRm^WGk{x=5bpiQp$k zMM~eC+HF0Z?-y~lD#V;ETNU0p4phLQ9gg=fKCED_Mpe_jEIdEUi5)y@-hP0J@D9#( zT;!g1yU!y(X)F7YQIwwYCyL95hmNzru5@aw#y{K7vb?Cz{^-F+8eUs_m^yQCG_`B^ zZ?xwez0Bv@UAEH-4dZwbI&>sNiO|Hq*KOY|%*Xr|QuS7zB>u-_Lf2-zX`s<{r2pNh z*;C5&^nnElK}K@8?*2kIU6h^x;e)Awjq>3q?YixrpZSI;RJ`*9Y5%>LP&(+cTG%I? zWxCdn9-bt$Vix1-Zs0b!WvY-Wm%#R_KUFAAPxS@Ic0|sPlcOW#OKsxJ?++7*=sU}I zei11BNuzGh4Ij)nE}QZg70_Q$5T0%Q-1+-7BoIkY%eeGh-o+L18M?@=j%X=8?O5Ej z|N1m=1jY9x^JJ#^gizJ%d=%PHXXp5|al;1V3*@t{`(@Da-8%{&1X%7NqL?ce7Z?3k zyX=j>KTs^6`7VO_S$=;0^OOAvz%doZ-JcuktfqXnPTFbA;$mkQ6-biNIJc~iaLZKDn5kmf~I0p26`*t3Xjts~tH3jWg zXc*liW4?xT-;Co%;qEyl*=J)Idy#&dzN<7o@qnYGD_1 z*jGJ5UWlEUoh$A>BX6*g{~R#Sse0$`-rnBtb3PvehBVJINglNfdk2#Sv{U0^=Hor- zlsFCRB}N$rKd2DL?FuQWosWPmbdDyx`{MHa9nqf6h|dYs(mk#bB$Rgv(ZT zaP0V&6!~dgsxu3a`SR>6p!e;e{1itA7u$#XgZSrzTl3#0119lU@=s36<`;dI2Xhk4 zAA7r=)1}KC=S=8W@zikQU}NtmZe%5HZc6^^@9NTS@%BFM|>63)cq-cQ^+tK-%6IET;AW2RHGqv^Y8~B5nCx za8x_vZ8(yzE_^SdeRp@4M8KsupzZYdg|@@xu|=7W?3X1W6Nhi-r-!k)H8xWou;9Nd zdDF!*G=YnbSDJR-v9;aIc^>aQr*SRB8ep4n70rmXg94-{0B6 z#Kasd#ARk=v>dN6HbRj>{%pHJV}W`e4&x#1h)huysPW5 zH2_-nw{PE)IL*Hqs2Y4a+WOlHb#A<1c}JIJbaeDel=!Tk?($9e2nGpy2B2dJp3Ug%3J*I$hV$&@PBLtoqGH;Z)SrYU=7WmZS0$4s2=t zqr<~Z&Z~r#r*P?h*U=s7CL=C~N9hFwCT3>R=4t>aN=QnsE}u&hp{q;f3??KbFzeLN zDWvTm9OzY=V23QrvBanGJ6m){Q^W6lY4MAVmsGw?uL%hEaGnCi_3Qo-jn@tC(7fEE z2n`K|I@{aZBNz6R@`%=J_H+knibgJJ?Dy{q5^}_j_hadc2KIgWM9P~tZ<6BVIj@ea zp&dM=rOktD=fM5?D5~SjmvrOqI4krV=VyIBq91*I8&FKBsHljdnp)euL(B03 zNsa&DBNA>a#f<^|3L|L{0X0Jd)6G3*n!R4Vde!yxQDb8x;JPsnepWg0`_nep*Lw|ALjlEWRhs1F=CU{F zvhX~5lnJY{CZW~~`W~!WrxjMfH-B{8q(rYA)TJUm#|2q8H{NkF4wIf=1u9yhf%(P7 zy44oL!$lgMcUa<2XCp*#0P@9Vpy370fiT(NvaWo=g&>54getkRAQVNYhY?7oT}$&F zp#Aje6Ucm>y}i`E1MG=waOv*u?i(8$Yuu7pH?Aot^skPVfjWwU$PJB_zHoGP9Ze;F zhLl%ScwC(E4H+`WbQ-a1wTF|9;{aw!31Ko*yldYTghu>;4O_#rF?Tn#~#l6xdPfsfal#agoqXP=bmac@F zg1Wtp82~pN*4fc$?-fRax@RiB!g(jq0ZHZ&Z{SE8&qc>d(c6AKFqz-QG)p20yu((3Aj9D1@DitpS0 z^`!_@lHp^)r+fGANxEDWy@y{p@LN#x7iUp3o9!yV#jCCzQYcQjQ{{8ASl>q*dDI=bREkdo=q@pt%wK(Xb}z$ z?2gYEV)g2sq-kQR&4=EVG+2ZXGRr)F4nOqA8VKQ&(2!w26yHz@`}FCtJ4UX#HcR|# zH@9-K4-4;~Wx|e+%p}CY!70)xGjYYgx~;|D(|R(H2hdwSzWcAs;>ru%=FG_XRb3p zpKd<(G*>=_AN&-#3zweW-mvg+8q`*zlamubOXQqpw}tn;ze24Ryo-s62@Grp2jSVH zJC0NW0;jP3N_1+ud3Z)W1@Xn5mj~zJ`OBWuBS%m?pw4&5unohc%+AZ>;3y=(L={&8 zcw{I*C&%k~HOvD$ZS3sqK)@Ztl*my0-qvP4UJ)Sp)~;?cGBOg3Dodu*E~5%4UuOO0 zkD+L$Ztm{l5)w7m6Y9@@usq=UO8YWfCMPF{QKK|8B7#=(#_e=rD(&BZo>HlaRm*ZFq2Bz+tWfI%*|B=(9&Rv9KDP zmht!uY;4Hy-1)n)=KWUP}-nw(=$;uA| ziD)MQoBBPs6R$FR}po@5X;*y94DA4ZL{lhYWsw47OzUY*1IP@Y2K3q!-%goOJw z>RsLa{fCE#J}@@;{%vfK6A&0%SQI8A8#65ww{LIti(Jyx3IitPXJ@aFj36(*FtMYEAHVo!@F{_b zR##2UdHbKZrR6GMKQnf`;7l+s?KY>I&dxj+IzZ)wZ|vKM{sAs#i^o2Likc1;9v?4n z`R5-E{Lpbhh>uQ{2hjz9;HSYZ4W!Gp^Pfp}#^}|5n+~OplBlY_?pQ@HgROwn6D|iZF$A&%3PrTK*P* z6&o9iJcyDa7j*jxK$fsbR1v>zaktZG9!BKR@$n~uP=4SwezLa1Lqj^XHe`(0CD8o= zxjw|cbfTEveTpuSq2R%$C0E>Us$E94T%B z9_)vxsDT0%TDfpR12pk80oU-ldo5n4+yVj(fc}}d5pJ8wqX?0Um)>{h78jw%nhmr6 zsJ4e)4ht1C1#18uT4MLr6_MfRPYQLz!wk6EL0<$ZOuj|~mX3{&kMWO-i+lL+A(WC( zgJs+UX1|;F&ELnyszIS{PS!o`y4~z~yaO!=(BHtEg*YG|m?e~4heJa{<7ANlE2;5r zx{Kk3v;m(sWV}znz`~NsV@tl4a+e1fJ>UFv8I${Vq$`8&i9k-ho;aE z>b15#{JKJwbXA+>jK01T*h$Q758(quM}39qK_-(DZDTm;XTl#FcH!$S4mD|(sl*OGD% zVJaGT6FNM5aQg;2x~0RXw{PCOk&dB>%BuntRjgARUc!z6BE{^FFvA*9V1Yk&ZCra& zy$$>HvEh%%@cuiL5@2Wth*yP5phX}))`=z>95iA_nF0$S3l+8y0J?{mH%598&>yLT(g%Wy+$@GU*I zKN}kb>vX4UtaW-nHW5Rz0UeioZhjucSCgrxwzez_SC&%_9ToNQsx0E0m1SsWS5D(I z0*vv`pFb@ZCn2QfFuIM5vbE!P85tR|u(5#wv8rr;_{hV+&^0`)=Cvs9Oh)taJ25&s zIuB1R6z+2>JS5%x1or31z<@biqscq!iLo(&Ym*JG5#wGvb3sK#mazM|>{f7>mzSfe zloS;eB^N2rx7#UvDGH77C86%u^!bQ5z~R5`Dz&j*-=lMB^5%*zz07W!2> z@_wX#9v7KcRcku~+|`WfoDsnA@@N^wxRCo!_JUzPw#ghvqU+q++EqX#Eakj)?FwSy z<7YQ(Edag-UFTwdR6n*X4j>RrX*t6phK#EyfPp>;C{SkElR7TTgVgii{49(O3@SX2 z9V$4d;Td&e=wXwvy+m&MtF9F?0?cteJ+L;>0n%y66^A1FD2hq1QPX{}BrR6;hMk0%D$KL$) zFK=(&<>cPeV2EYWs(3r+jco1iVqst?svN|28nvA5Ja=;9ELcWEV24G7hmRP&7C2!C zIy*=xmchovRIE{^H`f7Z&!j)Kw^%LR20$=%r7Zzw8^lmz88Iw+z_;#jA+rbw4-Y2{ zde&3p@9)3EpkP5AD+AzNf-vcZFZ9YH*3*T>#eUe>P~vkK@!jWt11aDMX9 zFb8hiU^QOx@aelq%FfPCk&B}&wBVlzwjaF(GMVgH#6 zzw38~J#RT$`gj6n+g0~6e+Tykb6$~rcWrf5z;;@Y%Xns@)>a{b&98VB6@i|3r7l49 zVR&>Ttl4VpMpzYArA@jni_hND9mi~lJ**5DL34jNt|SLa3@8&o^uMp=W@nF0ObGDu z=I>_@E8?r^>B-9&V&1qmj~ZL8C@wB8DvD^C*#dY;N)*jeqytX-Veu4r8?$D)C|R9i zh9dB9#z&9D>c(L@_rVoI@Ft^6A+VYJs1@6sEI2b)HZfCIn4Xo@7El8OQC5VjVJluW z_6=A!y%z71jTrTzT3h`JufN|==YQj9o52Xl_WJhww+8@PV%~!Pq&}|Wf*S}xBXyN- zM=h=KOz{vv#S+12AX@=t3;-_NkidCz4W_HM#rOAjz+<9pfbn|_9U&1##)1owFMC)v zbTXLEt(DQmB_-0fd$4{*CHYxuslXHWmXs<4d@ek(nXJTz_Q21AzVJL805~(0IoUW5 zA0Ke?&aTSjo}M0$rL!r?z;8;xlpaD1BNzJv}mhr=MTkVH*^F+!t`&AiaM-KiuLfX_W$* zDS3GuzCpN0*mnlb(%B3NzESF{08bSaZ+CvZ%1r@EuXikui5bEbITLjOtWoSoYis^OQCenTL@*b zgGjJ2Ad{m!pCO^0`S~+13rqOg#nEg8aYCTu&Ybi-L6vs31!z4Cu@RrWPY+63S}vgl zci!>xI^Wvbf;iVdGt+EsH=zvvbf_O7pGLK??*Y0(YhMwd3~ap#3XS*~5KossUr_c_ zHl9vTPaB;AP)icr&l>|qtEEL$34+UHi;s_U+BVcVgzSuJLF|r-ielJw@CK9$th*D# z6EOol8WxqaPLbxs1B%7jAJSY#MpW*T^nhnLOmVah`0N?KI9Ud#V%=`ZRJIKat6Zql%D z@TVNO+5!1kE;L@oh-JJF3!`rE_V#9BVX+W01VI6IK*v8)z-S>sK}y#8#bOy_Rpu(7 zbT9Aa&{;r64+I(F`=epa+6lfbHvq&_Q&U?>X555yT1G|&75Y5_0?=NHHkTt?|1#-* zj+}f0553c%miQ-l6BQ+bi?J^NyZIcf5mj27ndNT;wba$sU2QAlCt;zXnORwCI=Ky* znFb*LLYdP_-nw-QIv)oxhmV$f%aAY35;Vc~!j%2uOkNqh4($|_@xC+>1q(c{0)8lV zJUp?DP^i;HsN)k0wco#g%O`V(t^H_gGfyYSXdM`c>XDL{msek{yr3=2&sQWz<8t3I zst(75@MemLkFZvT79GBXghZjsrxs8%fzUFJR$Bc`{|Z_t7e`K^JP-kJuP)#L#4%~H zo55H7(XWz+>**`^nZ&ggbMo>o4<>9mUa~BsENG@6hYQ-yNHxn0T{rmUtgQ)}_ zuxao=)<7>UDq6ia9_<399~pVu0R11-y+Rw0#&iYhW=^Rjbjh~uiNKY5{S-Td5l7vlyf z#ymV4b;^Q>6jk&+R=tnHUMGMxA$JO{9NdEyY5@*RUZ5=5+n`-u$%D`@S2Tm$$Ho%6 z=coUJfqP3)5fKqdM5}B5ES>stj_nvVuS&;02>4IQURAsQMQ;G0wf2`|yE9yH2#CKE>Sc?d~a08CII{m{UI+Wz6{izL%4bf*z$+YgC4y1Soqi0Fa2vkhSt_6hh;A~36BGefK*>Oq(H{iPPs1Az)^w<8H79xPzN51Ul=+#7LfY?f5btzPPN4da2dO7KA<2o z;kIkmXC|j4=_m*jt+vD7^oyk(cK5G+aJB)HiB>1>BXg9IG~Bmi)8f4$mg#!ukYm41 z^*<(bTsM5FW~o^0bX2SD?Cs6hr|OqK25 z1lLI1@zz#KC^EH6p6;%$YuB%D&a^0mbHbEnXWuDGSx(+{?W>&Xhs|?$_wKCoZ0GjL z{60xMH=1wln_5;`Jtwy*ziYwmvuf@dbyfD};}tm}At9nHM_U)yk#|$K_O(}{Y8m)- zsl1p`5lU9d$fwJ(%HY@jNyg!%E-M&1O#7{9kFB;>cjR(5>0Aey56E*e_F^{>L!MJL zm6NT2VRq_Cc%;g4@y>pK8H(t~M>P@dJeZu0-X`9vd2g8F&jlXn(3xp z`tkmPl@~r2w@J_aD5+<;QJ_Q%J$hsS5R&0idgI?eXoL?c@I;-QuF7A!nu*JN^0PgV z=Y)(=z^BmSVFOwS%?6h0HOW+z`T2c?MltM^33?N_!_i)3q@?P_ni+*_$?@?#fR^Sh z7@!To%+{YMd;?*&$B(z6{{p1x@{Ho!{MxwiZ-M2{PVRg%=PW03yDMNeEu5!>J;!f) z$XsDm??uD(hJ{@pf)u~jnTYUly_CLucrLOjB1ZeFJCHeX@oh8~b!TgIqJP|7W^=w2 zl31Pn3QRgP@20v}rcaT`_>R@R^E~cy+yrA%VaZF9bDowa6k>>sYRgy5ZSfIRvM00~ zB-e58=Z;)QvTP*8(L;=EjWgY%lyE7ZP(JBAjt)&@M?{yHocPzCZPPt5^lOx2sb`KR z=)`{%(EBpkWIs8vgfk|-%RE?k$(t=AnRcUZ=r0f^=*+yQ-w5^tH0ia;I!D-GK*rq8j_j3`qCQggKkl&iS(itd z*Ic=8OTfC=5!gh$pg4yhXffD7$S6iZIF;}x_S!ga|K9#gkI83xv93`Sht%$(RqM}# zKN!3oCHo1B3l)~e`!vH@N58s>SRtVKB&F%{7aGmWgPUup!R!G`xl(#e@%Os@uo4|P zP(*7JZDRc8=pe>}pEhV)bh$9fgDARGL%2#y`I5>#k(Bq3XP4H`rKzV0N<3Mat>P7r z66y4eeofKwJc_TYSY<5~u^KJ^5k?a7Ec1Kjvloe_UWrYqvI_aPWxhwt9}1v|CK?kF z$Y_mg54YLV;fuSwxn<|%L@g%6=bvd>}?< zqQekd=)$&j305clprM7eb(7UNyEEsehMF2Q$cSHr1egJjA3p};M71+{rs=gS*h*a? zGGP=V-hfQ?R|JKOfy{vH2T_9OR#t1EA%d-4Ah<<>Ok+-C&VQ3I4s$ZDUr(wg;WNoT zwsC|^N$$kILqbw=bPKP`PcO_Y`KF`Y!_uQf^_cFpg&2vmizi;2i>!Na7je>A;vS!Q zJ6Q0VC++u_|IfVYunoumYhE?^!%{BY0LLBtP5rD<<+8RELej4d2V;;s7?M<&V5#6@ z+<{%;6ri9^=c}-PADR2YOmnTI9C0Q`FTiP{NyCN zeOolQwZ?YF8_LV#d^l5)4$fwL|CRN}ju*^Nc1}*!ndJ{K0m16HM@Y!t0OqBN9<`X7 zSrUX|s4e9c@d*eCa|`!zS#&?&CM1*~to&!k3%NB#J^SPCr&otYPGX^e^_ot$om&BY zT^(%cD6R;mXbn`ULUi)K#rnZ08xPo^0DeZZOb zXjdz9-gl|_*AkNE>MlR9d2!Gm&(V3~l&6kju4oboMdwEaYwmkF6dHPA(>C7qW7r)v6$*~@Ljl1r?TA*lt zM>&^(?IEK4+p2s#P(uVsfcvp^PF`K9K8es{nZ@~0FE^uL=w)%LdaRFyiFp;I0nq}O z4xMYVxrmTZ6BIa{n&D_rE^q=&Sx`_=DD)g8xY)ewCHgITQ)+gxch6ww412I-Ha2MD+%r#@gE@X<|@(A)f&DHW%Bv0}#BH^8=E~DPU`` zI7N*)LX?!VffU{kESVwJ#y~@pdoV@eP$$UF9$lP>fq>n11zpci^nV$uySN;{DH%{{ z_M)8mVDR!gulxcB3+&toU5>SBpIbuMFG@eF3QUb6=&#HJy54rp{q1~!o=V+c9`Z`f zB9`j;w}ILF9?hF8Svh-HE%$n41wtMZ5=1bX5xwxvn{;TTZgcnfyYO}%e}nl364Ojm zaV=4-n65$Dg!_A_>G4Ib`gZ;!V^vH#U(+^@H6zVfb?V;edS{2^+d{xC|AOY(Wl8dr zGbJhM$~lMp&E$_C64h7(`9WYKCnrw;LQTBM3@6W^*sqwD+SsQO(1)$9<Y z345tFiR**h49A81f*KYrMN9|)AeX!3Ifpl!$!8v!2$K@GAX zwN+JT9TBu6n(axKTCpHh-kp~DOtP(BIR#FDPLfsnciX!n0&8PiJ7SN!mTk%P>v ztJ1^u??Q1G{iFs4vOw9Jyk?`EsHk;ZtQ^h!cgf*aLt}#-Be{BZxC|=lR z!1k%pehOmV2oT!4czB>wsd=-i*MTO=$IpKyU>RiUh`6oB-k@Shgp-bgp01Gi zJxAz}qVnry*O2~o*)MC|IGrqliWmrC7SjrAN&oO7W-kO$ zzaAH)BdOT^#~(N(BMg7F=D*bN%hXkJDd}F$5; zZ;K6z9VDfvP7kdoMiD*OSpx`+ynNjE%_W0*)R)oeHX)h%Nvd4|ES1;kdMyw^ydWwe zp%?B1Cm%n41i=P!Fh76)*4`y}C>)ZKk`fejbNO*^R~Hyr2U}Z;Y61-6N)Q`_1gxox zii(Pmpy02=mlj4w&n$ewdxRP*Sbl~m>gqOvG@si>g1}fT-MK6UeJ&MzpEVYpn&N|@ z5Dc?*%`y1I!NC#R5^)POfz9UA@XiK^)twa= zZfd(-DvhJ(?X#g&7N6<4{~qH^_p|M`^(ds5jK7Z5v(&4x7BP^kN$qBTLGhPIWA)Ty zo1grM!@FF!jDl#SF**?vZm`}!eQy)IB3B&W^r&IU><*$SUtV?7EuJ{c<37O}i{g8H z7Rno z0-#gaW3OXmL_Im}-3wh^1_p)>vSau%#3xEiOA9@G?%s_V98|6l_44qjhvZLEE)|@s zO%e7=T4rHpVj^WXdVjLhb;UlKeq4<)f<)DMAf=GAde{Ic^a27P7RRYq$`FTX_)aki zYz#1QR+fGZd-wnezsgtz2mgi{2x6#6ale(ZF_+ucA0Ya0RC1uVw**b$__ycfG4Y=V zO#er&7K>~K*EBM|vm0XVNY2w`xLrtWBUjGAamU&ktcH9S1R#-^C!Eo@t)X+4Sye&ng(d~gFC3bpvjC|M#0TZ!)A$b`LhnC*!!$%lN?N>=*nUGL)*Vm(e`f(& z-;V=SQd0?Wm6q;wo$=DpI<~3lgoT14Rz12pKM_MC_vl`9L&Iy}1GhPn9i<%3G0mtTCL42ou%x)^1PJOf6dokJ6g3HlA~43zdV{kiC1Exj!`Mi)=0lP)~QPhq- zP9Qw@G%!ic|Jn^fR+e5RH*#QVWMl+-6XW8<9TvB(pUmARn?GOWU9D*njfRl}}ryUsf0--PND_?%g|ZRaJ+4E%K=fznaEbX$_ zqC*{k3BXo`*6GAwZxw1n2nQY-_(Ct%_1D+e0qH_ON!ixcmV_j^ek>+T7?tLwDx+9N zIounRAVEkQFyZVcIS`l;7QTQ?4oDSneWTF=?;${!*5C5_kfk#D!v`Y^iluuoA z=?ayyB%p>&TtKNDfWP!7VebT)CDDXHROCJwmudmF7l3GD1}v^r+`siL5D4kQZUaFQ zl3RtnM{}^1&i95CjHvE`If09-v7VPf13eCWD=;XpT!ZQnFrg>lLBNK9Jv0S2Hy!?k zzU`alTVTwo(m(_qa*0=u-=z_X4|=NldZl*Q04Et9p2POPhFIFqx;C=1vhc9fb{72n z{HXknPfl30tE8xHi;62M2HV>M-NUPDYJ?%%Svajl6LUq~jOebUGt6$9z<2M!(n=j4 z85){^u#Z35u;sZ=y~TKZ|04K2&PzX^p!yYJ%MD!xB_NjucL}G(IXEgIL3*$`Gc$Q6 z63mvxNxjCFXTqe5C{(Xf;|42b5Yr0`U$x#=Vfd8*8xpJ`+6~rhQQ=gk_NXnhsf7@{ z3J%#*onqd217UdZXhyhYs-wE+A!9pTYfC{CSk^N>?hYY3$e$F2VEJZhe+&1@Hh_@> zp)tKr1_2K1R1kPb6}-A5m?P18qBR&d-asf~MU{Zr(7vLT#4!WjgqkRq zKvq3!{gSj%<$6z-myzqQe5Jy!W_XeV0|Q2`Uwl!jJDZ_1s`NF3Ys}8BY*|^R$pq7H z2`nFtQe7?PQwLsBR@O3rUEr)kgU71e9KCs$O<5>7)8k;x{m&Oau(ucv4IzNj{{6db zB71<~mrregIXF2#+`9c-ULI;nUE1;|h-{s`dtjq8=-<49e2C}qhKz&E^e!AoFxoH& zngy|x(&$=97GuKO#8CDF8-RwTHtYIaMn>7joe(ns#;4M;K|h0%o?bJsP3Sk?pVRXc z=|~?Ne20I)(H=GS3uO2OF9uctR(!WJyf?u9J~KVN(#5g9s;UzZ8>q%wtMTZzS2WN} z!C1+D%EHGtJ~&tr=ctVG1=607A@0HV*j)(gYM)O^N{Tl2fRsb}6Mu`#)T{L(-~B+Z z0$oz?^zeo+MDeeVKK9fAnXR>X5q8Q8km~&Wyz`eMdBi<3vXa8S*8~uezd}WJc2^Zx z$W^4Nr6rfdNl!VxqetO^vDTF|iA|Z@NLh{^#h6D1UkfR;|v$$q~7l zJImJ>sc0}8c%-jClhiZ}R-0*WlK99J*b@M-LDj6rRSp2CfkVn`cXqUm8)6QjjZk8) zLfHMzwQO9<=vHqa$_300030}IigimbK@x&=ZLwD6;Lwm(P;h4cRbT!)4xAarZg%0* zu*a0zof|OBEsoz&C~u&ZdcD4Yr_*r&ez;n+7qrJB-PWrtA#}EqahR->stcQCWO&%P24b?}+SzL2bwQuwZ1t3t#b^kx ze~Enf)MD4>R<5~U&q;MnjUF7q?UitTT*MSv`)}I~=Fo4Bl|tBFpj^nVl#KkDgi#0& z-v$im0LGV@thbZvkmr3RCImOk8ClrjCx>23xfa z0dvAZ0_p|^9}IOprB87;kHEQAF8DAGTcI{FQLE(9b;K9mUL&$pA1ClGIOb(#`u>OX zOiX)lu!f+qPS-|C>U~_#AwkeHU_w_m0bEd_&_3k8udKyalzfBSkha0n)z!VSQXm#E zKhg)5KFpj_o!U}u_XpTZzY1b@{_#OKe+^BGd1e=80WI!VFujIPS}Y5I3CtCoL*a6H z8^w1T!ClZcFu0%f_ViF$K1KNg2@K1)K=1**PnK!fId37b^}yWMJ;kt;W+L1KAT(C~ z3aD6NoCgfH3XpQPw(Ll!L$BuAcN~^@0cc;q95fhf!4UieM)|1lrB^8cq?nt`kaq)4 z%=vmG6d1OH;p_FZ!dQD=(m_mSydXG_VR0Y~W&mY>JT%2>1rm@Ipv~;j@Cpb(N+bhq zQ$3sP#Ug$A|NxDO{H7pm+MP^ybn4-Z!FSmm?FR5O;MGhfR_wO(TR<5jT zqHOkgBdyu?Rk+J2>v`^7;t9xp-IRd18!GDX%Q+=Awc)G0fmT7f8Ve*n(iDg`Rcjd6$KE90Z${rMf#h@}WSgZ_)Gd9gph!P&WXq ztgWm(o#cU`1F`=uf@TPb7e?3haUDQ=1|*A)hNf<5ZU%=D;Vo%0Gc#2ijM)DR5omuM z8*_sV{`c?SE`MKm5Z-6o?QpqKN@6Pqy*x8?Jc(BsfVddXceoVtn1(MJ-5$gIQ{Sdn z^1fE8bxqj*-;Hrdo7yqcc0yzgHfW;kk2M&9HE3Efxyv0LQtZB1h(rW=$)r%(D;Q6p z3Z?QnnpFQ@fcXI#2iR{AGNRV`l);L?eiMh|^{~fE&ggo6(WSB*V-^TxTqT^~EsL-# zOBCtA!Ff{1I_wKkBRC%A&NJ`PU2SA@aXBWi>qb{A5}xMX!xsAZzR^r%K#ECXzW|1~gM_P6H-4 zTTjR}BmsB}BtU=jJ^q`YpO1lwnIz)lt*VN@{W&^%5Y`@up5L30+w15z*)lC3Qd2|v zl}2A*-@qjgf=$2`-vtCzi-^^#vE7-+Fj-v`snCZ3XoPlh&GS4rcQACvYkcT&=@d@lufXz-or0 z*#J{9w|8l%sX>4O;KKL%^=Vpc1NK0xCpAMGc&o}$0U2H z*H%~mtlB&h9xVL;`xd;dLF0tQ77ve`Fz-o4^NI(VbqkPCDV!c283`>L&Y9*z=|>MA zj*IBFBqIk&idw$Ddi3_~uWshcO-%e@cR}p(KJ^+#4*eOR_x#@y zWeX1a&xZ`MRtbc4&{>^0bqcD<#cIj%Tib>Xp9nl3TQZqv`64OY@g$H4v7}2 z12F+%LQ|c?9GYl~VtQRj1e5GjT_x;;9vQkj`XxZIU9Zj=8dO&fh*c3vR zvYk16#0W;OK9-g}%8njBjDZ*&Z+YI9_OM~!7z#}0$dB%wK|hQvfeIjasF8edPhmr= z`Z>HKCc@1MzB*;V)SWg2i~LLHRuvW%F&5}u3+aAA&5=IS_R11HACxe$&7GwhcTdm4 z)>d`Hm+I>7$L}|jEefucl$P2-psDF@m$jwGn)vhchPYk1i9+xOW>K)YZiV)dr7>6D zKGiKgDXAbwc%6xj6{*uVlFT^{sz|SzQcb<|YZUj^=u?8xRwztKVU>w5yg!3{wJEEg zDjok9lk?H_L+0X}{q3O1cm+Wu_YAU_J8fE*w3O@DB{H-O4b{>DM;6G4gsOwdkOQOU zi8SF#s;YU_;o0NIjk80q%lcGxAI+$Kvd^Cu0)f5428sBECgNc= zRs~mS#3_U5HTkUo8a()-Fj(DY$A3nO()IlKfg&Daua9y$$yYl2pI>}oRa0@g$vocp;-}|5uMhD zO&)XN8Pmh;I+~_ct5yZ7%(SowJFfPPfbt{8)^Bsv51SFz_VyJ>EKFKd9=W}Mo0XoFWE?VH&PYWoJJ@|T z6Bj6IRu(JUf0RssrPBN*KYj4J8Rj<2mMJuE0-}h1;Mjfi3u<&iM?)*il$V!RGAUWV zyWX+9z~XBnk*V4D$|Rda=KSwAdw3MQe5ughBrq6_cByTl6NjcVqSQiS@UUU)LDT6L z2CLVW-|b|t35;0T&C@h?sR&EbyWf6Nmp^uUH=RxJVBmc z5^QqZLMQR!l9emxT4W7Tqs;c`U2>_r!T9mL_oaeb7pPvP^WXiId0}rp>ZrCGEG=k9 z64V!8X!=&mxAR?8nb1CV-<)ld@M>edn5E_O7g^)Q?+p+ZL^j0iBv=zPm=hK{hV+fo zX3l)nbHon6X$h}Bl$P4F{8{(6jZwVZ0YG;nx^b4uUX%2X2vKZg;+785)O08*D_b$K z_%Hb&IXEsVN>w&+{ZaU%y?XVk8J&QA-^K0|Zrat+sycg`}d=3(~W-k(SxeMFMYPwVUOy~lhj^-=TuDFy?_667PafG$On#`{(Fnwc^OR6 z&=74uw|OE+B&ifd5Qs%XEVD{JCfDDQ+Ebw+HlsztY4vJU2Q$4k!l`4_q?>^mm1ixB?Cf^JM^8K8H#z)X9VOrUN!ltaWJMJbqnc^e^(wc}5Z_M)_p_vlE_npaE?s`r7HfJ*KRI9EJZ|gOt?zDctdblZIm6i1%`NV2KH<7;gl$(7 zV=C8aE4tQa}qS? z-sq+t7fTnOGbV=2w>YjhP)lpi@d=$wRp|pYJJiw@DITG}-4l8IcJz#T&QTp*rW5hR44;ijyV@sumAok^(70OldsAnJkE3!vo6c)N z0b<`G7;Pa>3iV{kBkK7*yNVZ17k>XbmH(mPHI;w={B&VcGL%1%`2bXeXVbXF%IZak z;^6lN_j5xO9saUEek?tsxFlOw`w@-DcnhO-j*g~@H%4fX1I=81gJ#4wPx6KEg+8EX z7Fl7VmzV4J54M3193lS`73K1DUDmDZ&mvHvUf8Pec#o{w=4UA+=9# zT_N?qnq+L;f{TO)q@@8fDd`!@#0~bC+;@_v*0@ie6Hft6r;d-6S{5fJB6BNk*HPJf zZ~Hbrm}T>!q+(a+quLQqa-H6bH?@3Sczm@5JNUuA-T`*63ks6ZaH#m0pDAqr_iu9A zC3iG^{O)MXlIE(jL8v-xGd#7IwGGM?;`kJ0*&O9jD{f&YaMRc+rI@#b&YvG10rr)TbuXSC|fdEs2SVCAl!30rS)UaI6;uCn7jam-ZTy(Gw;Z zZLK?1@E}?)I7VE-K6jM=-n|d04R|mz2bt7)Fm}BEdXb;K%8Zt7Py_ppet%;zIywjS z%XI4qNj{!8u@h^SY9K>7l&u-q9s@Ub+4AK*M)fhfJABwMB7nVfBm)6p^O@Q{m=D=x zdJQcs-)9;JS_cOgfuz@CUAf=^lKl2-0f~vVqzc?*K8CZ?CQh1U;-k>h&Fx3$zk1&! zRVeV@HhLjugZ3)PERUkf7E9YE(MC_0G==V2zsFzxNaR`Ftn8&UELepJekH@Q85``eZe(xgD81P^aYyTj z(P!6FzxA*5Uc7wyZJ-r;`uo8;qU^J?BM=r{qQvfKlouAg!oAnAJh!_>h1a^!FA#WX zj%KpYg!XX6%QEW=i!NbMQ7e$v=FXX=PQq@n!eZ1H?VOyVMy9sn?TgfR6&94|!7|m> zAsm2+xOqb$boTzF;22j9*OUUtqG58H8H8ihTvlNN6#MicGJx(+nWOuA6|5lw2d`80 zUNc_*SSi<(e_9lO8*$n5=*h>d60j;@aynW?7GgH>4s=Z?BBWDLc-l=H2t%o`aK5#* zzLu7R(E>X==-RiKZ^fB^>N#L4G1bt(pr0svO$y2#ST_S>mwR!n=6xfzvx;SJviQjk zDtnEBq@1Iv_c+a^7GRWbtd0v#vAJZd3c07!%>YHhdu(mzH&J2^hoDuMd6 z>ZE_d*LOEu`dG|+tpj&DC8ZgT_(s(xj{TYVc!_bp4=`GsbFQ*qb8Ych<d>VY^&!}^9J94UH4AmroQ47bpySsKcoKJRK6bq znGNt7KR$JgitK-XT->8a4+M<77~zV&YTvSz*{^xRD~glGZabAjtG|8gCnu+27pKm* zGZ_a1xs}Db(i%w*>J54c8$Gwmk0u$`$Q;?Z3UX|QA=zp@yX7RYNV&OY?Td9HhCc2& zk_@e5Jw>nzyxdEIvMlh|eLYubXnIT1JSZk~;R(N&VA!{;`X`2MA zFX+pprS0R7#>i~fTR(i3Ul!ciL0Dn^XP?~LO*gNLDErt8@?e8hpy_<7?B55jUUk3x z`B7bHVBmB_<`gw|L|3j{S$=odZQ4lC(>*HBA5tcX~@)M$d+q<~PC~h?L zZZMV-+iNlry3zIPhws_rGcDb34{@mLFU32|w1Mo(tmn@kc>bAdB*p?%^*L7|(SU1} z=>P3JeEc{Zsu`6FR!p0g^Y-nMY17V3$=Nb$qS_1U^OR1RgP}Wurkz{x02-IlKByfS z+o1CJ-7_f1Kfl^;WS?JqUBEV+o$XVKc|aUQw;QDz!q&u%=HsQy;E30+E0ouxl4Vpd zl>IttR3}9X`1pzyr!}rBy6R8n2~L^PU)^EM37R#52G0XR3-UhW=GXN&?Re0AQ)A`m zZYJ-eJ%LS->!&S7+NZ87g9BGK1zOYb(W@l3?HoOR{AxXwo1?2}nV_Y}N}jPy*KyZA z5*ay0C5$0}w^@U1@6DSxH&jW8Y_2n=hkxP(Oog?TFVa0IH8~U{DZUy+k3^Zu2OK(dcET%dEv*`_ zOp*lT`;Jk|?sj+|5_LMQFMGSlFi|9$cVy`GR~^06zNNoDI{&ChG=KB_y;IKAc*|Fa zi~QOhw^>xiT)FY^>BGu}4@4qk@h0=?yqvu6o4$#Oo<=^++`akZymQCQi^sSYbepxz z+4v^>F}VWNex~BV@<4!WW}UIF6-A5 z9c#aSE&jIHd;f}CTGJ?uKt4l$N_X`i(#$@mde_%iu6Iixyr4w`1S>HQSiEbv*#XCuB-rDzGVR+xYZRW}n38@%QU@ z)qhKi=6TJ}&DE118lGZzV0``*{fdU@v$t?-y#`lUJM*xN|B-_70Kh7A#3**T_UQMA`E2N>saE;8$< zdC{tqlqfA5Ru3tvNc*D|G3%_bFiWpXbavSr6f`&5;OKGx%i0`Gd&{#V_|(OIAw#e7 zyup@ZGw^npWn7{W`aqCT3B04QyPB^lKpc*0$>wyRQi}8WgHa2|GQ@TucCZXG(DC|t zblGCEFEo^@Kj!e^CQ7X%M~xMaR;LwU@@riTY3jNW`H>LRORI9Be@ZLgWLhMfAIAcz}oSMSK~>bT7D zpTggeS^Jzu=CyBc87?wjxBu|=SObw?PUWrdomcg5D~k$#ZCp9j{9@CN>Y=N+I-_W6 z(XI`D94b{r8hMj0Yn&B{VrvpF$R`%IT^XIca!|(;{jf1d#vPLoEi$~?X8%u2Wc>PE z>yDCMXB_&5j@@UaEG9alKjdP!3tdEHDnanb?ju#vayM4ZG)Z(Ib1{X|f%A6$Jp1;; z#?`07!;_h>-8`!(FVAd8K7Q9q02V?|;})VT=}+Rx!10^EEiw$2%1NSyOM4>iL!F+T zZG7uTUEK@EWcx#}sgt|P_UzuHN1*>Lemo{l6=Q!8Hz2{K6tAsY z2fKUVM)UX2pR}PK88YDfAOfdbqV=nH2;Cx_DaIju1>IV>Fd{tstE{C@yA-Uz7{246p1$aY&_$w*&fkDbYbU;-@9^+$`yAfNIsbs@qN>G zF-h5#Dsy`NPAKY?aI)DwJL`SwGLdolOrOxXz54_T%k|;t>$J|OLqqbkFKgTsmiz4E zq_t7KND{hd?Zc0&RvKF^0wgNTyr>9RS z>%fzV^j@LfKu0gJG+@c1MHD+SdlPFvWWCMJJ$o+V@}*14BkiPykLsarIFZ5C&2#T) zgLeA(gmml%J;V5mXKNbP`s(7fYn=?{smCBr5(WoXOdYv@#;ez_0i4pQaaip0=hp;% zs#iKRvg7Zo-6kw+MUm%WNuAd_FNlc_t$xzuTn{bz!w#tfpSKuA=G68m{yn)_Oys1K z5qDNh6kB^S@$=u9MZSv*7e7&c;@4b1N#UQC?5ZB4lYNbfPpyA3Ib!RL0WN%hU(abv zyM$Pb2^)R3htlJDOINNG1g|s(ToM4I+PW&1t{QsJdO^YGDr?@nWi>li;1$}~95an$ z>^H5!ZP6(jXY!|L0}H?mJ9F{hopyGoLPKTBupcTe`ovF z3$6?1e|Q@8J!oOx?0%;fMcD1$svV{s=D2@W{4Jx!D-G{_`rWBG!*oytf2AeaFx7I& zgGJiC%q7czZCjjv;gYMhyyJV)&*aII2M!d>1UQxLGODxY%sCkqW&1xCe(1~*Bn(_B z?`=*xe%!|1-aabcg+m1)BKGx0@(TuY6~42nhQR(eejFU}ggRBZ{TiPt)$xJ!Ew|OH zf3`KQy5)x81LBSKsB4Ldj5~DfI@E!A=UV=Sd&1o9UL8=|p5XVFu3h`p+^nf{{A{5! zn81f~XEl!H!5PI0jCN-S6AS?UPOM?Bv$^Qwc|q1We0agJ?T>5D-!=LW?VhCed-@^0 z@YvS4H@7;!r=NAcR4y-GciqzHpGfrCRi|A%ST)#OWx}ew_#W}| ze_pt8vGd&{r?uVtF2(V1+pOPOymIPvfF?w(_cX~- zbp6YXULJek2od`s+dVfowcpV^dp+LrS~8lGQxVvPwa;PSK_6OvC1mZk&R!na-v4*8 zdvVh6NsC@;JoVFRipk$<>G?d%zy9XW&h}#tixSIAb`?$Sd@?iNtwJYiaLS6#sGU}; z()Y#>uOI1pdSzLkYon6P(_?@6lpg!C>`uZj(RFYtlhnL+6LxTQ|aIF?VM}#cEjC&X-qLXj-l1(qgB9n9A0S} zVFWDe5lAuI_PPj1~^w()z0(zboM#v$ZPk!ZZ{_|+3ud-pu{+){t;ng_`uk!SO#efdgV zL|Q?!`kD1T^tf}E$0i@oP5ONE*+;XNOkXno$as6la`U+xbD|sTC=_TXQF$}Euzjzt8S!Mznl))@Y2J>XUL4=+AvD^^ zSPPEsed5HyF5SFx@gnRty1LT*hb9-ys-wlz0J^ z<;~UQC0(Pt(BlC8@O1ys=yp_J@i>+PeXVD|akFTGvVupRUEA5=wVKj>=S^4lrbA9| zRFy@>_50L61a!Qp>7NyBsi58Wwtm3C9~rirHg!A`6X|^!vpN6U`R5kHg_}&~H7{J) z+V*9~f`4fSPsW9mWS<+dAS@y*PczTx`ELnP?1`7;*UEB5_bC&ejJs%%+)q^ScgBX< zW1pCv$=!Qc(n5CZz6lBwYI1i@qq!7p^#&L*t9Ku|A&bz;A%!Nw)7}+tD;>^XaGG;w zcGK2Ahh?Vp>C>;!vJM+2y@Au&H*?O7Tr_ap6cdmx;N-E*ba}hMZSzf3RaKq4YzW~< zQvKz0_MDnmUQ|@Xp3nIi12Di$x9bU2VQs%UidP7|%N zCme_{7VS&<-x@_^{-m0oDE-u4kzb>9R^9!rmc7vjZZQbs6g~v26>8n?! zpVe%Yz0s34?H%m%l3P!;1bw1wO`TII# z)}jq#P6%vH;QKA|KUb#|V}>gbjEs%50f`naSa9;^<-zxm(2QwAxhp+gRan&I1B+I9ANKNO2 zfqw6~U(WYAKe%wExJZKs(i#_OH$+TrUhn1Sl57TUH6PhwG3@TF73=;PJya8(#n=a@ zhFMjo%sCM+Xcjst^$oEXk|=9nx{gt>}{yt*$q_yWVw+-K^n33&!9KdUrlZ7<)TF@u;S!jaQ^&`o4KXU;G^y#n05vgHkWK?3X3XDcF3U*Ap;Sae0* zXKYY}k9fjxTNBgLWQrRq%k}HlZGNS4+qe<&-Q&~n!}VC$+kOlMMy(cSH6E+*bk6Zx6>hMYXx&v2igez1;d=aS3oU%7n0 zThv8lc654%+Q^RJVdqEcod0)i?wVE8HHV+>D$a=BBELJvu6VKzYG-E8TEf2Dcx-qk}VTeQiY#-{Cl+jkvi(Kk9kw&!5_R zRmp{*>6aJ3O|l}%3G=H#gDRO+=oX(CEjxDfXvQs{(B1*N`Zmb=%GUh)@TpePP-p>F`FCV_Izvv>4ANVO)x%=7!C(cZjCa;+E!Es3hoDKH#MVP& zQxr!MB+B9K%a@035-tn{VS)%4SoWAAeS`j2ozMpWbpvIcIf9g^p?;xF;HNnF@^5l9 z`DMk(Jm!wLu-L|?4cgF5Gc%{PYbWdw2*R`+=gw90u6O-u?H0fGRkdL+`MVRn4192F zfF9URY85J!oE!(U9zE69CL$sLXQB-6tax{nsXnxudwas6%R!kwHF>N1Ce))t zxj6wtNb>mgxHt#%!Qky`(hY#CU6t%l2l(uK_-Gr;w`e6`S>zleuH2BjLk^lO(Iy_-}3rQOk_8GmMvp0+(7(ZW)P8A zZFOQy*SW*-6NNvm8SJdPEHzlg)2F6j;M9K4sy#8F_(KbP>w9(ec+7pyCp>uch``iu z3x+HbBMMPg-oz}ea@ZzVcl0Ah6H9~hs%etp0Zzu(5-7WP6Ge&rh7H{A_V}t=a9B+^ zlVq=6P0h`W3g38{$O>kOc#A}lPrx~Lg&D11zC4;n#p08hP6R%zw$CR$Sop&pcI!@0 zTfCz_4y9Vb?l)l3^mh2VM8*dFK+}w^_3AMyj`7!lPV8=ZCtn=*rl@FyO_Bydq#p6a z!@Ru9uh)r0)K1sw+a2RC2(uY1vD(73B$;=^gTr@V{m@=vpzpLll=xXYo@<-^I+ykE z>cCy&X#oURBGkp0I(_~AU2$clX9m9ETWKP_ya*gaW9B^U9|*`wEVtXjm44WTuVEy6 zmlkL}-Zn`xW0#GS8GW~k)bidShppX^U$L>HecQX!a3WJ=ULkOu_H*@^6R5}nN)4t= z@qrU*_H%i%;{yUwV@}ZoZS4n`a-y&y@vggc2W$q5G=q(mx%6Z(AVZ7#G%A`5w>L}w z#NOq>t+#e3*}*TE0892o+7_;TgKI3SynBJQwZQy`$rxj9GvbZF-g+Z5HMD{q*j-Vl z!j0|8Vs87(MojUIT@NC@0#L1aF?a9Wp&|;mosB$C;$`vK}r#> z8%;ld5|HZX+`0~x9XyWl01vsLj>JKC^n6CRDWlY69fiWUliehD$0Z~LrBfX*d;YhV zNF%bSdgVCrKdZWkAYHy+;(uuq;A ztgVj!vzaktZ%xo^1y0m5*c4t~3cY*({Phc!sq0VExR0J0bXGKubfv;*F0njpnoh)( z#KhLR4?Ea63_4;|+V&Wy3S-~&pc!Wf=)Va0oWp(lIxl8HXjj6$6qf-$CmYi1;RkA- z$dSvXv*hLFAz!zzH81V{IYr7nLbNHvF8wH+-gsrP;lN;xb-LuB42zN z+9|+4aIp2KTuDpYg4xJT8<dm9T6!?uaPN>m@GnvuIkut@jsHc?Cj1>@nW#LpfR zd9wwFa4Vh#LqF1epJMOc0@Jf?Cld|WJ0-P~*Bgx=FHDy+urO}vsVSH|VfwYy#>T7s zrBv`r>6X#cTZZV#rlh1yCip|)qzw)kRsH!h6u8Y;qHy}_-+i%SXj@m;GxXi2j8cwQ z!^VB*UwzFrFlCtS-a2mBQR&yoh><5uIF_&G-8$9w@Hf`T_~#FD)T=9%i1TH7PCrwK zn(KF|lBj`ln|x{dlR*Y(V2$igT`pxL<+5iWf^REYVqxL>^6YGWc28;Pe()UFt6Rl< z7RXPLlg&ZxOP^3zRh6?aNncYl2RCw(JpA8_-_7Z@4G8w#)&9y%A!7n5^OOFB^j+1feCIllargW9& zXoDE6HMh39zd1ZqZOoW49QQ@vjQakdBqubySupSVkt0QH6o+FfN6np}4<-Hk{9JYF z)-T(k1(dNI^l}YVUYAa(hSWxrmUjqo{Ei07ji&I!csWw zz*XIF&_6y5_IS5+2MxOJkRv%YtrS+A>-*G@o2@;%cmFtAKQ#!r6!8T?M*rvO?||(< zRL;&d47l0`tD0#1$2Peu0Zz)Z-~hA5$Mx%>zBZ+pekK}`GHWndEAY*Q`DYMycF6*x z+f!Y)4fAS_=(sZA!ad{tLgrmubTbBDigz!!-%d=Ft*aFm>B+hb%Vsx_1qBvi^PVqc zPl;~ba_Yb`&d0?S*4`G0;H_xY{pI-4W;RW_Ye{TuYimQ+vL`60x&0uj)JhE0!9$QJ zPrLIxSY0GAGxm@Yckj-ja_5Aa*p(qIcZW`B6PP|_#L7E63t~-@zE@RsS+#!KaSZg7 z4#V)ccXpXs?1nxf4WNMHjoy)WpI?;`YO%v|ltT=xDlZEkEMqDP*3bDd<+b}oB6?(= ziQXYB_P5Z&^l#_%);r#5ZVC}9r&AhGEFtjRibaXTvj9r)H)%(P_kX4YO;GW)_;6homX3d-0 z<#Z5uiHl;iz}jqIc4i2JIO)1Gu_7;vETH;G4E1(jUp z`RVy|3#S2dO#k}lClMt{Q14Yre&dYBUZt>rJ~RIB76`o5*E021X9~d?Ua4Ojt{>$C zgBk*PjKSu8H6Ozq-U;_{t+-Y5`7=JGS}ko-W^ds@S1w_yk8n<~`t=`T+hRau= zVq`0dG$&$AAUK27VieajMEgZ&$1kIIJ!NEEPD1Ld)SNWw#Fxd~S-t{jlJ};x zVd2F^z{+jdR~vXYXw>2vdv@KLIU-{ecyL@w(P=w zxcu{;Qyp`qIGVSj8PAUUF}BdLbdeuSgOJrKB9YN z(=3deLPMdcbT8vy_mGnEyWE;~_|Tyw$a-MZy_J;Y4o00g5pB5bWl2fazsXOf$RyqM z#2ZIJRGvahM+u&6$|UAAR%TeyrF>r5G4EoL0B>6sL!#noHJ#e+pfY-B?__I@p7Vd4 z)M*G9?>Ep)?6YSErF6h@NB8}tNN#E9x`ml?)cJY>vJH3tgw3ZE0)8I&C$Kvd^8;|$ zp)X=~75s?XRPcy})45H*N6=noxLjn0=)z17XAIj%6OL? zFujPq`}g-4{aqQ3-g7YKIG-r9L2jit!{>&FMA|3Y2p}Q+%hWwp49x$uwP7iA;p-Lo z;FV%LMzgV)@BRJ#TcAfDH$-XfOkqG4b6YN5Qc?n+S9uHEp?eVvcF#EnDA{{Uh|EHf zXs?4u&QB^b!$~P^*Zc@pG9{=Q{Gv+XI_yq!A9hr5Z$51T%Em?w@h?Q1nSA3$b+dld z{f{1XWw)u3O9g<`bhza1kCm04_}+5Djx6ZXm`C63?<_AP6Z+p`^>VzW_J3S}{h4&m z1cdjQ!)w`ITPIw;e3^$Ny(DHLQsUhX=FDrV3%wo1rBAyK+$nMM{Q1wI`QB0Zf|it2 zx#>pj%Y9UM}&A640qJ5v6BlpGoo?0iQy5Rt@j z%!vkjut$n{41Bcg-zN$Xt>HoxbCgWErWQ=13oN1|A`}M<=(UoQ6Yy~wgV8{@`H0 znX$bDT~*wj1E_o_u5ow2nw2%V^mX0q%WoOYgw!W%S5{T^8DZlAHW(k1a^S!VA`AsJ ziQKlon19=N^d!cqebH~A=Z0?PcqRM4+51~O+|$<|K**R2h~V(HynMiW*LCCiwJhfO z1A6XFxEHp}FR4dqqKHGAaPAz8iI2;f3AMkc0X2EFX4p{yh0ZY_Hhj2{pc4j;9C^p( z?MO!{>lA2lT_q$ESKK~nvmx9xE^*n7Z~P9^wRxr*yX1u@Wg36sf(mX(-i?mld-AH; zw-Aw1*B{v8=^5}7-znjc_gFb-#^2Ig+Z1OE|5^7zRXzXl<7`#K#@va(31$P_TMP>W%WuJa)D<;Of8g5ML*%#_XAG{z1JFZRTKVk@W>?$S_{MtH&&W? ztBo8zRB0c`VHwEF!^>Yx#r7U}3aNnonY6`}+JW>5a}b%R_#-=bW2Nh;7BnBKk=tU9 zr(Pb)aRNG3pR50za_Q8R9m?l!m}E{N@s?$3X1?6G&0Ni`%6|Ke-ezpCq*i^VQ-adyr=UP1p5 zzx@5fhimAXb)TpGXXXIF*UVxx#9qIS-B=PO*wZWi#;Lu96!i!}7=}yS48i34<2|67 zk%YLVONNR>N9Sy&nSW0~*0*=>t{t{F($ObEw0&4YaB6sufiOa^oA>wHK7iI+aB{!H z@f$Zb!|oaVJ@U*MP4}k=pIbP(nl<0Q@7TUQO{wWGjU#TVa_Ny`A_1D({7p%^VYpw+I7n2-ULm}RcJ3L*`J@L#p$H!zE@ZGA**pjU$Y5cssBHY>26sd@~f?N zJ$*@bB8^qS5$uxfC3kQ9ct4N{V0$p75OZoV5j;Q84!s`10Rg69FmvaOIK_L%ZU6xa zFwec+U^_GKhwSRX7ZLF@1H)M zb9yYST8OUu(=+U@0$oNuPrGp=(DN@7#>`9u=|J(&z7&k-mWu85ba8ZCuza}>Cv`WXPG=(l&5lQPQ_a+`rXoC?wkTO~)6 z(huC#`CBA#fy5>=473@H&o(!&`g?;b`$7Z%t_9GpAl2xP?p!3?LfyMxzkM@@i-|zD zk?4}{w$zn&&rb&Z1OCqsWL$#+WY7%BSI*1k z4#WBdf3(Z=>aKoI&y|zIror1m;hT@9oYbyh?;SfjYf%(V8K4m2A1e|hoN-E+ofVKw1m(dNsj5Xw(yM`IJ8>8f5 z#@r>vZevDiY-}v^bmMa*E#!cHU+Rlff}FFsfoIYD`TigN{MkOSXa0V8OR~rAVqo3@ zGD4iJxXgp>XW%uY%-z}f9Redj7Ioh+Y~e5PP4S*Hq|6e88n-R31yex4h9o8Ku0=FQ zYAPuAW(??YCjG*N8Zc_T&KcZc4Zj94e3tI(DKrZ?Q_@5tr!mDClstOW?GF5@JNEa) zZvkzFeM#JVZNZQueD3W#cAP0XEM>NKw?%PC!B%JF$ewFF@tMS@=@obr*X1xo zx^xMDH?5AB^az3m+ZLITtfVIMhBayHm4U4%Hj$p|OEbEBxB+#XNk-$4G6)+G^lbE1 zMCj|TQ~y$BYo?49Z|q_`oL*;ew$m86gTYVEHY~R(?dj_7K9x$iePYyeO7F3TKPXv} zc1<(Sb_{eHlX3MbX7)YmdEYc;AjPaYEp%pb zz_AIK*`PgCT^#&IBE=bE`MoRU;7<6}PR)UubWisqY+vI?!$sM|b9mQ)F2J&6kk~@i zoFuj)n!Wuq&TM{HGEGD7iodWGgYZC%|Du6-rdDj#}q?ZUI2>o#oYq~7r*Vge}SK9!>k;bA^5>FeLtc&JTDcBY1$ zk%+4S(G~)eWNQ-8shf!bB$)O6YGDQihm2WfI%m$M_;~RRQ>FIGR z6l%5l;9vg68t+l-NW`0a5JPYER5*Yi0N4<8zt}EgPguAwd+gs$;cLu>ajqf}%pDX# zCs`KEl%M@Dq#&hTpEhlRxPRL{A+BUf0~tzp@9w`Gu@r=40uM*6RW=KD6y!SO# z_Fm!hGq8DF%keN1a?kQ$^4pKn48>i;2{#xB-9Tv;*DW}(abzaPbwUQA;FuciL zs~(0CEnx3@W4?vPnhh(LzM-pFP7)b1K7NpQE?50A1kM$gm15%sSW_%4(Hb=9{@b^G z9xBbIEYIKdT1h?O3i!oD0|Q4D>3=i%)It&)Img=@Nm|Lr2}f$)m0F{g(XlvQuyG;V zp+A_PMErNbx)f9V)-VmYc%XZEvYK+iSG&CL!orQD+r4o4GExbJI?rv}egjOcb8*>P zo7jd1o@qjc-N-MKMIyxDgTnP>HN$670Pq^p-rZmH-*11xA*6i`nPebgwq(gxNIv&h zXOK&o;t4&+DB*RDCh||u&@Qwn^|NNp(x{#RRk3?N{~AfbPZ(R{fS3)Aj+OQGqXrHveA%5VA3(vA zk{TFyk;nLv$Y^=dDe#q4pxaxuBV^tXB}AW2V<`7eSe%Cydw(kf^TvLmQf3o`(^=S~ z!ZU-X$PhPEV=(9e*4;U35lkEq=~9ZI1S6vG;twc&`TOWe)dPC$7J58uaL@${?(a?j zR%cTks+ti09}*xZ1&-yI%pi?I!5YO2FT4j-SGn9-_#Y>8<&q^qs;e3;=T$D@GROH+ z0K)_UUO@A_2q}Cuh^E!{_1AM6rv7tlM=UBd4qAzh~(7rgJ!hKd~P_?z(-GVGnok={-O1>em%IB& z_b4cpE`3V>)_S0n;pv_{c@nYrouH>qV;X(Ahbr@CKSr^z26}TRW1l|0|E&1u2saRD z$aR4&C&1 zGtJB6yVsWwC#6En;ul=x<1xu#6D(Yq0&)qA_al7GJLu|!ZeD`I?ba>c950Tn{=XY6 z7vDq7bY{$8Z?7?YcnN)BdnNI$#e$Ovj?a{Znih`?EUCx?fvVCudJsa`Nu^2_39lM` zzj_(mSshxkii0GasN7tSuhm96K{?Q=gTf7=MU7CtoSE6Ld|3x8#53a^@{f78Yj+Cc zB9>(1T5aHG{$~968|oLI^8DH3F?X9`TfiONIboR`0gubAp?{VFs_>0U-2!Wjc@Eoq za-3+>z|b&5vzk47-Q{BfSNHn$F;^|!vbUGRoHBLZd&eli__t`(&+|k4G~& z2kZUc)_7S|boSL(qt!amb8y1vCxI4VB~D(4X=S%y!Jx;1vXVKt^x()wQNuqoi(GFu zS+JCN$mOf7D%5P6dmVTzSZH_;JYj+8su0^gO$|)SE~dE6*}PeR{8rxG)t?I}!@~#W zN@Qn9;uB_t&9H9r2O=3;K;)nY|>vC`wmFP1YJCAr(d(NVa30Uxy9y^jvi zn{Ad)R~7#k>VFG$9ca^|N00DKm-Y%X8UpC#EB(@m_DwIdxiyUGpm0=RwlcDJ z(;d?`;2oT6dHXRL<IU@^a@kiX$zDS~MXlBHSoh`sxbxs8w-|N{zi8TF07ViCujJ&7m#wx1 zuT*6IGO`;K@@LN=oX}s+5s@W!Tj*rI@qtOr{lxHU#jj=w zuh1jHS`cEGMA-=Ac4^{^S8qUMYHOYpP4fN0#fl12G{Ot*>8a5HBNooS*MY z-N*O*Hkwco@#xAC5LA%J^_dZt39lekJ1ij>)|nlib(Z#k`R=&>lPF-QlTL^9>8M(I zq0pHD{QJY@kgO7EYam704s*1DWq9)BzDHYm!&ZlW8tk7Tkk}@ARA5Gk`DbRp>iAU` z;jY2kqzXfJ71K>=*ir6m)#EopOHl9I80d_;Q{E_skA$$74T{}-npaPhEpQuf*F*mp zI6V37HrA^QfP<=?Zp-Lg2B;q@1?jPB5l#Cj$_@Y8e38A4nbLfGKN zB&*YN0QOW530S<-qN3CC*uhM=1YRJ-=5=dsgko(W%qHWzy%p!=J zyzuTnw~6)zAcW6Z#*>YyPA^p;uygJ}Qn^{o?TI*SPiHr`{rLmR6{|fnKz0Ou%AYRO zTwF8xNw|Ul0KOrXaCH586T^v$NrFGi(E}&7hYo%6`gLy|p|gcD!jGqZ9-n^#f?)qK zPLKIl;M%3G@e0F^u7`i`a9;u-!FtJ6vH%~E6HbM~hHD6k)8=ZeAlbfLMeUAApxL#E z0*r(0%kYrO%=Uc;#hvDiu%wg}9+F3X$(Wg`(#)q1o+n;FOJHY#OX&KvvpPTytJkeV z4pIDiL?i<}YFP5KZU_``Qry$0w4?KhN4dX=)N0%~%W?g(6Vg<dZgHv~OCRSEwFwKF7@lF;&Gy4i6lo;lo3{b@tD&1vO=$NilgpCx@HX zU)B22!LqT{fhhLRaQRtR@pqZrR_pED@9jHxB%j(YgbzH3C-b=NLohKKRFM;JHgjfr zi$985LJ&>Bx+hHs|Kr@XYjEVyh2sjw71ZSm9;kC^GdZ1I4GcEGaEb{dE@4ariJ-Z; zIckatIqc1wEqqvtG{bx$Ekhv8@a>$Mj}O%_l*s+ZuP^%lYAW+{LLg;Q%@kAb-eWK> z$_$B9ZX7lSiHUQ$@e?J3a6usC9c%-EDfW3YQfP(zND$!{k}>+r%afW5yexRyFb0v& zF*p=U5ED7W)wZ<6B!jDW7jwJ(fDLFu!}jk75Q7F$INqqskGQlneKH$ojTw&X?2w-= zEqLD14Az|fr4iuFvo=e}aZKhxZiUdr<{iHyfX{_z2)p#srEk4XM`_^R3`z-_3$Y`9 z>B6zQ?MTF;8>-ICxX`$f&%=IxR}lt!epDm35(XIrt9!V zxG@@oj$QLstmuFg=JvE13Pw62SE286qE>{UB5Vl8RoD|gX#P2XYkBtd9xljA)U536 zO38mD3vS!k57LS064aiO%)q6#wo%8A51D0{&O8Dbg1_Byy4)I{2?Dr>wtMTwJr+95 zJ9lFGL{fe{?gJ{duo^QWw{W2expPqcl<;0b*+y4DLwaV~I-!(73 zoXY>bvn(d>7{BR-!Z2>AyW?6sh6;hJFP+AKAw?WMEbhxi@BRC6Io+9sOP8)&ySCfl znu-d0GG^JGK#cggAt`az;Pt!3MC3e5X)@=%J1gK?GT&ztPw&(umRN#8SXp&keU<>4 z&F$!v8gyhk{@RQDDA9pEr!c|*Y8 z59K1PRaHfW?bh<+2g;a9lPBkRxQP2#R8@`TdZ(6X#^B7`4y+E*WB2vybr7m`oTY>b zS}d3?CVZR+N*7$c!nQ;ltAFKWT7dB^R$}x?+0vXo{K>Y*_CtA z$u6%m>aB=F(%6*LR5DTf6H9^zfBg#=iO3GXe{O(L&nzaL-M)Prcf$%9^o_`e=Dj9q zSAPY-3!ReUVw5W4svAEP z6nMbx0THwR@cs}dZIo@=vv==q=FbRt;>2u#)`8c*T$3wMwb!plYViz_#!okm4vFOg zCZRiJ%D*ftO#(h64Q$Y)osM2Amn#)jB?Yl{7@FcWdgE`d$)IpJr-BPT)1QVbGRfE> z@?LoCf9iT#0G9)hL*Hr7sOxrg4pdb1h>nxqkq11zywnKnwd-hWcyg`tN(%}gEQwyP zMHaFw*|Dqa?)#UlTKg)iT4*U??XreD;#bbIv0=b>e?fQL`!<8^jM(^AR zj}z*MaPaqH^#14Kc)`_$6$E3X>C_$NHShnp0G&1C0mx#Q!b2;RNR%+eeUe~6t9R#b z8SUk>=g<4-F544i(fO@HQYGOoRm^E-IYiD6U5-%u(QmAEbNi4!*0gTk!iAgQy0B$8 zuQWKsjf4wdv0CkGKlcg{ET$*~M%ely2gk|f_{o!w69TEesef&{_vB!r*ElXiK=Z~Y z*E@)&C++e0qBn22W1#E%%?cq(YHEfU1h$DAMDJqmBTyxG4B~QcIIP&iXXXu|5NC6b z*44d|Ws%OA;&2Ntb9Ax!j}VGwa(<~W4>mm*s`Rwz;zDkZV0s|&Y}#Kw38y;Y{P|rI zHX74kGfjgiB;I<}cYsHiuvc3#n2Cng$mO{IW^&{St|(~#BP`%gGPQ`{>9?(WF9f`CYf=)QmI#gUmJ?Wod`cB7ZR?vNvx~3ecdx&q5i+0Qk=E zTNWB}7&*~Tpntlb|NU-RfW|B)C5$L}Q@`d-T(|Bkl?c{{4TJstC$>wv`)%AlbH$1> zh;5lJlfs`kQNjy!?zJOFN%woc1HngK&@l<|djNr4Ks0k^LeN%F@}(gAp~q8LZ0NuK z{wBZP(p+a|WSB(E&{6;mA2DJ?(lsj3jm$R6pYqf_D^F1$2v#vk?{>2pNf?>7kI0`i z2rz!_CxgoX5pk7 z7dU7>+AZb)b}^?;2|Y=ob3f@o(-R2ru3XVQoz`ORr)q!dG$yqk5FYBb-)CgRjXZ+E zN%=$lGlm2v+Mah8Rw)e%cV4$HgDU&J1WSy}K}UwVJzJbOX+?;?`!#Mi| z*VY4Pf8$tXP5u#@6#=fVmu+kBW&%p_8}Nw*6K@)y`D* z1i=30xd{-InqaeSk9Ya7i356d<=xZVaP?tO2#19M24bPB8r2PYC!SG!pse_uHQby> z4n^pmd6cpWAG3KZ1XE%5aPs8Srb+U>d;jCFU)MI-Bq@B$zly=w6)J zIh&-<1kYafJ=y`HyYgkZikc4mc{X9+hXg;hN z7DBXT`D50_kJ$%$^0E0@9#x=FsDmJk_(x4aNMNOEUpH$?F-iXkX(HvwJ6o!4M)kX{ zOK)qfJpm=<%^&39JAWOYME|3wCpYyI+aW`-XghBPcHFyhqcN^?d3(_A2E}>L?%kg} zfBs<0Ns^7Xcl+9#Z2)G}n1>@GvJ!SM&4t7q8+fRA7Wg{38+vc!hx@@84t8Q9NzL(l z(z2xVBgc*be3fNv3euh<^P$JJWjCa^&S~yV5OoN=XK#n4^R>Gjj*V3i1Na$K8)5lV zylHKSu6H4hnR_DDZKKGituHD$H;vAQWFGpO(zUUv>5u!eo?6^;Pis=}2S6CR1m7js z!e^Y(B~`4c$;`^4KKk`-;NKjwI)h@#DAo?M#`f@~rgCt2wV6;x{k_cE*Vh|yt~=E( zW@NqP}j^A~2B>j0~FE8Te7(6}V90f*QMDa?+GikeA1QVez{v zbR@jFnD(cj4KNfIFIXVHgUXX51%AC#KH8T5~px3;M!^ z)Kneii^G=UaRlq7&G2O05^7~_9i0_fTlPPYmFeD{CW;!daa+-+dJ(yyBMyL6Uq4d& zi-brItO5y#@$y|Ad!9I&Swj7|}%Fn+RG)a$^MKH7?N822jRM7PmgoTOn4)Z|9C?lz|k{6jtiXgnjnQRMi zI)QTq!^_Ml2kAgZ8hIC&ye|%F0X_Is#&Dekd@$PJ!I)kIRICYFbFV$NWgK~f$4?vT zI@sTsM~tYUCThq_&KMpL$yVOvg>%RZ{YgEe4 zNLG=e%4-6fzPDS=l11P?C_9RAxq**`$)4O-O^vEPFq%^ZFgn@jTBz&vjhK zecX3@96QbD%uYl_-GY81O)^*(Nie2a)AX2@b}NV`U4fh(2x&KQ2EU@68MT!6JNSj zTqLkDnd|)!Uet!3*dEo;^yw37Wxd632Dk@nYrmoFThq1a%l&wN<0D=eF&bi$lFZL< z6_}8JAvP;f3}UoP-Vb3E&lpjJzZ}&XkZ?`%B6t@Fp&NO=;S=Nc&t2llOqu~7j{qSy z8aRY^h5}py!Xw|uiv^AlY2eh!@B1{~0wYN}06{))g6<#rgTkhSzX<4nuBfbX8eN$qd-Gf@76$40y@+ zA3nIn6e3i<8~W}e2G%23oB)y4wY9JQ-u00)2`A*c|G1MYa@#3uu@WI*6+D&pb&clW z-o1W3t$uaqku8gw4|8Sj%HQMwQcSWZAx9$Wo5Hc@s2f200OB)bG3JfLEmeye7{%s7 z^VQ3jE=~UY3Bya!rTdsz>wq^U|A=ww*RNhQe8&`VC_^kRq#iX`3Rb2`j~i$jx`3sc zZLm%Y9XzhfgUS`SyP-=7MpJelf&j)$GQb!vjH%Sg)@;=|dxfWYg+Dg0u7`WUO9DO#muO zdUz9j$|*WCPPJXlbF_ku<}%xTpXm!`Z=M2|}fQ%#9)idbi4x zs9oHVbverb4!}%$T%KXnK$S(JMC3j0O!6^Mk)RaBP^k@)tV;OICGN8a?)f8Mj`@i| z*Fd8DFpk3iTF19^s7ldVV6AAMzaqD^JI@cu;P1)FW^p%QCMQpvAR%vEkF(@(T-|hY zYlWOwgbCd&@buLTuGplcso%dtX?MYk8xb0MSX}&1*Dxt}0HF45O~6wC#uqF!qj0_? zB!pe2=Q`RsIG9MkxeHAU5HNJ0tSckb)WD8c{^T#O4YgAiba!P}#wR9Jsds`3KsA;? zzZpmx^egp zymH2Hv(h8>dH3$nL>rXw_%J9mSDBujhK*`+VAq~K_vg38#>E8&1uf{`;z8dbE6XNA z2kyjevcIeD5~(^lQ#=R`3yvZWDajr%*je)Z0mogbaMoNJK6x z9*Dt%L%mlmWC8L9IXc{L-+^~|gB*o9+`s=Ig&uX!z6|jUfJs^>pkbih2)d2Zh+*tRV>xUCwTRYbv z)oBkfYMd1*M+eRvkdTpa13gyJzZK!ETFJ-P(RS+;kXn7vg1C&Q2L8SRAA-X)Dd{pE z9IoSbt%7g0=n_E}%4V8M0Rck~3jqnLATxz5QaB$hl+gX5v|aYn?P7uf5Y8NVbllLx z78abqC%^4qW14`WJ-FU`eY5Z|Aw%Ab`7VMRkcQ^Y zvw&2uH))+@_yIZv++r>F9gM-OL#6}0#3@vuIE~EgA|b*8)8=t`u;S%Q^fg<((N#nu zBlLJ{#mS5uT;Cp2XSRt$-b6z)Ff`S}7cZ!24I_=(Fpn3uDHYaQPyR*-qd;K6m(%xC%Kv)|cR1KagaYiz~dhCP8a* z1n2<#VNaU@J0its$VTNM36wntR|z&sL9qG@bTyDrE*y!9KgEY?00ADTX19Avl4zjG zekrt1*kmmisCXmOVNSVzz1cz>dxAp2TSY$=v`wxXL_70ZumByXGwE!2*e-Zs82rm80;9&mvRxs9>M~d)<4Q)ew zRwoyidVPI1WISNYu9Ww^MGuqBK}Cuv4y~y0&Yf}??-n*JJ8fdJId)=t`2lDK1nDqq z4#OmdvnW~Os@9%=HK0teI)U|H+8S_s0Umc0gmWXuxEpbjlk`D-eaJNkDP(}jDEh&J zw$9EU>46U(JxVxi{vJFOTBrQ^-S|%k(J_>&zP&=$4XG>uae=7<6`Ya(Y+V2p6WSD4 zaEnVB4!PB>e!lKd#X4eaMK2WMcn-xRmttKSzCtt}tSp&8D$r{t3cr@aaSu$jW-1fI zSf-J1KQ=J}@CDw9TAfFv7#6Ifihm+|sa|8Kee9`E{4aKSkRWkvxe<|$PoH)em8KZr z+=M35+~5?vZz!ABMG0f*1vxn((GQyBl(~_BJkVV`4#8Io%7-*{=Y<}!@E^l@Yx;=e zS;uc=CXgnjNhfM6D}Mvam2li`7vBt5-d=(>5AG3!tY>5#OcpJG`VXW1Rsb^gs_;g_ zOg4tN<4xJ?M-#c3n4H#@97{@2v_Qs&mzj7YQ<k zA(!ddB|mm`MYnEh4xa$j4{M3f4-&Ey#@1fUpn#1AvINf~^=}v9hvXH6BEq!1AaTd= z@?{?=*&%sF8RLJCB-h1qMR|@CD#tlddio#)B;&g>+r&@fuk?3!OM_P55EZ{g9eD}` zaXIutm@z;zi2nYoijs`aR+;LmV^Gmx9IuFw5L(Xr5fP)C)?;uvLMkhuLPp@04~d8% zO@-S`gP(&H3)Jum6(I&)5BftNbSyY z9z}tp#ZAPwV<76L1X+3rTbh04%JZwNZ599pl<0OFt~c&o6_qh&((g zSkbiXk^-`_O9m!}4!gf>5vFRhE&v$&*SCctQ@Q?|tF(lKlbhT0nB6@@=!j5hJnW7 zxbGTNIv@z78&Bx!9zJ^XiSX2w15t4hi=(^}CP$VM0s{d5G;iUjyy&xvGed~`H%>x? z_szHmDbr&+z$+r3aUnEdi%j*gm)|wjW(TbZ!ky~EjgjKqE31tQkGBaE#E4n#XRFWi zzFibBj5F&CGSqLxjj{=cwel-a5CoY(wyyQtzRvS~TZjjek<1*k!pzV9D(`#scq{SX z$-ymbPnUfp2t~uwhOQgMsZWZ=uD_x;A|rS+dBq=dhBm%}yajcPKKC8Wv?wjb@sMY^ z6S|*5>?3I|u%U6VW3E4HE<;xcHp$Eh)>Pk(<*R$9q7o9yueNf}dEj0K^Rn)K$mc5r z3xKBrHKA_Ah>-c^8&v*lut}k_xkEb3VbOv1=2y?T4F#yQN#z+CjU}iTXn-qde@t-z zqaDJS-fkHR0;dx4v&3a&#=6YjO-pRf@RyK{9uCt#xlyv#@>)xg=wB?{pQcVuur-IR z#VuRRie&-8AcJ8&p$8a2Pxb{084>8BF&WHl&s6B%kEj4s zHr)Y|Kxwk>E_QqbX574~+>nruI2>1h>sJ8lL=e~4=X^XoxbNDF|C}B~d4P6H*7+C1 zf)m6&lfQo-0iaYw^EVlTO~f#kg7x;v!(w6%Zf;|z8>)saHb#tQBuu$gm=D|?zuS|X zzKzPd#aiD%XYUTCMy|$o%Zz97->O|G$cVEC&W4Y%|2Fyc>b}v7ml~nzcO_p)N0&XO zAOxN;hf}jtiYr-^P^Ct;KN(QBe=cDZC;rBg&1AQ|@R0bE-F{S(xi)vxLm5tlT=`z# z=3=X1)uT;RjA# zob+PdL1zxEVjeY86q37R)L(#BtGVKZ2rz1T`e`Ev9S8|<4gUuZqdH%^J7O@1gqbrq zyq-kAGZlm74cunJM!6J_e<+uLm2_@(b8&f*MuIyQ%jy0CuB8IviP{Ns^zLkSqj&^w ziz&6g|NOZ*vUV1g5kh#?U*N)J&5?l97N;nV?}p#18BCCaQA<5Q75Y=opj#1UM~anv|GPbz_MI2J{KgA#Kh>D=XFp8u()N5~o#_^gPg| z`P?w7S51X?STMDvl{%xZ}tT>`h@uBj@*}XVhWQdhlhF=S=y;p^ACwN;Dw3KLil0BR>T;st5qU%)kX3rN3 z159CJ{J1<8LkyG6ZlUDyf5#WPVm?ohHPIa)On)t;{PWH8u-+fOziMqg@Upg=$v$a) zyLZ1CDL+?Lrq_O|rDD0}-sWE!v{#kQ#pzMr=PJ%L>`mp(&EQnz8>w%oQ`q(GzWZ-& z*$F-3#DyLlP|!@(<#?ZgUZ<>V73HTXuJ{(L@7~t|2xh1QPVlur)_&+15cuQ6!a(Ct z*!-GD$2ErHaFhRsAijQxDQ<7%?xr~jY3iO&a<9eUxka~#)$q*mJC#3LIg(BkxR^XW zEk=>70g5xac=4$dxzYn*sHDaZC%SQO5ahThQh{+)_^h*M9m0Ws-q<)hE$zeOPQRqR zw`N;&$xW`lTGJ2FWJtC4VRB{5o0Hq4#v3S5{B>aT^o5iPx^?9h+=>$uUy?bL$Ek@}c~93W?g&wyouR;z#QKjZC~Sf^TCbV}hWq{d_mpD4 z1`EV&tfFCGuady+i0PD4LP9jF4er=Xs7Wu_Tyu(G+;(j zF?M;Zha6u!wN#`O?NtubH+AE63Gz<@S)mCmz z*;n6PUy$kh?bx+KNuJ$2p$*yUb6qK2;bT?N+%~PYF~u=gcjwTfuth0mdOjU=3BJz9 zq9!dO#h2aPOOdh+-_Jyxf^TJRu4oyrHHt5a@t?W^k9vE1H*ST+KY0QewY@3`CI!Sb zB=@}k#Q{hS*avvmlkqtFujo^hFq_TXzFWr@ijn~&^$yCT{mi}>&P$Lzef6ptPB#5)3gTl!1Bo5i{ab=br5Gb=RM=KiV}>$w;`J0hGjN?efQW;w zUMV0K@m0?CgJT3ksj1HzwmfD) z>83QxeJAKqe>CqUDnfDoX{Lw&(G{~-b6Iw+_Q9fAJ2GrMySEZ-d0u`ir(H@}YS-gv~gk+bNXCM?cHAx#_Vn-=C0rIpKJ&pQxhEP=q36VbVTG03> za9R|}dDkGgy>Vlx)f1;7hi9G7P zway2f`1VbB6gu4mPA91DR=OtJL$E!a)ctQ`g|;n}znW`3TTN+k;`OMM<})^3o41`~ zcUqgItu(CeVc4NNLtI~j(35kjS#an|w%CM(?_%m;Os#z3%Iw^hX-&!K->G+ysOI0) z4&TK=M*Lg&r&1pDfbSHul=}C;lXq?xj21nsn_m!yR|!r$C3^X#*M{J3_3fdZ?c;&8Y`vk9Ei{`%5Ds~BMgdd;QGwZYLEz-mR>*i}*B_3bX5|i1Z z@L+aiF*D0=T&UO3j9E!oitGDi*I*M__;6BaTIkaG9SnQ3`Lf+lM4jRxCsYeh$PK#` zjTLv`@ro;bdhW(MZ(S{Mtc;w(wk*f{0XpB(`KAt1_OdFBxHC zmtgo|obJwTf_OLo?)1Z9UbXZWojG^$^D_))cS4_P=tY|G^4bimKHS|LhDMAa$m9I} z)XhJ@t&4fncA7fSLfYDn53SK|1VBFr@TfLJ=j>VW|D1^T!d1$BH-~C!$XcAeS-q@C zN0*o$sjWlnzR9j=s2L*n}eHO<LdnK>d@ahEaY84g^)iLwxrL9++N0K&EzfLIc#? zqyXiUH_iz>f~Bj7^U`pMBSp}2D7TT~ySSNDwF4%JQc!1^DaiK|bNGsrP}6nL82k=0 z6Tnkh-`E+|fG=PJ=8U}C8WZF$YCvBUJQrvReX0DRhk^^Psk+)vuFxLrIOc}q?LdQ1 zWxf{yWDxoSn(O-&@qXm^EoMorT!_Ze{sR9Eln>ZSONx`@kPj#Ppjd?Vux=EGBVmQz z%lh4Wp1lw&K+_7rL+_*&{6El5(KCo(IZ4D*lYlC_y2xi56kW`SJ&ADsW2iFuYke7%$eRCIWJ;)iWq7qh=0T7S1 z#p&XGnts|dpP-w1((>xnRNnyx(# z5In77j~g&*$o_Bv0o?x-%2)>6=%{VCka!#^M_|Hr4FVP8fr#&UyS%oAbx>m}R&lZ0 z$&*_rV6vP{)7Nu@FomifbDbcufMOL#rX45we#l5hxpW1X0dl#gvEfC!Sxe_|6ZI>cB20z zurOitAQj_{i2xk{S);IfEq{SE@Dv|A8ymbkxB=K+b={s)f};m8dC6Y3Py|9*o0-+T z=E7w1m%w45b#hB03l=8ny44DbiqLwSjqho~EZ5=TkT=jXn26%1sc|TRt`2%WZ z=H~94@58T?zVYRw$be#MJJ?j+o^)V~fL0a%C@fM!fDHmV)%Py=P4F*t9MWMGDm1&r zRnMQF$Nu?s5zXX5G*pl;JB{kVzg1n0`EA<{=^_6JX}a)5+zs_kn<4laU=xs$0ru#N z*`NKGw2dsc52j+ME@#RT-PYdXU5{0PZviJ3cz%E&ND?>~7t7qM^QhHPmgHr?JGFDU z_9XDC7+Cx+W1p%)L#=B%f({Stm0B*zJ!oU|DMxPeCPL@-QIS_1z&?W<)y^a$9ZyF< zK(Toej#tPKfjKy|%wp{*K%k5thR8BS9zYd{H2l|}>DCfBU1f200fWHWGCV2)GcTAe zM6=p4?yVb32NN3UENU-jFJiqjf0*2 z<_%G-0fd?iwY3pd>=?NYsso?ZZusXWCG2wh_N4*>ua%v}PXIE3_iN(FVLD%bsE3pP zBFYYtICE_D^{9+NO;05Dz|Ic|fLZ551n7bEEdOn?zn~z3B}1ig{vdC(Idr`bHv<;y4r=OlD@Vt}w-vvp+pvVH zio+5A=#kgIAKU*BX&t{I(uMLC_n7f41t^uc`1qJdj}&j`fw2PY3#{juMroUxcKU{0MPwGOsZpkLo(#?i%0Cm!vspCl-po&^VTidGyIm+kQadY zJdq2qgVa5}kKcR-&V3E4;a{Pi7*}*#(KNS_3~FQ?Sif=Lh^+luIfe*EG zM=_KKdyo|1e6Ry&Aj}Hbc@C2kCKxRMFcf6Fn0jhf);O4UXpc=(DR@h z0?mR7MJM4ODrZ!JBdX^q$Zw;|odW=HOOj;a#q4oMkA3M_d=?guqM|77vEtDoy_t=J z!)a3JF+LIaRg4Zmim~4Xl=gi%p#XHet9!i^H7p{}n8uIy07D{vsyYd@%Ic7X1oCK@zd?wBNP5cP ztx)mM(bETeyg+>b1&Hy-NQAC0Vda9Yr0|5H;w{p+OPIf6==vxC2g9@$?9u#tTAY>S zGS#x#cx7z8Tfnjnp@|&0l!2lGOrpaF#S|S#l#e{AM>pkxxfs0`_BE;q*8l@}ZtjV4 z%G!aS_dQ4ngVjw4>%Sjc5i@UYYiM(Bkm0>-`ePFF$_j#@YPdn$K^z%SLDCA6aLe6F@Ft0iW41x$ z1lJbosD?0v3p!rLnoV$^BR$Ujfe{gOIdmZ>Q2o@_l2;(X7ew9nFNWBLII?(oH<`;J z)%`m^A9%GOK?SxBR5;MoEO;T|9f*cu71b^_7*@T!%Aq@*I4B}Q8h_mBT{pr6)HlH% z!ct@!YhD)DhAKI;pse}k>IjFehleIOR)}# z17oJ8MMo2k!*CBwM{nOARSSNvd>{%L&+S7)puqeVu%uA7BiiMAO8XiGNosq$!2%X} z9DsF6APMrbWXUMyqu}UdnZUEQkn;j}j&ZCK#add~}CVZpSQkp>~ zTL28BZb|<|@>h{g=Nq!v(mO*bEiu$Z9XxCP2RuPk5*iw~0jX)H)fo7YU~%S5SiG&c zq>wT44IbBH6dQD#qyNqlWBgx5tPzl^$nXPI7s`-3q_}U#n>VlI&Yxi5gKlj+VgO@B zkiWtayd(nJHt$Cyus?n6wIY z9qX>C)5XY6$e#1g-oOe+Kj=5M_lp^l<00~D<7hP%L(na#u99UMSq0LfM;;fHrKrto zz`jU89@m@m1HI(o>~NE}&Kbz5^~Cczf4&PF#jK;RFHYr94W6(LCz$T`Dzh!mlW?Nk zzeG5SaI)hRgAcjJoBtjSbs8qLSl|s6F@J#A3u(`0-EwYX;^Gi%*Y7ZgNN94nD!EaE zEMe-a6D3^nR^+$V=Y3f`Q`+s#oL zl(xBX2acL*+6$=2(gKhe9S9YJ>5)b_av^%wV~?UnH9&gE=uG_OaV=r-O;1exXrXwD z>kY>Oo6*}PbaluzGrqjzYn~s+*WpBn?U1Y4i!&C!0GWY0H&PkT$Ve8C?&tfR@M+R) zW12dis0K)s6F8_n^P1m(3i3yQ`WFblO(hUHNxct{m!f7EU@q8MZeHKyN9SWdj6^LZ zSJxusefF@D3E+4ShX8hmIi4go`AzqOek4+^N(yBG*r`0B+rTAofeaMhBiUHYKhVhz zgTFJos?t&etLpSHeLQOS_fteK9gWQXouQnX89Rx`!bV#y*)bKXWbdOC=)@hwwug|F@=H{itO6GGbqm?y@&4ENjZ8} z?dk8+z;DIqaSI=ik?DE&4tS`;c5VLdcHO| zS#lXEVcjr5Ak41!CjiruL{X=EplE?9VyfJY3NCBd(-nM=lTJf04%=e6rKit%dzUzR+wY7$HR~FE}EBSiz{?5^_sz z@ZWy5hR6w#3q7pL>j(ufnlt5i6dlILDWTIvnK6Kn#R-zk1YfS{imcnOO6DbWdJtEX zmNQq^(9YOz^WO`eQzvgbLGt9HFf5{f^x%PC^n5Q)k;q8K0kvfjT)ZSsv>A7flfXQc zzf|=ST}iMI#4^pt=T_6t7uEK3H~f6%NFrmBi=yDon|Orj52!UXHQljvBqOjGP%N9R3MlYG zRn;;ImK!HLCl|t#kWP|{hx)j#sTe zVrv0=-pWLVq8$Tj&tAOv>E{Q-BD**Q^>q$pWMvJYFU0aGS!1gbE+N~fz|jQH5~p1Y z)LJz)w1S&)&jUGUIr%pupJU&p8+Lp{b^-yy-g^F?syl#bG3 zIw`k4k09W-Mh+dK8XXus1y5-aCzOR0QsV~4a9opSG2{Ssa1!9^GWH1@W`YpsBorgt zC@HI*_u`>z@qLF;cy(z>F+dWPj20j3<{dypDt%+5c~7xow>$RLmgo~il3%AFE-tf{ zIaK^muQVq*Zm0CerxWr${o*VM*i$GlHplUdMl5J-9~KB?mtTr&SXo(xG{{gxf7$9p zh8Gt>bA>3ux;qL0pYY-sLGI^Au&wh6330Ns!`a?Er0Y`)0f*TiM#2=HC1W<`teu*TB5`clXr@^Nr5gh5&=B;MW~L1q+>e{^$o^hblE~RhQ&4D z(pydYUiF`_84xO%PBSNvGQBfQu75}Bwq?JZgGHSLVlC+Uw1Bl6S#ZO>g)YdLZ4UUg z*f$S&c8u>yG4bImq_|XrO3zsOHpC)aaQ}Nige%%Nltn*j%-aJz z96SQk(|=)GwAoTBl{~&rsYZ`1{sXYd`E{Jw=}T!7V0MP}E!oe?zwzRhpWr|FY7U{V zteo6;cCG|MrrMt-S{?AQoX}YSCQq@5iUv+lDxnEaNmkd>lN1mLiT_tbGAsrR3_~vH zcy*O}}vVD3x zhJhR0yl$OMHoC#Fiw#YkX>=0GdhC&#%VhAoQSKpeYFMl}#-&Xd29@_d7sX^l14Nk- zjrYwkBx2qifm1L|-7NKrs)lm#_D@JBP$}g79vP_#)ii^iNu!|(MPHuxqfNdeM|O{H zuD& z{q-eS6B1tD-ezyg%e`>4-?B~TvFzmi0)I9vwoOpRJ(`!Sqmd1v+U{uW(!V-@5}1%TIyjEigddDRa_OcDw8 zeh#=CSVS0aqVaK|bRHQYi$~!F71F{~e*KwcWa;c>2X;vrmr>0?)|X z&B$1zl9q*P6j!tzGAA&P?B?(i5`*kXCS_PCF>3xpSHh3g|E&dxQgp1Lz=GTAF}I3? zxB#~+H#76QP~|yN#s$bOyRA4*57~dgC2Jm?OiIze5fKrt10%}lXd8J0D!7zkROHc( zDTV^11}ZQgP6&KW4N{IdQ)t&vg4A01_-tU$AQC-hPaQYiRSH zM#3;7Jo#;MQXVID(fzZK`61>$9`8E-n7jCZ+VAb44g&rjgj)i~#1~F3nd*rX_yY9b z+o9PA-4?5yf+wjoY>#qO`$zs>xP|JsvH%^E#b#N3Z;w-`S7im=H4y5X%eyJ*zYx^S zpf=Hw`D+RaW?>iQdq2Wug3b0TfE~_MzLa9`Lnk08_{;%ZUk-1-tlx(sdCQ}5vJe$&6p6VuP1~0Sa8eH?;AjN}lS|D`bO0JcQ_$Mx5X{WVs>O zfrvq6js($;zx~19M#|22GFj8m!K0)rM=tO8uI_U%N!H(G$=i*4YTuB%KUA(bOp$X# z>xspccS64;03*L~y$G3}Nb4xRJ`l7^^A87Jo)U*ODH#8|_yO&tFwGaHyI_^Z3KL_} z#b9C;ktyzn2?;c5R(Q>+0fnQ9boI-!x&wcUPvC|?R98g~vch1Q%1yEWcq3Lcg~Hyj zd3O?U3eZrdzo`yHmBImnI?ZAEu!W^1oUdO`E1_~mQDJ|-!B-cXp9(QhRhgMPDjr8h zf{q?h75WUP67(2k@d(4s^QT=zE}b9aQA%<$j%T$}D89b#AZ}1O^pY=>GYS5BZ;9(3 zDTJoL3rOKTqg{1RAu9*;S(6!qCIjEW%y_F5xB_-=ZaVr>;Izl&<=yuW0s80oYLWzJ zEg0F_mvB`->M-AjVLb{^pV{5$&AZLS66mRAV{>S&2-!0;eB`?YTN|S|t;vun#(aPh zp@p+L3ufT4d*|Xox+IM&(sCb@#qeRH!)E#Qw~{AB|P`y;3n4HTME%W>L}O;txMa0)&m9 zeHEU?0Ra?{$%VI5z3CG-J+y846$D-xIPRFV)*Z)S0i#q+}Y^L zs`cl;`Z)3lVU7k?a$qx#|EY03H#Kc-`f+ZOR)~&nv{LZ{_B({1WCY#>{`r7HW(x{) z_fveIAshkx#>T*~_rQVo3#&*0MJjUjOBgm}EDFt#A0gReEj?(LshPWlIQ8Vz-SB0rP!6crY%n`BBkrsp z*^_CAH19;;u^jW2J9NWysCy-kh1mP-5U=_2bqTf9_Pn=lz|R3<{Cqc@G6wQXDNq?Q zT_6v$e@^FZy#;quxd)9BNfK>hq97;7L9}&uKaP(_4C%+ZF^-^0&EI@yL!d<~bVSVjAGyp=NxqaG$KU#9%NcKjbW}W6K$-7! z4(O>@77Mw?b(*A6O*jEKyswYKe4igFr8pLKQ;)z(*-jdr=6 zcO~O(YgsWkm;&9E^3`1QxWV7DJnLaI`f6p3I`f#Zv-zdAlCf|m3`wPsswVtU82#%e zV6ubWo>hMtp@C1qT46uX@7Ydr++lZSWoDu&YfD1p6_5zKw=>#bXP4E!)?8{k7R0A? zRw0FsirD+q+45j2q9~SrZREcxXCj{d$_(+@9~4NNnvOw3Ql7R?B%Y8Fni-nE(vqK@ z)}_=Ux^^$DlwFX<5k1fG_3mO#NM|L}K(UQvC>cY3mf9VNk2JImc~!nYFw zZo+CYId`Y-K0H_1_XcPdEc?CAsG}O_%gL1(>^?4nCd3BJ)8UFdg?yTCBT-a`03wLB z`~s*^KCetcAdZA!dISal<7aCJ#*`R$?%aVgT0I>jL13K>-kG#^Y;%o{q`ExCu5sw? zL2}~gu$%rZeXol7!l_eSgrf7K^v_eim3pd<&-zbGDH5=_p0~UdeQ9&W;@-xruO8j` zm)6KPl3KOF@~qQdU})vp8MT?gA}Xb6lQ(Nh5c6DxwQ1kR3v=f`kft`Lo``n!IVXWh zjlFlx@n&`QJ_!CXHio?5)E=;3^2Vc1AwWFllrLU0w*WZH3yh9-gG&3#DsEHrEb(eY4f%X@SvcJq>0;hr`6^ z?K5V4yNsPomENz(2+RR{q4Lbi} z^@x`&-ujxWeXIh{*$_yID0h+(iuTVbh#)%--s6$yjdZWYJp5&?OAr;e=?Df6!IwW; z-&#G26*~ORiOQ>4A=xg{cRdwLY5tCHCI6f#w4H5SD)lZ^v<3)D0i4-O%DYma+^w6@ ziR{qS9^`x%%iYAJ%*J|5e_LCtm-V(n5!+VwAUe99zWWB0!8#PAxv(VQc5+q`W<^Zm zF_VCb5duc}{t3t#hF%USYa$Sy|M>?89iSjE z#Rpu5F9?v=-vxJqKo^Q*>P|DVYBwTHQB)culFE)-&NVyu2E|64uMe)fCecpSF6Z*! ze$B57EvW(usm`b=shwYvY46EwJ7mL{b%Pcq%x6n# znwpwwtF!!VU7Iz!&0$*k^t+2%eZ&rexNuwOx(F>{?cI5i>q59Ut+I;xq(-C&C9!ui z?HJ*A+VXLK4DXz;w?me4R)10v8DTN{k*Z+_n02p1M|a5OS4pa(@pz$$laCCh4@Jev8?(DJPW-0jJf#i9bQ)JGE0LO z-q*&}b@gqsvbJ2hR4uIQu2b_*Fa3Ob_o2NzwxrTNAmfRnq!=+1Z{UlH>r=RKncqN> zU1#iz+^qYii%9PF<%$Dtqn^`8786q4ca(X=sH%R?(aFa+ji>49AFayYILE|pxz z85`naqg>8C7HmDg=A0jLXP|DX;l}rX5zk?RMa9IB5|7fmtjwV*cQ?{Lc6IFMEnMs= zny_K~u3GhKR#o(Z-p*vMYI1w&0 z)Qie&$fF5Fj?Z$VNoE~xPoM5X(cQ}%8F62BH{}Nq-A#*0t+P+nRCn&!xnq~J$l<6X zA`(|`MuaT6F8vwpO7yV0T7NG@u;+Yvy5X5!c`j9%5;=xWz7MhHGys&gC=374#c;^bCD ztyu@wHhF&D&(Ck0&Bq$+nNn=m_bh+s8xRxmZr?D3Cgsobe1F__+D{};b8T!aR{5?@ z7HhkQzo_)}8t_h9jvVSW6b*jS63g}@ccHka_}(eyWJ>c_yH(maB#(M={*CxS*6>~` zRidHq`#)`38EN}#bjvEd55;9)%m?UyR|@L9+gVbOBWK_nUbU`M7Q)BOcSmJJQAJU8 z=jwq2kNI5J-$vEMj8&B*JNN0nTYJ|PZ`_!2YL#EKw3~GB0sit_`c5nWW1N=r-TQdq z^7oj?{}8qy>hqU+cI&^T+AZX_(Y&%%&_R0u5MF0h^4HIK5Bt)etWw;E!J=p7R$jC} zZIz<)YpQJ8XK~Oiybe-XkmFfWZ{Dd7D^xCe^L}$U5;lL(oRW-&F%nA@iWXf>JMXWz zx8;=oQ-8(cvOTyCUoZp#uN+D9La9Z|XC@SOk|7_ZoP8l4rd0%*&UG`*PgN{lo~P^v z(kxOjceY|)0DrL-|0~QD$N}m2S1Q3`t9 z`EIAXNaO>aoM8(CI(uO~MjJ?WQv?zbF3>F62%S?U4a`6u zeE56Nc+ zy4PZB?R{oB3NyA#^7@$%0xauNJ1i$Ru%lHb4*G^$#}esJE{ykRdvCGrX>U*I?~co6 z84N-^vZQj#gN4M%CTvZBV4Wi%7rIVzv5q*%PQ4u$kxJ~JUL1BC_8#S5PT4}n*`bvn zYnH?%YyO^Q{MfRcSgr+Wpmun40xug)rnD#H$sqT@dbm_AQT+kwVUb)?4(TJ+?Gg~El)x5c4;>moUtrR@DtGd2wz1R#6%QpCQ8R9_7d26~`S%?+tS ziRw_y%S^nM! zj~`3JI_mOjCZ=l562+y5#$72&2fM!>6{E-V0WllCvh5)So1#=ry`-yaRzvI7OlDUT z(Iy~mT1|9q{7Su#Z;W-6}UcOk>yxxEJbfQeWFY3v|pE2LII7sn(fgmj&|A_W1W?&SF_{R`Lc@zwvlISBsqk3V#PHlR)L!MP|MXb^U<*O&`) zW7Dz6RtJ5mOu{EoN&viXmk!z1914&_jCr$*mFL+eoRKq5}fb_^G z2IM5K`V;JKJa@t4%RiWAYokV8Y+qS{NBxuk(yT7%!mRY*F`;HIhdUV}=NS7C0r6hF zWeWLvl{UE$gnw$?fsn$>lP(zC$n7b0PI_}|x?)k! zXi&v4e3`EIb;Z5*KY}L9cWsQ0_`$W^S*Q&A%6M*74*sUY(Zt0sPWSt1uETr@JQ5#u z3#G#uupp2VRkXVvO?3O>7>q4AwZ1rPaDA4}`SF!XiiKq_oaRapFxWKR#Kquo?+A5p z-C<0LbitjqLr}W_6XRq=@1I8?b>Gx_x)Sl>4lGEST7%FvWeQsgeH@?9>|((YjvV8; z?%4~F-JFk?`$`2NBJwT&{YO53Bw2jmKklzUsMa(XE1lynl_j1`E z2OyyA_mr^o&07oBn4>P>2hR_K}UzuJ?k zM&G4>E{pN7&4Gs@hHH_7s0Gp+3*o(lhFa0~$fhdJgiCINFX$kv=}P*tRLfYcn}b=A z_kGt=k0!tc`2NaUl}SIo33?90SyFEy^5i-qduhX)-e z3wttK(oDsc+EnN>1aEoeQ+*XcH6<>!B8OCcxFr6(8k<=2sbVKY1O#+ehYWRWY%(v_ zM~VFUh_CqUBxHHxg3pa`eLih@4C~4T_qL0woOB;R3wJR=(M!sE?ld}E!0VTK0g@;8 zsoZ&cUkq01DlF=fCXNSo{63?hA<+-@Y>&|ynoj`FKYkSJM;luFucMy#VN6Wg!p7|C zdiU_`Q^+e3+^iSedTciA!}oSWZPG981B}1c;r;ie?FIRD*Na=s(A{}K0h@PjNE}xAU^4K_NevPhh zbQyQaW$*d(75h)@A(ypzg;*Hyxz?oIqH>R9slYn3LP|KPUrWXKNh3Mt>?8n<@aT63 zW+`a9=}ob$Z+ww;DY0s153hGV2l}IF*HqQ&;IvlKv5fqrUn+!Jn&RG>T58dBmGS!< zcSAmW*A2+nW#W}DC38r+v86?S67B<=Y(D9}aXLfQoYGPDSuae)+*&d3{NYvcP-ajL zVhuNbL}}Xy^YW7{7G9N43w{!0m1ILtc&o2aLtZESzSu_Ljz zd?veo&uwWOgh+|a&VSeoDP-zNf$NObyf^D;WzrWQ3be~_`;L6%oT?2Emn9tJnQ`I& z{i*_&as94+aE#1^+k2_l%MV&qQb^monO^`*qIdo6(|xVKoiE=S2|PLQ{crD;{15~Z zbaA23np+sKAAgk=51VWT_Yvo^K>+F9M%tZw{Zb#e&$+=6*}dlsOQep#^P)nCF`610 z+Ksf`VrA|w;mJtq?|h?2xH&ub{?rz8oiOaWTzn((z4}{GxW3gCRw9pL+-w6*7RhcV zDZ81jFsE;>Wxzmg6hK*&Q?YOnk2(rpi{}m;aDC5O6Nv7XHU9M6+#bWzi%2Blm6sp1 zwjU^J775tZbIC37t(*O|YZuV140$}GAmhB=R9q$V#X$ulBe8#5%d@hCSCUVFTfOj# z>XMOBR&i{vMN+6m44+e}F@#&<{UZ*&<$7h&M>r$orpwQ{q*W~R+p-Q{Y-gqVntl_C zBZJHC_0||eH0<1==`sGh5()5`u3!LhS!#9a=i=HbVhacp|Fgbp^$Xd(5O;fgAJT@t z=Y>=t>=Q2j@{A6tX^t(+t)WE3A>1$LTF+m0={i69!CAP4v%1?vLiKl7R!loppz@ru zTGA1}>xW-;>s-8;sr3)ralraYE4cs86^R?g1FVgqhP%l)<$-lI*=j%ONh&;E_`+6M z*?-xn>zf{N&)ce2m1#EPN{ongfcuqJpyyI}k8t(*tbN~;Rfopr4a3Tq5}|e zKCB`18fHCrjTWc(`5X77@*W}Ds>`Y@_9JpiFv42Af5Ag!@lRH+epD9j9w7Mw6L0bvBaX}h$^$-P%PcW7QIj{gctVCFSD1Rm%0-28^H8l9^f zuv24$R{ehU;U(2qYZQ82ECn6E%m2RTK*^dz$9*ilf8i|!#?_1umKC?(u(PuW|MF2H zw?4(S<8>hLvO+B_0cMZ&`5ydrEufXi*2|)5WDj7+@0DN4Qnj~6p zRa_3A?`0&j^8}?0$3xqXWYzQHD-NS<{Y^naXW-zz8@S(ru3K zG4pzvoavEQyZSHRXOc^7NnZQG|HlDv+84@Xrg-lQ-<=_ScTQJvnaT!k4v=02@3un(>p))W0pTR)z%b~~byxyHvY8- z65ZMJb=^_9$;^xfw*|*v=Co%&P81$0F6VvNCc|T{ck=tgliTlw{LpH4dFkxaLs?O? zPvd?_h%BGm#i`J6{(jqm6MWZiUHnwdJZ~aZ(aS8$$q+f0)v;fIe^~Y)@Ae8Nar=q4 zmu4!aZGFlvsP4SCQ*=qI=bieW;#=#kR~HwPSLVCz-TuC%4sqG;&Gcuptg?CV0Nw7H z_kIQTFG5evSU9wXd-flnT2s6F@XdT`cbzsTE92&I-x2e~^@MHH$Cny5eRz47HI-DJ&G~tat+RGWwMZ_~xbNmY_HKGkb1$ zfk~o&D;ijVE_ZSAoUml=TD#g^4pZ9B>{ljk$W2IHUzSPh!d-?1eS4FjkEWCBtNamFY62#;W3uC2CCAjy)SQG%j{QK;!dNu9H3{ZvY0GiQ-cnlIBLB{qfIc^~ z>Os1_=9Fizney!evw9kL2OtZU!Fg#Y?8@Hh3Mey@Hri2S`VjJKV{{RE$R^_NGm<0=u?J*%GSePc*o~X7oURA~ zxz+b*EnE^gkq%XakiaF3Vf}U#lU0^omWE1U#P3ch94%*oz)Q+S>D2sr#H?GLR++q= zt+1}1b$E#F7}&@q!dNf+0vAT@f&MLoh_DJ-j}$d*4j7J;CuYzeKcRk=Wr#-2u~K|a z=Fd5$I(1g8vp(kunNCDJk9jlLB@C_CKX{HwJ;)od)W!K5WyLCqfi{6myE$b-@a9MU zbPl>$RaNx*2zzW41k2%YdR4kdePo9*GU6Ao=9p=-G&<#ad74iB@rER% zr7&^)iJXyYpjN(|vLJ9;bH#6H7IeNBrf`<#EMp_rq2|)tRc2br@lK31l6+ z7@vw0gAFi|U8o_F$ZhDLK{l*F0z_cT8! zko>+Xv7wg5$Jp5U8nFN%rXt2C%m$7$VHC!TD~H{;??=p|WYRocc`qA?bi_s8uH0LZoTOzGmLW$c#AfXtKyV57>nX<<|Z4pjMah65f_KrQX>EQ+h=#B)FK87uXB!y zntP1-G8|~gLsxyPnws|3wVG=C*M1Jy!%w=qw_RPMHh5L-+a}D-H$whbVo;ggeDR>$ Sc@)f6gO?A+-@D2)H2EJTf^Yo* literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_top_left/expected_curved_auto_leaving_labels_at_top_left.png b/tests/testdata/control_images/callouts/expected_curved_auto_leaving_labels_at_top_left/expected_curved_auto_leaving_labels_at_top_left.png new file mode 100644 index 0000000000000000000000000000000000000000..236f6c948c36fe730d77152cea1261c26dec7f2b GIT binary patch literal 62079 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 Pp3bnHYm;K_yz74f*lP^W literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/callouts/expected_curved_counterclockwise/expected_curved_counterclockwise.png b/tests/testdata/control_images/callouts/expected_curved_counterclockwise/expected_curved_counterclockwise.png new file mode 100644 index 0000000000000000000000000000000000000000..9f73e605b09284f6081f7b23218173b4b72d0d20 GIT binary patch literal 60876 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

cqb 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 literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/callouts/expected_curved_curvature/expected_curved_curvature.png b/tests/testdata/control_images/callouts/expected_curved_curvature/expected_curved_curvature.png new file mode 100644 index 0000000000000000000000000000000000000000..e64838df3b190257b979d181962568c8858bc40e GIT binary patch literal 63752 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 literal 0 HcmV?d00001 From 8672f06549c543f19a814429676170bde5c8d723 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 19 Mar 2021 14:36:04 +1000 Subject: [PATCH 135/377] Spelling --- .../core/auto_generated/geometry/qgsgeometryutils.sip.in | 2 +- src/core/geometry/qgsgeometryutils.cpp | 8 ++++---- src/core/geometry/qgsgeometryutils.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python/core/auto_generated/geometry/qgsgeometryutils.sip.in b/python/core/auto_generated/geometry/qgsgeometryutils.sip.in index 00cac788722c..50c46432ad34 100644 --- a/python/core/auto_generated/geometry/qgsgeometryutils.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometryutils.sip.in @@ -502,7 +502,7 @@ Averages two angles, correctly handling negative angles and ensuring the result %Docstring Returns a number representing the closest side of a rectangle defined by /a right, ``bottom``, ``left``, ``top`` to the point at (``x``, ``y``), where -the point may be in ther interior of the rectangle or outside it. +the point may be in the interior of the rectangle or outside it. The returned value may be: diff --git a/src/core/geometry/qgsgeometryutils.cpp b/src/core/geometry/qgsgeometryutils.cpp index ade16a1d3048..14af3ed00a7a 100644 --- a/src/core/geometry/qgsgeometryutils.cpp +++ b/src/core/geometry/qgsgeometryutils.cpp @@ -638,14 +638,14 @@ void QgsGeometryUtils::perpendicularOffsetPointAlongSegment( double x1, double y const double mY = y1 + ( y2 - y1 ) * proportion; const double pX = x1 - x2; const double pY = y1 - y2; - double normalX = -pY; + double normalX = -pY; //#spellok double normalY = pX; - const double normalLength = sqrt( ( normalX * normalX ) + ( normalY * normalY ) ); - normalX /= normalLength; + const double normalLength = sqrt( ( normalX * normalX ) + ( normalY * normalY ) ); //#spellok + normalX /= normalLength; //#spellok normalY /= normalLength; *x = mX + offset * normalX; - *y = mY + offset * normalY; + *y = mY + offset * normalY; //#spellok } QgsPoint QgsGeometryUtils::interpolatePointOnArc( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance ) diff --git a/src/core/geometry/qgsgeometryutils.h b/src/core/geometry/qgsgeometryutils.h index 9713d9a55777..e8b4358f8275 100644 --- a/src/core/geometry/qgsgeometryutils.h +++ b/src/core/geometry/qgsgeometryutils.h @@ -550,7 +550,7 @@ class CORE_EXPORT QgsGeometryUtils /** * Returns a number representing the closest side of a rectangle defined by /a right, * \a bottom, \a left, \a top to the point at (\a x, \a y), where - * the point may be in ther interior of the rectangle or outside it. + * the point may be in the interior of the rectangle or outside it. * * The returned value may be: * From 84dc7944391fc89e99c5e63f2e76b538a22c6891 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 19 Mar 2021 14:50:28 +1000 Subject: [PATCH 136/377] Spell again --- src/core/geometry/qgsgeometryutils.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/geometry/qgsgeometryutils.cpp b/src/core/geometry/qgsgeometryutils.cpp index 14af3ed00a7a..cc8533f585ad 100644 --- a/src/core/geometry/qgsgeometryutils.cpp +++ b/src/core/geometry/qgsgeometryutils.cpp @@ -638,11 +638,11 @@ void QgsGeometryUtils::perpendicularOffsetPointAlongSegment( double x1, double y const double mY = y1 + ( y2 - y1 ) * proportion; const double pX = x1 - x2; const double pY = y1 - y2; - double normalX = -pY; //#spellok - double normalY = pX; + double normalX = -pY; + double normalY = pX; //#spellok const double normalLength = sqrt( ( normalX * normalX ) + ( normalY * normalY ) ); //#spellok - normalX /= normalLength; //#spellok - normalY /= normalLength; + normalX /= normalLength; + normalY /= normalLength; //#spellok *x = mX + offset * normalX; *y = mY + offset * normalY; //#spellok From 79cd4450d84a5b743091b3f18dac268f8162a1e9 Mon Sep 17 00:00:00 2001 From: Hannes Date: Fri, 19 Mar 2021 14:44:42 +0100 Subject: [PATCH 137/377] Minor cleanup of INSTALL.md - Remove extra indentation of code blocks that made copy'n'pasting ugly - Probably fixed in indentation bug for `~/.config/QtProject/qtlogging.ini` - Some homogenization of code markup, didn't look through all parts of the document though - Turn inline comments into actual `#` comments - In Server part: - Use "example.com" for example domains - Be more explicite about paths - I also tried to fix some formatting markup --- INSTALL.md | 478 ++++++++++++++++++++++++++--------------------------- 1 file changed, 236 insertions(+), 242 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index d46b9eb2b56d..ff48e5e846fc 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -161,7 +161,7 @@ to you. The packages QGIS depends on to build are available in the "universe" component of Ubuntu. This is not activated by default, so you need to activate it: -1. Edit your /etc/apt/sources.list file. +1. Edit your `/etc/apt/sources.list` file. 2. Uncomment all the lines starting with "deb" Also you will need a recent enough distribution in order for all dependencies @@ -170,19 +170,19 @@ to be met. The supported distributions are listed in the following section. Now update your local sources database: ```bash - sudo apt-get update +sudo apt-get update ``` ## 3.3. Install build dependencies |Distribution|Install command for packages| |------------|----------------------------| -| buster | ``apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb`` | -| bullseye | ``apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb`` | -| bionic | ``apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb`` | -| focal | ``apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb`` | -| groovy | ``apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb`` | -| sid | ``apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga sip5-tools spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb`` | +| buster | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb` | +| bullseye | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb` | +| bionic | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb` | +| focal | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb` | +| groovy | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb` | +| sid | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga sip5-tools spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb`` | (extracted from the control.in file in `debian/`) @@ -195,9 +195,9 @@ and we build with GDAL2 from ubuntugis). You should also setup ccache to speed up compile times: ```bash - cd /usr/local/bin - sudo ln -s /usr/bin/ccache gcc - sudo ln -s /usr/bin/ccache g++ +cd /usr/local/bin +sudo ln -s /usr/bin/ccache gcc +sudo ln -s /usr/bin/ccache g++ ``` or simply add `/usr/lib/ccache` to your `PATH`. @@ -209,8 +209,8 @@ this case we will create a work environment for C++ development work like this: ```bash - mkdir -p ${HOME}/dev/cpp - cd ${HOME}/dev/cpp +mkdir -p ${HOME}/dev/cpp +cd ${HOME}/dev/cpp ``` This directory path will be assumed for all instructions that follow. @@ -219,21 +219,21 @@ This directory path will be assumed for all instructions that follow. There are two ways the source can be checked out. Use the anonymous method if you do not have edit privileges for the QGIS source repository, or use - the developer checkout if you have permissions to commit source code - changes. +the developer checkout if you have permissions to commit source code +changes. 1. Anonymous Checkout ```bash - cd ${HOME}/dev/cpp - git clone git://github.com/qgis/QGIS.git +cd ${HOME}/dev/cpp +git clone git://github.com/qgis/QGIS.git ``` 2. Developer Checkout ```bash - cd ${HOME}/dev/cpp - git clone git@github.com:qgis/QGIS.git +cd ${HOME}/dev/cpp +git clone git@github.com:qgis/QGIS.git ``` ## 3.7. Starting the compile @@ -244,16 +244,16 @@ you can use the binary packages of QGIS on your system along side with your development version. I suggest you do something similar: ```bash - mkdir -p ${HOME}/apps +mkdir -p ${HOME}/apps ``` Now we create a build directory and run ccmake: ```bash - cd QGIS - mkdir build-master - cd build-master - ccmake .. +cd QGIS +mkdir build-master +cd build-master +ccmake .. ``` When you run ccmake (note the .. is required!), a menu will appear where @@ -277,7 +277,7 @@ the empty build directory once before starting to use the interactive tools. Now on with the build: ```bash - make -jX +make -jX ``` where X is the number of available cores. Depending on your platform, @@ -285,59 +285,59 @@ this can speed up the build time considerably. Then you can directly run from the build directory: ```bash - ./output/bin/qgis +./output/bin/qgis ``` Another option is to install to your system: ```bash - make install +make install ``` After that you can try to run QGIS: ```bash - $HOME/apps/bin/qgis +$HOME/apps/bin/qgis ``` If all has worked properly the QGIS application should start up and appear on your screen. If you get the error message "error while loading shared libraries", execute this command in your shell. ```bash - sudo ldconfig +sudo ldconfig ``` If that doesn't help add the install path to LD_LIBRARY_PATH: ```bash - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/apps/lib/ +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/apps/lib/ ``` Optionally, if you already know what aspects you want in your custom build then you can skip the interactive ccmake .. part by using the cmake -D option for each aspect, e.g.: ```bash - cmake -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX=${HOME}/apps .. +cmake -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX=${HOME}/apps .. ``` Also, if you want to speed your build times, you can easily do it with ninja, an alternative to make with similar build options. For example, to configure your build you can do either one of: ```bash - ccmake -G Ninja .. - cmake -G Ninja -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX=${HOME}/apps .. +ccmake -G Ninja .. +cmake -G Ninja -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX=${HOME}/apps .. ``` Build and install with ninja: ```bash - ninja (uses all cores by default; also supports the above described -jX option) - ninja install +ninja # (uses all cores by default; also supports the above described -jX option) +ninja install ``` To build even faster, you can build just the targets you need using, for example: ```bash - ninja qgis - ninja pycore - # if it's on desktop related code only: - ninja qgis_desktop +ninja qgis +ninja pycore +# if it's on desktop related code only: +ninja qgis_desktop ``` ## 3.8. Compiling with 3D In the cmake, you need to enable: ```bash - WITH_3D=True +WITH_3D=True ``` ### 3.8.1. Compiling with 3D on Debian based distributions @@ -348,9 +348,9 @@ QGIS repository in `external/qt3dextra-headers`. To compile with 3D enabled, you need to add some cmake options: ```bash - CMAKE_PREFIX_PATH={path to QGIS Git repo}/external/qt3dextra-headers/cmake - QT5_3DEXTRA_INCLUDE_DIR={path to QGIS Git repo}/external/qt3dextra-headers - QT5_3DEXTRA_LIBRARY=/usr/lib/x86_64-linux-gnu/libQt53DExtras.so +CMAKE_PREFIX_PATH={path to QGIS Git repo}/external/qt3dextra-headers/cmake +QT5_3DEXTRA_INCLUDE_DIR={path to QGIS Git repo}/external/qt3dextra-headers +QT5_3DEXTRA_LIBRARY=/usr/lib/x86_64-linux-gnu/libQt53DExtras.so ``` ## 3.9. Building different branches @@ -360,13 +360,13 @@ several sources in parallel, based on the same Git configuration. We recommend you to read the documentation about this Git command: ```bash - git commit - git worktree add ../my_new_functionality - cd ../my_new_functionality - git fetch qgis/master - git rebase -i qgis/master - # only keep the commits to be pushed - git push -u my_own_repo my_new_functionality +git commit +git worktree add ../my_new_functionality +cd ../my_new_functionality +git fetch qgis/master +git rebase -i qgis/master +# only keep the commits to be pushed +git push -u my_own_repo my_new_functionality ``` ## 3.10. Building Debian packages @@ -378,20 +378,20 @@ you'll find a debian directory. First you need to install the debian packaging tools once: ```bash - apt-get install build-essential +apt-get install build-essential ``` First you need to create an changelog entry for your distribution. For example for Ubuntu Precise: ```bash - dch -l ~precise --force-distribution --distribution precise "precise build" +dch -l ~precise --force-distribution --distribution precise "precise build" ``` The QGIS packages will be created with: ```bash - dpkg-buildpackage -us -uc -b +dpkg-buildpackage -us -uc -b ``` **Note:** Install `devscripts` to get `dch`. @@ -405,14 +405,14 @@ build conflict. **Note:** By default tests are run in the process of building and their results are uploaded to https://cdash.orfeo-toolbox.org/index.php?project=QGIS. -You can turn the tests off using DEB_BUILD_OPTIONS=nocheck in front of the -build command. The upload of results can be avoided with DEB_TEST_TARGET=test. +You can turn the tests off using `DEB_BUILD_OPTIONS=nocheck` in front of the +build command. The upload of results can be avoided with `DEB_TEST_TARGET=test`. The packages are created in the parent directory (ie. one level up). -Install them using dpkg. E.g.: +Install them using `dpkg`. E.g.: ```bash - sudo debi +sudo debi ``` ## 3.11. On Fedora Linux @@ -424,13 +424,13 @@ new subdirectory called `build` or `build-qt5` in it. |Install command for dependencies| |--------------------------------| -|dnf install qt5-qtbase-private-devel qt5-qtwebkit-devel qt5-qtlocation-devel qt5-qttools-static qca-qt5-devel qca-qt5-ossl qt5-qt3d-devel python3-qt5-devel python3-qscintilla-qt5-devel qscintilla-qt5-devel python3-qscintilla-devel python3-qscintilla-qt5 clang flex bison geos-devel gdal-devel sqlite-devel libspatialite-devel qt5-qtsvg-devel spatialindex-devel expat-devel proj-devel qwt-qt5-devel gsl-devel postgresql-devel cmake python3-future gdal-python3 python3-psycopg2 python3-PyYAML python3-pygments python3-jinja2 python3-OWSLib qca-qt5-ossl qwt-qt5-devel qtkeychain-qt5-devel qwt-devel sip-devel libzip-devel exiv2-devel| +|`dnf install qt5-qtbase-private-devel qt5-qtwebkit-devel qt5-qtlocation-devel qt5-qttools-static qca-qt5-devel qca-qt5-ossl qt5-qt3d-devel python3-qt5-devel python3-qscintilla-qt5-devel qscintilla-qt5-devel python3-qscintilla-devel python3-qscintilla-qt5 clang flex bison geos-devel gdal-devel sqlite-devel libspatialite-devel qt5-qtsvg-devel spatialindex-devel expat-devel proj-devel qwt-qt5-devel gsl-devel postgresql-devel cmake python3-future gdal-python3 python3-psycopg2 python3-PyYAML python3-pygments python3-jinja2 python3-OWSLib qca-qt5-ossl qwt-qt5-devel qtkeychain-qt5-devel qwt-devel sip-devel libzip-devel exiv2-devel`| To build QGIS server additional dependencies are required: ```bash - dnf install fcgi-devel +dnf install fcgi-devel ``` Make sure that your build directory is completely empty when you enter the @@ -440,27 +440,27 @@ command in the empty build directory once before starting to use the interactive tools. ```bash - cmake .. +cmake .. ``` -If everything went OK you can finally start to compile. (As usual append a -jX +If everything went OK you can finally start to compile. (As usual append a `-jX` where X is the number of available cores option to make to speed up your build process) ```bash - make +make ``` Run from the build directory ```bash - ./output/bin/qgis +./output/bin/qgis ``` Or install to your system ```bash - make install +make install ``` ### 3.11.2. Suggested system tweaks @@ -471,10 +471,10 @@ the useful debug output which is normally printed when running the unit tests. To enable debug prints for the current user, execute: ```bash - cat > ~/.config/QtProject/qtlogging.ini << EOL - [Rules] - default.debug=true - EOL +cat > ~/.config/QtProject/qtlogging.ini << EOL +[Rules] +default.debug=true +EOL ``` # 4. Building on Windows @@ -503,7 +503,7 @@ Download and install following packages: * [CMake](https://cmake.org/files/v3.12/cmake-3.12.3-win64-x64.msi) * GNU flex, GNU bison and GIT with cygwin [32bit](https://cygwin.com/setup-x86.exe) or [64bit](https://cygwin.com/setup-x86_64.exe) * OSGeo4W [32bit](https://download.osgeo.org/osgeo4w/osgeo4w-setup-x86.exe) or [64bit](https://download.osgeo.org/osgeo4w/osgeo4w-setup-x86_64.exe) -* [ninja](https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-win.zip) +* [ninja](https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-win.zip): Copy the `ninja.exe` to `C:\OSGeo4W64\bin\` For the QGIS build you need to install following packages from cygwin: @@ -515,27 +515,24 @@ and from OSGeo4W (select *Advanced Install*): * qgis-dev-deps -This will also select packages the above packages depend on. + * This will also select packages the above packages depend on. - If you install other packages, this might cause issues. Particularly, make sure - **not** to install the msinttypes package. It installs a stdint.h file in - OSGeo4W[64]\include, that conflicts with Visual Studio own stdint.h, which for - example breaks the build of the virtual layer provider. + * Note: If you install other packages, this might cause issues. Particularly, make sure + **not** to install the msinttypes package. It installs a stdint.h file in + OSGeo4W[64]\include, that conflicts with Visual Studio own stdint.h, which for + example breaks the build of the virtual layer provider. Earlier versions of this document also covered how to build all above dependencies. If you're interested in that, check the history of this page in the Wiki or the SVN repository. -ninja: - copy ninja.exe to C:\OSGeo4W64\bin\ - ### 4.1.3. Clone the QGIS Source Code Choose a directory to store the QGIS source code. For example, to put it in the OSGeo4W64 install, navigate there: ```cmd - cd C:\OSGeo4W64 +cd C:\OSGeo4W64 ``` This directory will be assumed for all instructions @@ -545,7 +542,7 @@ On the command prompt clone the QGIS source from git to the source directory `QGIS`: ```cmd - git clone git://github.com/qgis/QGIS.git +git clone git://github.com/qgis/QGIS.git ``` This requires Git. If you have Git for Windows on your PATH already, @@ -556,8 +553,8 @@ a Cygwin[64] Terminal And, to avoid Git in Windows reporting changes to files not actually modified: ```cmd - cd QGIS - git config core.filemode false +cd QGIS +git config core.filemode false ``` ### 4.1.4. Configure and build with CMake from command line @@ -572,96 +569,95 @@ variables create the following batch file (assuming the above packages were installed in the default locations): ```cmd - @echo off - call C:\OSGeo4W64\QGIS\ms-windows\osgeo4w\msvc-env.bat x86_64 - @cmd +@echo off +call C:\OSGeo4W64\QGIS\ms-windows\osgeo4w\msvc-env.bat x86_64 +@cmd ``` Save the batch file as `C:\OSGeo4W64\OSGeo4W-dev.bat` and run it. #### 4.1.4.1 Using configonly.bat to create the MSVC solution file - We will be using the file `ms-windows/osgeo4w/configonly.bat` to create an MSVC solution file. - There are two supported CMake generators for creating a solution file: Ninja, and native MSVC. - The advantage of using native MSVC solution is that you can find the root of build problems much more easily. - configonly.bat is meant to create a configured build directory with a MSVC solution file: +We will be using the file `ms-windows/osgeo4w/configonly.bat` to create an MSVC solution file. +There are two supported CMake generators for creating a solution file: Ninja, and native MSVC. +The advantage of using native MSVC solution is that you can find the root of build problems much more easily. +configonly.bat is meant to create a configured build directory with a MSVC solution file: ```cmd - cd C:\OSGeo4W64\QGIS\ms-windows\osgeo4w - configonly.bat +cd C:\OSGeo4W64\QGIS\ms-windows\osgeo4w +configonly.bat ``` #### 4.1.4.2 Compiling QGIS with MSVC - We will need to run MSVC with all the environment variables set, thus we will run it as follows: - Run the batch file OSGeo4W-dev.bat you created before. - On the command prompt run `call gdal-dev-env.bat` to add the release gdal and proj libraries to your PATH. - On the command prompt run `devenv` to open MSVC. - From MSVC, open the solution file - `C:\OSGeo4W64\QGIS\ms-windows\osgeo4w\build-qgis-test-x86_64\qgis.sln`. - Try to build the solution (go grab a cup of tea, it may take a while). - If it fails, run it again and again until there are (hopefully) no errors. +We will need to run MSVC with all the environment variables set, thus we will run it as follows: +* Run the batch file OSGeo4W-dev.bat you created before. +* On the command prompt run `call gdal-dev-env.bat` to add the release gdal and proj libraries to your PATH. +* On the command prompt run `devenv` to open MSVC. +* From MSVC, open the solution file `C:\OSGeo4W64\QGIS\ms-windows\osgeo4w\build-qgis-test-x86_64\qgis.sln`. +* Try to build the solution (go grab a cup of tea, it may take a while). +* If it fails, run it again and again until there are (hopefully) no errors. Running QGIS from within MSVC: - Edit the properties of the project ALL_BUILD to include the path to the executable: - Debugging -> Command -> `C:\OSGeo4W64\QGIS\ms-windows\osgeo4w\build-qgis-test-x86_64\output\bin\RelWithDebInfo\qgis.exe`. - To run, use the menu commands: Debug -> Start Debugging (F5) or Start Without Debugging (Ctrl+F5). - Ignore the "These projects are out of date" message, it appears even if no files were changed. +* Edit the properties of the project ALL_BUILD to include the path to the executable: +* Debugging -> Command -> `C:\OSGeo4W64\QGIS\ms-windows\osgeo4w\build-qgis-test-x86_64\output\bin\RelWithDebInfo\qgis.exe`. +* To run, use the menu commands: Debug -> Start Debugging (F5) or Start Without Debugging (Ctrl+F5). +* Ignore the "These projects are out of date" message, it appears even if no files were changed. ### 4.1.5 Old alternative method that might still work using cmake-gui - Create a 'build' directory somewhere. This will be where all the build output - will be generated. +Create a 'build' directory somewhere. This will be where all the build output +will be generated. - Now run `cmake-gui` (still from `cmd`) and in the *Where is the source code:* - box, browse to the top level QGIS directory. +Now run `cmake-gui` (still from `cmd`) and in the *Where is the source code:* +box, browse to the top level QGIS directory. - In the *Where to build the binaries:* box, browse to the 'build' directory you - created. +In the *Where to build the binaries:* box, browse to the `build` directory you +created. - If the path to bison and flex contains blanks, you need to use the short name - for the directory (i.e. `C:\Program Files` should be rewritten to - `C:\Progra~n`, where `n` is the number as shown in `dir /x C:\``). +If the path to bison and flex contains blanks, you need to use the short name +for the directory (i.e. `C:\Program Files` should be rewritten to +`C:\Progra~n`, where `n` is the number as shown in `dir /x C:\`). - Verify that the 'BINDINGS_GLOBAL_INSTALL' option is not checked, so that python - bindings are placed into the output directory when you run the INSTALL target. +Verify that the `BINDINGS_GLOBAL_INSTALL` option is not checked, so that python +bindings are placed into the output directory when you run the `INSTALL` target. - Hit `Configure` to start the configuration and select `Visual Studio 9 2008` - and keep `native compilers` and click `Finish`. +Hit `Configure` to start the configuration and select `Visual Studio 9 2008` +and keep `native compilers` and click `Finish`. - The configuration should complete without any further questions and allow you to - click `Generate`. +The configuration should complete without any further questions and allow you to +click `Generate`. - Now close `cmake-gui` and continue on the command prompt by starting - `vcexpress`. Use File / Open / Project/Solutions and open the - qgis-x.y.z.sln File in your project directory. +Now close `cmake-gui` and continue on the command prompt by starting +`vcexpress`. Use File / Open / Project/Solutions and open the +qgis-x.y.z.sln File in your project directory. - Change `Solution Configuration` from `Debug` to `RelWithDebInfo` (Release - with Debug Info) or `Release` before you build QGIS using the ALL_BUILD - target (otherwise you need debug libraries that are not included). +Change `Solution Configuration` from `Debug` to `RelWithDebInfo` (Release +with Debug Info) or `Release` before you build QGIS using the `ALL_BUILD` +target (otherwise you need debug libraries that are not included). - After the build completed you should install QGIS using the INSTALL target. +After the build completed you should install QGIS using the `INSTALL` target. - Install QGIS by building the INSTALL project. By default this will install to - c:\Program Files\qgis (this can be changed by changing the - CMAKE_INSTALL_PREFIX variable in cmake-gui). +Install QGIS by building the `INSTALL` project. By default this will install to +`C:\Program Files\qgis` (this can be changed by changing the +`CMAKE_INSTALL_PREFIX` variable in `cmake-gui`). - You will also either need to add all the dependency DLLs to the QGIS install - directory or add their respective directories to your PATH. +You will also either need to add all the dependency DLLs to the QGIS install +directory or add their respective directories to your `PATH`. ### 4.1.6. Packaging -To create a standalone installer there is a perl script named 'creatensis.pl' -in 'qgis/ms-windows/osgeo4w'. It downloads all required packages from OSGeo4W +To create a standalone installer there is a perl script named `creatensis.pl` +in `qgis/ms-windows/osgeo4w`. It downloads all required packages from OSGeo4W and repackages them into an installer using NSIS. The script can be run on both Windows and Linux. -On Debian/Ubuntu you can just install the 'nsis' package. +On Debian/Ubuntu you can just install the `nsis` package. NSIS for Windows can be downloaded at: https://nsis.sourceforge.io/Main_Page -And Perl for Windows (including other requirements like 'wget', 'unzip', 'tar' -and 'bzip2') is available at: +And Perl for Windows (including other requirements like `wget`, `unzip`, `tar` +and `bzip2`) is available at: https://cygwin.com @@ -673,15 +669,15 @@ windows installation into the ms-windows file tree created by the creatensis script. ```cmd - cd ms-windows/ - rm -rf osgeo4w/unpacked/apps/qgis/* - cp -r /tmp/qgis1.7.0/* osgeo4w/unpacked/apps/qgis/ +cd ms-windows/ +rm -rf osgeo4w/unpacked/apps/qgis/* +cp -r /tmp/qgis1.7.0/* osgeo4w/unpacked/apps/qgis/ ``` Now create a package. ```cmd - ./quickpackage.sh +./quickpackage.sh ``` After this you should now have a nsis installer containing your own build @@ -701,7 +697,7 @@ in a Docker container. To build on Linux from your QGIS sources directory, launch: ```cmd - ms-windows/mingw/build.sh +ms-windows/mingw/build.sh ``` After a successful build, you will find two packages in the QGIS sources @@ -767,14 +763,14 @@ speed up compilation, but it's not automatic. Whenever you type "make" (but NOT "make install"), instead type: ```bash - make -j [#cpus] +make -j [#cpus] ``` Replace [#cpus] with the number of cores and/or processors your Mac has. To find out how many CPUs you have available, run the following in Terminal: ```bash - /usr/sbin/sysctl -n hw.ncpu +/usr/sbin/sysctl -n hw.ncpu ``` ## 5.1. Install Developer Tools @@ -783,7 +779,7 @@ Developer tools are not a part of a standard OS X installation. As minimum you require command line tools ```bash - sudo xcode-select --install +sudo xcode-select --install ``` but installation of Xcode from the App Store is recommended too. @@ -793,7 +789,7 @@ but installation of Xcode from the App Store is recommended too. For example install Homebrew ```bash - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" ``` and these development/build tools @@ -843,7 +839,7 @@ select Download .tar.gz. Double-click the tarball to unzip it. *Alternatively*, use git and clone the repository by ```bash - git clone git://github.com/qgis/QGIS.git +git clone git://github.com/qgis/QGIS.git ``` ## 5.5. Configure the build @@ -857,19 +853,19 @@ below assume you are building into a ${HOME}/Applications directory. In a Terminal cd to the qgis source folder previously downloaded, then: ```bash - cd .. - mkdir build - cd build +cd .. +mkdir build +cd build - QGIS_DEPS_VERSION=0.3.0;\ - QT_VERSION=5.14.1;\ - PATH=/opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}/stage/bin:$PATH;\ - cmake \ - -DCMAKE_INSTALL_PREFIX=~/Applications \ - -DCMAKE_BUILD_TYPE=Release \ - -DQGIS_MAC_DEPS_DIR=/opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}/stage \ - -DCMAKE_PREFIX_PATH=/opt/Qt/${QT_VERSION}/clang_64 \ - ../QGIS +QGIS_DEPS_VERSION=0.3.0;\ +QT_VERSION=5.14.1;\ +PATH=/opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}/stage/bin:$PATH;\ +cmake \ + -DCMAKE_INSTALL_PREFIX=~/Applications \ + -DCMAKE_BUILD_TYPE=Release \ + -DQGIS_MAC_DEPS_DIR=/opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}/stage \ + -DCMAKE_PREFIX_PATH=/opt/Qt/${QT_VERSION}/clang_64 \ + ../QGIS ``` Note: Don't forget the `../QGIS` on the last line, which tells CMake to look for the source files. @@ -881,8 +877,8 @@ Especially check Proj, GDAL, sqlite3 and Python paths. After the initial Terminal configure, you can use ccmake to make further changes: ```bash - cd build - ccmake ../QGIS +cd build +ccmake ../QGIS ``` ## 5.6. Building @@ -891,7 +887,7 @@ Now we can start the build process (remember the parallel compilation note at the beginning, this is a good place to use it, if you can): ```bash - make -j [#cpus] +make -j [#cpus] ``` Now you can run the QGIS from build directory by `./output/bin/QGIS.app/Contents/MacOS/QGIS` @@ -899,13 +895,13 @@ Now you can run the QGIS from build directory by `./output/bin/QGIS.app/Contents If all built without errors you can then install it: ```bash - make install +make install ``` or, for an /Applications build: ```bash - sudo make install +sudo make install ``` For running the installed QGIS, you need to keep the dependencies in `/opt/` folder in place. @@ -926,106 +922,107 @@ Note the git repo below will change to the default QGIS repo once this work is integrated into master. ```bash - git remote add blazek git://github.com/blazek/Quantum-GIS.git - git fetch blazek - git branch --track wcs2 blazek/wcs2 - git checkout wcs2 - cd /var/www/ - sudo mkdir wcs - sudo chown timlinux wcs - cd wcs/ - mkdir cgi-bin - cd cgi-bin/ +git remote add blazek git://github.com/blazek/Quantum-GIS.git +git fetch blazek +git branch --track wcs2 blazek/wcs2 +git checkout wcs2 +cd /var/www/ +sudo mkdir wcs +sudo chown timlinux wcs +cd wcs/ +mkdir cgi-bin +cd cgi-bin/ ``` ## 6.2. Setup mapserver ```bash - sudo apt-get install cgi-mapserver +sudo apt-get install cgi-mapserver ``` -Set the contents of cgi-bin/wcstest-1.9.0 to: +Set the contents of `/var/www/wcs/cgi-bin/wcstest-1.9.0` to: ```bash - #! /bin/sh - MS_MAPFILE=/var/www/wcs/testdata/qgis-1.9.0/raster/wcs.map - export MS_MAPFILE - /usr/lib/cgi-bin/mapserv +#! /bin/sh +MS_MAPFILE=/var/www/wcs/testdata/qgis-1.9.0/raster/wcs.map +export MS_MAPFILE +/usr/lib/cgi-bin/mapserv ``` Then do: ```bash - chmod +x cgi-bin/wcstest-1.9.0 - mkdir -p /var/www/wcs/testdata/qgis-1.9.0/raster/ - cd /var/www/wcs/testdata/qgis-1.9.0/raster/ - cp -r /home/timlinux/QGIS/tests/testdata/raster/* . +chmod +x var/www/wcs/cgi-bin/wcstest-1.9.0 +mkdir -p /var/www/wcs/testdata/qgis-1.9.0/raster/ +cd /var/www/wcs/testdata/qgis-1.9.0/raster/ +cp -r /home/timlinux/QGIS/tests/testdata/raster/* . ``` -Edit wcs.map and set the shapepath to this: +Edit `/var/www/wcs/testdata/qgis-1.9.0/raster/wcs.map` and set the shapepath to this: ```bash - SHAPEPATH "/var/www/wcs/testdata/qgis-1.9.0/raster" +SHAPEPATH "/var/www/wcs/testdata/qgis-1.9.0/raster" ``` -Then create /var/www/wcs/7-wcs.qgis.org.conf setting the contents to this: +Then create `/var/www/wcs/7-wcs.example.com.conf` setting the contents to this: ```bash - - ServerName wcs.qgis.org - ServerAdmin tim@linfiniti.com + +ServerName wcs.example.com +ServerAdmin wcs-admin@example.com - LogLevel warn - LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{forensic-id}n\"" combined - CustomLog /var/log/apache2/wcs_qgis.org/access.log combined - ErrorLog /var/log/apache2/wcs_qgis.org/error.log +LogLevel warn +LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{forensic-id}n\"" combined +CustomLog /var/log/apache2/wcs_example.com/access.log combined +ErrorLog /var/log/apache2/wcs_example.com/error.log - DocumentRoot /var/www/wcs/html +DocumentRoot /var/www/wcs/html - ScriptAlias /cgi-bin/ /var/www/wcs/cgi-bin/ - - AllowOverride None - Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch - Order allow,deny - Allow from all - +ScriptAlias /cgi-bin/ /var/www/wcs/cgi-bin/ + + AllowOverride None + Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch + Order allow,deny + Allow from all + - RewriteEngine on - RewriteRule /1.9.0/wcs /cgi-bin/wcstest-1.9.0 [PT] +RewriteEngine on +RewriteRule /1.9.0/wcs /cgi-bin/wcstest-1.9.0 [PT] - + ``` ## 6.3. Create a home page ```bash - mkdir html - vim html/index.html +mkdir html +vim html/index.html ``` Set the contents to: - - This is the test platform for QGIS' wcs client. You can use these services - from QGIS directly (to try out WCS for example) by pointing your QGIS to: - http://wcs.qgis.org/1.9.0/wcs +``` +This is the test platform for QGIS' wcs client. You can use these services +from QGIS directly (to try out WCS for example) by pointing your QGIS to: +http://wcs.example.com/1.9.0/wcs +``` ## 6.4. Now deploy it ```bash - sudo mkdir /var/log/apache2/wcs_qgis.org - sudo chown www-data /var/log/apache2/wcs_qgis.org - cd /etc/apache2/sites-available/ - sudo ln -s /var/www/wcs/7-wcs.qgis.org.conf . - cd /var/www/wcs/ - sudo a2ensite 7-wcs.qgis.org.conf - sudo /etc/init.d/apache2 reload +sudo mkdir /var/log/apache2/wcs_example.com +sudo chown www-data /var/log/apache2/wcs_example.com +cd /etc/apache2/sites-available/ +sudo ln -s /var/www/wcs/7-wcs.example.com.conf . +cd /var/www/wcs/ +sudo a2ensite 7-wcs.example.com.conf +sudo /etc/init.d/apache2 reload ``` ## 6.5. Debugging ```bash - sudo tail -f /var/log/apache2/wcs_qgis.org/error.log +sudo tail -f /var/log/apache2/wcs_example.com/error.log ``` # 7. Setting up a Jenkins Build Server @@ -1074,26 +1071,23 @@ Jenkins security to per project settings) * Set the github project to https://github.com/qgis/QGIS/ * Set source code management to Git * Set repository url to git://github.com/qgis/QGIS.git - * In advanced repository url settings set refspec to : - - +refs/heads/master:refs/remotes/origin/master - + * In advanced repository url settings set refspec to `+refs/heads/master:refs/remotes/origin/master` * Set branch to build to master * Repository Browser: Auto * Build triggers: set to Poll SCM and set schedule to `*****` (polls every minute) * Build - Execute shell and set shell script to: ```bash - cd build - cmake .. - xvfb-run --auto-servernum --server-num=1 \ - --server-args="-screen 0 1024x768x24" \ - make Experimental || true - if [ -f Testing/TAG ] ; then - xsltproc ../tests/ctest2junix.xsl \ - Testing/`head -n 1 < Testing/TAG`/Test.xml > \ - CTestResults.xml - fi +cd build +cmake .. +xvfb-run --auto-servernum --server-num=1 \ + --server-args="-screen 0 1024x768x24" \ + make Experimental || true +if [ -f Testing/TAG ] ; then + xsltproc ../tests/ctest2junix.xsl \ + Testing/`head -n 1 < Testing/TAG`/Test.xml > \ + CTestResults.xml +fi ``` * Add Junit post build action and set 'Publish Junit test result report' to: @@ -1120,7 +1114,7 @@ If you are interested in seeing embedded debug output, change the following CMake option: ```bash - -D CMAKE_BUILD_TYPE=DEBUG (or RELWITHDEBINFO) +-D CMAKE_BUILD_TYPE=DEBUG # (or RELWITHDEBINFO) ``` This will flood your terminal or system log with lots of useful output from @@ -1131,39 +1125,39 @@ directory, as it will not work with the installed/bundled app. First set the CMake option to enable tests: ```bash - -D ENABLE_TESTS=TRUE +-D ENABLE_TESTS=TRUE ``` Then run all tests from build directory: ```bash - cd build - make test +cd build +make test ``` To run all tests and report to http://cdash.orfeo-toolbox.org/index.php?project=QGIS ```bash - cd build - make Experimental +cd build +make Experimental ``` You can define the host name reported via 'make Experimental' by setting a CMake option: ```bash - -D SITE="my.domain.org" +-D SITE="my.domain.org" ``` To run specific test(s) (see 'man ctest'): ```bash - cd build - # show listing of tests, without running them - ctest --show-only +cd build +# show listing of tests, without running them +ctest --show-only - # run specific C++ or Python test(s) matching a regular expression - ctest --verbose --tests-regex SomeTestName +# run specific C++ or Python test(s) matching a regular expression +ctest --verbose --tests-regex SomeTestName ``` # 9. Authors and Acknowledgments From 2c26b247d618e44bb446755ba3219b88fe1cfe65 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 10:04:36 +1000 Subject: [PATCH 138/377] Remove redundant qgis::as_const implementation, move to c++17 std::as_const --- src/3d/qgs3dmapscene.cpp | 16 +- src/3d/qgs3dmapsettings.cpp | 4 +- src/3d/qgslayoutitem3dmap.cpp | 2 +- src/3d/qgsrulebased3drenderer.cpp | 16 +- src/3d/symbols/qgslinevertexdata_p.cpp | 4 +- .../interpolation/qgsidwinterpolator.cpp | 2 +- .../interpolation/qgsinterpolator.cpp | 2 +- .../interpolation/qgstininterpolator.cpp | 4 +- .../network/qgsvectorlayerdirector.cpp | 4 +- .../qgsalgorithmaddincrementalfield.cpp | 4 +- .../qgsalgorithmcategorizeusingstyle.cpp | 6 +- .../processing/qgsalgorithmcellstatistics.cpp | 10 +- .../qgsalgorithmconditionalbranch.cpp | 2 +- .../processing/qgsalgorithmdropfields.cpp | 8 +- .../processing/qgsalgorithmexplodehstore.cpp | 2 +- .../qgsalgorithmextractbylocation.cpp | 2 +- .../qgsalgorithmextractzmvalues.cpp | 2 +- .../processing/qgsalgorithmfilter.cpp | 6 +- .../processing/qgsalgorithmjoinbylocation.cpp | 6 +- .../qgsalgorithmlineintersection.cpp | 6 +- .../qgsalgorithmpolygonstolines.cpp | 2 +- .../processing/qgsalgorithmrasterize.cpp | 4 +- .../qgsalgorithmserviceareafromlayer.cpp | 2 +- .../processing/qgsalgorithmsplitwithlines.cpp | 4 +- .../processing/qgsbookmarkalgorithms.cpp | 4 +- src/analysis/raster/qgsrastercalculator.cpp | 8 +- .../geometry_checker/qgsgeometrychecker.cpp | 14 +- .../qgsgeometryisvalidcheck.cpp | 2 +- .../qgsgeometrymissingvertexcheck.cpp | 2 +- .../qgsvectordataproviderfeaturepool.cpp | 4 +- .../qgsvectorlayerfeaturepool.cpp | 4 +- src/analysis/vector/qgszonalstatistics.cpp | 4 +- .../decorations/qgsdecorationlayoutextent.cpp | 2 +- .../networklogger/qgsnetworklogger.cpp | 2 +- .../networklogger/qgsnetworkloggernode.cpp | 2 +- src/app/georeferencer/qgsgeorefmainwindow.cpp | 4 +- .../qgstransformsettingsdialog.cpp | 2 +- src/app/labeling/qgsmaptoollabel.cpp | 14 +- src/app/labeling/qgsmaptoolpinlabels.cpp | 2 +- src/app/labeling/qgsmaptoolshowhidelabels.cpp | 4 +- src/app/layout/qgslayout3dmapwidget.cpp | 2 +- src/app/layout/qgslayoutappmenuprovider.cpp | 2 +- src/app/layout/qgslayoutdesignerdialog.cpp | 10 +- src/app/layout/qgslayoutmanagerdialog.cpp | 2 +- src/app/locator/qgsinbuiltlocatorfilters.cpp | 9 +- src/app/main.cpp | 4 +- src/app/options/qgscodeeditoroptions.cpp | 2 +- src/app/options/qgsoptions.cpp | 12 +- src/app/qgisapp.cpp | 48 ++--- src/app/qgscustomization.cpp | 2 +- src/app/qgscustomprojectiondialog.cpp | 4 +- src/app/qgsdiscoverrelationsdialog.cpp | 2 +- src/app/qgsdxfexportdialog.cpp | 2 +- src/app/qgsgeometryvalidationmodel.cpp | 2 +- src/app/qgsgeometryvalidationservice.cpp | 4 +- src/app/qgshandlebadlayers.cpp | 2 +- src/app/qgslayerstylingwidget.cpp | 2 +- src/app/qgslayertreeviewbadlayerindicator.cpp | 8 +- src/app/qgsmapthemes.cpp | 4 +- src/app/qgsmaptooladdcircle.cpp | 2 +- src/app/qgsmaptooladdellipse.cpp | 2 +- src/app/qgsmaptooladdrectangle.cpp | 2 +- src/app/qgsmaptooladdregularpolygon.cpp | 2 +- src/app/qgsmaptoolfeatureaction.cpp | 4 +- src/app/qgsmaptoolmovefeature.cpp | 2 +- src/app/qgsmaptoolscalefeature.cpp | 2 +- src/app/qgsmergeattributesdialog.cpp | 2 +- src/app/qgsprojectproperties.cpp | 8 +- src/app/qgsrastercalcdialog.cpp | 2 +- src/app/qgssnappingwidget.cpp | 4 +- src/app/vertextool/qgsvertextool.cpp | 34 +-- .../qgsannotationlayerrenderer.cpp | 2 +- src/core/annotations/qgsannotationmanager.cpp | 4 +- src/core/auth/qgsauthmanager.cpp | 4 +- .../qgsclassificationmethodregistry.cpp | 2 +- src/core/diagram/qgshistogramdiagram.cpp | 4 +- src/core/diagram/qgsstackedbardiagram.cpp | 2 +- src/core/dxf/qgsdxfexport.cpp | 12 +- src/core/expression/qgsexpression.cpp | 10 +- src/core/expression/qgsexpressionfunction.cpp | 6 +- src/core/expression/qgsexpressionnodeimpl.cpp | 4 +- .../qgsvaluerelationfieldformatter.cpp | 6 +- src/core/geocms/geonode/qgsgeonoderequest.cpp | 2 +- src/core/geometry/qgscompoundcurve.cpp | 22 +- src/core/geometry/qgscurvepolygon.cpp | 30 +-- src/core/geometry/qgsgeometry.cpp | 8 +- src/core/geometry/qgsgeometrycollection.cpp | 26 +-- src/core/geometry/qgsgeos.cpp | 2 +- .../geometry/qgsinternalgeometryengine.cpp | 10 +- src/core/geometry/qgsmulticurve.cpp | 2 +- src/core/geometry/qgsmultipoint.cpp | 2 +- src/core/geometry/qgsmultipolygon.cpp | 2 +- src/core/geometry/qgsmultisurface.cpp | 2 +- src/core/geometry/qgspolygon.cpp | 2 +- src/core/labeling/qgslabelingengine.cpp | 20 +- src/core/labeling/qgspallabeling.cpp | 2 +- src/core/labeling/qgsrulebasedlabeling.cpp | 20 +- src/core/labeling/qgstextlabelfeature.cpp | 2 +- src/core/layertree/qgslayertree.cpp | 6 +- src/core/layertree/qgslayertreegroup.cpp | 22 +- src/core/layertree/qgslayertreemodel.cpp | 16 +- src/core/layertree/qgslayertreenode.cpp | 4 +- src/core/layout/qgsabstractreportsection.cpp | 12 +- src/core/layout/qgslayout.cpp | 16 +- src/core/layout/qgslayoutexporter.cpp | 6 +- src/core/layout/qgslayoutgeopdfexporter.cpp | 2 +- src/core/layout/qgslayoutguidecollection.cpp | 2 +- .../layout/qgslayoutitemattributetable.cpp | 8 +- src/core/layout/qgslayoutitemgroup.cpp | 16 +- .../layout/qgslayoutitemgroupundocommand.cpp | 2 +- src/core/layout/qgslayoutitemmanualtable.cpp | 4 +- src/core/layout/qgslayoutitemmap.cpp | 12 +- src/core/layout/qgslayoutitemmapitem.cpp | 4 +- src/core/layout/qgslayoutitemmapoverview.cpp | 2 +- src/core/layout/qgslayoutitemtexttable.cpp | 2 +- src/core/layout/qgslayoutmanager.cpp | 4 +- src/core/layout/qgslayoutmodel.cpp | 6 +- src/core/layout/qgslayoutmultiframe.cpp | 4 +- src/core/layout/qgslayoutpagecollection.cpp | 8 +- src/core/layout/qgslayoutsnapper.cpp | 2 +- src/core/layout/qgslayouttable.cpp | 16 +- src/core/layout/qgslayoututils.cpp | 2 +- .../layout/qgsreportsectionfieldgroup.cpp | 2 +- src/core/locator/qgslocator.cpp | 10 +- src/core/mesh/qgsmeshtracerenderer.cpp | 6 +- src/core/pal/feature.cpp | 2 +- src/core/pal/pal.cpp | 4 +- .../qgspointcloudattributebyramprenderer.cpp | 2 +- .../qgspointcloudclassifiedrenderer.cpp | 10 +- .../pointcloud/qgspointcloudlayerrenderer.cpp | 2 +- .../models/qgsprocessingmodelalgorithm.cpp | 16 +- .../qgsprocessingmodelchildalgorithm.cpp | 2 +- .../processing/qgsprocessingalgorithm.cpp | 2 +- src/core/processing/qgsprocessingutils.cpp | 6 +- src/core/project/qgsprojectproperty.cpp | 2 +- .../providers/arcgis/qgsarcgisrestutils.cpp | 2 +- src/core/providers/gdal/qgsgdalprovider.cpp | 2 +- .../ogr/qgsgeopackageproviderconnection.cpp | 14 +- src/core/providers/ogr/qgsogrprovider.cpp | 4 +- src/core/qgis.h | 17 -- .../qgsabstractdatabaseproviderconnection.cpp | 6 +- src/core/qgsabstractgeopdfexporter.cpp | 4 +- src/core/qgsactionmanager.cpp | 12 +- src/core/qgsapplication.cpp | 2 +- src/core/qgsbookmarkmanager.cpp | 6 +- src/core/qgsbrowsermodel.cpp | 4 +- src/core/qgsconnectionpool.h | 8 +- src/core/qgscoordinatereferencesystem.cpp | 2 +- src/core/qgsdatadefinedsizelegend.cpp | 10 +- src/core/qgsdataitemproviderregistry.cpp | 4 +- src/core/qgsdatumtransform.cpp | 8 +- src/core/qgsexpressioncontext.cpp | 4 +- src/core/qgsexpressionsorter.h | 8 +- src/core/qgsfeature.cpp | 2 +- src/core/qgsfeatureexpressionvaluesgatherer.h | 2 +- src/core/qgsfileutils.cpp | 2 +- src/core/qgsjsonutils.cpp | 4 +- src/core/qgslegendrenderer.cpp | 8 +- src/core/qgslocalizeddatapathregistry.cpp | 4 +- src/core/qgsmaplayermodel.cpp | 2 +- src/core/qgsmaplayerref.h | 2 +- src/core/qgsmaprenderercache.cpp | 2 +- src/core/qgsmapthemecollection.cpp | 18 +- src/core/qgsmultirenderchecker.cpp | 2 +- src/core/qgsobjectcustomproperties.cpp | 2 +- src/core/qgspolymorphicrelation.cpp | 10 +- src/core/qgspostgresstringutils.cpp | 2 +- src/core/qgsprojectcomponentvisitor.h | 193 ++++++++++++++++++ src/core/qgsprojutils.cpp | 2 +- src/core/qgspropertycollection.cpp | 4 +- src/core/qgsrelation.cpp | 16 +- src/core/qgsrelationmanager.cpp | 18 +- src/core/qgssnappingutils.cpp | 6 +- src/core/qgssqlstatement.cpp | 2 +- src/core/qgsstoredexpressionmanager.cpp | 12 +- src/core/qgsstringutils.cpp | 2 +- src/core/qgstaskmanager.cpp | 2 +- src/core/qgstracer.cpp | 6 +- src/core/qgsvectorfilewriter.cpp | 4 +- src/core/qgsweakrelation.cpp | 2 +- .../qgscategorizedsymbolrenderer.cpp | 8 +- src/core/symbology/qgsfillsymbollayer.cpp | 4 +- .../symbology/qgsgraduatedsymbolrenderer.cpp | 18 +- src/core/symbology/qgslinesymbollayer.cpp | 4 +- .../symbology/qgsmergedfeaturerenderer.cpp | 6 +- src/core/symbology/qgsrulebasedrenderer.cpp | 2 +- src/core/symbology/qgsrulebasedrenderer.h | 4 +- src/core/symbology/qgsstyle.cpp | 2 +- src/core/symbology/qgsstylemodel.cpp | 2 +- src/core/symbology/qgssymbol.cpp | 20 +- src/core/symbology/qgssymbollayer.cpp | 4 +- src/core/textrenderer/qgstextdocument.cpp | 2 +- src/core/textrenderer/qgstextrenderer.cpp | 4 +- src/core/vector/qgsvectorlayer.cpp | 20 +- src/core/vector/qgsvectorlayercache.cpp | 2 +- src/core/vector/qgsvectorlayereditbuffer.cpp | 4 +- src/core/vector/qgsvectorlayereditutils.cpp | 2 +- src/core/vector/qgsvectorlayerjoinbuffer.cpp | 2 +- src/core/vector/qgsvectorlayerjoininfo.cpp | 2 +- src/core/vector/qgsvectorlayerrenderer.cpp | 2 +- .../qgsvectorlayerundopassthroughcommand.cpp | 6 +- src/core/vector/qgsvectorlayerutils.cpp | 4 +- .../vectortile/qgsvectortilebasiclabeling.cpp | 8 +- .../vectortile/qgsvectortilebasicrenderer.cpp | 6 +- src/core/vectortile/qgsvectortileloader.cpp | 4 +- src/core/vectortile/qgsvectortileutils.cpp | 2 +- src/core/vectortile/qgsvectortilewriter.cpp | 4 +- .../codeeditors/qgscodeeditorexpression.cpp | 8 +- src/gui/codeeditors/qgscodeeditorsql.cpp | 2 +- .../qgsrelationreferencewidget.cpp | 14 +- .../qgsvaluerelationsearchwidgetwrapper.cpp | 2 +- .../qgsvaluerelationwidgetwrapper.cpp | 12 +- .../qgslayertreeviewdefaultactions.cpp | 4 +- src/gui/layout/qgslayoutguiutils.cpp | 8 +- src/gui/layout/qgslayoutlabelwidget.cpp | 82 ++++---- src/gui/layout/qgslayoutlegendwidget.cpp | 10 +- src/gui/layout/qgslayoutvaliditychecks.cpp | 8 +- src/gui/layout/qgslayoutview.cpp | 4 +- src/gui/layout/qgslayoutviewtooleditnodes.cpp | 6 +- src/gui/layout/qgslayoutviewtoolselect.cpp | 2 +- src/gui/locator/qgslocatorwidget.cpp | 2 +- .../qgsnumericformatselectorwidget.cpp | 2 +- src/gui/ogr/qgsvectorlayersaveasdialog.cpp | 2 +- .../models/qgsmodeldesignerdialog.cpp | 2 +- .../models/qgsmodelgraphicsview.cpp | 6 +- .../models/qgsmodelinputreorderwidget.cpp | 2 +- .../models/qgsmodelviewtoolselect.cpp | 2 +- .../qgsprocessingenummodelerwidget.cpp | 2 +- .../qgsprocessingmaplayercombobox.cpp | 2 +- .../qgsprocessingmatrixmodelerwidget.cpp | 4 +- .../qgsprocessingmatrixparameterdialog.cpp | 2 +- .../qgsprocessingmultipleselectiondialog.cpp | 2 +- .../qgsprocessingoutputdestinationwidget.cpp | 2 +- .../processing/qgsprocessingtoolboxmodel.cpp | 6 +- .../qgsprocessingwidgetwrapperimpl.cpp | 4 +- .../providers/gdal/qgsgdalsourceselect.cpp | 2 +- .../providers/ogr/qgsogrdbsourceselect.cpp | 4 +- src/gui/providers/ogr/qgsogrsourceselect.cpp | 2 +- src/gui/qgsaggregatetoolbutton.cpp | 4 +- src/gui/qgsattributeform.cpp | 30 +-- src/gui/qgscoordinateoperationwidget.cpp | 4 +- src/gui/qgsexpressionbuilderwidget.cpp | 2 +- src/gui/qgsexpressiontreeview.cpp | 6 +- src/gui/qgsfieldmappingmodel.cpp | 6 +- src/gui/qgsfilewidget.cpp | 4 +- src/gui/qgsgraphicsviewmousehandles.cpp | 2 +- src/gui/qgshistogramwidget.cpp | 4 +- src/gui/qgslegendpatchshapebutton.cpp | 2 +- src/gui/qgsmapcanvas.cpp | 4 +- src/gui/qgsmaptoolidentify.cpp | 2 +- src/gui/qgsmetadatawidget.cpp | 2 +- src/gui/qgsnewvectortabledialog.cpp | 6 +- src/gui/qgsoptionsdialogbase.cpp | 2 +- src/gui/qgsprojectionselectiontreewidget.cpp | 2 +- src/gui/qgspropertyoverridebutton.cpp | 2 +- src/gui/qgsrubberband.cpp | 14 +- src/gui/qgsscalewidget.cpp | 2 +- src/gui/raster/qgscolorrampshaderwidget.cpp | 4 +- src/gui/raster/qgspalettedrendererwidget.cpp | 2 +- src/gui/raster/qgsrasterlayerproperties.cpp | 2 +- .../qgsgraduatedsymbolrendererwidget.cpp | 8 +- src/gui/symbology/qgsstylemanagerdialog.cpp | 4 +- src/gui/symbology/qgsstylesavedialog.cpp | 2 +- src/gui/symbology/qgssvgselectorwidget.cpp | 4 +- src/gui/symbology/qgssymbollevelsdialog.cpp | 2 +- src/gui/vector/qgsvectorlayerproperties.cpp | 4 +- .../qgsgeometrycheckerresulttab.cpp | 6 +- .../qgsgeometrycheckersetuptab.cpp | 8 +- src/process/qgsprocess.cpp | 2 +- src/providers/arcgisrest/qgsamsprovider.cpp | 14 +- src/providers/db2/qgsdb2tablemodel.cpp | 6 +- src/providers/geonode/qgsgeonodedataitems.cpp | 2 +- src/providers/hana/qgshanaconnection.cpp | 2 +- src/providers/hana/qgshanadataitems.cpp | 2 +- src/providers/hana/qgshanafeatureiterator.cpp | 8 +- src/providers/hana/qgshanaprovider.cpp | 6 +- src/providers/hana/qgshanatablemodel.cpp | 2 +- src/providers/mssql/qgsmssqldataitems.cpp | 2 +- .../mssql/qgsmssqlfeatureiterator.cpp | 2 +- src/providers/mssql/qgsmssqltablemodel.cpp | 2 +- src/providers/ows/qgsowsdataitems.cpp | 2 +- src/providers/postgres/qgspgsourceselect.cpp | 14 +- .../qgspostgresprojectstoragedialog.cpp | 2 +- .../postgres/qgspostgresprovider.cpp | 8 +- .../qgspostgresproviderconnection.cpp | 8 +- .../raster/qgspostgresrasterprovider.cpp | 90 ++++---- .../spatialite/qgsspatialiteprovider.cpp | 2 +- .../qgsspatialiteproviderconnection.cpp | 2 +- src/providers/wcs/qgswcscapabilities.cpp | 2 +- .../qgsbackgroundcachedfeatureiterator.cpp | 2 +- .../wfs/qgsbackgroundcachedshareddata.cpp | 4 +- src/providers/wfs/qgswfsprovider.cpp | 4 +- src/providers/wms/qgswmscapabilities.cpp | 4 +- src/providers/wms/qgswmscapabilities.h | 2 +- src/providers/wms/qgswmsdataitems.cpp | 14 +- src/providers/wms/qgswmsprovider.cpp | 18 +- src/providers/wms/qgswmssourceselect.cpp | 12 +- src/quickgui/qgsquickmapcanvasmap.cpp | 2 +- src/quickgui/qgsquickutils.cpp | 2 +- src/server/qgsserverapiutils.cpp | 6 +- src/server/qgsserverfeatureid.cpp | 4 +- src/server/qgsserverogcapihandler.cpp | 2 +- src/server/qgsserversettings.cpp | 2 +- .../landingpage/qgslandingpageutils.cpp | 10 +- src/server/services/wfs/qgswfsgetfeature.cpp | 2 +- src/server/services/wfs/qgswfstransaction.cpp | 2 +- .../services/wfs/qgswfstransaction_1_0_0.cpp | 2 +- src/server/services/wfs/qgswfsutils.cpp | 2 +- .../services/wms/qgswmsgetcapabilities.cpp | 2 +- src/server/services/wms/qgswmsparameters.cpp | 2 +- .../services/wms/qgswmsrendercontext.cpp | 4 +- src/server/services/wms/qgswmsrenderer.cpp | 12 +- .../src/analysis/testqgsrastercalculator.cpp | 2 +- tests/src/core/testqgis.cpp | 2 +- .../src/core/testqgscompositionconverter.cpp | 10 +- tests/src/core/testqgsgeometry.cpp | 6 +- tests/src/core/testqgsgeopdfexport.cpp | 10 +- tests/src/core/testqgsmaprendererjob.cpp | 6 +- tests/src/core/testqgstaskmanager.cpp | 4 +- tests/src/gui/testprocessinggui.cpp | 2 +- 320 files changed, 1153 insertions(+), 976 deletions(-) create mode 100644 src/core/qgsprojectcomponentvisitor.h diff --git a/src/3d/qgs3dmapscene.cpp b/src/3d/qgs3dmapscene.cpp index c2541ccbb83c..d177d11b9b0b 100644 --- a/src/3d/qgs3dmapscene.cpp +++ b/src/3d/qgs3dmapscene.cpp @@ -250,7 +250,7 @@ int Qgs3DMapScene::terrainPendingJobsCount() const int Qgs3DMapScene::totalPendingJobsCount() const { int count = 0; - for ( QgsChunkedEntity *entity : qgis::as_const( mChunkEntities ) ) + for ( QgsChunkedEntity *entity : std::as_const( mChunkEntities ) ) count += entity->pendingJobsCount(); return count; } @@ -295,7 +295,7 @@ void Qgs3DMapScene::onLayerEntityPickedObject( Qt3DRender::QPickEvent *pickEvent if ( !vlayer ) return; - for ( Qgs3DMapScenePickHandler *pickHandler : qgis::as_const( mPickHandlers ) ) + for ( Qgs3DMapScenePickHandler *pickHandler : std::as_const( mPickHandlers ) ) { pickHandler->handlePickOnVectorLayer( vlayer, fid, pickEvent->worldIntersection(), pickEvent ); } @@ -383,7 +383,7 @@ void addQLayerComponentsToHierarchy( Qt3DCore::QEntity *entity, const QVectorisEnabled() ) entity->update( _sceneState( mCameraController ) ); @@ -447,7 +447,7 @@ bool Qgs3DMapScene::updateCameraNearFarPlanes() // Also involve all the other chunked entities to make sure that they will not get // clipped by the near or far plane - for ( QgsChunkedEntity *e : qgis::as_const( mChunkEntities ) ) + for ( QgsChunkedEntity *e : std::as_const( mChunkEntities ) ) { if ( e != mTerrain ) _updateNearFarPlane( e->activeNodes(), viewMatrix, fnear, ffar ); @@ -485,7 +485,7 @@ void Qgs3DMapScene::onFrameTriggered( float dt ) { mCameraController->frameTriggered( dt ); - for ( QgsChunkedEntity *entity : qgis::as_const( mChunkEntities ) ) + for ( QgsChunkedEntity *entity : std::as_const( mChunkEntities ) ) { if ( entity->isEnabled() && entity->needsUpdate() ) { @@ -585,10 +585,10 @@ void Qgs3DMapScene::onBackgroundColorChanged() void Qgs3DMapScene::updateLights() { - for ( Qt3DCore::QEntity *entity : qgis::as_const( mLightEntities ) ) + for ( Qt3DCore::QEntity *entity : std::as_const( mLightEntities ) ) entity->deleteLater(); mLightEntities.clear(); - for ( Qt3DCore::QEntity *entity : qgis::as_const( mLightOriginEntities ) ) + for ( Qt3DCore::QEntity *entity : std::as_const( mLightOriginEntities ) ) entity->deleteLater(); mLightOriginEntities.clear(); @@ -956,7 +956,7 @@ void Qgs3DMapScene::updateSceneState() return; } - for ( QgsChunkedEntity *entity : qgis::as_const( mChunkEntities ) ) + for ( QgsChunkedEntity *entity : std::as_const( mChunkEntities ) ) { if ( entity->isEnabled() && entity->pendingJobsCount() > 0 ) { diff --git a/src/3d/qgs3dmapsettings.cpp b/src/3d/qgs3dmapsettings.cpp index 3e90b87fcca8..09c92e989270 100644 --- a/src/3d/qgs3dmapsettings.cpp +++ b/src/3d/qgs3dmapsettings.cpp @@ -337,7 +337,7 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon elemTerrain.setAttribute( QStringLiteral( "show-labels" ), mShowLabels ? 1 : 0 ); QDomElement elemPointLights = doc.createElement( QStringLiteral( "point-lights" ) ); - for ( const QgsPointLightSettings &pointLight : qgis::as_const( mPointLights ) ) + for ( const QgsPointLightSettings &pointLight : std::as_const( mPointLights ) ) { QDomElement elemPointLight = pointLight.writeXml( doc ); elemPointLights.appendChild( elemPointLight ); @@ -345,7 +345,7 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon elem.appendChild( elemPointLights ); QDomElement elemDirectionalLights = doc.createElement( QStringLiteral( "directional-lights" ) ); - for ( const QgsDirectionalLightSettings &directionalLight : qgis::as_const( mDirectionalLights ) ) + for ( const QgsDirectionalLightSettings &directionalLight : std::as_const( mDirectionalLights ) ) { QDomElement elemDirectionalLight = directionalLight.writeXml( doc ); elemDirectionalLights.appendChild( elemDirectionalLight ); diff --git a/src/3d/qgslayoutitem3dmap.cpp b/src/3d/qgslayoutitem3dmap.cpp index 161ff6c45c97..2fc6870d7659 100644 --- a/src/3d/qgslayoutitem3dmap.cpp +++ b/src/3d/qgslayoutitem3dmap.cpp @@ -62,7 +62,7 @@ void QgsLayoutItem3DMap::assignFreeId() int maxId = -1; bool used = false; - for ( QgsLayoutItem3DMap *map : qgis::as_const( mapsList ) ) + for ( QgsLayoutItem3DMap *map : std::as_const( mapsList ) ) { if ( map == this ) continue; diff --git a/src/3d/qgsrulebased3drenderer.cpp b/src/3d/qgsrulebased3drenderer.cpp index 99a034aa4e29..7f0450e61a8c 100644 --- a/src/3d/qgsrulebased3drenderer.cpp +++ b/src/3d/qgsrulebased3drenderer.cpp @@ -107,7 +107,7 @@ void QgsRuleBased3DRenderer::Rule::initFilter() void QgsRuleBased3DRenderer::Rule::updateElseRules() { mElseRules.clear(); - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { if ( rule->isElse() ) mElseRules << rule; @@ -143,7 +143,7 @@ const QgsRuleBased3DRenderer::Rule *QgsRuleBased3DRenderer::Rule::findRuleByKey( if ( key == mRuleKey ) return this; - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { const Rule *r = rule->findRuleByKey( key ); if ( r ) @@ -157,7 +157,7 @@ QgsRuleBased3DRenderer::Rule *QgsRuleBased3DRenderer::Rule::findRuleByKey( const if ( key == mRuleKey ) return this; - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { Rule *r = rule->findRuleByKey( key ); if ( r ) @@ -172,7 +172,7 @@ QgsRuleBased3DRenderer::Rule *QgsRuleBased3DRenderer::Rule::clone() const Rule *newrule = new Rule( symbol, mFilterExp, mDescription ); newrule->setActive( mIsActive ); // clone children - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) newrule->appendChild( rule->clone() ); return newrule; } @@ -258,7 +258,7 @@ void QgsRuleBased3DRenderer::Rule::createHandlers( QgsVectorLayer *layer, QgsRul } // call recursively - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { rule->createHandlers( layer, handlers ); } @@ -284,7 +284,7 @@ void QgsRuleBased3DRenderer::Rule::prepare( const Qgs3DRenderContext &context, Q } // call recursively - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { rule->prepare( context, attributeNames, handlers ); } @@ -307,7 +307,7 @@ QgsRuleBased3DRenderer::Rule::RegisterResult QgsRuleBased3DRenderer::Rule::regis bool willRegisterSomething = false; // call recursively - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { // Don't process else rules yet if ( !rule->isElse() ) @@ -322,7 +322,7 @@ QgsRuleBased3DRenderer::Rule::RegisterResult QgsRuleBased3DRenderer::Rule::regis // If none of the rules passed then we jump into the else rules and process them. if ( !willRegisterSomething ) { - for ( Rule *rule : qgis::as_const( mElseRules ) ) + for ( Rule *rule : std::as_const( mElseRules ) ) { registered |= rule->registerFeature( feature, context, handlers ) != Filtered; } diff --git a/src/3d/symbols/qgslinevertexdata_p.cpp b/src/3d/symbols/qgslinevertexdata_p.cpp index fd6b58485dfb..c438caad2aa4 100644 --- a/src/3d/symbols/qgslinevertexdata_p.cpp +++ b/src/3d/symbols/qgslinevertexdata_p.cpp @@ -46,7 +46,7 @@ QByteArray QgsLineVertexData::createVertexBuffer() vertexBufferData.resize( vertices.size() * 3 * sizeof( float ) ); float *rawVertexArray = reinterpret_cast( vertexBufferData.data() ); int idx = 0; - for ( const auto &v : qgis::as_const( vertices ) ) + for ( const auto &v : std::as_const( vertices ) ) { rawVertexArray[idx++] = v.x(); rawVertexArray[idx++] = v.y(); @@ -61,7 +61,7 @@ QByteArray QgsLineVertexData::createIndexBuffer() indexBufferData.resize( indexes.size() * sizeof( int ) ); unsigned int *rawIndexArray = reinterpret_cast( indexBufferData.data() ); int idx = 0; - for ( unsigned int indexVal : qgis::as_const( indexes ) ) + for ( unsigned int indexVal : std::as_const( indexes ) ) { rawIndexArray[idx++] = indexVal; } diff --git a/src/analysis/interpolation/qgsidwinterpolator.cpp b/src/analysis/interpolation/qgsidwinterpolator.cpp index 729ffdfe453c..bff2715b10c4 100644 --- a/src/analysis/interpolation/qgsidwinterpolator.cpp +++ b/src/analysis/interpolation/qgsidwinterpolator.cpp @@ -34,7 +34,7 @@ int QgsIDWInterpolator::interpolatePoint( double x, double y, double &result, Qg double sumCounter = 0; double sumDenominator = 0; - for ( const QgsInterpolatorVertexData &vertex : qgis::as_const( mCachedBaseData ) ) + for ( const QgsInterpolatorVertexData &vertex : std::as_const( mCachedBaseData ) ) { double distance = std::sqrt( ( vertex.x - x ) * ( vertex.x - x ) + ( vertex.y - y ) * ( vertex.y - y ) ); if ( qgsDoubleNear( distance, 0.0 ) ) diff --git a/src/analysis/interpolation/qgsinterpolator.cpp b/src/analysis/interpolation/qgsinterpolator.cpp index 714206f59189..9e78082bc86c 100644 --- a/src/analysis/interpolation/qgsinterpolator.cpp +++ b/src/analysis/interpolation/qgsinterpolator.cpp @@ -43,7 +43,7 @@ QgsInterpolator::Result QgsInterpolator::cacheBaseData( QgsFeedback *feedback ) double layerStep = !mLayerData.empty() ? 100.0 / mLayerData.count() : 1; int layerCount = 0; - for ( const LayerData &layer : qgis::as_const( mLayerData ) ) + for ( const LayerData &layer : std::as_const( mLayerData ) ) { if ( feedback && feedback->isCanceled() ) return Canceled; diff --git a/src/analysis/interpolation/qgstininterpolator.cpp b/src/analysis/interpolation/qgstininterpolator.cpp index 7cc95a43857a..84c6cb462b91 100644 --- a/src/analysis/interpolation/qgstininterpolator.cpp +++ b/src/analysis/interpolation/qgstininterpolator.cpp @@ -96,7 +96,7 @@ void QgsTinInterpolator::initialize() int nProcessedFeatures = 0; if ( mFeedback ) { - for ( const LayerData &layer : qgis::as_const( mLayerData ) ) + for ( const LayerData &layer : std::as_const( mLayerData ) ) { if ( layer.source ) { @@ -108,7 +108,7 @@ void QgsTinInterpolator::initialize() const QgsCoordinateReferenceSystem crs = !mLayerData.empty() ? mLayerData.at( 0 ).source->sourceCrs() : QgsCoordinateReferenceSystem(); QgsFeature f; - for ( const LayerData &layer : qgis::as_const( mLayerData ) ) + for ( const LayerData &layer : std::as_const( mLayerData ) ) { if ( layer.source ) { diff --git a/src/analysis/network/qgsvectorlayerdirector.cpp b/src/analysis/network/qgsvectorlayerdirector.cpp index 13b3883fc660..9ddb0f7b08ba 100644 --- a/src/analysis/network/qgsvectorlayerdirector.cpp +++ b/src/analysis/network/qgsvectorlayerdirector.cpp @@ -216,7 +216,7 @@ void QgsVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const else if ( QgsWkbTypes::flatType( feature.geometry().wkbType() ) == QgsWkbTypes::LineString ) mpl.push_back( feature.geometry().asPolyline() ); - for ( const QgsPolylineXY &line : qgis::as_const( mpl ) ) + for ( const QgsPolylineXY &line : std::as_const( mpl ) ) { QgsPointXY pt1, pt2; bool isFirstPoint = true; @@ -339,7 +339,7 @@ void QgsVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const else if ( QgsWkbTypes::flatType( feature.geometry().wkbType() ) == QgsWkbTypes::LineString ) mpl.push_back( feature.geometry().asPolyline() ); - for ( const QgsPolylineXY &line : qgis::as_const( mpl ) ) + for ( const QgsPolylineXY &line : std::as_const( mpl ) ) { QgsPointXY pt1, pt2; diff --git a/src/analysis/processing/qgsalgorithmaddincrementalfield.cpp b/src/analysis/processing/qgsalgorithmaddincrementalfield.cpp index 0f2fe8583074..a084370fc35b 100644 --- a/src/analysis/processing/qgsalgorithmaddincrementalfield.cpp +++ b/src/analysis/processing/qgsalgorithmaddincrementalfield.cpp @@ -131,7 +131,7 @@ QgsFeatureList QgsAddIncrementalFieldAlgorithm::processFeature( const QgsFeature { if ( !mGroupedFieldNames.empty() && mGroupedFields.empty() ) { - for ( const QString &field : qgis::as_const( mGroupedFieldNames ) ) + for ( const QString &field : std::as_const( mGroupedFieldNames ) ) { int idx = mFields.lookupField( field ); if ( idx >= 0 ) @@ -150,7 +150,7 @@ QgsFeatureList QgsAddIncrementalFieldAlgorithm::processFeature( const QgsFeature { QgsAttributes groupAttributes; groupAttributes.reserve( mGroupedFields.size() ); - for ( int index : qgis::as_const( mGroupedFields ) ) + for ( int index : std::as_const( mGroupedFields ) ) { groupAttributes << f.attribute( index ); } diff --git a/src/analysis/processing/qgsalgorithmcategorizeusingstyle.cpp b/src/analysis/processing/qgsalgorithmcategorizeusingstyle.cpp index 39ffeefb028f..ea0f1ae02c34 100644 --- a/src/analysis/processing/qgsalgorithmcategorizeusingstyle.cpp +++ b/src/analysis/processing/qgsalgorithmcategorizeusingstyle.cpp @@ -217,7 +217,7 @@ QVariantMap QgsCategorizeUsingStyleAlgorithm::processAlgorithm( const QVariantMa QgsCategoryList cats; cats.reserve( uniqueVals.count() ); std::unique_ptr< QgsSymbol > defaultSymbol( QgsSymbol::defaultSymbol( mLayerGeometryType ) ); - for ( const QVariant &val : qgis::as_const( sortedUniqueVals ) ) + for ( const QVariant &val : std::as_const( sortedUniqueVals ) ) { cats.append( QgsRendererCategory( val, defaultSymbol->clone(), val.toString() ) ); } @@ -245,7 +245,7 @@ QVariantMap QgsCategorizeUsingStyleAlgorithm::processAlgorithm( const QVariantMa { feedback->pushInfo( QObject::tr( "\n%1 categories could not be matched:" ).arg( unmatchedCategories.count() ) ); std::sort( unmatchedCategories.begin(), unmatchedCategories.end() ); - for ( const QVariant &cat : qgis::as_const( unmatchedCategories ) ) + for ( const QVariant &cat : std::as_const( unmatchedCategories ) ) { feedback->pushInfo( QStringLiteral( "∙ “%1”" ).arg( cat.toString() ) ); if ( nonMatchingCategoriesSink ) @@ -261,7 +261,7 @@ QVariantMap QgsCategorizeUsingStyleAlgorithm::processAlgorithm( const QVariantMa { feedback->pushInfo( QObject::tr( "\n%1 symbols in style were not matched:" ).arg( unmatchedSymbols.count() ) ); std::sort( unmatchedSymbols.begin(), unmatchedSymbols.end() ); - for ( const QString &name : qgis::as_const( unmatchedSymbols ) ) + for ( const QString &name : std::as_const( unmatchedSymbols ) ) { feedback->pushInfo( QStringLiteral( "∙ “%1”" ).arg( name ) ); if ( nonMatchingSymbolsSink ) diff --git a/src/analysis/processing/qgsalgorithmcellstatistics.cpp b/src/analysis/processing/qgsalgorithmcellstatistics.cpp index b017812601bb..f6fc49873c01 100644 --- a/src/analysis/processing/qgsalgorithmcellstatistics.cpp +++ b/src/analysis/processing/qgsalgorithmcellstatistics.cpp @@ -104,7 +104,7 @@ bool QgsCellStatisticsAlgorithmBase::prepareAlgorithm( const QVariantMap ¶me //determine output raster data type //initially raster data type to most primitive data type that is possible mDataType = Qgis::Byte; - for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : qgis::as_const( mInputs ) ) + for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) ) { for ( int band : i.bands ) { @@ -275,7 +275,7 @@ void QgsCellStatisticsAlgorithm::processRasterStack( QgsProcessingFeedback *feed while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) ) { std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks; - for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : qgis::as_const( mInputs ) ) + for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) ) { if ( feedback->isCanceled() ) break; //in case some slow data sources are loaded @@ -452,7 +452,7 @@ void QgsCellStatisticsPercentileAlgorithm::processRasterStack( QgsProcessingFeed while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) ) { std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks; - for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : qgis::as_const( mInputs ) ) + for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) ) { if ( feedback->isCanceled() ) break; //in case some slow data sources are loaded @@ -590,7 +590,7 @@ void QgsCellStatisticsPercentRankFromValueAlgorithm::processRasterStack( QgsProc while ( outputIter.readNextRasterPart( 1, iterCols, iterRows, outputBlock, iterLeft, iterTop, &blockExtent ) ) { std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks; - for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : qgis::as_const( mInputs ) ) + for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) ) { if ( feedback->isCanceled() ) break; //in case some slow data sources are loaded @@ -735,7 +735,7 @@ void QgsCellStatisticsPercentRankFromRasterAlgorithm::processRasterStack( QgsPro std::unique_ptr< QgsRasterBlock > valueBlock( mValueRasterInterface->block( mValueRasterBand, blockExtent, iterCols, iterRows ) ); std::vector< std::unique_ptr< QgsRasterBlock > > inputBlocks; - for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : qgis::as_const( mInputs ) ) + for ( const QgsRasterAnalysisUtils::RasterLogicInput &i : std::as_const( mInputs ) ) { if ( feedback->isCanceled() ) break; //in case some slow data sources are loaded diff --git a/src/analysis/processing/qgsalgorithmconditionalbranch.cpp b/src/analysis/processing/qgsalgorithmconditionalbranch.cpp index 1184cc2e40c7..c8a470931cea 100644 --- a/src/analysis/processing/qgsalgorithmconditionalbranch.cpp +++ b/src/analysis/processing/qgsalgorithmconditionalbranch.cpp @@ -87,7 +87,7 @@ QVariantMap QgsConditionalBranchAlgorithm::processAlgorithm( const QVariantMap & QgsExpressionContext expressionContext = createExpressionContext( parameters, context ); QVariantMap results; - for ( Output *output : qgis::as_const( mOutputs ) ) + for ( Output *output : std::as_const( mOutputs ) ) { output->expression.prepare( &expressionContext ); const QVariant res = output->expression.evaluate( &expressionContext ); diff --git a/src/analysis/processing/qgsalgorithmdropfields.cpp b/src/analysis/processing/qgsalgorithmdropfields.cpp index 624ad1560246..3c4da23b5e69 100644 --- a/src/analysis/processing/qgsalgorithmdropfields.cpp +++ b/src/analysis/processing/qgsalgorithmdropfields.cpp @@ -99,7 +99,7 @@ QgsFields QgsDropTableFieldsAlgorithm::outputFields( const QgsFields &inputField std::sort( mFieldIndices.begin(), mFieldIndices.end(), std::greater< int >() ); // this second time we make a cleaned version of the fields - for ( const int index : qgis::as_const( mFieldIndices ) ) + for ( const int index : std::as_const( mFieldIndices ) ) { outFields.remove( index ); } @@ -115,7 +115,7 @@ bool QgsDropTableFieldsAlgorithm::prepareAlgorithm( const QVariantMap ¶meter std::unique_ptr< QgsProcessingFeatureSource> source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) ); if ( source ) { - for ( const QString &field : qgis::as_const( mFieldsToDelete ) ) + for ( const QString &field : std::as_const( mFieldsToDelete ) ) { const int index = source->fields().lookupField( field ); if ( index < 0 ) @@ -232,7 +232,7 @@ QgsFields QgsRetainTableFieldsAlgorithm::outputFields( const QgsFields &inputFie // this second time we make a cleaned version of the fields QgsFields outFields; - for ( const int index : qgis::as_const( mFieldIndices ) ) + for ( const int index : std::as_const( mFieldIndices ) ) { outFields.append( inputFields.at( index ) ); } @@ -248,7 +248,7 @@ bool QgsRetainTableFieldsAlgorithm::prepareAlgorithm( const QVariantMap ¶met std::unique_ptr< QgsProcessingFeatureSource> source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) ); if ( source ) { - for ( const QString &field : qgis::as_const( mFieldsToRetain ) ) + for ( const QString &field : std::as_const( mFieldsToRetain ) ) { const int index = source->fields().lookupField( field ); if ( index < 0 ) diff --git a/src/analysis/processing/qgsalgorithmexplodehstore.cpp b/src/analysis/processing/qgsalgorithmexplodehstore.cpp index 5f3d7fdddb2f..d0450b38bfaa 100644 --- a/src/analysis/processing/qgsalgorithmexplodehstore.cpp +++ b/src/analysis/processing/qgsalgorithmexplodehstore.cpp @@ -140,7 +140,7 @@ QVariantMap QgsExplodeHstoreAlgorithm::processAlgorithm( const QVariantMap ¶ QgsFeature outFeature; step = !features.empty() ? 50.0 / features.count() : 1; i = 0; - for ( const QgsFeature &feat : qgis::as_const( features ) ) + for ( const QgsFeature &feat : std::as_const( features ) ) { i++; if ( feedback->isCanceled() ) diff --git a/src/analysis/processing/qgsalgorithmextractbylocation.cpp b/src/analysis/processing/qgsalgorithmextractbylocation.cpp index 9d4d10f6bc1a..6f48a3ff6c2e 100644 --- a/src/analysis/processing/qgsalgorithmextractbylocation.cpp +++ b/src/analysis/processing/qgsalgorithmextractbylocation.cpp @@ -279,7 +279,7 @@ void QgsLocationBasedAlgorithm::processByIteratingOverIntersectSource( const Qgs bool isMatch = false; - for ( Predicate predicate : qgis::as_const( predicates ) ) + for ( Predicate predicate : std::as_const( predicates ) ) { switch ( predicate ) { diff --git a/src/analysis/processing/qgsalgorithmextractzmvalues.cpp b/src/analysis/processing/qgsalgorithmextractzmvalues.cpp index 2b7458871eea..5319a4419287 100644 --- a/src/analysis/processing/qgsalgorithmextractzmvalues.cpp +++ b/src/analysis/processing/qgsalgorithmextractzmvalues.cpp @@ -127,7 +127,7 @@ QgsFeatureList QgsExtractZMValuesAlgorithmBase::processFeature( const QgsFeature } stat.finalize(); - for ( QgsStatisticalSummary::Statistic s : qgis::as_const( mSelectedStats ) ) + for ( QgsStatisticalSummary::Statistic s : std::as_const( mSelectedStats ) ) attrs.append( stat.statistic( s ) ); } f.setAttributes( attrs ); diff --git a/src/analysis/processing/qgsalgorithmfilter.cpp b/src/analysis/processing/qgsalgorithmfilter.cpp index a4b22e02c214..24f24bb8e6db 100644 --- a/src/analysis/processing/qgsalgorithmfilter.cpp +++ b/src/analysis/processing/qgsalgorithmfilter.cpp @@ -93,7 +93,7 @@ QVariantMap QgsFilterAlgorithm::processAlgorithm( const QVariantMap ¶meters, throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) ); QgsExpressionContext expressionContext = createExpressionContext( parameters, context, source.get() ); - for ( Output *output : qgis::as_const( mOutputs ) ) + for ( Output *output : std::as_const( mOutputs ) ) { output->sink.reset( parameterAsSink( parameters, output->name, context, output->destinationIdentifier, source->fields(), source->wkbType(), source->sourceCrs() ) ); if ( !output->sink ) @@ -118,7 +118,7 @@ QVariantMap QgsFilterAlgorithm::processAlgorithm( const QVariantMap ¶meters, expressionContext.setFeature( f ); - for ( Output *output : qgis::as_const( mOutputs ) ) + for ( Output *output : std::as_const( mOutputs ) ) { if ( output->expression.evaluate( &expressionContext ).toBool() ) { @@ -131,7 +131,7 @@ QVariantMap QgsFilterAlgorithm::processAlgorithm( const QVariantMap ¶meters, } QVariantMap outputs; - for ( const Output *output : qgis::as_const( mOutputs ) ) + for ( const Output *output : std::as_const( mOutputs ) ) { outputs.insert( output->name, output->destinationIdentifier ); } diff --git a/src/analysis/processing/qgsalgorithmjoinbylocation.cpp b/src/analysis/processing/qgsalgorithmjoinbylocation.cpp index f4ba024d5012..8b8b53c1cc6c 100644 --- a/src/analysis/processing/qgsalgorithmjoinbylocation.cpp +++ b/src/analysis/processing/qgsalgorithmjoinbylocation.cpp @@ -454,7 +454,7 @@ bool QgsJoinByLocationAlgorithm::processFeatureFromJoinSource( QgsFeature &joinF { engine.reset( QgsGeometry::createGeometryEngine( featGeom.constGet() ) ); engine->prepareGeometry(); - for ( int ix : qgis::as_const( mJoinedFieldIndices ) ) + for ( int ix : std::as_const( mJoinedFieldIndices ) ) { joinAttributes.append( joinFeature.attribute( ix ) ); } @@ -535,7 +535,7 @@ bool QgsJoinByLocationAlgorithm::processFeatureFromInputSource( QgsFeature &base { QgsAttributes joinAttributes = baseFeature.attributes(); joinAttributes.reserve( joinAttributes.size() + mJoinedFieldIndices.size() ); - for ( int ix : qgis::as_const( mJoinedFieldIndices ) ) + for ( int ix : std::as_const( mJoinedFieldIndices ) ) { joinAttributes.append( joinFeature.attribute( ix ) ); } @@ -598,7 +598,7 @@ bool QgsJoinByLocationAlgorithm::processFeatureFromInputSource( QgsFeature &base { QgsAttributes joinAttributes = baseFeature.attributes(); joinAttributes.reserve( joinAttributes.size() + mJoinedFieldIndices.size() ); - for ( int ix : qgis::as_const( mJoinedFieldIndices ) ) + for ( int ix : std::as_const( mJoinedFieldIndices ) ) { joinAttributes.append( bestMatch.attribute( ix ) ); } diff --git a/src/analysis/processing/qgsalgorithmlineintersection.cpp b/src/analysis/processing/qgsalgorithmlineintersection.cpp index 0e7700c1f297..ff252a63e222 100644 --- a/src/analysis/processing/qgsalgorithmlineintersection.cpp +++ b/src/analysis/processing/qgsalgorithmlineintersection.cpp @@ -151,11 +151,11 @@ QVariantMap QgsLineIntersectionAlgorithm::processAlgorithm( const QVariantMap &p QgsMultiPointXY points; QgsGeometry intersectGeom = inGeom.intersection( tmpGeom ); QgsAttributes outAttributes; - for ( int a : qgis::as_const( fieldIndicesA ) ) + for ( int a : std::as_const( fieldIndicesA ) ) { outAttributes.append( inFeatureA.attribute( a ) ); } - for ( int b : qgis::as_const( fieldIndicesB ) ) + for ( int b : std::as_const( fieldIndicesB ) ) { outAttributes.append( inFeatureB.attribute( b ) ); } @@ -188,7 +188,7 @@ QVariantMap QgsLineIntersectionAlgorithm::processAlgorithm( const QVariantMap &p points.append( intersectGeom.asPoint() ); } } - for ( const QgsPointXY &j : qgis::as_const( points ) ) + for ( const QgsPointXY &j : std::as_const( points ) ) { outFeature.setGeometry( QgsGeometry::fromPointXY( j ) ); outFeature.setAttributes( outAttributes ); diff --git a/src/analysis/processing/qgsalgorithmpolygonstolines.cpp b/src/analysis/processing/qgsalgorithmpolygonstolines.cpp index 8537d0ffee4d..ffaa09315bee 100644 --- a/src/analysis/processing/qgsalgorithmpolygonstolines.cpp +++ b/src/analysis/processing/qgsalgorithmpolygonstolines.cpp @@ -122,7 +122,7 @@ QgsGeometry QgsPolygonsToLinesAlgorithm::convertToLines( const QgsGeometry &geom lineGeometry = std::make_unique(); lineGeometry->reserve( rings.size() ); - for ( auto ring : qgis::as_const( rings ) ) + for ( auto ring : std::as_const( rings ) ) lineGeometry->addGeometry( ring ); return QgsGeometry( lineGeometry.release() ); diff --git a/src/analysis/processing/qgsalgorithmrasterize.cpp b/src/analysis/processing/qgsalgorithmrasterize.cpp index 8e3f7d80765d..2e382a395547 100644 --- a/src/analysis/processing/qgsalgorithmrasterize.cpp +++ b/src/analysis/processing/qgsalgorithmrasterize.cpp @@ -326,7 +326,7 @@ bool QgsRasterizeAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, Qgs } else if ( ! mapLayers.isEmpty() ) { - for ( const QgsMapLayer *ml : qgis::as_const( mapLayers ) ) + for ( const QgsMapLayer *ml : std::as_const( mapLayers ) ) { mMapLayers.push_back( std::unique_ptr( ml->clone( ) ) ); } @@ -343,7 +343,7 @@ bool QgsRasterizeAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, Qgs layers << layer; } - for ( const QgsMapLayer *ml : qgis::as_const( layers ) ) + for ( const QgsMapLayer *ml : std::as_const( layers ) ) { mMapLayers.push_back( std::unique_ptr( ml->clone( ) ) ); } diff --git a/src/analysis/processing/qgsalgorithmserviceareafromlayer.cpp b/src/analysis/processing/qgsalgorithmserviceareafromlayer.cpp index 04868eae6f8a..de00d89a9bde 100644 --- a/src/analysis/processing/qgsalgorithmserviceareafromlayer.cpp +++ b/src/analysis/processing/qgsalgorithmserviceareafromlayer.cpp @@ -235,7 +235,7 @@ QVariantMap QgsServiceAreaFromLayerAlgorithm::processAlgorithm( const QVariantMa } } // costs - for ( int n : qgis::as_const( nodes ) ) + for ( int n : std::as_const( nodes ) ) { upperBoundary.push_back( graph->vertex( graph->edge( tree.at( n ) ).toVertex() ).point() ); lowerBoundary.push_back( graph->vertex( graph->edge( tree.at( n ) ).fromVertex() ).point() ); diff --git a/src/analysis/processing/qgsalgorithmsplitwithlines.cpp b/src/analysis/processing/qgsalgorithmsplitwithlines.cpp index a18345f95a2d..336deeb5a48e 100644 --- a/src/analysis/processing/qgsalgorithmsplitwithlines.cpp +++ b/src/analysis/processing/qgsalgorithmsplitwithlines.cpp @@ -166,7 +166,7 @@ QVariantMap QgsSplitWithLinesAlgorithm::processAlgorithm( const QVariantMap &par if ( !splittingLines.empty() ) { - for ( const QgsGeometry &splitGeom : qgis::as_const( splittingLines ) ) + for ( const QgsGeometry &splitGeom : std::as_const( splittingLines ) ) { QgsPointSequence splitterPList; QVector< QgsGeometry > outGeoms; @@ -242,7 +242,7 @@ QVariantMap QgsSplitWithLinesAlgorithm::processAlgorithm( const QVariantMap &par } QVector< QgsGeometry > parts; - for ( const QgsGeometry &aGeom : qgis::as_const( inGeoms ) ) + for ( const QgsGeometry &aGeom : std::as_const( inGeoms ) ) { if ( feedback->isCanceled() ) { diff --git a/src/analysis/processing/qgsbookmarkalgorithms.cpp b/src/analysis/processing/qgsbookmarkalgorithms.cpp index f7995b970806..a09a975f1d3e 100644 --- a/src/analysis/processing/qgsbookmarkalgorithms.cpp +++ b/src/analysis/processing/qgsbookmarkalgorithms.cpp @@ -119,7 +119,7 @@ QVariantMap QgsBookmarksToLayerAlgorithm::processAlgorithm( const QVariantMap &p int current = 0; double step = count > 0 ? 100.0 / count : 1; - for ( const QgsBookmark &b : qgis::as_const( mBookmarks ) ) + for ( const QgsBookmark &b : std::as_const( mBookmarks ) ) { if ( feedback->isCanceled() ) { @@ -322,7 +322,7 @@ QVariantMap QgsLayerToBookmarksAlgorithm::postProcessAlgorithm( QgsProcessingCon break; } - for ( const QgsBookmark &b : qgis::as_const( mBookmarks ) ) + for ( const QgsBookmark &b : std::as_const( mBookmarks ) ) dest->addBookmark( b ); QVariantMap res; diff --git a/src/analysis/raster/qgsrastercalculator.cpp b/src/analysis/raster/qgsrastercalculator.cpp index 115117b6abc6..6184a8886750 100644 --- a/src/analysis/raster/qgsrastercalculator.cpp +++ b/src/analysis/raster/qgsrastercalculator.cpp @@ -110,7 +110,7 @@ QgsRasterCalculator::Result QgsRasterCalculator::processCalculation( QgsFeedback } // Check input layers and bands - for ( const auto &entry : qgis::as_const( mRasterEntries ) ) + for ( const auto &entry : std::as_const( mRasterEntries ) ) { if ( !entry.raster ) // no raster layer in entry { @@ -173,7 +173,7 @@ QgsRasterCalculator::Result QgsRasterCalculator::processCalculation( QgsFeedback layerRef.chop( 1 ); if ( ! inputBlocks.count( layerRef ) ) { - for ( const QgsRasterCalculatorEntry &ref : qgis::as_const( mRasterEntries ) ) + for ( const QgsRasterCalculatorEntry &ref : std::as_const( mRasterEntries ) ) { if ( ref.ref == layerRef ) { @@ -365,7 +365,7 @@ QgsRasterCalculator::Result QgsRasterCalculator::processCalculationGPU( std::uni QList nodeList( calcNode->findNodes( QgsRasterCalcNode::Type::tRasterRef ) ); QSet capturedTexts; - for ( const auto &r : qgis::as_const( nodeList ) ) + for ( const auto &r : std::as_const( nodeList ) ) { QString s( r->toString().remove( 0, 1 ) ); s.chop( 1 ); @@ -702,7 +702,7 @@ QVector QgsRasterCalculatorEntry::rasterEntries() while ( true ) { bool unique( true ); - for ( const auto &ref : qgis::as_const( availableEntries ) ) + for ( const auto &ref : std::as_const( availableEntries ) ) { // Safety belt if ( !( entry.raster && ref.raster ) ) diff --git a/src/analysis/vector/geometry_checker/qgsgeometrychecker.cpp b/src/analysis/vector/geometry_checker/qgsgeometrychecker.cpp index ab53032c32ea..3e733bad244b 100644 --- a/src/analysis/vector/geometry_checker/qgsgeometrychecker.cpp +++ b/src/analysis/vector/geometry_checker/qgsgeometrychecker.cpp @@ -67,7 +67,7 @@ QFuture QgsGeometryChecker::execute( int *totalSteps ) if ( totalSteps ) { *totalSteps = 0; - for ( QgsGeometryCheck *check : qgis::as_const( mChecks ) ) + for ( QgsGeometryCheck *check : std::as_const( mChecks ) ) { for ( auto it = mFeaturePools.constBegin(); it != mFeaturePools.constEnd(); ++it ) { @@ -174,7 +174,7 @@ bool QgsGeometryChecker::fixError( QgsGeometryCheckError *error, int method, boo } } // - Determine extent to recheck for gaps - for ( QgsGeometryCheckError *err : qgis::as_const( mCheckErrors ) ) + for ( QgsGeometryCheckError *err : std::as_const( mCheckErrors ) ) { if ( err->check()->checkType() == QgsGeometryCheck::LayerCheck ) { @@ -195,7 +195,7 @@ bool QgsGeometryChecker::fixError( QgsGeometryCheckError *error, int method, boo // Recheck feature / changed area to detect new errors QList recheckErrors; - for ( const QgsGeometryCheck *check : qgis::as_const( mChecks ) ) + for ( const QgsGeometryCheck *check : std::as_const( mChecks ) ) { if ( check->checkType() == QgsGeometryCheck::LayerCheck ) { @@ -214,7 +214,7 @@ bool QgsGeometryChecker::fixError( QgsGeometryCheckError *error, int method, boo } // Go through error list, update other errors of the checked feature - for ( QgsGeometryCheckError *err : qgis::as_const( mCheckErrors ) ) + for ( QgsGeometryCheckError *err : std::as_const( mCheckErrors ) ) { if ( err == error || err->status() == QgsGeometryCheckError::StatusObsolete ) { @@ -228,7 +228,7 @@ bool QgsGeometryChecker::fixError( QgsGeometryCheckError *error, int method, boo // Check if this error now matches one found when rechecking the feature/area QgsGeometryCheckError *matchErr = nullptr; int nMatch = 0; - for ( QgsGeometryCheckError *recheckErr : qgis::as_const( recheckErrors ) ) + for ( QgsGeometryCheckError *recheckErr : std::as_const( recheckErrors ) ) { if ( recheckErr->isEqual( err ) || recheckErr->closeMatch( err ) ) { @@ -264,7 +264,7 @@ bool QgsGeometryChecker::fixError( QgsGeometryCheckError *error, int method, boo } // Add new errors - for ( QgsGeometryCheckError *recheckErr : qgis::as_const( recheckErrors ) ) + for ( QgsGeometryCheckError *recheckErr : std::as_const( recheckErrors ) ) { emit errorAdded( recheckErr ); mCheckErrors.append( recheckErr ); @@ -291,7 +291,7 @@ void QgsGeometryChecker::runCheck( const QMap &featur mCheckErrors.append( errors ); mMessages.append( messages ); mErrorListMutex.unlock(); - for ( QgsGeometryCheckError *error : qgis::as_const( errors ) ) + for ( QgsGeometryCheckError *error : std::as_const( errors ) ) { emit errorAdded( error ); } diff --git a/src/analysis/vector/geometry_checker/qgsgeometryisvalidcheck.cpp b/src/analysis/vector/geometry_checker/qgsgeometryisvalidcheck.cpp index fb05831d4dc5..70fb748dbcb7 100644 --- a/src/analysis/vector/geometry_checker/qgsgeometryisvalidcheck.cpp +++ b/src/analysis/vector/geometry_checker/qgsgeometryisvalidcheck.cpp @@ -47,7 +47,7 @@ QList QgsGeometryIsValidCheck::processGeometry( c validator.run(); QList result; - for ( const auto &error : qgis::as_const( errors ) ) + for ( const auto &error : std::as_const( errors ) ) { QgsGeometry errorGeometry; if ( error.hasWhere() ) diff --git a/src/analysis/vector/geometry_checker/qgsgeometrymissingvertexcheck.cpp b/src/analysis/vector/geometry_checker/qgsgeometrymissingvertexcheck.cpp index 40e006d1a50b..15714ba269af 100644 --- a/src/analysis/vector/geometry_checker/qgsgeometrymissingvertexcheck.cpp +++ b/src/analysis/vector/geometry_checker/qgsgeometrymissingvertexcheck.cpp @@ -170,7 +170,7 @@ void QgsGeometryMissingVertexCheck::processPolygon( const QgsCurvePolygon *polyg if ( closestVertex.distance( pt ) > mContext->tolerance ) { bool alreadyReported = false; - for ( QgsGeometryCheckError *error : qgis::as_const( errors ) ) + for ( QgsGeometryCheckError *error : std::as_const( errors ) ) { // Only list missing vertices once if ( error->featureId() == currentFeature.id() && error->location() == QgsPointXY( pt ) ) diff --git a/src/analysis/vector/geometry_checker/qgsvectordataproviderfeaturepool.cpp b/src/analysis/vector/geometry_checker/qgsvectordataproviderfeaturepool.cpp index 9b1c8117c878..33c64a34e944 100644 --- a/src/analysis/vector/geometry_checker/qgsvectordataproviderfeaturepool.cpp +++ b/src/analysis/vector/geometry_checker/qgsvectordataproviderfeaturepool.cpp @@ -114,14 +114,14 @@ bool QgsVectorDataProviderFeaturePool::addFeatures( QgsFeatureList &features, Qg if ( lyr ) { QgsFeatureIds selectedFeatureIds = lyr->selectedFeatureIds(); - for ( const QgsFeature &feature : qgis::as_const( features ) ) + for ( const QgsFeature &feature : std::as_const( features ) ) selectedFeatureIds.insert( feature.id() ); lyr->selectByIds( selectedFeatureIds ); } } ); } - for ( const QgsFeature &feature : qgis::as_const( features ) ) + for ( const QgsFeature &feature : std::as_const( features ) ) insertFeature( feature ); return res; diff --git a/src/analysis/vector/geometry_checker/qgsvectorlayerfeaturepool.cpp b/src/analysis/vector/geometry_checker/qgsvectorlayerfeaturepool.cpp index 41bec1db1cdb..88f4fde91059 100644 --- a/src/analysis/vector/geometry_checker/qgsvectorlayerfeaturepool.cpp +++ b/src/analysis/vector/geometry_checker/qgsvectorlayerfeaturepool.cpp @@ -92,7 +92,7 @@ bool QgsVectorLayerFeaturePool::addFeatures( QgsFeatureList &features, QgsFeatur if ( lyr ) { QgsFeatureIds selectedFeatureIds = lyr->selectedFeatureIds(); - for ( const QgsFeature &feature : qgis::as_const( features ) ) + for ( const QgsFeature &feature : std::as_const( features ) ) selectedFeatureIds.insert( feature.id() ); lyr->selectByIds( selectedFeatureIds ); } @@ -100,7 +100,7 @@ bool QgsVectorLayerFeaturePool::addFeatures( QgsFeatureList &features, QgsFeatur } #endif - for ( const QgsFeature &feature : qgis::as_const( features ) ) + for ( const QgsFeature &feature : std::as_const( features ) ) insertFeature( feature ); return res; diff --git a/src/analysis/vector/qgszonalstatistics.cpp b/src/analysis/vector/qgszonalstatistics.cpp index 74ed6e76284d..f7b89a8b1b95 100644 --- a/src/analysis/vector/qgszonalstatistics.cpp +++ b/src/analysis/vector/qgszonalstatistics.cpp @@ -179,7 +179,7 @@ QString QgsZonalStatistics::getUniqueFieldName( const QString &fieldName, const QString shortName = fieldName.mid( 0, 10 ); bool found = false; - for ( const QgsField &field : qgis::as_const( allFields ) ) + for ( const QgsField &field : std::as_const( allFields ) ) { if ( shortName == field.name() ) { @@ -199,7 +199,7 @@ QString QgsZonalStatistics::getUniqueFieldName( const QString &fieldName, const while ( found ) { found = false; - for ( const QgsField &field : qgis::as_const( allFields ) ) + for ( const QgsField &field : std::as_const( allFields ) ) { if ( shortName == field.name() ) { diff --git a/src/app/decorations/qgsdecorationlayoutextent.cpp b/src/app/decorations/qgsdecorationlayoutextent.cpp index a6711c5250a1..7fd71510018e 100644 --- a/src/app/decorations/qgsdecorationlayoutextent.cpp +++ b/src/app/decorations/qgsdecorationlayoutextent.cpp @@ -136,7 +136,7 @@ void QgsDecorationLayoutExtent::render( const QgsMapSettings &mapSettings, QgsRe QgsLayout *layout = designer->currentLayout(); QList< QgsLayoutItemMap * > maps; layout->layoutItems( maps ); - for ( const QgsLayoutItemMap *map : qgis::as_const( maps ) ) + for ( const QgsLayoutItemMap *map : std::as_const( maps ) ) { QPolygonF extent = map->visibleExtentPolygon(); QPointF labelPoint = extent.at( 1 ); diff --git a/src/app/devtools/networklogger/qgsnetworklogger.cpp b/src/app/devtools/networklogger/qgsnetworklogger.cpp index e36def558e4e..9b040ef3ad2e 100644 --- a/src/app/devtools/networklogger/qgsnetworklogger.cpp +++ b/src/app/devtools/networklogger/qgsnetworklogger.cpp @@ -195,7 +195,7 @@ void QgsNetworkLogger::removeRows( const QList &rows ) QList< int > res = rows; std::sort( res.begin(), res.end(), std::greater< int >() ); - for ( int row : qgis::as_const( res ) ) + for ( int row : std::as_const( res ) ) { int popId = data( index( row, 0, QModelIndex() ), QgsNetworkLoggerNode::RoleId ).toInt(); mRequestGroups.remove( popId ); diff --git a/src/app/devtools/networklogger/qgsnetworkloggernode.cpp b/src/app/devtools/networklogger/qgsnetworkloggernode.cpp index c2697ef42741..f191b8793915 100644 --- a/src/app/devtools/networklogger/qgsnetworkloggernode.cpp +++ b/src/app/devtools/networklogger/qgsnetworkloggernode.cpp @@ -293,7 +293,7 @@ QList QgsNetworkLoggerRequestGroup::actions( QObject *parent ) QObject::connect( copyAsCurlAction, &QAction::triggered, copyAsCurlAction, [ = ] { QString curlHeaders; - for ( const QPair< QString, QString > &header : qgis::as_const( mHeaders ) ) + for ( const QPair< QString, QString > &header : std::as_const( mHeaders ) ) curlHeaders += QStringLiteral( "-H '%1: %2' " ).arg( header.first, header.second ); QString curlData; diff --git a/src/app/georeferencer/qgsgeorefmainwindow.cpp b/src/app/georeferencer/qgsgeorefmainwindow.cpp index cb974c537392..24095db27e87 100644 --- a/src/app/georeferencer/qgsgeorefmainwindow.cpp +++ b/src/app/georeferencer/qgsgeorefmainwindow.cpp @@ -1305,7 +1305,7 @@ void QgsGeoreferencerMainWindow::saveGCPs() QTextStream points( &pointFile ); points << QStringLiteral( "#CRS: %1" ).arg( mProjection.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) ) << endl; points << "mapX,mapY,pixelX,pixelY,enable,dX,dY,residual" << endl; - for ( QgsGeorefDataPoint *pt : qgis::as_const( mPoints ) ) + for ( QgsGeorefDataPoint *pt : std::as_const( mPoints ) ) { points << QStringLiteral( "%1,%2,%3,%4,%5,%6,%7,%8" ) .arg( qgsDoubleToString( pt->transCoords().x() ), @@ -1890,7 +1890,7 @@ QString QgsGeoreferencerMainWindow::generateGDALtranslateCommand( bool generateT gdalCommand << QStringLiteral( "-co TFW=YES" ); } - for ( QgsGeorefDataPoint *pt : qgis::as_const( mPoints ) ) + for ( QgsGeorefDataPoint *pt : std::as_const( mPoints ) ) { gdalCommand << QStringLiteral( "-gcp %1 %2 %3 %4" ).arg( pt->pixelCoords().x() ).arg( -pt->pixelCoords().y() ) .arg( pt->transCoords().x() ).arg( pt->transCoords().y() ); diff --git a/src/app/georeferencer/qgstransformsettingsdialog.cpp b/src/app/georeferencer/qgstransformsettingsdialog.cpp index d43786afc5b6..2134437fde14 100644 --- a/src/app/georeferencer/qgstransformsettingsdialog.cpp +++ b/src/app/georeferencer/qgstransformsettingsdialog.cpp @@ -96,7 +96,7 @@ QgsTransformSettingsDialog::QgsTransformSettingsDialog( const QString &raster, c mListCompression.append( QStringLiteral( "PACKBITS" ) ); mListCompression.append( QStringLiteral( "DEFLATE" ) ); QStringList listCompressionTr; - for ( const QString &item : qgis::as_const( mListCompression ) ) + for ( const QString &item : std::as_const( mListCompression ) ) { listCompressionTr.append( tr( item.toLatin1().data() ) ); } diff --git a/src/app/labeling/qgsmaptoollabel.cpp b/src/app/labeling/qgsmaptoollabel.cpp index afd93c16099b..bb1d1f68174f 100644 --- a/src/app/labeling/qgsmaptoollabel.cpp +++ b/src/app/labeling/qgsmaptoollabel.cpp @@ -74,7 +74,7 @@ bool QgsMapToolLabel::labelAtPosition( QMouseEvent *e, QgsLabelPosition &p ) QList activeLayerLabels; if ( const QgsVectorLayer *currentLayer = qobject_cast< QgsVectorLayer * >( mCanvas->currentLayer() ) ) { - for ( const QgsLabelPosition &pos : qgis::as_const( labelPosList ) ) + for ( const QgsLabelPosition &pos : std::as_const( labelPosList ) ) { if ( pos.layerID == currentLayer->id() ) { @@ -87,7 +87,7 @@ bool QgsMapToolLabel::labelAtPosition( QMouseEvent *e, QgsLabelPosition &p ) // prioritize unplaced labels QList unplacedLabels; - for ( const QgsLabelPosition &pos : qgis::as_const( labelPosList ) ) + for ( const QgsLabelPosition &pos : std::as_const( labelPosList ) ) { if ( pos.isUnplaced ) { @@ -101,7 +101,7 @@ bool QgsMapToolLabel::labelAtPosition( QMouseEvent *e, QgsLabelPosition &p ) { // multiple candidates found, so choose the smallest (i.e. most difficult to select otherwise) double minSize = std::numeric_limits< double >::max(); - for ( const QgsLabelPosition &pos : qgis::as_const( labelPosList ) ) + for ( const QgsLabelPosition &pos : std::as_const( labelPosList ) ) { const double labelSize = pos.width * pos.height; if ( labelSize < minSize ) @@ -137,7 +137,7 @@ bool QgsMapToolLabel::calloutAtPosition( QMouseEvent *e, QgsCalloutPosition &p, QList activeLayerCallouts; if ( const QgsVectorLayer *currentLayer = qobject_cast< QgsVectorLayer * >( mCanvas->currentLayer() ) ) { - for ( const QgsCalloutPosition &pos : qgis::as_const( calloutPosList ) ) + for ( const QgsCalloutPosition &pos : std::as_const( calloutPosList ) ) { if ( pos.layerID == currentLayer->id() ) { @@ -846,7 +846,7 @@ bool QgsMapToolLabel::createAuxiliaryFields( LabelDetails &details, QgsPalIndexe QgsTemporaryCursorOverride cursor( Qt::WaitCursor ); bool changed = false; - for ( const QgsPalLayerSettings::Property &p : qgis::as_const( mPalProperties ) ) + for ( const QgsPalLayerSettings::Property &p : std::as_const( mPalProperties ) ) { int index = -1; @@ -897,7 +897,7 @@ bool QgsMapToolLabel::createAuxiliaryFields( LabelDetails &details, QgsDiagramIn QgsTemporaryCursorOverride cursor( Qt::WaitCursor ); bool changed = false; - for ( const QgsDiagramLayerSettings::Property &p : qgis::as_const( mDiagramProperties ) ) + for ( const QgsDiagramLayerSettings::Property &p : std::as_const( mDiagramProperties ) ) { int index = -1; @@ -946,7 +946,7 @@ bool QgsMapToolLabel::createAuxiliaryFields( QgsCalloutPosition &details, QgsCal QgsTemporaryCursorOverride cursor( Qt::WaitCursor ); bool changed = false; - for ( const QgsCallout::Property &p : qgis::as_const( mCalloutProperties ) ) + for ( const QgsCallout::Property &p : std::as_const( mCalloutProperties ) ) { int index = -1; diff --git a/src/app/labeling/qgsmaptoolpinlabels.cpp b/src/app/labeling/qgsmaptoolpinlabels.cpp index 37f1195412c7..f70bc58409e9 100644 --- a/src/app/labeling/qgsmaptoolpinlabels.cpp +++ b/src/app/labeling/qgsmaptoolpinlabels.cpp @@ -259,7 +259,7 @@ void QgsMapToolPinLabels::highlightPinnedLabels() void QgsMapToolPinLabels::removePinnedHighlights() { QApplication::setOverrideCursor( Qt::BusyCursor ); - for ( QgsRubberBand *rb : qgis::as_const( mHighlights ) ) + for ( QgsRubberBand *rb : std::as_const( mHighlights ) ) { delete rb; } diff --git a/src/app/labeling/qgsmaptoolshowhidelabels.cpp b/src/app/labeling/qgsmaptoolshowhidelabels.cpp index fd022c48afc0..d7e9afa7bfd1 100644 --- a/src/app/labeling/qgsmaptoolshowhidelabels.cpp +++ b/src/app/labeling/qgsmaptoolshowhidelabels.cpp @@ -180,7 +180,7 @@ void QgsMapToolShowHideLabels::showHideLabels( QMouseEvent *e ) QList positions; if ( selectedLabelFeatures( vlayer, positions ) ) { - for ( const QgsLabelPosition &pos : qgis::as_const( positions ) ) + for ( const QgsLabelPosition &pos : std::as_const( positions ) ) { if ( showHide( pos, false ) ) labelChanged = true; @@ -192,7 +192,7 @@ void QgsMapToolShowHideLabels::showHideLabels( QMouseEvent *e ) QgsFeatureIds fids; if ( selectedFeatures( vlayer, fids ) ) { - for ( const QgsFeatureId &fid : qgis::as_const( fids ) ) + for ( const QgsFeatureId &fid : std::as_const( fids ) ) { QgsLabelPosition pos; pos.featureId = fid; diff --git a/src/app/layout/qgslayout3dmapwidget.cpp b/src/app/layout/qgslayout3dmapwidget.cpp index 535cfaf48d1d..8c6ecdf76bc5 100644 --- a/src/app/layout/qgslayout3dmapwidget.cpp +++ b/src/app/layout/qgslayout3dmapwidget.cpp @@ -95,7 +95,7 @@ QgsLayout3DMapWidget::QgsLayout3DMapWidget( QgsLayoutItem3DMap *map3D ) QList lst; lst << mCenterXSpinBox << mCenterYSpinBox << mCenterZSpinBox << mDistanceToCenterSpinBox << mPitchAngleSpinBox << mHeadingAngleSpinBox; - for ( QgsDoubleSpinBox *spinBox : qgis::as_const( lst ) ) + for ( QgsDoubleSpinBox *spinBox : std::as_const( lst ) ) connect( spinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayout3DMapWidget::updateCameraPose ); updateCameraPoseWidgetsFromItem(); diff --git a/src/app/layout/qgslayoutappmenuprovider.cpp b/src/app/layout/qgslayoutappmenuprovider.cpp index 7c35916b569a..bc6eece592b3 100644 --- a/src/app/layout/qgslayoutappmenuprovider.cpp +++ b/src/app/layout/qgslayoutappmenuprovider.cpp @@ -58,7 +58,7 @@ QMenu *QgsLayoutAppMenuProvider::createContextMenu( QWidget *parent, QgsLayout * bool foundSelectedGroup = false; QList< QgsLayoutItemGroup * > groups; layout->layoutItems( groups ); - for ( QgsLayoutItemGroup *group : qgis::as_const( groups ) ) + for ( QgsLayoutItemGroup *group : std::as_const( groups ) ) { if ( group->isSelected() ) { diff --git a/src/app/layout/qgslayoutdesignerdialog.cpp b/src/app/layout/qgslayoutdesignerdialog.cpp index df09a14b2c0f..2ec4d3aae09c 100644 --- a/src/app/layout/qgslayoutdesignerdialog.cpp +++ b/src/app/layout/qgslayoutdesignerdialog.cpp @@ -1550,7 +1550,7 @@ void QgsLayoutDesignerDialog::dropEvent( QDropEvent *event ) connect( timer, &QTimer::timeout, this, [this, timer, files, layoutPoint] { - for ( const QString &file : qgis::as_const( files ) ) + for ( const QString &file : std::as_const( files ) ) { const QVector> handlers = QgisApp::instance()->customLayoutDropHandlers(); for ( QgsLayoutCustomDropHandler *handler : handlers ) @@ -4080,7 +4080,7 @@ bool QgsLayoutDesignerDialog::containsWmsLayers() const QList< QgsLayoutItemMap *> maps; mLayout->layoutItems( maps ); - for ( QgsLayoutItemMap *map : qgis::as_const( maps ) ) + for ( QgsLayoutItemMap *map : std::as_const( maps ) ) { if ( map->containsWmsLayer() ) return true; @@ -4137,7 +4137,7 @@ bool QgsLayoutDesignerDialog::requiresRasterization() const QList< QgsLayoutItem *> items; mLayout->layoutItems( items ); - for ( QgsLayoutItem *currentItem : qgis::as_const( items ) ) + for ( QgsLayoutItem *currentItem : std::as_const( items ) ) { if ( currentItem->requiresRasterization() ) return true; @@ -4150,7 +4150,7 @@ bool QgsLayoutDesignerDialog::containsAdvancedEffects() const QList< QgsLayoutItem *> items; mLayout->layoutItems( items ); - for ( QgsLayoutItem *currentItem : qgis::as_const( items ) ) + for ( QgsLayoutItem *currentItem : std::as_const( items ) ) { if ( currentItem->containsAdvancedEffects() ) return true; @@ -4625,7 +4625,7 @@ void QgsLayoutDesignerDialog::atlasFeatureChanged( const QgsFeature &feature ) // and we hit a feature with no geometry attached, then warn the user QList< QgsLayoutItemMap * > maps; mLayout->layoutItems( maps ); - for ( const QgsLayoutItemMap *map : qgis::as_const( maps ) ) + for ( const QgsLayoutItemMap *map : std::as_const( maps ) ) { if ( map->atlasDriven() ) { diff --git a/src/app/layout/qgslayoutmanagerdialog.cpp b/src/app/layout/qgslayoutmanagerdialog.cpp index 836bc46becb1..b2f37a27fce3 100644 --- a/src/app/layout/qgslayoutmanagerdialog.cpp +++ b/src/app/layout/qgslayoutmanagerdialog.cpp @@ -417,7 +417,7 @@ void QgsLayoutManagerDialog::removeClicked() } // Once we have the layout list, we can delete all of them ! - for ( QgsMasterLayoutInterface *l : qgis::as_const( layoutList ) ) + for ( QgsMasterLayoutInterface *l : std::as_const( layoutList ) ) { QgsProject::instance()->layoutManager()->removeLayout( l ); } diff --git a/src/app/locator/qgsinbuiltlocatorfilters.cpp b/src/app/locator/qgsinbuiltlocatorfilters.cpp index 4e94ebacfa52..07b6ac243af2 100644 --- a/src/app/locator/qgsinbuiltlocatorfilters.cpp +++ b/src/app/locator/qgsinbuiltlocatorfilters.cpp @@ -159,7 +159,7 @@ void QgsActionLocatorFilter::fetchResults( const QString &string, const QgsLocat QList found; - for ( QWidget *object : qgis::as_const( mActionParents ) ) + for ( QWidget *object : std::as_const( mActionParents ) ) { searchActions( string, object, found ); } @@ -381,13 +381,14 @@ void QgsActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, c fieldRestriction( searchString ); // propose available fields for restriction - for ( const QString &field : qgis::as_const( mFieldsCompletion ) ) + for ( const QString &field : std::as_const( mFieldsCompletion ) ) { QgsLocatorResult result; result.displayString = QStringLiteral( "@%1" ).arg( field ); result.description = tr( "Limit the search to the field '%1'" ).arg( field ); result.userData = QVariantMap( {{QStringLiteral( "type" ), QVariant::fromValue( ResultType::FieldRestriction )}, - {QStringLiteral( "search_text" ), QStringLiteral( "%1 @%2 " ).arg( prefix(), field ) } } ); + {QStringLiteral( "search_text" ), QStringLiteral( "%1 @%2 " ).arg( prefix(), field ) } + } ); result.score = 1; emit resultFetched( result ); } @@ -598,7 +599,7 @@ void QgsAllLayersFeaturesLocatorFilter::fetchResults( const QString &string, con QgsFeature f; // we cannot used const loop since iterator::nextFeature is not const - for ( auto preparedLayer : qgis::as_const( mPreparedLayers ) ) + for ( auto preparedLayer : std::as_const( mPreparedLayers ) ) { foundInCurrentLayer = 0; diff --git a/src/app/main.cpp b/src/app/main.cpp index b33b4479076c..159495b024d1 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -1035,7 +1035,7 @@ int main( int argc, char *argv[] ) QgsApplication myApp( argc, argv, myUseGuiFlag ); //write the log messages written before creating QgsApplication - for ( const QString &preApplicationLogMessage : qgis::as_const( preApplicationLogMessages ) ) + for ( const QString &preApplicationLogMessage : std::as_const( preApplicationLogMessages ) ) QgsMessageLog::logMessage( preApplicationLogMessage ); // Settings migration is only supported on the default profile for now. @@ -1399,7 +1399,7 @@ int main( int argc, char *argv[] ) ///////////////////////////////////////////////////////////////////// // autoload any file names that were passed in on the command line ///////////////////////////////////////////////////////////////////// - for ( const QString &layerName : qgis::as_const( sFileList ) ) + for ( const QString &layerName : std::as_const( sFileList ) ) { QgsDebugMsg( QStringLiteral( "Trying to load file : %1" ).arg( layerName ) ); // don't load anything with a .qgs extension - these are project files diff --git a/src/app/options/qgscodeeditoroptions.cpp b/src/app/options/qgscodeeditoroptions.cpp index 2c5582309dd8..7d6311c49137 100644 --- a/src/app/options/qgscodeeditoroptions.cpp +++ b/src/app/options/qgscodeeditoroptions.cpp @@ -94,7 +94,7 @@ QgsCodeEditorOptionsWidget::QgsCodeEditorOptionsWidget( QWidget *parent ) } std::sort( names.begin(), names.end() ); - for ( const QString &name : qgis::as_const( names ) ) + for ( const QString &name : std::as_const( names ) ) { mColorSchemeComboBox->addItem( name, themeNameToId.value( name ) ); } diff --git a/src/app/options/qgsoptions.cpp b/src/app/options/qgsoptions.cpp index b9e7550d4a08..8e015f1dea88 100644 --- a/src/app/options/qgsoptions.cpp +++ b/src/app/options/qgsoptions.cpp @@ -1197,7 +1197,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListcreateWidget( this ); if ( !page ) @@ -2407,11 +2407,11 @@ void QgsOptions::loadGdalDriverList() // sort list case insensitive - no existing function for this! QMap strMap; - for ( const QString &str : qgis::as_const( myDrivers ) ) + for ( const QString &str : std::as_const( myDrivers ) ) strMap.insert( str.toLower(), str ); myDrivers = strMap.values(); - for ( const QString &myName : qgis::as_const( myDrivers ) ) + for ( const QString &myName : std::as_const( myDrivers ) ) { QTreeWidgetItem *mypItem = new QTreeWidgetItem( QStringList( myName ) ); if ( mySkippedDrivers.contains( myName ) ) @@ -2450,13 +2450,13 @@ void QgsOptions::loadGdalDriverList() // populate cmbEditCreateOptions with gdal write drivers - sorted, GTiff first strMap.clear(); - for ( const QString &str : qgis::as_const( myGdalWriteDrivers ) ) + for ( const QString &str : std::as_const( myGdalWriteDrivers ) ) strMap.insert( str.toLower(), str ); myGdalWriteDrivers = strMap.values(); myGdalWriteDrivers.removeAll( QStringLiteral( "Gtiff" ) ); myGdalWriteDrivers.prepend( QStringLiteral( "GTiff" ) ); cmbEditCreateOptions->clear(); - for ( const QString &myName : qgis::as_const( myGdalWriteDrivers ) ) + for ( const QString &myName : std::as_const( myGdalWriteDrivers ) ) { cmbEditCreateOptions->addItem( myName ); } @@ -2844,7 +2844,7 @@ void QgsOptions::showHelp() QString link; // give first priority to created pages which have specified a help key - for ( const QgsOptionsPageWidget *widget : qgis::as_const( mAdditionalOptionWidgets ) ) + for ( const QgsOptionsPageWidget *widget : std::as_const( mAdditionalOptionWidgets ) ) { if ( widget == activeTab ) { diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index b86d88b09d88..2431befbb3c6 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -1863,7 +1863,7 @@ void QgisApp::dropEvent( QDropEvent *event ) { QgsCanvasRefreshBlocker refreshBlocker; - for ( const QString &file : qgis::as_const( files ) ) + for ( const QString &file : std::as_const( files ) ) { bool handled = false; @@ -2029,7 +2029,7 @@ void QgisApp::handleDropUriList( const QgsMimeDataUtils::UriList &lst ) std::sort( warnings.begin(), warnings.end() ); warnings.erase( std::unique( warnings.begin(), warnings.end() ), warnings.end() ); - for ( const QString &w : qgis::as_const( warnings ) ) + for ( const QString &w : std::as_const( warnings ) ) { message += QStringLiteral( "

  • %1
  • " ).arg( w.toHtmlEscaped().replace( '\n', QLatin1String( "
    " ) ) ); } @@ -2176,7 +2176,7 @@ const QList QgisApp::findBrokenLayerDependencies( QgsVectorLa { // Make sure we don't add it twice if it was already added by the form widgets check bool refFound = false; - for ( const QgsVectorLayerRef &otherRef : qgis::as_const( brokenDependencies ) ) + for ( const QgsVectorLayerRef &otherRef : std::as_const( brokenDependencies ) ) { if ( dependency.layerId == otherRef.layerId || ( dependency.source == otherRef.source && dependency.provider == otherRef.provider ) ) { @@ -4933,7 +4933,7 @@ void QgisApp::updateRecentProjectPaths() } std::vector< QgsNative::RecentProjectProperties > recentProjects; - for ( const QgsRecentProjectItemsModel::RecentProjectData &recentProject : qgis::as_const( mRecentProjects ) ) + for ( const QgsRecentProjectItemsModel::RecentProjectData &recentProject : std::as_const( mRecentProjects ) ) { QgsNative::RecentProjectProperties project; project.title = recentProject.title; @@ -4994,7 +4994,7 @@ void QgisApp::saveRecentProjectPath( bool savePreviewImage, const QIcon &iconOve int pinnedCount = 0; int nonPinnedPos = 0; bool pinnedTop = true; - for ( const QgsRecentProjectItemsModel::RecentProjectData &recentProject : qgis::as_const( mRecentProjects ) ) + for ( const QgsRecentProjectItemsModel::RecentProjectData &recentProject : std::as_const( mRecentProjects ) ) { if ( recentProject.pin ) { @@ -5511,7 +5511,7 @@ bool QgisApp::addVectorLayersPrivate( const QStringList &layerQStringList, const // Register this layer with the layers registry QgsProject::instance()->addMapLayers( layersToAdd ); - for ( QgsMapLayer *l : qgis::as_const( layersToAdd ) ) + for ( QgsMapLayer *l : std::as_const( layersToAdd ) ) { bool ok; l->loadDefaultStyle( ok ); @@ -5570,7 +5570,7 @@ QgsMeshLayer *QgisApp::addMeshLayerPrivate( const QString &url, const QString &b layer.reset( nullptr ); else { - for ( QgsMapLayer *newLayer : qgis::as_const( subLayers ) ) + for ( QgsMapLayer *newLayer : std::as_const( subLayers ) ) { askUserForDatumTransform( newLayer->crs(), QgsProject::instance()->crs(), newLayer ); QgsMeshLayer *meshLayer = qobject_cast( newLayer ); @@ -6127,7 +6127,7 @@ QList QgisApp::askUserForOGRSublayers( QgsVectorLayer *&parentLay group = QgsProject::instance()->layerTreeRoot()->insertGroup( 0, name ); QgsProject::instance()->addMapLayers( result, ! addToGroup ); - for ( QgsMapLayer *l : qgis::as_const( result ) ) + for ( QgsMapLayer *l : std::as_const( result ) ) { bool ok; l->loadDefaultStyle( ok ); @@ -6855,7 +6855,7 @@ void QgisApp::fileOpen() QStringList extensions; fileFilters << tr( "QGIS files" ) + QStringLiteral( " (*.qgs *.qgz *.QGS *.QGZ)" ); extensions << QStringLiteral( "qgs" ) << QStringLiteral( "qgz" ); - for ( QgsCustomProjectOpenHandler *handler : qgis::as_const( mCustomProjectOpenHandlers ) ) + for ( QgsCustomProjectOpenHandler *handler : std::as_const( mCustomProjectOpenHandlers ) ) { if ( handler ) { @@ -6941,7 +6941,7 @@ bool QgisApp::addProject( const QString &projectFile ) bool usedCustomHandler = false; bool customHandlerWantsThumbnail = false; QIcon customHandlerIcon; - for ( QgsCustomProjectOpenHandler *handler : qgis::as_const( mCustomProjectOpenHandlers ) ) + for ( QgsCustomProjectOpenHandler *handler : std::as_const( mCustomProjectOpenHandlers ) ) { if ( handler && handler->handleProjectOpen( projectFile ) ) { @@ -10456,7 +10456,7 @@ void QgisApp::pasteFromClipboard( QgsMapLayer *destinationLayer ) // Count collapsed geometries int invalidGeometriesCount = 0; - for ( const auto &feature : qgis::as_const( compatibleFeatures ) ) + for ( const auto &feature : std::as_const( compatibleFeatures ) ) { QgsGeometry geom = feature.geometry(); @@ -10575,7 +10575,7 @@ void QgisApp::pasteFeatures( QgsVectorLayer *pasteVectorLayer, int invalidGeomet { QgsFeatureIds newIds; newIds.reserve( features.size() ); - for ( const QgsFeature &f : qgis::as_const( features ) ) + for ( const QgsFeature &f : std::as_const( features ) ) { newIds << f.id(); } @@ -11679,7 +11679,7 @@ void QgisApp::removeLayer() } }; - for ( const auto &n : qgis::as_const( selectedNodes ) ) + for ( const auto &n : std::as_const( selectedNodes ) ) { harvest( n ); } @@ -11839,7 +11839,7 @@ void QgisApp::duplicateLayers( const QList &lyrList ) setActiveLayer( newSelection ); // display errors in message bar after duplication of layers - for ( QgsMessageBarItem *msgBar : qgis::as_const( msgBars ) ) + for ( QgsMessageBarItem *msgBar : std::as_const( msgBars ) ) { mInfoBar->pushItem( msgBar ); } @@ -12331,7 +12331,7 @@ QMap< QString, QString > QgisApp::projectPropertiesPagesMap() } ); int idx = sProjectPropertiesPagesMap.count(); - for ( const QPointer< QgsOptionsWidgetFactory > &f : qgis::as_const( mProjectPropertiesWidgetFactories ) ) + for ( const QPointer< QgsOptionsWidgetFactory > &f : std::as_const( mProjectPropertiesWidgetFactories ) ) { // remove any deleted factories if ( f ) @@ -12410,7 +12410,7 @@ QMap< QString, int > QgisApp::optionsPagesMap() } ); QList< std::pair< QString, QString > > pages = sOptionsPagesList; - for ( const QPointer< QgsOptionsWidgetFactory > &f : qgis::as_const( mOptionsWidgetFactories ) ) + for ( const QPointer< QgsOptionsWidgetFactory > &f : std::as_const( mOptionsWidgetFactories ) ) { // remove any deleted factories if ( f ) @@ -12871,7 +12871,7 @@ void QgisApp::switchToMapToolViaHandler() return; QgsAbstractMapToolHandler *handler = nullptr; - for ( QgsAbstractMapToolHandler *h : qgis::as_const( mMapToolHandlers ) ) + for ( QgsAbstractMapToolHandler *h : std::as_const( mMapToolHandlers ) ) { if ( h->action() == sourceAction ) { @@ -13483,7 +13483,7 @@ bool QgisApp::checkMemoryLayers() bool QgisApp::checkExitBlockers() { - for ( QgsApplicationExitBlockerInterface *blocker : qgis::as_const( mApplicationExitBlockers ) ) + for ( QgsApplicationExitBlockerInterface *blocker : std::as_const( mApplicationExitBlockers ) ) { if ( !blocker->allowExit() ) return false; @@ -14628,7 +14628,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer ) updateLayerModifiedActions(); QgsAbstractMapToolHandler::Context context; - for ( QgsAbstractMapToolHandler *handler : qgis::as_const( mMapToolHandlers ) ) + for ( QgsAbstractMapToolHandler *handler : std::as_const( mMapToolHandlers ) ) { handler->action()->setEnabled( handler->isCompatibleWithLayer( layer, context ) ); if ( handler->mapTool() == mMapCanvas->mapTool() ) @@ -15540,7 +15540,7 @@ QgsRasterLayer *QgisApp::addRasterLayerPrivate( // The first layer loaded is not useful in that case. The user can select it in // the list if he wants to load it. delete layer; - for ( QgsMapLayer *l : qgis::as_const( subLayers ) ) + for ( QgsMapLayer *l : std::as_const( subLayers ) ) askUserForDatumTransform( l->crs(), QgsProject::instance()->crs(), l ); layer = !subLayers.isEmpty() ? qobject_cast< QgsRasterLayer * >( subLayers.at( 0 ) ) : nullptr; } @@ -16248,7 +16248,7 @@ void QgisApp::showLayerProperties( QgsMapLayer *mapLayer, const QString &page ) { QgsRasterLayerProperties *rasterLayerPropertiesDialog = new QgsRasterLayerProperties( mapLayer, mMapCanvas, this ); - for ( QgsMapLayerConfigWidgetFactory *factory : qgis::as_const( mMapLayerPanelFactories ) ) + for ( QgsMapLayerConfigWidgetFactory *factory : std::as_const( mMapLayerPanelFactories ) ) { rasterLayerPropertiesDialog->addPropertiesPageFactory( factory ); } @@ -16278,7 +16278,7 @@ void QgisApp::showLayerProperties( QgsMapLayer *mapLayer, const QString &page ) { QgsMeshLayerProperties meshLayerPropertiesDialog( mapLayer, mMapCanvas, this ); - for ( QgsMapLayerConfigWidgetFactory *factory : qgis::as_const( mMapLayerPanelFactories ) ) + for ( QgsMapLayerConfigWidgetFactory *factory : std::as_const( mMapLayerPanelFactories ) ) { meshLayerPropertiesDialog.addPropertiesPageFactory( factory ); } @@ -16312,7 +16312,7 @@ void QgisApp::showLayerProperties( QgsMapLayer *mapLayer, const QString &page ) saveAsFile( clone.get() ); } } ); - for ( QgsMapLayerConfigWidgetFactory *factory : qgis::as_const( mMapLayerPanelFactories ) ) + for ( QgsMapLayerConfigWidgetFactory *factory : std::as_const( mMapLayerPanelFactories ) ) { vectorLayerPropertiesDialog->addPropertiesPageFactory( factory ); } @@ -16359,7 +16359,7 @@ void QgisApp::showLayerProperties( QgsMapLayer *mapLayer, const QString &page ) else pointCloudLayerPropertiesDialog.restoreLastPage(); - for ( QgsMapLayerConfigWidgetFactory *factory : qgis::as_const( mMapLayerPanelFactories ) ) + for ( QgsMapLayerConfigWidgetFactory *factory : std::as_const( mMapLayerPanelFactories ) ) { pointCloudLayerPropertiesDialog.addPropertiesPageFactory( factory ); } diff --git a/src/app/qgscustomization.cpp b/src/app/qgscustomization.cpp index b666dfec8a27..2bff4032919c 100644 --- a/src/app/qgscustomization.cpp +++ b/src/app/qgscustomization.cpp @@ -153,7 +153,7 @@ bool QgsCustomizationDialog::filterItems( const QString &text ) success = !items.empty(); mTreeInitialExpand.clear(); - for ( QTreeWidgetItem *item : qgis::as_const( items ) ) + for ( QTreeWidgetItem *item : std::as_const( items ) ) { setChildrenVisible( item, true ); diff --git a/src/app/qgscustomprojectiondialog.cpp b/src/app/qgscustomprojectiondialog.cpp index 71b7f43be8aa..9c35d64aa252 100644 --- a/src/app/qgscustomprojectiondialog.cpp +++ b/src/app/qgscustomprojectiondialog.cpp @@ -285,7 +285,7 @@ void QgsCustomProjectionDialog::buttonBox_accepted() //Check if all CRS are valid: QgsCoordinateReferenceSystem crs; - for ( const Definition &def : qgis::as_const( mDefinitions ) ) + for ( const Definition &def : std::as_const( mDefinitions ) ) { if ( !def.wkt.isEmpty() ) crs.createFromWkt( def.wkt ); @@ -350,7 +350,7 @@ void QgsCustomProjectionDialog::buttonBox_accepted() //Modify the CRS changed: bool saveSuccess = true; - for ( const Definition &def : qgis::as_const( mDefinitions ) ) + for ( const Definition &def : std::as_const( mDefinitions ) ) { if ( !def.wkt.isEmpty() ) crs.createFromWkt( def.wkt ); diff --git a/src/app/qgsdiscoverrelationsdialog.cpp b/src/app/qgsdiscoverrelationsdialog.cpp index 6ff2baf5d040..229564a6e2b2 100644 --- a/src/app/qgsdiscoverrelationsdialog.cpp +++ b/src/app/qgsdiscoverrelationsdialog.cpp @@ -34,7 +34,7 @@ QgsDiscoverRelationsDialog::QgsDiscoverRelationsDialog( const QList connect( mRelationsTable->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsDiscoverRelationsDialog::onSelectionChanged ); mFoundRelations = QgsRelationManager::discoverRelations( existingRelations, layers ); - for ( const QgsRelation &relation : qgis::as_const( mFoundRelations ) ) + for ( const QgsRelation &relation : std::as_const( mFoundRelations ) ) addRelation( relation ); mRelationsTable->resizeColumnsToContents(); diff --git a/src/app/qgsdxfexportdialog.cpp b/src/app/qgsdxfexportdialog.cpp index c9a49a295601..3b1357ddc390 100644 --- a/src/app/qgsdxfexportdialog.cpp +++ b/src/app/qgsdxfexportdialog.cpp @@ -281,7 +281,7 @@ QList< QgsDxfExport::DxfLayer > QgsVectorLayerAndAttributeModel::layers() const QList< QgsDxfExport::DxfLayer > layers; QHash< QString, int > layerIdx; - for ( const QModelIndex &idx : qgis::as_const( mCheckedLeafs ) ) + for ( const QModelIndex &idx : std::as_const( mCheckedLeafs ) ) { QgsLayerTreeNode *node = index2node( idx ); if ( QgsLayerTree::isGroup( node ) ) diff --git a/src/app/qgsgeometryvalidationmodel.cpp b/src/app/qgsgeometryvalidationmodel.cpp index 47505ff337f0..5b3d164cf2a1 100644 --- a/src/app/qgsgeometryvalidationmodel.cpp +++ b/src/app/qgsgeometryvalidationmodel.cpp @@ -211,7 +211,7 @@ QVariant QgsGeometryValidationModel::data( const QModelIndex &index, int role ) case DetailsRole: { QStringList details; - for ( const std::shared_ptr &error : qgis::as_const( featureItem.errors ) ) + for ( const std::shared_ptr &error : std::as_const( featureItem.errors ) ) { details << error->description(); } diff --git a/src/app/qgsgeometryvalidationservice.cpp b/src/app/qgsgeometryvalidationservice.cpp index 58e4e6fea219..6c6551e172df 100644 --- a/src/app/qgsgeometryvalidationservice.cpp +++ b/src/app/qgsgeometryvalidationservice.cpp @@ -208,7 +208,7 @@ void QgsGeometryValidationService::enableLayerChecks( QgsVectorLayer *layer ) if ( layer->geometryOptions()->geometryChecks().empty() ) { - for ( QMetaObject::Connection connection : qgis::as_const( checkInformation.connections ) ) + for ( QMetaObject::Connection connection : std::as_const( checkInformation.connections ) ) { disconnect( connection ); } @@ -248,7 +248,7 @@ void QgsGeometryValidationService::enableLayerChecks( QgsVectorLayer *layer ) } QList singleGeometryChecks; - for ( QgsGeometryCheck *check : qgis::as_const( layerChecks ) ) + for ( QgsGeometryCheck *check : std::as_const( layerChecks ) ) { Q_ASSERT( dynamic_cast( check ) ); singleGeometryChecks.append( dynamic_cast( check ) ); diff --git a/src/app/qgshandlebadlayers.cpp b/src/app/qgshandlebadlayers.cpp index ba1294ccb06f..c86dca818519 100644 --- a/src/app/qgshandlebadlayers.cpp +++ b/src/app/qgshandlebadlayers.cpp @@ -563,7 +563,7 @@ void QgsHandleBadLayers::autoFind() QProgressDialog progressDialog( QObject::tr( "Searching files" ), QObject::tr( "Cancel" ), 1, layersToFind.size(), this, Qt::Dialog ); - for ( int i : qgis::as_const( layersToFind ) ) + for ( int i : std::as_const( layersToFind ) ) { const int idx = mLayerList->item( i, 0 )->data( static_cast< int >( CustomRoles::Index ) ).toInt(); QDomNode &node = const_cast( mLayers[ idx ] ); diff --git a/src/app/qgslayerstylingwidget.cpp b/src/app/qgslayerstylingwidget.cpp index c741dbd8381c..918b0ae2050e 100644 --- a/src/app/qgslayerstylingwidget.cpp +++ b/src/app/qgslayerstylingwidget.cpp @@ -259,7 +259,7 @@ void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer ) break; } - for ( QgsMapLayerConfigWidgetFactory *factory : qgis::as_const( mPageFactories ) ) + for ( QgsMapLayerConfigWidgetFactory *factory : std::as_const( mPageFactories ) ) { if ( factory->supportsStyleDock() && factory->supportsLayer( layer ) ) { diff --git a/src/app/qgslayertreeviewbadlayerindicator.cpp b/src/app/qgslayertreeviewbadlayerindicator.cpp index 503618df275e..218cb26c3e0c 100644 --- a/src/app/qgslayertreeviewbadlayerindicator.cpp +++ b/src/app/qgslayertreeviewbadlayerindicator.cpp @@ -39,7 +39,7 @@ QgsLayerTreeViewBadLayerIndicatorProvider::QgsLayerTreeViewBadLayerIndicatorProv void QgsLayerTreeViewBadLayerIndicatorProvider::reportLayerError( const QString &error, QgsMapLayer *layer ) { - for ( const Error &e : qgis::as_const( mErrors ) ) + for ( const Error &e : std::as_const( mErrors ) ) { // don't report identical errors if ( e.layer == layer && error == e.error ) @@ -66,7 +66,7 @@ void QgsLayerTreeViewBadLayerIndicatorProvider::onIndicatorClicked( const QModel { QStringList thisLayerErrors; QList< Error > newErrors; - for ( const Error &error : qgis::as_const( mErrors ) ) + for ( const Error &error : std::as_const( mErrors ) ) { if ( error.layer != layer ) newErrors.append( error ); @@ -110,7 +110,7 @@ QString QgsLayerTreeViewBadLayerIndicatorProvider::tooltipText( QgsMapLayer *lay return tr( "Unavailable layer!
    Layer data source could not be found. Click to set a new data source" ); else { - for ( const Error &error : qgis::as_const( mErrors ) ) + for ( const Error &error : std::as_const( mErrors ) ) { if ( error.layer == layer ) return error.error; @@ -124,7 +124,7 @@ bool QgsLayerTreeViewBadLayerIndicatorProvider::acceptLayer( QgsMapLayer *layer if ( !layer->isValid() ) return true; - for ( const Error &error : qgis::as_const( mErrors ) ) + for ( const Error &error : std::as_const( mErrors ) ) { if ( error.layer == layer ) return true; diff --git a/src/app/qgsmapthemes.cpp b/src/app/qgsmapthemes.cpp index 275edcc5cc85..cb999a634de9 100644 --- a/src/app/qgsmapthemes.cpp +++ b/src/app/qgsmapthemes.cpp @@ -148,7 +148,7 @@ void QgsMapThemes::renameCurrentPreset() QgsMapThemeCollection::MapThemeRecord mapTheme = currentState(); QStringList existingNames = QgsProject::instance()->mapThemeCollection()->mapThemes(); - for ( QAction *actionPreset : qgis::as_const( mMenuPresetActions ) ) + for ( QAction *actionPreset : std::as_const( mMenuPresetActions ) ) { if ( actionPreset->isChecked() ) { @@ -173,7 +173,7 @@ void QgsMapThemes::renameCurrentPreset() void QgsMapThemes::removeCurrentPreset() { - for ( QAction *actionPreset : qgis::as_const( mMenuPresetActions ) ) + for ( QAction *actionPreset : std::as_const( mMenuPresetActions ) ) { if ( actionPreset->isChecked() ) { diff --git a/src/app/qgsmaptooladdcircle.cpp b/src/app/qgsmaptooladdcircle.cpp index 4d38d2a648e0..db43fcb84fda 100644 --- a/src/app/qgsmaptooladdcircle.cpp +++ b/src/app/qgsmaptooladdcircle.cpp @@ -97,7 +97,7 @@ void QgsMapToolAddCircle::deactivate() // keep z value from the first snapped point std::unique_ptr lineString( mCircle.toCircularString() ); - for ( const QgsPoint &point : qgis::as_const( mPoints ) ) + for ( const QgsPoint &point : std::as_const( mPoints ) ) { if ( QgsWkbTypes::hasZ( point.wkbType() ) && point.z() != defaultZValue() ) diff --git a/src/app/qgsmaptooladdellipse.cpp b/src/app/qgsmaptooladdellipse.cpp index f5cd837c8d7d..657a8cd84632 100644 --- a/src/app/qgsmaptooladdellipse.cpp +++ b/src/app/qgsmaptooladdellipse.cpp @@ -97,7 +97,7 @@ void QgsMapToolAddEllipse::deactivate() // keep z value from the first snapped point std::unique_ptr ls( mEllipse.toLineString( segments() ) ); - for ( const QgsPoint &point : qgis::as_const( mPoints ) ) + for ( const QgsPoint &point : std::as_const( mPoints ) ) { if ( QgsWkbTypes::hasZ( point.wkbType() ) && point.z() != defaultZValue() ) diff --git a/src/app/qgsmaptooladdrectangle.cpp b/src/app/qgsmaptooladdrectangle.cpp index d2754775ff1b..6f64a0fc5e7f 100644 --- a/src/app/qgsmaptooladdrectangle.cpp +++ b/src/app/qgsmaptooladdrectangle.cpp @@ -98,7 +98,7 @@ void QgsMapToolAddRectangle::deactivate( ) // keep z value from the first snapped point std::unique_ptr lineString( mRectangle.toLineString() ); - for ( const QgsPoint &point : qgis::as_const( mPoints ) ) + for ( const QgsPoint &point : std::as_const( mPoints ) ) { if ( QgsWkbTypes::hasZ( point.wkbType() ) && point.z() != defaultZValue() ) diff --git a/src/app/qgsmaptooladdregularpolygon.cpp b/src/app/qgsmaptooladdregularpolygon.cpp index 6e17cdfeb5b5..78c09e470d8c 100644 --- a/src/app/qgsmaptooladdregularpolygon.cpp +++ b/src/app/qgsmaptooladdregularpolygon.cpp @@ -115,7 +115,7 @@ void QgsMapToolAddRegularPolygon::deactivate() // keep z value from the first snapped point std::unique_ptr ls( mRegularPolygon.toLineString() ); - for ( const QgsPoint &point : qgis::as_const( mPoints ) ) + for ( const QgsPoint &point : std::as_const( mPoints ) ) { if ( QgsWkbTypes::hasZ( point.wkbType() ) && point.z() != defaultZValue() ) diff --git a/src/app/qgsmaptoolfeatureaction.cpp b/src/app/qgsmaptoolfeatureaction.cpp index d99333897b5c..a99ec5d880ca 100644 --- a/src/app/qgsmaptoolfeatureaction.cpp +++ b/src/app/qgsmaptoolfeatureaction.cpp @@ -143,7 +143,7 @@ bool QgsMapToolFeatureAction::doAction( QgsVectorLayer *layer, int x, int y ) exp.prepare( &context ); QMenu *featureMenu = new QMenu(); - for ( const QgsFeature &feature : qgis::as_const( features ) ) + for ( const QgsFeature &feature : std::as_const( features ) ) { context.setFeature( feature ); QString featureTitle = exp.evaluate( &context ).toString(); @@ -156,7 +156,7 @@ bool QgsMapToolFeatureAction::doAction( QgsVectorLayer *layer, int x, int y ) QAction *allFeatureAction = featureMenu->addAction( tr( "All Features" ) ); connect( allFeatureAction, &QAction::triggered, this, [ = ] { - for ( const QgsFeature &feature : qgis::as_const( features ) ) + for ( const QgsFeature &feature : std::as_const( features ) ) { doActionForFeature( layer, feature, point ); } diff --git a/src/app/qgsmaptoolmovefeature.cpp b/src/app/qgsmaptoolmovefeature.cpp index f670fdab61eb..7b52dac6e5ab 100644 --- a/src/app/qgsmaptoolmovefeature.cpp +++ b/src/app/qgsmaptoolmovefeature.cpp @@ -190,7 +190,7 @@ void QgsMapToolMoveFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) switch ( mMode ) { case Move: - for ( QgsFeatureId id : qgis::as_const( mMovedFeatures ) ) + for ( QgsFeatureId id : std::as_const( mMovedFeatures ) ) { vlayer->translateFeature( id, dx, dy ); diff --git a/src/app/qgsmaptoolscalefeature.cpp b/src/app/qgsmaptoolscalefeature.cpp index a4d356c42ef5..d3ec6a92f444 100644 --- a/src/app/qgsmaptoolscalefeature.cpp +++ b/src/app/qgsmaptoolscalefeature.cpp @@ -347,7 +347,7 @@ void QgsMapToolScaleFeature::applyScaling( double scale ) t.scale( mScaling, mScaling ); t.translate( -mFeatureCenterMapCoords.x(), -mFeatureCenterMapCoords.y() ); - for ( QgsFeatureId id : qgis::as_const( mScaledFeatures ) ) + for ( QgsFeatureId id : std::as_const( mScaledFeatures ) ) { QgsFeature feat; vlayer->getFeatures( QgsFeatureRequest().setFilterFid( id ) ).nextFeature( feat ); diff --git a/src/app/qgsmergeattributesdialog.cpp b/src/app/qgsmergeattributesdialog.cpp index 8a547866fa7b..1265e3e959f4 100644 --- a/src/app/qgsmergeattributesdialog.cpp +++ b/src/app/qgsmergeattributesdialog.cpp @@ -283,7 +283,7 @@ QComboBox *QgsMergeAttributesDialog::createMergeComboBox( QVariant::Type columnT case QVariant::Int: case QVariant::LongLong: { - for ( QgsStatisticalSummary::Statistic stat : qgis::as_const( DISPLAY_STATS ) ) + for ( QgsStatisticalSummary::Statistic stat : std::as_const( DISPLAY_STATS ) ) { newComboBox->addItem( QgsStatisticalSummary::displayName( stat ), stat ); } diff --git a/src/app/qgsprojectproperties.cpp b/src/app/qgsprojectproperties.cpp index 209d7fdeb88d..ec04358ad434 100644 --- a/src/app/qgsprojectproperties.cpp +++ b/src/app/qgsprojectproperties.cpp @@ -1593,7 +1593,7 @@ void QgsProjectProperties::apply() QgsProject::instance()->displaySettings()->setBearingFormat( mBearingFormat->clone() ); - for ( QgsOptionsPageWidget *widget : qgis::as_const( mAdditionalProjectPropertiesWidgets ) ) + for ( QgsOptionsPageWidget *widget : std::as_const( mAdditionalProjectPropertiesWidgets ) ) { widget->apply(); } @@ -2002,7 +2002,7 @@ void QgsProjectProperties::pbnLaunchOWSChecker_clicked() QString errors; if ( !results ) { - for ( const QgsProjectServerValidator::ValidationResult &result : qgis::as_const( validationResults ) ) + for ( const QgsProjectServerValidator::ValidationResult &result : std::as_const( validationResults ) ) { errors += QLatin1String( "" ) % QgsProjectServerValidator::displayValidationError( result.error ) % QLatin1String( " : " ); errors += result.identifier.toString(); @@ -2413,7 +2413,7 @@ void QgsProjectProperties::populateEllipsoidList() } // Add all items to selector - for ( const EllipsoidDefs &i : qgis::as_const( mEllipsoidList ) ) + for ( const EllipsoidDefs &i : std::as_const( mEllipsoidList ) ) { cmbEllipsoid->addItem( i.description ); } @@ -2595,7 +2595,7 @@ void QgsProjectProperties::showHelp() } // give first priority to created pages which have specified a help key - for ( const QgsOptionsPageWidget *widget : qgis::as_const( mAdditionalProjectPropertiesWidgets ) ) + for ( const QgsOptionsPageWidget *widget : std::as_const( mAdditionalProjectPropertiesWidgets ) ) { if ( widget == activeTab ) { diff --git a/src/app/qgsrastercalcdialog.cpp b/src/app/qgsrastercalcdialog.cpp index b3bd21c7263e..6a3df33aa572 100644 --- a/src/app/qgsrastercalcdialog.cpp +++ b/src/app/qgsrastercalcdialog.cpp @@ -182,7 +182,7 @@ void QgsRasterCalcDialog::insertAvailableRasterBands() { mAvailableRasterBands = QgsRasterCalculatorEntry::rasterEntries().toList(); mRasterBandsListWidget->clear(); - for ( const auto &entry : qgis::as_const( mAvailableRasterBands ) ) + for ( const auto &entry : std::as_const( mAvailableRasterBands ) ) { QgsRasterLayer *rlayer = entry.raster; if ( rlayer && rlayer->dataProvider() && rlayer->providerType() == QLatin1String( "gdal" ) ) diff --git a/src/app/qgssnappingwidget.cpp b/src/app/qgssnappingwidget.cpp index 314e1b1320df..53628e4c7fde 100644 --- a/src/app/qgssnappingwidget.cpp +++ b/src/app/qgssnappingwidget.cpp @@ -460,7 +460,7 @@ void QgsSnappingWidget::projectSnapSettingsChanged() } // update snapping flag actions - for ( QAction *action : qgis::as_const( mSnappingFlagActions ) ) + for ( QAction *action : std::as_const( mSnappingFlagActions ) ) { const QgsSnappingConfig::SnappingTypeFlag actionFlag = static_cast( action->data().toInt() ); action->setChecked( config.typeFlag() & actionFlag ); @@ -712,7 +712,7 @@ void QgsSnappingWidget::typeButtonTriggered( QAction *action ) else { // user unchecked the action -- find out which ones we should set as new default action - for ( QAction *flagAction : qgis::as_const( mSnappingFlagActions ) ) + for ( QAction *flagAction : std::as_const( mSnappingFlagActions ) ) { if ( type & static_cast( flagAction->data().toInt() ) ) { diff --git a/src/app/vertextool/qgsvertextool.cpp b/src/app/vertextool/qgsvertextool.cpp index a538c2943987..e50b2e5b75ab 100644 --- a/src/app/vertextool/qgsvertextool.cpp +++ b/src/app/vertextool/qgsvertextool.cpp @@ -423,11 +423,11 @@ void QgsVertexTool::clearDragBands() mDragPointMarkers.clear(); mDragPointMarkersOffset.clear(); - for ( const StraightBand &b : qgis::as_const( mDragStraightBands ) ) + for ( const StraightBand &b : std::as_const( mDragStraightBands ) ) delete b.band; mDragStraightBands.clear(); - for ( const CircularBand &b : qgis::as_const( mDragCircularBands ) ) + for ( const CircularBand &b : std::as_const( mDragCircularBands ) ) delete b.band; mDragCircularBands.clear(); } @@ -447,7 +447,7 @@ void QgsVertexTool::cadCanvasPressEvent( QgsMapMouseEvent *e ) QgsPointLocator::Match m = snapToEditableLayer( e ); if ( m.hasVertex() ) { - for ( const Vertex &selectedVertex : qgis::as_const( mSelectedVertices ) ) + for ( const Vertex &selectedVertex : std::as_const( mSelectedVertices ) ) { if ( selectedVertex.layer == m.layer() && selectedVertex.fid == m.featureId() && selectedVertex.vertexId == m.vertexIndex() ) { @@ -1095,7 +1095,7 @@ void QgsVertexTool::tryToSelectFeature( QgsMapMouseEvent *e ) // keep only corrsesponding vertices // todo: it might be nice to keep other vertices in memory, so we could select them when switching lokcked feature QList vertices; - for ( const Vertex &v : qgis::as_const( mSelectedVertices ) ) + for ( const Vertex &v : std::as_const( mSelectedVertices ) ) if ( v.layer == alternative.first && v.fid == alternative.second ) vertices << v; setHighlightedVertices( vertices, ModeReset ); @@ -1231,7 +1231,7 @@ void QgsVertexTool::mouseMoveNotDragging( QgsMapMouseEvent *e ) QgsPointSequence points; QgsGeometryUtils::segmentizeArc( QgsPoint( pX ), QgsPoint( p0 ), QgsPoint( p1 ), points ); mEdgeBand->reset(); - for ( const QgsPoint &pt : qgis::as_const( points ) ) + for ( const QgsPoint &pt : std::as_const( points ) ) mEdgeBand->addPoint( pt ); } else if ( isCircularVertex( geom, m.vertexIndex() + 1 ) ) @@ -1242,7 +1242,7 @@ void QgsVertexTool::mouseMoveNotDragging( QgsMapMouseEvent *e ) QgsPointSequence points; QgsGeometryUtils::segmentizeArc( QgsPoint( p0 ), QgsPoint( p1 ), QgsPoint( pX ), points ); mEdgeBand->reset(); - for ( const QgsPoint &pt : qgis::as_const( points ) ) + for ( const QgsPoint &pt : std::as_const( points ) ) mEdgeBand->addPoint( pt ); } else @@ -1604,7 +1604,7 @@ void QgsVertexTool::deleteVertexEditorSelection() QgsVectorLayer *layer = mLockedFeature->layer(); QgsFeatureId fid = mLockedFeature->featureId(); QgsGeometry geometry = cachedGeometry( layer, fid ); - for ( QgsVertexEntry *vertex : qgis::as_const( selFeatureVertices ) ) + for ( QgsVertexEntry *vertex : std::as_const( selFeatureVertices ) ) { if ( vertex->isSelected() ) { @@ -1686,7 +1686,7 @@ QSet QgsVertexTool::findCoincidentVertices( const QSet &vertices QSet topoVertices; const auto editableLayers = editableVectorLayers(); - for ( const Vertex &v : qgis::as_const( vertices ) ) + for ( const Vertex &v : std::as_const( vertices ) ) { QgsPointXY origPointV = cachedGeometryForVertex( v ).vertexAt( v.vertexId ); QgsPointXY mapPointV = toMapCoordinates( v.layer, origPointV ); @@ -1706,7 +1706,7 @@ QSet QgsVertexTool::findCoincidentVertices( const QSet &vertices void QgsVertexTool::buildExtraVertices( const QSet &vertices, const QgsPointXY &anchorPoint, QgsVectorLayer *anchorLayer ) { - for ( const Vertex &v : qgis::as_const( vertices ) ) + for ( const Vertex &v : std::as_const( vertices ) ) { if ( mDraggingVertex && v == *mDraggingVertex ) continue; @@ -1743,7 +1743,7 @@ void QgsVertexTool::startDraggingMoveVertex( const QgsPointLocator::Match &m ) QSet movingVertices; movingVertices << *mDraggingVertex; - for ( const Vertex &v : qgis::as_const( mSelectedVertices ) ) + for ( const Vertex &v : std::as_const( mSelectedVertices ) ) movingVertices << v; if ( QgsProject::instance()->topologicalEditing() ) @@ -1770,7 +1770,7 @@ void QgsVertexTool::buildDragBandsForVertices( const QSet &movingVertice // i.e. every circular band is defined by its middle circular vertex QSet verticesInCircularBands; - for ( const Vertex &v : qgis::as_const( movingVertices ) ) + for ( const Vertex &v : std::as_const( movingVertices ) ) { int v0idx, v1idx; QgsGeometry geom = cachedGeometry( v.layer, v.fid ); @@ -2309,7 +2309,7 @@ void QgsVertexTool::deleteVertex() { // if topo editing is enabled, delete all the vertices that are on the same location QSet topoVerticesToDelete; - for ( const Vertex &vertexToDelete : qgis::as_const( toDelete ) ) + for ( const Vertex &vertexToDelete : std::as_const( toDelete ) ) { QgsPointXY layerPt = cachedGeometryForVertex( vertexToDelete ).vertexAt( vertexToDelete.vertexId ); QgsPointXY mapPt = toMapCoordinates( vertexToDelete.layer, layerPt ); @@ -2329,7 +2329,7 @@ void QgsVertexTool::deleteVertex() // switch from a plain list to dictionary { layer: { fid: [vertexNr1, vertexNr2, ...] } } QHash > > toDeleteGrouped; - for ( const Vertex &vertex : qgis::as_const( toDelete ) ) + for ( const Vertex &vertex : std::as_const( toDelete ) ) { toDeleteGrouped[vertex.layer][vertex.fid].append( vertex.vertexId ); } @@ -2513,7 +2513,7 @@ void QgsVertexTool::setHighlightedVertices( const QList &listVertices, H if ( mode == ModeSubtract ) { // rebuild markers for remaining selection - for ( const Vertex &vertex : qgis::as_const( mSelectedVertices ) ) + for ( const Vertex &vertex : std::as_const( mSelectedVertices ) ) { createMarkerForVertex( vertex ); } @@ -2524,7 +2524,7 @@ void QgsVertexTool::setHighlightedVertices( const QList &listVertices, H disconnect( mLockedFeature.get(), &QgsLockedFeature::selectionChanged, this, &QgsVertexTool::lockedFeatureSelectionChanged ); mLockedFeature->deselectAllVertices(); - for ( const Vertex &vertex : qgis::as_const( mSelectedVertices ) ) + for ( const Vertex &vertex : std::as_const( mSelectedVertices ) ) { // we should never be able to select vertices that are not from the locked feature // cppcheck-suppress assertWithSideEffect @@ -2538,7 +2538,7 @@ void QgsVertexTool::setHighlightedVertices( const QList &listVertices, H void QgsVertexTool::setHighlightedVerticesVisible( bool visible ) { - for ( QgsVertexMarker *marker : qgis::as_const( mSelectedVerticesMarkers ) ) + for ( QgsVertexMarker *marker : std::as_const( mSelectedVerticesMarkers ) ) marker->setVisible( visible ); } @@ -2633,7 +2633,7 @@ void QgsVertexTool::CircularBand::updateRubberBand( const QgsPointXY &mapPoint ) QgsGeometryUtils::segmentizeArc( QgsPoint( v0 ), QgsPoint( v1 ), QgsPoint( v2 ), points ); // it would be useful to have QgsRubberBand::setPoints() call band->reset(); - for ( const QgsPoint &p : qgis::as_const( points ) ) + for ( const QgsPoint &p : std::as_const( points ) ) band->addPoint( p ); } diff --git a/src/core/annotations/qgsannotationlayerrenderer.cpp b/src/core/annotations/qgsannotationlayerrenderer.cpp index 450fc26d6847..3c502e2f12a9 100644 --- a/src/core/annotations/qgsannotationlayerrenderer.cpp +++ b/src/core/annotations/qgsannotationlayerrenderer.cpp @@ -50,7 +50,7 @@ bool QgsAnnotationLayerRenderer::render() QgsRenderContext &context = *renderContext(); bool canceled = false; - for ( QgsAnnotationItem *item : qgis::as_const( mItems ) ) + for ( QgsAnnotationItem *item : std::as_const( mItems ) ) { if ( mFeedback->isCanceled() ) { diff --git a/src/core/annotations/qgsannotationmanager.cpp b/src/core/annotations/qgsannotationmanager.cpp index 9a9210055e6a..465b0c42ee12 100644 --- a/src/core/annotations/qgsannotationmanager.cpp +++ b/src/core/annotations/qgsannotationmanager.cpp @@ -64,7 +64,7 @@ bool QgsAnnotationManager::removeAnnotation( QgsAnnotation *annotation ) void QgsAnnotationManager::clear() { - for ( auto *a : qgis::as_const( mAnnotations ) ) + for ( auto *a : std::as_const( mAnnotations ) ) { removeAnnotation( a ); } @@ -78,7 +78,7 @@ QList QgsAnnotationManager::annotations() const QList QgsAnnotationManager::cloneAnnotations() const { QList results; - for ( const auto *a : qgis::as_const( mAnnotations ) ) + for ( const auto *a : std::as_const( mAnnotations ) ) { results << a->clone(); } diff --git a/src/core/auth/qgsauthmanager.cpp b/src/core/auth/qgsauthmanager.cpp index b9b9fa1e377e..b7529bae0338 100644 --- a/src/core/auth/qgsauthmanager.cpp +++ b/src/core/auth/qgsauthmanager.cpp @@ -2579,7 +2579,7 @@ const QList QgsAuthManager::extraFileCAs() filecerts = QgsAuthCertUtils::certsFromFile( cafile ); } // only CAs or certs capable of signing other certs are allowed - for ( const auto &cert : qgis::as_const( filecerts ) ) + for ( const auto &cert : std::as_const( filecerts ) ) { if ( !allowinvalid.toBool() && ( cert.isBlacklisted() || cert.isNull() @@ -3554,7 +3554,7 @@ bool QgsAuthManager::reencryptAllAuthenticationSettings( const QString &prevpass QStringList encryptedsettings; encryptedsettings << ""; - for ( const auto & sett, qgis::as_const( encryptedsettings ) ) + for ( const auto & sett, std::as_const( encryptedsettings ) ) { if ( sett.isEmpty() || !existsAuthSetting( sett ) ) continue; diff --git a/src/core/classification/qgsclassificationmethodregistry.cpp b/src/core/classification/qgsclassificationmethodregistry.cpp index a381971e41e9..533193cc65da 100644 --- a/src/core/classification/qgsclassificationmethodregistry.cpp +++ b/src/core/classification/qgsclassificationmethodregistry.cpp @@ -59,7 +59,7 @@ QgsClassificationMethod *QgsClassificationMethodRegistry::method( const QString QMap QgsClassificationMethodRegistry::methodNames() const { QMap methods; - for ( const QgsClassificationMethod *method : qgis::as_const( mMethods ) ) + for ( const QgsClassificationMethod *method : std::as_const( mMethods ) ) methods.insert( method->name(), method->id() ); return methods; } diff --git a/src/core/diagram/qgshistogramdiagram.cpp b/src/core/diagram/qgshistogramdiagram.cpp index 566b99dfcbf6..fad003cd6b1d 100644 --- a/src/core/diagram/qgshistogramdiagram.cpp +++ b/src/core/diagram/qgshistogramdiagram.cpp @@ -50,7 +50,7 @@ QSizeF QgsHistogramDiagram::diagramSize( const QgsFeature &feature, const QgsRen if ( !feature.fields().isEmpty() ) expressionContext.setFields( feature.fields() ); - for ( const QString &cat : qgis::as_const( s.categoryAttributes ) ) + for ( const QString &cat : std::as_const( s.categoryAttributes ) ) { QgsExpression *expression = getExpression( cat, expressionContext ); maxValue = std::max( expression->evaluate( &expressionContext ).toDouble(), maxValue ); @@ -180,7 +180,7 @@ void QgsHistogramDiagram::renderDiagram( const QgsFeature &feature, QgsRenderCon expressionContext.setFields( feature.fields() ); values.reserve( s.categoryAttributes.size() ); - for ( const QString &cat : qgis::as_const( s.categoryAttributes ) ) + for ( const QString &cat : std::as_const( s.categoryAttributes ) ) { QgsExpression *expression = getExpression( cat, expressionContext ); double currentVal = expression->evaluate( &expressionContext ).toDouble(); diff --git a/src/core/diagram/qgsstackedbardiagram.cpp b/src/core/diagram/qgsstackedbardiagram.cpp index 620cd97fe26a..29faea84a227 100644 --- a/src/core/diagram/qgsstackedbardiagram.cpp +++ b/src/core/diagram/qgsstackedbardiagram.cpp @@ -173,7 +173,7 @@ void QgsStackedBarDiagram::renderDiagram( const QgsFeature &feature, QgsRenderCo double negativeTotal = 0; QList< QColor >::const_iterator colIt = s.categoryColors.constBegin(); - for ( const QString &cat : qgis::as_const( s.categoryAttributes ) ) + for ( const QString &cat : std::as_const( s.categoryAttributes ) ) { QgsExpression *expression = getExpression( cat, expressionContext ); double currentVal = expression->evaluate( &expressionContext ).toDouble(); diff --git a/src/core/dxf/qgsdxfexport.cpp b/src/core/dxf/qgsdxfexport.cpp index 05fd4fe51fc2..247ccc563a68 100644 --- a/src/core/dxf/qgsdxfexport.cpp +++ b/src/core/dxf/qgsdxfexport.cpp @@ -327,7 +327,7 @@ void QgsDxfExport::writeTables() writeDefaultLinetypes(); // Add custom linestyles - for ( const auto &symbolLayer : qgis::as_const( slList ) ) + for ( const auto &symbolLayer : std::as_const( slList ) ) { writeSymbolLayerLinetype( symbolLayer.first ); } @@ -353,7 +353,7 @@ void QgsDxfExport::writeTables() } int i = 0; - for ( const auto &symbolLayer : qgis::as_const( slList ) ) + for ( const auto &symbolLayer : std::as_const( slList ) ) { QgsMarkerSymbolLayer *ml = dynamic_cast< QgsMarkerSymbolLayer *>( symbolLayer.first ); if ( !ml ) @@ -501,7 +501,7 @@ void QgsDxfExport::writeTables() writeGroup( 6, QStringLiteral( "CONTINUOUS" ) ); writeHandle( 390, DXF_HANDPLOTSTYLE ); - for ( const QString &layerName : qgis::as_const( layerNames ) ) + for ( const QString &layerName : std::as_const( layerNames ) ) { writeGroup( 0, QStringLiteral( "LAYER" ) ); writeHandle(); @@ -577,7 +577,7 @@ void QgsDxfExport::writeBlocks() slList = symbolLayers( ct ); } - for ( const auto &symbolLayer : qgis::as_const( slList ) ) + for ( const auto &symbolLayer : std::as_const( slList ) ) { QgsMarkerSymbolLayer *ml = dynamic_cast< QgsMarkerSymbolLayer *>( symbolLayer.first ); if ( !ml ) @@ -635,7 +635,7 @@ void QgsDxfExport::writeEntities() mBlockHandle = QString::number( mBlockHandles[ QStringLiteral( "*Model_Space" )], 16 ); // iterate through the maplayers - for ( DxfLayerJob *job : qgis::as_const( mJobs ) ) + for ( DxfLayerJob *job : std::as_const( mJobs ) ) { QgsSymbolRenderContext sctx( mRenderContext, QgsUnitTypes::RenderMillimeters, 1.0, false, QgsSymbol::RenderHints(), nullptr ); @@ -843,7 +843,7 @@ void QgsDxfExport::writeEntitiesSymbolLevels( DxfLayerJob *job ) } // export symbol layers and symbology - for ( const QgsSymbolLevel &level : qgis::as_const( levels ) ) + for ( const QgsSymbolLevel &level : std::as_const( levels ) ) { for ( const QgsSymbolLevelItem &item : level ) { diff --git a/src/core/expression/qgsexpression.cpp b/src/core/expression/qgsexpression.cpp index abc42d1264a1..8e8f734f51c1 100644 --- a/src/core/expression/qgsexpression.cpp +++ b/src/core/expression/qgsexpression.cpp @@ -552,7 +552,7 @@ QString QgsExpression::helpText( QString name ) .arg( tr( "%1 %2" ).arg( f.mType, name ), f.mDescription ) ); - for ( const HelpVariant &v : qgis::as_const( f.mVariants ) ) + for ( const HelpVariant &v : std::as_const( f.mVariants ) ) { if ( f.mVariants.size() > 1 ) { @@ -586,7 +586,7 @@ QString QgsExpression::helpText( QString name ) helpContents += '('; QString delim; - for ( const HelpArg &a : qgis::as_const( v.mArguments ) ) + for ( const HelpArg &a : std::as_const( v.mArguments ) ) { if ( !a.mDescOnly ) { @@ -628,7 +628,7 @@ QString QgsExpression::helpText( QString name ) { helpContents += QStringLiteral( "

    %1

    \n
    \n" ).arg( tr( "Arguments" ) ); - for ( const HelpArg &a : qgis::as_const( v.mArguments ) ) + for ( const HelpArg &a : std::as_const( v.mArguments ) ) { if ( a.mSyntaxOnly ) continue; @@ -643,7 +643,7 @@ QString QgsExpression::helpText( QString name ) { helpContents += QStringLiteral( "

    %1

    \n
    \n
      \n" ).arg( tr( "Examples" ) ); - for ( const HelpExample &e : qgis::as_const( v.mExamples ) ) + for ( const HelpExample &e : std::as_const( v.mExamples ) ) { helpContents += "
    • " + e.mExpression + "" + e.mReturns + ""; @@ -675,7 +675,7 @@ QStringList QgsExpression::tags( const QString &name ) { const Help &f = ( *sFunctionHelpTexts() )[ name ]; - for ( const HelpVariant &v : qgis::as_const( f.mVariants ) ) + for ( const HelpVariant &v : std::as_const( f.mVariants ) ) { tags << v.mTags; } diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index cb196443db78..2df8fb5cbfb2 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -2766,7 +2766,7 @@ static QVariant fcnCollectGeometries( const QVariantList &values, const QgsExpre QVector< QgsGeometry > parts; parts.reserve( list.size() ); - for ( const QVariant &value : qgis::as_const( list ) ) + for ( const QVariant &value : std::as_const( list ) ) { if ( value.canConvert() ) { @@ -4338,7 +4338,7 @@ static QVariant fcnOrderParts( const QVariantList &values, const QgsExpressionCo while ( orderedGeom->partCount() ) orderedGeom->removeGeometry( 0 ); - for ( const QgsFeature &feature : qgis::as_const( partFeatures ) ) + for ( const QgsFeature &feature : std::as_const( partFeatures ) ) { orderedGeom->addGeometry( feature.geometry().constGet()->clone() ); } @@ -7295,7 +7295,7 @@ const QList &QgsExpression::Functions() QgsExpressionContextUtils::registerContextFunctions(); //QgsExpression has ownership of all built-in functions - for ( QgsExpressionFunction *func : qgis::as_const( functions ) ) + for ( QgsExpressionFunction *func : std::as_const( functions ) ) { *sOwnedFunctions() << func; *sBuiltinFunctions() << func->name(); diff --git a/src/core/expression/qgsexpressionnodeimpl.cpp b/src/core/expression/qgsexpressionnodeimpl.cpp index dc9bb78d57eb..d0d11e8d2ef2 100644 --- a/src/core/expression/qgsexpressionnodeimpl.cpp +++ b/src/core/expression/qgsexpressionnodeimpl.cpp @@ -1541,7 +1541,7 @@ QgsExpressionNode::NodeType QgsExpressionNodeCondition::nodeType() const QVariant QgsExpressionNodeCondition::evalNode( QgsExpression *parent, const QgsExpressionContext *context ) { - for ( WhenThen *cond : qgis::as_const( mConditions ) ) + for ( WhenThen *cond : std::as_const( mConditions ) ) { QVariant vWhen = cond->mWhenExp->eval( parent, context ); QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( vWhen, parent ); @@ -1568,7 +1568,7 @@ QVariant QgsExpressionNodeCondition::evalNode( QgsExpression *parent, const QgsE bool QgsExpressionNodeCondition::prepareNode( QgsExpression *parent, const QgsExpressionContext *context ) { bool res; - for ( WhenThen *cond : qgis::as_const( mConditions ) ) + for ( WhenThen *cond : std::as_const( mConditions ) ) { res = cond->mWhenExp->prepare( parent, context ) & cond->mThenExp->prepare( parent, context ); diff --git a/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp b/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp index 8a024f2f66c7..088edece47fd 100644 --- a/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp +++ b/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp @@ -79,7 +79,7 @@ QString QgsValueRelationFieldFormatter::representValue( QgsVectorLayer *layer, i QStringList valueList; - for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : qgis::as_const( vrCache ) ) + for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : std::as_const( vrCache ) ) { if ( keyList.contains( item.key.toString() ) ) { @@ -96,7 +96,7 @@ QString QgsValueRelationFieldFormatter::representValue( QgsVectorLayer *layer, i return QgsApplication::nullRepresentation(); } - for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : qgis::as_const( vrCache ) ) + for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : std::as_const( vrCache ) ) { if ( item.key == value ) { @@ -277,7 +277,7 @@ QStringList QgsValueRelationFieldFormatter::valueToStringList( const QVariant &v } checkList.reserve( valuesList.size() ); - for ( const QVariant &listItem : qgis::as_const( valuesList ) ) + for ( const QVariant &listItem : std::as_const( valuesList ) ) { QString v( listItem.toString( ) ); if ( ! v.isEmpty() ) diff --git a/src/core/geocms/geonode/qgsgeonoderequest.cpp b/src/core/geocms/geonode/qgsgeonoderequest.cpp index da5bb59bee6d..ee4dde93eeba 100644 --- a/src/core/geocms/geonode/qgsgeonoderequest.cpp +++ b/src/core/geocms/geonode/qgsgeonoderequest.cpp @@ -272,7 +272,7 @@ QList QgsGeoNodeRequest::parseLayers( con QString wmsURLFormat, wfsURLFormat, xyzURLFormat; - for ( const QVariant &layer : qgis::as_const( layerList ) ) + for ( const QVariant &layer : std::as_const( layerList ) ) { QgsGeoNodeRequest::ServiceLayerDetail layerStruct; const QVariantMap layerMap = layer.toMap(); diff --git a/src/core/geometry/qgscompoundcurve.cpp b/src/core/geometry/qgscompoundcurve.cpp index 5ce3849677f6..c3971f92266f 100644 --- a/src/core/geometry/qgscompoundcurve.cpp +++ b/src/core/geometry/qgscompoundcurve.cpp @@ -213,7 +213,7 @@ bool QgsCompoundCurve::fromWkt( const QString &wkt ) //if so, update the type dimensionality of the compound curve to match bool hasZ = false; bool hasM = false; - for ( const QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( const QgsCurve *curve : std::as_const( mCurves ) ) { hasZ = hasZ || curve->is3D(); hasM = hasM || curve->isMeasure(); @@ -602,7 +602,7 @@ void QgsCompoundCurve::draw( QPainter &p ) const void QgsCompoundCurve::transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d, bool transformZ ) { - for ( QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( QgsCurve *curve : std::as_const( mCurves ) ) { curve->transform( ct, d, transformZ ); } @@ -611,7 +611,7 @@ void QgsCompoundCurve::transform( const QgsCoordinateTransform &ct, QgsCoordinat void QgsCompoundCurve::transform( const QTransform &t, double zTranslate, double zScale, double mTranslate, double mScale ) { - for ( QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( QgsCurve *curve : std::as_const( mCurves ) ) { curve->transform( t, zTranslate, zScale, mTranslate, mScale ); } @@ -862,7 +862,7 @@ double QgsCompoundCurve::yAt( int index ) const bool QgsCompoundCurve::transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback ) { bool res = true; - for ( QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( QgsCurve *curve : std::as_const( mCurves ) ) { if ( !curve->transform( transformer ) ) { @@ -882,7 +882,7 @@ bool QgsCompoundCurve::transform( QgsAbstractGeometryTransformer *transformer, Q void QgsCompoundCurve::filterVertices( const std::function &filter ) { - for ( QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( QgsCurve *curve : std::as_const( mCurves ) ) { curve->filterVertices( filter ); } @@ -891,7 +891,7 @@ void QgsCompoundCurve::filterVertices( const std::function &transform ) { - for ( QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( QgsCurve *curve : std::as_const( mCurves ) ) { curve->transformVertices( transform ); } @@ -1033,7 +1033,7 @@ bool QgsCompoundCurve::addZValue( double zValue ) mWkbType = QgsWkbTypes::addZ( mWkbType ); - for ( QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( QgsCurve *curve : std::as_const( mCurves ) ) { curve->addZValue( zValue ); } @@ -1048,7 +1048,7 @@ bool QgsCompoundCurve::addMValue( double mValue ) mWkbType = QgsWkbTypes::addM( mWkbType ); - for ( QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( QgsCurve *curve : std::as_const( mCurves ) ) { curve->addMValue( mValue ); } @@ -1062,7 +1062,7 @@ bool QgsCompoundCurve::dropZValue() return false; mWkbType = QgsWkbTypes::dropZ( mWkbType ); - for ( QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( QgsCurve *curve : std::as_const( mCurves ) ) { curve->dropZValue(); } @@ -1076,7 +1076,7 @@ bool QgsCompoundCurve::dropMValue() return false; mWkbType = QgsWkbTypes::dropM( mWkbType ); - for ( QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( QgsCurve *curve : std::as_const( mCurves ) ) { curve->dropMValue(); } @@ -1086,7 +1086,7 @@ bool QgsCompoundCurve::dropMValue() void QgsCompoundCurve::swapXy() { - for ( QgsCurve *curve : qgis::as_const( mCurves ) ) + for ( QgsCurve *curve : std::as_const( mCurves ) ) { curve->swapXy(); } diff --git a/src/core/geometry/qgscurvepolygon.cpp b/src/core/geometry/qgscurvepolygon.cpp index 060884fb20b5..748120cd5e22 100644 --- a/src/core/geometry/qgscurvepolygon.cpp +++ b/src/core/geometry/qgscurvepolygon.cpp @@ -265,7 +265,7 @@ bool QgsCurvePolygon::fromWkt( const QString &wkt ) hasZ = hasZ || mExteriorRing->is3D(); hasM = hasM || mExteriorRing->isMeasure(); } - for ( const QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( const QgsCurve *curve : std::as_const( mInteriorRings ) ) { hasZ = hasZ || curve->is3D(); hasM = hasM || curve->isMeasure(); @@ -605,7 +605,7 @@ bool QgsCurvePolygon::removeDuplicateNodes( double epsilon, bool useZValues ) { result = cleanRing( mExteriorRing.get() ); } - for ( QgsCurve *ring : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *ring : std::as_const( mInteriorRings ) ) { if ( cleanRing( ring ) ) result = true; } @@ -684,7 +684,7 @@ void QgsCurvePolygon::setExteriorRing( QgsCurve *ring ) } //match dimensionality for rings - for ( QgsCurve *ring : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *ring : std::as_const( mInteriorRings ) ) { if ( is3D() ) ring->addZValue(); @@ -765,7 +765,7 @@ void QgsCurvePolygon::removeInvalidRings() { QVector validRings; validRings.reserve( mInteriorRings.size() ); - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { if ( !curve->isRing() ) { @@ -790,7 +790,7 @@ void QgsCurvePolygon::forceRHR() } QVector validRings; - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { if ( curve && curve->orientation() != QgsCurve::CounterClockwise ) { @@ -856,7 +856,7 @@ void QgsCurvePolygon::transform( const QgsCoordinateTransform &ct, QgsCoordinate mExteriorRing->transform( ct, d, transformZ ); } - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { curve->transform( ct, d, transformZ ); } @@ -870,7 +870,7 @@ void QgsCurvePolygon::transform( const QTransform &t, double zTranslate, double mExteriorRing->transform( t, zTranslate, zScale, mTranslate, mScale ); } - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { curve->transform( t, zTranslate, zScale, mTranslate, mScale ); } @@ -1225,7 +1225,7 @@ bool QgsCurvePolygon::addZValue( double zValue ) if ( mExteriorRing ) mExteriorRing->addZValue( zValue ); - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { curve->addZValue( zValue ); } @@ -1242,7 +1242,7 @@ bool QgsCurvePolygon::addMValue( double mValue ) if ( mExteriorRing ) mExteriorRing->addMValue( mValue ); - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { curve->addMValue( mValue ); } @@ -1258,7 +1258,7 @@ bool QgsCurvePolygon::dropZValue() mWkbType = QgsWkbTypes::dropZ( mWkbType ); if ( mExteriorRing ) mExteriorRing->dropZValue(); - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { curve->dropZValue(); } @@ -1274,7 +1274,7 @@ bool QgsCurvePolygon::dropMValue() mWkbType = QgsWkbTypes::dropM( mWkbType ); if ( mExteriorRing ) mExteriorRing->dropMValue(); - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { curve->dropMValue(); } @@ -1286,7 +1286,7 @@ void QgsCurvePolygon::swapXy() { if ( mExteriorRing ) mExteriorRing->swapXy(); - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { curve->swapXy(); } @@ -1313,7 +1313,7 @@ bool QgsCurvePolygon::transform( QgsAbstractGeometryTransformer *transformer, Qg return false; } - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { res = curve->transform( transformer ); @@ -1332,7 +1332,7 @@ void QgsCurvePolygon::filterVertices( const std::functionfilterVertices( filter ); - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { curve->filterVertices( filter ); } @@ -1344,7 +1344,7 @@ void QgsCurvePolygon::transformVertices( const std::functiontransformVertices( transform ); - for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *curve : std::as_const( mInteriorRings ) ) { curve->transformVertices( transform ); } diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 2a8311be9867..3141e979cd05 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -784,7 +784,7 @@ QgsGeometry QgsGeometry::removeInteriorRings( double minimumRingArea ) const return QgsGeometry(); QgsGeometry first = results.takeAt( 0 ); - for ( const QgsGeometry &result : qgis::as_const( results ) ) + for ( const QgsGeometry &result : std::as_const( results ) ) { first.addPart( result ); } @@ -1961,7 +1961,7 @@ QgsGeometry QgsGeometry::offsetCurve( double distance, int segments, JoinStyle j return QgsGeometry(); QgsGeometry first = results.takeAt( 0 ); - for ( const QgsGeometry &result : qgis::as_const( results ) ) + for ( const QgsGeometry &result : std::as_const( results ) ) { first.addPart( result ); } @@ -2019,7 +2019,7 @@ QgsGeometry QgsGeometry::singleSidedBuffer( double distance, int segments, Buffe return QgsGeometry(); QgsGeometry first = results.takeAt( 0 ); - for ( const QgsGeometry &result : qgis::as_const( results ) ) + for ( const QgsGeometry &result : std::as_const( results ) ) { first.addPart( result ); } @@ -2077,7 +2077,7 @@ QgsGeometry QgsGeometry::extendLine( double startDistance, double endDistance ) return QgsGeometry(); QgsGeometry first = results.takeAt( 0 ); - for ( const QgsGeometry &result : qgis::as_const( results ) ) + for ( const QgsGeometry &result : std::as_const( results ) ) { first.addPart( result ); } diff --git a/src/core/geometry/qgsgeometrycollection.cpp b/src/core/geometry/qgsgeometrycollection.cpp index 8d903d5d3f26..07d1145cd206 100644 --- a/src/core/geometry/qgsgeometrycollection.cpp +++ b/src/core/geometry/qgsgeometrycollection.cpp @@ -150,7 +150,7 @@ QgsGeometryCollection *QgsGeometryCollection::snappedToGrid( double hSpacing, do bool QgsGeometryCollection::removeDuplicateNodes( double epsilon, bool useZValues ) { bool result = false; - for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { if ( geom->removeDuplicateNodes( epsilon, useZValues ) ) result = true; } @@ -313,7 +313,7 @@ QString QgsGeometryCollection::geometryType() const void QgsGeometryCollection::transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d, bool transformZ ) { - for ( QgsAbstractGeometry *g : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *g : std::as_const( mGeometries ) ) { g->transform( ct, d, transformZ ); } @@ -322,7 +322,7 @@ void QgsGeometryCollection::transform( const QgsCoordinateTransform &ct, QgsCoor void QgsGeometryCollection::transform( const QTransform &t, double zTranslate, double zScale, double mTranslate, double mScale ) { - for ( QgsAbstractGeometry *g : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *g : std::as_const( mGeometries ) ) { g->transform( t, zTranslate, zScale, mTranslate, mScale ); } @@ -494,7 +494,7 @@ QDomElement QgsGeometryCollection::asGml3( QDomDocument &doc, int precision, con json QgsGeometryCollection::asJsonObject( int precision ) const { json coordinates( json::array( ) ); - for ( const QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { coordinates.push_back( geom->asJsonObject( precision ) ); } @@ -781,7 +781,7 @@ bool QgsGeometryCollection::fromCollectionWkt( const QString &wkt, const QVector //if so, update the type dimensionality of the collection to match bool hasZ = false; bool hasM = false; - for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { hasZ = hasZ || geom->is3D(); hasM = hasM || geom->isMeasure(); @@ -915,7 +915,7 @@ bool QgsGeometryCollection::addZValue( double zValue ) mWkbType = QgsWkbTypes::addZ( mWkbType ); - for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { geom->addZValue( zValue ); } @@ -930,7 +930,7 @@ bool QgsGeometryCollection::addMValue( double mValue ) mWkbType = QgsWkbTypes::addM( mWkbType ); - for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { geom->addMValue( mValue ); } @@ -945,7 +945,7 @@ bool QgsGeometryCollection::dropZValue() return false; mWkbType = QgsWkbTypes::dropZ( mWkbType ); - for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { geom->dropZValue(); } @@ -959,7 +959,7 @@ bool QgsGeometryCollection::dropMValue() return false; mWkbType = QgsWkbTypes::dropM( mWkbType ); - for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { geom->dropMValue(); } @@ -969,7 +969,7 @@ bool QgsGeometryCollection::dropMValue() void QgsGeometryCollection::filterVertices( const std::function &filter ) { - for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { if ( geom ) geom->filterVertices( filter ); @@ -979,7 +979,7 @@ void QgsGeometryCollection::filterVertices( const std::function &transform ) { - for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { if ( geom ) geom->transformVertices( transform ); @@ -989,7 +989,7 @@ void QgsGeometryCollection::transformVertices( const std::functionswapXy(); @@ -1014,7 +1014,7 @@ bool QgsGeometryCollection::transform( QgsAbstractGeometryTransformer *transform return false; bool res = true; - for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { if ( geom ) res = geom->transform( transformer, feedback ); diff --git a/src/core/geometry/qgsgeos.cpp b/src/core/geometry/qgsgeos.cpp index cbadd3199f98..b84e703874df 100644 --- a/src/core/geometry/qgsgeos.cpp +++ b/src/core/geometry/qgsgeos.cpp @@ -2602,7 +2602,7 @@ geos::unique_ptr QgsGeos::reshapeLine( const GEOSGeometry *line, const GEOSGeome bool alreadyAdded = false; double distance = 0; double bufferDistance = std::pow( 10.0L, geomDigits( currentGeom ) - 11 ); - for ( const GEOSGeometry *other : qgis::as_const( resultLineParts ) ) + for ( const GEOSGeometry *other : std::as_const( resultLineParts ) ) { GEOSHausdorffDistance_r( geosinit()->ctxt, currentGeom, other, &distance ); if ( distance < bufferDistance ) diff --git a/src/core/geometry/qgsinternalgeometryengine.cpp b/src/core/geometry/qgsinternalgeometryengine.cpp index d0eaafc87fca..f0d9a6eb22a1 100644 --- a/src/core/geometry/qgsinternalgeometryengine.cpp +++ b/src/core/geometry/qgsinternalgeometryengine.cpp @@ -79,7 +79,7 @@ QgsGeometry QgsInternalGeometryEngine::extrude( double x, double y ) const if ( !linesToProcess.empty() ) { std::unique_ptr< QgsLineString > secondline; - for ( QgsLineString *line : qgis::as_const( linesToProcess ) ) + for ( QgsLineString *line : std::as_const( linesToProcess ) ) { QTransform transform = QTransform::fromTranslate( x, y ); @@ -523,7 +523,7 @@ QgsGeometry QgsInternalGeometryEngine::orthogonalize( double tolerance, int maxI } QgsGeometry first = QgsGeometry( geometryList.takeAt( 0 ) ); - for ( QgsAbstractGeometry *g : qgis::as_const( geometryList ) ) + for ( QgsAbstractGeometry *g : std::as_const( geometryList ) ) { first.addPart( g ); } @@ -682,7 +682,7 @@ QgsGeometry QgsInternalGeometryEngine::densifyByCount( int extraNodesPerSegment } QgsGeometry first = QgsGeometry( geometryList.takeAt( 0 ) ); - for ( QgsAbstractGeometry *g : qgis::as_const( geometryList ) ) + for ( QgsAbstractGeometry *g : std::as_const( geometryList ) ) { first.addPart( g ); } @@ -718,7 +718,7 @@ QgsGeometry QgsInternalGeometryEngine::densifyByDistance( double distance ) cons } QgsGeometry first = QgsGeometry( geometryList.takeAt( 0 ) ); - for ( QgsAbstractGeometry *g : qgis::as_const( geometryList ) ) + for ( QgsAbstractGeometry *g : std::as_const( geometryList ) ) { first.addPart( g ); } @@ -1438,7 +1438,7 @@ QgsGeometry QgsInternalGeometryEngine::convertToCurves( double distanceTolerance } QgsGeometry first = QgsGeometry( geometryList.takeAt( 0 ) ); - for ( QgsAbstractGeometry *g : qgis::as_const( geometryList ) ) + for ( QgsAbstractGeometry *g : std::as_const( geometryList ) ) { first.addPart( g ); } diff --git a/src/core/geometry/qgsmulticurve.cpp b/src/core/geometry/qgsmulticurve.cpp index 1d269f39d010..f75208b9a85f 100644 --- a/src/core/geometry/qgsmulticurve.cpp +++ b/src/core/geometry/qgsmulticurve.cpp @@ -124,7 +124,7 @@ QDomElement QgsMultiCurve::asGml3( QDomDocument &doc, int precision, const QStri json QgsMultiCurve::asJsonObject( int precision ) const { json coordinates( json::array( ) ); - for ( const QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { if ( qgsgeometry_cast( geom ) ) { diff --git a/src/core/geometry/qgsmultipoint.cpp b/src/core/geometry/qgsmultipoint.cpp index 94e335620ded..22d1c44ec6c1 100644 --- a/src/core/geometry/qgsmultipoint.cpp +++ b/src/core/geometry/qgsmultipoint.cpp @@ -129,7 +129,7 @@ json QgsMultiPoint::asJsonObject( int precision ) const { "type", "MultiPoint" }, { "coordinates", json::array() }, }; - for ( const QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { const QgsPoint *point = static_cast( geom ); if ( point->is3D() ) diff --git a/src/core/geometry/qgsmultipolygon.cpp b/src/core/geometry/qgsmultipolygon.cpp index aea5caea77dc..fd655062a14a 100644 --- a/src/core/geometry/qgsmultipolygon.cpp +++ b/src/core/geometry/qgsmultipolygon.cpp @@ -112,7 +112,7 @@ QDomElement QgsMultiPolygon::asGml3( QDomDocument &doc, int precision, const QSt json QgsMultiPolygon::asJsonObject( int precision ) const { json polygons( json::array( ) ); - for ( const QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { if ( qgsgeometry_cast( geom ) ) { diff --git a/src/core/geometry/qgsmultisurface.cpp b/src/core/geometry/qgsmultisurface.cpp index caded658dbff..4d88edd2452f 100644 --- a/src/core/geometry/qgsmultisurface.cpp +++ b/src/core/geometry/qgsmultisurface.cpp @@ -123,7 +123,7 @@ QDomElement QgsMultiSurface::asGml3( QDomDocument &doc, int precision, const QSt json QgsMultiSurface::asJsonObject( int precision ) const { json polygons( json::array( ) ); - for ( const QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) + for ( const QgsAbstractGeometry *geom : std::as_const( mGeometries ) ) { if ( qgsgeometry_cast( geom ) ) { diff --git a/src/core/geometry/qgspolygon.cpp b/src/core/geometry/qgspolygon.cpp index 5d916c1b1ceb..104279704b74 100644 --- a/src/core/geometry/qgspolygon.cpp +++ b/src/core/geometry/qgspolygon.cpp @@ -243,7 +243,7 @@ void QgsPolygon::setExteriorRing( QgsCurve *ring ) setZMTypeFromSubGeometry( ring, QgsWkbTypes::Polygon ); //match dimensionality for rings - for ( QgsCurve *ring : qgis::as_const( mInteriorRings ) ) + for ( QgsCurve *ring : std::as_const( mInteriorRings ) ) { ring->convertTo( mExteriorRing->wkbType() ); } diff --git a/src/core/labeling/qgslabelingengine.cpp b/src/core/labeling/qgslabelingengine.cpp index 5199d990a68b..efb0cc12eba7 100644 --- a/src/core/labeling/qgslabelingengine.cpp +++ b/src/core/labeling/qgslabelingengine.cpp @@ -127,12 +127,12 @@ QList< QgsMapLayer * > QgsLabelingEngine::participatingLayers() const return false; } ); - for ( QgsAbstractLabelProvider *provider : qgis::as_const( providersByZ ) ) + for ( QgsAbstractLabelProvider *provider : std::as_const( providersByZ ) ) { if ( provider->layer() && !layers.contains( provider->layer() ) ) layers << provider->layer(); } - for ( QgsAbstractLabelProvider *provider : qgis::as_const( subProvidersByZ ) ) + for ( QgsAbstractLabelProvider *provider : std::as_const( subProvidersByZ ) ) { if ( provider->layer() && !layers.contains( provider->layer() ) ) layers << provider->layer(); @@ -173,12 +173,12 @@ QStringList QgsLabelingEngine::participatingLayerIds() const return false; } ); - for ( QgsAbstractLabelProvider *provider : qgis::as_const( providersByZ ) ) + for ( QgsAbstractLabelProvider *provider : std::as_const( providersByZ ) ) { if ( !layers.contains( provider->layerId() ) ) layers << provider->layerId(); } - for ( QgsAbstractLabelProvider *provider : qgis::as_const( subProvidersByZ ) ) + for ( QgsAbstractLabelProvider *provider : std::as_const( subProvidersByZ ) ) { if ( !layers.contains( provider->layerId() ) ) layers << provider->layerId(); @@ -278,7 +278,7 @@ void QgsLabelingEngine::registerLabels( QgsRenderContext &context ) mPal->setPlacementVersion( settings.placementVersion() ); // for each provider: get labels and register them in PAL - for ( QgsAbstractLabelProvider *provider : qgis::as_const( mProviders ) ) + for ( QgsAbstractLabelProvider *provider : std::as_const( mProviders ) ) { std::unique_ptr< QgsExpressionContextScopePopper > layerScopePopper; if ( QgsMapLayer *ml = provider->layer() ) @@ -410,7 +410,7 @@ void QgsLabelingEngine::drawLabels( QgsRenderContext &context, const QString &la QPainter *painter = context.painter(); // prepare for rendering - for ( QgsAbstractLabelProvider *provider : qgis::as_const( mProviders ) ) + for ( QgsAbstractLabelProvider *provider : std::as_const( mProviders ) ) { if ( !layerId.isEmpty() && provider->layerId() != layerId ) continue; @@ -425,7 +425,7 @@ void QgsLabelingEngine::drawLabels( QgsRenderContext &context, const QString &la std::unique_ptr< QgsExpressionContextScopePopper > symbolScopePopper = std::make_unique< QgsExpressionContextScopePopper >( context.expressionContext(), symbolScope ); // draw label backgrounds - for ( pal::LabelPosition *label : qgis::as_const( mLabels ) ) + for ( pal::LabelPosition *label : std::as_const( mLabels ) ) { if ( context.renderingStopped() ) break; @@ -449,7 +449,7 @@ void QgsLabelingEngine::drawLabels( QgsRenderContext &context, const QString &la } // draw the labels - for ( pal::LabelPosition *label : qgis::as_const( mLabels ) ) + for ( pal::LabelPosition *label : std::as_const( mLabels ) ) { if ( context.renderingStopped() ) break; @@ -477,7 +477,7 @@ void QgsLabelingEngine::drawLabels( QgsRenderContext &context, const QString &la // draw unplaced labels. These are always rendered on top if ( settings.testFlag( QgsLabelingEngineSettings::DrawUnplacedLabels ) ) { - for ( pal::LabelPosition *label : qgis::as_const( mUnlabeled ) ) + for ( pal::LabelPosition *label : std::as_const( mUnlabeled ) ) { if ( context.renderingStopped() ) break; @@ -505,7 +505,7 @@ void QgsLabelingEngine::drawLabels( QgsRenderContext &context, const QString &la symbolScopePopper.reset(); // cleanup - for ( QgsAbstractLabelProvider *provider : qgis::as_const( mProviders ) ) + for ( QgsAbstractLabelProvider *provider : std::as_const( mProviders ) ) { if ( !layerId.isEmpty() && provider->layerId() != layerId ) continue; diff --git a/src/core/labeling/qgspallabeling.cpp b/src/core/labeling/qgspallabeling.cpp index 4df28e2fd6ac..8cf2a602450c 100644 --- a/src/core/labeling/qgspallabeling.cpp +++ b/src/core/labeling/qgspallabeling.cpp @@ -3635,7 +3635,7 @@ QStringList QgsPalLabeling::splitToLines( const QString &text, const QString &wr { QStringList autoWrappedLines; autoWrappedLines.reserve( multiLineSplit.count() ); - for ( const QString &line : qgis::as_const( multiLineSplit ) ) + for ( const QString &line : std::as_const( multiLineSplit ) ) { autoWrappedLines.append( QgsStringUtils::wordWrap( line, autoWrapLength, useMaxLineLengthWhenAutoWrapping ).split( '\n' ) ); } diff --git a/src/core/labeling/qgsrulebasedlabeling.cpp b/src/core/labeling/qgsrulebasedlabeling.cpp index cf26ad859b19..94580a9f12ff 100644 --- a/src/core/labeling/qgsrulebasedlabeling.cpp +++ b/src/core/labeling/qgsrulebasedlabeling.cpp @@ -30,7 +30,7 @@ QgsVectorLayerLabelProvider *QgsRuleBasedLabelProvider::createProvider( QgsVecto bool QgsRuleBasedLabelProvider::prepare( QgsRenderContext &context, QSet &attributeNames ) { - for ( QgsVectorLayerLabelProvider *provider : qgis::as_const( mSubProviders ) ) + for ( QgsVectorLayerLabelProvider *provider : std::as_const( mSubProviders ) ) provider->setEngine( mEngine ); // populate sub-providers @@ -47,7 +47,7 @@ void QgsRuleBasedLabelProvider::registerFeature( const QgsFeature &feature, QgsR QList QgsRuleBasedLabelProvider::subProviders() { QList lst; - for ( QgsVectorLayerLabelProvider *subprovider : qgis::as_const( mSubProviders ) ) + for ( QgsVectorLayerLabelProvider *subprovider : std::as_const( mSubProviders ) ) lst << subprovider; return lst; } @@ -112,7 +112,7 @@ void QgsRuleBasedLabeling::Rule::initFilter() void QgsRuleBasedLabeling::Rule::updateElseRules() { mElseRules.clear(); - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { if ( rule->isElse() ) mElseRules << rule; @@ -124,7 +124,7 @@ bool QgsRuleBasedLabeling::Rule::requiresAdvancedEffects() const if ( mSettings && mSettings->format().containsAdvancedEffects() ) return true; - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { if ( rule->requiresAdvancedEffects() ) return true; @@ -163,7 +163,7 @@ bool QgsRuleBasedLabeling::Rule::accept( QgsStyleEntityVisitorInterface *visitor void QgsRuleBasedLabeling::Rule::subProviderIds( QStringList &list ) const { - for ( const Rule *rule : qgis::as_const( mChildren ) ) + for ( const Rule *rule : std::as_const( mChildren ) ) { if ( rule->settings() ) list << rule->ruleKey(); @@ -215,7 +215,7 @@ QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::findRuleByKey( const QSt if ( key == mRuleKey ) return this; - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { Rule *r = rule->findRuleByKey( key ); if ( r ) @@ -314,7 +314,7 @@ void QgsRuleBasedLabeling::Rule::createSubProviders( QgsVectorLayer *layer, QgsR } // call recursively - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { rule->createSubProviders( layer, subProviders, provider ); } @@ -339,7 +339,7 @@ void QgsRuleBasedLabeling::Rule::prepare( QgsRenderContext &context, QSetprepare( context, attributeNames, subProviders ); } @@ -365,7 +365,7 @@ QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerF bool willRegisterSomething = false; // call recursively - for ( Rule *rule : qgis::as_const( mChildren ) ) + for ( Rule *rule : std::as_const( mChildren ) ) { // Don't process else rules yet if ( !rule->isElse() ) @@ -380,7 +380,7 @@ QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerF // If none of the rules passed then we jump into the else rules and process them. if ( !willRegisterSomething ) { - for ( Rule *rule : qgis::as_const( mElseRules ) ) + for ( Rule *rule : std::as_const( mElseRules ) ) { registered |= rule->registerFeature( feature, context, subProviders, obstacleGeometry, symbol ) != Filtered; } diff --git a/src/core/labeling/qgstextlabelfeature.cpp b/src/core/labeling/qgstextlabelfeature.cpp index b92307c1e8dc..1c64197c752c 100644 --- a/src/core/labeling/qgstextlabelfeature.cpp +++ b/src/core/labeling/qgstextlabelfeature.cpp @@ -85,7 +85,7 @@ void QgsTextLabelFeature::calculateInfo( bool curvedLabeling, QFontMetricsF *fm, if ( document && curvedLabeling ) { - for ( const QgsTextBlock &block : qgis::as_const( *document ) ) + for ( const QgsTextBlock &block : std::as_const( *document ) ) { for ( const QgsTextFragment &fragment : block ) { diff --git a/src/core/layertree/qgslayertree.cpp b/src/core/layertree/qgslayertree.cpp index cd34a3605915..f0a39c3cec2c 100644 --- a/src/core/layertree/qgslayertree.cpp +++ b/src/core/layertree/qgslayertree.cpp @@ -129,14 +129,14 @@ void QgsLayerTree::writeXml( QDomElement &parentElement, const QgsReadWriteConte writeCommonXml( elem ); - for ( QgsLayerTreeNode *node : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *node : std::as_const( mChildren ) ) node->writeXml( elem, context ); QDomElement customOrderElem = doc.createElement( QStringLiteral( "custom-order" ) ); customOrderElem.setAttribute( QStringLiteral( "enabled" ), mHasCustomLayerOrder ? 1 : 0 ); elem.appendChild( customOrderElem ); - for ( QgsMapLayer *layer : qgis::as_const( mCustomLayerOrder ) ) + for ( QgsMapLayer *layer : std::as_const( mCustomLayerOrder ) ) { // Safety belt, see https://github.com/qgis/QGIS/issues/26975 // Crash when deleting an item from the layout legend @@ -187,7 +187,7 @@ void QgsLayerTree::nodeAddedChildren( QgsLayerTreeNode *node, int indexFrom, int } } - for ( QgsMapLayer *layer : qgis::as_const( layers ) ) + for ( QgsMapLayer *layer : std::as_const( layers ) ) { if ( !mCustomLayerOrder.contains( layer ) && layer ) mCustomLayerOrder.append( layer ); diff --git a/src/core/layertree/qgslayertreegroup.cpp b/src/core/layertree/qgslayertreegroup.cpp index 3da194459968..5f67f9979054 100644 --- a/src/core/layertree/qgslayertreegroup.cpp +++ b/src/core/layertree/qgslayertreegroup.cpp @@ -138,7 +138,7 @@ void QgsLayerTreeGroup::removeChildNode( QgsLayerTreeNode *node ) void QgsLayerTreeGroup::removeLayer( QgsMapLayer *layer ) { - for ( QgsLayerTreeNode *child : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *child : std::as_const( mChildren ) ) { if ( QgsLayerTree::isLayer( child ) ) { @@ -202,7 +202,7 @@ QgsLayerTreeLayer *QgsLayerTreeGroup::findLayer( QgsMapLayer *layer ) const QgsLayerTreeLayer *QgsLayerTreeGroup::findLayer( const QString &layerId ) const { - for ( QgsLayerTreeNode *child : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *child : std::as_const( mChildren ) ) { if ( QgsLayerTree::isLayer( child ) ) { @@ -223,7 +223,7 @@ QgsLayerTreeLayer *QgsLayerTreeGroup::findLayer( const QString &layerId ) const QList QgsLayerTreeGroup::findLayers() const { QList list; - for ( QgsLayerTreeNode *child : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *child : std::as_const( mChildren ) ) { if ( QgsLayerTree::isLayer( child ) ) list << QgsLayerTree::toLayer( child ); @@ -235,7 +235,7 @@ QList QgsLayerTreeGroup::findLayers() const QgsLayerTreeGroup *QgsLayerTreeGroup::findGroup( const QString &name ) { - for ( QgsLayerTreeNode *child : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *child : std::as_const( mChildren ) ) { if ( QgsLayerTree::isGroup( child ) ) { @@ -311,7 +311,7 @@ void QgsLayerTreeGroup::writeXml( QDomElement &parentElement, const QgsReadWrite writeCommonXml( elem ); - for ( QgsLayerTreeNode *node : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *node : std::as_const( mChildren ) ) node->writeXml( elem, context ); parentElement.appendChild( elem ); @@ -337,7 +337,7 @@ QString QgsLayerTreeGroup::dump() const { QString header = QStringLiteral( "GROUP: %1 checked=%2 expanded=%3\n" ).arg( name() ).arg( mChecked ).arg( mExpanded ); QStringList childrenDump; - for ( QgsLayerTreeNode *node : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *node : std::as_const( mChildren ) ) childrenDump << node->dump().split( '\n' ); for ( int i = 0; i < childrenDump.count(); ++i ) childrenDump[i].prepend( " " ); @@ -351,7 +351,7 @@ QgsLayerTreeGroup *QgsLayerTreeGroup::clone() const void QgsLayerTreeGroup::resolveReferences( const QgsProject *project, bool looseMatching ) { - for ( QgsLayerTreeNode *node : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *node : std::as_const( mChildren ) ) node->resolveReferences( project, looseMatching ); } @@ -380,7 +380,7 @@ void QgsLayerTreeGroup::setIsMutuallyExclusive( bool enabled, int initialChildIn { // try to use first checked index int index = 0; - for ( QgsLayerTreeNode *child : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *child : std::as_const( mChildren ) ) { if ( _nodeIsChecked( child ) ) { @@ -397,7 +397,7 @@ void QgsLayerTreeGroup::setIsMutuallyExclusive( bool enabled, int initialChildIn QStringList QgsLayerTreeGroup::findLayerIds() const { QStringList lst; - for ( QgsLayerTreeNode *child : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *child : std::as_const( mChildren ) ) { if ( QgsLayerTree::isGroup( child ) ) lst << QgsLayerTree::toGroup( child )->findLayerIds(); @@ -433,7 +433,7 @@ void QgsLayerTreeGroup::updateChildVisibilityMutuallyExclusive() mChangingChildVisibility = true; // guard against running again setVisible() triggered from children int index = 0; - for ( QgsLayerTreeNode *child : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *child : std::as_const( mChildren ) ) { child->setItemVisibilityChecked( index == mMutuallyExclusiveChildIndex ); ++index; @@ -456,7 +456,7 @@ void QgsLayerTreeGroup::setItemVisibilityCheckedRecursive( bool checked ) mChangingChildVisibility = true; // guard against running again setVisible() triggered from children int index = 0; - for ( QgsLayerTreeNode *child : qgis::as_const( mChildren ) ) + for ( QgsLayerTreeNode *child : std::as_const( mChildren ) ) { child->setItemVisibilityCheckedRecursive( checked && ( mMutuallyExclusiveChildIndex < 0 || index == mMutuallyExclusiveChildIndex ) ); ++index; diff --git a/src/core/layertree/qgslayertreemodel.cpp b/src/core/layertree/qgslayertreemodel.cpp index ed52ac6c2096..8528004b0c8c 100644 --- a/src/core/layertree/qgslayertreemodel.cpp +++ b/src/core/layertree/qgslayertreemodel.cpp @@ -516,7 +516,7 @@ QList QgsLayerTreeModel::indexes2nodes( const QModelIndexLis // remove any children of nodes if both parent node and children are selected QList nodesFinal; - for ( QgsLayerTreeNode *node : qgis::as_const( nodes ) ) + for ( QgsLayerTreeNode *node : std::as_const( nodes ) ) { if ( !_isChildOfNodes( node, nodes ) ) nodesFinal << node; @@ -1090,7 +1090,7 @@ QMimeData *QgsLayerTreeModel::mimeData( const QModelIndexList &indexes ) const QDomDocument layerTreeDoc; QDomElement rootLayerTreeElem = layerTreeDoc.createElement( QStringLiteral( "layer_tree_model_data" ) ); - for ( QgsLayerTreeNode *node : qgis::as_const( nodesFinal ) ) + for ( QgsLayerTreeNode *node : std::as_const( nodesFinal ) ) { node->writeXml( rootLayerTreeElem, QgsReadWriteContext() ); } @@ -1222,7 +1222,7 @@ QList QgsLayerTreeModel::filterLegendNodes( const if ( mLegendFilterByScale > 0 ) { - for ( QgsLayerTreeModelLegendNode *node : qgis::as_const( nodes ) ) + for ( QgsLayerTreeModelLegendNode *node : std::as_const( nodes ) ) { if ( node->isScaleOK( mLegendFilterByScale ) ) filtered << node; @@ -1232,7 +1232,7 @@ QList QgsLayerTreeModel::filterLegendNodes( const { if ( !nodes.isEmpty() && mLegendFilterMapSettings->layers().contains( nodes.at( 0 )->layerNode()->layer() ) ) { - for ( QgsLayerTreeModelLegendNode *node : qgis::as_const( nodes ) ) + for ( QgsLayerTreeModelLegendNode *node : std::as_const( nodes ) ) { switch ( node->data( QgsSymbolLegendNode::NodeTypeRole ).value() ) { @@ -1656,13 +1656,13 @@ void QgsLayerTreeModel::invalidateLegendMapBasedData() std::unique_ptr context( createTemporaryRenderContext() ); - for ( QgsLayerTreeLayer *layerNode : qgis::as_const( mInvalidatedNodes ) ) + for ( QgsLayerTreeLayer *layerNode : std::as_const( mInvalidatedNodes ) ) { const LayerLegendData &data = mLegend.value( layerNode ); QList symbolNodes; QMap widthMax; - for ( QgsLayerTreeModelLegendNode *legendNode : qgis::as_const( data.originalNodes ) ) + for ( QgsLayerTreeModelLegendNode *legendNode : std::as_const( data.originalNodes ) ) { QgsSymbolLegendNode *n = qobject_cast( legendNode ); if ( n ) @@ -1674,14 +1674,14 @@ void QgsLayerTreeModel::invalidateLegendMapBasedData() symbolNodes.append( n ); } } - for ( QgsSymbolLegendNode *n : qgis::as_const( symbolNodes ) ) + for ( QgsSymbolLegendNode *n : std::as_const( symbolNodes ) ) { const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() ); Q_ASSERT( widthMax[parentKey] > 0 ); const int twiceMarginWidth = 2; // a one pixel margin avoids hugly rendering of icon n->setIconSize( QSize( widthMax[parentKey] + twiceMarginWidth, n->iconSize().rheight() + twiceMarginWidth ) ); } - for ( QgsLayerTreeModelLegendNode *legendNode : qgis::as_const( data.originalNodes ) ) + for ( QgsLayerTreeModelLegendNode *legendNode : std::as_const( data.originalNodes ) ) legendNode->invalidateMapBasedData(); } diff --git a/src/core/layertree/qgslayertreenode.cpp b/src/core/layertree/qgslayertreenode.cpp index eb3c23238e17..1e4c81339d17 100644 --- a/src/core/layertree/qgslayertreenode.cpp +++ b/src/core/layertree/qgslayertreenode.cpp @@ -38,7 +38,7 @@ QgsLayerTreeNode::QgsLayerTreeNode( const QgsLayerTreeNode &other ) { QList clonedChildren; - for ( QgsLayerTreeNode *child : qgis::as_const( other.mChildren ) ) + for ( QgsLayerTreeNode *child : std::as_const( other.mChildren ) ) clonedChildren << child->clone(); insertChildrenPrivate( -1, clonedChildren ); } @@ -52,7 +52,7 @@ QList QgsLayerTreeNode::abandonChildren() { const QList orphans { mChildren }; mChildren.clear(); - for ( auto orphan : qgis::as_const( orphans ) ) + for ( auto orphan : std::as_const( orphans ) ) { orphan->makeOrphan( ); } diff --git a/src/core/layout/qgsabstractreportsection.cpp b/src/core/layout/qgsabstractreportsection.cpp index d5e7165e70a0..e213e7ae9f69 100644 --- a/src/core/layout/qgsabstractreportsection.cpp +++ b/src/core/layout/qgsabstractreportsection.cpp @@ -68,7 +68,7 @@ void QgsAbstractReportSection::setContext( const QgsReportSectionContext &contex if ( mFooter ) setReportContext( mFooter.get() ); - for ( QgsAbstractReportSection *section : qgis::as_const( mChildren ) ) + for ( QgsAbstractReportSection *section : std::as_const( mChildren ) ) { section->setContext( mContext ); } @@ -237,7 +237,7 @@ bool QgsAbstractReportSection::beginRender() // and all children too bool result = true; - for ( QgsAbstractReportSection *child : qgis::as_const( mChildren ) ) + for ( QgsAbstractReportSection *child : std::as_const( mChildren ) ) { result = result && child->beginRender(); } @@ -310,7 +310,7 @@ bool QgsAbstractReportSection::next() { mNextChild = 0; - for ( QgsAbstractReportSection *section : qgis::as_const( mChildren ) ) + for ( QgsAbstractReportSection *section : std::as_const( mChildren ) ) { section->reset(); } @@ -356,7 +356,7 @@ bool QgsAbstractReportSection::endRender() // and all children too bool result = true; - for ( QgsAbstractReportSection *child : qgis::as_const( mChildren ) ) + for ( QgsAbstractReportSection *child : std::as_const( mChildren ) ) { result = result && child->endRender(); } @@ -368,7 +368,7 @@ void QgsAbstractReportSection::reset() mCurrentLayout = nullptr; mNextChild = 0; mNextSection = Header; - for ( QgsAbstractReportSection *section : qgis::as_const( mChildren ) ) + for ( QgsAbstractReportSection *section : std::as_const( mChildren ) ) { section->reset(); } @@ -453,7 +453,7 @@ void QgsAbstractReportSection::copyCommonProperties( QgsAbstractReportSection *d qDeleteAll( destination->mChildren ); destination->mChildren.clear(); - for ( QgsAbstractReportSection *child : qgis::as_const( mChildren ) ) + for ( QgsAbstractReportSection *child : std::as_const( mChildren ) ) { destination->appendChild( child->clone() ); } diff --git a/src/core/layout/qgslayout.cpp b/src/core/layout/qgslayout.cpp index df577be9c817..959d44d61ff5 100644 --- a/src/core/layout/qgslayout.cpp +++ b/src/core/layout/qgslayout.cpp @@ -65,7 +65,7 @@ QgsLayout::~QgsLayout() while ( deleted ) { deleted = false; - for ( QGraphicsItem *item : qgis::as_const( itemList ) ) + for ( QGraphicsItem *item : std::as_const( itemList ) ) { if ( dynamic_cast< QgsLayoutItem * >( item ) && !dynamic_cast< QgsLayoutItemPage *>( item ) ) { @@ -239,7 +239,7 @@ QgsLayoutItem *QgsLayout::itemByUuid( const QString &uuid, bool includeTemplateU { QList itemList; layoutItems( itemList ); - for ( QgsLayoutItem *item : qgis::as_const( itemList ) ) + for ( QgsLayoutItem *item : std::as_const( itemList ) ) { if ( item->uuid() == uuid ) return item; @@ -254,7 +254,7 @@ QgsLayoutItem *QgsLayout::itemByTemplateUuid( const QString &uuid ) const { QList itemList; layoutItems( itemList ); - for ( QgsLayoutItem *item : qgis::as_const( itemList ) ) + for ( QgsLayoutItem *item : std::as_const( itemList ) ) { if ( item->mTemplateUuid == uuid ) return item; @@ -438,7 +438,7 @@ QgsLayoutItemMap *QgsLayout::referenceMap() const layoutItems( maps ); QgsLayoutItemMap *largestMap = nullptr; double largestMapArea = 0; - for ( QgsLayoutItemMap *map : qgis::as_const( maps ) ) + for ( QgsLayoutItemMap *map : std::as_const( maps ) ) { double area = map->rect().width() * map->rect().height(); if ( area > largestMapArea ) @@ -1113,7 +1113,7 @@ QList< QgsLayoutItem * > QgsLayout::addItemsFromXml( const QDomElement &parentEl { profile->switchTask( tr( "Finalize restore" ) ); } - for ( QgsLayoutItem *item : qgis::as_const( newItems ) ) + for ( QgsLayoutItem *item : std::as_const( newItems ) ) { if ( profile ) itemProfile = std::make_unique< QgsScopedRuntimeProfile >( item->displayName(), QStringLiteral( "projectload" ) ); @@ -1121,7 +1121,7 @@ QList< QgsLayoutItem * > QgsLayout::addItemsFromXml( const QDomElement &parentEl if ( itemProfile ) itemProfile.reset(); } - for ( QgsLayoutMultiFrame *mf : qgis::as_const( newMultiFrames ) ) + for ( QgsLayoutMultiFrame *mf : std::as_const( newMultiFrames ) ) { if ( profile ) itemProfile = std::make_unique< QgsScopedRuntimeProfile >( mf->displayName(), QStringLiteral( "projectload" ) ); @@ -1130,11 +1130,11 @@ QList< QgsLayoutItem * > QgsLayout::addItemsFromXml( const QDomElement &parentEl itemProfile.reset(); } - for ( QgsLayoutItem *item : qgis::as_const( newItems ) ) + for ( QgsLayoutItem *item : std::as_const( newItems ) ) { item->mTemplateUuid.clear(); } - for ( QgsLayoutMultiFrame *mf : qgis::as_const( newMultiFrames ) ) + for ( QgsLayoutMultiFrame *mf : std::as_const( newMultiFrames ) ) { mf->mTemplateUuid.clear(); } diff --git a/src/core/layout/qgslayoutexporter.cpp b/src/core/layout/qgslayoutexporter.cpp index 1bb8c8b16e15..d39be77223bf 100644 --- a/src/core/layout/qgslayoutexporter.cpp +++ b/src/core/layout/qgslayoutexporter.cpp @@ -399,14 +399,14 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToImage( const QString } else { - for ( int page : qgis::as_const( settings.pages ) ) + for ( int page : std::as_const( settings.pages ) ) { if ( page >= 0 && page < mLayout->pageCollection()->pageCount() ) pages << page; } } - for ( int page : qgis::as_const( pages ) ) + for ( int page : std::as_const( pages ) ) { if ( !mLayout->pageCollection()->shouldExportPage( page ) ) { @@ -626,7 +626,7 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToPdf( const QString &f // setup georeferencing QList< QgsLayoutItemMap * > maps; mLayout->layoutItems( maps ); - for ( QgsLayoutItemMap *map : qgis::as_const( maps ) ) + for ( QgsLayoutItemMap *map : std::as_const( maps ) ) { QgsAbstractGeoPdfExporter::GeoReferencedSection georef; georef.crs = map->crs(); diff --git a/src/core/layout/qgslayoutgeopdfexporter.cpp b/src/core/layout/qgslayoutgeopdfexporter.cpp index 9195bb1c3e64..d432d7d16558 100644 --- a/src/core/layout/qgslayoutgeopdfexporter.cpp +++ b/src/core/layout/qgslayoutgeopdfexporter.cpp @@ -138,7 +138,7 @@ QgsLayoutGeoPdfExporter::QgsLayoutGeoPdfExporter( QgsLayout *layout ) // on construction, we install a rendered feature handler on layout item maps QList< QgsLayoutItemMap * > maps; mLayout->layoutItems( maps ); - for ( QgsLayoutItemMap *map : qgis::as_const( maps ) ) + for ( QgsLayoutItemMap *map : std::as_const( maps ) ) { QgsGeoPdfRenderedFeatureHandler *handler = new QgsGeoPdfRenderedFeatureHandler( map, this, exportableLayerIds ); mMapHandlers.insert( map, handler ); diff --git a/src/core/layout/qgslayoutguidecollection.cpp b/src/core/layout/qgslayoutguidecollection.cpp index a2768e15cc5a..67edc3c3ce2b 100644 --- a/src/core/layout/qgslayoutguidecollection.cpp +++ b/src/core/layout/qgslayoutguidecollection.cpp @@ -443,7 +443,7 @@ void QgsLayoutGuideCollection::applyGuidesToAllOtherPages( int sourcePage ) } // remaining guides belong to source page - clone them to other pages - for ( QgsLayoutGuide *guide : qgis::as_const( mGuides ) ) + for ( QgsLayoutGuide *guide : std::as_const( mGuides ) ) { for ( int p = 0; p < mPageCollection->pageCount(); ++p ) { diff --git a/src/core/layout/qgslayoutitemattributetable.cpp b/src/core/layout/qgslayoutitemattributetable.cpp index 526c30791b68..4c8a49e23b23 100644 --- a/src/core/layout/qgslayoutitemattributetable.cpp +++ b/src/core/layout/qgslayoutitemattributetable.cpp @@ -486,7 +486,7 @@ bool QgsLayoutItemAttributeTable::getTableContents( QgsLayoutTableContents &cont req.setFilterFid( atlasFeature.id() ); } - for ( const QgsLayoutTableColumn &column : qgis::as_const( mSortColumns ) ) + for ( const QgsLayoutTableColumn &column : std::as_const( mSortColumns ) ) { req.addOrderBy( column.attribute(), column.sortOrder() == Qt::AscendingOrder ); } @@ -558,7 +558,7 @@ bool QgsLayoutItemAttributeTable::getTableContents( QgsLayoutTableContents &cont QgsLayoutTableRow rowContents; rowContents.reserve( mColumns.count() ); - for ( const QgsLayoutTableColumn &column : qgis::as_const( mColumns ) ) + for ( const QgsLayoutTableColumn &column : std::as_const( mColumns ) ) { int idx = layer->fields().lookupField( column.attribute() ); @@ -726,7 +726,7 @@ QgsLayoutTableColumns QgsLayoutItemAttributeTable::filteredColumns() QHash> columnAttributesMap; QSet allowedAttributes; - for ( const auto &c : qgis::as_const( allowedColumns ) ) + for ( const auto &c : std::as_const( allowedColumns ) ) { if ( ! c.attribute().isEmpty() && ! columnAttributesMap.contains( c.attribute() ) ) { @@ -752,7 +752,7 @@ QgsLayoutTableColumns QgsLayoutItemAttributeTable::filteredColumns() const auto forbidden { allowedAttributes.subtract( filteredAttributesSet ) }; allowedColumns.erase( std::remove_if( allowedColumns.begin(), allowedColumns.end(), [ &columnAttributesMap, &forbidden ]( QgsLayoutTableColumn & c ) -> bool { - for ( const auto &f : qgis::as_const( forbidden ) ) + for ( const auto &f : std::as_const( forbidden ) ) { if ( columnAttributesMap[ c.attribute() ].contains( f ) ) { diff --git a/src/core/layout/qgslayoutitemgroup.cpp b/src/core/layout/qgslayoutitemgroup.cpp index 8b1e03e3ad45..026513b8297f 100644 --- a/src/core/layout/qgslayoutitemgroup.cpp +++ b/src/core/layout/qgslayoutitemgroup.cpp @@ -28,7 +28,7 @@ QgsLayoutItemGroup::QgsLayoutItemGroup( QgsLayout *layout ) void QgsLayoutItemGroup::cleanup() { //loop through group members and remove them from the scene - for ( QgsLayoutItem *item : qgis::as_const( mItems ) ) + for ( QgsLayoutItem *item : std::as_const( mItems ) ) { if ( !item ) continue; @@ -86,7 +86,7 @@ void QgsLayoutItemGroup::addItem( QgsLayoutItem *item ) void QgsLayoutItemGroup::removeItems() { - for ( QgsLayoutItem *item : qgis::as_const( mItems ) ) + for ( QgsLayoutItem *item : std::as_const( mItems ) ) { if ( !item ) continue; @@ -99,7 +99,7 @@ void QgsLayoutItemGroup::removeItems() QList QgsLayoutItemGroup::items() const { QList val; - for ( QgsLayoutItem *item : qgis::as_const( mItems ) ) + for ( QgsLayoutItem *item : std::as_const( mItems ) ) { if ( !item ) continue; @@ -113,7 +113,7 @@ void QgsLayoutItemGroup::setVisibility( const bool visible ) if ( !shouldBlockUndoCommands() ) mLayout->undoStack()->beginMacro( tr( "Set Group Visibility" ) ); //also set visibility for all items within the group - for ( QgsLayoutItem *item : qgis::as_const( mItems ) ) + for ( QgsLayoutItem *item : std::as_const( mItems ) ) { if ( !item ) continue; @@ -148,7 +148,7 @@ void QgsLayoutItemGroup::attemptMove( const QgsLayoutPoint &point, bool useRefer double deltaY = scenePoint.y() - pos().y(); //also move all items within the group - for ( QgsLayoutItem *item : qgis::as_const( mItems ) ) + for ( QgsLayoutItem *item : std::as_const( mItems ) ) { if ( !item ) continue; @@ -189,7 +189,7 @@ void QgsLayoutItemGroup::attemptResize( const QgsLayoutSize &size, bool includes newRect.setSize( newSizeLayoutUnits ); //also resize all items within the group - for ( QgsLayoutItem *item : qgis::as_const( mItems ) ) + for ( QgsLayoutItem *item : std::as_const( mItems ) ) { if ( !item ) continue; @@ -260,7 +260,7 @@ bool QgsLayoutItemGroup::readPropertiesFromElement( const QDomElement &itemEleme void QgsLayoutItemGroup::finalizeRestoreFromXml() { - for ( const QString &uuid : qgis::as_const( mItemUuids ) ) + for ( const QString &uuid : std::as_const( mItemUuids ) ) { QgsLayoutItem *item = mLayout->itemByUuid( uuid, true ); if ( item ) @@ -289,7 +289,7 @@ void QgsLayoutItemGroup::draw( QgsLayoutItemRenderContext & ) void QgsLayoutItemGroup::resetBoundingRect() { mBoundingRectangle = QRectF(); - for ( QgsLayoutItem *item : qgis::as_const( mItems ) ) + for ( QgsLayoutItem *item : std::as_const( mItems ) ) { updateBoundingRect( item ); } diff --git a/src/core/layout/qgslayoutitemgroupundocommand.cpp b/src/core/layout/qgslayoutitemgroupundocommand.cpp index d7b605c6465c..12129e474fa8 100644 --- a/src/core/layout/qgslayoutitemgroupundocommand.cpp +++ b/src/core/layout/qgslayoutitemgroupundocommand.cpp @@ -75,7 +75,7 @@ void QgsLayoutItemGroupUndoCommand::switchState() mLayout->addLayoutItemPrivate( group ); } - for ( const QString &childUuid : qgis::as_const( mItemUuids ) ) + for ( const QString &childUuid : std::as_const( mItemUuids ) ) { QgsLayoutItem *childItem = mLayout->itemByUuid( childUuid ); group->addItem( childItem ); diff --git a/src/core/layout/qgslayoutitemmanualtable.cpp b/src/core/layout/qgslayoutitemmanualtable.cpp index 82b073d358d0..ae7342aad59f 100644 --- a/src/core/layout/qgslayoutitemmanualtable.cpp +++ b/src/core/layout/qgslayoutitemmanualtable.cpp @@ -67,7 +67,7 @@ bool QgsLayoutItemManualTable::getTableContents( QgsLayoutTableContents &content QgsExpressionContext context = createExpressionContext(); int rowNumber = 0; - for ( const QgsTableRow &row : qgis::as_const( mContents ) ) + for ( const QgsTableRow &row : std::as_const( mContents ) ) { QgsLayoutTableRow currentRow; @@ -189,7 +189,7 @@ bool QgsLayoutItemManualTable::writePropertiesToElement( QDomElement &tableElem, //headers QDomElement headersElem = doc.createElement( QStringLiteral( "headers" ) ); - for ( const QgsLayoutTableColumn &header : qgis::as_const( mHeaders ) ) + for ( const QgsLayoutTableColumn &header : std::as_const( mHeaders ) ) { QDomElement headerElem = doc.createElement( QStringLiteral( "header" ) ); header.writeXml( headerElem, doc ); diff --git a/src/core/layout/qgslayoutitemmap.cpp b/src/core/layout/qgslayoutitemmap.cpp index 5620febd1097..3b87d61243dc 100644 --- a/src/core/layout/qgslayoutitemmap.cpp +++ b/src/core/layout/qgslayoutitemmap.cpp @@ -122,7 +122,7 @@ void QgsLayoutItemMap::assignFreeId() int maxId = -1; bool used = false; - for ( QgsLayoutItemMap *map : qgis::as_const( mapsList ) ) + for ( QgsLayoutItemMap *map : std::as_const( mapsList ) ) { if ( map == this ) continue; @@ -343,7 +343,7 @@ void QgsLayoutItemMap::setLayerStyleOverrides( const QMap &ove void QgsLayoutItemMap::storeCurrentLayerStyles() { mLayerStyleOverrides.clear(); - for ( const QgsMapLayerRef &layerRef : qgis::as_const( mLayers ) ) + for ( const QgsMapLayerRef &layerRef : std::as_const( mLayers ) ) { if ( QgsMapLayer *layer = layerRef.get() ) { @@ -681,7 +681,7 @@ bool QgsLayoutItemMap::writePropertiesToElement( QDomElement &mapElem, QDomDocum mapElem.setAttribute( QStringLiteral( "mapFlags" ), static_cast< int>( mMapFlags ) ); QDomElement labelBlockingItemsElem = doc.createElement( QStringLiteral( "labelBlockingItems" ) ); - for ( const auto &item : qgis::as_const( mBlockingLabelItems ) ) + for ( const auto &item : std::as_const( mBlockingLabelItems ) ) { if ( !item ) continue; @@ -1557,7 +1557,7 @@ QgsMapSettings QgsLayoutItemMap::mapSettings( const QgsRectangle &extent, QSizeF jobMapSettings.setLabelBlockingRegions( createLabelBlockingRegions( jobMapSettings ) ); } - for ( QgsRenderedFeatureHandlerInterface *handler : qgis::as_const( mRenderedFeatureHandlers ) ) + for ( QgsRenderedFeatureHandlerInterface *handler : std::as_const( mRenderedFeatureHandlers ) ) { jobMapSettings.addRenderedFeatureHandler( handler ); } @@ -1623,7 +1623,7 @@ void QgsLayoutItemMap::finalizeRestoreFromXml() assignFreeId(); mBlockingLabelItems.clear(); - for ( const QString &uuid : qgis::as_const( mBlockingLabelItemUuids ) ) + for ( const QString &uuid : std::as_const( mBlockingLabelItemUuids ) ) { QgsLayoutItem *item = mLayout->itemByUuid( uuid, true ); if ( item ) @@ -2059,7 +2059,7 @@ QList QgsLayoutItemMap::createLabelBlockingRegions( cons const QTransform mapTransform = layoutToMapCoordsTransform(); QList< QgsLabelBlockingRegion > blockers; blockers.reserve( mBlockingLabelItems.count() ); - for ( const auto &item : qgis::as_const( mBlockingLabelItems ) ) + for ( const auto &item : std::as_const( mBlockingLabelItems ) ) { // invisible items don't block labels! if ( !item ) diff --git a/src/core/layout/qgslayoutitemmapitem.cpp b/src/core/layout/qgslayoutitemmapitem.cpp index d1b142ac70ab..ee5fbb90ad35 100644 --- a/src/core/layout/qgslayoutitemmapitem.cpp +++ b/src/core/layout/qgslayoutitemmapitem.cpp @@ -263,7 +263,7 @@ bool QgsLayoutItemMapItemStack::writeXml( QDomElement &elem, QDomDocument &doc, void QgsLayoutItemMapItemStack::finalizeRestoreFromXml() { - for ( QgsLayoutItemMapItem *item : qgis::as_const( mItems ) ) + for ( QgsLayoutItemMapItem *item : std::as_const( mItems ) ) { item->finalizeRestoreFromXml(); } @@ -276,7 +276,7 @@ void QgsLayoutItemMapItemStack::drawItems( QPainter *painter, bool ignoreStackin return; } - for ( QgsLayoutItemMapItem *item : qgis::as_const( mItems ) ) + for ( QgsLayoutItemMapItem *item : std::as_const( mItems ) ) { switch ( item->stackingPosition() ) { diff --git a/src/core/layout/qgslayoutitemmapoverview.cpp b/src/core/layout/qgslayoutitemmapoverview.cpp index 0e44bd788164..86876279b822 100644 --- a/src/core/layout/qgslayoutitemmapoverview.cpp +++ b/src/core/layout/qgslayoutitemmapoverview.cpp @@ -468,7 +468,7 @@ QList QgsLayoutItemMapOverviewStack::modifyMapLayerList( const QL { QList res = layers; res.reserve( layers.count() + mItems.count() ); - for ( QgsLayoutItemMapItem *item : qgis::as_const( mItems ) ) + for ( QgsLayoutItemMapItem *item : std::as_const( mItems ) ) { if ( !item ) continue; diff --git a/src/core/layout/qgslayoutitemtexttable.cpp b/src/core/layout/qgslayoutitemtexttable.cpp index 95d7b613b9aa..f1d633216a76 100644 --- a/src/core/layout/qgslayoutitemtexttable.cpp +++ b/src/core/layout/qgslayoutitemtexttable.cpp @@ -57,7 +57,7 @@ bool QgsLayoutItemTextTable::getTableContents( QgsLayoutTableContents &contents { contents.clear(); - for ( const QStringList &row : qgis::as_const( mRowText ) ) + for ( const QStringList &row : std::as_const( mRowText ) ) { QgsLayoutTableRow currentRow; diff --git a/src/core/layout/qgslayoutmanager.cpp b/src/core/layout/qgslayoutmanager.cpp index cae4041109ac..b8a87433fec4 100644 --- a/src/core/layout/qgslayoutmanager.cpp +++ b/src/core/layout/qgslayoutmanager.cpp @@ -44,7 +44,7 @@ bool QgsLayoutManager::addLayout( QgsMasterLayoutInterface *layout ) return false; // check for duplicate name - for ( QgsMasterLayoutInterface *l : qgis::as_const( mLayouts ) ) + for ( QgsMasterLayoutInterface *l : std::as_const( mLayouts ) ) { if ( l->name() == layout->name() ) { @@ -172,7 +172,7 @@ bool QgsLayoutManager::readXml( const QDomElement &element, const QDomDocument & do { isDuplicateName = false; - for ( QgsMasterLayoutInterface *layout : qgis::as_const( mLayouts ) ) + for ( QgsMasterLayoutInterface *layout : std::as_const( mLayouts ) ) { if ( l->name() == layout->name() ) { diff --git a/src/core/layout/qgslayoutmodel.cpp b/src/core/layout/qgslayoutmodel.cpp index 5f7582cbf4c2..67aa424674d7 100644 --- a/src/core/layout/qgslayoutmodel.cpp +++ b/src/core/layout/qgslayoutmodel.cpp @@ -78,7 +78,7 @@ void QgsLayoutModel::refreshItemsInScene() const QList< QGraphicsItem * > items = mLayout->items(); //filter paper items from list //TODO - correctly handle grouped item z order placement - for ( QgsLayoutItem *item : qgis::as_const( mItemZList ) ) + for ( QgsLayoutItem *item : std::as_const( mItemZList ) ) { if ( item->type() != QgsLayoutItemRegistry::LayoutPage && items.contains( item ) ) { @@ -373,7 +373,7 @@ bool QgsLayoutModel::dropMimeData( const QMimeData *data, //calculate position to insert moved rows to int insertPos = destPos; - for ( QgsLayoutItem *item : qgis::as_const( droppedItems ) ) + for ( QgsLayoutItem *item : std::as_const( droppedItems ) ) { int listPos = mItemZList.indexOf( item ); if ( listPos == -1 ) @@ -471,7 +471,7 @@ void QgsLayoutModel::rebuildSceneItemList() //emitting signals as required int row = 0; const QList< QGraphicsItem * > items = mLayout->items(); - for ( QgsLayoutItem *item : qgis::as_const( mItemZList ) ) + for ( QgsLayoutItem *item : std::as_const( mItemZList ) ) { if ( item->type() == QgsLayoutItemRegistry::LayoutPage || !items.contains( item ) ) { diff --git a/src/core/layout/qgslayoutmultiframe.cpp b/src/core/layout/qgslayoutmultiframe.cpp index a7ea7b40d777..15e1aba5cb1b 100644 --- a/src/core/layout/qgslayoutmultiframe.cpp +++ b/src/core/layout/qgslayoutmultiframe.cpp @@ -444,7 +444,7 @@ void QgsLayoutMultiFrame::removeFrame( int i, const bool removeEmptyPages ) void QgsLayoutMultiFrame::update() { - for ( QgsLayoutFrame *frame : qgis::as_const( mFrameItems ) ) + for ( QgsLayoutFrame *frame : std::as_const( mFrameItems ) ) { frame->update(); } @@ -456,7 +456,7 @@ void QgsLayoutMultiFrame::deleteFrames() ResizeMode bkResizeMode = mResizeMode; mResizeMode = UseExistingFrames; mLayout->undoStack()->blockCommands( true ); - for ( QgsLayoutFrame *frame : qgis::as_const( mFrameItems ) ) + for ( QgsLayoutFrame *frame : std::as_const( mFrameItems ) ) { mLayout->removeLayoutItem( frame ); } diff --git a/src/core/layout/qgslayoutpagecollection.cpp b/src/core/layout/qgslayoutpagecollection.cpp index 3f4c3060b17c..8d9b11ab765d 100644 --- a/src/core/layout/qgslayoutpagecollection.cpp +++ b/src/core/layout/qgslayoutpagecollection.cpp @@ -48,7 +48,7 @@ void QgsLayoutPageCollection::setPageStyleSymbol( QgsFillSymbol *symbol ) mPageStyleSymbol.reset( static_cast( symbol->clone() ) ); - for ( QgsLayoutItemPage *page : qgis::as_const( mPages ) ) + for ( QgsLayoutItemPage *page : std::as_const( mPages ) ) { page->setPageStyleSymbol( symbol->clone() ); page->update(); @@ -66,7 +66,7 @@ void QgsLayoutPageCollection::beginPageSizeChange() QList< QgsLayoutItem * > items; mLayout->layoutItems( items ); - for ( QgsLayoutItem *item : qgis::as_const( items ) ) + for ( QgsLayoutItem *item : std::as_const( items ) ) { if ( item->type() == QgsLayoutItemRegistry::LayoutPage ) continue; @@ -387,7 +387,7 @@ bool QgsLayoutPageCollection::readXml( const QDomElement &e, const QDomDocument mBlockUndoCommands = true; int i = 0; - for ( QgsLayoutItemPage *page : qgis::as_const( mPages ) ) + for ( QgsLayoutItemPage *page : std::as_const( mPages ) ) { emit pageAboutToBeRemoved( i ); mLayout->removeItem( page ); @@ -548,7 +548,7 @@ bool QgsLayoutPageCollection::shouldExportPage( int page ) const //check all frame items on page QList frames; itemsOnPage( frames, page ); - for ( QgsLayoutFrame *frame : qgis::as_const( frames ) ) + for ( QgsLayoutFrame *frame : std::as_const( frames ) ) { if ( frame->hidePageIfEmpty() && frame->isEmpty() ) { diff --git a/src/core/layout/qgslayoutsnapper.cpp b/src/core/layout/qgslayoutsnapper.cpp index 0845305520ab..05bbe77ecf70 100644 --- a/src/core/layout/qgslayoutsnapper.cpp +++ b/src/core/layout/qgslayoutsnapper.cpp @@ -372,7 +372,7 @@ double QgsLayoutSnapper::snapPointsToItems( const QList &points, Qt::Ori } } - for ( double val : qgis::as_const( currentCoords ) ) + for ( double val : std::as_const( currentCoords ) ) { for ( double p : points ) { diff --git a/src/core/layout/qgslayouttable.cpp b/src/core/layout/qgslayouttable.cpp index 9cf1c3de1bf9..e10cff0c44b0 100644 --- a/src/core/layout/qgslayouttable.cpp +++ b/src/core/layout/qgslayouttable.cpp @@ -94,7 +94,7 @@ bool QgsLayoutTable::writePropertiesToElement( QDomElement &elem, QDomDocument & // display columns QDomElement displayColumnsElem = doc.createElement( QStringLiteral( "displayColumns" ) ); - for ( const QgsLayoutTableColumn &column : qgis::as_const( mColumns ) ) + for ( const QgsLayoutTableColumn &column : std::as_const( mColumns ) ) { QDomElement columnElem = doc.createElement( QStringLiteral( "column" ) ); column.writeXml( columnElem, doc ); @@ -103,7 +103,7 @@ bool QgsLayoutTable::writePropertiesToElement( QDomElement &elem, QDomDocument & elem.appendChild( displayColumnsElem ); // sort columns QDomElement sortColumnsElem = doc.createElement( QStringLiteral( "sortColumns" ) ); - for ( const QgsLayoutTableColumn &column : qgis::as_const( mSortColumns ) ) + for ( const QgsLayoutTableColumn &column : std::as_const( mSortColumns ) ) { QDomElement columnElem = doc.createElement( QStringLiteral( "column" ) ); column.writeXml( columnElem, doc ); @@ -431,7 +431,7 @@ void QgsLayoutTable::render( QgsLayoutItemRenderContext &context, const QRectF & { //draw the headers int col = 0; - for ( const QgsLayoutTableColumn &column : qgis::as_const( mColumns ) ) + for ( const QgsLayoutTableColumn &column : std::as_const( mColumns ) ) { std::unique_ptr< QgsExpressionContextScope > headerCellScope = std::make_unique< QgsExpressionContextScope >(); headerCellScope->setVariable( QStringLiteral( "column_number" ), col + 1, true ); @@ -511,7 +511,7 @@ void QgsLayoutTable::render( QgsLayoutItemRenderContext &context, const QRectF & //calculate row height double rowHeight = mMaxRowHeightMap[row + 1] + 2 * mCellMargin; - for ( const QgsLayoutTableColumn &column : qgis::as_const( mColumns ) ) + for ( const QgsLayoutTableColumn &column : std::as_const( mColumns ) ) { const QRectF fullCell( currentX, currentY, mMaxColumnWidthMap[col] + 2 * mCellMargin, rowHeight ); //draw background @@ -589,7 +589,7 @@ void QgsLayoutTable::render( QgsLayoutItemRenderContext &context, const QRectF & } else { - for ( const QgsLayoutTableColumn &column : qgis::as_const( mColumns ) ) + for ( const QgsLayoutTableColumn &column : std::as_const( mColumns ) ) { Q_UNUSED( column ) @@ -987,7 +987,7 @@ QMap QgsLayoutTable::headerLabels() const QMap headers; int i = 0; - for ( const QgsLayoutTableColumn &col : qgis::as_const( mColumns ) ) + for ( const QgsLayoutTableColumn &col : std::as_const( mColumns ) ) { headers.insert( i, col.heading() ); i++; @@ -1090,7 +1090,7 @@ bool QgsLayoutTable::calculateMaxColumnWidths() //first, go through all the column headers and calculate the sizes int i = 0; - for ( const QgsLayoutTableColumn &col : qgis::as_const( mColumns ) ) + for ( const QgsLayoutTableColumn &col : std::as_const( mColumns ) ) { if ( col.width() > 0 ) { @@ -1174,7 +1174,7 @@ bool QgsLayoutTable::calculateMaxRowHeights() //first, go through all the column headers and calculate the sizes int i = 0; - for ( const QgsLayoutTableColumn &col : qgis::as_const( mColumns ) ) + for ( const QgsLayoutTableColumn &col : std::as_const( mColumns ) ) { std::unique_ptr< QgsExpressionContextScope > headerCellScope = std::make_unique< QgsExpressionContextScope >(); headerCellScope->setVariable( QStringLiteral( "column_number" ), i + 1, true ); diff --git a/src/core/layout/qgslayoututils.cpp b/src/core/layout/qgslayoututils.cpp index 39979418296a..4e576b555b12 100644 --- a/src/core/layout/qgslayoututils.cpp +++ b/src/core/layout/qgslayoututils.cpp @@ -480,7 +480,7 @@ bool QgsLayoutUtils::itemIsAClippingSource( const QgsLayoutItem *item ) // current only maps can be clipped QList< QgsLayoutItemMap * > maps; item->layout()->layoutItems( maps ); - for ( QgsLayoutItemMap *map : qgis::as_const( maps ) ) + for ( QgsLayoutItemMap *map : std::as_const( maps ) ) { if ( map->itemClippingSettings()->isActive() && map->itemClippingSettings()->sourceItem() == item ) return true; diff --git a/src/core/layout/qgsreportsectionfieldgroup.cpp b/src/core/layout/qgsreportsectionfieldgroup.cpp index d70208c451a1..f39f7c34d610 100644 --- a/src/core/layout/qgsreportsectionfieldgroup.cpp +++ b/src/core/layout/qgsreportsectionfieldgroup.cpp @@ -294,7 +294,7 @@ void QgsReportSectionFieldGroup::updateChildContexts( const QgsFeature &feature c.fieldFilters = currentFilter; const QList< QgsAbstractReportSection * > sections = childSections(); - for ( QgsAbstractReportSection *section : qgis::as_const( sections ) ) + for ( QgsAbstractReportSection *section : std::as_const( sections ) ) { section->setContext( c ); } diff --git a/src/core/locator/qgslocator.cpp b/src/core/locator/qgslocator.cpp index 5596ba29bd2f..28ec0154e070 100644 --- a/src/core/locator/qgslocator.cpp +++ b/src/core/locator/qgslocator.cpp @@ -159,7 +159,7 @@ void QgsLocator::fetchResults( const QString &string, const QgsLocatorContext &c QString prefix = searchString.left( std::max( searchString.indexOf( ' ' ), 0 ) ); if ( !prefix.isEmpty() ) { - for ( QgsLocatorFilter *filter : qgis::as_const( mFilters ) ) + for ( QgsLocatorFilter *filter : std::as_const( mFilters ) ) { if ( filter->activePrefix().compare( prefix, Qt::CaseInsensitive ) == 0 && filter->enabled() ) { @@ -174,7 +174,7 @@ void QgsLocator::fetchResults( const QString &string, const QgsLocatorContext &c } else { - for ( QgsLocatorFilter *filter : qgis::as_const( mFilters ) ) + for ( QgsLocatorFilter *filter : std::as_const( mFilters ) ) { if ( filter->useWithoutPrefix() && filter->enabled() ) { @@ -184,7 +184,7 @@ void QgsLocator::fetchResults( const QString &string, const QgsLocatorContext &c } QList< QgsLocatorFilter *> threadedFilters; - for ( QgsLocatorFilter *filter : qgis::as_const( activeFilters ) ) + for ( QgsLocatorFilter *filter : std::as_const( activeFilters ) ) { filter->clearPreviousResults(); std::unique_ptr< QgsLocatorFilter > clone( filter->clone() ); @@ -215,7 +215,7 @@ void QgsLocator::fetchResults( const QString &string, const QgsLocatorContext &c } mActiveThreads.clear(); - for ( QgsLocatorFilter *filter : qgis::as_const( threadedFilters ) ) + for ( QgsLocatorFilter *filter : std::as_const( threadedFilters ) ) { QThread *thread = new QThread(); mActiveThreads.append( thread ); @@ -270,7 +270,7 @@ bool QgsLocator::isRunning() const void QgsLocator::clearPreviousResults() { - for ( QgsLocatorFilter *filter : qgis::as_const( mFilters ) ) + for ( QgsLocatorFilter *filter : std::as_const( mFilters ) ) { if ( filter->enabled() ) { diff --git a/src/core/mesh/qgsmeshtracerenderer.cpp b/src/core/mesh/qgsmeshtracerenderer.cpp index 8b3c59918c04..c5b832223ed2 100644 --- a/src/core/mesh/qgsmeshtracerenderer.cpp +++ b/src/core/mesh/qgsmeshtracerenderer.cpp @@ -406,14 +406,14 @@ void QgsMeshStreamField::addTracesOnMesh( const QgsTriangularMesh &mesh, const Q { QList facesInExtent = mesh.faceIndexesForRectangle( extent ); QSet vertices; - for ( auto f : qgis::as_const( facesInExtent ) ) + for ( auto f : std::as_const( facesInExtent ) ) { auto face = mesh.triangles().at( f ); - for ( auto i : qgis::as_const( face ) ) + for ( auto i : std::as_const( face ) ) vertices.insert( i ); } - for ( auto i : qgis::as_const( vertices ) ) + for ( auto i : std::as_const( vertices ) ) { addTrace( mesh.vertices().at( i ) ); } diff --git a/src/core/pal/feature.cpp b/src/core/pal/feature.cpp index 597c9c4c30cd..cfc36862e788 100644 --- a/src/core/pal/feature.cpp +++ b/src/core/pal/feature.cpp @@ -69,7 +69,7 @@ FeaturePart::FeaturePart( const FeaturePart &other ) : PointSet( other ) , mLF( other.mLF ) { - for ( const FeaturePart *hole : qgis::as_const( other.mHoles ) ) + for ( const FeaturePart *hole : std::as_const( other.mHoles ) ) { mHoles << new FeaturePart( *hole ); mHoles.last()->holeOf = this; diff --git a/src/core/pal/pal.cpp b/src/core/pal/pal.cpp index 6a865592e8f2..6ee5c9e56b21 100644 --- a/src/core/pal/pal.cpp +++ b/src/core/pal/pal.cpp @@ -156,7 +156,7 @@ std::unique_ptr Pal::extract( const QgsRectangle &extent, const QgsGeom QMutexLocker locker( &layer->mMutex ); // generate candidates for all features - for ( FeaturePart *featurePart : qgis::as_const( layer->mFeatureParts ) ) + for ( FeaturePart *featurePart : std::as_const( layer->mFeatureParts ) ) { if ( isCanceled() ) break; @@ -241,7 +241,7 @@ std::unique_ptr Pal::extract( const QgsRectangle &extent, const QgsGeom return nullptr; // collate all layer obstacles - for ( FeaturePart *obstaclePart : qgis::as_const( layer->mObstacleParts ) ) + for ( FeaturePart *obstaclePart : std::as_const( layer->mObstacleParts ) ) { if ( isCanceled() ) break; // do not continue searching diff --git a/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp b/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp index c432c8029d22..604dd897415f 100644 --- a/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp +++ b/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp @@ -197,7 +197,7 @@ QList QgsPointCloudAttributeByRampRenderer::creat QList< QPair< QString, QColor > > items; mColorRampShader.legendSymbologyItems( items ); res.reserve( items.size() ); - for ( const QPair< QString, QColor > &item : qgis::as_const( items ) ) + for ( const QPair< QString, QColor > &item : std::as_const( items ) ) { res << new QgsRasterSymbolLegendNode( nodeLayer, item.second, item.first ); } diff --git a/src/core/pointcloud/qgspointcloudclassifiedrenderer.cpp b/src/core/pointcloud/qgspointcloudclassifiedrenderer.cpp index 098324dae04a..078d81a683f4 100644 --- a/src/core/pointcloud/qgspointcloudclassifiedrenderer.cpp +++ b/src/core/pointcloud/qgspointcloudclassifiedrenderer.cpp @@ -83,7 +83,7 @@ void QgsPointCloudClassifiedRenderer::renderBlock( const QgsPointCloudBlock *blo const bool reproject = ct.isValid(); QHash< int, QColor > colors; - for ( const QgsPointCloudCategory &category : qgis::as_const( mCategories ) ) + for ( const QgsPointCloudCategory &category : std::as_const( mCategories ) ) { if ( !category.renderState() ) continue; @@ -142,7 +142,7 @@ bool QgsPointCloudClassifiedRenderer::willRenderPoint( const QVariantMap &pointA int attributeInt = pointAttributes[ mAttribute ].toInt( &parsedCorrectly ); if ( !parsedCorrectly ) return false; - for ( const QgsPointCloudCategory &category : qgis::as_const( mCategories ) ) + for ( const QgsPointCloudCategory &category : std::as_const( mCategories ) ) { if ( category.value() == attributeInt ) return category.renderState(); @@ -239,7 +239,7 @@ QList QgsPointCloudClassifiedRenderer::createLege { QList nodes; - for ( const QgsPointCloudCategory &category : qgis::as_const( mCategories ) ) + for ( const QgsPointCloudCategory &category : std::as_const( mCategories ) ) { nodes << new QgsRasterSymbolLegendNode( nodeLayer, category.color(), category.label(), nullptr, true, QString::number( category.value() ) ); } @@ -250,7 +250,7 @@ QList QgsPointCloudClassifiedRenderer::createLege QStringList QgsPointCloudClassifiedRenderer::legendRuleKeys() const { QStringList res; - for ( const QgsPointCloudCategory &category : qgis::as_const( mCategories ) ) + for ( const QgsPointCloudCategory &category : std::as_const( mCategories ) ) { res << QString::number( category.value() ); } @@ -264,7 +264,7 @@ bool QgsPointCloudClassifiedRenderer::legendItemChecked( const QString &key ) if ( !ok ) return false; - for ( const QgsPointCloudCategory &category : qgis::as_const( mCategories ) ) + for ( const QgsPointCloudCategory &category : std::as_const( mCategories ) ) { if ( category.value() == value ) return category.renderState(); diff --git a/src/core/pointcloud/qgspointcloudlayerrenderer.cpp b/src/core/pointcloud/qgspointcloudlayerrenderer.cpp index f2e7ec252b29..4e3833063473 100644 --- a/src/core/pointcloud/qgspointcloudlayerrenderer.cpp +++ b/src/core/pointcloud/qgspointcloudlayerrenderer.cpp @@ -121,7 +121,7 @@ bool QgsPointCloudLayerRenderer::render() if ( !context.renderContext().zRange().isInfinite() ) rendererAttributes.insert( QStringLiteral( "Z" ) ); - for ( const QString &attribute : qgis::as_const( rendererAttributes ) ) + for ( const QString &attribute : std::as_const( rendererAttributes ) ) { if ( mAttributes.indexOf( attribute ) >= 0 ) continue; // don't re-add attributes we are already going to fetch diff --git a/src/core/processing/models/qgsprocessingmodelalgorithm.cpp b/src/core/processing/models/qgsprocessingmodelalgorithm.cpp index c5d893bc7d4d..daab03b3c16e 100644 --- a/src/core/processing/models/qgsprocessingmodelalgorithm.cpp +++ b/src/core/processing/models/qgsprocessingmodelalgorithm.cpp @@ -293,7 +293,7 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa while ( executedAlg && executed.count() < toExecute.count() ) { executedAlg = false; - for ( const QString &childId : qgis::as_const( toExecute ) ) + for ( const QString &childId : std::as_const( toExecute ) ) { if ( feedback && feedback->isCanceled() ) break; @@ -398,7 +398,7 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa { // check if any dependent algorithms should be canceled based on the outputs of this algorithm run // first find all direct dependencies of this algorithm by looking through all remaining child algorithms - for ( const QString &candidateId : qgis::as_const( toExecute ) ) + for ( const QString &candidateId : std::as_const( toExecute ) ) { if ( executed.contains( candidateId ) ) continue; @@ -802,7 +802,7 @@ QStringList QgsProcessingModelAlgorithm::asPythonCode( const QgsProcessing::Pyth } bool found = false; - for ( const QString &line : qgis::as_const( lines ) ) + for ( const QString &line : std::as_const( lines ) ) { if ( line.contains( it.key() ) ) { @@ -865,7 +865,7 @@ QMap QgsProcessingMode << QgsProcessingOutputString::typeName() << QgsProcessingOutputBoolean::typeName() ); - for ( const QgsProcessingModelChildParameterSource &source : qgis::as_const( sources ) ) + for ( const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) ) { QString name; QVariant value; @@ -910,7 +910,7 @@ QMap QgsProcessingMode << QgsProcessingOutputRasterLayer::typeName() << QgsProcessingOutputMapLayer::typeName() ); - for ( const QgsProcessingModelChildParameterSource &source : qgis::as_const( sources ) ) + for ( const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) ) { QString name; QVariant value; @@ -969,7 +969,7 @@ QMap QgsProcessingMode sources = availableSourcesForChild( childId, QStringList() << QgsProcessingParameterFeatureSource::typeName() ); - for ( const QgsProcessingModelChildParameterSource &source : qgis::as_const( sources ) ) + for ( const QgsProcessingModelChildParameterSource &source : std::as_const( sources ) ) { QString name; QVariant value; @@ -1183,7 +1183,7 @@ bool QgsProcessingModelAlgorithm::validate( QStringList &issues ) const QStringList childIssues; res = validateChildAlgorithm( it->childId(), childIssues ) && res; - for ( const QString &issue : qgis::as_const( childIssues ) ) + for ( const QString &issue : std::as_const( childIssues ) ) { issues << QStringLiteral( "%1: %2" ).arg( it->description(), issue ); } @@ -1439,7 +1439,7 @@ bool QgsProcessingModelAlgorithm::loadVariant( const QVariant &model ) QSet< QString > loadedParams; // first add parameters respecting mParameterOrder - for ( const QString &name : qgis::as_const( mParameterOrder ) ) + for ( const QString &name : std::as_const( mParameterOrder ) ) { if ( paramDefMap.contains( name ) ) { diff --git a/src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp b/src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp index 7e88b644ab1b..75a7a162b720 100644 --- a/src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp +++ b/src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp @@ -260,7 +260,7 @@ QStringList QgsProcessingModelChildAlgorithm::asPythonCode( const QgsProcessing: lines << baseIndent + QStringLiteral( "alg_params = {" ); lines.reserve( lines.size() + paramParts.size() ); - for ( const QString &p : qgis::as_const( paramParts ) ) + for ( const QString &p : std::as_const( paramParts ) ) { lines << baseIndent + lineIndent + p + ','; } diff --git a/src/core/processing/qgsprocessingalgorithm.cpp b/src/core/processing/qgsprocessingalgorithm.cpp index 5e5f8fa7a3b4..f73ddc85ca73 100644 --- a/src/core/processing/qgsprocessingalgorithm.cpp +++ b/src/core/processing/qgsprocessingalgorithm.cpp @@ -137,7 +137,7 @@ void QgsProcessingAlgorithm::setProvider( QgsProcessingProvider *provider ) if ( mProvider && !mProvider->supportsNonFileBasedOutput() ) { // need to update all destination parameters to turn off non file based outputs - for ( const QgsProcessingParameterDefinition *definition : qgis::as_const( mParameters ) ) + for ( const QgsProcessingParameterDefinition *definition : std::as_const( mParameters ) ) { if ( definition->isDestination() ) { diff --git a/src/core/processing/qgsprocessingutils.cpp b/src/core/processing/qgsprocessingutils.cpp index 1584d8472c53..ac72c22fdf2f 100644 --- a/src/core/processing/qgsprocessingutils.cpp +++ b/src/core/processing/qgsprocessingutils.cpp @@ -203,17 +203,17 @@ QgsMapLayer *QgsProcessingUtils::mapLayerFromStore( const QString &string, QgsMa return true; }; - for ( QgsMapLayer *l : qgis::as_const( layers ) ) + for ( QgsMapLayer *l : std::as_const( layers ) ) { if ( isCompatibleType( l ) && l->id() == string ) return l; } - for ( QgsMapLayer *l : qgis::as_const( layers ) ) + for ( QgsMapLayer *l : std::as_const( layers ) ) { if ( isCompatibleType( l ) && l->name() == string ) return l; } - for ( QgsMapLayer *l : qgis::as_const( layers ) ) + for ( QgsMapLayer *l : std::as_const( layers ) ) { if ( isCompatibleType( l ) && normalizeLayerSource( l->source() ) == normalizeLayerSource( string ) ) return l; diff --git a/src/core/project/qgsprojectproperty.cpp b/src/core/project/qgsprojectproperty.cpp index 0728cf356160..bc27b51d8c55 100644 --- a/src/core/project/qgsprojectproperty.cpp +++ b/src/core/project/qgsprojectproperty.cpp @@ -411,7 +411,7 @@ bool QgsProjectPropertyKey::writeXml( QString const &nodeName, QDomElement &elem auto keys = mProperties.keys(); std::sort( keys.begin(), keys.end() ); - for ( const auto &key : qgis::as_const( keys ) ) + for ( const auto &key : std::as_const( keys ) ) { if ( !mProperties.value( key )->writeXml( key, keyElement, document ) ) QgsMessageLog::logMessage( tr( "Failed to save project property %1" ).arg( key ) ); diff --git a/src/core/providers/arcgis/qgsarcgisrestutils.cpp b/src/core/providers/arcgis/qgsarcgisrestutils.cpp index e2056c956224..9024c431d24a 100644 --- a/src/core/providers/arcgis/qgsarcgisrestutils.cpp +++ b/src/core/providers/arcgis/qgsarcgisrestutils.cpp @@ -237,7 +237,7 @@ std::unique_ptr< QgsMultiCurve > QgsArcGisRestUtils::convertGeometryPolyline( co return nullptr; std::unique_ptr< QgsMultiCurve > multiCurve = std::make_unique< QgsMultiCurve >(); multiCurve->reserve( pathsList.size() ); - for ( const QVariant &pathData : qgis::as_const( pathsList ) ) + for ( const QVariant &pathData : std::as_const( pathsList ) ) { std::unique_ptr< QgsCompoundCurve > curve = convertCompoundCurve( pathData.toList(), pointType ); if ( !curve ) diff --git a/src/core/providers/gdal/qgsgdalprovider.cpp b/src/core/providers/gdal/qgsgdalprovider.cpp index b6dad129615b..bbfbbe43dfe4 100644 --- a/src/core/providers/gdal/qgsgdalprovider.cpp +++ b/src/core/providers/gdal/qgsgdalprovider.cpp @@ -2533,7 +2533,7 @@ void buildSupportedRasterFileFilterAndExtensions( QString &fileFiltersString, QS // can't forget the all supported case QStringList exts; - for ( const QString &ext : qgis::as_const( extensions ) ) + for ( const QString &ext : std::as_const( extensions ) ) exts << QStringLiteral( "*.%1 *.%2" ).arg( ext, ext.toUpper() ); fileFiltersString.prepend( QObject::tr( "All supported files" ) + QStringLiteral( " (%1);;" ).arg( exts.join( QLatin1Char( ' ' ) ) ) ); diff --git a/src/core/providers/ogr/qgsgeopackageproviderconnection.cpp b/src/core/providers/ogr/qgsgeopackageproviderconnection.cpp index 2e80ac727b50..0e547df3342d 100644 --- a/src/core/providers/ogr/qgsgeopackageproviderconnection.cpp +++ b/src/core/providers/ogr/qgsgeopackageproviderconnection.cpp @@ -221,7 +221,7 @@ bool QgsGeoPackageProviderConnection::spatialIndexExists( const QString &schema, QgsMessageLog::logMessage( QStringLiteral( "Schema is not supported by GPKG, ignoring" ), QStringLiteral( "OGR" ), Qgis::Info ); } const auto res { executeGdalSqlPrivate( QStringLiteral( "SELECT HasSpatialIndex(%1, %2)" ).arg( QgsSqliteUtils::quotedString( name ), - QgsSqliteUtils::quotedString( geometryColumn ) ) ).rows() }; + QgsSqliteUtils::quotedString( geometryColumn ) ) ).rows() }; return !res.isEmpty() && !res.at( 0 ).isEmpty() && res.at( 0 ).at( 0 ).toBool(); } @@ -256,11 +256,11 @@ QList QgsGeoPackageProviderConne try { const QString sql { QStringLiteral( "SELECT c.table_name, data_type, description, c.srs_id, g.geometry_type_name, g.column_name " - "FROM gpkg_contents c LEFT JOIN gpkg_geometry_columns g ON (c.table_name = g.table_name) " - "WHERE c.table_name NOT IN (%1)" ).arg( excludedTableNames.join( ',' ) ) }; + "FROM gpkg_contents c LEFT JOIN gpkg_geometry_columns g ON (c.table_name = g.table_name) " + "WHERE c.table_name NOT IN (%1)" ).arg( excludedTableNames.join( ',' ) ) }; results = executeSql( sql ); - for ( const auto &row : qgis::as_const( results ) ) + for ( const auto &row : std::as_const( results ) ) { if ( row.size() != 6 ) @@ -398,7 +398,7 @@ QgsAbstractDatabaseProviderConnection::QueryResult QgsGeoPackageProviderConnecti QgsFields fields { QgsOgrUtils::readOgrFields( fet.get(), QTextCodec::codecForName( "UTF-8" ) ) }; iterator->setFields( fields ); - for ( const auto &f : qgis::as_const( fields ) ) + for ( const auto &f : std::as_const( fields ) ) { results.appendColumn( f.name() ); } @@ -491,8 +491,8 @@ QList QgsGeoPackageProviderConnection::native if ( ! vl.isValid() || ! vl.dataProvider() ) { const QString errorCause { vl.dataProvider() &&vl.dataProvider()->hasErrors() ? - vl.dataProvider()->errors().join( '\n' ) : - QObject::tr( "unknown error" ) }; + vl.dataProvider()->errors().join( '\n' ) : + QObject::tr( "unknown error" ) }; throw QgsProviderConnectionException( QObject::tr( "Error retrieving native types for %1: %2" ).arg( uri(), errorCause ) ); } return vl.dataProvider()->nativeTypes(); diff --git a/src/core/providers/ogr/qgsogrprovider.cpp b/src/core/providers/ogr/qgsogrprovider.cpp index 186fba5f65d4..84b6c55ad052 100644 --- a/src/core/providers/ogr/qgsogrprovider.cpp +++ b/src/core/providers/ogr/qgsogrprovider.cpp @@ -444,7 +444,7 @@ QgsVectorLayerExporter::ExportError QgsOgrProvider::createEmptyLayer( const QStr // At this point we must check if there is a real FID field in the the fields argument, // because in that case we don't want to shift all fields (see issue GH #34333) // Check for unique values should be performed in client code. - for ( const auto &f : qgis::as_const( fields ) ) + for ( const auto &f : std::as_const( fields ) ) { if ( f.name().compare( ogrFidColumnName, Qt::CaseSensitivity::CaseInsensitive ) == 0 ) { @@ -3517,7 +3517,7 @@ QString createFilters( const QString &type ) // can't forget the all supported case QStringList exts; - for ( const QString &ext : qgis::as_const( sExtensions ) ) + for ( const QString &ext : std::as_const( sExtensions ) ) exts << QStringLiteral( "*.%1 *.%2" ).arg( ext, ext.toUpper() ); sFileFilters.prepend( QObject::tr( "All supported files" ) + QStringLiteral( " (%1);;" ).arg( exts.join( QLatin1Char( ' ' ) ) ) ); diff --git a/src/core/qgis.h b/src/core/qgis.h index 507c419c3e21..33d3f3fc3715 100644 --- a/src/core/qgis.h +++ b/src/core/qgis.h @@ -384,23 +384,6 @@ inline double qgsRound( double number, int places ) */ namespace qgis { - // as_const - - /** - * Adds const to non-const objects. - * - * To be used as a proxy for std::as_const until we target c++17 minimum. - * - * \note not available in Python bindings - * \since QGIS 3.0 - */ - template struct QgsAddConst { typedef const T Type; }; - - template - constexpr typename QgsAddConst::Type &as_const( T &t ) noexcept { return t; } - - template - void as_const( const T && ) = delete; /** * Used for new-style Qt connects to overloaded signals, avoiding the usual horrible connect syntax required diff --git a/src/core/qgsabstractdatabaseproviderconnection.cpp b/src/core/qgsabstractdatabaseproviderconnection.cpp index 4e01d682bdcf..abd401e95827 100644 --- a/src/core/qgsabstractdatabaseproviderconnection.cpp +++ b/src/core/qgsabstractdatabaseproviderconnection.cpp @@ -267,7 +267,7 @@ void QgsAbstractDatabaseProviderConnection::TableProperty::addGeometryColumnType { // Do not add the type if it's already present const QgsAbstractDatabaseProviderConnection::TableProperty::GeometryColumnType toAdd { type, crs }; - for ( const auto &t : qgis::as_const( mGeometryColumnTypes ) ) + for ( const auto &t : std::as_const( mGeometryColumnTypes ) ) { if ( t == toAdd ) { @@ -330,7 +330,7 @@ void QgsAbstractDatabaseProviderConnection::TableProperty::setFlag( const QgsAbs int QgsAbstractDatabaseProviderConnection::TableProperty::maxCoordinateDimensions() const { int res = 0; - for ( const TableProperty::GeometryColumnType &ct : qgis::as_const( mGeometryColumnTypes ) ) + for ( const TableProperty::GeometryColumnType &ct : std::as_const( mGeometryColumnTypes ) ) { res = std::max( res, QgsWkbTypes::coordDimensions( ct.wkbType ) ); } @@ -399,7 +399,7 @@ void QgsAbstractDatabaseProviderConnection::TableProperty::setFlags( const QgsAb QList QgsAbstractDatabaseProviderConnection::TableProperty::crsList() const { QList crss; - for ( const auto &t : qgis::as_const( mGeometryColumnTypes ) ) + for ( const auto &t : std::as_const( mGeometryColumnTypes ) ) { crss.push_back( t.crs ); } diff --git a/src/core/qgsabstractgeopdfexporter.cpp b/src/core/qgsabstractgeopdfexporter.cpp index 13a1eff928dd..511bb2b660cf 100644 --- a/src/core/qgsabstractgeopdfexporter.cpp +++ b/src/core/qgsabstractgeopdfexporter.cpp @@ -277,7 +277,7 @@ QString QgsAbstractGeoPdfExporter::createCompositionXml( const QListdataProvider() ) { @@ -177,7 +177,7 @@ QList QgsActionManager::actions( const QString &actionScope ) const { QList actions; - for ( const QgsAction &action : qgis::as_const( mActions ) ) + for ( const QgsAction &action : std::as_const( mActions ) ) { if ( action.actionScopes().contains( actionScope ) ) actions.append( action ); @@ -232,7 +232,7 @@ bool QgsActionManager::writeXml( QDomNode &layer_node ) const aActions.appendChild( defaultActionElement ); } - for ( const QgsAction &action : qgis::as_const( mActions ) ) + for ( const QgsAction &action : std::as_const( mActions ) ) { action.writeXml( aActions ); } @@ -270,7 +270,7 @@ bool QgsActionManager::readXml( const QDomNode &layer_node ) QgsAction QgsActionManager::action( QUuid id ) { - for ( const QgsAction &action : qgis::as_const( mActions ) ) + for ( const QgsAction &action : std::as_const( mActions ) ) { if ( action.id() == id ) return action; diff --git a/src/core/qgsapplication.cpp b/src/core/qgsapplication.cpp index a8a7dec3c606..d519c968c838 100644 --- a/src/core/qgsapplication.cpp +++ b/src/core/qgsapplication.cpp @@ -1084,7 +1084,7 @@ QStringList QgsApplication::svgPaths() if ( !paths.contains( path ) ) paths.append( path ); } - for ( const QString &path : qgis::as_const( *sDefaultSvgPaths() ) ) + for ( const QString &path : std::as_const( *sDefaultSvgPaths() ) ) { if ( !paths.contains( path ) ) paths.append( path ); diff --git a/src/core/qgsbookmarkmanager.cpp b/src/core/qgsbookmarkmanager.cpp index 995a6bbb120b..b294426f26a9 100644 --- a/src/core/qgsbookmarkmanager.cpp +++ b/src/core/qgsbookmarkmanager.cpp @@ -134,7 +134,7 @@ QString QgsBookmarkManager::addBookmark( const QgsBookmark &b, bool *ok ) else { // check for duplicate ID - for ( const QgsBookmark &b : qgis::as_const( mBookmarks ) ) + for ( const QgsBookmark &b : std::as_const( mBookmarks ) ) { if ( b.id() == bookmark.id() ) { @@ -167,7 +167,7 @@ bool QgsBookmarkManager::removeBookmark( const QString &id ) QString group; int pos = -1; int i = 0; - for ( const QgsBookmark &b : qgis::as_const( mBookmarks ) ) + for ( const QgsBookmark &b : std::as_const( mBookmarks ) ) { if ( b.id() == id ) { @@ -198,7 +198,7 @@ bool QgsBookmarkManager::updateBookmark( const QgsBookmark &bookmark ) { // check for duplicate ID int i = 0; - for ( const QgsBookmark &b : qgis::as_const( mBookmarks ) ) + for ( const QgsBookmark &b : std::as_const( mBookmarks ) ) { if ( b.id() == bookmark.id() ) { diff --git a/src/core/qgsbrowsermodel.cpp b/src/core/qgsbrowsermodel.cpp index a1c0886e44b5..3a11e8184ffa 100644 --- a/src/core/qgsbrowsermodel.cpp +++ b/src/core/qgsbrowsermodel.cpp @@ -202,7 +202,7 @@ void QgsBrowserModel::dataItemProviderWillBeRemoved( QgsDataItemProvider *provid void QgsBrowserModel::onConnectionsChanged( const QString &providerKey ) { // refresh the matching provider - for ( QgsDataItem *item : qgis::as_const( mRootItems ) ) + for ( QgsDataItem *item : std::as_const( mRootItems ) ) { if ( item->providerKey() == providerKey ) { @@ -634,7 +634,7 @@ QMimeData *QgsBrowserModel::mimeData( const QModelIndexList &indexes ) const { QgsDataItem *ptr = reinterpret_cast< QgsDataItem * >( index.internalPointer() ); const QgsMimeDataUtils::UriList uris = ptr->mimeUris(); - for ( const auto &uri : qgis::as_const( uris ) ) + for ( const auto &uri : std::as_const( uris ) ) { lst.append( uri ); } diff --git a/src/core/qgsconnectionpool.h b/src/core/qgsconnectionpool.h index 9b6380ae3dd5..02bd808a9299 100644 --- a/src/core/qgsconnectionpool.h +++ b/src/core/qgsconnectionpool.h @@ -76,7 +76,7 @@ class QgsConnectionPoolGroup ~QgsConnectionPoolGroup() { - for ( const Item &item : qgis::as_const( conns ) ) + for ( const Item &item : std::as_const( conns ) ) { qgsConnectionPool_ConnectionDestroy( item.c ); } @@ -185,12 +185,12 @@ class QgsConnectionPoolGroup void invalidateConnections() { connMutex.lock(); - for ( const Item &i : qgis::as_const( conns ) ) + for ( const Item &i : std::as_const( conns ) ) { qgsConnectionPool_ConnectionDestroy( i.c ); } conns.clear(); - for ( T c : qgis::as_const( acquiredConns ) ) + for ( T c : std::as_const( acquiredConns ) ) qgsConnectionPool_InvalidateConnection( c ); connMutex.unlock(); } @@ -275,7 +275,7 @@ class QgsConnectionPool virtual ~QgsConnectionPool() { mMutex.lock(); - for ( T_Group *group : qgis::as_const( mGroups ) ) + for ( T_Group *group : std::as_const( mGroups ) ) { delete group; } diff --git a/src/core/qgscoordinatereferencesystem.cpp b/src/core/qgscoordinatereferencesystem.cpp index 56af02efbc39..13713ae6457c 100644 --- a/src/core/qgscoordinatereferencesystem.cpp +++ b/src/core/qgscoordinatereferencesystem.cpp @@ -2515,7 +2515,7 @@ void QgsCoordinateReferenceSystem::pushRecentCoordinateReferenceSystem( const Qg proj.reserve( recent.size() ); QStringList wkt; wkt.reserve( recent.size() ); - for ( const QgsCoordinateReferenceSystem &c : qgis::as_const( recent ) ) + for ( const QgsCoordinateReferenceSystem &c : std::as_const( recent ) ) { authids << c.authid(); proj << c.toProj(); diff --git a/src/core/qgsdatadefinedsizelegend.cpp b/src/core/qgsdatadefinedsizelegend.cpp index 340c6c82719c..0bf08f31d720 100644 --- a/src/core/qgsdatadefinedsizelegend.cpp +++ b/src/core/qgsdatadefinedsizelegend.cpp @@ -209,7 +209,7 @@ void QgsDataDefinedSizeLegend::drawCollapsedLegend( QgsRenderContext &context, Q // find out how wide the text will be double maxTextWidth = 0; - for ( const SizeClass &c : qgis::as_const( classes ) ) + for ( const SizeClass &c : std::as_const( classes ) ) { maxTextWidth = std::max( maxTextWidth, fm.boundingRect( c.label ).width() ); } @@ -222,7 +222,7 @@ void QgsDataDefinedSizeLegend::drawCollapsedLegend( QgsRenderContext &context, Q // find out top Y coordinate for individual symbol sizes QList symbolTopY; - for ( const SizeClass &c : qgis::as_const( classes ) ) + for ( const SizeClass &c : std::as_const( classes ) ) { double outputSymbolSize = context.convertToPainterUnits( c.size, s->sizeUnit(), s->sizeMapUnitScale() ); switch ( mVAlign ) @@ -275,7 +275,7 @@ void QgsDataDefinedSizeLegend::drawCollapsedLegend( QgsRenderContext &context, Q p->translate( 0, -textTopY ); // draw symbols first so that they do not cover - for ( const SizeClass &c : qgis::as_const( classes ) ) + for ( const SizeClass &c : std::as_const( classes ) ) { s->setSize( c.size ); @@ -304,7 +304,7 @@ void QgsDataDefinedSizeLegend::drawCollapsedLegend( QgsRenderContext &context, Q } int i = 0; - for ( const SizeClass &c : qgis::as_const( classes ) ) + for ( const SizeClass &c : std::as_const( classes ) ) { // line from symbol to the text if ( mLineSymbol ) @@ -461,7 +461,7 @@ void QgsDataDefinedSizeLegend::writeXml( QDomElement &elem, const QgsReadWriteCo if ( !mSizeClasses.isEmpty() ) { QDomElement elemClasses = doc.createElement( QStringLiteral( "classes" ) ); - for ( const SizeClass &sc : qgis::as_const( mSizeClasses ) ) + for ( const SizeClass &sc : std::as_const( mSizeClasses ) ) { QDomElement elemClass = doc.createElement( QStringLiteral( "class" ) ); elemClass.setAttribute( QStringLiteral( "size" ), sc.size ); diff --git a/src/core/qgsdataitemproviderregistry.cpp b/src/core/qgsdataitemproviderregistry.cpp index 65736be3f7fb..133a944fea75 100644 --- a/src/core/qgsdataitemproviderregistry.cpp +++ b/src/core/qgsdataitemproviderregistry.cpp @@ -30,7 +30,7 @@ QgsDataItemProviderRegistry::QgsDataItemProviderRegistry() { QList providerList = QgsProviderRegistry::instance()->dataItemProviders( key ); mProviders << providerList; - for ( const auto &p : qgis::as_const( providerList ) ) + for ( const auto &p : std::as_const( providerList ) ) { if ( ! p->dataProviderKey().isEmpty() ) { @@ -49,7 +49,7 @@ QList QgsDataItemProviderRegistry::providers() const { re QgsDataItemProvider *QgsDataItemProviderRegistry::provider( const QString &providerName ) const { - for ( const auto &p : qgis::as_const( mProviders ) ) + for ( const auto &p : std::as_const( mProviders ) ) { if ( p->name() == providerName ) { diff --git a/src/core/qgsdatumtransform.cpp b/src/core/qgsdatumtransform.cpp index 0a9505661871..a93757693f71 100644 --- a/src/core/qgsdatumtransform.cpp +++ b/src/core/qgsdatumtransform.cpp @@ -104,20 +104,20 @@ QList< QgsDatumTransform::TransformPair > QgsDatumTransform::datumTransformation destToWgs84 ); //add direct datum transformations - for ( int transform : qgis::as_const( directTransforms ) ) + for ( int transform : std::as_const( directTransforms ) ) { transformations.push_back( QgsDatumTransform::TransformPair( transform, -1 ) ); } //add direct datum transformations - for ( int transform : qgis::as_const( reverseDirectTransforms ) ) + for ( int transform : std::as_const( reverseDirectTransforms ) ) { transformations.push_back( QgsDatumTransform::TransformPair( -1, transform ) ); } - for ( int srcTransform : qgis::as_const( srcToWgs84 ) ) + for ( int srcTransform : std::as_const( srcToWgs84 ) ) { - for ( int destTransform : qgis::as_const( destToWgs84 ) ) + for ( int destTransform : std::as_const( destToWgs84 ) ) { transformations.push_back( QgsDatumTransform::TransformPair( srcTransform, destTransform ) ); } diff --git a/src/core/qgsexpressioncontext.cpp b/src/core/qgsexpressioncontext.cpp index 07b85a867789..be4d09759b4d 100644 --- a/src/core/qgsexpressioncontext.cpp +++ b/src/core/qgsexpressioncontext.cpp @@ -234,7 +234,7 @@ QgsExpressionContext::QgsExpressionContext( const QListsetFeature( indexedFeatureToAppend.mFeature ); int i = 0; - for ( const QgsFeatureRequest::OrderByClause &orderBy : qgis::as_const( mPreparedOrderBys ) ) + for ( const QgsFeatureRequest::OrderByClause &orderBy : std::as_const( mPreparedOrderBys ) ) { indexedFeatureToAppend.mIndexes.replace( i++, orderBy.expression().evaluate( expressionContext ) ); } @@ -164,7 +164,7 @@ class QgsExpressionSorter features.clear(); - for ( const QgsIndexedFeature &indexedFeature : qgis::as_const( indexedFeatures ) ) + for ( const QgsIndexedFeature &indexedFeature : std::as_const( indexedFeatures ) ) features.append( indexedFeature.mFeature ); } diff --git a/src/core/qgsfeature.cpp b/src/core/qgsfeature.cpp index de86e1bf98ca..1665ebb4b4d1 100644 --- a/src/core/qgsfeature.cpp +++ b/src/core/qgsfeature.cpp @@ -351,7 +351,7 @@ int QgsFeature::approximateMemoryUsage() const size_t s = sizeof( *this ) + sizeof( *d ); // Attributes - for ( const QVariant &attr : qgis::as_const( d->attributes ) ) + for ( const QVariant &attr : std::as_const( d->attributes ) ) { s += qgsQVariantApproximateMemoryUsage( attr ); } diff --git a/src/core/qgsfeatureexpressionvaluesgatherer.h b/src/core/qgsfeatureexpressionvaluesgatherer.h index 07af32c96cbf..3bf4f9991fac 100644 --- a/src/core/qgsfeatureexpressionvaluesgatherer.h +++ b/src/core/qgsfeatureexpressionvaluesgatherer.h @@ -97,7 +97,7 @@ class QgsFeatureExpressionValuesGatherer: public QThread QgsFeature feature; QList attributeIndexes; - for ( const QString &fieldName : qgis::as_const( mIdentifierFields ) ) + for ( const QString &fieldName : std::as_const( mIdentifierFields ) ) attributeIndexes << mSource->fields().indexOf( fieldName ); while ( iterator.nextFeature( feature ) ) diff --git a/src/core/qgsfileutils.cpp b/src/core/qgsfileutils.cpp index 170b9a74df10..5835fa10d6f1 100644 --- a/src/core/qgsfileutils.cpp +++ b/src/core/qgsfileutils.cpp @@ -97,7 +97,7 @@ QString QgsFileUtils::ensureFileNameHasExtension( const QString &f, const QStrin QString fileName = f; bool hasExt = false; - for ( const QString &extension : qgis::as_const( extensions ) ) + for ( const QString &extension : std::as_const( extensions ) ) { const QString extWithDot = extension.startsWith( '.' ) ? extension : '.' + extension; if ( fileName.endsWith( extWithDot, Qt::CaseInsensitive ) ) diff --git a/src/core/qgsjsonutils.cpp b/src/core/qgsjsonutils.cpp index 57410ed80322..cbeb113a48a1 100644 --- a/src/core/qgsjsonutils.cpp +++ b/src/core/qgsjsonutils.cpp @@ -195,7 +195,7 @@ json QgsJsonExporter::exportFeatureToJsonObject( const QgsFeature &feature, cons if ( mLayer && mIncludeRelatedAttributes ) { QList< QgsRelation > relations = QgsProject::instance()->relationManager()->referencedRelations( mLayer.data() ); - for ( const auto &relation : qgis::as_const( relations ) ) + for ( const auto &relation : std::as_const( relations ) ) { QgsFeatureRequest req = relation.getRelatedFeaturesRequest( feature ); req.setFlags( QgsFeatureRequest::NoGeometry ); @@ -241,7 +241,7 @@ json QgsJsonExporter::exportFeaturesToJsonObject( const QgsFeatureList &features { "type", "FeatureCollection" }, { "features", json::array() } }; - for ( const QgsFeature &feature : qgis::as_const( features ) ) + for ( const QgsFeature &feature : std::as_const( features ) ) { data["features"].push_back( exportFeatureToJsonObject( feature ) ); } diff --git a/src/core/qgslegendrenderer.cpp b/src/core/qgslegendrenderer.cpp index 943257106dcc..bbe488a212f7 100644 --- a/src/core/qgslegendrenderer.cpp +++ b/src/core/qgslegendrenderer.cpp @@ -169,7 +169,7 @@ QSizeF QgsLegendRenderer::paintAndDetermineSize( QgsRenderContext &context ) // until now. BUUUUUUUUUUUUT. Because everything sucks, we can't even start the actual render of items // at the same time we calculate this -- legend items REQUIRE the REAL width of the columns in order to // correctly align right or center-aligned symbols/text. Bah -- A triple iteration it is! - for ( const LegendComponentGroup &group : qgis::as_const( componentGroups ) ) + for ( const LegendComponentGroup &group : std::as_const( componentGroups ) ) { const QSizeF actualSize = drawGroup( group, context, ColumnContext() ); maxEqualColumnWidth = std::max( actualSize.width(), maxEqualColumnWidth ); @@ -200,7 +200,7 @@ QSizeF QgsLegendRenderer::paintAndDetermineSize( QgsRenderContext &context ) columnContext.right = std::max( mLegendSize.width() - mSettings.boxSpace(), mSettings.boxSpace() ); double currentY = columnTop; - for ( const LegendComponentGroup &group : qgis::as_const( componentGroups ) ) + for ( const LegendComponentGroup &group : std::as_const( componentGroups ) ) { if ( group.column > column ) { @@ -443,7 +443,7 @@ int QgsLegendRenderer::setColumns( QList &componentGroups qreal maxGroupHeight = 0; int forcedColumnBreaks = 0; double totalSpaceAboveGroups = 0; - for ( const LegendComponentGroup &group : qgis::as_const( componentGroups ) ) + for ( const LegendComponentGroup &group : std::as_const( componentGroups ) ) { totalHeight += spaceAboveGroup( group ); totalSpaceAboveGroups += spaceAboveGroup( group ); @@ -649,7 +649,7 @@ QSizeF QgsLegendRenderer::drawGroup( const LegendComponentGroup &group, QgsRende bool first = true; QSizeF size = QSizeF( group.size ); double currentY = top; - for ( const LegendComponent &component : qgis::as_const( group.components ) ) + for ( const LegendComponent &component : std::as_const( group.components ) ) { if ( QgsLayerTreeGroup *groupItem = qobject_cast( component.item ) ) { diff --git a/src/core/qgslocalizeddatapathregistry.cpp b/src/core/qgslocalizeddatapathregistry.cpp index a1668519c905..e2749881f5ed 100644 --- a/src/core/qgslocalizeddatapathregistry.cpp +++ b/src/core/qgslocalizeddatapathregistry.cpp @@ -30,7 +30,7 @@ QString QgsLocalizedDataPathRegistry::globalPath( const QString &relativePath ) { QgsReadWriteLocker locker( mLock, QgsReadWriteLocker::Read ); - for ( const QDir &basePath : qgis::as_const( mPaths ) ) + for ( const QDir &basePath : std::as_const( mPaths ) ) if ( basePath.exists( relativePath ) ) return basePath.absoluteFilePath( relativePath ); @@ -41,7 +41,7 @@ QString QgsLocalizedDataPathRegistry::localizedPath( const QString &fullPath ) c { QgsReadWriteLocker locker( mLock, QgsReadWriteLocker::Read ); - for ( const QDir &basePath : qgis::as_const( mPaths ) ) + for ( const QDir &basePath : std::as_const( mPaths ) ) if ( fullPath.startsWith( basePath.absolutePath() ) ) return basePath.relativeFilePath( fullPath ); diff --git a/src/core/qgsmaplayermodel.cpp b/src/core/qgsmaplayermodel.cpp index e922320e8b57..74776150c783 100644 --- a/src/core/qgsmaplayermodel.cpp +++ b/src/core/qgsmaplayermodel.cpp @@ -493,7 +493,7 @@ bool QgsMapLayerModel::dropMimeData( const QMimeData *data, Qt::DropAction actio } insertRows( row, rows, QModelIndex() ); - for ( const QString &text : qgis::as_const( newItems ) ) + for ( const QString &text : std::as_const( newItems ) ) { QModelIndex idx = index( row, 0, QModelIndex() ); setData( idx, text, LayerIdRole ); diff --git a/src/core/qgsmaplayerref.h b/src/core/qgsmaplayerref.h index 24b8e4ad00dc..bd55941d47a0 100644 --- a/src/core/qgsmaplayerref.h +++ b/src/core/qgsmaplayerref.h @@ -229,7 +229,7 @@ struct _LayerRef { layers = project->mapLayers().values(); } - for ( QgsMapLayer *l : qgis::as_const( layers ) ) + for ( QgsMapLayer *l : std::as_const( layers ) ) { if ( TYPE *tl = qobject_cast< TYPE *>( l ) ) { diff --git a/src/core/qgsmaprenderercache.cpp b/src/core/qgsmaprenderercache.cpp index cb95a7d14c88..8f102d375961 100644 --- a/src/core/qgsmaprenderercache.cpp +++ b/src/core/qgsmaprenderercache.cpp @@ -40,7 +40,7 @@ void QgsMapRendererCache::clearInternal() mScale = 0; // make sure we are disconnected from all layers - for ( const QgsWeakMapLayerPointer &layer : qgis::as_const( mConnectedLayers ) ) + for ( const QgsWeakMapLayerPointer &layer : std::as_const( mConnectedLayers ) ) { if ( layer.data() ) { diff --git a/src/core/qgsmapthemecollection.cpp b/src/core/qgsmapthemecollection.cpp index d244c2444ebf..c95f2b6c64fd 100644 --- a/src/core/qgsmapthemecollection.cpp +++ b/src/core/qgsmapthemecollection.cpp @@ -111,7 +111,7 @@ QgsMapThemeCollection::MapThemeRecord QgsMapThemeCollection::createThemeFromCurr bool QgsMapThemeCollection::findRecordForLayer( QgsMapLayer *layer, const QgsMapThemeCollection::MapThemeRecord &rec, QgsMapThemeCollection::MapThemeLayerRecord &layerRec ) { - for ( const QgsMapThemeCollection::MapThemeLayerRecord &lr : qgis::as_const( rec.mLayerRecords ) ) + for ( const QgsMapThemeCollection::MapThemeLayerRecord &lr : std::as_const( rec.mLayerRecords ) ) { if ( lr.layer() == layer ) { @@ -418,9 +418,9 @@ void QgsMapThemeCollection::reconnectToLayersStyleManager() // disconnect( 0, 0, this, SLOT( layerStyleRenamed( QString, QString ) ) ); QSet layers; - for ( const MapThemeRecord &rec : qgis::as_const( mMapThemes ) ) + for ( const MapThemeRecord &rec : std::as_const( mMapThemes ) ) { - for ( const MapThemeLayerRecord &layerRec : qgis::as_const( rec.mLayerRecords ) ) + for ( const MapThemeLayerRecord &layerRec : std::as_const( rec.mLayerRecords ) ) { if ( auto *lLayer = layerRec.layer() ) layers << lLayer; @@ -575,7 +575,7 @@ void QgsMapThemeCollection::writeXml( QDomDocument &doc ) std::sort( keys.begin(), keys.end() ); - for ( const QString &grpName : qgis::as_const( keys ) ) + for ( const QString &grpName : std::as_const( keys ) ) { const MapThemeRecord &rec = mMapThemes.value( grpName ); QDomElement visPresetElem = doc.createElement( QStringLiteral( "visibility-preset" ) ); @@ -584,7 +584,7 @@ void QgsMapThemeCollection::writeXml( QDomDocument &doc ) visPresetElem.setAttribute( QStringLiteral( "has-expanded-info" ), QStringLiteral( "1" ) ); if ( rec.hasCheckedStateInfo() ) visPresetElem.setAttribute( QStringLiteral( "has-checked-group-info" ), QStringLiteral( "1" ) ); - for ( const MapThemeLayerRecord &layerRec : qgis::as_const( rec.mLayerRecords ) ) + for ( const MapThemeLayerRecord &layerRec : std::as_const( rec.mLayerRecords ) ) { if ( !layerRec.layer() ) continue; @@ -600,7 +600,7 @@ void QgsMapThemeCollection::writeXml( QDomDocument &doc ) { QDomElement checkedLegendNodesElem = doc.createElement( QStringLiteral( "checked-legend-nodes" ) ); checkedLegendNodesElem.setAttribute( QStringLiteral( "id" ), layerID ); - for ( const QString &checkedLegendNode : qgis::as_const( layerRec.checkedLegendItems ) ) + for ( const QString &checkedLegendNode : std::as_const( layerRec.checkedLegendItems ) ) { QDomElement checkedLegendNodeElem = doc.createElement( QStringLiteral( "checked-legend-node" ) ); checkedLegendNodeElem.setAttribute( QStringLiteral( "id" ), checkedLegendNode ); @@ -615,7 +615,7 @@ void QgsMapThemeCollection::writeXml( QDomDocument &doc ) QDomElement expandedLegendNodesElem = doc.createElement( QStringLiteral( "expanded-legend-nodes" ) ); expandedLegendNodesElem.setAttribute( QStringLiteral( "id" ), layerID ); - for ( const QString &expandedLegendNode : qgis::as_const( layerRec.expandedLegendItems ) ) + for ( const QString &expandedLegendNode : std::as_const( layerRec.expandedLegendItems ) ) { QDomElement expandedLegendNodeElem = doc.createElement( QStringLiteral( "expanded-legend-node" ) ); expandedLegendNodeElem.setAttribute( QStringLiteral( "id" ), expandedLegendNode ); @@ -677,7 +677,7 @@ void QgsMapThemeCollection::registryLayersRemoved( const QStringList &layerIDs ) } } - for ( const QString &theme : qgis::as_const( changedThemes ) ) + for ( const QString &theme : std::as_const( changedThemes ) ) { emit mapThemeChanged( theme ); } @@ -710,7 +710,7 @@ void QgsMapThemeCollection::layerStyleRenamed( const QString &oldName, const QSt } } - for ( const QString &theme : qgis::as_const( changedThemes ) ) + for ( const QString &theme : std::as_const( changedThemes ) ) { emit mapThemeChanged( theme ); } diff --git a/src/core/qgsmultirenderchecker.cpp b/src/core/qgsmultirenderchecker.cpp index 10470d11b0ea..a1ab0e040c64 100644 --- a/src/core/qgsmultirenderchecker.cpp +++ b/src/core/qgsmultirenderchecker.cpp @@ -47,7 +47,7 @@ bool QgsMultiRenderChecker::runTest( const QString &testName, unsigned int misma QVector dartMeasurements; - for ( const QString &suffix : qgis::as_const( subDirs ) ) + for ( const QString &suffix : std::as_const( subDirs ) ) { if ( subDirs.count() > 1 ) { diff --git a/src/core/qgsobjectcustomproperties.cpp b/src/core/qgsobjectcustomproperties.cpp index f634f8bfcef4..6b825b735f30 100644 --- a/src/core/qgsobjectcustomproperties.cpp +++ b/src/core/qgsobjectcustomproperties.cpp @@ -127,7 +127,7 @@ void QgsObjectCustomProperties::writeXml( QDomNode &parentNode, QDomDocument &do std::sort( keys.begin(), keys.end() ); - for ( const auto &key : qgis::as_const( keys ) ) + for ( const auto &key : std::as_const( keys ) ) { QDomElement propElement = doc.createElement( QStringLiteral( "property" ) ); propElement.setAttribute( QStringLiteral( "key" ), key ); diff --git a/src/core/qgspolymorphicrelation.cpp b/src/core/qgspolymorphicrelation.cpp index fedc0628d1a2..618a9e7d6dd5 100644 --- a/src/core/qgspolymorphicrelation.cpp +++ b/src/core/qgspolymorphicrelation.cpp @@ -108,10 +108,10 @@ void QgsPolymorphicRelation::writeXml( QDomNode &node, QDomDocument &doc ) const elem.setAttribute( QStringLiteral( "relationStrength" ), qgsEnumValueToKey( d->mRelationStrength ) ); // note that a layer id can store a comma in theory. Luckyly, this is not easy to achieve, e.g. you need to modify the .qgs file manually - for ( const QString &layerId : qgis::as_const( d->mReferencedLayerIds ) ) + for ( const QString &layerId : std::as_const( d->mReferencedLayerIds ) ) Q_ASSERT( ! layerId.contains( "," ) ); - for ( const QgsRelation::FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const QgsRelation::FieldPair &pair : std::as_const( d->mFieldPairs ) ) { QDomElement referenceElem = doc.createElement( QStringLiteral( "fieldRef" ) ); referenceElem.setAttribute( QStringLiteral( "referencingField" ), pair.first ); @@ -195,7 +195,7 @@ QgsAttributeList QgsPolymorphicRelation::referencedFields( const QString &layerI if ( vl && vl->isValid() ) { - for ( const QgsRelation::FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const QgsRelation::FieldPair &pair : std::as_const( d->mFieldPairs ) ) { attrs << vl->fields().lookupField( pair.second ); } @@ -209,7 +209,7 @@ QgsAttributeList QgsPolymorphicRelation::referencingFields() const { QgsAttributeList attrs; - for ( const QgsRelation::FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const QgsRelation::FieldPair &pair : std::as_const( d->mFieldPairs ) ) { attrs << d->mReferencingLayer->fields().lookupField( pair.first ); } @@ -288,7 +288,7 @@ void QgsPolymorphicRelation::updateRelationStatus() return; } - for ( const QgsRelation::FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const QgsRelation::FieldPair &pair : std::as_const( d->mFieldPairs ) ) { if ( d->mReferencingLayer->fields().lookupField( pair.first ) == -1 ) { diff --git a/src/core/qgspostgresstringutils.cpp b/src/core/qgspostgresstringutils.cpp index d1e03279ed6b..f347caece8ac 100644 --- a/src/core/qgspostgresstringutils.cpp +++ b/src/core/qgspostgresstringutils.cpp @@ -119,7 +119,7 @@ QVariantList QgsPostgresStringUtils::parseArray( const QString &string ) QString QgsPostgresStringUtils::buildArray( const QVariantList &list ) { QStringList sl; - for ( const QVariant &v : qgis::as_const( list ) ) + for ( const QVariant &v : std::as_const( list ) ) { // Convert to proper type switch ( v.type() ) diff --git a/src/core/qgsprojectcomponentvisitor.h b/src/core/qgsprojectcomponentvisitor.h new file mode 100644 index 000000000000..e48843543fbc --- /dev/null +++ b/src/core/qgsprojectcomponentvisitor.h @@ -0,0 +1,193 @@ +/*************************************************************************** + qgsprojectcomponentvisitor.h + --------------- + begin : June 2020 + copyright : (C) 2020 by Nyall Dawson + email : nyall dot dawson at gmail dot com + ***************************************************************************/ + +/*************************************************************************** + * - + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * - + ***************************************************************************/ + +#ifndef QGSPROJECTCOMPONENTVISITOR_H +#define QGSPROJECTCOMPONENTVISITOR_H + +#include "qgis_core.h" +#include + +class QgsProjectComponentInterface; + +/** + * \class QgsComponentEntityVisitorInterface + * \ingroup core + * + * An interface for classes which can visit project components (e.g. symbols, expressions, etc) using the visitor pattern. + * + * \since QGIS 3.14 + */ +class CORE_EXPORT QgsProjectComponentVisitorInterface +{ + + public: + + /** + * Describes the types of nodes which may be visited by the visitor. + */ + enum class NodeType : int + { + Layer, //!< Map layer + SymbolRule, //!< Rule based symbology or label child rule + Layouts, //!< Layout collection + PrintLayout, //!< An individual print layout + LayoutItem, //!< Individual item in a print layout + Report, //!< A QGIS print report + ReportHeader, //!< Report header section + ReportFooter, //!< Report footer section + ReportSection, //!< Report sub section + Annotations, //!< Annotations collection + Annotation, //!< An individual annotation + + Other, //!< Other/unclassified type + }; + + /** + * Contains information relating to the project component currently being visited. + */ + struct ComponentLeaf + { + + /** + * Constructor for ComponentLeaf, visiting the given \a component with the specified \a identifier and \a description. + * + * Ownership of \a component is not transferred. + */ + ComponentLeaf( const QgsProjectComponentInterface *component, const QString &identifier = QString(), const QString &description = QString() ) + : identifier( identifier ) + , description( description ) + , component( component ) + {} + + /** + * A string identifying the project component. The actual value of \a identifier will vary + * depending on the class being visited. E.g for a categorized renderer, the + * identifier will be the category ID associated with the symbol. + * + * This may be blank if no identifier is required, e.g. when a renderer has a single + * symbol only. + * + * Note that in some cases where a specific identifier is not available, a generic, untranslated + * one may be used (e.g. "overview", "grid"). + */ + QString identifier; + + /** + * A string describing the project copmonent. The actual value of \a description will vary + * depending on the class being visited. E.g for a categorized renderer, the + * description will be the category label associated with the symbol, for a print layout, it will + * be the name of the layout in the project. + * + * This may be blank if no description is associated with a style entity, e.g. when a renderer has a single + * symbol only. + * + * This value may be a generic, translated value in some cases, e.g. "Grid" or "Overview". + */ + QString description; + + /** + * Reference to component being visited. + */ + const QgsProjectComponentInterface *component = nullptr; + }; + + /** + * Contains information relating to a node (i.e. a group of symbols or other nodes) + * being visited. + */ + struct Node + { + + /** + * Constructor for Node, visiting the node with the specified \a identifier and \a description. + */ + Node( QgsProjectComponentVisitorInterface::NodeType type, const QString &identifier, const QString &description ) + : type( type ) + , identifier( identifier ) + , description( description ) + {} + + /** + * Node type. + */ + QgsProjectComponentVisitorInterface::NodeType type = QgsProjectComponentVisitorInterface::NodeType::Other; + + /** + * A string identifying the node. The actual value of \a identifier will vary + * depending on the node being visited. E.g for a rule based renderer, the + * identifier will be a rule ID. For a project, node identifiers will be + * layer IDs. + */ + QString identifier; + + /** + * A string describing the node. The actual value of \a description will vary + * depending on the node being visited. E.g for a rule based renderer, the + * identifier will be a rule label. For a project, node identifiers will be + * layer names. + */ + QString description; + + }; + + virtual ~QgsProjectComponentVisitorInterface() = default; + + /** + * Called when the visitor will visit a project \a component. + * + * Subclasses should return FALSE to abort further visitations, or TRUE to continue + * visiting after processing this component. + */ + virtual bool visit( const QgsProjectComponentVisitorInterface::ComponentLeaf &component ) + { + Q_UNUSED( component ) + return true; + } + + /** + * Called when the visitor starts visiting a \a node. + * + * Subclasses should return FALSE if they do NOT want to visit this particular node - e.g. + * if the node type is QgsProjectComponentVisitorInterface::NodeType::Layouts and they do not wish to visit + * layout objects. In this case the visitor will not process the node, and will move to the next available + * node instead. Return TRUE to proceed with visiting the node. + * + * The default implementation returns TRUE. + */ + virtual bool visitEnter( const QgsProjectComponentVisitorInterface::Node &node ) + { + Q_UNUSED( node ) + return true; + } + + /** + * Called when the visitor stops visiting a \a node. + * + * Subclasses should return FALSE to abort further visitations, or TRUE to continue + * visiting other nodes. + * + * The default implementation returns TRUE. + */ + virtual bool visitExit( const QgsProjectComponentVisitorInterface::Node &node ) + { + Q_UNUSED( node ) + return true; + } + +}; + +#endif // QGSPROJECTCOMPONENTVISITOR_H diff --git a/src/core/qgsprojutils.cpp b/src/core/qgsprojutils.cpp index 7e3006ba4991..76890abfbd40 100644 --- a/src/core/qgsprojutils.cpp +++ b/src/core/qgsprojutils.cpp @@ -313,7 +313,7 @@ QStringList QgsProjUtils::searchPaths() // thin out duplicates from paths -- see https://github.com/OSGeo/proj.4/pull/1498 QStringList res; res.reserve( paths.count() ); - for ( const QString &p : qgis::as_const( paths ) ) + for ( const QString &p : std::as_const( paths ) ) { if ( existing.contains( p ) ) continue; diff --git a/src/core/qgspropertycollection.cpp b/src/core/qgspropertycollection.cpp index 27a2b3e45138..6ae012e3d094 100644 --- a/src/core/qgspropertycollection.cpp +++ b/src/core/qgspropertycollection.cpp @@ -394,7 +394,7 @@ QgsPropertyCollectionStack::QgsPropertyCollectionStack( const QgsPropertyCollect { clear(); - for ( QgsPropertyCollection *collection : qgis::as_const( other.mStack ) ) + for ( QgsPropertyCollection *collection : std::as_const( other.mStack ) ) { mStack << new QgsPropertyCollection( *collection ); } @@ -405,7 +405,7 @@ QgsPropertyCollectionStack &QgsPropertyCollectionStack::operator=( const QgsProp setName( other.name() ); clear(); - for ( QgsPropertyCollection *collection : qgis::as_const( other.mStack ) ) + for ( QgsPropertyCollection *collection : std::as_const( other.mStack ) ) { mStack << new QgsPropertyCollection( *collection ); } diff --git a/src/core/qgsrelation.cpp b/src/core/qgsrelation.cpp index c3616ea0b789..8f80e715ffdd 100644 --- a/src/core/qgsrelation.cpp +++ b/src/core/qgsrelation.cpp @@ -123,7 +123,7 @@ void QgsRelation::writeXml( QDomNode &node, QDomDocument &doc ) const elem.setAttribute( QStringLiteral( "referencedLayer" ), d->mReferencedLayerId ); elem.setAttribute( QStringLiteral( "strength" ), qgsEnumValueToKey( d->mRelationStrength ) ); - for ( const FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) ) { QDomElement referenceElem = doc.createElement( QStringLiteral( "fieldRef" ) ); referenceElem.setAttribute( QStringLiteral( "referencingField" ), pair.first ); @@ -218,7 +218,7 @@ QString QgsRelation::getRelatedFeaturesFilter( const QgsFeature &feature ) const } } - for ( const FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) ) { QVariant val( feature.attribute( pair.referencedField() ) ); conditions << QgsExpression::createFieldEqualityExpression( pair.referencingField(), val ); @@ -231,7 +231,7 @@ QgsFeatureRequest QgsRelation::getReferencedFeatureRequest( const QgsAttributes { QStringList conditions; - for ( const FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) ) { int referencingIdx = referencingLayer()->fields().lookupField( pair.referencingField() ); conditions << QgsExpression::createFieldEqualityExpression( pair.referencedField(), attributes.at( referencingIdx ) ); @@ -318,7 +318,7 @@ QgsAttributeList QgsRelation::referencedFields() const { QgsAttributeList attrs; attrs.reserve( d->mFieldPairs.size() ); - for ( const FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) ) { attrs << d->mReferencedLayer->fields().lookupField( pair.second ); } @@ -329,7 +329,7 @@ QgsAttributeList QgsRelation::referencingFields() const { QgsAttributeList attrs; - for ( const FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) ) { attrs << d->mReferencingLayer->fields().lookupField( pair.first ); } @@ -349,7 +349,7 @@ bool QgsRelation::hasEqualDefinition( const QgsRelation &other ) const QString QgsRelation::resolveReferencedField( const QString &referencingField ) const { - for ( const FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) ) { if ( pair.first == referencingField ) return pair.second; @@ -359,7 +359,7 @@ QString QgsRelation::resolveReferencedField( const QString &referencingField ) c QString QgsRelation::resolveReferencingField( const QString &referencedField ) const { - for ( const FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) ) { if ( pair.second == referencedField ) return pair.first; @@ -401,7 +401,7 @@ void QgsRelation::updateRelationStatus() d->mValid = false; } - for ( const FieldPair &pair : qgis::as_const( d->mFieldPairs ) ) + for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) ) { if ( -1 == d->mReferencingLayer->fields().lookupField( pair.first ) ) { diff --git a/src/core/qgsrelationmanager.cpp b/src/core/qgsrelationmanager.cpp index ff8e68cf8c36..582e58d85d72 100644 --- a/src/core/qgsrelationmanager.cpp +++ b/src/core/qgsrelationmanager.cpp @@ -44,7 +44,7 @@ QgsRelationContext QgsRelationManager::context() const void QgsRelationManager::setRelations( const QList &relations ) { mRelations.clear(); - for ( const QgsRelation &rel : qgis::as_const( relations ) ) + for ( const QgsRelation &rel : std::as_const( relations ) ) { addRelation( rel ); } @@ -101,7 +101,7 @@ QList QgsRelationManager::relationsByName( const QString &name ) co { QList relations; - for ( const QgsRelation &rel : qgis::as_const( mRelations ) ) + for ( const QgsRelation &rel : std::as_const( mRelations ) ) { if ( QString::compare( rel.name(), name, Qt::CaseInsensitive ) == 0 ) relations << rel; @@ -125,7 +125,7 @@ QList QgsRelationManager::referencingRelations( const QgsVectorLaye QList relations; - for ( const QgsRelation &rel : qgis::as_const( mRelations ) ) + for ( const QgsRelation &rel : std::as_const( mRelations ) ) { if ( rel.referencingLayer() == layer ) { @@ -163,7 +163,7 @@ QList QgsRelationManager::referencedRelations( const QgsVectorLayer QList relations; - for ( const QgsRelation &rel : qgis::as_const( mRelations ) ) + for ( const QgsRelation &rel : std::as_const( mRelations ) ) { if ( rel.referencedLayer() == layer ) { @@ -232,7 +232,7 @@ void QgsRelationManager::writeProject( QDomDocument &doc ) QDomElement relationsNode = doc.createElement( QStringLiteral( "relations" ) ); qgisNode.appendChild( relationsNode ); - for ( const QgsRelation &relation : qgis::as_const( mRelations ) ) + for ( const QgsRelation &relation : std::as_const( mRelations ) ) { // the generated relations for polymorphic relations should be ignored, // they are generated every time when a polymorphic relation is added @@ -245,7 +245,7 @@ void QgsRelationManager::writeProject( QDomDocument &doc ) QDomElement polymorphicRelationsNode = doc.createElement( QStringLiteral( "polymorphicRelations" ) ); qgisNode.appendChild( polymorphicRelationsNode ); - for ( const QgsPolymorphicRelation &relation : qgis::as_const( mPolymorphicRelations ) ) + for ( const QgsPolymorphicRelation &relation : std::as_const( mPolymorphicRelations ) ) { relation.writeXml( polymorphicRelationsNode, doc ); } @@ -254,7 +254,7 @@ void QgsRelationManager::writeProject( QDomDocument &doc ) void QgsRelationManager::layersRemoved( const QStringList &layers ) { bool relationsChanged = false; - for ( const QString &layer : qgis::as_const( layers ) ) + for ( const QString &layer : std::as_const( layers ) ) { QMapIterator it( mRelations ); @@ -278,7 +278,7 @@ void QgsRelationManager::layersRemoved( const QStringList &layers ) static bool hasRelationWithEqualDefinition( const QList &existingRelations, const QgsRelation &relation ) { - for ( const QgsRelation &cur : qgis::as_const( existingRelations ) ) + for ( const QgsRelation &cur : std::as_const( existingRelations ) ) { if ( cur.hasEqualDefinition( relation ) ) return true; } @@ -288,7 +288,7 @@ static bool hasRelationWithEqualDefinition( const QList &existingRe QList QgsRelationManager::discoverRelations( const QList &existingRelations, const QList &layers ) { QList result; - for ( const QgsVectorLayer *layer : qgis::as_const( layers ) ) + for ( const QgsVectorLayer *layer : std::as_const( layers ) ) { const auto constDiscoverRelations = layer->dataProvider()->discoverRelations( layer, layers ); for ( const QgsRelation &relation : constDiscoverRelations ) diff --git a/src/core/qgssnappingutils.cpp b/src/core/qgssnappingutils.cpp index ec194b10d6bf..c21fbcf9f393 100644 --- a/src/core/qgssnappingutils.cpp +++ b/src/core/qgssnappingutils.cpp @@ -325,7 +325,7 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPointXY &pointMap, bool inRangeGlobal = ( mSnappingConfig.minimumScale() <= 0.0 || mMapSettings.scale() <= mSnappingConfig.minimumScale() ) && ( mSnappingConfig.maximumScale() <= 0.0 || mMapSettings.scale() >= mSnappingConfig.maximumScale() ); - for ( const LayerConfig &layerConfig : qgis::as_const( mLayers ) ) + for ( const LayerConfig &layerConfig : std::as_const( mLayers ) ) { QgsSnappingConfig::IndividualLayerSettings layerSettings = mSnappingConfig.individualLayerSettings( layerConfig.layer ); @@ -350,7 +350,7 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPointXY &pointMap, double maxTolerance = 0; QgsPointLocator::Type maxTypes = QgsPointLocator::Invalid; - for ( const LayerConfig &layerConfig : qgis::as_const( filteredConfigs ) ) + for ( const LayerConfig &layerConfig : std::as_const( filteredConfigs ) ) { double tolerance = QgsTolerance::toleranceInProjectUnits( layerConfig.tolerance, layerConfig.layer, mMapSettings, layerConfig.unit ); if ( QgsPointLocator *loc = locatorForLayerUsingStrategy( layerConfig.layer, pointMap, tolerance ) ) @@ -398,7 +398,7 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPointXY &pointMap, QgsPointLocator::MatchList edges; // for snap on intersection QgsPointLocator::Match bestMatch; - for ( const LayerAndAreaOfInterest &entry : qgis::as_const( layers ) ) + for ( const LayerAndAreaOfInterest &entry : std::as_const( layers ) ) { QgsVectorLayer *vl = entry.first; if ( QgsPointLocator *loc = locatorForLayerUsingStrategy( vl, pointMap, tolerance ) ) diff --git a/src/core/qgssqlstatement.cpp b/src/core/qgssqlstatement.cpp index 5b56d85f0265..32de9433052e 100644 --- a/src/core/qgssqlstatement.cpp +++ b/src/core/qgssqlstatement.cpp @@ -256,7 +256,7 @@ bool QgsSQLStatement::doBasicValidationChecks( QString &errorMsgOut ) const QgsSQLStatementCollectTableNames v; mRootNode->accept( v ); - for ( const QgsSQLStatementCollectTableNames::TableColumnPair &pair : qgis::as_const( v.tableNamesReferenced ) ) + for ( const QgsSQLStatementCollectTableNames::TableColumnPair &pair : std::as_const( v.tableNamesReferenced ) ) { if ( !v.tableNamesDeclared.contains( pair.first ) ) { diff --git a/src/core/qgsstoredexpressionmanager.cpp b/src/core/qgsstoredexpressionmanager.cpp index f92be67ecc85..db343ff5e221 100644 --- a/src/core/qgsstoredexpressionmanager.cpp +++ b/src/core/qgsstoredexpressionmanager.cpp @@ -33,7 +33,7 @@ QString QgsStoredExpressionManager::addStoredExpression( const QString &name, co void QgsStoredExpressionManager::removeStoredExpression( const QString &id ) { int i = 0; - for ( const QgsStoredExpression &storedExpression : qgis::as_const( mStoredExpressions ) ) + for ( const QgsStoredExpression &storedExpression : std::as_const( mStoredExpressions ) ) { if ( storedExpression.id == id ) { @@ -48,7 +48,7 @@ void QgsStoredExpressionManager::removeStoredExpression( const QString &id ) void QgsStoredExpressionManager::updateStoredExpression( const QString &id, const QString &name, const QString &expression, const QgsStoredExpression::Category &tag ) { int i = 0; - for ( const QgsStoredExpression &storedExpression : qgis::as_const( mStoredExpressions ) ) + for ( const QgsStoredExpression &storedExpression : std::as_const( mStoredExpressions ) ) { if ( storedExpression.id == id ) { @@ -73,7 +73,7 @@ QList< QgsStoredExpression > QgsStoredExpressionManager::storedExpressions( cons { QList< QgsStoredExpression > storedExpressions; - for ( const QgsStoredExpression &storedExpression : qgis::as_const( mStoredExpressions ) ) + for ( const QgsStoredExpression &storedExpression : std::as_const( mStoredExpressions ) ) { if ( storedExpression.tag & tag ) { @@ -85,7 +85,7 @@ QList< QgsStoredExpression > QgsStoredExpressionManager::storedExpressions( cons QgsStoredExpression QgsStoredExpressionManager::storedExpression( const QString &id ) const { - for ( const QgsStoredExpression &storedExpression : qgis::as_const( mStoredExpressions ) ) + for ( const QgsStoredExpression &storedExpression : std::as_const( mStoredExpressions ) ) { if ( storedExpression.id == id ) { @@ -97,7 +97,7 @@ QgsStoredExpression QgsStoredExpressionManager::storedExpression( const QString QgsStoredExpression QgsStoredExpressionManager::findStoredExpressionByExpression( const QString &expression, const QgsStoredExpression::Category &tag ) const { - for ( const QgsStoredExpression &storedExpression : qgis::as_const( mStoredExpressions ) ) + for ( const QgsStoredExpression &storedExpression : std::as_const( mStoredExpressions ) ) { if ( storedExpression.expression == expression && storedExpression.tag & tag ) { @@ -116,7 +116,7 @@ bool QgsStoredExpressionManager::writeXml( QDomNode &layerNode ) const { QDomElement aStoredExpressions = layerNode.ownerDocument().createElement( QStringLiteral( "storedexpressions" ) ); - for ( const QgsStoredExpression &storedExpression : qgis::as_const( mStoredExpressions ) ) + for ( const QgsStoredExpression &storedExpression : std::as_const( mStoredExpressions ) ) { QDomElement aStoredExpression = layerNode.ownerDocument().createElement( QStringLiteral( "storedexpression" ) ); aStoredExpression.setAttribute( QStringLiteral( "name" ), storedExpression.name ); diff --git a/src/core/qgsstringutils.cpp b/src/core/qgsstringutils.cpp index 6806bc8f7b6a..86295a3e9aa1 100644 --- a/src/core/qgsstringutils.cpp +++ b/src/core/qgsstringutils.cpp @@ -83,7 +83,7 @@ QString QgsStringUtils::capitalize( const QString &string, QgsStringUtils::Capit bool firstWord = true; int i = 0; int lastWord = parts.count() - 1; - for ( const QString &word : qgis::as_const( parts ) ) + for ( const QString &word : std::as_const( parts ) ) { if ( newPhraseSeparators.contains( word.trimmed() ) ) { diff --git a/src/core/qgstaskmanager.cpp b/src/core/qgstaskmanager.cpp index ae71205ddbf9..8fae9514340d 100644 --- a/src/core/qgstaskmanager.cpp +++ b/src/core/qgstaskmanager.cpp @@ -464,7 +464,7 @@ long QgsTaskManager::addTaskPrivate( QgsTask *task, QgsTaskList dependencies, bo } // add all subtasks, must be done before dependency resolution - for ( const QgsTask::SubTask &subTask : qgis::as_const( task->mSubTasks ) ) + for ( const QgsTask::SubTask &subTask : std::as_const( task->mSubTasks ) ) { switch ( subTask.dependency ) { diff --git a/src/core/qgstracer.cpp b/src/core/qgstracer.cpp index ff87a63b4099..4b2ad322d8d0 100644 --- a/src/core/qgstracer.cpp +++ b/src/core/qgstracer.cpp @@ -386,7 +386,7 @@ void resetGraph( QgsTracerGraph &g ) g.joinedVertices = 0; // fix vertices of deactivated edges - for ( int eIdx : qgis::as_const( g.inactiveEdges ) ) + for ( int eIdx : std::as_const( g.inactiveEdges ) ) { if ( eIdx >= g.e.count() ) continue; @@ -488,7 +488,7 @@ bool QgsTracer::initGraph() t1.start(); int featuresCounted = 0; bool enableInvisibleFeature = QgsSettings().value( QStringLiteral( "/qgis/digitizing/snap_invisible_feature" ), false ).toBool(); - for ( const QgsVectorLayer *vl : qgis::as_const( mLayers ) ) + for ( const QgsVectorLayer *vl : std::as_const( mLayers ) ) { QgsFeatureRequest request; bool filter = false; @@ -606,7 +606,7 @@ void QgsTracer::setLayers( const QList &layers ) if ( mLayers == layers ) return; - for ( QgsVectorLayer *layer : qgis::as_const( mLayers ) ) + for ( QgsVectorLayer *layer : std::as_const( mLayers ) ) { disconnect( layer, &QgsVectorLayer::featureAdded, this, &QgsTracer::onFeatureAdded ); disconnect( layer, &QgsVectorLayer::featureDeleted, this, &QgsTracer::onFeatureDeleted ); diff --git a/src/core/qgsvectorfilewriter.cpp b/src/core/qgsvectorfilewriter.cpp index 1f228207a52e..3f0d2b16440e 100644 --- a/src/core/qgsvectorfilewriter.cpp +++ b/src/core/qgsvectorfilewriter.cpp @@ -2884,7 +2884,7 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::prepareWriteAsVectorFormat if ( !details.attributes.isEmpty() ) { - for ( int attrIdx : qgis::as_const( details.attributes ) ) + for ( int attrIdx : std::as_const( details.attributes ) ) { details.outputFields.append( details.sourceFields.at( attrIdx ) ); } @@ -3409,7 +3409,7 @@ QList< QgsVectorFileWriter::DriverDetails > QgsVectorFileWriter::ogrDriverList( } results.reserve( writableDrivers.count() ); - for ( const QString &drvName : qgis::as_const( writableDrivers ) ) + for ( const QString &drvName : std::as_const( writableDrivers ) ) { MetaData metadata; if ( driverMetadata( drvName, metadata ) && !metadata.trLongName.isEmpty() ) diff --git a/src/core/qgsweakrelation.cpp b/src/core/qgsweakrelation.cpp index 877fdc7c6ca6..c1e11c26f110 100644 --- a/src/core/qgsweakrelation.cpp +++ b/src/core/qgsweakrelation.cpp @@ -50,7 +50,7 @@ QgsRelation QgsWeakRelation::resolvedRelation( const QgsProject *project, QgsVec { relation.setReferencingLayer( referencingLayer->id() ); } - for ( const auto &fp : qgis::as_const( mFieldPairs ) ) + for ( const auto &fp : std::as_const( mFieldPairs ) ) { relation.addFieldPair( fp ); } diff --git a/src/core/symbology/qgscategorizedsymbolrenderer.cpp b/src/core/symbology/qgscategorizedsymbolrenderer.cpp index b75b8c2a213d..53f477264063 100644 --- a/src/core/symbology/qgscategorizedsymbolrenderer.cpp +++ b/src/core/symbology/qgscategorizedsymbolrenderer.cpp @@ -187,7 +187,7 @@ void QgsCategorizedSymbolRenderer::rebuildHash() { mSymbolHash.clear(); - for ( const QgsRendererCategory &cat : qgis::as_const( mCategories ) ) + for ( const QgsRendererCategory &cat : std::as_const( mCategories ) ) { const QVariant val = cat.value(); if ( val.type() == QVariant::List ) @@ -430,7 +430,7 @@ void QgsCategorizedSymbolRenderer::startRender( QgsRenderContext &context, const mExpression->prepare( &context.expressionContext() ); } - for ( const QgsRendererCategory &cat : qgis::as_const( mCategories ) ) + for ( const QgsRendererCategory &cat : std::as_const( mCategories ) ) { cat.symbol()->startRender( context, fields ); } @@ -440,7 +440,7 @@ void QgsCategorizedSymbolRenderer::stopRender( QgsRenderContext &context ) { QgsFeatureRenderer::stopRender( context ); - for ( const QgsRendererCategory &cat : qgis::as_const( mCategories ) ) + for ( const QgsRendererCategory &cat : std::as_const( mCategories ) ) { cat.symbol()->stopRender( context ); } @@ -537,7 +537,7 @@ QString QgsCategorizedSymbolRenderer::filter( const QgsFields &fields ) QString activeValues; QString inactiveValues; - for ( const QgsRendererCategory &cat : qgis::as_const( mCategories ) ) + for ( const QgsRendererCategory &cat : std::as_const( mCategories ) ) { if ( cat.value() == "" || cat.value().isNull() ) { diff --git a/src/core/symbology/qgsfillsymbollayer.cpp b/src/core/symbology/qgsfillsymbollayer.cpp index ca0de4445f39..dd7c1b64647d 100644 --- a/src/core/symbology/qgsfillsymbollayer.cpp +++ b/src/core/symbology/qgsfillsymbollayer.cpp @@ -2922,7 +2922,7 @@ void QgsLinePatternFillSymbolLayer::applyPattern( const QgsSymbolRenderContext & polygons.append( QPolygonF() << p5 << p6 ); } - for ( const QPolygonF &polygon : qgis::as_const( polygons ) ) + for ( const QPolygonF &polygon : std::as_const( polygons ) ) { fillLineSymbol->renderPolyline( polygon, context.feature(), lineRenderContext, -1, context.selected() ); } @@ -4583,7 +4583,7 @@ void QgsRandomMarkerFillSymbolLayer::render( QgsRenderContext &context, const QV int pointNum = 0; const bool needsExpressionContext = hasDataDefinedProperties(); - for ( const QgsPointXY &p : qgis::as_const( randomPoints ) ) + for ( const QgsPointXY &p : std::as_const( randomPoints ) ) { if ( needsExpressionContext ) scope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM, ++pointNum, true ) ); diff --git a/src/core/symbology/qgsgraduatedsymbolrenderer.cpp b/src/core/symbology/qgsgraduatedsymbolrenderer.cpp index bac6c4968048..717f54ab504d 100644 --- a/src/core/symbology/qgsgraduatedsymbolrenderer.cpp +++ b/src/core/symbology/qgsgraduatedsymbolrenderer.cpp @@ -172,7 +172,7 @@ void QgsGraduatedSymbolRenderer::startRender( QgsRenderContext &context, const Q mExpression->prepare( &context.expressionContext() ); } - for ( const QgsRendererRange &range : qgis::as_const( mRanges ) ) + for ( const QgsRendererRange &range : std::as_const( mRanges ) ) { if ( !range.symbol() ) continue; @@ -185,7 +185,7 @@ void QgsGraduatedSymbolRenderer::stopRender( QgsRenderContext &context ) { QgsFeatureRenderer::stopRender( context ); - for ( const QgsRendererRange &range : qgis::as_const( mRanges ) ) + for ( const QgsRendererRange &range : std::as_const( mRanges ) ) { if ( !range.symbol() ) continue; @@ -343,7 +343,7 @@ QgsSymbolList QgsGraduatedSymbolRenderer::symbols( QgsRenderContext &context ) c Q_UNUSED( context ) QgsSymbolList lst; lst.reserve( mRanges.count() ); - for ( const QgsRendererRange &range : qgis::as_const( mRanges ) ) + for ( const QgsRendererRange &range : std::as_const( mRanges ) ) { lst.append( range.symbol() ); } @@ -352,7 +352,7 @@ QgsSymbolList QgsGraduatedSymbolRenderer::symbols( QgsRenderContext &context ) c bool QgsGraduatedSymbolRenderer::accept( QgsStyleEntityVisitorInterface *visitor ) const { - for ( const QgsRendererRange &range : qgis::as_const( mRanges ) ) + for ( const QgsRendererRange &range : std::as_const( mRanges ) ) { QgsStyleSymbolEntity entity( range.symbol() ); if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity, QStringLiteral( "%1 - %2" ).arg( range.lowerValue() ).arg( range.upperValue() ), range.label() ) ) ) @@ -588,7 +588,7 @@ QgsFeatureRenderer *QgsGraduatedSymbolRenderer::create( QDomElement &element, co QDomElement rotationElem = element.firstChildElement( QStringLiteral( "rotation" ) ); if ( !rotationElem.isNull() && !rotationElem.attribute( QStringLiteral( "field" ) ).isEmpty() ) { - for ( const QgsRendererRange &range : qgis::as_const( r->mRanges ) ) + for ( const QgsRendererRange &range : std::as_const( r->mRanges ) ) { convertSymbolRotation( range.symbol(), rotationElem.attribute( QStringLiteral( "field" ) ) ); } @@ -600,7 +600,7 @@ QgsFeatureRenderer *QgsGraduatedSymbolRenderer::create( QDomElement &element, co QDomElement sizeScaleElem = element.firstChildElement( QStringLiteral( "sizescale" ) ); if ( !sizeScaleElem.isNull() && !sizeScaleElem.attribute( QStringLiteral( "field" ) ).isEmpty() ) { - for ( const QgsRendererRange &range : qgis:: as_const( r->mRanges ) ) + for ( const QgsRendererRange &range : std::as_const( r->mRanges ) ) { convertSymbolSizeScale( range.symbol(), QgsSymbolLayerUtils::decodeScaleMethod( sizeScaleElem.attribute( QStringLiteral( "scalemethod" ) ) ), @@ -901,7 +901,7 @@ void QgsGraduatedSymbolRenderer::updateColorRamp( QgsColorRamp *ramp ) if ( mSourceColorRamp ) { - for ( const QgsRendererRange &range : qgis::as_const( mRanges ) ) + for ( const QgsRendererRange &range : std::as_const( mRanges ) ) { QgsSymbol *symbol = range.symbol() ? range.symbol()->clone() : nullptr; if ( symbol ) @@ -923,7 +923,7 @@ void QgsGraduatedSymbolRenderer::updateSymbols( QgsSymbol *sym ) return; int i = 0; - for ( const QgsRendererRange &range : qgis::as_const( mRanges ) ) + for ( const QgsRendererRange &range : std::as_const( mRanges ) ) { std::unique_ptr symbol( sym->clone() ); if ( mGraduatedMethod == GraduatedColor ) @@ -1078,7 +1078,7 @@ void QgsGraduatedSymbolRenderer::calculateLabelPrecision( bool updateRanges ) { // Find the minimum size of a class double minClassRange = 0.0; - for ( const QgsRendererRange &rendererRange : qgis::as_const( mRanges ) ) + for ( const QgsRendererRange &rendererRange : std::as_const( mRanges ) ) { double range = rendererRange.upperValue() - rendererRange.lowerValue(); if ( range <= 0.0 ) diff --git a/src/core/symbology/qgslinesymbollayer.cpp b/src/core/symbology/qgslinesymbollayer.cpp index 4ffda1dd3145..96300c7bf424 100644 --- a/src/core/symbology/qgslinesymbollayer.cpp +++ b/src/core/symbology/qgslinesymbollayer.cpp @@ -323,7 +323,7 @@ void QgsSimpleLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, con case InteriorRingsOnly: { mOffset = -mOffset; // invert the offset for rings! - for ( const QPolygonF &ring : qgis::as_const( *rings ) ) + for ( const QPolygonF &ring : std::as_const( *rings ) ) renderPolyline( ring, context ); mOffset = -mOffset; } @@ -676,7 +676,7 @@ void QgsSimpleLineSymbolLayer::applyDataDefinedSymbology( QgsSymbolRenderContext //re-scale pattern vector after data defined pen width was applied QVector scaledVector; - for ( double v : qgis::as_const( mCustomDashVector ) ) + for ( double v : std::as_const( mCustomDashVector ) ) { //the dash is specified in terms of pen widths, therefore the division scaledVector << context.renderContext().convertToPainterUnits( v, mCustomDashPatternUnit, mCustomDashPatternMapUnitScale ) / dashWidthDiv; diff --git a/src/core/symbology/qgsmergedfeaturerenderer.cpp b/src/core/symbology/qgsmergedfeaturerenderer.cpp index 3daafec050f3..a6cd8981c86f 100644 --- a/src/core/symbology/qgsmergedfeaturerenderer.cpp +++ b/src/core/symbology/qgsmergedfeaturerenderer.cpp @@ -284,7 +284,7 @@ void QgsMergedFeatureRenderer::stopRender( QgsRenderContext &context ) QgsMultiPolygonXY finalMulti; //avoid expensive allocation for list for every feature QgsPolygonXY newPoly; - for ( const CombinedFeature &cit : qgis::as_const( mFeaturesCategories ) ) + for ( const CombinedFeature &cit : std::as_const( mFeaturesCategories ) ) { finalMulti.resize( 0 ); //preserve capacity - don't use clear! QgsFeature feat = cit.feature; // just a copy, so that we do not accumulate geometries again @@ -325,7 +325,7 @@ void QgsMergedFeatureRenderer::stopRender( QgsRenderContext &context ) // operations do not need geometries to be valid finalMulti.append( mExtentPolygon ); - for ( const QgsGeometry &geom : qgis::as_const( cit.geometries ) ) + for ( const QgsGeometry &geom : std::as_const( cit.geometries ) ) { QgsMultiPolygonXY multi; QgsWkbTypes::Type type = QgsWkbTypes::flatType( geom.constGet()->wkbType() ); @@ -391,7 +391,7 @@ void QgsMergedFeatureRenderer::stopRender( QgsRenderContext &context ) } // draw feature decorations - for ( FeatureDecoration deco : qgis::as_const( mFeatureDecorations ) ) + for ( FeatureDecoration deco : std::as_const( mFeatureDecorations ) ) { mSubRenderer->renderFeature( deco.feature, mContext, deco.layer, deco.selected, deco.drawMarkers ); } diff --git a/src/core/symbology/qgsrulebasedrenderer.cpp b/src/core/symbology/qgsrulebasedrenderer.cpp index 064f4c5c8e9a..4460056ff948 100644 --- a/src/core/symbology/qgsrulebasedrenderer.cpp +++ b/src/core/symbology/qgsrulebasedrenderer.cpp @@ -995,7 +995,7 @@ void QgsRuleBasedRenderer::stopRender( QgsRenderContext &context ) { //QgsDebugMsg(QString("level %1").arg(level.zIndex)); // go through all jobs at the level - for ( const RenderJob *job : qgis::as_const( level.jobs ) ) + for ( const RenderJob *job : std::as_const( level.jobs ) ) { context.expressionContext().setFeature( job->ftr.feat ); //QgsDebugMsg(QString("job fid %1").arg(job->f->id())); diff --git a/src/core/symbology/qgsrulebasedrenderer.h b/src/core/symbology/qgsrulebasedrenderer.h index 934272d8c951..f0184ba9b744 100644 --- a/src/core/symbology/qgsrulebasedrenderer.h +++ b/src/core/symbology/qgsrulebasedrenderer.h @@ -102,7 +102,7 @@ class CORE_EXPORT QgsRuleBasedRenderer : public QgsFeatureRenderer zIndex = rh.zIndex; qDeleteAll( jobs ); jobs.clear(); - for ( RenderJob *job : qgis::as_const( rh.jobs ) ) + for ( RenderJob *job : std::as_const( rh.jobs ) ) { jobs << new RenderJob( *job ); } @@ -112,7 +112,7 @@ class CORE_EXPORT QgsRuleBasedRenderer : public QgsFeatureRenderer RenderLevel( const QgsRuleBasedRenderer::RenderLevel &other ) : zIndex( other.zIndex ), jobs() { - for ( RenderJob *job : qgis::as_const( other.jobs ) ) + for ( RenderJob *job : std::as_const( other.jobs ) ) { jobs << new RenderJob( *job ); } diff --git a/src/core/symbology/qgsstyle.cpp b/src/core/symbology/qgsstyle.cpp index e4b644896345..877b4f646308 100644 --- a/src/core/symbology/qgsstyle.cpp +++ b/src/core/symbology/qgsstyle.cpp @@ -2425,7 +2425,7 @@ QStringList QgsStyle::symbolsOfSmartgroup( StyleEntity type, int id ) { QStringList dummy = symbols; symbols.clear(); - for ( const QString &result : qgis::as_const( resultNames ) ) + for ( const QString &result : std::as_const( resultNames ) ) { if ( dummy.contains( result ) ) symbols << result; diff --git a/src/core/symbology/qgsstylemodel.cpp b/src/core/symbology/qgsstylemodel.cpp index 7f7e734df9a0..721018d7c38d 100644 --- a/src/core/symbology/qgsstylemodel.cpp +++ b/src/core/symbology/qgsstylemodel.cpp @@ -865,7 +865,7 @@ bool QgsStyleProxyModel::filterAcceptsRow( int source_row, const QModelIndex &so for ( const QString &part : partsToMatch ) { bool found = false; - for ( const QString &partToSearch : qgis::as_const( partsToSearch ) ) + for ( const QString &partToSearch : std::as_const( partsToSearch ) ) { if ( partToSearch.contains( part, Qt::CaseInsensitive ) ) { diff --git a/src/core/symbology/qgssymbol.cpp b/src/core/symbology/qgssymbol.cpp index e209c259509b..ddb149bed770 100644 --- a/src/core/symbology/qgssymbol.cpp +++ b/src/core/symbology/qgssymbol.cpp @@ -617,7 +617,7 @@ void QgsSymbol::drawPreviewIcon( QPainter *painter, QSize size, QgsRenderContext context->setExpressionContext( expContext ); } - for ( QgsSymbolLayer *layer : qgis::as_const( mLayers ) ) + for ( QgsSymbolLayer *layer : std::as_const( mLayers ) ) { if ( !layer->enabled() || ( customContext && !customContext->isSymbolLayerEnabled( layer ) ) ) continue; @@ -1255,7 +1255,7 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont case QgsSymbol::Marker: { int geometryPartNumber = 0; - for ( const PointInfo &point : qgis::as_const( pointsToRender ) ) + for ( const PointInfo &point : std::as_const( pointsToRender ) ) { if ( context.renderingStopped() ) break; @@ -1277,7 +1277,7 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont break; int geometryPartNumber = 0; - for ( const LineInfo &line : qgis::as_const( linesToRender ) ) + for ( const LineInfo &line : std::as_const( linesToRender ) ) { if ( context.renderingStopped() ) break; @@ -1296,7 +1296,7 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont case QgsSymbol::Fill: { int geometryPartNumber = 0; - for ( const PolygonInfo &info : qgis::as_const( polygonsToRender ) ) + for ( const PolygonInfo &info : std::as_const( polygonsToRender ) ) { if ( context.renderingStopped() ) break; @@ -1326,7 +1326,7 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont case QgsSymbol::Marker: { markers.reserve( pointsToRender.size() ); - for ( const PointInfo &info : qgis::as_const( pointsToRender ) ) + for ( const PointInfo &info : std::as_const( pointsToRender ) ) { if ( context.hasRenderedFeatureHandlers() || context.testFlag( QgsRenderContext::DrawSymbolBounds ) ) { @@ -1355,7 +1355,7 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont case QgsSymbol::Line: { - for ( const LineInfo &info : qgis::as_const( linesToRender ) ) + for ( const LineInfo &info : std::as_const( linesToRender ) ) { if ( context.hasRenderedFeatureHandlers() && !info.renderLine.empty() ) { @@ -1374,7 +1374,7 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont case QgsSymbol::Fill: { int i = 0; - for ( const PolygonInfo &info : qgis::as_const( polygonsToRender ) ) + for ( const PolygonInfo &info : std::as_const( polygonsToRender ) ) { if ( context.hasRenderedFeatureHandlers() && !info.renderExterior.empty() ) { @@ -1643,7 +1643,7 @@ void QgsMarkerSymbol::setAngle( double symbolAngle ) double QgsMarkerSymbol::angle() const { - for ( QgsSymbolLayer *layer : qgis::as_const( mLayers ) ) + for ( QgsSymbolLayer *layer : std::as_const( mLayers ) ) { if ( layer->type() != QgsSymbol::Marker ) continue; @@ -1670,7 +1670,7 @@ void QgsMarkerSymbol::setDataDefinedAngle( const QgsProperty &property ) const double symbolRotation = angle(); - for ( QgsSymbolLayer *layer : qgis::as_const( mLayers ) ) + for ( QgsSymbolLayer *layer : std::as_const( mLayers ) ) { if ( layer->type() != QgsSymbol::Marker ) continue; @@ -2028,7 +2028,7 @@ void QgsMarkerSymbol::renderPoint( QPointF point, const QgsFeature *f, QgsRender } - for ( QgsSymbolLayer *symbolLayer : qgis::as_const( mLayers ) ) + for ( QgsSymbolLayer *symbolLayer : std::as_const( mLayers ) ) { if ( context.renderingStopped() ) break; diff --git a/src/core/symbology/qgssymbollayer.cpp b/src/core/symbology/qgssymbollayer.cpp index 33adb39132a9..e561673dc717 100644 --- a/src/core/symbology/qgssymbollayer.cpp +++ b/src/core/symbology/qgssymbollayer.cpp @@ -478,7 +478,7 @@ void QgsMarkerSymbolLayer::drawPreviewIcon( QgsSymbolRenderContext &context, QSi if ( effect && effect->enabled() ) effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect ); - for ( QPointF point : qgis::as_const( points ) ) + for ( QPointF point : std::as_const( points ) ) renderPoint( point, context ); effectPainter.reset(); @@ -708,7 +708,7 @@ void QgsLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, const QVe case AllRings: case InteriorRingsOnly: { - for ( const QPolygonF &ring : qgis::as_const( *rings ) ) + for ( const QPolygonF &ring : std::as_const( *rings ) ) renderPolyline( ring, context ); } break; diff --git a/src/core/textrenderer/qgstextdocument.cpp b/src/core/textrenderer/qgstextdocument.cpp index 0c9f4fbb8739..f28aaf364432 100644 --- a/src/core/textrenderer/qgstextdocument.cpp +++ b/src/core/textrenderer/qgstextdocument.cpp @@ -158,7 +158,7 @@ void QgsTextDocument::splitLines( const QString &wrapCharacter, int autoWrapLeng { QStringList autoWrappedLines; autoWrappedLines.reserve( thisParts.count() ); - for ( const QString &line : qgis::as_const( thisParts ) ) + for ( const QString &line : std::as_const( thisParts ) ) { autoWrappedLines.append( QgsStringUtils::wordWrap( line, autoWrapLength, useMaxLineLengthWhenAutoWrapping ).split( '\n' ) ); } diff --git a/src/core/textrenderer/qgstextrenderer.cpp b/src/core/textrenderer/qgstextrenderer.cpp index 85b029891ef0..b8755dbc2108 100644 --- a/src/core/textrenderer/qgstextrenderer.cpp +++ b/src/core/textrenderer/qgstextrenderer.cpp @@ -1402,7 +1402,7 @@ void QgsTextRenderer::drawTextInternalHorizontal( QgsRenderContext &context, con } } - for ( const QString &line : qgis::as_const( textLines ) ) + for ( const QString &line : std::as_const( textLines ) ) { const QgsTextBlock block = document.at( i ); @@ -1644,7 +1644,7 @@ void QgsTextRenderer::drawTextInternalVertical( QgsRenderContext &context, const } int maxLineLength = 0; - for ( const QString &line : qgis::as_const( textLines ) ) + for ( const QString &line : std::as_const( textLines ) ) { maxLineLength = std::max( maxLineLength, line.length() ); } diff --git a/src/core/vector/qgsvectorlayer.cpp b/src/core/vector/qgsvectorlayer.cpp index 0d75f072c3ba..f394b676b951 100644 --- a/src/core/vector/qgsvectorlayer.cpp +++ b/src/core/vector/qgsvectorlayer.cpp @@ -186,7 +186,7 @@ QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath, setDataSource( vectorLayerPath, baseName, providerKey, providerOptions, options.loadDefaultStyle ); } - for ( const QgsField &field : qgis::as_const( mFields ) ) + for ( const QgsField &field : std::as_const( mFields ) ) { mAttributeAliasMap.insert( field.name(), QString() ); } @@ -827,7 +827,7 @@ void QgsVectorLayer::updateDefaultValues( QgsFeatureId fid, QgsFeature feature ) feature = getFeature( fid ); int size = mFields.size(); - for ( int idx : qgis::as_const( mDefaultValueOnUpdateFields ) ) + for ( int idx : std::as_const( mDefaultValueOnUpdateFields ) ) { if ( idx < 0 || idx >= size ) continue; @@ -2671,7 +2671,7 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString fieldConfigurationElement = doc.createElement( QStringLiteral( "fieldConfiguration" ) ); node.appendChild( fieldConfigurationElement ); - for ( const QgsField &field : qgis::as_const( mFields ) ) + for ( const QgsField &field : std::as_const( mFields ) ) { QDomElement fieldElement = doc.createElement( QStringLiteral( "field" ) ); fieldElement.setAttribute( QStringLiteral( "name" ), field.name() ); @@ -2703,7 +2703,7 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString { //attribute aliases QDomElement aliasElem = doc.createElement( QStringLiteral( "aliases" ) ); - for ( const QgsField &field : qgis::as_const( mFields ) ) + for ( const QgsField &field : std::as_const( mFields ) ) { QDomElement aliasEntryElem = doc.createElement( QStringLiteral( "alias" ) ); aliasEntryElem.setAttribute( QStringLiteral( "field" ), field.name() ); @@ -2715,7 +2715,7 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString //default expressions QDomElement defaultsElem = doc.createElement( QStringLiteral( "defaults" ) ); - for ( const QgsField &field : qgis::as_const( mFields ) ) + for ( const QgsField &field : std::as_const( mFields ) ) { QDomElement defaultElem = doc.createElement( QStringLiteral( "default" ) ); defaultElem.setAttribute( QStringLiteral( "field" ), field.name() ); @@ -2727,7 +2727,7 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString // constraints QDomElement constraintsElem = doc.createElement( QStringLiteral( "constraints" ) ); - for ( const QgsField &field : qgis::as_const( mFields ) ) + for ( const QgsField &field : std::as_const( mFields ) ) { QDomElement constraintElem = doc.createElement( QStringLiteral( "constraint" ) ); constraintElem.setAttribute( QStringLiteral( "field" ), field.name() ); @@ -2741,7 +2741,7 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString // constraint expressions QDomElement constraintExpressionsElem = doc.createElement( QStringLiteral( "constraintExpressions" ) ); - for ( const QgsField &field : qgis::as_const( mFields ) ) + for ( const QgsField &field : std::as_const( mFields ) ) { QDomElement constraintExpressionElem = doc.createElement( QStringLiteral( "constraint" ) ); constraintExpressionElem.setAttribute( QStringLiteral( "field" ), field.name() ); @@ -3232,7 +3232,7 @@ bool QgsVectorLayer::deleteAttributes( const QList &attrs ) std::sort( attrList.begin(), attrList.end(), std::greater() ); - for ( int attr : qgis::as_const( attrList ) ) + for ( int attr : std::as_const( attrList ) ) { if ( deleteAttribute( attr ) ) { @@ -5408,7 +5408,7 @@ bool QgsVectorLayer::setDependencies( const QSet &oDeps ) QSet toAdd = deps - dependencies(); // disconnect layers that are not present in the list of dependencies anymore - for ( const QgsMapLayerDependency &dep : qgis::as_const( mDependencies ) ) + for ( const QgsMapLayerDependency &dep : std::as_const( mDependencies ) ) { QgsVectorLayer *lyr = static_cast( QgsProject::instance()->mapLayer( dep.layerId() ) ); if ( !lyr ) @@ -5429,7 +5429,7 @@ bool QgsVectorLayer::setDependencies( const QSet &oDeps ) emit dependenciesChanged(); // connect to new layers - for ( const QgsMapLayerDependency &dep : qgis::as_const( mDependencies ) ) + for ( const QgsMapLayerDependency &dep : std::as_const( mDependencies ) ) { QgsVectorLayer *lyr = static_cast( QgsProject::instance()->mapLayer( dep.layerId() ) ); if ( !lyr ) diff --git a/src/core/vector/qgsvectorlayercache.cpp b/src/core/vector/qgsvectorlayercache.cpp index 87e7adf2601e..2e17ee6fe887 100644 --- a/src/core/vector/qgsvectorlayercache.cpp +++ b/src/core/vector/qgsvectorlayercache.cpp @@ -208,7 +208,7 @@ void QgsVectorLayerCache::requestCompleted( const QgsFeatureRequest &featureRequ // If a request is too large for the cache don't notify to prevent from indexing incomplete requests if ( fids.count() <= mCache.size() ) { - for ( const auto &idx : qgis::as_const( mCacheIndices ) ) + for ( const auto &idx : std::as_const( mCacheIndices ) ) { idx->requestCompleted( featureRequest, fids ); } diff --git a/src/core/vector/qgsvectorlayereditbuffer.cpp b/src/core/vector/qgsvectorlayereditbuffer.cpp index a0b491645988..cabfe8d2711a 100644 --- a/src/core/vector/qgsvectorlayereditbuffer.cpp +++ b/src/core/vector/qgsvectorlayereditbuffer.cpp @@ -348,7 +348,7 @@ bool QgsVectorLayerEditBuffer::commitChanges( QStringList &commitErrors ) { if ( provider->doesStrictFeatureTypeCheck() ) { - for ( const QgsFeature &f : qgis::as_const( mAddedFeatures ) ) + for ( const QgsFeature &f : std::as_const( mAddedFeatures ) ) { if ( ( ! f.hasGeometry() ) || ( f.geometry().wkbType() == provider->wkbType() ) ) @@ -581,7 +581,7 @@ bool QgsVectorLayerEditBuffer::commitChanges( QStringList &commitErrors ) { commitErrors << tr( "SUCCESS: %n feature(s) deleted.", "deleted features count", mDeletedFeatureIds.size() ); // TODO[MD]: we should not need this here - for ( QgsFeatureId id : qgis::as_const( mDeletedFeatureIds ) ) + for ( QgsFeatureId id : std::as_const( mDeletedFeatureIds ) ) { mChangedAttributeValues.remove( id ); mChangedGeometries.remove( id ); diff --git a/src/core/vector/qgsvectorlayereditutils.cpp b/src/core/vector/qgsvectorlayereditutils.cpp index 8f03854607d9..e004ada69cbe 100644 --- a/src/core/vector/qgsvectorlayereditutils.cpp +++ b/src/core/vector/qgsvectorlayereditutils.cpp @@ -377,7 +377,7 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QgsCu //insert new features QgsAttributeMap attributeMap = feat.attributes().toMap(); - for ( const QgsGeometry &geom : qgis::as_const( newGeometries ) ) + for ( const QgsGeometry &geom : std::as_const( newGeometries ) ) { featuresDataToAdd << QgsVectorLayerUtils::QgsFeatureData( geom, attributeMap ); } diff --git a/src/core/vector/qgsvectorlayerjoinbuffer.cpp b/src/core/vector/qgsvectorlayerjoinbuffer.cpp index bc025f18b815..5ca5ebbe609f 100644 --- a/src/core/vector/qgsvectorlayerjoinbuffer.cpp +++ b/src/core/vector/qgsvectorlayerjoinbuffer.cpp @@ -543,7 +543,7 @@ bool QgsVectorLayerJoinBuffer::addFeatures( QgsFeatureList &features, QgsFeature { QgsFeatureList joinFeatures; - for ( const QgsFeature &feature : qgis::as_const( features ) ) + for ( const QgsFeature &feature : std::as_const( features ) ) { const QgsFeature joinFeature = info.extractJoinedFeature( feature ); diff --git a/src/core/vector/qgsvectorlayerjoininfo.cpp b/src/core/vector/qgsvectorlayerjoininfo.cpp index 6a4d88fe6e91..654659d0811e 100644 --- a/src/core/vector/qgsvectorlayerjoininfo.cpp +++ b/src/core/vector/qgsvectorlayerjoininfo.cpp @@ -92,7 +92,7 @@ QStringList QgsVectorLayerJoinInfo::joinFieldNamesSubset( const QgsVectorLayerJo QStringList *lst = info.joinFieldNamesSubset(); if ( lst ) { - for ( const QString &s : qgis::as_const( *lst ) ) + for ( const QString &s : std::as_const( *lst ) ) { if ( !info.joinFieldNamesBlockList().contains( s ) ) fieldNames.append( s ); diff --git a/src/core/vector/qgsvectorlayerrenderer.cpp b/src/core/vector/qgsvectorlayerrenderer.cpp index 8981cd99fcfe..5030c3a2f044 100644 --- a/src/core/vector/qgsvectorlayerrenderer.cpp +++ b/src/core/vector/qgsvectorlayerrenderer.cpp @@ -68,7 +68,7 @@ QgsVectorLayerRenderer::QgsVectorLayerRenderer( QgsVectorLayer *layer, QgsRender bool insertedMainRenderer = false; double prevLevel = std::numeric_limits< double >::lowest(); mRenderer = mainRenderer.get(); - for ( const QgsFeatureRendererGenerator *generator : qgis::as_const( generators ) ) + for ( const QgsFeatureRendererGenerator *generator : std::as_const( generators ) ) { if ( generator->level() >= 0 && prevLevel < 0 && !insertedMainRenderer ) { diff --git a/src/core/vector/qgsvectorlayerundopassthroughcommand.cpp b/src/core/vector/qgsvectorlayerundopassthroughcommand.cpp index f69549975f8e..64c2eb70d47f 100644 --- a/src/core/vector/qgsvectorlayerundopassthroughcommand.cpp +++ b/src/core/vector/qgsvectorlayerundopassthroughcommand.cpp @@ -107,7 +107,7 @@ QgsVectorLayerUndoPassthroughCommandAddFeatures::QgsVectorLayerUndoPassthroughCo : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "add features" ) ) { static int sAddedIdLowWaterMark = -1; - for ( const QgsFeature &f : qgis::as_const( features ) ) + for ( const QgsFeature &f : std::as_const( features ) ) { mInitialFeatures << f; //assign a temporary id to the feature (use negative numbers) @@ -122,7 +122,7 @@ void QgsVectorLayerUndoPassthroughCommandAddFeatures::undo() { if ( rollBackToSavePoint() ) { - for ( const QgsFeature &f : qgis::as_const( mFeatures ) ) + for ( const QgsFeature &f : std::as_const( mFeatures ) ) { mBuffer->mAddedFeatures.remove( f.id() ); emit mBuffer->featureDeleted( f.id() ); @@ -137,7 +137,7 @@ void QgsVectorLayerUndoPassthroughCommandAddFeatures::redo() mBuffer->L->dataProvider()->clearErrors(); if ( setSavePoint() && mBuffer->L->dataProvider()->addFeatures( mFeatures ) && ! mBuffer->L->dataProvider()->hasErrors() ) { - for ( const QgsFeature &f : qgis::as_const( mFeatures ) ) + for ( const QgsFeature &f : std::as_const( mFeatures ) ) { mBuffer->mAddedFeatures.insert( f.id(), f ); emit mBuffer->featureAdded( f.id() ); diff --git a/src/core/vector/qgsvectorlayerutils.cpp b/src/core/vector/qgsvectorlayerutils.cpp index c7e89b89e72b..526b9e59b988 100644 --- a/src/core/vector/qgsvectorlayerutils.cpp +++ b/src/core/vector/qgsvectorlayerutils.cpp @@ -342,7 +342,7 @@ QVariant QgsVectorLayerUtils::createUniqueValueFromCache( const QgsVectorLayer * // try variants like base_1, base_2, etc until a new value found QStringList vals; - for ( const auto &v : qgis::as_const( existingValues ) ) + for ( const auto &v : std::as_const( existingValues ) ) { if ( v.toString().startsWith( base ) ) vals.push_back( v.toString() ); @@ -522,7 +522,7 @@ QgsFeatureList QgsVectorLayerUtils::createFeatures( const QgsVectorLayer *layer, return uniqueValueCache[ fieldIdx ].contains( value ); }; - for ( const auto &fd : qgis::as_const( featuresData ) ) + for ( const auto &fd : std::as_const( featuresData ) ) { QgsFeature newFeature( fields ); diff --git a/src/core/vectortile/qgsvectortilebasiclabeling.cpp b/src/core/vectortile/qgsvectortilebasiclabeling.cpp index 881ea5b92096..2272a8bfd1e6 100644 --- a/src/core/vectortile/qgsvectortilebasiclabeling.cpp +++ b/src/core/vectortile/qgsvectortilebasiclabeling.cpp @@ -127,7 +127,7 @@ QgsVectorTileBasicLabelProvider::QgsVectorTileBasicLabelProvider( QgsVectorTileL QMap > QgsVectorTileBasicLabelProvider::usedAttributes( const QgsRenderContext &context, int tileZoom ) const { QMap > requiredFields; - for ( const QgsVectorTileBasicLabelingStyle &layerStyle : qgis::as_const( mStyles ) ) + for ( const QgsVectorTileBasicLabelingStyle &layerStyle : std::as_const( mStyles ) ) { if ( !layerStyle.isActive( tileZoom ) ) continue; @@ -146,7 +146,7 @@ QMap > QgsVectorTileBasicLabelProvider::usedAttributes( c QSet QgsVectorTileBasicLabelProvider::requiredLayers( QgsRenderContext &, int tileZoom ) const { QSet< QString > res; - for ( const QgsVectorTileBasicLabelingStyle &layerStyle : qgis::as_const( mStyles ) ) + for ( const QgsVectorTileBasicLabelingStyle &layerStyle : std::as_const( mStyles ) ) { if ( layerStyle.isActive( tileZoom ) ) { @@ -164,7 +164,7 @@ void QgsVectorTileBasicLabelProvider::setFields( const QMap QList QgsVectorTileBasicLabelProvider::subProviders() { QList lst; - for ( QgsVectorLayerLabelProvider *subprovider : qgis::as_const( mSubProviders ) ) + for ( QgsVectorLayerLabelProvider *subprovider : std::as_const( mSubProviders ) ) { if ( subprovider ) // sub-providers that failed to initialize are set to null lst << subprovider; @@ -174,7 +174,7 @@ QList QgsVectorTileBasicLabelProvider::subProviders( bool QgsVectorTileBasicLabelProvider::prepare( QgsRenderContext &context, QSet &attributeNames ) { - for ( QgsVectorLayerLabelProvider *provider : qgis::as_const( mSubProviders ) ) + for ( QgsVectorLayerLabelProvider *provider : std::as_const( mSubProviders ) ) provider->setEngine( mEngine ); // populate sub-providers diff --git a/src/core/vectortile/qgsvectortilebasicrenderer.cpp b/src/core/vectortile/qgsvectortilebasicrenderer.cpp index eb778b1eab1e..934342ec5bf8 100644 --- a/src/core/vectortile/qgsvectortilebasicrenderer.cpp +++ b/src/core/vectortile/qgsvectortilebasicrenderer.cpp @@ -120,7 +120,7 @@ void QgsVectorTileBasicRenderer::startRender( QgsRenderContext &context, int til Q_UNUSED( context ) Q_UNUSED( tileRange ) // figure out required fields for different layers - for ( const QgsVectorTileBasicRendererStyle &layerStyle : qgis::as_const( mStyles ) ) + for ( const QgsVectorTileBasicRendererStyle &layerStyle : std::as_const( mStyles ) ) { if ( layerStyle.isActive( tileZoom ) ) { @@ -145,7 +145,7 @@ QMap > QgsVectorTileBasicRenderer::usedAttributes( const QSet QgsVectorTileBasicRenderer::requiredLayers( QgsRenderContext &, int tileZoom ) const { QSet< QString > res; - for ( const QgsVectorTileBasicRendererStyle &layerStyle : qgis::as_const( mStyles ) ) + for ( const QgsVectorTileBasicRendererStyle &layerStyle : std::as_const( mStyles ) ) { if ( layerStyle.isActive( tileZoom ) ) { @@ -165,7 +165,7 @@ void QgsVectorTileBasicRenderer::renderTile( const QgsVectorTileRendererData &ti const QgsVectorTileFeatures tileData = tile.features(); int zoomLevel = tile.id().zoomLevel(); - for ( const QgsVectorTileBasicRendererStyle &layerStyle : qgis::as_const( mStyles ) ) + for ( const QgsVectorTileBasicRendererStyle &layerStyle : std::as_const( mStyles ) ) { if ( !layerStyle.isActive( zoomLevel ) ) continue; diff --git a/src/core/vectortile/qgsvectortileloader.cpp b/src/core/vectortile/qgsvectortileloader.cpp index f84b756e8668..a68d82ec078f 100644 --- a/src/core/vectortile/qgsvectortileloader.cpp +++ b/src/core/vectortile/qgsvectortileloader.cpp @@ -47,7 +47,7 @@ QgsVectorTileLoader::QgsVectorTileLoader( const QString &uri, const QgsTileMatri QgsDebugMsgLevel( QStringLiteral( "Starting network loader" ), 2 ); QVector tiles = QgsVectorTileUtils::tilesInRange( range, tileMatrix.zoomLevel() ); QgsVectorTileUtils::sortTilesByDistanceFromCenter( tiles, viewCenter ); - for ( QgsTileXYZ id : qgis::as_const( tiles ) ) + for ( QgsTileXYZ id : std::as_const( tiles ) ) { loadFromNetworkAsync( id, tileMatrix, uri ); } @@ -173,7 +173,7 @@ QList QgsVectorTileLoader::blockingFetchTileRawData( const QVector tiles = QgsVectorTileUtils::tilesInRange( range, tileMatrix.zoomLevel() ); QgsVectorTileUtils::sortTilesByDistanceFromCenter( tiles, viewCenter ); - for ( QgsTileXYZ id : qgis::as_const( tiles ) ) + for ( QgsTileXYZ id : std::as_const( tiles ) ) { QByteArray rawData = isUrl ? loadFromNetwork( id, tileMatrix, sourcePath, authid, referer ) : loadFromMBTiles( id, mbReader ); if ( !rawData.isEmpty() ) diff --git a/src/core/vectortile/qgsvectortileutils.cpp b/src/core/vectortile/qgsvectortileutils.cpp index b97c4f372589..6f81467262a9 100644 --- a/src/core/vectortile/qgsvectortileutils.cpp +++ b/src/core/vectortile/qgsvectortileutils.cpp @@ -53,7 +53,7 @@ QgsFields QgsVectorTileUtils::makeQgisFields( QSet flds ) QgsFields fields; QStringList fieldsSorted = qgis::setToList( flds ); std::sort( fieldsSorted.begin(), fieldsSorted.end() ); - for ( const QString &fieldName : qgis::as_const( fieldsSorted ) ) + for ( const QString &fieldName : std::as_const( fieldsSorted ) ) { fields.append( QgsField( fieldName, QVariant::String ) ); } diff --git a/src/core/vectortile/qgsvectortilewriter.cpp b/src/core/vectortile/qgsvectortilewriter.cpp index f1dde6a50e13..0d7ec6a430c0 100644 --- a/src/core/vectortile/qgsvectortilewriter.cpp +++ b/src/core/vectortile/qgsvectortilewriter.cpp @@ -165,7 +165,7 @@ bool QgsVectorTileWriter::writeTiles( QgsFeedback *feedback ) QgsVectorTileMVTEncoder encoder( tileID ); encoder.setTransformContext( mTransformContext ); - for ( const Layer &layer : qgis::as_const( mLayers ) ) + for ( const Layer &layer : std::as_const( mLayers ) ) { if ( ( layer.minZoom() >= 0 && zoomLevel < layer.minZoom() ) || ( layer.maxZoom() >= 0 && zoomLevel > layer.maxZoom() ) ) @@ -267,7 +267,7 @@ bool QgsVectorTileWriter::writeTileFileXYZ( const QString &sourcePath, QgsTileXY QString QgsVectorTileWriter::mbtilesJsonSchema() { QVariantList arrayLayers; - for ( const Layer &layer : qgis::as_const( mLayers ) ) + for ( const Layer &layer : std::as_const( mLayers ) ) { QgsVectorLayer *vl = layer.layer(); const QgsFields fields = vl->fields(); diff --git a/src/gui/codeeditors/qgscodeeditorexpression.cpp b/src/gui/codeeditors/qgscodeeditorexpression.cpp index 41d72cacbfd6..f241f86feeda 100644 --- a/src/gui/codeeditors/qgscodeeditorexpression.cpp +++ b/src/gui/codeeditors/qgscodeeditorexpression.cpp @@ -137,22 +137,22 @@ void QgsCodeEditorExpression::updateApis() { mApis = new QgsSciApisExpression( mSqlLexer ); - for ( const QString &var : qgis::as_const( mVariables ) ) + for ( const QString &var : std::as_const( mVariables ) ) { mApis->add( var ); } - for ( const QString &function : qgis::as_const( mContextFunctions ) ) + for ( const QString &function : std::as_const( mContextFunctions ) ) { mApis->add( function ); } - for ( const QString &function : qgis::as_const( mFunctions ) ) + for ( const QString &function : std::as_const( mFunctions ) ) { mApis->add( function ); } - for ( const QString &fieldName : qgis::as_const( mFieldNames ) ) + for ( const QString &fieldName : std::as_const( mFieldNames ) ) { mApis->add( fieldName ); } diff --git a/src/gui/codeeditors/qgscodeeditorsql.cpp b/src/gui/codeeditors/qgscodeeditorsql.cpp index ac8bce1cdbda..4a04e861b423 100644 --- a/src/gui/codeeditors/qgscodeeditorsql.cpp +++ b/src/gui/codeeditors/qgscodeeditorsql.cpp @@ -85,7 +85,7 @@ void QgsCodeEditorSQL::updateApis() { mApis = new QsciAPIs( mSqlLexer ); - for ( const QString &fieldName : qgis::as_const( mFieldNames ) ) + for ( const QString &fieldName : std::as_const( mFieldNames ) ) { mApis->add( fieldName ); } diff --git a/src/gui/editorwidgets/qgsrelationreferencewidget.cpp b/src/gui/editorwidgets/qgsrelationreferencewidget.cpp index 73360b6b473d..48420062f073 100644 --- a/src/gui/editorwidgets/qgsrelationreferencewidget.cpp +++ b/src/gui/editorwidgets/qgsrelationreferencewidget.cpp @@ -286,7 +286,7 @@ void QgsRelationReferenceWidget::setForeignKeys( const QVariantList &values ) } mForeignKeys.clear(); - for ( const QString &fieldName : qgis::as_const( mReferencedFields ) ) + for ( const QString &fieldName : std::as_const( mReferencedFields ) ) mForeignKeys << mFeature.attribute( fieldName ); QgsExpression expr( mReferencedLayer->displayExpression() ); @@ -296,7 +296,7 @@ void QgsRelationReferenceWidget::setForeignKeys( const QVariantList &values ) if ( expr.hasEvalError() ) { QStringList titleFields; - for ( const QString &fieldName : qgis::as_const( mReferencedFields ) ) + for ( const QString &fieldName : std::as_const( mReferencedFields ) ) titleFields << mFeature.attribute( fieldName ).toString(); title = titleFields.join( QLatin1Char( ' ' ) ); } @@ -352,7 +352,7 @@ void QgsRelationReferenceWidget::deleteForeignKeys() } mLineEdit->setText( nullText ); QVariantList nullAttributes; - for ( const QString &fieldName : qgis::as_const( mReferencedFields ) ) + for ( const QString &fieldName : std::as_const( mReferencedFields ) ) { Q_UNUSED( fieldName ); nullAttributes << QVariant( QVariant::Int ); @@ -513,7 +513,7 @@ void QgsRelationReferenceWidget::init() if ( !mFilterFields.isEmpty() ) { - for ( const QString &fieldName : qgis::as_const( mFilterFields ) ) + for ( const QString &fieldName : std::as_const( mFilterFields ) ) { int idx = mReferencedLayer->fields().lookupField( fieldName ); @@ -769,14 +769,14 @@ void QgsRelationReferenceWidget::featureIdentified( const QgsFeature &feature ) if ( expr.hasEvalError() ) { QStringList titleFields; - for ( const QString &fieldName : qgis::as_const( mReferencedFields ) ) + for ( const QString &fieldName : std::as_const( mReferencedFields ) ) titleFields << mFeature.attribute( fieldName ).toString(); title = titleFields.join( QLatin1Char( ' ' ) ); } mLineEdit->setText( title ); mForeignKeys.clear(); mFeature = feature; - for ( const QString &fieldName : qgis::as_const( mReferencedFields ) ) + for ( const QString &fieldName : std::as_const( mReferencedFields ) ) mForeignKeys << mFeature.attribute( fieldName ); } else @@ -1028,7 +1028,7 @@ void QgsRelationReferenceWidget::entryAdded( const QgsFeature &feat ) if ( mEditorContext.vectorLayerTools()->addFeature( mReferencedLayer, attributes, f.geometry(), &f ) ) { QVariantList attrs; - for ( const QString &fieldName : qgis::as_const( mReferencedFields ) ) + for ( const QString &fieldName : std::as_const( mReferencedFields ) ) attrs << f.attribute( fieldName ); setForeignKeys( attrs ); diff --git a/src/gui/editorwidgets/qgsvaluerelationsearchwidgetwrapper.cpp b/src/gui/editorwidgets/qgsvaluerelationsearchwidgetwrapper.cpp index ad6f7e4fe33a..9be8a6adc54f 100644 --- a/src/gui/editorwidgets/qgsvaluerelationsearchwidgetwrapper.cpp +++ b/src/gui/editorwidgets/qgsvaluerelationsearchwidgetwrapper.cpp @@ -233,7 +233,7 @@ void QgsValueRelationSearchWidgetWrapper::initWidget( QWidget *editor ) { QStringList values; values.reserve( mCache.size() ); - for ( const QgsValueRelationFieldFormatter::ValueRelationItem &i : qgis::as_const( mCache ) ) + for ( const QgsValueRelationFieldFormatter::ValueRelationItem &i : std::as_const( mCache ) ) { values << i.value; } diff --git a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp index 3c6ace1cfb13..1ca3aaa62ac8 100644 --- a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp +++ b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp @@ -79,7 +79,7 @@ QVariant QgsValueRelationWidgetWrapper::value() const QVariantList vl; //store as QVariantList because the field type supports data structure - for ( const QString &s : qgis::as_const( selection ) ) + for ( const QString &s : std::as_const( selection ) ) { // Convert to proper type const QVariant::Type type { fkType() }; @@ -111,7 +111,7 @@ QVariant QgsValueRelationWidgetWrapper::value() const if ( mLineEdit ) { - for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : qgis::as_const( mCache ) ) + for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : std::as_const( mCache ) ) { if ( item.value == mLineEdit->text() ) { @@ -247,7 +247,7 @@ void QgsValueRelationWidgetWrapper::updateValues( const QVariant &value, const Q { mLineEdit->clear(); bool wasFound { false }; - for ( const QgsValueRelationFieldFormatter::ValueRelationItem &i : qgis::as_const( mCache ) ) + for ( const QgsValueRelationFieldFormatter::ValueRelationItem &i : std::as_const( mCache ) ) { if ( i.key == value ) { @@ -381,7 +381,7 @@ void QgsValueRelationWidgetWrapper::populate( ) whileBlocking( mComboBox )->addItem( tr( "(no selection)" ), QVariant( field().type( ) ) ); } - for ( const QgsValueRelationFieldFormatter::ValueRelationItem &element : qgis::as_const( mCache ) ) + for ( const QgsValueRelationFieldFormatter::ValueRelationItem &element : std::as_const( mCache ) ) { whileBlocking( mComboBox )->addItem( element.value, element.key ); if ( !element.description.isEmpty() ) @@ -404,7 +404,7 @@ void QgsValueRelationWidgetWrapper::populate( ) whileBlocking( mTableWidget )->clear(); int row = 0; int column = 0; - for ( const QgsValueRelationFieldFormatter::ValueRelationItem &element : qgis::as_const( mCache ) ) + for ( const QgsValueRelationFieldFormatter::ValueRelationItem &element : std::as_const( mCache ) ) { if ( column == nofColumns ) { @@ -423,7 +423,7 @@ void QgsValueRelationWidgetWrapper::populate( ) { QStringList values; values.reserve( mCache.size() ); - for ( const QgsValueRelationFieldFormatter::ValueRelationItem &i : qgis::as_const( mCache ) ) + for ( const QgsValueRelationFieldFormatter::ValueRelationItem &i : std::as_const( mCache ) ) { values << i.value; } diff --git a/src/gui/layertree/qgslayertreeviewdefaultactions.cpp b/src/gui/layertree/qgslayertreeviewdefaultactions.cpp index ec734e017c9c..7d68aa1b3d9f 100644 --- a/src/gui/layertree/qgslayertreeviewdefaultactions.cpp +++ b/src/gui/layertree/qgslayertreeviewdefaultactions.cpp @@ -480,7 +480,7 @@ void QgsLayerTreeViewDefaultActions::moveToTop() { return a->depth() > b->depth(); } ); - for ( QgsLayerTreeNode *n : qgis::as_const( selectedNodes ) ) + for ( QgsLayerTreeNode *n : std::as_const( selectedNodes ) ) { QgsLayerTreeGroup *parentGroup = qobject_cast( n->parent() ); QgsLayerTreeNode *clonedNode = n->clone(); @@ -498,7 +498,7 @@ void QgsLayerTreeViewDefaultActions::moveToBottom() { return a->depth() > b->depth(); } ); - for ( QgsLayerTreeNode *n : qgis::as_const( selectedNodes ) ) + for ( QgsLayerTreeNode *n : std::as_const( selectedNodes ) ) { QgsLayerTreeGroup *parentGroup = qobject_cast( n->parent() ); QgsLayerTreeNode *clonedNode = n->clone(); diff --git a/src/gui/layout/qgslayoutguiutils.cpp b/src/gui/layout/qgslayoutguiutils.cpp index e1458805c6d5..a4a94174816b 100644 --- a/src/gui/layout/qgslayoutguiutils.cpp +++ b/src/gui/layout/qgslayoutguiutils.cpp @@ -61,7 +61,7 @@ QgsLayoutItemMap *findSensibleDefaultLinkedMapItem( QgsLayoutItem *referenceItem referenceItem->layout()->layoutItems( mapItems ); QgsLayoutItemMap *targetMap = nullptr; - for ( QgsLayoutItemMap *map : qgis::as_const( mapItems ) ) + for ( QgsLayoutItemMap *map : std::as_const( mapItems ) ) { if ( map->isSelected() ) { @@ -71,7 +71,7 @@ QgsLayoutItemMap *findSensibleDefaultLinkedMapItem( QgsLayoutItem *referenceItem // nope, no selection... hm, was the item drawn over a map? If so, use the topmost intersecting one double largestZValue = std::numeric_limits< double >::lowest(); - for ( QgsLayoutItemMap *map : qgis::as_const( mapItems ) ) + for ( QgsLayoutItemMap *map : std::as_const( mapItems ) ) { if ( map->collidesWithItem( referenceItem ) && map->zValue() > largestZValue ) { @@ -140,7 +140,7 @@ void QgsLayoutGuiUtils::registerGuiForKnownItemTypes( QgsMapCanvas *mapCanvas ) while ( true ) { existing = false; - for ( QgsLayoutItemMap *otherMap : qgis::as_const( mapsList ) ) + for ( QgsLayoutItemMap *otherMap : std::as_const( mapsList ) ) { if ( map == otherMap ) continue; @@ -280,7 +280,7 @@ void QgsLayoutGuiUtils::registerGuiForKnownItemTypes( QgsMapCanvas *mapCanvas ) QgsSettings settings; const QString defaultPath = settings.value( QStringLiteral( "LayoutDesigner/defaultNorthArrow" ), QStringLiteral( ":/images/north_arrows/layout_default_north_arrow.svg" ), QgsSettings::Gui ).toString(); - for ( QgsLayoutItemPicture *p : qgis::as_const( pictureItems ) ) + for ( QgsLayoutItemPicture *p : std::as_const( pictureItems ) ) { // look for pictures which use the default north arrow svg if ( p->picturePath() == defaultPath ) diff --git a/src/gui/layout/qgslayoutlabelwidget.cpp b/src/gui/layout/qgslayoutlabelwidget.cpp index f9ae1e7694d1..678d652d94f9 100644 --- a/src/gui/layout/qgslayoutlabelwidget.cpp +++ b/src/gui/layout/qgslayoutlabelwidget.cpp @@ -106,11 +106,11 @@ void QgsLayoutLabelWidget::buildInsertDynamicTextMenu( QgsLayout *layout, QMenu QMenu *dateMenu = new QMenu( tr( "Current Date" ), menu ); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "ISO Format (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "yyyy-MM-dd" ) ) ), QStringLiteral( "format_date(now(), 'yyyy-MM-dd')" ) ), - std::make_pair( tr( "Day/Month/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "dd/MM/yyyy" ) ) ), QStringLiteral( "format_date(now(), 'dd/MM/yyyy')" ) ), - std::make_pair( tr( "Month/Day/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "MM/dd/yyyy" ) ) ), QStringLiteral( "format_date(now(), 'MM/dd/yyyy')" ) ), - } ) +{ + std::make_pair( tr( "ISO Format (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "yyyy-MM-dd" ) ) ), QStringLiteral( "format_date(now(), 'yyyy-MM-dd')" ) ), + std::make_pair( tr( "Day/Month/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "dd/MM/yyyy" ) ) ), QStringLiteral( "format_date(now(), 'dd/MM/yyyy')" ) ), + std::make_pair( tr( "Month/Day/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "MM/dd/yyyy" ) ) ), QStringLiteral( "format_date(now(), 'MM/dd/yyyy')" ) ), + } ) { addExpression( dateMenu, expression.first, expression.second ); } @@ -119,7 +119,7 @@ void QgsLayoutLabelWidget::buildInsertDynamicTextMenu( QgsLayout *layout, QMenu QMenu *mapsMenu = new QMenu( tr( "Map Properties" ), menu ); QList< QgsLayoutItemMap * > maps; layout->layoutItems( maps ); - for ( QgsLayoutItemMap *map : qgis::as_const( maps ) ) + for ( QgsLayoutItemMap *map : std::as_const( maps ) ) { // these expressions require the map to have a non-empty ID set if ( map->id().isEmpty() ) @@ -127,21 +127,21 @@ void QgsLayoutLabelWidget::buildInsertDynamicTextMenu( QgsLayout *layout, QMenu QMenu *mapMenu = new QMenu( map->displayName(), mapsMenu ); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "Scale (%1)" ).arg( map->scale() ), QStringLiteral( "item_variables('%1')['map_scale']" ).arg( map->id() ) ), - std::make_pair( tr( "Rotation (%1)" ).arg( map->rotation() ), QStringLiteral( "item_variables('%1')['map_rotation']" ).arg( map->id() ) ), - } ) + { + std::make_pair( tr( "Scale (%1)" ).arg( map->scale() ), QStringLiteral( "item_variables('%1')['map_scale']" ).arg( map->id() ) ), + std::make_pair( tr( "Rotation (%1)" ).arg( map->rotation() ), QStringLiteral( "item_variables('%1')['map_rotation']" ).arg( map->id() ) ), + } ) { addExpression( mapMenu, expression.first, expression.second ); } mapMenu->addSeparator(); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "CRS Identifier (%1)" ).arg( map->crs().authid() ), QStringLiteral( "item_variables('%1')['map_crs']" ).arg( map->id() ) ), - std::make_pair( tr( "CRS Name (%1)" ).arg( map->crs().description() ), QStringLiteral( "item_variables('%1')['map_crs_description']" ).arg( map->id() ) ), - std::make_pair( tr( "Ellipsoid Name (%1)" ).arg( map->crs().ellipsoidAcronym() ), QStringLiteral( "item_variables('%1')['map_crs_ellipsoid']" ).arg( map->id() ) ), - std::make_pair( tr( "Units (%1)" ).arg( QgsUnitTypes::toString( map->crs().mapUnits() ) ), QStringLiteral( "item_variables('%1')['map_units']" ).arg( map->id() ) ), - } ) + { + std::make_pair( tr( "CRS Identifier (%1)" ).arg( map->crs().authid() ), QStringLiteral( "item_variables('%1')['map_crs']" ).arg( map->id() ) ), + std::make_pair( tr( "CRS Name (%1)" ).arg( map->crs().description() ), QStringLiteral( "item_variables('%1')['map_crs_description']" ).arg( map->id() ) ), + std::make_pair( tr( "Ellipsoid Name (%1)" ).arg( map->crs().ellipsoidAcronym() ), QStringLiteral( "item_variables('%1')['map_crs_ellipsoid']" ).arg( map->id() ) ), + std::make_pair( tr( "Units (%1)" ).arg( QgsUnitTypes::toString( map->crs().mapUnits() ) ), QStringLiteral( "item_variables('%1')['map_units']" ).arg( map->id() ) ), + } ) { addExpression( mapMenu, expression.first, expression.second ); } @@ -150,22 +150,22 @@ void QgsLayoutLabelWidget::buildInsertDynamicTextMenu( QgsLayout *layout, QMenu const QgsRectangle mapExtent = map->extent(); const QgsPointXY center = mapExtent.center(); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "Center (X) (%1)" ).arg( center.x() ), QStringLiteral( "x(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ), - std::make_pair( tr( "Center (Y) (%1)" ).arg( center.y() ), QStringLiteral( "y(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ), - std::make_pair( tr( "X Minimum (%1)" ).arg( mapExtent.xMinimum() ), QStringLiteral( "x_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), - std::make_pair( tr( "Y Minimum (%1)" ).arg( mapExtent.yMinimum() ), QStringLiteral( "y_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), - std::make_pair( tr( "X Maximum (%1)" ).arg( mapExtent.xMaximum() ), QStringLiteral( "x_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), - std::make_pair( tr( "Y Maximum (%1)" ).arg( mapExtent.yMaximum() ), QStringLiteral( "y_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), - } ) + { + std::make_pair( tr( "Center (X) (%1)" ).arg( center.x() ), QStringLiteral( "x(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ), + std::make_pair( tr( "Center (Y) (%1)" ).arg( center.y() ), QStringLiteral( "y(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ), + std::make_pair( tr( "X Minimum (%1)" ).arg( mapExtent.xMinimum() ), QStringLiteral( "x_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), + std::make_pair( tr( "Y Minimum (%1)" ).arg( mapExtent.yMinimum() ), QStringLiteral( "y_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), + std::make_pair( tr( "X Maximum (%1)" ).arg( mapExtent.xMaximum() ), QStringLiteral( "x_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), + std::make_pair( tr( "Y Maximum (%1)" ).arg( mapExtent.yMaximum() ), QStringLiteral( "y_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), + } ) { addExpression( mapMenu, expression.first, expression.second ); } mapMenu->addSeparator(); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "Layer Credits" ), QStringLiteral( "array_to_string(map_credits('%1'))" ).arg( map->id() ) ), - } ) + { + std::make_pair( tr( "Layer Credits" ), QStringLiteral( "array_to_string(map_credits('%1'))" ).arg( map->id() ) ), + } ) { addExpression( mapMenu, expression.first, expression.second ); } @@ -189,30 +189,30 @@ void QgsLayoutLabelWidget::buildInsertDynamicTextMenu( QgsLayout *layout, QMenu } for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "Layout Name" ), QStringLiteral( "@layout_name" ) ), - std::make_pair( tr( "Layout Page Number" ), QStringLiteral( "@layout_page" ) ), - std::make_pair( tr( "Layout Page Count" ), QStringLiteral( "@layout_numpages" ) ) - } ) +{ + std::make_pair( tr( "Layout Name" ), QStringLiteral( "@layout_name" ) ), + std::make_pair( tr( "Layout Page Number" ), QStringLiteral( "@layout_page" ) ), + std::make_pair( tr( "Layout Page Count" ), QStringLiteral( "@layout_numpages" ) ) + } ) { addExpression( menu, expression.first, expression.second ); } menu->addSeparator(); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "Project Author" ), QStringLiteral( "@project_author" ) ), - std::make_pair( tr( "Project Title" ), QStringLiteral( "@project_title" ) ), - std::make_pair( tr( "Project Path" ), QStringLiteral( "@project_path" ) ) - } ) +{ + std::make_pair( tr( "Project Author" ), QStringLiteral( "@project_author" ) ), + std::make_pair( tr( "Project Title" ), QStringLiteral( "@project_title" ) ), + std::make_pair( tr( "Project Path" ), QStringLiteral( "@project_path" ) ) + } ) { addExpression( menu, expression.first, expression.second ); } menu->addSeparator(); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "Current User Name" ), QStringLiteral( "@user_full_name" ) ), - std::make_pair( tr( "Current User Account" ), QStringLiteral( "@user_account_name" ) ) - } ) +{ + std::make_pair( tr( "Current User Name" ), QStringLiteral( "@user_full_name" ) ), + std::make_pair( tr( "Current User Account" ), QStringLiteral( "@user_account_name" ) ) + } ) { addExpression( menu, expression.first, expression.second ); } diff --git a/src/gui/layout/qgslayoutlegendwidget.cpp b/src/gui/layout/qgslayoutlegendwidget.cpp index ebe2db1150c2..4e77b6b3fea6 100644 --- a/src/gui/layout/qgslayoutlegendwidget.cpp +++ b/src/gui/layout/qgslayoutlegendwidget.cpp @@ -797,7 +797,7 @@ void QgsLayoutLegendWidget::mCheckBoxAutoUpdate_stateChanged( int state, bool us widgets << mMoveDownToolButton << mMoveUpToolButton << mRemoveToolButton << mAddToolButton << mEditPushButton << mCountToolButton << mUpdateAllPushButton << mAddGroupToolButton << mExpressionFilterButton; - for ( QWidget *w : qgis::as_const( widgets ) ) + for ( QWidget *w : std::as_const( widgets ) ) w->setEnabled( state != Qt::Checked ); if ( state == Qt::Unchecked ) @@ -947,7 +947,7 @@ void QgsLayoutLegendWidget::mRemoveToolButton_clicked() // first try to remove legend nodes QHash > nodesWithRemoval; - for ( const QPersistentModelIndex &proxyIndex : qgis::as_const( proxyIndexes ) ) + for ( const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) ) { if ( QgsLayerTreeModelLegendNode *legendNode = mItemTreeView->index2legendNode( proxyIndex ) ) { @@ -961,7 +961,7 @@ void QgsLayoutLegendWidget::mRemoveToolButton_clicked() std::sort( toDelete.begin(), toDelete.end(), std::greater() ); QList order = QgsMapLayerLegendUtils::legendNodeOrder( it.key() ); - for ( int i : qgis::as_const( toDelete ) ) + for ( int i : std::as_const( toDelete ) ) { if ( i >= 0 && i < order.count() ) order.removeAt( i ); @@ -972,7 +972,7 @@ void QgsLayoutLegendWidget::mRemoveToolButton_clicked() } // then remove layer tree nodes - for ( const QPersistentModelIndex &proxyIndex : qgis::as_const( proxyIndexes ) ) + for ( const QPersistentModelIndex &proxyIndex : std::as_const( proxyIndexes ) ) { if ( proxyIndex.isValid() && mItemTreeView->index2node( proxyIndex ) ) { @@ -1426,7 +1426,7 @@ QMenu *QgsLayoutLegendMenuProvider::createContextMenu() QList lst; lst << QgsLegendStyle::Hidden << QgsLegendStyle::Group << QgsLegendStyle::Subgroup; - for ( QgsLegendStyle::Style style : qgis::as_const( lst ) ) + for ( QgsLegendStyle::Style style : std::as_const( lst ) ) { QAction *action = menu->addAction( QgsLegendStyle::styleLabel( style ), mWidget, &QgsLayoutLegendWidget::setCurrentNodeStyleFromAction ); action->setCheckable( true ); diff --git a/src/gui/layout/qgslayoutvaliditychecks.cpp b/src/gui/layout/qgslayoutvaliditychecks.cpp index b9cd481ca8ef..fc071ea51fbd 100644 --- a/src/gui/layout/qgslayoutvaliditychecks.cpp +++ b/src/gui/layout/qgslayoutvaliditychecks.cpp @@ -53,7 +53,7 @@ bool QgsLayoutScaleBarValidityCheck::prepareCheck( const QgsValidityCheckContext QList< QgsLayoutItemScaleBar * > barItems; layoutContext->layout->layoutItems( barItems ); - for ( QgsLayoutItemScaleBar *bar : qgis::as_const( barItems ) ) + for ( QgsLayoutItemScaleBar *bar : std::as_const( barItems ) ) { if ( !bar->linkedMap() ) { @@ -108,7 +108,7 @@ bool QgsLayoutNorthArrowValidityCheck::prepareCheck( const QgsValidityCheckConte QList< QgsLayoutItemPicture * > pictureItems; layoutContext->layout->layoutItems( pictureItems ); - for ( QgsLayoutItemPicture *picture : qgis::as_const( pictureItems ) ) + for ( QgsLayoutItemPicture *picture : std::as_const( pictureItems ) ) { // look for pictures which use the default north arrow svg, but aren't actually linked to maps. // alternatively identify them by looking for the default "North Arrow" string in their id @@ -163,7 +163,7 @@ bool QgsLayoutOverviewValidityCheck::prepareCheck( const QgsValidityCheckContext QList< QgsLayoutItemMap * > mapItems; layoutContext->layout->layoutItems( mapItems ); - for ( QgsLayoutItemMap *map : qgis::as_const( mapItems ) ) + for ( QgsLayoutItemMap *map : std::as_const( mapItems ) ) { for ( int i = 0; i < map->overviews()->size(); ++i ) { @@ -220,7 +220,7 @@ bool QgsLayoutPictureSourceValidityCheck::prepareCheck( const QgsValidityCheckCo QList< QgsLayoutItemPicture * > pictureItems; layoutContext->layout->layoutItems( pictureItems ); - for ( QgsLayoutItemPicture *picture : qgis::as_const( pictureItems ) ) + for ( QgsLayoutItemPicture *picture : std::as_const( pictureItems ) ) { if ( picture->isMissingImage() ) { diff --git a/src/gui/layout/qgslayoutview.cpp b/src/gui/layout/qgslayoutview.cpp index 030ca7960d24..fec49b64bbfc 100644 --- a/src/gui/layout/qgslayoutview.cpp +++ b/src/gui/layout/qgslayoutview.cpp @@ -918,7 +918,7 @@ void QgsLayoutView::ungroupSelectedItems() if ( !ungroupedItems.empty() ) { - for ( QgsLayoutItem *item : qgis::as_const( ungroupedItems ) ) + for ( QgsLayoutItem *item : std::as_const( ungroupedItems ) ) { item->setSelected( true ); } @@ -1163,7 +1163,7 @@ void QgsLayoutView::invalidateCachedRenders() QList< QgsLayoutItem *> items; currentLayout()->layoutItems( items ); - for ( QgsLayoutItem *item : qgis::as_const( items ) ) + for ( QgsLayoutItem *item : std::as_const( items ) ) { item->invalidateCache(); } diff --git a/src/gui/layout/qgslayoutviewtooleditnodes.cpp b/src/gui/layout/qgslayoutviewtooleditnodes.cpp index 606aa917f604..d76ab3042da0 100644 --- a/src/gui/layout/qgslayoutviewtooleditnodes.cpp +++ b/src/gui/layout/qgslayoutviewtooleditnodes.cpp @@ -243,7 +243,7 @@ void QgsLayoutViewToolEditNodes::displayNodes( bool display ) QList nodesShapes; layout()->layoutItems( nodesShapes ); - for ( QgsLayoutNodesItem *item : qgis::as_const( nodesShapes ) ) + for ( QgsLayoutNodesItem *item : std::as_const( nodesShapes ) ) { item->setDisplayNodes( display ); item->update(); @@ -255,7 +255,7 @@ void QgsLayoutViewToolEditNodes::deselectNodes() QList nodesShapes; layout()->layoutItems( nodesShapes ); - for ( QgsLayoutNodesItem *item : qgis::as_const( nodesShapes ) ) + for ( QgsLayoutNodesItem *item : std::as_const( nodesShapes ) ) { item->deselectNode(); item->update(); @@ -267,7 +267,7 @@ void QgsLayoutViewToolEditNodes::setSelectedNode( QgsLayoutNodesItem *shape, int QList nodesShapes; layout()->layoutItems( nodesShapes ); - for ( QgsLayoutNodesItem *item : qgis::as_const( nodesShapes ) ) + for ( QgsLayoutNodesItem *item : std::as_const( nodesShapes ) ) { if ( item == shape ) { diff --git a/src/gui/layout/qgslayoutviewtoolselect.cpp b/src/gui/layout/qgslayoutviewtoolselect.cpp index 9f86f211c351..106d2d6d2357 100644 --- a/src/gui/layout/qgslayoutviewtoolselect.cpp +++ b/src/gui/layout/qgslayoutviewtoolselect.cpp @@ -218,7 +218,7 @@ void QgsLayoutViewToolSelect::layoutReleaseEvent( QgsLayoutViewMouseEvent *event itemList = layout()->items( rect.center(), selectionMode ); else itemList = layout()->items( rect, selectionMode ); - for ( QGraphicsItem *item : qgis::as_const( itemList ) ) + for ( QGraphicsItem *item : std::as_const( itemList ) ) { QgsLayoutItem *layoutItem = dynamic_cast( item ); QgsLayoutItemPage *paperItem = dynamic_cast( item ); diff --git a/src/gui/locator/qgslocatorwidget.cpp b/src/gui/locator/qgslocatorwidget.cpp index 04b169a459ea..466161f947f9 100644 --- a/src/gui/locator/qgslocatorwidget.cpp +++ b/src/gui/locator/qgslocatorwidget.cpp @@ -132,7 +132,7 @@ void QgsLocatorWidget::setMapCanvas( QgsMapCanvas *canvas ) if ( mMapCanvas == canvas ) return; - for ( const QMetaObject::Connection &conn : qgis::as_const( mCanvasConnections ) ) + for ( const QMetaObject::Connection &conn : std::as_const( mCanvasConnections ) ) { disconnect( conn ); } diff --git a/src/gui/numericformats/qgsnumericformatselectorwidget.cpp b/src/gui/numericformats/qgsnumericformatselectorwidget.cpp index a08d7ebfb138..214f212981a6 100644 --- a/src/gui/numericformats/qgsnumericformatselectorwidget.cpp +++ b/src/gui/numericformats/qgsnumericformatselectorwidget.cpp @@ -122,7 +122,7 @@ void QgsNumericFormatSelectorWidget::populateTypes() return false; } ); - for ( const QString &id : qgis::as_const( ids ) ) + for ( const QString &id : std::as_const( ids ) ) mCategoryCombo->addItem( QgsApplication::numericFormatRegistry()->visibleName( id ), id ); } diff --git a/src/gui/ogr/qgsvectorlayersaveasdialog.cpp b/src/gui/ogr/qgsvectorlayersaveasdialog.cpp index 7c3bd2044786..b0f54f429cf9 100644 --- a/src/gui/ogr/qgsvectorlayersaveasdialog.cpp +++ b/src/gui/ogr/qgsvectorlayersaveasdialog.cpp @@ -228,7 +228,7 @@ QList > QgsVectorLayerSaveAsDialog::createControls( c { QComboBox *cb = new QComboBox(); cb->setObjectName( it.key() ); - for ( const QString &val : qgis::as_const( opt->values ) ) + for ( const QString &val : std::as_const( opt->values ) ) { cb->addItem( val, val ); } diff --git a/src/gui/processing/models/qgsmodeldesignerdialog.cpp b/src/gui/processing/models/qgsmodeldesignerdialog.cpp index f0ccdba1e7aa..7f61d4ad269c 100644 --- a/src/gui/processing/models/qgsmodeldesignerdialog.cpp +++ b/src/gui/processing/models/qgsmodeldesignerdialog.cpp @@ -951,7 +951,7 @@ void QgsModelDesignerDialog::fillInputsTree() return QString::localeAwareCompare( a->name(), b->name() ) < 0; } ); - for ( QgsProcessingParameterType *param : qgis::as_const( available ) ) + for ( QgsProcessingParameterType *param : std::as_const( available ) ) { if ( param->flags() & QgsProcessingParameterType::ExposeToModeler ) { diff --git a/src/gui/processing/models/qgsmodelgraphicsview.cpp b/src/gui/processing/models/qgsmodelgraphicsview.cpp index 506810070cf0..aee41d174c76 100644 --- a/src/gui/processing/models/qgsmodelgraphicsview.cpp +++ b/src/gui/processing/models/qgsmodelgraphicsview.cpp @@ -776,17 +776,17 @@ void QgsModelGraphicsView::pasteItems( QgsModelGraphicsView::PasteMode mode ) if ( !offset.isNull() ) { - for ( QgsProcessingModelGroupBox pastedGroup : qgis::as_const( pastedGroups ) ) + for ( QgsProcessingModelGroupBox pastedGroup : std::as_const( pastedGroups ) ) { pastedGroup.setPosition( pastedGroup.position() + offset ); modelScene()->model()->addGroupBox( pastedGroup ); } - for ( const QString &pastedParam : qgis::as_const( pastedParameters ) ) + for ( const QString &pastedParam : std::as_const( pastedParameters ) ) { modelScene()->model()->parameterComponent( pastedParam ).setPosition( modelScene()->model()->parameterComponent( pastedParam ).position() + offset ); modelScene()->model()->parameterComponent( pastedParam ).comment()->setPosition( modelScene()->model()->parameterComponent( pastedParam ).comment()->position() + offset ); } - for ( const QString &pastedAlg : qgis::as_const( pastedAlgorithms ) ) + for ( const QString &pastedAlg : std::as_const( pastedAlgorithms ) ) { modelScene()->model()->childAlgorithm( pastedAlg ).setPosition( modelScene()->model()->childAlgorithm( pastedAlg ).position() + offset ); modelScene()->model()->childAlgorithm( pastedAlg ).comment()->setPosition( modelScene()->model()->childAlgorithm( pastedAlg ).comment()->position() + offset ); diff --git a/src/gui/processing/models/qgsmodelinputreorderwidget.cpp b/src/gui/processing/models/qgsmodelinputreorderwidget.cpp index 43bc5077b8af..312b55cac008 100644 --- a/src/gui/processing/models/qgsmodelinputreorderwidget.cpp +++ b/src/gui/processing/models/qgsmodelinputreorderwidget.cpp @@ -61,7 +61,7 @@ void QgsModelInputReorderWidget::setModel( QgsProcessingModelAlgorithm *model ) mParameters = mModel->orderedParameters(); QStringList res; mItemModel->clear(); - for ( const QgsProcessingModelParameter ¶m : qgis::as_const( mParameters ) ) + for ( const QgsProcessingModelParameter ¶m : std::as_const( mParameters ) ) { QStandardItem *item = new QStandardItem( mModel->parameterDefinition( param.parameterName() )->description() ); item->setData( param.parameterName() ); diff --git a/src/gui/processing/models/qgsmodelviewtoolselect.cpp b/src/gui/processing/models/qgsmodelviewtoolselect.cpp index 63d2a2e6a222..433b06de26ba 100644 --- a/src/gui/processing/models/qgsmodelviewtoolselect.cpp +++ b/src/gui/processing/models/qgsmodelviewtoolselect.cpp @@ -271,7 +271,7 @@ void QgsModelViewToolSelect::modelReleaseEvent( QgsModelViewMouseEvent *event ) itemList = scene()->items( rect.center(), selectionMode ); else itemList = scene()->items( rect, selectionMode ); - for ( QGraphicsItem *item : qgis::as_const( itemList ) ) + for ( QGraphicsItem *item : std::as_const( itemList ) ) { if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast( item ) ) { diff --git a/src/gui/processing/qgsprocessingenummodelerwidget.cpp b/src/gui/processing/qgsprocessingenummodelerwidget.cpp index 699be7b1bc70..87e5603b6518 100644 --- a/src/gui/processing/qgsprocessingenummodelerwidget.cpp +++ b/src/gui/processing/qgsprocessingenummodelerwidget.cpp @@ -64,7 +64,7 @@ void QgsProcessingEnumModelerWidget::removeItems( const bool removeAll ) std::sort( rowsToDelete.begin(), rowsToDelete.end(), std::greater() ); mItemList->setUpdatesEnabled( false ); - for ( int i : qgis::as_const( rowsToDelete ) ) + for ( int i : std::as_const( rowsToDelete ) ) mModel->removeRows( i, 1 ); mItemList->setUpdatesEnabled( true ); } diff --git a/src/gui/processing/qgsprocessingmaplayercombobox.cpp b/src/gui/processing/qgsprocessingmaplayercombobox.cpp index 20110bc1d7d9..465ac09faf30 100644 --- a/src/gui/processing/qgsprocessingmaplayercombobox.cpp +++ b/src/gui/processing/qgsprocessingmaplayercombobox.cpp @@ -510,7 +510,7 @@ QString QgsProcessingMapLayerComboBox::compatibleUriFromMimeData( const QMimeDat if ( !data->text().isEmpty() && !rawPaths.contains( data->text() ) ) rawPaths.append( data->text() ); - for ( const QString &path : qgis::as_const( rawPaths ) ) + for ( const QString &path : std::as_const( rawPaths ) ) { QFileInfo file( path ); if ( file.isFile() ) diff --git a/src/gui/processing/qgsprocessingmatrixmodelerwidget.cpp b/src/gui/processing/qgsprocessingmatrixmodelerwidget.cpp index e5e28d958fec..26b068db78bc 100644 --- a/src/gui/processing/qgsprocessingmatrixmodelerwidget.cpp +++ b/src/gui/processing/qgsprocessingmatrixmodelerwidget.cpp @@ -54,7 +54,7 @@ void QgsProcessingMatrixModelerWidget::removeColumns() std::sort( selected.begin(), selected.end(), []( const QModelIndex & a, const QModelIndex & b ) { return b < a; } ); mTableView->setUpdatesEnabled( false ); - for ( QModelIndex i : qgis::as_const( selected ) ) + for ( QModelIndex i : std::as_const( selected ) ) mModel->removeColumns( i.column(), 1 ); mTableView->setUpdatesEnabled( true ); @@ -75,7 +75,7 @@ void QgsProcessingMatrixModelerWidget::removeRows() std::sort( selected.begin(), selected.end(), []( const QModelIndex & a, const QModelIndex & b ) { return b < a; } ); mTableView->setUpdatesEnabled( false ); - for ( QModelIndex i : qgis::as_const( selected ) ) + for ( QModelIndex i : std::as_const( selected ) ) mModel->removeRows( i.row(), 1 ); mTableView->setUpdatesEnabled( true ); diff --git a/src/gui/processing/qgsprocessingmatrixparameterdialog.cpp b/src/gui/processing/qgsprocessingmatrixparameterdialog.cpp index f84a33229ade..7efeb22a25cb 100644 --- a/src/gui/processing/qgsprocessingmatrixparameterdialog.cpp +++ b/src/gui/processing/qgsprocessingmatrixparameterdialog.cpp @@ -105,7 +105,7 @@ void QgsProcessingMatrixParameterPanelWidget::deleteRow() QList< int > rowsToDelete = qgis::setToList( rows ); std::sort( rowsToDelete.begin(), rowsToDelete.end(), std::greater() ); mTblView->setUpdatesEnabled( false ); - for ( int i : qgis::as_const( rowsToDelete ) ) + for ( int i : std::as_const( rowsToDelete ) ) mModel->removeRows( i, 1 ); mTblView->setUpdatesEnabled( true ); diff --git a/src/gui/processing/qgsprocessingmultipleselectiondialog.cpp b/src/gui/processing/qgsprocessingmultipleselectiondialog.cpp index c64fee09bc97..091fff8522c1 100644 --- a/src/gui/processing/qgsprocessingmultipleselectiondialog.cpp +++ b/src/gui/processing/qgsprocessingmultipleselectiondialog.cpp @@ -175,7 +175,7 @@ void QgsProcessingMultipleSelectionPanelWidget::populateList( const QVariantList remainingOptions.removeAll( option ); } - for ( const QVariant &option : qgis::as_const( remainingOptions ) ) + for ( const QVariant &option : std::as_const( remainingOptions ) ) { addOption( option, mValueFormatter( option ), false ); } diff --git a/src/gui/processing/qgsprocessingoutputdestinationwidget.cpp b/src/gui/processing/qgsprocessingoutputdestinationwidget.cpp index 4edaeff5abe7..ec33c94cc12e 100644 --- a/src/gui/processing/qgsprocessingoutputdestinationwidget.cpp +++ b/src/gui/processing/qgsprocessingoutputdestinationwidget.cpp @@ -657,7 +657,7 @@ QString QgsProcessingLayerOutputDestinationWidget::mimeDataToPath( const QMimeDa if ( !data->text().isEmpty() && !rawPaths.contains( data->text() ) ) rawPaths.append( data->text() ); - for ( const QString &path : qgis::as_const( rawPaths ) ) + for ( const QString &path : std::as_const( rawPaths ) ) { QFileInfo file( path ); if ( file.isFile() && ( mParameter->type() == QgsProcessingParameterFeatureSink::typeName() diff --git a/src/gui/processing/qgsprocessingtoolboxmodel.cpp b/src/gui/processing/qgsprocessingtoolboxmodel.cpp index 6321d6195f05..db731230c20e 100644 --- a/src/gui/processing/qgsprocessingtoolboxmodel.cpp +++ b/src/gui/processing/qgsprocessingtoolboxmodel.cpp @@ -44,7 +44,7 @@ QgsProcessingToolboxModelNode *QgsProcessingToolboxModelNode::takeChild( QgsProc QgsProcessingToolboxModelGroupNode *QgsProcessingToolboxModelNode::getChildGroupNode( const QString &groupId ) { - for ( QgsProcessingToolboxModelNode *node : qgis::as_const( mChildren ) ) + for ( QgsProcessingToolboxModelNode *node : std::as_const( mChildren ) ) { if ( node->nodeType() == NodeGroup ) { @@ -199,7 +199,7 @@ void QgsProcessingToolboxModel::repopulateRecentAlgorithms( bool resetting ) beginInsertRows( recentIndex, 0, recentAlgorithms.count() - 1 ); } - for ( const QgsProcessingAlgorithm *algorithm : qgis::as_const( recentAlgorithms ) ) + for ( const QgsProcessingAlgorithm *algorithm : std::as_const( recentAlgorithms ) ) { std::unique_ptr< QgsProcessingToolboxModelAlgorithmNode > algorithmNode = std::make_unique< QgsProcessingToolboxModelAlgorithmNode >( algorithm ); mRecentNode->addChildNode( algorithmNode.release() ); @@ -750,7 +750,7 @@ bool QgsProcessingToolboxProxyModel::filterAcceptsRow( int sourceRow, const QMod for ( const QString &part : partsToMatch ) { bool found = false; - for ( const QString &partToSearch : qgis::as_const( partsToSearch ) ) + for ( const QString &partToSearch : std::as_const( partsToSearch ) ) { if ( partToSearch.contains( part, Qt::CaseInsensitive ) ) { diff --git a/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp b/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp index a7bf26437a2f..d53ca7302347 100644 --- a/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp +++ b/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp @@ -3833,7 +3833,7 @@ void QgsProcessingFieldPanelWidget::showDialog() QVariantList availableOptions; QStringList fieldNames; availableOptions.reserve( mFields.size() ); - for ( const QgsField &field : qgis::as_const( mFields ) ) + for ( const QgsField &field : std::as_const( mFields ) ) { availableOptions << field.name(); } @@ -6060,7 +6060,7 @@ void QgsProcessingRasterBandPanelWidget::showDialog() QVariantList availableOptions; QStringList fieldNames; availableOptions.reserve( mBands.size() ); - for ( int band : qgis::as_const( mBands ) ) + for ( int band : std::as_const( mBands ) ) { availableOptions << band; } diff --git a/src/gui/providers/gdal/qgsgdalsourceselect.cpp b/src/gui/providers/gdal/qgsgdalsourceselect.cpp index 0e259c1464d7..9f329af4269a 100644 --- a/src/gui/providers/gdal/qgsgdalsourceselect.cpp +++ b/src/gui/providers/gdal/qgsgdalsourceselect.cpp @@ -323,7 +323,7 @@ void QgsGdalSourceSelect::fillOpenOptions() else if ( !options.isEmpty() ) { QComboBox *cb = new QComboBox(); - for ( const QString &val : qgis::as_const( options ) ) + for ( const QString &val : std::as_const( options ) ) { cb->addItem( val, val ); } diff --git a/src/gui/providers/ogr/qgsogrdbsourceselect.cpp b/src/gui/providers/ogr/qgsogrdbsourceselect.cpp index 00412b8c716e..316f7fc50e8b 100644 --- a/src/gui/providers/ogr/qgsogrdbsourceselect.cpp +++ b/src/gui/providers/ogr/qgsogrdbsourceselect.cpp @@ -305,11 +305,11 @@ void QgsOgrDbSourceSelect::addButtonClicked() else { // Use OGR - for ( const LayerInfo &info : qgis::as_const( selectedVectors ) ) + for ( const LayerInfo &info : std::as_const( selectedVectors ) ) { emit addVectorLayer( info.first, info.second ); } - for ( const LayerInfo &info : qgis::as_const( selectedRasters ) ) + for ( const LayerInfo &info : std::as_const( selectedRasters ) ) { emit addRasterLayer( info.first, info.second, QStringLiteral( "gdal" ) ); } diff --git a/src/gui/providers/ogr/qgsogrsourceselect.cpp b/src/gui/providers/ogr/qgsogrsourceselect.cpp index 000be5a9eacb..fe30bebaefa9 100644 --- a/src/gui/providers/ogr/qgsogrsourceselect.cpp +++ b/src/gui/providers/ogr/qgsogrsourceselect.cpp @@ -735,7 +735,7 @@ void QgsOgrSourceSelect::fillOpenOptions() else if ( !options.isEmpty() ) { QComboBox *cb = new QComboBox(); - for ( const QString &val : qgis::as_const( options ) ) + for ( const QString &val : std::as_const( options ) ) { cb->addItem( val, val ); } diff --git a/src/gui/qgsaggregatetoolbutton.cpp b/src/gui/qgsaggregatetoolbutton.cpp index 938c231e0430..38c5eb14d1e1 100644 --- a/src/gui/qgsaggregatetoolbutton.cpp +++ b/src/gui/qgsaggregatetoolbutton.cpp @@ -50,7 +50,7 @@ void QgsAggregateToolButton::aboutToShowMenu() setActive( false ); } ); - for ( const auto &aggregate : qgis::as_const( mAvailableAggregates ) ) + for ( const auto &aggregate : std::as_const( mAvailableAggregates ) ) { QAction *action = mMenu->addAction( aggregate.name ); connect( action, &QAction::triggered, this, [ this, aggregate ] @@ -98,7 +98,7 @@ void QgsAggregateToolButton::setAggregate( const QString &aggregate ) mAggregate = QString(); - for ( const auto &agg : qgis::as_const( mAvailableAggregates ) ) + for ( const auto &agg : std::as_const( mAvailableAggregates ) ) { if ( agg.function == aggregate ) { diff --git a/src/gui/qgsattributeform.cpp b/src/gui/qgsattributeform.cpp index e0ddc4822171..635f1f60f535 100644 --- a/src/gui/qgsattributeform.cpp +++ b/src/gui/qgsattributeform.cpp @@ -167,7 +167,7 @@ void QgsAttributeForm::setMode( QgsAttributeEditorContext::Mode mode ) } //update all form editor widget modes to match - for ( QgsAttributeFormWidget *w : qgis::as_const( mFormWidgets ) ) + for ( QgsAttributeFormWidget *w : std::as_const( mFormWidgets ) ) { switch ( mode ) { @@ -201,7 +201,7 @@ void QgsAttributeForm::setMode( QgsAttributeEditorContext::Mode mode ) } } //update all form editor widget modes to match - for ( QgsWidgetWrapper *w : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *w : std::as_const( mWidgets ) ) { QgsAttributeEditorContext newContext = w->context(); newContext.setAttributeFormMode( mMode ); @@ -343,7 +343,7 @@ bool QgsAttributeForm::saveEdits( QString *error ) QgsAttributes src = mFeature.attributes(); QgsAttributes dst = mFeature.attributes(); - for ( QgsWidgetWrapper *ww : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *ww : std::as_const( mWidgets ) ) { QgsEditorWidgetWrapper *eww = qobject_cast( ww ); if ( eww ) @@ -489,7 +489,7 @@ bool QgsAttributeForm::updateDefaultValues( const int originIdx ) if ( mFeature.isValid() || mMode == QgsAttributeEditorContext::AddFeatureMode ) { QgsAttributes dst = mFeature.attributes(); - for ( QgsWidgetWrapper *ww : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *ww : std::as_const( mWidgets ) ) { QgsEditorWidgetWrapper *eww = qobject_cast( ww ); if ( eww ) @@ -524,7 +524,7 @@ bool QgsAttributeForm::updateDefaultValues( const int originIdx ) // go through depending fields and update the fields with defaultexpression QList relevantWidgets = mDefaultValueDependencies.values( originIdx ); - for ( QgsWidgetWrapper *ww : qgis::as_const( relevantWidgets ) ) + for ( QgsWidgetWrapper *ww : std::as_const( relevantWidgets ) ) { QgsEditorWidgetWrapper *eww = qobject_cast( ww ); if ( eww ) @@ -752,7 +752,7 @@ bool QgsAttributeForm::saveWithDetails( QString *error ) if ( mIsSaving ) return true; - for ( QgsWidgetWrapper *wrapper : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *wrapper : std::as_const( mWidgets ) ) { wrapper->notifyAboutToSave(); } @@ -850,7 +850,7 @@ void QgsAttributeForm::clearMultiEditMessages() QString QgsAttributeForm::createFilterExpression() const { QStringList filters; - for ( QgsAttributeFormWidget *w : qgis::as_const( mFormWidgets ) ) + for ( QgsAttributeFormWidget *w : std::as_const( mFormWidgets ) ) { QString filter = w->currentFilterExpression(); if ( !filter.isEmpty() ) @@ -1086,7 +1086,7 @@ bool QgsAttributeForm::currentFormValuesFeature( QgsFeature &feature ) feature = QgsFeature( mFeature ); QgsAttributes dst = feature.attributes(); - for ( QgsWidgetWrapper *ww : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *ww : std::as_const( mWidgets ) ) { QgsEditorWidgetWrapper *eww = qobject_cast( ww ); @@ -1150,7 +1150,7 @@ bool QgsAttributeForm::currentFormValidConstraints( QStringList &invalidFields, { bool valid( true ); - for ( QgsWidgetWrapper *ww : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *ww : std::as_const( mWidgets ) ) { QgsEditorWidgetWrapper *eww = qobject_cast( ww ); if ( eww ) @@ -1245,7 +1245,7 @@ QList QgsAttributeForm::constraintDependencies( QgsEdi QString name = w->field().name(); // for each widget in the current form - for ( QgsWidgetWrapper *ww : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *ww : std::as_const( mWidgets ) ) { // get the wrapper QgsEditorWidgetWrapper *eww = qobject_cast( ww ); @@ -1311,7 +1311,7 @@ void QgsAttributeForm::refreshFeature() void QgsAttributeForm::parentFormValueChanged( const QString &attribute, const QVariant &newValue ) { - for ( QgsWidgetWrapper *ww : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *ww : std::as_const( mWidgets ) ) { QgsEditorWidgetWrapper *eww = qobject_cast( ww ); if ( eww ) @@ -1327,7 +1327,7 @@ void QgsAttributeForm::synchronizeEnabledState() || mMode == QgsAttributeEditorContext::AddFeatureMode || mMode == QgsAttributeEditorContext::MultiEditMode ) && mLayer->isEditable(); - for ( QgsWidgetWrapper *ww : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *ww : std::as_const( mWidgets ) ) { QgsEditorWidgetWrapper *eww = qobject_cast( ww ); if ( eww ) @@ -2182,7 +2182,7 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt void QgsAttributeForm::addWidgetWrapper( QgsEditorWidgetWrapper *eww ) { - for ( QgsWidgetWrapper *ww : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *ww : std::as_const( mWidgets ) ) { QgsEditorWidgetWrapper *meww = qobject_cast( ww ); if ( meww ) @@ -2371,7 +2371,7 @@ void QgsAttributeForm::setMultiEditFeatureIds( const QgsFeatureIds &fids ) fit.nextFeature( firstFeature ); const auto constMixedValueFields = mixedValueFields; - for ( int fieldIndex : qgis::as_const( mixedValueFields ) ) + for ( int fieldIndex : std::as_const( mixedValueFields ) ) { if ( QgsAttributeFormEditorWidget *w = mFormEditorWidgets.value( fieldIndex, nullptr ) ) { @@ -2544,7 +2544,7 @@ void QgsAttributeForm::updateDefaultValueDependencies() { mDefaultValueDependencies.clear(); //create defaultValueDependencies - for ( QgsWidgetWrapper *ww : qgis::as_const( mWidgets ) ) + for ( QgsWidgetWrapper *ww : std::as_const( mWidgets ) ) { QgsEditorWidgetWrapper *eww = qobject_cast( ww ); if ( eww ) diff --git a/src/gui/qgscoordinateoperationwidget.cpp b/src/gui/qgscoordinateoperationwidget.cpp index 29cf846c8c4e..84d90782303d 100644 --- a/src/gui/qgscoordinateoperationwidget.cpp +++ b/src/gui/qgscoordinateoperationwidget.cpp @@ -134,7 +134,7 @@ void QgsCoordinateOperationWidget::loadAvailableOperations() int row = 0; int preferredInitialRow = -1; - for ( const QgsDatumTransform::TransformDetails &transform : qgis::as_const( mDatumTransforms ) ) + for ( const QgsDatumTransform::TransformDetails &transform : std::as_const( mDatumTransforms ) ) { std::unique_ptr< QTableWidgetItem > item = std::make_unique< QTableWidgetItem >(); item->setData( ProjRole, transform.proj ); @@ -347,7 +347,7 @@ QgsCoordinateOperationWidget::OperationDetails QgsCoordinateOperationWidget::def OperationDetails preferred; // for proj 6, return the first available transform -- they are sorted by preference by proj already - for ( const QgsDatumTransform::TransformDetails &transform : qgis::as_const( mDatumTransforms ) ) + for ( const QgsDatumTransform::TransformDetails &transform : std::as_const( mDatumTransforms ) ) { if ( transform.isAvailable ) { diff --git a/src/gui/qgsexpressionbuilderwidget.cpp b/src/gui/qgsexpressionbuilderwidget.cpp index 37f74770c0c6..e890a303a067 100644 --- a/src/gui/qgsexpressionbuilderwidget.cpp +++ b/src/gui/qgsexpressionbuilderwidget.cpp @@ -535,7 +535,7 @@ void QgsExpressionBuilderWidget::fillFieldValues( const QString &fieldName, int std::sort( values.begin(), values.end() ); mValuesModel->clear(); - for ( const QVariant &value : qgis::as_const( values ) ) + for ( const QVariant &value : std::as_const( values ) ) { QString strValue; if ( value.isNull() ) diff --git a/src/gui/qgsexpressiontreeview.cpp b/src/gui/qgsexpressiontreeview.cpp index 788e5bd7a149..795d095990b4 100644 --- a/src/gui/qgsexpressiontreeview.cpp +++ b/src/gui/qgsexpressiontreeview.cpp @@ -546,7 +546,7 @@ void QgsExpressionTreeView::loadUserExpressions( ) QString expression; int i = 0; mUserExpressionLabels = settings.childGroups(); - for ( const auto &label : qgis::as_const( mUserExpressionLabels ) ) + for ( const auto &label : std::as_const( mUserExpressionLabels ) ) { settings.beginGroup( label ); expression = settings.value( QStringLiteral( "expression" ) ).toString(); @@ -578,7 +578,7 @@ QJsonDocument QgsExpressionTreeView::exportUserExpressions() mUserExpressionLabels = settings.childGroups(); - for ( const QString &label : qgis::as_const( mUserExpressionLabels ) ) + for ( const QString &label : std::as_const( mUserExpressionLabels ) ) { settings.beginGroup( label ); @@ -749,7 +749,7 @@ const QList QgsExpressionTreeView::findExpressions( const Q { QList result; const QList found { mModel->findItems( label, Qt::MatchFlag::MatchRecursive ) }; - for ( const auto &item : qgis::as_const( found ) ) + for ( const auto &item : std::as_const( found ) ) { result.push_back( static_cast( item ) ); } diff --git a/src/gui/qgsfieldmappingmodel.cpp b/src/gui/qgsfieldmappingmodel.cpp index a4237343d548..03932051eaf4 100644 --- a/src/gui/qgsfieldmappingmodel.cpp +++ b/src/gui/qgsfieldmappingmodel.cpp @@ -288,7 +288,7 @@ QString QgsFieldMappingModel::findExpressionForDestinationField( const QgsFieldM { // Search for fields in the source // 1. match by name - for ( const QgsField &sf : qgis::as_const( mSourceFields ) ) + for ( const QgsField &sf : std::as_const( mSourceFields ) ) { if ( sf.name() == f.field.name() ) { @@ -297,7 +297,7 @@ QString QgsFieldMappingModel::findExpressionForDestinationField( const QgsFieldM } } // 2. match by type - for ( const QgsField &sf : qgis::as_const( mSourceFields ) ) + for ( const QgsField &sf : std::as_const( mSourceFields ) ) { if ( excludedFieldNames.contains( sf.name() ) || sf.type() != f.field.type() ) continue; @@ -314,7 +314,7 @@ void QgsFieldMappingModel::setSourceFields( const QgsFields &sourceFields ) mExpressionContextGenerator->setSourceFields( mSourceFields ); QStringList usedFields; beginResetModel(); - for ( const Field &f : qgis::as_const( mMapping ) ) + for ( const Field &f : std::as_const( mMapping ) ) { if ( QgsExpression( f.expression ).isField() ) { diff --git a/src/gui/qgsfilewidget.cpp b/src/gui/qgsfilewidget.cpp index ae76ae34bf0d..058370d6afbb 100644 --- a/src/gui/qgsfilewidget.cpp +++ b/src/gui/qgsfilewidget.cpp @@ -505,7 +505,7 @@ QString QgsFileDropEdit::acceptableFilePath( QDropEvent *event ) const } QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( event->mimeData() ); - for ( const QgsMimeDataUtils::Uri &u : qgis::as_const( lst ) ) + for ( const QgsMimeDataUtils::Uri &u : std::as_const( lst ) ) { if ( !rawPaths.contains( u.uri ) ) rawPaths.append( u.uri ); @@ -515,7 +515,7 @@ QString QgsFileDropEdit::acceptableFilePath( QDropEvent *event ) const rawPaths.append( event->mimeData()->text() ); paths.reserve( rawPaths.count() ); - for ( const QString &path : qgis::as_const( rawPaths ) ) + for ( const QString &path : std::as_const( rawPaths ) ) { QFileInfo file( path ); switch ( mStorageMode ) diff --git a/src/gui/qgsgraphicsviewmousehandles.cpp b/src/gui/qgsgraphicsviewmousehandles.cpp index b244cbe997c4..829fb8b4e9db 100644 --- a/src/gui/qgsgraphicsviewmousehandles.cpp +++ b/src/gui/qgsgraphicsviewmousehandles.cpp @@ -155,7 +155,7 @@ void QgsGraphicsViewMouseHandles::drawSelectedItemBounds( QPainter *painter ) QList< QGraphicsItem * > itemsToDraw; expandItemList( selectedItems, itemsToDraw ); - for ( QGraphicsItem *item : qgis::as_const( itemsToDraw ) ) + for ( QGraphicsItem *item : std::as_const( itemsToDraw ) ) { //get bounds of selected item QPolygonF itemBounds; diff --git a/src/gui/qgshistogramwidget.cpp b/src/gui/qgshistogramwidget.cpp index 7af3db2bba0e..93c1326fd4e8 100644 --- a/src/gui/qgshistogramwidget.cpp +++ b/src/gui/qgshistogramwidget.cpp @@ -201,7 +201,7 @@ void QgsHistogramWidget::drawHistogram() // make colors list mHistoColors.clear(); - for ( const QgsRendererRange &range : qgis::as_const( mRanges ) ) + for ( const QgsRendererRange &range : std::as_const( mRanges ) ) { mHistoColors << ( range.symbol() ? range.symbol()->color() : Qt::black ); } @@ -248,7 +248,7 @@ void QgsHistogramWidget::drawHistogram() plotHistogram->attach( mpPlot ); mRangeMarkers.clear(); - for ( const QgsRendererRange &range : qgis::as_const( mRanges ) ) + for ( const QgsRendererRange &range : std::as_const( mRanges ) ) { QwtPlotMarker *rangeMarker = new QwtPlotMarker(); rangeMarker->attach( mpPlot ); diff --git a/src/gui/qgslegendpatchshapebutton.cpp b/src/gui/qgslegendpatchshapebutton.cpp index 5347318c4917..bd1684661c28 100644 --- a/src/gui/qgslegendpatchshapebutton.cpp +++ b/src/gui/qgslegendpatchshapebutton.cpp @@ -194,7 +194,7 @@ void QgsLegendPatchShapeButton::prepareMenu() QStringList patchNames = QgsStyle::defaultStyle()->symbolsOfFavorite( QgsStyle::LegendPatchShapeEntity ); patchNames.sort(); const int iconSize = QgsGuiUtils::scaleIconSize( 16 ); - for ( const QString &name : qgis::as_const( patchNames ) ) + for ( const QString &name : std::as_const( patchNames ) ) { const QgsLegendPatchShape shape = QgsStyle::defaultStyle()->legendPatchShape( name ); if ( shape.symbolType() == mType ) diff --git a/src/gui/qgsmapcanvas.cpp b/src/gui/qgsmapcanvas.cpp index c09d8cf79146..6b44d151a396 100644 --- a/src/gui/qgsmapcanvas.cpp +++ b/src/gui/qgsmapcanvas.cpp @@ -2510,7 +2510,7 @@ void QgsMapCanvas::dropEvent( QDropEvent *event ) for ( const QgsMimeDataUtils::Uri &uri : lst ) { bool handled = false; - for ( QgsCustomDropHandler *handler : qgis::as_const( mDropHandlers ) ) + for ( QgsCustomDropHandler *handler : std::as_const( mDropHandlers ) ) { if ( handler && handler->customUriProviderKey() == uri.providerKey ) { @@ -2740,7 +2740,7 @@ void QgsMapCanvas::dragEnterEvent( QDragEnterEvent *event ) for ( const QgsMimeDataUtils::Uri &uri : lst ) { bool handled = false; - for ( QgsCustomDropHandler *handler : qgis::as_const( mDropHandlers ) ) + for ( QgsCustomDropHandler *handler : std::as_const( mDropHandlers ) ) { if ( handler->canHandleCustomUriCanvasDrop( uri, this ) ) { diff --git a/src/gui/qgsmaptoolidentify.cpp b/src/gui/qgsmaptoolidentify.cpp index 6bd5be86e6d5..1a2cc9204644 100644 --- a/src/gui/qgsmaptoolidentify.cpp +++ b/src/gui/qgsmaptoolidentify.cpp @@ -643,7 +643,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QListcapabilities() & QgsFeatureRenderer::Filter; } - for ( const QgsFeature &feature : qgis::as_const( featureList ) ) + for ( const QgsFeature &feature : std::as_const( featureList ) ) { QMap< QString, QString > derivedAttributes = commonDerivedAttributes; diff --git a/src/gui/qgsmetadatawidget.cpp b/src/gui/qgsmetadatawidget.cpp index 8c9dbdb2e630..658061b82c7b 100644 --- a/src/gui/qgsmetadatawidget.cpp +++ b/src/gui/qgsmetadatawidget.cpp @@ -794,7 +794,7 @@ bool QgsMetadataWidget::checkMetadata() QString errors; if ( !results ) { - for ( const QgsAbstractMetadataBaseValidator::ValidationResult &result : qgis::as_const( validationResults ) ) + for ( const QgsAbstractMetadataBaseValidator::ValidationResult &result : std::as_const( validationResults ) ) { errors += QLatin1String( "" ) % result.section; if ( ! result._identifier().isNull() ) diff --git a/src/gui/qgsnewvectortabledialog.cpp b/src/gui/qgsnewvectortabledialog.cpp index 6e0b5ef05ebb..3e311e1dfa35 100644 --- a/src/gui/qgsnewvectortabledialog.cpp +++ b/src/gui/qgsnewvectortabledialog.cpp @@ -428,7 +428,7 @@ QWidget *QgsNewVectorTableDialogFieldsDelegate::createEditor( QWidget *parent, c cbo->setEditable( false ); cbo->setFrame( false ); connect( cbo, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsNewVectorTableDialogFieldsDelegate::onFieldTypeChanged ); - for ( const auto &f : qgis::as_const( mTypeList ) ) + for ( const auto &f : std::as_const( mTypeList ) ) { cbo->addItem( f.mTypeDesc, f.mTypeName ); } @@ -719,7 +719,7 @@ QList QgsNewVectorTableFieldModel::nativeType QString QgsNewVectorTableFieldModel::typeDesc( const QString &typeName ) const { - for ( const auto &t : qgis::as_const( mNativeTypes ) ) + for ( const auto &t : std::as_const( mNativeTypes ) ) { if ( t.mTypeName.compare( typeName, Qt::CaseSensitivity::CaseInsensitive ) == 0 ) { @@ -736,7 +736,7 @@ QVariant::Type QgsNewVectorTableFieldModel::type( const QString &typeName ) cons QgsVectorDataProvider::NativeType QgsNewVectorTableFieldModel::nativeType( const QString &typeName ) const { - for ( const auto &t : qgis::as_const( mNativeTypes ) ) + for ( const auto &t : std::as_const( mNativeTypes ) ) { if ( t.mTypeName.compare( typeName, Qt::CaseSensitivity::CaseInsensitive ) == 0 ) { diff --git a/src/gui/qgsoptionsdialogbase.cpp b/src/gui/qgsoptionsdialogbase.cpp index 6c7418061212..ed214453d41b 100644 --- a/src/gui/qgsoptionsdialogbase.cpp +++ b/src/gui/qgsoptionsdialogbase.cpp @@ -318,7 +318,7 @@ void QgsOptionsDialogBase::searchText( const QString &text ) mOptListWidget->setRowHidden( r, text.length() >= minimumTextLength ); } - for ( const QPair< QgsOptionsDialogHighlightWidget *, int > &rsw : qgis::as_const( mRegisteredSearchWidgets ) ) + for ( const QPair< QgsOptionsDialogHighlightWidget *, int > &rsw : std::as_const( mRegisteredSearchWidgets ) ) { if ( rsw.first->searchHighlight( text.length() >= minimumTextLength ? text : QString() ) ) { diff --git a/src/gui/qgsprojectionselectiontreewidget.cpp b/src/gui/qgsprojectionselectiontreewidget.cpp index abd82112152d..8182212b02f5 100644 --- a/src/gui/qgsprojectionselectiontreewidget.cpp +++ b/src/gui/qgsprojectionselectiontreewidget.cpp @@ -137,7 +137,7 @@ void QgsProjectionSelectionTreeWidget::showEvent( QShowEvent *event ) if ( !mRecentProjListDone ) { - for ( const QgsCoordinateReferenceSystem &crs : qgis::as_const( mRecentProjections ) ) + for ( const QgsCoordinateReferenceSystem &crs : std::as_const( mRecentProjections ) ) insertRecent( crs ); mRecentProjListDone = true; } diff --git a/src/gui/qgspropertyoverridebutton.cpp b/src/gui/qgspropertyoverridebutton.cpp index da23123f0b08..ef0169a4a3af 100644 --- a/src/gui/qgspropertyoverridebutton.cpp +++ b/src/gui/qgspropertyoverridebutton.cpp @@ -958,7 +958,7 @@ void QgsPropertyOverrideButton::registerExpressionContextGenerator( QgsExpressio void QgsPropertyOverrideButton::registerLinkedWidget( QWidget *widget ) { - for ( const SiblingWidget &sw : qgis::as_const( mSiblingWidgets ) ) + for ( const SiblingWidget &sw : std::as_const( mSiblingWidgets ) ) { if ( widget == sw.mWidgetPointer.data() && sw.mSiblingType == SiblingLinkedWidget ) return; diff --git a/src/gui/qgsrubberband.cpp b/src/gui/qgsrubberband.cpp index 387f8763a233..f43aaea0ec13 100644 --- a/src/gui/qgsrubberband.cpp +++ b/src/gui/qgsrubberband.cpp @@ -441,7 +441,7 @@ void QgsRubberBand::paint( QPainter *p ) QVector< QVector > shapes; shapes.reserve( mPoints.size() ); - for ( const QgsPolygonXY &poly : qgis::as_const( mPoints ) ) + for ( const QgsPolygonXY &poly : std::as_const( mPoints ) ) { QVector rings; rings.reserve( poly.size() ); @@ -466,7 +466,7 @@ void QgsRubberBand::paint( QPainter *p ) context.setFlag( QgsRenderContext::Antialiasing, true ); lineSymbol->startRender( context ); - for ( const QVector &shape : qgis::as_const( shapes ) ) + for ( const QVector &shape : std::as_const( shapes ) ) { drawShape( p, shape ); for ( const QPolygonF &ring : shape ) @@ -495,7 +495,7 @@ void QgsRubberBand::paint( QPainter *p ) p->setPen( mPen ); } - for ( const QVector &shape : qgis::as_const( shapes ) ) + for ( const QVector &shape : std::as_const( shapes ) ) { drawShape( p, shape ); } @@ -633,7 +633,7 @@ void QgsRubberBand::updateRect() qreal w = ( ( mIconSize - 1 ) / 2 + mPen.width() ); // in canvas units QgsRectangle r; // in canvas units - for ( const QgsPolygonXY &poly : qgis::as_const( mPoints ) ) + for ( const QgsPolygonXY &poly : std::as_const( mPoints ) ) { for ( const QgsPointXY &point : poly.at( 0 ) ) { @@ -698,7 +698,7 @@ int QgsRubberBand::partSize( int geometryIndex ) const int QgsRubberBand::numberOfVertices() const { int count = 0; - for ( const QgsPolygonXY &poly : qgis::as_const( mPoints ) ) + for ( const QgsPolygonXY &poly : std::as_const( mPoints ) ) { for ( const QgsPolylineXY &ring : poly ) { @@ -735,7 +735,7 @@ QgsGeometry QgsRubberBand::asGeometry() const { QgsMultiPointXY multiPoint; - for ( const QgsPolygonXY &poly : qgis::as_const( mPoints ) ) + for ( const QgsPolygonXY &poly : std::as_const( mPoints ) ) { if ( poly.isEmpty() ) continue; @@ -753,7 +753,7 @@ QgsGeometry QgsRubberBand::asGeometry() const if ( mPoints.size() > 1 ) { QgsMultiPolylineXY multiPolyline; - for ( const QgsPolygonXY &poly : qgis::as_const( mPoints ) ) + for ( const QgsPolygonXY &poly : std::as_const( mPoints ) ) { if ( poly.isEmpty() ) continue; diff --git a/src/gui/qgsscalewidget.cpp b/src/gui/qgsscalewidget.cpp index fabb14d13732..0625d75b7f22 100644 --- a/src/gui/qgsscalewidget.cpp +++ b/src/gui/qgsscalewidget.cpp @@ -123,7 +123,7 @@ void QgsScaleWidget::menuAboutToShow() first = false; QMenu *layoutMenu = new QMenu( layout->name(), mMenu ); - for ( const QgsLayoutItemMap *map : qgis::as_const( maps ) ) + for ( const QgsLayoutItemMap *map : std::as_const( maps ) ) { scale = map->scale(); QAction *mapScaleAction = new QAction( tr( "%1 (1:%2)" ).arg( map->displayName(), qgsDoubleToString( scale, 0 ) ), mMenu ); diff --git a/src/gui/raster/qgscolorrampshaderwidget.cpp b/src/gui/raster/qgscolorrampshaderwidget.cpp index 3515a0bce8e6..ce0e654efb67 100644 --- a/src/gui/raster/qgscolorrampshaderwidget.cpp +++ b/src/gui/raster/qgscolorrampshaderwidget.cpp @@ -834,7 +834,7 @@ void QgsColorRampShaderWidget::changeColor() colorWidget->setAllowOpacity( true ); connect( colorWidget, &QgsCompoundColorWidget::currentColorChanged, this, [ = ]( const QColor & newColor ) { - for ( QTreeWidgetItem *item : qgis::as_const( itemList ) ) + for ( QTreeWidgetItem *item : std::as_const( itemList ) ) { item->setData( ColorColumn, Qt::ItemDataRole::EditRole, newColor ); } @@ -850,7 +850,7 @@ void QgsColorRampShaderWidget::changeColor() QColor newColor = QgsColorDialog::getColor( currentColor, this, QStringLiteral( "Change Color" ), true ); if ( newColor.isValid() ) { - for ( QTreeWidgetItem *item : qgis::as_const( itemList ) ) + for ( QTreeWidgetItem *item : std::as_const( itemList ) ) { item->setData( ColorColumn, Qt::ItemDataRole::EditRole, newColor ); } diff --git a/src/gui/raster/qgspalettedrendererwidget.cpp b/src/gui/raster/qgspalettedrendererwidget.cpp index 3d618c780dbf..0267f0e8ef4a 100644 --- a/src/gui/raster/qgspalettedrendererwidget.cpp +++ b/src/gui/raster/qgspalettedrendererwidget.cpp @@ -851,7 +851,7 @@ void QgsPalettedRendererClassGatherer::run() for ( ; classIt != newClasses.end(); ++classIt ) { // check if existing classes contains this same class - for ( const QgsPalettedRasterRenderer::Class &existingClass : qgis::as_const( mClasses ) ) + for ( const QgsPalettedRasterRenderer::Class &existingClass : std::as_const( mClasses ) ) { if ( existingClass.value == classIt->value ) { diff --git a/src/gui/raster/qgsrasterlayerproperties.cpp b/src/gui/raster/qgsrasterlayerproperties.cpp index 02cf90dac1c4..90da6b5c7122 100644 --- a/src/gui/raster/qgsrasterlayerproperties.cpp +++ b/src/gui/raster/qgsrasterlayerproperties.cpp @@ -945,7 +945,7 @@ void QgsRasterLayerProperties::sync() mTemporalWidget->syncToLayer(); - for ( QgsMapLayerConfigWidget *page : qgis::as_const( mLayerPropertiesPages ) ) + for ( QgsMapLayerConfigWidget *page : std::as_const( mLayerPropertiesPages ) ) { page->syncToLayer( mRasterLayer ); } diff --git a/src/gui/symbology/qgsgraduatedsymbolrendererwidget.cpp b/src/gui/symbology/qgsgraduatedsymbolrendererwidget.cpp index 414edb4e999f..c0b7ab00e9e5 100644 --- a/src/gui/symbology/qgsgraduatedsymbolrendererwidget.cpp +++ b/src/gui/symbology/qgsgraduatedsymbolrendererwidget.cpp @@ -642,7 +642,7 @@ void QgsGraduatedSymbolRendererWidget::connectUpdateHandlers() connect( cboSymmetryPoint, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished, this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished ); - for ( const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) ) + for ( const auto &ppww : std::as_const( mParameterWidgetWrappers ) ) { connect( ppww.get(), &QgsAbstractProcessingParameterWidgetWrapper::widgetValueHasChanged, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); } @@ -668,7 +668,7 @@ void QgsGraduatedSymbolRendererWidget::disconnectUpdateHandlers() disconnect( cboSymmetryPoint, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished, this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished ); - for ( const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) ) + for ( const auto &ppww : std::as_const( mParameterWidgetWrappers ) ) { disconnect( ppww.get(), &QgsAbstractProcessingParameterWidgetWrapper::widgetValueHasChanged, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); } @@ -706,7 +706,7 @@ void QgsGraduatedSymbolRendererWidget::updateUiFromRenderer( bool updateCount ) cbxTrimTrailingZeroes->setChecked( method->labelTrimTrailingZeroes() ); QgsProcessingContext context; - for ( const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) ) + for ( const auto &ppww : std::as_const( mParameterWidgetWrappers ) ) { const QgsProcessingParameterDefinition *def = ppww->parameterDefinition(); QVariant value = method->parameterValues().value( def->name(), def->defaultValueForGui() ); @@ -1016,7 +1016,7 @@ void QgsGraduatedSymbolRendererWidget::classifyGraduated() } QVariantMap parameterValues; - for ( const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) ) + for ( const auto &ppww : std::as_const( mParameterWidgetWrappers ) ) parameterValues.insert( ppww->parameterDefinition()->name(), ppww->parameterValue() ); method->setParameterValues( parameterValues ); diff --git a/src/gui/symbology/qgsstylemanagerdialog.cpp b/src/gui/symbology/qgsstylemanagerdialog.cpp index 32b1475c3b95..fa06e7526a60 100644 --- a/src/gui/symbology/qgsstylemanagerdialog.cpp +++ b/src/gui/symbology/qgsstylemanagerdialog.cpp @@ -2162,7 +2162,7 @@ void QgsStyleManagerDialog::populateGroups() taggroup->setEditable( false ); QStringList tags = mStyle->tags(); tags.sort(); - for ( const QString &tag : qgis::as_const( tags ) ) + for ( const QString &tag : std::as_const( tags ) ) { QStandardItem *item = new QStandardItem( tag ); item->setData( mStyle->tagId( tag ) ); @@ -2600,7 +2600,7 @@ void QgsStyleManagerDialog::listitemsContextMenu( QPoint point ) QAction *a = nullptr; QStringList tags = mStyle->tags(); tags.sort(); - for ( const QString &tag : qgis::as_const( tags ) ) + for ( const QString &tag : std::as_const( tags ) ) { a = new QAction( tag, mGroupListMenu ); a->setData( tag ); diff --git a/src/gui/symbology/qgsstylesavedialog.cpp b/src/gui/symbology/qgsstylesavedialog.cpp index ca1b0b2c43b8..915ff17037bf 100644 --- a/src/gui/symbology/qgsstylesavedialog.cpp +++ b/src/gui/symbology/qgsstylesavedialog.cpp @@ -82,7 +82,7 @@ QgsStyleSaveDialog::QgsStyleSaveDialog( QWidget *parent, QgsStyle::StyleEntity t } else { - for ( QgsStyle::StyleEntity e : qgis::as_const( possibleEntities ) ) + for ( QgsStyle::StyleEntity e : std::as_const( possibleEntities ) ) { switch ( e ) { diff --git a/src/gui/symbology/qgssvgselectorwidget.cpp b/src/gui/symbology/qgssvgselectorwidget.cpp index 3723599ea2fb..6d6584920dd2 100644 --- a/src/gui/symbology/qgssvgselectorwidget.cpp +++ b/src/gui/symbology/qgssvgselectorwidget.cpp @@ -571,7 +571,7 @@ void QgsSvgParametersModel::setParameters( const QMap &par QMap QgsSvgParametersModel::parameters() const { QMap params; - for ( const Parameter ¶m : qgis::as_const( mParameters ) ) + for ( const Parameter ¶m : std::as_const( mParameters ) ) { if ( !param.name.isEmpty() ) params.insert( param.name, param.property ); @@ -643,7 +643,7 @@ bool QgsSvgParametersModel::setData( const QModelIndex &index, const QVariant &v { QString oldName = mParameters.at( index.row() ).name; QString newName = value.toString(); - for ( const Parameter ¶m : qgis::as_const( mParameters ) ) + for ( const Parameter ¶m : std::as_const( mParameters ) ) { if ( param.name == newName && param.name != oldName ) { diff --git a/src/gui/symbology/qgssymbollevelsdialog.cpp b/src/gui/symbology/qgssymbollevelsdialog.cpp index af8f48a913f0..4028471e5d89 100644 --- a/src/gui/symbology/qgssymbollevelsdialog.cpp +++ b/src/gui/symbology/qgssymbollevelsdialog.cpp @@ -129,7 +129,7 @@ void QgsSymbolLevelsWidget::updateUi() void QgsSymbolLevelsWidget::apply() { - for ( const QgsLegendSymbolItem &legendSymbol : qgis::as_const( mLegendSymbols ) ) + for ( const QgsLegendSymbolItem &legendSymbol : std::as_const( mLegendSymbols ) ) { QgsSymbol *sym = legendSymbol.symbol(); for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ ) diff --git a/src/gui/vector/qgsvectorlayerproperties.cpp b/src/gui/vector/qgsvectorlayerproperties.cpp index 9721ad602854..c60b96d83603 100644 --- a/src/gui/vector/qgsvectorlayerproperties.cpp +++ b/src/gui/vector/qgsvectorlayerproperties.cpp @@ -844,7 +844,7 @@ void QgsVectorLayerProperties::onCancel() for ( const QgsVectorLayerJoinInfo &info : constVectorJoins ) mLayer->removeJoin( info.joinLayerId() ); - for ( const QgsVectorLayerJoinInfo &info : qgis::as_const( mOldJoins ) ) + for ( const QgsVectorLayerJoinInfo &info : std::as_const( mOldJoins ) ) mLayer->addJoin( info ); } @@ -1222,7 +1222,7 @@ void QgsVectorLayerProperties::saveMultipleStylesAs() if ( ! stylesSelected.isEmpty() ) { int styleIndex = 0; - for ( const QString &styleName : qgis::as_const( stylesSelected ) ) + for ( const QString &styleName : std::as_const( stylesSelected ) ) { bool defaultLoadedFlag = false; diff --git a/src/plugins/geometry_checker/qgsgeometrycheckerresulttab.cpp b/src/plugins/geometry_checker/qgsgeometrycheckerresulttab.cpp index a5b3c6db1557..ec5274de832e 100644 --- a/src/plugins/geometry_checker/qgsgeometrycheckerresulttab.cpp +++ b/src/plugins/geometry_checker/qgsgeometrycheckerresulttab.cpp @@ -339,7 +339,7 @@ void QgsGeometryCheckerResultTab::highlightErrors( bool current ) { items.append( ui.tableWidgetErrors->selectedItems() ); } - for ( QTableWidgetItem *item : qgis::as_const( items ) ) + for ( QTableWidgetItem *item : std::as_const( items ) ) { QgsGeometryCheckError *error = ui.tableWidgetErrors->item( item->row(), 0 )->data( Qt::UserRole ).value(); @@ -470,7 +470,7 @@ void QgsGeometryCheckerResultTab::fixErrors( bool prompt ) rows = ui.tableWidgetErrors->selectionModel()->selectedRows(); } QList errors; - for ( const QModelIndex &index : qgis::as_const( rows ) ) + for ( const QModelIndex &index : std::as_const( rows ) ) { QgsGeometryCheckError *error = ui.tableWidgetErrors->item( index.row(), 0 )->data( Qt::UserRole ).value(); if ( error->status() < QgsGeometryCheckError::StatusFixed ) @@ -516,7 +516,7 @@ void QgsGeometryCheckerResultTab::fixErrors( bool prompt ) ui.progressBarFixErrors->setVisible( true ); ui.progressBarFixErrors->setRange( 0, errors.size() ); - for ( QgsGeometryCheckError *error : qgis::as_const( errors ) ) + for ( QgsGeometryCheckError *error : std::as_const( errors ) ) { int fixMethod = QgsSettings().value( sSettingsGroup + error->check()->id(), QVariant::fromValue( 0 ) ).toInt(); mChecker->fixError( error, fixMethod ); diff --git a/src/plugins/geometry_checker/qgsgeometrycheckersetuptab.cpp b/src/plugins/geometry_checker/qgsgeometrycheckersetuptab.cpp index 56f2462d7e29..64445caf276b 100644 --- a/src/plugins/geometry_checker/qgsgeometrycheckersetuptab.cpp +++ b/src/plugins/geometry_checker/qgsgeometrycheckersetuptab.cpp @@ -398,7 +398,7 @@ void QgsGeometryCheckerSetupTab::runChecks() // Check if output layers are editable QList nonEditableLayers; - for ( QgsVectorLayer *layer : qgis::as_const( processLayers ) ) + for ( QgsVectorLayer *layer : std::as_const( processLayers ) ) { if ( ( layer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeGeometries ) == 0 ) { @@ -416,7 +416,7 @@ void QgsGeometryCheckerSetupTab::runChecks() { if ( ui.radioButtonOutputNew->isChecked() ) { - for ( QgsVectorLayer *layer : qgis::as_const( processLayers ) ) + for ( QgsVectorLayer *layer : std::as_const( processLayers ) ) { QString layerPath = layer->dataProvider()->dataSourceUri(); delete layer; @@ -441,7 +441,7 @@ void QgsGeometryCheckerSetupTab::runChecks() ui.labelStatus->setText( tr( "Building spatial index…" ) ); QApplication::processEvents( QEventLoop::ExcludeUserInputEvents ); QMap featurePools; - for ( QgsVectorLayer *layer : qgis::as_const( processLayers ) ) + for ( QgsVectorLayer *layer : std::as_const( processLayers ) ) { featurePools.insert( layer->id(), new QgsVectorDataProviderFeaturePool( layer, selectedOnly ) ); } @@ -471,7 +471,7 @@ void QgsGeometryCheckerSetupTab::runChecks() if ( ui.radioButtonOutputNew->isChecked() ) { QList addLayers; - for ( QgsVectorLayer *layer : qgis::as_const( processLayers ) ) + for ( QgsVectorLayer *layer : std::as_const( processLayers ) ) { addLayers.append( layer ); } diff --git a/src/process/qgsprocess.cpp b/src/process/qgsprocess.cpp index 66b8f7c0c5fd..ea7504f43241 100644 --- a/src/process/qgsprocess.cpp +++ b/src/process/qgsprocess.cpp @@ -983,7 +983,7 @@ int QgsProcessingExec::execute( const QString &id, const QVariantMap ¶ms, co if ( !missingParams.isEmpty() ) { std::cerr << QStringLiteral( "ERROR: The following mandatory parameters were not specified\n\n" ).toLocal8Bit().constData(); - for ( const QgsProcessingParameterDefinition *p : qgis::as_const( missingParams ) ) + for ( const QgsProcessingParameterDefinition *p : std::as_const( missingParams ) ) { std::cerr << QStringLiteral( "\t%1:\t%2\n" ).arg( p->name(), p->description() ).toLocal8Bit().constData(); } diff --git a/src/providers/arcgisrest/qgsamsprovider.cpp b/src/providers/arcgisrest/qgsamsprovider.cpp index 33a8cd7bee26..5ce2ad210076 100644 --- a/src/providers/arcgisrest/qgsamsprovider.cpp +++ b/src/providers/arcgisrest/qgsamsprovider.cpp @@ -164,7 +164,7 @@ void QgsAmsLegendFetcher::handleFinished() typedef QPair LegendEntry_t; QSize maxImageSize( 0, 0 ); - for ( const LegendEntry_t &legendEntry : qgis::as_const( legendEntries ) ) + for ( const LegendEntry_t &legendEntry : std::as_const( legendEntries ) ) { maxImageSize.setWidth( std::max( maxImageSize.width(), legendEntry.second.width() ) ); maxImageSize.setHeight( std::max( maxImageSize.height(), legendEntry.second.height() ) ); @@ -178,7 +178,7 @@ void QgsAmsLegendFetcher::handleFinished() QPainter painter( &mLegendImage ); painter.setFont( font ); int i = 0; - for ( const LegendEntry_t &legendEntry : qgis::as_const( legendEntries ) ) + for ( const LegendEntry_t &legendEntry : std::as_const( legendEntries ) ) { QImage symbol = legendEntry.second.scaled( legendEntry.second.width() * scaleFactor, legendEntry.second.height() * scaleFactor, Qt::KeepAspectRatio, Qt::SmoothTransformation ); painter.drawImage( 0, verticalPadding + i * ( verticalSize + verticalPadding ) + ( verticalSize - symbol.height() ), symbol ); @@ -584,7 +584,7 @@ QImage QgsAmsProvider::draw( const QgsRectangle &viewExtent, int pixelWidth, int tileImages.reserve( requests.size() ); missing.reserve( requests.size() ); requestsFinal.reserve( requests.size() ); - for ( const TileRequest &r : qgis::as_const( requests ) ) + for ( const TileRequest &r : std::as_const( requests ) ) { QImage localImage; if ( QgsTileCache::tile( r.url, localImage ) ) @@ -618,7 +618,7 @@ QImage QgsAmsProvider::draw( const QgsRectangle &viewExtent, int pixelWidth, int TileRequests otherRequests; getRequests( otherLevel, otherRequests ); QList missingRectsToDelete; - for ( const TileRequest &r : qgis::as_const( otherRequests ) ) + for ( const TileRequest &r : std::as_const( otherRequests ) ) { QImage localImage; if ( ! QgsTileCache::tile( r.url, localImage ) ) @@ -627,7 +627,7 @@ QImage QgsAmsProvider::draw( const QgsRectangle &viewExtent, int pixelWidth, int otherResTiles << TileImage( r.rect, localImage, false ); // see if there are any missing rects that are completely covered by this tile - for ( const QRectF &missingRect : qgis::as_const( missingRects ) ) + for ( const QRectF &missingRect : std::as_const( missingRects ) ) { // we need to do a fuzzy "contains" check because the coordinates may not align perfectly // due to numerical errors and/or transform of coords from double to floats @@ -640,7 +640,7 @@ QImage QgsAmsProvider::draw( const QgsRectangle &viewExtent, int pixelWidth, int // remove all the rectangles we have completely covered by tiles from this resolution // so we will not use tiles from multiple resolutions for one missing tile (to save time) - for ( const QRectF &rectToDelete : qgis::as_const( missingRectsToDelete ) ) + for ( const QRectF &rectToDelete : std::as_const( missingRectsToDelete ) ) { missingRects.removeOne( rectToDelete ); } @@ -673,7 +673,7 @@ QImage QgsAmsProvider::draw( const QgsRectangle &viewExtent, int pixelWidth, int } // draw composite in this resolution - for ( const TileImage &ti : qgis::as_const( tileImages ) ) + for ( const TileImage &ti : std::as_const( tileImages ) ) { if ( ti.smooth ) p.setRenderHint( QPainter::SmoothPixmapTransform, true ); diff --git a/src/providers/db2/qgsdb2tablemodel.cpp b/src/providers/db2/qgsdb2tablemodel.cpp index dfcfcf1939b6..2c4c86429efc 100644 --- a/src/providers/db2/qgsdb2tablemodel.cpp +++ b/src/providers/db2/qgsdb2tablemodel.cpp @@ -136,7 +136,7 @@ void QgsDb2TableModel::addTableEntry( const QgsDb2LayerProperty &layerProperty ) if ( detailsFromThread ) flags |= Qt::ItemIsEnabled; - for ( QStandardItem *item : qgis::as_const( childItemList ) ) + for ( QStandardItem *item : std::as_const( childItemList ) ) { item->setFlags( item->flags() & ~flags ); } @@ -260,7 +260,7 @@ void QgsDb2TableModel::setGeometryTypesForTable( QgsDb2LayerProperty layerProper row[ DbtmSrid ]->setText( tr( "Enter…" ) ); row[ DbtmSrid ]->setFlags( row[ DbtmSrid ]->flags() | Qt::ItemIsEditable ); - for ( QStandardItem *item : qgis::as_const( row ) ) + for ( QStandardItem *item : std::as_const( row ) ) { item->setFlags( item->flags() | Qt::ItemIsEnabled ); } @@ -281,7 +281,7 @@ void QgsDb2TableModel::setGeometryTypesForTable( QgsDb2LayerProperty layerProper if ( layerProperty.pkCols.size() < 2 ) flags |= Qt::ItemIsSelectable; - for ( QStandardItem *item : qgis::as_const( row ) ) + for ( QStandardItem *item : std::as_const( row ) ) { item->setFlags( item->flags() | flags ); } diff --git a/src/providers/geonode/qgsgeonodedataitems.cpp b/src/providers/geonode/qgsgeonodedataitems.cpp index 4d0a1e8caf1e..92bb8490d62e 100644 --- a/src/providers/geonode/qgsgeonodedataitems.cpp +++ b/src/providers/geonode/qgsgeonodedataitems.cpp @@ -130,7 +130,7 @@ QVector QgsGeoNodeServiceItem::createChildren() return items; } - for ( QgsDataItem *item : qgis::as_const( items ) ) + for ( QgsDataItem *item : std::as_const( items ) ) { item->populate( true ); // populate in foreground - this is already run in a thread diff --git a/src/providers/hana/qgshanaconnection.cpp b/src/providers/hana/qgshanaconnection.cpp index 7be3f8c2044b..35eefba94aec 100644 --- a/src/providers/hana/qgshanaconnection.cpp +++ b/src/providers/hana/qgshanaconnection.cpp @@ -530,7 +530,7 @@ QVector QgsHanaConnection::getLayers( if ( values.size() == 1 ) values[0].isUnique = true; - for ( const QgsHanaLayerProperty &lp : qgis::as_const( values ) ) + for ( const QgsHanaLayerProperty &lp : std::as_const( values ) ) list << lp; } diff --git a/src/providers/hana/qgshanadataitems.cpp b/src/providers/hana/qgshanadataitems.cpp index c7f1ff5e9bab..1b5541c4858f 100644 --- a/src/providers/hana/qgshanadataitems.cpp +++ b/src/providers/hana/qgshanadataitems.cpp @@ -100,7 +100,7 @@ bool QgsHanaConnectionItem::equal( const QgsDataItem *other ) void QgsHanaConnectionItem::refreshSchema( const QString &schema ) { - for ( QgsDataItem *child : qgis::as_const( mChildren ) ) + for ( QgsDataItem *child : std::as_const( mChildren ) ) { if ( child->name() == schema || schema.isEmpty() ) child->refresh(); diff --git a/src/providers/hana/qgshanafeatureiterator.cpp b/src/providers/hana/qgshanafeatureiterator.cpp index c54f7edd1487..d490a5494e1a 100644 --- a/src/providers/hana/qgshanafeatureiterator.cpp +++ b/src/providers/hana/qgshanafeatureiterator.cpp @@ -180,7 +180,7 @@ bool QgsHanaFeatureIterator::fetchFeature( QgsFeature &feature ) { QVariantList pkValues; pkValues.reserve( mSource->mPrimaryKeyAttrs.size() ); - for ( int idx : qgis::as_const( mSource->mPrimaryKeyAttrs ) ) + for ( int idx : std::as_const( mSource->mPrimaryKeyAttrs ) ) { QVariant v = mResultSet->getValue( paramIndex ); pkValues << v; @@ -201,7 +201,7 @@ bool QgsHanaFeatureIterator::fetchFeature( QgsFeature &feature ) // Read attributes if ( mHasAttributes ) { - for ( int idx : qgis::as_const( mAttributesToFetch ) ) + for ( int idx : std::as_const( mAttributesToFetch ) ) { feature.setAttribute( idx, mResultSet->getValue( paramIndex ) ); ++paramIndex; @@ -337,13 +337,13 @@ QString QgsHanaFeatureIterator::buildSqlQuery( const QgsFeatureRequest &request QStringList sqlFields; // Add feature id column - for ( int idx : qgis::as_const( mSource->mPrimaryKeyAttrs ) ) + for ( int idx : std::as_const( mSource->mPrimaryKeyAttrs ) ) { QString fieldName = mSource->mFields.at( idx ).name(); sqlFields.push_back( QgsHanaUtils::quotedIdentifier( fieldName ) ); } - for ( int idx : qgis::as_const( attrIds ) ) + for ( int idx : std::as_const( attrIds ) ) { if ( mSource->mPrimaryKeyAttrs.contains( idx ) ) continue; diff --git a/src/providers/hana/qgshanaprovider.cpp b/src/providers/hana/qgshanaprovider.cpp index f4802ae56ee3..1e92d0756722 100644 --- a/src/providers/hana/qgshanaprovider.cpp +++ b/src/providers/hana/qgshanaprovider.cpp @@ -702,7 +702,7 @@ bool QgsHanaProvider::addFeatures( QgsFeatureList &flist, Flags flags ) { QVariantList primaryKeyVals; primaryKeyVals.reserve( mPrimaryKeyAttrs.size() ); - for ( int idx : qgis::as_const( mPrimaryKeyAttrs ) ) + for ( int idx : std::as_const( mPrimaryKeyAttrs ) ) primaryKeyVals << attrs.at( idx ); feature.setId( mPrimaryKeyCntx->lookupFid( primaryKeyVals ) ); } @@ -951,7 +951,7 @@ bool QgsHanaProvider::renameAttributes( const QgsFieldNameMap &fieldMap ) while ( !renameCandidates.empty() ) { bool found = false; - for ( const QPair &candidate : qgis::as_const( renameCandidates ) ) + for ( const QPair &candidate : std::as_const( renameCandidates ) ) { if ( resultFieldNames.contains( candidate.first ) && !resultFieldNames.contains( candidate.second ) ) { @@ -974,7 +974,7 @@ bool QgsHanaProvider::renameAttributes( const QgsFieldNameMap &fieldMap ) try { - for ( const QPair &kv : qgis::as_const( fieldsToRename ) ) + for ( const QPair &kv : std::as_const( fieldsToRename ) ) { QString sql = QStringLiteral( "RENAME COLUMN %1.%2.%3 TO %4" ).arg( QgsHanaUtils::quotedIdentifier( mSchemaName ), QgsHanaUtils::quotedIdentifier( mTableName ), diff --git a/src/providers/hana/qgshanatablemodel.cpp b/src/providers/hana/qgshanatablemodel.cpp index c8f310f951e6..ecde2ef14052 100644 --- a/src/providers/hana/qgshanatablemodel.cpp +++ b/src/providers/hana/qgshanatablemodel.cpp @@ -125,7 +125,7 @@ void QgsHanaTableModel::addTableEntry( const QString &connName, const QgsHanaLay childItemList << selItem; childItemList << sqlItem; - for ( QStandardItem *item : qgis::as_const( childItemList ) ) + for ( QStandardItem *item : std::as_const( childItemList ) ) { if ( tip.isEmpty() || withTipButSelectable ) item->setFlags( item->flags() | Qt::ItemIsSelectable ); diff --git a/src/providers/mssql/qgsmssqldataitems.cpp b/src/providers/mssql/qgsmssqldataitems.cpp index 8be00623ce91..ca1f3d80309d 100644 --- a/src/providers/mssql/qgsmssqldataitems.cpp +++ b/src/providers/mssql/qgsmssqldataitems.cpp @@ -283,7 +283,7 @@ QVector QgsMssqlConnectionItem::createChildren() else { //set all as populated -- we also need to do this for newly created items, because they won't yet be children of this item - for ( QgsDataItem *child : qgis::as_const( children ) ) + for ( QgsDataItem *child : std::as_const( children ) ) { child->setState( Populated ); } diff --git a/src/providers/mssql/qgsmssqlfeatureiterator.cpp b/src/providers/mssql/qgsmssqlfeatureiterator.cpp index c984e64f3c26..f03fbf40b845 100644 --- a/src/providers/mssql/qgsmssqlfeatureiterator.cpp +++ b/src/providers/mssql/qgsmssqlfeatureiterator.cpp @@ -173,7 +173,7 @@ void QgsMssqlFeatureIterator::BuildStatement( const QgsFeatureRequest &request ) } } - for ( int i : qgis::as_const( attrs ) ) + for ( int i : std::as_const( attrs ) ) { if ( mSource->mPrimaryKeyAttrs.contains( i ) ) continue; diff --git a/src/providers/mssql/qgsmssqltablemodel.cpp b/src/providers/mssql/qgsmssqltablemodel.cpp index 376abf7f2efa..b23da3b0b82e 100644 --- a/src/providers/mssql/qgsmssqltablemodel.cpp +++ b/src/providers/mssql/qgsmssqltablemodel.cpp @@ -289,7 +289,7 @@ void QgsMssqlTableModel::setGeometryTypesForTable( QgsMssqlLayerProperty layerPr if ( layerProperty.pkCols.size() < 2 ) flags |= Qt::ItemIsSelectable; - for ( QStandardItem *item : qgis::as_const( row ) ) + for ( QStandardItem *item : std::as_const( row ) ) { item->setFlags( item->flags() | flags ); } diff --git a/src/providers/ows/qgsowsdataitems.cpp b/src/providers/ows/qgsowsdataitems.cpp index 4f9fb8cf45b1..068a13541bf2 100644 --- a/src/providers/ows/qgsowsdataitems.cpp +++ b/src/providers/ows/qgsowsdataitems.cpp @@ -70,7 +70,7 @@ QVector QgsOWSConnectionItem::createChildren() continue; } - for ( QgsDataItem *item : qgis::as_const( items ) ) + for ( QgsDataItem *item : std::as_const( items ) ) { item->populate( true ); // populate in foreground - this is already run in a thread diff --git a/src/providers/postgres/qgspgsourceselect.cpp b/src/providers/postgres/qgspgsourceselect.cpp index 4b20fd85be39..5af5382adfef 100644 --- a/src/providers/postgres/qgspgsourceselect.cpp +++ b/src/providers/postgres/qgspgsourceselect.cpp @@ -60,12 +60,12 @@ QWidget *QgsPgSourceSelectDelegate::createEditor( QWidget *parent, const QStyleO { QComboBox *cb = new QComboBox( parent ); static const QList types { QgsWkbTypes::Point - , QgsWkbTypes::LineString - , QgsWkbTypes::Polygon - , QgsWkbTypes::MultiPoint - , QgsWkbTypes::MultiLineString - , QgsWkbTypes::MultiPolygon - , QgsWkbTypes::NoGeometry }; + , QgsWkbTypes::LineString + , QgsWkbTypes::Polygon + , QgsWkbTypes::MultiPoint + , QgsWkbTypes::MultiLineString + , QgsWkbTypes::MultiPolygon + , QgsWkbTypes::NoGeometry }; for ( QgsWkbTypes::Type type : types ) { cb->addItem( QgsLayerItem::iconForWkbType( type ), QgsPostgresConn::displayStringForWkbType( type ), type ); @@ -534,7 +534,7 @@ void QgsPgSourceSelect::addButtonClicked() } if ( ! rasterTables.isEmpty() ) { - for ( const auto &u : qgis::as_const( rasterTables ) ) + for ( const auto &u : std::as_const( rasterTables ) ) { // Use "gdal" to proxy rasters to GDAL provider, or "postgresraster" for native PostGIS raster provider emit addRasterLayer( u.second, u.first, QLatin1String( "postgresraster" ) ); diff --git a/src/providers/postgres/qgspostgresprojectstoragedialog.cpp b/src/providers/postgres/qgspostgresprojectstoragedialog.cpp index 361965018f01..c6d25f9d1953 100644 --- a/src/providers/postgres/qgspostgresprojectstoragedialog.cpp +++ b/src/providers/postgres/qgspostgresprojectstoragedialog.cpp @@ -119,7 +119,7 @@ void QgsPostgresProjectStorageDialog::populateSchemas() return; } - for ( const QgsPostgresSchemaProperty &schema : qgis::as_const( schemas ) ) + for ( const QgsPostgresSchemaProperty &schema : std::as_const( schemas ) ) { mCboSchema->addItem( schema.name ); } diff --git a/src/providers/postgres/qgspostgresprovider.cpp b/src/providers/postgres/qgspostgresprovider.cpp index e6f2db769cd5..dc9afaec9672 100644 --- a/src/providers/postgres/qgspostgresprovider.cpp +++ b/src/providers/postgres/qgspostgresprovider.cpp @@ -600,7 +600,7 @@ QString QgsPostgresUtils::whereClause( const QgsFeatureIds &featureIds, const Qg QString delim; expr = QStringLiteral( "%1 IN (" ).arg( ( pkType == PktOid ? QStringLiteral( "oid" ) : QgsPostgresConn::quotedIdentifier( fields.at( pkAttrs[0] ).name() ) ) ); - for ( const QgsFeatureId featureId : qgis::as_const( featureIds ) ) + for ( const QgsFeatureId featureId : std::as_const( featureIds ) ) { expr += delim + FID_TO_STRING( ( pkType == PktOid ? featureId : FID2PKINT( featureId ) ) ); delim = ','; @@ -621,7 +621,7 @@ QString QgsPostgresUtils::whereClause( const QgsFeatureIds &featureIds, const Qg QString delim; expr = QStringLiteral( "%1 IN (" ).arg( QgsPostgresConn::quotedIdentifier( fields.at( pkAttrs[0] ).name() ) ); - for ( const QgsFeatureId featureId : qgis::as_const( featureIds ) ) + for ( const QgsFeatureId featureId : std::as_const( featureIds ) ) { QVariantList pkVals = sharedData->lookupKey( featureId ); if ( !pkVals.isEmpty() ) @@ -642,7 +642,7 @@ QString QgsPostgresUtils::whereClause( const QgsFeatureIds &featureIds, const Qg { //complex primary key, need to build up where string QStringList whereClauses; - for ( const QgsFeatureId featureId : qgis::as_const( featureIds ) ) + for ( const QgsFeatureId featureId : std::as_const( featureIds ) ) { whereClauses << whereClause( featureId, fields, conn, pkType, pkAttrs, sharedData ); } @@ -902,7 +902,7 @@ bool QgsPostgresProvider::loadFields() if ( !attroids.isEmpty() ) { QStringList attroidsList; - for ( Oid attroid : qgis::as_const( attroids ) ) + for ( Oid attroid : std::as_const( attroids ) ) { attroidsList.append( QString::number( attroid ) ); } diff --git a/src/providers/postgres/qgspostgresproviderconnection.cpp b/src/providers/postgres/qgspostgresproviderconnection.cpp index 1af2a6ebdb8e..bb51b74a87c5 100644 --- a/src/providers/postgres/qgspostgresproviderconnection.cpp +++ b/src/providers/postgres/qgspostgresproviderconnection.cpp @@ -301,7 +301,7 @@ QgsAbstractDatabaseProviderConnection::QueryResult QgsPostgresProviderConnection const QList typesResolved( executeSqlPrivate( QStringLiteral( "SELECT oid, typname FROM pg_type WHERE oid IN (%1)" ).arg( oids.join( ',' ) ), false, nullptr, pgconn ) ); QgsStringMap oidTypeMap; - for ( const auto &typeRes : qgis::as_const( typesResolved ) ) + for ( const auto &typeRes : std::as_const( typesResolved ) ) { const QString oid { typeRes.constLast().toString() }; if ( ! oidTypeMap.contains( oid ) ) @@ -610,7 +610,7 @@ QList QgsPostgresProviderConnectio )" ).arg( QgsPostgresConn::quotedIdentifier( pr.schemaName ), QgsPostgresConn::quotedIdentifier( pr.tableName ) ) ); QStringList pkNames; - for ( const auto &pk : qgis::as_const( pks ) ) + for ( const auto &pk : std::as_const( pks ) ) { pkNames.push_back( pk.first().toString() ); } @@ -657,7 +657,7 @@ QStringList QgsPostgresProviderConnection::schemas( ) const } else { - for ( const auto &s : qgis::as_const( schemaProperties ) ) + for ( const auto &s : std::as_const( schemaProperties ) ) { schemas.push_back( s.name ); } @@ -730,7 +730,7 @@ QIcon QgsPostgresProviderConnection::icon() const QList QgsPostgresProviderConnection::nativeTypes() const { QList types; - QgsPostgresConn *conn = QgsPostgresConnPool::instance()->acquireConnection( QgsDataSourceUri{ uri() }.connectionInfo( false ) ); + QgsPostgresConn *conn = QgsPostgresConnPool::instance()->acquireConnection( QgsDataSourceUri{ uri() } .connectionInfo( false ) ); if ( conn ) { types = conn->nativeTypes(); diff --git a/src/providers/postgres/raster/qgspostgresrasterprovider.cpp b/src/providers/postgres/raster/qgspostgresrasterprovider.cpp index b9c7c19289b0..a9685037c739 100644 --- a/src/providers/postgres/raster/qgspostgresrasterprovider.cpp +++ b/src/providers/postgres/raster/qgspostgresrasterprovider.cpp @@ -441,7 +441,7 @@ bool QgsPostgresRasterProvider::readBlock( int bandNo, const QgsRectangle &viewE // Write tiles to the temporary raster CPLErrorReset(); - for ( auto &tile : qgis::as_const( tileResponse.tiles ) ) + for ( auto &tile : std::as_const( tileResponse.tiles ) ) { // Offset in px from the base raster const int xOff { static_cast( std::round( ( tile.upperLeftX - tilesExtent.xMinimum() ) / tile.scaleX ) ) }; @@ -618,7 +618,7 @@ QVariantMap QgsPostgresRasterProviderMetadata::decodeUri( const QString &uri ) c QStringLiteral( "enableTime" ) }}; - for ( const QString &pname : qgis::as_const( params ) ) + for ( const QString &pname : std::as_const( params ) ) { if ( dsUri.hasParam( pname ) ) { @@ -1006,13 +1006,13 @@ bool QgsPostgresRasterProvider::init() try { const QString sql { QStringLiteral( "SELECT r_raster_column, srid," - "num_bands, pixel_types, nodata_values, ST_AsBinary(extent), blocksize_x, blocksize_y," - "out_db, spatial_index, scale_x, scale_y, same_alignment," - "regular_blocking " - "FROM raster_columns WHERE " - "r_table_name = %1 AND r_table_schema = %2" ) - .arg( quotedValue( mTableName ) ) - .arg( quotedValue( mSchemaName ) ) }; + "num_bands, pixel_types, nodata_values, ST_AsBinary(extent), blocksize_x, blocksize_y," + "out_db, spatial_index, scale_x, scale_y, same_alignment," + "regular_blocking " + "FROM raster_columns WHERE " + "r_table_name = %1 AND r_table_schema = %2" ) + .arg( quotedValue( mTableName ) ) + .arg( quotedValue( mSchemaName ) ) }; QgsPostgresResult result( connectionRO()->PQexec( sql ) ); @@ -1059,7 +1059,7 @@ bool QgsPostgresRasterProvider::init() } int i = 0; - for ( const QString &t : qgis::as_const( pxTypes ) ) + for ( const QString &t : std::as_const( pxTypes ) ) { Qgis::DataType type { pixelTypeFromString( t ) }; if ( t == Qgis::DataType::UnknownDataType ) @@ -1100,10 +1100,10 @@ bool QgsPostgresRasterProvider::init() { // Try to determine extent from raster const QString extentSql { QStringLiteral( "SELECT ST_Envelope( %1 ) " - "FROM %2 WHERE %3" ) - .arg( quotedIdentifier( mRasterColumn ) ) - .arg( mQuery ) - .arg( subsetString().isEmpty() ? "'t'" : subsetString() ) }; + "FROM %2 WHERE %3" ) + .arg( quotedIdentifier( mRasterColumn ) ) + .arg( mQuery ) + .arg( subsetString().isEmpty() ? "'t'" : subsetString() ) }; QgsPostgresResult extentResult( connectionRO()->PQexec( extentSql ) ); const QByteArray extentHexAscii { extentResult.PQgetvalue( 0, 0 ).toLatin1() }; @@ -1183,9 +1183,9 @@ bool QgsPostgresRasterProvider::init() if ( mRasterColumn.isEmpty() ) { const QString sql { QStringLiteral( "SELECT column_name FROM information_schema.columns WHERE " - "table_name = %1 AND table_schema = %2 AND udt_name = 'raster'" ) - .arg( quotedValue( mTableName ) ) - .arg( quotedValue( mSchemaName ) )}; + "table_name = %1 AND table_schema = %2 AND udt_name = 'raster'" ) + .arg( quotedValue( mTableName ) ) + .arg( quotedValue( mSchemaName ) )}; QgsPostgresResult result( connectionRO()->PQexec( sql ) ); @@ -1404,10 +1404,10 @@ bool QgsPostgresRasterProvider::initFieldsAndTemporal( ) const QString temporalFieldName { mAttributeFields.field( temporalFieldIndex ).name() }; // Calculate the range const QString sql { QStringLiteral( "SELECT MIN(%1::timestamp), MAX(%1::timestamp) " - "FROM %2 %3" ) - .arg( quotedIdentifier( temporalFieldName ) ) - .arg( mQuery ) - .arg( where )}; + "FROM %2 %3" ) + .arg( quotedIdentifier( temporalFieldName ) ) + .arg( mQuery ) + .arg( where )}; QgsPostgresResult result( connectionRO()->PQexec( sql ) ); @@ -1829,15 +1829,15 @@ bool QgsPostgresRasterProvider::loadFields() { const QString seqName { mTableName + '_' + fieldName + QStringLiteral( "_seq" ) }; const QString seqSql { QStringLiteral( "SELECT c.oid " - " FROM pg_class c " - " LEFT JOIN pg_namespace n " - " ON ( n.oid = c.relnamespace ) " - " WHERE c.relkind = 'S' " - " AND c.relname = %1 " - " AND n.nspname = %2" ) - .arg( quotedValue( seqName ) ) - .arg( quotedValue( mSchemaName ) ) - }; + " FROM pg_class c " + " LEFT JOIN pg_namespace n " + " ON ( n.oid = c.relnamespace ) " + " WHERE c.relkind = 'S' " + " AND c.relname = %1 " + " AND n.nspname = %2" ) + .arg( quotedValue( seqName ) ) + .arg( quotedValue( mSchemaName ) ) + }; QgsPostgresResult seqResult( connectionRO()->PQexec( seqSql ) ); if ( seqResult.PQntuples() == 1 ) { @@ -2156,10 +2156,10 @@ void QgsPostgresRasterProvider::determinePrimaryKeyFromUriKeyColumn() const QString keyCandidate { mUri.keyColumn() }; QgsPostgresPrimaryKeyType pkType { QgsPostgresPrimaryKeyType::PktUnknown }; const QString sql { QStringLiteral( "SELECT data_type FROM information_schema.columns " - "WHERE column_name = %1 AND table_name = %2 AND table_schema = %3" ) - .arg( keyCandidate ) - .arg( mTableName ) - .arg( mSchemaName ) }; + "WHERE column_name = %1 AND table_name = %2 AND table_schema = %3" ) + .arg( keyCandidate ) + .arg( mTableName ) + .arg( mSchemaName ) }; QgsPostgresResult result( connectionRO()->PQexec( sql ) ); if ( PGRES_TUPLES_OK == result.PQresultStatus() ) { @@ -2188,7 +2188,7 @@ QString QgsPostgresRasterProvider::pkSql() if ( mPrimaryKeyAttrs.count( ) > 1 ) { QStringList pkeys; - for ( const auto &k : qgis::as_const( mPrimaryKeyAttrs ) ) + for ( const auto &k : std::as_const( mPrimaryKeyAttrs ) ) { pkeys.push_back( quotedIdentifier( k ) ); } @@ -2205,9 +2205,9 @@ QString QgsPostgresRasterProvider::dataComment() const void QgsPostgresRasterProvider::findOverviews() { const QString sql { QStringLiteral( "SELECT overview_factor, o_table_schema, o_table_name, o_raster_column " - "FROM raster_overviews WHERE r_table_schema = %1 AND r_table_name = %2" ) - .arg( quotedValue( mSchemaName ) ) - .arg( quotedValue( mTableName ) ) }; + "FROM raster_overviews WHERE r_table_schema = %1 AND r_table_name = %2" ) + .arg( quotedValue( mSchemaName ) ) + .arg( quotedValue( mTableName ) ) }; //QgsDebugMsg( QStringLiteral( "Raster overview information sql: %1" ).arg( sql ) ); QgsPostgresResult result( connectionRO()->PQexec( sql ) ); @@ -2341,13 +2341,13 @@ QgsRasterBandStats QgsPostgresRasterProvider::bandStatistics( int bandNo, int st } const QString sql { QStringLiteral( "SELECT (ST_SummaryStatsAgg( %1, %2, TRUE, %3 )).* " - "FROM %4 %5" ) - .arg( quotedIdentifier( mRasterColumn ) ) - .arg( bandNo ) - .arg( std::max( 0, std::min( 1, statsRatio ) ) ) - .arg( tableToQuery ) - .arg( where ) - }; + "FROM %4 %5" ) + .arg( quotedIdentifier( mRasterColumn ) ) + .arg( bandNo ) + .arg( std::max( 0, std::min( 1, statsRatio ) ) ) + .arg( tableToQuery ) + .arg( where ) + }; QgsPostgresResult result( connectionRO()->PQexec( sql ) ); diff --git a/src/providers/spatialite/qgsspatialiteprovider.cpp b/src/providers/spatialite/qgsspatialiteprovider.cpp index 2b5d8e11176c..e9a1af1bb03f 100644 --- a/src/providers/spatialite/qgsspatialiteprovider.cpp +++ b/src/providers/spatialite/qgsspatialiteprovider.cpp @@ -988,7 +988,7 @@ void QgsSpatiaLiteProvider::fetchConstraints() } sqlite3_free_table( results ); - for ( const auto fieldIdx : qgis::as_const( mPrimaryKeyAttrs ) ) + for ( const auto fieldIdx : std::as_const( mPrimaryKeyAttrs ) ) { QgsFieldConstraints constraints = mAttributeFields.at( fieldIdx ).constraints(); constraints.setConstraint( QgsFieldConstraints::ConstraintUnique, QgsFieldConstraints::ConstraintOriginProvider ); diff --git a/src/providers/spatialite/qgsspatialiteproviderconnection.cpp b/src/providers/spatialite/qgsspatialiteproviderconnection.cpp index a08755496767..6ea7afcf316e 100644 --- a/src/providers/spatialite/qgsspatialiteproviderconnection.cpp +++ b/src/providers/spatialite/qgsspatialiteproviderconnection.cpp @@ -430,7 +430,7 @@ QgsAbstractDatabaseProviderConnection::QueryResult QgsSpatiaLiteProviderConnecti QgsFields fields { QgsOgrUtils::readOgrFields( fet.get(), QTextCodec::codecForName( "UTF-8" ) ) }; iterator->setFields( fields ); - for ( const auto &f : qgis::as_const( fields ) ) + for ( const auto &f : std::as_const( fields ) ) { results.appendColumn( f.name() ); } diff --git a/src/providers/wcs/qgswcscapabilities.cpp b/src/providers/wcs/qgswcscapabilities.cpp index 1c81378e8a71..7aca38d38038 100644 --- a/src/providers/wcs/qgswcscapabilities.cpp +++ b/src/providers/wcs/qgswcscapabilities.cpp @@ -854,7 +854,7 @@ bool QgsWcsCapabilities::parseDescribeCoverageDom10( QByteArray const &xml, QgsW } // exclude invalid CRSs from the lists - for ( const QString &crsid : qgis::as_const( crsList ) ) + for ( const QString &crsid : std::as_const( crsList ) ) { if ( QgsCoordinateReferenceSystem::fromOgcWmsCrs( crsid ).isValid() ) { diff --git a/src/providers/wfs/qgsbackgroundcachedfeatureiterator.cpp b/src/providers/wfs/qgsbackgroundcachedfeatureiterator.cpp index 34ad36ff487b..a762b087d50a 100644 --- a/src/providers/wfs/qgsbackgroundcachedfeatureiterator.cpp +++ b/src/providers/wfs/qgsbackgroundcachedfeatureiterator.cpp @@ -865,7 +865,7 @@ void QgsBackgroundCachedFeatureIterator::copyFeature( const QgsFeature &srcFeatu if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { - for ( auto i : qgis::as_const( mSubSetAttributes ) ) + for ( auto i : std::as_const( mSubSetAttributes ) ) { setAttr( i ); } diff --git a/src/providers/wfs/qgsbackgroundcachedshareddata.cpp b/src/providers/wfs/qgsbackgroundcachedshareddata.cpp index 49f935ade735..afd6da148ab8 100644 --- a/src/providers/wfs/qgsbackgroundcachedshareddata.cpp +++ b/src/providers/wfs/qgsbackgroundcachedshareddata.cpp @@ -163,7 +163,7 @@ bool QgsBackgroundCachedSharedData::createCache() QgsFields cacheFields; std::set setSQLiteColumnNameUpperCase; - for ( const QgsField &field : qgis::as_const( mFields ) ) + for ( const QgsField &field : std::as_const( mFields ) ) { QVariant::Type type = field.type(); // Map DateTime to int64 milliseconds from epoch @@ -263,7 +263,7 @@ bool QgsBackgroundCachedSharedData::createCache() mCacheTablename = QStringLiteral( "features" ); sql = QStringLiteral( "CREATE TABLE %1 (%2 INTEGER PRIMARY KEY" ).arg( mCacheTablename, fidName ); - for ( const QgsField &field : qgis::as_const( cacheFields ) ) + for ( const QgsField &field : std::as_const( cacheFields ) ) { QString type( QStringLiteral( "VARCHAR" ) ); if ( field.type() == QVariant::Int ) diff --git a/src/providers/wfs/qgswfsprovider.cpp b/src/providers/wfs/qgswfsprovider.cpp index 0b9e2ff93597..edf6469089e4 100644 --- a/src/providers/wfs/qgswfsprovider.cpp +++ b/src/providers/wfs/qgswfsprovider.cpp @@ -427,7 +427,7 @@ bool QgsWFSProvider::processSQL( const QString &sqlString, QString &errorMsg, QS } QString concatenatedTypenames; - for ( const QString &typeName : qgis::as_const( typenameList ) ) + for ( const QString &typeName : std::as_const( typenameList ) ) { if ( !concatenatedTypenames.isEmpty() ) concatenatedTypenames += QLatin1Char( ',' ); @@ -459,7 +459,7 @@ bool QgsWFSProvider::processSQL( const QString &sqlString, QString &errorMsg, QS mShared->mLayerPropertiesList.clear(); QMap < QString, QgsFields > mapTypenameToFields; QMap < QString, QString > mapTypenameToGeometryAttribute; - for ( const QString &typeName : qgis::as_const( typenameList ) ) + for ( const QString &typeName : std::as_const( typenameList ) ) { QString geometryAttribute; QgsFields fields; diff --git a/src/providers/wms/qgswmscapabilities.cpp b/src/providers/wms/qgswmscapabilities.cpp index ad64f3e654b9..8dda3d2aadcf 100644 --- a/src/providers/wms/qgswmscapabilities.cpp +++ b/src/providers/wms/qgswmscapabilities.cpp @@ -505,7 +505,7 @@ bool QgsWmsCapabilities::parseResponse( const QByteArray &response, QgsWmsParser } // get identify formats - for ( const QString &f : qgis::as_const( mCapabilities.capability.request.getFeatureInfo.format ) ) + for ( const QString &f : std::as_const( mCapabilities.capability.request.getFeatureInfo.format ) ) { // Don't use mSupportedGetFeatureFormats, there are too many possibilities QgsDebugMsgLevel( "supported format = " + f, 2 ); @@ -959,7 +959,7 @@ void QgsWmsCapabilities::parseCapability( const QDomElement &element, QgsWmsCapa QHash abstracts; // Build layer identifier - title|abstract mapping - for ( const QgsWmsLayerProperty &layer : qgis::as_const( mLayersSupported ) ) + for ( const QgsWmsLayerProperty &layer : std::as_const( mLayersSupported ) ) { if ( !layer.name.isEmpty() ) { diff --git a/src/providers/wms/qgswmscapabilities.h b/src/providers/wms/qgswmscapabilities.h index d3a6a0940fb5..c689410709f5 100644 --- a/src/providers/wms/qgswmscapabilities.h +++ b/src/providers/wms/qgswmscapabilities.h @@ -370,7 +370,7 @@ struct QgsWmsLayerProperty if ( dimensions.isEmpty() ) return false; - for ( const QgsWmsDimensionProperty &dimension : qgis::as_const( dimensions ) ) + for ( const QgsWmsDimensionProperty &dimension : std::as_const( dimensions ) ) { if ( dimension.name == dimensionName ) return true; diff --git a/src/providers/wms/qgswmsdataitems.cpp b/src/providers/wms/qgswmsdataitems.cpp index 0d407cf9655f..4fbc5384e70a 100644 --- a/src/providers/wms/qgswmsdataitems.cpp +++ b/src/providers/wms/qgswmsdataitems.cpp @@ -88,7 +88,7 @@ QVector QgsWMSConnectionItem::createChildren() QgsWmsCapabilitiesProperty capabilitiesProperty = caps.capabilitiesProperty(); const QgsWmsCapabilityProperty &capabilityProperty = capabilitiesProperty.capability; - for ( const QgsWmsLayerProperty &layerProperty : qgis::as_const( capabilityProperty.layers ) ) + for ( const QgsWmsLayerProperty &layerProperty : std::as_const( capabilityProperty.layers ) ) { // Attention, the name may be empty QgsDebugMsgLevel( QString::number( layerProperty.orderId ) + ' ' + layerProperty.name + ' ' + layerProperty.title, 2 ); @@ -127,7 +127,7 @@ QVector QgsWMSConnectionItem::createChildren() children << layerItem; } - for ( const QgsWmtsStyle &style : qgis::as_const( l.styles ) ) + for ( const QgsWmtsStyle &style : std::as_const( l.styles ) ) { QString styleName = style.title.isEmpty() ? style.identifier : style.title; if ( layerItem == this ) @@ -159,7 +159,7 @@ QVector QgsWMSConnectionItem::createChildren() } } - for ( const QgsWmtsTileMatrixSetLink &setLink : qgis::as_const( l.setLinks ) ) + for ( const QgsWmtsTileMatrixSetLink &setLink : std::as_const( l.setLinks ) ) { QString linkName = setLink.tileMatrixSet; if ( styleItem == layerItem ) @@ -191,7 +191,7 @@ QVector QgsWMSConnectionItem::createChildren() } } - for ( const QString &format : qgis::as_const( l.formats ) ) + for ( const QString &format : std::as_const( l.formats ) ) { QString name = format; if ( linkItem == styleItem ) @@ -282,7 +282,7 @@ QString QgsWMSItemBase::createUri() mDataSourceUri.setParam( QStringLiteral( "styles" ), style ); // Check for layer dimensions - for ( const QgsWmsDimensionProperty &dimension : qgis::as_const( mLayerProperty.dimensions ) ) + for ( const QgsWmsDimensionProperty &dimension : std::as_const( mLayerProperty.dimensions ) ) { // add temporal dimensions only if ( dimension.name == QLatin1String( "time" ) || dimension.name == QLatin1String( "reference_time" ) ) @@ -319,7 +319,7 @@ QString QgsWMSItemBase::createUri() QString crs; // get first known if possible QgsCoordinateReferenceSystem testCrs; - for ( const QString &c : qgis::as_const( mLayerProperty.crs ) ) + for ( const QString &c : std::as_const( mLayerProperty.crs ) ) { testCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( c ); if ( testCrs.isValid() ) @@ -349,7 +349,7 @@ QgsWMSLayerCollectionItem::QgsWMSLayerCollectionItem( QgsDataItem *parent, QStri mUri = createUri(); // Populate everything, it costs nothing, all info about layers is collected - for ( const QgsWmsLayerProperty &layerProperty : qgis::as_const( mLayerProperty.layer ) ) + for ( const QgsWmsLayerProperty &layerProperty : std::as_const( mLayerProperty.layer ) ) { // Attention, the name may be empty QgsDebugMsgLevel( QString::number( layerProperty.orderId ) + ' ' + layerProperty.name + ' ' + layerProperty.title, 2 ); diff --git a/src/providers/wms/qgswmsprovider.cpp b/src/providers/wms/qgswmsprovider.cpp index eaf30aecc826..c91eb9f0997f 100644 --- a/src/providers/wms/qgswmsprovider.cpp +++ b/src/providers/wms/qgswmsprovider.cpp @@ -184,7 +184,7 @@ QgsWmsProvider::QgsWmsProvider( QString const &uri, const ProviderOptions &optio if ( mSettings.mCrsId.isEmpty() && !mSettings.mActiveSubLayers.empty() ) { // if crs not specified via layer uri, use the first available from server capabilities - for ( const QgsWmsLayerProperty &property : qgis::as_const( mCaps.mLayersSupported ) ) + for ( const QgsWmsLayerProperty &property : std::as_const( mCaps.mLayersSupported ) ) { if ( property.name == mSettings.mActiveSubLayers[0] ) { @@ -396,7 +396,7 @@ bool QgsWmsProvider::addLayers() } // Set the visibility of these new layers on by default - for ( const QString &layer : qgis::as_const( mSettings.mActiveSubLayers ) ) + for ( const QString &layer : std::as_const( mSettings.mActiveSubLayers ) ) { mActiveSubLayerVisibility[ layer ] = true; QgsDebugMsgLevel( QStringLiteral( "set visibility of layer '%1' to true." ).arg( layer ), 3 ); @@ -1602,7 +1602,7 @@ static const QgsWmsLayerProperty *_findNestedLayerProperty( const QString &layer if ( prop->name == layerName ) return prop; - for ( const QgsWmsLayerProperty &child : qgis::as_const( prop->layer ) ) + for ( const QgsWmsLayerProperty &child : std::as_const( prop->layer ) ) { if ( const QgsWmsLayerProperty *res = _findNestedLayerProperty( layerName, &child ) ) return res; @@ -1615,7 +1615,7 @@ static const QgsWmsLayerProperty *_findNestedLayerProperty( const QString &layer bool QgsWmsProvider::extentForNonTiledLayer( const QString &layerName, const QString &crs, QgsRectangle &extent ) const { const QgsWmsLayerProperty *layerProperty = nullptr; - for ( const QgsWmsLayerProperty &toplevelLayer : qgis::as_const( mCaps.mCapabilities.capability.layers ) ) + for ( const QgsWmsLayerProperty &toplevelLayer : std::as_const( mCaps.mCapabilities.capability.layers ) ) { layerProperty = _findNestedLayerProperty( layerName, &toplevelLayer ); if ( layerProperty ) @@ -2135,7 +2135,7 @@ QString QgsWmsProvider::layerMetadata( QgsWmsLayerProperty &layer ) tr( "Extent" ) % QStringLiteral( "" ); - for ( const QgsWmsDimensionProperty &d : qgis::as_const( layer.dimensions ) ) + for ( const QgsWmsDimensionProperty &d : std::as_const( layer.dimensions ) ) { metadata += QStringLiteral( "
    " ); } @@ -2155,7 +2155,7 @@ QString QgsWmsProvider::layerMetadata( QgsWmsLayerProperty &layer ) tr( "URL" ) % QStringLiteral( "" ); - for ( const QgsWmsMetadataUrlProperty &l : qgis::as_const( layer.metadataUrl ) ) + for ( const QgsWmsMetadataUrlProperty &l : std::as_const( layer.metadataUrl ) ) { metadata += QStringLiteral( "" ); } @@ -2513,7 +2513,7 @@ QString QgsWmsProvider::htmlMetadata() "
    " ) % d.name % QStringLiteral( "" ) % d.units % QStringLiteral( "" ) % d.extent % QStringLiteral( "
    " ) % l.format % QStringLiteral( "" ) % l.onlineResource.xlinkHref % QStringLiteral( "
    " ); // Nested table 3 - for ( const QgsWmtsTileLayer &l : qgis::as_const( mCaps.mTileLayersSupported ) ) + for ( const QgsWmtsTileLayer &l : std::as_const( mCaps.mTileLayersSupported ) ) { metadata += QStringLiteral( "
    " ) % tr( "Identifier" ) % @@ -2580,7 +2580,7 @@ QString QgsWmsProvider::htmlMetadata() QStringLiteral( "" "" ); QStringList styles; - for ( const QgsWmtsStyle &style : qgis::as_const( l.styles ) ) + for ( const QgsWmtsStyle &style : std::as_const( l.styles ) ) { styles << style.identifier; } @@ -2612,7 +2612,7 @@ QString QgsWmsProvider::htmlMetadata() tr( "Available Tilesets" ) % QStringLiteral( "" ); - for ( const QgsWmtsTileMatrixSetLink &setLink : qgis::as_const( l.setLinks ) ) + for ( const QgsWmtsTileMatrixSetLink &setLink : std::as_const( l.setLinks ) ) { metadata += setLink.tileMatrixSet + "
    "; } diff --git a/src/providers/wms/qgswmssourceselect.cpp b/src/providers/wms/qgswmssourceselect.cpp index aeea5fe81a76..77ec77c33db4 100644 --- a/src/providers/wms/qgswmssourceselect.cpp +++ b/src/providers/wms/qgswmssourceselect.cpp @@ -369,7 +369,7 @@ bool QgsWMSSourceSelect::populateLayerList( const QgsWmsCapabilities &capabiliti QHash tileMatrixSets = capabilities.supportedTileMatrixSets(); int rows = 0; - for ( const QgsWmtsTileLayer &l : qgis::as_const( mTileLayers ) ) + for ( const QgsWmtsTileLayer &l : std::as_const( mTileLayers ) ) { rows += l.styles.size() * l.setLinks.size() * l.formats.size(); } @@ -379,7 +379,7 @@ bool QgsWMSSourceSelect::populateLayerList( const QgsWmsCapabilities &capabiliti lstTilesets->setSortingEnabled( false ); int row = 0; - for ( const QgsWmtsTileLayer &l : qgis::as_const( mTileLayers ) ) + for ( const QgsWmtsTileLayer &l : std::as_const( mTileLayers ) ) { for ( const QgsWmtsStyle &style : l.styles ) { @@ -545,7 +545,7 @@ void QgsWMSSourceSelect::addButtonClicked() const QgsWmtsTileLayer *layer = nullptr; - for ( const QgsWmtsTileLayer &l : qgis::as_const( mTileLayers ) ) + for ( const QgsWmtsTileLayer &l : std::as_const( mTileLayers ) ) { if ( l.identifier == layers.join( QLatin1Char( ',' ) ) ) { @@ -1023,12 +1023,12 @@ void QgsWMSSourceSelect::collectSelectedLayers( QStringList &layers, QStringList void QgsWMSSourceSelect::collectDimensions( QStringList &layers, QgsDataSourceUri &uri ) { - for ( const QgsWmsLayerProperty &layerProperty : qgis::as_const( mLayerProperties ) ) + for ( const QgsWmsLayerProperty &layerProperty : std::as_const( mLayerProperties ) ) { if ( layerProperty.name == layers.join( ',' ) ) { // Check for layer dimensions - for ( const QgsWmsDimensionProperty &dimension : qgis::as_const( layerProperty.dimensions ) ) + for ( const QgsWmsDimensionProperty &dimension : std::as_const( layerProperty.dimensions ) ) { // add temporal dimensions only if ( dimension.name == QLatin1String( "time" ) || @@ -1150,7 +1150,7 @@ void QgsWMSSourceSelect::filterLayers( const QString &searchText ) } mTreeInitialExpand.clear(); - for ( QTreeWidgetItem *item : qgis::as_const( items ) ) + for ( QTreeWidgetItem *item : std::as_const( items ) ) { setChildrenVisible( item, true ); diff --git a/src/quickgui/qgsquickmapcanvasmap.cpp b/src/quickgui/qgsquickmapcanvasmap.cpp index d52ee61f1654..6afcdee84864 100644 --- a/src/quickgui/qgsquickmapcanvasmap.cpp +++ b/src/quickgui/qgsquickmapcanvasmap.cpp @@ -335,7 +335,7 @@ void QgsQuickMapCanvasMap::onLayersChanged() if ( mMapSettings->extent().isEmpty() ) zoomToFullExtent(); - for ( const QMetaObject::Connection &conn : qgis::as_const( mLayerConnections ) ) + for ( const QMetaObject::Connection &conn : std::as_const( mLayerConnections ) ) { disconnect( conn ); } diff --git a/src/quickgui/qgsquickutils.cpp b/src/quickgui/qgsquickutils.cpp index 66d3b3d3fa32..d607c8326080 100644 --- a/src/quickgui/qgsquickutils.cpp +++ b/src/quickgui/qgsquickutils.cpp @@ -369,7 +369,7 @@ QVariantMap QgsQuickUtils::createValueRelationCache( const QVariantMap &config, QVariantMap valueMap; QgsValueRelationFieldFormatter::ValueRelationCache cache = QgsValueRelationFieldFormatter::createCache( config, formFeature ); - for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : qgis::as_const( cache ) ) + for ( const QgsValueRelationFieldFormatter::ValueRelationItem &item : std::as_const( cache ) ) { valueMap.insert( item.key.toString(), item.value ); } diff --git a/src/server/qgsserverapiutils.cpp b/src/server/qgsserverapiutils.cpp index 7bf3a775c8cc..70d7e82b6c1d 100644 --- a/src/server/qgsserverapiutils.cpp +++ b/src/server/qgsserverapiutils.cpp @@ -284,7 +284,7 @@ QgsExpression QgsServerApiUtils::temporalFilterExpression( const QgsVectorLayer { QgsDateRange dateInterval { QgsServerApiUtils::parseTemporalDateInterval( interval ) }; - for ( const auto &dimension : qgis::as_const( dimensions ) ) + for ( const auto &dimension : std::as_const( dimensions ) ) { // Determine the field type from the dimension name "time"/"date" @@ -320,7 +320,7 @@ QgsExpression QgsServerApiUtils::temporalFilterExpression( const QgsVectorLayer else // try datetime { QgsDateTimeRange dateTimeInterval { QgsServerApiUtils::parseTemporalDateTimeInterval( interval ) }; - for ( const auto &dimension : qgis::as_const( dimensions ) ) + for ( const auto &dimension : std::as_const( dimensions ) ) { // Determine the field type from the dimension name "time"/"date" @@ -369,7 +369,7 @@ QgsExpression QgsServerApiUtils::temporalFilterExpression( const QgsVectorLayer else // single value { - for ( const auto &dimension : qgis::as_const( dimensions ) ) + for ( const auto &dimension : std::as_const( dimensions ) ) { // Determine the field type from the dimension name "time"/"date" const bool fieldIsDateTime { dimension.name.toLower() == QLatin1String( "time" ) }; diff --git a/src/server/qgsserverfeatureid.cpp b/src/server/qgsserverfeatureid.cpp index a7f3edca29e9..285d5e4ab6d4 100644 --- a/src/server/qgsserverfeatureid.cpp +++ b/src/server/qgsserverfeatureid.cpp @@ -29,7 +29,7 @@ QString QgsServerFeatureId::getServerFid( const QgsFeature &feature, const QgsAt } QStringList pkValues; - for ( const auto &attrIdx : qgis::as_const( pkAttributes ) ) + for ( const auto &attrIdx : std::as_const( pkAttributes ) ) { pkValues.append( feature.attribute( attrIdx ).toString() ); } @@ -64,7 +64,7 @@ QgsFeatureRequest QgsServerFeatureId::updateFeatureRequestFromServerFids( QgsFea else { QString fullExpression; - for ( const QString &exp : qgis::as_const( expList ) ) + for ( const QString &exp : std::as_const( expList ) ) { if ( !fullExpression.isEmpty() ) { diff --git a/src/server/qgsserverogcapihandler.cpp b/src/server/qgsserverogcapihandler.cpp index 30b3f71775a0..7e1c7ff0204d 100644 --- a/src/server/qgsserverogcapihandler.cpp +++ b/src/server/qgsserverogcapihandler.cpp @@ -590,7 +590,7 @@ json QgsServerOgcApiHandler::jsonTags() const void QgsServerOgcApiHandler::setContentTypesInt( const QList &contentTypes ) { mContentTypes.clear(); - for ( const int &i : qgis::as_const( contentTypes ) ) + for ( const int &i : std::as_const( contentTypes ) ) { mContentTypes.push_back( static_cast( i ) ); } diff --git a/src/server/qgsserversettings.cpp b/src/server/qgsserversettings.cpp index c216d7ba9754..3f3ccd06c017 100644 --- a/src/server/qgsserversettings.cpp +++ b/src/server/qgsserversettings.cpp @@ -395,7 +395,7 @@ void QgsServerSettings::logSummary() const const QMetaEnum metaEnumSrc( QMetaEnum::fromType() ); QgsMessageLog::logMessage( "QGIS Server Settings: ", "Server", Qgis::Info ); - for ( const Setting &s : qgis::as_const( mSettings ) ) + for ( const Setting &s : std::as_const( mSettings ) ) { const QString src = metaEnumSrc.valueToKey( s.src ); const QString var = name( s.envVar ); diff --git a/src/server/services/landingpage/qgslandingpageutils.cpp b/src/server/services/landingpage/qgslandingpageutils.cpp index 9f50e1f0afa2..99561ea432a9 100644 --- a/src/server/services/landingpage/qgslandingpageutils.cpp +++ b/src/server/services/landingpage/qgslandingpageutils.cpp @@ -153,7 +153,7 @@ json QgsLandingPageUtils::projectInfo( const QString &projectUri, const QgsServe auto jList = [ ]( const QStringList & l ) -> json { json a = json::array( ); - for ( const auto &e : qgis::as_const( l ) ) + for ( const auto &e : std::as_const( l ) ) { a.push_back( e.toStdString() ); } @@ -306,7 +306,7 @@ json QgsLandingPageUtils::projectInfo( const QString &projectUri, const QgsServe // CRS const QStringList wmsOutputCrsList { QgsServerProjectUtils::wmsOutputCrsList( *p ) }; const QString crs { wmsOutputCrsList.contains( QStringLiteral( "EPSG:4326" ) ) || wmsOutputCrsList.isEmpty() ? - QStringLiteral( "EPSG:4326" ) : wmsOutputCrsList.first() }; + QStringLiteral( "EPSG:4326" ) : wmsOutputCrsList.first() }; info["crs"] = crs.toStdString(); // Typenames for WMS const bool useIds { QgsServerProjectUtils::wmsUseLayerIds( *p ) }; @@ -474,11 +474,11 @@ json QgsLandingPageUtils::projectInfo( const QString &projectUri, const QgsServe } const QgsFieldConstraints::Constraints constraints { field.constraints().constraints() }; const bool notNull { constraints &QgsFieldConstraints::Constraint::ConstraintNotNull && - field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintNotNull ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; + field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintNotNull ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; const bool unique { constraints &QgsFieldConstraints::Constraint::ConstraintUnique && - field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintUnique ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; + field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintUnique ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; const bool hasExpression { constraints &QgsFieldConstraints::Constraint::ConstraintExpression && - field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintExpression ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; + field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintExpression ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; const QString &defaultValue { vl->dataProvider()->defaultValueClause( fieldIdx ) }; const bool isReadOnly( notNull && unique && ! defaultValue.isEmpty() ); fieldsData[ field.name().toStdString() ] = diff --git a/src/server/services/wfs/qgswfsgetfeature.cpp b/src/server/services/wfs/qgswfsgetfeature.cpp index f2a68f2aa7d5..1b288036c615 100644 --- a/src/server/services/wfs/qgswfsgetfeature.cpp +++ b/src/server/services/wfs/qgswfsgetfeature.cpp @@ -333,7 +333,7 @@ namespace QgsWfs accessControl->filterFeatures( vlayer, featureRequest ); QStringList attributes = QStringList(); - for ( int idx : qgis::as_const( attrIndexes ) ) + for ( int idx : std::as_const( attrIndexes ) ) { attributes.append( vlayer->fields().field( idx ).name() ); } diff --git a/src/server/services/wfs/qgswfstransaction.cpp b/src/server/services/wfs/qgswfstransaction.cpp index 3c5e116373c7..a0ca806847e5 100644 --- a/src/server/services/wfs/qgswfstransaction.cpp +++ b/src/server/services/wfs/qgswfstransaction.cpp @@ -776,7 +776,7 @@ namespace QgsWfs // Get the Feature Ids of the inserted feature QgsAttributeList pkAttributes = provider->pkAttributeIndexes(); - for ( const QgsFeature &feat : qgis::as_const( featureList ) ) + for ( const QgsFeature &feat : std::as_const( featureList ) ) { action.insertFeatureIds << QStringLiteral( "%1.%2" ).arg( typeName, QgsServerFeatureId::getServerFid( feat, pkAttributes ) ); } diff --git a/src/server/services/wfs/qgswfstransaction_1_0_0.cpp b/src/server/services/wfs/qgswfstransaction_1_0_0.cpp index b8e584aa8434..7faf05ab5ea9 100644 --- a/src/server/services/wfs/qgswfstransaction_1_0_0.cpp +++ b/src/server/services/wfs/qgswfstransaction_1_0_0.cpp @@ -752,7 +752,7 @@ namespace QgsWfs // Get the Feature Ids of the inserted feature QgsAttributeList pkAttributes = provider->pkAttributeIndexes(); - for ( const QgsFeature &feat : qgis::as_const( featureList ) ) + for ( const QgsFeature &feat : std::as_const( featureList ) ) { action.insertFeatureIds << QStringLiteral( "%1.%2" ).arg( typeName, QgsServerFeatureId::getServerFid( feat, pkAttributes ) ); } diff --git a/src/server/services/wfs/qgswfsutils.cpp b/src/server/services/wfs/qgswfsutils.cpp index 292327473796..d31060680e8b 100644 --- a/src/server/services/wfs/qgswfsutils.cpp +++ b/src/server/services/wfs/qgswfsutils.cpp @@ -81,7 +81,7 @@ namespace QgsWfs QgsVectorLayer *layerByTypeName( const QgsProject *project, const QString &typeName ) { QStringList layerIds = QgsServerProjectUtils::wfsLayerIds( *project ); - for ( const QString &layerId : qgis::as_const( layerIds ) ) + for ( const QString &layerId : std::as_const( layerIds ) ) { QgsMapLayer *layer = project->mapLayer( layerId ); if ( !layer ) diff --git a/src/server/services/wms/qgswmsgetcapabilities.cpp b/src/server/services/wms/qgswmsgetcapabilities.cpp index ba2550661d42..9b135faa9186 100644 --- a/src/server/services/wms/qgswmsgetcapabilities.cpp +++ b/src/server/services/wms/qgswmsgetcapabilities.cpp @@ -1988,7 +1988,7 @@ namespace QgsWms keywordsElem.appendChild( keywordElem ); parent.appendChild( keywordsElem ); QStringList keywords = QgsServerProjectUtils::owsServiceKeywords( *project ); - for ( const QString &keyword : qgis::as_const( keywords ) ) + for ( const QString &keyword : std::as_const( keywords ) ) { if ( !keyword.isEmpty() ) { diff --git a/src/server/services/wms/qgswmsparameters.cpp b/src/server/services/wms/qgswmsparameters.cpp index d2488003ce75..b18b76610fb9 100644 --- a/src/server/services/wms/qgswmsparameters.cpp +++ b/src/server/services/wms/qgswmsparameters.cpp @@ -1779,7 +1779,7 @@ namespace QgsWms QStringList layers; QList eParams; - for ( const auto &layer : qgis::as_const( allLayers ) ) + for ( const auto &layer : std::as_const( allLayers ) ) { if ( isExternalLayer( layer ) ) { diff --git a/src/server/services/wms/qgswmsrendercontext.cpp b/src/server/services/wms/qgswmsrendercontext.cpp index f2f8dbfd487f..7b5dfb8dbf14 100644 --- a/src/server/services/wms/qgswmsrendercontext.cpp +++ b/src/server/services/wms/qgswmsrendercontext.cpp @@ -212,7 +212,7 @@ QStringList QgsWmsRenderContext::flattenedQueryLayers( const QStringList &layerN return _result; }; - for ( const auto &name : qgis::as_const( layerNames ) ) + for ( const auto &name : std::as_const( layerNames ) ) { result.append( findLeaves( name ) ); } @@ -384,7 +384,7 @@ void QgsWmsRenderContext::initRestrictedLayers() QStringList restrictedLayersNames; QgsLayerTreeGroup *root = mProject->layerTreeRoot(); - for ( const QString &l : qgis::as_const( restricted ) ) + for ( const QString &l : std::as_const( restricted ) ) { const QgsLayerTreeGroup *group = root->findGroup( l ); if ( group ) diff --git a/src/server/services/wms/qgswmsrenderer.cpp b/src/server/services/wms/qgswmsrenderer.cpp index 62e824f6d4e5..2fe5e58ff471 100644 --- a/src/server/services/wms/qgswmsrenderer.cpp +++ b/src/server/services/wms/qgswmsrenderer.cpp @@ -577,7 +577,7 @@ namespace QgsWms // has id 0 and so on ... int mapId = 0; - for ( const auto &map : qgis::as_const( maps ) ) + for ( const auto &map : std::as_const( maps ) ) { QgsWmsParametersComposerMap cMapParams = mWmsParameters.composerMapParameters( mapId ); mapId++; @@ -682,7 +682,7 @@ namespace QgsWms // Labels QList labels; c->layoutItems( labels ); - for ( const auto &label : qgis::as_const( labels ) ) + for ( const auto &label : std::as_const( labels ) ) { bool ok = false; const QString labelId = label->id(); @@ -706,7 +706,7 @@ namespace QgsWms // HTMLs QList htmls; c->layoutObjects( htmls ); - for ( const auto &html : qgis::as_const( htmls ) ) + for ( const auto &html : std::as_const( htmls ) ) { if ( html->frameCount() == 0 ) continue; @@ -740,7 +740,7 @@ namespace QgsWms // legends QList legends; c->layoutItems( legends ); - for ( const auto &legend : qgis::as_const( legends ) ) + for ( const auto &legend : std::as_const( legends ) ) { if ( legend->autoUpdateModel() ) { @@ -1297,7 +1297,7 @@ namespace QgsWms { bool validLayer = false; bool queryableLayer = true; - for ( QgsMapLayer *layer : qgis::as_const( layers ) ) + for ( QgsMapLayer *layer : std::as_const( layers ) ) { if ( queryLayer == mContext.layerNickname( *layer ) ) { @@ -2453,7 +2453,7 @@ namespace QgsWms exporter.setIncludeGeometry( withGeometry ); exporter.setTransformGeometries( false ); - for ( const auto &feature : qgis::as_const( features ) ) + for ( const auto &feature : std::as_const( features ) ) { const QString id = QStringLiteral( "%1.%2" ).arg( layerName ).arg( fidMap.value( feature.id() ) ); json["features"].push_back( exporter.exportFeatureToJsonObject( feature, QVariantMap(), id ) ); diff --git a/tests/src/analysis/testqgsrastercalculator.cpp b/tests/src/analysis/testqgsrastercalculator.cpp index 18cc55014636..aae3c2e2c1e8 100644 --- a/tests/src/analysis/testqgsrastercalculator.cpp +++ b/tests/src/analysis/testqgsrastercalculator.cpp @@ -612,7 +612,7 @@ void TestQgsRasterCalculator::testRasterEntries() QgsProject::instance()->addMapLayers( layers ); QVector availableRasterBands = QgsRasterCalculatorEntry::rasterEntries(); QMap entryMap; - for ( const auto &rb : qgis::as_const( availableRasterBands ) ) + for ( const auto &rb : std::as_const( availableRasterBands ) ) { entryMap[rb.ref] = rb; } diff --git a/tests/src/core/testqgis.cpp b/tests/src/core/testqgis.cpp index 4ad74d6ce8a6..e2ebd5a37470 100644 --- a/tests/src/core/testqgis.cpp +++ b/tests/src/core/testqgis.cpp @@ -342,7 +342,7 @@ void TestQgis::testQgsAsConst() ConstTester ct; ct.doSomething(); QCOMPARE( ct.mVal, 1 ); - qgis::as_const( ct ).doSomething(); + std::as_const( ct ).doSomething(); QCOMPARE( ct.mVal, 2 ); } diff --git a/tests/src/core/testqgscompositionconverter.cpp b/tests/src/core/testqgscompositionconverter.cpp index 564f5cb5c7c9..3a1ab011ef26 100644 --- a/tests/src/core/testqgscompositionconverter.cpp +++ b/tests/src/core/testqgscompositionconverter.cpp @@ -420,7 +420,7 @@ void TestQgsCompositionConverter::importComposerTemplateMap() int count = 0; QList items; layout->layoutItems( items ); - for ( auto const &mapItem : qgis::as_const( items ) ) + for ( auto const &mapItem : std::as_const( items ) ) { const auto overviewItems = mapItem->overviews()->asList(); for ( auto const &item : overviewItems ) @@ -622,7 +622,7 @@ void TestQgsCompositionConverter::importComposerTemplate() QList mapItems; layout->layoutItems( mapItems ); mapUuids.reserve( mapItems.count() ); - for ( auto const &item : qgis::as_const( mapItems ) ) + for ( auto const &item : std::as_const( mapItems ) ) { mapUuids << item->uuid(); } @@ -632,7 +632,7 @@ void TestQgsCompositionConverter::importComposerTemplate() int count = 0; QList items; layout->layoutItems( items ); - for ( auto const &item : qgis::as_const( items ) ) + for ( auto const &item : std::as_const( items ) ) { if ( item->linkedMap() ) { @@ -650,7 +650,7 @@ void TestQgsCompositionConverter::importComposerTemplate() int count = 0; QList items; layout->layoutItems( items ); - for ( auto const &item : qgis::as_const( items ) ) + for ( auto const &item : std::as_const( items ) ) { if ( item->linkedMap() ) { @@ -667,7 +667,7 @@ void TestQgsCompositionConverter::importComposerTemplate() int count = 0; QList items; layout->layoutItems( items ); - for ( auto const &item : qgis::as_const( items ) ) + for ( auto const &item : std::as_const( items ) ) { if ( item->linkedMap( ) ) { diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp index 22b940f0440c..9a2f49c7bc40 100644 --- a/tests/src/core/testqgsgeometry.cpp +++ b/tests/src/core/testqgsgeometry.cpp @@ -18397,7 +18397,7 @@ void TestQgsGeometry::testRandomPointsInPolygon() QgsGeometry g = QgsGeometry::fromWkt( QStringLiteral( "Polygon(( 5 15, 10 15, 10 20, 5 20, 5 15 ), (6 16, 8 16, 8 18, 6 16 ))" ) ); points = g.randomPointsInPolygon( 10000 ); QCOMPARE( points.count(), 10000 ); - for ( const QgsPointXY &p : qgis::as_const( points ) ) + for ( const QgsPointXY &p : std::as_const( points ) ) QVERIFY( g.intersects( QgsGeometry::fromPointXY( p ) ) ); // valid multipolygon @@ -18406,7 +18406,7 @@ void TestQgsGeometry::testRandomPointsInPolygon() QCOMPARE( points.count(), 10000 ); bool foundp1Point = false; bool foundp2Point = false; - for ( const QgsPointXY &p : qgis::as_const( points ) ) + for ( const QgsPointXY &p : std::as_const( points ) ) { QVERIFY( g.intersects( QgsGeometry::fromPointXY( p ) ) ); foundp1Point |= p.x() < 100; @@ -18438,7 +18438,7 @@ void TestQgsGeometry::testRandomPointsInPolygon() QCOMPARE( points.count(), 10000 ); foundp1Point = false; foundp2Point = false; - for ( const QgsPointXY &p : qgis::as_const( points ) ) + for ( const QgsPointXY &p : std::as_const( points ) ) { QVERIFY( g.intersects( QgsGeometry::fromPointXY( p ) ) ); foundp1Point |= p.x() < 100; diff --git a/tests/src/core/testqgsgeopdfexport.cpp b/tests/src/core/testqgsgeopdfexport.cpp index ecd40c2c328a..12b5560dccb1 100644 --- a/tests/src/core/testqgsgeopdfexport.cpp +++ b/tests/src/core/testqgsgeopdfexport.cpp @@ -131,7 +131,7 @@ void TestQgsGeoPdfExport::testCollectingFeatures() QVERIFY( geoPdfExporter.saveTemporaryLayers() ); QCOMPARE( geoPdfExporter.mVectorComponents.count(), 2 ); QgsAbstractGeoPdfExporter::VectorComponentDetail component; - for ( const auto &it : qgis::as_const( geoPdfExporter.mVectorComponents ) ) + for ( const auto &it : std::as_const( geoPdfExporter.mVectorComponents ) ) { if ( it.mapLayerId == QLatin1String( "layer1" ) ) { @@ -158,7 +158,7 @@ void TestQgsGeoPdfExport::testCollectingFeatures() QCOMPARE( f.attributes().at( 2 ).toInt(), 22 ); QCOMPARE( f.geometry().asWkt(), QStringLiteral( "Polygon ((2 10, 7 10, 7 20, 2 20, 2 10))" ) ); - for ( const auto &it : qgis::as_const( geoPdfExporter.mVectorComponents ) ) + for ( const auto &it : std::as_const( geoPdfExporter.mVectorComponents ) ) { if ( it.mapLayerId == QLatin1String( "layer2" ) ) { @@ -209,7 +209,7 @@ void TestQgsGeoPdfExport::testComposition() QString layer2Path; QString layer2Layer; - for ( const auto &it : qgis::as_const( geoPdfExporter.mVectorComponents ) ) + for ( const auto &it : std::as_const( geoPdfExporter.mVectorComponents ) ) { if ( it.mapLayerId == QLatin1String( "layer1" ) ) { @@ -448,7 +448,7 @@ void TestQgsGeoPdfExport::testGroups() QString layer2Path; QString layer2Layer; - for ( const auto &it : qgis::as_const( geoPdfExporter.mVectorComponents ) ) + for ( const auto &it : std::as_const( geoPdfExporter.mVectorComponents ) ) { if ( it.mapLayerId == QLatin1String( "layer1" ) ) { @@ -529,7 +529,7 @@ void TestQgsGeoPdfExport::testCustomGroups() QString layer2Path; QString layer2Layer; - for ( const auto &it : qgis::as_const( geoPdfExporter.mVectorComponents ) ) + for ( const auto &it : std::as_const( geoPdfExporter.mVectorComponents ) ) { if ( it.mapLayerId == QLatin1String( "layer1" ) ) { diff --git a/tests/src/core/testqgsmaprendererjob.cpp b/tests/src/core/testqgsmaprendererjob.cpp index d9421324e0ee..04a4104e8ead 100644 --- a/tests/src/core/testqgsmaprendererjob.cpp +++ b/tests/src/core/testqgsmaprendererjob.cpp @@ -433,7 +433,7 @@ void TestQgsMapRendererJob::testRenderedFeatureHandlers() QCOMPARE( geometries2.count(), 5 ); QStringList attributes; - for ( const QgsFeature &f : qgis::as_const( features1 ) ) + for ( const QgsFeature &f : std::as_const( features1 ) ) { QStringList bits; for ( const QVariant &v : f.attributes() ) @@ -448,7 +448,7 @@ void TestQgsMapRendererJob::testRenderedFeatureHandlers() QCOMPARE( attributes.at( 4 ), QStringLiteral( "Jet,,,,," ) ); QStringList wkts; - for ( const QgsGeometry &g : qgis::as_const( geometries1 ) ) + for ( const QgsGeometry &g : std::as_const( geometries1 ) ) { QgsDebugMsg( g.asWkt( 1 ) ); wkts << g.asWkt( 1 ); @@ -473,7 +473,7 @@ void TestQgsMapRendererJob::testRenderedFeatureHandlers() QCOMPARE( features3.count(), 5 ); QCOMPARE( geometries3.count(), 5 ); attributes.clear(); - for ( const QgsFeature &f : qgis::as_const( features3 ) ) + for ( const QgsFeature &f : std::as_const( features3 ) ) { QStringList bits; for ( const QVariant &v : f.attributes() ) diff --git a/tests/src/core/testqgstaskmanager.cpp b/tests/src/core/testqgstaskmanager.cpp index 60c8e47d15aa..2a6e5e5c7935 100644 --- a/tests/src/core/testqgstaskmanager.cpp +++ b/tests/src/core/testqgstaskmanager.cpp @@ -1564,12 +1564,12 @@ void TestQgsTaskManager::cancelBeforeStart() manager.addTask( task ); } - for ( QgsTask *t : qgis::as_const( tasks ) ) + for ( QgsTask *t : std::as_const( tasks ) ) { t->cancel(); } - for ( QgsTask *t : qgis::as_const( tasks ) ) + for ( QgsTask *t : std::as_const( tasks ) ) { t->waitForFinished(); } diff --git a/tests/src/gui/testprocessinggui.cpp b/tests/src/gui/testprocessinggui.cpp index 8190ba034ed0..9fcd4b661c13 100644 --- a/tests/src/gui/testprocessinggui.cpp +++ b/tests/src/gui/testprocessinggui.cpp @@ -1281,7 +1281,7 @@ void TestProcessingGui::testAuthCfgWrapper() QgsAuthManager *authm = QgsApplication::authManager(); QStringList authIds; - for ( QgsAuthMethodConfig config : qgis::as_const( configs ) ) + for ( QgsAuthMethodConfig config : std::as_const( configs ) ) { QVERIFY( config.isValid() ); From d571df638fa32a22f3c2c48574352d1bbda1333d Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 10:05:27 +1000 Subject: [PATCH 139/377] Fix build --- src/core/qgsmaplayerref.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/qgsmaplayerref.h b/src/core/qgsmaplayerref.h index bd55941d47a0..69e68e53694d 100644 --- a/src/core/qgsmaplayerref.h +++ b/src/core/qgsmaplayerref.h @@ -23,6 +23,7 @@ #include "qgsmaplayer.h" #include "qgsdataprovider.h" #include "qgsproject.h" +#include /** * Internal structure to keep weak pointer to QgsMapLayer or layerId From 352b073450f2a27a9241d18a13dd1b03af5d30b9 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 10:18:01 +1000 Subject: [PATCH 140/377] Can't use std::as_const in headers which sip reads... --- src/core/qgsmaplayerref.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/qgsmaplayerref.h b/src/core/qgsmaplayerref.h index 69e68e53694d..d0eac9f57c2c 100644 --- a/src/core/qgsmaplayerref.h +++ b/src/core/qgsmaplayerref.h @@ -230,9 +230,9 @@ struct _LayerRef { layers = project->mapLayers().values(); } - for ( QgsMapLayer *l : std::as_const( layers ) ) + for ( auto it = layers.constBegin(); it != layers.constEnd(); ++it ) { - if ( TYPE *tl = qobject_cast< TYPE *>( l ) ) + if ( TYPE *tl = qobject_cast< TYPE *>( *it ) ) { if ( layerMatchesWeakly( tl, matchType ) ) { From 9b80f428d5c7565338a0dd2f38d905bd043425b4 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 10:21:27 +1000 Subject: [PATCH 141/377] Fix build again --- src/core/symbology/qgsrulebasedrenderer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/symbology/qgsrulebasedrenderer.h b/src/core/symbology/qgsrulebasedrenderer.h index f0184ba9b744..86d20f2e1cb1 100644 --- a/src/core/symbology/qgsrulebasedrenderer.h +++ b/src/core/symbology/qgsrulebasedrenderer.h @@ -102,9 +102,9 @@ class CORE_EXPORT QgsRuleBasedRenderer : public QgsFeatureRenderer zIndex = rh.zIndex; qDeleteAll( jobs ); jobs.clear(); - for ( RenderJob *job : std::as_const( rh.jobs ) ) + for ( auto it = rh.jobs.constBegin(); it != rh.jobs.constEnd(); ++it ) { - jobs << new RenderJob( *job ); + jobs << new RenderJob( *( *it ) ); } return *this; } @@ -112,9 +112,9 @@ class CORE_EXPORT QgsRuleBasedRenderer : public QgsFeatureRenderer RenderLevel( const QgsRuleBasedRenderer::RenderLevel &other ) : zIndex( other.zIndex ), jobs() { - for ( RenderJob *job : std::as_const( other.jobs ) ) + for ( auto it = other.jobs.constBegin(); it != other.jobs.constEnd(); ++it ) { - jobs << new RenderJob( *job ); + jobs << new RenderJob( * ( *it ) ); } } From b1d1b36bd605fa14fdfa4b83779618f7476f2581 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 10:37:20 +1000 Subject: [PATCH 142/377] Remove redundant qgsOverload, use qOverload instead --- src/app/3d/qgs3danimationwidget.cpp | 4 +-- src/app/3d/qgslightswidget.cpp | 20 +++++------ src/app/3d/qgsmap3dexportwidget.cpp | 6 ++-- src/app/3d/qgspointcloud3dsymbolwidget.cpp | 12 +++---- .../3d/qgsskyboxrenderingsettingswidget.cpp | 2 +- .../3d/qgsvectorlayer3dpropertieswidget.cpp | 2 +- src/app/3d/qgsvectorlayer3drendererwidget.cpp | 2 +- .../qgsdecorationcopyrightdialog.cpp | 2 +- .../decorations/qgsdecorationimagedialog.cpp | 2 +- .../qgsdecorationnortharrowdialog.cpp | 2 +- .../qgsdecorationscalebardialog.cpp | 2 +- .../decorations/qgsdecorationtitledialog.cpp | 2 +- .../networklogger/qgsnetworklogger.cpp | 12 +++---- .../profiler/qgsprofilerpanelwidget.cpp | 2 +- src/app/gps/qgsgpsinformationwidget.cpp | 10 +++--- src/app/layout/qgslayout3dmapwidget.cpp | 2 +- src/app/maptools/qgsappmaptools.cpp | 2 +- src/app/mesh/qgsmeshcalculatordialog.cpp | 4 +-- src/app/options/qgscodeeditoroptions.cpp | 6 ++-- src/app/options/qgsoptions.cpp | 4 +-- ...qgspointcloudelevationpropertieswidget.cpp | 4 +-- src/app/qgisapp.cpp | 6 ++-- src/app/qgsapplayertreeviewmenuprovider.cpp | 4 +-- src/app/qgscustomprojectiondialog.cpp | 2 +- src/app/qgsidentifyresultsdialog.cpp | 4 +-- src/app/qgsmapcanvasdockwidget.cpp | 4 +-- src/app/qgsmaptoolcircle2tangentspoint.cpp | 2 +- src/app/qgsrelationaddpolymorphicdlg.cpp | 2 +- src/app/qgssnappingwidget.cpp | 2 +- src/auth/oauth2/qgsauthoauth2edit.cpp | 4 +-- src/auth/oauth2/qgso2.cpp | 2 +- .../layertree/qgslayertreeregistrybridge.cpp | 2 +- .../network/qgsblockingnetworkrequest.cpp | 2 +- src/core/network/qgsfiledownloader.cpp | 2 +- src/core/network/qgsnetworkaccessmanager.cpp | 16 ++++----- .../pointcloud/qgspointclouddataprovider.cpp | 2 +- src/core/project/qgsproject.cpp | 16 ++++----- src/core/qgis.h | 21 ------------ src/core/qgsfeatureexpressionvaluesgatherer.h | 4 +-- src/core/qgsrunprocess.cpp | 2 +- src/gui/attributetable/qgsdualview.cpp | 2 +- .../editorwidgets/qgscheckboxconfigdlg.cpp | 2 +- .../qgsrelationreferencewidget.cpp | 4 +-- .../labeling/qgslabelengineconfigdialog.cpp | 8 ++--- src/gui/labeling/qgslabelinggui.cpp | 4 +-- src/gui/labeling/qgslabellineanchorwidget.cpp | 6 ++-- .../qgslabelobstaclesettingswidget.cpp | 2 +- src/gui/layout/qgslayoutatlaswidget.cpp | 2 +- src/gui/layout/qgslayoutguidewidget.cpp | 2 +- src/gui/layout/qgslayoutlegendwidget.cpp | 6 ++-- src/gui/layout/qgslayoutmapwidget.cpp | 4 +-- .../mesh/qgsmeshrenderer3daveragingwidget.cpp | 30 ++++++++-------- .../qgsmeshrenderermeshsettingswidget.cpp | 2 +- .../qgsmeshrendererscalarsettingswidget.cpp | 4 +-- .../qgsmeshrenderervectorsettingswidget.cpp | 26 +++++++------- .../mesh/qgsmeshvariablestrokewidthwidget.cpp | 4 +-- .../numericformats/qgsnumericformatwidget.cpp | 14 ++++---- ...ointcloudattributebyramprendererwidget.cpp | 4 +-- .../qgspointcloudrendererpropertieswidget.cpp | 4 +-- .../qgsprocessingaggregatewidgets.cpp | 2 +- ...gsprocessingfeaturesourceoptionswidget.cpp | 4 +-- .../qgsprocessingmeshdatasetwidget.cpp | 2 +- ...ingvectortilewriterlayerswidgetwrapper.cpp | 4 +-- .../qgsprocessingwidgetwrapperimpl.cpp | 16 ++++----- .../ogr/qgsgeopackageprojectstoragedialog.cpp | 6 ++-- src/gui/qgscolorramplegendnodewidget.cpp | 4 +-- src/gui/qgsfieldmappingwidget.cpp | 4 +-- src/gui/qgsmaplayerloadstyledialog.cpp | 2 +- src/gui/qgsnewvectortabledialog.cpp | 4 +-- src/gui/qgstemporalcontrollerwidget.cpp | 4 +-- src/gui/qgstemporalmapsettingswidget.cpp | 2 +- ...qgsvectorlayertemporalpropertieswidget.cpp | 2 +- src/gui/raster/qgscolorrampshaderwidget.cpp | 2 +- .../qgsgraduatedsymbolrendererwidget.cpp | 26 +++++++------- src/gui/symbology/qgssymbollayerwidget.cpp | 10 +++--- .../qgstableeditorformattingwidget.cpp | 6 ++-- .../vector/qgsattributesformproperties.cpp | 2 +- .../vector/qgsvectorlayersavestyledialog.cpp | 2 +- src/gui/vector/qgswmsdimensiondialog.cpp | 2 +- .../qgspostgresprojectstoragedialog.cpp | 6 ++-- src/providers/wfs/qgsbasenetworkrequest.cpp | 2 +- src/providers/wfs/qgswfsprovider.cpp | 2 +- .../src/core/testqgsnetworkaccessmanager.cpp | 34 +++++++++---------- 83 files changed, 231 insertions(+), 252 deletions(-) diff --git a/src/app/3d/qgs3danimationwidget.cpp b/src/app/3d/qgs3danimationwidget.cpp index c792fb68b3a3..5eefa8b11c13 100644 --- a/src/app/3d/qgs3danimationwidget.cpp +++ b/src/app/3d/qgs3danimationwidget.cpp @@ -52,14 +52,14 @@ Qgs3DAnimationWidget::Qgs3DAnimationWidget( QWidget *parent ) connect( btnEditKeyframe, &QToolButton::clicked, this, &Qgs3DAnimationWidget::onEditKeyframe ); connect( btnDuplicateKeyframe, &QToolButton::clicked, this, &Qgs3DAnimationWidget::onDuplicateKeyframe ); connect( btnExportAnimation, &QToolButton::clicked, this, &Qgs3DAnimationWidget::onExportAnimation ); - connect( cboInterpolation, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &Qgs3DAnimationWidget::onInterpolationChanged ); + connect( cboInterpolation, qOverload( &QComboBox::currentIndexChanged ), this, &Qgs3DAnimationWidget::onInterpolationChanged ); btnPlayPause->setCheckable( true ); connect( btnPlayPause, &QToolButton::clicked, this, &Qgs3DAnimationWidget::onPlayPause ); connect( sliderTime, &QSlider::valueChanged, this, &Qgs3DAnimationWidget::onSliderValueChanged ); - connect( cboKeyframe, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &Qgs3DAnimationWidget::onKeyframeChanged ); + connect( cboKeyframe, qOverload( &QComboBox::currentIndexChanged ), this, &Qgs3DAnimationWidget::onKeyframeChanged ); } Qgs3DAnimationWidget::~Qgs3DAnimationWidget() = default; diff --git a/src/app/3d/qgslightswidget.cpp b/src/app/3d/qgslightswidget.cpp index b6520d3ce2f8..12fee9f630ac 100644 --- a/src/app/3d/qgslightswidget.cpp +++ b/src/app/3d/qgslightswidget.cpp @@ -59,22 +59,22 @@ QgsLightsWidget::QgsLightsWidget( QWidget *parent ) connect( btnRemoveLight, &QToolButton::clicked, this, &QgsLightsWidget::onRemoveLight ); - connect( spinPositionX, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); - connect( spinPositionY, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); - connect( spinPositionZ, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); - connect( spinIntensity, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); + connect( spinPositionX, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); + connect( spinPositionY, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); + connect( spinPositionZ, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); + connect( spinIntensity, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); connect( btnColor, &QgsColorButton::colorChanged, this, &QgsLightsWidget::updateCurrentLightParameters ); - connect( spinA0, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); - connect( spinA1, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); - connect( spinA2, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); + connect( spinA0, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); + connect( spinA1, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); + connect( spinA2, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentLightParameters ); - connect( spinDirectionalIntensity, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentDirectionalLightParameters ); + connect( spinDirectionalIntensity, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentDirectionalLightParameters ); connect( btnDirectionalColor, &QgsColorButton::colorChanged, this, &QgsLightsWidget::updateCurrentDirectionalLightParameters ); connect( dialAzimuth, &QSlider::valueChanged, [this]( int value ) {spinBoxAzimuth->setValue( ( value + 180 ) % 360 );} ); connect( sliderAltitude, &QSlider::valueChanged, spinBoxAltitude, &QgsDoubleSpinBox::setValue ); - connect( spinBoxAzimuth, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::onDirectionChange ); - connect( spinBoxAltitude, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::onDirectionChange ); + connect( spinBoxAzimuth, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::onDirectionChange ); + connect( spinBoxAltitude, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::onDirectionChange ); mLightsListView->selectionModel()->select( mLightsModel->index( 0, 0 ), QItemSelectionModel::ClearAndSelect ); selectedLightChanged( mLightsListView->selectionModel()->selection(), QItemSelection() ); diff --git a/src/app/3d/qgsmap3dexportwidget.cpp b/src/app/3d/qgsmap3dexportwidget.cpp index 3d27d1db4423..1cb4f66b7c1d 100644 --- a/src/app/3d/qgsmap3dexportwidget.cpp +++ b/src/app/3d/qgsmap3dexportwidget.cpp @@ -43,11 +43,11 @@ QgsMap3DExportWidget::QgsMap3DExportWidget( Qgs3DMapScene *scene, Qgs3DMapExport connect( ui->sceneNameLineEdit, &QLineEdit::textChanged, [ = ]( const QString & ) { settingsChanged(); } ); connect( ui->selectFolderWidget, &QgsFileWidget::fileChanged, [ = ]( const QString & ) { settingsChanged(); } ); connect( ui->smoothEdgesCheckBox, &QCheckBox::stateChanged, [ = ]( int ) { settingsChanged(); } ); - connect( ui->terrainResolutionSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), [ = ]( int ) { settingsChanged(); } ); + connect( ui->terrainResolutionSpinBox, qOverload( &QSpinBox::valueChanged ), [ = ]( int ) { settingsChanged(); } ); connect( ui->exportNormalsCheckBox, &QCheckBox::stateChanged, [ = ]( int ) { settingsChanged(); } ); connect( ui->exportTexturesCheckBox, &QCheckBox::stateChanged, [ = ]( int ) { settingsChanged(); } ); - connect( ui->terrainTextureResolutionSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), [ = ]( int ) { settingsChanged(); } ); - connect( ui->scaleSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), [ = ]( int ) { settingsChanged(); } ); + connect( ui->terrainTextureResolutionSpinBox, qOverload( &QSpinBox::valueChanged ), [ = ]( int ) { settingsChanged(); } ); + connect( ui->scaleSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), [ = ]( int ) { settingsChanged(); } ); // sets the export settings to whatever is on the scene settingsChanged(); diff --git a/src/app/3d/qgspointcloud3dsymbolwidget.cpp b/src/app/3d/qgspointcloud3dsymbolwidget.cpp index d07c39d2de33..57ff58ff1885 100644 --- a/src/app/3d/qgspointcloud3dsymbolwidget.cpp +++ b/src/app/3d/qgspointcloud3dsymbolwidget.cpp @@ -95,18 +95,18 @@ QgsPointCloud3DSymbolWidget::QgsPointCloud3DSymbolWidget( QgsPointCloudLayer *la if ( symbol ) setSymbol( symbol ); - connect( mPointSizeSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloud3DSymbolWidget::emitChangedSignal ); - connect( mRenderingStyleComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, &QgsPointCloud3DSymbolWidget::onRenderingStyleChanged ); + connect( mPointSizeSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloud3DSymbolWidget::emitChangedSignal ); + connect( mRenderingStyleComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, &QgsPointCloud3DSymbolWidget::onRenderingStyleChanged ); connect( mScalarRecalculateMinMaxButton, &QPushButton::clicked, this, &QgsPointCloud3DSymbolWidget::setMinMaxFromLayer ); connect( mColorRampShaderWidget, &QgsColorRampShaderWidget::widgetChanged, this, &QgsPointCloud3DSymbolWidget::emitChangedSignal ); connect( mSingleColorBtn, &QgsColorButton::colorChanged, this, &QgsPointCloud3DSymbolWidget::emitChangedSignal ); connect( mRenderingParameterComboBox, &QgsPointCloudAttributeComboBox::attributeChanged, this, &QgsPointCloud3DSymbolWidget::rampAttributeChanged ); - connect( mColorRampShaderMinEdit, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloud3DSymbolWidget::minMaxChanged ); - connect( mColorRampShaderMaxEdit, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloud3DSymbolWidget::minMaxChanged ); + connect( mColorRampShaderMinEdit, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloud3DSymbolWidget::minMaxChanged ); + connect( mColorRampShaderMaxEdit, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloud3DSymbolWidget::minMaxChanged ); - connect( mMaxScreenErrorSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, [&]() { emitChangedSignal(); } ); + connect( mMaxScreenErrorSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, [&]() { emitChangedSignal(); } ); connect( mShowBoundingBoxesCheckBox, &QCheckBox::stateChanged, this, [&]() { emitChangedSignal(); } ); - connect( mPointBudgetSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), this, [&]() { emitChangedSignal(); } ); + connect( mPointBudgetSpinBox, qOverload( &QSpinBox::valueChanged ), this, [&]() { emitChangedSignal(); } ); if ( !symbol ) // if we have a symbol, this was already handled in setSymbol above rampAttributeChanged(); diff --git a/src/app/3d/qgsskyboxrenderingsettingswidget.cpp b/src/app/3d/qgsskyboxrenderingsettingswidget.cpp index e3a312c99fc5..ed74f2a3432e 100644 --- a/src/app/3d/qgsskyboxrenderingsettingswidget.cpp +++ b/src/app/3d/qgsskyboxrenderingsettingswidget.cpp @@ -28,7 +28,7 @@ QgsSkyboxRenderingSettingsWidget::QgsSkyboxRenderingSettingsWidget( QWidget *par // To future maintainers: make sure the order of added items is the same as the order at QgsSkyboxEntity::SkyboxType skyboxTypeComboBox->addItem( tr( "Panoramic Texture" ) ); skyboxTypeComboBox->addItem( tr( "Distinct Faces" ) ); - connect( skyboxTypeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsSkyboxRenderingSettingsWidget::showSkyboxSettings ); + connect( skyboxTypeComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsSkyboxRenderingSettingsWidget::showSkyboxSettings ); showSkyboxSettings( 0 ); } diff --git a/src/app/3d/qgsvectorlayer3dpropertieswidget.cpp b/src/app/3d/qgsvectorlayer3dpropertieswidget.cpp index 6a6fe3fd9425..43fa8f0c5ee9 100644 --- a/src/app/3d/qgsvectorlayer3dpropertieswidget.cpp +++ b/src/app/3d/qgsvectorlayer3dpropertieswidget.cpp @@ -26,7 +26,7 @@ QgsVectorLayer3DPropertiesWidget::QgsVectorLayer3DPropertiesWidget( QWidget *par groupLayerRendering->setCollapsed( true ); connect( chkShowBoundingBoxes, &QCheckBox::clicked, this, &QgsVectorLayer3DPropertiesWidget::changed ); - connect( spinZoomLevelsCount, qgis::overload::of( &QSpinBox::valueChanged ), this, &QgsVectorLayer3DPropertiesWidget::changed ); + connect( spinZoomLevelsCount, qOverload( &QSpinBox::valueChanged ), this, &QgsVectorLayer3DPropertiesWidget::changed ); } void QgsVectorLayer3DPropertiesWidget::load( QgsAbstractVectorLayer3DRenderer *renderer ) diff --git a/src/app/3d/qgsvectorlayer3drendererwidget.cpp b/src/app/3d/qgsvectorlayer3drendererwidget.cpp index 0543ff47e768..d39c4d2d587e 100644 --- a/src/app/3d/qgsvectorlayer3drendererwidget.cpp +++ b/src/app/3d/qgsvectorlayer3drendererwidget.cpp @@ -98,7 +98,7 @@ QgsVectorLayer3DRendererWidget::QgsVectorLayer3DRendererWidget( QgsMapLayer *lay widgetRendererStack->addWidget( widgetSingleSymbolRenderer ); widgetRendererStack->addWidget( widgetRuleBasedRenderer ); - connect( cboRendererType, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, &QgsVectorLayer3DRendererWidget::onRendererTypeChanged ); + connect( cboRendererType, qOverload< int >( &QComboBox::currentIndexChanged ), this, &QgsVectorLayer3DRendererWidget::onRendererTypeChanged ); connect( widgetSingleSymbolRenderer, &QgsSingleSymbol3DRendererWidget::widgetChanged, this, &QgsVectorLayer3DRendererWidget::widgetChanged ); connect( widgetRuleBasedRenderer, &QgsRuleBased3DRendererWidget::widgetChanged, this, &QgsVectorLayer3DRendererWidget::widgetChanged ); connect( widgetRuleBasedRenderer, &QgsRuleBased3DRendererWidget::showPanel, this, &QgsPanelWidget::openPanel ); diff --git a/src/app/decorations/qgsdecorationcopyrightdialog.cpp b/src/app/decorations/qgsdecorationcopyrightdialog.cpp index 64df48c2da95..c9c281365690 100644 --- a/src/app/decorations/qgsdecorationcopyrightdialog.cpp +++ b/src/app/decorations/qgsdecorationcopyrightdialog.cpp @@ -66,7 +66,7 @@ QgsDecorationCopyrightDialog::QgsDecorationCopyrightDialog( QgsDecorationCopyrig cboPlacement->addItem( tr( "Bottom Left" ), QgsDecorationItem::BottomLeft ); cboPlacement->addItem( tr( "Bottom Center" ), QgsDecorationItem::BottomCenter ); cboPlacement->addItem( tr( "Bottom Right" ), QgsDecorationItem::BottomRight ); - connect( cboPlacement, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( cboPlacement, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { spnHorizontal->setMinimum( cboPlacement->currentData() == QgsDecorationItem::TopCenter || cboPlacement->currentData() == QgsDecorationItem::BottomCenter ? -100 : 0 ); } ); diff --git a/src/app/decorations/qgsdecorationimagedialog.cpp b/src/app/decorations/qgsdecorationimagedialog.cpp index e7ffaf6d8778..c162cfb383de 100644 --- a/src/app/decorations/qgsdecorationimagedialog.cpp +++ b/src/app/decorations/qgsdecorationimagedialog.cpp @@ -54,7 +54,7 @@ QgsDecorationImageDialog::QgsDecorationImageDialog( QgsDecorationImage &deco, QW cboPlacement->addItem( tr( "Bottom Left" ), QgsDecorationItem::BottomLeft ); cboPlacement->addItem( tr( "Bottom Center" ), QgsDecorationItem::BottomCenter ); cboPlacement->addItem( tr( "Bottom Right" ), QgsDecorationItem::BottomRight ); - connect( cboPlacement, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( cboPlacement, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { spinHorizontal->setMinimum( cboPlacement->currentData() == QgsDecorationItem::TopCenter || cboPlacement->currentData() == QgsDecorationItem::BottomCenter ? -100 : 0 ); } ); diff --git a/src/app/decorations/qgsdecorationnortharrowdialog.cpp b/src/app/decorations/qgsdecorationnortharrowdialog.cpp index aecd71a0a7a3..8bfc27cfbce5 100644 --- a/src/app/decorations/qgsdecorationnortharrowdialog.cpp +++ b/src/app/decorations/qgsdecorationnortharrowdialog.cpp @@ -67,7 +67,7 @@ QgsDecorationNorthArrowDialog::QgsDecorationNorthArrowDialog( QgsDecorationNorth cboPlacement->addItem( tr( "Bottom Left" ), QgsDecorationItem::BottomLeft ); cboPlacement->addItem( tr( "Bottom Center" ), QgsDecorationItem::BottomCenter ); cboPlacement->addItem( tr( "Bottom Right" ), QgsDecorationItem::BottomRight ); - connect( cboPlacement, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( cboPlacement, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { spinHorizontal->setMinimum( cboPlacement->currentData() == QgsDecorationItem::TopCenter || cboPlacement->currentData() == QgsDecorationItem::BottomCenter ? -100 : 0 ); } ); diff --git a/src/app/decorations/qgsdecorationscalebardialog.cpp b/src/app/decorations/qgsdecorationscalebardialog.cpp index 7370371ac829..848fa01225f5 100644 --- a/src/app/decorations/qgsdecorationscalebardialog.cpp +++ b/src/app/decorations/qgsdecorationscalebardialog.cpp @@ -62,7 +62,7 @@ QgsDecorationScaleBarDialog::QgsDecorationScaleBarDialog( QgsDecorationScaleBar cboPlacement->addItem( tr( "Bottom Left" ), QgsDecorationItem::BottomLeft ); cboPlacement->addItem( tr( "Bottom Center" ), QgsDecorationItem::BottomCenter ); cboPlacement->addItem( tr( "Bottom Right" ), QgsDecorationItem::BottomRight ); - connect( cboPlacement, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( cboPlacement, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { spnHorizontal->setMinimum( cboPlacement->currentData() == QgsDecorationItem::TopCenter || cboPlacement->currentData() == QgsDecorationItem::BottomCenter ? -100 : 0 ); } ); diff --git a/src/app/decorations/qgsdecorationtitledialog.cpp b/src/app/decorations/qgsdecorationtitledialog.cpp index 03917cb118e4..fdb65e353036 100644 --- a/src/app/decorations/qgsdecorationtitledialog.cpp +++ b/src/app/decorations/qgsdecorationtitledialog.cpp @@ -73,7 +73,7 @@ QgsDecorationTitleDialog::QgsDecorationTitleDialog( QgsDecorationTitle &deco, QW cboPlacement->addItem( tr( "Bottom Left" ), QgsDecorationItem::BottomLeft ); cboPlacement->addItem( tr( "Bottom Center" ), QgsDecorationItem::BottomCenter ); cboPlacement->addItem( tr( "Bottom Right" ), QgsDecorationItem::BottomRight ); - connect( cboPlacement, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( cboPlacement, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { spnHorizontal->setMinimum( cboPlacement->currentData() == QgsDecorationItem::TopCenter || cboPlacement->currentData() == QgsDecorationItem::BottomCenter ? -100 : 0 ); } ); diff --git a/src/app/devtools/networklogger/qgsnetworklogger.cpp b/src/app/devtools/networklogger/qgsnetworklogger.cpp index 9b040ef3ad2e..8489c351fc9f 100644 --- a/src/app/devtools/networklogger/qgsnetworklogger.cpp +++ b/src/app/devtools/networklogger/qgsnetworklogger.cpp @@ -45,17 +45,17 @@ void QgsNetworkLogger::enableLogging( bool enabled ) { if ( enabled ) { - connect( mNam, qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), this, &QgsNetworkLogger::requestAboutToBeCreated, Qt::UniqueConnection ); - connect( mNam, qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), this, &QgsNetworkLogger::requestFinished, Qt::UniqueConnection ); - connect( mNam, qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsNetworkLogger::requestTimedOut, Qt::UniqueConnection ); + connect( mNam, qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), this, &QgsNetworkLogger::requestAboutToBeCreated, Qt::UniqueConnection ); + connect( mNam, qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), this, &QgsNetworkLogger::requestFinished, Qt::UniqueConnection ); + connect( mNam, qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsNetworkLogger::requestTimedOut, Qt::UniqueConnection ); connect( mNam, &QgsNetworkAccessManager::downloadProgress, this, &QgsNetworkLogger::downloadProgress, Qt::UniqueConnection ); connect( mNam, &QgsNetworkAccessManager::requestEncounteredSslErrors, this, &QgsNetworkLogger::requestEncounteredSslErrors, Qt::UniqueConnection ); } else { - disconnect( mNam, qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), this, &QgsNetworkLogger::requestAboutToBeCreated ); - disconnect( mNam, qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), this, &QgsNetworkLogger::requestFinished ); - disconnect( mNam, qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsNetworkLogger::requestTimedOut ); + disconnect( mNam, qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), this, &QgsNetworkLogger::requestAboutToBeCreated ); + disconnect( mNam, qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), this, &QgsNetworkLogger::requestFinished ); + disconnect( mNam, qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsNetworkLogger::requestTimedOut ); disconnect( mNam, &QgsNetworkAccessManager::downloadProgress, this, &QgsNetworkLogger::downloadProgress ); disconnect( mNam, &QgsNetworkAccessManager::requestEncounteredSslErrors, this, &QgsNetworkLogger::requestEncounteredSslErrors ); } diff --git a/src/app/devtools/profiler/qgsprofilerpanelwidget.cpp b/src/app/devtools/profiler/qgsprofilerpanelwidget.cpp index 8642152cc19f..36b5a8d5e594 100644 --- a/src/app/devtools/profiler/qgsprofilerpanelwidget.cpp +++ b/src/app/devtools/profiler/qgsprofilerpanelwidget.cpp @@ -50,7 +50,7 @@ QgsProfilerPanelWidget::QgsProfilerPanelWidget( QgsRuntimeProfiler *profiler, QW } } ); - connect( mCategoryComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mCategoryComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { mProxyModel->setGroup( mCategoryComboBox->currentData().toString() ); } ); diff --git a/src/app/gps/qgsgpsinformationwidget.cpp b/src/app/gps/qgsgpsinformationwidget.cpp index 70366adcb94e..1171f0ee1da9 100644 --- a/src/app/gps/qgsgpsinformationwidget.cpp +++ b/src/app/gps/qgsgpsinformationwidget.cpp @@ -85,7 +85,7 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *mapCanvas, QWidg connect( mRecenterButton, &QPushButton::clicked, this, &QgsGpsInformationWidget::recenter ); connect( mConnectButton, &QAbstractButton::toggled, mRecenterButton, &QWidget::setEnabled ); connect( mBtnTrackColor, &QgsColorButton::colorChanged, this, &QgsGpsInformationWidget::trackColorChanged ); - connect( mSpinTrackWidth, qgis::overload< int >::of( &QSpinBox::valueChanged ), this, &QgsGpsInformationWidget::mSpinTrackWidth_valueChanged ); + connect( mSpinTrackWidth, qOverload< int >( &QSpinBox::valueChanged ), this, &QgsGpsInformationWidget::mSpinTrackWidth_valueChanged ); connect( mBtnPosition, &QToolButton::clicked, this, &QgsGpsInformationWidget::mBtnPosition_clicked ); connect( mBtnSignal, &QToolButton::clicked, this, &QgsGpsInformationWidget::mBtnSignal_clicked ); connect( mBtnSatellites, &QToolButton::clicked, this, &QgsGpsInformationWidget::mBtnSatellites_clicked ); @@ -381,9 +381,9 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *mapCanvas, QWidg mCboTimestampFormat->addItem( tr( "UTC" ), Qt::TimeSpec::UTC ); mCboTimestampFormat->addItem( tr( "Time Zone" ), Qt::TimeSpec::TimeZone ); mCboTimestampFormat->setCurrentIndex( mySettings.value( QStringLiteral( "gps/timeStampFormat" ), Qt::LocalTime ).toInt() ); - connect( mCboTimestampFormat, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), + connect( mCboTimestampFormat, qOverload< int >( &QComboBox::currentIndexChanged ), this, &QgsGpsInformationWidget::timestampFormatChanged ); - connect( mCboTimestampField, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), + connect( mCboTimestampField, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int index ) { const bool enabled { index > 0 }; @@ -427,9 +427,9 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *mapCanvas, QWidg connect( mAcquisitionTimer.get(), &QTimer::timeout, this, &QgsGpsInformationWidget::switchAcquisition ); - connect( mCboAcquisitionInterval, qgis::overload< const QString & >::of( &QComboBox::currentTextChanged ), + connect( mCboAcquisitionInterval, qOverload< const QString & >( &QComboBox::currentTextChanged ), this, &QgsGpsInformationWidget::cboAcquisitionIntervalEdited ); - connect( mCboDistanceThreshold, qgis::overload< const QString & >::of( &QComboBox::currentTextChanged ), + connect( mCboDistanceThreshold, qOverload< const QString & >( &QComboBox::currentTextChanged ), this, &QgsGpsInformationWidget::cboDistanceThresholdEdited ); mMapCanvas->installInteractionBlocker( this ); diff --git a/src/app/layout/qgslayout3dmapwidget.cpp b/src/app/layout/qgslayout3dmapwidget.cpp index 8c6ecdf76bc5..505a68365849 100644 --- a/src/app/layout/qgslayout3dmapwidget.cpp +++ b/src/app/layout/qgslayout3dmapwidget.cpp @@ -96,7 +96,7 @@ QgsLayout3DMapWidget::QgsLayout3DMapWidget( QgsLayoutItem3DMap *map3D ) QList lst; lst << mCenterXSpinBox << mCenterYSpinBox << mCenterZSpinBox << mDistanceToCenterSpinBox << mPitchAngleSpinBox << mHeadingAngleSpinBox; for ( QgsDoubleSpinBox *spinBox : std::as_const( lst ) ) - connect( spinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayout3DMapWidget::updateCameraPose ); + connect( spinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayout3DMapWidget::updateCameraPose ); updateCameraPoseWidgetsFromItem(); } diff --git a/src/app/maptools/qgsappmaptools.cpp b/src/app/maptools/qgsappmaptools.cpp index 60bf77512410..23b14b310e93 100644 --- a/src/app/maptools/qgsappmaptools.cpp +++ b/src/app/maptools/qgsappmaptools.cpp @@ -95,7 +95,7 @@ QgsStreamDigitizingSettingsAction::QgsStreamDigitizingSettingsAction( QWidget *p QLabel *label = new QLabel( tr( "Streaming Tolerance" ) ); gLayout->addWidget( label, 1, 0 ); gLayout->addWidget( mStreamToleranceSpinBox, 1, 1 ); - connect( mStreamToleranceSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), this, [ = ]( int value ) + connect( mStreamToleranceSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, [ = ]( int value ) { QgsSettings settings; settings.setValue( QStringLiteral( "/qgis/digitizing/stream_tolerance" ), value ); diff --git a/src/app/mesh/qgsmeshcalculatordialog.cpp b/src/app/mesh/qgsmeshcalculatordialog.cpp index 09d1745dbb0b..abe5435100bb 100644 --- a/src/app/mesh/qgsmeshcalculatordialog.cpp +++ b/src/app/mesh/qgsmeshcalculatordialog.cpp @@ -54,8 +54,8 @@ QgsMeshCalculatorDialog::QgsMeshCalculatorDialog( QgsMeshLayer *meshLayer, QWidg getMeshDrivers(); populateDriversComboBox( ); - connect( mOutputFormatComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsMeshCalculatorDialog::updateInfoMessage ); - connect( mOutputFormatComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsMeshCalculatorDialog::onOutputFormatChange ); + connect( mOutputFormatComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsMeshCalculatorDialog::updateInfoMessage ); + connect( mOutputFormatComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsMeshCalculatorDialog::onOutputFormatChange ); connect( mOutputGroupNameLineEdit, &QLineEdit::textChanged, this, &QgsMeshCalculatorDialog::updateInfoMessage ); connect( mDatasetsListWidget, &QListView::doubleClicked, this, &QgsMeshCalculatorDialog::datasetGroupEntry ); diff --git a/src/app/options/qgscodeeditoroptions.cpp b/src/app/options/qgscodeeditoroptions.cpp index 7d6311c49137..64b285a4dfc6 100644 --- a/src/app/options/qgscodeeditoroptions.cpp +++ b/src/app/options/qgscodeeditoroptions.cpp @@ -112,7 +112,7 @@ QgsCodeEditorOptionsWidget::QgsCodeEditorOptionsWidget( QWidget *parent ) mColorSchemeComboBox->setCurrentIndex( mColorSchemeComboBox->findData( QStringLiteral( "custom" ) ) ); } - connect( mColorSchemeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ] + connect( mColorSchemeComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ] { const QString theme = mColorSchemeComboBox->currentData().toString(); if ( theme != QLatin1String( "custom" ) ) @@ -147,11 +147,11 @@ QgsCodeEditorOptionsWidget::QgsCodeEditorOptionsWidget( QWidget *parent ) mSizeSpin->setValue( font.pointSize() ); mOverrideFontGroupBox->setChecked( !settings.value( QStringLiteral( "codeEditor/fontfamily" ), QString(), QgsSettings::Gui ).toString().isEmpty() ); - connect( mFontComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ] + connect( mFontComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ] { updatePreview(); } ); - connect( mSizeSpin, qgis::overload::of( &QSpinBox::valueChanged ), this, [ = ] + connect( mSizeSpin, qOverload( &QSpinBox::valueChanged ), this, [ = ] { updatePreview(); } ); diff --git a/src/app/options/qgsoptions.cpp b/src/app/options/qgsoptions.cpp index 8e015f1dea88..7017da5fcf73 100644 --- a/src/app/options/qgsoptions.cpp +++ b/src/app/options/qgsoptions.cpp @@ -113,7 +113,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { updateSampleLocaleText( ); } ); + connect( cboGlobalLocale, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { updateSampleLocaleText( ); } ); connect( cbShowGroupSeparator, &QCheckBox::toggled, this, [ = ]( bool ) { updateSampleLocaleText(); } ); // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states, @@ -1243,7 +1243,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListsetText( QgsOpenClUtils::deviceDescription( mOpenClDevicesCombo->currentData().toString() ) ); }; - connect( mOpenClDevicesCombo, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), infoUpdater ); + connect( mOpenClDevicesCombo, qOverload< int >( &QComboBox::currentIndexChanged ), infoUpdater ); mOpenClDevicesCombo->setCurrentIndex( mOpenClDevicesCombo->findData( QgsOpenClUtils::deviceId( QgsOpenClUtils::activeDevice() ) ) ); infoUpdater( -1 ); mOpenClContainerWidget->show(); diff --git a/src/app/pointcloud/qgspointcloudelevationpropertieswidget.cpp b/src/app/pointcloud/qgspointcloudelevationpropertieswidget.cpp index f80b6e2bc2aa..f406635925e9 100644 --- a/src/app/pointcloud/qgspointcloudelevationpropertieswidget.cpp +++ b/src/app/pointcloud/qgspointcloudelevationpropertieswidget.cpp @@ -31,8 +31,8 @@ QgsPointCloudElevationPropertiesWidget::QgsPointCloudElevationPropertiesWidget( syncToLayer( layer ); - connect( mOffsetZSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudElevationPropertiesWidget::onChanged ); - connect( mScaleZSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudElevationPropertiesWidget::onChanged ); + connect( mOffsetZSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudElevationPropertiesWidget::onChanged ); + connect( mScaleZSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudElevationPropertiesWidget::onChanged ); connect( mShifPointCloudZAxisButton, &QPushButton::clicked, this, &QgsPointCloudElevationPropertiesWidget::shiftPointCloudZAxis ); } diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 2431befbb3c6..d08edd272cad 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -2712,7 +2712,7 @@ void QgisApp::createActions() connect( mActionSetLayerCRS, &QAction::triggered, this, &QgisApp::setLayerCrs ); connect( mActionSetProjectCRSFromLayer, &QAction::triggered, this, &QgisApp::setProjectCrsFromLayer ); connect( mActionLayerProperties, &QAction::triggered, this, &QgisApp::layerProperties ); - connect( mActionLayerSubsetString, &QAction::triggered, this, qgis::overload<>::of( &QgisApp::layerSubsetString ) ); + connect( mActionLayerSubsetString, &QAction::triggered, this, qOverload<>( &QgisApp::layerSubsetString ) ); connect( mActionAddToOverview, &QAction::triggered, this, &QgisApp::isInOverview ); connect( mActionAddAllToOverview, &QAction::triggered, this, &QgisApp::addAllToOverview ); connect( mActionRemoveAllFromOverview, &QAction::triggered, this, &QgisApp::removeAllFromOverview ); @@ -8753,7 +8753,7 @@ QString QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer, const bool defau } ); // when an error occurs: - connect( writerTask, qgis::overload< int, const QString &>::of( &QgsRasterFileWriterTask::errorOccurred ), this, [ = ]( int error, const QString & errorMessage ) + connect( writerTask, qOverload< int, const QString &>( &QgsRasterFileWriterTask::errorOccurred ), this, [ = ]( int error, const QString & errorMessage ) { if ( error != QgsRasterFileWriter::WriteCanceled ) { @@ -16408,7 +16408,7 @@ void QgisApp::namSetup() connect( nam, &QNetworkAccessManager::proxyAuthenticationRequired, this, &QgisApp::namProxyAuthenticationRequired ); - connect( nam, qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestTimedOut ), + connect( nam, qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestTimedOut ), this, &QgisApp::namRequestTimedOut ); nam->setAuthHandler( std::make_unique() ); diff --git a/src/app/qgsapplayertreeviewmenuprovider.cpp b/src/app/qgsapplayertreeviewmenuprovider.cpp index 47b82a72a74c..858998576282 100644 --- a/src/app/qgsapplayertreeviewmenuprovider.cpp +++ b/src/app/qgsapplayertreeviewmenuprovider.cpp @@ -286,7 +286,7 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu() if ( provider && provider->supportsSubsetString() ) { - QAction *action = menu->addAction( tr( "&Filter…" ), QgisApp::instance(), qgis::overload<>::of( &QgisApp::layerSubsetString ) ); + QAction *action = menu->addAction( tr( "&Filter…" ), QgisApp::instance(), qOverload<>( &QgisApp::layerSubsetString ) ); action->setEnabled( !vlayer->isEditable() ); } } @@ -295,7 +295,7 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu() rlayer->dataProvider() && rlayer->dataProvider()->supportsSubsetString() ) { - menu->addAction( tr( "&Filter…" ), QgisApp::instance(), qgis::overload<>::of( &QgisApp::layerSubsetString ) ); + menu->addAction( tr( "&Filter…" ), QgisApp::instance(), qOverload<>( &QgisApp::layerSubsetString ) ); } // change data source is only supported for vectors and rasters, point clouds diff --git a/src/app/qgscustomprojectiondialog.cpp b/src/app/qgscustomprojectiondialog.cpp index 9c35d64aa252..bb06c2e0e729 100644 --- a/src/app/qgscustomprojectiondialog.cpp +++ b/src/app/qgscustomprojectiondialog.cpp @@ -89,7 +89,7 @@ QgsCustomProjectionDialog::QgsCustomProjectionDialog( QWidget *parent, Qt::Windo connect( leName, &QLineEdit::textChanged, this, &QgsCustomProjectionDialog::updateListFromCurrentItem ); connect( teParameters, &QPlainTextEdit::textChanged, this, &QgsCustomProjectionDialog::updateListFromCurrentItem ); - connect( mFormatComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsCustomProjectionDialog::formatChanged ); + connect( mFormatComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsCustomProjectionDialog::formatChanged ); } void QgsCustomProjectionDialog::populateList() diff --git a/src/app/qgsidentifyresultsdialog.cpp b/src/app/qgsidentifyresultsdialog.cpp index 7da1d72ac352..3b7bc98a0334 100644 --- a/src/app/qgsidentifyresultsdialog.cpp +++ b/src/app/qgsidentifyresultsdialog.cpp @@ -929,8 +929,8 @@ void QgsIdentifyResultsDialog::addFeature( QgsRasterLayer *layer, QTreeWidgetItem *formatItem = new QTreeWidgetItem( QStringList() << ' ' + tr( "Format" ) ); layItem->addChild( formatItem ); lstResults->setItemWidget( formatItem, 1, formatCombo ); - connect( formatCombo, qgis::overload::of( &QComboBox::currentIndexChanged ), - this, qgis::overload::of( &QgsIdentifyResultsDialog::formatChanged ) ); + connect( formatCombo, qOverload( &QComboBox::currentIndexChanged ), + this, qOverload( &QgsIdentifyResultsDialog::formatChanged ) ); } else { diff --git a/src/app/qgsmapcanvasdockwidget.cpp b/src/app/qgsmapcanvasdockwidget.cpp index 06c43130bd8e..295d464ed6d2 100644 --- a/src/app/qgsmapcanvasdockwidget.cpp +++ b/src/app/qgsmapcanvasdockwidget.cpp @@ -525,9 +525,9 @@ void QgsMapCanvasDockWidget::showLabels( bool show ) void QgsMapCanvasDockWidget::autoZoomToSelection( bool autoZoom ) { if ( autoZoom ) - connect( mMapCanvas, &QgsMapCanvas::selectionChanged, mMapCanvas, qgis::overload::of( &QgsMapCanvas::zoomToSelected ) ); + connect( mMapCanvas, &QgsMapCanvas::selectionChanged, mMapCanvas, qOverload( &QgsMapCanvas::zoomToSelected ) ); else - disconnect( mMapCanvas, &QgsMapCanvas::selectionChanged, mMapCanvas, qgis::overload::of( &QgsMapCanvas::zoomToSelected ) ); + disconnect( mMapCanvas, &QgsMapCanvas::selectionChanged, mMapCanvas, qOverload( &QgsMapCanvas::zoomToSelected ) ); } QgsMapSettingsAction::QgsMapSettingsAction( QWidget *parent ) diff --git a/src/app/qgsmaptoolcircle2tangentspoint.cpp b/src/app/qgsmaptoolcircle2tangentspoint.cpp index f242916d2c7e..d739b7b6b2ed 100644 --- a/src/app/qgsmaptoolcircle2tangentspoint.cpp +++ b/src/app/qgsmaptoolcircle2tangentspoint.cpp @@ -209,7 +209,7 @@ void QgsMapToolCircle2TangentsPoint::createRadiusSpinBox() mRadiusSpinBox->setValue( mRadius ); QgisApp::instance()->addUserInputWidget( mRadiusSpinBox ); mRadiusSpinBox->setFocus( Qt::TabFocusReason ); - QObject::connect( mRadiusSpinBox, qgis::overload< double >::of( &QDoubleSpinBox::valueChanged ), this, &QgsMapToolCircle2TangentsPoint::radiusSpinBoxChanged ); + QObject::connect( mRadiusSpinBox, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, &QgsMapToolCircle2TangentsPoint::radiusSpinBoxChanged ); } void QgsMapToolCircle2TangentsPoint::deleteRadiusSpinBox() diff --git a/src/app/qgsrelationaddpolymorphicdlg.cpp b/src/app/qgsrelationaddpolymorphicdlg.cpp index 70b316c55526..e3a9192063dc 100644 --- a/src/app/qgsrelationaddpolymorphicdlg.cpp +++ b/src/app/qgsrelationaddpolymorphicdlg.cpp @@ -76,7 +76,7 @@ QgsRelationAddPolymorphicDlg::QgsRelationAddPolymorphicDlg( bool isEditDialog, Q connect( mFieldsMappingAddButton, &QToolButton::clicked, this, &QgsRelationAddPolymorphicDlg::addFieldsRow ); connect( mFieldsMappingRemoveButton, &QToolButton::clicked, this, &QgsRelationAddPolymorphicDlg::removeFieldsRow ); connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateDialogButtons ); - connect( mRelationStrengthComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int index ) { Q_UNUSED( index ); updateDialogButtons(); } ); + connect( mRelationStrengthComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int index ) { Q_UNUSED( index ); updateDialogButtons(); } ); connect( mReferencedLayerExpressionWidget, static_cast( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsRelationAddPolymorphicDlg::updateDialogButtons ); connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateChildRelationsComboBox ); connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateReferencingFieldsComboBoxes ); diff --git a/src/app/qgssnappingwidget.cpp b/src/app/qgssnappingwidget.cpp index 53628e4c7fde..546bb7dba4b5 100644 --- a/src/app/qgssnappingwidget.cpp +++ b/src/app/qgssnappingwidget.cpp @@ -230,7 +230,7 @@ QgsSnappingWidget::QgsSnappingWidget( QgsProject *project, QgsMapCanvas *canvas, mUnitsComboBox->addItem( mapCanvasDistanceUnits, QgsTolerance::ProjectUnits ); mUnitsComboBox->setToolTip( tr( "Snapping Unit Type: Pixels (px) or Project/Map Units (%1)" ).arg( mapCanvasDistanceUnits ) ); mUnitsComboBox->setObjectName( QStringLiteral( "SnappingUnitComboBox" ) ); - connect( mUnitsComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), + connect( mUnitsComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsSnappingWidget::changeUnit ); connect( mCanvas, &QgsMapCanvas::destinationCrsChanged, this, [ = ] diff --git a/src/auth/oauth2/qgsauthoauth2edit.cpp b/src/auth/oauth2/qgsauthoauth2edit.cpp index afc16fa1efae..f92a002611e1 100644 --- a/src/auth/oauth2/qgsauthoauth2edit.cpp +++ b/src/auth/oauth2/qgsauthoauth2edit.cpp @@ -1145,7 +1145,7 @@ void QgsAuthOAuth2Edit::registerSoftStatement( const QString ®istrationUrl ) registerReply = QgsNetworkAccessManager::instance()->post( registerRequest, json ); mDownloading = true; connect( registerReply, &QNetworkReply::finished, this, &QgsAuthOAuth2Edit::registerReplyFinished, Qt::QueuedConnection ); - connect( registerReply, qgis::overload::of( &QNetworkReply::error ), this, &QgsAuthOAuth2Edit::networkError, Qt::QueuedConnection ); + connect( registerReply, qOverload( &QNetworkReply::error ), this, &QgsAuthOAuth2Edit::networkError, Qt::QueuedConnection ); } void QgsAuthOAuth2Edit::getSoftwareStatementConfig() @@ -1163,7 +1163,7 @@ void QgsAuthOAuth2Edit::getSoftwareStatementConfig() QNetworkReply *configReply = QgsNetworkAccessManager::instance()->get( configRequest ); mDownloading = true; connect( configReply, &QNetworkReply::finished, this, &QgsAuthOAuth2Edit::configReplyFinished, Qt::QueuedConnection ); - connect( configReply, qgis::overload::of( &QNetworkReply::error ), this, &QgsAuthOAuth2Edit::networkError, Qt::QueuedConnection ); + connect( configReply, qOverload( &QNetworkReply::error ), this, &QgsAuthOAuth2Edit::networkError, Qt::QueuedConnection ); } } diff --git a/src/auth/oauth2/qgso2.cpp b/src/auth/oauth2/qgso2.cpp index 788ea3a75b9e..f738cbb56452 100644 --- a/src/auth/oauth2/qgso2.cpp +++ b/src/auth/oauth2/qgso2.cpp @@ -312,7 +312,7 @@ void QgsO2::onVerificationReceived( QMap response ) QNetworkReply *tokenReply = getManager()->post( tokenRequest, data ); timedReplies_.add( tokenReply ); connect( tokenReply, &QNetworkReply::finished, this, &QgsO2::onTokenReplyFinished, Qt::QueuedConnection ); - connect( tokenReply, qgis::overload::of( &QNetworkReply::error ), this, &QgsO2::onTokenReplyError, Qt::QueuedConnection ); + connect( tokenReply, qOverload( &QNetworkReply::error ), this, &QgsO2::onTokenReplyError, Qt::QueuedConnection ); } else if ( grantFlow_ == GrantFlowImplicit ) { diff --git a/src/core/layertree/qgslayertreeregistrybridge.cpp b/src/core/layertree/qgslayertreeregistrybridge.cpp index c61fcddd6afc..44dbddbedd74 100644 --- a/src/core/layertree/qgslayertreeregistrybridge.cpp +++ b/src/core/layertree/qgslayertreeregistrybridge.cpp @@ -30,7 +30,7 @@ QgsLayerTreeRegistryBridge::QgsLayerTreeRegistryBridge( QgsLayerTreeGroup *root, , mInsertionPoint( root, 0 ) { connect( mProject, &QgsProject::legendLayersAdded, this, &QgsLayerTreeRegistryBridge::layersAdded ); - connect( mProject, qgis::overload::of( &QgsProject::layersWillBeRemoved ), this, &QgsLayerTreeRegistryBridge::layersWillBeRemoved ); + connect( mProject, qOverload( &QgsProject::layersWillBeRemoved ), this, &QgsLayerTreeRegistryBridge::layersWillBeRemoved ); connect( mRoot, &QgsLayerTreeNode::willRemoveChildren, this, &QgsLayerTreeRegistryBridge::groupWillRemoveChildren ); connect( mRoot, &QgsLayerTreeNode::removedChildren, this, &QgsLayerTreeRegistryBridge::groupRemovedChildren ); diff --git a/src/core/network/qgsblockingnetworkrequest.cpp b/src/core/network/qgsblockingnetworkrequest.cpp index 2078bed9b8e1..5d854a42cfcf 100644 --- a/src/core/network/qgsblockingnetworkrequest.cpp +++ b/src/core/network/qgsblockingnetworkrequest.cpp @@ -30,7 +30,7 @@ QgsBlockingNetworkRequest::QgsBlockingNetworkRequest() { - connect( QgsNetworkAccessManager::instance(), qgis::overload< QNetworkReply * >::of( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsBlockingNetworkRequest::requestTimedOut ); + connect( QgsNetworkAccessManager::instance(), qOverload< QNetworkReply * >( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsBlockingNetworkRequest::requestTimedOut ); } QgsBlockingNetworkRequest::~QgsBlockingNetworkRequest() diff --git a/src/core/network/qgsfiledownloader.cpp b/src/core/network/qgsfiledownloader.cpp index 7ebd4548718d..c1644578d113 100644 --- a/src/core/network/qgsfiledownloader.cpp +++ b/src/core/network/qgsfiledownloader.cpp @@ -74,7 +74,7 @@ void QgsFileDownloader::startDownload() connect( mReply, &QNetworkReply::readyRead, this, &QgsFileDownloader::onReadyRead ); connect( mReply, &QNetworkReply::finished, this, &QgsFileDownloader::onFinished ); connect( mReply, &QNetworkReply::downloadProgress, this, &QgsFileDownloader::onDownloadProgress ); - connect( nam, qgis::overload< QNetworkReply *>::of( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsFileDownloader::onRequestTimedOut, Qt::UniqueConnection ); + connect( nam, qOverload< QNetworkReply *>( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsFileDownloader::onRequestTimedOut, Qt::UniqueConnection ); #ifndef QT_NO_SSL connect( nam, &QgsNetworkAccessManager::sslErrors, this, &QgsFileDownloader::onSslErrors, Qt::UniqueConnection ); #endif diff --git a/src/core/network/qgsnetworkaccessmanager.cpp b/src/core/network/qgsnetworkaccessmanager.cpp index d85ae0b605e0..3c4bc09ca978 100644 --- a/src/core/network/qgsnetworkaccessmanager.cpp +++ b/src/core/network/qgsnetworkaccessmanager.cpp @@ -522,17 +522,17 @@ void QgsNetworkAccessManager::setupDefaultProxyAndCache( Qt::ConnectionType conn sMainNAM, &QNetworkAccessManager::proxyAuthenticationRequired, connectionType ); - connect( this, qgis::overload< QNetworkReply *>::of( &QgsNetworkAccessManager::requestTimedOut ), - sMainNAM, qgis::overload< QNetworkReply *>::of( &QgsNetworkAccessManager::requestTimedOut ) ); + connect( this, qOverload< QNetworkReply *>( &QgsNetworkAccessManager::requestTimedOut ), + sMainNAM, qOverload< QNetworkReply *>( &QgsNetworkAccessManager::requestTimedOut ) ); - connect( this, qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestTimedOut ), - sMainNAM, qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestTimedOut ) ); + connect( this, qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestTimedOut ), + sMainNAM, qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestTimedOut ) ); - connect( this, qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), - sMainNAM, qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ) ); + connect( this, qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), + sMainNAM, qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ) ); - connect( this, qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), - sMainNAM, qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ) ); + connect( this, qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), + sMainNAM, qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ) ); connect( this, &QgsNetworkAccessManager::downloadProgress, sMainNAM, &QgsNetworkAccessManager::downloadProgress ); diff --git a/src/core/pointcloud/qgspointclouddataprovider.cpp b/src/core/pointcloud/qgspointclouddataprovider.cpp index 8fa5b05c0165..2356c873da24 100644 --- a/src/core/pointcloud/qgspointclouddataprovider.cpp +++ b/src/core/pointcloud/qgspointclouddataprovider.cpp @@ -260,7 +260,7 @@ QVector QgsPointCloudDataProvider::identify( acceptedPoints = QtConcurrent::blockingMappedReduced( nodes, MapIndexedPointCloudNode( request, index->scale(), index->offset(), extentGeometry, extentZRange, index, pointsLimit ), - qgis::overload>&>::of( &QVector>::append ), + qOverload>&>( &QVector>::append ), QtConcurrent::UnorderedReduce ); return acceptedPoints; diff --git a/src/core/project/qgsproject.cpp b/src/core/project/qgsproject.cpp index 4b37e07e0186..d21650782d3b 100644 --- a/src/core/project/qgsproject.cpp +++ b/src/core/project/qgsproject.cpp @@ -425,18 +425,18 @@ QgsProject::QgsProject( QObject *parent ) mLayerTreeRegistryBridge = new QgsLayerTreeRegistryBridge( mRootGroup, this, this ); connect( this, &QgsProject::layersAdded, this, &QgsProject::onMapLayersAdded ); connect( this, &QgsProject::layersRemoved, this, [ = ] { cleanTransactionGroups(); } ); - connect( this, qgis::overload< const QList & >::of( &QgsProject::layersWillBeRemoved ), this, &QgsProject::onMapLayersRemoved ); + connect( this, qOverload< const QList & >( &QgsProject::layersWillBeRemoved ), this, &QgsProject::onMapLayersRemoved ); // proxy map layer store signals to this - connect( mLayerStore.get(), qgis::overload::of( &QgsMapLayerStore::layersWillBeRemoved ), + connect( mLayerStore.get(), qOverload( &QgsMapLayerStore::layersWillBeRemoved ), this, [ = ]( const QStringList & layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } ); - connect( mLayerStore.get(), qgis::overload< const QList & >::of( &QgsMapLayerStore::layersWillBeRemoved ), + connect( mLayerStore.get(), qOverload< const QList & >( &QgsMapLayerStore::layersWillBeRemoved ), this, [ = ]( const QList &layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } ); - connect( mLayerStore.get(), qgis::overload< const QString & >::of( &QgsMapLayerStore::layerWillBeRemoved ), + connect( mLayerStore.get(), qOverload< const QString & >( &QgsMapLayerStore::layerWillBeRemoved ), this, [ = ]( const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } ); - connect( mLayerStore.get(), qgis::overload< QgsMapLayer * >::of( &QgsMapLayerStore::layerWillBeRemoved ), + connect( mLayerStore.get(), qOverload< QgsMapLayer * >( &QgsMapLayerStore::layerWillBeRemoved ), this, [ = ]( QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } ); - connect( mLayerStore.get(), qgis::overload::of( &QgsMapLayerStore::layersRemoved ), this, + connect( mLayerStore.get(), qOverload( &QgsMapLayerStore::layersRemoved ), this, [ = ]( const QStringList & layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } ); connect( mLayerStore.get(), &QgsMapLayerStore::layerRemoved, this, [ = ]( const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } ); @@ -452,7 +452,7 @@ QgsProject::QgsProject( QObject *parent ) connect( QgsApplication::instance(), &QgsApplication::requestForTranslatableObjects, this, &QgsProject::registerTranslatableObjects ); } - connect( mLayerStore.get(), qgis::overload< const QList & >::of( &QgsMapLayerStore::layersWillBeRemoved ), this, + connect( mLayerStore.get(), qOverload< const QList & >( &QgsMapLayerStore::layersWillBeRemoved ), this, [ = ]( const QList &layers ) { for ( const auto &layer : layers ) @@ -461,7 +461,7 @@ QgsProject::QgsProject( QObject *parent ) } } ); - connect( mLayerStore.get(), qgis::overload< const QList & >::of( &QgsMapLayerStore::layersAdded ), this, + connect( mLayerStore.get(), qOverload< const QList & >( &QgsMapLayerStore::layersAdded ), this, [ = ]( const QList &layers ) { for ( const auto &layer : layers ) diff --git a/src/core/qgis.h b/src/core/qgis.h index 33d3f3fc3715..53989f0f703d 100644 --- a/src/core/qgis.h +++ b/src/core/qgis.h @@ -385,27 +385,6 @@ inline double qgsRound( double number, int places ) namespace qgis { - /** - * Used for new-style Qt connects to overloaded signals, avoiding the usual horrible connect syntax required - * in these circumstances. - * - * Example usage: - * - * connect( mSpinBox, qgis::overload< int >::of( &QSpinBox::valueChanged ), this, &MyClass::mySlot ); - * - * This is an alternative to qOverload, which was implemented in Qt 5.7. - * - * See https://stackoverflow.com/a/16795664/1861260 - */ - template struct overload - { - template - static constexpr auto of( R( C::*pmf )( Args... ) ) -> decltype( pmf ) - { - return pmf; - } - }; - template QSet listToSet( const QList &list ) { diff --git a/src/core/qgsfeatureexpressionvaluesgatherer.h b/src/core/qgsfeatureexpressionvaluesgatherer.h index 3bf4f9991fac..c70e5ddca5d2 100644 --- a/src/core/qgsfeatureexpressionvaluesgatherer.h +++ b/src/core/qgsfeatureexpressionvaluesgatherer.h @@ -97,8 +97,8 @@ class QgsFeatureExpressionValuesGatherer: public QThread QgsFeature feature; QList attributeIndexes; - for ( const QString &fieldName : std::as_const( mIdentifierFields ) ) - attributeIndexes << mSource->fields().indexOf( fieldName ); + for ( auto it = mIdentifierFields.constBegin(); it != mIdentifierFields.constEnd(); ++it ) + attributeIndexes << mSource->fields().indexOf( *it ); while ( iterator.nextFeature( feature ) ) { diff --git a/src/core/qgsrunprocess.cpp b/src/core/qgsrunprocess.cpp index f43a5eee4b0c..1d9a9dabf70a 100644 --- a/src/core/qgsrunprocess.cpp +++ b/src/core/qgsrunprocess.cpp @@ -302,7 +302,7 @@ int QgsBlockingProcess::run( QgsFeedback *feedback ) p.terminate(); #endif } ); - connect( &p, qgis::overload< int, QProcess::ExitStatus >::of( &QProcess::finished ), this, [&loop, &result, &exitStatus]( int res, QProcess::ExitStatus st ) + connect( &p, qOverload< int, QProcess::ExitStatus >( &QProcess::finished ), this, [&loop, &result, &exitStatus]( int res, QProcess::ExitStatus st ) { result = res; exitStatus = st; diff --git a/src/gui/attributetable/qgsdualview.cpp b/src/gui/attributetable/qgsdualview.cpp index a237b346811a..ac150d9d0dcd 100644 --- a/src/gui/attributetable/qgsdualview.cpp +++ b/src/gui/attributetable/qgsdualview.cpp @@ -106,7 +106,7 @@ QgsDualView::QgsDualView( QWidget *parent ) QAbstractButton *bt = buttonGroup->button( static_cast( action ) ); if ( bt ) bt->setChecked( true ); - connect( buttonGroup, qgis::overload< QAbstractButton *, bool >::of( &QButtonGroup::buttonToggled ), this, &QgsDualView::panZoomGroupButtonToggled ); + connect( buttonGroup, qOverload< QAbstractButton *, bool >( &QButtonGroup::buttonToggled ), this, &QgsDualView::panZoomGroupButtonToggled ); mFlashButton->setChecked( QgsSettings().value( QStringLiteral( "/qgis/attributeTable/featureListHighlightFeature" ), true ).toBool() ); connect( mFlashButton, &QToolButton::clicked, this, &QgsDualView::flashButtonClicked ); } diff --git a/src/gui/editorwidgets/qgscheckboxconfigdlg.cpp b/src/gui/editorwidgets/qgscheckboxconfigdlg.cpp index 30833dc4d333..f1a0a7a873ce 100644 --- a/src/gui/editorwidgets/qgscheckboxconfigdlg.cpp +++ b/src/gui/editorwidgets/qgscheckboxconfigdlg.cpp @@ -28,7 +28,7 @@ QgsCheckBoxConfigDlg::QgsCheckBoxConfigDlg( QgsVectorLayer *vl, int fieldIdx, QW connect( leCheckedState, &QLineEdit::textEdited, this, &QgsEditorConfigWidget::changed ); connect( leUncheckedState, &QLineEdit::textEdited, this, &QgsEditorConfigWidget::changed ); - connect( mDisplayAsTextComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsEditorConfigWidget::changed ); + connect( mDisplayAsTextComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsEditorConfigWidget::changed ); if ( vl->fields().at( fieldIdx ).type() == QVariant::Bool ) { diff --git a/src/gui/editorwidgets/qgsrelationreferencewidget.cpp b/src/gui/editorwidgets/qgsrelationreferencewidget.cpp index 48420062f073..8c0d81ae0b2f 100644 --- a/src/gui/editorwidgets/qgsrelationreferencewidget.cpp +++ b/src/gui/editorwidgets/qgsrelationreferencewidget.cpp @@ -712,7 +712,7 @@ void QgsRelationReferenceWidget::mapIdentification() mMapToolIdentify->setLayer( mReferencedLayer ); setMapTool( mMapToolIdentify ); - connect( mMapToolIdentify, qgis::overload::of( &QgsMapToolIdentifyFeature::featureIdentified ), this, &QgsRelationReferenceWidget::featureIdentified ); + connect( mMapToolIdentify, qOverload( &QgsMapToolIdentifyFeature::featureIdentified ), this, &QgsRelationReferenceWidget::featureIdentified ); if ( mMessageBar ) { @@ -821,7 +821,7 @@ void QgsRelationReferenceWidget::unsetMapTool() } else { - disconnect( mMapToolIdentify, qgis::overload::of( &QgsMapToolIdentifyFeature::featureIdentified ), this, &QgsRelationReferenceWidget::featureIdentified ); + disconnect( mMapToolIdentify, qOverload( &QgsMapToolIdentifyFeature::featureIdentified ), this, &QgsRelationReferenceWidget::featureIdentified ); } } } diff --git a/src/gui/labeling/qgslabelengineconfigdialog.cpp b/src/gui/labeling/qgslabelengineconfigdialog.cpp index cfe33166d5b8..39d6eed0cfa5 100644 --- a/src/gui/labeling/qgslabelengineconfigdialog.cpp +++ b/src/gui/labeling/qgslabelengineconfigdialog.cpp @@ -76,15 +76,15 @@ QgsLabelEngineConfigWidget::QgsLabelEngineConfigWidget( QgsMapCanvas *canvas, QW mTextRenderFormatComboBox->setCurrentIndex( mTextRenderFormatComboBox->findData( engineSettings.defaultTextRenderFormat() ) ); - connect( spinCandLine, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, &QgsLabelEngineConfigWidget::widgetChanged ); - connect( spinCandPolygon, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, &QgsLabelEngineConfigWidget::widgetChanged ); + connect( spinCandLine, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsLabelEngineConfigWidget::widgetChanged ); + connect( spinCandPolygon, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsLabelEngineConfigWidget::widgetChanged ); connect( chkShowCandidates, &QCheckBox::toggled, this, &QgsLabelEngineConfigWidget::widgetChanged ); connect( chkShowAllLabels, &QCheckBox::toggled, this, &QgsLabelEngineConfigWidget::widgetChanged ); connect( chkShowUnplaced, &QCheckBox::toggled, this, &QgsLabelEngineConfigWidget::widgetChanged ); connect( chkShowPartialsLabels, &QCheckBox::toggled, this, &QgsLabelEngineConfigWidget::widgetChanged ); - connect( mTextRenderFormatComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsLabelEngineConfigWidget::widgetChanged ); + connect( mTextRenderFormatComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsLabelEngineConfigWidget::widgetChanged ); connect( mUnplacedColorButton, &QgsColorButton::colorChanged, this, &QgsLabelEngineConfigWidget::widgetChanged ); - connect( mPlacementVersionComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsLabelEngineConfigWidget::widgetChanged ); + connect( mPlacementVersionComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsLabelEngineConfigWidget::widgetChanged ); mWidgetMenu = new QMenu( this ); QAction *resetAction = new QAction( tr( "Restore Defaults" ), this ); diff --git a/src/gui/labeling/qgslabelinggui.cpp b/src/gui/labeling/qgslabelinggui.cpp index 425af01a7dcb..ed32c2983257 100644 --- a/src/gui/labeling/qgslabelinggui.cpp +++ b/src/gui/labeling/qgslabelinggui.cpp @@ -252,11 +252,11 @@ QgsLabelingGui::QgsLabelingGui( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, connect( mScaleBasedVisibilityChkBx, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi ); connect( mFontLimitPixelChkBox, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi ); connect( mGeometryGeneratorGroupBox, &QGroupBox::toggled, this, &QgsLabelingGui::updateGeometryTypeBasedWidgets ); - connect( mGeometryGeneratorType, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsLabelingGui::updateGeometryTypeBasedWidgets ); + connect( mGeometryGeneratorType, qOverload( &QComboBox::currentIndexChanged ), this, &QgsLabelingGui::updateGeometryTypeBasedWidgets ); connect( mGeometryGeneratorExpressionButton, &QToolButton::clicked, this, &QgsLabelingGui::showGeometryGeneratorExpressionBuilder ); connect( mGeometryGeneratorGroupBox, &QGroupBox::toggled, this, &QgsLabelingGui::validateGeometryGeneratorExpression ); connect( mGeometryGenerator, &QgsCodeEditorExpression::textChanged, this, &QgsLabelingGui::validateGeometryGeneratorExpression ); - connect( mGeometryGeneratorType, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsLabelingGui::validateGeometryGeneratorExpression ); + connect( mGeometryGeneratorType, qOverload( &QComboBox::currentIndexChanged ), this, &QgsLabelingGui::validateGeometryGeneratorExpression ); connect( mObstacleSettingsButton, &QAbstractButton::clicked, this, &QgsLabelingGui::showObstacleSettings ); connect( mLineAnchorSettingsButton, &QAbstractButton::clicked, this, &QgsLabelingGui::showLineAnchorSettings ); diff --git a/src/gui/labeling/qgslabellineanchorwidget.cpp b/src/gui/labeling/qgslabellineanchorwidget.cpp index a6d4d29e58fc..12dad3cbd4d7 100644 --- a/src/gui/labeling/qgslabellineanchorwidget.cpp +++ b/src/gui/labeling/qgslabellineanchorwidget.cpp @@ -33,7 +33,7 @@ QgsLabelLineAnchorWidget::QgsLabelLineAnchorWidget( QWidget *parent, QgsVectorLa mAnchorTypeComboBox->addItem( tr( "Preferred Placement Hint" ), static_cast< int >( QgsLabelLineSettings::AnchorType::HintOnly ) ); mAnchorTypeComboBox->addItem( tr( "Strict" ), static_cast< int >( QgsLabelLineSettings::AnchorType::Strict ) ); - connect( mPercentPlacementComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mPercentPlacementComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { if ( !mBlockSignals ) emit changed(); @@ -48,13 +48,13 @@ QgsLabelLineAnchorWidget::QgsLabelLineAnchorWidget( QWidget *parent, QgsVectorLa mBlockSignals = false; } } ); - connect( mCustomPlacementSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, [ = ]( double ) + connect( mCustomPlacementSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, [ = ]( double ) { if ( !mBlockSignals ) emit changed(); } ); - connect( mAnchorTypeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mAnchorTypeComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { if ( !mBlockSignals ) emit changed(); diff --git a/src/gui/labeling/qgslabelobstaclesettingswidget.cpp b/src/gui/labeling/qgslabelobstaclesettingswidget.cpp index c7ab3836a96d..1bd98a4359b3 100644 --- a/src/gui/labeling/qgslabelobstaclesettingswidget.cpp +++ b/src/gui/labeling/qgslabelobstaclesettingswidget.cpp @@ -27,7 +27,7 @@ QgsLabelObstacleSettingsWidget::QgsLabelObstacleSettingsWidget( QWidget *parent, mObstacleTypeComboBox->addItem( tr( "Over the Feature's Interior" ), QgsLabelObstacleSettings::PolygonInterior ); mObstacleTypeComboBox->addItem( tr( "Over the Feature's Boundary" ), QgsLabelObstacleSettings::PolygonBoundary ); - connect( mObstacleTypeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mObstacleTypeComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { if ( !mBlockSignals ) emit changed(); diff --git a/src/gui/layout/qgslayoutatlaswidget.cpp b/src/gui/layout/qgslayoutatlaswidget.cpp index f48996689e90..330bff3d31f5 100644 --- a/src/gui/layout/qgslayoutatlaswidget.cpp +++ b/src/gui/layout/qgslayoutatlaswidget.cpp @@ -63,7 +63,7 @@ QgsLayoutAtlasWidget::QgsLayoutAtlasWidget( QWidget *parent, QgsPrintLayout *lay { mAtlasFileFormat->addItem( QString( formats.at( i ) ) ); } - connect( mAtlasFileFormat, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { changeFileFormat(); } ); + connect( mAtlasFileFormat, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { changeFileFormat(); } ); updateGuiElements(); } diff --git a/src/gui/layout/qgslayoutguidewidget.cpp b/src/gui/layout/qgslayoutguidewidget.cpp index 93e85384f92c..ce46bc3ffec8 100644 --- a/src/gui/layout/qgslayoutguidewidget.cpp +++ b/src/gui/layout/qgslayoutguidewidget.cpp @@ -57,7 +57,7 @@ QgsLayoutGuideWidget::QgsLayoutGuideWidget( QWidget *parent, QgsLayout *layout, connect( mLayout->pageCollection(), &QgsLayoutPageCollection::changed, this, &QgsLayoutGuideWidget::updatePageCount ); updatePageCount(); - connect( mPageNumberComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mPageNumberComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { setCurrentPage( mPageNumberComboBox->currentData().toInt() ); } ); diff --git a/src/gui/layout/qgslayoutlegendwidget.cpp b/src/gui/layout/qgslayoutlegendwidget.cpp index 4e77b6b3fea6..5c02f3e5052c 100644 --- a/src/gui/layout/qgslayoutlegendwidget.cpp +++ b/src/gui/layout/qgslayoutlegendwidget.cpp @@ -1621,15 +1621,15 @@ QgsLayoutLegendNodeWidget::QgsLayoutLegendNodeWidget( QgsLayoutItemLegend *legen connect( mPatchShapeButton, &QgsLegendPatchShapeButton::changed, this, &QgsLayoutLegendNodeWidget::patchChanged ); connect( mInsertExpressionButton, &QPushButton::clicked, this, &QgsLayoutLegendNodeWidget::insertExpression ); - connect( mWidthSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutLegendNodeWidget::sizeChanged ); - connect( mHeightSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutLegendNodeWidget::sizeChanged ); + connect( mWidthSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutLegendNodeWidget::sizeChanged ); + connect( mHeightSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutLegendNodeWidget::sizeChanged ); connect( mCustomSymbolCheckBox, &QGroupBox::toggled, this, &QgsLayoutLegendNodeWidget::customSymbolChanged ); connect( mCustomSymbolButton, &QgsSymbolButton::changed, this, &QgsLayoutLegendNodeWidget::customSymbolChanged ); connect( mColumnBreakBeforeCheckBox, &QCheckBox::toggled, this, &QgsLayoutLegendNodeWidget::columnBreakToggled ); - connect( mColumnSplitBehaviorComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsLayoutLegendNodeWidget::columnSplitChanged ); + connect( mColumnSplitBehaviorComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsLayoutLegendNodeWidget::columnSplitChanged ); connect( mColorRampLegendWidget, &QgsColorRampLegendNodeWidget::widgetChanged, this, &QgsLayoutLegendNodeWidget::colorRampLegendChanged ); diff --git a/src/gui/layout/qgslayoutmapwidget.cpp b/src/gui/layout/qgslayoutmapwidget.cpp index 1f64160f207c..dbf5cd75c4aa 100644 --- a/src/gui/layout/qgslayoutmapwidget.cpp +++ b/src/gui/layout/qgslayoutmapwidget.cpp @@ -2006,7 +2006,7 @@ QgsLayoutMapClippingWidget::QgsLayoutMapClippingWidget( QgsLayoutItemMap *map ) mMapItem->endCommand(); } } ); - connect( mAtlasClippingTypeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ] + connect( mAtlasClippingTypeComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ] { if ( !mBlockUpdates ) { @@ -2064,7 +2064,7 @@ QgsLayoutMapClippingWidget::QgsLayoutMapClippingWidget( QgsLayoutItemMap *map ) mMapItem->endCommand(); } } ); - connect( mItemClippingTypeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ] + connect( mItemClippingTypeComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ] { if ( !mBlockUpdates ) { diff --git a/src/gui/mesh/qgsmeshrenderer3daveragingwidget.cpp b/src/gui/mesh/qgsmeshrenderer3daveragingwidget.cpp index 010b7fd5fed7..1f799e7bbaa5 100644 --- a/src/gui/mesh/qgsmeshrenderer3daveragingwidget.cpp +++ b/src/gui/mesh/qgsmeshrenderer3daveragingwidget.cpp @@ -57,11 +57,11 @@ QgsMeshRenderer3dAveragingWidget::QgsMeshRenderer3dAveragingWidget( QWidget *par { setupUi( this ); - connect( mAveragingMethodComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), + connect( mAveragingMethodComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsMeshRenderer3dAveragingWidget::onAveragingMethodChanged ); // Single Level Average Method (top) - connect( mSingleVerticalLayerIndexTopSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), + connect( mSingleVerticalLayerIndexTopSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); _setSvg( mSingleTopPngLabel, QStringLiteral( "SingleTop.svg" ) @@ -69,61 +69,61 @@ QgsMeshRenderer3dAveragingWidget::QgsMeshRenderer3dAveragingWidget( QWidget *par mSingleTopGroup->adjustSize(); // Single Level Average Method (bottom) - connect( mSingleVerticalLayerIndexBottomSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), + connect( mSingleVerticalLayerIndexBottomSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); _setSvg( mSingleBottomPngLabel, QStringLiteral( "SingleBottom.svg" ) ); // Multi Levels Averaging Method (top) - connect( mMultiTopVerticalLayerStartIndexSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), + connect( mMultiTopVerticalLayerStartIndexSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); - connect( mMultiTopVerticalLayerEndIndexSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), + connect( mMultiTopVerticalLayerEndIndexSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); _setSvg( mMultiTopPngLabel, QStringLiteral( "MultiTop.svg" ) ); // MultiLevels Averaging Method (bottom) - connect( mMultiBottomVerticalLayerStartIndexSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), + connect( mMultiBottomVerticalLayerStartIndexSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); - connect( mMultiBottomVerticalLayerEndIndexSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), + connect( mMultiBottomVerticalLayerEndIndexSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); _setSvg( mMultiBottomPngLabel, QStringLiteral( "MultiBottom.svg" ) ); // Sigma Averaging Method - connect( mSigmaStartFractionSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mSigmaStartFractionSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); - connect( mSigmaEndFractionSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mSigmaEndFractionSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); _setSvg( mSigmaPngLabel, QStringLiteral( "Sigma.svg" ) ); // Depth Averaging Method - connect( mDepthStartSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mDepthStartSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); - connect( mDepthEndSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mDepthEndSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); _setSvg( mDepthPngLabel, QStringLiteral( "Depth.svg" ) ); // Height Averaging Method - connect( mHeightStartSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mHeightStartSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); - connect( mHeightEndSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mHeightEndSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); _setSvg( mHeightPngLabel, QStringLiteral( "Height.svg" ) ); // Elevation Averaging Method - connect( mElevationStartSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mElevationStartSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); - connect( mElevationEndSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mElevationEndSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRenderer3dAveragingWidget::widgetChanged ); _setSvg( mElevationPngLabel, QStringLiteral( "Elevation.svg" ) diff --git a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp index 5d0a97ede9df..17cd0d95549e 100644 --- a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp +++ b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp @@ -40,7 +40,7 @@ QgsMeshRendererMeshSettingsWidget::QgsMeshRendererMeshSettingsWidget( QWidget *p connect( mColorWidget, &QgsColorButton::colorChanged, this, &QgsMeshRendererMeshSettingsWidget::widgetChanged ); - connect( mLineWidthSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mLineWidthSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRendererMeshSettingsWidget::widgetChanged ); connect( mLineUnitsComboBox, &QgsUnitSelectionWidget::changed, this, &QgsMeshRendererMeshSettingsWidget::widgetChanged ); diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp index 82ea3b90e822..253d69803912 100644 --- a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp +++ b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp @@ -52,11 +52,11 @@ QgsMeshRendererScalarSettingsWidget::QgsMeshRendererScalarSettingsWidget( QWidge connect( mScalarColorRampShaderWidget, &QgsColorRampShaderWidget::widgetChanged, this, &QgsMeshRendererScalarSettingsWidget::widgetChanged ); connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsMeshRendererScalarSettingsWidget::widgetChanged ); - connect( mScalarInterpolationTypeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsMeshRendererScalarSettingsWidget::widgetChanged ); + connect( mScalarInterpolationTypeComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsMeshRendererScalarSettingsWidget::widgetChanged ); connect( mScalarEdgeStrokeWidthUnitSelectionWidget, &QgsUnitSelectionWidget::changed, this, &QgsMeshRendererScalarSettingsWidget::widgetChanged ); - connect( mScalarEdgeStrokeWidthSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mScalarEdgeStrokeWidthSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRendererScalarSettingsWidget::widgetChanged ); connect( mScalarEdgeStrokeWidthVariableRadioButton, &QCheckBox::toggled, this, &QgsMeshRendererScalarSettingsWidget::widgetChanged ); connect( mScalarEdgeStrokeWidthFixedRadioButton, &QCheckBox::toggled, this, &QgsMeshRendererScalarSettingsWidget::widgetChanged ); diff --git a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp index 58938ecc5736..3b59756b0177 100644 --- a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp +++ b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp @@ -36,7 +36,7 @@ QgsMeshRendererVectorSettingsWidget::QgsMeshRendererVectorSettingsWidget( QWidge mTracesMaxLengthSpinBox->setClearValue( 100.0 ); connect( mColorWidget, &QgsColorButton::colorChanged, this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); - connect( mColoringMethodComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), + connect( mColoringMethodComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsMeshRendererVectorSettingsWidget::onColoringMethodChanged ); connect( mColorRampShaderWidget, &QgsColorRampShaderWidget::widgetChanged, this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); @@ -45,13 +45,13 @@ QgsMeshRendererVectorSettingsWidget::QgsMeshRendererVectorSettingsWidget( QWidge connect( mColorRampShaderMaximumEditLine, &QLineEdit::textEdited, this, &QgsMeshRendererVectorSettingsWidget::onColorRampMinMaxChanged ); - connect( mLineWidthSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mLineWidthSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); - connect( mShaftLengthComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), + connect( mShaftLengthComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); - connect( mShaftLengthComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), + connect( mShaftLengthComboBox, qOverload( &QComboBox::currentIndexChanged ), mShaftOptionsStackedWidget, &QStackedWidget::setCurrentIndex ); connect( mDisplayVectorsOnGridGroupBox, &QGroupBox::toggled, this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); @@ -71,30 +71,30 @@ QgsMeshRendererVectorSettingsWidget::QgsMeshRendererVectorSettingsWidget( QWidge connect( widget, &QLineEdit::textChanged, this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); } - connect( mXSpacingSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); - connect( mYSpacingSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); + connect( mXSpacingSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); + connect( mYSpacingSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); - connect( mSymbologyVectorComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), + connect( mSymbologyVectorComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsMeshRendererVectorSettingsWidget::onSymbologyChanged ); onSymbologyChanged( 0 ); - connect( mSymbologyVectorComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), + connect( mSymbologyVectorComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); - connect( mStreamlinesSeedingMethodComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), + connect( mStreamlinesSeedingMethodComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsMeshRendererVectorSettingsWidget::onStreamLineSeedingMethodChanged ); onStreamLineSeedingMethodChanged( 0 ); - connect( mStreamlinesSeedingMethodComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), + connect( mStreamlinesSeedingMethodComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); - connect( mStreamlinesDensitySpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mStreamlinesDensitySpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); - connect( mTracesMaxLengthSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mTracesMaxLengthSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); - connect( mTracesParticlesCountSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), + connect( mTracesParticlesCountSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); mTracesTailLengthMapUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() diff --git a/src/gui/mesh/qgsmeshvariablestrokewidthwidget.cpp b/src/gui/mesh/qgsmeshvariablestrokewidthwidget.cpp index dd72890c63a4..8886963b7d81 100644 --- a/src/gui/mesh/qgsmeshvariablestrokewidthwidget.cpp +++ b/src/gui/mesh/qgsmeshvariablestrokewidthwidget.cpp @@ -39,9 +39,9 @@ QgsMeshVariableStrokeWidthWidget::QgsMeshVariableStrokeWidthWidget( connect( mValueMinimumLineEdit, &QLineEdit::textEdited, this, &QgsMeshVariableStrokeWidthWidget::widgetChanged ); connect( mValueMaximumLineEdit, &QLineEdit::textEdited, this, &QgsMeshVariableStrokeWidthWidget::widgetChanged ); - connect( mWidthMinimumSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mWidthMinimumSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshVariableStrokeWidthWidget::widgetChanged ); - connect( mWidthMaximumSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), + connect( mWidthMaximumSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsMeshVariableStrokeWidthWidget::widgetChanged ); connect( mIgnoreOutOfRangecheckBox, &QCheckBox::toggled, this, &QgsMeshVariableStrokeWidthWidget::widgetChanged ); diff --git a/src/gui/numericformats/qgsnumericformatwidget.cpp b/src/gui/numericformats/qgsnumericformatwidget.cpp index 3e34d8fe629b..1765d8fc8fc8 100644 --- a/src/gui/numericformats/qgsnumericformatwidget.cpp +++ b/src/gui/numericformats/qgsnumericformatwidget.cpp @@ -58,7 +58,7 @@ QgsBasicNumericFormatWidget::QgsBasicNumericFormatWidget( const QgsNumericFormat emit changed(); } ); - connect( mDecimalsSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), this, [ = ]( int value ) + connect( mDecimalsSpinBox, qOverload( &QSpinBox::valueChanged ), this, [ = ]( int value ) { mFormat->setNumberDecimalPlaces( value ); if ( !mBlockSignals ) @@ -155,14 +155,14 @@ QgsBearingNumericFormatWidget::QgsBearingNumericFormatWidget( const QgsNumericFo emit changed(); } ); - connect( mDecimalsSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), this, [ = ]( int value ) + connect( mDecimalsSpinBox, qOverload( &QSpinBox::valueChanged ), this, [ = ]( int value ) { mFormat->setNumberDecimalPlaces( value ); if ( !mBlockSignals ) emit changed(); } ); - connect( mFormatComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mFormatComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { mFormat->setDirectionFormat( static_cast < QgsBearingNumericFormat::FormatDirectionOption >( mFormatComboBox->currentData().toInt() ) ); if ( !mBlockSignals ) @@ -249,7 +249,7 @@ QgsCurrencyNumericFormatWidget::QgsCurrencyNumericFormatWidget( const QgsNumeric emit changed(); } ); - connect( mDecimalsSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), this, [ = ]( int value ) + connect( mDecimalsSpinBox, qOverload( &QSpinBox::valueChanged ), this, [ = ]( int value ) { mFormat->setNumberDecimalPlaces( value ); if ( !mBlockSignals ) @@ -330,14 +330,14 @@ QgsPercentageNumericFormatWidget::QgsPercentageNumericFormatWidget( const QgsNum emit changed(); } ); - connect( mDecimalsSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), this, [ = ]( int value ) + connect( mDecimalsSpinBox, qOverload( &QSpinBox::valueChanged ), this, [ = ]( int value ) { mFormat->setNumberDecimalPlaces( value ); if ( !mBlockSignals ) emit changed(); } ); - connect( mScalingComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mScalingComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { mFormat->setInputValues( static_cast < QgsPercentageNumericFormat::InputValues >( mScalingComboBox->currentData().toInt() ) ); if ( !mBlockSignals ) @@ -389,7 +389,7 @@ QgsScientificNumericFormatWidget::QgsScientificNumericFormatWidget( const QgsNum emit changed(); } ); - connect( mDecimalsSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), this, [ = ]( int value ) + connect( mDecimalsSpinBox, qOverload( &QSpinBox::valueChanged ), this, [ = ]( int value ) { mFormat->setNumberDecimalPlaces( value ); if ( !mBlockSignals ) diff --git a/src/gui/pointcloud/qgspointcloudattributebyramprendererwidget.cpp b/src/gui/pointcloud/qgspointcloudattributebyramprendererwidget.cpp index 747fce0112c6..e2a8bf4ec766 100644 --- a/src/gui/pointcloud/qgspointcloudattributebyramprendererwidget.cpp +++ b/src/gui/pointcloud/qgspointcloudattributebyramprendererwidget.cpp @@ -45,8 +45,8 @@ QgsPointCloudAttributeByRampRendererWidget::QgsPointCloudAttributeByRampRenderer connect( mAttributeComboBox, &QgsPointCloudAttributeComboBox::attributeChanged, this, &QgsPointCloudAttributeByRampRendererWidget::attributeChanged ); - connect( mMinSpin, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudAttributeByRampRendererWidget::minMaxChanged ); - connect( mMaxSpin, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudAttributeByRampRendererWidget::minMaxChanged ); + connect( mMinSpin, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudAttributeByRampRendererWidget::minMaxChanged ); + connect( mMaxSpin, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudAttributeByRampRendererWidget::minMaxChanged ); connect( mScalarColorRampShaderWidget, &QgsColorRampShaderWidget::widgetChanged, this, &QgsPointCloudAttributeByRampRendererWidget::emitWidgetChanged ); connect( mScalarRecalculateMinMaxButton, &QPushButton::clicked, this, &QgsPointCloudAttributeByRampRendererWidget::setMinMaxFromLayer ); diff --git a/src/gui/pointcloud/qgspointcloudrendererpropertieswidget.cpp b/src/gui/pointcloud/qgspointcloudrendererpropertieswidget.cpp index 417059f08438..184090f2fa4b 100644 --- a/src/gui/pointcloud/qgspointcloudrendererpropertieswidget.cpp +++ b/src/gui/pointcloud/qgspointcloudrendererpropertieswidget.cpp @@ -96,14 +96,14 @@ QgsPointCloudRendererPropertiesWidget::QgsPointCloudRendererPropertiesWidget( Qg mPointSizeUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); - connect( mPointSizeSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); + connect( mPointSizeSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); connect( mPointSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); mMaxErrorUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); mMaxErrorSpinBox->setClearValue( 0.3 ); - connect( mMaxErrorSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); + connect( mMaxErrorSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); connect( mMaxErrorUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); connect( mPointStyleComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); diff --git a/src/gui/processing/qgsprocessingaggregatewidgets.cpp b/src/gui/processing/qgsprocessingaggregatewidgets.cpp index 4bd7d4fd708d..53581c801ab0 100644 --- a/src/gui/processing/qgsprocessingaggregatewidgets.cpp +++ b/src/gui/processing/qgsprocessingaggregatewidgets.cpp @@ -529,7 +529,7 @@ QWidget *QgsAggregateMappingWidget::AggregateDelegate::createEditor( QWidget *pa } connect( editor, - qgis::overload::of( &QComboBox::currentIndexChanged ), + qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int currentIndex ) { diff --git a/src/gui/processing/qgsprocessingfeaturesourceoptionswidget.cpp b/src/gui/processing/qgsprocessingfeaturesourceoptionswidget.cpp index ddfbbe240032..e1809e99fbda 100644 --- a/src/gui/processing/qgsprocessingfeaturesourceoptionswidget.cpp +++ b/src/gui/processing/qgsprocessingfeaturesourceoptionswidget.cpp @@ -32,8 +32,8 @@ QgsProcessingFeatureSourceOptionsWidget::QgsProcessingFeatureSourceOptionsWidget mComboInvalidFeatureFiltering->addItem( tr( "Skip (Ignore) Features with Invalid Geometries" ), QgsFeatureRequest::GeometrySkipInvalid ); mComboInvalidFeatureFiltering->addItem( tr( "Stop Algorithm Execution When a Geometry is Invalid" ), QgsFeatureRequest::GeometryAbortOnInvalid ); - connect( mFeatureLimitSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), this, &QgsPanelWidget::widgetChanged ); - connect( mComboInvalidFeatureFiltering, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsPanelWidget::widgetChanged ); + connect( mFeatureLimitSpinBox, qOverload( &QSpinBox::valueChanged ), this, &QgsPanelWidget::widgetChanged ); + connect( mComboInvalidFeatureFiltering, qOverload( &QComboBox::currentIndexChanged ), this, &QgsPanelWidget::widgetChanged ); } void QgsProcessingFeatureSourceOptionsWidget::setGeometryCheckMethod( bool isOverridden, QgsFeatureRequest::InvalidGeometryCheck check ) diff --git a/src/gui/processing/qgsprocessingmeshdatasetwidget.cpp b/src/gui/processing/qgsprocessingmeshdatasetwidget.cpp index 5b742eca26e3..ce86657e56e6 100644 --- a/src/gui/processing/qgsprocessingmeshdatasetwidget.cpp +++ b/src/gui/processing/qgsprocessingmeshdatasetwidget.cpp @@ -442,7 +442,7 @@ QgsProcessingMeshDatasetTimeWidget::QgsProcessingMeshDatasetTimeWidget( QWidget connect( radioButtonDefinedDateTime, &QRadioButton::toggled, [this]( bool isChecked ) {if ( isChecked ) this->updateValue();} ); connect( radioButtonDatasetGroupTimeStep, &QRadioButton::toggled, [this]( bool isChecked ) {if ( isChecked ) this->updateValue();} ); connect( dateTimeEdit, &QgsDateTimeEdit::dateTimeChanged, this, &QgsProcessingMeshDatasetTimeWidget::updateValue ); - connect( comboBoxDatasetTimeStep, qgis::overload::of( &QComboBox::currentIndexChanged ), + connect( comboBoxDatasetTimeStep, qOverload( &QComboBox::currentIndexChanged ), this, &QgsProcessingMeshDatasetTimeWidget::updateValue ); updateWidget(); diff --git a/src/gui/processing/qgsprocessingvectortilewriterlayerswidgetwrapper.cpp b/src/gui/processing/qgsprocessingvectortilewriterlayerswidgetwrapper.cpp index 35a5b2de1c24..157c86365ba0 100644 --- a/src/gui/processing/qgsprocessingvectortilewriterlayerswidgetwrapper.cpp +++ b/src/gui/processing/qgsprocessingvectortilewriterlayerswidgetwrapper.cpp @@ -57,8 +57,8 @@ QgsProcessingVectorTileWriteLayerDetailsWidget::QgsProcessingVectorTileWriteLaye mEditLayerName->setPlaceholderText( mLayer->name() ); mEditFilterExpression->setExpression( layer.filterExpression() ); - connect( mSpinMinZoom, qgis::overload::of( &QSpinBox::valueChanged ), this, &QgsPanelWidget::widgetChanged ); - connect( mSpinMaxZoom, qgis::overload::of( &QSpinBox::valueChanged ), this, &QgsPanelWidget::widgetChanged ); + connect( mSpinMinZoom, qOverload( &QSpinBox::valueChanged ), this, &QgsPanelWidget::widgetChanged ); + connect( mSpinMaxZoom, qOverload( &QSpinBox::valueChanged ), this, &QgsPanelWidget::widgetChanged ); connect( mEditLayerName, &QLineEdit::textChanged, this, &QgsPanelWidget::widgetChanged ); connect( mEditFilterExpression, &QgsExpressionLineEdit::expressionChanged, this, &QgsPanelWidget::widgetChanged ); } diff --git a/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp b/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp index d53ca7302347..28af979a3022 100644 --- a/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp +++ b/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp @@ -138,7 +138,7 @@ QWidget *QgsProcessingBooleanWidgetWrapper::createWidget() mComboBox->addItem( tr( "No" ), false ); mComboBox->setToolTip( parameterDefinition()->toolTip() ); - connect( mComboBox, qgis::overload< int>::of( &QComboBox::currentIndexChanged ), this, [ = ] + connect( mComboBox, qOverload< int>( &QComboBox::currentIndexChanged ), this, [ = ] { emit widgetValueHasChanged( this ); } ); @@ -805,9 +805,9 @@ QWidget *QgsProcessingNumericWidgetWrapper::createWidget() } if ( mDoubleSpinBox ) - connect( mDoubleSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, [ = ] { emit widgetValueHasChanged( this ); } ); + connect( mDoubleSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, [ = ] { emit widgetValueHasChanged( this ); } ); else if ( mSpinBox ) - connect( mSpinBox, qgis::overload::of( &QgsSpinBox::valueChanged ), this, [ = ] { emit widgetValueHasChanged( this ); } ); + connect( mSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, [ = ] { emit widgetValueHasChanged( this ); } ); return spinBox; } @@ -1426,7 +1426,7 @@ QWidget *QgsProcessingRangeWidgetWrapper::createWidget() w->setToolTip( parameterDefinition()->toolTip() ); - connect( mMinSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( const double v ) + connect( mMinSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( const double v ) { mBlockChangedSignal++; if ( !mAllowingNull && v > mMaxSpinBox->value() ) @@ -1436,7 +1436,7 @@ QWidget *QgsProcessingRangeWidgetWrapper::createWidget() if ( !mBlockChangedSignal ) emit widgetValueHasChanged( this ); } ); - connect( mMaxSpinBox, qgis::overload::of( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( const double v ) + connect( mMaxSpinBox, qOverload( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( const double v ) { mBlockChangedSignal++; if ( !mAllowingNull && v < mMinSpinBox->value() ) @@ -1704,7 +1704,7 @@ QgsProcessingFileParameterDefinitionWidget::QgsProcessingFileParameterDefinition mDefaultFileWidget->setStorageMode( QgsFileWidget::GetFile ); vlayout->addWidget( mDefaultFileWidget ); - connect( mTypeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ] + connect( mTypeComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ] { QgsProcessingParameterFile::Behavior behavior = static_cast< QgsProcessingParameterFile::Behavior >( mTypeComboBox->currentData().toInt() ); mFilterComboBox->setEnabled( behavior == QgsProcessingParameterFile::File ); @@ -2437,7 +2437,7 @@ QWidget *QgsProcessingEnumWidgetWrapper::createWidget() } mComboBox->setToolTip( parameterDefinition()->toolTip() ); - connect( mComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { emit widgetValueHasChanged( this ); } ); @@ -4428,7 +4428,7 @@ QWidget *QgsProcessingMapThemeWidgetWrapper::createWidget() } mComboBox->setToolTip( parameterDefinition()->toolTip() ); - connect( mComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { emit widgetValueHasChanged( this ); } ); diff --git a/src/gui/providers/ogr/qgsgeopackageprojectstoragedialog.cpp b/src/gui/providers/ogr/qgsgeopackageprojectstoragedialog.cpp index 224c7f1a7794..dd9a1d72d343 100644 --- a/src/gui/providers/ogr/qgsgeopackageprojectstoragedialog.cpp +++ b/src/gui/providers/ogr/qgsgeopackageprojectstoragedialog.cpp @@ -78,12 +78,12 @@ QgsGeoPackageProjectStorageDialog::QgsGeoPackageProjectStorageDialog( bool savin mCboConnection->setItemData( mCboConnection->findText( connName ), conn.path(), Qt::ItemDataRole::ToolTipRole ); } - connect( mCboProject, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsGeoPackageProjectStorageDialog::projectChanged ); - connect( mCboProject, qgis::overload< const QString & >::of( &QComboBox::currentTextChanged ), this, [ = ]( const QString & ) + connect( mCboProject, qOverload( &QComboBox::currentIndexChanged ), this, &QgsGeoPackageProjectStorageDialog::projectChanged ); + connect( mCboProject, qOverload< const QString & >( &QComboBox::currentTextChanged ), this, [ = ]( const QString & ) { mCboProject->setItemData( mCboProject->currentIndex(), false ); } ); - connect( mCboConnection, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsGeoPackageProjectStorageDialog::populateProjects ); + connect( mCboConnection, qOverload( &QComboBox::currentIndexChanged ), this, &QgsGeoPackageProjectStorageDialog::populateProjects ); // If possible, set the item currently displayed database QString toSelect = QgsOgrDbConnection::selectedConnection( QStringLiteral( "GPKG" ) ); diff --git a/src/gui/qgscolorramplegendnodewidget.cpp b/src/gui/qgscolorramplegendnodewidget.cpp index 6a155e06be9e..8a14e36329e5 100644 --- a/src/gui/qgscolorramplegendnodewidget.cpp +++ b/src/gui/qgscolorramplegendnodewidget.cpp @@ -49,8 +49,8 @@ QgsColorRampLegendNodeWidget::QgsColorRampLegendNodeWidget( QWidget *parent ) connect( mMaxLabelLineEdit, &QLineEdit::textChanged, this, &QgsColorRampLegendNodeWidget::onChanged ); connect( mPrefixLineEdit, &QLineEdit::textChanged, this, &QgsColorRampLegendNodeWidget::onChanged ); connect( mSuffixLineEdit, &QLineEdit::textChanged, this, &QgsColorRampLegendNodeWidget::onChanged ); - connect( mDirectionComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsColorRampLegendNodeWidget::onChanged ); - connect( mOrientationComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsColorRampLegendNodeWidget::onOrientationChanged ); + connect( mDirectionComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsColorRampLegendNodeWidget::onChanged ); + connect( mOrientationComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsColorRampLegendNodeWidget::onOrientationChanged ); connect( mNumberFormatPushButton, &QPushButton::clicked, this, &QgsColorRampLegendNodeWidget::changeNumberFormat ); connect( mFontButton, &QgsFontButton::changed, this, &QgsColorRampLegendNodeWidget::onChanged ); } diff --git a/src/gui/qgsfieldmappingwidget.cpp b/src/gui/qgsfieldmappingwidget.cpp index 7bde6028769a..acafc45dfd52 100644 --- a/src/gui/qgsfieldmappingwidget.cpp +++ b/src/gui/qgsfieldmappingwidget.cpp @@ -282,7 +282,7 @@ QWidget *QgsFieldMappingWidget::ExpressionDelegate::createEditor( QWidget *paren editor->setField( index.model()->data( index, Qt::DisplayRole ).toString() ); connect( editor, - qgis::overload::of( &QgsFieldExpressionWidget::fieldChanged ), + qOverload( &QgsFieldExpressionWidget::fieldChanged ), this, [ = ]( const QString & fieldName, bool isValid ) { @@ -326,7 +326,7 @@ QWidget *QgsFieldMappingWidget::TypeDelegate::createEditor( QWidget *parent, con else { connect( editor, - qgis::overload::of( &QComboBox::currentIndexChanged ), + qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int currentIndex ) { diff --git a/src/gui/qgsmaplayerloadstyledialog.cpp b/src/gui/qgsmaplayerloadstyledialog.cpp index b37ec06fb07d..4c84e8a75f2d 100644 --- a/src/gui/qgsmaplayerloadstyledialog.cpp +++ b/src/gui/qgsmaplayerloadstyledialog.cpp @@ -55,7 +55,7 @@ QgsMapLayerLoadStyleDialog::QgsMapLayerLoadStyleDialog( QgsMapLayer *layer, QWid QString myLastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString(); // load style type combobox - connect( mStyleTypeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mStyleTypeComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { QgsVectorLayerProperties::StyleType type = currentStyleType(); QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( mLayer ); diff --git a/src/gui/qgsnewvectortabledialog.cpp b/src/gui/qgsnewvectortabledialog.cpp index 3e311e1dfa35..a6bb57beb93d 100644 --- a/src/gui/qgsnewvectortabledialog.cpp +++ b/src/gui/qgsnewvectortabledialog.cpp @@ -122,7 +122,7 @@ QgsNewVectorTableDialog::QgsNewVectorTableDialog( QgsAbstractDatabaseProviderCon } ); // Enable/disable geometry options and call validate - connect( mGeomTypeCbo, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int index ) + connect( mGeomTypeCbo, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int index ) { const bool hasGeom { index != 0 }; mGeomColumn->setEnabled( hasGeom ); @@ -427,7 +427,7 @@ QWidget *QgsNewVectorTableDialogFieldsDelegate::createEditor( QWidget *parent, c QComboBox *cbo = new QComboBox { parent }; cbo->setEditable( false ); cbo->setFrame( false ); - connect( cbo, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsNewVectorTableDialogFieldsDelegate::onFieldTypeChanged ); + connect( cbo, qOverload( &QComboBox::currentIndexChanged ), this, &QgsNewVectorTableDialogFieldsDelegate::onFieldTypeChanged ); for ( const auto &f : std::as_const( mTypeList ) ) { cbo->addItem( f.mTypeDesc, f.mTypeName ); diff --git a/src/gui/qgstemporalcontrollerwidget.cpp b/src/gui/qgstemporalcontrollerwidget.cpp index 6d745011c189..874e1204a3c6 100644 --- a/src/gui/qgstemporalcontrollerwidget.cpp +++ b/src/gui/qgstemporalcontrollerwidget.cpp @@ -77,8 +77,8 @@ QgsTemporalControllerWidget::QgsTemporalControllerWidget( QWidget *parent ) connect( mEndDateTime, &QDateTimeEdit::dateTimeChanged, this, &QgsTemporalControllerWidget::startEndDateTime_changed ); connect( mFixedRangeStartDateTime, &QDateTimeEdit::dateTimeChanged, this, &QgsTemporalControllerWidget::fixedRangeStartEndDateTime_changed ); connect( mFixedRangeEndDateTime, &QDateTimeEdit::dateTimeChanged, this, &QgsTemporalControllerWidget::fixedRangeStartEndDateTime_changed ); - connect( mStepSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsTemporalControllerWidget::updateFrameDuration ); - connect( mTimeStepsComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsTemporalControllerWidget::updateFrameDuration ); + connect( mStepSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsTemporalControllerWidget::updateFrameDuration ); + connect( mTimeStepsComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsTemporalControllerWidget::updateFrameDuration ); connect( mSlider, &QSlider::valueChanged, this, &QgsTemporalControllerWidget::timeSlider_valueChanged ); mStepSpinBox->setClearValue( 1 ); diff --git a/src/gui/qgstemporalmapsettingswidget.cpp b/src/gui/qgstemporalmapsettingswidget.cpp index 2e295b3f74f0..00658a67f57b 100644 --- a/src/gui/qgstemporalmapsettingswidget.cpp +++ b/src/gui/qgstemporalmapsettingswidget.cpp @@ -28,7 +28,7 @@ QgsTemporalMapSettingsWidget::QgsTemporalMapSettingsWidget( QWidget *parent ) mFrameSpinBox->setClearValue( 1 ); - connect( mFrameSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsTemporalMapSettingsWidget::frameRateChanged ); + connect( mFrameSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsTemporalMapSettingsWidget::frameRateChanged ); connect( mCumulativeTemporalRange, &QCheckBox::toggled, this, &QgsTemporalMapSettingsWidget::temporalRangeCumulativeChanged ); } diff --git a/src/gui/qgsvectorlayertemporalpropertieswidget.cpp b/src/gui/qgsvectorlayertemporalpropertieswidget.cpp index 3c904459999a..e4fc8a47ee3b 100644 --- a/src/gui/qgsvectorlayertemporalpropertieswidget.cpp +++ b/src/gui/qgsvectorlayertemporalpropertieswidget.cpp @@ -39,7 +39,7 @@ QgsVectorLayerTemporalPropertiesWidget::QgsVectorLayerTemporalPropertiesWidget( mModeComboBox->addItem( tr( "Start and End Date/Time from Expressions" ), QgsVectorLayerTemporalProperties::ModeFeatureDateTimeStartAndEndFromExpressions ); mModeComboBox->addItem( tr( "Redraw Layer Only" ), QgsVectorLayerTemporalProperties::ModeRedrawLayerOnly ); - connect( mModeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), mStackedWidget, &QStackedWidget::setCurrentIndex ); + connect( mModeComboBox, qOverload( &QComboBox::currentIndexChanged ), mStackedWidget, &QStackedWidget::setCurrentIndex ); mStartTemporalDateTimeEdit->setDisplayFormat( "yyyy-MM-dd HH:mm:ss" ); mEndTemporalDateTimeEdit->setDisplayFormat( "yyyy-MM-dd HH:mm:ss" ); diff --git a/src/gui/raster/qgscolorrampshaderwidget.cpp b/src/gui/raster/qgscolorrampshaderwidget.cpp index ce0e654efb67..ab3b9cf7bd7b 100644 --- a/src/gui/raster/qgscolorrampshaderwidget.cpp +++ b/src/gui/raster/qgscolorrampshaderwidget.cpp @@ -105,7 +105,7 @@ QgsColorRampShaderWidget::QgsColorRampShaderWidget( QWidget *parent ) connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsColorRampShaderWidget::applyColorRamp ); connect( mNumberOfEntriesSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsColorRampShaderWidget::classify ); connect( mClipCheckBox, &QAbstractButton::toggled, this, &QgsColorRampShaderWidget::widgetChanged ); - connect( mLabelPrecisionSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), this, [ = ]( int ) + connect( mLabelPrecisionSpinBox, qOverload( &QSpinBox::valueChanged ), this, [ = ]( int ) { autoLabel(); } ); diff --git a/src/gui/symbology/qgsgraduatedsymbolrendererwidget.cpp b/src/gui/symbology/qgsgraduatedsymbolrendererwidget.cpp index c0b7ab00e9e5..1251bfaaf7fa 100644 --- a/src/gui/symbology/qgsgraduatedsymbolrendererwidget.cpp +++ b/src/gui/symbology/qgsgraduatedsymbolrendererwidget.cpp @@ -563,7 +563,7 @@ QgsGraduatedSymbolRendererWidget::QgsGraduatedSymbolRendererWidget( QgsVectorLay connect( cbxLinkBoundaries, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::toggleBoundariesLink ); connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed ); - connect( cboGraduatedMode, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters ); + connect( cboGraduatedMode, qOverload( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters ); connectUpdateHandlers(); @@ -625,21 +625,21 @@ void QgsGraduatedSymbolRendererWidget::setContext( const QgsSymbolWidgetContext // Connect/disconnect event handlers which trigger updating renderer void QgsGraduatedSymbolRendererWidget::connectUpdateHandlers() { - connect( spinGraduatedClasses, qgis::overload::of( &QSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); - connect( cboGraduatedMode, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); + connect( spinGraduatedClasses, qOverload( &QSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); + connect( cboGraduatedMode, qOverload( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsGraduatedSymbolRendererWidget::reapplyColorRamp ); - connect( spinPrecision, qgis::overload::of( &QSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::labelFormatChanged ); + connect( spinPrecision, qOverload( &QSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::labelFormatChanged ); connect( cbxTrimTrailingZeroes, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::labelFormatChanged ); connect( txtLegendFormat, &QLineEdit::textChanged, this, &QgsGraduatedSymbolRendererWidget::labelFormatChanged ); - connect( minSizeSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::reapplySizes ); - connect( maxSizeSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::reapplySizes ); + connect( minSizeSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::reapplySizes ); + connect( maxSizeSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::reapplySizes ); connect( mModel, &QgsGraduatedSymbolRendererModel::rowsMoved, this, &QgsGraduatedSymbolRendererWidget::rowsMoved ); connect( mModel, &QAbstractItemModel::dataChanged, this, &QgsGraduatedSymbolRendererWidget::modelDataChanged ); connect( mGroupBoxSymmetric, &QGroupBox::toggled, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); connect( cbxAstride, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); - connect( cboSymmetryPoint, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); + connect( cboSymmetryPoint, qOverload( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished, this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished ); for ( const auto &ppww : std::as_const( mParameterWidgetWrappers ) ) @@ -651,21 +651,21 @@ void QgsGraduatedSymbolRendererWidget::connectUpdateHandlers() // Connect/disconnect event handlers which trigger updating renderer void QgsGraduatedSymbolRendererWidget::disconnectUpdateHandlers() { - disconnect( spinGraduatedClasses, qgis::overload::of( &QSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); - disconnect( cboGraduatedMode, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); + disconnect( spinGraduatedClasses, qOverload( &QSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); + disconnect( cboGraduatedMode, qOverload( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); disconnect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsGraduatedSymbolRendererWidget::reapplyColorRamp ); - disconnect( spinPrecision, qgis::overload::of( &QSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::labelFormatChanged ); + disconnect( spinPrecision, qOverload( &QSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::labelFormatChanged ); disconnect( cbxTrimTrailingZeroes, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::labelFormatChanged ); disconnect( txtLegendFormat, &QLineEdit::textChanged, this, &QgsGraduatedSymbolRendererWidget::labelFormatChanged ); - disconnect( minSizeSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::reapplySizes ); - disconnect( maxSizeSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::reapplySizes ); + disconnect( minSizeSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::reapplySizes ); + disconnect( maxSizeSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::reapplySizes ); disconnect( mModel, &QgsGraduatedSymbolRendererModel::rowsMoved, this, &QgsGraduatedSymbolRendererWidget::rowsMoved ); disconnect( mModel, &QAbstractItemModel::dataChanged, this, &QgsGraduatedSymbolRendererWidget::modelDataChanged ); disconnect( mGroupBoxSymmetric, &QGroupBox::toggled, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); disconnect( cbxAstride, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); - disconnect( cboSymmetryPoint, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); + disconnect( cboSymmetryPoint, qOverload( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished, this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished ); for ( const auto &ppww : std::as_const( mParameterWidgetWrappers ) ) diff --git a/src/gui/symbology/qgssymbollayerwidget.cpp b/src/gui/symbology/qgssymbollayerwidget.cpp index ae9c23a75628..5d4d6dbd271e 100644 --- a/src/gui/symbology/qgssymbollayerwidget.cpp +++ b/src/gui/symbology/qgssymbollayerwidget.cpp @@ -246,7 +246,7 @@ QgsSimpleLineSymbolLayerWidget::QgsSimpleLineSymbolLayerWidget( QgsVectorLayer * mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings ); mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly ); mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly ); - connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mRingFilterComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { if ( mLayer ) { @@ -1616,8 +1616,8 @@ QgsShapeburstFillSymbolLayerWidget::QgsShapeburstFillSymbolLayerWidget( QgsVecto mLayer = nullptr; setupUi( this ); - connect( mSpinBlurRadius, qgis::overload< int >::of( &QSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged ); - connect( mSpinMaxDistance, qgis::overload< double >::of( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged ); + connect( mSpinBlurRadius, qOverload< int >( &QSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinBlurRadius_valueChanged ); + connect( mSpinMaxDistance, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, &QgsShapeburstFillSymbolLayerWidget::mSpinMaxDistance_valueChanged ); connect( mDistanceUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mDistanceUnitWidget_changed ); connect( mRadioUseWholeShape, &QRadioButton::toggled, this, &QgsShapeburstFillSymbolLayerWidget::mRadioUseWholeShape_toggled ); connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShapeburstFillSymbolLayerWidget::mOffsetUnitWidget_changed ); @@ -1898,7 +1898,7 @@ QgsMarkerLineSymbolLayerWidget::QgsMarkerLineSymbolLayerWidget( QgsVectorLayer * mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings ); mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly ); mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly ); - connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mRingFilterComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { if ( mLayer ) { @@ -2145,7 +2145,7 @@ QgsHashedLineSymbolLayerWidget::QgsHashedLineSymbolLayerWidget( QgsVectorLayer * mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings ); mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly ); mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly ); - connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mRingFilterComboBox, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { if ( mLayer ) { diff --git a/src/gui/tableeditor/qgstableeditorformattingwidget.cpp b/src/gui/tableeditor/qgstableeditorformattingwidget.cpp index 6a4bba358079..f5461e6bc29a 100644 --- a/src/gui/tableeditor/qgstableeditorformattingwidget.cpp +++ b/src/gui/tableeditor/qgstableeditorformattingwidget.cpp @@ -82,7 +82,7 @@ QgsTableEditorFormattingWidget::QgsTableEditorFormattingWidget( QWidget *parent openPanel( widget ); } ); - connect( mRowHeightSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, [ = ]( double height ) + connect( mRowHeightSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, [ = ]( double height ) { if ( !mBlockSignals ) { @@ -93,7 +93,7 @@ QgsTableEditorFormattingWidget::QgsTableEditorFormattingWidget( QWidget *parent mBlockSignals--; } } ); - connect( mColumnWidthSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, [ = ]( double width ) + connect( mColumnWidthSpinBox, qOverload( &QDoubleSpinBox::valueChanged ), this, [ = ]( double width ) { if ( !mBlockSignals ) { @@ -121,7 +121,7 @@ QgsTableEditorFormattingWidget::QgsTableEditorFormattingWidget( QWidget *parent } } ); - connect( mExpressionEdit, qgis::overload::of( &QgsFieldExpressionWidget::fieldChanged ), this, [ = ]( const QString & expression ) + connect( mExpressionEdit, qOverload( &QgsFieldExpressionWidget::fieldChanged ), this, [ = ]( const QString & expression ) { if ( !mBlockSignals ) { diff --git a/src/gui/vector/qgsattributesformproperties.cpp b/src/gui/vector/qgsattributesformproperties.cpp index ea44e3575f19..6d59c00bfa9b 100644 --- a/src/gui/vector/qgsattributesformproperties.cpp +++ b/src/gui/vector/qgsattributesformproperties.cpp @@ -1188,7 +1188,7 @@ void QgsAttributesDnDTree::onItemDoubleClicked( QTreeWidgetItem *item, int colum qmlObjectTemplate->addItem( tr( "Rectangle" ) ); qmlObjectTemplate->addItem( tr( "Pie Chart" ) ); qmlObjectTemplate->addItem( tr( "Bar Chart" ) ); - connect( qmlObjectTemplate, qgis::overload::of( &QComboBox::activated ), qmlCode, [ = ]( int index ) + connect( qmlObjectTemplate, qOverload( &QComboBox::activated ), qmlCode, [ = ]( int index ) { qmlCode->clear(); switch ( index ) diff --git a/src/gui/vector/qgsvectorlayersavestyledialog.cpp b/src/gui/vector/qgsvectorlayersavestyledialog.cpp index 74c770da76a6..c83624fe9170 100644 --- a/src/gui/vector/qgsvectorlayersavestyledialog.cpp +++ b/src/gui/vector/qgsvectorlayersavestyledialog.cpp @@ -43,7 +43,7 @@ QgsVectorLayerSaveStyleDialog::QgsVectorLayerSaveStyleDialog( QgsVectorLayer *la QString myLastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString(); // save style type combobox - connect( mStyleTypeComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, [ = ]( int ) + connect( mStyleTypeComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { QgsVectorLayerProperties::StyleType type = currentStyleType(); mSaveToFileWidget->setVisible( type != QgsVectorLayerProperties::DB ); diff --git a/src/gui/vector/qgswmsdimensiondialog.cpp b/src/gui/vector/qgswmsdimensiondialog.cpp index b2b47453f95b..35cd8ecb348b 100644 --- a/src/gui/vector/qgswmsdimensiondialog.cpp +++ b/src/gui/vector/qgswmsdimensiondialog.cpp @@ -43,7 +43,7 @@ QgsWmsDimensionDialog::QgsWmsDimensionDialog( QgsVectorLayer *layer, QStringList connect( mFieldComboBox, &QgsFieldComboBox::fieldChanged, this, &QgsWmsDimensionDialog::fieldChanged ); connect( mEndFieldComboBox, &QgsFieldComboBox::fieldChanged, this, &QgsWmsDimensionDialog::fieldChanged ); connect( mNameComboBox, &QComboBox::editTextChanged, this, &QgsWmsDimensionDialog::nameChanged ); - connect( mDefaultDisplayComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsWmsDimensionDialog::defaultDisplayChanged ); + connect( mDefaultDisplayComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsWmsDimensionDialog::defaultDisplayChanged ); // Set available names const QMetaEnum pnMetaEnum( QMetaEnum::fromType() ); diff --git a/src/providers/postgres/qgspostgresprojectstoragedialog.cpp b/src/providers/postgres/qgspostgresprojectstoragedialog.cpp index c6d25f9d1953..b5a2d617b8d7 100644 --- a/src/providers/postgres/qgspostgresprojectstoragedialog.cpp +++ b/src/providers/postgres/qgspostgresprojectstoragedialog.cpp @@ -51,7 +51,7 @@ QgsPostgresProjectStorageDialog::QgsPostgresProjectStorageDialog( bool saving, Q setWindowTitle( tr( "Load project from PostgreSQL" ) ); } - connect( mCboConnection, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, &QgsPostgresProjectStorageDialog::populateSchemas ); + connect( mCboConnection, qOverload< int >( &QComboBox::currentIndexChanged ), this, &QgsPostgresProjectStorageDialog::populateSchemas ); mLblProjectsNotAllowed->setVisible( false ); @@ -63,8 +63,8 @@ QgsPostgresProjectStorageDialog::QgsPostgresProjectStorageDialog( bool saving, Q mCboConnection->setCurrentIndex( mCboConnection->findText( toSelect ) ); populateProjects(); - connect( mCboSchema, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, &QgsPostgresProjectStorageDialog::populateProjects ); - connect( mCboProject, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, &QgsPostgresProjectStorageDialog::projectChanged ); + connect( mCboSchema, qOverload< int >( &QComboBox::currentIndexChanged ), this, &QgsPostgresProjectStorageDialog::populateProjects ); + connect( mCboProject, qOverload< int >( &QComboBox::currentIndexChanged ), this, &QgsPostgresProjectStorageDialog::projectChanged ); projectChanged(); } diff --git a/src/providers/wfs/qgsbasenetworkrequest.cpp b/src/providers/wfs/qgsbasenetworkrequest.cpp index 021300d0edd9..be292cd2a98e 100644 --- a/src/providers/wfs/qgsbasenetworkrequest.cpp +++ b/src/providers/wfs/qgsbasenetworkrequest.cpp @@ -31,7 +31,7 @@ QgsBaseNetworkRequest::QgsBaseNetworkRequest( const QgsAuthorizationSettings &au : mAuth( auth ) , mTranslatedComponent( translatedComponent ) { - connect( QgsNetworkAccessManager::instance(), qgis::overload< QNetworkReply *>::of( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsBaseNetworkRequest::requestTimedOut ); + connect( QgsNetworkAccessManager::instance(), qOverload< QNetworkReply *>( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsBaseNetworkRequest::requestTimedOut ); } QgsBaseNetworkRequest::~QgsBaseNetworkRequest() diff --git a/src/providers/wfs/qgswfsprovider.cpp b/src/providers/wfs/qgswfsprovider.cpp index edf6469089e4..bbbd76a29024 100644 --- a/src/providers/wfs/qgswfsprovider.cpp +++ b/src/providers/wfs/qgswfsprovider.cpp @@ -126,7 +126,7 @@ QgsWFSProvider::QgsWFSProvider( const QString &uri, const ProviderOptions &optio auto downloader = std::make_unique(); downloader->setImpl( std::make_unique( mShared.get(), downloader.get(), requestMadeFromMainThread ) ); connect( downloader.get(), - qgis::overload < QVector >::of( &QgsFeatureDownloader::featureReceived ), + qOverload < QVector >( &QgsFeatureDownloader::featureReceived ), this, &QgsWFSProvider::featureReceivedAnalyzeOneFeature ); if ( requestMadeFromMainThread ) { diff --git a/tests/src/core/testqgsnetworkaccessmanager.cpp b/tests/src/core/testqgsnetworkaccessmanager.cpp index e18feb336ba1..0cffcd23a5de 100644 --- a/tests/src/core/testqgsnetworkaccessmanager.cpp +++ b/tests/src/core/testqgsnetworkaccessmanager.cpp @@ -229,7 +229,7 @@ void TestQgsNetworkAccessManager::fetchEmptyUrl() bool loaded = false; bool gotRequestAboutToBeCreatedSignal = false; int requestId = -1; - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) { gotRequestAboutToBeCreatedSignal = true; requestId = params.requestId(); @@ -237,7 +237,7 @@ void TestQgsNetworkAccessManager::fetchEmptyUrl() QCOMPARE( params.operation(), QNetworkAccessManager::GetOperation ); QCOMPARE( params.request().url(), QUrl() ); } ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) { QCOMPARE( reply.errorString(), QStringLiteral( "Protocol \"\" is unknown" ) ); QCOMPARE( reply.requestId(), requestId ); @@ -307,7 +307,7 @@ void TestQgsNetworkAccessManager::fetchBadUrl() bool loaded = false; bool gotRequestAboutToBeCreatedSignal = false; int requestId = -1; - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) { gotRequestAboutToBeCreatedSignal = true; requestId = params.requestId(); @@ -315,7 +315,7 @@ void TestQgsNetworkAccessManager::fetchBadUrl() QCOMPARE( params.operation(), QNetworkAccessManager::GetOperation ); QCOMPARE( params.request().url(), QUrl( QStringLiteral( "http://x" ) ) ); } ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) { QCOMPARE( reply.errorString(), QStringLiteral( "Host x not found" ) ); QCOMPARE( reply.requestId(), requestId ); @@ -386,7 +386,7 @@ void TestQgsNetworkAccessManager::fetchEncodedContent() bool gotRequestAboutToBeCreatedSignal = false; int requestId = -1; QUrl u = QUrl::fromLocalFile( QStringLiteral( TEST_DATA_DIR ) + '/' + "encoded_html.html" ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) { gotRequestAboutToBeCreatedSignal = true; requestId = params.requestId(); @@ -396,7 +396,7 @@ void TestQgsNetworkAccessManager::fetchEncodedContent() QCOMPARE( params.initiatorClassName(), QStringLiteral( "myTestClass" ) ); QCOMPARE( params.initiatorRequestId().toInt(), 55 ); } ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) { QCOMPARE( reply.error(), QNetworkReply::NoError ); QCOMPARE( reply.requestId(), requestId ); @@ -471,7 +471,7 @@ void TestQgsNetworkAccessManager::fetchPost() bool gotRequestAboutToBeCreatedSignal = false; int requestId = -1; QUrl u = QUrl( QStringLiteral( "http://" ) + mHttpBinHost + QStringLiteral( "/post" ) ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) { gotRequestAboutToBeCreatedSignal = true; requestId = params.requestId(); @@ -480,7 +480,7 @@ void TestQgsNetworkAccessManager::fetchPost() QCOMPARE( params.request().url(), u ); QCOMPARE( params.content(), QByteArray( "a=b&c=d" ) ); } ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) { QCOMPARE( reply.error(), QNetworkReply::NoError ); QCOMPARE( reply.requestId(), requestId ); @@ -566,7 +566,7 @@ void TestQgsNetworkAccessManager::fetchBadSsl() bool gotRequestEncounteredSslError = false; int requestId = -1; QUrl u = QUrl( QStringLiteral( "https://expired.badssl.com" ) ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) { gotRequestAboutToBeCreatedSignal = true; requestId = params.requestId(); @@ -574,7 +574,7 @@ void TestQgsNetworkAccessManager::fetchBadSsl() QCOMPARE( params.operation(), QNetworkAccessManager::GetOperation ); QCOMPARE( params.request().url(), u ); } ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) { QCOMPARE( reply.error(), QNetworkReply::SslHandshakeFailedError ); QCOMPARE( reply.requestId(), requestId ); @@ -667,7 +667,7 @@ void TestQgsNetworkAccessManager::testSslErrorHandler() int requestId = -1; bool gotRequestEncounteredSslError = false; QUrl u = QUrl( QStringLiteral( "https://self-signed.badssl.com/" ) ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) { gotRequestAboutToBeCreatedSignal = true; requestId = params.requestId(); @@ -675,7 +675,7 @@ void TestQgsNetworkAccessManager::testSslErrorHandler() QCOMPARE( params.operation(), QNetworkAccessManager::GetOperation ); QCOMPARE( params.request().url(), u ); } ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) { QCOMPARE( reply.error(), QNetworkReply::NoError ); // because handler ignores error QCOMPARE( reply.requestId(), requestId ); @@ -774,7 +774,7 @@ void TestQgsNetworkAccessManager::testAuthRequestHandler() int requestId = -1; QUrl u = QUrl( QStringLiteral( "http://" ) + mHttpBinHost + QStringLiteral( "/basic-auth/me/" ) + hash ); QNetworkReply::NetworkError expectedError = QNetworkReply::NoError; - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) { gotRequestAboutToBeCreatedSignal = true; requestId = params.requestId(); @@ -782,7 +782,7 @@ void TestQgsNetworkAccessManager::testAuthRequestHandler() QCOMPARE( params.operation(), QNetworkAccessManager::GetOperation ); QCOMPARE( params.request().url(), u ); } ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) { QCOMPARE( reply.error(), expectedError ); QCOMPARE( reply.requestId(), requestId ); @@ -978,7 +978,7 @@ void TestQgsNetworkAccessManager::fetchTimeout() bool finished = false; int requestId = -1; QUrl u = QUrl( QStringLiteral( "http://" ) + mHttpBinHost + QStringLiteral( "/delay/10" ) ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestAboutToBeCreated ), &context, [&]( const QgsNetworkRequestParameters & params ) { gotRequestAboutToBeCreatedSignal = true; requestId = params.requestId(); @@ -986,12 +986,12 @@ void TestQgsNetworkAccessManager::fetchTimeout() QCOMPARE( params.operation(), QNetworkAccessManager::GetOperation ); QCOMPARE( params.request().url(), u ); } ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkRequestParameters >::of( &QgsNetworkAccessManager::requestTimedOut ), &context, [&]( const QgsNetworkRequestParameters & request ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkRequestParameters >( &QgsNetworkAccessManager::requestTimedOut ), &context, [&]( const QgsNetworkRequestParameters & request ) { QCOMPARE( request.requestId(), requestId ); gotTimeoutError = true; } ); - connect( QgsNetworkAccessManager::instance(), qgis::overload< QgsNetworkReplyContent >::of( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) + connect( QgsNetworkAccessManager::instance(), qOverload< QgsNetworkReplyContent >( &QgsNetworkAccessManager::finished ), &context, [&]( const QgsNetworkReplyContent & reply ) { finished = reply.error() != QNetworkReply::OperationCanceledError; // should not happen! } ); From 04d9c6519b8242424b4973cbbf059f4fa71a8add Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 10:55:08 +1000 Subject: [PATCH 143/377] Remove accidental checkin --- src/core/qgsprojectcomponentvisitor.h | 193 -------------------------- 1 file changed, 193 deletions(-) delete mode 100644 src/core/qgsprojectcomponentvisitor.h diff --git a/src/core/qgsprojectcomponentvisitor.h b/src/core/qgsprojectcomponentvisitor.h deleted file mode 100644 index e48843543fbc..000000000000 --- a/src/core/qgsprojectcomponentvisitor.h +++ /dev/null @@ -1,193 +0,0 @@ -/*************************************************************************** - qgsprojectcomponentvisitor.h - --------------- - begin : June 2020 - copyright : (C) 2020 by Nyall Dawson - email : nyall dot dawson at gmail dot com - ***************************************************************************/ - -/*************************************************************************** - * - - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * - - ***************************************************************************/ - -#ifndef QGSPROJECTCOMPONENTVISITOR_H -#define QGSPROJECTCOMPONENTVISITOR_H - -#include "qgis_core.h" -#include - -class QgsProjectComponentInterface; - -/** - * \class QgsComponentEntityVisitorInterface - * \ingroup core - * - * An interface for classes which can visit project components (e.g. symbols, expressions, etc) using the visitor pattern. - * - * \since QGIS 3.14 - */ -class CORE_EXPORT QgsProjectComponentVisitorInterface -{ - - public: - - /** - * Describes the types of nodes which may be visited by the visitor. - */ - enum class NodeType : int - { - Layer, //!< Map layer - SymbolRule, //!< Rule based symbology or label child rule - Layouts, //!< Layout collection - PrintLayout, //!< An individual print layout - LayoutItem, //!< Individual item in a print layout - Report, //!< A QGIS print report - ReportHeader, //!< Report header section - ReportFooter, //!< Report footer section - ReportSection, //!< Report sub section - Annotations, //!< Annotations collection - Annotation, //!< An individual annotation - - Other, //!< Other/unclassified type - }; - - /** - * Contains information relating to the project component currently being visited. - */ - struct ComponentLeaf - { - - /** - * Constructor for ComponentLeaf, visiting the given \a component with the specified \a identifier and \a description. - * - * Ownership of \a component is not transferred. - */ - ComponentLeaf( const QgsProjectComponentInterface *component, const QString &identifier = QString(), const QString &description = QString() ) - : identifier( identifier ) - , description( description ) - , component( component ) - {} - - /** - * A string identifying the project component. The actual value of \a identifier will vary - * depending on the class being visited. E.g for a categorized renderer, the - * identifier will be the category ID associated with the symbol. - * - * This may be blank if no identifier is required, e.g. when a renderer has a single - * symbol only. - * - * Note that in some cases where a specific identifier is not available, a generic, untranslated - * one may be used (e.g. "overview", "grid"). - */ - QString identifier; - - /** - * A string describing the project copmonent. The actual value of \a description will vary - * depending on the class being visited. E.g for a categorized renderer, the - * description will be the category label associated with the symbol, for a print layout, it will - * be the name of the layout in the project. - * - * This may be blank if no description is associated with a style entity, e.g. when a renderer has a single - * symbol only. - * - * This value may be a generic, translated value in some cases, e.g. "Grid" or "Overview". - */ - QString description; - - /** - * Reference to component being visited. - */ - const QgsProjectComponentInterface *component = nullptr; - }; - - /** - * Contains information relating to a node (i.e. a group of symbols or other nodes) - * being visited. - */ - struct Node - { - - /** - * Constructor for Node, visiting the node with the specified \a identifier and \a description. - */ - Node( QgsProjectComponentVisitorInterface::NodeType type, const QString &identifier, const QString &description ) - : type( type ) - , identifier( identifier ) - , description( description ) - {} - - /** - * Node type. - */ - QgsProjectComponentVisitorInterface::NodeType type = QgsProjectComponentVisitorInterface::NodeType::Other; - - /** - * A string identifying the node. The actual value of \a identifier will vary - * depending on the node being visited. E.g for a rule based renderer, the - * identifier will be a rule ID. For a project, node identifiers will be - * layer IDs. - */ - QString identifier; - - /** - * A string describing the node. The actual value of \a description will vary - * depending on the node being visited. E.g for a rule based renderer, the - * identifier will be a rule label. For a project, node identifiers will be - * layer names. - */ - QString description; - - }; - - virtual ~QgsProjectComponentVisitorInterface() = default; - - /** - * Called when the visitor will visit a project \a component. - * - * Subclasses should return FALSE to abort further visitations, or TRUE to continue - * visiting after processing this component. - */ - virtual bool visit( const QgsProjectComponentVisitorInterface::ComponentLeaf &component ) - { - Q_UNUSED( component ) - return true; - } - - /** - * Called when the visitor starts visiting a \a node. - * - * Subclasses should return FALSE if they do NOT want to visit this particular node - e.g. - * if the node type is QgsProjectComponentVisitorInterface::NodeType::Layouts and they do not wish to visit - * layout objects. In this case the visitor will not process the node, and will move to the next available - * node instead. Return TRUE to proceed with visiting the node. - * - * The default implementation returns TRUE. - */ - virtual bool visitEnter( const QgsProjectComponentVisitorInterface::Node &node ) - { - Q_UNUSED( node ) - return true; - } - - /** - * Called when the visitor stops visiting a \a node. - * - * Subclasses should return FALSE to abort further visitations, or TRUE to continue - * visiting other nodes. - * - * The default implementation returns TRUE. - */ - virtual bool visitExit( const QgsProjectComponentVisitorInterface::Node &node ) - { - Q_UNUSED( node ) - return true; - } - -}; - -#endif // QGSPROJECTCOMPONENTVISITOR_H From 907d1da20008e5709f0f815c29cf5e8d6d87f081 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 11:01:39 +1000 Subject: [PATCH 144/377] Identation --- .../ogr/qgsgeopackageproviderconnection.cpp | 16 ++-- src/gui/layout/qgslayoutlabelwidget.cpp | 80 +++++++++---------- src/providers/postgres/qgspgsourceselect.cpp | 14 ++-- 3 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/core/providers/ogr/qgsgeopackageproviderconnection.cpp b/src/core/providers/ogr/qgsgeopackageproviderconnection.cpp index 0e547df3342d..4c1fc9705e73 100644 --- a/src/core/providers/ogr/qgsgeopackageproviderconnection.cpp +++ b/src/core/providers/ogr/qgsgeopackageproviderconnection.cpp @@ -220,8 +220,8 @@ bool QgsGeoPackageProviderConnection::spatialIndexExists( const QString &schema, { QgsMessageLog::logMessage( QStringLiteral( "Schema is not supported by GPKG, ignoring" ), QStringLiteral( "OGR" ), Qgis::Info ); } - const auto res { executeGdalSqlPrivate( QStringLiteral( "SELECT HasSpatialIndex(%1, %2)" ).arg( QgsSqliteUtils::quotedString( name ), - QgsSqliteUtils::quotedString( geometryColumn ) ) ).rows() }; + const QList > res = executeGdalSqlPrivate( QStringLiteral( "SELECT HasSpatialIndex(%1, %2)" ).arg( QgsSqliteUtils::quotedString( name ), + QgsSqliteUtils::quotedString( geometryColumn ) ) ).rows(); return !res.isEmpty() && !res.at( 0 ).isEmpty() && res.at( 0 ).at( 0 ).toBool(); } @@ -255,9 +255,9 @@ QList QgsGeoPackageProviderConne try { - const QString sql { QStringLiteral( "SELECT c.table_name, data_type, description, c.srs_id, g.geometry_type_name, g.column_name " - "FROM gpkg_contents c LEFT JOIN gpkg_geometry_columns g ON (c.table_name = g.table_name) " - "WHERE c.table_name NOT IN (%1)" ).arg( excludedTableNames.join( ',' ) ) }; + const QString sql = QStringLiteral( "SELECT c.table_name, data_type, description, c.srs_id, g.geometry_type_name, g.column_name " + "FROM gpkg_contents c LEFT JOIN gpkg_geometry_columns g ON (c.table_name = g.table_name) " + "WHERE c.table_name NOT IN (%1)" ).arg( excludedTableNames.join( ',' ) ); results = executeSql( sql ); for ( const auto &row : std::as_const( results ) ) @@ -490,9 +490,9 @@ QList QgsGeoPackageProviderConnection::native const QgsVectorLayer vl { uri(), QStringLiteral( "temp_layer" ), QStringLiteral( "ogr" ), options }; if ( ! vl.isValid() || ! vl.dataProvider() ) { - const QString errorCause { vl.dataProvider() &&vl.dataProvider()->hasErrors() ? - vl.dataProvider()->errors().join( '\n' ) : - QObject::tr( "unknown error" ) }; + const QString errorCause = vl.dataProvider() && vl.dataProvider()->hasErrors() ? + vl.dataProvider()->errors().join( '\n' ) : + QObject::tr( "unknown error" ); throw QgsProviderConnectionException( QObject::tr( "Error retrieving native types for %1: %2" ).arg( uri(), errorCause ) ); } return vl.dataProvider()->nativeTypes(); diff --git a/src/gui/layout/qgslayoutlabelwidget.cpp b/src/gui/layout/qgslayoutlabelwidget.cpp index 678d652d94f9..8ad2945291e7 100644 --- a/src/gui/layout/qgslayoutlabelwidget.cpp +++ b/src/gui/layout/qgslayoutlabelwidget.cpp @@ -106,11 +106,11 @@ void QgsLayoutLabelWidget::buildInsertDynamicTextMenu( QgsLayout *layout, QMenu QMenu *dateMenu = new QMenu( tr( "Current Date" ), menu ); for ( const std::pair< QString, QString > &expression : -{ - std::make_pair( tr( "ISO Format (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "yyyy-MM-dd" ) ) ), QStringLiteral( "format_date(now(), 'yyyy-MM-dd')" ) ), - std::make_pair( tr( "Day/Month/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "dd/MM/yyyy" ) ) ), QStringLiteral( "format_date(now(), 'dd/MM/yyyy')" ) ), - std::make_pair( tr( "Month/Day/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "MM/dd/yyyy" ) ) ), QStringLiteral( "format_date(now(), 'MM/dd/yyyy')" ) ), - } ) + { + std::make_pair( tr( "ISO Format (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "yyyy-MM-dd" ) ) ), QStringLiteral( "format_date(now(), 'yyyy-MM-dd')" ) ), + std::make_pair( tr( "Day/Month/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "dd/MM/yyyy" ) ) ), QStringLiteral( "format_date(now(), 'dd/MM/yyyy')" ) ), + std::make_pair( tr( "Month/Day/Year (%1)" ).arg( QDateTime::currentDateTime().toString( QStringLiteral( "MM/dd/yyyy" ) ) ), QStringLiteral( "format_date(now(), 'MM/dd/yyyy')" ) ), + } ) { addExpression( dateMenu, expression.first, expression.second ); } @@ -127,21 +127,21 @@ void QgsLayoutLabelWidget::buildInsertDynamicTextMenu( QgsLayout *layout, QMenu QMenu *mapMenu = new QMenu( map->displayName(), mapsMenu ); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "Scale (%1)" ).arg( map->scale() ), QStringLiteral( "item_variables('%1')['map_scale']" ).arg( map->id() ) ), - std::make_pair( tr( "Rotation (%1)" ).arg( map->rotation() ), QStringLiteral( "item_variables('%1')['map_rotation']" ).arg( map->id() ) ), - } ) + { + std::make_pair( tr( "Scale (%1)" ).arg( map->scale() ), QStringLiteral( "item_variables('%1')['map_scale']" ).arg( map->id() ) ), + std::make_pair( tr( "Rotation (%1)" ).arg( map->rotation() ), QStringLiteral( "item_variables('%1')['map_rotation']" ).arg( map->id() ) ), + } ) { addExpression( mapMenu, expression.first, expression.second ); } mapMenu->addSeparator(); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "CRS Identifier (%1)" ).arg( map->crs().authid() ), QStringLiteral( "item_variables('%1')['map_crs']" ).arg( map->id() ) ), - std::make_pair( tr( "CRS Name (%1)" ).arg( map->crs().description() ), QStringLiteral( "item_variables('%1')['map_crs_description']" ).arg( map->id() ) ), - std::make_pair( tr( "Ellipsoid Name (%1)" ).arg( map->crs().ellipsoidAcronym() ), QStringLiteral( "item_variables('%1')['map_crs_ellipsoid']" ).arg( map->id() ) ), - std::make_pair( tr( "Units (%1)" ).arg( QgsUnitTypes::toString( map->crs().mapUnits() ) ), QStringLiteral( "item_variables('%1')['map_units']" ).arg( map->id() ) ), - } ) + { + std::make_pair( tr( "CRS Identifier (%1)" ).arg( map->crs().authid() ), QStringLiteral( "item_variables('%1')['map_crs']" ).arg( map->id() ) ), + std::make_pair( tr( "CRS Name (%1)" ).arg( map->crs().description() ), QStringLiteral( "item_variables('%1')['map_crs_description']" ).arg( map->id() ) ), + std::make_pair( tr( "Ellipsoid Name (%1)" ).arg( map->crs().ellipsoidAcronym() ), QStringLiteral( "item_variables('%1')['map_crs_ellipsoid']" ).arg( map->id() ) ), + std::make_pair( tr( "Units (%1)" ).arg( QgsUnitTypes::toString( map->crs().mapUnits() ) ), QStringLiteral( "item_variables('%1')['map_units']" ).arg( map->id() ) ), + } ) { addExpression( mapMenu, expression.first, expression.second ); } @@ -150,22 +150,22 @@ void QgsLayoutLabelWidget::buildInsertDynamicTextMenu( QgsLayout *layout, QMenu const QgsRectangle mapExtent = map->extent(); const QgsPointXY center = mapExtent.center(); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "Center (X) (%1)" ).arg( center.x() ), QStringLiteral( "x(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ), - std::make_pair( tr( "Center (Y) (%1)" ).arg( center.y() ), QStringLiteral( "y(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ), - std::make_pair( tr( "X Minimum (%1)" ).arg( mapExtent.xMinimum() ), QStringLiteral( "x_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), - std::make_pair( tr( "Y Minimum (%1)" ).arg( mapExtent.yMinimum() ), QStringLiteral( "y_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), - std::make_pair( tr( "X Maximum (%1)" ).arg( mapExtent.xMaximum() ), QStringLiteral( "x_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), - std::make_pair( tr( "Y Maximum (%1)" ).arg( mapExtent.yMaximum() ), QStringLiteral( "y_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), - } ) + { + std::make_pair( tr( "Center (X) (%1)" ).arg( center.x() ), QStringLiteral( "x(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ), + std::make_pair( tr( "Center (Y) (%1)" ).arg( center.y() ), QStringLiteral( "y(item_variables('%1')['map_extent_center'])" ).arg( map->id() ) ), + std::make_pair( tr( "X Minimum (%1)" ).arg( mapExtent.xMinimum() ), QStringLiteral( "x_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), + std::make_pair( tr( "Y Minimum (%1)" ).arg( mapExtent.yMinimum() ), QStringLiteral( "y_min(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), + std::make_pair( tr( "X Maximum (%1)" ).arg( mapExtent.xMaximum() ), QStringLiteral( "x_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), + std::make_pair( tr( "Y Maximum (%1)" ).arg( mapExtent.yMaximum() ), QStringLiteral( "y_max(item_variables('%1')['map_extent'])" ).arg( map->id() ) ), + } ) { addExpression( mapMenu, expression.first, expression.second ); } mapMenu->addSeparator(); for ( const std::pair< QString, QString > &expression : - { - std::make_pair( tr( "Layer Credits" ), QStringLiteral( "array_to_string(map_credits('%1'))" ).arg( map->id() ) ), - } ) + { + std::make_pair( tr( "Layer Credits" ), QStringLiteral( "array_to_string(map_credits('%1'))" ).arg( map->id() ) ), + } ) { addExpression( mapMenu, expression.first, expression.second ); } @@ -189,30 +189,30 @@ void QgsLayoutLabelWidget::buildInsertDynamicTextMenu( QgsLayout *layout, QMenu } for ( const std::pair< QString, QString > &expression : -{ - std::make_pair( tr( "Layout Name" ), QStringLiteral( "@layout_name" ) ), - std::make_pair( tr( "Layout Page Number" ), QStringLiteral( "@layout_page" ) ), - std::make_pair( tr( "Layout Page Count" ), QStringLiteral( "@layout_numpages" ) ) - } ) + { + std::make_pair( tr( "Layout Name" ), QStringLiteral( "@layout_name" ) ), + std::make_pair( tr( "Layout Page Number" ), QStringLiteral( "@layout_page" ) ), + std::make_pair( tr( "Layout Page Count" ), QStringLiteral( "@layout_numpages" ) ) + } ) { addExpression( menu, expression.first, expression.second ); } menu->addSeparator(); for ( const std::pair< QString, QString > &expression : -{ - std::make_pair( tr( "Project Author" ), QStringLiteral( "@project_author" ) ), - std::make_pair( tr( "Project Title" ), QStringLiteral( "@project_title" ) ), - std::make_pair( tr( "Project Path" ), QStringLiteral( "@project_path" ) ) - } ) + { + std::make_pair( tr( "Project Author" ), QStringLiteral( "@project_author" ) ), + std::make_pair( tr( "Project Title" ), QStringLiteral( "@project_title" ) ), + std::make_pair( tr( "Project Path" ), QStringLiteral( "@project_path" ) ) + } ) { addExpression( menu, expression.first, expression.second ); } menu->addSeparator(); for ( const std::pair< QString, QString > &expression : -{ - std::make_pair( tr( "Current User Name" ), QStringLiteral( "@user_full_name" ) ), - std::make_pair( tr( "Current User Account" ), QStringLiteral( "@user_account_name" ) ) - } ) + { + std::make_pair( tr( "Current User Name" ), QStringLiteral( "@user_full_name" ) ), + std::make_pair( tr( "Current User Account" ), QStringLiteral( "@user_account_name" ) ) + } ) { addExpression( menu, expression.first, expression.second ); } diff --git a/src/providers/postgres/qgspgsourceselect.cpp b/src/providers/postgres/qgspgsourceselect.cpp index 5af5382adfef..fdfeb9beb314 100644 --- a/src/providers/postgres/qgspgsourceselect.cpp +++ b/src/providers/postgres/qgspgsourceselect.cpp @@ -59,13 +59,13 @@ QWidget *QgsPgSourceSelectDelegate::createEditor( QWidget *parent, const QStyleO if ( index.column() == QgsPgTableModel::DbtmType && index.data( Qt::UserRole + 1 ).toBool() ) { QComboBox *cb = new QComboBox( parent ); - static const QList types { QgsWkbTypes::Point - , QgsWkbTypes::LineString - , QgsWkbTypes::Polygon - , QgsWkbTypes::MultiPoint - , QgsWkbTypes::MultiLineString - , QgsWkbTypes::MultiPolygon - , QgsWkbTypes::NoGeometry }; + static const QList types { QgsWkbTypes::Point, + QgsWkbTypes::LineString, + QgsWkbTypes::Polygon, + QgsWkbTypes::MultiPoint, + QgsWkbTypes::MultiLineString, + QgsWkbTypes::MultiPolygon, + QgsWkbTypes::NoGeometry }; for ( QgsWkbTypes::Type type : types ) { cb->addItem( QgsLayerItem::iconForWkbType( type ), QgsPostgresConn::displayStringForWkbType( type ), type ); From 04f157982c999f081e17ebba255c46d3fc7ae011 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 11:04:32 +1000 Subject: [PATCH 145/377] Indentation --- .../raster/qgspostgresrasterprovider.cpp | 64 ++++++++----------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/src/providers/postgres/raster/qgspostgresrasterprovider.cpp b/src/providers/postgres/raster/qgspostgresrasterprovider.cpp index a9685037c739..40941728476f 100644 --- a/src/providers/postgres/raster/qgspostgresrasterprovider.cpp +++ b/src/providers/postgres/raster/qgspostgresrasterprovider.cpp @@ -1005,14 +1005,13 @@ bool QgsPostgresRasterProvider::init() { try { - const QString sql { QStringLiteral( "SELECT r_raster_column, srid," - "num_bands, pixel_types, nodata_values, ST_AsBinary(extent), blocksize_x, blocksize_y," - "out_db, spatial_index, scale_x, scale_y, same_alignment," - "regular_blocking " - "FROM raster_columns WHERE " - "r_table_name = %1 AND r_table_schema = %2" ) - .arg( quotedValue( mTableName ) ) - .arg( quotedValue( mSchemaName ) ) }; + const QString sql = QStringLiteral( "SELECT r_raster_column, srid," + "num_bands, pixel_types, nodata_values, ST_AsBinary(extent), blocksize_x, blocksize_y," + "out_db, spatial_index, scale_x, scale_y, same_alignment," + "regular_blocking " + "FROM raster_columns WHERE " + "r_table_name = %1 AND r_table_schema = %2" ) + .arg( quotedValue( mTableName ), quotedValue( mSchemaName ) ); QgsPostgresResult result( connectionRO()->PQexec( sql ) ); @@ -1182,10 +1181,9 @@ bool QgsPostgresRasterProvider::init() // if ( mRasterColumn.isEmpty() ) { - const QString sql { QStringLiteral( "SELECT column_name FROM information_schema.columns WHERE " - "table_name = %1 AND table_schema = %2 AND udt_name = 'raster'" ) - .arg( quotedValue( mTableName ) ) - .arg( quotedValue( mSchemaName ) )}; + const QString sql = QStringLiteral( "SELECT column_name FROM information_schema.columns WHERE " + "table_name = %1 AND table_schema = %2 AND udt_name = 'raster'" ) + .arg( quotedValue( mTableName ), quotedValue( mSchemaName ) ); QgsPostgresResult result( connectionRO()->PQexec( sql ) ); @@ -1230,7 +1228,7 @@ bool QgsPostgresRasterProvider::init() // Fastest SQL: fetch all metadata in one pass // 0 1 3 3 4 5 6 7 8 9 10 11 12 13 14 // encode | upperleftx | upperlefty | width | height | scalex | scaley | skewx | skewy | srid | numbands | pixeltype | nodatavalue | isoutdb | path - const QString sql { QStringLiteral( R"( + const QString sql = QStringLiteral( R"( WITH cte_filtered_raster AS ( SELECT %1 AS filtered_rast FROM %2 %3 ), cte_rast AS ( SELECT ST_Union( cte_filtered_raster.filtered_rast ) AS united_raster FROM cte_filtered_raster ), cte_bandno AS ( SELECT * FROM generate_series(1, ST_NumBands ( ( SELECT cte_rast.united_raster FROM cte_rast ) ) ) AS bandno ), @@ -1238,8 +1236,7 @@ bool QgsPostgresRasterProvider::init() SELECT ENCODE( ST_AsBinary( ST_Envelope( band ) ), 'hex'), (ST_Metadata( band )).*, (ST_BandMetadata( band )).* - FROM cte_band - )" ).arg( quotedIdentifier( mRasterColumn ), tableToQuery, where ) }; + FROM cte_band)" ).arg( quotedIdentifier( mRasterColumn ), tableToQuery, where ); QgsDebugMsgLevel( QStringLiteral( "Raster information sql: %1" ).arg( sql ), 4 ); @@ -1403,11 +1400,10 @@ bool QgsPostgresRasterProvider::initFieldsAndTemporal( ) { const QString temporalFieldName { mAttributeFields.field( temporalFieldIndex ).name() }; // Calculate the range - const QString sql { QStringLiteral( "SELECT MIN(%1::timestamp), MAX(%1::timestamp) " - "FROM %2 %3" ) - .arg( quotedIdentifier( temporalFieldName ) ) - .arg( mQuery ) - .arg( where )}; + const QString sql = QStringLiteral( "SELECT MIN(%1::timestamp), MAX(%1::timestamp) " + "FROM %2 %3" ).arg( quotedIdentifier( temporalFieldName ), + mQuery, + where ); QgsPostgresResult result( connectionRO()->PQexec( sql ) ); @@ -2155,11 +2151,9 @@ void QgsPostgresRasterProvider::determinePrimaryKeyFromUriKeyColumn() mPrimaryKeyAttrs.clear(); const QString keyCandidate { mUri.keyColumn() }; QgsPostgresPrimaryKeyType pkType { QgsPostgresPrimaryKeyType::PktUnknown }; - const QString sql { QStringLiteral( "SELECT data_type FROM information_schema.columns " - "WHERE column_name = %1 AND table_name = %2 AND table_schema = %3" ) - .arg( keyCandidate ) - .arg( mTableName ) - .arg( mSchemaName ) }; + const QString sql = QStringLiteral( "SELECT data_type FROM information_schema.columns " + "WHERE column_name = %1 AND table_name = %2 AND table_schema = %3" ) + .arg( keyCandidate, mTableName, mSchemaName ); QgsPostgresResult result( connectionRO()->PQexec( sql ) ); if ( PGRES_TUPLES_OK == result.PQresultStatus() ) { @@ -2204,10 +2198,9 @@ QString QgsPostgresRasterProvider::dataComment() const void QgsPostgresRasterProvider::findOverviews() { - const QString sql { QStringLiteral( "SELECT overview_factor, o_table_schema, o_table_name, o_raster_column " - "FROM raster_overviews WHERE r_table_schema = %1 AND r_table_name = %2" ) - .arg( quotedValue( mSchemaName ) ) - .arg( quotedValue( mTableName ) ) }; + const QString sql = QStringLiteral( "SELECT overview_factor, o_table_schema, o_table_name, o_raster_column " + "FROM raster_overviews WHERE r_table_schema = %1 AND r_table_name = %2" ).arg( quotedValue( mSchemaName ), + quotedValue( mTableName ) ); //QgsDebugMsg( QStringLiteral( "Raster overview information sql: %1" ).arg( sql ) ); QgsPostgresResult result( connectionRO()->PQexec( sql ) ); @@ -2340,14 +2333,11 @@ QgsRasterBandStats QgsPostgresRasterProvider::bandStatistics( int bandNo, int st QStringLiteral( " AND %1" ).arg( subsetString() ) ); } - const QString sql { QStringLiteral( "SELECT (ST_SummaryStatsAgg( %1, %2, TRUE, %3 )).* " - "FROM %4 %5" ) - .arg( quotedIdentifier( mRasterColumn ) ) - .arg( bandNo ) - .arg( std::max( 0, std::min( 1, statsRatio ) ) ) - .arg( tableToQuery ) - .arg( where ) - }; + const QString sql = QStringLiteral( "SELECT (ST_SummaryStatsAgg( %1, %2, TRUE, %3 )).* " + "FROM %4 %5" ).arg( quotedIdentifier( mRasterColumn ) ) + .arg( bandNo ) + .arg( std::max( 0, std::min( 1, statsRatio ) ) ) + .arg( tableToQuery, where ); QgsPostgresResult result( connectionRO()->PQexec( sql ) ); From 1e2984596bcf26422b34d74e5d436917fddfd365 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 11:05:40 +1000 Subject: [PATCH 146/377] Indentation --- .../landingpage/qgslandingpageutils.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/server/services/landingpage/qgslandingpageutils.cpp b/src/server/services/landingpage/qgslandingpageutils.cpp index 99561ea432a9..6a7ad5f3467d 100644 --- a/src/server/services/landingpage/qgslandingpageutils.cpp +++ b/src/server/services/landingpage/qgslandingpageutils.cpp @@ -305,8 +305,8 @@ json QgsLandingPageUtils::projectInfo( const QString &projectUri, const QgsServe info["description"] = description.toStdString(); // CRS const QStringList wmsOutputCrsList { QgsServerProjectUtils::wmsOutputCrsList( *p ) }; - const QString crs { wmsOutputCrsList.contains( QStringLiteral( "EPSG:4326" ) ) || wmsOutputCrsList.isEmpty() ? - QStringLiteral( "EPSG:4326" ) : wmsOutputCrsList.first() }; + const QString crs = wmsOutputCrsList.contains( QStringLiteral( "EPSG:4326" ) ) || wmsOutputCrsList.isEmpty() ? + QStringLiteral( "EPSG:4326" ) : wmsOutputCrsList.first(); info["crs"] = crs.toStdString(); // Typenames for WMS const bool useIds { QgsServerProjectUtils::wmsUseLayerIds( *p ) }; @@ -473,14 +473,14 @@ json QgsLandingPageUtils::projectInfo( const QString &projectUri, const QgsServe continue; } const QgsFieldConstraints::Constraints constraints { field.constraints().constraints() }; - const bool notNull { constraints &QgsFieldConstraints::Constraint::ConstraintNotNull && - field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintNotNull ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; - const bool unique { constraints &QgsFieldConstraints::Constraint::ConstraintUnique && - field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintUnique ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; - const bool hasExpression { constraints &QgsFieldConstraints::Constraint::ConstraintExpression && - field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintExpression ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard }; - const QString &defaultValue { vl->dataProvider()->defaultValueClause( fieldIdx ) }; - const bool isReadOnly( notNull && unique && ! defaultValue.isEmpty() ); + const bool notNull = constraints & QgsFieldConstraints::Constraint::ConstraintNotNull && + field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintNotNull ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard; + const bool unique = constraints & QgsFieldConstraints::Constraint::ConstraintUnique && + field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintUnique ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard; + const bool hasExpression = constraints & QgsFieldConstraints::Constraint::ConstraintExpression && + field.constraints().constraintStrength( QgsFieldConstraints::Constraint::ConstraintExpression ) == QgsFieldConstraints::ConstraintStrength::ConstraintStrengthHard; + const QString defaultValue = vl->dataProvider()->defaultValueClause( fieldIdx ); + const bool isReadOnly = notNull && unique && ! defaultValue.isEmpty(); fieldsData[ field.name().toStdString() ] = { { "type", field.typeName().toStdString() }, From c4cd940cebbf501c0d9051d8a377b1987017b007 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 11:10:50 +1000 Subject: [PATCH 147/377] More indentation --- .../postgres/raster/qgspostgresrasterprovider.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/providers/postgres/raster/qgspostgresrasterprovider.cpp b/src/providers/postgres/raster/qgspostgresrasterprovider.cpp index 40941728476f..be7bc970c3e2 100644 --- a/src/providers/postgres/raster/qgspostgresrasterprovider.cpp +++ b/src/providers/postgres/raster/qgspostgresrasterprovider.cpp @@ -1098,11 +1098,11 @@ bool QgsPostgresRasterProvider::init() if ( hexAscii.isEmpty() || ! p.fromWkb( ptr ) ) { // Try to determine extent from raster - const QString extentSql { QStringLiteral( "SELECT ST_Envelope( %1 ) " - "FROM %2 WHERE %3" ) - .arg( quotedIdentifier( mRasterColumn ) ) - .arg( mQuery ) - .arg( subsetString().isEmpty() ? "'t'" : subsetString() ) }; + const QString extentSql = QStringLiteral( "SELECT ST_Envelope( %1 ) " + "FROM %2 WHERE %3" ) + .arg( quotedIdentifier( mRasterColumn ), + mQuery, + subsetString().isEmpty() ? "'t'" : subsetString() ); QgsPostgresResult extentResult( connectionRO()->PQexec( extentSql ) ); const QByteArray extentHexAscii { extentResult.PQgetvalue( 0, 0 ).toLatin1() }; From b308e592456a489158c54f8b3225bd41e807682a Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 11:16:59 +1000 Subject: [PATCH 148/377] More indentation --- .../raster/qgspostgresrasterprovider.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/providers/postgres/raster/qgspostgresrasterprovider.cpp b/src/providers/postgres/raster/qgspostgresrasterprovider.cpp index be7bc970c3e2..89d4044af3b6 100644 --- a/src/providers/postgres/raster/qgspostgresrasterprovider.cpp +++ b/src/providers/postgres/raster/qgspostgresrasterprovider.cpp @@ -1824,16 +1824,15 @@ bool QgsPostgresRasterProvider::loadFields() && defValMap[tableoid][attnum].isEmpty() ) { const QString seqName { mTableName + '_' + fieldName + QStringLiteral( "_seq" ) }; - const QString seqSql { QStringLiteral( "SELECT c.oid " - " FROM pg_class c " - " LEFT JOIN pg_namespace n " - " ON ( n.oid = c.relnamespace ) " - " WHERE c.relkind = 'S' " - " AND c.relname = %1 " - " AND n.nspname = %2" ) - .arg( quotedValue( seqName ) ) - .arg( quotedValue( mSchemaName ) ) - }; + const QString seqSql = QStringLiteral( "SELECT c.oid " + " FROM pg_class c " + " LEFT JOIN pg_namespace n " + " ON ( n.oid = c.relnamespace ) " + " WHERE c.relkind = 'S' " + " AND c.relname = %1 " + " AND n.nspname = %2" ) + .arg( quotedValue( seqName ), + quotedValue( mSchemaName ) ); QgsPostgresResult seqResult( connectionRO()->PQexec( seqSql ) ); if ( seqResult.PQntuples() == 1 ) { From 58f7f5102ba6c557a8a04a49b7b42f0799e59086 Mon Sep 17 00:00:00 2001 From: nirvn Date: Sat, 20 Mar 2021 11:18:44 +0700 Subject: [PATCH 149/377] Fix building QGIS when WITH_GUI is false --- src/providers/spatialite/qgsspatialitedataitems.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/providers/spatialite/qgsspatialitedataitems.cpp b/src/providers/spatialite/qgsspatialitedataitems.cpp index 58a647d2b53e..0c1d7dafc903 100644 --- a/src/providers/spatialite/qgsspatialitedataitems.cpp +++ b/src/providers/spatialite/qgsspatialitedataitems.cpp @@ -26,6 +26,9 @@ #include "qgsvectorlayerexporter.h" #include "qgsvectorlayer.h" +#include +#include + bool SpatiaLiteUtils::deleteLayer( const QString &dbPath, const QString &tableName, QString &errCause ) { From 514a6cd60e3cc7502cdd7180d796aa0cbc37b2e0 Mon Sep 17 00:00:00 2001 From: nirvn Date: Sat, 20 Mar 2021 11:21:02 +0700 Subject: [PATCH 150/377] Fix building QGIS when WITH_GEOREFERENCER is false --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 93d47918d96b..cd3fd9da2eff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -678,7 +678,7 @@ add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050800) # For fast string concatenation add_definitions(-DQT_USE_QSTRINGBUILDER) -if (WITH_GEOREFERENCER) +if (WITH_GEOREFERENCER OR WITH_ANALYSIS) find_package(GSL REQUIRED) set(HAVE_GEOREFERENCER TRUE) endif() From 8b7cc02ccba310013f94c5859e55a399706259f8 Mon Sep 17 00:00:00 2001 From: nirvn Date: Sat, 20 Mar 2021 12:06:42 +0700 Subject: [PATCH 151/377] Switch WITH_GUI and WITH_GEOREFERENCER to false on the OGC CI --- .ci/ogc/build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.ci/ogc/build.sh b/.ci/ogc/build.sh index a0fc02abb1ac..429c7db8a857 100755 --- a/.ci/ogc/build.sh +++ b/.ci/ogc/build.sh @@ -18,7 +18,10 @@ cmake -GNinja \ -DWITH_QWTPOLAR=OFF \ -DWITH_APIDOC=OFF \ -DWITH_ASTYLE=OFF \ + -DWITH_GEOREFERENCER=OFF \ + -DWITH_ANALYSIS=ON \ -DWITH_DESKTOP=OFF \ + -DWITH_GUI=OFF \ -DWITH_BINDINGS=ON \ -DWITH_SERVER=ON \ -DWITH_SERVER_PLUGINS=ON \ From ea78df3cfd65a708a68d540630457436dd1a18b9 Mon Sep 17 00:00:00 2001 From: uclaros Date: Sat, 20 Mar 2021 23:29:18 +0200 Subject: [PATCH 152/377] Update tooltips for scale and rotate features tools --- src/ui/qgisapp.ui | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui index 2442d904f920..0b02af7098f4 100644 --- a/src/ui/qgisapp.ui +++ b/src/ui/qgisapp.ui @@ -2531,7 +2531,8 @@ Acts on the currently active layer only. Scale Feature(s) - Scale Feature(s) + Scale Feature(s) +Ctrl+click to set the base point. @@ -2546,7 +2547,9 @@ Acts on the currently active layer only. Rotate Feature(s) - Rotate Feature(s) + Rotate Feature(s) +Ctrl+click to set the center of rotation. +Shift+click to snap rotation to 45 degree steps. From ecabbd3bc57f172760877a65e64d1e5da911de30 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 21 Mar 2021 10:58:38 +1000 Subject: [PATCH 153/377] Definitely no more Q_FOREACH --- src/3d/chunks/qgschunkboundsentity_p.cpp | 2 +- src/3d/chunks/qgschunkedentity_p.cpp | 4 +- src/3d/qgs3dmapscene.cpp | 10 +++-- src/3d/qgs3dmapsettings.cpp | 16 ++++---- src/3d/terrain/qgsterrainentity_p.cpp | 7 ++-- .../terrain/qgsterraintexturegenerator_p.cpp | 2 +- src/core/qgstracer.cpp | 3 -- src/core/symbology/qgscptcityarchive.cpp | 6 --- src/crashhandler/qgscrashreport.cpp | 6 +-- src/gui/ogr/qgsvectorlayersaveasdialog.cpp | 1 - src/gui/symbology/qgssymbolslistwidget.cpp | 7 ---- .../qgsgeometrycheckerresulttab.cpp | 2 +- src/plugins/grass/qgsgrasseditrenderer.cpp | 4 +- src/plugins/grass/qgsgrassmodule.cpp | 2 +- src/plugins/grass/qgsgrassmoduleinput.cpp | 32 ++++++++-------- src/plugins/grass/qgsgrassmoduleoptions.cpp | 14 +++---- src/plugins/grass/qgsgrassmoduleparam.cpp | 18 ++++----- src/plugins/grass/qgsgrassplugin.cpp | 4 +- src/plugins/grass/qgsgrasstools.cpp | 2 +- .../offline_editing_plugin_gui.cpp | 10 +++-- src/providers/db2/qgsdb2sourceselect.cpp | 19 +++++----- src/providers/grass/qgsgrass.cpp | 2 +- src/providers/grass/qgsgrassimport.cpp | 4 +- src/providers/mssql/qgsmssqlsourceselect.cpp | 19 +++++----- src/providers/oracle/qgsoracledataitems.cpp | 3 +- .../oracle/qgsoraclefeatureiterator.cpp | 4 +- .../oracle/qgsoraclesourceselect.cpp | 19 +++++----- src/providers/oracle/qgsoracletablecache.cpp | 8 ++-- src/providers/ows/qgsowsdataitems.cpp | 7 ++-- .../postgres/qgspostgresdataitems.cpp | 3 +- .../postgres/qgspostgresfeatureiterator.cpp | 4 +- .../spatialite/qgsspatialitedataitems.cpp | 3 +- .../spatialite/qgsspatialitesourceselect.cpp | 3 +- .../virtual/qgsvirtuallayersqlitemodule.cpp | 5 ++- src/providers/wcs/qgswcscapabilities.cpp | 12 ++++-- src/providers/wcs/qgswcsdataitems.cpp | 10 +++-- src/providers/wfs/qgswfscapabilities.cpp | 4 +- src/providers/wfs/qgswfsdataitems.cpp | 3 +- src/providers/wfs/qgswfsfeatureiterator.cpp | 2 +- src/providers/wfs/qgswfssourceselect.cpp | 2 +- .../wfs/qgswfssubsetstringeditor.cpp | 10 ++--- src/python/qgspythonutilsimpl.cpp | 16 ++++++-- tests/bench/main.cpp | 6 +-- tests/code_layout/test_banned_keywords.sh | 3 ++ tests/src/analysis/testqgsprocessing.cpp | 29 +++++++------- tests/src/app/testqgisappclipboard.cpp | 2 +- tests/src/core/testqgsauthmanager.cpp | 10 ++--- tests/src/core/testqgsdataitem.cpp | 2 +- tests/src/core/testqgsexpression.cpp | 2 +- tests/src/core/testqgsfeature.cpp | 6 +-- tests/src/core/testqgsfields.cpp | 4 +- tests/src/core/testqgsgeometry.cpp | 2 +- tests/src/core/testqgslayertree.cpp | 10 ++--- tests/src/core/testqgslegendrenderer.cpp | 4 +- tests/src/core/testqgsrasterfilewriter.cpp | 2 +- tests/src/core/testqgsrasterlayer.cpp | 2 +- tests/src/core/testqgsrastersublayer.cpp | 2 +- tests/src/core/testqgsrulebasedrenderer.cpp | 4 +- tests/src/core/testqgssnappingutils.cpp | 4 +- tests/src/core/testqgsspatialindex.cpp | 4 +- tests/src/core/testqgsstyle.cpp | 4 +- tests/src/core/testqgstracer.cpp | 6 +-- tests/src/core/testqgsvectorlayercache.cpp | 2 +- .../src/core/testqgsvectorlayerjoinbuffer.cpp | 8 ++-- tests/src/core/testziplayer.cpp | 30 +++++++-------- tests/src/gui/testprocessinggui.cpp | 2 +- tests/src/gui/testprojectionissues.cpp | 2 +- tests/src/gui/testqgsmapcanvas.cpp | 4 +- .../gui/testqgsrelationreferencewidget.cpp | 6 +-- tests/src/providers/testqgswcsprovider.cpp | 4 +- .../src/providers/testqgswcspublicservers.cpp | 38 +++++++++---------- 71 files changed, 268 insertions(+), 250 deletions(-) diff --git a/src/3d/chunks/qgschunkboundsentity_p.cpp b/src/3d/chunks/qgschunkboundsentity_p.cpp index 1c9d3436adf3..16ffbf6d495c 100644 --- a/src/3d/chunks/qgschunkboundsentity_p.cpp +++ b/src/3d/chunks/qgschunkboundsentity_p.cpp @@ -73,7 +73,7 @@ AABBMesh::AABBMesh( Qt3DCore::QNode *parent ) void AABBMesh::setBoxes( const QList &bboxes ) { QList vertices; - Q_FOREACH ( const QgsAABB &bbox, bboxes ) + for ( const QgsAABB &bbox : bboxes ) vertices << bbox.verticesForLines(); mLineMeshGeo->setVertices( vertices ); setVertexCount( mLineMeshGeo->vertexCount() ); diff --git a/src/3d/chunks/qgschunkedentity_p.cpp b/src/3d/chunks/qgschunkedentity_p.cpp index 8481ff090846..3a7557bec799 100644 --- a/src/3d/chunks/qgschunkedentity_p.cpp +++ b/src/3d/chunks/qgschunkedentity_p.cpp @@ -177,7 +177,7 @@ void QgsChunkedEntity::update( const SceneState &state ) if ( mBboxesEntity ) { QList bboxes; - Q_FOREACH ( QgsChunkNode *n, mActiveNodes ) + for ( QgsChunkNode *n : std::as_const( mActiveNodes ) ) bboxes << n->bbox(); mBboxesEntity->setBoxes( bboxes ); } @@ -217,7 +217,7 @@ void QgsChunkedEntity::setShowBoundingBoxes( bool enabled ) void QgsChunkedEntity::updateNodes( const QList &nodes, QgsChunkQueueJobFactory *updateJobFactory ) { - Q_FOREACH ( QgsChunkNode *node, nodes ) + for ( QgsChunkNode *node : nodes ) { if ( node->state() == QgsChunkNode::QueuedForUpdate ) { diff --git a/src/3d/qgs3dmapscene.cpp b/src/3d/qgs3dmapscene.cpp index d177d11b9b0b..19af89353938 100644 --- a/src/3d/qgs3dmapscene.cpp +++ b/src/3d/qgs3dmapscene.cpp @@ -561,7 +561,8 @@ void Qgs3DMapScene::createTerrainDeferred() onCameraChanged(); // force update of the new terrain // make sure that renderers for layers are re-created as well - Q_FOREACH ( QgsMapLayer *layer, mMap.layers() ) + const QList layers = mMap.layers(); + for ( QgsMapLayer *layer : layers ) { // remove old entity - if any removeLayerEntity( layer ); @@ -704,7 +705,8 @@ void Qgs3DMapScene::onLayersChanged() { QSet layersBefore = qgis::listToSet( mLayerEntities.keys() ); QList layersAdded; - Q_FOREACH ( QgsMapLayer *layer, mMap.layers() ) + const QList layers = mMap.layers(); + for ( QgsMapLayer *layer : layers ) { if ( !layersBefore.contains( layer ) ) { @@ -717,12 +719,12 @@ void Qgs3DMapScene::onLayersChanged() } // what is left in layersBefore are layers that have been removed - Q_FOREACH ( QgsMapLayer *layer, layersBefore ) + for ( QgsMapLayer *layer : std::as_const( layersBefore ) ) { removeLayerEntity( layer ); } - Q_FOREACH ( QgsMapLayer *layer, layersAdded ) + for ( QgsMapLayer *layer : std::as_const( layersAdded ) ) { addLayerEntity( layer ); } diff --git a/src/3d/qgs3dmapsettings.cpp b/src/3d/qgs3dmapsettings.cpp index 09c92e989270..e4373f413f79 100644 --- a/src/3d/qgs3dmapsettings.cpp +++ b/src/3d/qgs3dmapsettings.cpp @@ -78,7 +78,7 @@ Qgs3DMapSettings::Qgs3DMapSettings( const Qgs3DMapSettings &other ) , mDebugDepthMapCorner( other.mDebugDepthMapCorner ) , mDebugDepthMapSize( other.mDebugDepthMapSize ) { - Q_FOREACH ( QgsAbstract3DRenderer *renderer, other.mRenderers ) + for ( QgsAbstract3DRenderer *renderer : std::as_const( other.mRenderers ) ) { mRenderers << renderer->clone(); } @@ -353,7 +353,7 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon elem.appendChild( elemDirectionalLights ); QDomElement elemMapLayers = doc.createElement( QStringLiteral( "layers" ) ); - Q_FOREACH ( const QgsMapLayerRef &layerRef, mLayers ) + for ( const QgsMapLayerRef &layerRef : mLayers ) { QDomElement elemMapLayer = doc.createElement( QStringLiteral( "layer" ) ); elemMapLayer.setAttribute( QStringLiteral( "id" ), layerRef.layerId ); @@ -362,7 +362,7 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon elemTerrain.appendChild( elemMapLayers ); QDomElement elemTerrainMapLayers = doc.createElement( QStringLiteral( "terrainLayers" ) ); - Q_FOREACH ( const QgsMapLayerRef &layerRef, mTerrainLayers ) + for ( const QgsMapLayerRef &layerRef : mTerrainLayers ) { QDomElement elemMapLayer = doc.createElement( QStringLiteral( "layer" ) ); elemMapLayer.setAttribute( QStringLiteral( "id" ), layerRef.layerId ); @@ -377,7 +377,7 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon elem.appendChild( elemTerrain ); QDomElement elemRenderers = doc.createElement( QStringLiteral( "renderers" ) ); - Q_FOREACH ( const QgsAbstract3DRenderer *renderer, mRenderers ) + for ( const QgsAbstract3DRenderer *renderer : mRenderers ) { QDomElement elemRenderer = doc.createElement( QStringLiteral( "renderer" ) ); elemRenderer.setAttribute( QStringLiteral( "type" ), renderer->type() ); @@ -519,7 +519,7 @@ void Qgs3DMapSettings::setLayers( const QList &layers ) { QList lst; lst.reserve( layers.count() ); - Q_FOREACH ( QgsMapLayer *layer, layers ) + for ( QgsMapLayer *layer : layers ) { lst.append( layer ); } @@ -535,7 +535,7 @@ QList Qgs3DMapSettings::layers() const { QList lst; lst.reserve( mLayers.count() ); - Q_FOREACH ( const QgsMapLayerRef &layerRef, mLayers ) + for ( const QgsMapLayerRef &layerRef : mLayers ) { if ( layerRef.layer ) lst.append( layerRef.layer ); @@ -547,7 +547,7 @@ void Qgs3DMapSettings::setTerrainLayers( const QList &layers ) { QList lst; lst.reserve( layers.count() ); - Q_FOREACH ( QgsMapLayer *layer, layers ) + for ( QgsMapLayer *layer : layers ) { lst.append( layer ); } @@ -563,7 +563,7 @@ QList Qgs3DMapSettings::terrainLayers() const { QList lst; lst.reserve( mTerrainLayers.count() ); - Q_FOREACH ( const QgsMapLayerRef &layerRef, mTerrainLayers ) + for ( const QgsMapLayerRef &layerRef : mTerrainLayers ) { if ( layerRef.layer ) lst.append( layerRef.layer ); diff --git a/src/3d/terrain/qgsterrainentity_p.cpp b/src/3d/terrain/qgsterrainentity_p.cpp index 09b1813aab9c..5f9eb954b3ff 100644 --- a/src/3d/terrain/qgsterrainentity_p.cpp +++ b/src/3d/terrain/qgsterrainentity_p.cpp @@ -152,7 +152,8 @@ void QgsTerrainEntity::invalidateMapImages() // handle inactive nodes afterwards QList inactiveNodes; - Q_FOREACH ( QgsChunkNode *node, mRootNode->descendants() ) + const QList descendants = mRootNode->descendants(); + for ( QgsChunkNode *node : descendants ) { if ( !node->entity() ) continue; @@ -174,14 +175,14 @@ void QgsTerrainEntity::onLayersChanged() void QgsTerrainEntity::connectToLayersRepaintRequest() { - Q_FOREACH ( QgsMapLayer *layer, mLayers ) + for ( QgsMapLayer *layer : std::as_const( mLayers ) ) { disconnect( layer, &QgsMapLayer::repaintRequested, this, &QgsTerrainEntity::invalidateMapImages ); } mLayers = mMap.terrainLayers(); - Q_FOREACH ( QgsMapLayer *layer, mLayers ) + for ( QgsMapLayer *layer : std::as_const( mLayers ) ) { connect( layer, &QgsMapLayer::repaintRequested, this, &QgsTerrainEntity::invalidateMapImages ); } diff --git a/src/3d/terrain/qgsterraintexturegenerator_p.cpp b/src/3d/terrain/qgsterraintexturegenerator_p.cpp index 290c8af5d82c..7669de8491a8 100644 --- a/src/3d/terrain/qgsterraintexturegenerator_p.cpp +++ b/src/3d/terrain/qgsterraintexturegenerator_p.cpp @@ -59,7 +59,7 @@ int QgsTerrainTextureGenerator::render( const QgsRectangle &extent, QgsChunkNode void QgsTerrainTextureGenerator::cancelJob( int jobId ) { - Q_FOREACH ( const JobData &jd, mJobs ) + for ( const JobData &jd : std::as_const( mJobs ) ) { if ( jd.jobId == jobId ) { diff --git a/src/core/qgstracer.cpp b/src/core/qgstracer.cpp index 4b2ad322d8d0..19ea5f8bf87b 100644 --- a/src/core/qgstracer.cpp +++ b/src/core/qgstracer.cpp @@ -253,9 +253,6 @@ QVector shortestPath( const QgsTracerGraph &g, int v1, int v2 ) } std::reverse( path.begin(), path.end() ); - //Q_FOREACH (int x, path) - // qDebug("e: %d", x); - std::reverse( points.begin(), points.end() ); return points; } diff --git a/src/core/symbology/qgscptcityarchive.cpp b/src/core/symbology/qgscptcityarchive.cpp index 5b20320163d4..22bbba709f45 100644 --- a/src/core/symbology/qgscptcityarchive.cpp +++ b/src/core/symbology/qgscptcityarchive.cpp @@ -1338,12 +1338,6 @@ void QgsCptCityBrowserModel::addRootItems() void QgsCptCityBrowserModel::removeRootItems() { - // don't remove root items, they belong to the QgsCptCityArchive - // Q_FOREACH ( QgsCptCityDataItem* item, mRootItems ) - // { - // delete item; - // } - mRootItems.clear(); } diff --git a/src/crashhandler/qgscrashreport.cpp b/src/crashhandler/qgscrashreport.cpp index bffa33b21d68..94ac70cb12f6 100644 --- a/src/crashhandler/qgscrashreport.cpp +++ b/src/crashhandler/qgscrashreport.cpp @@ -55,7 +55,7 @@ const QString QgsCrashReport::toHtml() const else { reportData.append( QStringLiteral( "
    " ) );
    -      Q_FOREACH ( const QgsStackTrace::StackLine &line, mStackTrace->lines )
    +      for ( const QgsStackTrace::StackLine &line : mStackTrace->lines )
           {
             QFileInfo fileInfo( line.fileName );
             QString filename( fileInfo.fileName() );
    @@ -98,7 +98,7 @@ const QString QgsCrashReport::toHtml() const
       }
     
       QString report;
    -  Q_FOREACH ( const QString &line, reportData )
    +  for ( const QString &line : std::as_const( reportData ) )
       {
         report += line + "
    "; } @@ -115,7 +115,7 @@ const QString QgsCrashReport::crashID() const QString data = QString(); // Hashes the full stack. - Q_FOREACH ( const QgsStackTrace::StackLine &line, mStackTrace->lines ) + for ( const QgsStackTrace::StackLine &line : mStackTrace->lines ) { #if 0 QFileInfo fileInfo( line.fileName ); diff --git a/src/gui/ogr/qgsvectorlayersaveasdialog.cpp b/src/gui/ogr/qgsvectorlayersaveasdialog.cpp index b0f54f429cf9..ab2545a524de 100644 --- a/src/gui/ogr/qgsvectorlayersaveasdialog.cpp +++ b/src/gui/ogr/qgsvectorlayersaveasdialog.cpp @@ -582,7 +582,6 @@ void QgsVectorLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( int idx ) delete item; } - // workaround so the Q_FOREACH macro does not get confused by the ',' typedef QPair LabelControlPair; if ( QgsVectorFileWriter::driverMetadata( format(), driverMetaData ) ) diff --git a/src/gui/symbology/qgssymbolslistwidget.cpp b/src/gui/symbology/qgssymbolslistwidget.cpp index 3d0f720d3eb8..10625408b968 100644 --- a/src/gui/symbology/qgssymbolslistwidget.cpp +++ b/src/gui/symbology/qgssymbolslistwidget.cpp @@ -240,13 +240,6 @@ void QgsSymbolsListWidget::setContext( const QgsSymbolWidgetContext &context ) { unitWidget->setMapCanvas( mContext.mapCanvas() ); } -#if 0 - Q_FOREACH ( QgsPropertyOverrideButton *ddButton, findChildren() ) - { - if ( ddButton->assistant() ) - ddButton->assistant()->setMapCanvas( mContext.mapCanvas() ); - } -#endif } QgsSymbolWidgetContext QgsSymbolsListWidget::context() const diff --git a/src/plugins/geometry_checker/qgsgeometrycheckerresulttab.cpp b/src/plugins/geometry_checker/qgsgeometrycheckerresulttab.cpp index ec5274de832e..d3e848e7e63c 100644 --- a/src/plugins/geometry_checker/qgsgeometrycheckerresulttab.cpp +++ b/src/plugins/geometry_checker/qgsgeometrycheckerresulttab.cpp @@ -382,7 +382,7 @@ void QgsGeometryCheckerResultTab::highlightErrors( bool current ) { double cx = 0., cy = 0.; QgsRectangle pointExtent( errorPositions.first(), errorPositions.first() ); - Q_FOREACH ( const QgsPointXY &p, errorPositions ) + for ( const QgsPointXY &p : std::as_const( errorPositions ) ) { cx += p.x(); cy += p.y(); diff --git a/src/plugins/grass/qgsgrasseditrenderer.cpp b/src/plugins/grass/qgsgrasseditrenderer.cpp index acca94cdd16e..55c93cd5c309 100644 --- a/src/plugins/grass/qgsgrasseditrenderer.cpp +++ b/src/plugins/grass/qgsgrasseditrenderer.cpp @@ -64,7 +64,7 @@ QgsGrassEditRenderer::QgsGrassEditRenderer() firstVertexMarkerLine->setPlacement( QgsTemplatedLineSymbolLayerBase::FirstVertex ); QgsMarkerLineSymbolLayer *lastVertexMarkerLine = static_cast( firstVertexMarkerLine->clone() ); lastVertexMarkerLine->setPlacement( QgsTemplatedLineSymbolLayerBase::LastVertex ); - Q_FOREACH ( int value, colors.keys() ) + for ( int value : colors.keys() ) { QgsSymbol *symbol = QgsSymbol::defaultSymbol( QgsWkbTypes::LineGeometry ); symbol->setColor( colors.value( value ) ); @@ -91,7 +91,7 @@ QgsGrassEditRenderer::QgsGrassEditRenderer() categoryList.clear(); - Q_FOREACH ( int value, colors.keys() ) + for ( int value : colors.keys() ) { QgsSymbol *symbol = QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ); symbol->setColor( colors.value( value ) ); diff --git a/src/plugins/grass/qgsgrassmodule.cpp b/src/plugins/grass/qgsgrassmodule.cpp index 99b72f70e062..7533399dd3b3 100644 --- a/src/plugins/grass/qgsgrassmodule.cpp +++ b/src/plugins/grass/qgsgrassmodule.cpp @@ -620,7 +620,7 @@ void QgsGrassModule::run() // Print some important variables variables << QStringLiteral( "QGIS_PREFIX_PATH" ) << QStringLiteral( "QGIS_GRASS_CRS" ) << QStringLiteral( "GRASS_REGION" ); - Q_FOREACH ( const QString &v, variables ) + for ( const QString &v : variables ) { mOutputTextBrowser->append( v + "=" + environment.value( v ) + "
    " ); } diff --git a/src/plugins/grass/qgsgrassmoduleinput.cpp b/src/plugins/grass/qgsgrassmoduleinput.cpp index 996e9c477cdb..c482a0664494 100644 --- a/src/plugins/grass/qgsgrassmoduleinput.cpp +++ b/src/plugins/grass/qgsgrassmoduleinput.cpp @@ -92,7 +92,7 @@ void QgsGrassModuleInputModel::onDirectoryChanged( const QString &path ) } } - Q_FOREACH ( const QString &dirName, dirNames ) + for ( const QString &dirName : dirNames ) { // Add to watcher in any case, either for WIND, cellhd or vector QString dirPath = locationPath + "/" + dirName; @@ -108,7 +108,7 @@ void QgsGrassModuleInputModel::onDirectoryChanged( const QString &path ) QgsDebugMsg( "mapset = " + path ); QDir dir( path ); mapset = dir.dirName(); - Q_FOREACH ( const QString &watchedDir, watchedDirs() ) + for ( const QString &watchedDir : watchedDirs() ) { watch( path + "/" + watchedDir ); } @@ -205,12 +205,12 @@ void QgsGrassModuleInputModel::refreshMapset( QStandardItem *mapsetItem, const Q typesCopy << QgsGrassObject::Raster << QgsGrassObject::Vector; typesCopy << QgsGrassObject::Strds << QgsGrassObject::Stvds << QgsGrassObject::Str3ds; } - Q_FOREACH ( QgsGrassObject::Type type, typesCopy ) + for ( QgsGrassObject::Type type : typesCopy ) { QgsGrassObject mapsetObject( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation(), mapset, QString(), QgsGrassObject::Mapset ); QStringList maps = QgsGrass::grassObjects( mapsetObject, type ); QStringList mapNames; - Q_FOREACH ( const QString &map, maps ) + for ( const QString &map : maps ) { if ( map.startsWith( QLatin1String( "qgis_import_tmp_" ) ) ) { @@ -278,7 +278,7 @@ void QgsGrassModuleInputModel::reload() mLocationPath = QgsGrass::getDefaultLocationPath(); QStringList mapsets = QgsGrass::mapsets( QgsGrass::getDefaultGisdbase(), QgsGrass::getDefaultLocation() ); - Q_FOREACH ( const QString &mapset, mapsets ) + for ( const QString &mapset : mapsets ) { addMapset( mapset ); } @@ -287,13 +287,13 @@ void QgsGrassModuleInputModel::reload() // Watching all dirs in location because a dir may become a mapset later, when WIND is created QStringList dirNames = locationDirNames(); - Q_FOREACH ( const QString &dirName, dirNames ) + for ( const QString &dirName : dirNames ) { QString dirPath = mLocationPath + "/" + dirName; // Watch the dir in any case, WIND maybe created later mWatcher->addPath( dirPath ); - Q_FOREACH ( const QString &watchedDir, watchedDirs() ) + for ( const QString &watchedDir : watchedDirs() ) { watch( dirPath + "/" + watchedDir ); } @@ -855,7 +855,7 @@ QgsGrassModuleInput::QgsGrassModuleInput( QgsGrassModule *module, { int mask = 0; - Q_FOREACH ( const QString &typeName, opt.split( ',' ) ) + for ( const QString &typeName : opt.split( ',' ) ) { mask |= QgsGrass::vectorType( typeName ); } @@ -972,7 +972,7 @@ QgsGrassModuleInput::QgsGrassModuleInput( QgsGrassModule *module, QList types; types << GV_POINT << GV_LINE << GV_BOUNDARY << GV_CENTROID << GV_AREA; - Q_FOREACH ( int type, types ) + for ( int type : types ) { if ( !( type & mGeometryTypeMask ) ) { @@ -1101,7 +1101,7 @@ QgsGrassVectorLayer *QgsGrassModuleInput::currentLayer() QStringList QgsGrassModuleInput::currentGeometryTypeNames() { QStringList typeNames; - Q_FOREACH ( int checkBoxType, mTypeCheckBoxes.keys() ) + for ( int checkBoxType : mTypeCheckBoxes.keys() ) { QCheckBox *checkBox = mTypeCheckBoxes.value( checkBoxType ); if ( checkBox->isChecked() ) @@ -1118,7 +1118,7 @@ QStringList QgsGrassModuleInput::currentLayerCodes() if ( auto *lCurrentLayer = currentLayer() ) { - Q_FOREACH ( QString type, currentGeometryTypeNames() ) + for ( QString type : currentGeometryTypeNames() ) { type.replace( QLatin1String( "area" ), QLatin1String( "polygon" ) ); list << QStringLiteral( "%1_%2" ).arg( lCurrentLayer->number() ).arg( type ); @@ -1158,7 +1158,7 @@ void QgsGrassModuleInput::onChanged( const QString &text ) else { // Find layers matching type mask - Q_FOREACH ( QgsGrassVectorLayer *layer, mVector->layers() ) + for ( QgsGrassVectorLayer *layer : mVector->layers() ) { QgsDebugMsg( QString( "layer->number() = %1 layer.type() = %2 mGeometryTypeMask = %3" ).arg( layer->number() ).arg( layer->type() ).arg( mGeometryTypeMask ) ); // TODO: does it make sense to add layer 0, i.e. no layer? @@ -1171,7 +1171,7 @@ void QgsGrassModuleInput::onChanged( const QString &text ) QgsDebugMsg( QString( "mLayers.size() = %1" ).arg( mLayers.size() ) ); // Combo is used to get layer even if just one - Q_FOREACH ( QgsGrassVectorLayer *layer, mLayers ) + for ( QgsGrassVectorLayer *layer : mLayers ) { mLayerComboBox->addItem( QString::number( layer->number() ), layer->number() ); } @@ -1197,7 +1197,7 @@ void QgsGrassModuleInput::onLayerChanged() { return; } - Q_FOREACH ( int checkBoxType, mTypeCheckBoxes.keys() ) + for ( int checkBoxType : mTypeCheckBoxes.keys() ) { QCheckBox *checkBox = mTypeCheckBoxes.value( checkBoxType ); checkBox->setChecked( false ); @@ -1209,7 +1209,7 @@ void QgsGrassModuleInput::onLayerChanged() { // number of types in the layer matching mGeometryTypeMask int typeCount = 0; - Q_FOREACH ( int type, layer->types() ) + for ( int type : layer->types() ) { if ( type & mGeometryTypeMask ) { @@ -1219,7 +1219,7 @@ void QgsGrassModuleInput::onLayerChanged() QgsDebugMsg( QString( "typeCount = %1" ).arg( typeCount ) ); int layerType = layer->type(); // may be multiple - Q_FOREACH ( int checkBoxType, mTypeCheckBoxes.keys() ) + for ( int checkBoxType : mTypeCheckBoxes.keys() ) { QCheckBox *checkBox = mTypeCheckBoxes.value( checkBoxType ); checkBox->hide(); diff --git a/src/plugins/grass/qgsgrassmoduleoptions.cpp b/src/plugins/grass/qgsgrassmoduleoptions.cpp index e375c00c3f9f..cf0dc25aa64f 100644 --- a/src/plugins/grass/qgsgrassmoduleoptions.cpp +++ b/src/plugins/grass/qgsgrassmoduleoptions.cpp @@ -328,7 +328,7 @@ QgsGrassModuleStandardOptions::QgsGrassModuleStandardOptions( // (guidependency missing in GRASS 6) // Add default inter param relations QListvectorInputs; - Q_FOREACH ( QgsGrassModuleParam *param, mParams ) + for ( QgsGrassModuleParam *param : mParams ) { QgsGrassModuleInput *vectorInput = dynamic_cast( param ); if ( vectorInput ) @@ -340,7 +340,7 @@ QgsGrassModuleStandardOptions::QgsGrassModuleStandardOptions( { QgsDebugMsg( "One input found, try to connect with column options" ); QgsGrassModuleInput *vectorInput = vectorInputs[0]; - Q_FOREACH ( QgsGrassModuleParam *param, mParams ) + for ( QgsGrassModuleParam *param : mParams ) { QgsGrassModuleField *moduleField = dynamic_cast( param ); if ( moduleField ) @@ -365,7 +365,7 @@ QgsGrassModuleStandardOptions::QgsGrassModuleStandardOptions( layout->addStretch(); } - Q_FOREACH ( QgsGrassModuleParam *item, mParams ) + for ( QgsGrassModuleParam *item : mParams ) { mErrors << item->errors(); } @@ -465,7 +465,7 @@ QStringList QgsGrassModuleStandardOptions::checkOutput() QList QgsGrassModuleStandardOptions::grassProviders() { QList providers; - Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->mapLayers().values() ) + for ( QgsMapLayer *layer : QgsProject::instance()->mapLayers().values() ) { if ( layer->type() == QgsMapLayerType::VectorLayer ) { @@ -486,7 +486,7 @@ QList QgsGrassModuleStandardOptions::grassProviders() QList QgsGrassModuleStandardOptions::grassRasterProviders() { QList providers; - Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->mapLayers().values() ) + for ( QgsMapLayer *layer : QgsProject::instance()->mapLayers().values() ) { if ( layer->type() == QgsMapLayerType::RasterLayer ) { @@ -528,7 +528,7 @@ void QgsGrassModuleStandardOptions::freezeOutput( bool freeze ) outputObject.setType( QgsGrassObject::Vector ); QgsDebugMsg( "outputObject = " + outputObject.toString() ); - Q_FOREACH ( QgsGrassProvider *provider, grassProviders() ) + for ( QgsGrassProvider *provider : grassProviders() ) { QgsGrassObject layerObject; layerObject.setFromUri( provider->dataSourceUri() ); @@ -556,7 +556,7 @@ void QgsGrassModuleStandardOptions::freezeOutput( bool freeze ) outputObject.setType( QgsGrassObject::Raster ); QgsDebugMsg( "outputObject = " + outputObject.toString() ); - Q_FOREACH ( QgsGrassRasterProvider *provider, grassRasterProviders() ) + for ( QgsGrassRasterProvider *provider : grassRasterProviders() ) { QgsGrassObject layerObject; layerObject.setFromUri( provider->dataSourceUri() ); diff --git a/src/plugins/grass/qgsgrassmoduleparam.cpp b/src/plugins/grass/qgsgrassmoduleparam.cpp index ccfe0565b508..697cbea76c81 100644 --- a/src/plugins/grass/qgsgrassmoduleparam.cpp +++ b/src/plugins/grass/qgsgrassmoduleparam.cpp @@ -864,7 +864,7 @@ void QgsGrassModuleGdalInput::updateQgisLayers() mLayerComboBox->addItem( tr( "Select a layer" ), QVariant() ); } - Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->mapLayers().values() ) + for ( QgsMapLayer *layer : QgsProject::instance()->mapLayers().values() ) { if ( !layer ) continue; @@ -1027,7 +1027,7 @@ QgsGrassModuleField::QgsGrassModuleField( QgsGrassModule *module, QString key, // Validator is disabled to also allow entering of expressions #if 0 QRegExp rx( "^[a-zA-Z_][a-zA-Z0-9_]*$" ); - Q_FOREACH ( QLineEdit *lineEdit, mLineEdits ) + for ( QLineEdit *lineEdit : mLineEdits ) { lineEdit->setValidator( new QRegExpValidator( rx, this ) ); } @@ -1103,7 +1103,7 @@ void QgsGrassModuleVectorField::removeRow() void QgsGrassModuleVectorField::updateFields() { - Q_FOREACH ( QComboBox *comboBox, mComboBoxList ) + for ( QComboBox *comboBox : mComboBoxList ) { QString current = comboBox->currentText(); comboBox->clear(); @@ -1114,7 +1114,7 @@ void QgsGrassModuleVectorField::updateFields() } int index = 0; - Q_FOREACH ( const QgsField &field, mLayerInput->currentFields() ) + for ( const QgsField &field : mLayerInput->currentFields() ) { if ( mType.contains( field.typeName() ) ) { @@ -1135,7 +1135,7 @@ QStringList QgsGrassModuleVectorField::options() QStringList list; QStringList valueList; - Q_FOREACH ( QComboBox *comboBox, mComboBoxList ) + for ( QComboBox *comboBox : mComboBoxList ) { if ( !comboBox->currentText().isEmpty() ) { @@ -1209,7 +1209,7 @@ void QgsGrassModuleSelection::onLayerChanged() QStringList layerIds; // add new layers matching selected input layer if not yet present - Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->mapLayers().values() ) + for ( QgsMapLayer *layer : QgsProject::instance()->mapLayers().values() ) { QgsVectorLayer *vectorLayer = qobject_cast( layer ); if ( vectorLayer && vectorLayer->providerType() == QLatin1String( "grass" ) ) @@ -1254,7 +1254,7 @@ void QgsGrassModuleSelection::onLayerChanged() if ( layerIds.size() == 0 ) // non of selected layer is in canvas { - Q_FOREACH ( QString layerCode, mLayerInput->currentLayerCodes() ) + for ( QString layerCode : mLayerInput->currentLayerCodes() ) { if ( mLayerInput->currentLayer() ) { @@ -1333,7 +1333,7 @@ void QgsGrassModuleSelection::onLayerSelectionChanged() } QList cats; - Q_FOREACH ( QgsFeatureId fid, vectorLayer->selectedFeatureIds() ) + for ( QgsFeatureId fid : vectorLayer->selectedFeatureIds() ) { cats << QgsGrassFeatureIterator::catFromFid( fid ); } @@ -1342,7 +1342,7 @@ void QgsGrassModuleSelection::onLayerSelectionChanged() // make ranges of cats int last = -1; int range = false; - Q_FOREACH ( int cat, cats ) + for ( int cat : cats ) { if ( cat == 0 ) { diff --git a/src/plugins/grass/qgsgrassplugin.cpp b/src/plugins/grass/qgsgrassplugin.cpp index 2d7b530150d7..04b2d58021a5 100644 --- a/src/plugins/grass/qgsgrassplugin.cpp +++ b/src/plugins/grass/qgsgrassplugin.cpp @@ -428,7 +428,7 @@ void QgsGrassPlugin::onFieldsChanged() QString uri = grassProvider->dataSourceUri(); uri.remove( QRegExp( "[^_]*$" ) ); QgsDebugMsg( "uri = " + uri ); - Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->mapLayers().values() ) + for ( QgsMapLayer *layer : QgsProject::instance()->mapLayers().values() ) { if ( !layer || layer->type() != QgsMapLayerType::VectorLayer ) { @@ -792,7 +792,7 @@ void QgsGrassPlugin::unload() disconnect( qGisInterface->layerTreeView(), &QgsLayerTreeView::currentLayerChanged, this, &QgsGrassPlugin::onCurrentLayerChanged ); - Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->mapLayers().values() ) + for ( QgsMapLayer *layer : QgsProject::instance()->mapLayers().values() ) { if ( !layer || layer->type() != QgsMapLayerType::VectorLayer ) { diff --git a/src/plugins/grass/qgsgrasstools.cpp b/src/plugins/grass/qgsgrasstools.cpp index 772fcf4ad093..f45f1504930b 100644 --- a/src/plugins/grass/qgsgrasstools.cpp +++ b/src/plugins/grass/qgsgrasstools.cpp @@ -638,7 +638,7 @@ int QgsGrassTools::debug( QStandardItem *item ) } QgsGrassModule *module = new QgsGrassModule( this, name, mIface, false ); QgsDebugMsg( QString( "module: %1 errors: %2" ).arg( name ).arg( module->errors().size() ) ); - Q_FOREACH ( QString error, module->errors() ) + for ( QString error : module->errors() ) { // each error may have multiple rows and may be html formatted (
    ) label += "\n ERROR:\t" + error.replace( QLatin1String( "
    " ), QLatin1String( "\n" ) ).replace( QLatin1String( "\n" ), QLatin1String( "\n\t" ) ); diff --git a/src/plugins/offline_editing/offline_editing_plugin_gui.cpp b/src/plugins/offline_editing/offline_editing_plugin_gui.cpp index 396711e98af2..dea6e8828331 100644 --- a/src/plugins/offline_editing/offline_editing_plugin_gui.cpp +++ b/src/plugins/offline_editing/offline_editing_plugin_gui.cpp @@ -223,7 +223,9 @@ void QgsOfflineEditingPluginGui::buttonBox_accepted() } mSelectedLayerIds.clear(); - Q_FOREACH ( QgsLayerTreeLayer *nodeLayer, mLayerTree->layerTreeModel()->rootGroup()->findLayers() ) + + const QList layers = mLayerTree->layerTreeModel()->rootGroup()->findLayers(); + for ( QgsLayerTreeLayer *nodeLayer : layers ) { if ( nodeLayer->isVisible() ) { @@ -252,13 +254,15 @@ void QgsOfflineEditingPluginGui::restoreState() void QgsOfflineEditingPluginGui::selectAll() { - Q_FOREACH ( QgsLayerTreeLayer *nodeLayer, mLayerTree->layerTreeModel()->rootGroup()->findLayers() ) + const QList layers = mLayerTree->layerTreeModel()->rootGroup()->findLayers(); + for ( QgsLayerTreeLayer *nodeLayer : layers ) nodeLayer->setItemVisibilityChecked( true ); } void QgsOfflineEditingPluginGui::deSelectAll() { - Q_FOREACH ( QgsLayerTreeLayer *nodeLayer, mLayerTree->layerTreeModel()->rootGroup()->findLayers() ) + const QList layers = mLayerTree->layerTreeModel()->rootGroup()->findLayers(); + for ( QgsLayerTreeLayer *nodeLayer : layers ) nodeLayer->setItemVisibilityChecked( false ); } diff --git a/src/providers/db2/qgsdb2sourceselect.cpp b/src/providers/db2/qgsdb2sourceselect.cpp index 92ed37d26b7b..113d699640de 100644 --- a/src/providers/db2/qgsdb2sourceselect.cpp +++ b/src/providers/db2/qgsdb2sourceselect.cpp @@ -55,15 +55,16 @@ QWidget *QgsDb2SourceSelectDelegate::createEditor( QWidget *parent, const QStyle if ( index.column() == QgsDb2TableModel::DbtmType && index.data( Qt::UserRole + 1 ).toBool() ) { QComboBox *cb = new QComboBox( parent ); - Q_FOREACH ( QgsWkbTypes::Type type, - QList() - << QgsWkbTypes::Point - << QgsWkbTypes::LineString - << QgsWkbTypes::Polygon - << QgsWkbTypes::MultiPoint - << QgsWkbTypes::MultiLineString - << QgsWkbTypes::MultiPolygon - << QgsWkbTypes::NoGeometry ) + for ( QgsWkbTypes::Type type : + { + QgsWkbTypes::Point, + QgsWkbTypes::LineString, + QgsWkbTypes::Polygon, + QgsWkbTypes::MultiPoint, + QgsWkbTypes::MultiLineString, + QgsWkbTypes::MultiPolygon, + QgsWkbTypes::NoGeometry + } ) { cb->addItem( QgsLayerItem::iconForWkbType( type ), QgsWkbTypes::translatedDisplayString( type ), type ); } diff --git a/src/providers/grass/qgsgrass.cpp b/src/providers/grass/qgsgrass.cpp index 1a3e90f76e98..616b8c55e2e1 100644 --- a/src/providers/grass/qgsgrass.cpp +++ b/src/providers/grass/qgsgrass.cpp @@ -1513,7 +1513,7 @@ QStringList QgsGrass::grassObjects( const QgsGrassObject &mapsetObject, QgsGrass try { QByteArray data = runModule( mapsetObject.gisdbase(), mapsetObject.location(), mapsetObject.mapset(), cmd, arguments, timeout, false ); - Q_FOREACH ( QString fullName, QString::fromLocal8Bit( data ).split( '\n' ) ) + for ( QString fullName : QString::fromLocal8Bit( data ).split( '\n' ) ) { fullName = fullName.trimmed(); if ( !fullName.isEmpty() ) diff --git a/src/providers/grass/qgsgrassimport.cpp b/src/providers/grass/qgsgrassimport.cpp index db2af8786ec6..e54c2e0a66b9 100644 --- a/src/providers/grass/qgsgrassimport.cpp +++ b/src/providers/grass/qgsgrassimport.cpp @@ -71,7 +71,7 @@ void QgsGrassImportProgress::onReadyReadStandardError() { // TODO: parse better progress output QString output = QString::fromLocal8Bit( mProcess->readAllStandardError() ); - Q_FOREACH ( const QString &line, output.split( "\n" ) ) + for ( const QString &line : output.split( "\n" ) ) { QgsDebugMsg( "line = '" + line + "'" ); QString text, html; @@ -517,7 +517,7 @@ QStringList QgsGrassRasterImport::names() const QStringList list; if ( mPipe && mPipe->provider() ) { - Q_FOREACH ( const QString &ext, extensions( mPipe->provider() ) ) + for ( const QString &ext : extensions( mPipe->provider() ) ) { list << mGrassObject.name() + ext; } diff --git a/src/providers/mssql/qgsmssqlsourceselect.cpp b/src/providers/mssql/qgsmssqlsourceselect.cpp index a51104088471..14e2ac07d915 100644 --- a/src/providers/mssql/qgsmssqlsourceselect.cpp +++ b/src/providers/mssql/qgsmssqlsourceselect.cpp @@ -56,15 +56,16 @@ QWidget *QgsMssqlSourceSelectDelegate::createEditor( QWidget *parent, const QSty if ( index.column() == QgsMssqlTableModel::DbtmType && index.data( Qt::UserRole + 1 ).toBool() ) { QComboBox *cb = new QComboBox( parent ); - Q_FOREACH ( QgsWkbTypes::Type type, - QList() - << QgsWkbTypes::Point - << QgsWkbTypes::LineString - << QgsWkbTypes::Polygon - << QgsWkbTypes::MultiPoint - << QgsWkbTypes::MultiLineString - << QgsWkbTypes::MultiPolygon - << QgsWkbTypes::NoGeometry ) + for ( QgsWkbTypes::Type type : + { + QgsWkbTypes::Point, + QgsWkbTypes::LineString, + QgsWkbTypes::Polygon, + QgsWkbTypes::MultiPoint, + QgsWkbTypes::MultiLineString, + QgsWkbTypes::MultiPolygon, + QgsWkbTypes::NoGeometry + } ) { cb->addItem( QgsLayerItem::iconForWkbType( type ), QgsWkbTypes::translatedDisplayString( type ), type ); } diff --git a/src/providers/oracle/qgsoracledataitems.cpp b/src/providers/oracle/qgsoracledataitems.cpp index 20898e0329a7..19dd5a8d8aa4 100644 --- a/src/providers/oracle/qgsoracledataitems.cpp +++ b/src/providers/oracle/qgsoracledataitems.cpp @@ -545,7 +545,8 @@ QgsOracleRootItem::QgsOracleRootItem( QgsDataItem *parent, const QString &name, QVector QgsOracleRootItem::createChildren() { QVector connections; - Q_FOREACH ( QString connName, QgsOracleConn::connectionList() ) + const QStringList list = QgsOracleConn::connectionList(); + for ( QString connName : list ) { connections << new QgsOracleConnectionItem( this, connName, mPath + '/' + connName ); } diff --git a/src/providers/oracle/qgsoraclefeatureiterator.cpp b/src/providers/oracle/qgsoraclefeatureiterator.cpp index 16ce715fd841..5980fed91f6e 100644 --- a/src/providers/oracle/qgsoraclefeatureiterator.cpp +++ b/src/providers/oracle/qgsoraclefeatureiterator.cpp @@ -356,7 +356,7 @@ bool QgsOracleFeatureIterator::fetchFeature( QgsFeature &feature ) QVariantList primaryKeyVals; if ( mSource->mPrimaryKeyType == PktFidMap ) { - Q_FOREACH ( int idx, mSource->mPrimaryKeyAttrs ) + for ( int idx : std::as_const( mSource->mPrimaryKeyAttrs ) ) { QgsField fld = mSource->mFields.at( idx ); @@ -478,7 +478,7 @@ bool QgsOracleFeatureIterator::openQuery( const QString &whereClause, const QVar break; case PktFidMap: - Q_FOREACH ( int idx, mSource->mPrimaryKeyAttrs ) + for ( int idx : std::as_const( mSource->mPrimaryKeyAttrs ) ) { query += delim + mConnection->fieldExpression( mSource->mFields.at( idx ) ); delim = ','; diff --git a/src/providers/oracle/qgsoraclesourceselect.cpp b/src/providers/oracle/qgsoraclesourceselect.cpp index c2173437acc6..9b5ee51f9390 100644 --- a/src/providers/oracle/qgsoraclesourceselect.cpp +++ b/src/providers/oracle/qgsoraclesourceselect.cpp @@ -57,15 +57,16 @@ QWidget *QgsOracleSourceSelectDelegate::createEditor( QWidget *parent, const QSt if ( index.column() == QgsOracleTableModel::DbtmType && index.data( Qt::UserRole + 1 ).toBool() ) { QComboBox *cb = new QComboBox( parent ); - Q_FOREACH ( QgsWkbTypes::Type type, - QList() - << QgsWkbTypes::Point - << QgsWkbTypes::LineString - << QgsWkbTypes::Polygon - << QgsWkbTypes::MultiPoint - << QgsWkbTypes::MultiLineString - << QgsWkbTypes::MultiPolygon - << QgsWkbTypes::NoGeometry ) + for ( QgsWkbTypes::Type type : + { + QgsWkbTypes::Poin, + QgsWkbTypes::LineString, + QgsWkbTypes::Polygon, + QgsWkbTypes::MultiPoint, + QgsWkbTypes::MultiLineString, + QgsWkbTypes::MultiPolygon, + QgsWkbTypes::NoGeometry + } ) { cb->addItem( QgsLayerItem::iconForWkbType( type ), QgsWkbTypes::translatedDisplayString( type ), type ); } diff --git a/src/providers/oracle/qgsoracletablecache.cpp b/src/providers/oracle/qgsoracletablecache.cpp index 5ee2a5576359..c8382d1e8926 100644 --- a/src/providers/oracle/qgsoracletablecache.cpp +++ b/src/providers/oracle/qgsoracletablecache.cpp @@ -168,12 +168,12 @@ bool QgsOracleTableCache::saveToCache( const QString &connName, CacheFlags flags sqlite3_bind_text( stmtInsert, 6, item.pkCols.join( "," ).toUtf8().constData(), -1, SQLITE_TRANSIENT ); QStringList geomTypes; - Q_FOREACH ( QgsWkbTypes::Type geomType, item.types ) + for ( QgsWkbTypes::Type geomType : std::as_const( item.types ) ) geomTypes.append( QString::number( static_cast( geomType ) ) ); sqlite3_bind_text( stmtInsert, 7, geomTypes.join( "," ).toUtf8().constData(), -1, SQLITE_TRANSIENT ); QStringList geomSrids; - Q_FOREACH ( int geomSrid, item.srids ) + for ( int geomSrid : std::as_const( item.srids ) ) geomSrids.append( QString::number( geomSrid ) ); sqlite3_bind_text( stmtInsert, 8, geomSrids.join( "," ).toUtf8().constData(), -1, SQLITE_TRANSIENT ); @@ -222,11 +222,11 @@ bool QgsOracleTableCache::loadFromCache( const QString &connName, CacheFlags fla layer.pkCols = pkCols.split( ",", QString::SkipEmptyParts ); QString geomTypes = QString::fromUtf8( ( const char * ) sqlite3_column_text( stmt, 6 ) ); - Q_FOREACH ( QString geomType, geomTypes.split( ",", QString::SkipEmptyParts ) ) + for ( QString geomType : geomTypes.split( ",", QString::SkipEmptyParts ) ) layer.types.append( static_cast( geomType.toInt() ) ); QString geomSrids = QString::fromUtf8( ( const char * ) sqlite3_column_text( stmt, 7 ) ); - Q_FOREACH ( QString geomSrid, geomSrids.split( ",", QString::SkipEmptyParts ) ) + for ( QString geomSrid : geomSrids.split( ",", QString::SkipEmptyParts ) ) layer.srids.append( geomSrid.toInt() ); layers.append( layer ); diff --git a/src/providers/ows/qgsowsdataitems.cpp b/src/providers/ows/qgsowsdataitems.cpp index 068a13541bf2..beea4b5dd60e 100644 --- a/src/providers/ows/qgsowsdataitems.cpp +++ b/src/providers/ows/qgsowsdataitems.cpp @@ -38,7 +38,7 @@ QVector QgsOWSConnectionItem::createChildren() int layerCount = 0; // Try to open with WMS,WFS,WCS - Q_FOREACH ( const QString &key, QStringList() << "wms" << "WFS" << "wcs" ) + for ( const QString &key : { "wms", "WFS", "wcs" } ) { QgsDebugMsg( "Add connection for provider " + key ); const QList providerList = QgsProviderRegistry::instance()->dataItemProviders( key ); @@ -153,9 +153,10 @@ QVector QgsOWSRootItem::createChildren() QVector connections; // Combine all WMS,WFS,WCS connections QStringList connNames; - Q_FOREACH ( const QString &service, QStringList() << "WMS" << "WFS" << "WCS" ) + for ( const QString &service : { "WMS", "WFS", "WCS"} ) { - Q_FOREACH ( const QString &connName, QgsOwsConnection::connectionList( service ) ) + const QStringList list = QgsOwsConnection::connectionList( service ); + for ( const QString &connName : list ) { if ( !connNames.contains( connName ) ) { diff --git a/src/providers/postgres/qgspostgresdataitems.cpp b/src/providers/postgres/qgspostgresdataitems.cpp index 63948f9fc16c..896c69affbf7 100644 --- a/src/providers/postgres/qgspostgresdataitems.cpp +++ b/src/providers/postgres/qgspostgresdataitems.cpp @@ -550,7 +550,8 @@ QgsPGRootItem::QgsPGRootItem( QgsDataItem *parent, const QString &name, const QS QVector QgsPGRootItem::createChildren() { QVector connections; - Q_FOREACH ( const QString &connName, QgsPostgresConn::connectionList() ) + const QStringList list = QgsPostgresConn::connectionList(); + for ( const QString &connName : list ) { connections << new QgsPGConnectionItem( this, connName, mPath + '/' + connName ); } diff --git a/src/providers/postgres/qgspostgresfeatureiterator.cpp b/src/providers/postgres/qgspostgresfeatureiterator.cpp index 6f3588880b55..e4e424d0b1f8 100644 --- a/src/providers/postgres/qgspostgresfeatureiterator.cpp +++ b/src/providers/postgres/qgspostgresfeatureiterator.cpp @@ -685,7 +685,7 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString &whereClause, long break; case PktFidMap: - Q_FOREACH ( int idx, mSource->mPrimaryKeyAttrs ) + for ( int idx : std::as_const( mSource->mPrimaryKeyAttrs ) ) { query += delim + mConn->fieldExpression( mSource->mFields.at( idx ) ); delim = ','; @@ -847,7 +847,7 @@ bool QgsPostgresFeatureIterator::getFeature( QgsPostgresResult &queryResult, int { QVariantList primaryKeyVals; - Q_FOREACH ( int idx, mSource->mPrimaryKeyAttrs ) + for ( int idx : std::as_const( mSource->mPrimaryKeyAttrs ) ) { QgsField fld = mSource->mFields.at( idx ); QVariant v; diff --git a/src/providers/spatialite/qgsspatialitedataitems.cpp b/src/providers/spatialite/qgsspatialitedataitems.cpp index 0c1d7dafc903..a09f925fc57e 100644 --- a/src/providers/spatialite/qgsspatialitedataitems.cpp +++ b/src/providers/spatialite/qgsspatialitedataitems.cpp @@ -175,7 +175,8 @@ QgsSLRootItem::QgsSLRootItem( QgsDataItem *parent, const QString &name, const QS QVector QgsSLRootItem::createChildren() { QVector connections; - Q_FOREACH ( const QString &connName, QgsSpatiaLiteConnection::connectionList() ) + const QStringList list = QgsSpatiaLiteConnection::connectionList(); + for ( const QString &connName : list ) { QgsDataItem *conn = new QgsSLConnectionItem( this, connName, mPath + '/' + connName ); connections.push_back( conn ); diff --git a/src/providers/spatialite/qgsspatialitesourceselect.cpp b/src/providers/spatialite/qgsspatialitesourceselect.cpp index e37c5c65e5ee..5b2f562c3dab 100644 --- a/src/providers/spatialite/qgsspatialitesourceselect.cpp +++ b/src/providers/spatialite/qgsspatialitesourceselect.cpp @@ -246,7 +246,8 @@ void QgsSpatiaLiteSourceSelect::setLayerType( const QString &table, const QStrin void QgsSpatiaLiteSourceSelect::populateConnectionList() { cmbConnections->clear(); - Q_FOREACH ( const QString &name, QgsSpatiaLiteConnection::connectionList() ) + const QStringList list = QgsSpatiaLiteConnection::connectionList(); + for ( const QString &name : list ) { // retrieving the SQLite DB name and full path QString text = name + tr( "@" ) + QgsSpatiaLiteConnection::connectionPath( name ); diff --git a/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp b/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp index 20e080ee822a..9f3006ccf9ec 100644 --- a/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp +++ b/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp @@ -863,7 +863,8 @@ void registerQgisFunctions( sqlite3 *db ) QStringList reservedFunctions; reservedFunctions << QStringLiteral( "left" ) << QStringLiteral( "right" ) << QStringLiteral( "union" ); // register QGIS expression functions - Q_FOREACH ( QgsExpressionFunction *foo, QgsExpression::Functions() ) + const QList functions = QgsExpression::Functions(); + for ( QgsExpressionFunction *foo : functions ) { if ( foo->usesGeometry( nullptr ) || foo->lazyEval() ) { @@ -885,7 +886,7 @@ void registerQgisFunctions( sqlite3 *db ) params = -1; } - Q_FOREACH ( QString name, names ) // for each alias + for ( QString name : std::as_const( names ) ) // for each alias { if ( reservedFunctions.contains( name ) ) // reserved keyword name = "_" + name; diff --git a/src/providers/wcs/qgswcscapabilities.cpp b/src/providers/wcs/qgswcscapabilities.cpp index 7aca38d38038..d63e0ee279f5 100644 --- a/src/providers/wcs/qgswcscapabilities.cpp +++ b/src/providers/wcs/qgswcscapabilities.cpp @@ -652,7 +652,8 @@ QString QgsWcsCapabilities::domElementText( const QDomElement &element, const QS QList QgsWcsCapabilities::parseInts( const QString &text ) { QList list; - Q_FOREACH ( const QString &s, text.split( ' ' ) ) + const QStringList parts = text.split( ' ' ); + for ( const QString &s : parts ) { bool ok; list.append( s.toInt( &ok ) ); @@ -668,7 +669,8 @@ QList QgsWcsCapabilities::parseInts( const QString &text ) QList QgsWcsCapabilities::parseDoubles( const QString &text ) { QList list; - Q_FOREACH ( const QString &s, text.split( ' ' ) ) + const QStringList parts = text.split( ' ' ); + for ( const QString &s : parts ) { bool ok; list.append( s.toDouble( &ok ) ); @@ -978,7 +980,8 @@ bool QgsWcsCapabilities::parseDescribeCoverageDom10( QByteArray const &xml, QgsW // NULL / no data values // TODO: handle multiple range sets - Q_FOREACH ( const QString &text, domElementsTexts( coverageOfferingElement, "rangeSet.RangeSet.nullValue.singleValue" ) ) + const QStringList elements = domElementsTexts( coverageOfferingElement, "rangeSet.RangeSet.nullValue.singleValue" ); + for ( const QString &text : elements ) { bool ok; double val = text.toDouble( &ok ); @@ -1095,7 +1098,8 @@ bool QgsWcsCapabilities::parseDescribeCoverageDom11( QByteArray const &xml, QgsW // NULL / no data values // TODO: handle multiple fields / ranges (?) - Q_FOREACH ( const QString &text, domElementsTexts( documentElement, "CoverageDescription.Range.Field.NullValue" ) ) + const QStringList elements = domElementsTexts( documentElement, "CoverageDescription.Range.Field.NullValue" ); + for ( const QString &text : elements ) { bool ok; double val = text.toDouble( &ok ); diff --git a/src/providers/wcs/qgswcsdataitems.cpp b/src/providers/wcs/qgswcsdataitems.cpp index 5dd465c3f342..702bb4df0f30 100644 --- a/src/providers/wcs/qgswcsdataitems.cpp +++ b/src/providers/wcs/qgswcsdataitems.cpp @@ -52,7 +52,8 @@ QVector QgsWCSConnectionItem::createChildren() return children; } - Q_FOREACH ( const QgsWcsCoverageSummary &coverageSummary, mWcsCapabilities.capabilities().contents.coverageSummary ) + const QVector summaries = mWcsCapabilities.capabilities().contents.coverageSummary; + for ( const QgsWcsCoverageSummary &coverageSummary : summaries ) { // Attention, the name may be empty QgsDebugMsgLevel( QString::number( coverageSummary.orderId ) + ' ' + coverageSummary.identifier + ' ' + coverageSummary.title, 2 ); @@ -93,7 +94,7 @@ QgsWCSLayerItem::QgsWCSLayerItem( QgsDataItem *parent, QString name, QString pat QgsDebugMsgLevel( "uri = " + mDataSourceUri.encodedUri(), 2 ); mUri = createUri(); // Populate everything, it costs nothing, all info about layers is collected - Q_FOREACH ( const QgsWcsCoverageSummary &coverageSummary, mCoverageSummary.coverageSummary ) + for ( const QgsWcsCoverageSummary &coverageSummary : std::as_const( mCoverageSummary.coverageSummary ) ) { // Attention, the name may be empty QgsDebugMsgLevel( QString::number( coverageSummary.orderId ) + ' ' + coverageSummary.identifier + ' ' + coverageSummary.title, 2 ); @@ -155,7 +156,7 @@ QString QgsWCSLayerItem::createUri() // TODO: prefer project CRS // get first known if possible QgsCoordinateReferenceSystem testCrs; - Q_FOREACH ( const QString &c, mCoverageSummary.supportedCrs ) + for ( const QString &c : std::as_const( mCoverageSummary.supportedCrs ) ) { testCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( c ); if ( testCrs.isValid() ) @@ -189,7 +190,8 @@ QgsWCSRootItem::QgsWCSRootItem( QgsDataItem *parent, QString name, QString path QVectorQgsWCSRootItem::createChildren() { QVector connections; - Q_FOREACH ( const QString &connName, QgsOwsConnection::connectionList( "WCS" ) ) + const QStringList list = QgsOwsConnection::connectionList( "WCS" ); + for ( const QString &connName : list ) { QgsOwsConnection connection( QStringLiteral( "WCS" ), connName ); QgsDataItem *conn = new QgsWCSConnectionItem( this, connName, mPath + '/' + connName, connection.uri().encodedUri() ); diff --git a/src/providers/wfs/qgswfscapabilities.cpp b/src/providers/wfs/qgswfscapabilities.cpp index f4676f2192bd..be16b5edcedd 100644 --- a/src/providers/wfs/qgswfscapabilities.cpp +++ b/src/providers/wfs/qgswfscapabilities.cpp @@ -93,7 +93,7 @@ QString QgsWfsCapabilities::Capabilities::addPrefixIfNeeded( const QString &name QString QgsWfsCapabilities::Capabilities::getNamespaceForTypename( const QString &name ) const { - Q_FOREACH ( const QgsWfsCapabilities::FeatureType &f, featureTypes ) + for ( const QgsWfsCapabilities::FeatureType &f : featureTypes ) { if ( f.name == name ) { @@ -608,7 +608,7 @@ void QgsWfsCapabilities::capabilitiesReplyFinished() mCaps.featureTypes.push_back( featureType ); } - Q_FOREACH ( const FeatureType &f, mCaps.featureTypes ) + for ( const FeatureType &f : std::as_const( mCaps.featureTypes ) ) { mCaps.setAllTypenames.insert( f.name ); QString unprefixed( QgsWFSUtils::removeNamespacePrefix( f.name ) ); diff --git a/src/providers/wfs/qgswfsdataitems.cpp b/src/providers/wfs/qgswfsdataitems.cpp index aea7468663f2..6c34501e4288 100644 --- a/src/providers/wfs/qgswfsdataitems.cpp +++ b/src/providers/wfs/qgswfsdataitems.cpp @@ -239,7 +239,8 @@ QVector QgsWfsRootItem::createChildren() { QVector connections; - Q_FOREACH ( const QString &connName, QgsWfsConnection::connectionList() ) + const QStringList list = QgsWfsConnection::connectionList() ; + for ( const QString &connName : list ) { QgsWfsConnection connection( connName ); QString path = "wfs:/" + connName; diff --git a/src/providers/wfs/qgswfsfeatureiterator.cpp b/src/providers/wfs/qgswfsfeatureiterator.cpp index 8cc95c491e6c..27175a359817 100644 --- a/src/providers/wfs/qgswfsfeatureiterator.cpp +++ b/src/providers/wfs/qgswfsfeatureiterator.cpp @@ -122,7 +122,7 @@ QUrl QgsWFSFeatureDownloaderImpl::buildURL( qint64 startIndex, int maxFeatures, } else { - Q_FOREACH ( const QgsOgcUtils::LayerProperties layerProperties, mShared->mLayerPropertiesList ) + for ( const QgsOgcUtils::LayerProperties &layerProperties : std::as_const( mShared->mLayerPropertiesList ) ) { if ( !typenames.isEmpty() ) typenames += QLatin1Char( ',' ); diff --git a/src/providers/wfs/qgswfssourceselect.cpp b/src/providers/wfs/qgswfssourceselect.cpp index 008d532ccaf6..2602c14d8904 100644 --- a/src/providers/wfs/qgswfssourceselect.cpp +++ b/src/providers/wfs/qgswfssourceselect.cpp @@ -237,7 +237,7 @@ void QgsWFSSourceSelect::capabilitiesReplyFinished() mCaps = mCapabilities->capabilities(); mAvailableCRS.clear(); - Q_FOREACH ( const QgsWfsCapabilities::FeatureType &featureType, mCaps.featureTypes ) + for ( const QgsWfsCapabilities::FeatureType &featureType : std::as_const( mCaps.featureTypes ) ) { // insert the typenames, titles and abstracts into the tree view QStandardItem *titleItem = new QStandardItem( featureType.title ); diff --git a/src/providers/wfs/qgswfssubsetstringeditor.cpp b/src/providers/wfs/qgswfssubsetstringeditor.cpp index 27b099a4d9a6..0c95266ed929 100644 --- a/src/providers/wfs/qgswfssubsetstringeditor.cpp +++ b/src/providers/wfs/qgswfssubsetstringeditor.cpp @@ -44,7 +44,7 @@ QgsSubsetStringEditorInterface *QgsWfsSubsetStringEditor::create( QgsVectorLayer d->setSupportMultipleTables( bSupportJoins, QgsSQLStatement::quotedIdentifierIfNeeded( displayedTypeName ) ); QMap< QString, QString > mapTypenameToTitle; - Q_FOREACH ( const QgsWfsCapabilities::FeatureType f, caps.featureTypes ) + for ( const QgsWfsCapabilities::FeatureType f : std::as_const( caps.featureTypes ) ) mapTypenameToTitle[f.name] = f.title; QList< QgsSQLComposerDialog::PairNameTitle > tablenames; @@ -70,14 +70,14 @@ QgsSubsetStringEditorInterface *QgsWfsSubsetStringEditor::create( QgsVectorLayer d->addTableNames( tablenames ); QList< QgsSQLComposerDialog::Function> functionList; - Q_FOREACH ( const QgsWfsCapabilities::Function &f, caps.functionList ) + for ( const QgsWfsCapabilities::Function &f : std::as_const( caps.functionList ) ) { QgsSQLComposerDialog::Function dialogF; dialogF.name = f.name; dialogF.returnType = f.returnType; dialogF.minArgs = f.minArgs; dialogF.maxArgs = f.maxArgs; - Q_FOREACH ( const QgsWfsCapabilities::Argument &arg, f.argumentList ) + for ( const QgsWfsCapabilities::Argument &arg : std::as_const( f.argumentList ) ) { dialogF.argumentList << QgsSQLComposerDialog::Argument( arg.name, arg.type ); } @@ -86,14 +86,14 @@ QgsSubsetStringEditorInterface *QgsWfsSubsetStringEditor::create( QgsVectorLayer d->addFunctions( functionList ); QList< QgsSQLComposerDialog::Function> spatialPredicateList; - Q_FOREACH ( const QgsWfsCapabilities::Function &f, caps.spatialPredicatesList ) + for ( const QgsWfsCapabilities::Function &f : std::as_const( caps.spatialPredicatesList ) ) { QgsSQLComposerDialog::Function dialogF; dialogF.name = f.name; dialogF.returnType = f.returnType; dialogF.minArgs = f.minArgs; dialogF.maxArgs = f.maxArgs; - Q_FOREACH ( const QgsWfsCapabilities::Argument &arg, f.argumentList ) + for ( const QgsWfsCapabilities::Argument &arg : std::as_const( f.argumentList ) ) { dialogF.argumentList << QgsSQLComposerDialog::Argument( arg.name, arg.type ); } diff --git a/src/python/qgspythonutilsimpl.cpp b/src/python/qgspythonutilsimpl.cpp index be49ed3db861..5979e88c778e 100644 --- a/src/python/qgspythonutilsimpl.cpp +++ b/src/python/qgspythonutilsimpl.cpp @@ -73,7 +73,8 @@ bool QgsPythonUtilsImpl::checkSystemImports() // locally installed plugins have priority over the system plugins // use os.path.expanduser to support usernames with special characters (see #2512) QStringList pluginpaths; - Q_FOREACH ( QString p, extraPluginsPaths() ) + const QStringList extraPaths = extraPluginsPaths(); + for ( QString p : extraPaths ) { if ( !QDir( p ).exists() ) { @@ -109,9 +110,16 @@ bool QgsPythonUtilsImpl::checkSystemImports() } // set PyQt api versions - QStringList apiV2classes; - apiV2classes << QStringLiteral( "QDate" ) << QStringLiteral( "QDateTime" ) << QStringLiteral( "QString" ) << QStringLiteral( "QTextStream" ) << QStringLiteral( "QTime" ) << QStringLiteral( "QUrl" ) << QStringLiteral( "QVariant" ); - Q_FOREACH ( const QString &clsName, apiV2classes ) + for ( const QString &clsName : +{ + QStringLiteral( "QDate" ), + QStringLiteral( "QDateTime" ), + QStringLiteral( "QString" ), + QStringLiteral( "QTextStream" ), + QStringLiteral( "QTime" ), + QStringLiteral( "QUrl" ), + QStringLiteral( "QVariant" ) + } ) { if ( !runString( QStringLiteral( "sip.setapi('%1', 2)" ).arg( clsName ), QObject::tr( "Couldn't set SIP API versions." ) + '\n' + QObject::tr( "Python support will be disabled." ) ) ) diff --git a/tests/bench/main.cpp b/tests/bench/main.cpp index 1df364910e3e..455653936eb6 100644 --- a/tests/bench/main.cpp +++ b/tests/bench/main.cpp @@ -418,7 +418,7 @@ int main( int argc, char *argv[] ) gdalShares << QCoreApplication::applicationDirPath().append( "/share/gdal" ) << appResources.append( "/share/gdal" ) << appResources.append( "/gdal" ); - Q_FOREACH ( const QString &gdalShare, gdalShares ) + for ( const QString &gdalShare : std::as_const( gdalShares ) ) { if ( QFile::exists( gdalShare ) ) { @@ -501,8 +501,8 @@ int main( int argc, char *argv[] ) if ( ! myQuality.isEmpty() ) { QPainter::RenderHints hints; - QStringList list = myQuality.split( ',' ); - Q_FOREACH ( const QString &q, list ) + const QStringList list = myQuality.split( ',' ); + for ( const QString &q : list ) { if ( q == QLatin1String( "Antialiasing" ) ) hints |= QPainter::Antialiasing; else if ( q == QLatin1String( "TextAntialiasing" ) ) hints |= QPainter::TextAntialiasing; diff --git a/tests/code_layout/test_banned_keywords.sh b/tests/code_layout/test_banned_keywords.sh index 94811b101366..5b27a506c496 100755 --- a/tests/code_layout/test_banned_keywords.sh +++ b/tests/code_layout/test_banned_keywords.sh @@ -131,6 +131,9 @@ HINTS[35]="Use \see instead (works correct with Python docstrings)" KEYWORDS[36]="@brief" HINTS[36]="Use \brief instead (works correct with Python docstrings)" +KEYWORDS[37]="Q_FOREACH" +HINTS[37]="Use range based for loops instead" + RES= DIR=$(git rev-parse --show-toplevel) diff --git a/tests/src/analysis/testqgsprocessing.cpp b/tests/src/analysis/testqgsprocessing.cpp index 919f5e8fbe24..c0399beb8164 100644 --- a/tests/src/analysis/testqgsprocessing.cpp +++ b/tests/src/analysis/testqgsprocessing.cpp @@ -812,13 +812,14 @@ void TestQgsProcessing::compatibleLayers() // sorted QStringList lIds; - Q_FOREACH ( QgsRasterLayer *rl, QgsProcessingUtils::compatibleRasterLayers( &p ) ) + QList layers = QgsProcessingUtils::compatibleRasterLayers( &p ); + for ( QgsRasterLayer *rl : layers ) lIds << rl->name(); QCOMPARE( lIds, QStringList() << "ar2" << "R1" << "zz" ); // unsorted lIds.clear(); - Q_FOREACH ( QgsRasterLayer *rl, QgsProcessingUtils::compatibleRasterLayers( &p, false ) ) + for ( QgsRasterLayer *rl : QgsProcessingUtils::compatibleRasterLayers( &p, false ) ) lIds << rl->name(); QCOMPARE( lIds, QStringList() << "R1" << "ar2" << "zz" ); @@ -827,13 +828,13 @@ void TestQgsProcessing::compatibleLayers() // sorted lIds.clear(); - Q_FOREACH ( QgsMeshLayer *rl, QgsProcessingUtils::compatibleMeshLayers( &p ) ) + for ( QgsMeshLayer *rl : QgsProcessingUtils::compatibleMeshLayers( &p ) ) lIds << rl->name(); QCOMPARE( lIds, QStringList() << "mA" << "MX" ); // unsorted lIds.clear(); - Q_FOREACH ( QgsMeshLayer *rl, QgsProcessingUtils::compatibleMeshLayers( &p, false ) ) + for ( QgsMeshLayer *rl : QgsProcessingUtils::compatibleMeshLayers( &p, false ) ) lIds << rl->name(); QCOMPARE( lIds, QStringList() << "MX" << "mA" ); @@ -842,49 +843,49 @@ void TestQgsProcessing::compatibleLayers() // sorted lIds.clear(); - Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p ) ) + for ( QgsVectorLayer *vl : QgsProcessingUtils::compatibleVectorLayers( &p ) ) lIds << vl->name(); QCOMPARE( lIds, QStringList() << "v1" << "v3" << "V4" << "vvvv4" ); // unsorted lIds.clear(); - Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList(), false ) ) + for ( QgsVectorLayer *vl : QgsProcessingUtils::compatibleVectorLayers( &p, QList(), false ) ) lIds << vl->name(); QCOMPARE( lIds, QStringList() << "V4" << "v1" << "v3" << "vvvv4" ); // point only lIds.clear(); - Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVectorPoint ) ) + for ( QgsVectorLayer *vl : QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVectorPoint ) ) lIds << vl->name(); QCOMPARE( lIds, QStringList() << "v1" ); // polygon only lIds.clear(); - Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVectorPolygon ) ) + for ( QgsVectorLayer *vl : QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVectorPolygon ) ) lIds << vl->name(); QCOMPARE( lIds, QStringList() << "V4" ); // line only lIds.clear(); - Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVectorLine ) ) + for ( QgsVectorLayer *vl : QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVectorLine ) ) lIds << vl->name(); QCOMPARE( lIds, QStringList() << "v3" ); // point and line only lIds.clear(); - Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVectorPoint << QgsProcessing::TypeVectorLine ) ) + for ( QgsVectorLayer *vl : QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVectorPoint << QgsProcessing::TypeVectorLine ) ) lIds << vl->name(); QCOMPARE( lIds, QStringList() << "v1" << "v3" ); // any vector w geometry lIds.clear(); - Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVectorAnyGeometry ) ) + for ( QgsVectorLayer *vl : QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVectorAnyGeometry ) ) lIds << vl->name(); QCOMPARE( lIds, QStringList() << "v1" << "v3" << "V4" ); // any vector lIds.clear(); - Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVector ) ) + for ( QgsVectorLayer *vl : QgsProcessingUtils::compatibleVectorLayers( &p, QList() << QgsProcessing::TypeVector ) ) lIds << vl->name(); QCOMPARE( lIds, QStringList() << "v1" << "v3" << "V4" << "vvvv4" ); @@ -893,13 +894,13 @@ void TestQgsProcessing::compatibleLayers() // sorted lIds.clear(); - Q_FOREACH ( QgsMapLayer *l, QgsProcessingUtils::compatibleLayers( &p ) ) + for ( QgsMapLayer *l : QgsProcessingUtils::compatibleLayers( &p ) ) lIds << l->name(); QCOMPARE( lIds, QStringList() << "ar2" << "mA" << "MX" << "R1" << "v1" << "v3" << "V4" << "vvvv4" << "zz" ); // unsorted lIds.clear(); - Q_FOREACH ( QgsMapLayer *l, QgsProcessingUtils::compatibleLayers( &p, false ) ) + for ( QgsMapLayer *l : QgsProcessingUtils::compatibleLayers( &p, false ) ) lIds << l->name(); QCOMPARE( lIds, QStringList() << "R1" << "ar2" << "zz" << "V4" << "v1" << "v3" << "vvvv4" << "MX" << "mA" ); } diff --git a/tests/src/app/testqgisappclipboard.cpp b/tests/src/app/testqgisappclipboard.cpp index 2bc44775873a..706d714957e3 100644 --- a/tests/src/app/testqgisappclipboard.cpp +++ b/tests/src/app/testqgisappclipboard.cpp @@ -93,7 +93,7 @@ void TestQgisAppClipboard::copyPaste() filesCounts.insert( QStringLiteral( "lines.shp" ), 6 ); filesCounts.insert( QStringLiteral( "polys.shp" ), 10 ); - Q_FOREACH ( const QString &fileName, filesCounts.keys() ) + for ( const QString &fileName : filesCounts.keys() ) { // add vector layer QString filePath = mTestDataDir + fileName; diff --git a/tests/src/core/testqgsauthmanager.cpp b/tests/src/core/testqgsauthmanager.cpp index 6d95ad227a34..1890ee6d38d8 100644 --- a/tests/src/core/testqgsauthmanager.cpp +++ b/tests/src/core/testqgsauthmanager.cpp @@ -148,7 +148,7 @@ void TestQgsAuthManager::cleanupTempDir() QDir tmpDir = QDir( mTempDir ); if ( tmpDir.exists() ) { - Q_FOREACH ( const QString &tf, tmpDir.entryList( QDir::NoDotAndDotDot | QDir::Files ) ) + for ( const QString &tf : tmpDir.entryList( QDir::NoDotAndDotDot | QDir::Files ) ) { QVERIFY2( tmpDir.remove( mTempDir + '/' + tf ), qPrintable( "Could not remove " + mTempDir + '/' + tf ) ); } @@ -238,7 +238,7 @@ void TestQgsAuthManager::testAuthConfigs() QgsAuthManager *authm = QgsApplication::authManager(); // test storing/loading/updating - Q_FOREACH ( QgsAuthMethodConfig config, configs ) + for ( QgsAuthMethodConfig config : configs ) { QVERIFY( config.isValid() ); @@ -273,7 +273,7 @@ void TestQgsAuthManager::testAuthConfigs() QVERIFY( config == config2 ); // changed config should update then correctly roundtrip - Q_FOREACH ( const QString &key, config2.configMap().keys() ) + for ( const QString &key : config2.configMap().keys() ) { config2.setConfig( key, config2.configMap().value( key ) + "changed" ); } @@ -318,7 +318,7 @@ void TestQgsAuthManager::testAuthConfigs() // test storing, then retrieving configid -> config map QgsAuthMethodConfigsMap idcfgmap; - Q_FOREACH ( QgsAuthMethodConfig config, configs ) + for ( QgsAuthMethodConfig config : configs ) { QVERIFY( authm->storeAuthenticationConfig( config ) ); idcfgmap.insert( config.id(), config ); @@ -352,7 +352,7 @@ void TestQgsAuthManager::testAuthMethods() QgsAuthManager *authm = QgsApplication::authManager(); - Q_FOREACH ( QgsAuthMethodConfig config, configs ) + for ( QgsAuthMethodConfig config : configs ) { QVERIFY( config.isValid() ); QVERIFY( authm->storeAuthenticationConfig( config ) ); diff --git a/tests/src/core/testqgsdataitem.cpp b/tests/src/core/testqgsdataitem.cpp index ff3158151f19..65b10f9435c4 100644 --- a/tests/src/core/testqgsdataitem.cpp +++ b/tests/src/core/testqgsdataitem.cpp @@ -129,7 +129,7 @@ void TestQgsDataItem::testDirItemChildren() QgsSettings settings; QStringList tmpSettings; tmpSettings << QString() << QStringLiteral( "contents" ) << QStringLiteral( "extension" ); - Q_FOREACH ( const QString &tmpSetting, tmpSettings ) + for ( const QString &tmpSetting : tmpSettings ) { settings.setValue( QStringLiteral( "/qgis/scanItemsInBrowser2" ), tmpSetting ); QgsDirectoryItem *dirItem = new QgsDirectoryItem( nullptr, QStringLiteral( "Test" ), TEST_DATA_DIR ); diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp index 08e73fd685b6..adc958aebab7 100644 --- a/tests/src/core/testqgsexpression.cpp +++ b/tests/src/core/testqgsexpression.cpp @@ -2616,7 +2616,7 @@ class TestQgsExpression: public QObject QSet refCols = exp.referencedColumns(); // make sure we have lower case QSet refColsSet; - Q_FOREACH ( const QString &col, refCols ) + for ( const QString &col : refCols ) refColsSet.insert( col.toLower() ); QCOMPARE( refColsSet, expectedCols ); diff --git a/tests/src/core/testqgsfeature.cpp b/tests/src/core/testqgsfeature.cpp index 393ee0f121a1..179de5ac077f 100644 --- a/tests/src/core/testqgsfeature.cpp +++ b/tests/src/core/testqgsfeature.cpp @@ -180,7 +180,7 @@ void TestQgsFeature::create() QCOMPARE( featureFromFieldsId.isValid(), false ); //should be 3 invalid attributes QCOMPARE( featureFromFieldsId.attributes().count(), 3 ); - Q_FOREACH ( const QVariant &a, featureFromFieldsId.attributes() ) + for ( const QVariant &a : featureFromFieldsId.attributes() ) { QVERIFY( !a.isValid() ); } @@ -293,7 +293,7 @@ void TestQgsFeature::attributes() QCOMPARE( copy.attributes(), mAttrs ); copy.initAttributes( 5 ); QCOMPARE( copy.attributes().count(), 5 ); - Q_FOREACH ( const QVariant &a, copy.attributes() ) + for ( const QVariant &a : copy.attributes() ) { QVERIFY( !a.isValid() ); } @@ -423,7 +423,7 @@ void TestQgsFeature::fields() QCOMPARE( copy.fields(), mFields ); //should be 3 invalid attributes QCOMPARE( copy.attributes().count(), 3 ); - Q_FOREACH ( const QVariant &a, copy.attributes() ) + for ( const QVariant &a : copy.attributes() ) { QVERIFY( !a.isValid() ); } diff --git a/tests/src/core/testqgsfields.cpp b/tests/src/core/testqgsfields.cpp index 0db51f90433d..0d7745140130 100644 --- a/tests/src/core/testqgsfields.cpp +++ b/tests/src/core/testqgsfields.cpp @@ -513,7 +513,7 @@ void TestQgsFields::qforeach() fields.append( field2 ); int i = 0; - Q_FOREACH ( const QgsField &field, fields ) + for ( const QgsField &field : fields ) { QCOMPARE( field, fields.at( i ) ); ++i; @@ -568,7 +568,7 @@ void TestQgsFields::constIterator() //test with empty fields QCOMPARE( fields.constBegin(), fields.constEnd() ); QCOMPARE( const_cast< const QgsFields * >( &fields )->begin(), const_cast< const QgsFields * >( &fields )->end() ); - Q_FOREACH ( const QgsField &f, fields ) + for ( const QgsField &f : fields ) { Q_UNUSED( f ); //should not be called! diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp index 9a2f49c7bc40..a8377b1b685b 100644 --- a/tests/src/core/testqgsgeometry.cpp +++ b/tests/src/core/testqgsgeometry.cpp @@ -17858,7 +17858,7 @@ void TestQgsGeometry::makeValid() geoms << qMakePair( QStringLiteral( "MultiLineString ((356984.0625 6300089, 356984.0625 6300089))" ), QStringLiteral( "MultiPoint ((356984.0625 6300089))" ) ); - Q_FOREACH ( const InputAndExpectedWktPair &pair, geoms ) + for ( const InputAndExpectedWktPair &pair : geoms ) { QgsGeometry gInput = QgsGeometry::fromWkt( pair.first ); QgsGeometry gExp = QgsGeometry::fromWkt( pair.second ); diff --git a/tests/src/core/testqgslayertree.cpp b/tests/src/core/testqgslayertree.cpp index d5f9aa6e147d..b0432ef7375a 100644 --- a/tests/src/core/testqgslayertree.cpp +++ b/tests/src/core/testqgslayertree.cpp @@ -367,19 +367,19 @@ void TestQgsLayerTree::testShowHideAllSymbolNodes() //test that all nodes are initially checked QList nodes = m->layerLegendNodes( n ); QCOMPARE( nodes.length(), 3 ); - Q_FOREACH ( QgsLayerTreeModelLegendNode *ln, nodes ) + for ( QgsLayerTreeModelLegendNode *ln : nodes ) { QVERIFY( ln->data( Qt::CheckStateRole ) == Qt::Checked ); } //uncheck all and test that all nodes are unchecked static_cast< QgsSymbolLegendNode * >( nodes.at( 0 ) )->uncheckAllItems(); - Q_FOREACH ( QgsLayerTreeModelLegendNode *ln, nodes ) + for ( QgsLayerTreeModelLegendNode *ln : nodes ) { QVERIFY( ln->data( Qt::CheckStateRole ) == Qt::Unchecked ); } //check all and test that all nodes are checked static_cast< QgsSymbolLegendNode * >( nodes.at( 0 ) )->checkAllItems(); - Q_FOREACH ( QgsLayerTreeModelLegendNode *ln, nodes ) + for ( QgsLayerTreeModelLegendNode *ln : nodes ) { QVERIFY( ln->data( Qt::CheckStateRole ) == Qt::Checked ); } @@ -418,7 +418,7 @@ void TestQgsLayerTree::testFindLegendNode() QVERIFY( !m->findLegendNode( QString( "vl" ), QString( "rule" ) ) ); QgsLegendSymbolList symbolList = renderer->legendSymbolItems(); - Q_FOREACH ( const QgsLegendSymbolItem &symbol, symbolList ) + for ( const QgsLegendSymbolItem &symbol : symbolList ) { QgsLayerTreeModelLegendNode *found = m->findLegendNode( vl->id(), symbol.ruleKey() ); QVERIFY( found ); @@ -550,7 +550,7 @@ void TestQgsLayerTree::testRendererLegend( QgsFeatureRenderer *renderer ) //test initial symbol QgsLegendSymbolList symbolList = renderer->legendSymbolItems(); - Q_FOREACH ( const QgsLegendSymbolItem &symbol, symbolList ) + for ( const QgsLegendSymbolItem &symbol : symbolList ) { QgsSymbolLegendNode *symbolNode = dynamic_cast< QgsSymbolLegendNode * >( m->findLegendNode( vl->id(), symbol.ruleKey() ) ); QVERIFY( symbolNode ); diff --git a/tests/src/core/testqgslegendrenderer.cpp b/tests/src/core/testqgslegendrenderer.cpp index 9d848eb7cdbb..366c1930d414 100644 --- a/tests/src/core/testqgslegendrenderer.cpp +++ b/tests/src/core/testqgslegendrenderer.cpp @@ -58,7 +58,7 @@ static void _setStandardTestFont( QgsLegendSettings &settings, const QString &st << QgsLegendStyle::Group << QgsLegendStyle::Subgroup << QgsLegendStyle::SymbolLabel; - Q_FOREACH ( QgsLegendStyle::Style st, styles ) + for ( QgsLegendStyle::Style st : styles ) { QFont font( QgsFontUtils::getStandardTestFont( style ) ); font.setPointSizeF( settings.style( st ).font().pointSizeF() ); @@ -945,7 +945,7 @@ bool TestQgsLegendRenderer::_testLegendColumns( int itemCount, int columnCount, _renderLegend( testName, &legendModel, settings ); bool result = _verifyImage( testName, mReport ); - Q_FOREACH ( QgsVectorLayer *l, layers ) + for ( QgsVectorLayer *l : layers ) { QgsProject::instance()->removeMapLayer( l ); } diff --git a/tests/src/core/testqgsrasterfilewriter.cpp b/tests/src/core/testqgsrasterfilewriter.cpp index 06ff14cf8061..3ba0e72f2760 100644 --- a/tests/src/core/testqgsrasterfilewriter.cpp +++ b/tests/src/core/testqgsrasterfilewriter.cpp @@ -98,7 +98,7 @@ void TestQgsRasterFileWriter::writeTest() filters << QStringLiteral( "*.tif" ); QStringList rasterNames = dir.entryList( filters, QDir::Files ); bool allOK = true; - Q_FOREACH ( const QString &rasterName, rasterNames ) + for ( const QString &rasterName : rasterNames ) { bool ok = writeTest( "raster/" + rasterName ); if ( !ok ) allOK = false; diff --git a/tests/src/core/testqgsrasterlayer.cpp b/tests/src/core/testqgsrasterlayer.cpp index b72333332502..2c476f143cea 100644 --- a/tests/src/core/testqgsrasterlayer.cpp +++ b/tests/src/core/testqgsrasterlayer.cpp @@ -491,7 +491,7 @@ void TestQgsRasterLayer::checkScaleOffset() if ( identifyResult.isValid() ) { QMap values = identifyResult.results(); - Q_FOREACH ( int bandNo, values.keys() ) + for ( int bandNo : values.keys() ) { QString valueString; if ( values.value( bandNo ).isNull() ) diff --git a/tests/src/core/testqgsrastersublayer.cpp b/tests/src/core/testqgsrastersublayer.cpp index 44e22e3c2d2c..19afbdd257fc 100644 --- a/tests/src/core/testqgsrastersublayer.cpp +++ b/tests/src/core/testqgsrastersublayer.cpp @@ -136,7 +136,7 @@ void TestQgsRasterSubLayer::subLayersList() expected << QStringLiteral( ":Band2!!::!![200x200] Band2 (8-bit integer)" ); QStringList sublayers; - Q_FOREACH ( const QString &s, mpRasterLayer->subLayers() ) + for ( const QString &s : mpRasterLayer->subLayers() ) { qDebug() << "sublayer: " << s; int pos = s.indexOf( QLatin1String( ":Band" ) ); diff --git a/tests/src/core/testqgsrulebasedrenderer.cpp b/tests/src/core/testqgsrulebasedrenderer.cpp index 15fd7504e219..0b6fda00695a 100644 --- a/tests/src/core/testqgsrulebasedrenderer.cpp +++ b/tests/src/core/testqgsrulebasedrenderer.cpp @@ -200,7 +200,7 @@ class TestQgsRuleBasedRenderer: public QObject // and does not have a parent QVERIFY( !root->parent() ); - Q_FOREACH ( QgsRuleBasedRenderer::Rule *node, root->children() ) + for ( QgsRuleBasedRenderer::Rule *node : root->children() ) check_non_root_rule( node ); } @@ -212,7 +212,7 @@ class TestQgsRuleBasedRenderer: public QObject // and must have a parent QVERIFY( node->parent() ); // check that all children are okay - Q_FOREACH ( QgsRuleBasedRenderer::Rule *child, node->children() ) + for ( QgsRuleBasedRenderer::Rule *child : node->children() ) check_non_root_rule( child ); } diff --git a/tests/src/core/testqgssnappingutils.cpp b/tests/src/core/testqgssnappingutils.cpp index 129083ea6934..788b0527392e 100644 --- a/tests/src/core/testqgssnappingutils.cpp +++ b/tests/src/core/testqgssnappingutils.cpp @@ -158,7 +158,7 @@ class TestQgsSnappingUtils : public QObject //test that all nodes are initially checked QList nodes = m->layerLegendNodes( n ); QCOMPARE( nodes.length(), 1 ); - Q_FOREACH ( QgsLayerTreeModelLegendNode *ln, nodes ) + for ( QgsLayerTreeModelLegendNode *ln : nodes ) { QVERIFY( ln->data( Qt::CheckStateRole ) == Qt::Checked ); } @@ -198,7 +198,7 @@ class TestQgsSnappingUtils : public QObject //uncheck all and test that all nodes are unchecked static_cast< QgsSymbolLegendNode * >( nodes.at( 0 ) )->uncheckAllItems(); - Q_FOREACH ( QgsLayerTreeModelLegendNode *ln, nodes ) + for ( QgsLayerTreeModelLegendNode *ln : nodes ) { QVERIFY( ln->data( Qt::CheckStateRole ) == Qt::Unchecked ); } diff --git a/tests/src/core/testqgsspatialindex.cpp b/tests/src/core/testqgsspatialindex.cpp index 3325544e915c..ff9cd427bb43 100644 --- a/tests/src/core/testqgsspatialindex.cpp +++ b/tests/src/core/testqgsspatialindex.cpp @@ -71,7 +71,7 @@ class TestQgsSpatialIndex : public QObject void testQuery() { QgsSpatialIndex index; - Q_FOREACH ( const QgsFeature &f, _pointFeatures() ) + for ( const QgsFeature &f : _pointFeatures() ) { QgsFeature indexFeature( f ); index.addFeature( indexFeature ); @@ -114,7 +114,7 @@ class TestQgsSpatialIndex : public QObject void testCopy() { QgsSpatialIndex *index = new QgsSpatialIndex; - Q_FOREACH ( const QgsFeature &f, _pointFeatures() ) + for ( const QgsFeature &f : _pointFeatures() ) { QgsFeature indexFeature( f ); index->addFeature( indexFeature ); diff --git a/tests/src/core/testqgsstyle.cpp b/tests/src/core/testqgsstyle.cpp index 572d14d87e38..cf7ce29288f0 100644 --- a/tests/src/core/testqgsstyle.cpp +++ b/tests/src/core/testqgsstyle.cpp @@ -553,7 +553,7 @@ void TestStyle::testLoadColorRamps() QgsDebugMsg( "loaded colorRamps: " + colorRamps.join( " " ) ); - Q_FOREACH ( const QString &name, colorRampsTest ) + for ( const QString &name : colorRampsTest ) { QgsDebugMsg( "colorRamp " + name ); QVERIFY( colorRamps.contains( name ) ); @@ -581,7 +581,7 @@ void TestStyle::testSaveLoad() QStringList colorRampsTest = QStringList() << QStringLiteral( "test_gradient" ); - Q_FOREACH ( const QString &name, colorRampsTest ) + for ( const QString &name : colorRampsTest ) { QgsDebugMsg( "colorRamp " + name ); QVERIFY( colorRamps.contains( name ) ); diff --git a/tests/src/core/testqgstracer.cpp b/tests/src/core/testqgstracer.cpp index 679fcafffe75..b0fbda3a86ee 100644 --- a/tests/src/core/testqgstracer.cpp +++ b/tests/src/core/testqgstracer.cpp @@ -73,7 +73,7 @@ static QgsVectorLayer *make_layer( const QStringList &wkts ) Q_ASSERT( vl->isValid() ); vl->startEditing(); - Q_FOREACH ( const QString &wkt, wkts ) + for ( const QString &wkt : wkts ) { QgsFeature f( make_feature( wkt ) ); vl->addFeature( f ); @@ -91,7 +91,7 @@ void print_shortest_path( QgsTracer &tracer, const QgsPointXY &p1, const QgsPoin if ( points.isEmpty() ) qDebug( "no path!" ); - Q_FOREACH ( const QgsPointXY &p, points ) + for ( const QgsPointXY &p : points ) qDebug( "p: %f %f", p.x(), p.y() ); } @@ -216,7 +216,7 @@ void TestQgsTracer::testInvisible() QCOMPARE( nodes.length(), 1 ); //uncheck all and test that all nodes are unchecked static_cast< QgsSymbolLegendNode * >( nodes.at( 0 ) )->uncheckAllItems(); - Q_FOREACH ( QgsLayerTreeModelLegendNode *ln, nodes ) + for ( QgsLayerTreeModelLegendNode *ln : nodes ) { QVERIFY( ln->data( Qt::CheckStateRole ) == Qt::Unchecked ); } diff --git a/tests/src/core/testqgsvectorlayercache.cpp b/tests/src/core/testqgsvectorlayercache.cpp index f8d361ac6cec..dbf26d83b9e1 100644 --- a/tests/src/core/testqgsvectorlayercache.cpp +++ b/tests/src/core/testqgsvectorlayercache.cpp @@ -81,7 +81,7 @@ void TestVectorLayerCache::initTestCase() QString myDataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt QString myTestDataDir = myDataDir + '/'; - Q_FOREACH ( const QString &f, backupFiles ) + for ( const QString &f : backupFiles ) { QString origFileName = myTestDataDir + f; QFileInfo origFileInfo( origFileName ); diff --git a/tests/src/core/testqgsvectorlayerjoinbuffer.cpp b/tests/src/core/testqgsvectorlayerjoinbuffer.cpp index d583b5d3a5e2..457db69c0c0d 100644 --- a/tests/src/core/testqgsvectorlayerjoinbuffer.cpp +++ b/tests/src/core/testqgsvectorlayerjoinbuffer.cpp @@ -160,7 +160,7 @@ void TestVectorLayerJoinBuffer::initTestCase() fX1.setAttribute( QStringLiteral( "value_x2" ), 222 ); // Commit features and layers to qgis - Q_FOREACH ( const QString provider, mProviders ) + for ( const QString provider : mProviders ) { QgsVectorLayer *vl = mLayers.value( QPair( QStringLiteral( "A" ), provider ) ); vl->dataProvider()->addFeatures( QgsFeatureList() << fA1 << fA2 ); @@ -168,7 +168,7 @@ void TestVectorLayerJoinBuffer::initTestCase() mProject.addMapLayer( vl ); } - Q_FOREACH ( const QString provider, mProviders ) + for ( const QString provider : mProviders ) { QgsVectorLayer *vl = mLayers.value( QPair( QStringLiteral( "B" ), provider ) ); vl->dataProvider()->addFeatures( QgsFeatureList() << fB1 << fB2 ); @@ -176,7 +176,7 @@ void TestVectorLayerJoinBuffer::initTestCase() mProject.addMapLayer( vl ); } - Q_FOREACH ( const QString provider, mProviders ) + for ( const QString provider : mProviders ) { QgsVectorLayer *vl = mLayers.value( QPair( QStringLiteral( "C" ), provider ) ); vl->dataProvider()->addFeatures( QgsFeatureList() << fC1 ); @@ -184,7 +184,7 @@ void TestVectorLayerJoinBuffer::initTestCase() mProject.addMapLayer( vl ); } - Q_FOREACH ( const QString provider, mProviders ) + for ( const QString provider : mProviders ) { QgsVectorLayer *vl = mLayers.value( QPair( QStringLiteral( "X" ), provider ) ); vl->dataProvider()->addFeatures( QgsFeatureList() << fX1 ); diff --git a/tests/src/core/testziplayer.cpp b/tests/src/core/testziplayer.cpp index f39e93ce9da5..a1063213f762 100644 --- a/tests/src/core/testziplayer.cpp +++ b/tests/src/core/testziplayer.cpp @@ -170,7 +170,7 @@ bool TestZipLayer::testZipItem( const QString &myFileName, const QString &myChil QgsDebugMsg( QStringLiteral( "has %1 items" ).arg( myChildren.size() ) ); if ( !myChildren.isEmpty() ) { - Q_FOREACH ( QgsDataItem *item, myChildren ) + for ( QgsDataItem *item : std::as_const( myChildren ) ) { QgsDebugMsg( QStringLiteral( "child name=%1" ).arg( item->name() ) ); QgsLayerItem *layerItem = dynamic_cast( item ); @@ -264,7 +264,7 @@ int TestZipLayer::getLayerTransparency( const QString &myFileName, const QString bool TestZipLayer::testZipItemTransparency( const QString &myFileName, const QString &myProviderKey, int myTarget ) { int myTransparency; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { myTransparency = getLayerTransparency( myFileName, myProviderKey, s ); if ( myTransparency != myTarget ) @@ -319,7 +319,7 @@ void TestZipLayer::testPassthruVectorZip() QString myFileName = mDataDir + "points2.zip"; QgsDebugMsg( "GDAL: " + QString( GDAL_RELEASE_NAME ) ); QgsDebugMsg( "FILE: " + QString( myFileName ) ); - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -331,7 +331,7 @@ void TestZipLayer::testPassthruVectorTar() { QgsSettings settings; QString myFileName = mDataDir + "points2.tar"; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -342,7 +342,7 @@ void TestZipLayer::testPassthruVectorTar() void TestZipLayer::testPassthruVectorGzip() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -353,7 +353,7 @@ void TestZipLayer::testPassthruVectorGzip() void TestZipLayer::testPassthruRasterZip() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -364,7 +364,7 @@ void TestZipLayer::testPassthruRasterZip() void TestZipLayer::testPassthruRasterTar() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -375,7 +375,7 @@ void TestZipLayer::testPassthruRasterTar() void TestZipLayer::testPassthruRasterGzip() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -386,7 +386,7 @@ void TestZipLayer::testPassthruRasterGzip() void TestZipLayer::testZipItemRaster() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -397,7 +397,7 @@ void TestZipLayer::testZipItemRaster() void TestZipLayer::testTarItemRaster() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -408,7 +408,7 @@ void TestZipLayer::testTarItemRaster() void TestZipLayer::testZipItemVector() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -419,7 +419,7 @@ void TestZipLayer::testZipItemVector() void TestZipLayer::testTarItemVector() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -482,7 +482,7 @@ void TestZipLayer::testGzipItemRasterTransparency() void TestZipLayer::testZipItemSubfolder() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -493,7 +493,7 @@ void TestZipLayer::testZipItemSubfolder() void TestZipLayer::testTarItemSubfolder() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); @@ -505,7 +505,7 @@ void TestZipLayer::testTarItemSubfolder() void TestZipLayer::testZipItemVRT() { QgsSettings settings; - Q_FOREACH ( const QString &s, mScanZipSettings ) + for ( const QString &s : std::as_const( mScanZipSettings ) ) { settings.setValue( mSettingsKey, s ); QVERIFY( s == settings.value( mSettingsKey ).toString() ); diff --git a/tests/src/gui/testprocessinggui.cpp b/tests/src/gui/testprocessinggui.cpp index 9fcd4b661c13..0b3723be18bd 100644 --- a/tests/src/gui/testprocessinggui.cpp +++ b/tests/src/gui/testprocessinggui.cpp @@ -9796,7 +9796,7 @@ void TestProcessingGui::cleanupTempDir() QDir tmpDir = QDir( mTempDir ); if ( tmpDir.exists() ) { - Q_FOREACH ( const QString &tf, tmpDir.entryList( QDir::NoDotAndDotDot | QDir::Files ) ) + for ( const QString &tf : tmpDir.entryList( QDir::NoDotAndDotDot | QDir::Files ) ) { QVERIFY2( tmpDir.remove( mTempDir + '/' + tf ), qPrintable( "Could not remove " + mTempDir + '/' + tf ) ); } diff --git a/tests/src/gui/testprojectionissues.cpp b/tests/src/gui/testprojectionissues.cpp index 0f01ae89ede5..77b7e0cd7750 100644 --- a/tests/src/gui/testprojectionissues.cpp +++ b/tests/src/gui/testprojectionissues.cpp @@ -64,7 +64,7 @@ void TestProjectionIssues::initTestCase() // Add all layers in registry to the canvas QList canvasLayers; - Q_FOREACH ( QgsMapLayer *layer, QgsProject::instance()->mapLayers() ) + for ( QgsMapLayer *layer : QgsProject::instance()->mapLayers() ) { canvasLayers.append( layer ); } diff --git a/tests/src/gui/testqgsmapcanvas.cpp b/tests/src/gui/testqgsmapcanvas.cpp index 5615ebd6d0ac..93a3917989ff 100644 --- a/tests/src/gui/testqgsmapcanvas.cpp +++ b/tests/src/gui/testqgsmapcanvas.cpp @@ -95,7 +95,7 @@ void TestQgsMapCanvas::testPanByKeyboard() QgsRectangle initialExtent( 100, 100, 110, 110 ); - Q_FOREACH ( double rotation, rotations ) + for ( double rotation : rotations ) { // Set rotation and initial extent mCanvas->setRotation( rotation ); @@ -103,7 +103,7 @@ void TestQgsMapCanvas::testPanByKeyboard() // Save actual extent, simulate panning by keyboard and verify the extent is unchanged QgsRectangle originalExtent = mCanvas->extent(); - Q_FOREACH ( Qt::Key key, keys ) + for ( Qt::Key key : keys ) { QgsRectangle tempExtent = mCanvas->extent(); QKeyEvent keyEvent( QEvent::KeyPress, key, Qt::NoModifier ); diff --git a/tests/src/gui/testqgsrelationreferencewidget.cpp b/tests/src/gui/testqgsrelationreferencewidget.cpp index abd8ff8fa8ac..e82d8a619159 100644 --- a/tests/src/gui/testqgsrelationreferencewidget.cpp +++ b/tests/src/gui/testqgsrelationreferencewidget.cpp @@ -192,7 +192,7 @@ void TestQgsRelationReferenceWidget::testChainFilter() // check default status for comboboxes QList cbs = w.mFilterComboBoxes; QCOMPARE( cbs.count(), 3 ); - Q_FOREACH ( const QComboBox *cb, cbs ) + for ( const QComboBox *cb : std::as_const( cbs ) ) { if ( cb->currentText() == QLatin1String( "raccord" ) ) QCOMPARE( cb->count(), 5 ); @@ -215,7 +215,7 @@ void TestQgsRelationReferenceWidget::testChainFilter() loop.exec(); QCOMPARE( w.mComboBox->currentText(), allowNull ? QString( "NULL" ) : QString( "10" ) ); - Q_FOREACH ( const QComboBox *cb, cbs ) + for ( const QComboBox *cb : std::as_const( cbs ) ) { if ( cb->itemText( 0 ) == QLatin1String( "material" ) ) QCOMPARE( cb->count(), 4 ); @@ -365,7 +365,7 @@ void TestQgsRelationReferenceWidget::testChainFilterFirstInit() // check default status for comboboxes QList cbs = w.mFilterComboBoxes; QCOMPARE( cbs.count(), 3 ); - Q_FOREACH ( const QComboBox *cb, cbs ) + for ( const QComboBox *cb : std::as_const( cbs ) ) { if ( cb->currentText() == QLatin1String( "raccord" ) ) QCOMPARE( cb->count(), 5 ); diff --git a/tests/src/providers/testqgswcsprovider.cpp b/tests/src/providers/testqgswcsprovider.cpp index 5dfb3c64d786..af855cb43b91 100644 --- a/tests/src/providers/testqgswcsprovider.cpp +++ b/tests/src/providers/testqgswcsprovider.cpp @@ -120,9 +120,9 @@ void TestQgsWcsProvider::read() tmpFile->open(); QString tmpFilePath = tmpFile->fileName(); delete tmpFile; // removes the file - Q_FOREACH ( const QString &version, versions ) + for ( const QString &version : versions ) { - Q_FOREACH ( const QString &identifier, identifiers ) + for ( const QString &identifier : identifiers ) { // copy to temporary to avoid creation/changes/use of GDAL .aux.xml files QString testFilePath = mTestDataDir + '/' + identifier + ".tif"; diff --git a/tests/src/providers/testqgswcspublicservers.cpp b/tests/src/providers/testqgswcspublicservers.cpp index fab8805e9a17..739fca818b4d 100644 --- a/tests/src/providers/testqgswcspublicservers.cpp +++ b/tests/src/providers/testqgswcspublicservers.cpp @@ -93,7 +93,7 @@ void TestQgsWcsPublicServers::init() QStringList providers; providers << QStringLiteral( "wcs" ) << QStringLiteral( "gdal" ); - Q_FOREACH ( const QString &provider, providers ) + for ( const QString &provider : providers ) { QString prefix = provider == QLatin1String( "gdal" ) ? "GDAL " : ""; mHead << prefix + "CRS"; @@ -181,7 +181,7 @@ void TestQgsWcsPublicServers::init() TestQgsWcsPublicServers::Server TestQgsWcsPublicServers::getServer( const QString &url ) { - Q_FOREACH ( const Server &server, mServers ) + for ( const Server &server : std::as_const( mServers ) ) { if ( server.url == url ) return server; } @@ -191,11 +191,11 @@ TestQgsWcsPublicServers::Server TestQgsWcsPublicServers::getServer( const QStrin QList TestQgsWcsPublicServers::issues( const QString &url, const QString &coverage, const QString &version ) { QList issues; - Q_FOREACH ( const Server &server, mServers ) + for ( const Server &server : std::as_const( mServers ) ) { if ( server.url == url ) { - Q_FOREACH ( const Issue &issue, server.issues ) + for ( const Issue &issue : server.issues ) { if ( ( issue.coverages.isEmpty() || issue.coverages.contains( coverage ) ) && ( issue.versions.isEmpty() || issue.versions.contains( version ) ) ) @@ -211,7 +211,7 @@ QList TestQgsWcsPublicServers::issues( const QSt QStringList TestQgsWcsPublicServers::issueDescriptions( const QString &url, const QString &coverage, const QString &version ) { QStringList descriptions; - Q_FOREACH ( const Issue &myIssue, issues( url, coverage, version ) ) + for ( const Issue &myIssue : issues( url, coverage, version ) ) { descriptions << myIssue.description; } @@ -221,7 +221,7 @@ QStringList TestQgsWcsPublicServers::issueDescriptions( const QString &url, cons int TestQgsWcsPublicServers::issueOffender( const QString &url, const QString &coverage, const QString &version ) { int offender = NoOffender; - Q_FOREACH ( const Issue &myIssue, issues( url, coverage, version ) ) + for ( const Issue &myIssue : issues( url, coverage, version ) ) { if ( myIssue.offender == QLatin1String( "server" ) ) { @@ -260,13 +260,13 @@ void TestQgsWcsPublicServers::test() } else { - Q_FOREACH ( const Server &server, mServers ) + for ( const Server &server : std::as_const( mServers ) ) { serverUrls << server.url; } } - Q_FOREACH ( const QString &serverUrl, serverUrls ) + for ( const QString &serverUrl : serverUrls ) { Server myServer = getServer( serverUrl ); QStringList myServerLog; @@ -285,7 +285,7 @@ void TestQgsWcsPublicServers::test() QString myServerLogPath = myServerDir.absolutePath() + "/server.log"; - Q_FOREACH ( const QString &version, versions ) + for ( const QString &version : versions ) { QgsDebugMsg( "server: " + serverUrl + " version: " + version ); QStringList myVersionLog; @@ -311,7 +311,7 @@ void TestQgsWcsPublicServers::test() } myServerUri.setParam( QStringLiteral( "cache" ), QStringLiteral( "AlwaysNetwork" ) ); - Q_FOREACH ( const QString &key, myServer.params.keys() ) + for ( const QString &key : myServer.params.keys() ) { myServerUri.setParam( key, myServer.params.value( key ) ); } @@ -343,7 +343,7 @@ void TestQgsWcsPublicServers::test() int myStep = myCoverages.size() / std::min( mMaxCoverages, myCoverages.size() ); int myStepCount = -1; bool myCoverageFound = false; - Q_FOREACH ( QgsWcsCoverageSummary myCoverage, myCoverages ) + for ( QgsWcsCoverageSummary myCoverage : myCoverages ) { QgsDebugMsg( "coverage: " + myCoverage.identifier ); if ( !mCoverage.isEmpty() && myCoverage.identifier != mCoverage ) continue; @@ -402,7 +402,7 @@ void TestQgsWcsPublicServers::test() QStringList providers; providers << QStringLiteral( "wcs" ) << QStringLiteral( "gdal" ); - Q_FOREACH ( const QString &provider, providers ) + for ( const QString &provider : providers ) { QElapsedTimer time; time.start(); @@ -561,7 +561,7 @@ void TestQgsWcsPublicServers::report() int myCoverageErrCount = 0; int myCoverageWarnCount = 0; - Q_FOREACH ( const QString &myServerDirName, mCacheDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) ) + for ( const QString &myServerDirName : mCacheDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) ) { myServerCount++; QDir myServerDir( mCacheDir.absolutePath() + '/' + myServerDirName ); @@ -578,7 +578,7 @@ void TestQgsWcsPublicServers::report() if ( !myServer.params.isEmpty() ) { myReport += QLatin1String( "
    Additional params: " ); - Q_FOREACH ( const QString &key, myServer.params.keys() ) + for ( const QString &key : myServer.params.keys() ) { myReport += key + '=' + myServer.params.value( key ) + " "; } @@ -589,7 +589,7 @@ void TestQgsWcsPublicServers::report() bool myServerErr = false; bool myServerWarn = false; - Q_FOREACH ( const QString &myVersionDirName, myServerDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) ) + for ( const QString &myVersionDirName : myServerDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) ) { QString myVersionReport; int myVersionCoverageCount = 0; @@ -607,7 +607,7 @@ void TestQgsWcsPublicServers::report() if ( !myVersionLog.value( QStringLiteral( "error" ) ).isEmpty() ) { // Server may have more errors, for each version - //Q_FOREACH ( QString err, myServerLog.values( "error" ) ) + //for ( QString err : myServerLog.values( "error" ) ) //{ //myVersionReport += error( err ); //} @@ -621,7 +621,7 @@ void TestQgsWcsPublicServers::report() QStringList filters; filters << QStringLiteral( "*.log" ); myVersionDir.setNameFilters( filters ); - Q_FOREACH ( const QString &myLogFileName, myVersionDir.entryList( QDir::Files ) ) + for ( const QString &myLogFileName : myVersionDir.entryList( QDir::Files ) ) { if ( myLogFileName == QLatin1String( "version.log" ) ) continue; myVersionCoverageCount++; @@ -644,7 +644,7 @@ void TestQgsWcsPublicServers::report() providers << QStringLiteral( "wcs" ) << QStringLiteral( "gdal" ); bool hasErr = false; - Q_FOREACH ( const QString &provider, providers ) + for ( const QString &provider : providers ) { QString imgPath = myVersionDir.absolutePath() + '/' + QFileInfo( myLogPath ).completeBaseName() + "-" + provider + ".png"; @@ -785,7 +785,7 @@ QMap TestQgsWcsPublicServers::readLog( const QString &fileName if ( myFile.open( QIODevice::ReadOnly ) ) { QTextStream myStream( &myFile ); - Q_FOREACH ( const QString &row, myStream.readAll().split( '\n' ) ) + for ( const QString &row : myStream.readAll().split( '\n' ) ) { int sepIdx = row.indexOf( ':' ); myMap.insert( row.left( sepIdx ), row.mid( sepIdx + 1 ) ); From 260e067b5ae03a87c2d91a4b91d74921b1bfd9f3 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 21 Mar 2021 11:03:19 +1000 Subject: [PATCH 154/377] ...and DEFINITELY no 'foreach'!! --- src/app/qtmain_android.cpp | 2 +- src/core/expression/qgsexpressionfunction.cpp | 2 +- src/core/expression/qgsexpressionfunction.h | 2 +- src/core/pal/feature.cpp | 2 +- src/core/pal/pal.cpp | 4 ++-- src/core/pal/problem.cpp | 4 ++-- src/providers/grass/qgsgrassgislib.cpp | 2 +- src/providers/mssql/qgsmssqlfeatureiterator.cpp | 2 +- src/providers/oracle/ocispatial/qsql_ocispatial.cpp | 4 ++-- src/server/services/wms/qgswmsrenderer.cpp | 4 ++-- tests/code_layout/test_banned_keywords.sh | 3 +++ 11 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/app/qtmain_android.cpp b/src/app/qtmain_android.cpp index e3455c8e058d..7b3aa96d9d68 100644 --- a/src/app/qtmain_android.cpp +++ b/src/app/qtmain_android.cpp @@ -82,7 +82,7 @@ static jboolean startQtApp( JNIEnv *env, jobject /*object*/, jstring paramsStrin env->ReleaseStringUTFChars( environmentString, nativeString ); m_applicationParams = string.split( '\t' ); qDebug() << "environmentString" << string << m_applicationParams; - foreach ( string, m_applicationParams ) + for ( string : m_applicationParams ) if ( putenv( string.constData() ) ) qWarning() << "Can't set environment" << string; diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index 2df8fb5cbfb2..9b09e053a9a1 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -7351,7 +7351,7 @@ const QStringList &QgsExpression::BuiltinFunctions() QgsArrayForeachExpressionFunction::QgsArrayForeachExpressionFunction() - : QgsExpressionFunction( QStringLiteral( "array_foreach" ), QgsExpressionFunction::ParameterList() + : QgsExpressionFunction( QStringLiteral( "array_foreach" ), QgsExpressionFunction::ParameterList() // skip-keyword-check << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "expression" ) ), QStringLiteral( "Arrays" ) ) diff --git a/src/core/expression/qgsexpressionfunction.h b/src/core/expression/qgsexpressionfunction.h index dca2ea592e39..675856758e4f 100644 --- a/src/core/expression/qgsexpressionfunction.h +++ b/src/core/expression/qgsexpressionfunction.h @@ -522,7 +522,7 @@ class QgsStaticExpressionFunction : public QgsExpressionFunction }; /** - * \brief Handles the ``array_foreach(array, expression)`` expression function. + * \brief Handles the array looping``array_Foreach(array, expression)`` expression function. * It temporarily appends a new scope to the expression context. * * \ingroup core diff --git a/src/core/pal/feature.cpp b/src/core/pal/feature.cpp index cfc36862e788..1718456e149d 100644 --- a/src/core/pal/feature.cpp +++ b/src/core/pal/feature.cpp @@ -1660,7 +1660,7 @@ std::size_t FeaturePart::createCandidatesForPolygon( std::vector< std::unique_pt std::vector< OrientedConvexHullBoundingBox > boxes; boxes.reserve( shapes_final.size() ); - // Compute bounding box foreach finalShape + // Compute bounding box for each finalShape while ( !shapes_final.isEmpty() ) { PointSet *shape = shapes_final.takeFirst(); diff --git a/src/core/pal/pal.cpp b/src/core/pal/pal.cpp index 6ee5c9e56b21..79c5b984a87a 100644 --- a/src/core/pal/pal.cpp +++ b/src/core/pal/pal.cpp @@ -311,7 +311,7 @@ std::unique_ptr Pal::extract( const QgsRectangle &extent, const QgsGeom } int idlp = 0; - for ( std::size_t i = 0; i < prob->mFeatureCount; i++ ) /* foreach feature into prob */ + for ( std::size_t i = 0; i < prob->mFeatureCount; i++ ) /* for each feature into prob */ { std::unique_ptr< Feats > feat = std::move( features.front() ); features.pop_front(); @@ -424,7 +424,7 @@ std::unique_ptr Pal::extract( const QgsRectangle &extent, const QgsGeom double amin[2]; double amax[2]; - while ( !features.empty() ) // foreach feature + while ( !features.empty() ) // for each feature { if ( isCanceled() ) return nullptr; diff --git a/src/core/pal/problem.cpp b/src/core/pal/problem.cpp index 14e89b239b17..855531cb98f4 100644 --- a/src/core/pal/problem.cpp +++ b/src/core/pal/problem.cpp @@ -90,7 +90,7 @@ void Problem::reduce() for ( i = 0; i < static_cast< int >( mFeatureCount ); i++ ) { // ok[i] = true; - for ( j = 0; j < mFeatNbLp[i]; j++ ) // foreach candidate + for ( j = 0; j < mFeatNbLp[i]; j++ ) // for each candidate { if ( !ok[mFeatStartId[i] + j] ) { @@ -503,7 +503,7 @@ inline Chain *Problem::chain( int seed ) { conflicts.clear(); } - } // end foreach labelposition + } // end for each labelposition if ( next_seed == -1 ) { diff --git a/src/providers/grass/qgsgrassgislib.cpp b/src/providers/grass/qgsgrassgislib.cpp index e4c3dcdd1b74..9f996ab381e0 100644 --- a/src/providers/grass/qgsgrassgislib.cpp +++ b/src/providers/grass/qgsgrassgislib.cpp @@ -455,7 +455,7 @@ QgsGrassGisLib::Raster QgsGrassGisLib::raster( QString name ) { QgsDebugMsg( "name = " + name ); - foreach ( Raster raster, mRasters ) + for ( Raster raster : mRasters ) { if ( raster.name == name ) return raster; } diff --git a/src/providers/mssql/qgsmssqlfeatureiterator.cpp b/src/providers/mssql/qgsmssqlfeatureiterator.cpp index f03fbf40b845..716801e8bc5d 100644 --- a/src/providers/mssql/qgsmssqlfeatureiterator.cpp +++ b/src/providers/mssql/qgsmssqlfeatureiterator.cpp @@ -498,7 +498,7 @@ bool QgsMssqlFeatureIterator::fetchFeature( QgsFeature &feature ) case PktFidMap: { QVariantList primaryKeyVals; - foreach ( int idx, mSource->mPrimaryKeyAttrs ) + for ( int idx : mSource->mPrimaryKeyAttrs ) { QgsField fld = mSource->mFields.at( idx ); diff --git a/src/providers/oracle/ocispatial/qsql_ocispatial.cpp b/src/providers/oracle/ocispatial/qsql_ocispatial.cpp index 98c147b0316f..c788ee58ae43 100644 --- a/src/providers/oracle/ocispatial/qsql_ocispatial.cpp +++ b/src/providers/oracle/ocispatial/qsql_ocispatial.cpp @@ -657,14 +657,14 @@ int QOCISpatialResultPrivate::bindValue( OCIStmt *sql, OCIBind **hbnd, OCIError geometryInd->elem_info = g.eleminfo.size() == 0 ? OCI_IND_NULL : OCI_IND_NOTNULL; geometryInd->ordinates = g.ordinates.size() == 0 ? OCI_IND_NULL : OCI_IND_NOTNULL; - foreach ( int e, g.eleminfo ) + for ( int e : g.eleminfo ) { OCINumber n; OCI_VERIFY_E( err, OCINumberFromInt( err, &e, sizeof( int ), OCI_NUMBER_SIGNED, &n ) ); OCI_VERIFY_E( err, OCICollAppend( env, err, &n, nullptr, geometryObj->elem_info ) ); } - foreach ( double o, g.ordinates ) + for ( double o : g.ordinates ) { OCINumber n; OCI_VERIFY_E( err, OCINumberFromReal( err, &o, sizeof( double ), &n ) ); diff --git a/src/server/services/wms/qgswmsrenderer.cpp b/src/server/services/wms/qgswmsrenderer.cpp index 2fe5e58ff471..e6164957145e 100644 --- a/src/server/services/wms/qgswmsrenderer.cpp +++ b/src/server/services/wms/qgswmsrenderer.cpp @@ -1734,8 +1734,8 @@ namespace QgsWms parentElem.appendChild( nameElem ); } - QList children = container->children(); - foreach ( const QgsAttributeEditorElement *child, children ) + const QList children = container->children(); + for ( const QgsAttributeEditorElement *child : children ) { if ( child->type() == QgsAttributeEditorElement::AeTypeContainer ) { diff --git a/tests/code_layout/test_banned_keywords.sh b/tests/code_layout/test_banned_keywords.sh index 5b27a506c496..cd797703626a 100755 --- a/tests/code_layout/test_banned_keywords.sh +++ b/tests/code_layout/test_banned_keywords.sh @@ -134,6 +134,9 @@ HINTS[36]="Use \brief instead (works correct with Python docstrings)" KEYWORDS[37]="Q_FOREACH" HINTS[37]="Use range based for loops instead" +KEYWORDS[38]="foreach" +HINTS[38]="Use range based for loops instead" + RES= DIR=$(git rev-parse --show-toplevel) From b1d809ea239d2125764e5a1a827dd67096d331d1 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 21 Mar 2021 11:41:39 +1000 Subject: [PATCH 155/377] Fixups --- src/providers/wfs/qgswfssubsetstringeditor.cpp | 2 +- src/python/qgspythonutilsimpl.cpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/providers/wfs/qgswfssubsetstringeditor.cpp b/src/providers/wfs/qgswfssubsetstringeditor.cpp index 0c95266ed929..25d9f0df21d1 100644 --- a/src/providers/wfs/qgswfssubsetstringeditor.cpp +++ b/src/providers/wfs/qgswfssubsetstringeditor.cpp @@ -44,7 +44,7 @@ QgsSubsetStringEditorInterface *QgsWfsSubsetStringEditor::create( QgsVectorLayer d->setSupportMultipleTables( bSupportJoins, QgsSQLStatement::quotedIdentifierIfNeeded( displayedTypeName ) ); QMap< QString, QString > mapTypenameToTitle; - for ( const QgsWfsCapabilities::FeatureType f : std::as_const( caps.featureTypes ) ) + for ( const QgsWfsCapabilities::FeatureType &f : std::as_const( caps.featureTypes ) ) mapTypenameToTitle[f.name] = f.title; QList< QgsSQLComposerDialog::PairNameTitle > tablenames; diff --git a/src/python/qgspythonutilsimpl.cpp b/src/python/qgspythonutilsimpl.cpp index 5979e88c778e..18b7b468551a 100644 --- a/src/python/qgspythonutilsimpl.cpp +++ b/src/python/qgspythonutilsimpl.cpp @@ -111,15 +111,15 @@ bool QgsPythonUtilsImpl::checkSystemImports() // set PyQt api versions for ( const QString &clsName : -{ - QStringLiteral( "QDate" ), - QStringLiteral( "QDateTime" ), - QStringLiteral( "QString" ), - QStringLiteral( "QTextStream" ), - QStringLiteral( "QTime" ), - QStringLiteral( "QUrl" ), - QStringLiteral( "QVariant" ) - } ) + { + QStringLiteral( "QDate" ), + QStringLiteral( "QDateTime" ), + QStringLiteral( "QString" ), + QStringLiteral( "QTextStream" ), + QStringLiteral( "QTime" ), + QStringLiteral( "QUrl" ), + QStringLiteral( "QVariant" ) + } ) { if ( !runString( QStringLiteral( "sip.setapi('%1', 2)" ).arg( clsName ), QObject::tr( "Couldn't set SIP API versions." ) + '\n' + QObject::tr( "Python support will be disabled." ) ) ) From c1e26f90674bb6b2b5a529f2f52adbeb661b4b7a Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 21 Mar 2021 12:03:11 +1000 Subject: [PATCH 156/377] Fix build --- src/providers/oracle/qgsoraclesourceselect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/providers/oracle/qgsoraclesourceselect.cpp b/src/providers/oracle/qgsoraclesourceselect.cpp index 9b5ee51f9390..6c851e352226 100644 --- a/src/providers/oracle/qgsoraclesourceselect.cpp +++ b/src/providers/oracle/qgsoraclesourceselect.cpp @@ -59,7 +59,7 @@ QWidget *QgsOracleSourceSelectDelegate::createEditor( QWidget *parent, const QSt QComboBox *cb = new QComboBox( parent ); for ( QgsWkbTypes::Type type : { - QgsWkbTypes::Poin, + QgsWkbTypes::Point, QgsWkbTypes::LineString, QgsWkbTypes::Polygon, QgsWkbTypes::MultiPoint, From 9e3b89b19cae78a4506e7e476e9e6b8f3d77ba63 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 21 Mar 2021 12:30:00 +1000 Subject: [PATCH 157/377] Fix warning --- tests/src/core/testqgsvectorlayerjoinbuffer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/src/core/testqgsvectorlayerjoinbuffer.cpp b/tests/src/core/testqgsvectorlayerjoinbuffer.cpp index 457db69c0c0d..5dfebb5a3d60 100644 --- a/tests/src/core/testqgsvectorlayerjoinbuffer.cpp +++ b/tests/src/core/testqgsvectorlayerjoinbuffer.cpp @@ -160,7 +160,7 @@ void TestVectorLayerJoinBuffer::initTestCase() fX1.setAttribute( QStringLiteral( "value_x2" ), 222 ); // Commit features and layers to qgis - for ( const QString provider : mProviders ) + for ( const QString &provider : mProviders ) { QgsVectorLayer *vl = mLayers.value( QPair( QStringLiteral( "A" ), provider ) ); vl->dataProvider()->addFeatures( QgsFeatureList() << fA1 << fA2 ); @@ -168,7 +168,7 @@ void TestVectorLayerJoinBuffer::initTestCase() mProject.addMapLayer( vl ); } - for ( const QString provider : mProviders ) + for ( const QString &provider : mProviders ) { QgsVectorLayer *vl = mLayers.value( QPair( QStringLiteral( "B" ), provider ) ); vl->dataProvider()->addFeatures( QgsFeatureList() << fB1 << fB2 ); @@ -176,7 +176,7 @@ void TestVectorLayerJoinBuffer::initTestCase() mProject.addMapLayer( vl ); } - for ( const QString provider : mProviders ) + for ( const QString &provider : mProviders ) { QgsVectorLayer *vl = mLayers.value( QPair( QStringLiteral( "C" ), provider ) ); vl->dataProvider()->addFeatures( QgsFeatureList() << fC1 ); @@ -184,7 +184,7 @@ void TestVectorLayerJoinBuffer::initTestCase() mProject.addMapLayer( vl ); } - for ( const QString provider : mProviders ) + for ( const QString &provider : mProviders ) { QgsVectorLayer *vl = mLayers.value( QPair( QStringLiteral( "X" ), provider ) ); vl->dataProvider()->addFeatures( QgsFeatureList() << fX1 ); From 995c68e4c7ac6ac90743d4417335c64a5876df2f Mon Sep 17 00:00:00 2001 From: vcloarec Date: Sat, 20 Mar 2021 23:43:27 -0400 Subject: [PATCH 158/377] add temporal controller ui file to GUI_UI headers --- src/gui/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 400f5f75a1a1..004b010a2fe9 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -1324,7 +1324,7 @@ set(QGIS_GUI_UI_HDRS ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsmeshlayerpropertiesbase.h ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsmeshdatasetgrouptreewidgetbase.h ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgsmeshstaticdatasetwidgetbase.h - + ${CMAKE_CURRENT_BINARY_DIR}/../ui/ui_qgstemporalcontrollerwidgetbase.h ) if(ENABLE_MODELTEST) From 7aedf3065cbccbd7a6b8c60db844994c92176f6a Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 20 Mar 2021 08:41:32 +1000 Subject: [PATCH 159/377] [feature] Add new "balloon" (speech bubble) callout style --- .../auto_generated/callouts/qgscallout.sip.in | 179 +++++++ src/core/callouts/qgscallout.cpp | 246 +++++++++ src/core/callouts/qgscallout.h | 171 +++++++ src/core/callouts/qgscalloutsregistry.cpp | 1 + src/gui/callouts/qgscalloutwidget.cpp | 147 ++++++ src/gui/callouts/qgscalloutwidget.h | 34 ++ src/gui/labeling/qgslabelinggui.cpp | 1 + src/ui/callouts/widget_ballooncallout.ui | 480 ++++++++++++++++++ 8 files changed, 1259 insertions(+) create mode 100644 src/ui/callouts/widget_ballooncallout.ui diff --git a/python/core/auto_generated/callouts/qgscallout.sip.in b/python/core/auto_generated/callouts/qgscallout.sip.in index 69f5b1fdd086..8674950f446c 100644 --- a/python/core/auto_generated/callouts/qgscallout.sip.in +++ b/python/core/auto_generated/callouts/qgscallout.sip.in @@ -38,6 +38,10 @@ relevant symbology elements to render them. { sipType = sipType_QgsCurvedLineCallout; } + else if ( sipCpp->type() == "balloon" && dynamic_cast( sipCpp ) != NULL ) + { + sipType = sipType_QgsBalloonCallout; + } else { sipType = 0; @@ -59,6 +63,7 @@ relevant symbology elements to render them. DestinationY, Curvature, Orientation, + Margins, }; enum DrawOrder @@ -819,6 +824,180 @@ Sets the callout line's curve ``orientation``. }; +class QgsBalloonCallout : QgsCallout +{ +%Docstring +A cartoon talking bubble callout style. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgscallout.h" +%End + public: + + QgsBalloonCallout(); + ~QgsBalloonCallout(); + + + static QgsCallout *create( const QVariantMap &properties = QVariantMap(), const QgsReadWriteContext &context = QgsReadWriteContext() ) /Factory/; +%Docstring +Creates a new QgsBalloonCallout, using the settings +serialized in the ``properties`` map (corresponding to the output from +:py:func:`QgsBalloonCallout.properties()` ). +%End + + virtual QString type() const; + + virtual QgsBalloonCallout *clone() const; + + virtual QVariantMap properties( const QgsReadWriteContext &context ) const; + + virtual void readProperties( const QVariantMap &props, const QgsReadWriteContext &context ); + + virtual void startRender( QgsRenderContext &context ); + + virtual void stopRender( QgsRenderContext &context ); + + virtual QSet< QString > referencedFields( const QgsRenderContext &context ) const; + + + QgsFillSymbol *fillSymbol(); +%Docstring +Returns the fill symbol used to render the callout. + +Ownership is not transferred. + +.. seealso:: :py:func:`setFillSymbol` +%End + + void setFillSymbol( QgsFillSymbol *symbol /Transfer/ ); +%Docstring +Sets the fill ``symbol`` used to render the callout. Ownership of ``symbol`` is +transferred to the callout. + +.. seealso:: :py:func:`fillSymbol` +%End + + double offsetFromAnchor() const; +%Docstring +Returns the offset distance from the anchor point at which to start the line. Units are specified through :py:func:`~QgsBalloonCallout.offsetFromAnchorUnit`. + +.. seealso:: :py:func:`setOffsetFromAnchor` + +.. seealso:: :py:func:`offsetFromAnchorUnit` +%End + + void setOffsetFromAnchor( double distance ); +%Docstring +Sets the offset ``distance`` from the anchor point at which to start the line. Units are specified through :py:func:`~QgsBalloonCallout.setOffsetFromAnchorUnit`. + +.. seealso:: :py:func:`offsetFromAnchor` + +.. seealso:: :py:func:`setOffsetFromAnchorUnit` +%End + + void setOffsetFromAnchorUnit( QgsUnitTypes::RenderUnit unit ); +%Docstring +Sets the ``unit`` for the offset from anchor distance. + +.. seealso:: :py:func:`offsetFromAnchor` + +.. seealso:: :py:func:`setOffsetFromAnchor` +%End + + QgsUnitTypes::RenderUnit offsetFromAnchorUnit() const; +%Docstring +Returns the units for the offset from anchor point. + +.. seealso:: :py:func:`setOffsetFromAnchorUnit` + +.. seealso:: :py:func:`offsetFromAnchor` +%End + + void setOffsetFromAnchorMapUnitScale( const QgsMapUnitScale &scale ); +%Docstring +Sets the map unit ``scale`` for the offset from anchor. + +.. seealso:: :py:func:`offsetFromAnchorMapUnitScale` + +.. seealso:: :py:func:`setOffsetFromAnchorUnit` + +.. seealso:: :py:func:`setOffsetFromAnchor` +%End + + const QgsMapUnitScale &offsetFromAnchorMapUnitScale() const; +%Docstring +Returns the map unit scale for the offset from anchor. + +.. seealso:: :py:func:`setOffsetFromAnchorMapUnitScale` + +.. seealso:: :py:func:`offsetFromAnchorUnit` + +.. seealso:: :py:func:`offsetFromAnchor` +%End + + const QgsMargins &margins() const; +%Docstring +Returns the margins between the outside of the callout frame and the label's bounding rectangle. + +Units are retrieved via :py:func:`~QgsBalloonCallout.marginsUnit` + +.. note:: + + Negative margins are acceptable. + +.. seealso:: :py:func:`setMargins` + +.. seealso:: :py:func:`marginsUnit` +%End + + void setMargins( const QgsMargins &margins ); +%Docstring +Sets the ``margins`` between the outside of the callout frame and the label's bounding rectangle. + +Units are set via :py:func:`~QgsBalloonCallout.setMarginsUnit` + +.. note:: + + Negative margins are acceptable. + +.. seealso:: :py:func:`margins` + +.. seealso:: :py:func:`setMarginsUnit` +%End + + void setMarginsUnit( QgsUnitTypes::RenderUnit unit ); +%Docstring +Sets the ``unit`` for the margins between the outside of the callout frame and the label's bounding rectangle. + +.. seealso:: :py:func:`margins` + +.. seealso:: :py:func:`marginsUnit` +%End + + QgsUnitTypes::RenderUnit marginsUnit() const; +%Docstring +Returns the units for the margins between the outside of the callout frame and the label's bounding rectangle. + +.. seealso:: :py:func:`setMarginsUnit` + +.. seealso:: :py:func:`margins` +%End + + protected: + virtual void draw( QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ); + + + private: + QgsBalloonCallout( const QgsBalloonCallout &other ); + QgsBalloonCallout &operator=( const QgsBalloonCallout & ); +}; + + + + /************************************************************************ * This file has been generated automatically from * * * diff --git a/src/core/callouts/qgscallout.cpp b/src/core/callouts/qgscallout.cpp index 07b94cf92c3d..74c220e7a35f 100644 --- a/src/core/callouts/qgscallout.cpp +++ b/src/core/callouts/qgscallout.cpp @@ -19,6 +19,7 @@ #include "qgsrendercontext.h" #include "qgssymbol.h" #include "qgslinesymbollayer.h" +#include "qgsfillsymbollayer.h" #include "qgssymbollayerutils.h" #include "qgsxmlutils.h" #include "qgslinestring.h" @@ -26,6 +27,7 @@ #include "qgsgeos.h" #include "qgsgeometryutils.h" #include "qgscircularstring.h" +#include "qgsshapegenerator.h" #include #include @@ -57,6 +59,9 @@ void QgsCallout::initPropertyDefinitions() { QgsCallout::Orientation, QgsPropertyDefinition( "Orientation", QgsPropertyDefinition::DataTypeString, QObject::tr( "Callout curve orientation" ), QObject::tr( "string " ) + "[auto|clockwise|counterclockwise]", origin ) }, + { + QgsCallout::Margins, QgsPropertyDefinition( "Margins", QgsPropertyDefinition::DataTypeString, QObject::tr( "Margins" ), QObject::tr( "string of four doubles 'top,right,bottom,left' or array of doubles [top, right, bottom, left]" ) ) + }, }; } @@ -993,3 +998,244 @@ void QgsCurvedLineCallout::setCurvature( double curvature ) { mCurvature = curvature; } + + + +// +// QgsBalloonCallout +// + +QgsBalloonCallout::QgsBalloonCallout() +{ + mFillSymbol = std::make_unique< QgsFillSymbol >( QgsSymbolLayerList() << new QgsSimpleFillSymbolLayer( QColor( 255, 200, 60 ) ) ); +} + +QgsBalloonCallout::~QgsBalloonCallout() = default; + +QgsBalloonCallout::QgsBalloonCallout( const QgsBalloonCallout &other ) + : QgsCallout( other ) + , mFillSymbol( other.mFillSymbol ? other.mFillSymbol->clone() : nullptr ) + , mOffsetFromAnchorDistance( other.mOffsetFromAnchorDistance ) + , mOffsetFromAnchorUnit( other.mOffsetFromAnchorUnit ) + , mOffsetFromAnchorScale( other.mOffsetFromAnchorScale ) + , mMargins( other.mMargins ) + , mMarginUnit( other.mMarginUnit ) +{ + +} + +QgsCallout *QgsBalloonCallout::create( const QVariantMap &properties, const QgsReadWriteContext &context ) +{ + std::unique_ptr< QgsBalloonCallout > callout = std::make_unique< QgsBalloonCallout >(); + callout->readProperties( properties, context ); + return callout.release(); +} + +QString QgsBalloonCallout::type() const +{ + return QStringLiteral( "balloon" ); +} + +QgsBalloonCallout *QgsBalloonCallout::clone() const +{ + return new QgsBalloonCallout( *this ); +} + +QVariantMap QgsBalloonCallout::properties( const QgsReadWriteContext &context ) const +{ + QVariantMap props = QgsCallout::properties( context ); + + if ( mFillSymbol ) + { + props[ QStringLiteral( "fillSymbol" ) ] = QgsSymbolLayerUtils::symbolProperties( mFillSymbol.get() ); + } + + props[ QStringLiteral( "offsetFromAnchor" ) ] = mOffsetFromAnchorDistance; + props[ QStringLiteral( "offsetFromAnchorUnit" ) ] = QgsUnitTypes::encodeUnit( mOffsetFromAnchorUnit ); + props[ QStringLiteral( "offsetFromAnchorMapUnitScale" ) ] = QgsSymbolLayerUtils::encodeMapUnitScale( mOffsetFromAnchorScale ); + + props[ QStringLiteral( "margins" ) ] = mMargins.toString(); + props[ QStringLiteral( "marginsUnit" ) ] = QgsUnitTypes::encodeUnit( mMarginUnit ); + + return props; +} + +void QgsBalloonCallout::readProperties( const QVariantMap &props, const QgsReadWriteContext &context ) +{ + QgsCallout::readProperties( props, context ); + + const QString fillSymbolDef = props.value( QStringLiteral( "fillSymbol" ) ).toString(); + QDomDocument doc( QStringLiteral( "symbol" ) ); + doc.setContent( fillSymbolDef ); + QDomElement symbolElem = doc.firstChildElement( QStringLiteral( "symbol" ) ); + std::unique_ptr< QgsFillSymbol > fillSymbol( QgsSymbolLayerUtils::loadSymbol< QgsFillSymbol >( symbolElem, context ) ); + if ( fillSymbol ) + mFillSymbol = std::move( fillSymbol ); + + mOffsetFromAnchorDistance = props.value( QStringLiteral( "offsetFromAnchor" ), 0 ).toDouble(); + mOffsetFromAnchorUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "offsetFromAnchorUnit" ) ).toString() ); + mOffsetFromAnchorScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "offsetFromAnchorMapUnitScale" ) ).toString() ); + + mMargins = QgsMargins::fromString( props.value( QStringLiteral( "margins" ) ).toString() ); + mMarginUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "marginsUnit" ) ).toString() ); +} + +void QgsBalloonCallout::startRender( QgsRenderContext &context ) +{ + QgsCallout::startRender( context ); + if ( mFillSymbol ) + mFillSymbol->startRender( context ); +} + +void QgsBalloonCallout::stopRender( QgsRenderContext &context ) +{ + QgsCallout::stopRender( context ); + if ( mFillSymbol ) + mFillSymbol->stopRender( context ); +} + +QSet QgsBalloonCallout::referencedFields( const QgsRenderContext &context ) const +{ + QSet fields = QgsCallout::referencedFields( context ); + if ( mFillSymbol ) + fields.unite( mFillSymbol->usedAttributes( context ) ); + return fields; +} + +QgsFillSymbol *QgsBalloonCallout::fillSymbol() +{ + return mFillSymbol.get(); +} + +void QgsBalloonCallout::setFillSymbol( QgsFillSymbol *symbol ) +{ + mFillSymbol.reset( symbol ); +} + +void QgsBalloonCallout::draw( QgsRenderContext &context, const QRectF &rect, const double, const QgsGeometry &anchor, QgsCalloutContext &calloutContext ) +{ + bool destinationIsPinned = false; + QgsGeometry line = calloutLineToPart( QgsGeometry::fromRect( rect ), anchor.constGet(), context, calloutContext, destinationIsPinned ); + + double offsetFromAnchor = mOffsetFromAnchorDistance; + if ( dataDefinedProperties().isActive( QgsCallout::OffsetFromAnchor ) ) + { + context.expressionContext().setOriginalValueVariable( offsetFromAnchor ); + offsetFromAnchor = dataDefinedProperties().valueAsDouble( QgsCallout::OffsetFromAnchor, context.expressionContext(), offsetFromAnchor ); + } + const double offsetFromAnchorPixels = context.convertToPainterUnits( offsetFromAnchor, mOffsetFromAnchorUnit, mOffsetFromAnchorScale ); + + if ( offsetFromAnchorPixels > 0 ) + { + if ( const QgsLineString *ls = qgsgeometry_cast< const QgsLineString * >( line.constGet() ) ) + { + line = QgsGeometry( ls->curveSubstring( 0, ls->length() - offsetFromAnchorPixels ) ); + } + } + + QgsPointXY destination; + QgsPointXY origin; + if ( const QgsLineString *ls = qgsgeometry_cast< const QgsLineString * >( line.constGet() ) ) + { + origin = ls->startPoint(); + destination = ls->endPoint(); + } + else + { + destination = QgsPointXY( rect.center() ); + } + + const QPolygonF points = getPoints( context, destination, rect ); + if ( points.empty() ) + return; + + if ( !origin.isEmpty() ) + { + QgsCalloutPosition position; + position.setOrigin( context.mapToPixel().toMapCoordinates( origin.x(), origin.y() ).toQPointF() ); + position.setOriginIsPinned( false ); + position.setDestination( context.mapToPixel().toMapCoordinates( destination.x(), destination.y() ).toQPointF() ); + position.setDestinationIsPinned( destinationIsPinned ); + calloutContext.addCalloutPosition( position ); + } + + mFillSymbol->renderPolygon( points, nullptr, nullptr, context ); +} + +QPolygonF QgsBalloonCallout::getPoints( QgsRenderContext &context, QgsPointXY origin, QRectF rect ) const +{ + double segmentPointWidth = context.convertToPainterUnits( 2.64, QgsUnitTypes::RenderMillimeters ); + + double left = mMargins.left(); + double right = mMargins.right(); + double top = mMargins.top(); + double bottom = mMargins.bottom(); + + if ( dataDefinedProperties().isActive( QgsCallout::Margins ) ) + { + const QVariant value = dataDefinedProperties().value( QgsCallout::Margins, context.expressionContext() ); + if ( !value.isNull() ) + { + if ( value.type() == QVariant::List ) + { + const QVariantList list = value.toList(); + if ( list.size() == 4 ) + { + bool topOk = false; + bool rightOk = false; + bool bottomOk = false; + bool leftOk = false; + double evaluatedTop = list.at( 0 ).toDouble( &topOk ); + double evaluatedRight = list.at( 1 ).toDouble( &rightOk ); + double evaluatedBottom = list.at( 2 ).toDouble( &bottomOk ); + double evaluatedLeft = list.at( 3 ).toDouble( &leftOk ); + if ( topOk && rightOk && bottomOk && leftOk ) + { + left = evaluatedLeft; + top = evaluatedTop; + right = evaluatedRight; + bottom = evaluatedBottom; + } + } + } + else + { + const QStringList list = value.toString().trimmed().split( ',' ); + if ( list.count() == 4 ) + { + bool topOk = false; + bool rightOk = false; + bool bottomOk = false; + bool leftOk = false; + double evaluatedTop = list.at( 0 ).toDouble( &topOk ); + double evaluatedRight = list.at( 1 ).toDouble( &rightOk ); + double evaluatedBottom = list.at( 2 ).toDouble( &bottomOk ); + double evaluatedLeft = list.at( 3 ).toDouble( &leftOk ); + if ( topOk && rightOk && bottomOk && leftOk ) + { + left = evaluatedLeft; + top = evaluatedTop; + right = evaluatedRight; + bottom = evaluatedBottom; + } + } + } + } + } + + const double marginLeft = context.convertToPainterUnits( left, mMarginUnit ); + const double marginRight = context.convertToPainterUnits( right, mMarginUnit ); + const double marginTop = context.convertToPainterUnits( top, mMarginUnit ); + const double marginBottom = context.convertToPainterUnits( bottom, mMarginUnit ); + + const QRectF expandedRect( rect.left() - marginLeft, rect.top() + marginBottom, + rect.width() + marginLeft + marginRight, + rect.height() - marginTop - marginBottom ); + + // IMPORTANT -- check for degenerate height is >=0, because QRectF are not normalized and we are using painter + // coordinates with descending vertical axis! + if ( expandedRect.width() <= 0 || expandedRect.height() >= 0 ) + return QPolygonF(); + + return QgsShapeGenerator::createBalloon( origin, expandedRect, segmentPointWidth ); +} diff --git a/src/core/callouts/qgscallout.h b/src/core/callouts/qgscallout.h index 57f5692ac8ee..5df8106dce36 100644 --- a/src/core/callouts/qgscallout.h +++ b/src/core/callouts/qgscallout.h @@ -24,11 +24,13 @@ #include "qgspropertycollection.h" #include "qgsmapunitscale.h" #include "qgscalloutposition.h" +#include "qgsmargins.h" #include #include #include class QgsLineSymbol; +class QgsFillSymbol; class QgsGeometry; class QgsRenderContext; @@ -61,6 +63,10 @@ class CORE_EXPORT QgsCallout { sipType = sipType_QgsCurvedLineCallout; } + else if ( sipCpp->type() == "balloon" && dynamic_cast( sipCpp ) != NULL ) + { + sipType = sipType_QgsBalloonCallout; + } else { sipType = 0; @@ -85,6 +91,7 @@ class CORE_EXPORT QgsCallout DestinationY, //!< Y-coordinate of callout destination (feature anchor) (since QGIS 3.20) Curvature, //!< Curvature of curved line callouts (since QGIS 3.20) Orientation, //!< Orientation of curved line callouts (since QGIS 3.20) + Margins, //!< Margin from text (since QGIS 3.20) }; //! Options for draw order (stacking) of callouts @@ -844,5 +851,169 @@ class CORE_EXPORT QgsCurvedLineCallout : public QgsSimpleLineCallout double mCurvature = 0.1; }; + +/** + * \ingroup core + * \brief A cartoon talking bubble callout style. + * + * \since QGIS 3.20 + */ +class CORE_EXPORT QgsBalloonCallout : public QgsCallout +{ + public: + + QgsBalloonCallout(); + ~QgsBalloonCallout() override; + +#ifndef SIP_RUN + + /** + * Copy constructor. + */ + QgsBalloonCallout( const QgsBalloonCallout &other ); + QgsBalloonCallout &operator=( const QgsBalloonCallout & ) = delete; +#endif + + /** + * Creates a new QgsBalloonCallout, using the settings + * serialized in the \a properties map (corresponding to the output from + * QgsBalloonCallout::properties() ). + */ + static QgsCallout *create( const QVariantMap &properties = QVariantMap(), const QgsReadWriteContext &context = QgsReadWriteContext() ) SIP_FACTORY; + + QString type() const override; + QgsBalloonCallout *clone() const override; + QVariantMap properties( const QgsReadWriteContext &context ) const override; + void readProperties( const QVariantMap &props, const QgsReadWriteContext &context ) override; + void startRender( QgsRenderContext &context ) override; + void stopRender( QgsRenderContext &context ) override; + QSet< QString > referencedFields( const QgsRenderContext &context ) const override; + + /** + * Returns the fill symbol used to render the callout. + * + * Ownership is not transferred. + * + * \see setFillSymbol() + */ + QgsFillSymbol *fillSymbol(); + + /** + * Sets the fill \a symbol used to render the callout. Ownership of \a symbol is + * transferred to the callout. + * + * \see fillSymbol() + */ + void setFillSymbol( QgsFillSymbol *symbol SIP_TRANSFER ); + + /** + * Returns the offset distance from the anchor point at which to start the line. Units are specified through offsetFromAnchorUnit(). + * \see setOffsetFromAnchor() + * \see offsetFromAnchorUnit() + */ + double offsetFromAnchor() const { return mOffsetFromAnchorDistance; } + + /** + * Sets the offset \a distance from the anchor point at which to start the line. Units are specified through setOffsetFromAnchorUnit(). + * \see offsetFromAnchor() + * \see setOffsetFromAnchorUnit() + */ + void setOffsetFromAnchor( double distance ) { mOffsetFromAnchorDistance = distance; } + + /** + * Sets the \a unit for the offset from anchor distance. + * \see offsetFromAnchor() + * \see setOffsetFromAnchor() + */ + void setOffsetFromAnchorUnit( QgsUnitTypes::RenderUnit unit ) { mOffsetFromAnchorUnit = unit; } + + /** + * Returns the units for the offset from anchor point. + * \see setOffsetFromAnchorUnit() + * \see offsetFromAnchor() + */ + QgsUnitTypes::RenderUnit offsetFromAnchorUnit() const { return mOffsetFromAnchorUnit; } + + /** + * Sets the map unit \a scale for the offset from anchor. + * \see offsetFromAnchorMapUnitScale() + * \see setOffsetFromAnchorUnit() + * \see setOffsetFromAnchor() + */ + void setOffsetFromAnchorMapUnitScale( const QgsMapUnitScale &scale ) { mOffsetFromAnchorScale = scale; } + + /** + * Returns the map unit scale for the offset from anchor. + * \see setOffsetFromAnchorMapUnitScale() + * \see offsetFromAnchorUnit() + * \see offsetFromAnchor() + */ + const QgsMapUnitScale &offsetFromAnchorMapUnitScale() const { return mOffsetFromAnchorScale; } + + /** + * Returns the margins between the outside of the callout frame and the label's bounding rectangle. + * + * Units are retrieved via marginsUnit() + * + * \note Negative margins are acceptable. + * + * \see setMargins() + * \see marginsUnit() + */ + const QgsMargins &margins() const { return mMargins; } + + /** + * Sets the \a margins between the outside of the callout frame and the label's bounding rectangle. + * + * Units are set via setMarginsUnit() + * + * \note Negative margins are acceptable. + * + * \see margins() + * \see setMarginsUnit() + */ + void setMargins( const QgsMargins &margins ) { mMargins = margins; } + + /** + * Sets the \a unit for the margins between the outside of the callout frame and the label's bounding rectangle. + * + * \see margins() + * \see marginsUnit() + */ + void setMarginsUnit( QgsUnitTypes::RenderUnit unit ) { mMarginUnit = unit; } + + /** + * Returns the units for the margins between the outside of the callout frame and the label's bounding rectangle. + * + * \see setMarginsUnit() + * \see margins() + */ + QgsUnitTypes::RenderUnit marginsUnit() const { return mMarginUnit; } + + protected: + void draw( QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ) override; + + private: + + QPolygonF getPoints( QgsRenderContext &context, QgsPointXY origin, QRectF rect ) const; + +#ifdef SIP_RUN + QgsBalloonCallout( const QgsBalloonCallout &other ); + QgsBalloonCallout &operator=( const QgsBalloonCallout & ); +#endif + + std::unique_ptr< QgsFillSymbol > mFillSymbol; + + double mOffsetFromAnchorDistance = 0; + QgsUnitTypes::RenderUnit mOffsetFromAnchorUnit = QgsUnitTypes::RenderMillimeters; + QgsMapUnitScale mOffsetFromAnchorScale; + + QgsMargins mMargins; + QgsUnitTypes::RenderUnit mMarginUnit = QgsUnitTypes::RenderMillimeters; + +}; + + + #endif // QGSCALLOUT_H diff --git a/src/core/callouts/qgscalloutsregistry.cpp b/src/core/callouts/qgscalloutsregistry.cpp index 1703d2744598..02c731fd3fe2 100644 --- a/src/core/callouts/qgscalloutsregistry.cpp +++ b/src/core/callouts/qgscalloutsregistry.cpp @@ -52,6 +52,7 @@ QgsCalloutRegistry::QgsCalloutRegistry() addCalloutType( new QgsCalloutMetadata( QStringLiteral( "simple" ), QObject::tr( "Simple lines" ), QgsApplication::getThemeIcon( QStringLiteral( "labelingCalloutSimple.svg" ) ), QgsSimpleLineCallout::create ) ); addCalloutType( new QgsCalloutMetadata( QStringLiteral( "manhattan" ), QObject::tr( "Manhattan lines" ), QgsApplication::getThemeIcon( QStringLiteral( "labelingCalloutManhattan.svg" ) ), QgsManhattanLineCallout::create ) ); addCalloutType( new QgsCalloutMetadata( QStringLiteral( "curved" ), QObject::tr( "Curved lines" ), QgsApplication::getThemeIcon( QStringLiteral( "labelingCalloutSimple.svg" ) ), QgsCurvedLineCallout::create ) ); + addCalloutType( new QgsCalloutMetadata( QStringLiteral( "balloon" ), QObject::tr( "Balloons" ), QgsApplication::getThemeIcon( QStringLiteral( "labelingCalloutManhattan.svg" ) ), QgsBalloonCallout::create ) ); } QgsCalloutRegistry::~QgsCalloutRegistry() diff --git a/src/gui/callouts/qgscalloutwidget.cpp b/src/gui/callouts/qgscalloutwidget.cpp index 58bc8911a7e1..a4868330d7de 100644 --- a/src/gui/callouts/qgscalloutwidget.cpp +++ b/src/gui/callouts/qgscalloutwidget.cpp @@ -520,5 +520,152 @@ void QgsCurvedLineCalloutWidget::drawToAllPartsToggled( bool active ) } +// +// QgsBalloonCalloutWidget +// + +QgsBalloonCalloutWidget::QgsBalloonCalloutWidget( QgsVectorLayer *vl, QWidget *parent ) + : QgsCalloutWidget( parent, vl ) +{ + setupUi( this ); + + // Callout options - to move to custom widgets when multiple callout styles exist + mCalloutFillStyleButton->setSymbolType( QgsSymbol::Fill ); + mCalloutFillStyleButton->setDialogTitle( tr( "Balloon Symbol" ) ); + mCalloutFillStyleButton->registerExpressionContextGenerator( this ); + + mCalloutFillStyleButton->setLayer( vl ); + mOffsetFromAnchorUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels + << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); + mMarginUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels + << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); + + mSpinBottomMargin->setClearValue( 0 ); + mSpinTopMargin->setClearValue( 0 ); + mSpinRightMargin->setClearValue( 0 ); + mSpinLeftMargin->setClearValue( 0 ); + + connect( mOffsetFromAnchorUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsBalloonCalloutWidget::offsetFromAnchorUnitWidgetChanged ); + connect( mOffsetFromAnchorSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsBalloonCalloutWidget::offsetFromAnchorChanged ); + + // Anchor point options + mAnchorPointComboBox->addItem( tr( "Pole of Inaccessibility" ), static_cast< int >( QgsCallout::PoleOfInaccessibility ) ); + mAnchorPointComboBox->addItem( tr( "Point on Exterior" ), static_cast< int >( QgsCallout::PointOnExterior ) ); + mAnchorPointComboBox->addItem( tr( "Point on Surface" ), static_cast< int >( QgsCallout::PointOnSurface ) ); + mAnchorPointComboBox->addItem( tr( "Centroid" ), static_cast< int >( QgsCallout::Centroid ) ); + connect( mAnchorPointComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsBalloonCalloutWidget::mAnchorPointComboBox_currentIndexChanged ); + + connect( mCalloutFillStyleButton, &QgsSymbolButton::changed, this, &QgsBalloonCalloutWidget::fillSymbolChanged ); + + connect( mSpinBottomMargin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value ) + { + QgsMargins margins = mCallout->margins(); + margins.setBottom( value ); + mCallout->setMargins( margins ); + emit changed(); + } ); + connect( mSpinTopMargin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value ) + { + QgsMargins margins = mCallout->margins(); + margins.setTop( value ); + mCallout->setMargins( margins ); + emit changed(); + } ); + connect( mSpinLeftMargin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value ) + { + QgsMargins margins = mCallout->margins(); + margins.setLeft( value ); + mCallout->setMargins( margins ); + emit changed(); + } ); + connect( mSpinRightMargin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value ) + { + QgsMargins margins = mCallout->margins(); + margins.setRight( value ); + mCallout->setMargins( margins ); + emit changed(); + } ); + connect( mMarginUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ] + { + mCallout->setMarginsUnit( mMarginUnitWidget->unit() ); + emit changed(); + } ); + +} + +void QgsBalloonCalloutWidget::setCallout( QgsCallout *callout ) +{ + if ( !callout ) + return; + + mCallout.reset( dynamic_cast( callout->clone() ) ); + if ( !mCallout ) + return; + + mOffsetFromAnchorUnitWidget->blockSignals( true ); + mOffsetFromAnchorUnitWidget->setUnit( mCallout->offsetFromAnchorUnit() ); + mOffsetFromAnchorUnitWidget->setMapUnitScale( mCallout->offsetFromAnchorMapUnitScale() ); + mOffsetFromAnchorUnitWidget->blockSignals( false ); + whileBlocking( mOffsetFromAnchorSpin )->setValue( mCallout->offsetFromAnchor() ); + + whileBlocking( mSpinBottomMargin )->setValue( mCallout->margins().bottom() ); + whileBlocking( mSpinTopMargin )->setValue( mCallout->margins().top() ); + whileBlocking( mSpinLeftMargin )->setValue( mCallout->margins().left() ); + whileBlocking( mSpinRightMargin )->setValue( mCallout->margins().right() ); + whileBlocking( mMarginUnitWidget )->setUnit( mCallout->marginsUnit() ); + + whileBlocking( mCalloutFillStyleButton )->setSymbol( mCallout->fillSymbol()->clone() ); + + whileBlocking( mAnchorPointComboBox )->setCurrentIndex( mAnchorPointComboBox->findData( static_cast< int >( callout->anchorPoint() ) ) ); + + registerDataDefinedButton( mOffsetFromAnchorDDBtn, QgsCallout::OffsetFromAnchor ); + registerDataDefinedButton( mAnchorPointDDBtn, QgsCallout::AnchorPointPosition ); + + registerDataDefinedButton( mDestXDDBtn, QgsCallout::DestinationX ); + registerDataDefinedButton( mDestYDDBtn, QgsCallout::DestinationY ); + registerDataDefinedButton( mMarginsDDBtn, QgsCallout::Margins ); +} + +void QgsBalloonCalloutWidget::setGeometryType( QgsWkbTypes::GeometryType type ) +{ + bool isPolygon = type == QgsWkbTypes::PolygonGeometry; + mAnchorPointLbl->setEnabled( isPolygon ); + mAnchorPointLbl->setVisible( isPolygon ); + mAnchorPointComboBox->setEnabled( isPolygon ); + mAnchorPointComboBox->setVisible( isPolygon ); + mAnchorPointDDBtn->setEnabled( isPolygon ); + mAnchorPointDDBtn->setVisible( isPolygon ); +} + +QgsCallout *QgsBalloonCalloutWidget::callout() +{ + return mCallout.get(); +} + +void QgsBalloonCalloutWidget::offsetFromAnchorUnitWidgetChanged() +{ + mCallout->setOffsetFromAnchorUnit( mOffsetFromAnchorUnitWidget->unit() ); + mCallout->setOffsetFromAnchorMapUnitScale( mOffsetFromAnchorUnitWidget->getMapUnitScale() ); + emit changed(); +} + +void QgsBalloonCalloutWidget::offsetFromAnchorChanged() +{ + mCallout->setOffsetFromAnchor( mOffsetFromAnchorSpin->value() ); + emit changed(); +} + +void QgsBalloonCalloutWidget::fillSymbolChanged() +{ + mCallout->setFillSymbol( mCalloutFillStyleButton->clonedSymbol< QgsFillSymbol >() ); + emit changed(); +} + +void QgsBalloonCalloutWidget::mAnchorPointComboBox_currentIndexChanged( int index ) +{ + mCallout->setAnchorPoint( static_cast( mAnchorPointComboBox->itemData( index ).toInt() ) ); + emit changed(); +} + ///@endcond diff --git a/src/gui/callouts/qgscalloutwidget.h b/src/gui/callouts/qgscalloutwidget.h index 73e10498e372..2a1ff6221e70 100644 --- a/src/gui/callouts/qgscalloutwidget.h +++ b/src/gui/callouts/qgscalloutwidget.h @@ -215,6 +215,40 @@ class GUI_EXPORT QgsCurvedLineCalloutWidget : public QgsCalloutWidget, private U }; +/////////// + +#include "ui_widget_ballooncallout.h" + +class QgsBalloonCallout; + +class GUI_EXPORT QgsBalloonCalloutWidget : public QgsCalloutWidget, private Ui::WidgetBalloonCallout +{ + Q_OBJECT + + public: + + QgsBalloonCalloutWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr ); + + static QgsCalloutWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsBalloonCalloutWidget( vl ); } + + void setCallout( QgsCallout *callout ) override; + + QgsCallout *callout() override; + + void setGeometryType( QgsWkbTypes::GeometryType type ) override; + + private slots: + + void offsetFromAnchorUnitWidgetChanged(); + void offsetFromAnchorChanged(); + void fillSymbolChanged(); + void mAnchorPointComboBox_currentIndexChanged( int index ); + + private: + std::unique_ptr< QgsBalloonCallout > mCallout; + +}; + #endif ///@endcond diff --git a/src/gui/labeling/qgslabelinggui.cpp b/src/gui/labeling/qgslabelinggui.cpp index ed32c2983257..a9e3d64ab985 100644 --- a/src/gui/labeling/qgslabelinggui.cpp +++ b/src/gui/labeling/qgslabelinggui.cpp @@ -85,6 +85,7 @@ void QgsLabelingGui::initCalloutWidgets() _initCalloutWidgetFunction( QStringLiteral( "simple" ), QgsSimpleLineCalloutWidget::create ); _initCalloutWidgetFunction( QStringLiteral( "manhattan" ), QgsManhattanLineCalloutWidget::create ); _initCalloutWidgetFunction( QStringLiteral( "curved" ), QgsCurvedLineCalloutWidget::create ); + _initCalloutWidgetFunction( QStringLiteral( "balloon" ), QgsBalloonCalloutWidget::create ); } void QgsLabelingGui::updateCalloutWidget( QgsCallout *callout ) diff --git a/src/ui/callouts/widget_ballooncallout.ui b/src/ui/callouts/widget_ballooncallout.ui new file mode 100644 index 000000000000..2a8484e7b16a --- /dev/null +++ b/src/ui/callouts/widget_ballooncallout.ui @@ -0,0 +1,480 @@ + + + WidgetBalloonCallout + + + + 0 + 0 + 371 + 425 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + + + Offset from feature + + + + + + + + 0 + 0 + + + + Symbol… + + + + + + + + + + + + + + + + + + + + + Fill style + + + + + + + Anchor point + + + + + + + + + + + 1 + 0 + + + + 6 + + + 100000.000000000000000 + + + 0.200000000000000 + + + 0.000000000000000 + + + true + + + + + + + + 10 + 0 + + + + Qt::StrongFocus + + + + + + + + + Margins + + + + + + + 10 + 0 + + + + Qt::StrongFocus + + + + + + + Units + + + + + + + Data defined + + + + + + + Bottom + + + + + + + + 1 + 0 + + + + + + + 6 + + + -10000000.000000000000000 + + + 10000000.000000000000000 + + + 0.200000000000000 + + + 1.000000000000000 + + + + + + + Left + + + + + + + Top + + + + + + + + 1 + 0 + + + + + + + 6 + + + -10000000.000000000000000 + + + 10000000.000000000000000 + + + 0.200000000000000 + + + 1.000000000000000 + + + + + + + + 1 + 0 + + + + + + + 6 + + + -10000000.000000000000000 + + + 10000000.000000000000000 + + + 0.200000000000000 + + + 1.000000000000000 + + + + + + + Right + + + + + + + + 1 + 0 + + + + + + + 6 + + + -10000000.000000000000000 + + + 10000000.000000000000000 + + + 0.200000000000000 + + + 1.000000000000000 + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Data Defined Placement + + + false + + + labelplacementgroup + + + + 8 + + + 8 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 0 + + + + X + + + + + + + + + + + + + + + 0 + 0 + + + + Y + + + + + + + + + + + + + + Qt::Horizontal + + + + 0 + 20 + + + + + + + + + + + + + Destination + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    + + QgsCollapsibleGroupBox + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1 +
    + + QgsSymbolButton + QToolButton +
    qgssymbolbutton.h
    +
    + + QgsPropertyOverrideButton + QToolButton +
    qgspropertyoverridebutton.h
    +
    + + QgsUnitSelectionWidget + QWidget +
    qgsunitselectionwidget.h
    + 1 +
    +
    + + mCalloutFillStyleButton + + + +
    From 3abe2b96dcdfe76421ef91b8b3a11aae57baf48c Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 21 Mar 2021 08:30:00 +1000 Subject: [PATCH 160/377] Expose control over balloon wedge width --- .../auto_generated/callouts/qgscallout.sip.in | 64 +++++++++++++++ src/core/callouts/qgscallout.cpp | 20 ++++- src/core/callouts/qgscallout.h | 60 ++++++++++++++ src/core/qgsshapegenerator.cpp | 10 ++- src/gui/callouts/qgscalloutwidget.cpp | 21 +++++ src/ui/callouts/widget_ballooncallout.ui | 80 +++++++++++++++---- 6 files changed, 237 insertions(+), 18 deletions(-) diff --git a/python/core/auto_generated/callouts/qgscallout.sip.in b/python/core/auto_generated/callouts/qgscallout.sip.in index 8674950f446c..77506411d95b 100644 --- a/python/core/auto_generated/callouts/qgscallout.sip.in +++ b/python/core/auto_generated/callouts/qgscallout.sip.in @@ -64,6 +64,7 @@ relevant symbology elements to render them. Curvature, Orientation, Margins, + WedgeWidth, }; enum DrawOrder @@ -986,6 +987,69 @@ Returns the units for the margins between the outside of the callout frame and t .. seealso:: :py:func:`margins` %End + + double wedgeWidth() const; +%Docstring +Returns the width of the wedge shape at the side it connects with the label. + +Units are specified through :py:func:`~QgsBalloonCallout.wedgeWidthUnit`. + +.. seealso:: :py:func:`setWedgeWidth` + +.. seealso:: :py:func:`wedgeWidthUnit` +%End + + void setWedgeWidth( double width ); +%Docstring +Returns the ``width`` of the wedge shape at the side it connects with the label. + +Units are specified through :py:func:`~QgsBalloonCallout.setWedgeWidthUnit`. + +.. seealso:: :py:func:`wedgeWidth` + +.. seealso:: :py:func:`setWedgeWidthUnit` +%End + + void setWedgeWidthUnit( QgsUnitTypes::RenderUnit unit ); +%Docstring +Sets the ``unit`` for the wedge width. + +.. seealso:: :py:func:`wedgeWidthUnit` + +.. seealso:: :py:func:`setWedgeWidth` +%End + + QgsUnitTypes::RenderUnit wedgeWidthUnit() const; +%Docstring +Returns the units for the wedge width. + +.. seealso:: :py:func:`setWedgeWidthUnit` + +.. seealso:: :py:func:`wedgeWidth` +%End + + void setWedgeWidthMapUnitScale( const QgsMapUnitScale &scale ); +%Docstring +Sets the map unit ``scale`` for the wedge width. + +.. seealso:: :py:func:`wedgeWidthMapUnitScale` + +.. seealso:: :py:func:`setWedgeWidthUnit` + +.. seealso:: :py:func:`setWedgeWidth` +%End + + const QgsMapUnitScale &wedgeWidthMapUnitScale() const; +%Docstring +Returns the map unit scale for the wedge width. + +.. seealso:: :py:func:`setWedgeWidthMapUnitScale` + +.. seealso:: :py:func:`wedgeWidthUnit` + +.. seealso:: :py:func:`wedgeWidth` +%End + protected: virtual void draw( QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ); diff --git a/src/core/callouts/qgscallout.cpp b/src/core/callouts/qgscallout.cpp index 74c220e7a35f..3d73fa6e4fc3 100644 --- a/src/core/callouts/qgscallout.cpp +++ b/src/core/callouts/qgscallout.cpp @@ -62,6 +62,7 @@ void QgsCallout::initPropertyDefinitions() { QgsCallout::Margins, QgsPropertyDefinition( "Margins", QgsPropertyDefinition::DataTypeString, QObject::tr( "Margins" ), QObject::tr( "string of four doubles 'top,right,bottom,left' or array of doubles [top, right, bottom, left]" ) ) }, + { QgsCallout::WedgeWidth, QgsPropertyDefinition( "WedgeWidth", QObject::tr( "Wedge width" ), QgsPropertyDefinition::DoublePositive, origin ) }, }; } @@ -1020,6 +1021,9 @@ QgsBalloonCallout::QgsBalloonCallout( const QgsBalloonCallout &other ) , mOffsetFromAnchorScale( other.mOffsetFromAnchorScale ) , mMargins( other.mMargins ) , mMarginUnit( other.mMarginUnit ) + , mWedgeWidth( other.mWedgeWidth ) + , mWedgeWidthUnit( other.mWedgeWidthUnit ) + , mWedgeWidthScale( other.mWedgeWidthScale ) { } @@ -1057,6 +1061,10 @@ QVariantMap QgsBalloonCallout::properties( const QgsReadWriteContext &context ) props[ QStringLiteral( "margins" ) ] = mMargins.toString(); props[ QStringLiteral( "marginsUnit" ) ] = QgsUnitTypes::encodeUnit( mMarginUnit ); + props[ QStringLiteral( "wedgeWidth" ) ] = mWedgeWidth; + props[ QStringLiteral( "wedgeWidthUnit" ) ] = QgsUnitTypes::encodeUnit( mWedgeWidthUnit ); + props[ QStringLiteral( "wedgeWidthMapUnitScale" ) ] = QgsSymbolLayerUtils::encodeMapUnitScale( mWedgeWidthScale ); + return props; } @@ -1078,6 +1086,10 @@ void QgsBalloonCallout::readProperties( const QVariantMap &props, const QgsReadW mMargins = QgsMargins::fromString( props.value( QStringLiteral( "margins" ) ).toString() ); mMarginUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "marginsUnit" ) ).toString() ); + + mWedgeWidth = props.value( QStringLiteral( "wedgeWidth" ), 2.64 ).toDouble(); + mWedgeWidthUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "wedgeWidthUnit" ) ).toString() ); + mWedgeWidthScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "wedgeWidthMapUnitScale" ) ).toString() ); } void QgsBalloonCallout::startRender( QgsRenderContext &context ) @@ -1164,7 +1176,13 @@ void QgsBalloonCallout::draw( QgsRenderContext &context, const QRectF &rect, con QPolygonF QgsBalloonCallout::getPoints( QgsRenderContext &context, QgsPointXY origin, QRectF rect ) const { - double segmentPointWidth = context.convertToPainterUnits( 2.64, QgsUnitTypes::RenderMillimeters ); + double segmentPointWidth = mWedgeWidth; + if ( dataDefinedProperties().isActive( QgsCallout::WedgeWidth ) ) + { + context.expressionContext().setOriginalValueVariable( segmentPointWidth ); + segmentPointWidth = dataDefinedProperties().valueAsDouble( QgsCallout::WedgeWidth, context.expressionContext(), segmentPointWidth ); + } + segmentPointWidth = context.convertToPainterUnits( segmentPointWidth, mWedgeWidthUnit, mWedgeWidthScale ); double left = mMargins.left(); double right = mMargins.right(); diff --git a/src/core/callouts/qgscallout.h b/src/core/callouts/qgscallout.h index 5df8106dce36..937a4acb9a71 100644 --- a/src/core/callouts/qgscallout.h +++ b/src/core/callouts/qgscallout.h @@ -92,6 +92,7 @@ class CORE_EXPORT QgsCallout Curvature, //!< Curvature of curved line callouts (since QGIS 3.20) Orientation, //!< Orientation of curved line callouts (since QGIS 3.20) Margins, //!< Margin from text (since QGIS 3.20) + WedgeWidth, //!< Balloon callout wedge width (since QGIS 3.20) }; //! Options for draw order (stacking) of callouts @@ -990,6 +991,61 @@ class CORE_EXPORT QgsBalloonCallout : public QgsCallout */ QgsUnitTypes::RenderUnit marginsUnit() const { return mMarginUnit; } + + /** + * Returns the width of the wedge shape at the side it connects with the label. + * + * Units are specified through wedgeWidthUnit(). + * + * \see setWedgeWidth() + * \see wedgeWidthUnit() + */ + double wedgeWidth() const { return mWedgeWidth; } + + /** + * Returns the \a width of the wedge shape at the side it connects with the label. + * + * Units are specified through setWedgeWidthUnit(). + * + * \see wedgeWidth() + * \see setWedgeWidthUnit() + */ + void setWedgeWidth( double width ) { mWedgeWidth = width; } + + /** + * Sets the \a unit for the wedge width. + * + * \see wedgeWidthUnit() + * \see setWedgeWidth() + */ + void setWedgeWidthUnit( QgsUnitTypes::RenderUnit unit ) { mWedgeWidthUnit = unit; } + + /** + * Returns the units for the wedge width. + * + * \see setWedgeWidthUnit() + * \see wedgeWidth() + */ + QgsUnitTypes::RenderUnit wedgeWidthUnit() const { return mWedgeWidthUnit; } + + /** + * Sets the map unit \a scale for the wedge width. + * + * \see wedgeWidthMapUnitScale() + * \see setWedgeWidthUnit() + * \see setWedgeWidth() + */ + void setWedgeWidthMapUnitScale( const QgsMapUnitScale &scale ) { mWedgeWidthScale = scale; } + + /** + * Returns the map unit scale for the wedge width. + * + * \see setWedgeWidthMapUnitScale() + * \see wedgeWidthUnit() + * \see wedgeWidth() + */ + const QgsMapUnitScale &wedgeWidthMapUnitScale() const { return mWedgeWidthScale; } + protected: void draw( QgsRenderContext &context, const QRectF &bodyBoundingBox, const double angle, const QgsGeometry &anchor, QgsCallout::QgsCalloutContext &calloutContext ) override; @@ -1011,6 +1067,10 @@ class CORE_EXPORT QgsBalloonCallout : public QgsCallout QgsMargins mMargins; QgsUnitTypes::RenderUnit mMarginUnit = QgsUnitTypes::RenderMillimeters; + double mWedgeWidth = 2.64; + QgsUnitTypes::RenderUnit mWedgeWidthUnit = QgsUnitTypes::RenderMillimeters; + QgsMapUnitScale mWedgeWidthScale; + }; diff --git a/src/core/qgsshapegenerator.cpp b/src/core/qgsshapegenerator.cpp index 0672893f6d05..ab4ff8f93d88 100644 --- a/src/core/qgsshapegenerator.cpp +++ b/src/core/qgsshapegenerator.cpp @@ -19,6 +19,7 @@ #include "qgsgeometryutils.h" #include #include +#include QLineF segment( int index, QRectF rect ) { @@ -111,18 +112,21 @@ QPolygonF QgsShapeGenerator::createBalloon( const QgsPointXY &origin, const QRec balloonSegment = minEdgeIndex; QPointF minEdgeEnd = minEdge.p2(); balloonSegmentPoint1 = QPointF( minEdgePoint.x(), minEdgePoint.y() ); - if ( std::sqrt( minEdgePoint.sqrDist( minEdgeEnd.x(), minEdgeEnd.y() ) ) < wedgeWidth ) + + const double segmentLength = minEdge.length(); + const double clampedWedgeWidth = std::clamp( wedgeWidth, 0.0, segmentLength ); + if ( std::sqrt( minEdgePoint.sqrDist( minEdgeEnd.x(), minEdgeEnd.y() ) ) < clampedWedgeWidth ) { double x = 0; double y = 0; - QgsGeometryUtils::pointOnLineWithDistance( minEdge.p2().x(), minEdge.p2().y(), minEdge.p1().x(), minEdge.p1().y(), wedgeWidth, x, y ); + QgsGeometryUtils::pointOnLineWithDistance( minEdge.p2().x(), minEdge.p2().y(), minEdge.p1().x(), minEdge.p1().y(), clampedWedgeWidth, x, y ); balloonSegmentPoint1 = QPointF( x, y ); } { double x = 0; double y = 0; - QgsGeometryUtils::pointOnLineWithDistance( balloonSegmentPoint1.x(), balloonSegmentPoint1.y(), minEdge.p2().x(), minEdge.p2().y(), wedgeWidth, x, y ); + QgsGeometryUtils::pointOnLineWithDistance( balloonSegmentPoint1.x(), balloonSegmentPoint1.y(), minEdge.p2().x(), minEdge.p2().y(), clampedWedgeWidth, x, y ); balloonSegmentPoint2 = QPointF( x, y ); } } diff --git a/src/gui/callouts/qgscalloutwidget.cpp b/src/gui/callouts/qgscalloutwidget.cpp index a4868330d7de..dc14ca0537ad 100644 --- a/src/gui/callouts/qgscalloutwidget.cpp +++ b/src/gui/callouts/qgscalloutwidget.cpp @@ -539,11 +539,14 @@ QgsBalloonCalloutWidget::QgsBalloonCalloutWidget( QgsVectorLayer *vl, QWidget *p << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); mMarginUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); + mWedgeWidthUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels + << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); mSpinBottomMargin->setClearValue( 0 ); mSpinTopMargin->setClearValue( 0 ); mSpinRightMargin->setClearValue( 0 ); mSpinLeftMargin->setClearValue( 0 ); + mWedgeWidthSpin->setClearValue( 2.64 ); connect( mOffsetFromAnchorUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsBalloonCalloutWidget::offsetFromAnchorUnitWidgetChanged ); connect( mOffsetFromAnchorSpin, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsBalloonCalloutWidget::offsetFromAnchorChanged ); @@ -591,6 +594,17 @@ QgsBalloonCalloutWidget::QgsBalloonCalloutWidget( QgsVectorLayer *vl, QWidget *p emit changed(); } ); + connect( mWedgeWidthUnitWidget, &QgsUnitSelectionWidget::changed, this, [ = ] + { + mCallout->setWedgeWidthUnit( mWedgeWidthUnitWidget->unit() ); + mCallout->setWedgeWidthMapUnitScale( mWedgeWidthUnitWidget->getMapUnitScale() ); + emit changed(); + } ); + connect( mWedgeWidthSpin, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, [ = ]( double value ) + { + mCallout->setWedgeWidth( value ); + emit changed(); + } ); } void QgsBalloonCalloutWidget::setCallout( QgsCallout *callout ) @@ -614,6 +628,12 @@ void QgsBalloonCalloutWidget::setCallout( QgsCallout *callout ) whileBlocking( mSpinRightMargin )->setValue( mCallout->margins().right() ); whileBlocking( mMarginUnitWidget )->setUnit( mCallout->marginsUnit() ); + mWedgeWidthUnitWidget->blockSignals( true ); + mWedgeWidthUnitWidget->setUnit( mCallout->wedgeWidthUnit() ); + mWedgeWidthUnitWidget->setMapUnitScale( mCallout->wedgeWidthMapUnitScale() ); + mWedgeWidthUnitWidget->blockSignals( false ); + whileBlocking( mWedgeWidthSpin )->setValue( mCallout->wedgeWidth() ); + whileBlocking( mCalloutFillStyleButton )->setSymbol( mCallout->fillSymbol()->clone() ); whileBlocking( mAnchorPointComboBox )->setCurrentIndex( mAnchorPointComboBox->findData( static_cast< int >( callout->anchorPoint() ) ) ); @@ -624,6 +644,7 @@ void QgsBalloonCalloutWidget::setCallout( QgsCallout *callout ) registerDataDefinedButton( mDestXDDBtn, QgsCallout::DestinationX ); registerDataDefinedButton( mDestYDDBtn, QgsCallout::DestinationY ); registerDataDefinedButton( mMarginsDDBtn, QgsCallout::Margins ); + registerDataDefinedButton( mWedgeWidthDDBtn, QgsCallout::WedgeWidth ); } void QgsBalloonCalloutWidget::setGeometryType( QgsWkbTypes::GeometryType type ) diff --git a/src/ui/callouts/widget_ballooncallout.ui b/src/ui/callouts/widget_ballooncallout.ui index 2a8484e7b16a..c3b53372a7ad 100644 --- a/src/ui/callouts/widget_ballooncallout.ui +++ b/src/ui/callouts/widget_ballooncallout.ui @@ -7,7 +7,7 @@ 0 0 371 - 425 + 456 @@ -41,6 +41,13 @@ + + + + + + + @@ -54,10 +61,38 @@ - - + + + + + - + Anchor point + + + + + + + + 1 + 0 + + + + 6 + + + 100000.000000000000000 + + + 0.200000000000000 + + + 0.000000000000000 + + + true @@ -68,6 +103,19 @@ + + + + + 10 + 0 + + + + Qt::StrongFocus + + + @@ -75,18 +123,15 @@ - - + + - Anchor point + Wedge width - - - - - + + 1 @@ -110,8 +155,8 @@ - - + + 10 @@ -123,6 +168,13 @@ + + + + + + + From a68befc52f669090639ca6a1b90bfccbd6647884 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 21 Mar 2021 15:37:53 +1000 Subject: [PATCH 161/377] Unit tests --- tests/src/core/testqgscallout.cpp | 167 ++++++++++++++++++ .../expected_balloon_callout_margin.png | Bin 0 -> 24564 bytes .../expected_balloon_callout_render.png | Bin 0 -> 23718 bytes .../expected_balloon_callout_wedge_width.png | Bin 0 -> 26974 bytes 4 files changed, 167 insertions(+) create mode 100644 tests/testdata/control_images/callouts/expected_balloon_callout_margin/expected_balloon_callout_margin.png create mode 100644 tests/testdata/control_images/callouts/expected_balloon_callout_render/expected_balloon_callout_render.png create mode 100644 tests/testdata/control_images/callouts/expected_balloon_callout_wedge_width/expected_balloon_callout_wedge_width.png diff --git a/tests/src/core/testqgscallout.cpp b/tests/src/core/testqgscallout.cpp index e8dcc49f1760..df2b4e76932a 100644 --- a/tests/src/core/testqgscallout.cpp +++ b/tests/src/core/testqgscallout.cpp @@ -172,6 +172,9 @@ class TestQgsCallout: public QObject void curvedClockwise(); void curvedCounterClockwise(); void curvedCurvature(); + void balloonCallout(); + void balloonCalloutMargin(); + void balloonCalloutWedgeWidth(); private: bool imageCheck( const QString &testName, QImage &image, unsigned int mismatchCount = 0 ); @@ -3886,6 +3889,170 @@ void TestQgsCallout::curvedCurvature() QVERIFY( imageCheck( "curved_curvature", img, 20 ) ); } +void TestQgsCallout::balloonCallout() +{ + QSize size( 640, 480 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setExtent( vl->extent() ); + mapSettings.setLayers( QList() << vl ); + mapSettings.setOutputDpi( 96 ); + + // first render the map and labeling separately + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "Class" ); + settings.placement = QgsPalLayerSettings::AroundPoint; + settings.dist = 7; + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsBalloonCallout *callout = new QgsBalloonCallout(); + callout->setEnabled( true ); + callout->setFillSymbol( QgsFillSymbol::createSimple( QVariantMap( { { "color", "#ffcccc"}, + { "outline-width", "1"} + } ) ) ); + settings.setCallout( callout ); + + vl->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); + vl->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl, QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "balloon_callout_render", img, 20 ) ); +} + +void TestQgsCallout::balloonCalloutMargin() +{ + QSize size( 640, 480 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setExtent( vl->extent() ); + mapSettings.setLayers( QList() << vl ); + mapSettings.setOutputDpi( 96 ); + + // first render the map and labeling separately + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "Class" ); + settings.placement = QgsPalLayerSettings::AroundPoint; + settings.dist = 10; + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsBalloonCallout *callout = new QgsBalloonCallout(); + callout->setEnabled( true ); + callout->setFillSymbol( QgsFillSymbol::createSimple( QVariantMap( { { "color", "#ffcccc"}, + { "outline-width", "1"} + } ) ) ); + callout->setMargins( QgsMargins( 1, 2, 3, 4 ) ); + settings.setCallout( callout ); + + vl->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); + vl->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl, QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "balloon_callout_margin", img, 20 ) ); +} + +void TestQgsCallout::balloonCalloutWedgeWidth() +{ + QSize size( 640, 480 ); + QgsMapSettings mapSettings; + mapSettings.setOutputSize( size ); + mapSettings.setExtent( vl->extent() ); + mapSettings.setLayers( QList() << vl ); + mapSettings.setOutputDpi( 96 ); + + // first render the map and labeling separately + + QgsMapRendererSequentialJob job( mapSettings ); + job.start(); + job.waitForFinished(); + + QImage img = job.renderedImage(); + + QPainter p( &img ); + QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); + context.setPainter( &p ); + + QgsPalLayerSettings settings; + settings.fieldName = QStringLiteral( "Class" ); + settings.placement = QgsPalLayerSettings::AroundPoint; + settings.dist = 10; + + QgsTextFormat format; + format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() ); + format.setSize( 12 ); + format.setNamedStyle( QStringLiteral( "Bold" ) ); + format.setColor( QColor( 200, 0, 200 ) ); + settings.setFormat( format ); + + QgsBalloonCallout *callout = new QgsBalloonCallout(); + callout->setEnabled( true ); + callout->setFillSymbol( QgsFillSymbol::createSimple( QVariantMap( { { "color", "#ffcccc"}, + { "outline-width", "1"} + } ) ) ); + callout->setWedgeWidth( 6 ); + settings.setCallout( callout ); + + vl->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); + vl->setLabelsEnabled( true ); + + QgsDefaultLabelingEngine engine; + engine.setMapSettings( mapSettings ); + engine.addProvider( new QgsVectorLayerLabelProvider( vl, QString(), true, &settings ) ); + //engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly ); + engine.run( context ); + + p.end(); + + QVERIFY( imageCheck( "balloon_callout_wedge_width", img, 20 ) ); +} + // // Private helper functions not called directly by CTest // diff --git a/tests/testdata/control_images/callouts/expected_balloon_callout_margin/expected_balloon_callout_margin.png b/tests/testdata/control_images/callouts/expected_balloon_callout_margin/expected_balloon_callout_margin.png new file mode 100644 index 0000000000000000000000000000000000000000..85193307c516b33a8f02e03109d81585292c37ca GIT binary patch literal 24564 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 literal 0 HcmV?d00001 From 0adb7f07b0ae1e532a9004929cbbe36a268afe2f Mon Sep 17 00:00:00 2001 From: Andrea Giudiceandrea Date: Sun, 21 Mar 2021 11:14:44 +0100 Subject: [PATCH 162/377] Fix markup typo in INSTALL.md --- INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index ff48e5e846fc..7e2b97f3daee 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -182,7 +182,7 @@ sudo apt-get update | bionic | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb` | | focal | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb` | | groovy | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-sip-dev python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb` | -| sid | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga sip5-tools spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb`` | +| sid | `apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev libgsl-dev libpdal-dev libpq-dev libproj-dev libprotobuf-dev libqca-qt5-2-dev libqca-qt5-2-plugins libqscintilla2-qt5-dev libqt5opengl5-dev libqt5serialport5-dev libqt5sql5-sqlite libqt5svg5-dev libqt5webkit5-dev libqt5xmlpatterns5-dev libqwt-qt5-dev libspatialindex-dev libspatialite-dev libsqlite3-dev libsqlite3-mod-spatialite libyaml-tiny-perl libzip-dev libzstd-dev lighttpd locales ninja-build ocl-icd-opencl-dev opencl-headers pdal pkg-config poppler-utils protobuf-compiler pyqt5-dev pyqt5-dev-tools pyqt5.qsci-dev python3-all-dev python3-autopep8 python3-dateutil python3-dev python3-future python3-gdal python3-httplib2 python3-jinja2 python3-lxml python3-markupsafe python3-mock python3-nose2 python3-owslib python3-plotly python3-psycopg2 python3-pygments python3-pyproj python3-pyqt5 python3-pyqt5.qsci python3-pyqt5.qtsql python3-pyqt5.qtsvg python3-pyqt5.qtwebkit python3-requests python3-sip python3-six python3-termcolor python3-tz python3-yaml qt3d-assimpsceneimport-plugin qt3d-defaultgeometryloader-plugin qt3d-gltfsceneio-plugin qt3d-scene2d-plugin qt3d5-dev qt5-default qt5keychain-dev qtbase5-dev qtbase5-private-dev qtpositioning5-dev qttools5-dev qttools5-dev-tools saga sip5-tools spawn-fcgi xauth xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable xvfb` | (extracted from the control.in file in `debian/`) From 7fc68e1594f2358bdb95b91c6a26120a0b743582 Mon Sep 17 00:00:00 2001 From: t0b3 Date: Sat, 20 Mar 2021 10:20:17 +0100 Subject: [PATCH 163/377] add build test for Qt 5.15 Signed-off-by: t0b3 --- .github/workflows/run-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 3333fdfa8bfc..67105f339b5a 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -34,8 +34,8 @@ jobs: strategy: matrix: - # tests run on 20.04 (Qt 5.12), compile test on 20.10 (Qt 5.14) - ubuntu-base: ['20.04', '20.10'] + # tests run on 20.04 (Qt 5.12), compile test on 20.10 (Qt 5.14) and 21.04 (Qt 5.15) + ubuntu-base: ['20.04', '20.10', '21.04'] fail-fast: false outputs: From a9eec0c43674f7c5d6fc7081904ce31d8ba1643a Mon Sep 17 00:00:00 2001 From: t0b3 Date: Sat, 20 Mar 2021 11:17:15 +0100 Subject: [PATCH 164/377] fix: notification(arg1) is deprecated: Use the 3-args version of notification() instead. Signed-off-by: t0b3 --- external/qspatialite/qsql_spatialite.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/external/qspatialite/qsql_spatialite.cpp b/external/qspatialite/qsql_spatialite.cpp index afd71d956a48..0e8f15a25f76 100644 --- a/external/qspatialite/qsql_spatialite.cpp +++ b/external/qspatialite/qsql_spatialite.cpp @@ -927,7 +927,6 @@ void QSpatiaLiteDriver::handleNotification( const QString &tableName, qint64 row Q_D( const QSpatiaLiteDriver ); if ( d->notificationid.contains( tableName ) ) { - emit notification( tableName ); emit notification( tableName, QSqlDriver::UnknownSource, QVariant( rowid ) ); } } From 99616c3d43a4965ce5570cabde4044765cdd0130 Mon Sep 17 00:00:00 2001 From: t0b3 Date: Sun, 21 Mar 2021 10:54:28 +0100 Subject: [PATCH 165/377] fix: replace deprecated QString::SkipEmptyParts with Qt::SkipEmptyParts Signed-off-by: t0b3 --- src/providers/oracle/qgsoracletablecache.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/providers/oracle/qgsoracletablecache.cpp b/src/providers/oracle/qgsoracletablecache.cpp index c8382d1e8926..9564097ff346 100644 --- a/src/providers/oracle/qgsoracletablecache.cpp +++ b/src/providers/oracle/qgsoracletablecache.cpp @@ -219,14 +219,26 @@ bool QgsOracleTableCache::loadFromCache( const QString &connName, CacheFlags fla layer.sql = QString::fromUtf8( ( const char * ) sqlite3_column_text( stmt, 4 ) ); QString pkCols = QString::fromUtf8( ( const char * ) sqlite3_column_text( stmt, 5 ) ); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) layer.pkCols = pkCols.split( ",", QString::SkipEmptyParts ); +#else + layer.pkCols = pkCols.split( ",", Qt::SkipEmptyParts ); +#endif QString geomTypes = QString::fromUtf8( ( const char * ) sqlite3_column_text( stmt, 6 ) ); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) for ( QString geomType : geomTypes.split( ",", QString::SkipEmptyParts ) ) +#else + for ( QString geomType : geomTypes.split( ",", Qt::SkipEmptyParts ) ) +#endif layer.types.append( static_cast( geomType.toInt() ) ); QString geomSrids = QString::fromUtf8( ( const char * ) sqlite3_column_text( stmt, 7 ) ); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) for ( QString geomSrid : geomSrids.split( ",", QString::SkipEmptyParts ) ) +#else + for ( QString geomSrid : geomSrids.split( ",", Qt::SkipEmptyParts ) ) +#endif layer.srids.append( geomSrid.toInt() ); layers.append( layer ); From f57c343c798c15c963b7641dca13c7c892e8d6fa Mon Sep 17 00:00:00 2001 From: t0b3 Date: Sat, 20 Mar 2021 17:11:06 +0100 Subject: [PATCH 166/377] fix: build w/o 3D for Qt 5.15 (many deprecation warnings) Signed-off-by: t0b3 --- .docker/docker-qgis-build.sh | 2 +- .github/workflows/run-tests.yml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.docker/docker-qgis-build.sh b/.docker/docker-qgis-build.sh index dcd3edd49e46..0ddfec0212f7 100755 --- a/.docker/docker-qgis-build.sh +++ b/.docker/docker-qgis-build.sh @@ -47,7 +47,7 @@ cmake \ -GNinja \ -DUSE_CCACHE=OFF \ -DWITH_QUICK=OFF \ - -DWITH_3D=ON \ + -DWITH_3D=${WITH_3D} \ -DWITH_STAGED_PLUGINS=ON \ -DWITH_GRASS=OFF \ -DSUPPRESS_QT_WARNINGS=ON \ diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 67105f339b5a..306222aa0b39 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -58,15 +58,19 @@ jobs: DOCKER_TAG=$(echo $( [[ ${GITHUB_EVENT_NAME} =~ ^pull_request$ ]] && echo ${GITHUB_BASE_REF} || echo ${GITHUB_REF##*/} ) | sed 's/^master$/latest/')$( [[ ${UBUNTU_BASE} != ${DEFAULT_UBUNTU_BASE} ]] && echo "_${UBUNTU_BASE}" || echo "" ) CTEST_BUILD_NAME=$( [[ ${GITHUB_EVENT_NAME} =~ ^pull_request$ ]] && echo "PR${GITHUB_PR_NUMBER}" || echo ${GITHUB_REF##*/} )"_${GITHUB_SHA}" [[ ${UBUNTU_BASE} == "20.04" ]] && PATCH_QT_3D=true || PATCH_QT_3D=false + # build w/o 3D for Qt 5.15 (many deprecation warnings) + [[ ${UBUNTU_BASE} == "21.04" ]] && WITH_3D=FALSE || WITH_3D=TRUE echo "DOCKER_TAG=${DOCKER_TAG}" >> $GITHUB_ENV echo "CTEST_BUILD_NAME=${CTEST_BUILD_NAME}" >> $GITHUB_ENV echo "PATCH_QT_3D=${PATCH_QT_3D}" >> $GITHUB_ENV + echo "WITH_3D=${WITH_3D}" >> $GITHUB_ENV - name: Print vars run: | echo DOCKER_TAG: ${DOCKER_TAG} echo CTEST_BUILD_NAME: ${CTEST_BUILD_NAME} echo PATCH_QT_3D: ${PATCH_QT_3D} + echo WITH_3D: ${WITH_3D} - name: Build deps env: @@ -116,6 +120,7 @@ jobs: -v /home/runner/QGIS/.ccache:/root/.ccache \ --env-file .docker/docker-variables.env \ --env PUSH_TO_CDASH=true \ + --env WITH_3D=${WITH_3D} \ qgis/qgis3-build-deps:${DOCKER_TAG} \ /root/QGIS/.docker/docker-qgis-build.sh docker commit qgis_container qgis_image From e9849abf557ca705e2da6dd02f47e5f8adbe4f6f Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 21 Mar 2021 08:44:08 +1000 Subject: [PATCH 167/377] Use c++17 std::clamp instead of qBound --- .../terrain/qgsdemterraintilegeometry_p.cpp | 16 ++++---- src/3d/terrain/qgsdemterraintileloader_p.cpp | 4 +- .../qgsclassificationmethod.cpp | 2 +- src/core/effects/qgscoloreffect.cpp | 11 +++++ src/core/effects/qgscoloreffect.h | 4 +- src/core/effects/qgsimageoperation.cpp | 8 ++-- src/core/expression/qgsexpressionfunction.cpp | 6 +-- .../labeling/qgslabelobstaclesettings.cpp | 2 +- src/core/labeling/qgspallabeling.cpp | 6 +-- src/core/qgscolorramp.cpp | 6 +-- src/core/qgspropertytransformer.cpp | 40 +++++++++---------- src/core/qgstiles.cpp | 16 ++++---- .../raster/qgsbrightnesscontrastfilter.cpp | 19 ++++++++- src/core/raster/qgsbrightnesscontrastfilter.h | 6 +-- src/core/raster/qgshillshaderenderer.cpp | 14 +++---- src/core/raster/qgshuesaturationfilter.cpp | 2 +- src/core/symbology/qgsrendererrange.cpp | 2 +- .../vector/qgsvectorlayerdiagramprovider.cpp | 2 +- src/gui/layout/qgslayoutview.cpp | 4 +- .../models/qgsmodelgraphicsview.cpp | 2 +- src/gui/qgsfloatingwidget.cpp | 2 +- src/gui/qgsgradientcolorrampdialog.cpp | 10 ++--- src/gui/qgsgradientstopeditor.cpp | 2 +- src/gui/qgshighlight.cpp | 2 +- src/gui/qgsmapcanvas.cpp | 4 +- src/gui/tableeditor/qgstableeditorwidget.cpp | 4 +- src/providers/wms/qgswmscapabilities.cpp | 8 ++-- tests/code_layout/test_banned_keywords.sh | 3 ++ tests/qt_modeltest/modeltest.cpp | 2 +- 29 files changed, 119 insertions(+), 90 deletions(-) diff --git a/src/3d/terrain/qgsdemterraintilegeometry_p.cpp b/src/3d/terrain/qgsdemterraintilegeometry_p.cpp index 0caaa43fc8f7..cba304df13ad 100644 --- a/src/3d/terrain/qgsdemterraintilegeometry_p.cpp +++ b/src/3d/terrain/qgsdemterraintilegeometry_p.cpp @@ -64,14 +64,14 @@ static QByteArray createPlaneVertexData( int res, float side, float vertScale, f // Iterate over z for ( int j = -1; j <= resolution.height(); ++j ) { - int jBound = qBound( 0, j, jMax ); + int jBound = std::clamp( j, 0, jMax ); const float z = z0 + static_cast( jBound ) * dz; const float v = static_cast( jBound ) * dv; // Iterate over x for ( int i = -1; i <= resolution.width(); ++i ) { - int iBound = qBound( 0, i, iMax ); + int iBound = std::clamp( i, 0, iMax ); const float x = x0 + static_cast( iBound ) * dx; const float u = static_cast( iBound ) * du; @@ -95,10 +95,10 @@ static QByteArray createPlaneVertexData( int res, float side, float vertScale, f // calculate normal coordinates #define zAt( ii, jj ) zData[ jj * resolution.width() + ii ] * vertScale - float zi0 = zAt( qBound( 0, i - 1, iMax ), jBound ); - float zi1 = zAt( qBound( 0, i + 1, iMax ), jBound ); - float zj0 = zAt( iBound, qBound( 0, j - 1, jMax ) ); - float zj1 = zAt( iBound, qBound( 0, j + 1, jMax ) ); + float zi0 = zAt( std::clamp( i - 1, 0, iMax ), jBound ); + float zi1 = zAt( std::clamp( i + 1, 0, iMax ), jBound ); + float zj0 = zAt( iBound, std::clamp( j - 1, 0, jMax ) ); + float zj1 = zAt( iBound, std::clamp( j + 1, 0, jMax ) ); QVector3D n; if ( std::isnan( zi0 ) || std::isnan( zi1 ) || std::isnan( zj0 ) || std::isnan( zj1 ) ) @@ -137,8 +137,8 @@ static QByteArray createPlaneVertexData( int res, float side, float vertScale, f inline int ijToHeightMapIndex( int i, int j, int resX, int resZ ) { - i = qBound( 1, i, resX ) - 1; - j = qBound( 1, j, resZ ) - 1; + i = std::clamp( i, 1, resX ) - 1; + j = std::clamp( j, 1, resZ ) - 1; return j * resX + i; } diff --git a/src/3d/terrain/qgsdemterraintileloader_p.cpp b/src/3d/terrain/qgsdemterraintileloader_p.cpp index 87bce73a8e05..1a0fc9ab8551 100644 --- a/src/3d/terrain/qgsdemterraintileloader_p.cpp +++ b/src/3d/terrain/qgsdemterraintileloader_p.cpp @@ -293,8 +293,8 @@ float QgsDemHeightMapGenerator::heightAt( double x, double y ) int cellX = ( int )( ( x - rect.xMinimum() ) / rect.width() * res + .5f ); int cellY = ( int )( ( rect.yMaximum() - y ) / rect.height() * res + .5f ); - cellX = qBound( 0, cellX, res - 1 ); - cellY = qBound( 0, cellY, res - 1 ); + cellX = std::clamp( cellX, 0, res - 1 ); + cellY = std::clamp( cellY, 0, res - 1 ); const float *data = ( const float * ) mDtmCoarseData.constData(); return data[cellX + cellY * res]; diff --git a/src/core/classification/qgsclassificationmethod.cpp b/src/core/classification/qgsclassificationmethod.cpp index cc12200f581d..dd0aa7dba0ff 100644 --- a/src/core/classification/qgsclassificationmethod.cpp +++ b/src/core/classification/qgsclassificationmethod.cpp @@ -142,7 +142,7 @@ void QgsClassificationMethod::setSymmetricMode( bool enabled, double symmetryPoi void QgsClassificationMethod::setLabelPrecision( int precision ) { // Limit the range of decimal places to a reasonable range - precision = qBound( MIN_PRECISION, precision, MAX_PRECISION ); + precision = std::clamp( precision, MIN_PRECISION, MAX_PRECISION ); mLabelPrecision = precision; mLabelNumberScale = 1.0; mLabelNumberSuffix.clear(); diff --git a/src/core/effects/qgscoloreffect.cpp b/src/core/effects/qgscoloreffect.cpp index 1280860fe4aa..495da21b528c 100644 --- a/src/core/effects/qgscoloreffect.cpp +++ b/src/core/effects/qgscoloreffect.cpp @@ -18,6 +18,7 @@ #include "qgscoloreffect.h" #include "qgsimageoperation.h" #include "qgssymbollayerutils.h" +#include QgsPaintEffect *QgsColorEffect::create( const QVariantMap &map ) { @@ -119,6 +120,16 @@ QgsColorEffect *QgsColorEffect::clone() const return newEffect; } +void QgsColorEffect::setBrightness( int brightness ) +{ + mBrightness = std::clamp( brightness, -255, 255 ); +} + +void QgsColorEffect::setContrast( int contrast ) +{ + mContrast = std::clamp( contrast, -100, 100 ); +} + void QgsColorEffect::setColorizeColor( const QColor &colorizeColor ) { mColorizeColor = colorizeColor; diff --git a/src/core/effects/qgscoloreffect.h b/src/core/effects/qgscoloreffect.h index 6f8f175a36a8..1b964f6b7552 100644 --- a/src/core/effects/qgscoloreffect.h +++ b/src/core/effects/qgscoloreffect.h @@ -58,7 +58,7 @@ class CORE_EXPORT QgsColorEffect : public QgsPaintEffect SIP_NODEFAULTCTORS * lightening * \see setBrightness */ - void setBrightness( int brightness ) { mBrightness = qBound( -255, brightness, 255 ); } + void setBrightness( int brightness ); /** * Returns the brightness modification for the effect. @@ -76,7 +76,7 @@ class CORE_EXPORT QgsColorEffect : public QgsPaintEffect SIP_NODEFAULTCTORS * greater contrast * \see setContrast */ - void setContrast( int contrast ) { mContrast = qBound( -100, contrast, 100 ); } + void setContrast( int contrast ); /** * Returns the contrast modification for the effect. diff --git a/src/core/effects/qgsimageoperation.cpp b/src/core/effects/qgsimageoperation.cpp index 53dc542fe561..d722a3443def 100644 --- a/src/core/effects/qgsimageoperation.cpp +++ b/src/core/effects/qgsimageoperation.cpp @@ -260,7 +260,7 @@ void QgsImageOperation::BrightnessContrastPixelOperation::operator()( QRgb &rgb, int QgsImageOperation::adjustColorComponent( int colorComponent, int brightness, double contrastFactor ) { - return qBound( 0, static_cast< int >( ( ( ( ( ( colorComponent / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + brightness ), 255 ); + return std::clamp( static_cast< int >( ( ( ( ( ( colorComponent / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + brightness ), 0, 255 ); } //hue/saturation @@ -348,7 +348,7 @@ void QgsImageOperation::MultiplyOpacityPixelOperation::operator()( QRgb &rgb, co { Q_UNUSED( x ) Q_UNUSED( y ) - rgb = qRgba( qRed( rgb ), qGreen( rgb ), qBlue( rgb ), qBound( 0.0, std::round( mFactor * qAlpha( rgb ) ), 255.0 ) ); + rgb = qRgba( qRed( rgb ), qGreen( rgb ), qBlue( rgb ), std::clamp( std::round( mFactor * qAlpha( rgb ) ), 0.0, 255.0 ) ); } // overlay color @@ -694,7 +694,7 @@ inline QRgb QgsImageOperation::GaussianBlurOperation::gaussianBlurVertical( cons for ( int i = 0; i <= mRadius * 2; ++i ) { - y = qBound( 0, posy + ( i - mRadius ), height - 1 ); + y = std::clamp( posy + ( i - mRadius ), 0, height - 1 ); ref = sourceFirstLine + sourceBpl * y; QRgb *refRgb = reinterpret_cast< QRgb * >( ref ); @@ -718,7 +718,7 @@ inline QRgb QgsImageOperation::GaussianBlurOperation::gaussianBlurHorizontal( co for ( int i = 0; i <= mRadius * 2; ++i ) { - x = qBound( 0, posx + ( i - mRadius ), width - 1 ); + x = std::clamp( posx + ( i - mRadius ), 0, width - 1 ); ref = sourceFirstLine + x * 4; QRgb *refRgb = reinterpret_cast< QRgb * >( ref ); diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index 9b09e053a9a1..4247ddfda484 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -2741,9 +2741,9 @@ static QVariant fcnSmooth( const QVariantList &values, const QgsExpressionContex return QVariant(); int iterations = std::min( QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ), 10 ); - double offset = qBound( 0.0, QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.5 ); + double offset = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ), 0.0, 0.5 ); double minLength = QgsExpressionUtils::getDoubleValue( values.at( 3 ), parent ); - double maxAngle = qBound( 0.0, QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 180.0 ); + double maxAngle = std::clamp( QgsExpressionUtils::getDoubleValue( values.at( 4 ), parent ), 0.0, 180.0 ); QgsGeometry smoothed = geom.smooth( static_cast( iterations ), offset, minLength, maxAngle ); if ( smoothed.isNull() ) @@ -4055,7 +4055,7 @@ static QVariant fcnHausdorffDistance( const QVariantList &values, const QgsExpre if ( values.length() == 3 && values.at( 2 ).isValid() ) { double densify = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ); - densify = qBound( 0.0, densify, 1.0 ); + densify = std::clamp( densify, 0.0, 1.0 ); res = g1.hausdorffDistanceDensify( g2, densify ); } else diff --git a/src/core/labeling/qgslabelobstaclesettings.cpp b/src/core/labeling/qgslabelobstaclesettings.cpp index 5e64ee09d156..4344e29038a1 100644 --- a/src/core/labeling/qgslabelobstaclesettings.cpp +++ b/src/core/labeling/qgslabelobstaclesettings.cpp @@ -40,7 +40,7 @@ void QgsLabelObstacleSettings::updateDataDefinedProperties( const QgsPropertyCol double factorD = exprVal.toDouble( &ok ); if ( ok ) { - factorD = qBound( 0.0, factorD, 10.0 ); + factorD = std::clamp( factorD, 0.0, 10.0 ); factorD = factorD / 5.0 + 0.0001; // convert 0 -> 10 to 0.0001 -> 2.0 mObstacleFactor = factorD; } diff --git a/src/core/labeling/qgspallabeling.cpp b/src/core/labeling/qgspallabeling.cpp index 8cf2a602450c..34bc9395625e 100644 --- a/src/core/labeling/qgspallabeling.cpp +++ b/src/core/labeling/qgspallabeling.cpp @@ -1937,8 +1937,8 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext const QPointF maxcharanglePt = QgsSymbolLayerUtils::toPoint( exprVal, &ok ); if ( ok ) { - maxcharanglein = qBound( 20.0, static_cast< double >( maxcharanglePt.x() ), 60.0 ); - maxcharangleout = qBound( 20.0, static_cast< double >( maxcharanglePt.y() ), 95.0 ); + maxcharanglein = std::clamp( static_cast< double >( maxcharanglePt.x() ), 20.0, 60.0 ); + maxcharangleout = std::clamp( static_cast< double >( maxcharanglePt.y() ), 20.0, 95.0 ); } } // make sure maxcharangleout is always negative @@ -2592,7 +2592,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext double priorityD = exprVal.toDouble( &ok ); if ( ok ) { - priorityD = qBound( 0.0, priorityD, 10.0 ); + priorityD = std::clamp( priorityD, 0.0, 10.0 ); priorityD = 1 - priorityD / 10.0; // convert 0..10 --> 1..0 ( *labelFeature )->setPriority( priorityD ); } diff --git a/src/core/qgscolorramp.cpp b/src/core/qgscolorramp.cpp index c9e1f575aac0..f97fc1d0651c 100644 --- a/src/core/qgscolorramp.cpp +++ b/src/core/qgscolorramp.cpp @@ -411,9 +411,9 @@ QList QgsLimitedRandomColorRamp::randomColors( int count, //see http://basecase.org/env/on-rainbows for more details currentHueAngle += 137.50776; //scale hue to between hueMax and hueMin - h = qBound( 0.0, std::round( ( std::fmod( currentHueAngle, 360.0 ) / 360.0 ) * ( safeHueMax - safeHueMin ) + safeHueMin ), 359.0 ); - s = qBound( 0, ( qrand() % ( safeSatMax - safeSatMin + 1 ) ) + safeSatMin, 255 ); - v = qBound( 0, ( qrand() % ( safeValMax - safeValMin + 1 ) ) + safeValMin, 255 ); + h = std::clamp( std::round( ( std::fmod( currentHueAngle, 360.0 ) / 360.0 ) * ( safeHueMax - safeHueMin ) + safeHueMin ), 0.0, 359.0 ); + s = std::clamp( ( qrand() % ( safeSatMax - safeSatMin + 1 ) ) + safeSatMin, 0, 255 ); + v = std::clamp( ( qrand() % ( safeValMax - safeValMin + 1 ) ) + safeValMin, 0, 255 ); colors.append( QColor::fromHsv( h, s, v ) ); } return colors; diff --git a/src/core/qgspropertytransformer.cpp b/src/core/qgspropertytransformer.cpp index a60e7ecccb16..08e3a44672c3 100644 --- a/src/core/qgspropertytransformer.cpp +++ b/src/core/qgspropertytransformer.cpp @@ -178,13 +178,13 @@ bool QgsGenericNumericTransformer::loadVariant( const QVariant &transformer ) double QgsGenericNumericTransformer::value( double input ) const { if ( qgsDoubleNear( mMaxValue, mMinValue ) ) - return qBound( mMinOutput, input, mMaxOutput ); + return std::clamp( input, mMinOutput, mMaxOutput ); input = transformNumeric( input ); if ( qgsDoubleNear( mExponent, 1.0 ) ) - return mMinOutput + ( qBound( mMinValue, input, mMaxValue ) - mMinValue ) * ( mMaxOutput - mMinOutput ) / ( mMaxValue - mMinValue ); + return mMinOutput + ( std::clamp( input, mMinValue, mMaxValue ) - mMinValue ) * ( mMaxOutput - mMinOutput ) / ( mMaxValue - mMinValue ); else - return mMinOutput + std::pow( qBound( mMinValue, input, mMaxValue ) - mMinValue, mExponent ) * ( mMaxOutput - mMinOutput ) / std::pow( mMaxValue - mMinValue, mExponent ); + return mMinOutput + std::pow( std::clamp( input, mMinValue, mMaxValue ) - mMinValue, mExponent ) * ( mMaxOutput - mMinOutput ) / std::pow( mMaxValue - mMinValue, mExponent ); } QVariant QgsGenericNumericTransformer::transform( const QgsExpressionContext &context, const QVariant &v ) const @@ -360,12 +360,12 @@ double QgsSizeScaleTransformer::size( double value ) const switch ( mType ) { case Linear: - return mMinSize + ( qBound( mMinValue, value, mMaxValue ) - mMinValue ) * ( mMaxSize - mMinSize ) / ( mMaxValue - mMinValue ); + return mMinSize + ( std::clamp( value, mMinValue, mMaxValue ) - mMinValue ) * ( mMaxSize - mMinSize ) / ( mMaxValue - mMinValue ); case Area: case Flannery: case Exponential: - return mMinSize + std::pow( qBound( mMinValue, value, mMaxValue ) - mMinValue, mExponent ) * ( mMaxSize - mMinSize ) / std::pow( mMaxValue - mMinValue, mExponent ); + return mMinSize + std::pow( std::clamp( value, mMinValue, mMaxValue ) - mMinValue, mExponent ) * ( mMaxSize - mMinSize ) / std::pow( mMaxValue - mMinValue, mExponent ); } return 0; @@ -631,7 +631,7 @@ QString QgsColorRampTransformer::toExpression( const QString &baseExpression ) c QColor QgsColorRampTransformer::color( double value ) const { value = transformNumeric( value ); - double scaledVal = qBound( 0.0, ( value - mMinValue ) / ( mMaxValue - mMinValue ), 1.0 ); + double scaledVal = std::clamp( ( value - mMinValue ) / ( mMaxValue - mMinValue ), 0.0, 1.0 ); if ( !mGradientRamp ) return mNullColor; @@ -708,8 +708,8 @@ void QgsCurveTransform::setControlPoints( const QList &points ) std::sort( mControlPoints.begin(), mControlPoints.end(), sortByX ); for ( int i = 0; i < mControlPoints.count(); ++i ) { - mControlPoints[ i ] = QgsPointXY( qBound( 0.0, mControlPoints.at( i ).x(), 1.0 ), - qBound( 0.0, mControlPoints.at( i ).y(), 1.0 ) ); + mControlPoints[ i ] = QgsPointXY( std::clamp( mControlPoints.at( i ).x(), 0.0, 1.0 ), + std::clamp( mControlPoints.at( i ).y(), 0.0, 1.0 ) ); } calcSecondDerivativeArray(); } @@ -747,27 +747,27 @@ double QgsCurveTransform::y( double x ) const { int n = mControlPoints.count(); if ( n < 2 ) - return qBound( 0.0, x, 1.0 ); // invalid + return std::clamp( x, 0.0, 1.0 ); // invalid else if ( n < 3 ) { // linear if ( x <= mControlPoints.at( 0 ).x() ) - return qBound( 0.0, mControlPoints.at( 0 ).y(), 1.0 ); + return std::clamp( mControlPoints.at( 0 ).y(), 0.0, 1.0 ); else if ( x >= mControlPoints.at( n - 1 ).x() ) - return qBound( 0.0, mControlPoints.at( 1 ).y(), 1.0 ); + return std::clamp( mControlPoints.at( 1 ).y(), 0.0, 1.0 ); else { double dx = mControlPoints.at( 1 ).x() - mControlPoints.at( 0 ).x(); double dy = mControlPoints.at( 1 ).y() - mControlPoints.at( 0 ).y(); - return qBound( 0.0, ( x - mControlPoints.at( 0 ).x() ) * ( dy / dx ) + mControlPoints.at( 0 ).y(), 1.0 ); + return std::clamp( ( x - mControlPoints.at( 0 ).x() ) * ( dy / dx ) + mControlPoints.at( 0 ).y(), 0.0, 1.0 ); } } // safety check if ( x <= mControlPoints.at( 0 ).x() ) - return qBound( 0.0, mControlPoints.at( 0 ).y(), 1.0 ); + return std::clamp( mControlPoints.at( 0 ).y(), 0.0, 1.0 ); if ( x >= mControlPoints.at( n - 1 ).x() ) - return qBound( 0.0, mControlPoints.at( n - 1 ).y(), 1.0 ); + return std::clamp( mControlPoints.at( n - 1 ).y(), 0.0, 1.0 ); // find corresponding segment QList::const_iterator pointIt = mControlPoints.constBegin(); @@ -785,8 +785,8 @@ double QgsCurveTransform::y( double x ) const double a = 1 - t; - return qBound( 0.0, a * currentControlPoint.y() + t * nextControlPoint.y() + ( h * h / 6 ) * ( ( a * a * a - a ) * mSecondDerivativeArray[i] + ( t * t * t - t ) * mSecondDerivativeArray[i + 1] ), - 1.0 ); + return std::clamp( a * currentControlPoint.y() + t * nextControlPoint.y() + ( h * h / 6 ) * ( ( a * a * a - a ) * mSecondDerivativeArray[i] + ( t * t * t - t ) * mSecondDerivativeArray[i + 1] ), + 0.0, 1.0 ); } ++pointIt; @@ -798,7 +798,7 @@ double QgsCurveTransform::y( double x ) const } //should not happen - return qBound( 0.0, x, 1.0 ); + return std::clamp( x, 0.0, 1.0 ); } // this code is adapted from https://github.com/OpenFibers/Photoshop-Curves @@ -831,7 +831,7 @@ QVector QgsCurveTransform::y( const QVector &x ) const // safety check while ( currentX <= currentControlPoint.x() ) { - result << qBound( 0.0, currentControlPoint.y(), 1.0 ); + result << std::clamp( currentControlPoint.y(), 0.0, 1.0 ); xIndex++; currentX = x.at( xIndex ); } @@ -847,7 +847,7 @@ QVector QgsCurveTransform::y( const QVector &x ) const double a = 1 - t; - result << qBound( 0.0, a * currentControlPoint.y() + t * nextControlPoint.y() + ( h * h / 6 ) * ( ( a * a * a - a )*mSecondDerivativeArray[i] + ( t * t * t - t )*mSecondDerivativeArray[i + 1] ), 1.0 ); + result << std::clamp( a * currentControlPoint.y() + t * nextControlPoint.y() + ( h * h / 6 ) * ( ( a * a * a - a )*mSecondDerivativeArray[i] + ( t * t * t - t )*mSecondDerivativeArray[i + 1] ), 0.0, 1.0 ); xIndex++; if ( xIndex == x.count() ) return result; @@ -866,7 +866,7 @@ QVector QgsCurveTransform::y( const QVector &x ) const // safety check while ( xIndex < x.count() ) { - result << qBound( 0.0, nextControlPoint.y(), 1.0 ); + result << std::clamp( nextControlPoint.y(), 0.0, 1.0 ); xIndex++; } diff --git a/src/core/qgstiles.cpp b/src/core/qgstiles.cpp index 3beade14fca8..4764d4bafb74 100644 --- a/src/core/qgstiles.cpp +++ b/src/core/qgstiles.cpp @@ -53,10 +53,10 @@ QgsPointXY QgsTileMatrix::tileCenter( QgsTileXYZ id ) const QgsTileRange QgsTileMatrix::tileRangeFromExtent( const QgsRectangle &r ) { - double x0 = qBound( mExtent.xMinimum(), r.xMinimum(), mExtent.xMaximum() ); - double y0 = qBound( mExtent.yMinimum(), r.yMinimum(), mExtent.yMaximum() ); - double x1 = qBound( mExtent.xMinimum(), r.xMaximum(), mExtent.xMaximum() ); - double y1 = qBound( mExtent.yMinimum(), r.yMaximum(), mExtent.yMaximum() ); + double x0 = std::clamp( r.xMinimum(), mExtent.xMinimum(), mExtent.xMaximum() ); + double y0 = std::clamp( r.yMinimum(), mExtent.yMinimum(), mExtent.yMaximum() ); + double x1 = std::clamp( r.xMaximum(), mExtent.xMinimum(), mExtent.xMaximum() ); + double y1 = std::clamp( r.yMaximum(), mExtent.yMinimum(), mExtent.yMaximum() ); if ( x0 >= x1 || y0 >= y1 ) return QgsTileRange(); // nothing to display @@ -68,10 +68,10 @@ QgsTileRange QgsTileMatrix::tileRangeFromExtent( const QgsRectangle &r ) QgsDebugMsgLevel( QStringLiteral( "Tile range of edges [%1,%2] - [%3,%4]" ).arg( tileX1 ).arg( tileY1 ).arg( tileX2 ).arg( tileY2 ), 2 ); // figure out tile range from zoom - int startColumn = qBound( 0, static_cast( floor( tileX1 ) ), mMatrixWidth - 1 ); - int endColumn = qBound( 0, static_cast( floor( tileX2 ) ), mMatrixWidth - 1 ); - int startRow = qBound( 0, static_cast( floor( tileY1 ) ), mMatrixHeight - 1 ); - int endRow = qBound( 0, static_cast( floor( tileY2 ) ), mMatrixHeight - 1 ); + int startColumn = std::clamp( static_cast( floor( tileX1 ) ), 0, mMatrixWidth - 1 ); + int endColumn = std::clamp( static_cast( floor( tileX2 ) ), 0, mMatrixWidth - 1 ); + int startRow = std::clamp( static_cast( floor( tileY1 ) ), 0, mMatrixHeight - 1 ); + int endRow = std::clamp( static_cast( floor( tileY2 ) ), 0, mMatrixHeight - 1 ); return QgsTileRange( startColumn, endColumn, startRow, endRow ); } diff --git a/src/core/raster/qgsbrightnesscontrastfilter.cpp b/src/core/raster/qgsbrightnesscontrastfilter.cpp index 9862caf5a7a1..1cff8bb4423c 100644 --- a/src/core/raster/qgsbrightnesscontrastfilter.cpp +++ b/src/core/raster/qgsbrightnesscontrastfilter.cpp @@ -163,12 +163,27 @@ QgsRasterBlock *QgsBrightnessContrastFilter::block( int bandNo, QgsRectangle co return outputBlock.release(); } +void QgsBrightnessContrastFilter::setBrightness( int brightness ) +{ + mBrightness = std::clamp( brightness, -255, 255 ); +} + +void QgsBrightnessContrastFilter::setContrast( int contrast ) +{ + mContrast = std::clamp( contrast, -100, 100 ); +} + +void QgsBrightnessContrastFilter::setGamma( double gamma ) +{ + mGamma = std::clamp( gamma, 0.1, 10.0 ); +} + int QgsBrightnessContrastFilter::adjustColorComponent( int colorComponent, int alpha, int brightness, double contrastFactor, double gammaCorrection ) const { if ( alpha == 255 ) { // Opaque pixel, do simpler math - return qBound( 0, ( int )( 255 * std::pow( ( ( ( ( ( ( colorComponent / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + brightness ) / 255.0, gammaCorrection ) ), 255 ); + return std::clamp( ( int )( 255 * std::pow( ( ( ( ( ( ( colorComponent / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + brightness ) / 255.0, gammaCorrection ) ), 0, 255 ); } else if ( alpha == 0 ) { @@ -183,7 +198,7 @@ int QgsBrightnessContrastFilter::adjustColorComponent( int colorComponent, int a double adjustedColor = colorComponent / alphaFactor; // Make sure to return a premultiplied color - return alphaFactor * qBound( 0., 255 * std::pow( ( ( ( ( ( ( adjustedColor / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + brightness ) / 255, gammaCorrection ), 255. ); + return alphaFactor * std::clamp( 255 * std::pow( ( ( ( ( ( ( adjustedColor / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + brightness ) / 255, gammaCorrection ), 0., 255. ); } } diff --git a/src/core/raster/qgsbrightnesscontrastfilter.h b/src/core/raster/qgsbrightnesscontrastfilter.h index d3516aa4d595..d32f81cfeed6 100644 --- a/src/core/raster/qgsbrightnesscontrastfilter.h +++ b/src/core/raster/qgsbrightnesscontrastfilter.h @@ -64,7 +64,7 @@ class CORE_EXPORT QgsBrightnessContrastFilter : public QgsRasterInterface * Set brightness level. Acceptable value range is -255…255 * \see brightness() */ - void setBrightness( int brightness ) { mBrightness = qBound( -255, brightness, 255 ); } + void setBrightness( int brightness ); /** * Returns current brightness level. @@ -76,7 +76,7 @@ class CORE_EXPORT QgsBrightnessContrastFilter : public QgsRasterInterface * Set contrast level. Acceptable value range is -100…100 * \see contrast() */ - void setContrast( int contrast ) { mContrast = qBound( -100, contrast, 100 ); } + void setContrast( int contrast ); /** * Returns current contrast level. @@ -90,7 +90,7 @@ class CORE_EXPORT QgsBrightnessContrastFilter : public QgsRasterInterface * * \since QGIS 3.16 */ - void setGamma( double gamma ) { mGamma = qBound( 0.1, gamma, 10.0 ); } + void setGamma( double gamma ); /** * Returns current gamma value. diff --git a/src/core/raster/qgshillshaderenderer.cpp b/src/core/raster/qgshillshaderenderer.cpp index 8d5dba1be869..679a4f07d040 100644 --- a/src/core/raster/qgshillshaderenderer.cpp +++ b/src/core/raster/qgshillshaderenderer.cpp @@ -448,11 +448,11 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext if ( !mMultiDirectional ) { // Standard single direction hillshade - grayValue = qBound( 0.0, ( sin_altRadians_mul_254 - - ( derY * cos_az_mul_cos_alt_mul_z_mul_254 - - derX * sin_az_mul_cos_alt_mul_z_mul_254 ) ) / - std::sqrt( 1 + square_z * ( derX * derX + derY * derY ) ) - , 255.0 ); + grayValue = std::clamp( ( sin_altRadians_mul_254 - + ( derY * cos_az_mul_cos_alt_mul_z_mul_254 - + derX * sin_az_mul_cos_alt_mul_z_mul_254 ) ) / + std::sqrt( 1 + square_z * ( derX * derX + derY * derY ) ), + 0.0, 255.0 ); } else { @@ -464,7 +464,7 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext // Flat? if ( xx_plus_yy == 0.0 ) { - grayValue = qBound( 0.0f, static_cast( 1.0 + sin_altRadians_mul_254 ), 255.0f ); + grayValue = std::clamp( static_cast( 1.0 + sin_altRadians_mul_254 ), 0.0f, 255.0f ); } else { @@ -494,7 +494,7 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext weight_360 * val360_mul_127 ) / xx_plus_yy ) / ( 1 + square_z * xx_plus_yy ); - grayValue = qBound( 0.0f, 1.0f + cang_mul_127, 255.0f ); + grayValue = std::clamp( 1.0f + cang_mul_127, 0.0f, 255.0f ); } } diff --git a/src/core/raster/qgshuesaturationfilter.cpp b/src/core/raster/qgshuesaturationfilter.cpp index 5c0e5aaa613a..ab7b158ec3cd 100644 --- a/src/core/raster/qgshuesaturationfilter.cpp +++ b/src/core/raster/qgshuesaturationfilter.cpp @@ -313,7 +313,7 @@ void QgsHueSaturationFilter::processSaturation( int &r, int &g, int &b, int &h, void QgsHueSaturationFilter::setSaturation( int saturation ) { - mSaturation = qBound( -100, saturation, 100 ); + mSaturation = std::clamp( saturation, -100, 100 ); // Scale saturation value to [0-2], where 0 = desaturated mSaturationScale = ( ( double ) mSaturation / 100 ) + 1; diff --git a/src/core/symbology/qgsrendererrange.cpp b/src/core/symbology/qgsrendererrange.cpp index 789763f0c612..c5139a44a12b 100644 --- a/src/core/symbology/qgsrendererrange.cpp +++ b/src/core/symbology/qgsrendererrange.cpp @@ -193,7 +193,7 @@ bool QgsRendererRangeLabelFormat::operator!=( const QgsRendererRangeLabelFormat void QgsRendererRangeLabelFormat::setPrecision( int precision ) { // Limit the range of decimal places to a reasonable range - precision = qBound( MIN_PRECISION, precision, MAX_PRECISION ); + precision = std::clamp( precision, MIN_PRECISION, MAX_PRECISION ); mPrecision = precision; mNumberScale = 1.0; mNumberSuffix.clear(); diff --git a/src/core/vector/qgsvectorlayerdiagramprovider.cpp b/src/core/vector/qgsvectorlayerdiagramprovider.cpp index 842e920f9c12..4104f1d76015 100644 --- a/src/core/vector/qgsvectorlayerdiagramprovider.cpp +++ b/src/core/vector/qgsvectorlayerdiagramprovider.cpp @@ -314,7 +314,7 @@ QgsLabelFeature *QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature &fea { context.expressionContext().setOriginalValueVariable( mSettings.priority() ); double priorityD = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::Priority, context.expressionContext(), mSettings.priority() ); - priorityD = qBound( 0.0, priorityD, 10.0 ); + priorityD = std::clamp( priorityD, 0.0, 10.0 ); priorityD = 1 - priorityD / 10.0; // convert 0..10 --> 1..0 lf->setPriority( priorityD ); } diff --git a/src/gui/layout/qgslayoutview.cpp b/src/gui/layout/qgslayoutview.cpp index fec49b64bbfc..7cb93caf5a29 100644 --- a/src/gui/layout/qgslayoutview.cpp +++ b/src/gui/layout/qgslayoutview.cpp @@ -190,7 +190,7 @@ void QgsLayoutView::scaleSafe( double scale ) { double currentScale = transform().m11(); scale *= currentScale; - scale = qBound( MIN_VIEW_SCALE, scale, MAX_VIEW_SCALE ); + scale = std::clamp( scale, MIN_VIEW_SCALE, MAX_VIEW_SCALE ); setTransform( QTransform::fromScale( scale, scale ) ); emit zoomLevelChanged(); viewChanged(); @@ -213,7 +213,7 @@ void QgsLayoutView::setZoomLevel( double level ) dpi = 72; //desired pixel width for 1mm on screen - level = qBound( MIN_VIEW_SCALE, level, MAX_VIEW_SCALE ); + level = std::clamp( level, MIN_VIEW_SCALE, MAX_VIEW_SCALE ); double mmLevel = currentLayout()->convertFromLayoutUnits( level, QgsUnitTypes::LayoutMillimeters ).length() * dpi / 25.4; setTransform( QTransform::fromScale( mmLevel, mmLevel ) ); } diff --git a/src/gui/processing/models/qgsmodelgraphicsview.cpp b/src/gui/processing/models/qgsmodelgraphicsview.cpp index aee41d174c76..14d25229d4e8 100644 --- a/src/gui/processing/models/qgsmodelgraphicsview.cpp +++ b/src/gui/processing/models/qgsmodelgraphicsview.cpp @@ -170,7 +170,7 @@ void QgsModelGraphicsView::scaleSafe( double scale ) { double currentScale = transform().m11(); scale *= currentScale; - scale = qBound( MIN_VIEW_SCALE, scale, MAX_VIEW_SCALE ); + scale = std::clamp( scale, MIN_VIEW_SCALE, MAX_VIEW_SCALE ); setTransform( QTransform::fromScale( scale, scale ) ); } diff --git a/src/gui/qgsfloatingwidget.cpp b/src/gui/qgsfloatingwidget.cpp index 9dc793620745..6d4c50cca9fc 100644 --- a/src/gui/qgsfloatingwidget.cpp +++ b/src/gui/qgsfloatingwidget.cpp @@ -183,7 +183,7 @@ void QgsFloatingWidget::onAnchorPointChanged() } // constrain x so that widget floats within parent widget - anchorX = qBound( 0, anchorX, parentWidget()->width() - width() ); + anchorX = std::clamp( anchorX, 0, parentWidget()->width() - width() ); move( anchorX, anchorY ); } diff --git a/src/gui/qgsgradientcolorrampdialog.cpp b/src/gui/qgsgradientcolorrampdialog.cpp index 2ea7d21b1656..d7b28d0e88c5 100644 --- a/src/gui/qgsgradientcolorrampdialog.cpp +++ b/src/gui/qgsgradientcolorrampdialog.cpp @@ -445,15 +445,15 @@ void QgsGradientColorRampDialog::plotMouseMove( QPointF point ) QColor newColor = mStopEditor->selectedStop().color; if ( mCurrentPlotColorComponent == 0 ) - newColor = QColor::fromHslF( qBound( qreal( 0.0 ), point.y(), qreal( 1.0 ) ), newColor.hslSaturationF(), newColor.lightnessF(), newColor.alphaF() ); + newColor = QColor::fromHslF( std::clamp( point.y(), qreal( 0.0 ), qreal( 1.0 ) ), newColor.hslSaturationF(), newColor.lightnessF(), newColor.alphaF() ); else if ( mCurrentPlotColorComponent == 1 ) - newColor = QColor::fromHslF( newColor.hslHueF(), newColor.hslSaturationF(), qBound( qreal( 0.0 ), point.y(), qreal( 1.0 ) ), newColor.alphaF() ); + newColor = QColor::fromHslF( newColor.hslHueF(), newColor.hslSaturationF(), std::clamp( point.y(), qreal( 0.0 ), qreal( 1.0 ) ), newColor.alphaF() ); else if ( mCurrentPlotColorComponent == 2 ) - newColor = QColor::fromHslF( newColor.hslHueF(), qBound( qreal( 0.0 ), point.y(), qreal( 1.0 ) ), newColor.lightnessF(), newColor.alphaF() ); + newColor = QColor::fromHslF( newColor.hslHueF(), std::clamp( point.y(), qreal( 0.0 ), qreal( 1.0 ) ), newColor.lightnessF(), newColor.alphaF() ); else if ( mCurrentPlotColorComponent == 3 ) - newColor = QColor::fromHslF( newColor.hslHueF(), newColor.hslSaturationF(), newColor.lightnessF(), qBound( qreal( 0.0 ), point.y(), qreal( 1.0 ) ) ); + newColor = QColor::fromHslF( newColor.hslHueF(), newColor.hslSaturationF(), newColor.lightnessF(), std::clamp( point.y(), qreal( 0.0 ), qreal( 1.0 ) ) ); - mStopEditor->setSelectedStopDetails( newColor, qBound( qreal( 0.0 ), point.x(), qreal( 1.0 ) ) ); + mStopEditor->setSelectedStopDetails( newColor, std::clamp( point.x(), qreal( 0.0 ), qreal( 1.0 ) ) ); } bool byX( QPointF p1, QPointF p2 ) diff --git a/src/gui/qgsgradientstopeditor.cpp b/src/gui/qgsgradientstopeditor.cpp index a294a8f3d070..349dca0e7dc9 100644 --- a/src/gui/qgsgradientstopeditor.cpp +++ b/src/gui/qgsgradientstopeditor.cpp @@ -365,7 +365,7 @@ void QgsGradientStopEditor::keyPressEvent( QKeyEvent *e ) if ( e->key() == Qt::Key_Left ) offsetDiff *= -1; - mStops[ mSelectedStop - 1 ].offset = qBound( 0.0, mStops[ mSelectedStop - 1 ].offset + offsetDiff, 1.0 ); + mStops[ mSelectedStop - 1 ].offset = std::clamp( mStops[ mSelectedStop - 1 ].offset + offsetDiff, 0.0, 1.0 ); mGradient.setStops( mStops ); update(); e->accept(); diff --git a/src/gui/qgshighlight.cpp b/src/gui/qgshighlight.cpp index c09ad7caca84..1cbf98a545a5 100644 --- a/src/gui/qgshighlight.cpp +++ b/src/gui/qgshighlight.cpp @@ -372,7 +372,7 @@ void QgsHighlight::paint( QPainter *p ) if ( alpha > 0 ) { int green = qGreen( line[c] ); - line[c] = qRgba( penRed, penGreen, penBlue, qBound( 0, alpha - ( green * k ), 255 ) ); + line[c] = qRgba( penRed, penGreen, penBlue, std::clamp( static_cast< int >( alpha - ( green * k ) ), 0, 255 ) ); } } } diff --git a/src/gui/qgsmapcanvas.cpp b/src/gui/qgsmapcanvas.cpp index 6b44d151a396..c31d0b809ca3 100644 --- a/src/gui/qgsmapcanvas.cpp +++ b/src/gui/qgsmapcanvas.cpp @@ -290,7 +290,7 @@ void QgsMapCanvas::setMagnificationFactor( double factor, const QgsPointXY *cent // do not go higher or lower than min max magnification ratio double magnifierMin = QgsGuiUtils::CANVAS_MAGNIFICATION_MIN; double magnifierMax = QgsGuiUtils::CANVAS_MAGNIFICATION_MAX; - factor = qBound( magnifierMin, factor, magnifierMax ); + factor = std::clamp( factor, magnifierMin, magnifierMax ); // the magnifier widget is in integer percent if ( !qgsDoubleNear( factor, mSettings.magnificationFactor(), 0.01 ) ) @@ -1151,7 +1151,7 @@ void QgsMapCanvas::setExtent( const QgsRectangle &r, bool magnified ) ScaleRestorer restorer( this ); const double ratio { extent().width() / extent().height() }; const double factor { r.width() / r.height() > ratio ? extent().width() / r.width() : extent().height() / r.height() }; - const double scaleFactor { qBound( QgsGuiUtils::CANVAS_MAGNIFICATION_MIN, mSettings.magnificationFactor() * factor, QgsGuiUtils::CANVAS_MAGNIFICATION_MAX ) }; + const double scaleFactor { std::clamp( mSettings.magnificationFactor() * factor, QgsGuiUtils::CANVAS_MAGNIFICATION_MIN, QgsGuiUtils::CANVAS_MAGNIFICATION_MAX ) }; const QgsPointXY newCenter { r.center() }; mSettings.setMagnificationFactor( scaleFactor, &newCenter ); emit magnificationChanged( scaleFactor ); diff --git a/src/gui/tableeditor/qgstableeditorwidget.cpp b/src/gui/tableeditor/qgstableeditorwidget.cpp index efd528db74a6..f346f66162c0 100644 --- a/src/gui/tableeditor/qgstableeditorwidget.cpp +++ b/src/gui/tableeditor/qgstableeditorwidget.cpp @@ -1364,8 +1364,8 @@ void QgsTableEditorTextEdit::resizeToContents() int parentWidth = parent->width(); int maxWidth = isRightToLeft() ? position.x() + oldWidth : parentWidth - position.x(); int maxHeight = parent->height() - position.y(); - int newWidth = qBound( mOriginalWidth, hintWidth, maxWidth ); - int newHeight = qBound( mOriginalHeight, hintHeight, maxHeight ); + int newWidth = std::clamp( hintWidth, mOriginalWidth, maxWidth ); + int newHeight = std::clamp( hintHeight, mOriginalHeight, maxHeight ); if ( mWidgetOwnsGeometry ) { diff --git a/src/providers/wms/qgswmscapabilities.cpp b/src/providers/wms/qgswmscapabilities.cpp index 8dda3d2aadcf..4d50741d3e19 100644 --- a/src/providers/wms/qgswmscapabilities.cpp +++ b/src/providers/wms/qgswmscapabilities.cpp @@ -2567,10 +2567,10 @@ void QgsWmtsTileMatrix::viewExtentIntersection( const QgsRectangle &viewExtent, maxTileRow = tml->maxTileRow; } - col0 = qBound( minTileCol, ( int ) std::floor( ( viewExtent.xMinimum() - topLeft.x() ) / twMap ), maxTileCol ); - row0 = qBound( minTileRow, ( int ) std::floor( ( topLeft.y() - viewExtent.yMaximum() ) / thMap ), maxTileRow ); - col1 = qBound( minTileCol, ( int ) std::floor( ( viewExtent.xMaximum() - topLeft.x() ) / twMap ), maxTileCol ); - row1 = qBound( minTileRow, ( int ) std::floor( ( topLeft.y() - viewExtent.yMinimum() ) / thMap ), maxTileRow ); + col0 = std::clamp( ( int ) std::floor( ( viewExtent.xMinimum() - topLeft.x() ) / twMap ), minTileCol, maxTileCol ); + row0 = std::clamp( ( int ) std::floor( ( topLeft.y() - viewExtent.yMaximum() ) / thMap ), minTileRow, maxTileRow ); + col1 = std::clamp( ( int ) std::floor( ( viewExtent.xMaximum() - topLeft.x() ) / twMap ), minTileCol, maxTileCol ); + row1 = std::clamp( ( int ) std::floor( ( topLeft.y() - viewExtent.yMinimum() ) / thMap ), minTileRow, maxTileRow ); } const QgsWmtsTileMatrix *QgsWmtsTileMatrixSet::findNearestResolution( double vres ) const diff --git a/tests/code_layout/test_banned_keywords.sh b/tests/code_layout/test_banned_keywords.sh index cd797703626a..4b5140ed0278 100755 --- a/tests/code_layout/test_banned_keywords.sh +++ b/tests/code_layout/test_banned_keywords.sh @@ -137,6 +137,9 @@ HINTS[37]="Use range based for loops instead" KEYWORDS[38]="foreach" HINTS[38]="Use range based for loops instead" +KEYWORDS[39]="\bqBound(" +HINTS[39]="Use std::clamp instead (but be careful of the different argument order!!)" + RES= DIR=$(git rev-parse --show-toplevel) diff --git a/tests/qt_modeltest/modeltest.cpp b/tests/qt_modeltest/modeltest.cpp index de63369b4acf..ebdbc185dfd5 100644 --- a/tests/qt_modeltest/modeltest.cpp +++ b/tests/qt_modeltest/modeltest.cpp @@ -511,7 +511,7 @@ void ModelTest::rowsInserted( const QModelIndex &parent, int start, int end ) void ModelTest::layoutAboutToBeChanged() { - for ( int i = 0; i < qBound( 0, model->rowCount(), 100 ); ++i ) + for ( int i = 0; i < std::clamp( model->rowCount(), 0, 100 ); ++i ) changing.append( QPersistentModelIndex( model->index( i, 0 ) ) ); } From 23ba780e218cd13c4c942fc1d29e10c51777dbbd Mon Sep 17 00:00:00 2001 From: Harrissou Sant-anna Date: Sun, 21 Mar 2021 13:09:24 +0100 Subject: [PATCH 168/377] Fix use of TAB to explore dialogs and some Qt automatic cleanup --- src/ui/3d/animation3dwidget.ui | 2 + src/ui/3d/goochmaterialwidget.ui | 14 +- src/ui/3d/map3dconfigwidget.ui | 73 +++++--- src/ui/3d/phongmaterialwidget.ui | 15 +- src/ui/3d/polygon3dsymbolwidget.ui | 26 +-- src/ui/3d/qgs3drendererrulepropswidget.ui | 2 + src/ui/3d/qgslightswidget.ui | 7 + src/ui/3d/qgsmesh3dpropswidget.ui | 13 +- src/ui/3d/qgspointcloud3dsymbolwidget.ui | 38 +++- src/ui/3d/qgsvectorlayer3dpropertieswidget.ui | 4 + .../qgsattributeformcontaineredit.ui | 22 ++- .../qgsattributetypeedit.ui | 17 +- src/ui/callouts/widget_curvedlinecallout.ui | 17 +- src/ui/callouts/widget_simplelinecallout.ui | 12 +- .../editorwidgets/qgscheckboxconfigdlgbase.ui | 5 + .../qgsexternalresourceconfigdlg.ui | 24 ++- .../qgsrelationreferenceconfigdlgbase.ui | 10 +- .../qgsvaluerelationconfigdlgbase.ui | 15 +- src/ui/effects/widget_blur.ui | 17 +- src/ui/effects/widget_glow.ui | 34 ++-- src/ui/effects/widget_shadoweffect.ui | 35 ++-- .../qgstransformsettingsdialogbase.ui | 5 +- src/ui/labeling/qgslabelingrulepropswidget.ui | 14 +- .../labeling/qgslabellineanchorwidgetbase.ui | 16 +- .../qgslabelobstaclesettingswidgetbase.ui | 7 +- src/ui/labeling/qgslabelpropertydialogbase.ui | 28 +-- src/ui/layout/qgslayout3dmapwidgetbase.ui | 17 +- src/ui/layout/qgslayoutatlaswidgetbase.ui | 59 ++---- .../qgslayoutattributeselectiondialogbase.ui | 3 +- .../qgslayoutattributetablewidgetbase.ui | 45 ++--- src/ui/layout/qgslayoutlabelwidgetbase.ui | 28 +-- .../layout/qgslayoutlegendnodewidgetbase.ui | 14 +- src/ui/layout/qgslayoutlegendwidgetbase.ui | 66 +++---- .../layout/qgslayoutmanualtablewidgetbase.ui | 26 +-- src/ui/layout/qgslayoutmapgridwidgetbase.ui | 60 +++--- .../layout/qgslayoutmaplabelingwidgetbase.ui | 22 ++- src/ui/layout/qgslayoutmapwidgetbase.ui | 56 +++--- src/ui/layout/qgslayoutmarkerwidgetbase.ui | 31 ++-- .../layout/qgslayoutpagepropertieswidget.ui | 18 +- src/ui/layout/qgslayoutpicturewidgetbase.ui | 35 ++-- src/ui/layout/qgslayoutpolylinewidgetbase.ui | 41 +++-- src/ui/layout/qgsreportorganizerwidgetbase.ui | 36 +--- src/ui/mesh/qgsmeshcalculatordialogbase.ui | 44 ++++- src/ui/mesh/qgsmeshlayerpropertiesbase.ui | 61 ++++--- ...qgsmeshrendererscalarsettingswidgetbase.ui | 25 ++- .../qgsmeshvariablestrokewidthwidgetbase.ui | 4 +- .../qgsbasicnumericformatwidgetbase.ui | 24 ++- .../qgsbearingnumericformatwidgetbase.ui | 5 + .../qgscurrencynumericformatwidgetbase.ui | 8 + .../qgspercentagenumericformatwidgetbase.ui | 7 + ...spointcloudclassifiedrendererwidgetbase.ui | 1 + ...pointcloudelevationpropertieswidgetbase.ui | 16 +- .../qgspointcloudrendererpropsdialogbase.ui | 22 ++- .../qgsprocessingenummodelerwidgetbase.ui | 7 + .../qgsprocessingmatrixmodelerwidgetbase.ui | 9 + .../qgsprocessingmeshdatasettimewidget.ui | 11 +- .../qgsprocessingtinmeshdatawidgetbase.ui | 18 +- src/ui/qgsadvanceddigitizingfloaterbase.ui | 6 + src/ui/qgsanimationexportdialogbase.ui | 13 ++ src/ui/qgsattributesformproperties.ui | 13 +- src/ui/qgscolorrampshaderwidgetbase.ui | 2 + src/ui/qgscoordinateoperationwidgetbase.ui | 5 +- src/ui/qgscredentialdialog.ui | 6 +- src/ui/qgsdatadefinedsizelegendwidget.ui | 1 + src/ui/qgsdecorationlayoutextentdialog.ui | 5 +- src/ui/qgsdecorationscalebardialog.ui | 32 ++-- src/ui/qgsdecorationtitledialog.ui | 29 ++- src/ui/qgseditconditionalformatrulewidget.ui | 33 +++- src/ui/qgsexpressionbuilder.ui | 33 +++- src/ui/qgsfieldconditionalformatwidget.ui | 14 +- src/ui/qgsgeometryvalidationdockbase.ui | 7 + src/ui/qgsgpsinformationwidgetbase.ui | 70 +++---- src/ui/qgsgradientcolorrampdialogbase.ui | 28 ++- src/ui/qgsgraduatedsymbolrendererwidget.ui | 39 ++-- src/ui/qgsjoindialogbase.ui | 4 + src/ui/qgsmapsavedialog.ui | 26 +-- src/ui/qgsmetadatawidget.ui | 16 +- src/ui/qgsmssqlnewconnectionbase.ui | 17 +- src/ui/qgsnewhttpconnectionbase.ui | 16 +- src/ui/qgsnewogrconnectionbase.ui | 3 +- src/ui/qgsogrsourceselectbase.ui | 42 +++-- src/ui/qgsoptionsbase.ui | 118 ++++++------ src/ui/qgspgnewconnectionbase.ui | 27 ++- .../qgspointdisplacementrendererwidgetbase.ui | 38 ++-- src/ui/qgsprojectpropertiesbase.ui | 122 ++++++++----- src/ui/qgspropertyassistantwidgetbase.ui | 5 +- src/ui/qgsquerybuilderbase.ui | 12 +- src/ui/qgsrastercalcdialogbase.ui | 16 +- src/ui/qgsrasterlayerpropertiesbase.ui | 126 ++++++------- src/ui/qgsrelationmanageradddialogbase.ui | 8 + ...relationmanageraddpolymorphicdialogbase.ui | 21 ++- src/ui/qgssourcefieldsproperties.ui | 7 + src/ui/qgstextformatwidgetbase.ui | 171 +++++++++--------- src/ui/qgstilesourceselectbase.ui | 5 + src/ui/qgsvectorlayerpropertiesbase.ui | 65 ++++--- src/ui/qgswmsdimensiondialogbase.ui | 9 + src/ui/qgsxyzsourcewidgetbase.ui | 19 +- ...rasterlayertemporalpropertieswidgetbase.ui | 3 +- src/ui/symbollayer/widget_fontmarker.ui | 28 +-- src/ui/symbollayer/widget_randommarkerfill.ui | 29 ++- src/ui/symbollayer/widget_rastermarker.ui | 20 +- src/ui/symbollayer/widget_simpleline.ui | 32 ++-- src/ui/symbollayer/widget_svgmarker.ui | 22 ++- src/ui/symbollayer/widget_svgselector.ui | 20 +- src/ui/symbollayer/widget_symbolslist.ui | 31 ++-- 105 files changed, 1642 insertions(+), 1063 deletions(-) diff --git a/src/ui/3d/animation3dwidget.ui b/src/ui/3d/animation3dwidget.ui index 6ec20da25344..f69e90d8de46 100644 --- a/src/ui/3d/animation3dwidget.ui +++ b/src/ui/3d/animation3dwidget.ui @@ -295,9 +295,11 @@ btnRemoveKeyframe btnEditKeyframe btnDuplicateKeyframe + btnExportAnimation cboInterpolation btnPlayPause sliderTime + mLoopingCheckBox diff --git a/src/ui/3d/goochmaterialwidget.ui b/src/ui/3d/goochmaterialwidget.ui index db99fadb4011..d07dd88a5132 100644 --- a/src/ui/3d/goochmaterialwidget.ui +++ b/src/ui/3d/goochmaterialwidget.ui @@ -197,22 +197,26 @@
    qgsdoublespinbox.h
    - QgsColorButton + QgsPropertyOverrideButton QToolButton -
    qgscolorbutton.h
    - 1 +
    qgspropertyoverridebutton.h
    - QgsPropertyOverrideButton + QgsColorButton QToolButton -
    qgspropertyoverridebutton.h
    +
    qgscolorbutton.h
    + 1
    btnDiffuse + mDiffuseDataDefinedButton btnWarm + mWarmDataDefinedButton btnCool + mCoolDataDefinedButton btnSpecular + mSpecularDataDefinedButton spinShininess spinAlpha spinBeta diff --git a/src/ui/3d/map3dconfigwidget.ui b/src/ui/3d/map3dconfigwidget.ui index b0281470ac3a..110a5a7c95eb 100644 --- a/src/ui/3d/map3dconfigwidget.ui +++ b/src/ui/3d/map3dconfigwidget.ui @@ -179,7 +179,7 @@ - 3 + 0 @@ -205,8 +205,8 @@ 0 0 - 341 - 301 + 710 + 604 @@ -410,8 +410,8 @@ 0 0 - 77 - 47 + 710 + 604 @@ -494,8 +494,8 @@ 0 0 - 151 - 47 + 710 + 604 @@ -584,7 +584,7 @@ 0 0 - 709 + 710 604 @@ -724,8 +724,8 @@ 0 0 - 304 - 701 + 696 + 661 @@ -1040,55 +1040,66 @@ - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    QgsSpinBox QSpinBox
    qgsspinbox.h
    + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsScrollArea QScrollArea
    qgsscrollarea.h
    1
    - - QgsPhongMaterialWidget - QWidget -
    qgsphongmaterialwidget.h
    - 1 -
    QgsMapLayerComboBox QComboBox
    qgsmaplayercombobox.h
    - QgsLightsWidget + QgsMessageBar QWidget -
    qgslightswidget.h
    +
    qgsmessagebar.h
    1
    - QgsMessageBar + QgsPhongMaterialWidget QWidget -
    qgsmessagebar.h
    +
    qgsphongmaterialwidget.h
    + 1 +
    + + QgsLightsWidget + QWidget +
    qgslightswidget.h
    1
    - spinCameraFieldOfView + m3DOptionsListWidget + scrollAreaTerrain cboTerrainType cboTerrainLayer spinTerrainScale spinTerrainResolution spinTerrainSkirtHeight + terrainElevationOffsetSpinBox groupTerrainShading + scrollAreaLight + scrollAreaShadow + groupShadowRendering + scrollAreaCameraSkybox + cboCameraProjectionType + spinCameraFieldOfView + mCameraNavigationModeCombo + mCameraMovementSpeed groupSkyboxSettings + scrollAreaAdvanced spinMapResolution spinScreenError spinGroundError @@ -1097,6 +1108,16 @@ chkShowBoundingBoxes chkShowCameraViewCenter chkShowLightSourceOrigins + mFpsCounterCheckBox + edlGroupBox + edlStrengthSpinBox + edlDistanceSpinBox + mDebugShadowMapGroupBox + mDebugShadowMapCornerComboBox + mDebugShadowMapSizeSpinBox + mDebugDepthMapGroupBox + mDebugDepthMapCornerComboBox + mDebugDepthMapSizeSpinBox diff --git a/src/ui/3d/phongmaterialwidget.ui b/src/ui/3d/phongmaterialwidget.ui index 429cbea0fc71..2ae58aa75512 100644 --- a/src/ui/3d/phongmaterialwidget.ui +++ b/src/ui/3d/phongmaterialwidget.ui @@ -7,7 +7,7 @@ 0 0 394 - 133 + 134 @@ -127,21 +127,24 @@
    qgsdoublespinbox.h
    - QgsColorButton + QgsPropertyOverrideButton QToolButton -
    qgscolorbutton.h
    - 1 +
    qgspropertyoverridebutton.h
    - QgsPropertyOverrideButton + QgsColorButton QToolButton -
    qgspropertyoverridebutton.h
    +
    qgscolorbutton.h
    + 1
    btnDiffuse + mDiffuseDataDefinedButton btnAmbient + mAmbientDataDefinedButton btnSpecular + mSpecularDataDefinedButton spinShininess diff --git a/src/ui/3d/polygon3dsymbolwidget.ui b/src/ui/3d/polygon3dsymbolwidget.ui index f1d845a80946..d16fc6d3942f 100644 --- a/src/ui/3d/polygon3dsymbolwidget.ui +++ b/src/ui/3d/polygon3dsymbolwidget.ui @@ -278,9 +278,9 @@
    - QgsMaterialWidget - QWidget -
    qgsmaterialwidget.h
    + QgsCollapsibleGroupBox + QGroupBox +
    qgscollapsiblegroupbox.h
    1
    @@ -289,20 +289,20 @@
    qgsdoublespinbox.h
    - QgsColorButton + QgsPropertyOverrideButton QToolButton -
    qgscolorbutton.h
    - 1 +
    qgspropertyoverridebutton.h
    - QgsPropertyOverrideButton + QgsColorButton QToolButton -
    qgspropertyoverridebutton.h
    +
    qgscolorbutton.h
    + 1
    - QgsCollapsibleGroupBox - QGroupBox -
    qgscollapsiblegroupbox.h
    + QgsMaterialWidget + QWidget +
    qgsmaterialwidget.h
    1
    @@ -314,8 +314,12 @@ cboAltClamping cboAltBinding cboCullingMode + cboRenderedFacade chkAddBackFaces chkInvertNormals + groupEdges + spinEdgeWidth + btnEdgeColor
    diff --git a/src/ui/3d/qgs3drendererrulepropswidget.ui b/src/ui/3d/qgs3drendererrulepropswidget.ui index 0629f01907ff..c9358e2818f7 100644 --- a/src/ui/3d/qgs3drendererrulepropswidget.ui +++ b/src/ui/3d/qgs3drendererrulepropswidget.ui @@ -169,9 +169,11 @@ scrollArea editDescription + mFilterRadio editFilter btnExpressionBuilder btnTestFilter + mElseRadio groupSymbol diff --git a/src/ui/3d/qgslightswidget.ui b/src/ui/3d/qgslightswidget.ui index 5ad4b9c2b9c8..5b0147ab2eff 100644 --- a/src/ui/3d/qgslightswidget.ui +++ b/src/ui/3d/qgslightswidget.ui @@ -494,6 +494,9 @@ + mLightsListView + btnAddLight + btnRemoveLight spinPositionX spinPositionY spinPositionZ @@ -502,6 +505,10 @@ spinA0 spinA1 spinA2 + dialAzimuth + spinBoxAzimuth + spinBoxAltitude + sliderAltitude btnDirectionalColor spinDirectionalIntensity diff --git a/src/ui/3d/qgsmesh3dpropswidget.ui b/src/ui/3d/qgsmesh3dpropswidget.ui index d95e4713f901..03df89e562b6 100644 --- a/src/ui/3d/qgsmesh3dpropswidget.ui +++ b/src/ui/3d/qgsmesh3dpropswidget.ui @@ -406,6 +406,12 @@
    + + QgsCollapsibleGroupBox + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1 +
    QgsDoubleSpinBox QDoubleSpinBox @@ -417,12 +423,6 @@
    qgscolorbutton.h
    1
    - - QgsCollapsibleGroupBox - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 -
    QgsColorRampShaderWidget QWidget @@ -435,6 +435,7 @@ mGroupBoxWireframe mSpinBoxWireframeLineWidth mColorButtonWireframe + mLodSlider mSpinBoxVerticaleScale mComboBoxDatasetVertical mCheckBoxVerticalMagnitudeRelative diff --git a/src/ui/3d/qgspointcloud3dsymbolwidget.ui b/src/ui/3d/qgspointcloud3dsymbolwidget.ui index e77361d1aaec..30cd4e4b1cd4 100644 --- a/src/ui/3d/qgspointcloud3dsymbolwidget.ui +++ b/src/ui/3d/qgspointcloud3dsymbolwidget.ui @@ -6,7 +6,7 @@ 0 0 - 573 + 581 491 @@ -542,9 +542,10 @@ enhancement
    qgsdoublespinbox.h
    - QgsPointCloudAttributeComboBox - QComboBox -
    qgspointcloudattributecombobox.h
    + QgsColorButton + QToolButton +
    qgscolorbutton.h
    + 1
    QgsColorRampShaderWidget @@ -553,12 +554,33 @@ enhancement 1 - QgsColorButton - QToolButton -
    qgscolorbutton.h
    - 1 + QgsPointCloudAttributeComboBox + QComboBox +
    qgspointcloudattributecombobox.h
    + + mRenderingStyleComboBox + mSingleColorBtn + mPointSizeSpinBox + mMaxScreenErrorSpinBox + mPointBudgetSpinBox + mShowBoundingBoxesCheckBox + mRenderingParameterComboBox + mColorRampShaderMinEdit + mColorRampShaderMaxEdit + mScalarRecalculateMinMaxButton + mContrastEnhancementAlgorithmComboBox + mRedMinLineEdit + mRedAttributeComboBox + mGreenAttributeComboBox + mBlueAttributeComboBox + mRedMaxLineEdit + mGreenMinLineEdit + mBlueMinLineEdit + mBlueMaxLineEdit + mGreenMaxLineEdit + diff --git a/src/ui/3d/qgsvectorlayer3dpropertieswidget.ui b/src/ui/3d/qgsvectorlayer3dpropertieswidget.ui index e0835f0783c6..fd5ba4dbb911 100644 --- a/src/ui/3d/qgsvectorlayer3dpropertieswidget.ui +++ b/src/ui/3d/qgsvectorlayer3dpropertieswidget.ui @@ -81,6 +81,10 @@
    qgsspinbox.h
    + + spinZoomLevelsCount + chkShowBoundingBoxes + diff --git a/src/ui/attributeformconfig/qgsattributeformcontaineredit.ui b/src/ui/attributeformconfig/qgsattributeformcontaineredit.ui index 1437295d45f8..5694c5380c06 100644 --- a/src/ui/attributeformconfig/qgsattributeformcontaineredit.ui +++ b/src/ui/attributeformconfig/qgsattributeformcontaineredit.ui @@ -58,7 +58,7 @@ - +
    @@ -111,11 +111,6 @@
    qgscollapsiblegroupbox.h
    1 - - QgsColorButton - QToolButton -
    qgscolorbutton.h
    -
    QgsSpinBox QSpinBox @@ -125,8 +120,23 @@ QgsFieldExpressionWidget QWidget
    qgsfieldexpressionwidget.h
    + 1 +
    + + QgsColorButton + QToolButton +
    qgscolorbutton.h
    + 1
    + + mShowLabelCheckBox + mShowAsGroupBoxCheckBox + mTitleLineEdit + mColumnCountSpinBox + mControlVisibilityGroupBox + mBackgroundColorButton + diff --git a/src/ui/attributeformconfig/qgsattributetypeedit.ui b/src/ui/attributeformconfig/qgsattributetypeedit.ui index 87f7719f49a7..88a463f1b4ea 100644 --- a/src/ui/attributeformconfig/qgsattributetypeedit.ui +++ b/src/ui/attributeformconfig/qgsattributetypeedit.ui @@ -6,7 +6,7 @@ 0 0 - 751 + 752 620 @@ -299,20 +299,24 @@
    qgsfieldexpressionwidget.h
    1 + + QgsPropertyOverrideButton + QToolButton +
    qgspropertyoverridebutton.h
    +
    QgsExpressionLineEdit QWidget
    qgsexpressionlineedit.h
    1
    - - QgsPropertyOverrideButton - QToolButton -
    qgspropertyoverridebutton.h
    -
    + mAlias + mAliasExpressionButton isFieldEditableCheckBox + reuseLastValuesCheckBox + labelOnTopCheckBox mWidgetTypeComboBox notNullCheckBox mCheckBoxEnforceNotNull @@ -322,6 +326,7 @@ leConstraintExpressionDescription mCheckBoxEnforceExpression mExpressionWidget + mApplyDefaultValueOnUpdateCheckBox diff --git a/src/ui/callouts/widget_curvedlinecallout.ui b/src/ui/callouts/widget_curvedlinecallout.ui index b2ab822adae9..f7bc071a2312 100644 --- a/src/ui/callouts/widget_curvedlinecallout.ui +++ b/src/ui/callouts/widget_curvedlinecallout.ui @@ -516,14 +516,14 @@
    qgsdoublespinbox.h
    - QgsSymbolButton + QgsPropertyOverrideButton QToolButton -
    qgssymbolbutton.h
    +
    qgspropertyoverridebutton.h
    - QgsPropertyOverrideButton + QgsSymbolButton QToolButton -
    qgspropertyoverridebutton.h
    +
    qgssymbolbutton.h
    QgsUnitSelectionWidget @@ -534,6 +534,11 @@ mCalloutLineStyleButton + mCurvatureSlider + mCurvatureSpinBox + mCalloutCurvatureDDBtn + mOrientationComboBox + mCalloutOrientationDDBtn mMinCalloutLengthSpin mMinCalloutWidthUnitWidget mMinCalloutLengthDDBtn @@ -549,6 +554,10 @@ mAnchorPointDDBtn mLabelAnchorPointComboBox mLabelAnchorPointDDBtn + mOriginXDDBtn + mOriginYDDBtn + mDestXDDBtn + mDestYDDBtn diff --git a/src/ui/callouts/widget_simplelinecallout.ui b/src/ui/callouts/widget_simplelinecallout.ui index 18f9623434a2..0029d61de425 100644 --- a/src/ui/callouts/widget_simplelinecallout.ui +++ b/src/ui/callouts/widget_simplelinecallout.ui @@ -449,14 +449,14 @@
    qgsdoublespinbox.h
    - QgsSymbolButton + QgsPropertyOverrideButton QToolButton -
    qgssymbolbutton.h
    +
    qgspropertyoverridebutton.h
    - QgsPropertyOverrideButton + QgsSymbolButton QToolButton -
    qgspropertyoverridebutton.h
    +
    qgssymbolbutton.h
    QgsUnitSelectionWidget @@ -482,6 +482,10 @@ mAnchorPointDDBtn mLabelAnchorPointComboBox mLabelAnchorPointDDBtn + mOriginXDDBtn + mOriginYDDBtn + mDestXDDBtn + mDestYDDBtn diff --git a/src/ui/editorwidgets/qgscheckboxconfigdlgbase.ui b/src/ui/editorwidgets/qgscheckboxconfigdlgbase.ui index 174dd38b950c..f819f019fb94 100644 --- a/src/ui/editorwidgets/qgscheckboxconfigdlgbase.ui +++ b/src/ui/editorwidgets/qgscheckboxconfigdlgbase.ui @@ -102,6 +102,11 @@
    + + leCheckedState + leUncheckedState + mDisplayAsTextComboBox + diff --git a/src/ui/editorwidgets/qgsexternalresourceconfigdlg.ui b/src/ui/editorwidgets/qgsexternalresourceconfigdlg.ui index ad7f98de68a4..b42331f86659 100644 --- a/src/ui/editorwidgets/qgsexternalresourceconfigdlg.ui +++ b/src/ui/editorwidgets/qgsexternalresourceconfigdlg.ui @@ -46,8 +46,8 @@ 0 0 - 467 - 715 + 481 + 690 @@ -478,17 +478,17 @@ + + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    QgsScrollArea QScrollArea
    qgsscrollarea.h
    1
    - - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    -
    QgsPropertyOverrideButton QToolButton @@ -498,6 +498,9 @@ scrollArea mRootPath + mRootPathExpression + mRootPathButton + mRootPathPropertyOverrideButton mRelativeGroupBox mRelativeProject mRelativeDefault @@ -508,13 +511,16 @@ mFileWidgetFilterLineEdit mUseLink mFullUrl - mDocumentViewerGroupBox mDocumentViewerContentComboBox + mDocumentViewerContentExpression + mDocumentViewerContentPropertyOverrideButton + mDocumentViewerWidth + mDocumentViewerHeight - + diff --git a/src/ui/editorwidgets/qgsrelationreferenceconfigdlgbase.ui b/src/ui/editorwidgets/qgsrelationreferenceconfigdlgbase.ui index cb9529751038..3d089ce956ec 100644 --- a/src/ui/editorwidgets/qgsrelationreferenceconfigdlgbase.ui +++ b/src/ui/editorwidgets/qgsrelationreferenceconfigdlgbase.ui @@ -7,7 +7,7 @@ 0 0 470 - 502 + 540 @@ -82,12 +82,12 @@ - - Display expression Ⓘ - This setting is not saved in the style. It is changing the display name on the referenced layer. + + Display expression Ⓘ + @@ -246,6 +246,8 @@ mRemoveFilterButton mFilterFieldsList mCbxChainFilters + mEditExpression + mFilterExpression diff --git a/src/ui/editorwidgets/qgsvaluerelationconfigdlgbase.ui b/src/ui/editorwidgets/qgsvaluerelationconfigdlgbase.ui index 81e25c7f5556..c6d71b9dd2dd 100644 --- a/src/ui/editorwidgets/qgsvaluerelationconfigdlgbase.ui +++ b/src/ui/editorwidgets/qgsvaluerelationconfigdlgbase.ui @@ -152,20 +152,15 @@ - - QgsFieldComboBox - QComboBox -
    qgsfieldcombobox.h
    -
    QgsSpinBox QSpinBox
    qgsspinbox.h
    - QgsMapLayerComboBox + QgsFieldComboBox QComboBox -
    qgsmaplayercombobox.h
    +
    qgsfieldcombobox.h
    QgsFieldExpressionWidget @@ -173,6 +168,11 @@
    qgsfieldexpressionwidget.h
    1
    + + QgsMapLayerComboBox + QComboBox +
    qgsmaplayercombobox.h
    +
    mLayerName @@ -181,6 +181,7 @@ mAllowNull mOrderByValue mAllowMulti + mNofColumns mUseCompleter mEditExpression mFilterExpression diff --git a/src/ui/effects/widget_blur.ui b/src/ui/effects/widget_blur.ui index 1d7cc706b07a..a259ec7d78c4 100644 --- a/src/ui/effects/widget_blur.ui +++ b/src/ui/effects/widget_blur.ui @@ -141,14 +141,15 @@
    qgsdoublespinbox.h
    - QgsBlendModeComboBox - QComboBox -
    qgsblendmodecombobox.h
    + QgsUnitSelectionWidget + QWidget +
    qgsunitselectionwidget.h
    + 1
    - QgsEffectDrawModeComboBox + QgsBlendModeComboBox QComboBox -
    qgseffectdrawmodecombobox.h
    +
    qgsblendmodecombobox.h
    QgsOpacityWidget @@ -156,10 +157,16 @@
    qgsopacitywidget.h
    1
    + + QgsEffectDrawModeComboBox + QComboBox +
    qgseffectdrawmodecombobox.h
    +
    mBlurTypeCombo mBlurStrengthSpnBx + mBlurUnitWidget mOpacityWidget mBlendCmbBx mDrawModeComboBox diff --git a/src/ui/effects/widget_glow.ui b/src/ui/effects/widget_glow.ui index 55b5957b544c..c2dd1cb74447 100644 --- a/src/ui/effects/widget_glow.ui +++ b/src/ui/effects/widget_glow.ui @@ -216,6 +216,11 @@ + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsColorButton QToolButton @@ -223,48 +228,39 @@ 1 - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    + QgsUnitSelectionWidget + QWidget +
    qgsunitselectionwidget.h
    + 1
    QgsBlendModeComboBox QComboBox
    qgsblendmodecombobox.h
    - - QgsEffectDrawModeComboBox - QComboBox -
    qgseffectdrawmodecombobox.h
    -
    QgsOpacityWidget QWidget
    qgsopacitywidget.h
    1
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    - - QgsUnitSelectionWidget - QWidget -
    qgsunitselectionwidget.h
    - 1 -
    QgsColorRampButton QToolButton
    qgscolorrampbutton.h
    1
    + + QgsEffectDrawModeComboBox + QComboBox +
    qgseffectdrawmodecombobox.h
    +
    mSpreadSpnBx mSpreadUnitWidget mBlurRadiusSpnBx + mBlurUnitWidget mOpacityWidget radioSingleColor mColorBtn diff --git a/src/ui/effects/widget_shadoweffect.ui b/src/ui/effects/widget_shadoweffect.ui index c4dbe3f50d75..c0d6906f44fb 100644 --- a/src/ui/effects/widget_shadoweffect.ui +++ b/src/ui/effects/widget_shadoweffect.ui @@ -250,6 +250,16 @@ + + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsColorButton QToolButton @@ -257,20 +267,16 @@ 1 - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    + QgsUnitSelectionWidget + QWidget +
    qgsunitselectionwidget.h
    + 1
    QgsBlendModeComboBox QComboBox
    qgsblendmodecombobox.h
    - - QgsEffectDrawModeComboBox - QComboBox -
    qgseffectdrawmodecombobox.h
    -
    QgsOpacityWidget QWidget @@ -278,15 +284,9 @@ 1 - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    - - QgsUnitSelectionWidget - QWidget -
    qgsunitselectionwidget.h
    - 1 + QgsEffectDrawModeComboBox + QComboBox +
    qgseffectdrawmodecombobox.h
    @@ -295,6 +295,7 @@ mShadowOffsetSpnBx mOffsetUnitWidget mShadowRadiuSpnBx + mBlurUnitWidget mOpacityWidget mShadowColorBtn mShadowBlendCmbBx diff --git a/src/ui/georeferencer/qgstransformsettingsdialogbase.ui b/src/ui/georeferencer/qgstransformsettingsdialogbase.ui index dc6d26608910..fe2d9a833d06 100644 --- a/src/ui/georeferencer/qgstransformsettingsdialogbase.ui +++ b/src/ui/georeferencer/qgstransformsettingsdialogbase.ui @@ -340,15 +340,14 @@ cmbTransformType cmbResampling mCrsSelector - mOutputRaster cmbCompressionComboBox + saveGcpCheckBox mWorldFileCheckBox cbxZeroAsTrans cbxUserResolution dsbHorizRes dsbVerticalRes - mPdfMap - mPdfReport + cbxLoadInQgisWhenDone diff --git a/src/ui/labeling/qgslabelingrulepropswidget.ui b/src/ui/labeling/qgslabelingrulepropswidget.ui index fc2c938825eb..41758b54f936 100644 --- a/src/ui/labeling/qgslabelingrulepropswidget.ui +++ b/src/ui/labeling/qgslabelingrulepropswidget.ui @@ -119,7 +119,7 @@ - + :/images/themes/default/mIconExpression.svg:/images/themes/default/mIconExpression.svg @@ -184,24 +184,26 @@ - - QgsScaleRangeWidget - QWidget -
    qgsscalerangewidget.h
    -
    QgsScrollArea QScrollArea
    qgsscrollarea.h
    1
    + + QgsScaleRangeWidget + QWidget +
    qgsscalerangewidget.h
    +
    scrollArea editDescription + mFilterRadio editFilter btnExpressionBuilder btnTestFilter + mElseRadio groupScale groupSettings diff --git a/src/ui/labeling/qgslabellineanchorwidgetbase.ui b/src/ui/labeling/qgslabellineanchorwidgetbase.ui index df75f87549f1..ee79527e5e32 100644 --- a/src/ui/labeling/qgslabellineanchorwidgetbase.ui +++ b/src/ui/labeling/qgslabellineanchorwidgetbase.ui @@ -110,6 +110,11 @@ + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsPropertyOverrideButton QToolButton @@ -121,12 +126,13 @@
    qgspanelwidget.h
    1
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    + + mPercentPlacementComboBox + mLinePlacementDDBtn + mCustomPlacementSpinBox + mAnchorTypeComboBox + diff --git a/src/ui/labeling/qgslabelobstaclesettingswidgetbase.ui b/src/ui/labeling/qgslabelobstaclesettingswidgetbase.ui index 7202a2090fa8..db653a953815 100644 --- a/src/ui/labeling/qgslabelobstaclesettingswidgetbase.ui +++ b/src/ui/labeling/qgslabelobstaclesettingswidgetbase.ui @@ -6,7 +6,7 @@ 0 0 - 237 + 249 225 @@ -140,6 +140,11 @@ 1 + + mObstacleFactorSlider + mObstacleFactorDDBtn + mObstacleTypeComboBox + diff --git a/src/ui/labeling/qgslabelpropertydialogbase.ui b/src/ui/labeling/qgslabelpropertydialogbase.ui index d0c9cd85dab4..00585cd3ee57 100644 --- a/src/ui/labeling/qgslabelpropertydialogbase.ui +++ b/src/ui/labeling/qgslabelpropertydialogbase.ui @@ -40,7 +40,7 @@ 0 - -108 + 0 419 731 @@ -678,28 +678,28 @@ - - QgsScrollArea - QScrollArea -
    qgsscrollarea.h
    - 1 -
    QgsCollapsibleGroupBox QGroupBox
    qgscollapsiblegroupbox.h
    1
    - - QgsScaleWidget - QWidget -
    qgsscalewidget.h
    -
    QgsDoubleSpinBox QDoubleSpinBox
    qgsdoublespinbox.h
    + + QgsScrollArea + QScrollArea +
    qgsscrollarea.h
    + 1 +
    + + QgsScaleWidget + QWidget +
    qgsscalewidget.h
    +
    QgsColorButton QToolButton @@ -722,14 +722,18 @@ mFontItalicBtn mFontSizeSpinBox mFontColorButton + mMultiLineAlignComboBox + mBufferDrawChkbx mBufferSizeSpinBox mBufferColorButton + mShowCalloutChkbx mLabelDistanceSpinBox mXCoordSpinBox mYCoordSpinBox mHaliComboBox mValiComboBox mRotationSpinBox + mLabelAllPartsCheckBox
    diff --git a/src/ui/layout/qgslayout3dmapwidgetbase.ui b/src/ui/layout/qgslayout3dmapwidgetbase.ui index d0a4d202cdcc..20c622db1b5f 100644 --- a/src/ui/layout/qgslayout3dmapwidgetbase.ui +++ b/src/ui/layout/qgslayout3dmapwidgetbase.ui @@ -54,9 +54,9 @@ 0 - -128 - 510 - 698 + 0 + 538 + 590 @@ -222,6 +222,17 @@
    qgsdoublespinbox.h
    + + scrollArea + mCopySettingsButton + mCenterXSpinBox + mCenterYSpinBox + mCenterZSpinBox + mDistanceToCenterSpinBox + mPitchAngleSpinBox + mHeadingAngleSpinBox + mPoseFromViewButton + diff --git a/src/ui/layout/qgslayoutatlaswidgetbase.ui b/src/ui/layout/qgslayoutatlaswidgetbase.ui index a4343851b877..2ad279918ebf 100644 --- a/src/ui/layout/qgslayoutatlaswidgetbase.ui +++ b/src/ui/layout/qgslayoutatlaswidgetbase.ui @@ -109,10 +109,10 @@ - -122 - -223 - 525 - 673 + 0 + 0 + 417 + 354 @@ -325,31 +325,33 @@ - - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 -
    QgsScrollArea QScrollArea
    qgsscrollarea.h
    1
    + + QgsFieldExpressionWidget + QWidget +
    qgsfieldexpressionwidget.h
    + 1 +
    QgsMapLayerComboBox QComboBox -
    qgsmaplayercombobox.h
    +
    qgsmaplayercombobox.h
    - QgsFieldExpressionWidget - QWidget -
    qgsfieldexpressionwidget.h
    + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1
    mUseAtlasCheckBox + scrollArea mConfigurationGroup mAtlasCoverageLayerComboBox mAtlasHideCoverageCheckBox @@ -357,42 +359,15 @@ mAtlasFeatureFilterEdit mAtlasFeatureFilterButton mAtlasSortFeatureCheckBox - mAtlasSortExpressionWidget mAtlasSortFeatureDirectionButton mOutputGroup mAtlasFilenamePatternEdit mAtlasFilenameExpressionButton mAtlasSingleFileCheckBox - scrollArea + mAtlasFileFormat - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/ui/layout/qgslayoutattributeselectiondialogbase.ui b/src/ui/layout/qgslayoutattributeselectiondialogbase.ui index d3fb3224bc29..c31883e6a266 100644 --- a/src/ui/layout/qgslayoutattributeselectiondialogbase.ui +++ b/src/ui/layout/qgslayoutattributeselectiondialogbase.ui @@ -243,11 +243,12 @@ mAddColumnPushButton mRemoveColumnPushButton mResetColumnsPushButton + mClearColumnsPushButton mSortColumnTableView mSortColumnUpPushButton mSortColumnDownPushButton + mAddSortColumnPushButton mRemoveSortColumnPushButton - buttonBox
    diff --git a/src/ui/layout/qgslayoutattributetablewidgetbase.ui b/src/ui/layout/qgslayoutattributetablewidgetbase.ui index e5c457194e5a..d994c6c03a1b 100644 --- a/src/ui/layout/qgslayoutattributetablewidgetbase.ui +++ b/src/ui/layout/qgslayoutattributetablewidgetbase.ui @@ -54,9 +54,9 @@ 0 - -629 + -551 394 - 1419 + 1343 @@ -686,10 +686,14 @@ - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    QgsScrollArea @@ -698,9 +702,9 @@ 1 - QgsMapLayerComboBox - QComboBox -
    qgsmaplayercombobox.h
    + QgsPropertyOverrideButton + QToolButton +
    qgspropertyoverridebutton.h
    QgsColorButton @@ -708,31 +712,27 @@
    qgscolorbutton.h
    1
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    QgsFontButton QToolButton
    qgsfontbutton.h
    - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    + QgsMapLayerComboBox + QComboBox +
    qgsmaplayercombobox.h
    +
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1
    QgsLayoutItemComboBox QComboBox
    qgslayoutitemcombobox.h
    - - QgsPropertyOverrideButton - QToolButton -
    qgspropertyoverridebutton.h
    -
    scrollArea @@ -760,6 +760,7 @@ mEmptyMessageLineEdit mBackgroundColorButton mAdvancedCustomizationButton + mUseConditionalStylingCheckBox mWrapStringLineEdit mWrapBehaviorComboBox mShowGridGroupCheckBox diff --git a/src/ui/layout/qgslayoutlabelwidgetbase.ui b/src/ui/layout/qgslayoutlabelwidgetbase.ui index e702767ce24a..13e5dfe0889b 100644 --- a/src/ui/layout/qgslayoutlabelwidgetbase.ui +++ b/src/ui/layout/qgslayoutlabelwidgetbase.ui @@ -62,7 +62,7 @@ 0 0 358 - 680 + 682 @@ -373,6 +373,11 @@ + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsScrollArea QScrollArea @@ -385,22 +390,17 @@
    qgscolorbutton.h
    1
    - - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 -
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    QgsFontButton QToolButton
    qgsfontbutton.h
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1 +
    scrollArea @@ -408,6 +408,7 @@ mTextEdit mHtmlCheckBox mInsertExpressionButton + mDynamicTextButton mAppearanceGroup mFontButton mFontColorButton @@ -416,6 +417,7 @@ mLeftRadioButton mCenterRadioButton mRightRadioButton + mJustifyRadioButton mTopRadioButton mMiddleRadioButton mBottomRadioButton @@ -423,7 +425,7 @@ - + diff --git a/src/ui/layout/qgslayoutlegendnodewidgetbase.ui b/src/ui/layout/qgslayoutlegendnodewidgetbase.ui index 4c033792343d..60b959e223ae 100644 --- a/src/ui/layout/qgslayoutlegendnodewidgetbase.ui +++ b/src/ui/layout/qgslayoutlegendnodewidgetbase.ui @@ -193,17 +193,17 @@ QDoubleSpinBox
    qgsdoublespinbox.h
    + + QgsSymbolButton + QToolButton +
    qgssymbolbutton.h
    +
    QgsPanelWidget QWidget
    qgspanelwidget.h
    1
    - - QgsSymbolButton - QToolButton -
    qgssymbolbutton.h
    -
    QgsLegendPatchShapeButton QToolButton @@ -222,6 +222,10 @@ mPatchShapeButton mWidthSpinBox mHeightSpinBox + mCustomSymbolCheckBox + mCustomSymbolButton + mColumnBreakBeforeCheckBox + mColumnSplitBehaviorComboBox
    diff --git a/src/ui/layout/qgslayoutlegendwidgetbase.ui b/src/ui/layout/qgslayoutlegendwidgetbase.ui index 37d383b3c290..ac7de8ee6b82 100644 --- a/src/ui/layout/qgslayoutlegendwidgetbase.ui +++ b/src/ui/layout/qgslayoutlegendwidgetbase.ui @@ -63,9 +63,9 @@ 0 - -1031 - 387 - 2728 + 0 + 367 + 2191 @@ -1315,10 +1315,14 @@ - QgsColorButton - QToolButton -
    qgscolorbutton.h
    - 1 + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    QgsScrollArea @@ -1327,51 +1331,47 @@ 1 - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    + QgsPropertyOverrideButton + QToolButton +
    qgspropertyoverridebutton.h
    - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    + QgsColorButton + QToolButton +
    qgscolorbutton.h
    1
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    - - QgsLayoutItemComboBox - QComboBox -
    qgslayoutitemcombobox.h
    -
    QgsFontButton QToolButton
    qgsfontbutton.h
    - QgsPropertyOverrideButton - QToolButton -
    qgspropertyoverridebutton.h
    + QgsAlignmentComboBox + QComboBox +
    qgsalignmentcombobox.h
    +
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1
    QgsLayerTreeView QTreeView
    qgslayertreeview.h
    + + QgsLayoutItemComboBox + QComboBox +
    qgslayoutitemcombobox.h
    +
    QgsLegendFilterButton QToolButton
    qgslegendfilterbutton.h
    - - QgsAlignmentComboBox - QComboBox -
    qgsalignmentcombobox.h
    -
    scrollArea @@ -1392,6 +1392,7 @@ mAddToolButton mRemoveToolButton mEditPushButton + mLayerExpressionButton mCountToolButton mExpressionFilterButton mFilterByMapCheckBox @@ -1414,6 +1415,8 @@ mSymbolsColGroupBox mSymbolWidthSpinBox mSymbolHeightSpinBox + mMinSymbolSizeSpinBox + mMaxSymbolSizeSpinBox mRasterStrokeGroupBox mRasterStrokeColorButton mRasterStrokeWidthSpinBox @@ -1434,7 +1437,6 @@ mBoxSpaceSpinBox mColumnSpaceSpinBox mLineSpacingSpinBox - mLayerExpressionButton diff --git a/src/ui/layout/qgslayoutmanualtablewidgetbase.ui b/src/ui/layout/qgslayoutmanualtablewidgetbase.ui index 8b9aeb55b3e7..70dd58163e9a 100644 --- a/src/ui/layout/qgslayoutmanualtablewidgetbase.ui +++ b/src/ui/layout/qgslayoutmanualtablewidgetbase.ui @@ -54,9 +54,9 @@ 0 - 0 + -76 394 - 914 + 868 @@ -464,10 +464,9 @@ - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    QgsScrollArea @@ -481,16 +480,17 @@
    qgscolorbutton.h
    1
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    QgsFontButton QToolButton
    qgsfontbutton.h
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1 +
    scrollArea @@ -499,6 +499,7 @@ groupBox_6 mDrawEmptyCheckBox mMarginSpinBox + mHeaderModeComboBox mBackgroundColorButton mAdvancedCustomizationButton mWrapBehaviorComboBox @@ -507,6 +508,9 @@ mGridColorButton mDrawHorizontalGrid mDrawVerticalGrid + mHeaderFontToolButton + mHeaderHAlignmentComboBox + mContentFontToolButton frameGroupBox mResizeModeComboBox mAddFramePushButton diff --git a/src/ui/layout/qgslayoutmapgridwidgetbase.ui b/src/ui/layout/qgslayoutmapgridwidgetbase.ui index 4815fafc2649..eaeac3767336 100644 --- a/src/ui/layout/qgslayoutmapgridwidgetbase.ui +++ b/src/ui/layout/qgslayoutmapgridwidgetbase.ui @@ -48,8 +48,8 @@ 0 0 - 492 - 1225 + 493 + 1620 @@ -1110,15 +1110,20 @@ + + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    QgsDoubleSpinBox QDoubleSpinBox
    qgsdoublespinbox.h
    - QgsColorButton - QToolButton -
    qgscolorbutton.h
    + QgsProjectionSelectionWidget + QWidget +
    qgsprojectionselectionwidget.h
    1
    @@ -1127,41 +1132,36 @@
    qgsscrollarea.h
    1
    - - QgsFontButton - QToolButton -
    qgsfontbutton.h
    -
    QgsPropertyOverrideButton QToolButton
    qgspropertyoverridebutton.h
    - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    + QgsColorButton + QToolButton +
    qgscolorbutton.h
    + 1
    QgsSymbolButton QToolButton
    qgssymbolbutton.h
    - - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 -
    QgsBlendModeComboBox QComboBox
    qgsblendmodecombobox.h
    - QgsProjectionSelectionWidget - QWidget -
    qgsprojectionselectionwidget.h
    + QgsFontButton + QToolButton +
    qgsfontbutton.h
    +
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    1
    @@ -1198,6 +1198,14 @@ mGridFramePenColorButton mGridFrameFill1ColorButton mGridFrameFill2ColorButton + mFrameDivisionsLeftComboBox + mFrameDivisionsLeftDDBtn + mFrameDivisionsRightComboBox + mFrameDivisionsRightDDBtn + mFrameDivisionsTopComboBox + mFrameDivisionsTopDDBtn + mFrameDivisionsBottomComboBox + mFrameDivisionsBottomDDBtn mCheckGridLeftSide mCheckGridRightSide mCheckGridTopSide @@ -1209,12 +1217,20 @@ mDrawAnnotationGroupBox mAnnotationFormatComboBox mAnnotationFormatButton + mAnnotationDisplayLeftComboBox + mAnnotationDisplayLeftDDBtn mAnnotationPositionLeftComboBox mAnnotationDirectionComboBoxLeft + mAnnotationDisplayRightComboBox + mAnnotationDisplayRightDDBtn mAnnotationPositionRightComboBox mAnnotationDirectionComboBoxRight + mAnnotationDisplayTopComboBox + mAnnotationDisplayTopDDBtn mAnnotationPositionTopComboBox mAnnotationDirectionComboBoxTop + mAnnotationDisplayBottomComboBox + mAnnotationDisplayBottomDDBtn mAnnotationPositionBottomComboBox mAnnotationDirectionComboBoxBottom mAnnotationFontButton diff --git a/src/ui/layout/qgslayoutmaplabelingwidgetbase.ui b/src/ui/layout/qgslayoutmaplabelingwidgetbase.ui index 07a38f94cf7d..b9e4f649fca8 100644 --- a/src/ui/layout/qgslayoutmaplabelingwidgetbase.ui +++ b/src/ui/layout/qgslayoutmaplabelingwidgetbase.ui @@ -6,7 +6,7 @@ 0 0 - 211 + 318 408
    @@ -146,20 +146,20 @@ - - QgsPropertyOverrideButton - QToolButton -
    qgspropertyoverridebutton.h
    -
    QgsDoubleSpinBox QDoubleSpinBox
    qgsdoublespinbox.h
    + + QgsPropertyOverrideButton + QToolButton +
    qgspropertyoverridebutton.h
    +
    QgsCollapsibleGroupBoxBasic QGroupBox -
    qgscollapsiblegroupbox.h
    +
    qgscollapsiblegroupbox.h
    1
    @@ -168,6 +168,14 @@
    qgslayoutunitscombobox.h
    + + mLabelBoundarySpinBox + mLabelBoundaryUnitsCombo + mLabelMarginDDBtn + mShowPartialLabelsCheckBox + mBlockingItemsListView + mShowUnplacedCheckBox + diff --git a/src/ui/layout/qgslayoutmapwidgetbase.ui b/src/ui/layout/qgslayoutmapwidgetbase.ui index 472d94484370..5db8a572bcc4 100644 --- a/src/ui/layout/qgslayoutmapwidgetbase.ui +++ b/src/ui/layout/qgslayoutmapwidgetbase.ui @@ -90,7 +90,7 @@ 0 0 548 - 1284 + 1336 @@ -1011,10 +1011,9 @@ - QgsScrollArea - QScrollArea -
    qgsscrollarea.h
    - 1 + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    QgsDoubleSpinBox @@ -1022,20 +1021,16 @@
    qgsdoublespinbox.h
    - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    -
    - - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    + QgsProjectionSelectionWidget + QWidget +
    qgsprojectionselectionwidget.h
    1
    - QgsLayoutItemComboBox - QComboBox -
    qgslayoutitemcombobox.h
    + QgsScrollArea + QScrollArea +
    qgsscrollarea.h
    + 1
    QgsPropertyOverrideButton @@ -1043,9 +1038,9 @@
    qgspropertyoverridebutton.h
    - QgsMapLayerComboBox - QComboBox -
    qgsmaplayercombobox.h
    + QgsSymbolButton + QToolButton +
    qgssymbolbutton.h
    QgsBlendModeComboBox @@ -1053,15 +1048,20 @@
    qgsblendmodecombobox.h
    - QgsProjectionSelectionWidget - QWidget -
    qgsprojectionselectionwidget.h
    + QgsMapLayerComboBox + QComboBox +
    qgsmaplayercombobox.h
    +
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    1
    - QgsSymbolButton - QToolButton -
    qgssymbolbutton.h
    + QgsLayoutItemComboBox + QComboBox +
    qgslayoutitemcombobox.h
    @@ -1072,6 +1072,7 @@ mMapRotationSpinBox mMapRotationDDBtn mCrsSelector + mCRSDDBtn mDrawCanvasItemsCheckBox mFollowVisibilityPresetCheckBox mFollowVisibilityPresetCombo @@ -1089,6 +1090,11 @@ mXMaxDDBtn mYMaxLineEdit mYMaxDDBtn + mTemporalCheckBox + mStartDateTime + mStartDateTimeDDBtn + mEndDateTime + mEndDateTimeDDBtn mAtlasCheckBox mAtlasMarginRadio mAtlasMarginSpinBox diff --git a/src/ui/layout/qgslayoutmarkerwidgetbase.ui b/src/ui/layout/qgslayoutmarkerwidgetbase.ui index 22fc9546436a..abc0323411fd 100644 --- a/src/ui/layout/qgslayoutmarkerwidgetbase.ui +++ b/src/ui/layout/qgslayoutmarkerwidgetbase.ui @@ -56,7 +56,7 @@ 0 0 306 - 247 + 249
    @@ -166,28 +166,28 @@ + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsScrollArea QScrollArea
    qgsscrollarea.h
    1
    - - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 -
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    QgsSymbolButton QToolButton
    qgssymbolbutton.h
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1 +
    QgsLayoutItemComboBox QComboBox @@ -195,9 +195,14 @@
    - groupBox scrollArea + groupBox mShapeStyleButton + mRotationGroupBox + mRotationFromMapCheckBox + mMapComboBox + mNorthTypeComboBox + mNorthOffsetSpinBox diff --git a/src/ui/layout/qgslayoutpagepropertieswidget.ui b/src/ui/layout/qgslayoutpagepropertieswidget.ui index 378dc8c84e32..20ef60783221 100644 --- a/src/ui/layout/qgslayoutpagepropertieswidget.ui +++ b/src/ui/layout/qgslayoutpagepropertieswidget.ui @@ -255,6 +255,12 @@
    + + QgsRatioLockButton + QToolButton +
    qgsratiolockbutton.h
    + 1 +
    QgsDoubleSpinBox QDoubleSpinBox @@ -266,21 +272,15 @@
    qgspropertyoverridebutton.h
    - QgsRatioLockButton + QgsSymbolButton QToolButton -
    qgsratiolockbutton.h
    - 1 +
    qgssymbolbutton.h
    QgsLayoutUnitsComboBox QComboBox
    qgslayoutunitscombobox.h
    - - QgsSymbolButton - QToolButton -
    qgssymbolbutton.h
    -
    mPageSizeComboBox @@ -289,9 +289,9 @@ mOrientationDDBtn mWidthSpin mWidthDDBtn - mLockAspectRatio mHeightSpin mHeightDDBtn + mLockAspectRatio mSizeUnitsComboBox mExcludePageCheckBox mExcludePageDDBtn diff --git a/src/ui/layout/qgslayoutpicturewidgetbase.ui b/src/ui/layout/qgslayoutpicturewidgetbase.ui index c3fef8527765..e1be95e9347f 100644 --- a/src/ui/layout/qgslayoutpicturewidgetbase.ui +++ b/src/ui/layout/qgslayoutpicturewidgetbase.ui @@ -60,9 +60,9 @@ 0 - -4 + -368 520 - 881 + 845 @@ -556,12 +556,22 @@ + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsScrollArea QScrollArea
    qgsscrollarea.h
    1
    + + QgsPropertyOverrideButton + QToolButton +
    qgspropertyoverridebutton.h
    +
    QgsColorButton QToolButton @@ -571,30 +581,20 @@ QgsCollapsibleGroupBoxBasic QGroupBox -
    qgscollapsiblegroupbox.h
    +
    qgscollapsiblegroupbox.h
    1
    - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    - - QgsPropertyOverrideButton - QToolButton -
    qgspropertyoverridebutton.h
    + QgsImageSourceLineEdit + QWidget +
    qgsfilecontentsourcelineedit.h
    + 1
    QgsLayoutItemComboBox QComboBox
    qgslayoutitemcombobox.h
    - - QgsImageSourceLineEdit - QWidget -
    qgsfilecontentsourcelineedit.h
    - 1 -
    QgsSvgSourceLineEdit QWidget @@ -607,6 +607,7 @@ mRadioSVG mRadioRaster mImageSourceLineEdit + mSourceDDBtn viewGroups viewImages mSvgSourceLineEdit diff --git a/src/ui/layout/qgslayoutpolylinewidgetbase.ui b/src/ui/layout/qgslayoutpolylinewidgetbase.ui index 5413af4c5f5f..2d19c624eb26 100644 --- a/src/ui/layout/qgslayoutpolylinewidgetbase.ui +++ b/src/ui/layout/qgslayoutpolylinewidgetbase.ui @@ -54,9 +54,9 @@ 0 - -83 + 0 318 - 459 + 426 @@ -329,6 +329,11 @@ + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsScrollArea QScrollArea @@ -336,9 +341,9 @@ 1 - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    + QgsColorButton + QToolButton +
    qgscolorbutton.h
    1
    @@ -347,21 +352,31 @@
    qgssymbolbutton.h
    - QgsColorButton - QToolButton -
    qgscolorbutton.h
    + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    1
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    scrollArea groupBox mLineStyleButton + mArrowMarkersGroupBox + mRadioStartNoMarker + mRadioStartArrow + mRadioStartSVG + mStartMarkerLineEdit + mStartMarkerToolButton + mRadioEndNoMarker + mRadioEndArrow + mRadioEndSvg + mEndMarkerLineEdit + mEndMarkerToolButton + mArrowHeadStrokeColorButton + mArrowHeadFillColorButton + mStrokeWidthSpinBox + mArrowHeadWidthSpinBox diff --git a/src/ui/layout/qgsreportorganizerwidgetbase.ui b/src/ui/layout/qgsreportorganizerwidgetbase.ui index 69c1fdc88ab7..c20e078dede5 100644 --- a/src/ui/layout/qgsreportorganizerwidgetbase.ui +++ b/src/ui/layout/qgsreportorganizerwidgetbase.ui @@ -109,8 +109,8 @@ 0 0 - 687 - 207 + 302 + 232 @@ -130,34 +130,14 @@ + + mViewSections + mButtonAddSection + mButtonRemoveSection + scrollArea + - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/ui/mesh/qgsmeshcalculatordialogbase.ui b/src/ui/mesh/qgsmeshcalculatordialogbase.ui index 822dcdb698c5..e5e23f1bd567 100644 --- a/src/ui/mesh/qgsmeshcalculatordialogbase.ui +++ b/src/ui/mesh/qgsmeshcalculatordialogbase.ui @@ -620,31 +620,65 @@
    qgscollapsiblegroupbox.h
    1
    - - QgsMapLayerComboBox - QComboBox -
    qgsmaplayercombobox.h
    -
    QgsFileWidget QWidget
    qgsfilewidget.h
    + 1
    QgsDoubleSpinBox QDoubleSpinBox
    qgsdoublespinbox.h
    + + QgsMapLayerComboBox + QComboBox +
    qgsmaplayercombobox.h
    +
    + mDatasetsListWidget + mOutputOnFileRadioButton + mOutputVirtualRadioButton + mOutputFormatComboBox + mOutputGroupNameLineEdit + useExtentCb + useMaskCb + cboLayerMask + mCurrentLayerExtentButton mXMinSpinBox mXMaxSpinBox mYMinSpinBox mYMaxSpinBox + mAllTimesButton + mStartTimeComboBox + mEndTimeComboBox mPlusPushButton mMultiplyPushButton + mOpenBracketPushButton + mMinButton + mIfButton + mSumAggrButton mMinusPushButton mDividePushButton + mCloseBracketPushButton + mMaxButton + mAndButton + mMaxAggrButton + mLessButton + mGreaterButton + mEqualButton + mAbsButton + mOrButton + mMinAggrButton + mLesserEqualButton + mGreaterEqualButton + mNotEqualButton + mPowButton + mNotButton + mAverageAggrButton + mNoDataButton mExpressionTextEdit diff --git a/src/ui/mesh/qgsmeshlayerpropertiesbase.ui b/src/ui/mesh/qgsmeshlayerpropertiesbase.ui index 5d88f6087195..78e2f3f22380 100644 --- a/src/ui/mesh/qgsmeshlayerpropertiesbase.ui +++ b/src/ui/mesh/qgsmeshlayerpropertiesbase.ui @@ -260,8 +260,8 @@ 0 0 - 470 - 383 + 661 + 508 @@ -473,8 +473,8 @@ border-radius: 2px; 0 0 - 100 - 30 + 661 + 508 @@ -844,23 +844,22 @@ border-radius: 2px; - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    - - QgsScrollArea - QScrollArea -
    qgsscrollarea.h
    - 1 -
    QgsCollapsibleGroupBox QGroupBox
    qgscollapsiblegroupbox.h
    1
    + + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsFilterLineEdit QLineEdit @@ -873,9 +872,16 @@ border-radius: 2px; 1 - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    + QgsScrollArea + QScrollArea +
    qgsscrollarea.h
    + 1 +
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1
    QgsMeshStaticDatasetWidget @@ -889,20 +895,27 @@ border-radius: 2px;
    qgsmeshdatasetgrouptreewidget.h
    1
    - - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 -
    mSearchLineEdit mOptionsListWidget mInformationTextBrowser scrollArea_3 + mLayerOrigNameLineEd + leDisplayName + mCrsGroupBox mCrsSelector + mTemporalStaticDatasetCheckBox scrollArea + mSimplifyMeshGroupBox + mSimplifyReductionFactorSpinBox + mSimplifyMeshResolutionSpinBox + mTemporalDateTimeReference + mTemporalReloadButton + mTemporalDateTimeStart + mTemporalDateTimeEnd + mComboBoxTemporalDatasetMatchingMethod + mTemporalProviderTimeUnitComboBox diff --git a/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui b/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui index 1026d932ccdc..95505c13afaa 100644 --- a/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui +++ b/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui @@ -108,7 +108,7 @@ - + @@ -206,9 +206,14 @@
    + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsUnitSelectionWidget - QComboBox + QWidget
    qgsunitselectionwidget.h
    1
    @@ -224,17 +229,23 @@
    raster/qgscolorrampshaderwidget.h
    1 - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    QgsMeshVariableStrokeWidthButton QPushButton
    qgsmeshvariablestrokewidthwidget.h
    + + mOpacityWidget + mScalarEdgeStrokeWidthFixedRadioButton + mScalarEdgeStrokeWidthVariableRadioButton + mScalarEdgeStrokeWidthSpinBox + mScalarEdgeStrokeWidthVariablePushButton + mScalarMinLineEdit + mScalarMaxLineEdit + mScalarRecalculateMinMaxButton + mScalarInterpolationTypeComboBox + diff --git a/src/ui/mesh/qgsmeshvariablestrokewidthwidgetbase.ui b/src/ui/mesh/qgsmeshvariablestrokewidthwidgetbase.ui index aba70daf2bc1..5c7e757c6e3a 100644 --- a/src/ui/mesh/qgsmeshvariablestrokewidthwidgetbase.ui +++ b/src/ui/mesh/qgsmeshvariablestrokewidthwidgetbase.ui @@ -6,7 +6,7 @@ 0 0 - 340 + 395 220 @@ -152,6 +152,8 @@ mValueMinimumLineEdit mValueMaximumLineEdit mDefaultMinMaxButton + mIgnoreOutOfRangecheckBox + mUseAbsoluteValueCheckBox mWidthMinimumSpinBox mWidthMaximumSpinBox
    diff --git a/src/ui/numericformats/qgsbasicnumericformatwidgetbase.ui b/src/ui/numericformats/qgsbasicnumericformatwidgetbase.ui index 8dd2292421f9..1eb136d0a922 100644 --- a/src/ui/numericformats/qgsbasicnumericformatwidgetbase.ui +++ b/src/ui/numericformats/qgsbasicnumericformatwidgetbase.ui @@ -6,7 +6,7 @@ 0 0 - 221 + 224 285 @@ -119,12 +119,6 @@
    - - QgsPanelWidget - QWidget -
    qgspanelwidget.h
    - 1 -
    QgsSpinBox QSpinBox @@ -135,7 +129,23 @@ QLineEdit
    qgsfilterlineedit.h
    + + QgsPanelWidget + QWidget +
    qgspanelwidget.h
    + 1 +
    + + mDecimalsSpinBox + mRadDecimalPlaces + mRadSignificantFigures + mShowThousandsCheckBox + mShowPlusCheckBox + mShowTrailingZerosCheckBox + mThousandsLineEdit + mDecimalLineEdit + diff --git a/src/ui/numericformats/qgsbearingnumericformatwidgetbase.ui b/src/ui/numericformats/qgsbearingnumericformatwidgetbase.ui index b683c6b1e852..0e36592f0862 100644 --- a/src/ui/numericformats/qgsbearingnumericformatwidgetbase.ui +++ b/src/ui/numericformats/qgsbearingnumericformatwidgetbase.ui @@ -73,6 +73,11 @@ 1 + + mFormatComboBox + mDecimalsSpinBox + mShowTrailingZerosCheckBox + diff --git a/src/ui/numericformats/qgscurrencynumericformatwidgetbase.ui b/src/ui/numericformats/qgscurrencynumericformatwidgetbase.ui index b8d7b453ff7c..6130c8ceed3f 100644 --- a/src/ui/numericformats/qgscurrencynumericformatwidgetbase.ui +++ b/src/ui/numericformats/qgscurrencynumericformatwidgetbase.ui @@ -104,6 +104,14 @@ 1 + + mPrefixLineEdit + mSuffixLineEdit + mDecimalsSpinBox + mShowThousandsCheckBox + mShowPlusCheckBox + mShowTrailingZerosCheckBox + diff --git a/src/ui/numericformats/qgspercentagenumericformatwidgetbase.ui b/src/ui/numericformats/qgspercentagenumericformatwidgetbase.ui index bf2bebef2d60..eb3a95919b34 100644 --- a/src/ui/numericformats/qgspercentagenumericformatwidgetbase.ui +++ b/src/ui/numericformats/qgspercentagenumericformatwidgetbase.ui @@ -90,6 +90,13 @@ 1 + + mDecimalsSpinBox + mShowThousandsCheckBox + mShowPlusCheckBox + mShowTrailingZerosCheckBox + mScalingComboBox + diff --git a/src/ui/pointcloud/qgspointcloudclassifiedrendererwidgetbase.ui b/src/ui/pointcloud/qgspointcloudclassifiedrendererwidgetbase.ui index f4067cbe63f2..a73d2ceb9628 100644 --- a/src/ui/pointcloud/qgspointcloudclassifiedrendererwidgetbase.ui +++ b/src/ui/pointcloud/qgspointcloudclassifiedrendererwidgetbase.ui @@ -136,6 +136,7 @@ + mAttributeComboBox viewCategories btnAddCategories btnAddCategory diff --git a/src/ui/pointcloud/qgspointcloudelevationpropertieswidgetbase.ui b/src/ui/pointcloud/qgspointcloudelevationpropertieswidgetbase.ui index cc968ffa4cde..88d57d891390 100644 --- a/src/ui/pointcloud/qgspointcloudelevationpropertieswidgetbase.ui +++ b/src/ui/pointcloud/qgspointcloudelevationpropertieswidgetbase.ui @@ -144,18 +144,24 @@
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    QgsCollapsibleGroupBox QGroupBox
    qgscollapsiblegroupbox.h
    1
    + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    + + mCrsGroupBox_2 + mScaleZSpinBox + mOffsetZSpinBox + mShifPointCloudZAxisButton + diff --git a/src/ui/pointcloud/qgspointcloudrendererpropsdialogbase.ui b/src/ui/pointcloud/qgspointcloudrendererpropsdialogbase.ui index eb2296821305..b38b0a1f4000 100644 --- a/src/ui/pointcloud/qgspointcloudrendererpropsdialogbase.ui +++ b/src/ui/pointcloud/qgspointcloudrendererpropsdialogbase.ui @@ -109,7 +109,7 @@ 3 - + 0 @@ -207,7 +207,7 @@ - + 0 @@ -250,17 +250,17 @@ QDoubleSpinBox
    qgsdoublespinbox.h
    - - QgsBlendModeComboBox - QComboBox -
    qgsblendmodecombobox.h
    -
    QgsUnitSelectionWidget - QComboBox + QWidget
    qgsunitselectionwidget.h
    1
    + + QgsBlendModeComboBox + QComboBox +
    qgsblendmodecombobox.h
    +
    QgsOpacityWidget QWidget @@ -276,7 +276,13 @@ cboRenderers + mPointSizeSpinBox + mPointSizeUnitWidget + mPointStyleComboBox + mMaxErrorSpinBox + mMaxErrorUnitWidget mOpacityWidget + mBlendModeComboBox diff --git a/src/ui/processing/qgsprocessingenummodelerwidgetbase.ui b/src/ui/processing/qgsprocessingenummodelerwidgetbase.ui index 10a44efb1151..94ac37c928f8 100644 --- a/src/ui/processing/qgsprocessingenummodelerwidgetbase.ui +++ b/src/ui/processing/qgsprocessingenummodelerwidgetbase.ui @@ -103,6 +103,13 @@
    + + mButtonAdd + mButtonRemove + mButtonClear + mItemList + mAllowMultiple + diff --git a/src/ui/processing/qgsprocessingmatrixmodelerwidgetbase.ui b/src/ui/processing/qgsprocessingmatrixmodelerwidgetbase.ui index 384b94b9d8c0..4680c808e338 100644 --- a/src/ui/processing/qgsprocessingmatrixmodelerwidgetbase.ui +++ b/src/ui/processing/qgsprocessingmatrixmodelerwidgetbase.ui @@ -128,6 +128,15 @@ + + mTableView + mButtonAddColumn + mButtonRemoveColumn + mButtonAddRow + mButtonRemoveRow + mButtonClear + mFixedRows + diff --git a/src/ui/processing/qgsprocessingmeshdatasettimewidget.ui b/src/ui/processing/qgsprocessingmeshdatasettimewidget.ui index 58af9e2bc7c5..d6c892b53437 100644 --- a/src/ui/processing/qgsprocessingmeshdatasettimewidget.ui +++ b/src/ui/processing/qgsprocessingmeshdatasettimewidget.ui @@ -6,8 +6,8 @@ 0 0 - 465 - 122 + 535 + 129 @@ -67,6 +67,13 @@ + + radioButtonCurrentCanvasTime + radioButtonDefinedDateTime + radioButtonDatasetGroupTimeStep + comboBoxDatasetTimeStep + dateTimeEdit + diff --git a/src/ui/processing/qgsprocessingtinmeshdatawidgetbase.ui b/src/ui/processing/qgsprocessingtinmeshdatawidgetbase.ui index df72ce82a522..1b80b34bf721 100644 --- a/src/ui/processing/qgsprocessingtinmeshdatawidgetbase.ui +++ b/src/ui/processing/qgsprocessingtinmeshdatawidgetbase.ui @@ -132,17 +132,25 @@ - QgsMapLayerComboBox + QgsFieldComboBox QComboBox -
    qgsmaplayercombobox.h
    - 1 +
    qgsfieldcombobox.h
    - QgsFieldComboBox + QgsMapLayerComboBox QComboBox -
    qgsfieldcombobox.h
    +
    qgsmaplayercombobox.h
    + 1
    + + mComboLayers + mComboFields + mCheckBoxUseZCoordinate + mButtonAdd + mButtonRemove + mTableView + diff --git a/src/ui/qgsadvanceddigitizingfloaterbase.ui b/src/ui/qgsadvanceddigitizingfloaterbase.ui index a1d8933c9286..e2abb0669e63 100644 --- a/src/ui/qgsadvanceddigitizingfloaterbase.ui +++ b/src/ui/qgsadvanceddigitizingfloaterbase.ui @@ -187,6 +187,12 @@ + + mDistanceLineEdit + mAngleLineEdit + mXLineEdit + mYLineEdit + diff --git a/src/ui/qgsanimationexportdialogbase.ui b/src/ui/qgsanimationexportdialogbase.ui index 33840745a55f..4caeef349e4c 100644 --- a/src/ui/qgsanimationexportdialogbase.ui +++ b/src/ui/qgsanimationexportdialogbase.ui @@ -298,6 +298,19 @@
    qgsdoublespinbox.h
    + + mTemplateLineEdit + mExtentGroupBox + mOutputWidthSpinBox + mOutputHeightSpinBox + mLockAspectRatio + mDrawDecorations + mStartDateTime + mEndDateTime + mSetToProjectTimeButton + mFrameDurationSpinBox + mTimeStepsComboBox + diff --git a/src/ui/qgsattributesformproperties.ui b/src/ui/qgsattributesformproperties.ui index 172ed58639e2..20f14c71974c 100644 --- a/src/ui/qgsattributesformproperties.ui +++ b/src/ui/qgsattributesformproperties.ui @@ -223,7 +223,7 @@ Use this function to add extra logic to your forms. 0 0 598 - 480 + 492
    @@ -239,6 +239,17 @@ Use this function to add extra logic to your forms. + + mEditorLayoutComboBox + mTbInitCode + mFormSuppressCmbBx + mEditFormLineEdit + pbnSelectEditForm + mAddTabOrGroupButton + mRemoveTabOrGroupButton + mInvertSelectionButton + scrollArea_2 + diff --git a/src/ui/qgscolorrampshaderwidgetbase.ui b/src/ui/qgscolorrampshaderwidgetbase.ui index 91dff0bb5f59..0a101bb6f33c 100644 --- a/src/ui/qgscolorrampshaderwidgetbase.ui +++ b/src/ui/qgscolorrampshaderwidgetbase.ui @@ -315,6 +315,7 @@ Negative rounds to powers of 10 mColorInterpolationComboBox btnColorRamp mUnitLineEdit + mLabelPrecisionSpinBox mColormapTreeWidget mClassificationModeComboBox mNumberOfEntriesSpinBox @@ -324,6 +325,7 @@ Negative rounds to powers of 10 mLoadFromBandButton mLoadFromFileButton mExportToFileButton + mLegendSettingsButton mClipCheckBox diff --git a/src/ui/qgscoordinateoperationwidgetbase.ui b/src/ui/qgscoordinateoperationwidgetbase.ui index bea5764d838f..ec2f3d8ea86f 100644 --- a/src/ui/qgscoordinateoperationwidgetbase.ui +++ b/src/ui/qgscoordinateoperationwidgetbase.ui @@ -6,7 +6,7 @@ 0 0 - 651 + 1000 433 @@ -196,7 +196,10 @@ file are transformed). mCoordinateOperationTableWidget + mInstallGridButton mHideDeprecatedCheckBox + mShowSupersededCheckBox + mAllowFallbackCheckBox mMakeDefaultCheckBox diff --git a/src/ui/qgscredentialdialog.ui b/src/ui/qgscredentialdialog.ui index 48476ccf3c73..740714764707 100644 --- a/src/ui/qgscredentialdialog.ui +++ b/src/ui/qgscredentialdialog.ui @@ -6,7 +6,7 @@ 0 0 - 358 + 387 293 @@ -269,7 +269,11 @@ font-style: italic; lePassword leMasterPass leMasterPassVerify + chkbxPasswordHelperEnable chkbxEraseAuthDb + mOkButton + mIgnoreButton + mCancelButton diff --git a/src/ui/qgsdatadefinedsizelegendwidget.ui b/src/ui/qgsdatadefinedsizelegendwidget.ui index 0834b7257727..0703257e2528 100644 --- a/src/ui/qgsdatadefinedsizelegendwidget.ui +++ b/src/ui/qgsdatadefinedsizelegendwidget.ui @@ -213,6 +213,7 @@ btnRemoveClass viewSizeClasses cboAlignSymbols + mLineSymbolButton viewLayerTree diff --git a/src/ui/qgsdecorationlayoutextentdialog.ui b/src/ui/qgsdecorationlayoutextentdialog.ui index cf97681e2fa1..739d5f241067 100644 --- a/src/ui/qgsdecorationlayoutextentdialog.ui +++ b/src/ui/qgsdecorationlayoutextentdialog.ui @@ -7,7 +7,7 @@ 0 0 377 - 148 + 152 @@ -121,7 +121,8 @@ grpEnable mSymbolButton - buttonBox + mCheckBoxLabelExtents + mButtonFontStyle diff --git a/src/ui/qgsdecorationscalebardialog.ui b/src/ui/qgsdecorationscalebardialog.ui index 8ac64f3e8d3c..a6f9c5ed5719 100644 --- a/src/ui/qgsdecorationscalebardialog.ui +++ b/src/ui/qgsdecorationscalebardialog.ui @@ -6,7 +6,7 @@ 0 0 - 565 + 596 337 @@ -197,7 +197,7 @@ Font of bar - + @@ -210,7 +210,7 @@ Font - + @@ -417,7 +417,7 @@ - + Qt::Vertical @@ -428,7 +428,7 @@ 40 - + @@ -437,41 +437,41 @@ + + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    QgsColorButton QToolButton
    qgscolorbutton.h
    1
    - - QgsFontButton - QToolButton -
    qgsfontbutton.h
    -
    - - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    -
    QgsUnitSelectionWidget QWidget
    qgsunitselectionwidget.h
    1
    + + QgsFontButton + QToolButton +
    qgsfontbutton.h
    +
    grpEnable cboStyle pbnChangeColor pbnChangeOutlineColor + mButtonFontStyle spnSize chkSnapping cboPlacement spnHorizontal spnVertical wgtUnitSelection - buttonBox diff --git a/src/ui/qgsdecorationtitledialog.ui b/src/ui/qgsdecorationtitledialog.ui index 2016fa57714f..86319f9abfa6 100644 --- a/src/ui/qgsdecorationtitledialog.ui +++ b/src/ui/qgsdecorationtitledialog.ui @@ -45,7 +45,7 @@ false - + @@ -133,8 +133,7 @@ - - + @@ -206,7 +205,7 @@ - + @@ -241,39 +240,39 @@ + + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    QgsColorButton QToolButton
    qgscolorbutton.h
    1
    - - QgsSymbolButton - QToolButton -
    qgssymbolbutton.h
    -
    - - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    -
    QgsUnitSelectionWidget QWidget
    qgsunitselectionwidget.h
    1
    + + QgsFontButton + QToolButton +
    qgsfontbutton.h
    +
    grpEnable txtTitleText mInsertExpressionButton mButtonFontStyle + pbnBackgroundColor cboPlacement spnHorizontal spnVertical wgtUnitSelection - buttonBox diff --git a/src/ui/qgseditconditionalformatrulewidget.ui b/src/ui/qgseditconditionalformatrulewidget.ui index 33efaefcfb9c..0790e3261844 100644 --- a/src/ui/qgseditconditionalformatrulewidget.ui +++ b/src/ui/qgseditconditionalformatrulewidget.ui @@ -6,7 +6,7 @@ 0 0 - 328 + 384 331 @@ -317,7 +317,7 @@
    - +
    @@ -436,21 +436,38 @@
    - - QgsSymbolButton - QToolButton -
    qgssymbolbutton.h
    -
    QgsColorButton QToolButton
    qgscolorbutton.h
    1
    + + QgsSymbolButton + QToolButton +
    qgssymbolbutton.h
    +
    + + mNameEdit + mRuleEdit + btnBuildExpression + mPresetsList + btnBackgroundColor + btnTextColor + checkIcon + btnChangeIcon + mFontBoldBtn + mFontItalicBtn + mFontUnderlineBtn + mFontStrikethroughBtn + mFontFamilyCmbBx + mSaveRule + mCancelButton + mDeleteButton + - diff --git a/src/ui/qgsexpressionbuilder.ui b/src/ui/qgsexpressionbuilder.ui index f1f290f71937..4b1a8b7180c3 100644 --- a/src/ui/qgsexpressionbuilder.ui +++ b/src/ui/qgsexpressionbuilder.ui @@ -905,9 +905,40 @@ Saved scripts are auto loaded on QGIS startup. 1 + + tabWidget + btnClearEditor + btnSaveExpression + btnEditExpression + btnRemoveExpression + btnImportExpressions + btnExportExpressions + btnEqualPushButton + btnPlusPushButton + btnMinusPushButton + btnDividePushButton + btnMultiplyPushButton + btnExpButton + btnConcatButton + btnOpenBracketPushButton + btnCloseBracketPushButton + btnNewLinePushButton + txtSearchEdit + mShowHelpButton + mExpressionTreeView + txtHelpText + txtSearchEditValues + btnLoadAll + btnLoadSample + cbxValuesInUse + mValuesListView + cmbFileNames + btnNewFile + btnRemoveFile + btnRun + - diff --git a/src/ui/qgsfieldconditionalformatwidget.ui b/src/ui/qgsfieldconditionalformatwidget.ui index 43292eec9e67..dbba96fc3b0e 100644 --- a/src/ui/qgsfieldconditionalformatwidget.ui +++ b/src/ui/qgsfieldconditionalformatwidget.ui @@ -108,15 +108,15 @@
    qgsfieldcombobox.h
    + + fieldRadio + mFieldCombo + rowRadio + mNewButton + listView + - - - - false - - - diff --git a/src/ui/qgsgeometryvalidationdockbase.ui b/src/ui/qgsgeometryvalidationdockbase.ui index 2ef10186d1c9..eb306e458115 100644 --- a/src/ui/qgsgeometryvalidationdockbase.ui +++ b/src/ui/qgsgeometryvalidationdockbase.ui @@ -153,6 +153,13 @@ 1 + + mPreviousButton + mZoomToFeatureButton + mZoomToProblemButton + mNextButton + mErrorListView + diff --git a/src/ui/qgsgpsinformationwidgetbase.ui b/src/ui/qgsgpsinformationwidgetbase.ui index f0bf2f7fd374..ec34828db84c 100644 --- a/src/ui/qgsgpsinformationwidgetbase.ui +++ b/src/ui/qgsgpsinformationwidgetbase.ui @@ -157,8 +157,8 @@ gray = no data 0 0 - 565 - 724 + 579 + 744 @@ -601,8 +601,8 @@ gray = no data 0 0 - 354 - 1346 + 565 + 1126 @@ -1484,12 +1484,6 @@ gray = no data - - QgsScrollArea - QScrollArea -
    qgsscrollarea.h
    - 1 -
    QgsCollapsibleGroupBox QGroupBox @@ -1497,15 +1491,9 @@ gray = no data 1 - QgsSymbolButton - QToolButton -
    qgssymbolbutton.h
    -
    - - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    QgsFieldComboBox @@ -1513,24 +1501,36 @@ gray = no data
    qgsfieldcombobox.h
    - QgsPanelWidget - QWidget -
    qgspanelwidget.h
    + QgsScrollArea + QScrollArea +
    qgsscrollarea.h
    1
    QgsColorButton QToolButton
    qgscolorbutton.h
    + 1
    - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    + QgsSymbolButton + QToolButton +
    qgssymbolbutton.h
    +
    + + QgsPanelWidget + QWidget +
    qgspanelwidget.h
    + 1 +
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1
    - mBtnCloseFeature mBtnAddVertex mBtnResetFeature mBtnPosition @@ -1538,6 +1538,7 @@ gray = no data mBtnSatellites mBtnOptions mBtnDebug + mRecenterButton mConnectButton scrollArea mRadAutodetect @@ -1550,9 +1551,15 @@ gray = no data mGpsdPort mGpsdDevice mCbxAutoCommit + mCboTimestampField + mCboTimestampFormat + mCboTimeZones + mCbxLeapSeconds + mLeapSeconds mCbxAutoAddVertices mSpinTrackWidth mBtnTrackColor + mTravelBearingCheckBox mGroupShowMarker mSliderMarkerSize mCboAcquisitionInterval @@ -1562,6 +1569,9 @@ gray = no data mSpinMapExtentMultiplier radNeverRecenter mRotateMapCheckBox + mSpinMapRotateInterval + mShowBearingLineCheck + mBearingLineStyleButton mLogFileGroupBox mTxtLogFile mBtnLogFile @@ -1570,6 +1580,7 @@ gray = no data mTxtLatitude mTxtLongitude mTxtAltitude + mTxtAltitudeDiff mTxtDateTime mTxtSpeed mTxtDirection @@ -1578,16 +1589,13 @@ gray = no data mTxtPdop mTxtHacc mTxtVacc + mTxt3Dacc mTxtFixMode mTxtFixType mTxtQuality mTxtStatus mTxtSatellitesUsed - mCboTimestampField - mCboTimestampFormat - mCboTimeZones - mLeapSeconds - mCbxLeapSeconds + mBtnCloseFeature diff --git a/src/ui/qgsgradientcolorrampdialogbase.ui b/src/ui/qgsgradientcolorrampdialogbase.ui index e91d3987036a..9eb8a7f24d4b 100644 --- a/src/ui/qgsgradientcolorrampdialogbase.ui +++ b/src/ui/qgsgradientcolorrampdialogbase.ui @@ -148,7 +148,7 @@ 0 0 850 - 494 + 498 @@ -330,12 +330,23 @@ + + QwtPlot + QFrame +
    qwt_plot.h
    + 1 +
    QgsCollapsibleGroupBox QGroupBox
    qgscollapsiblegroupbox.h
    1
    + + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    QgsScrollArea QScrollArea @@ -348,17 +359,6 @@
    qgscolorbutton.h
    1
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    - - QwtPlot - QFrame -
    qwt_plot.h
    - 1 -
    QgsGradientStopEditor QWidget @@ -377,17 +377,15 @@ btnColor2 cboType mStopEditor - groupBox_2 + scrollArea mPositionSpinBox mDeleteStopButton mColorWidget - mPlotGroupBox mPlotHueCheckbox mPlotSaturationCheckbox mPlotLightnessCheckbox mPlotAlphaCheckbox btnInformation - scrollArea diff --git a/src/ui/qgsgraduatedsymbolrendererwidget.ui b/src/ui/qgsgraduatedsymbolrendererwidget.ui index 8a06d327aedc..3f7b0708fbe6 100644 --- a/src/ui/qgsgraduatedsymbolrendererwidget.ui +++ b/src/ui/qgsgraduatedsymbolrendererwidget.ui @@ -502,50 +502,50 @@ Negative rounds to powers of 10
    + + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    QgsDoubleSpinBox QDoubleSpinBox
    qgsdoublespinbox.h
    - - QgsUnitSelectionWidget - QWidget -
    qgsunitselectionwidget.h
    - 1 -
    QgsFieldExpressionWidget QWidget
    qgsfieldexpressionwidget.h
    1
    - - QgsColorRampButton - QToolButton -
    qgscolorrampbutton.h
    - 1 -
    QgsSymbolButton QToolButton
    qgssymbolbutton.h
    - QgsGraduatedHistogramWidget + QgsUnitSelectionWidget QWidget -
    qgsgraduatedhistogramwidget.h
    +
    qgsunitselectionwidget.h
    + 1 +
    + + QgsColorRampButton + QToolButton +
    qgscolorrampbutton.h
    1
    QgsCollapsibleGroupBoxBasic QGroupBox -
    qgscollapsiblegroupbox.h
    +
    qgscollapsiblegroupbox.h
    1
    - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    + QgsGraduatedHistogramWidget + QWidget +
    qgsgraduatedhistogramwidget.h
    + 1
    @@ -563,6 +563,9 @@ Negative rounds to powers of 10 viewGraduated cboGraduatedMode spinGraduatedClasses + mGroupBoxSymmetric + cboSymmetryPoint + cbxAstride btnGraduatedClassify btnGraduatedAdd btnGraduatedDelete diff --git a/src/ui/qgsjoindialogbase.ui b/src/ui/qgsjoindialogbase.ui index 52978e122f00..37779fd5f638 100644 --- a/src/ui/qgsjoindialogbase.ui +++ b/src/ui/qgsjoindialogbase.ui @@ -191,6 +191,10 @@ mTargetFieldComboBox mCacheInMemoryCheckBox mCreateIndexCheckBox + mDynamicFormCheckBox + mEditableJoinLayer + mUpsertOnEditCheckBox + mDeleteCascadeCheckBox mUseJoinFieldsSubset mJoinFieldsSubsetView mUseCustomPrefix diff --git a/src/ui/qgsmapsavedialog.ui b/src/ui/qgsmapsavedialog.ui index d41425fcc755..4f5fb1e41205 100644 --- a/src/ui/qgsmapsavedialog.ui +++ b/src/ui/qgsmapsavedialog.ui @@ -15,7 +15,7 @@ - + @@ -373,22 +373,11 @@ Rasterizing the map is recommended when such effects are used.
    qgscollapsiblegroupbox.h
    1 - - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 -
    QgsSpinBox QSpinBox
    qgsspinbox.h
    - - QgsScaleWidget - QWidget -
    qgsscalewidget.h
    -
    QgsExtentGroupBox QgsCollapsibleGroupBox @@ -401,6 +390,17 @@ Rasterizing the map is recommended when such effects are used.
    qgsratiolockbutton.h
    1
    + + QgsScaleWidget + QWidget +
    qgsscalewidget.h
    +
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1 +
    mExtentGroupBox @@ -411,9 +411,9 @@ Rasterizing the map is recommended when such effects are used. mDrawDecorations mDrawAnnotations mSaveWorldFile + mExportMetadataCheckBox mGeoPDFGroupBox mGeoPdfFormatComboBox - mExportMetadataCheckBox mExportGeoPdfFeaturesCheckBox mSaveAsRaster mSimplifyGeometriesCheckbox diff --git a/src/ui/qgsmetadatawidget.ui b/src/ui/qgsmetadatawidget.ui index dd5c45442cf5..04a3e87f64d4 100644 --- a/src/ui/qgsmetadatawidget.ui +++ b/src/ui/qgsmetadatawidget.ui @@ -68,7 +68,7 @@ 0 0 786 - 721 + 670
    @@ -1491,17 +1491,17 @@
    qgscollapsiblegroupbox.h
    1 - - QgsExtentGroupBox - QGroupBox -
    qgsextentgroupbox.h
    - 1 -
    QgsSpinBox QSpinBox
    qgsspinbox.h
    + + QgsExtentGroupBox + QgsCollapsibleGroupBox +
    qgsextentgroupbox.h
    + 1 +
    QgsDateTimeEdit QDateTimeEdit @@ -1512,7 +1512,6 @@ tabWidget scrollArea lineEditParentId - comboEncoding lineEditIdentifier btnAutoSource lineEditTitle @@ -1521,6 +1520,7 @@ mCreationDateTimeEdit comboLanguage textEditAbstract + comboEncoding btnAutoEncoding listDefaultCategories btnAddDefaultCategory diff --git a/src/ui/qgsmssqlnewconnectionbase.ui b/src/ui/qgsmssqlnewconnectionbase.ui index 1acea916072b..1b66d440a924 100644 --- a/src/ui/qgsmssqlnewconnectionbase.ui +++ b/src/ui/qgsmssqlnewconnectionbase.ui @@ -375,6 +375,12 @@ Untick save if you don't wish to be the case.
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1 +
    QgsMessageBar QWidget @@ -386,12 +392,6 @@ Untick save if you don't wish to be the case. QLineEdit
    qgspasswordlineedit.h
    - - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 -
    txtName @@ -404,9 +404,14 @@ Untick save if you don't wish to be the case. chkStorePassword btnListDatabase listDatabase + groupBoxGeometryColumns + checkBoxExtentFromGeometryColumns + checkBoxPKFromGeometryColumns cb_allowGeometrylessTables cb_useEstimatedMetadata mCheckNoInvalidGeometryHandling + groupBoxSchemasFilter + schemaView btnConnect diff --git a/src/ui/qgsnewhttpconnectionbase.ui b/src/ui/qgsnewhttpconnectionbase.ui index 0cbab6703a13..a3fe746f6101 100644 --- a/src/ui/qgsnewhttpconnectionbase.ui +++ b/src/ui/qgsnewhttpconnectionbase.ui @@ -6,8 +6,8 @@ 0 0 - 448 - 815 + 567 + 821 @@ -332,17 +332,17 @@ - - QgsFilterLineEdit - QLineEdit -
    qgsfilterlineedit.h
    -
    QgsAuthSettingsWidget QWidget
    auth/qgsauthsettingswidget.h
    1
    + + QgsFilterLineEdit + QLineEdit +
    qgsfilterlineedit.h
    +
    txtName @@ -355,10 +355,12 @@ txtPageSize cbxWfsIgnoreAxisOrientation cbxWfsInvertAxisOrientation + cbxWfsUseGml2EncodingForTransactions cmbDpiMode cbxIgnoreGetMapURI cbxIgnoreGetFeatureInfoURI cbxWmsIgnoreAxisOrientation + cbxWmsIgnoreReportedLayerExtents cbxWmsInvertAxisOrientation cbxSmoothPixmapTransform mTestConnectionButton diff --git a/src/ui/qgsnewogrconnectionbase.ui b/src/ui/qgsnewogrconnectionbase.ui index 9db282cebbfc..61882c5cfdc8 100644 --- a/src/ui/qgsnewogrconnectionbase.ui +++ b/src/ui/qgsnewogrconnectionbase.ui @@ -180,11 +180,12 @@ + cmbDatabaseTypes txtName txtHost txtDatabase txtPort - buttonBox + btnConnect diff --git a/src/ui/qgsogrsourceselectbase.ui b/src/ui/qgsogrsourceselectbase.ui index 8c255f4100f1..5e2602d7dda9 100644 --- a/src/ui/qgsogrsourceselectbase.ui +++ b/src/ui/qgsogrsourceselectbase.ui @@ -9,8 +9,8 @@ 0 0 - 480 - 735 + 521 + 775
    @@ -358,20 +358,20 @@ Options - - - - - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - + + + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + +
    @@ -401,6 +401,12 @@ + + QgsCollapsibleGroupBox + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1 +
    QgsFileWidget QWidget @@ -422,11 +428,11 @@ cmbEncodings cmbProtocolTypes protocolURI + mBucket + mKey cmbDirectoryTypes - mFileWidget cmbDatabaseTypes cmbConnections - mOpenOptionsGroupBox btnNew btnEdit btnDelete diff --git a/src/ui/qgsoptionsbase.ui b/src/ui/qgsoptionsbase.ui index 230d94107694..5ab6c8812963 100644 --- a/src/ui/qgsoptionsbase.ui +++ b/src/ui/qgsoptionsbase.ui @@ -332,7 +332,7 @@ - 4 + 0 @@ -361,8 +361,8 @@ 0 0 - 848 - 987 + 843 + 959 @@ -1133,8 +1133,8 @@ 0 0 - 848 - 1102 + 843 + 1068 @@ -1672,8 +1672,8 @@ 0 0 - 848 - 678 + 857 + 695 @@ -1864,8 +1864,8 @@ 0 0 - 848 - 678 + 596 + 105 @@ -1947,8 +1947,8 @@ 0 0 - 848 - 760 + 637 + 717 @@ -2339,8 +2339,8 @@ 0 0 - 848 - 1154 + 719 + 1132 @@ -3144,8 +3144,8 @@ 0 0 - 848 - 678 + 508 + 357 @@ -3589,8 +3589,8 @@ 0 0 - 848 - 729 + 630 + 686 @@ -4106,8 +4106,8 @@ The bigger the number, the faster zooming with the mouse wheel will be. 0 0 - 848 - 678 + 147 + 251 @@ -4286,8 +4286,8 @@ The bigger the number, the faster zooming with the mouse wheel will be. 0 0 - 848 - 939 + 555 + 968 @@ -4960,8 +4960,8 @@ The bigger the number, the faster zooming with the mouse wheel will be. 0 0 - 848 - 678 + 494 + 539 @@ -5241,8 +5241,8 @@ The bigger the number, the faster zooming with the mouse wheel will be. 0 0 - 848 - 678 + 457 + 419 @@ -5513,8 +5513,8 @@ The bigger the number, the faster zooming with the mouse wheel will be. 0 0 - 848 - 708 + 657 + 669 @@ -6112,15 +6112,19 @@ p, li { white-space: pre-wrap; } 1 - QgsColorButton - QToolButton -
    qgscolorbutton.h
    - 1 + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    - QgsScrollArea - QScrollArea -
    qgsscrollarea.h
    + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    + + QgsAuthSettingsWidget + QWidget +
    auth/qgsauthsettingswidget.h
    1
    @@ -6129,9 +6133,15 @@ p, li { white-space: pre-wrap; }
    qgsfilterlineedit.h
    - QgsColorSchemeList + QgsProjectionSelectionWidget QWidget -
    qgscolorschemelist.h
    +
    qgsprojectionselectionwidget.h
    + 1 +
    + + QgsScrollArea + QScrollArea +
    qgsscrollarea.h
    1
    @@ -6141,26 +6151,27 @@ p, li { white-space: pre-wrap; } 1 - QgsDatumTransformTableWidget - QWidget -
    qgsdatumtransformtablewidget.h
    - 1 + QgsScaleComboBox + QComboBox +
    qgsscalecombobox.h
    - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    + QgsColorButton + QToolButton +
    qgscolorbutton.h
    + 1
    - QgsProjectionSelectionWidget + QgsColorSchemeList QWidget -
    qgsprojectionselectionwidget.h
    +
    qgscolorschemelist.h
    1
    - QgsScaleComboBox - QComboBox -
    qgsscalecombobox.h
    + QgsDatumTransformTableWidget + QWidget +
    qgsdatumtransformtablewidget.h
    + 1
    QgsAuthEditorWidgets @@ -6168,17 +6179,6 @@ p, li { white-space: pre-wrap; }
    qgsautheditorwidgets.h
    1
    - - QgsAuthSettingsWidget - QWidget -
    auth/qgsauthsettingswidget.h
    - 1 -
    - - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    -
    mSearchLineEdit diff --git a/src/ui/qgspgnewconnectionbase.ui b/src/ui/qgspgnewconnectionbase.ui index 5036e9a9126e..13d6de94f4b1 100644 --- a/src/ui/qgspgnewconnectionbase.ui +++ b/src/ui/qgspgnewconnectionbase.ui @@ -6,8 +6,8 @@ 0 0 - 447 - 554 + 448 + 556 @@ -255,18 +255,33 @@ - QgsMessageBar + QgsAuthSettingsWidget QWidget -
    qgsmessagebar.h
    +
    auth/qgsauthsettingswidget.h
    1
    - QgsAuthSettingsWidget + QgsMessageBar QWidget -
    auth/qgsauthsettingswidget.h
    +
    qgsmessagebar.h
    1
    + + txtName + txtService + txtHost + txtPort + txtDatabase + cbxSSLmode + btnConnect + cb_geometryColumnsOnly + cb_dontResolveType + cb_publicSchemaOnly + cb_allowGeometrylessTables + cb_useEstimatedMetadata + cb_projectsInDatabase + diff --git a/src/ui/qgspointdisplacementrendererwidgetbase.ui b/src/ui/qgspointdisplacementrendererwidgetbase.ui index ada036c4000e..6c1ae77651f3 100644 --- a/src/ui/qgspointdisplacementrendererwidgetbase.ui +++ b/src/ui/qgspointdisplacementrendererwidgetbase.ui @@ -57,7 +57,7 @@
    - + Qt::StrongFocus @@ -307,37 +307,26 @@
    - - QgsColorButton - QToolButton -
    qgscolorbutton.h
    - 1 -
    QgsDoubleSpinBox QDoubleSpinBox
    qgsdoublespinbox.h
    - - QgsFontButton - QToolButton -
    qgsfontbutton.h
    -
    QgsScaleWidget QWidget
    qgsscalewidget.h
    - QgsSymbolButton + QgsColorButton QToolButton -
    qgssymbolbutton.h
    +
    qgscolorbutton.h
    + 1
    - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 + QgsSymbolButton + QToolButton +
    qgssymbolbutton.h
    QgsUnitSelectionWidget @@ -345,6 +334,17 @@
    qgsunitselectionwidget.h
    1
    + + QgsFontButton + QToolButton +
    qgsfontbutton.h
    +
    + + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1 +
    mCenterSymbolToolButton @@ -359,7 +359,9 @@ mLabelFieldComboBox mLabelFontButton mLabelColorButton + mLabelDistanceFactorSpinBox mScaleDependentLabelsCheckBox + mMinLabelScaleWidget diff --git a/src/ui/qgsprojectpropertiesbase.ui b/src/ui/qgsprojectpropertiesbase.ui index e9e49c905597..5a707e1b17ed 100644 --- a/src/ui/qgsprojectpropertiesbase.ui +++ b/src/ui/qgsprojectpropertiesbase.ui @@ -298,8 +298,8 @@ 0 0 - 671 - 821 + 685 + 681 @@ -954,8 +954,8 @@ 0 0 - 692 - 673 + 685 + 681 @@ -1007,8 +1007,8 @@ 0 0 - 692 - 673 + 685 + 681 @@ -1067,8 +1067,8 @@ 0 0 - 692 - 673 + 685 + 681 @@ -1643,8 +1643,8 @@ 0 0 - 692 - 673 + 685 + 681 @@ -1705,8 +1705,8 @@ 0 0 - 685 - 3591 + 671 + 3119 @@ -3156,15 +3156,20 @@ - QgsColorButton - QToolButton -
    qgscolorbutton.h
    + QgsCollapsibleGroupBox + QGroupBox +
    qgscollapsiblegroupbox.h
    1
    - QgsScrollArea - QScrollArea -
    qgsscrollarea.h
    + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    + + QgsExtentGroupBox + QgsCollapsibleGroupBox +
    qgsextentgroupbox.h
    1
    @@ -3173,9 +3178,20 @@
    qgsfilterlineedit.h
    - QgsProjectionSelectionTreeWidget + QgsScrollArea + QScrollArea +
    qgsscrollarea.h
    + 1 +
    + + QgsDateTimeEdit + QDateTimeEdit +
    qgsdatetimeedit.h
    +
    + + QgsVariableEditorWidget QWidget -
    qgsprojectionselectiontreewidget.h
    +
    qgsvariableeditorwidget.h
    1
    @@ -3184,59 +3200,44 @@
    qgspropertyoverridebutton.h
    - QgsCollapsibleGroupBox - QGroupBox -
    qgscollapsiblegroupbox.h
    + QgsColorButton + QToolButton +
    qgscolorbutton.h
    1
    - QgsColorSchemeList + QgsOpacityWidget QWidget -
    qgscolorschemelist.h
    +
    qgsopacitywidget.h
    1
    - QgsVariableEditorWidget + QgsProjectionSelectionTreeWidget QWidget -
    qgsvariableeditorwidget.h
    +
    qgsprojectionselectiontreewidget.h
    1
    - QgsDatumTransformTableWidget + QgsColorSchemeList QWidget -
    qgsdatumtransformtablewidget.h
    +
    qgscolorschemelist.h
    1
    - QgsDateTimeEdit - QDateTimeEdit -
    qgsdatetimeedit.h
    -
    - - QgsOpacityWidget + QgsDatumTransformTableWidget QWidget -
    qgsopacitywidget.h
    +
    qgsdatumtransformtablewidget.h
    1
    - - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    -
    QgsCodeEditorPython QWidget
    qgscodeeditorpython.h
    1
    - - QgsExtentGroupBox - QGroupBox -
    qgsextentgroupbox.h
    - 1 -
    + mSearchLineEdit mOptionsListWidget scrollArea_2 mProjectFileLineEdit @@ -3257,7 +3258,19 @@ radAutomatic radManual spinBoxDP + mCustomizeBearingFormatButton + cbtsLocale + generateTsFileButton + grpProjectScales + lstScales + pbnAddScale + pbnRemoveScale + pbnImportScales + pbnExportScales + mExtentGroupBox scrollArea + scrollArea_3 + mShowDatumTransformDialogCheckBox scrollArea_4 cboStyleMarker pbtnStyleMarker @@ -3279,6 +3292,10 @@ mAutoTransaction mEvaluateDefaultValues mTrustProjectCheckBox + mLayerCapabilitiesTree + mLayerCapabilitiesToggleSelectionButton + mShowSpatialLayersCheckBox + mLayerCapabilitiesTreeFilterLineEdit scrollArea_6 grpPythonMacros scrollArea_5 @@ -3286,6 +3303,8 @@ mWMSName mWMSTitle mWMSContactOrganization + mWMSOnlineResourceLineEdit + mWMSOnlineResourceExpressionButton mWMSContactPerson mWMSContactPositionCb mWMSContactMail @@ -3301,7 +3320,6 @@ mWMSExtMaxY pbnWMSExtCanvas grpWMSList - mSearchLineEdit pbnWMSAddSRS pbnWMSRemoveSRS pbnWMSSetUsedSRS @@ -3323,6 +3341,7 @@ mWMSInspireTemporalReference mWMSInspireMetadataDate mWmsUseLayerIDs + mUseAttributeFormSettingsCheckBox mAddWktGeometryCheckBox mSegmentizeFeatureInfoGeometryCheckBox mWMSPrecisionSpinBox @@ -3330,6 +3349,10 @@ mMaxWidthLineEdit mMaxHeightLineEdit mWMSImageQualitySpinBox + mWMSMaxAtlasFeaturesSpinBox + mWMSTileBufferSpinBox + twWmtsLayers + twWmtsGrids mWMTSMinScaleSpinBox mWMTSUrlLineEdit twWFSLayers @@ -3342,6 +3365,9 @@ mWCSUrlLineEdit pbnLaunchOWSChecker teOWSChecker + mStartDateTimeEdit + mEndDateTimeEdit + mCalculateFromLayerButton diff --git a/src/ui/qgspropertyassistantwidgetbase.ui b/src/ui/qgspropertyassistantwidgetbase.ui index d9ad6b062c8e..ce2d6f1d264d 100644 --- a/src/ui/qgspropertyassistantwidgetbase.ui +++ b/src/ui/qgspropertyassistantwidgetbase.ui @@ -6,7 +6,7 @@ 0 0 - 525 + 545 426 @@ -247,6 +247,9 @@ minValueSpinBox maxValueSpinBox computeValuesButton + mTransformCurveCheckBox + mCurveEditor + mLegendPreview
    diff --git a/src/ui/qgsquerybuilderbase.ui b/src/ui/qgsquerybuilderbase.ui index 628e83333a3c..0df3b72dc100 100644 --- a/src/ui/qgsquerybuilderbase.ui +++ b/src/ui/qgsquerybuilderbase.ui @@ -346,17 +346,17 @@ p, li { white-space: pre-wrap; } - - QgsFilterLineEdit - QLineEdit -
    qgsfilterlineedit.h
    -
    QgsCollapsibleGroupBox QGroupBox
    qgscollapsiblegroupbox.h
    1
    + + QgsFilterLineEdit + QLineEdit +
    qgsfilterlineedit.h
    +
    QgsCodeEditorSQL QWidget @@ -366,11 +366,11 @@ p, li { white-space: pre-wrap; }
    lstFields + mFilterLineEdit lstValues btnSampleValues btnGetAllValues mUseUnfilteredLayer - groupBox4 btnEqual btnLessThan btnGreaterThan diff --git a/src/ui/qgsrastercalcdialogbase.ui b/src/ui/qgsrastercalcdialogbase.ui index 945ceeab9ebe..29660e2bc235 100644 --- a/src/ui/qgsrastercalcdialogbase.ui +++ b/src/ui/qgsrastercalcdialogbase.ui @@ -519,10 +519,16 @@
    qgscollapsiblegroupbox.h
    1 + + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    QgsFileWidget QWidget
    qgsfilewidget.h
    + 1
    QgsDoubleSpinBox @@ -535,15 +541,9 @@
    qgsprojectionselectionwidget.h
    1
    - - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    -
    mRasterBandsListWidget - mOutputLayer mOutputFormatComboBox mCurrentLayerExtentButton mXMinSpinBox @@ -554,7 +554,6 @@ mNRowsSpinBox mCrsSelector mAddResultToProjectCheckBox - mOperatorsGroupBox mPlusPushButton mMultiplyPushButton mSqrtButton @@ -579,6 +578,9 @@ mGreaterEqualButton mAndButton mOrButton + mAbsButton + mMinButton + mMaxButton mExpressionTextEdit diff --git a/src/ui/qgsrasterlayerpropertiesbase.ui b/src/ui/qgsrasterlayerpropertiesbase.ui index 5303fc1b5531..fb928cf91c80 100644 --- a/src/ui/qgsrasterlayerpropertiesbase.ui +++ b/src/ui/qgsrasterlayerpropertiesbase.ui @@ -169,7 +169,7 @@ Temporal Settings - + :/images/themes/default/propertyicons/temporal.svg:/images/themes/default/propertyicons/temporal.svg
    @@ -303,7 +303,7 @@ 0 0 629 - 1168 + 1109 @@ -760,8 +760,8 @@ border-radius: 2px; 0 0 - 619 - 383 + 643 + 681 @@ -1296,8 +1296,8 @@ border-radius: 2px; 0 0 - 343 - 474 + 643 + 681 @@ -1649,8 +1649,8 @@ border-radius: 2px; 0 0 - 86 - 41 + 643 + 681 @@ -1867,8 +1867,8 @@ border-radius: 2px; 0 0 - 577 - 190 + 643 + 681 @@ -2097,8 +2097,8 @@ p, li { white-space: pre-wrap; } 0 0 - 343 - 684 + 643 + 681 @@ -2549,15 +2549,15 @@ p, li { white-space: pre-wrap; } - QgsFilterLineEdit - QLineEdit -
    qgsfilterlineedit.h
    + QgsCollapsibleGroupBox + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1
    - QgsScrollArea - QScrollArea -
    qgsscrollarea.h
    - 1 + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    QgsDoubleSpinBox @@ -2565,43 +2565,37 @@ p, li { white-space: pre-wrap; }
    qgsdoublespinbox.h
    - QgsDateTimeEdit - QDateTimeEdit -
    qgsdatetimeedit.h
    -
    - - QgsCollapsibleGroupBox - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 + QgsFilterLineEdit + QLineEdit +
    qgsfilterlineedit.h
    - QgsColorButton - QToolButton -
    qgscolorbutton.h
    + QgsProjectionSelectionWidget + QWidget +
    qgsprojectionselectionwidget.h
    1
    - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    + QgsFieldComboBox + QComboBox +
    qgsfieldcombobox.h
    - QgsOpacityWidget + QgsWebView QWidget -
    qgsopacitywidget.h
    +
    qgswebview.h
    1
    - QgsProjectionSelectionWidget - QWidget -
    qgsprojectionselectionwidget.h
    + QgsScrollArea + QScrollArea +
    qgsscrollarea.h
    1
    - QgsRasterBandComboBox - QComboBox -
    qgsrasterbandcombobox.h
    + QgsDateTimeEdit + QDateTimeEdit +
    qgsdatetimeedit.h
    QgsScaleRangeWidget @@ -2614,33 +2608,54 @@ p, li { white-space: pre-wrap; }
    qgslayertreeembeddedconfigwidget.h
    1
    + + QgsColorButton + QToolButton +
    qgscolorbutton.h
    + 1 +
    QgsBlendModeComboBox QComboBox
    qgsblendmodecombobox.h
    - QgsWebView + QgsOpacityWidget QWidget -
    qgswebview.h
    +
    qgsopacitywidget.h
    1
    - QgsFieldComboBox + QgsRasterBandComboBox QComboBox -
    qgsfieldcombobox.h
    +
    raster/qgsrasterbandcombobox.h
    mSearchLineEdit mOptionsListWidget + scrollArea_3 mLayerOrigNameLineEd leDisplayName + mCrsGroupBox mCrsSelector + mWmstGroup + mFetchModeComboBox + mDisableTime + mStaticTemporalRange + mStartStaticDateTimeEdit + mEndStaticDateTimeEdit + mSetEndAsStartStaticButton + mProjectTemporalRange + mReferenceTime + mReferenceDateTimeEdit + mPostgresRasterTemporalGroup + mPostgresRasterTemporalFieldComboBox + mPostgresRasterDefaultTime + mResetColorRenderingBtn scrollArea mRenderTypeComboBox mBlendModeComboBox - mResetColorRenderingBtn mSliderBrightness mBrightnessSpinBox mSliderContrast @@ -2657,6 +2672,7 @@ p, li { white-space: pre-wrap; } mZoomedInResamplingComboBox mZoomedOutResamplingComboBox mMaximumOversamplingSpinBox + mCbEarlyResampling scrollArea_2 mOpacityWidget mSrcNoDataValueCheckBox @@ -2669,10 +2685,10 @@ p, li { white-space: pre-wrap; } pbnDefaultValues pbnImportTransparentPixelValues pbnExportTransparentPixelValues + scrollArea_6 chkUseScaleDependentRendering mRefreshLayerCheckBox mRefreshLayerIntervalSpinBox - scrollArea_6 scrollArea_5 tePyramidDescription lbxPyramidResolutions @@ -2696,20 +2712,6 @@ p, li { white-space: pre-wrap; } mWMSPrintLayerLineEdit mPublishDataSourceUrlCheckBox mBackgroundLayerCheckBox - scrollArea_3 - mWmstGroup - mFetchModeComboBox - mDisableTime - mReferenceDateTimeEdit - mReferenceTime - mStaticTemporalRange - mSetEndAsStartStaticButton - mEndStaticDateTimeEdit - mStartStaticDateTimeEdit - mProjectTemporalRange - mPostgresRasterTemporalGroup - mPostgresRasterTemporalFieldComboBox - mPostgresRasterDefaultTime diff --git a/src/ui/qgsrelationmanageradddialogbase.ui b/src/ui/qgsrelationmanageradddialogbase.ui index 8ad1e3c88c9b..270aad37efab 100644 --- a/src/ui/qgsrelationmanageradddialogbase.ui +++ b/src/ui/qgsrelationmanageradddialogbase.ui @@ -134,6 +134,14 @@
    + + mIdLineEdit + mNameLineEdit + mRelationStrengthComboBox + mFieldsMappingTable + mFieldsMappingAddButton + mFieldsMappingRemoveButton + diff --git a/src/ui/qgsrelationmanageraddpolymorphicdialogbase.ui b/src/ui/qgsrelationmanageraddpolymorphicdialogbase.ui index c13f87c360df..502b05ab1195 100644 --- a/src/ui/qgsrelationmanageraddpolymorphicdialogbase.ui +++ b/src/ui/qgsrelationmanageraddpolymorphicdialogbase.ui @@ -170,11 +170,6 @@
    - - QgsCheckableComboBox - QComboBox -
    qgscheckablecombobox.h
    -
    QgsFieldComboBox QComboBox @@ -184,13 +179,29 @@ QgsFieldExpressionWidget QWidget
    qgsfieldexpressionwidget.h
    + 1
    QgsMapLayerComboBox QComboBox
    qgsmaplayercombobox.h
    + + QgsCheckableComboBox + QComboBox +
    qgscheckablecombobox.h
    +
    + + mIdLineEdit + mReferencingLayerComboBox + mReferencedLayerFieldComboBox + mRelationStrengthComboBox + mFieldsMappingTable + mFieldsMappingAddButton + mFieldsMappingRemoveButton + mReferencedLayersComboBox + diff --git a/src/ui/qgssourcefieldsproperties.ui b/src/ui/qgssourcefieldsproperties.ui index 91cca52d67bc..e5a8106f485e 100644 --- a/src/ui/qgssourcefieldsproperties.ui +++ b/src/ui/qgssourcefieldsproperties.ui @@ -111,6 +111,13 @@
    + + mFieldsList + mAddAttributeButton + mDeleteAttributeButton + mToggleEditingButton + mCalculateFieldButton + diff --git a/src/ui/qgstextformatwidgetbase.ui b/src/ui/qgstextformatwidgetbase.ui index a0646d2b865e..9699ddc844ba 100644 --- a/src/ui/qgstextformatwidgetbase.ui +++ b/src/ui/qgstextformatwidgetbase.ui @@ -718,7 +718,7 @@ 0 0 485 - 429 + 433 @@ -1280,8 +1280,8 @@ font-style: italic; 0 0 - 374 - 708 + 471 + 666 @@ -2164,8 +2164,8 @@ font-style: italic; 0 0 - 299 - 308 + 485 + 433 @@ -2510,8 +2510,8 @@ font-style: italic; 0 0 - 296 - 291 + 485 + 433 @@ -2788,8 +2788,8 @@ font-style: italic; 0 0 - 444 - 786 + 471 + 740 @@ -3549,8 +3549,8 @@ font-style: italic; 0 0 - 324 - 457 + 485 + 433 @@ -3977,8 +3977,8 @@ font-style: italic; 0 0 - 159 - 211 + 485 + 433 @@ -4127,8 +4127,8 @@ font-style: italic; 0 0 - 472 - 1686 + 474 + 1599 @@ -5826,9 +5826,9 @@ font-style: italic; 0 - -304 + 0 471 - 708 + 666 @@ -6578,20 +6578,9 @@ font-style: italic; - QgsPropertyOverrideButton - QToolButton -
    qgspropertyoverridebutton.h
    -
    - - QgsColorButton - QToolButton -
    qgscolorbutton.h
    - 1 -
    - - QgsScrollArea - QScrollArea -
    qgsscrollarea.h
    + QgsCollapsibleGroupBox + QGroupBox +
    qgscollapsiblegroupbox.h
    1
    @@ -6605,14 +6594,9 @@ font-style: italic;
    qgsdoublespinbox.h
    - QgsSymbolButton - QToolButton -
    qgssymbolbutton.h
    -
    - - QgsCollapsibleGroupBox - QGroupBox -
    qgscollapsiblegroupbox.h
    + QgsScrollArea + QScrollArea +
    qgsscrollarea.h
    1
    @@ -6622,15 +6606,31 @@ font-style: italic; 1 - QgsUnitSelectionWidget + QgsScaleWidget QWidget -
    qgsunitselectionwidget.h
    +
    qgsscalewidget.h
    +
    + + QgsPropertyOverrideButton + QToolButton +
    qgspropertyoverridebutton.h
    +
    + + QgsColorButton + QToolButton +
    qgscolorbutton.h
    1
    - QgsScaleWidget + QgsSymbolButton + QToolButton +
    qgssymbolbutton.h
    +
    + + QgsUnitSelectionWidget QWidget -
    qgsscalewidget.h
    +
    qgsunitselectionwidget.h
    + 1
    QgsEffectStackCompactWidget @@ -6674,6 +6674,7 @@ font-style: italic;
    mFieldExpressionWidget + scrollArea_mPreview mPreviewTextEdit mPreviewTextBtn mPreviewScaleComboBox @@ -6703,6 +6704,19 @@ font-style: italic; mFontOpacityDDBtn mHtmlFormattingCheckBox scrollArea_5 + mFontCapitalsComboBox + mFontCaseDDBtn + mFontLetterSpacingSpinBox + mFontLetterSpacingDDBtn + mFontWordSpacingSpinBox + mFontWordSpacingDDBtn + mKerningCheckBox + mTextOrientationComboBox + mTextOrientationDDBtn + comboBlendMode + mFontBlendModeDDBtn + mCheckBoxSubstituteText + mToolButtonConfigureSubstitutes wrapCharacterEdit mWrapCharDDBtn mAutoWrapLengthSpinBox @@ -6733,8 +6747,8 @@ font-style: italic; mFormatNumPlusSignChkBx mFormatNumPlusSignDDBtn scrollArea_7 - mEnableMaskChkBx - mEnableMaskDDBtn + mBufferDrawChkBx + mBufferDrawDDBtn spinBufferSize mBufferSizeDDBtn mBufferUnitWidget @@ -6748,6 +6762,17 @@ font-style: italic; mBufferJoinStyleDDBtn comboBufferBlendMode mBufferBlendModeDDBtn + scrollArea_71 + mEnableMaskChkBx + mEnableMaskDDBtn + mMaskBufferSizeSpinBox + mMaskBufferSizeDDBtn + mMaskBufferUnitWidget + mMaskBufferUnitsDDBtn + mMaskOpacityWidget + mMaskOpacityDDBtn + mMaskJoinStyleComboBox + mMaskJoinStyleDDBtn scrollArea_2 mShapeDrawChkBx mShapeDrawDDBtn @@ -6820,15 +6845,19 @@ font-style: italic; mShadowColorDDBtn mShadowBlendCmbBx mShadowBlendDDBtn + scrollArea_6 + mCalloutsDrawCheckBox + mCalloutDrawDDBtn + mCalloutStyleComboBox scrollArea_3 mPlacementModeComboBox chkLineAbove chkLineOn chkLineBelow + mLinePlacementFlagsDDBtn chkLineOrientationDependent mCheckAllowLabelsOutsidePolygons mAllowOutsidePolygonsDDBtn - mLinePlacementFlagsDDBtn mCentroidRadioVisible mCentroidRadioWhole mCentroidDDBtn @@ -6855,9 +6884,20 @@ font-style: italic; mPointOffsetUnitWidget mPointOffsetUnitsDDBtn mPointAngleSpinBox + mRepeatDistanceSpinBox + mRepeatDistanceDDBtn + mRepeatDistanceUnitWidget + mRepeatDistanceUnitDDBtn + mOverrunDistanceUnitWidget + mOverrunDistanceSpinBox + mOverrunDistanceDDBtn + mLineAnchorSettingsButton mMaxCharAngleInDSpinBox mMaxCharAngleOutDSpinBox mMaxCharAngleDDBtn + mGeometryGeneratorGroupBox + mGeometryGeneratorExpressionButton + mGeometryGeneratorType mCoordXDDBtn mCoordYDDBtn mCoordAlignmentHDDBtn @@ -6866,6 +6906,9 @@ font-style: italic; chkPreserveRotation mPrioritySlider mPriorityDDBtn + mChkNoObstacle + mIsObstacleDDBtn + mObstacleSettingsButton scrollArea_4 mScaleBasedVisibilityChkBx mScaleBasedVisibilityDDBtn @@ -6894,42 +6937,6 @@ font-style: italic; mLimitLabelSpinBox mMinSizeSpinBox mFitInsidePolygonCheckBox - scrollArea_mPreview - mGeometryGeneratorGroupBox - mGeometryGeneratorExpressionButton - mGeometryGeneratorType - mFontWordSpacingSpinBox - mFontCaseDDBtn - mFontLetterSpacingSpinBox - comboBlendMode - mToolButtonConfigureSubstitutes - mFontBlendModeDDBtn - mFontCapitalsComboBox - mFontLetterSpacingDDBtn - mCheckBoxSubstituteText - mFontWordSpacingDDBtn - mTextOrientationComboBox - mTextOrientationDDBtn - mKerningCheckBox - mBufferDrawDDBtn - mBufferDrawChkBx - scrollArea_71 - mMaskJoinStyleComboBox - mMaskOpacityDDBtn - mMaskBufferUnitWidget - mMaskJoinStyleDDBtn - mMaskBufferUnitsDDBtn - mMaskBufferSizeSpinBox - mMaskBufferSizeDDBtn - mMaskOpacityWidget - scrollArea_6 - mCalloutsDrawCheckBox - mCalloutDrawDDBtn - mCalloutStyleComboBox - mChkNoObstacle - mIsObstacleDDBtn - mObstacleSettingsButton - mLineAnchorSettingsButton diff --git a/src/ui/qgstilesourceselectbase.ui b/src/ui/qgstilesourceselectbase.ui index 7fb33546965c..85c2c9df20da 100644 --- a/src/ui/qgstilesourceselectbase.ui +++ b/src/ui/qgstilesourceselectbase.ui @@ -122,6 +122,11 @@ cmbConnections + btnNew + btnEdit + btnDelete + btnLoad + btnSave diff --git a/src/ui/qgsvectorlayerpropertiesbase.ui b/src/ui/qgsvectorlayerpropertiesbase.ui index e96e23f628c1..4eec1e27e407 100644 --- a/src/ui/qgsvectorlayerpropertiesbase.ui +++ b/src/ui/qgsvectorlayerpropertiesbase.ui @@ -440,7 +440,7 @@ 0 0 653 - 679 + 681 @@ -756,8 +756,8 @@ border-radius: 2px; 0 0 - 100 - 30 + 653 + 681 @@ -973,8 +973,8 @@ border-radius: 2px; 0 0 - 104 - 102 + 653 + 681 @@ -1368,8 +1368,8 @@ border-radius: 2px; 0 0 - 100 - 30 + 653 + 681 @@ -1570,8 +1570,8 @@ border-radius: 2px; 0 0 - 689 - 356 + 695 + 667 @@ -2062,8 +2062,8 @@ border-radius: 2px; 0 0 - 343 - 797 + 639 + 769 @@ -2567,15 +2567,27 @@ border-radius: 2px; - QgsFilterLineEdit - QLineEdit -
    qgsfilterlineedit.h
    + QgsCollapsibleGroupBox + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1
    QgsDoubleSpinBox QDoubleSpinBox
    qgsdoublespinbox.h
    + + QgsFilterLineEdit + QLineEdit +
    qgsfilterlineedit.h
    +
    + + QgsProjectionSelectionWidget + QWidget +
    qgsprojectionselectionwidget.h
    + 1 +
    QgsScrollArea QScrollArea @@ -2583,9 +2595,9 @@ border-radius: 2px; 1 - QgsCollapsibleGroupBox - QGroupBox -
    qgscollapsiblegroupbox.h
    + QgsFieldExpressionWidget + QWidget +
    qgsfieldexpressionwidget.h
    1
    @@ -2594,12 +2606,6 @@ border-radius: 2px;
    qgsvariableeditorwidget.h
    1
    - - QgsProjectionSelectionWidget - QWidget -
    qgsprojectionselectionwidget.h
    - 1 -
    QgsScaleComboBox QComboBox @@ -2622,12 +2628,6 @@ border-radius: 2px;
    qgslayertreeembeddedconfigwidget.h
    1
    - - QgsFieldExpressionWidget - QWidget -
    qgsfieldexpressionwidget.h
    - 1 -
    QgsCodeEditorHTML QWidget @@ -2648,10 +2648,11 @@ border-radius: 2px; mLayerOrigNameLineEdit txtDisplayName cboProviderEncoding + mCrsGroupBox mCrsSelector + mGeomGroupBox pbnIndex pbnUpdateExtents - txtSubsetSQL pbnQueryBuilder scrollArea_3 mJoinTreeWidget @@ -2699,6 +2700,10 @@ border-radius: 2px; mLayerMetadataUrlFormatComboBox mLayerLegendUrlLineEdit mLayerLegendUrlFormatComboBox + mWmsDimensionsTreeWidget + mButtonAddWmsDimension + mButtonEditWmsDimension + mButtonRemoveWmsDimension diff --git a/src/ui/qgswmsdimensiondialogbase.ui b/src/ui/qgswmsdimensiondialogbase.ui index 8708b916c19d..35da75034cb7 100644 --- a/src/ui/qgswmsdimensiondialogbase.ui +++ b/src/ui/qgswmsdimensiondialogbase.ui @@ -151,6 +151,15 @@
    qgsfieldcombobox.h
    + + mNameComboBox + mFieldComboBox + mEndFieldComboBox + mUnitsLineEdit + mUnitSymbolLineEdit + mDefaultDisplayComboBox + mReferenceValueComboBox + diff --git a/src/ui/qgsxyzsourcewidgetbase.ui b/src/ui/qgsxyzsourcewidgetbase.ui index 401b5eeb3b3b..85325a98bb6a 100644 --- a/src/ui/qgsxyzsourcewidgetbase.ui +++ b/src/ui/qgsxyzsourcewidgetbase.ui @@ -156,6 +156,11 @@
    + + QgsSpinBox + QSpinBox +
    qgsspinbox.h
    +
    QgsAuthSettingsWidget QWidget @@ -168,12 +173,16 @@
    qgsprovidersourcewidget.h
    1
    - - QgsSpinBox - QSpinBox -
    qgsspinbox.h
    -
    + + mEditUrl + mCheckBoxZMin + mSpinZMin + mCheckBoxZMax + mSpinZMax + mEditReferer + mComboTileResolution + diff --git a/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui b/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui index dda8c31c5733..0b71a341e16f 100644 --- a/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui +++ b/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui @@ -212,10 +212,11 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti scrollArea + mTemporalGroupBox + mModeAutomaticRadio mModeFixedRangeRadio mStartTemporalDateTimeEdit mEndTemporalDateTimeEdit - mTemporalGroupBox diff --git a/src/ui/symbollayer/widget_fontmarker.ui b/src/ui/symbollayer/widget_fontmarker.ui index 69ef3df2fce0..b7763f48e86c 100644 --- a/src/ui/symbollayer/widget_fontmarker.ui +++ b/src/ui/symbollayer/widget_fontmarker.ui @@ -550,9 +550,14 @@ - QgsColorButton - QToolButton -
    qgscolorbutton.h
    + QgsDoubleSpinBox + QDoubleSpinBox +
    qgsdoublespinbox.h
    +
    + + QgsScrollArea + QScrollArea +
    qgsscrollarea.h
    1
    @@ -561,9 +566,10 @@
    qgspropertyoverridebutton.h
    - QgsDoubleSpinBox - QDoubleSpinBox -
    qgsdoublespinbox.h
    + QgsColorButton + QToolButton +
    qgscolorbutton.h
    + 1
    QgsUnitSelectionWidget @@ -576,16 +582,12 @@ QComboBox
    qgspenstylecombobox.h
    - - QgsScrollArea - QScrollArea -
    qgsscrollarea.h
    - 1 -
    cboFont + mFontFamilyDDBtn mFontStyleComboBox + mFontStyleDDBtn spinSize mSizeUnitWidget mSizeDDBtn @@ -609,7 +611,9 @@ mHorizontalAnchorComboBox mHorizontalAnchorDDBtn scrollArea + mCharLineEdit mCharDDBtn + mCharPreview diff --git a/src/ui/symbollayer/widget_randommarkerfill.ui b/src/ui/symbollayer/widget_randommarkerfill.ui index 44b4cabc6ab7..580eb80e6945 100644 --- a/src/ui/symbollayer/widget_randommarkerfill.ui +++ b/src/ui/symbollayer/widget_randommarkerfill.ui @@ -92,7 +92,7 @@ 6 - 0.0 + 0.000000000000000 99999999.989999994635582 @@ -113,7 +113,7 @@ Qt::StrongFocus - +
    @@ -164,11 +164,6 @@
    - - QgsPropertyOverrideButton - QToolButton -
    qgspropertyoverridebutton.h
    -
    QgsSpinBox QSpinBox @@ -179,9 +174,29 @@ QDoubleSpinBox
    qgsdoublespinbox.h
    + + QgsPropertyOverrideButton + QToolButton +
    qgspropertyoverridebutton.h
    +
    + + QgsUnitSelectionWidget + QWidget +
    qgsunitselectionwidget.h
    + 1 +
    + mCountMethodComboBox + mPointCountSpinBox mPointCountDdbtn + mDensityAreaSpinBox + mDensityAreaUnitWidget + mDensityAreaDdbtn + mSeedSpinBox + mSeedDdbtn + mClipPointsCheckBox + mClipPointsDdbtn diff --git a/src/ui/symbollayer/widget_rastermarker.ui b/src/ui/symbollayer/widget_rastermarker.ui index 4bde60f25a2b..3448c9434159 100644 --- a/src/ui/symbollayer/widget_rastermarker.ui +++ b/src/ui/symbollayer/widget_rastermarker.ui @@ -6,8 +6,8 @@ 0 0 - 338 - 439 + 372 + 485 @@ -177,7 +177,7 @@ 2 - + 0 @@ -450,6 +450,12 @@
    + + QgsRatioLockButton + QToolButton +
    qgsratiolockbutton.h
    + 1 +
    QgsDoubleSpinBox QDoubleSpinBox @@ -466,11 +472,6 @@
    qgsunitselectionwidget.h
    1
    - - QgsRatioLockButton - QWidget -
    qgsratiolockbutton.h
    -
    QgsOpacityWidget QWidget @@ -488,8 +489,9 @@ mImageSourceLineEdit mFilenameDDBtn mWidthSpinBox - mWidthDDBtn mHeightSpinBox + mLockAspectRatio + mWidthDDBtn mHeightDDBtn mSizeUnitWidget mOpacityWidget diff --git a/src/ui/symbollayer/widget_simpleline.ui b/src/ui/symbollayer/widget_simpleline.ui index d3844a683426..58e1e123f8f3 100644 --- a/src/ui/symbollayer/widget_simpleline.ui +++ b/src/ui/symbollayer/widget_simpleline.ui @@ -509,15 +509,15 @@
    qgsdoublespinbox.h
    - QgsColorButton + QgsPropertyOverrideButton QToolButton -
    qgscolorbutton.h
    - 1 +
    qgspropertyoverridebutton.h
    - QgsPropertyOverrideButton + QgsColorButton QToolButton -
    qgspropertyoverridebutton.h
    +
    qgscolorbutton.h
    + 1
    QgsUnitSelectionWidget @@ -531,9 +531,10 @@
    qgspenstylecombobox.h
    - QgsPenStyleComboBox - QComboBox -
    qgspenstylecombobox.h
    + QgsCollapsibleGroupBoxBasic + QGroupBox +
    qgscollapsiblegroupbox.h
    + 1
    QgsPenCapStyleComboBox @@ -541,10 +542,9 @@
    qgspenstylecombobox.h
    - QgsCollapsibleGroupBoxBasic - QGroupBox -
    qgscollapsiblegroupbox.h
    - 1 + QgsPenStyleComboBox + QComboBox +
    qgspenstylecombobox.h
    @@ -569,6 +569,14 @@ spinPatternOffset mPatternOffsetUnitWidget mPatternOffsetDDBtn + mCheckAlignDash + mCheckDashCorners + mTrimStartDistanceSpin + mTrimDistanceStartUnitWidget + mTrimDistanceStartDDBtn + mTrimDistanceEndSpin + mTrimDistanceEndUnitWidget + mTrimDistanceEndDDBtn mDrawInsideCheckBox mRingFilterComboBox diff --git a/src/ui/symbollayer/widget_svgmarker.ui b/src/ui/symbollayer/widget_svgmarker.ui index 597f562b6d03..e0656f70726f 100644 --- a/src/ui/symbollayer/widget_svgmarker.ui +++ b/src/ui/symbollayer/widget_svgmarker.ui @@ -152,7 +152,7 @@ 2 - + 0 @@ -486,9 +486,9 @@ - QgsColorButton - QPushButton -
    qgscolorbutton.h
    + QgsRatioLockButton + QToolButton +
    qgsratiolockbutton.h
    1
    @@ -502,15 +502,16 @@
    qgspropertyoverridebutton.h
    - QgsUnitSelectionWidget - QWidget -
    qgsunitselectionwidget.h
    + QgsColorButton + QToolButton +
    qgscolorbutton.h
    1
    - QgsRatioLockButton + QgsUnitSelectionWidget QWidget -
    qgsratiolockbutton.h
    +
    qgsunitselectionwidget.h
    + 1
    QgsSvgSelectorWidget @@ -522,9 +523,10 @@ spinWidth spinHeight - mSizeUnitWidget + mLockAspectRatio mWidthDDBtn mHeightDDBtn + mSizeUnitWidget mChangeColorButton mFillColorDDBtn mChangeStrokeColorButton diff --git a/src/ui/symbollayer/widget_svgselector.ui b/src/ui/symbollayer/widget_svgselector.ui index 9c060e0f7533..a70e1459a2e4 100644 --- a/src/ui/symbollayer/widget_svgselector.ui +++ b/src/ui/symbollayer/widget_svgselector.ui @@ -209,18 +209,26 @@
    - QgsSvgSourceLineEdit - QWidget -
    qgsfilecontentsourcelineedit.h
    + QgsCollapsibleGroupBox + QGroupBox +
    qgscollapsiblegroupbox.h
    1
    - QgsCollapsibleGroupBox - QGroupBox -
    qgscollapsiblegroupbox.h
    + QgsSvgSourceLineEdit + QWidget +
    qgsfilecontentsourcelineedit.h
    1
    + + mSvgSourceLineEdit + mGroupsTreeView + mImagesListView + mParametersTreeView + mAddParameterButton + mRemoveParameterButton + diff --git a/src/ui/symbollayer/widget_symbolslist.ui b/src/ui/symbollayer/widget_symbolslist.ui index 79477de9fcd6..1f64794611c4 100644 --- a/src/ui/symbollayer/widget_symbolslist.ui +++ b/src/ui/symbollayer/widget_symbolslist.ui @@ -444,9 +444,14 @@
    qgsdoublespinbox.h
    - QgsOpacityWidget - QWidget -
    qgsopacitywidget.h
    + QgsPropertyOverrideButton + QToolButton +
    qgspropertyoverridebutton.h
    +
    + + QgsColorButton + QToolButton +
    qgscolorbutton.h
    1
    @@ -456,16 +461,11 @@ 1 - QgsColorButton - QToolButton -
    qgscolorbutton.h
    + QgsOpacityWidget + QWidget +
    qgsopacitywidget.h
    1
    - - QgsPropertyOverrideButton - QToolButton -
    qgspropertyoverridebutton.h
    -
    QgsStyleItemsListWidget QWidget @@ -480,12 +480,21 @@ mRotationDDBtn spinWidth mWidthDDBtn + btnMarkerColor + mMarkerOpacityWidget + mMarkerOpacityDDBtn spinSize mSizeDDBtn spinAngle mRotationDDBtn + btnLineColor + mLineOpacityWidget + mLineOpacityDDBtn spinWidth mWidthDDBtn + btnFillColor + mFillOpacityWidget + mFillOpacityDDBtn From f77cc81a52f0d9205306b6ca6a8521783f338f6a Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 09:37:11 +1000 Subject: [PATCH 169/377] Fix some ArcGis VectorTileServer urls cannot be directly loaded Some services don't default to returning JSON for the capabilities, so explicitly request it Fixes #42314 --- src/core/vectortile/qgsvectortilelayer.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/core/vectortile/qgsvectortilelayer.cpp b/src/core/vectortile/qgsvectortilelayer.cpp index 118cd160e701..4fea13cb025e 100644 --- a/src/core/vectortile/qgsvectortilelayer.cpp +++ b/src/core/vectortile/qgsvectortilelayer.cpp @@ -34,6 +34,7 @@ #include "qgsmaplayerfactory.h" #include +#include QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseName ) : QgsMapLayer( QgsMapLayerType::VectorTileLayer, baseName ) @@ -123,9 +124,16 @@ bool QgsVectorTileLayer::loadDataSource() bool QgsVectorTileLayer::setupArcgisVectorTileServiceConnection( const QString &uri, const QgsDataSourceUri &dataSourceUri ) { - QNetworkRequest request = QNetworkRequest( QUrl( uri ) ); + QUrl url( uri ); + // some services don't default to json format, while others do... so let's explicitly request it! + // (refs https://github.com/qgis/QGIS/issues/4231) + QUrlQuery query; + query.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "pjson" ) ); + url.setQuery( query ); - QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) ); + QNetworkRequest request = QNetworkRequest( url ); + + QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) ) QgsBlockingNetworkRequest networkRequest; switch ( networkRequest.get( request ) ) @@ -417,7 +425,7 @@ bool QgsVectorTileLayer::loadDefaultStyle( QString &error, QStringList &warnings for ( int resolution = 2; resolution > 0; resolution-- ) { QNetworkRequest request = QNetworkRequest( QUrl( spriteUriBase + QStringLiteral( "%1.json" ).arg( resolution > 1 ? QStringLiteral( "@%1x" ).arg( resolution ) : QString() ) ) ); - QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) ); + QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) ) QgsBlockingNetworkRequest networkRequest; switch ( networkRequest.get( request ) ) { @@ -429,7 +437,7 @@ bool QgsVectorTileLayer::loadDefaultStyle( QString &error, QStringList &warnings // retrieve sprite images QNetworkRequest request = QNetworkRequest( QUrl( spriteUriBase + QStringLiteral( "%1.png" ).arg( resolution > 1 ? QStringLiteral( "@%1x" ).arg( resolution ) : QString() ) ) ); - QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) ); + QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) ) QgsBlockingNetworkRequest networkRequest; switch ( networkRequest.get( request ) ) From 66ffbc37e611d65e3bcf8ed7bdb3b486ad27f83b Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 09:51:28 +1000 Subject: [PATCH 170/377] [processing] When running "point on surface" with "create point for each part" option enabled, discard incoming fid fields and regenerate Because we are potentially outputing multiple features per input feature when this option is enabled, we can't guarantee that the existing fid values will be unique. Fixes #42350 --- src/analysis/processing/qgsalgorithmpointonsurface.cpp | 8 ++++++++ src/analysis/processing/qgsalgorithmpointonsurface.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/analysis/processing/qgsalgorithmpointonsurface.cpp b/src/analysis/processing/qgsalgorithmpointonsurface.cpp index 0328c9922d44..7f25752e5340 100644 --- a/src/analysis/processing/qgsalgorithmpointonsurface.cpp +++ b/src/analysis/processing/qgsalgorithmpointonsurface.cpp @@ -50,6 +50,14 @@ QString QgsPointOnSurfaceAlgorithm::outputName() const return QObject::tr( "Point" ); } +QgsFeatureSink::SinkFlags QgsPointOnSurfaceAlgorithm::sinkFlags() const +{ + if ( mAllParts ) + return QgsProcessingFeatureBasedAlgorithm::sinkFlags() | QgsFeatureSink::RegeneratePrimaryKey; + else + return QgsProcessingFeatureBasedAlgorithm::sinkFlags(); +} + QString QgsPointOnSurfaceAlgorithm::shortHelpString() const { return QObject::tr( "Returns a point guaranteed to lie on the surface of a geometry." ); diff --git a/src/analysis/processing/qgsalgorithmpointonsurface.h b/src/analysis/processing/qgsalgorithmpointonsurface.h index b804535495ca..56fade80a8b3 100644 --- a/src/analysis/processing/qgsalgorithmpointonsurface.h +++ b/src/analysis/processing/qgsalgorithmpointonsurface.h @@ -51,6 +51,7 @@ class QgsPointOnSurfaceAlgorithm : public QgsProcessingFeatureBasedAlgorithm QString outputName() const override; QgsProcessing::SourceType outputLayerType() const override { return QgsProcessing::TypeVectorPoint; } QgsWkbTypes::Type outputWkbType( QgsWkbTypes::Type inputWkbType ) const override { Q_UNUSED( inputWkbType ) return QgsWkbTypes::Point; } + QgsFeatureSink::SinkFlags sinkFlags() const override; bool prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; QgsFeatureList processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; From 988b9fa6920288b0569139d229f91eb00da07fc4 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 09:55:26 +1000 Subject: [PATCH 171/377] Better error reporting in Point on Surface --- src/analysis/processing/qgsalgorithmpointonsurface.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/analysis/processing/qgsalgorithmpointonsurface.cpp b/src/analysis/processing/qgsalgorithmpointonsurface.cpp index 7f25752e5340..e8ec1d317f6a 100644 --- a/src/analysis/processing/qgsalgorithmpointonsurface.cpp +++ b/src/analysis/processing/qgsalgorithmpointonsurface.cpp @@ -94,7 +94,7 @@ QgsFeatureList QgsPointOnSurfaceAlgorithm::processFeature( const QgsFeature &f, { QgsFeatureList list; QgsFeature feature = f; - if ( feature.hasGeometry() ) + if ( feature.hasGeometry() && !feature.geometry().isEmpty() ) { QgsGeometry geom = feature.geometry(); @@ -106,13 +106,15 @@ QgsFeatureList QgsPointOnSurfaceAlgorithm::processFeature( const QgsFeature &f, { const QgsGeometryCollection *geomCollection = static_cast( geom.constGet() ); - for ( int i = 0; i < geomCollection->partCount(); ++i ) + const int partCount = geomCollection->partCount(); + list.reserve( partCount ); + for ( int i = 0; i < partCount; ++i ) { QgsGeometry partGeometry( geomCollection->geometryN( i )->clone() ); QgsGeometry outputGeometry = partGeometry.pointOnSurface(); if ( outputGeometry.isNull() ) { - feedback->pushInfo( QObject::tr( "Error calculating point on surface for feature %1 part %2: %3" ).arg( feature.id() ).arg( i ).arg( outputGeometry.lastError() ) ); + feedback->reportError( QObject::tr( "Error calculating point on surface for feature %1 part %2: %3" ).arg( feature.id() ).arg( i ).arg( outputGeometry.lastError() ) ); } feature.setGeometry( outputGeometry ); list << feature; @@ -123,7 +125,7 @@ QgsFeatureList QgsPointOnSurfaceAlgorithm::processFeature( const QgsFeature &f, QgsGeometry outputGeometry = feature.geometry().pointOnSurface(); if ( outputGeometry.isNull() ) { - feedback->pushInfo( QObject::tr( "Error calculating point on surface for feature %1: %2" ).arg( feature.id() ).arg( outputGeometry.lastError() ) ); + feedback->reportError( QObject::tr( "Error calculating point on surface for feature %1: %2" ).arg( feature.id() ).arg( outputGeometry.lastError() ) ); } feature.setGeometry( outputGeometry ); list << feature; From 972173901c6164ad7393614392c09d0ca6090f8c Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 10:27:40 +1000 Subject: [PATCH 172/377] Don't allow temporal dock to be shrunk shorter than its contents --- .../auto_generated/qgspanelwidgetstack.sip.in | 5 ++++ src/gui/qgspanelwidgetstack.cpp | 14 +++++++++ src/gui/qgspanelwidgetstack.h | 3 ++ src/ui/qgstemporalcontrollerwidgetbase.ui | 29 +++++++++---------- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/python/gui/auto_generated/qgspanelwidgetstack.sip.in b/python/gui/auto_generated/qgspanelwidgetstack.sip.in index b47e2cd85811..1e414f1c2ac2 100644 --- a/python/gui/auto_generated/qgspanelwidgetstack.sip.in +++ b/python/gui/auto_generated/qgspanelwidgetstack.sip.in @@ -90,6 +90,11 @@ Returns the panel currently shown in the stack. .. versionadded:: 3.0 %End + virtual QSize sizeHint() const; + + virtual QSize minimumSizeHint() const; + + public slots: void acceptCurrentPanel(); diff --git a/src/gui/qgspanelwidgetstack.cpp b/src/gui/qgspanelwidgetstack.cpp index 220c29295471..175061abb0c2 100644 --- a/src/gui/qgspanelwidgetstack.cpp +++ b/src/gui/qgspanelwidgetstack.cpp @@ -90,6 +90,20 @@ QgsPanelWidget *QgsPanelWidgetStack::currentPanel() return qobject_cast( mStackedWidget->currentWidget() ); } +QSize QgsPanelWidgetStack::sizeHint() const +{ + if ( QWidget *widget = mStackedWidget->currentWidget() ) + return widget->sizeHint(); + return QWidget::sizeHint(); +} + +QSize QgsPanelWidgetStack::minimumSizeHint() const +{ + if ( QWidget *widget = mStackedWidget->currentWidget() ) + return widget->minimumSizeHint(); + return QWidget::minimumSizeHint(); +} + void QgsPanelWidgetStack::acceptCurrentPanel() { // You can't accept the main panel. diff --git a/src/gui/qgspanelwidgetstack.h b/src/gui/qgspanelwidgetstack.h index d774af833972..5d0fa0b660a3 100644 --- a/src/gui/qgspanelwidgetstack.h +++ b/src/gui/qgspanelwidgetstack.h @@ -91,6 +91,9 @@ class GUI_EXPORT QgsPanelWidgetStack : public QWidget, private Ui::QgsRendererWi */ QgsPanelWidget *currentPanel(); + QSize sizeHint() const override; + QSize minimumSizeHint() const override; + public slots: /** diff --git a/src/ui/qgstemporalcontrollerwidgetbase.ui b/src/ui/qgstemporalcontrollerwidgetbase.ui index 765c1a011012..c9b35e637dff 100644 --- a/src/ui/qgstemporalcontrollerwidgetbase.ui +++ b/src/ui/qgstemporalcontrollerwidgetbase.ui @@ -2,14 +2,6 @@ QgsTemporalControllerWidgetBase - - - 0 - 0 - 747 - 131 - - QgsDockWidget @@ -122,14 +114,8 @@
    - - - 0 - 0 - - - 1 + 2 @@ -525,6 +511,19 @@
    + + + + Qt::Vertical + + + + 20 + 40 + + + +
    From c1f2d1d8ffc70c3dd2947272b4316a8957769b84 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 10:11:29 +1000 Subject: [PATCH 173/377] Explicitly state in temporal controller dock that the visible time range is lower < t <= upper Provides explicit clarification to users that the upper time in the current filter time range is NOT visible in the canvas --- src/ui/qgstemporalcontrollerwidgetbase.ui | 68 ++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/src/ui/qgstemporalcontrollerwidgetbase.ui b/src/ui/qgstemporalcontrollerwidgetbase.ui index c9b35e637dff..1eaa92807c89 100644 --- a/src/ui/qgstemporalcontrollerwidgetbase.ui +++ b/src/ui/qgstemporalcontrollerwidgetbase.ui @@ -178,13 +178,45 @@ + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + - to + <html><head/><body><p>≤ <span style=" font-style:italic;">t</span> &lt;</p></body></html> + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + @@ -406,13 +438,45 @@ + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + - to + <html><head/><body><p>≤ <span style=" font-style:italic;">t</span> &lt;</p></body></html> + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + From a979e5d5d813b6b49ea7c3544a5c15e6cd48b261 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 11:55:37 +1000 Subject: [PATCH 174/377] An experiment --- .docker/docker-qgis-build-qt6.sh | 34 ++++++++++++++++++++++ .docker/qgis3-qt6-build-deps.dockerfile | 37 ++++++++++++++++++++++++ .github/workflows/qt6.yml | 38 +++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100755 .docker/docker-qgis-build-qt6.sh create mode 100644 .docker/qgis3-qt6-build-deps.dockerfile create mode 100644 .github/workflows/qt6.yml diff --git a/.docker/docker-qgis-build-qt6.sh b/.docker/docker-qgis-build-qt6.sh new file mode 100755 index 000000000000..1bdf7d7fc9d2 --- /dev/null +++ b/.docker/docker-qgis-build-qt6.sh @@ -0,0 +1,34 @@ + +mkdir /usr/src/qgis/build +cd /usr/src/qgis/build || exit -1 + +CLANG_WARNINGS="-Wrange-loop-construct" + +cmake -GNinja \ + -DWITH_QUICK=OFF \ + -DWITH_3D=ON \ + -DWITH_STAGED_PLUGINS=ON \ + -DWITH_GRASS=OFF \ + -DSUPPRESS_QT_WARNINGS=ON \ + -DENABLE_MODELTEST=ON \ + -DENABLE_PGTEST=ON \ + -DENABLE_SAGA_TESTS=ON \ + -DENABLE_MSSQLTEST=ON \ + -DWITH_QSPATIALITE=OFF \ + -DWITH_QWTPOLAR=OFF \ + -DWITH_APIDOC=OFF \ + -DWITH_ASTYLE=OFF \ + -DWITH_CUSTOM_WIDGETS=ON \ + -DWITH_DESKTOP=ON \ + -DWITH_BINDINGS=ON \ + -DWITH_SERVER=ON \ + -DWITH_ORACLE=OFF \ + -DDISABLE_DEPRECATED=ON \ + -DCXX_EXTRA_FLAGS="${CLANG_WARNINGS}" \ + -DCMAKE_C_COMPILER=/bin/clang \ + -DCMAKE_CXX_COMPILER=/bin/clang++ \ + -DADD_CLAZY_CHECKS=ON \ + -DWERROR=TRUE \ + .. + +ninja diff --git a/.docker/qgis3-qt6-build-deps.dockerfile b/.docker/qgis3-qt6-build-deps.dockerfile new file mode 100644 index 000000000000..c2e7d0bc2cd2 --- /dev/null +++ b/.docker/qgis3-qt6-build-deps.dockerfile @@ -0,0 +1,37 @@ +FROM fedora:rawhide +MAINTAINER Matthias Kuhn + +RUN dnf -y install \ + bison \ + clang \ + clazy \ + exiv2-devel \ + fcgi-devel \ + flex \ + gdal-devel \ + geos-devel \ + gsl-devel \ + libpq-devel \ + libspatialite-devel \ + libzip-devel \ + libzstd-devel \ + ninja-build \ + proj-devel \ + protobuf-devel \ + protobuf-lite-devel \ + python3-pyqt5-sip \ + python3-qscintilla-qt5 \ + python3-qt5-devel \ + qca-qt5-devel \ + qscintilla-qt5-devel \ + qt5-qt3d-devel \ + qt5-qtbase-devel \ + qt5-qtlocation-devel \ + qt5-qtserialport-devel \ + qt5-qttools-static \ + qt5-qtwebkit-devel \ + qtkeychain-qt5-devel \ + qwt-qt5-devel \ + spatialindex-devel \ + sqlite-devel \ + unzip diff --git a/.github/workflows/qt6.yml b/.github/workflows/qt6.yml new file mode 100644 index 000000000000..8906a40e757f --- /dev/null +++ b/.github/workflows/qt6.yml @@ -0,0 +1,38 @@ +name: Build with Qt 6 + +on: + push: + branches: + - master + - release-** + paths: + - 'src/**' + - 'tests/**' + - 'CMakeLists.txt' + - '.github/workflows/**' + - '.ci/**' + pull_request: + branches: + - master + - release-** + paths: + - 'src/**' + - 'tests/**' + - 'CMakeLists.txt' + - '.github/workflows/**' + - '.ci/**' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Setup build dependencies + run: | + docker build -t qgis_build_deps -f .docker/qgis3-qt6-build-deps.dockerfile . + - name: Run build + run: | + docker run -v $(pwd):/usr/src/qgis qgis_build_deps /usr/src/qgis/.docker/docker-qgis-build-qt6.sh + From 745230ceb93b066ec1f915aba0ce823afb920d8d Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 11:58:30 +1000 Subject: [PATCH 175/377] Super minimal build --- .docker/docker-qgis-build-qt6.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.docker/docker-qgis-build-qt6.sh b/.docker/docker-qgis-build-qt6.sh index 1bdf7d7fc9d2..266dbd111992 100755 --- a/.docker/docker-qgis-build-qt6.sh +++ b/.docker/docker-qgis-build-qt6.sh @@ -6,22 +6,25 @@ CLANG_WARNINGS="-Wrange-loop-construct" cmake -GNinja \ -DWITH_QUICK=OFF \ - -DWITH_3D=ON \ + -DWITH_3D=OFF \ + -DWITH_ANALYSIS=OFF \ + -DWITH_DESKTOP=OFF \ + -DWITH_GUI=OFF \ -DWITH_STAGED_PLUGINS=ON \ -DWITH_GRASS=OFF \ -DSUPPRESS_QT_WARNINGS=ON \ -DENABLE_MODELTEST=ON \ - -DENABLE_PGTEST=ON \ - -DENABLE_SAGA_TESTS=ON \ - -DENABLE_MSSQLTEST=ON \ + -DENABLE_PGTEST=OFF \ + -DENABLE_SAGA_TESTS=OFF \ + -DENABLE_MSSQLTEST=OFF \ -DWITH_QSPATIALITE=OFF \ -DWITH_QWTPOLAR=OFF \ -DWITH_APIDOC=OFF \ -DWITH_ASTYLE=OFF \ - -DWITH_CUSTOM_WIDGETS=ON \ - -DWITH_DESKTOP=ON \ - -DWITH_BINDINGS=ON \ - -DWITH_SERVER=ON \ + -DWITH_CUSTOM_WIDGETS=OFF \ + -DWITH_DESKTOP=OFF \ + -DWITH_BINDINGS=OFF \ + -DWITH_SERVER=OFF \ -DWITH_ORACLE=OFF \ -DDISABLE_DEPRECATED=ON \ -DCXX_EXTRA_FLAGS="${CLANG_WARNINGS}" \ From 52c6e79f6beaf590b90d1bef2bed3b81242def38 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:06:19 +1000 Subject: [PATCH 176/377] Super minimal --- .docker/docker-qgis-build-qt6.sh | 2 +- .docker/qgis3-qt6-build-deps.dockerfile | 16 +++------------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/.docker/docker-qgis-build-qt6.sh b/.docker/docker-qgis-build-qt6.sh index 266dbd111992..79d6aa3d45e1 100755 --- a/.docker/docker-qgis-build-qt6.sh +++ b/.docker/docker-qgis-build-qt6.sh @@ -1,6 +1,6 @@ mkdir /usr/src/qgis/build -cd /usr/src/qgis/build || exit -1 +cd /usr/src/qgis/build || exit 1 CLANG_WARNINGS="-Wrange-loop-construct" diff --git a/.docker/qgis3-qt6-build-deps.dockerfile b/.docker/qgis3-qt6-build-deps.dockerfile index c2e7d0bc2cd2..f9c471873a86 100644 --- a/.docker/qgis3-qt6-build-deps.dockerfile +++ b/.docker/qgis3-qt6-build-deps.dockerfile @@ -19,19 +19,9 @@ RUN dnf -y install \ proj-devel \ protobuf-devel \ protobuf-lite-devel \ - python3-pyqt5-sip \ - python3-qscintilla-qt5 \ - python3-qt5-devel \ - qca-qt5-devel \ - qscintilla-qt5-devel \ - qt5-qt3d-devel \ - qt5-qtbase-devel \ - qt5-qtlocation-devel \ - qt5-qtserialport-devel \ - qt5-qttools-static \ - qt5-qtwebkit-devel \ - qtkeychain-qt5-devel \ - qwt-qt5-devel \ + qt6-qt3d-devel \ + qt6-qtbase-devel \ + qt6-qttools-static \ spatialindex-devel \ sqlite-devel \ unzip From 3580b67e0179f2c3575a12a7887d758ae758ec1b Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:10:17 +1000 Subject: [PATCH 177/377] Bash --- .docker/docker-qgis-build-qt6.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.docker/docker-qgis-build-qt6.sh b/.docker/docker-qgis-build-qt6.sh index 79d6aa3d45e1..567b395b4662 100755 --- a/.docker/docker-qgis-build-qt6.sh +++ b/.docker/docker-qgis-build-qt6.sh @@ -1,3 +1,6 @@ +#!/usr/bin/env bash + +set -e mkdir /usr/src/qgis/build cd /usr/src/qgis/build || exit 1 From eab992a74ce6c67cc5b61c0f7ca07be1fea373d6 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:15:23 +1000 Subject: [PATCH 178/377] No qgis_process --- .docker/docker-qgis-build-qt6.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.docker/docker-qgis-build-qt6.sh b/.docker/docker-qgis-build-qt6.sh index 567b395b4662..70b6a5d890d8 100755 --- a/.docker/docker-qgis-build-qt6.sh +++ b/.docker/docker-qgis-build-qt6.sh @@ -15,6 +15,7 @@ cmake -GNinja \ -DWITH_GUI=OFF \ -DWITH_STAGED_PLUGINS=ON \ -DWITH_GRASS=OFF \ + -DWITH_QGIS_PROCESS=OFF \ -DSUPPRESS_QT_WARNINGS=ON \ -DENABLE_MODELTEST=ON \ -DENABLE_PGTEST=OFF \ From 687b1c76a6fa2aae09c64e7e7d0b84e520707a89 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:16:42 +1000 Subject: [PATCH 179/377] Even less --- .docker/docker-qgis-build-qt6.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.docker/docker-qgis-build-qt6.sh b/.docker/docker-qgis-build-qt6.sh index 70b6a5d890d8..aea8b6d6f4ea 100755 --- a/.docker/docker-qgis-build-qt6.sh +++ b/.docker/docker-qgis-build-qt6.sh @@ -16,6 +16,8 @@ cmake -GNinja \ -DWITH_STAGED_PLUGINS=ON \ -DWITH_GRASS=OFF \ -DWITH_QGIS_PROCESS=OFF \ + -DWITH_QTWEBKIT=OFF \ + -DWITH_QT5SERIALPORT=OFF \ -DSUPPRESS_QT_WARNINGS=ON \ -DENABLE_MODELTEST=ON \ -DENABLE_PGTEST=OFF \ From 8af180af28bc81faf5d5815664af424cf5efaad0 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:22:44 +1000 Subject: [PATCH 180/377] Gross hack --- CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cd3fd9da2eff..9b4f50df222d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -432,33 +432,33 @@ if(WITH_CORE) ############################################################# # search for Qt5 - set(QT_MIN_VERSION 5.12.0) + set(QT_MIN_VERSION 6.0.0) # Use Qt5SerialPort optionally for GPS set (WITH_QT5SERIALPORT TRUE CACHE BOOL "Determines whether Qt5SerialPort should be tried for GPS positioning") if (WITH_QT5SERIALPORT) - find_package(Qt5 COMPONENTS SerialPort REQUIRED) + find_package(Qt6 COMPONENTS SerialPort REQUIRED) # following variable is used in qgsconfig.h set (HAVE_QT5SERIALPORT TRUE) endif() - find_package(Qt5 COMPONENTS Core Gui Widgets Network Xml Svg Concurrent Test UiTools Sql REQUIRED) + find_package(Qt6 COMPONENTS Core Gui Widgets Network Xml Svg Concurrent Test UiTools Sql REQUIRED) if (NOT IOS) - find_package(Qt5 COMPONENTS PrintSupport REQUIRED) + find_package(Qt6 COMPONENTS PrintSupport REQUIRED) else() add_definitions(-DQT_NO_PRINTER) endif() - find_package(Qt5 COMPONENTS Positioning) + find_package(Qt6 COMPONENTS Positioning) if (WITH_QTWEBKIT) find_package(Qt5WebKit REQUIRED) find_package(Qt5WebKitWidgets REQUIRED) endif() if (WITH_3D) - find_package(Qt5 COMPONENTS 3DCore 3DRender 3DInput 3DLogic 3DExtras REQUIRED) + find_package(Qt6 COMPONENTS 3DCore 3DRender 3DInput 3DLogic 3DExtras REQUIRED) set(HAVE_3D TRUE) # used in qgsconfig.h endif() if (APPLE) - find_package(Qt5 COMPONENTS MacExtras REQUIRED) + find_package(Qt6 COMPONENTS MacExtras REQUIRED) endif() # get the Qt plugins directory @@ -468,9 +468,9 @@ if(WITH_CORE) message(STATUS "Found Qt version: ${Qt5Core_VERSION_STRING}") if (WITH_QUICK) - find_package(Qt5 COMPONENTS Qml Quick REQUIRED) + find_package(Qt6 COMPONENTS Qml Quick REQUIRED) if(${CMAKE_SYSTEM_NAME} MATCHES "Android") - find_package(Qt5 COMPONENTS AndroidExtras) + find_package(Qt6 COMPONENTS AndroidExtras) else() find_package(QtQmlTools) endif() From 7bf3be8b1c996ac75afc5c4aa78ad032a94b6abf Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:29:07 +1000 Subject: [PATCH 181/377] Add svg --- .docker/qgis3-qt6-build-deps.dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/.docker/qgis3-qt6-build-deps.dockerfile b/.docker/qgis3-qt6-build-deps.dockerfile index f9c471873a86..425cc219998c 100644 --- a/.docker/qgis3-qt6-build-deps.dockerfile +++ b/.docker/qgis3-qt6-build-deps.dockerfile @@ -22,6 +22,7 @@ RUN dnf -y install \ qt6-qt3d-devel \ qt6-qtbase-devel \ qt6-qttools-static \ + qt6-qtsvg-devel \ spatialindex-devel \ sqlite-devel \ unzip From 1993cd451f5d156fd4ef5cfc32ec5b8fa2e59dd6 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:34:23 +1000 Subject: [PATCH 182/377] Another dumb hack --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b4f50df222d..2df1d80ee757 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -448,7 +448,7 @@ if(WITH_CORE) else() add_definitions(-DQT_NO_PRINTER) endif() - find_package(Qt6 COMPONENTS Positioning) + # find_package(Qt6 COMPONENTS Positioning) if (WITH_QTWEBKIT) find_package(Qt5WebKit REQUIRED) find_package(Qt5WebKitWidgets REQUIRED) From 4945f818d4d30fabf671a3b5dfc35cec6587ce6f Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:36:42 +1000 Subject: [PATCH 183/377] hacks --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2df1d80ee757..29ea9c7466c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -448,7 +448,7 @@ if(WITH_CORE) else() add_definitions(-DQT_NO_PRINTER) endif() - # find_package(Qt6 COMPONENTS Positioning) + find_package(Qt6 COMPONENTS Positioning) if (WITH_QTWEBKIT) find_package(Qt5WebKit REQUIRED) find_package(Qt5WebKitWidgets REQUIRED) @@ -462,11 +462,11 @@ if(WITH_CORE) endif() # get the Qt plugins directory - get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION) + get_target_property(QMAKE_EXECUTABLE Qt6::qmake LOCATION) EXEC_PROGRAM(${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_PLUGINS" RETURN_VALUE return_code OUTPUT_VARIABLE DEFAULT_QT_PLUGINS_DIR ) set (QT_PLUGINS_DIR ${DEFAULT_QT_PLUGINS_DIR} CACHE STRING "Path to installation directory for Qt Plugins. Defaults to Qt native plugin directory") - message(STATUS "Found Qt version: ${Qt5Core_VERSION_STRING}") + message(STATUS "Found Qt version: ${Qt6Core_VERSION_STRING}") if (WITH_QUICK) find_package(Qt6 COMPONENTS Qml Quick REQUIRED) if(${CMAKE_SYSTEM_NAME} MATCHES "Android") From 7476422be7341ba4925df19b68dbe9a6a858f10b Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:44:38 +1000 Subject: [PATCH 184/377] Less hacky --- CMakeLists.txt | 96 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 29ea9c7466c2..1af0c4c89c8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -431,48 +431,96 @@ if(WITH_CORE) endif() ############################################################# - # search for Qt5 - set(QT_MIN_VERSION 6.0.0) + # search for Qt + + set (WITH_QT6 TRUE CACHE BOOL "Enable (broken, experimental) Qt6 support") + if (WITH_QT6) + set(QT_MIN_VERSION 6.0.0) + else() + set(QT_MIN_VERSION 5.12.0) + endif() # Use Qt5SerialPort optionally for GPS set (WITH_QT5SERIALPORT TRUE CACHE BOOL "Determines whether Qt5SerialPort should be tried for GPS positioning") if (WITH_QT5SERIALPORT) - find_package(Qt6 COMPONENTS SerialPort REQUIRED) + if (WITH_QT6) + find_package(Qt6 COMPONENTS SerialPort REQUIRED) + else() + find_package(Qt5 COMPONENTS SerialPort REQUIRED) + endif() # following variable is used in qgsconfig.h set (HAVE_QT5SERIALPORT TRUE) endif() - find_package(Qt6 COMPONENTS Core Gui Widgets Network Xml Svg Concurrent Test UiTools Sql REQUIRED) + if (WITH_QT6) + find_package(Qt6 COMPONENTS Core Gui Widgets Network Xml Svg Concurrent Test UiTools Sql REQUIRED) + else() + find_package(Qt5 COMPONENTS Core Gui Widgets Network Xml Svg Concurrent Test UiTools Sql REQUIRED) + endif() if (NOT IOS) - find_package(Qt6 COMPONENTS PrintSupport REQUIRED) + if (WITH_QT6) + find_package(Qt6 COMPONENTS PrintSupport REQUIRED) + else() + find_package(Qt5 COMPONENTS PrintSupport REQUIRED) + endif() else() add_definitions(-DQT_NO_PRINTER) endif() - find_package(Qt6 COMPONENTS Positioning) - if (WITH_QTWEBKIT) + if (WITH_QT6) + find_package(Qt6 COMPONENTS Positioning) + else() + find_package(Qt5 COMPONENTS Positioning) + endif() + if (WITH_QTWEBKIT AND NOT WITH_QT6) find_package(Qt5WebKit REQUIRED) find_package(Qt5WebKitWidgets REQUIRED) endif() if (WITH_3D) - find_package(Qt6 COMPONENTS 3DCore 3DRender 3DInput 3DLogic 3DExtras REQUIRED) + if (WITH_QT6) + find_package(Qt6 COMPONENTS 3DCore 3DRender 3DInput 3DLogic 3DExtras REQUIRED) + else() + find_package(Qt5 COMPONENTS 3DCore 3DRender 3DInput 3DLogic 3DExtras REQUIRED) + endif() set(HAVE_3D TRUE) # used in qgsconfig.h endif() if (APPLE) - find_package(Qt6 COMPONENTS MacExtras REQUIRED) + if (WITH_QT6) + find_package(Qt6 COMPONENTS MacExtras REQUIRED) + else() + find_package(Qt6 COMPONENTS MacExtras REQUIRED) + endif() endif() # get the Qt plugins directory - get_target_property(QMAKE_EXECUTABLE Qt6::qmake LOCATION) + if (WITH_QT6) + get_target_property(QMAKE_EXECUTABLE Qt6::qmake LOCATION) + else() + get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION) + endif() + EXEC_PROGRAM(${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_PLUGINS" RETURN_VALUE return_code OUTPUT_VARIABLE DEFAULT_QT_PLUGINS_DIR ) set (QT_PLUGINS_DIR ${DEFAULT_QT_PLUGINS_DIR} CACHE STRING "Path to installation directory for Qt Plugins. Defaults to Qt native plugin directory") - message(STATUS "Found Qt version: ${Qt6Core_VERSION_STRING}") + if (WITH_QT6) + message(STATUS "Found Qt version: ${Qt6Core_VERSION_STRING}") + else() + message(STATUS "Found Qt version: ${Qt5Core_VERSION_STRING}") + endif() if (WITH_QUICK) - find_package(Qt6 COMPONENTS Qml Quick REQUIRED) - if(${CMAKE_SYSTEM_NAME} MATCHES "Android") + if (WITH_QT6) + find_package(Qt6 COMPONENTS Qml Quick REQUIRED) + if(${CMAKE_SYSTEM_NAME} MATCHES "Android") find_package(Qt6 COMPONENTS AndroidExtras) + else() + find_package(QtQmlTools) + endif() else() - find_package(QtQmlTools) + find_package(Qt5 COMPONENTS Qml Quick REQUIRED) + if(${CMAKE_SYSTEM_NAME} MATCHES "Android") + find_package(Qt5 COMPONENTS AndroidExtras) + else() + find_package(QtQmlTools) + endif() endif() # following variable is used in qgsconfig.h @@ -493,14 +541,18 @@ if(WITH_CORE) endif() # Password helper - find_package(QtKeychain REQUIRED) - # Master password hash and authentication encryption - find_package(QCA REQUIRED) - # Check for runtime dependency of qca-ossl plugin - # REQUIRED if unit tests are to be run from build directory - if(NOT MSVC) - include(QCAMacros) - FIND_QCAOSSL_PLUGIN_CPP(ENABLE_TESTS) + if (WITH_QT6) + # nope, not yet! + else() + find_package(QtKeychain REQUIRED) + # Master password hash and authentication encryption + find_package(QCA REQUIRED) + # Check for runtime dependency of qca-ossl plugin + # REQUIRED if unit tests are to be run from build directory + if(NOT MSVC) + include(QCAMacros) + FIND_QCAOSSL_PLUGIN_CPP(ENABLE_TESTS) + endif() endif() if (APPLE) From 7087e79f645d334d123c2dd13e4a97b13e4f641e Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:45:49 +1000 Subject: [PATCH 185/377] No more hacks --- .docker/docker-qgis-build-qt6.sh | 1 + CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.docker/docker-qgis-build-qt6.sh b/.docker/docker-qgis-build-qt6.sh index aea8b6d6f4ea..45c624684492 100755 --- a/.docker/docker-qgis-build-qt6.sh +++ b/.docker/docker-qgis-build-qt6.sh @@ -8,6 +8,7 @@ cd /usr/src/qgis/build || exit 1 CLANG_WARNINGS="-Wrange-loop-construct" cmake -GNinja \ + -DWITH_QT6=ON \ -DWITH_QUICK=OFF \ -DWITH_3D=OFF \ -DWITH_ANALYSIS=OFF \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 1af0c4c89c8b..c81eedc0f528 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -433,7 +433,7 @@ if(WITH_CORE) ############################################################# # search for Qt - set (WITH_QT6 TRUE CACHE BOOL "Enable (broken, experimental) Qt6 support") + set (WITH_QT6 FALSE CACHE BOOL "Enable (broken, experimental) Qt6 support") if (WITH_QT6) set(QT_MIN_VERSION 6.0.0) else() From 87fb181ab66b310bfe19dce9b177b33f344bf352 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:51:24 +1000 Subject: [PATCH 186/377] Maybe --- src/native/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index 796060164c24..44512c5cdd84 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -10,7 +10,11 @@ endif() set(NATIVE_LINK_LIBS) if(UNIX AND NOT APPLE AND NOT ANDROID) - find_package(Qt5DBus REQUIRED) + if (WITH_QT6) + find_package(Qt6DBus REQUIRED) + else() + find_package(Qt5DBus REQUIRED) + endif() endif() if(APPLE) From 7fba4cb4d08730251a257adb2eb622cfe440f9c1 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:53:11 +1000 Subject: [PATCH 187/377] Get the important stuff right --- .github/workflows/qt6.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/qt6.yml b/.github/workflows/qt6.yml index 8906a40e757f..a9c3bb06e702 100644 --- a/.github/workflows/qt6.yml +++ b/.github/workflows/qt6.yml @@ -1,4 +1,4 @@ -name: Build with Qt 6 +name: 😱 Build with Qt 6 on: push: From 8879d9386db9214baebcfaf07fed5fd7c70cc6d5 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:56:35 +1000 Subject: [PATCH 188/377] Dbus component --- src/native/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index 44512c5cdd84..4cd1ae384a44 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -11,7 +11,7 @@ set(NATIVE_LINK_LIBS) if(UNIX AND NOT APPLE AND NOT ANDROID) if (WITH_QT6) - find_package(Qt6DBus REQUIRED) + find_package(Qt6 COMPONENTS Dbus REQUIRED) else() find_package(Qt5DBus REQUIRED) endif() From 855897aaccbd479646ca1abad6d3e4aa3b88f05e Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 12:57:52 +1000 Subject: [PATCH 189/377] Remove other workflows temporarily --- .github/workflows/backport.yml | 18 -- .github/workflows/build-docker.yml | 157 ------------- .github/workflows/code_layout.yml | 218 ----------------- .github/workflows/flake8.yml | 28 --- .github/workflows/macos-build.yml | 156 ------------- .github/workflows/mingw64.yml | 110 --------- .github/workflows/ogc.yml | 60 ----- .github/workflows/pr-auto-milestone.yml | 141 ----------- .github/workflows/pr-needs-documentation.yml | 131 ----------- .github/workflows/release.yml | 31 --- .github/workflows/run-tests.yml | 233 ------------------- .github/workflows/stale_issues.yml | 43 ---- .github/workflows/stale_pr.yml | 54 ----- .github/workflows/unstale.yml | 15 -- 14 files changed, 1395 deletions(-) delete mode 100644 .github/workflows/backport.yml delete mode 100644 .github/workflows/build-docker.yml delete mode 100644 .github/workflows/code_layout.yml delete mode 100644 .github/workflows/flake8.yml delete mode 100644 .github/workflows/macos-build.yml delete mode 100644 .github/workflows/mingw64.yml delete mode 100644 .github/workflows/ogc.yml delete mode 100644 .github/workflows/pr-auto-milestone.yml delete mode 100644 .github/workflows/pr-needs-documentation.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/run-tests.yml delete mode 100644 .github/workflows/stale_issues.yml delete mode 100644 .github/workflows/stale_pr.yml delete mode 100644 .github/workflows/unstale.yml diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml deleted file mode 100644 index 493216253aa1..000000000000 --- a/.github/workflows/backport.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: ♻ Backport -on: - pull_request_target: - types: - - closed - - labeled - -jobs: - backport: - runs-on: ubuntu-18.04 - name: Backport - steps: - - name: Backport Bot - id: backport - if: github.event.pull_request.merged && ( ( github.event.action == 'closed' && contains( join( github.event.pull_request.labels.*.name ), 'backport') ) || contains( github.event.label.name, 'backport' ) ) - uses: m-kuhn/backport@v1.1.1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml deleted file mode 100644 index 8048eb23c497..000000000000 --- a/.github/workflows/build-docker.yml +++ /dev/null @@ -1,157 +0,0 @@ -name: 🐳 Build Docker images for current branches - -# on commits to this file, schedule and dispatch runs, the workflow will build the 3 different Docker images (master, PR, LTR) -# on tags, it will build only the image of the given tag -# this is made by using a matrix defined in a dedicated job -on: - push: - tags: - - final-* - branches: - - master - paths: - - .github/workflows/build-docker.yml - schedule: - # runs every day - - cron: '0 0 * * *' - workflow_dispatch: - # POST https://api.github.com/repos/qgis/QGIS/actions/workflows/2264135/dispatches: - -jobs: - define-strategy: - if: github.repository_owner == 'qgis' - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.matrix.outputs.matrix }} - steps: - - id: matrix - run: | - if [[ "${GITHUB_REF}" =~ ^refs/tags ]]; then - echo "::set-output name=matrix::{\"branch\":[\"${GITHUB_REF##*/}\"]}" - else - echo "::set-output name=matrix::{\"branch\":[\"master\", \"release-3_16\", \"release-3_18\"]}" - fi - - build-docker: - if: github.repository_owner == 'qgis' - runs-on: ubuntu-latest - needs: define-strategy - - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - GH_TOKEN: ${{ secrets.GH_TOKEN }} - CC: /usr/lib/ccache/gcc - CXX: /usr/lib/ccache/g++ # Building SIP binding freezes with Clang in Docker, maybe a SIP issue, maybe not - DOCKER_BUILD_DEPS_FILE: qgis3-build-deps.dockerfile - - strategy: - matrix: ${{ fromJSON( needs.define-strategy.outputs.matrix ) }} - - steps: - - name: Cache - id: cache - uses: actions/cache@v2.1.4 - with: - path: ~/.ccache - key: docker-build-${{ matrix.branch }}-${{ github.sha }} - restore-keys: | - docker-build-${{ matrix.branch }}- - docker-build-master- - - - name: checkout ${{ matrix.branch }} - uses: actions/checkout@v2 - with: - ref: ${{ matrix.branch }} - - - name: Define vars - env: - branch: ${{ matrix.branch }} - run: | - export DOCKER_TAG=${branch//master/latest} - export DOCKER_DEPS_TAG=${DOCKER_TAG} - - # add vars for next steps - echo "DOCKER_TAG=${DOCKER_TAG}" >> $GITHUB_ENV - echo "DOCKER_DEPS_TAG=${DOCKER_DEPS_TAG}" >> $GITHUB_ENV - - echo "branch: ${branch}" - echo "docker tag: ${DOCKER_TAG}" - echo "docker deps tag: ${DOCKER_DEPS_TAG}" - - - name: Copy cache - run: | - [[ -d ~/.ccache ]] && echo "cache directory (~/.ccache) exists" || mkdir -p ~/.ccache - # copy ccache dir within QGIS source so it can be accessed from docker - cp -r ~/.ccache/. ./.ccache_image_build - - - name: QGIS deps Docker pull/rebuild - run: | - cd .docker - docker --version - docker pull "qgis/qgis3-build-deps:${DOCKER_DEPS_TAG}" || true - docker build --cache-from "qgis/qgis3-build-deps:${DOCKER_DEPS_TAG}" -t "qgis/qgis3-build-deps:${DOCKER_DEPS_TAG}" -f ${DOCKER_BUILD_DEPS_FILE} . - echo "push to qgis/qgis3-build-deps:${DOCKER_DEPS_TAG}" - docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" - docker push "qgis/qgis3-build-deps:${DOCKER_DEPS_TAG}" - - - name: Docker QGIS build - run: | - cd .docker - DOCKER_BUILD_ARGS="--build-arg DOCKER_DEPS_TAG --build-arg CC --build-arg CXX" - docker build ${DOCKER_BUILD_ARGS} \ - --cache-from "qgis/qgis:${DOCKER_TAG}" \ - -t "qgis/qgis:BUILDER" \ - -f qgis.dockerfile .. - - - name: Tag container and copy cache - run: | - docker run --name qgis_container qgis/qgis:BUILDER /bin/true - docker cp qgis_container:/QGIS/build_exit_value ./build_exit_value - - if [[ $(cat ./build_exit_value) != "OK" ]]; then - echo "Build failed, not pushing image" - exit 1 - fi - - echo "Copy build cache from Docker container to Travis cache directory" - rm -rf ~/.ccache/* - mkdir -p ~/.ccache - docker cp qgis_container:/QGIS/.ccache_image_build/. ~/.ccache - echo "Cache size: "$(du -sh ~/.ccache) - - - name: Finalize image - run: | - cd .docker - # enable experimental features in Docker to squash - echo '{ "experimental": true}' | sudo tee /etc/docker/daemon.json - sudo service docker restart - docker build ${DOCKER_BUILD_ARGS} \ - --cache-from "qgis/qgis:BUILDER" \ - --squash \ - -t "qgis/qgis:${DOCKER_TAG}" \ - -f qgis.dockerfile .. - - - name: Pushing image to docker hub - run: | - docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" - docker push "qgis/qgis:${DOCKER_TAG}" - - - name: Trigger PyQGIS API docs build for ${{ matrix.branch }} - if: success() && !startsWith(github.ref, 'refs/tags/') - env: - branch: ${{ matrix.branch }} - run: | - body='{ - "ref": "master", - "inputs": {"qgis_branch": "__QGIS_VERSION_BRANCH__"} - }' - body=$(sed "s/__QGIS_VERSION_BRANCH__/${branch}/;" <<< $body) - curl -X POST \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: token ${GH_TOKEN}" \ - https://api.github.com/repos/qgis/pyqgis/actions/workflows/2246440/dispatches \ - -d "${body}" - - - diff --git a/.github/workflows/code_layout.yml b/.github/workflows/code_layout.yml deleted file mode 100644 index bd10d111386b..000000000000 --- a/.github/workflows/code_layout.yml +++ /dev/null @@ -1,218 +0,0 @@ -name: 🧹 Code Layout - -on: - push: - branches: - - master - - release-** - pull_request: - -jobs: - documentation_checks: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Set up Python 3.7 - uses: actions/setup-python@v2.2.1 - with: - python-version: 3.7 - - name: Install Requirements - run: | - sudo apt install -y \ - doxygen \ - cpanminus \ - libyaml-tiny-perl \ - libio-socket-ssl-perl \ - libhttp-date-perl \ - libgetopt-long-descriptive-perl \ - libmoo-perl \ - libnamespace-clean-perl \ - libpath-tiny-perl \ - libpod-constants-perl \ - libscalar-list-utils-perl \ - libsort-key-perl \ - libstrictures-perl \ - libstring-escape-perl \ - libtry-tiny-perl \ - expect - cpanm --notest App::Licensecheck - python -m pip install --upgrade pip - pip install autopep8 nose2 mock termcolor - - name: Make - run: | - mkdir build - cd build - cmake -DWITH_SERVER=ON -DUSE_CCACHE=OFF -DWITH_CORE=OFF -DWITH_APIDOC=ON -DWITH_ASTYLE=ON -DENABLE_TESTS=ON -DWITH_DOT=NO -DWERROR=ON .. - make -j3 apidoc - - name: Run Tests - run: cd build && ctest -V -R PyQgsDocCoverage - - license_check: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Install Requirements - run: | - sudo apt install -y \ - cpanminus - cpanm --notest App::Licensecheck - - - name: Run License Check - run: ./tests/code_layout/test_licenses.sh - - shell_check: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Install Requirements - run: | - sudo apt install -y \ - shellcheck - - - name: Run Shellcheck - run: ./tests/code_layout/test_shellcheck.sh - - banned_keywords_check: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Run Banned Keywords Test - run: ./tests/code_layout/test_banned_keywords.sh - - def_window_title_check: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Def Window Title Test - run: ./tests/code_layout/test_defwindowtitle.sh - - qvariant_no_brace_init: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: No brace initialization of QVariant variables - run: ./tests/code_layout/test_qvariant_no_brace_init.sh - - qt_module_wide_imports: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: No module-wide imports of Qt modules - run: ./tests/code_layout/test_qt_imports.sh - - doxygen_layout_check: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Install Requirements - run: | - sudo apt install -y \ - expect \ - silversearcher-ag - - name: Doxygen Layout Test - run: ./tests/code_layout/test_doxygen_layout.sh - - indentation_check: - if: github.event_name == 'pull_request' - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - fetch-depth: 100 - - name: Install Requirements - run: | - sudo apt install -y \ - astyle \ - python3-autopep8 \ - flip - - name: Indentation Test - run: ./scripts/verify_indentation.sh HEAD~1 - - spell_check: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Install Requirements - run: | - sudo apt install -y \ - expect \ - silversearcher-ag - - uses: trilom/file-changes-action@v1.2.4 - id: changed_files - with: - output: ' ' - githubToken: ${{ secrets.GITHUB_TOKEN }} - - name: Spell Test - run: ./scripts/spell_check/check_spelling.sh -r ${{ steps.changed_files.outputs.files_modified }} ${{ steps.changed_files.outputs.files_added }} - - sip_check: - runs-on: ubuntu-latest - steps: - - name: Set up Python 3.7 - uses: actions/setup-python@v2.2.1 - with: - python-version: 3.7 - - name: Install Requirements - run: | - sudo apt install -y \ - cpanminus \ - libyaml-tiny-perl \ - libio-socket-ssl-perl \ - libhttp-date-perl \ - libgetopt-long-descriptive-perl \ - libmoo-perl \ - libnamespace-clean-perl \ - libpath-tiny-perl \ - libpod-constants-perl \ - libscalar-list-utils-perl \ - libsort-key-perl \ - libstrictures-perl \ - libstring-escape-perl \ - libtry-tiny-perl \ - expect - python -m pip install --upgrade pip - pip install autopep8 nose2 mock termcolor - - name: Checkout - uses: actions/checkout@v2 - - name: Sip Checks - run: ./tests/code_layout/test_sipify.sh - - name: Sip Include Test - run: ./tests/code_layout/test_sip_include.sh - - name: Sip Files Up To Date - run: ./tests/code_layout/test_sipfiles.sh - - cppcheck_16_04: - runs-on: ubuntu-16.04 - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Install Requirements - run: | - sudo apt install -y cppcheck - - - name: Run cppcheck test - run: ./scripts/cppcheck.sh - - cppcheck_18_04: - runs-on: ubuntu-18.04 - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Install Requirements - run: | - sudo apt install -y cppcheck - - - name: Run cppcheck test - run: ./scripts/cppcheck.sh diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml deleted file mode 100644 index 5a4305df275e..000000000000 --- a/.github/workflows/flake8.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: ❄ Flake8 - -on: - push: - paths: - - '**.py' - pull_request: - paths: - - '**.py' - -jobs: - flake8_py3: - name: Python Lint - runs-on: ubuntu-latest - steps: - - name: Setup Python - uses: actions/setup-python@v2.2.1 - with: - python-version: 3.7 - architecture: x64 - - name: Checkout - uses: actions/checkout@v2 - - name: Run flake8 - uses: julianwachholz/flake8-action@v1.1.0 - with: - checkName: 'Python Lint' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/macos-build.yml b/.github/workflows/macos-build.yml deleted file mode 100644 index 197d09b6976d..000000000000 --- a/.github/workflows/macos-build.yml +++ /dev/null @@ -1,156 +0,0 @@ -name: 🍏 Mac OS build -on: - push: - branches: - - master - - release-** - paths: - - 'src/**' - - 'external/**' - - 'python/**' - - 'tests/**' - - 'mac/**' - - '.github/workflows/macos-build.yml' - - '.ci/**' - - 'CMakeLists.txt' - pull_request: - branches: - - master - - release-** - paths: - - 'src/**' - - 'external/**' - - 'python/**' - - 'tests/**' - - 'mac/**' - - '.github/workflows/macos-build.yml' - - '.ci/**' - - 'CMakeLists.txt' - -env: - QT_VERSION: 5.14.2 - QGIS_DEPS_VERSION: 0.7.0 - CCACHE_DIR: /Users/runner/work/ccache - BUILD_DIR: /Users/runner/work/QGIS/build-QGIS - # apparently we cannot cache /opt directory as it fails to restore - # so we copy the deps in the home directory - DEPS_CACHE_DIR: /Users/runner/work/deps-cache - -jobs: - mac_os_build: - if: github.repository == 'qgis/QGIS' - runs-on: macos-latest - steps: - - uses: actions/checkout@v2 - - - name: Prepare build cache for pull request - uses: pat-s/always-upload-cache@v2.1.3 - if: github.event_name == 'pull_request' - with: - path: ${{ env.CCACHE_DIR }} - key: build-mac-ccache-${{ github.actor }}-${{ github.head_ref }}-${{ github.sha }} - # The head_ref or source branch of the pull request in a workflow run. - # The base_ref or target branch of the pull request in a workflow run. - restore-keys: | - build-mac-ccache-${{ github.actor }}-${{ github.head_ref }}- - build-mac-ccache-refs/heads/${{ github.base_ref }}- - build-mac-ccache-refs/heads/master- - - - name: Prepare build cache for branch/tag - # use a fork of actions/cache@v2 to upload cache even when the build or test failed - uses: pat-s/always-upload-cache@v2.1.3 - if: github.event_name != 'pull_request' - with: - path: ${{ env.CCACHE_DIR }} - # The branch or tag ref that triggered the workflow run. For branches this in the format refs/heads/, and for tags it is refs/tags/ - key: build-mac-ccache-${{ github.ref }}-${{ github.sha }} - restore-keys: | - build-mac-ccache-${{ github.ref }}- - build-mac-ccache-refs/heads/master- - - - # Qt caching - - name: Cache Qt - id: cache-qt - uses: pat-s/always-upload-cache@v2.1.3 - with: - path: ${{ env.DEPS_CACHE_DIR }}/Qt/${{ env.QT_VERSION }} - key: mac-qt-v4-${{ env.QT_VERSION }} - - - name: Restore Qt - if: steps.cache-qt.outputs.cache-hit == 'true' - run: | - sudo mkdir -p /opt - sudo mkdir -p /opt/Qt - sudo cp -r ${DEPS_CACHE_DIR}/Qt/${QT_VERSION} /opt/Qt/${QT_VERSION} - - - name: Download Qt - if: steps.cache-qt.outputs.cache-hit != 'true' - run: | - wget https://qgis.org/downloads/macos/deps/qt-${QT_VERSION}.tar.gz - mkdir -p ${DEPS_CACHE_DIR} - mkdir -p ${DEPS_CACHE_DIR}/Qt - - - # QGIS-deps caching - - name: Cache qgis-deps - id: cache-deps - uses: pat-s/always-upload-cache@v2.1.3 - with: - path: ${{ env.DEPS_CACHE_DIR }}/QGIS/qgis-deps-${{ env.QGIS_DEPS_VERSION }} - key: mac-qgis-deps-v4-${{ env.QGIS_DEPS_VERSION }} - - - name: Restore qgis-deps - if: steps.cache-deps.outputs.cache-hit == 'true' - run: | - sudo mkdir -p /opt - sudo mkdir -p /opt/QGIS - sudo cp -r ${DEPS_CACHE_DIR}/QGIS/qgis-deps-${QGIS_DEPS_VERSION} /opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION} - - - name: Download qgis-deps - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - wget https://qgis.org/downloads/macos/deps/qgis-deps-${QGIS_DEPS_VERSION}.tar.gz - mkdir -p ${DEPS_CACHE_DIR} - mkdir -p ${DEPS_CACHE_DIR}/QGIS - - - - - name: Install Qt and deps - env: - QT_ALREADY_CACHED: ${{ steps.cache-qt.outputs.cache-hit }} - QGIS_DEPS_ALREADY_CACHED: ${{ steps.cache-deps.outputs.cache-hit }} - run: | - wget https://qgis.org/downloads/macos/deps/install_qgis_deps-${QGIS_DEPS_VERSION}.bash - chmod +x ./install_qgis_deps-${QGIS_DEPS_VERSION}.bash - echo ::group::Install deps - sudo ./install_qgis_deps-${QGIS_DEPS_VERSION}.bash - echo ::endgroup:: - [[ ${QT_ALREADY_CACHED} != "true" ]] && cp -r /opt/Qt/${QT_VERSION} ${DEPS_CACHE_DIR}/Qt/${QT_VERSION} || true - [[ ${QGIS_DEPS_ALREADY_CACHED} != "true" ]] && cp -r /opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION} ${DEPS_CACHE_DIR}/QGIS/qgis-deps-${QGIS_DEPS_VERSION} || true - - - name: Install ccache - run: | - mkdir -p ${CCACHE_DIR} - brew install ccache - ccache --set-config=max_size=2.0G - ccache -s - - - name: Run cmake - run: | - mkdir -p ${BUILD_DIR} - cd ${BUILD_DIR} - - PATH=/opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}/stage/bin:$PATH \ - cmake -DQGIS_MAC_DEPS_DIR=/opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}/stage \ - -DCMAKE_PREFIX_PATH=/opt/Qt/${QT_VERSION}/clang_64 \ - -DWITH_BINDINGS=TRUE \ - -DWITH_3D=TRUE \ - -DWITH_PDAL=TRUE \ - -DWITH_EPT=TRUE \ - ../QGIS - - - name: Build QGIS - run: | - cd ${BUILD_DIR} - make -j $(sysctl -n hw.ncpu) diff --git a/.github/workflows/mingw64.yml b/.github/workflows/mingw64.yml deleted file mode 100644 index 0ada144677fa..000000000000 --- a/.github/workflows/mingw64.yml +++ /dev/null @@ -1,110 +0,0 @@ -name: 🪟 MingW64 Windows 64bit Build - -on: - push: - branches: - - master - - release-** - paths: - - 'src/**' - - 'external/**' - - 'python/**' - - 'tests/**' - - 'ms-windows/**' - - 'CMakeLists.txt' - - '.github/workflows/mingw64.yml' - pull_request: - paths: - - 'src/**' - - 'external/**' - - 'python/**' - - 'tests/**' - - 'ms-windows/**' - - 'CMakeLists.txt' - - '.github/workflows/mingw64.yml' - workflow_dispatch: - -jobs: - mingw64-build: - env: - CCACHE_DIR: ${{ github.workspace }}/.ccache - name: MinGW64 Windows Build - runs-on: ubuntu-latest - steps: - - - uses: actions/checkout@v2 - - - name: Build Docker Container with Build Environment - id: docker-build - uses: whoan/docker-build-with-cache-action@v5 - with: - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - registry: docker.pkg.github.com - image_name: qgis3-mingw-buildenv - dockerfile: ms-windows/mingw/qgis3-build-deps-mingw.dockerfile - push_git_tag: true - push_image_and_stages: on:push - pull_image_and_stages: ${{ github.event_name != 'workflow_dispatch' }} - - - name: Prepare build cache for pull request - uses: pat-s/always-upload-cache@v2.1.3 - if: github.event_name == 'pull_request' - with: - path: ${{ github.workspace }}/.ccache - key: mingw64-ccache-${{ github.actor }}-${{ github.head_ref }}-${{ github.sha }} - # The head_ref or source branch of the pull request in a workflow run. - # The base_ref or target branch of the pull request in a workflow run. - restore-keys: | - mingw64-ccache-${{ github.actor }}-${{ github.head_ref }}- - mingw64-ccache-${{ github.base_ref }}- - mingw64-ccache-refs/heads/master- - - - name: Prepare build cache for branch/tag - # use a fork of actions/cache@v2 to upload cache even when the build or test failed - uses: pat-s/always-upload-cache@v2.1.3 - if: github.event_name != 'pull_request' - with: - path: ${{ github.workspace }}/.ccache - # The branch or tag ref that triggered the workflow run. For branches this in the format refs/heads/, and for tags it is refs/tags/ - key: mingw64-ccache-${{ github.ref }}-${{ github.sha }} - restore-keys: | - mingw64-ccache-${{ github.ref }}- - mingw64-ccache-refs/heads/master- - - - name: Build QGIS Application - run: | - mkdir -p ${GITHUB_WORKSPACE}/.ccache - docker run \ - --env CCACHE_DIR=/QGIS/.ccache \ - -w /QGIS \ - -v ${GITHUB_WORKSPACE}:/QGIS \ - ${DOCKER_IMAGE} \ - ms-windows/mingw/build.sh x86_64 nodebug 4 - env: - DOCKER_IMAGE: ${{ steps.docker-build.outputs.FULL_IMAGE_NAME }} - - - name: Create Portable zip - run: | - DISTROOT=build_mingw64/dist/usr/x86_64-w64-mingw32/sys-root/mingw - DEBUGROOT=dist_debug - for file in $(find $DISTROOT -name '*.debug' \( -type l -or -type f \)); do - DEST=${file/$DISTROOT/$DEBUGROOT} - mkdir -p "$(dirname $DEST)" - sudo mv "$file" "$DEST" - done - sudo mv $DISTROOT QGIS-Portable - zip -r qgis-portable-win64.zip QGIS-Portable - (cd $DEBUGROOT && zip -r - *) > qgis-portable-win64-debugsym.zip - - - name: Upload QGIS for Windows 64bit - uses: actions/upload-artifact@v2.2.2 - with: - name: QGIS for Windows 64bit - path: qgis-portable-win64.zip - - - name: Upload QGIS for Windows 64bit Debug Symbols - uses: actions/upload-artifact@v2.2.2 - with: - name: QGIS for Windows 64bit Debug Symbols - path: qgis-portable-win64-debugsym.zip diff --git a/.github/workflows/ogc.yml b/.github/workflows/ogc.yml deleted file mode 100644 index 101b804599f7..000000000000 --- a/.github/workflows/ogc.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: 🗺 OGC tests for QGIS Server - -on: - push: - branches: - - master - - release-** - paths: - - 'src/core/**' - - 'src/auth/**' - - 'src/providers/**' - - 'src/server/**' - - 'src/CMakeLists.txt' - - 'external/**' - - 'CMakeLists.txt' - - '.github/workflows/ogc.yml' - pull_request: - branches: - - master - - release-** - paths: - - 'src/core/**' - - 'src/auth/**' - - 'src/providers/**' - - 'src/server/**' - - 'src/CMakeLists.txt' - - 'external/**' - - 'CMakeLists.txt' - - '.github/workflows/ogc.yml' - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@master - - - name: Setup build dependencies - run: | - docker build -t qgis_server_deps -f .ci/ogc/Dockerfile .ci/ogc/ - - - name: Run build - run: | - docker run -v $(pwd):/usr/src/qgis qgis_server_deps /usr/src/qgis/.ci/ogc/build.sh - - - name: Install pyogctest - run: | - sudo apt-get install python3-virtualenv virtualenv git - git clone https://github.com/pblottiere/pyogctest - cd pyogctest && git checkout 1.0.2 && cd - - virtualenv -p /usr/bin/python3 venv && source venv/bin/activate && pip install -e pyogctest/ - - - name: Download WMS 1.3.0 dataset - run: | - source venv/bin/activate && ./pyogctest/pyogctest.py -s wms130 -w - - - name: Run WMS 1.3.0 OGC tests - run: | - docker-compose -f .ci/ogc/docker-compose.yml up -d - source venv/bin/activate && ./pyogctest/pyogctest.py -n ogc_qgis -s wms130 -v -u http://$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' qgis_server_nginx)/qgisserver diff --git a/.github/workflows/pr-auto-milestone.yml b/.github/workflows/pr-auto-milestone.yml deleted file mode 100644 index ce64b1bfc7f5..000000000000 --- a/.github/workflows/pr-auto-milestone.yml +++ /dev/null @@ -1,141 +0,0 @@ -name: 📅 Auto set milestone on PR - -on: - pull_request_target: - types: - - opened - -env: - QGIS_MAJOR_VERSION: 3 - -jobs: - pr-without-milestones: - runs-on: ubuntu-latest - if: github.repository == 'qgis/QGIS' - steps: - # list the tags and milestones - - uses: octokit/graphql-action@v2.x - id: graphql_request - with: - query: | - query { - repository(owner: "qgis", name: "QGIS") { - pullRequests(states: OPEN, last: 100) { - edges { - node { - number - title - milestone { - number - } - baseRef { - name - } - } - } - } - milestones(orderBy: {field: CREATED_AT, direction: DESC}, first: 50) { - edges { - node { - title - number - } - } - } - refs(refPrefix: "refs/tags/", orderBy: {field: TAG_COMMIT_DATE, direction: DESC}, first: 30) { - edges { - node { - name - } - } - } - } - } - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # take the first unprocessed PR and determine if some remain - - name: Filter PR to check - id: extract_data - env: - JSON_DATA: ${{ steps.graphql_request.outputs.data }} - run: | - # get PRs without milestones - PRS_TO_PROCESS=$(echo "${JSON_DATA}" | jq '.repository.pullRequests.edges[] | select( .node.milestone.number | not ) | .node.number') - - NUMBER_OF_PRS=$(echo "${PRS_TO_PROCESS}" | jq -s '. | length') - echo "NUMBER_OF_PRS: ${NUMBER_OF_PRS}" - # early exit - [[ ${NUMBER_OF_PRS} == 0 ]] && echo "::set-output name=has_milestone_to_set::0" && exit 0 - - # Take the first - PR_NUMBER=$(echo "${PRS_TO_PROCESS}" | jq -s '. | first') - echo "PR_NUMBER: ${PR_NUMBER}" - - # Not used for now - RE_RUN_JOB=$(echo "${JSON_DATA}" | jq -s '. | length > 1') - echo "RE_RUN_JOB: ${RE_RUN_JOB}" - - # Get the base branch - BASE_BRANCH=$(echo "${JSON_DATA}" | jq -r ".repository.pullRequests.edges[] | select( .node.number == ${PR_NUMBER} ) | .node.baseRef.name") - echo "BASE_BRANCH: ${BASE_BRANCH}" - - # master => NOTHING, release_3-10 => _10 - MINOR_VERSION=$(echo ${BASE_BRANCH} | sed -r -e 's/^release-[0-9]_([0-9]+)/_\1/;t;d') - echo "MINOR_VERSION: ${MINOR_VERSION}" - - # get the max release from the tags - MAX_RELEASE=$(echo "${JSON_DATA}" | jq ".repository.refs.edges[].node.name | select( . | test(\"^final-${QGIS_MAJOR_VERSION}${MINOR_VERSION}\") ) | sub(\"^final-${QGIS_MAJOR_VERSION}_(?[0-9]+)_(?

    .)\"; .m+\".\"+.p) | tonumber" | jq -s '. | max') - echo "MAX_RELEASE: ${MAX_RELEASE}" - - # increase the number to get milestone: round+2 for master, +0.1 for release_xxx branches - INCREASE_OPERATION=$([[ -z ${MINOR_VERSION} ]] && echo "${MAX_RELEASE%.*} + 2.0" || echo "${MAX_RELEASE} + 0.1" ) - echo "INCREASE_OPERATION: ${INCREASE_OPERATION}" - MILESTONE_TITLE="${QGIS_MAJOR_VERSION}."$(echo "${INCREASE_OPERATION}" | bc) - echo "MILESTONE_TITLE: ${MILESTONE_TITLE}" - - MILESTONE_NUMBER=$(echo "${JSON_DATA}" | jq ".repository.milestones.edges[] | select( .node.title == \"${MILESTONE_TITLE}\" ) | .node.number") - echo "MILESTONE_NUMBER: ${MILESTONE_NUMBER}" - - HAS_MILESTONE_TO_CREATE=$([[ -z ${MILESTONE_NUMBER} ]] && echo "1" || echo "0" ) - echo "HAS_MILESTONE_TO_CREATE: ${HAS_MILESTONE_TO_CREATE}" - - echo "::set-output name=has_milestone_to_set::1" - echo "::set-output name=pr_number::${PR_NUMBER}" - echo "::set-output name=milestone_title::${MILESTONE_TITLE}" - echo "::set-output name=milestone_number::${MILESTONE_NUMBER}" - echo "::set-output name=has_milestone_to_create::${HAS_MILESTONE_TO_CREATE}" - - # create the milestone if needed - - name: Create milestone if needed - id: create_milestone - if: steps.extract_data.outputs.has_milestone_to_set == 1 && steps.extract_data.outputs.has_milestone_to_create == 1 - uses: octokit/request-action@v2.x - with: - route: POST /repos/qgis/QGIS/milestones - title: ${{ steps.extract_data.outputs.milestone_title }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # Compute the milestone number - - name: Compute milestone number from existing or created - id: compute_milestone - if: always() && steps.extract_data.outputs.has_milestone_to_set == 1 - env: - MILESTONE_NUMBER_EXISTING: ${{ steps.extract_data.outputs.milestone_number }} - MILESTONE_NUMBER_CREATED_JSON: ${{ steps.create_milestone.outputs.data }} - run: | - FINAL_MILESTONE_NUMBER=$([[ -n ${MILESTONE_NUMBER_EXISTING} ]] && echo "${MILESTONE_NUMBER_EXISTING}" || echo $(echo "${MILESTONE_NUMBER_CREATED_JSON}" | jq .number )) - echo "FINAL_MILESTONE_NUMBER: ${FINAL_MILESTONE_NUMBER}" - echo "::set-output name=milestone_number::${FINAL_MILESTONE_NUMBER}" - - # update PR with milestone - - name: update PR milestone - if: steps.extract_data.outputs.has_milestone_to_set == 1 - uses: octokit/request-action@v2.x - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - route: PATCH /repos/qgis/QGIS/issues/:pull_number - pull_number: ${{ steps.extract_data.outputs.pr_number }} - milestone: ${{ steps.compute_milestone.outputs.milestone_number }} diff --git a/.github/workflows/pr-needs-documentation.yml b/.github/workflows/pr-needs-documentation.yml deleted file mode 100644 index 1a30cd3eb678..000000000000 --- a/.github/workflows/pr-needs-documentation.yml +++ /dev/null @@ -1,131 +0,0 @@ - -name: 📖 PR needs documentation - -# a message will be added to the PR to ping the author about her/his responsibility to handle the documentation issue -# an issue is automatically created in the QGIS-Documentation repository when the PR gets merged - -on: - pull_request_target: - types: - - opened - - closed - - labeled - -jobs: - ping-author-message: - if: github.event.action != 'closed' && github.event.label.name == 'Needs Documentation' - runs-on: ubuntu-latest - name: Write comment to ping author about the future creation of an issue in docs - steps: - - # write comment to ping the PR author - - name: Create comment - uses: peter-evans/create-or-update-comment@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - issue-number: ${{ github.event.pull_request.number }} - body: | - @${{ github.event.pull_request.user.login }} - This pull request has been tagged as **requiring documentation**. - - A documentation ticket will be opened at https://github.com/qgis/QGIS-Documentation **when this PR is merged**. - - **Please update the description** (not the comments) with helpful description and screenshot to help the work from documentors. - Also, any commit having [needs-doc] or [Needs Documentation] in will see its message pushed to the issue, so please be as verbose as you can. - - Thank you! - reactions: 'rocket' - - - create-doc-issue: - if: github.event.pull_request.merged && ( ( github.event.action == 'closed' && contains( github.event.pull_request.labels.*.name, 'Needs Documentation') ) || github.event.label.name == 'Needs Documentation' ) - runs-on: ubuntu-latest - name: Create issue on doc repo for labeled issue - steps: - - # transform the milestone (e.g. 3.10.4) to a doc label (3.10) - - name: QGIS milestone to Doc label - id: milestone2label - env: - MILESTONE: ${{ github.event.pull_request.milestone.title }} - run: | - LABEL=$(sed -r 's/^([[:digit:]]\.[[:digit:]]+)(\.[[:digit:]]+)?$/\1/' <<< ${MILESTONE}) - echo ${LABEL} - echo "::set-output name=label::${LABEL}" - # get the PR body - - # get the PR body - - name: Get PR body as JSON - id: get_pr_info - uses: octokit/request-action@v2.x - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - route: GET /repos/qgis/QGIS/pulls/:pull_number - pull_number: ${{ github.event.pull_request.number }} - - # extract body from json output - - name: Get PR body as text - id: get_pr_body - uses: gr2m/get-json-paths-action@v1.x - with: - json: ${{ steps.get_pr_info.outputs.data }} - body: "body" - - # get commits from the PR - - name: Get PR commits - uses: octokit/request-action@v2.x - id: get_pr_commits - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - route: GET /repos/qgis/QGIS/pulls/:pull_number/commits - pull_number: ${{ github.event.pull_request.number }} - - # extracts the matching commits - - name: Filter commits with \[needs?.doc(umentation)?s?\] - id: filtered_commits - env: - JSON_DATA: ${{ steps.get_pr_commits.outputs.data }} - run: | - COMMITS_MESSAGES=$(echo ${JSON_DATA} | jq '.[].commit.message | select( . |test("\\[(feature|needs?.doc(umentation)?s?)\\]"; "i")) | sub("\\[needs?.doc(umentation)?s?\\]"; "\n\n\n\n"; "i")') - echo "::set-output name=commits::$(echo ${COMMITS_MESSAGES} | tr -d '\n' )" - - # create the documentation issue - - name: Create Documentation issue - id: doc_issue - uses: maxkomarychev/oction-create-issue@v0.7.1 - with: - token: ${{ secrets.GH_TOKEN_BOT }} - owner: qgis - repo: QGIS-Documentation - title: ${{ format('{0} (Request in QGIS)', github.event.pull_request.title) }} - # do not modify the QGIS version, an action automatically creates a label in the doc repo - # this is not possible to set labels directly due to security reasons - # the token is in clear, so no rights are given to qgis-bot - body: | - ### Request for documentation - From pull request QGIS/qgis#${{ github.event.pull_request.number }} - Author: @${{ github.event.pull_request.user.login }} - QGIS version: ${{ steps.milestone2label.outputs.label }} - - **${{ github.event.pull_request.title }}** - - ### PR Description: - ${{ steps.get_pr_body.outputs.body }} - - ### Commits tagged with [need-docs] or [FEATURE] - ${{ steps.filtered_commits.outputs.commits }} - - # write comment to ping the PR author - - name: Create comment - uses: peter-evans/create-or-update-comment@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - issue-number: ${{ github.event.pull_request.number }} - body: | - @${{ github.event.pull_request.user.login }} - A documentation ticket has been opened at https://github.com/qgis/QGIS-Documentation/issues/${{ steps.doc_issue.outputs.number }} - It is **your** responsibility to visit this ticket and add as much detail as possible for the documentation team to correctly document this change. - Thank you! - reactions: 'rocket' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index ad8f98217d77..000000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: 🚀 Release - -on: - push: - tags: - - 'final-*_*_*' - -jobs: - build: - name: Create Release - runs-on: ubuntu-latest - steps: - - - name: Prepare release names - run: | - VERSION_CHANGELOG=$(echo ${{ github.ref }} | cut -d '-' -f 2 | cut -d '_' -f1,2 | sed 's/_/\./g') - echo "version_url=https://changelog.qgis.org/en/qgis/version/${VERSION_CHANGELOG}" >> $GITHUB_ENV - VERSION_NAME=$(echo ${{ github.ref }} | cut -d '-' -f 2 | sed 's/_/\./g') - echo "version_name=${VERSION_NAME}" >> $GITHUB_ENV - - - name: Create release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: ${{ env.version_name }} - body: ${{ env.version_url }} - draft: false - prerelease: false diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml deleted file mode 100644 index 306222aa0b39..000000000000 --- a/.github/workflows/run-tests.yml +++ /dev/null @@ -1,233 +0,0 @@ -name: 🧪 QGIS tests - -on: - push: - branches: - - master - - release-** - paths: - - 'src/**' - - 'external/**' - - 'python/**' - - 'tests/**' - - 'CMakeLists.txt' - - '.github/workflows/run-tests.yml' - - '.docker/**' - - '.ci/**' - pull_request: - branches: - - master - - release-** - # paths cannot be filtered on this workflow on pull request as it is a required one in the branch protection - # feature request and hacks: https://github.community/t/feature-request-conditional-required-checks/16761 - -jobs: - build: - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - GH_WORKSPACE: ${{ github.workspace }} # used in docker compose - DEFAULT_UBUNTU_BASE: '20.04' - RUN_FLAKY_TESTS: ${{ contains( github.event.pull_request.labels.*.name, 'run flaky tests') }} - - runs-on: ubuntu-latest - - strategy: - matrix: - # tests run on 20.04 (Qt 5.12), compile test on 20.10 (Qt 5.14) and 21.04 (Qt 5.15) - ubuntu-base: ['20.04', '20.10', '21.04'] - fail-fast: false - - outputs: - compile_outcome: ${{ steps.compile.outcome }} - tests_failing: ${{ steps.tests.outputs.TESTS_FAILING }} - cdash_url: ${{ steps.tests.outputs.CDASH_URL }} - runners_outcome: ${{ steps.runners.outcome }} - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set vars - env: - GITHUB_EVENT_NAME: ${{ github.event_name }} - GITHUB_REF: ${{ github.ref }} - GITHUB_PR_NUMBER: ${{github.event.number}} - UBUNTU_BASE: ${{ matrix.ubuntu-base }} - run: | - DOCKER_TAG=$(echo $( [[ ${GITHUB_EVENT_NAME} =~ ^pull_request$ ]] && echo ${GITHUB_BASE_REF} || echo ${GITHUB_REF##*/} ) | sed 's/^master$/latest/')$( [[ ${UBUNTU_BASE} != ${DEFAULT_UBUNTU_BASE} ]] && echo "_${UBUNTU_BASE}" || echo "" ) - CTEST_BUILD_NAME=$( [[ ${GITHUB_EVENT_NAME} =~ ^pull_request$ ]] && echo "PR${GITHUB_PR_NUMBER}" || echo ${GITHUB_REF##*/} )"_${GITHUB_SHA}" - [[ ${UBUNTU_BASE} == "20.04" ]] && PATCH_QT_3D=true || PATCH_QT_3D=false - # build w/o 3D for Qt 5.15 (many deprecation warnings) - [[ ${UBUNTU_BASE} == "21.04" ]] && WITH_3D=FALSE || WITH_3D=TRUE - echo "DOCKER_TAG=${DOCKER_TAG}" >> $GITHUB_ENV - echo "CTEST_BUILD_NAME=${CTEST_BUILD_NAME}" >> $GITHUB_ENV - echo "PATCH_QT_3D=${PATCH_QT_3D}" >> $GITHUB_ENV - echo "WITH_3D=${WITH_3D}" >> $GITHUB_ENV - - - name: Print vars - run: | - echo DOCKER_TAG: ${DOCKER_TAG} - echo CTEST_BUILD_NAME: ${CTEST_BUILD_NAME} - echo PATCH_QT_3D: ${PATCH_QT_3D} - echo WITH_3D: ${WITH_3D} - - - name: Build deps - env: - UBUNTU_BASE: ${{ matrix.ubuntu-base }} - run: | - pushd .docker - docker pull qgis/qgis3-build-deps:${DOCKER_TAG} || true - docker build --build-arg UBUNTU_BASE=${UBUNTU_BASE} --cache-from qgis/qgis3-build-deps:${DOCKER_TAG} -t qgis/qgis3-build-deps:${DOCKER_TAG} -f qgis3-build-deps.dockerfile . - popd - - - name: Push deps image - if: ${{ github.event_name != 'pull_request' }} - run: | - docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}" - docker push "qgis/qgis3-build-deps:${DOCKER_TAG}" - - - name: Prepare build cache for pull request - uses: pat-s/always-upload-cache@v2.1.3 - if: github.event_name == 'pull_request' - with: - path: /home/runner/QGIS/.ccache - key: build-ccache-${{ matrix.ubuntu-base }}-${{ github.actor }}-${{ github.head_ref }}-${{ github.sha }} - # The head_ref or source branch of the pull request in a workflow run. - # The base_ref or target branch of the pull request in a workflow run. - restore-keys: | - build-ccache-${{ matrix.ubuntu-base }}-${{ github.actor }}-${{ github.head_ref }}- - build-ccache-${{ matrix.ubuntu-base }}-refs/heads/${{ github.base_ref }}- - build-ccache-${{ matrix.ubuntu-base }}-refs/heads/master- - - - name: Prepare build cache for branch/tag - # use a fork of actions/cache@v2 to upload cache even when the build or test failed - uses: pat-s/always-upload-cache@v2.1.3 - if: github.event_name != 'pull_request' - with: - path: /home/runner/QGIS/.ccache - # The branch or tag ref that triggered the workflow run. For branches this in the format refs/heads/, and for tags it is refs/tags/ - key: build-ccache-${{ matrix.ubuntu-base }}-${{ github.ref }}-${{ github.sha }} - restore-keys: | - build-ccache-${{ matrix.ubuntu-base }}-${{ github.ref }}- - build-ccache-${{ matrix.ubuntu-base }}-refs/heads/master- - - - name: Compile QGIS - id: compile - run: | - docker run -t --name qgis_container \ - -v $(pwd):/root/QGIS \ - -v /home/runner/QGIS/.ccache:/root/.ccache \ - --env-file .docker/docker-variables.env \ - --env PUSH_TO_CDASH=true \ - --env WITH_3D=${WITH_3D} \ - qgis/qgis3-build-deps:${DOCKER_TAG} \ - /root/QGIS/.docker/docker-qgis-build.sh - docker commit qgis_container qgis_image - - - name: Push image - if: github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'Push Docker Image') - env: - GITHUB_PR_NUMBER: ${{github.event.number}} - run: | - docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}" - docker commit qgis_container qgis/qgis-pr-build:PR${GITHUB_PR_NUMBER} - docker push qgis/qgis-pr-build:PR${GITHUB_PR_NUMBER} - - - name: Run unit tests - id: tests - if: ${{ matrix.ubuntu-base == env.DEFAULT_UBUNTU_BASE }} - run: docker-compose -f .docker/docker-compose-testing.yml run qgis-deps /root/QGIS/.docker/docker-qgis-test.sh - -# - name: Test QGIS runners -# id: runners -# if: ${{ matrix.ubuntu-base == env.DEFAULT_UBUNTU_BASE }} -# run: | -# docker run -d --name qgis-testing-environment \ -# -v $(pwd):/root/QGIS \ -# -v $(pwd)/tests/src/python:/tests_directory \ -# -v $(pwd)/.docker/qgis_resources/test_runner:/usr/bin/test_runner \ -# -v $(pwd)/.docker/qgis_resources/supervisor:/etc/supervisor \ -# -e QGIS_BUILD_PATH=/root/QGIS/build/output/bin/qgis \ -# -e TEST_RUNNER_PATH=/usr/bin/test_runner/qgis_testrunner.py \ -# -e DISPLAY=:99 \ -# qgis_image \ -# /usr/bin/supervisord -c /etc/supervisor/supervisord.conf -# # Wait for xvfb to finish starting -# printf "Waiting for the docker...🐳..." -# sleep 10 -# echo " done 🥩" -# -# declare -A testrunners -# # Passing cases: -# testrunners["test_testrunner.run_passing"]=0 -# testrunners["test_testrunner.run_skipped_and_passing"]=0 -# # Failing cases: -# testrunners["test_testrunner"]=1 -# testrunners["test_testrunner.run_all"]=1 -# testrunners["test_testrunner.run_failing"]=1 -# set +e # do not exit on error -# # Run tests in the docker -# for i in "${!testrunners[@]}" -# do -# echo "::group::docker_test_runner_${i}" -# echo "test ${i}..." -# docker exec -i qgis-testing-environment sh -c "cd /tests_directory && /usr/bin/test_runner/qgis_testrunner.sh ${i}" -# [[ $? -eq "${testrunners[$i]}" ]] && echo "success" || exit 1 -# echo "::endgroup::" -# done -# set -e # switch back -# docker stop qgis-testing-environment - - -# tests-report-comment: -# name: Write tests report in a comment -# needs: build -# runs-on: ubuntu-latest -# if: always() && ( needs.build.result == 'failure' || needs.build.result == 'success' ) && github.event_name == 'pull_request' -# steps: -# - name: Find Comment -# uses: peter-evans/find-comment@v1 -# id: find-comment -# with: -# issue-number: ${{ github.event.pull_request.number }} -# comment-author: 'github-actions[bot]' -# body-includes: Tests report -# -# - name: Create comment -# if: ${{ steps.find-comment.outputs.comment-id == 0 }} -# uses: peter-evans/create-or-update-comment@v1 -# id: create-comment -# with: -# issue-number: ${{ github.event.pull_request.number }} -# body: | -# **Tests report** -# -# - name: Process -# id: process-vars -# env: -# COMMENT_FOUND: ${{ steps.find-comment.outputs.comment-id }} -# COMMENT_CREATED: ${{ steps.create-comment.outputs.comment-id }} -# COMMIT_SHA: ${{ github.event.pull_request.head.sha }} -# CDASH_URL: ${{ needs.build.outputs.cdash_url }} -# COMPILE_OUTCOME: ${{ needs.build.outputs.compile_outcome }} -# TESTS_FAILING: ${{ needs.build.outputs.tests_failing }} -# RUNNERS_OUTCOME: ${{ needs.build.outputs.runners_outcome }} -# run: | -# echo "::set-output name=COMMENT_ID::"$([[ "${COMMENT_FOUND}" -eq "0" ]] && echo ${COMMENT_CREATED} || echo ${COMMENT_FOUND}) -# if [[ ${COMPILE_OUTCOME} != "success" ]]; then -# echo "::set-output name=COMMENT_BODY::${COMMIT_SHA} :scream: compilation failed" -# elif [[ ${TESTS_FAILING} != "0" ]]; then -# echo "::set-output name=COMMENT_BODY::${COMMIT_SHA} :fire: ${TESTS_FAILING} unit-tests are failing ${CDASH_URL}" -# elif [[ ${RUNNERS_OUTCOME} != "success" ]]; then -# echo "::set-output name=COMMENT_BODY::${COMMIT_SHA} :broken_heart: QGIS runners test failed" -# else -# echo "::set-output name=COMMENT_BODY::${COMMIT_SHA} :sunglasses: unit-tests succeeded" -# fi -# -# - name: Update comment -# uses: peter-evans/create-or-update-comment@v1 -# with: -# comment-id: ${{ steps.process-vars.outputs.COMMENT_ID }} -# edit-mode: append -# body: ${{ steps.process-vars.outputs.COMMENT_BODY }} diff --git a/.github/workflows/stale_issues.yml b/.github/workflows/stale_issues.yml deleted file mode 100644 index 2f505385e06e..000000000000 --- a/.github/workflows/stale_issues.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: 👓 Handle stale issues -on: - schedule: - - cron: "30 1 * * *" - -jobs: - stale: - if: github.repository_owner == 'qgis' - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: > - The QGIS project highly values your report and would love to see it addressed. - However, this issue has been left in feedback mode for the last 14 days and is - being automatically marked as "stale". - - If you would like to continue with this issue, please provide any missing information - or answer any open questions. If you could resolve the issue yourself meanwhile, - please leave a note for future readers with the same problem and close the issue. - - In case you should have any uncertainty, please leave a comment and we will be - happy to help you proceed with this issue. - - If there is no further activity on this issue, it will be closed in a week. - - - close-issue-message: > - While we hate to see this happen, this issue has been automatically closed because - it has not had any activity in the last 42 days despite being marked as feedback. - If this issue should be reconsidered, please follow the guidelines in the previous - comment and reopen this issue. - - Or, if you have any further questions, there are also - [further support channels](https://www.qgis.org/en/site/forusers/support.html) - that can help you. - - - stale-issue-label: 'stale' - only-labels: 'feedback' - days-before-stale: 14 - days-before-close: 28 diff --git a/.github/workflows/stale_pr.yml b/.github/workflows/stale_pr.yml deleted file mode 100644 index b04a8f8ff0cd..000000000000 --- a/.github/workflows/stale_pr.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: 👓 Handle stale pull requests -on: - schedule: - - cron: "30 2 * * *" - -jobs: - stale: - if: github.repository_owner == 'qgis' - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-pr-message: > - The QGIS project highly values your contribution and would love to see - this work merged! - Unfortunately this PR has not had any activity in the last 14 days and - is being automatically marked as "stale". - If you think this pull request should be merged, please check - - - that all unit tests are passing - - - that all comments by reviewers have been addressed - - - that there is enough information for reviewers, in particular - - - link to any issues which this pull request fixes - - - add a description of workflows which this pull request fixes - - - add screenshots if applicable - - - that you have written unit tests where possible - - In case you should have any uncertainty, please leave a comment and we will - be happy to help you proceed with this pull request. - - If there is no further activity on this pull request, it will be closed in a - week. - - - close-pr-message: > - While we hate to see this happen, this PR has been automatically closed because - it has not had any activity in the last 21 days. If this pull request should be - reconsidered, please follow the guidelines in the previous comment and reopen - this pull request. Or, if you have any further questions, just ask! We love to - help, and if there's anything the QGIS project can do to help push this PR forward - please let us know how we can assist. - - - stale-pr-label: 'stale' - exempt-pr-labels: 'Merge After Thaw' - days-before-stale: 14 - days-before-close: 7 diff --git a/.github/workflows/unstale.yml b/.github/workflows/unstale.yml deleted file mode 100644 index 5c9eaf26303e..000000000000 --- a/.github/workflows/unstale.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: Remove Labels - -on: [issue_comment] - -jobs: - remove_labels: - if: contains(github.event.issue.labels.*.name, 'stale') - runs-on: ubuntu-latest - steps: - - uses: actions-ecosystem/action-remove-labels@v1 - if: ${{ github.event.comment.user.url != 'https://github.com/apps/github-actions' }} - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - labels: | - stale From e0df35101d43bc0d59a326f751a20d45df560f44 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 13:02:21 +1000 Subject: [PATCH 190/377] Fix capitalisation --- src/native/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/CMakeLists.txt b/src/native/CMakeLists.txt index 4cd1ae384a44..8b4c3daced7f 100644 --- a/src/native/CMakeLists.txt +++ b/src/native/CMakeLists.txt @@ -11,7 +11,7 @@ set(NATIVE_LINK_LIBS) if(UNIX AND NOT APPLE AND NOT ANDROID) if (WITH_QT6) - find_package(Qt6 COMPONENTS Dbus REQUIRED) + find_package(Qt6 COMPONENTS DBus REQUIRED) else() find_package(Qt5DBus REQUIRED) endif() From aafa6f9bad1ea4959c1e30011073a991ac4cb510 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 13:11:29 +1000 Subject: [PATCH 191/377] Cleanups --- CMakeLists.txt | 63 +++++++++++--------------------------------------- 1 file changed, 14 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c81eedc0f528..d49e55b2e3a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -436,67 +436,41 @@ if(WITH_CORE) set (WITH_QT6 FALSE CACHE BOOL "Enable (broken, experimental) Qt6 support") if (WITH_QT6) set(QT_MIN_VERSION 6.0.0) + set(QT_VERSION_BASE "Qt6") else() set(QT_MIN_VERSION 5.12.0) + set(QT_VERSION_BASE "Qt5") endif() # Use Qt5SerialPort optionally for GPS set (WITH_QT5SERIALPORT TRUE CACHE BOOL "Determines whether Qt5SerialPort should be tried for GPS positioning") if (WITH_QT5SERIALPORT) - if (WITH_QT6) - find_package(Qt6 COMPONENTS SerialPort REQUIRED) - else() - find_package(Qt5 COMPONENTS SerialPort REQUIRED) - endif() + find_package(${QT_VERSION_BASE} COMPONENTS SerialPort REQUIRED) # following variable is used in qgsconfig.h set (HAVE_QT5SERIALPORT TRUE) endif() - if (WITH_QT6) - find_package(Qt6 COMPONENTS Core Gui Widgets Network Xml Svg Concurrent Test UiTools Sql REQUIRED) - else() - find_package(Qt5 COMPONENTS Core Gui Widgets Network Xml Svg Concurrent Test UiTools Sql REQUIRED) - endif() + find_package(${QT_VERSION_BASE} COMPONENTS Core Gui Widgets Network Xml Svg Concurrent Test UiTools Sql REQUIRED) if (NOT IOS) - if (WITH_QT6) - find_package(Qt6 COMPONENTS PrintSupport REQUIRED) - else() - find_package(Qt5 COMPONENTS PrintSupport REQUIRED) - endif() + find_package(${QT_VERSION_BASE} COMPONENTS PrintSupport REQUIRED) else() add_definitions(-DQT_NO_PRINTER) endif() - if (WITH_QT6) - find_package(Qt6 COMPONENTS Positioning) - else() - find_package(Qt5 COMPONENTS Positioning) - endif() + find_package(${QT_VERSION_BASE} COMPONENTS Positioning) if (WITH_QTWEBKIT AND NOT WITH_QT6) find_package(Qt5WebKit REQUIRED) find_package(Qt5WebKitWidgets REQUIRED) endif() if (WITH_3D) - if (WITH_QT6) - find_package(Qt6 COMPONENTS 3DCore 3DRender 3DInput 3DLogic 3DExtras REQUIRED) - else() - find_package(Qt5 COMPONENTS 3DCore 3DRender 3DInput 3DLogic 3DExtras REQUIRED) - endif() + find_package(${QT_VERSION_BASE} COMPONENTS 3DCore 3DRender 3DInput 3DLogic 3DExtras REQUIRED) set(HAVE_3D TRUE) # used in qgsconfig.h endif() if (APPLE) - if (WITH_QT6) - find_package(Qt6 COMPONENTS MacExtras REQUIRED) - else() - find_package(Qt6 COMPONENTS MacExtras REQUIRED) - endif() + find_package(${QT_VERSION_BASE} COMPONENTS MacExtras REQUIRED) endif() # get the Qt plugins directory - if (WITH_QT6) - get_target_property(QMAKE_EXECUTABLE Qt6::qmake LOCATION) - else() - get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION) - endif() + get_target_property(QMAKE_EXECUTABLE ${QT_VERSION_BASE}::qmake LOCATION) EXEC_PROGRAM(${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_PLUGINS" RETURN_VALUE return_code OUTPUT_VARIABLE DEFAULT_QT_PLUGINS_DIR ) set (QT_PLUGINS_DIR ${DEFAULT_QT_PLUGINS_DIR} CACHE STRING "Path to installation directory for Qt Plugins. Defaults to Qt native plugin directory") @@ -507,20 +481,11 @@ if(WITH_CORE) message(STATUS "Found Qt version: ${Qt5Core_VERSION_STRING}") endif() if (WITH_QUICK) - if (WITH_QT6) - find_package(Qt6 COMPONENTS Qml Quick REQUIRED) - if(${CMAKE_SYSTEM_NAME} MATCHES "Android") - find_package(Qt6 COMPONENTS AndroidExtras) - else() - find_package(QtQmlTools) - endif() + find_package(${QT_VERSION_BASE} COMPONENTS Qml Quick REQUIRED) + if(${CMAKE_SYSTEM_NAME} MATCHES "Android") + find_package(${QT_VERSION_BASE} COMPONENTS AndroidExtras) else() - find_package(Qt5 COMPONENTS Qml Quick REQUIRED) - if(${CMAKE_SYSTEM_NAME} MATCHES "Android") - find_package(Qt5 COMPONENTS AndroidExtras) - else() - find_package(QtQmlTools) - endif() + find_package(QtQmlTools) endif() # following variable is used in qgsconfig.h @@ -977,7 +942,7 @@ endif() ############################################################# # Python bindings -if (WITH_CORE AND WITH_BINDINGS) +if (WITH_CORE AND WITH_BINDINGS AND NOT WITH_QT6) # python support: check for interpreter, sip, pyqt5 find_package(PyQt5 REQUIRED) set(PYQT_SIP_FLAGS ${PYQT5_SIP_FLAGS}) From 98f270e2805d524458d8a93e9fb3f60f160cda88 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 13:15:43 +1000 Subject: [PATCH 192/377] Revert "Remove other workflows temporarily" This reverts commit 49962230dd1c87e0ef53e0ee900f89f9316512ca. --- .github/workflows/backport.yml | 18 ++ .github/workflows/build-docker.yml | 157 +++++++++++++ .github/workflows/code_layout.yml | 218 +++++++++++++++++ .github/workflows/flake8.yml | 28 +++ .github/workflows/macos-build.yml | 156 +++++++++++++ .github/workflows/mingw64.yml | 110 +++++++++ .github/workflows/ogc.yml | 60 +++++ .github/workflows/pr-auto-milestone.yml | 141 +++++++++++ .github/workflows/pr-needs-documentation.yml | 131 +++++++++++ .github/workflows/release.yml | 31 +++ .github/workflows/run-tests.yml | 233 +++++++++++++++++++ .github/workflows/stale_issues.yml | 43 ++++ .github/workflows/stale_pr.yml | 54 +++++ .github/workflows/unstale.yml | 15 ++ 14 files changed, 1395 insertions(+) create mode 100644 .github/workflows/backport.yml create mode 100644 .github/workflows/build-docker.yml create mode 100644 .github/workflows/code_layout.yml create mode 100644 .github/workflows/flake8.yml create mode 100644 .github/workflows/macos-build.yml create mode 100644 .github/workflows/mingw64.yml create mode 100644 .github/workflows/ogc.yml create mode 100644 .github/workflows/pr-auto-milestone.yml create mode 100644 .github/workflows/pr-needs-documentation.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/run-tests.yml create mode 100644 .github/workflows/stale_issues.yml create mode 100644 .github/workflows/stale_pr.yml create mode 100644 .github/workflows/unstale.yml diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 000000000000..493216253aa1 --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,18 @@ +name: ♻ Backport +on: + pull_request_target: + types: + - closed + - labeled + +jobs: + backport: + runs-on: ubuntu-18.04 + name: Backport + steps: + - name: Backport Bot + id: backport + if: github.event.pull_request.merged && ( ( github.event.action == 'closed' && contains( join( github.event.pull_request.labels.*.name ), 'backport') ) || contains( github.event.label.name, 'backport' ) ) + uses: m-kuhn/backport@v1.1.1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml new file mode 100644 index 000000000000..8048eb23c497 --- /dev/null +++ b/.github/workflows/build-docker.yml @@ -0,0 +1,157 @@ +name: 🐳 Build Docker images for current branches + +# on commits to this file, schedule and dispatch runs, the workflow will build the 3 different Docker images (master, PR, LTR) +# on tags, it will build only the image of the given tag +# this is made by using a matrix defined in a dedicated job +on: + push: + tags: + - final-* + branches: + - master + paths: + - .github/workflows/build-docker.yml + schedule: + # runs every day + - cron: '0 0 * * *' + workflow_dispatch: + # POST https://api.github.com/repos/qgis/QGIS/actions/workflows/2264135/dispatches: + +jobs: + define-strategy: + if: github.repository_owner == 'qgis' + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.matrix.outputs.matrix }} + steps: + - id: matrix + run: | + if [[ "${GITHUB_REF}" =~ ^refs/tags ]]; then + echo "::set-output name=matrix::{\"branch\":[\"${GITHUB_REF##*/}\"]}" + else + echo "::set-output name=matrix::{\"branch\":[\"master\", \"release-3_16\", \"release-3_18\"]}" + fi + + build-docker: + if: github.repository_owner == 'qgis' + runs-on: ubuntu-latest + needs: define-strategy + + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + GH_TOKEN: ${{ secrets.GH_TOKEN }} + CC: /usr/lib/ccache/gcc + CXX: /usr/lib/ccache/g++ # Building SIP binding freezes with Clang in Docker, maybe a SIP issue, maybe not + DOCKER_BUILD_DEPS_FILE: qgis3-build-deps.dockerfile + + strategy: + matrix: ${{ fromJSON( needs.define-strategy.outputs.matrix ) }} + + steps: + - name: Cache + id: cache + uses: actions/cache@v2.1.4 + with: + path: ~/.ccache + key: docker-build-${{ matrix.branch }}-${{ github.sha }} + restore-keys: | + docker-build-${{ matrix.branch }}- + docker-build-master- + + - name: checkout ${{ matrix.branch }} + uses: actions/checkout@v2 + with: + ref: ${{ matrix.branch }} + + - name: Define vars + env: + branch: ${{ matrix.branch }} + run: | + export DOCKER_TAG=${branch//master/latest} + export DOCKER_DEPS_TAG=${DOCKER_TAG} + + # add vars for next steps + echo "DOCKER_TAG=${DOCKER_TAG}" >> $GITHUB_ENV + echo "DOCKER_DEPS_TAG=${DOCKER_DEPS_TAG}" >> $GITHUB_ENV + + echo "branch: ${branch}" + echo "docker tag: ${DOCKER_TAG}" + echo "docker deps tag: ${DOCKER_DEPS_TAG}" + + - name: Copy cache + run: | + [[ -d ~/.ccache ]] && echo "cache directory (~/.ccache) exists" || mkdir -p ~/.ccache + # copy ccache dir within QGIS source so it can be accessed from docker + cp -r ~/.ccache/. ./.ccache_image_build + + - name: QGIS deps Docker pull/rebuild + run: | + cd .docker + docker --version + docker pull "qgis/qgis3-build-deps:${DOCKER_DEPS_TAG}" || true + docker build --cache-from "qgis/qgis3-build-deps:${DOCKER_DEPS_TAG}" -t "qgis/qgis3-build-deps:${DOCKER_DEPS_TAG}" -f ${DOCKER_BUILD_DEPS_FILE} . + echo "push to qgis/qgis3-build-deps:${DOCKER_DEPS_TAG}" + docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" + docker push "qgis/qgis3-build-deps:${DOCKER_DEPS_TAG}" + + - name: Docker QGIS build + run: | + cd .docker + DOCKER_BUILD_ARGS="--build-arg DOCKER_DEPS_TAG --build-arg CC --build-arg CXX" + docker build ${DOCKER_BUILD_ARGS} \ + --cache-from "qgis/qgis:${DOCKER_TAG}" \ + -t "qgis/qgis:BUILDER" \ + -f qgis.dockerfile .. + + - name: Tag container and copy cache + run: | + docker run --name qgis_container qgis/qgis:BUILDER /bin/true + docker cp qgis_container:/QGIS/build_exit_value ./build_exit_value + + if [[ $(cat ./build_exit_value) != "OK" ]]; then + echo "Build failed, not pushing image" + exit 1 + fi + + echo "Copy build cache from Docker container to Travis cache directory" + rm -rf ~/.ccache/* + mkdir -p ~/.ccache + docker cp qgis_container:/QGIS/.ccache_image_build/. ~/.ccache + echo "Cache size: "$(du -sh ~/.ccache) + + - name: Finalize image + run: | + cd .docker + # enable experimental features in Docker to squash + echo '{ "experimental": true}' | sudo tee /etc/docker/daemon.json + sudo service docker restart + docker build ${DOCKER_BUILD_ARGS} \ + --cache-from "qgis/qgis:BUILDER" \ + --squash \ + -t "qgis/qgis:${DOCKER_TAG}" \ + -f qgis.dockerfile .. + + - name: Pushing image to docker hub + run: | + docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" + docker push "qgis/qgis:${DOCKER_TAG}" + + - name: Trigger PyQGIS API docs build for ${{ matrix.branch }} + if: success() && !startsWith(github.ref, 'refs/tags/') + env: + branch: ${{ matrix.branch }} + run: | + body='{ + "ref": "master", + "inputs": {"qgis_branch": "__QGIS_VERSION_BRANCH__"} + }' + body=$(sed "s/__QGIS_VERSION_BRANCH__/${branch}/;" <<< $body) + curl -X POST \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: token ${GH_TOKEN}" \ + https://api.github.com/repos/qgis/pyqgis/actions/workflows/2246440/dispatches \ + -d "${body}" + + + diff --git a/.github/workflows/code_layout.yml b/.github/workflows/code_layout.yml new file mode 100644 index 000000000000..bd10d111386b --- /dev/null +++ b/.github/workflows/code_layout.yml @@ -0,0 +1,218 @@ +name: 🧹 Code Layout + +on: + push: + branches: + - master + - release-** + pull_request: + +jobs: + documentation_checks: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python 3.7 + uses: actions/setup-python@v2.2.1 + with: + python-version: 3.7 + - name: Install Requirements + run: | + sudo apt install -y \ + doxygen \ + cpanminus \ + libyaml-tiny-perl \ + libio-socket-ssl-perl \ + libhttp-date-perl \ + libgetopt-long-descriptive-perl \ + libmoo-perl \ + libnamespace-clean-perl \ + libpath-tiny-perl \ + libpod-constants-perl \ + libscalar-list-utils-perl \ + libsort-key-perl \ + libstrictures-perl \ + libstring-escape-perl \ + libtry-tiny-perl \ + expect + cpanm --notest App::Licensecheck + python -m pip install --upgrade pip + pip install autopep8 nose2 mock termcolor + - name: Make + run: | + mkdir build + cd build + cmake -DWITH_SERVER=ON -DUSE_CCACHE=OFF -DWITH_CORE=OFF -DWITH_APIDOC=ON -DWITH_ASTYLE=ON -DENABLE_TESTS=ON -DWITH_DOT=NO -DWERROR=ON .. + make -j3 apidoc + - name: Run Tests + run: cd build && ctest -V -R PyQgsDocCoverage + + license_check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install Requirements + run: | + sudo apt install -y \ + cpanminus + cpanm --notest App::Licensecheck + + - name: Run License Check + run: ./tests/code_layout/test_licenses.sh + + shell_check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install Requirements + run: | + sudo apt install -y \ + shellcheck + + - name: Run Shellcheck + run: ./tests/code_layout/test_shellcheck.sh + + banned_keywords_check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Run Banned Keywords Test + run: ./tests/code_layout/test_banned_keywords.sh + + def_window_title_check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Def Window Title Test + run: ./tests/code_layout/test_defwindowtitle.sh + + qvariant_no_brace_init: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: No brace initialization of QVariant variables + run: ./tests/code_layout/test_qvariant_no_brace_init.sh + + qt_module_wide_imports: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: No module-wide imports of Qt modules + run: ./tests/code_layout/test_qt_imports.sh + + doxygen_layout_check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install Requirements + run: | + sudo apt install -y \ + expect \ + silversearcher-ag + - name: Doxygen Layout Test + run: ./tests/code_layout/test_doxygen_layout.sh + + indentation_check: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 100 + - name: Install Requirements + run: | + sudo apt install -y \ + astyle \ + python3-autopep8 \ + flip + - name: Indentation Test + run: ./scripts/verify_indentation.sh HEAD~1 + + spell_check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install Requirements + run: | + sudo apt install -y \ + expect \ + silversearcher-ag + - uses: trilom/file-changes-action@v1.2.4 + id: changed_files + with: + output: ' ' + githubToken: ${{ secrets.GITHUB_TOKEN }} + - name: Spell Test + run: ./scripts/spell_check/check_spelling.sh -r ${{ steps.changed_files.outputs.files_modified }} ${{ steps.changed_files.outputs.files_added }} + + sip_check: + runs-on: ubuntu-latest + steps: + - name: Set up Python 3.7 + uses: actions/setup-python@v2.2.1 + with: + python-version: 3.7 + - name: Install Requirements + run: | + sudo apt install -y \ + cpanminus \ + libyaml-tiny-perl \ + libio-socket-ssl-perl \ + libhttp-date-perl \ + libgetopt-long-descriptive-perl \ + libmoo-perl \ + libnamespace-clean-perl \ + libpath-tiny-perl \ + libpod-constants-perl \ + libscalar-list-utils-perl \ + libsort-key-perl \ + libstrictures-perl \ + libstring-escape-perl \ + libtry-tiny-perl \ + expect + python -m pip install --upgrade pip + pip install autopep8 nose2 mock termcolor + - name: Checkout + uses: actions/checkout@v2 + - name: Sip Checks + run: ./tests/code_layout/test_sipify.sh + - name: Sip Include Test + run: ./tests/code_layout/test_sip_include.sh + - name: Sip Files Up To Date + run: ./tests/code_layout/test_sipfiles.sh + + cppcheck_16_04: + runs-on: ubuntu-16.04 + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install Requirements + run: | + sudo apt install -y cppcheck + + - name: Run cppcheck test + run: ./scripts/cppcheck.sh + + cppcheck_18_04: + runs-on: ubuntu-18.04 + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install Requirements + run: | + sudo apt install -y cppcheck + + - name: Run cppcheck test + run: ./scripts/cppcheck.sh diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml new file mode 100644 index 000000000000..5a4305df275e --- /dev/null +++ b/.github/workflows/flake8.yml @@ -0,0 +1,28 @@ +name: ❄ Flake8 + +on: + push: + paths: + - '**.py' + pull_request: + paths: + - '**.py' + +jobs: + flake8_py3: + name: Python Lint + runs-on: ubuntu-latest + steps: + - name: Setup Python + uses: actions/setup-python@v2.2.1 + with: + python-version: 3.7 + architecture: x64 + - name: Checkout + uses: actions/checkout@v2 + - name: Run flake8 + uses: julianwachholz/flake8-action@v1.1.0 + with: + checkName: 'Python Lint' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/macos-build.yml b/.github/workflows/macos-build.yml new file mode 100644 index 000000000000..197d09b6976d --- /dev/null +++ b/.github/workflows/macos-build.yml @@ -0,0 +1,156 @@ +name: 🍏 Mac OS build +on: + push: + branches: + - master + - release-** + paths: + - 'src/**' + - 'external/**' + - 'python/**' + - 'tests/**' + - 'mac/**' + - '.github/workflows/macos-build.yml' + - '.ci/**' + - 'CMakeLists.txt' + pull_request: + branches: + - master + - release-** + paths: + - 'src/**' + - 'external/**' + - 'python/**' + - 'tests/**' + - 'mac/**' + - '.github/workflows/macos-build.yml' + - '.ci/**' + - 'CMakeLists.txt' + +env: + QT_VERSION: 5.14.2 + QGIS_DEPS_VERSION: 0.7.0 + CCACHE_DIR: /Users/runner/work/ccache + BUILD_DIR: /Users/runner/work/QGIS/build-QGIS + # apparently we cannot cache /opt directory as it fails to restore + # so we copy the deps in the home directory + DEPS_CACHE_DIR: /Users/runner/work/deps-cache + +jobs: + mac_os_build: + if: github.repository == 'qgis/QGIS' + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + + - name: Prepare build cache for pull request + uses: pat-s/always-upload-cache@v2.1.3 + if: github.event_name == 'pull_request' + with: + path: ${{ env.CCACHE_DIR }} + key: build-mac-ccache-${{ github.actor }}-${{ github.head_ref }}-${{ github.sha }} + # The head_ref or source branch of the pull request in a workflow run. + # The base_ref or target branch of the pull request in a workflow run. + restore-keys: | + build-mac-ccache-${{ github.actor }}-${{ github.head_ref }}- + build-mac-ccache-refs/heads/${{ github.base_ref }}- + build-mac-ccache-refs/heads/master- + + - name: Prepare build cache for branch/tag + # use a fork of actions/cache@v2 to upload cache even when the build or test failed + uses: pat-s/always-upload-cache@v2.1.3 + if: github.event_name != 'pull_request' + with: + path: ${{ env.CCACHE_DIR }} + # The branch or tag ref that triggered the workflow run. For branches this in the format refs/heads/, and for tags it is refs/tags/ + key: build-mac-ccache-${{ github.ref }}-${{ github.sha }} + restore-keys: | + build-mac-ccache-${{ github.ref }}- + build-mac-ccache-refs/heads/master- + + + # Qt caching + - name: Cache Qt + id: cache-qt + uses: pat-s/always-upload-cache@v2.1.3 + with: + path: ${{ env.DEPS_CACHE_DIR }}/Qt/${{ env.QT_VERSION }} + key: mac-qt-v4-${{ env.QT_VERSION }} + + - name: Restore Qt + if: steps.cache-qt.outputs.cache-hit == 'true' + run: | + sudo mkdir -p /opt + sudo mkdir -p /opt/Qt + sudo cp -r ${DEPS_CACHE_DIR}/Qt/${QT_VERSION} /opt/Qt/${QT_VERSION} + + - name: Download Qt + if: steps.cache-qt.outputs.cache-hit != 'true' + run: | + wget https://qgis.org/downloads/macos/deps/qt-${QT_VERSION}.tar.gz + mkdir -p ${DEPS_CACHE_DIR} + mkdir -p ${DEPS_CACHE_DIR}/Qt + + + # QGIS-deps caching + - name: Cache qgis-deps + id: cache-deps + uses: pat-s/always-upload-cache@v2.1.3 + with: + path: ${{ env.DEPS_CACHE_DIR }}/QGIS/qgis-deps-${{ env.QGIS_DEPS_VERSION }} + key: mac-qgis-deps-v4-${{ env.QGIS_DEPS_VERSION }} + + - name: Restore qgis-deps + if: steps.cache-deps.outputs.cache-hit == 'true' + run: | + sudo mkdir -p /opt + sudo mkdir -p /opt/QGIS + sudo cp -r ${DEPS_CACHE_DIR}/QGIS/qgis-deps-${QGIS_DEPS_VERSION} /opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION} + + - name: Download qgis-deps + if: steps.cache-deps.outputs.cache-hit != 'true' + run: | + wget https://qgis.org/downloads/macos/deps/qgis-deps-${QGIS_DEPS_VERSION}.tar.gz + mkdir -p ${DEPS_CACHE_DIR} + mkdir -p ${DEPS_CACHE_DIR}/QGIS + + + + - name: Install Qt and deps + env: + QT_ALREADY_CACHED: ${{ steps.cache-qt.outputs.cache-hit }} + QGIS_DEPS_ALREADY_CACHED: ${{ steps.cache-deps.outputs.cache-hit }} + run: | + wget https://qgis.org/downloads/macos/deps/install_qgis_deps-${QGIS_DEPS_VERSION}.bash + chmod +x ./install_qgis_deps-${QGIS_DEPS_VERSION}.bash + echo ::group::Install deps + sudo ./install_qgis_deps-${QGIS_DEPS_VERSION}.bash + echo ::endgroup:: + [[ ${QT_ALREADY_CACHED} != "true" ]] && cp -r /opt/Qt/${QT_VERSION} ${DEPS_CACHE_DIR}/Qt/${QT_VERSION} || true + [[ ${QGIS_DEPS_ALREADY_CACHED} != "true" ]] && cp -r /opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION} ${DEPS_CACHE_DIR}/QGIS/qgis-deps-${QGIS_DEPS_VERSION} || true + + - name: Install ccache + run: | + mkdir -p ${CCACHE_DIR} + brew install ccache + ccache --set-config=max_size=2.0G + ccache -s + + - name: Run cmake + run: | + mkdir -p ${BUILD_DIR} + cd ${BUILD_DIR} + + PATH=/opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}/stage/bin:$PATH \ + cmake -DQGIS_MAC_DEPS_DIR=/opt/QGIS/qgis-deps-${QGIS_DEPS_VERSION}/stage \ + -DCMAKE_PREFIX_PATH=/opt/Qt/${QT_VERSION}/clang_64 \ + -DWITH_BINDINGS=TRUE \ + -DWITH_3D=TRUE \ + -DWITH_PDAL=TRUE \ + -DWITH_EPT=TRUE \ + ../QGIS + + - name: Build QGIS + run: | + cd ${BUILD_DIR} + make -j $(sysctl -n hw.ncpu) diff --git a/.github/workflows/mingw64.yml b/.github/workflows/mingw64.yml new file mode 100644 index 000000000000..0ada144677fa --- /dev/null +++ b/.github/workflows/mingw64.yml @@ -0,0 +1,110 @@ +name: 🪟 MingW64 Windows 64bit Build + +on: + push: + branches: + - master + - release-** + paths: + - 'src/**' + - 'external/**' + - 'python/**' + - 'tests/**' + - 'ms-windows/**' + - 'CMakeLists.txt' + - '.github/workflows/mingw64.yml' + pull_request: + paths: + - 'src/**' + - 'external/**' + - 'python/**' + - 'tests/**' + - 'ms-windows/**' + - 'CMakeLists.txt' + - '.github/workflows/mingw64.yml' + workflow_dispatch: + +jobs: + mingw64-build: + env: + CCACHE_DIR: ${{ github.workspace }}/.ccache + name: MinGW64 Windows Build + runs-on: ubuntu-latest + steps: + + - uses: actions/checkout@v2 + + - name: Build Docker Container with Build Environment + id: docker-build + uses: whoan/docker-build-with-cache-action@v5 + with: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + registry: docker.pkg.github.com + image_name: qgis3-mingw-buildenv + dockerfile: ms-windows/mingw/qgis3-build-deps-mingw.dockerfile + push_git_tag: true + push_image_and_stages: on:push + pull_image_and_stages: ${{ github.event_name != 'workflow_dispatch' }} + + - name: Prepare build cache for pull request + uses: pat-s/always-upload-cache@v2.1.3 + if: github.event_name == 'pull_request' + with: + path: ${{ github.workspace }}/.ccache + key: mingw64-ccache-${{ github.actor }}-${{ github.head_ref }}-${{ github.sha }} + # The head_ref or source branch of the pull request in a workflow run. + # The base_ref or target branch of the pull request in a workflow run. + restore-keys: | + mingw64-ccache-${{ github.actor }}-${{ github.head_ref }}- + mingw64-ccache-${{ github.base_ref }}- + mingw64-ccache-refs/heads/master- + + - name: Prepare build cache for branch/tag + # use a fork of actions/cache@v2 to upload cache even when the build or test failed + uses: pat-s/always-upload-cache@v2.1.3 + if: github.event_name != 'pull_request' + with: + path: ${{ github.workspace }}/.ccache + # The branch or tag ref that triggered the workflow run. For branches this in the format refs/heads/, and for tags it is refs/tags/ + key: mingw64-ccache-${{ github.ref }}-${{ github.sha }} + restore-keys: | + mingw64-ccache-${{ github.ref }}- + mingw64-ccache-refs/heads/master- + + - name: Build QGIS Application + run: | + mkdir -p ${GITHUB_WORKSPACE}/.ccache + docker run \ + --env CCACHE_DIR=/QGIS/.ccache \ + -w /QGIS \ + -v ${GITHUB_WORKSPACE}:/QGIS \ + ${DOCKER_IMAGE} \ + ms-windows/mingw/build.sh x86_64 nodebug 4 + env: + DOCKER_IMAGE: ${{ steps.docker-build.outputs.FULL_IMAGE_NAME }} + + - name: Create Portable zip + run: | + DISTROOT=build_mingw64/dist/usr/x86_64-w64-mingw32/sys-root/mingw + DEBUGROOT=dist_debug + for file in $(find $DISTROOT -name '*.debug' \( -type l -or -type f \)); do + DEST=${file/$DISTROOT/$DEBUGROOT} + mkdir -p "$(dirname $DEST)" + sudo mv "$file" "$DEST" + done + sudo mv $DISTROOT QGIS-Portable + zip -r qgis-portable-win64.zip QGIS-Portable + (cd $DEBUGROOT && zip -r - *) > qgis-portable-win64-debugsym.zip + + - name: Upload QGIS for Windows 64bit + uses: actions/upload-artifact@v2.2.2 + with: + name: QGIS for Windows 64bit + path: qgis-portable-win64.zip + + - name: Upload QGIS for Windows 64bit Debug Symbols + uses: actions/upload-artifact@v2.2.2 + with: + name: QGIS for Windows 64bit Debug Symbols + path: qgis-portable-win64-debugsym.zip diff --git a/.github/workflows/ogc.yml b/.github/workflows/ogc.yml new file mode 100644 index 000000000000..101b804599f7 --- /dev/null +++ b/.github/workflows/ogc.yml @@ -0,0 +1,60 @@ +name: 🗺 OGC tests for QGIS Server + +on: + push: + branches: + - master + - release-** + paths: + - 'src/core/**' + - 'src/auth/**' + - 'src/providers/**' + - 'src/server/**' + - 'src/CMakeLists.txt' + - 'external/**' + - 'CMakeLists.txt' + - '.github/workflows/ogc.yml' + pull_request: + branches: + - master + - release-** + paths: + - 'src/core/**' + - 'src/auth/**' + - 'src/providers/**' + - 'src/server/**' + - 'src/CMakeLists.txt' + - 'external/**' + - 'CMakeLists.txt' + - '.github/workflows/ogc.yml' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Setup build dependencies + run: | + docker build -t qgis_server_deps -f .ci/ogc/Dockerfile .ci/ogc/ + + - name: Run build + run: | + docker run -v $(pwd):/usr/src/qgis qgis_server_deps /usr/src/qgis/.ci/ogc/build.sh + + - name: Install pyogctest + run: | + sudo apt-get install python3-virtualenv virtualenv git + git clone https://github.com/pblottiere/pyogctest + cd pyogctest && git checkout 1.0.2 && cd - + virtualenv -p /usr/bin/python3 venv && source venv/bin/activate && pip install -e pyogctest/ + + - name: Download WMS 1.3.0 dataset + run: | + source venv/bin/activate && ./pyogctest/pyogctest.py -s wms130 -w + + - name: Run WMS 1.3.0 OGC tests + run: | + docker-compose -f .ci/ogc/docker-compose.yml up -d + source venv/bin/activate && ./pyogctest/pyogctest.py -n ogc_qgis -s wms130 -v -u http://$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' qgis_server_nginx)/qgisserver diff --git a/.github/workflows/pr-auto-milestone.yml b/.github/workflows/pr-auto-milestone.yml new file mode 100644 index 000000000000..ce64b1bfc7f5 --- /dev/null +++ b/.github/workflows/pr-auto-milestone.yml @@ -0,0 +1,141 @@ +name: 📅 Auto set milestone on PR + +on: + pull_request_target: + types: + - opened + +env: + QGIS_MAJOR_VERSION: 3 + +jobs: + pr-without-milestones: + runs-on: ubuntu-latest + if: github.repository == 'qgis/QGIS' + steps: + # list the tags and milestones + - uses: octokit/graphql-action@v2.x + id: graphql_request + with: + query: | + query { + repository(owner: "qgis", name: "QGIS") { + pullRequests(states: OPEN, last: 100) { + edges { + node { + number + title + milestone { + number + } + baseRef { + name + } + } + } + } + milestones(orderBy: {field: CREATED_AT, direction: DESC}, first: 50) { + edges { + node { + title + number + } + } + } + refs(refPrefix: "refs/tags/", orderBy: {field: TAG_COMMIT_DATE, direction: DESC}, first: 30) { + edges { + node { + name + } + } + } + } + } + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # take the first unprocessed PR and determine if some remain + - name: Filter PR to check + id: extract_data + env: + JSON_DATA: ${{ steps.graphql_request.outputs.data }} + run: | + # get PRs without milestones + PRS_TO_PROCESS=$(echo "${JSON_DATA}" | jq '.repository.pullRequests.edges[] | select( .node.milestone.number | not ) | .node.number') + + NUMBER_OF_PRS=$(echo "${PRS_TO_PROCESS}" | jq -s '. | length') + echo "NUMBER_OF_PRS: ${NUMBER_OF_PRS}" + # early exit + [[ ${NUMBER_OF_PRS} == 0 ]] && echo "::set-output name=has_milestone_to_set::0" && exit 0 + + # Take the first + PR_NUMBER=$(echo "${PRS_TO_PROCESS}" | jq -s '. | first') + echo "PR_NUMBER: ${PR_NUMBER}" + + # Not used for now + RE_RUN_JOB=$(echo "${JSON_DATA}" | jq -s '. | length > 1') + echo "RE_RUN_JOB: ${RE_RUN_JOB}" + + # Get the base branch + BASE_BRANCH=$(echo "${JSON_DATA}" | jq -r ".repository.pullRequests.edges[] | select( .node.number == ${PR_NUMBER} ) | .node.baseRef.name") + echo "BASE_BRANCH: ${BASE_BRANCH}" + + # master => NOTHING, release_3-10 => _10 + MINOR_VERSION=$(echo ${BASE_BRANCH} | sed -r -e 's/^release-[0-9]_([0-9]+)/_\1/;t;d') + echo "MINOR_VERSION: ${MINOR_VERSION}" + + # get the max release from the tags + MAX_RELEASE=$(echo "${JSON_DATA}" | jq ".repository.refs.edges[].node.name | select( . | test(\"^final-${QGIS_MAJOR_VERSION}${MINOR_VERSION}\") ) | sub(\"^final-${QGIS_MAJOR_VERSION}_(?[0-9]+)_(?

    .)\"; .m+\".\"+.p) | tonumber" | jq -s '. | max') + echo "MAX_RELEASE: ${MAX_RELEASE}" + + # increase the number to get milestone: round+2 for master, +0.1 for release_xxx branches + INCREASE_OPERATION=$([[ -z ${MINOR_VERSION} ]] && echo "${MAX_RELEASE%.*} + 2.0" || echo "${MAX_RELEASE} + 0.1" ) + echo "INCREASE_OPERATION: ${INCREASE_OPERATION}" + MILESTONE_TITLE="${QGIS_MAJOR_VERSION}."$(echo "${INCREASE_OPERATION}" | bc) + echo "MILESTONE_TITLE: ${MILESTONE_TITLE}" + + MILESTONE_NUMBER=$(echo "${JSON_DATA}" | jq ".repository.milestones.edges[] | select( .node.title == \"${MILESTONE_TITLE}\" ) | .node.number") + echo "MILESTONE_NUMBER: ${MILESTONE_NUMBER}" + + HAS_MILESTONE_TO_CREATE=$([[ -z ${MILESTONE_NUMBER} ]] && echo "1" || echo "0" ) + echo "HAS_MILESTONE_TO_CREATE: ${HAS_MILESTONE_TO_CREATE}" + + echo "::set-output name=has_milestone_to_set::1" + echo "::set-output name=pr_number::${PR_NUMBER}" + echo "::set-output name=milestone_title::${MILESTONE_TITLE}" + echo "::set-output name=milestone_number::${MILESTONE_NUMBER}" + echo "::set-output name=has_milestone_to_create::${HAS_MILESTONE_TO_CREATE}" + + # create the milestone if needed + - name: Create milestone if needed + id: create_milestone + if: steps.extract_data.outputs.has_milestone_to_set == 1 && steps.extract_data.outputs.has_milestone_to_create == 1 + uses: octokit/request-action@v2.x + with: + route: POST /repos/qgis/QGIS/milestones + title: ${{ steps.extract_data.outputs.milestone_title }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Compute the milestone number + - name: Compute milestone number from existing or created + id: compute_milestone + if: always() && steps.extract_data.outputs.has_milestone_to_set == 1 + env: + MILESTONE_NUMBER_EXISTING: ${{ steps.extract_data.outputs.milestone_number }} + MILESTONE_NUMBER_CREATED_JSON: ${{ steps.create_milestone.outputs.data }} + run: | + FINAL_MILESTONE_NUMBER=$([[ -n ${MILESTONE_NUMBER_EXISTING} ]] && echo "${MILESTONE_NUMBER_EXISTING}" || echo $(echo "${MILESTONE_NUMBER_CREATED_JSON}" | jq .number )) + echo "FINAL_MILESTONE_NUMBER: ${FINAL_MILESTONE_NUMBER}" + echo "::set-output name=milestone_number::${FINAL_MILESTONE_NUMBER}" + + # update PR with milestone + - name: update PR milestone + if: steps.extract_data.outputs.has_milestone_to_set == 1 + uses: octokit/request-action@v2.x + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + route: PATCH /repos/qgis/QGIS/issues/:pull_number + pull_number: ${{ steps.extract_data.outputs.pr_number }} + milestone: ${{ steps.compute_milestone.outputs.milestone_number }} diff --git a/.github/workflows/pr-needs-documentation.yml b/.github/workflows/pr-needs-documentation.yml new file mode 100644 index 000000000000..1a30cd3eb678 --- /dev/null +++ b/.github/workflows/pr-needs-documentation.yml @@ -0,0 +1,131 @@ + +name: 📖 PR needs documentation + +# a message will be added to the PR to ping the author about her/his responsibility to handle the documentation issue +# an issue is automatically created in the QGIS-Documentation repository when the PR gets merged + +on: + pull_request_target: + types: + - opened + - closed + - labeled + +jobs: + ping-author-message: + if: github.event.action != 'closed' && github.event.label.name == 'Needs Documentation' + runs-on: ubuntu-latest + name: Write comment to ping author about the future creation of an issue in docs + steps: + + # write comment to ping the PR author + - name: Create comment + uses: peter-evans/create-or-update-comment@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.pull_request.number }} + body: | + @${{ github.event.pull_request.user.login }} + This pull request has been tagged as **requiring documentation**. + + A documentation ticket will be opened at https://github.com/qgis/QGIS-Documentation **when this PR is merged**. + + **Please update the description** (not the comments) with helpful description and screenshot to help the work from documentors. + Also, any commit having [needs-doc] or [Needs Documentation] in will see its message pushed to the issue, so please be as verbose as you can. + + Thank you! + reactions: 'rocket' + + + create-doc-issue: + if: github.event.pull_request.merged && ( ( github.event.action == 'closed' && contains( github.event.pull_request.labels.*.name, 'Needs Documentation') ) || github.event.label.name == 'Needs Documentation' ) + runs-on: ubuntu-latest + name: Create issue on doc repo for labeled issue + steps: + + # transform the milestone (e.g. 3.10.4) to a doc label (3.10) + - name: QGIS milestone to Doc label + id: milestone2label + env: + MILESTONE: ${{ github.event.pull_request.milestone.title }} + run: | + LABEL=$(sed -r 's/^([[:digit:]]\.[[:digit:]]+)(\.[[:digit:]]+)?$/\1/' <<< ${MILESTONE}) + echo ${LABEL} + echo "::set-output name=label::${LABEL}" + # get the PR body + + # get the PR body + - name: Get PR body as JSON + id: get_pr_info + uses: octokit/request-action@v2.x + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + route: GET /repos/qgis/QGIS/pulls/:pull_number + pull_number: ${{ github.event.pull_request.number }} + + # extract body from json output + - name: Get PR body as text + id: get_pr_body + uses: gr2m/get-json-paths-action@v1.x + with: + json: ${{ steps.get_pr_info.outputs.data }} + body: "body" + + # get commits from the PR + - name: Get PR commits + uses: octokit/request-action@v2.x + id: get_pr_commits + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + route: GET /repos/qgis/QGIS/pulls/:pull_number/commits + pull_number: ${{ github.event.pull_request.number }} + + # extracts the matching commits + - name: Filter commits with \[needs?.doc(umentation)?s?\] + id: filtered_commits + env: + JSON_DATA: ${{ steps.get_pr_commits.outputs.data }} + run: | + COMMITS_MESSAGES=$(echo ${JSON_DATA} | jq '.[].commit.message | select( . |test("\\[(feature|needs?.doc(umentation)?s?)\\]"; "i")) | sub("\\[needs?.doc(umentation)?s?\\]"; "\n\n\n\n"; "i")') + echo "::set-output name=commits::$(echo ${COMMITS_MESSAGES} | tr -d '\n' )" + + # create the documentation issue + - name: Create Documentation issue + id: doc_issue + uses: maxkomarychev/oction-create-issue@v0.7.1 + with: + token: ${{ secrets.GH_TOKEN_BOT }} + owner: qgis + repo: QGIS-Documentation + title: ${{ format('{0} (Request in QGIS)', github.event.pull_request.title) }} + # do not modify the QGIS version, an action automatically creates a label in the doc repo + # this is not possible to set labels directly due to security reasons + # the token is in clear, so no rights are given to qgis-bot + body: | + ### Request for documentation + From pull request QGIS/qgis#${{ github.event.pull_request.number }} + Author: @${{ github.event.pull_request.user.login }} + QGIS version: ${{ steps.milestone2label.outputs.label }} + + **${{ github.event.pull_request.title }}** + + ### PR Description: + ${{ steps.get_pr_body.outputs.body }} + + ### Commits tagged with [need-docs] or [FEATURE] + ${{ steps.filtered_commits.outputs.commits }} + + # write comment to ping the PR author + - name: Create comment + uses: peter-evans/create-or-update-comment@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.pull_request.number }} + body: | + @${{ github.event.pull_request.user.login }} + A documentation ticket has been opened at https://github.com/qgis/QGIS-Documentation/issues/${{ steps.doc_issue.outputs.number }} + It is **your** responsibility to visit this ticket and add as much detail as possible for the documentation team to correctly document this change. + Thank you! + reactions: 'rocket' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000000..ad8f98217d77 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,31 @@ +name: 🚀 Release + +on: + push: + tags: + - 'final-*_*_*' + +jobs: + build: + name: Create Release + runs-on: ubuntu-latest + steps: + + - name: Prepare release names + run: | + VERSION_CHANGELOG=$(echo ${{ github.ref }} | cut -d '-' -f 2 | cut -d '_' -f1,2 | sed 's/_/\./g') + echo "version_url=https://changelog.qgis.org/en/qgis/version/${VERSION_CHANGELOG}" >> $GITHUB_ENV + VERSION_NAME=$(echo ${{ github.ref }} | cut -d '-' -f 2 | sed 's/_/\./g') + echo "version_name=${VERSION_NAME}" >> $GITHUB_ENV + + - name: Create release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: ${{ env.version_name }} + body: ${{ env.version_url }} + draft: false + prerelease: false diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 000000000000..306222aa0b39 --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,233 @@ +name: 🧪 QGIS tests + +on: + push: + branches: + - master + - release-** + paths: + - 'src/**' + - 'external/**' + - 'python/**' + - 'tests/**' + - 'CMakeLists.txt' + - '.github/workflows/run-tests.yml' + - '.docker/**' + - '.ci/**' + pull_request: + branches: + - master + - release-** + # paths cannot be filtered on this workflow on pull request as it is a required one in the branch protection + # feature request and hacks: https://github.community/t/feature-request-conditional-required-checks/16761 + +jobs: + build: + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + GH_WORKSPACE: ${{ github.workspace }} # used in docker compose + DEFAULT_UBUNTU_BASE: '20.04' + RUN_FLAKY_TESTS: ${{ contains( github.event.pull_request.labels.*.name, 'run flaky tests') }} + + runs-on: ubuntu-latest + + strategy: + matrix: + # tests run on 20.04 (Qt 5.12), compile test on 20.10 (Qt 5.14) and 21.04 (Qt 5.15) + ubuntu-base: ['20.04', '20.10', '21.04'] + fail-fast: false + + outputs: + compile_outcome: ${{ steps.compile.outcome }} + tests_failing: ${{ steps.tests.outputs.TESTS_FAILING }} + cdash_url: ${{ steps.tests.outputs.CDASH_URL }} + runners_outcome: ${{ steps.runners.outcome }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set vars + env: + GITHUB_EVENT_NAME: ${{ github.event_name }} + GITHUB_REF: ${{ github.ref }} + GITHUB_PR_NUMBER: ${{github.event.number}} + UBUNTU_BASE: ${{ matrix.ubuntu-base }} + run: | + DOCKER_TAG=$(echo $( [[ ${GITHUB_EVENT_NAME} =~ ^pull_request$ ]] && echo ${GITHUB_BASE_REF} || echo ${GITHUB_REF##*/} ) | sed 's/^master$/latest/')$( [[ ${UBUNTU_BASE} != ${DEFAULT_UBUNTU_BASE} ]] && echo "_${UBUNTU_BASE}" || echo "" ) + CTEST_BUILD_NAME=$( [[ ${GITHUB_EVENT_NAME} =~ ^pull_request$ ]] && echo "PR${GITHUB_PR_NUMBER}" || echo ${GITHUB_REF##*/} )"_${GITHUB_SHA}" + [[ ${UBUNTU_BASE} == "20.04" ]] && PATCH_QT_3D=true || PATCH_QT_3D=false + # build w/o 3D for Qt 5.15 (many deprecation warnings) + [[ ${UBUNTU_BASE} == "21.04" ]] && WITH_3D=FALSE || WITH_3D=TRUE + echo "DOCKER_TAG=${DOCKER_TAG}" >> $GITHUB_ENV + echo "CTEST_BUILD_NAME=${CTEST_BUILD_NAME}" >> $GITHUB_ENV + echo "PATCH_QT_3D=${PATCH_QT_3D}" >> $GITHUB_ENV + echo "WITH_3D=${WITH_3D}" >> $GITHUB_ENV + + - name: Print vars + run: | + echo DOCKER_TAG: ${DOCKER_TAG} + echo CTEST_BUILD_NAME: ${CTEST_BUILD_NAME} + echo PATCH_QT_3D: ${PATCH_QT_3D} + echo WITH_3D: ${WITH_3D} + + - name: Build deps + env: + UBUNTU_BASE: ${{ matrix.ubuntu-base }} + run: | + pushd .docker + docker pull qgis/qgis3-build-deps:${DOCKER_TAG} || true + docker build --build-arg UBUNTU_BASE=${UBUNTU_BASE} --cache-from qgis/qgis3-build-deps:${DOCKER_TAG} -t qgis/qgis3-build-deps:${DOCKER_TAG} -f qgis3-build-deps.dockerfile . + popd + + - name: Push deps image + if: ${{ github.event_name != 'pull_request' }} + run: | + docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}" + docker push "qgis/qgis3-build-deps:${DOCKER_TAG}" + + - name: Prepare build cache for pull request + uses: pat-s/always-upload-cache@v2.1.3 + if: github.event_name == 'pull_request' + with: + path: /home/runner/QGIS/.ccache + key: build-ccache-${{ matrix.ubuntu-base }}-${{ github.actor }}-${{ github.head_ref }}-${{ github.sha }} + # The head_ref or source branch of the pull request in a workflow run. + # The base_ref or target branch of the pull request in a workflow run. + restore-keys: | + build-ccache-${{ matrix.ubuntu-base }}-${{ github.actor }}-${{ github.head_ref }}- + build-ccache-${{ matrix.ubuntu-base }}-refs/heads/${{ github.base_ref }}- + build-ccache-${{ matrix.ubuntu-base }}-refs/heads/master- + + - name: Prepare build cache for branch/tag + # use a fork of actions/cache@v2 to upload cache even when the build or test failed + uses: pat-s/always-upload-cache@v2.1.3 + if: github.event_name != 'pull_request' + with: + path: /home/runner/QGIS/.ccache + # The branch or tag ref that triggered the workflow run. For branches this in the format refs/heads/, and for tags it is refs/tags/ + key: build-ccache-${{ matrix.ubuntu-base }}-${{ github.ref }}-${{ github.sha }} + restore-keys: | + build-ccache-${{ matrix.ubuntu-base }}-${{ github.ref }}- + build-ccache-${{ matrix.ubuntu-base }}-refs/heads/master- + + - name: Compile QGIS + id: compile + run: | + docker run -t --name qgis_container \ + -v $(pwd):/root/QGIS \ + -v /home/runner/QGIS/.ccache:/root/.ccache \ + --env-file .docker/docker-variables.env \ + --env PUSH_TO_CDASH=true \ + --env WITH_3D=${WITH_3D} \ + qgis/qgis3-build-deps:${DOCKER_TAG} \ + /root/QGIS/.docker/docker-qgis-build.sh + docker commit qgis_container qgis_image + + - name: Push image + if: github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'Push Docker Image') + env: + GITHUB_PR_NUMBER: ${{github.event.number}} + run: | + docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}" + docker commit qgis_container qgis/qgis-pr-build:PR${GITHUB_PR_NUMBER} + docker push qgis/qgis-pr-build:PR${GITHUB_PR_NUMBER} + + - name: Run unit tests + id: tests + if: ${{ matrix.ubuntu-base == env.DEFAULT_UBUNTU_BASE }} + run: docker-compose -f .docker/docker-compose-testing.yml run qgis-deps /root/QGIS/.docker/docker-qgis-test.sh + +# - name: Test QGIS runners +# id: runners +# if: ${{ matrix.ubuntu-base == env.DEFAULT_UBUNTU_BASE }} +# run: | +# docker run -d --name qgis-testing-environment \ +# -v $(pwd):/root/QGIS \ +# -v $(pwd)/tests/src/python:/tests_directory \ +# -v $(pwd)/.docker/qgis_resources/test_runner:/usr/bin/test_runner \ +# -v $(pwd)/.docker/qgis_resources/supervisor:/etc/supervisor \ +# -e QGIS_BUILD_PATH=/root/QGIS/build/output/bin/qgis \ +# -e TEST_RUNNER_PATH=/usr/bin/test_runner/qgis_testrunner.py \ +# -e DISPLAY=:99 \ +# qgis_image \ +# /usr/bin/supervisord -c /etc/supervisor/supervisord.conf +# # Wait for xvfb to finish starting +# printf "Waiting for the docker...🐳..." +# sleep 10 +# echo " done 🥩" +# +# declare -A testrunners +# # Passing cases: +# testrunners["test_testrunner.run_passing"]=0 +# testrunners["test_testrunner.run_skipped_and_passing"]=0 +# # Failing cases: +# testrunners["test_testrunner"]=1 +# testrunners["test_testrunner.run_all"]=1 +# testrunners["test_testrunner.run_failing"]=1 +# set +e # do not exit on error +# # Run tests in the docker +# for i in "${!testrunners[@]}" +# do +# echo "::group::docker_test_runner_${i}" +# echo "test ${i}..." +# docker exec -i qgis-testing-environment sh -c "cd /tests_directory && /usr/bin/test_runner/qgis_testrunner.sh ${i}" +# [[ $? -eq "${testrunners[$i]}" ]] && echo "success" || exit 1 +# echo "::endgroup::" +# done +# set -e # switch back +# docker stop qgis-testing-environment + + +# tests-report-comment: +# name: Write tests report in a comment +# needs: build +# runs-on: ubuntu-latest +# if: always() && ( needs.build.result == 'failure' || needs.build.result == 'success' ) && github.event_name == 'pull_request' +# steps: +# - name: Find Comment +# uses: peter-evans/find-comment@v1 +# id: find-comment +# with: +# issue-number: ${{ github.event.pull_request.number }} +# comment-author: 'github-actions[bot]' +# body-includes: Tests report +# +# - name: Create comment +# if: ${{ steps.find-comment.outputs.comment-id == 0 }} +# uses: peter-evans/create-or-update-comment@v1 +# id: create-comment +# with: +# issue-number: ${{ github.event.pull_request.number }} +# body: | +# **Tests report** +# +# - name: Process +# id: process-vars +# env: +# COMMENT_FOUND: ${{ steps.find-comment.outputs.comment-id }} +# COMMENT_CREATED: ${{ steps.create-comment.outputs.comment-id }} +# COMMIT_SHA: ${{ github.event.pull_request.head.sha }} +# CDASH_URL: ${{ needs.build.outputs.cdash_url }} +# COMPILE_OUTCOME: ${{ needs.build.outputs.compile_outcome }} +# TESTS_FAILING: ${{ needs.build.outputs.tests_failing }} +# RUNNERS_OUTCOME: ${{ needs.build.outputs.runners_outcome }} +# run: | +# echo "::set-output name=COMMENT_ID::"$([[ "${COMMENT_FOUND}" -eq "0" ]] && echo ${COMMENT_CREATED} || echo ${COMMENT_FOUND}) +# if [[ ${COMPILE_OUTCOME} != "success" ]]; then +# echo "::set-output name=COMMENT_BODY::${COMMIT_SHA} :scream: compilation failed" +# elif [[ ${TESTS_FAILING} != "0" ]]; then +# echo "::set-output name=COMMENT_BODY::${COMMIT_SHA} :fire: ${TESTS_FAILING} unit-tests are failing ${CDASH_URL}" +# elif [[ ${RUNNERS_OUTCOME} != "success" ]]; then +# echo "::set-output name=COMMENT_BODY::${COMMIT_SHA} :broken_heart: QGIS runners test failed" +# else +# echo "::set-output name=COMMENT_BODY::${COMMIT_SHA} :sunglasses: unit-tests succeeded" +# fi +# +# - name: Update comment +# uses: peter-evans/create-or-update-comment@v1 +# with: +# comment-id: ${{ steps.process-vars.outputs.COMMENT_ID }} +# edit-mode: append +# body: ${{ steps.process-vars.outputs.COMMENT_BODY }} diff --git a/.github/workflows/stale_issues.yml b/.github/workflows/stale_issues.yml new file mode 100644 index 000000000000..2f505385e06e --- /dev/null +++ b/.github/workflows/stale_issues.yml @@ -0,0 +1,43 @@ +name: 👓 Handle stale issues +on: + schedule: + - cron: "30 1 * * *" + +jobs: + stale: + if: github.repository_owner == 'qgis' + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: > + The QGIS project highly values your report and would love to see it addressed. + However, this issue has been left in feedback mode for the last 14 days and is + being automatically marked as "stale". + + If you would like to continue with this issue, please provide any missing information + or answer any open questions. If you could resolve the issue yourself meanwhile, + please leave a note for future readers with the same problem and close the issue. + + In case you should have any uncertainty, please leave a comment and we will be + happy to help you proceed with this issue. + + If there is no further activity on this issue, it will be closed in a week. + + + close-issue-message: > + While we hate to see this happen, this issue has been automatically closed because + it has not had any activity in the last 42 days despite being marked as feedback. + If this issue should be reconsidered, please follow the guidelines in the previous + comment and reopen this issue. + + Or, if you have any further questions, there are also + [further support channels](https://www.qgis.org/en/site/forusers/support.html) + that can help you. + + + stale-issue-label: 'stale' + only-labels: 'feedback' + days-before-stale: 14 + days-before-close: 28 diff --git a/.github/workflows/stale_pr.yml b/.github/workflows/stale_pr.yml new file mode 100644 index 000000000000..b04a8f8ff0cd --- /dev/null +++ b/.github/workflows/stale_pr.yml @@ -0,0 +1,54 @@ +name: 👓 Handle stale pull requests +on: + schedule: + - cron: "30 2 * * *" + +jobs: + stale: + if: github.repository_owner == 'qgis' + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-pr-message: > + The QGIS project highly values your contribution and would love to see + this work merged! + Unfortunately this PR has not had any activity in the last 14 days and + is being automatically marked as "stale". + If you think this pull request should be merged, please check + + - that all unit tests are passing + + - that all comments by reviewers have been addressed + + - that there is enough information for reviewers, in particular + + - link to any issues which this pull request fixes + + - add a description of workflows which this pull request fixes + + - add screenshots if applicable + + - that you have written unit tests where possible + + In case you should have any uncertainty, please leave a comment and we will + be happy to help you proceed with this pull request. + + If there is no further activity on this pull request, it will be closed in a + week. + + + close-pr-message: > + While we hate to see this happen, this PR has been automatically closed because + it has not had any activity in the last 21 days. If this pull request should be + reconsidered, please follow the guidelines in the previous comment and reopen + this pull request. Or, if you have any further questions, just ask! We love to + help, and if there's anything the QGIS project can do to help push this PR forward + please let us know how we can assist. + + + stale-pr-label: 'stale' + exempt-pr-labels: 'Merge After Thaw' + days-before-stale: 14 + days-before-close: 7 diff --git a/.github/workflows/unstale.yml b/.github/workflows/unstale.yml new file mode 100644 index 000000000000..5c9eaf26303e --- /dev/null +++ b/.github/workflows/unstale.yml @@ -0,0 +1,15 @@ +name: Remove Labels + +on: [issue_comment] + +jobs: + remove_labels: + if: contains(github.event.issue.labels.*.name, 'stale') + runs-on: ubuntu-latest + steps: + - uses: actions-ecosystem/action-remove-labels@v1 + if: ${{ github.event.comment.user.url != 'https://github.com/apps/github-actions' }} + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + labels: | + stale From 2b8f919d35e70d2164dba5216fd535b17ac13d8d Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 13:16:24 +1000 Subject: [PATCH 193/377] Disable qt6 workflow for now --- .github/workflows/{qt6.yml => qt6.disabled} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{qt6.yml => qt6.disabled} (100%) diff --git a/.github/workflows/qt6.yml b/.github/workflows/qt6.disabled similarity index 100% rename from .github/workflows/qt6.yml rename to .github/workflows/qt6.disabled From 538d04f75c629e98cac3a13f909533503f635f1f Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 19 Mar 2021 11:13:48 +0100 Subject: [PATCH 194/377] reuse existing constructor --- src/gui/symbology/qgssvgselectorwidget.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/gui/symbology/qgssvgselectorwidget.cpp b/src/gui/symbology/qgssvgselectorwidget.cpp index 6d6584920dd2..030633ced9b5 100644 --- a/src/gui/symbology/qgssvgselectorwidget.cpp +++ b/src/gui/symbology/qgssvgselectorwidget.cpp @@ -221,14 +221,8 @@ void QgsSvgGroupLoader::loadGroup( const QString &parentPath ) // QgsSvgSelectorListModel::QgsSvgSelectorListModel( QObject *parent, int iconSize ) - : QAbstractListModel( parent ) - , mSvgLoader( new QgsSvgSelectorLoader( this ) ) - , mIconSize( iconSize ) -{ - mSvgLoader->setPath( QString() ); - connect( mSvgLoader, &QgsSvgSelectorLoader::foundSvgs, this, &QgsSvgSelectorListModel::addSvgs ); - mSvgLoader->start(); -} + : QgsSvgSelectorListModel( parent, QString(), iconSize ) +{} QgsSvgSelectorListModel::QgsSvgSelectorListModel( QObject *parent, const QString &path, int iconSize ) : QAbstractListModel( parent ) From f4426ddc60e21a6339599281d3825c8010fa3cf3 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 19 Mar 2021 11:14:01 +0100 Subject: [PATCH 195/377] add filter line edit to UI --- src/ui/symbollayer/widget_svgselector.ui | 31 +++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/ui/symbollayer/widget_svgselector.ui b/src/ui/symbollayer/widget_svgselector.ui index a70e1459a2e4..d7f2fc609f40 100644 --- a/src/ui/symbollayer/widget_svgselector.ui +++ b/src/ui/symbollayer/widget_svgselector.ui @@ -38,7 +38,7 @@ SVG browser - + Qt::Horizontal @@ -129,6 +129,30 @@ + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + + @@ -220,6 +244,11 @@

    qgsfilecontentsourcelineedit.h
    1 + + QgsFilterLineEdit + QLineEdit +
    qgsfilterlineedit.h
    +
    mSvgSourceLineEdit From ba787ca0da6276593cf338cf2187158e39839c7d Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 19 Mar 2021 11:38:16 +0100 Subject: [PATCH 196/377] create a sort filter proxy model --- .../symbology/qgssvgselectorwidget.sip.in | 26 +++++++++++++++++ src/gui/symbology/qgssvgselectorwidget.cpp | 15 ++++++++++ src/gui/symbology/qgssvgselectorwidget.h | 28 +++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/python/gui/auto_generated/symbology/qgssvgselectorwidget.sip.in b/python/gui/auto_generated/symbology/qgssvgselectorwidget.sip.in index 7aecdac8bf25..98b4dcd9b2ff 100644 --- a/python/gui/auto_generated/symbology/qgssvgselectorwidget.sip.in +++ b/python/gui/auto_generated/symbology/qgssvgselectorwidget.sip.in @@ -13,6 +13,32 @@ +class QgsSvgSelectorFilterModel : QSortFilterProxyModel +{ +%Docstring +A model for displaying SVG files with a preview icon which can be filtered by file name. +Population of the model is performed in a background thread to ensure that +initial creation of the model is responsive and does not block the GUI. + +.. versionadded:: 3.20 +%End + +%TypeHeaderCode +#include "qgssvgselectorwidget.h" +%End + public: + + QgsSvgSelectorFilterModel( QObject *parent /TransferThis/, const QString &path = QString(), int iconSize = 30 ); +%Docstring +Constructor for creating a model for SVG files in a specific path. + +:param parent: parent object +:param path: initial path, which is recursively searched +:param iconSize: desired size of SVG icons to create +%End + +}; + class QgsSvgSelectorListModel : QAbstractListModel { %Docstring diff --git a/src/gui/symbology/qgssvgselectorwidget.cpp b/src/gui/symbology/qgssvgselectorwidget.cpp index 030633ced9b5..3f04464b7ec0 100644 --- a/src/gui/symbology/qgssvgselectorwidget.cpp +++ b/src/gui/symbology/qgssvgselectorwidget.cpp @@ -29,6 +29,7 @@ #include "qgsvectorlayer.h" #include +#include #include #include #include @@ -216,6 +217,18 @@ void QgsSvgGroupLoader::loadGroup( const QString &parentPath ) ///@endcond + + + +QgsSvgSelectorFilterModel::QgsSvgSelectorFilterModel( QObject *parent, const QString &path, int iconSize ) + : QSortFilterProxyModel( parent ) +{ + mModel = new QgsSvgSelectorListModel( parent, path, iconSize ); + setFilterCaseSensitivity( Qt::CaseInsensitive ); + setSourceModel( mModel ); + setFilterRole( Qt::UserRole ); +} + //, // QgsSvgSelectorListModel // @@ -731,3 +744,5 @@ void QgsSvgParameterValueDelegate::updateEditorGeometry( QWidget *editor, const } ///@endcond + + diff --git a/src/gui/symbology/qgssvgselectorwidget.h b/src/gui/symbology/qgssvgselectorwidget.h index 9977beb323cc..25f85f389d3c 100644 --- a/src/gui/symbology/qgssvgselectorwidget.h +++ b/src/gui/symbology/qgssvgselectorwidget.h @@ -23,6 +23,7 @@ #include "qgsguiutils.h" #include "qgsproperty.h" +#include #include #include #include @@ -42,6 +43,7 @@ class QPushButton; class QTreeView; class QgsExpressionContextGenerator; +class QgsSvgSelectorListModel; #ifndef SIP_RUN @@ -267,6 +269,32 @@ class GUI_EXPORT QgsSvgGroupLoader : public QThread ///@endcond #endif +/** + * \ingroup gui + * \class QgsSvgSelectorListModel + * \brief A model for displaying SVG files with a preview icon which can be filtered by file name. + * Population of the model is performed in a background thread to ensure that + * initial creation of the model is responsive and does not block the GUI. + * \since QGIS 3.20 + */ +class GUI_EXPORT QgsSvgSelectorFilterModel : public QSortFilterProxyModel +{ + Q_OBJECT + + public: + + /** + * Constructor for creating a model for SVG files in a specific path. + * \param parent parent object + * \param path initial path, which is recursively searched + * \param iconSize desired size of SVG icons to create + */ + QgsSvgSelectorFilterModel( QObject *parent SIP_TRANSFERTHIS, const QString &path = QString(), int iconSize = 30 ); + + private: + QgsSvgSelectorListModel *mModel = nullptr; +}; + /** * \ingroup gui * \class QgsSvgSelectorListModel From 17701be21e2980922bfd5fe028fb71d30339a74d Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 19 Mar 2021 11:48:21 +0100 Subject: [PATCH 197/377] use filter proxy in the widget --- src/gui/symbology/qgssvgselectorwidget.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/symbology/qgssvgselectorwidget.cpp b/src/gui/symbology/qgssvgselectorwidget.cpp index 3f04464b7ec0..799dc69fce4c 100644 --- a/src/gui/symbology/qgssvgselectorwidget.cpp +++ b/src/gui/symbology/qgssvgselectorwidget.cpp @@ -491,8 +491,9 @@ void QgsSvgSelectorWidget::populateIcons( const QModelIndex &idx ) QString path = idx.data( Qt::UserRole + 1 ).toString(); QAbstractItemModel *oldModel = mImagesListView->model(); - QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( mImagesListView, path, mIconSize ); + QgsSvgSelectorFilterModel *m = new QgsSvgSelectorFilterModel( mImagesListView, path, mIconSize ); mImagesListView->setModel( m ); + connect( mSvgFilterLineEdit, &QgsFilterLineEdit::textChanged, m, &QSortFilterProxyModel::setFilterFixedString ); delete oldModel; //explicitly delete old model to force any background threads to stop connect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged, @@ -520,8 +521,9 @@ void QgsSvgSelectorWidget::populateList() // Initially load the icons in the List view without any grouping QAbstractItemModel *oldModel = mImagesListView->model(); - QgsSvgSelectorListModel *m = new QgsSvgSelectorListModel( mImagesListView ); + QgsSvgSelectorFilterModel *m = new QgsSvgSelectorFilterModel( mImagesListView ); mImagesListView->setModel( m ); + connect( mSvgFilterLineEdit, &QgsFilterLineEdit::textChanged, m, &QSortFilterProxyModel::setFilterFixedString ); delete oldModel; //explicitly delete old model to force any background threads to stop } From 522521220ca682d37f1d0e7c6efa7f963bc93880 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 19 Mar 2021 11:49:31 +0100 Subject: [PATCH 198/377] move line edit to bottom --- src/ui/symbollayer/widget_svgselector.ui | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ui/symbollayer/widget_svgselector.ui b/src/ui/symbollayer/widget_svgselector.ui index d7f2fc609f40..a6b81ca71e86 100644 --- a/src/ui/symbollayer/widget_svgselector.ui +++ b/src/ui/symbollayer/widget_svgselector.ui @@ -7,7 +7,7 @@ 0 0 331 - 490 + 500
    @@ -38,6 +38,9 @@ SVG browser + + 3 + @@ -129,7 +132,7 @@
    - + From 147ff1a793e7c7e77df51269effb04dea5c81242 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 19 Mar 2021 13:12:30 +0100 Subject: [PATCH 199/377] avoid removing already set icon --- src/gui/symbology/qgssvgselectorwidget.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/symbology/qgssvgselectorwidget.cpp b/src/gui/symbology/qgssvgselectorwidget.cpp index 799dc69fce4c..3918fa506737 100644 --- a/src/gui/symbology/qgssvgselectorwidget.cpp +++ b/src/gui/symbology/qgssvgselectorwidget.cpp @@ -402,6 +402,15 @@ QgsSvgSelectorWidget::QgsSvgSelectorWidget( QWidget *parent ) mGroupsTreeView->setHeaderHidden( true ); populateList(); + connect( mSvgFilterLineEdit, &QgsFilterLineEdit::textChanged, this, [ = ]( const QString & filterText ) + { + disconnect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgSelectorWidget::svgSelectionChanged ); + mImagesListView->selectionModel()->clearSelection(); + connect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgSelectorWidget::svgSelectionChanged ); + qobject_cast( mImagesListView->model() )->setFilterFixedString( filterText ); + } ); + + mParametersModel = new QgsSvgParametersModel( this ); mParametersTreeView->setModel( mParametersModel ); mParametersGroupBox->setVisible( mAllowParameters ); @@ -523,7 +532,6 @@ void QgsSvgSelectorWidget::populateList() QAbstractItemModel *oldModel = mImagesListView->model(); QgsSvgSelectorFilterModel *m = new QgsSvgSelectorFilterModel( mImagesListView ); mImagesListView->setModel( m ); - connect( mSvgFilterLineEdit, &QgsFilterLineEdit::textChanged, m, &QSortFilterProxyModel::setFilterFixedString ); delete oldModel; //explicitly delete old model to force any background threads to stop } From cfb5006e12428517e52f5a97e106b5bccc7ff9fa Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 19 Mar 2021 13:19:06 +0100 Subject: [PATCH 200/377] fix docs --- src/gui/symbology/qgssvgselectorwidget.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/symbology/qgssvgselectorwidget.h b/src/gui/symbology/qgssvgselectorwidget.h index 25f85f389d3c..f65a2419b58b 100644 --- a/src/gui/symbology/qgssvgselectorwidget.h +++ b/src/gui/symbology/qgssvgselectorwidget.h @@ -271,7 +271,7 @@ class GUI_EXPORT QgsSvgGroupLoader : public QThread /** * \ingroup gui - * \class QgsSvgSelectorListModel + * \class QgsSvgSelectorFilterModel * \brief A model for displaying SVG files with a preview icon which can be filtered by file name. * Population of the model is performed in a background thread to ensure that * initial creation of the model is responsive and does not block the GUI. From b651bb497ff006040bf3a2f6353cc63e993a3655 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 19 Mar 2021 14:21:39 +0100 Subject: [PATCH 201/377] avoid extra calls to clearing the selection --- src/gui/symbology/qgssvgselectorwidget.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/symbology/qgssvgselectorwidget.cpp b/src/gui/symbology/qgssvgselectorwidget.cpp index 3918fa506737..02500623de29 100644 --- a/src/gui/symbology/qgssvgselectorwidget.cpp +++ b/src/gui/symbology/qgssvgselectorwidget.cpp @@ -404,9 +404,12 @@ QgsSvgSelectorWidget::QgsSvgSelectorWidget( QWidget *parent ) connect( mSvgFilterLineEdit, &QgsFilterLineEdit::textChanged, this, [ = ]( const QString & filterText ) { - disconnect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgSelectorWidget::svgSelectionChanged ); - mImagesListView->selectionModel()->clearSelection(); - connect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgSelectorWidget::svgSelectionChanged ); + if ( mImagesListView->selectionModel()->selectedIndexes().count() > 0 ) + { + disconnect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgSelectorWidget::svgSelectionChanged ); + mImagesListView->selectionModel()->clearSelection(); + connect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgSelectorWidget::svgSelectionChanged ); + } qobject_cast( mImagesListView->model() )->setFilterFixedString( filterText ); } ); From b2951e6edfe655d1722d36f38f62c0055511ee2f Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 22 Mar 2021 08:45:42 +0100 Subject: [PATCH 202/377] better layout --- src/gui/symbology/qgssvgselectorwidget.cpp | 2 +- src/ui/symbollayer/widget_svgselector.ui | 37 ++++++++-------------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/gui/symbology/qgssvgselectorwidget.cpp b/src/gui/symbology/qgssvgselectorwidget.cpp index 02500623de29..7609f84f8cfa 100644 --- a/src/gui/symbology/qgssvgselectorwidget.cpp +++ b/src/gui/symbology/qgssvgselectorwidget.cpp @@ -404,7 +404,7 @@ QgsSvgSelectorWidget::QgsSvgSelectorWidget( QWidget *parent ) connect( mSvgFilterLineEdit, &QgsFilterLineEdit::textChanged, this, [ = ]( const QString & filterText ) { - if ( mImagesListView->selectionModel()->selectedIndexes().count() > 0 ) + if ( !mImagesListView->selectionModel()->selectedIndexes().isEmpty() ) { disconnect( mImagesListView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsSvgSelectorWidget::svgSelectionChanged ); mImagesListView->selectionModel()->clearSelection(); diff --git a/src/ui/symbollayer/widget_svgselector.ui b/src/ui/symbollayer/widget_svgselector.ui index a6b81ca71e86..20e33694c1f6 100644 --- a/src/ui/symbollayer/widget_svgselector.ui +++ b/src/ui/symbollayer/widget_svgselector.ui @@ -48,6 +48,9 @@ + + 2 + @@ -75,6 +78,9 @@ + + 2 + @@ -128,34 +134,17 @@ + + + + true + + + - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - true - - - - - From a11985f18db49cb3fb9a267a99b402edcb70356f Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 22 Mar 2021 09:33:37 +0100 Subject: [PATCH 203/377] disable Docker build workflow (#42374) workflow cannot succeed due to missing space on the device see https://github.com/qgis/QGIS-Enhancement-Proposals/issues/221 --- .github/workflows/{build-docker.yml => build-docker.yml.disabled} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{build-docker.yml => build-docker.yml.disabled} (100%) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml.disabled similarity index 100% rename from .github/workflows/build-docker.yml rename to .github/workflows/build-docker.yml.disabled From 999177212cb1f498dbfab2e83bc98c7e521d0e64 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Mon, 22 Mar 2021 10:03:49 +0100 Subject: [PATCH 204/377] Free space to build docker images --- .github/workflows/build-docker.yml.disabled | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/build-docker.yml.disabled b/.github/workflows/build-docker.yml.disabled index 8048eb23c497..dbaac626382b 100644 --- a/.github/workflows/build-docker.yml.disabled +++ b/.github/workflows/build-docker.yml.disabled @@ -49,6 +49,19 @@ jobs: matrix: ${{ fromJSON( needs.define-strategy.outputs.matrix ) }} steps: + - name: Free additional space + run: | + df -h + rm -rf /tmp/workspace + rm -rf /usr/share/dotnet/sdk + sudo apt remove llvm-* ghc-* google-chrome-* dotnet-sdk-* + dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -n | tail -n 100 + du -a /usr/share | sort -n -r | head -n 10 + du -a /usr/local/share | sort -n -r | head -n 10 + df -h + sudo apt clean + df -h + - name: Cache id: cache uses: actions/cache@v2.1.4 From 3f667e5094fcb6f017c14ac7fc67318cb829ed1f Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 22 Mar 2021 13:23:23 +0100 Subject: [PATCH 205/377] enable workflow again --- .github/workflows/{build-docker.yml.disabled => build-docker.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{build-docker.yml.disabled => build-docker.yml} (100%) diff --git a/.github/workflows/build-docker.yml.disabled b/.github/workflows/build-docker.yml similarity index 100% rename from .github/workflows/build-docker.yml.disabled rename to .github/workflows/build-docker.yml From 4383ccce11974531850bb83f0ba8c4de7a0c4ae3 Mon Sep 17 00:00:00 2001 From: Jorge Gustavo Rocha Date: Mon, 22 Mar 2021 12:51:08 +0000 Subject: [PATCH 206/377] Prevent collapse/expand in Dynamic SVG parameters table (#42185) --- src/ui/symbollayer/widget_svgselector.ui | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ui/symbollayer/widget_svgselector.ui b/src/ui/symbollayer/widget_svgselector.ui index 20e33694c1f6..f291eb9da0d1 100644 --- a/src/ui/symbollayer/widget_svgselector.ui +++ b/src/ui/symbollayer/widget_svgselector.ui @@ -190,7 +190,14 @@ - + + + false + + + false + +
    From 0a0e1a8c6a90cfea5af8afb1be06dc9cb0c8a443 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 22 Mar 2021 13:51:37 +0100 Subject: [PATCH 207/377] remove leftover from PR (#42373) --- src/gui/qgsfeaturelistcombobox.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/qgsfeaturelistcombobox.h b/src/gui/qgsfeaturelistcombobox.h index 4c7b1330912a..9570790d30d1 100644 --- a/src/gui/qgsfeaturelistcombobox.h +++ b/src/gui/qgsfeaturelistcombobox.h @@ -259,7 +259,6 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox bool mIsCurrentlyEdited = false; friend class TestQgsFeatureListComboBox; - friend class TestQgsRelationReferenceWidget; }; From 1f5ecb74726ff05bcc5ee0432ee1874054f8fac3 Mon Sep 17 00:00:00 2001 From: Damiano Date: Wed, 17 Mar 2021 20:55:20 +0100 Subject: [PATCH 208/377] Fix QgsAbstractRelationEditorWidget redondancy mNmRelation/nNmRelationId mNmRelation and nNmRelationId represent the same QgsRelation instance but it was possible to set them to different values. Also added method nmRelation() to access the nmRelation directly. --- .../auto_generated/qgsabstractrelationeditorwidget.sip.in | 7 +++++++ src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp | 2 -- src/gui/qgsabstractrelationeditorwidget.cpp | 7 +++++-- src/gui/qgsabstractrelationeditorwidget.h | 7 ++++++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/python/gui/auto_generated/qgsabstractrelationeditorwidget.sip.in b/python/gui/auto_generated/qgsabstractrelationeditorwidget.sip.in index ca61945e17aa..702bd3b55918 100644 --- a/python/gui/auto_generated/qgsabstractrelationeditorwidget.sip.in +++ b/python/gui/auto_generated/qgsabstractrelationeditorwidget.sip.in @@ -61,6 +61,13 @@ inserting and deleting entries on the intermediate table as required. %Docstring Returns the relation +.. versionadded:: 3.18 +%End + + QgsRelation nmRelation() const; +%Docstring +Returns the nm relation + .. versionadded:: 3.18 %End diff --git a/src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp b/src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp index 1b05818fe53f..9f5f02977884 100644 --- a/src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp +++ b/src/gui/editorwidgets/qgsrelationwidgetwrapper.cpp @@ -268,8 +268,6 @@ void QgsRelationWidgetWrapper::setNmRelationId( const QVariant &nmRelationId ) { if ( mWidget ) { - mWidget->setNmRelationId( nmRelationId ); - mNmRelation = QgsProject::instance()->relationManager()->relation( nmRelationId.toString() ); // If this widget is already embedded by the same relation, reduce functionality diff --git a/src/gui/qgsabstractrelationeditorwidget.cpp b/src/gui/qgsabstractrelationeditorwidget.cpp index 1732652570dd..8ded817e00a4 100644 --- a/src/gui/qgsabstractrelationeditorwidget.cpp +++ b/src/gui/qgsabstractrelationeditorwidget.cpp @@ -22,6 +22,7 @@ #include "qgsfeature.h" #include "qgsfeatureselectiondlg.h" #include "qgsrelation.h" +#include "qgsrelationmanager.h" #include "qgspolymorphicrelation.h" #include "qgsvectorlayertools.h" #include "qgsproject.h" @@ -116,12 +117,14 @@ void QgsAbstractRelationEditorWidget::setFeature( const QgsFeature &feature, boo void QgsAbstractRelationEditorWidget::setNmRelationId( const QVariant &nmRelationId ) { - mNmRelationId = nmRelationId; + QgsRelation nmrelation = QgsProject::instance()->relationManager()->relation( nmRelationId.toString() ); + beforeSetRelations( mRelation, nmrelation ); + mNmRelation = nmrelation; } QVariant QgsAbstractRelationEditorWidget::nmRelationId() const { - return mNmRelationId; + return mNmRelation.id(); } QString QgsAbstractRelationEditorWidget::label() const diff --git a/src/gui/qgsabstractrelationeditorwidget.h b/src/gui/qgsabstractrelationeditorwidget.h index a7f383918aea..a3e44a5a8ced 100644 --- a/src/gui/qgsabstractrelationeditorwidget.h +++ b/src/gui/qgsabstractrelationeditorwidget.h @@ -86,6 +86,12 @@ class GUI_EXPORT QgsAbstractRelationEditorWidget : public QWidget */ QgsRelation relation() const {return mRelation;} + /** + * Returns the nm relation + * \since QGIS 3.18 + */ + QgsRelation nmRelation() const {return mNmRelation;} + /** * Sets the \a feature being edited and updates the UI unless \a update is set to FALSE */ @@ -226,7 +232,6 @@ class GUI_EXPORT QgsAbstractRelationEditorWidget : public QWidget bool mLayerInSameTransactionGroup = false; bool mForceSuppressFormPopup = false; - QVariant mNmRelationId; QString mLabel; /** From d35eb67fac73b0b9fadd471b0a1df838ac9debd1 Mon Sep 17 00:00:00 2001 From: Damiano Date: Thu, 18 Mar 2021 08:34:32 +0100 Subject: [PATCH 209/377] Added two missing calls (afterSetRelations and updateUi) --- src/gui/qgsabstractrelationeditorwidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/qgsabstractrelationeditorwidget.cpp b/src/gui/qgsabstractrelationeditorwidget.cpp index 8ded817e00a4..1299c2d75e50 100644 --- a/src/gui/qgsabstractrelationeditorwidget.cpp +++ b/src/gui/qgsabstractrelationeditorwidget.cpp @@ -120,6 +120,8 @@ void QgsAbstractRelationEditorWidget::setNmRelationId( const QVariant &nmRelatio QgsRelation nmrelation = QgsProject::instance()->relationManager()->relation( nmRelationId.toString() ); beforeSetRelations( mRelation, nmrelation ); mNmRelation = nmrelation; + afterSetRelations(); + updateUi(); } QVariant QgsAbstractRelationEditorWidget::nmRelationId() const From 39d14d06506919c4b56db058b9a98ea2cbb7f965 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Mon, 15 Mar 2021 14:39:43 +0100 Subject: [PATCH 210/377] Allow specifying width and height for GetPrint images ... to override layout provided width and height --- src/server/services/wms/qgswmsrenderer.cpp | 28 +++++++++++++++++- .../src/python/test_qgsserver_wms_getprint.py | 20 +++++++++++++ .../WMS_GetPrint_Size/WMS_GetPrint_Size.png | Bin 0 -> 5053 bytes 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetPrint_Size/WMS_GetPrint_Size.png diff --git a/src/server/services/wms/qgswmsrenderer.cpp b/src/server/services/wms/qgswmsrenderer.cpp index e6164957145e..52689e7fb83a 100644 --- a/src/server/services/wms/qgswmsrenderer.cpp +++ b/src/server/services/wms/qgswmsrenderer.cpp @@ -495,9 +495,35 @@ namespace QgsWms exportSettings.flags |= QgsLayoutRenderContext::FlagDrawSelection; // Destination image size in px QgsLayoutSize layoutSize( layout->pageCollection()->page( 0 )->sizeWithUnits() ); + QgsLayoutMeasurement width( layout->convertFromLayoutUnits( layoutSize.width(), QgsUnitTypes::LayoutUnit::LayoutMillimeters ) ); QgsLayoutMeasurement height( layout->convertFromLayoutUnits( layoutSize.height(), QgsUnitTypes::LayoutUnit::LayoutMillimeters ) ); - exportSettings.imageSize = QSize( static_cast( width.length() * dpi / 25.4 ), static_cast( height.length() * dpi / 25.4 ) ); + + const QSize imageSize = QSize( static_cast( width.length() * dpi / 25.4 ), static_cast( height.length() * dpi / 25.4 ) ); + + const QString paramWidth = mWmsParameters.width(); + const QString paramHeight = mWmsParameters.height(); + + // Prefer width and height from the http request + // Fallback to predefined values from layout + // Preserve aspect ratio if only one value is specified + if ( !paramWidth.isEmpty() && !paramHeight.isEmpty() ) + { + exportSettings.imageSize = QSize( paramWidth.toInt(), paramHeight.toInt() ); + } + else if ( !paramWidth.isEmpty() && paramHeight.isEmpty() ) + { + exportSettings.imageSize = QSize( paramWidth.toInt(), static_cast( paramWidth.toInt() ) / imageSize.width() * imageSize.height() ); + } + else if ( paramWidth.isEmpty() && !paramHeight.isEmpty() ) + { + exportSettings.imageSize = QSize( static_cast( paramHeight.toInt() ) / imageSize.height() * imageSize.width(), paramHeight.toInt() ); + } + else + { + exportSettings.imageSize = imageSize; + } + // Export first page only (unless it's a pdf, see below) exportSettings.pages.append( 0 ); if ( atlas ) diff --git a/tests/src/python/test_qgsserver_wms_getprint.py b/tests/src/python/test_qgsserver_wms_getprint.py index 57a4920bcd35..f12db89bb9bb 100644 --- a/tests/src/python/test_qgsserver_wms_getprint.py +++ b/tests/src/python/test_qgsserver_wms_getprint.py @@ -25,6 +25,8 @@ from test_qgsserver import QgsServerTestBase +from qgis.PyQt.QtCore import QSize + class TestQgsServerWMSGetPrint(QgsServerTestBase): """QGIS Server WMS Tests for GetPrint request""" @@ -274,6 +276,24 @@ def test_wms_getprint_scale(self): r, h = self._result(self._execute_request(qs)) self._img_diff_error(r, h, "WMS_GetPrint_Scale") + def test_wms_getprint_size(self): + qs = "?" + "&".join(["%s=%s" % i for i in list({ + "MAP": urllib.parse.quote(self.projectPath), + "SERVICE": "WMS", + "VERSION": "1.1.1", + "REQUEST": "GetPrint", + "TEMPLATE": "layoutA4", + "FORMAT": "png", + "map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031", + "map0:LAYERS": "Country,Hello", + "map0:SCALE": "36293562", + "CRS": "EPSG:3857", + "HEIGHT": "100" + }.items())]) + + r, h = self._result(self._execute_request(qs)) + self._img_diff_error(r, h, "WMS_GetPrint_Size", max_size_diff=QSize(1, 1)) + def test_wms_getprint_grid(self): qs = "?" + "&".join(["%s=%s" % i for i in list({ "MAP": urllib.parse.quote(self.projectPath), diff --git a/tests/testdata/control_images/qgis_server/WMS_GetPrint_Size/WMS_GetPrint_Size.png b/tests/testdata/control_images/qgis_server/WMS_GetPrint_Size/WMS_GetPrint_Size.png new file mode 100644 index 0000000000000000000000000000000000000000..c95ef962a1ea66b62fd614348e72da284d8a35b0 GIT binary patch literal 5053 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 Zdr93U`Q$1bhSTE!RYfg@S~;7D{{pHRu3`WH literal 0 HcmV?d00001 From aa063a6c4b952e5aca61c9dc0b8a5971979a5f07 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Wed, 17 Mar 2021 18:38:15 +0100 Subject: [PATCH 211/377] Warning when image ratio prevents export --- src/core/layout/qgslayoutexporter.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/layout/qgslayoutexporter.cpp b/src/core/layout/qgslayoutexporter.cpp index d39be77223bf..ca4f920af482 100644 --- a/src/core/layout/qgslayoutexporter.cpp +++ b/src/core/layout/qgslayoutexporter.cpp @@ -199,12 +199,14 @@ QImage QgsLayoutExporter::renderPageToImage( int page, QSize imageSize, double d QRectF paperRect = QRectF( pageItem->pos().x(), pageItem->pos().y(), pageItem->rect().width(), pageItem->rect().height() ); - if ( imageSize.isValid() && ( !qgsDoubleNear( static_cast< double >( imageSize.width() ) / imageSize.height(), - paperRect.width() / paperRect.height(), 0.008 ) ) ) + const double imageAspectRatio = static_cast< double >( imageSize.width() ) / imageSize.height(); + const double paperAspectRatio = paperRect.width() / paperRect.height(); + if ( imageSize.isValid() && ( !qgsDoubleNear( imageAspectRatio, paperAspectRatio, 0.008 ) ) ) { // specified image size is wrong aspect ratio for paper rect - so ignore it and just use dpi // this can happen e.g. as a result of data defined page sizes // see https://github.com/qgis/QGIS/issues/26422 + QgsMessageLog::logMessage( QObject::tr( "Ignoring custom image size because aspect ratio %1 does not match paper ratio %2" ).arg( QString::number( imageAspectRatio, 'g', 3 ), QString::number( paperAspectRatio, 'g', 3 ) ), QStringLiteral( "Layout" ), Qgis::Warning ); imageSize = QSize(); } From 600a215a1c89dd149d020c4633e09ee7efccdc69 Mon Sep 17 00:00:00 2001 From: Matthias Kuhn Date: Thu, 18 Mar 2021 13:12:08 +0100 Subject: [PATCH 212/377] Everybody wears a mask but how long will it last https://www.youtube.com/watch?v=mIue359_ZN4 --- .../WMS_GetPrint_Size/WMS_GetPrint_Size_mask.png | Bin 0 -> 342 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/testdata/control_images/qgis_server/WMS_GetPrint_Size/WMS_GetPrint_Size_mask.png diff --git a/tests/testdata/control_images/qgis_server/WMS_GetPrint_Size/WMS_GetPrint_Size_mask.png b/tests/testdata/control_images/qgis_server/WMS_GetPrint_Size/WMS_GetPrint_Size_mask.png new file mode 100644 index 0000000000000000000000000000000000000000..a8576c0bd0e9b2a0c40f0ffaa1f13a43794b06cc GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^y+EA8!2~2t%2jp%Db50q$YKTt{zMRFTw%XFlYxPe z!_&nvq+-t7i;lbv1`G!r+UglAW(&n7B<^2(a&D8F?D-n~zVi2c37!7DcBVhBJP2+c gc8tfjV-Ix68@8|*$;@kG1_l&^r>mdKI;Vst05D#Qo&W#< literal 0 HcmV?d00001 From 75e76c091fdda274b7862f771d2bbe8d52cbf3b5 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 22 Mar 2021 14:33:28 +1000 Subject: [PATCH 213/377] Fix cannot add qlr from browser (fixes #42366) --- src/app/qgsappbrowserproviders.cpp | 5 +++++ src/app/qgsappbrowserproviders.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/app/qgsappbrowserproviders.cpp b/src/app/qgsappbrowserproviders.cpp index c2006c8fe998..a14121682293 100644 --- a/src/app/qgsappbrowserproviders.cpp +++ b/src/app/qgsappbrowserproviders.cpp @@ -104,6 +104,11 @@ QgsMimeDataUtils::Uri QgsQlrDataItem::mimeUri() const return u; } +QgsMimeDataUtils::UriList QgsQlrDataItem::mimeUris() const +{ + return QgsMimeDataUtils::UriList() << QgsQlrDataItem::mimeUri(); +} + // // QgsQlrDataItemProvider // diff --git a/src/app/qgsappbrowserproviders.h b/src/app/qgsappbrowserproviders.h index f200b810aede..6122fb563b48 100644 --- a/src/app/qgsappbrowserproviders.h +++ b/src/app/qgsappbrowserproviders.h @@ -34,6 +34,7 @@ class QgsQlrDataItem : public QgsLayerItem QgsQlrDataItem( QgsDataItem *parent, const QString &name, const QString &path ); bool hasDragEnabled() const override; QgsMimeDataUtils::Uri mimeUri() const override; + QgsMimeDataUtils::UriList mimeUris() const override; }; From a78f84641295763fb12991adae341865c442e741 Mon Sep 17 00:00:00 2001 From: Andrea Giudiceandrea Date: Mon, 22 Mar 2021 12:36:02 +0100 Subject: [PATCH 214/377] [processing] Fix "Centroids" alg with multipart geometries when the "Create centroid for each part" option is enabled discard incoming fid field and regenerate it See 1b2ca794d2475454b8254c673832c8301370c9dd https://github.com/qgis/QGIS/pull/42363 --- src/analysis/processing/qgsalgorithmcentroid.cpp | 8 ++++++++ src/analysis/processing/qgsalgorithmcentroid.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/analysis/processing/qgsalgorithmcentroid.cpp b/src/analysis/processing/qgsalgorithmcentroid.cpp index b9699897594a..85b4e9be80a6 100644 --- a/src/analysis/processing/qgsalgorithmcentroid.cpp +++ b/src/analysis/processing/qgsalgorithmcentroid.cpp @@ -50,6 +50,14 @@ QString QgsCentroidAlgorithm::outputName() const return QObject::tr( "Centroids" ); } +QgsFeatureSink::SinkFlags QgsCentroidAlgorithm::sinkFlags() const +{ + if ( mAllParts ) + return QgsProcessingFeatureBasedAlgorithm::sinkFlags() | QgsFeatureSink::RegeneratePrimaryKey; + else + return QgsProcessingFeatureBasedAlgorithm::sinkFlags(); +} + QString QgsCentroidAlgorithm::shortHelpString() const { return QObject::tr( "This algorithm creates a new point layer, with points representing the centroid of the geometries in an input layer.\n\n" diff --git a/src/analysis/processing/qgsalgorithmcentroid.h b/src/analysis/processing/qgsalgorithmcentroid.h index f48b59b14f66..3f3074d26bf1 100644 --- a/src/analysis/processing/qgsalgorithmcentroid.h +++ b/src/analysis/processing/qgsalgorithmcentroid.h @@ -51,6 +51,7 @@ class QgsCentroidAlgorithm : public QgsProcessingFeatureBasedAlgorithm QString outputName() const override; QgsProcessing::SourceType outputLayerType() const override { return QgsProcessing::TypeVectorPoint; } QgsWkbTypes::Type outputWkbType( QgsWkbTypes::Type inputWkbType ) const override { Q_UNUSED( inputWkbType ) return QgsWkbTypes::Point; } + QgsFeatureSink::SinkFlags sinkFlags() const override; bool prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; QgsFeatureList processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; From dec4f6e2523e268d673a97a98060190453cbc7b6 Mon Sep 17 00:00:00 2001 From: Andrea Giudiceandrea Date: Mon, 22 Mar 2021 12:57:48 +0100 Subject: [PATCH 215/377] [processing] Centroids: optimize for multipart and better error reporting See 954ad351575e811e69fddc8eb6976ebab52b2988 https://github.com/qgis/QGIS/pull/42363 --- src/analysis/processing/qgsalgorithmcentroid.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/analysis/processing/qgsalgorithmcentroid.cpp b/src/analysis/processing/qgsalgorithmcentroid.cpp index 85b4e9be80a6..92acb39ca709 100644 --- a/src/analysis/processing/qgsalgorithmcentroid.cpp +++ b/src/analysis/processing/qgsalgorithmcentroid.cpp @@ -95,7 +95,7 @@ QgsFeatureList QgsCentroidAlgorithm::processFeature( const QgsFeature &f, QgsPro { QgsFeatureList list; QgsFeature feature = f; - if ( feature.hasGeometry() ) + if ( feature.hasGeometry() && !feature.geometry().isEmpty() ) { QgsGeometry geom = feature.geometry(); @@ -107,14 +107,15 @@ QgsFeatureList QgsCentroidAlgorithm::processFeature( const QgsFeature &f, QgsPro { const QgsGeometryCollection *geomCollection = static_cast( geom.constGet() ); - list.reserve( geomCollection->partCount() ); - for ( int i = 0; i < geomCollection->partCount(); ++i ) + const int partCount = geomCollection->partCount(); + list.reserve( partCount ); + for ( int i = 0; i < partCount; ++i ) { QgsGeometry partGeometry( geomCollection->geometryN( i )->clone() ); QgsGeometry outputGeometry = partGeometry.centroid(); if ( outputGeometry.isNull() ) { - feedback->pushInfo( QObject::tr( "Error calculating centroid for feature %1 part %2: %3" ).arg( feature.id() ).arg( i ).arg( outputGeometry.lastError() ) ); + feedback->reportError( QObject::tr( "Error calculating centroid for feature %1 part %2: %3" ).arg( feature.id() ).arg( i ).arg( outputGeometry.lastError() ) ); } feature.setGeometry( outputGeometry ); list << feature; @@ -125,7 +126,7 @@ QgsFeatureList QgsCentroidAlgorithm::processFeature( const QgsFeature &f, QgsPro QgsGeometry outputGeometry = feature.geometry().centroid(); if ( outputGeometry.isNull() ) { - feedback->pushInfo( QObject::tr( "Error calculating centroid for feature %1: %2" ).arg( feature.id() ).arg( outputGeometry.lastError() ) ); + feedback->reportError( QObject::tr( "Error calculating centroid for feature %1: %2" ).arg( feature.id() ).arg( outputGeometry.lastError() ) ); } feature.setGeometry( outputGeometry ); list << feature; From 3b1f479c5e7b2e7ea6aba0cf8f09bd4ea7e26f92 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 22 Mar 2021 21:11:28 +0100 Subject: [PATCH 216/377] [pyqgis] move constructor docstring after the class docstring --- scripts/sipify.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/sipify.pl b/scripts/sipify.pl index 286e6b79486f..f2d241c55a79 100755 --- a/scripts/sipify.pl +++ b/scripts/sipify.pl @@ -466,7 +466,7 @@ sub fix_annotations { $line =~ s/\bSIP_NODEFAULTCTORS\b/\/NoDefaultCtors\//; $line =~ s/\bSIP_OUT\b/\/Out\//g; $line =~ s/\bSIP_RELEASEGIL\b/\/ReleaseGIL\//; - $line =~ s/\bSIP_HOLDGIL\b/\/HoldGIL\//; + $line =~ s/\bSIP_HOLDGIL\b/\/HoldGIL\//; $line =~ s/\bSIP_TRANSFER\b/\/Transfer\//g; $line =~ s/\bSIP_TRANSFERBACK\b/\/TransferBack\//; $line =~ s/\bSIP_TRANSFERTHIS\b/\/TransferThis\//; @@ -899,7 +899,7 @@ sub detect_non_method_member{ $LINE .= "\n{\n"; if ( $COMMENT !~ m/^\s*$/ ){ - $LINE .= "%Docstring\n$COMMENT\n%End\n"; + $LINE .= "%Docstring(signature=\"appended\")\n$COMMENT\n%End\n"; } $LINE .= "\n%TypeHeaderCode\n#include \"" . basename($headerfile) . "\""; # for template based inheritance, add a typedef to define the base type From e2d5e35ec7b0743c8be2afff0a9b67585ab63637 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 22 Mar 2021 21:13:52 +0100 Subject: [PATCH 217/377] run sipify --- .../qgsabstractmaterialsettings.sip.in | 4 +- .../materials/qgsgoochmaterialsettings.sip.in | 2 +- .../materials/qgsmaterialregistry.sip.in | 4 +- .../materials/qgsnullmaterialsettings.sip.in | 2 +- .../materials/qgsphongmaterialsettings.sip.in | 2 +- .../qgsphongtexturedmaterialsettings.sip.in | 2 +- .../qgssimplelinematerialsettings.sip.in | 2 +- .../processing/qgs3dalgorithms.sip.in | 2 +- python/3d/auto_generated/qgs3d.sip.in | 2 +- .../qgs3dmapexportsettings.sip.in | 2 +- .../3d/auto_generated/qgs3dmapsettings.sip.in | 2 +- python/3d/auto_generated/qgs3dtypes.sip.in | 2 +- .../qgsabstractvectorlayer3drenderer.sip.in | 4 +- python/3d/auto_generated/qgscamerapose.sip.in | 2 +- .../qgsdirectionallightsettings.sip.in | 2 +- .../auto_generated/qgslayoutitem3dmap.sip.in | 2 +- .../qgspointcloudlayer3drenderer.sip.in | 2 +- .../qgspointlightsettings.sip.in | 2 +- .../qgsrulebased3drenderer.sip.in | 6 +- .../qgsvectorlayer3drenderer.sip.in | 4 +- .../symbols/qgsline3dsymbol.sip.in | 2 +- .../symbols/qgspoint3dsymbol.sip.in | 2 +- .../symbols/qgspointcloud3dsymbol.sip.in | 10 +-- .../symbols/qgspolygon3dsymbol.sip.in | 2 +- .../qgsgcpgeometrytransformer.sip.in | 2 +- .../georeferencing/qgsgcptransformer.sip.in | 2 +- .../interpolation/qgsgridfilewriter.sip.in | 2 +- .../interpolation/qgsidwinterpolator.sip.in | 2 +- .../interpolation/qgsinterpolator.sip.in | 2 +- .../interpolation/qgstininterpolator.sip.in | 2 +- .../mesh/qgsmeshcontours.sip.in | 2 +- .../mesh/qgsmeshtriangulation.sip.in | 4 +- .../auto_generated/network/qgsgraph.sip.in | 6 +- .../network/qgsgraphanalyzer.sip.in | 2 +- .../network/qgsgraphbuilder.sip.in | 2 +- .../network/qgsgraphbuilderinterface.sip.in | 2 +- .../network/qgsgraphdirector.sip.in | 2 +- .../network/qgsnetworkdistancestrategy.sip.in | 2 +- .../network/qgsnetworkspeedstrategy.sip.in | 2 +- .../network/qgsnetworkstrategy.sip.in | 2 +- .../network/qgsvectorlayerdirector.sip.in | 2 +- .../qgsalgorithmbatchgeocode.sip.in | 2 +- .../processing/qgsnativealgorithms.sip.in | 2 +- .../auto_generated/qgsanalysis.sip.in | 2 +- .../raster/qgsalignraster.sip.in | 2 +- .../raster/qgsaspectfilter.sip.in | 2 +- .../raster/qgsderivativefilter.sip.in | 2 +- .../auto_generated/raster/qgsexiftools.sip.in | 4 +- .../raster/qgshillshadefilter.sip.in | 2 +- .../auto_generated/raster/qgskde.sip.in | 2 +- .../raster/qgsninecellfilter.sip.in | 2 +- .../raster/qgsrastercalcnode.sip.in | 2 +- .../raster/qgsrastercalculator.sip.in | 4 +- .../raster/qgsrastermatrix.sip.in | 2 +- .../auto_generated/raster/qgsrelief.sip.in | 2 +- .../raster/qgsruggednessfilter.sip.in | 2 +- .../raster/qgsslopefilter.sip.in | 2 +- .../raster/qgstotalcurvaturefilter.sip.in | 2 +- .../geometry_checker/qgsfeaturepool.sip.in | 2 +- .../geometry_checker/qgsgeometrycheck.sip.in | 2 +- .../qgsgeometrycheckcontext.sip.in | 2 +- .../qgsgeometrycheckerror.sip.in | 2 +- .../qgsgeometrycheckerutils.sip.in | 6 +- .../qgsgeometrycheckfactory.sip.in | 4 +- .../qgsgeometrycheckregistry.sip.in | 2 +- .../qgsgeometrycheckresolutionmethod.sip.in | 2 +- .../qgssinglegeometrycheck.sip.in | 6 +- .../vector/qgsgeometrysnapper.sip.in | 4 +- .../qgsgeometrysnappersinglesource.sip.in | 2 +- .../vector/qgszonalstatistics.sip.in | 2 +- .../3d/qgs3drendererregistry.sip.in | 4 +- .../3d/qgs3dsymbolregistry.sip.in | 4 +- .../3d/qgsabstract3drenderer.sip.in | 2 +- .../3d/qgsabstract3dsymbol.sip.in | 2 +- .../annotations/qgsannotation.sip.in | 2 +- .../annotations/qgsannotationitem.sip.in | 2 +- .../qgsannotationitemregistry.sip.in | 4 +- .../annotations/qgsannotationlayer.sip.in | 2 +- .../annotations/qgsannotationlineitem.sip.in | 2 +- .../annotations/qgsannotationmanager.sip.in | 2 +- .../qgsannotationmarkeritem.sip.in | 2 +- .../qgsannotationpointtextitem.sip.in | 2 +- .../qgsannotationpolygonitem.sip.in | 2 +- .../annotations/qgshtmlannotation.sip.in | 2 +- .../annotations/qgssvgannotation.sip.in | 2 +- .../annotations/qgstextannotation.sip.in | 2 +- .../auth/qgsauthcertutils.sip.in | 2 +- .../auto_generated/auth/qgsauthconfig.sip.in | 8 +- .../auto_generated/auth/qgsauthmanager.sip.in | 2 +- .../auto_generated/auth/qgsauthmethod.sip.in | 2 +- .../auto_generated/callouts/qgscallout.sip.in | 12 +-- .../callouts/qgscalloutsregistry.sip.in | 6 +- .../qgsclassificationcustom.sip.in | 2 +- .../qgsclassificationequalinterval.sip.in | 2 +- .../qgsclassificationjenks.sip.in | 2 +- .../qgsclassificationlogarithmic.sip.in | 2 +- .../qgsclassificationmethod.sip.in | 4 +- .../qgsclassificationmethodregistry.sip.in | 2 +- .../qgsclassificationprettybreaks.sip.in | 2 +- .../qgsclassificationquantile.sip.in | 2 +- .../qgsclassificationstandarddeviation.sip.in | 2 +- .../auto_generated/diagram/qgsdiagram.sip.in | 2 +- .../diagram/qgshistogramdiagram.sip.in | 2 +- .../diagram/qgspiediagram.sip.in | 2 +- .../diagram/qgsstackedbardiagram.sip.in | 2 +- .../diagram/qgstextdiagram.sip.in | 2 +- .../auto_generated/dxf/qgsdxfexport.sip.in | 2 +- .../qgsattributeeditorcontainer.sip.in | 2 +- .../editform/qgsattributeeditorelement.sip.in | 2 +- .../editform/qgsattributeeditorfield.sip.in | 2 +- .../qgsattributeeditorhtmlelement.sip.in | 2 +- .../qgsattributeeditorqmlelement.sip.in | 2 +- .../qgsattributeeditorrelation.sip.in | 2 +- .../editform/qgseditformconfig.sip.in | 2 +- .../effects/qgsblureffect.sip.in | 2 +- .../effects/qgscoloreffect.sip.in | 2 +- .../effects/qgseffectstack.sip.in | 2 +- .../effects/qgsgloweffect.sip.in | 6 +- .../effects/qgsimageoperation.sip.in | 2 +- .../effects/qgspainteffect.sip.in | 6 +- .../effects/qgspainteffectregistry.sip.in | 4 +- .../effects/qgsshadoweffect.sip.in | 6 +- .../effects/qgstransformeffect.sip.in | 2 +- .../expression/qgsexpression.sip.in | 2 +- .../qgsexpressioncontextutils.sip.in | 2 +- .../expression/qgsexpressionfunction.sip.in | 4 +- .../expression/qgsexpressionnode.sip.in | 4 +- .../expression/qgsexpressionnodeimpl.sip.in | 18 ++-- .../qgscheckboxfieldformatter.sip.in | 2 +- .../qgsdatetimefieldformatter.sip.in | 2 +- .../qgsfallbackfieldformatter.sip.in | 2 +- .../qgskeyvaluefieldformatter.sip.in | 2 +- .../qgslistfieldformatter.sip.in | 2 +- .../qgsrangefieldformatter.sip.in | 2 +- .../qgsrelationreferencefieldformatter.sip.in | 2 +- .../qgsvaluemapfieldformatter.sip.in | 2 +- .../qgsvaluerelationfieldformatter.sip.in | 2 +- .../geonode/qgsgeonodeconnection.sip.in | 4 +- .../geocms/geonode/qgsgeonoderequest.sip.in | 2 +- .../qgsabstractgeocoderlocatorfilter.sip.in | 2 +- .../geocoding/qgsgeocoder.sip.in | 2 +- .../geocoding/qgsgeocodercontext.sip.in | 2 +- .../geocoding/qgsgeocoderresult.sip.in | 2 +- .../geocoding/qgsgooglemapsgeocoder.sip.in | 2 +- .../geocoding/qgsnominatimgeocoder.sip.in | 2 +- .../geometry/qgsabstractgeometry.sip.in | 8 +- .../auto_generated/geometry/qgsbox3d.sip.in | 2 +- .../auto_generated/geometry/qgscircle.sip.in | 2 +- .../geometry/qgscircularstring.sip.in | 2 +- .../geometry/qgscompoundcurve.sip.in | 2 +- .../auto_generated/geometry/qgscurve.sip.in | 2 +- .../geometry/qgscurvepolygon.sip.in | 2 +- .../auto_generated/geometry/qgsellipse.sip.in | 2 +- .../geometry/qgsgeometry.sip.in | 4 +- .../geometry/qgsgeometrycollection.sip.in | 2 +- .../geometry/qgsgeometryengine.sip.in | 2 +- .../geometry/qgsgeometrytransformer.sip.in | 2 +- .../geometry/qgsgeometryutils.sip.in | 2 +- .../geometry/qgslinesegment.sip.in | 2 +- .../geometry/qgslinestring.sip.in | 2 +- .../geometry/qgsmulticurve.sip.in | 2 +- .../geometry/qgsmultilinestring.sip.in | 2 +- .../geometry/qgsmultipoint.sip.in | 2 +- .../geometry/qgsmultipolygon.sip.in | 2 +- .../geometry/qgsmultisurface.sip.in | 2 +- .../auto_generated/geometry/qgspoint.sip.in | 2 +- .../auto_generated/geometry/qgspolygon.sip.in | 2 +- .../geometry/qgsquadrilateral.sip.in | 2 +- .../auto_generated/geometry/qgsray3d.sip.in | 2 +- .../geometry/qgsrectangle.sip.in | 2 +- .../geometry/qgsreferencedgeometry.sip.in | 8 +- .../geometry/qgsregularpolygon.sip.in | 2 +- .../auto_generated/geometry/qgssurface.sip.in | 2 +- .../geometry/qgstriangle.sip.in | 2 +- .../auto_generated/geometry/qgswkbptr.sip.in | 4 +- .../geometry/qgswkbtypes.sip.in | 2 +- .../gps/qgsgpsconnection.sip.in | 6 +- .../gps/qgsgpsconnectionregistry.sip.in | 2 +- .../gps/qgsgpsdconnection.sip.in | 2 +- .../auto_generated/gps/qgsgpsdetector.sip.in | 2 +- .../gps/qgsnmeaconnection.sip.in | 2 +- .../gps/qgsqtlocationconnection.sip.in | 2 +- .../labeling/qgscalloutposition.sip.in | 2 +- .../labeling/qgslabeling.sip.in | 2 +- .../labeling/qgslabelingenginesettings.sip.in | 2 +- .../labeling/qgslabelingresults.sip.in | 2 +- .../labeling/qgslabellinesettings.sip.in | 2 +- .../labeling/qgslabelobstaclesettings.sip.in | 2 +- .../labeling/qgslabelposition.sip.in | 2 +- .../labeling/qgslabelsearchtree.sip.in | 2 +- .../labeling/qgslabelthinningsettings.sip.in | 2 +- .../labeling/qgspallabeling.sip.in | 6 +- .../labeling/qgsrulebasedlabeling.sip.in | 4 +- .../labeling/qgsvectorlayerlabeling.sip.in | 4 +- .../layertree/qgscolorramplegendnode.sip.in | 2 +- .../qgscolorramplegendnodesettings.sip.in | 2 +- .../layertree/qgslayertree.sip.in | 2 +- .../qgslayertreefilterproxymodel.sip.in | 2 +- .../layertree/qgslayertreegroup.sip.in | 2 +- .../layertree/qgslayertreelayer.sip.in | 2 +- .../layertree/qgslayertreemodel.sip.in | 2 +- .../qgslayertreemodellegendnode.sip.in | 14 +-- .../layertree/qgslayertreenode.sip.in | 2 +- .../qgslayertreeregistrybridge.sip.in | 2 +- .../layertree/qgslayertreeutils.sip.in | 2 +- .../layertree/qgslegendpatchshape.sip.in | 2 +- .../layout/qgsabstractlayoutiterator.sip.in | 2 +- .../layout/qgsabstractreportsection.sip.in | 4 +- .../auto_generated/layout/qgslayout.sip.in | 2 +- .../layout/qgslayoutaligner.sip.in | 2 +- .../layout/qgslayoutatlas.sip.in | 2 +- .../layout/qgslayouteffect.sip.in | 2 +- .../layout/qgslayoutexporter.sip.in | 2 +- .../layout/qgslayoutframe.sip.in | 2 +- .../layout/qgslayoutgridsettings.sip.in | 2 +- .../layout/qgslayoutguidecollection.sip.in | 6 +- .../layout/qgslayoutitem.sip.in | 4 +- .../layout/qgslayoutitemattributetable.sip.in | 2 +- .../layout/qgslayoutitemgroup.sip.in | 2 +- .../layout/qgslayoutitemhtml.sip.in | 2 +- .../layout/qgslayoutitemlabel.sip.in | 2 +- .../layout/qgslayoutitemlegend.sip.in | 4 +- .../layout/qgslayoutitemmanualtable.sip.in | 2 +- .../layout/qgslayoutitemmap.sip.in | 6 +- .../layout/qgslayoutitemmapgrid.sip.in | 4 +- .../layout/qgslayoutitemmapitem.sip.in | 4 +- .../layout/qgslayoutitemmapoverview.sip.in | 4 +- .../layout/qgslayoutitemmarker.sip.in | 2 +- .../layout/qgslayoutitemnodeitem.sip.in | 2 +- .../layout/qgslayoutitempage.sip.in | 2 +- .../layout/qgslayoutitempicture.sip.in | 2 +- .../layout/qgslayoutitempolygon.sip.in | 2 +- .../layout/qgslayoutitempolyline.sip.in | 2 +- .../layout/qgslayoutitemregistry.sip.in | 6 +- .../layout/qgslayoutitemscalebar.sip.in | 2 +- .../layout/qgslayoutitemshape.sip.in | 2 +- .../layout/qgslayoutitemtexttable.sip.in | 2 +- .../layout/qgslayoutmanager.sip.in | 6 +- .../layout/qgslayoutmeasurement.sip.in | 2 +- .../qgslayoutmeasurementconverter.sip.in | 2 +- .../layout/qgslayoutmodel.sip.in | 4 +- .../layout/qgslayoutmultiframe.sip.in | 2 +- .../layout/qgslayoutnortharrowhandler.sip.in | 2 +- .../layout/qgslayoutobject.sip.in | 2 +- .../layout/qgslayoutpagecollection.sip.in | 2 +- .../layout/qgslayoutpoint.sip.in | 2 +- .../layout/qgslayoutrendercontext.sip.in | 2 +- .../layout/qgslayoutreportcontext.sip.in | 2 +- .../layout/qgslayoutserializableobject.sip.in | 2 +- .../layout/qgslayoutsize.sip.in | 2 +- .../layout/qgslayoutsnapper.sip.in | 2 +- .../layout/qgslayouttable.sip.in | 4 +- .../layout/qgslayouttablecolumn.sip.in | 2 +- .../layout/qgslayoutundocommand.sip.in | 4 +- .../layout/qgslayoutundostack.sip.in | 2 +- .../layout/qgslayoututils.sip.in | 2 +- .../layout/qgsmasterlayoutinterface.sip.in | 2 +- .../layout/qgspagesizeregistry.sip.in | 4 +- .../layout/qgsprintlayout.sip.in | 2 +- .../auto_generated/layout/qgsreport.sip.in | 2 +- .../layout/qgsreportsectionfieldgroup.sip.in | 2 +- .../layout/qgsreportsectionlayout.sip.in | 2 +- .../auto_generated/locator/qgslocator.sip.in | 2 +- .../locator/qgslocatorcontext.sip.in | 2 +- .../locator/qgslocatorfilter.sip.in | 4 +- .../locator/qgslocatormodel.sip.in | 6 +- .../locator/qgslocatormodelbridge.sip.in | 2 +- .../mesh/qgsmesh3daveraging.sip.in | 10 +-- .../mesh/qgsmeshcalculator.sip.in | 2 +- .../mesh/qgsmeshdataprovider.sip.in | 6 +- ...eshdataprovidertemporalcapabilities.sip.in | 2 +- .../auto_generated/mesh/qgsmeshdataset.sip.in | 18 ++-- .../auto_generated/mesh/qgsmeshlayer.sip.in | 2 +- .../qgsmeshlayertemporalproperties.sip.in | 2 +- .../mesh/qgsmeshrenderersettings.sip.in | 14 +-- .../mesh/qgsmeshspatialindex.sip.in | 2 +- .../mesh/qgsmeshtimesettings.sip.in | 2 +- .../mesh/qgsmeshtracerenderer.sip.in | 2 +- .../metadata/qgsabstractmetadatabase.sip.in | 2 +- .../metadata/qgslayermetadata.sip.in | 2 +- .../metadata/qgslayermetadataformatter.sip.in | 2 +- .../metadata/qgslayermetadatavalidator.sip.in | 10 +-- .../metadata/qgsprojectmetadata.sip.in | 2 +- .../network/qgsblockingnetworkrequest.sip.in | 2 +- .../network/qgsfiledownloader.sip.in | 2 +- .../network/qgsnetworkaccessmanager.sip.in | 4 +- .../network/qgsnetworkcontentfetcher.sip.in | 2 +- .../qgsnetworkcontentfetcherregistry.sip.in | 4 +- .../qgsnetworkcontentfetchertask.sip.in | 2 +- .../network/qgsnetworkreply.sip.in | 2 +- .../network/qgsnewsfeedmodel.sip.in | 4 +- .../network/qgsnewsfeedparser.sip.in | 4 +- .../qgsbasicnumericformat.sip.in | 2 +- .../qgsbearingnumericformat.sip.in | 2 +- .../qgscurrencynumericformat.sip.in | 2 +- .../qgsfallbacknumericformat.sip.in | 2 +- .../qgsfractionnumericformat.sip.in | 2 +- .../numericformats/qgsnumericformat.sip.in | 4 +- .../qgsnumericformatregistry.sip.in | 2 +- .../qgspercentagenumericformat.sip.in | 2 +- .../qgsscientificnumericformat.sip.in | 2 +- .../pointcloud/qgspointcloudattribute.sip.in | 4 +- ...gspointcloudattributebyramprenderer.sip.in | 2 +- .../qgspointcloudattributemodel.sip.in | 4 +- .../pointcloud/qgspointcloudblock.sip.in | 2 +- .../qgspointcloudclassifiedrenderer.sip.in | 4 +- .../qgspointclouddataprovider.sip.in | 2 +- .../qgspointcloudextentrenderer.sip.in | 2 +- .../pointcloud/qgspointcloudlayer.sip.in | 2 +- ...spointcloudlayerelevationproperties.sip.in | 2 +- .../pointcloud/qgspointcloudrenderer.sip.in | 4 +- .../qgspointcloudrendererregistry.sip.in | 6 +- .../qgspointcloudrgbrenderer.sip.in | 2 +- .../models/qgsprocessingmodelalgorithm.sip.in | 4 +- .../qgsprocessingmodelchildalgorithm.sip.in | 2 +- .../qgsprocessingmodelchilddependency.sip.in | 2 +- ...processingmodelchildparametersource.sip.in | 2 +- .../models/qgsprocessingmodelcomment.sip.in | 2 +- .../models/qgsprocessingmodelcomponent.sip.in | 2 +- .../models/qgsprocessingmodelgroupbox.sip.in | 2 +- .../models/qgsprocessingmodeloutput.sip.in | 2 +- .../models/qgsprocessingmodelparameter.sip.in | 2 +- .../processing/qgsprocessing.sip.in | 2 +- .../processing/qgsprocessingalgorithm.sip.in | 4 +- .../qgsprocessingalgrunnertask.sip.in | 2 +- .../processing/qgsprocessingcontext.sip.in | 6 +- .../processing/qgsprocessingfeedback.sip.in | 4 +- .../processing/qgsprocessingoutputs.sip.in | 24 +++--- .../qgsprocessingparameteraggregate.sip.in | 2 +- .../qgsprocessingparameterdxflayers.sip.in | 2 +- .../qgsprocessingparameterfieldmap.sip.in | 2 +- .../qgsprocessingparametermeshdataset.sip.in | 4 +- .../processing/qgsprocessingparameters.sip.in | 86 +++++++++---------- ...gsprocessingparametertininputlayers.sip.in | 2 +- .../qgsprocessingparametertype.sip.in | 2 +- ...singparametervectortilewriterlayers.sip.in | 2 +- .../processing/qgsprocessingprovider.sip.in | 2 +- .../processing/qgsprocessingregistry.sip.in | 2 +- .../processing/qgsprocessingutils.sip.in | 4 +- .../auto_generated/project/qgsproject.sip.in | 4 +- .../project/qgsprojectbadlayerhandler.sip.in | 2 +- .../project/qgsprojectdisplaysettings.sip.in | 2 +- .../project/qgsprojectfiletransform.sip.in | 2 +- .../project/qgsprojectproperty.sip.in | 6 +- .../project/qgsprojectservervalidator.sip.in | 2 +- .../project/qgsprojectstorage.sip.in | 4 +- .../project/qgsprojectstorageregistry.sip.in | 2 +- .../project/qgsprojecttimesettings.sip.in | 2 +- .../project/qgsprojecttranslator.sip.in | 2 +- .../project/qgsprojectversion.sip.in | 2 +- .../project/qgsprojectviewsettings.sip.in | 2 +- .../arcgis/qgsarcgisportalutils.sip.in | 2 +- .../arcgis/qgsarcgisrestutils.sip.in | 2 +- .../memory/qgsmemoryproviderutils.sip.in | 2 +- python/core/auto_generated/qgis.sip.in | 2 +- .../qgsabstractcontentcache.sip.in | 4 +- ...sabstractdatabaseproviderconnection.sip.in | 2 +- .../qgsabstractproviderconnection.sip.in | 2 +- python/core/auto_generated/qgsaction.sip.in | 2 +- .../auto_generated/qgsactionmanager.sip.in | 2 +- .../core/auto_generated/qgsactionscope.sip.in | 2 +- .../qgsactionscoperegistry.sip.in | 2 +- .../qgsaggregatecalculator.sip.in | 2 +- .../auto_generated/qgsanimatedicon.sip.in | 2 +- .../core/auto_generated/qgsapplication.sip.in | 2 +- python/core/auto_generated/qgsarchive.sip.in | 4 +- .../qgsattributetableconfig.sip.in | 2 +- .../auto_generated/qgsauxiliarystorage.sip.in | 4 +- .../auto_generated/qgsbearingutils.sip.in | 2 +- .../auto_generated/qgsbookmarkmanager.sip.in | 4 +- .../auto_generated/qgsbookmarkmodel.sip.in | 4 +- .../auto_generated/qgsbrowsermodel.sip.in | 2 +- .../qgsbrowserproxymodel.sip.in | 2 +- .../qgscachedfeatureiterator.sip.in | 4 +- .../core/auto_generated/qgscacheindex.sip.in | 2 +- python/core/auto_generated/qgscadutils.sip.in | 2 +- python/core/auto_generated/qgsclipper.sip.in | 2 +- .../core/auto_generated/qgscolorramp.sip.in | 14 +-- .../core/auto_generated/qgscolorscheme.sip.in | 12 +-- .../qgscolorschemeregistry.sip.in | 2 +- .../auto_generated/qgsconditionalstyle.sip.in | 4 +- .../qgsconnectionregistry.sip.in | 2 +- .../qgscoordinateformatter.sip.in | 2 +- .../qgscoordinatereferencesystem.sip.in | 2 +- ...gscoordinatereferencesystemregistry.sip.in | 4 +- .../qgscoordinatetransform.sip.in | 2 +- .../qgscoordinatetransformcontext.sip.in | 2 +- .../core/auto_generated/qgscredentials.sip.in | 6 +- .../qgsdatabaseschemamodel.sip.in | 2 +- .../qgsdatabasetablemodel.sip.in | 2 +- .../qgsdatadefinedsizelegend.sip.in | 2 +- python/core/auto_generated/qgsdataitem.sip.in | 26 +++--- .../auto_generated/qgsdataitemprovider.sip.in | 2 +- .../qgsdataitemproviderregistry.sip.in | 2 +- .../auto_generated/qgsdataprovider.sip.in | 2 +- ...qgsdataprovidertemporalcapabilities.sip.in | 2 +- .../auto_generated/qgsdatasourceuri.sip.in | 2 +- .../qgsdatetimestatisticalsummary.sip.in | 2 +- .../auto_generated/qgsdatumtransform.sip.in | 2 +- .../qgsdbfilterproxymodel.sip.in | 2 +- .../auto_generated/qgsdefaultvalue.sip.in | 2 +- .../auto_generated/qgsdiagramrenderer.sip.in | 10 +-- .../auto_generated/qgsdistancearea.sip.in | 2 +- .../qgseditorwidgetsetup.sip.in | 2 +- .../auto_generated/qgselevationutils.sip.in | 2 +- .../auto_generated/qgsellipsoidutils.sip.in | 2 +- python/core/auto_generated/qgserror.sip.in | 4 +- .../qgsexpressioncontext.sip.in | 6 +- .../qgsexpressioncontextgenerator.sip.in | 2 +- .../qgsexpressioncontextscopegenerator.sip.in | 2 +- .../qgsexpressionfieldbuffer.sip.in | 2 +- python/core/auto_generated/qgsfeature.sip.in | 2 +- .../qgsfeaturefiltermodel.sip.in | 2 +- .../qgsfeaturefilterprovider.sip.in | 2 +- .../auto_generated/qgsfeatureiterator.sip.in | 6 +- .../qgsfeaturepickermodel.sip.in | 2 +- .../qgsfeaturepickermodelbase.sip.in | 2 +- .../auto_generated/qgsfeaturerequest.sip.in | 8 +- .../core/auto_generated/qgsfeaturesink.sip.in | 2 +- .../auto_generated/qgsfeaturesource.sip.in | 2 +- .../auto_generated/qgsfeaturestore.sip.in | 2 +- python/core/auto_generated/qgsfeedback.sip.in | 2 +- python/core/auto_generated/qgsfield.sip.in | 2 +- .../auto_generated/qgsfieldconstraints.sip.in | 2 +- .../auto_generated/qgsfieldformatter.sip.in | 4 +- .../qgsfieldformatterregistry.sip.in | 2 +- .../core/auto_generated/qgsfieldmodel.sip.in | 2 +- .../auto_generated/qgsfieldproxymodel.sip.in | 2 +- python/core/auto_generated/qgsfields.sip.in | 2 +- .../qgsfilefiltergenerator.sip.in | 2 +- .../core/auto_generated/qgsfileutils.sip.in | 2 +- .../auto_generated/qgsgeometryoptions.sip.in | 2 +- .../qgsgeometrysimplifier.sip.in | 4 +- python/core/auto_generated/qgsgml.sip.in | 2 +- .../core/auto_generated/qgsgmlschema.sip.in | 2 +- .../core/auto_generated/qgshistogram.sip.in | 2 +- .../core/auto_generated/qgshtmlutils.sip.in | 2 +- .../auto_generated/qgsidentifycontext.sip.in | 2 +- .../core/auto_generated/qgsimagecache.sip.in | 2 +- python/core/auto_generated/qgsinterval.sip.in | 2 +- .../core/auto_generated/qgsjsonutils.sip.in | 4 +- .../auto_generated/qgslayerdefinition.sip.in | 4 +- .../auto_generated/qgslegendrenderer.sip.in | 2 +- .../auto_generated/qgslegendsettings.sip.in | 2 +- .../core/auto_generated/qgslegendstyle.sip.in | 2 +- .../qgslocaldefaultsettings.sip.in | 2 +- .../qgslocalizeddatapathregistry.sip.in | 2 +- python/core/auto_generated/qgslogger.sip.in | 2 +- .../qgsmapclippingregion.sip.in | 2 +- .../auto_generated/qgsmapclippingutils.sip.in | 2 +- .../auto_generated/qgsmapdecoration.sip.in | 2 +- .../core/auto_generated/qgsmaphittest.sip.in | 2 +- python/core/auto_generated/qgsmaplayer.sip.in | 2 +- .../qgsmaplayerdependency.sip.in | 2 +- .../qgsmaplayerelevationproperties.sip.in | 2 +- .../auto_generated/qgsmaplayerfactory.sip.in | 2 +- .../auto_generated/qgsmaplayerlegend.sip.in | 12 +-- .../auto_generated/qgsmaplayermodel.sip.in | 2 +- .../qgsmaplayerproxymodel.sip.in | 2 +- .../auto_generated/qgsmaplayerrenderer.sip.in | 2 +- .../auto_generated/qgsmaplayerstore.sip.in | 2 +- .../auto_generated/qgsmaplayerstyle.sip.in | 4 +- .../qgsmaplayerstylemanager.sip.in | 2 +- .../qgsmaplayertemporalproperties.sip.in | 2 +- .../auto_generated/qgsmaprenderercache.sip.in | 2 +- .../qgsmaprenderercustompainterjob.sip.in | 4 +- .../auto_generated/qgsmaprendererjob.sip.in | 4 +- .../qgsmaprendererparalleljob.sip.in | 2 +- .../qgsmaprenderersequentialjob.sip.in | 2 +- .../auto_generated/qgsmaprenderertask.sip.in | 2 +- .../core/auto_generated/qgsmapsettings.sip.in | 4 +- .../auto_generated/qgsmapsettingsutils.sip.in | 2 +- .../qgsmapthemecollection.sip.in | 6 +- .../core/auto_generated/qgsmaptopixel.sip.in | 2 +- .../qgsmaptopixelgeometrysimplifier.sip.in | 2 +- .../auto_generated/qgsmapunitscale.sip.in | 2 +- .../auto_generated/qgsmaskidprovider.sip.in | 2 +- .../core/auto_generated/qgsmessagelog.sip.in | 6 +- .../auto_generated/qgsmessageoutput.sip.in | 4 +- .../qgsmultirenderchecker.sip.in | 4 +- .../qgsobjectcustomproperties.sip.in | 2 +- python/core/auto_generated/qgsogcutils.sip.in | 2 +- python/core/auto_generated/qgsoptional.sip.in | 2 +- .../qgsoptionalexpression.sip.in | 2 +- .../auto_generated/qgsowsconnection.sip.in | 2 +- .../auto_generated/qgspaintenginehack.sip.in | 2 +- python/core/auto_generated/qgspainting.sip.in | 2 +- .../auto_generated/qgspathresolver.sip.in | 2 +- .../core/auto_generated/qgspluginlayer.sip.in | 2 +- .../qgspluginlayerregistry.sip.in | 4 +- .../auto_generated/qgspointlocator.sip.in | 2 +- python/core/auto_generated/qgspointxy.sip.in | 2 +- .../qgspolymorphicrelation.sip.in | 2 +- .../qgspostgresstringutils.sip.in | 2 +- .../core/auto_generated/qgsprojutils.sip.in | 2 +- python/core/auto_generated/qgsproperty.sip.in | 4 +- .../qgspropertycollection.sip.in | 6 +- .../qgspropertytransformer.sip.in | 10 +-- .../qgsproviderconnectionmodel.sip.in | 2 +- .../auto_generated/qgsprovidermetadata.sip.in | 4 +- .../auto_generated/qgsproviderregistry.sip.in | 8 +- .../auto_generated/qgsproxyfeaturesink.sip.in | 2 +- .../qgsproxyprogresstask.sip.in | 4 +- .../auto_generated/qgspythonrunner.sip.in | 2 +- .../auto_generated/qgsqueryresultmodel.sip.in | 2 +- python/core/auto_generated/qgsrange.sip.in | 8 +- .../auto_generated/qgsreadwritecontext.sip.in | 4 +- .../auto_generated/qgsreadwritelocker.sip.in | 2 +- .../auto_generated/qgsrelationcontext.sip.in | 2 +- .../auto_generated/qgsrelationmanager.sip.in | 2 +- .../qgsremappingproxyfeaturesink.sip.in | 4 +- .../auto_generated/qgsrenderchecker.sip.in | 2 +- .../auto_generated/qgsrendercontext.sip.in | 2 +- .../qgsrenderedfeaturehandlerinterface.sip.in | 2 +- .../core/auto_generated/qgsrunprocess.sip.in | 4 +- .../auto_generated/qgsruntimeprofiler.sip.in | 4 +- .../auto_generated/qgsscalecalculator.sip.in | 2 +- python/core/auto_generated/qgssettings.sip.in | 2 +- .../auto_generated/qgssimplifymethod.sip.in | 2 +- .../auto_generated/qgssnappingconfig.sip.in | 4 +- .../auto_generated/qgssnappingutils.sip.in | 2 +- .../core/auto_generated/qgssourcecache.sip.in | 2 +- .../auto_generated/qgsspatialindex.sip.in | 2 +- .../qgsspatialindexkdbush.sip.in | 2 +- .../qgsspatialindexkdbushdata.sip.in | 2 +- .../core/auto_generated/qgssqliteutils.sip.in | 2 +- .../auto_generated/qgssqlstatement.sip.in | 38 ++++---- .../qgsstatisticalsummary.sip.in | 2 +- .../qgsstoredexpressionmanager.sip.in | 2 +- .../qgsstringstatisticalsummary.sip.in | 2 +- .../core/auto_generated/qgsstringutils.sip.in | 6 +- .../core/auto_generated/qgstablecell.sip.in | 2 +- .../core/auto_generated/qgstaskmanager.sip.in | 4 +- .../qgstemporalcontroller.sip.in | 2 +- .../qgstemporalnavigationobject.sip.in | 2 +- .../auto_generated/qgstemporalproperty.sip.in | 2 +- .../qgstemporalrangeobject.sip.in | 2 +- .../auto_generated/qgstemporalutils.sip.in | 2 +- .../core/auto_generated/qgstessellator.sip.in | 2 +- python/core/auto_generated/qgstiles.sip.in | 6 +- .../core/auto_generated/qgstolerance.sip.in | 2 +- python/core/auto_generated/qgstracer.sip.in | 2 +- .../core/auto_generated/qgstransaction.sip.in | 2 +- .../qgstranslationcontext.sip.in | 2 +- .../core/auto_generated/qgsunittypes.sip.in | 2 +- .../core/auto_generated/qgsuserprofile.sip.in | 2 +- .../qgsuserprofilemanager.sip.in | 2 +- python/core/auto_generated/qgsvector.sip.in | 2 +- python/core/auto_generated/qgsvector3d.sip.in | 2 +- .../auto_generated/qgsvectorfilewriter.sip.in | 6 +- .../qgsvectorfilewritertask.sip.in | 2 +- .../qgsvectorsimplifymethod.sip.in | 2 +- .../qgsvirtuallayerdefinition.sip.in | 4 +- .../qgsvirtuallayerdefinitionutils.sip.in | 2 +- .../auto_generated/qgsvirtuallayertask.sip.in | 2 +- python/core/auto_generated/qgsxmlutils.sip.in | 2 +- .../raster/qgsbilinearrasterresampler.sip.in | 2 +- .../raster/qgsbrightnesscontrastfilter.sip.in | 2 +- .../raster/qgscliptominmaxenhancement.sip.in | 2 +- .../raster/qgscolorrampshader.sip.in | 2 +- .../raster/qgscontrastenhancement.sip.in | 2 +- .../qgscontrastenhancementfunction.sip.in | 2 +- .../raster/qgscubicrasterresampler.sip.in | 2 +- .../raster/qgshillshaderenderer.sip.in | 2 +- .../raster/qgshuesaturationfilter.sip.in | 2 +- .../raster/qgslinearminmaxenhancement.sip.in | 2 +- .../qgslinearminmaxenhancementwithclip.sip.in | 2 +- .../raster/qgsmultibandcolorrenderer.sip.in | 2 +- .../raster/qgspalettedrasterrenderer.sip.in | 2 +- .../auto_generated/raster/qgsraster.sip.in | 2 +- .../raster/qgsrasterbandstats.sip.in | 2 +- .../raster/qgsrasterblock.sip.in | 2 +- .../raster/qgsrasterchecker.sip.in | 2 +- .../raster/qgsrastercontourrenderer.sip.in | 2 +- .../raster/qgsrasterdataprovider.sip.in | 4 +- ...terdataprovidertemporalcapabilities.sip.in | 2 +- .../raster/qgsrasterdrawer.sip.in | 2 +- .../raster/qgsrasterfilewriter.sip.in | 2 +- .../raster/qgsrasterfilewritertask.sip.in | 2 +- .../raster/qgsrasterhistogram.sip.in | 2 +- .../raster/qgsrasteridentifyresult.sip.in | 2 +- .../raster/qgsrasterinterface.sip.in | 4 +- .../raster/qgsrasteriterator.sip.in | 2 +- .../raster/qgsrasterlayer.sip.in | 2 +- .../qgsrasterlayertemporalproperties.sip.in | 2 +- .../raster/qgsrasterminmaxorigin.sip.in | 2 +- .../raster/qgsrasternuller.sip.in | 2 +- .../raster/qgsrasterpipe.sip.in | 2 +- .../raster/qgsrasterprojector.sip.in | 2 +- .../raster/qgsrasterpyramid.sip.in | 2 +- .../raster/qgsrasterrange.sip.in | 2 +- .../raster/qgsrasterrenderer.sip.in | 2 +- .../raster/qgsrasterrendererutils.sip.in | 2 +- .../raster/qgsrasterresamplefilter.sip.in | 2 +- .../raster/qgsrasterresampler.sip.in | 4 +- .../raster/qgsrastershader.sip.in | 2 +- .../raster/qgsrastershaderfunction.sip.in | 2 +- .../raster/qgsrastertransparency.sip.in | 2 +- .../qgssinglebandcolordatarenderer.sip.in | 2 +- .../raster/qgssinglebandgrayrenderer.sip.in | 2 +- .../qgssinglebandpseudocolorrenderer.sip.in | 2 +- .../qgsdoubleboxscalebarrenderer.sip.in | 2 +- .../scalebar/qgshollowscalebarrenderer.sip.in | 2 +- .../qgsnumericscalebarrenderer.sip.in | 2 +- .../scalebar/qgsscalebarrenderer.sip.in | 2 +- .../qgsscalebarrendererregistry.sip.in | 2 +- .../scalebar/qgsscalebarsettings.sip.in | 2 +- .../qgssingleboxscalebarrenderer.sip.in | 2 +- .../qgssteppedlinescalebarrenderer.sip.in | 2 +- .../scalebar/qgsticksscalebarrenderer.sip.in | 2 +- .../symbology/qgsarrowsymbollayer.sip.in | 2 +- .../qgscategorizedsymbolrenderer.sip.in | 2 +- .../symbology/qgscptcityarchive.sip.in | 12 +-- .../symbology/qgsellipsesymbollayer.sip.in | 2 +- .../qgsembeddedsymbolrenderer.sip.in | 2 +- .../qgsfeaturerenderergenerator.sip.in | 2 +- .../symbology/qgsfillsymbollayer.sip.in | 10 +-- .../symbology/qgsheatmaprenderer.sip.in | 2 +- .../qgsinterpolatedlinerenderer.sip.in | 6 +- .../qgsinvertedpolygonrenderer.sip.in | 2 +- .../symbology/qgslegendsymbolitem.sip.in | 2 +- .../symbology/qgslinesymbollayer.sip.in | 8 +- .../symbology/qgsmarkersymbollayer.sip.in | 8 +- .../symbology/qgsmasksymbollayer.sip.in | 2 +- .../symbology/qgsmergedfeaturerenderer.sip.in | 2 +- .../symbology/qgsnullsymbolrenderer.sip.in | 2 +- .../symbology/qgspointclusterrenderer.sip.in | 2 +- .../qgspointdisplacementrenderer.sip.in | 2 +- .../symbology/qgspointdistancerenderer.sip.in | 2 +- .../symbology/qgsrendererrange.sip.in | 2 +- .../symbology/qgsrendererregistry.sip.in | 6 +- .../symbology/qgsrulebasedrenderer.sip.in | 4 +- .../auto_generated/symbology/qgsstyle.sip.in | 14 +-- .../symbology/qgsstyleentityvisitor.sip.in | 2 +- .../symbology/qgsstylemodel.sip.in | 4 +- .../symbology/qgssvgcache.sip.in | 2 +- .../auto_generated/symbology/qgssymbol.sip.in | 8 +- .../symbology/qgssymbollayer.sip.in | 2 +- .../symbology/qgssymbollayerreference.sip.in | 4 +- .../symbology/qgssymbollayerregistry.sip.in | 6 +- .../qgsvectorfieldsymbollayer.sip.in | 2 +- .../qgstextbackgroundsettings.sip.in | 2 +- .../textrenderer/qgstextblock.sip.in | 2 +- .../textrenderer/qgstextbuffersettings.sip.in | 2 +- .../qgstextcharacterformat.sip.in | 2 +- .../textrenderer/qgstextdocument.sip.in | 2 +- .../textrenderer/qgstextformat.sip.in | 2 +- .../textrenderer/qgstextfragment.sip.in | 2 +- .../textrenderer/qgstextmasksettings.sip.in | 2 +- .../textrenderer/qgstextrenderer.sip.in | 2 +- .../textrenderer/qgstextrendererutils.sip.in | 2 +- .../textrenderer/qgstextshadowsettings.sip.in | 2 +- .../validity/qgsabstractvaliditycheck.sip.in | 4 +- .../validity/qgsvaliditycheckcontext.sip.in | 4 +- .../validity/qgsvaliditycheckregistry.sip.in | 2 +- .../vector/qgsvectordataprovider.sip.in | 2 +- ...tordataprovidertemporalcapabilities.sip.in | 2 +- .../vector/qgsvectorlayer.sip.in | 2 +- .../vector/qgsvectorlayercache.sip.in | 2 +- .../vector/qgsvectorlayerexporter.sip.in | 4 +- .../qgsvectorlayerfeaturecounter.sip.in | 2 +- .../qgsvectorlayerfeatureiterator.sip.in | 4 +- .../vector/qgsvectorlayerjoinbuffer.sip.in | 2 +- .../vector/qgsvectorlayerjoininfo.sip.in | 2 +- .../qgsvectorlayerserverproperties.sip.in | 2 +- .../qgsvectorlayertemporalproperties.sip.in | 4 +- .../vector/qgsvectorlayertools.sip.in | 2 +- .../vector/qgsvectorlayerundocommand.sip.in | 16 ++-- ...gsvectorlayerundopassthroughcommand.sip.in | 20 ++--- .../vector/qgsvectorlayerutils.sip.in | 6 +- .../qgsmapboxglstyleconverter.sip.in | 4 +- .../qgsvectortilebasiclabeling.sip.in | 4 +- .../qgsvectortilebasicrenderer.sip.in | 4 +- .../vectortile/qgsvectortilelabeling.sip.in | 2 +- .../vectortile/qgsvectortilelayer.sip.in | 2 +- .../vectortile/qgsvectortilerenderer.sip.in | 4 +- .../vectortile/qgsvectortilewriter.sip.in | 4 +- .../qgsattributetabledelegate.sip.in | 2 +- .../qgsattributetablemodel.sip.in | 2 +- .../qgsattributetableview.sip.in | 2 +- .../attributetable/qgsdualview.sip.in | 2 +- .../attributetable/qgsfeaturelistview.sip.in | 2 +- .../qgsfieldconditionalformatwidget.sip.in | 4 +- .../qgsifeatureselectionmanager.sip.in | 2 +- .../qgsorganizetablecolumnsdialog.sip.in | 2 +- .../auth/qgsauthauthoritieseditor.sip.in | 2 +- .../auth/qgsauthcertificateinfo.sip.in | 4 +- .../auth/qgsauthcertificatemanager.sip.in | 4 +- .../qgsauthcerttrustpolicycombobox.sip.in | 2 +- .../auth/qgsauthconfigeditor.sip.in | 2 +- .../auth/qgsauthconfigselect.sip.in | 4 +- .../auth/qgsautheditorwidgets.sip.in | 4 +- .../auth/qgsauthidentitieseditor.sip.in | 2 +- .../auth/qgsauthimportcertdialog.sip.in | 2 +- .../auth/qgsauthimportidentitydialog.sip.in | 2 +- .../auth/qgsauthmethodedit.sip.in | 2 +- .../auth/qgsauthserverseditor.sip.in | 2 +- .../auth/qgsauthsettingswidget.sip.in | 2 +- .../auth/qgsauthsslconfigwidget.sip.in | 4 +- .../auth/qgsauthsslerrorsdialog.sip.in | 2 +- .../auth/qgsauthsslimportdialog.sip.in | 2 +- .../auth/qgsauthtrustedcasdialog.sip.in | 2 +- .../callouts/qgscalloutwidget.sip.in | 2 +- .../codeeditors/qgscodeeditor.sip.in | 2 +- .../qgscodeeditorcolorscheme.sip.in | 2 +- .../qgscodeeditorcolorschemeregistry.sip.in | 2 +- .../codeeditors/qgscodeeditorcss.sip.in | 2 +- .../qgscodeeditorexpression.sip.in | 2 +- .../codeeditors/qgscodeeditorhtml.sip.in | 2 +- .../codeeditors/qgscodeeditorjs.sip.in | 2 +- .../codeeditors/qgscodeeditorpython.sip.in | 2 +- .../codeeditors/qgscodeeditorsql.sip.in | 2 +- .../devtools/qgsdevtoolwidget.sip.in | 2 +- .../devtools/qgsdevtoolwidgetfactory.sip.in | 2 +- .../core/qgseditorconfigwidget.sip.in | 2 +- .../core/qgseditorwidgetautoconf.sip.in | 2 +- .../core/qgseditorwidgetfactory.sip.in | 2 +- .../core/qgseditorwidgetregistry.sip.in | 2 +- .../core/qgseditorwidgetwrapper.sip.in | 2 +- .../core/qgssearchwidgetwrapper.sip.in | 2 +- .../core/qgswidgetwrapper.sip.in | 2 +- .../qgscheckboxsearchwidgetwrapper.sip.in | 2 +- .../editorwidgets/qgsdatetimeedit.sip.in | 6 +- .../qgsdatetimesearchwidgetwrapper.sip.in | 2 +- .../qgsdefaultsearchwidgetwrapper.sip.in | 2 +- .../editorwidgets/qgsdoublespinbox.sip.in | 2 +- .../editorwidgets/qgshtmlwidgetwrapper.sip.in | 2 +- .../qgsmultiedittoolbutton.sip.in | 2 +- .../editorwidgets/qgsqmlwidgetwrapper.sip.in | 2 +- ...elationaggregatesearchwidgetwrapper.sip.in | 2 +- ...elationreferencesearchwidgetwrapper.sip.in | 2 +- .../qgsrelationreferencewidgetwrapper.sip.in | 2 +- .../qgssearchwidgettoolbutton.sip.in | 2 +- .../editorwidgets/qgsspinbox.sip.in | 2 +- .../qgsvaluemapsearchwidgetwrapper.sip.in | 2 +- ...qgsvaluerelationsearchwidgetwrapper.sip.in | 2 +- .../effects/qgseffectdrawmodecombobox.sip.in | 2 +- .../qgseffectstackpropertieswidget.sip.in | 6 +- .../qgspainteffectpropertieswidget.sip.in | 2 +- .../effects/qgspainteffectwidget.sip.in | 2 +- .../labeling/qgslabellineanchorwidget.sip.in | 2 +- .../qgslabelobstaclesettingswidget.sip.in | 2 +- .../qgslabelsettingswidgetbase.sip.in | 4 +- .../qgscustomlayerorderwidget.sip.in | 2 +- .../qgslayertreeembeddedconfigwidget.sip.in | 2 +- .../qgslayertreeembeddedwidgetregistry.sip.in | 4 +- .../qgslayertreemapcanvasbridge.sip.in | 2 +- .../layertree/qgslayertreeview.sip.in | 6 +- .../qgslayertreeviewdefaultactions.sip.in | 2 +- .../qgslayertreeviewindicator.sip.in | 2 +- .../layout/qgslayoutcombobox.sip.in | 2 +- .../layout/qgslayoutcustomdrophandler.sip.in | 2 +- .../layout/qgslayoutdesignerinterface.sip.in | 2 +- .../layout/qgslayoutitemcombobox.sip.in | 2 +- .../layout/qgslayoutitemguiregistry.sip.in | 6 +- .../layout/qgslayoutitemwidget.sip.in | 6 +- .../qgslayoutnewitempropertiesdialog.sip.in | 2 +- .../layout/qgslayoutruler.sip.in | 2 +- .../layout/qgslayoutunitscombobox.sip.in | 2 +- .../layout/qgslayoutview.sip.in | 4 +- .../layout/qgslayoutviewmouseevent.sip.in | 2 +- .../layout/qgslayoutviewrubberband.sip.in | 8 +- .../layout/qgslayoutviewtool.sip.in | 2 +- .../layout/qgslayoutviewtooladditem.sip.in | 2 +- .../qgslayoutviewtooladdnodeitem.sip.in | 2 +- .../layout/qgslayoutviewtooleditnodes.sip.in | 2 +- .../qgslayoutviewtoolmoveitemcontent.sip.in | 2 +- .../layout/qgslayoutviewtoolpan.sip.in | 2 +- .../layout/qgslayoutviewtoolselect.sip.in | 2 +- .../qgslayoutviewtooltemporarykeypan.sip.in | 2 +- .../qgslayoutviewtooltemporarykeyzoom.sip.in | 2 +- .../qgslayoutviewtooltemporarymousepan.sip.in | 2 +- .../layout/qgslayoutviewtoolzoom.sip.in | 2 +- .../locator/qgslocatorwidget.sip.in | 2 +- .../mesh/qgsmeshlayerproperties.sip.in | 2 +- .../qgsnumericformatguiregistry.sip.in | 4 +- .../qgsnumericformatselectorwidget.sip.in | 2 +- .../qgsnumericformatwidget.sip.in | 16 ++-- ...spointcloudrendererpropertieswidget.sip.in | 2 +- .../qgspointcloudrendererwidget.sip.in | 2 +- .../models/qgsmodelarrowitem.sip.in | 2 +- .../qgsmodelcomponentgraphicitem.sip.in | 12 +-- .../models/qgsmodeldesignerdialog.sip.in | 2 +- .../models/qgsmodelgraphicitem.sip.in | 4 +- .../models/qgsmodelgraphicsscene.sip.in | 2 +- .../models/qgsmodelgraphicsview.sip.in | 4 +- .../qgsprocessingaggregatewidgets.sip.in | 4 +- ...cessingalgorithmconfigurationwidget.sip.in | 4 +- .../qgsprocessingalgorithmdialogbase.sip.in | 2 +- .../processing/qgsprocessinggui.sip.in | 2 +- .../qgsprocessingguiregistry.sip.in | 2 +- .../qgsprocessingmaplayercombobox.sip.in | 2 +- ...qgsprocessingmodelerparameterwidget.sip.in | 2 +- ...gsprocessingmultipleselectiondialog.sip.in | 8 +- ...gsprocessingoutputdestinationwidget.sip.in | 2 +- ...processingparameterdefinitionwidget.sip.in | 6 +- .../qgsprocessingparameterswidget.sip.in | 2 +- .../qgsprocessingrecentalgorithmlog.sip.in | 2 +- .../qgsprocessingtoolboxmodel.sip.in | 14 +-- .../qgsprocessingtoolboxtreeview.sip.in | 2 +- .../qgsprocessingwidgetwrapper.sip.in | 12 +-- .../gui/auto_generated/qgisinterface.sip.in | 2 +- .../auto_generated/qgs3dsymbolwidget.sip.in | 4 +- .../qgsabstractdatasourcewidget.sip.in | 2 +- .../qgsabstractmaptoolhandler.sip.in | 2 +- .../qgsabstractrelationeditorwidget.sip.in | 6 +- .../gui/auto_generated/qgsactionmenu.sip.in | 2 +- .../qgsadvanceddigitizingcanvasitem.sip.in | 2 +- .../qgsadvanceddigitizingdockwidget.sip.in | 4 +- .../qgsadvanceddigitizingfloater.sip.in | 2 +- .../qgsaggregatetoolbutton.sip.in | 2 +- .../qgsalignmentcombobox.sip.in | 2 +- .../qgsapplicationexitblockerinterface.sip.in | 2 +- .../qgsattributeeditorcontext.sip.in | 2 +- .../qgsattributeformeditorwidget.sip.in | 2 +- ...gsattributeformrelationeditorwidget.sip.in | 2 +- .../qgsattributeformwidget.sip.in | 2 +- .../qgsblendmodecombobox.sip.in | 2 +- .../qgsbrowserdockwidget.sip.in | 2 +- .../auto_generated/qgsbrowserguimodel.sip.in | 2 +- .../auto_generated/qgsbrowsertreeview.sip.in | 2 +- .../qgsbusyindicatordialog.sip.in | 2 +- .../qgscharacterselectordialog.sip.in | 2 +- .../qgscheckablecombobox.sip.in | 2 +- .../qgscollapsiblegroupbox.sip.in | 4 +- .../qgscolorbrewercolorrampdialog.sip.in | 4 +- .../gui/auto_generated/qgscolorbutton.sip.in | 2 +- .../gui/auto_generated/qgscolordialog.sip.in | 2 +- .../auto_generated/qgscolorrampbutton.sip.in | 2 +- .../qgscolorramplegendnodewidget.sip.in | 4 +- .../auto_generated/qgscolorschemelist.sip.in | 6 +- .../auto_generated/qgscolorswatchgrid.sip.in | 4 +- .../gui/auto_generated/qgscolorwidgets.sip.in | 16 ++-- .../qgscompoundcolorwidget.sip.in | 2 +- .../qgsconfigureshortcutsdialog.sip.in | 2 +- ...qgscoordinateboundspreviewmapwidget.sip.in | 2 +- .../qgscoordinateoperationwidget.sip.in | 2 +- .../auto_generated/qgscredentialdialog.sip.in | 2 +- .../qgscurveeditorwidget.sip.in | 2 +- .../qgscustomdrophandler.sip.in | 2 +- .../qgscustomprojectopenhandler.sip.in | 2 +- .../qgsdatabaseschemacombobox.sip.in | 2 +- .../qgsdatabasetablecombobox.sip.in | 2 +- .../qgsdataitemguiprovider.sip.in | 4 +- .../qgsdataitemguiproviderregistry.sip.in | 2 +- .../qgsdatasourceselectdialog.sip.in | 4 +- .../auto_generated/qgsdetaileditemdata.sip.in | 2 +- .../qgsdetaileditemdelegate.sip.in | 2 +- .../qgsdetaileditemwidget.sip.in | 2 +- python/gui/auto_generated/qgsdialog.sip.in | 2 +- .../gui/auto_generated/qgsdockwidget.sip.in | 2 +- .../auto_generated/qgsdoublevalidator.sip.in | 2 +- .../qgsencodingfiledialog.sip.in | 4 +- .../qgsexpressionbuilderdialog.sip.in | 2 +- .../qgsexpressionbuilderwidget.sip.in | 2 +- .../qgsexpressionlineedit.sip.in | 2 +- .../qgsexpressionpreviewwidget.sip.in | 2 +- .../qgsexpressionselectiondialog.sip.in | 2 +- .../qgsexpressionstoredialog.sip.in | 2 +- .../qgsexpressiontreeview.sip.in | 8 +- .../auto_generated/qgsextentgroupbox.sip.in | 2 +- .../gui/auto_generated/qgsextentwidget.sip.in | 2 +- .../qgsexternalresourcewidget.sip.in | 2 +- .../qgsfeaturelistcombobox.sip.in | 2 +- .../qgsfeaturepickerwidget.sip.in | 2 +- .../auto_generated/qgsfieldcombobox.sip.in | 2 +- .../qgsfieldexpressionwidget.sip.in | 2 +- .../qgsfieldmappingmodel.sip.in | 2 +- .../qgsfieldmappingwidget.sip.in | 2 +- .../qgsfieldvalueslineedit.sip.in | 2 +- .../qgsfilecontentsourcelineedit.sip.in | 6 +- .../qgsfiledownloaderdialog.sip.in | 2 +- .../gui/auto_generated/qgsfilewidget.sip.in | 2 +- .../auto_generated/qgsfilterlineedit.sip.in | 2 +- .../qgsfindfilesbypatternwidget.sip.in | 4 +- .../auto_generated/qgsfloatingwidget.sip.in | 2 +- .../gui/auto_generated/qgsfocuswatcher.sip.in | 2 +- .../gui/auto_generated/qgsfontbutton.sip.in | 2 +- .../auto_generated/qgsformannotation.sip.in | 2 +- .../qgsgeocoderlocatorfilter.sip.in | 2 +- .../qgsgeometryrubberband.sip.in | 2 +- .../qgsgradientcolorrampdialog.sip.in | 2 +- .../qgsgradientstopeditor.sip.in | 2 +- python/gui/auto_generated/qgsgui.sip.in | 2 +- python/gui/auto_generated/qgshelp.sip.in | 2 +- python/gui/auto_generated/qgshighlight.sip.in | 2 +- .../qgshighlightablelineedit.sip.in | 2 +- .../auto_generated/qgshistogramwidget.sip.in | 2 +- .../gui/auto_generated/qgsidentifymenu.sip.in | 2 +- .../auto_generated/qgskeyvaluewidget.sip.in | 2 +- .../qgslegendfilterbutton.sip.in | 2 +- .../qgslegendpatchshapebutton.sip.in | 2 +- .../qgslegendpatchshapewidget.sip.in | 4 +- .../qgslimitedrandomcolorrampdialog.sip.in | 4 +- .../gui/auto_generated/qgslistwidget.sip.in | 2 +- python/gui/auto_generated/qgsmapcanvas.sip.in | 2 +- .../qgsmapcanvasannotationitem.sip.in | 2 +- .../qgsmapcanvasinteractionblocker.sip.in | 2 +- .../auto_generated/qgsmapcanvasitem.sip.in | 2 +- .../qgsmapcanvassnappingutils.sip.in | 2 +- .../auto_generated/qgsmapcanvastracer.sip.in | 2 +- .../auto_generated/qgsmapcanvasutils.sip.in | 2 +- .../qgsmaplayeractionregistry.sip.in | 4 +- .../auto_generated/qgsmaplayercombobox.sip.in | 2 +- .../qgsmaplayerconfigwidget.sip.in | 2 +- .../qgsmaplayerconfigwidgetfactory.sip.in | 2 +- .../qgsmaplayerstylemanagerwidget.sip.in | 2 +- .../auto_generated/qgsmapmouseevent.sip.in | 2 +- .../qgsmapoverviewcanvas.sip.in | 2 +- python/gui/auto_generated/qgsmaptip.sip.in | 2 +- python/gui/auto_generated/qgsmaptool.sip.in | 2 +- .../qgsmaptooladvanceddigitizing.sip.in | 2 +- .../qgsmaptooldigitizefeature.sip.in | 2 +- .../gui/auto_generated/qgsmaptooledit.sip.in | 2 +- .../auto_generated/qgsmaptoolemitpoint.sip.in | 2 +- .../auto_generated/qgsmaptoolextent.sip.in | 2 +- .../auto_generated/qgsmaptoolidentify.sip.in | 2 +- .../qgsmaptoolidentifyfeature.sip.in | 2 +- .../gui/auto_generated/qgsmaptoolpan.sip.in | 2 +- .../gui/auto_generated/qgsmaptoolzoom.sip.in | 2 +- .../gui/auto_generated/qgsmenuheader.sip.in | 4 +- .../gui/auto_generated/qgsmessagebar.sip.in | 2 +- .../auto_generated/qgsmessagebaritem.sip.in | 2 +- .../auto_generated/qgsmessagelogviewer.sip.in | 2 +- .../auto_generated/qgsmessageviewer.sip.in | 2 +- .../auto_generated/qgsmetadatawidget.sip.in | 2 +- .../qgsnewauxiliaryfielddialog.sip.in | 2 +- .../qgsnewauxiliarylayerdialog.sip.in | 2 +- .../qgsnewdatabasetablenamewidget.sip.in | 4 +- .../qgsnewgeopackagelayerdialog.sip.in | 2 +- .../qgsnewhttpconnection.sip.in | 2 +- .../auto_generated/qgsnewnamedialog.sip.in | 2 +- .../qgsnewvectortabledialog.sip.in | 2 +- .../auto_generated/qgsopacitywidget.sip.in | 2 +- .../qgsoptionsdialogbase.sip.in | 2 +- .../qgsoptionsdialoghighlightwidget.sip.in | 2 +- ...gsoptionsdialoghighlightwidgetsimpl.sip.in | 10 +-- .../qgsoptionswidgetfactory.sip.in | 2 +- .../auto_generated/qgsorderbydialog.sip.in | 2 +- .../auto_generated/qgsowssourceselect.sip.in | 2 +- .../gui/auto_generated/qgspanelwidget.sip.in | 4 +- .../auto_generated/qgspanelwidgetstack.sip.in | 2 +- .../auto_generated/qgspasswordlineedit.sip.in | 2 +- .../gui/auto_generated/qgspixmaplabel.sip.in | 2 +- .../qgspointcloudattributecombobox.sip.in | 2 +- .../qgspresetcolorrampdialog.sip.in | 4 +- .../auto_generated/qgsprevieweffect.sip.in | 2 +- .../qgsprojectionselectiondialog.sip.in | 2 +- .../qgsprojectionselectiontreewidget.sip.in | 2 +- .../qgsprojectionselectionwidget.sip.in | 2 +- .../qgsprojectstorageguiprovider.sip.in | 2 +- .../qgsprojectstorageguiregistry.sip.in | 2 +- .../qgspropertyassistantwidget.sip.in | 2 +- .../qgspropertyoverridebutton.sip.in | 2 +- .../qgsproviderconnectioncombobox.sip.in | 2 +- .../qgsproviderguimetadata.sip.in | 2 +- .../qgsproviderguiregistry.sip.in | 2 +- .../qgsprovidersourcewidget.sip.in | 2 +- .../qgsprovidersourcewidgetprovider.sip.in | 2 +- ...rovidersourcewidgetproviderregistry.sip.in | 2 +- .../gui/auto_generated/qgsproxystyle.sip.in | 2 +- .../gui/auto_generated/qgsquerybuilder.sip.in | 2 +- .../gui/auto_generated/qgsrangeslider.sip.in | 2 +- .../qgsrasterformatsaveoptionswidget.sip.in | 2 +- .../qgsrasterpyramidsoptionswidget.sip.in | 2 +- .../auto_generated/qgsratiolockbutton.sip.in | 2 +- .../qgsrelationeditorwidget.sip.in | 4 +- .../qgsrelationwidgetregistry.sip.in | 2 +- .../gui/auto_generated/qgsrubberband.sip.in | 2 +- .../auto_generated/qgsscalecombobox.sip.in | 2 +- .../auto_generated/qgsscalerangewidget.sip.in | 2 +- .../qgsscalevisibilitydialog.sip.in | 2 +- .../gui/auto_generated/qgsscalewidget.sip.in | 2 +- .../gui/auto_generated/qgsscrollarea.sip.in | 2 +- .../qgssearchquerybuilder.sip.in | 2 +- .../auto_generated/qgsshortcutsmanager.sip.in | 2 +- .../auto_generated/qgssnapindicator.sip.in | 2 +- .../qgssnaptogridcanvasitem.sip.in | 2 +- .../qgssourceselectprovider.sip.in | 2 +- .../qgssourceselectproviderregistry.sip.in | 2 +- python/gui/auto_generated/qgsstatusbar.sip.in | 2 +- .../qgsstyleitemslistwidget.sip.in | 2 +- .../qgssubsetstringeditorinterface.sip.in | 2 +- .../qgssubsetstringeditorprovider.sip.in | 2 +- ...ssubsetstringeditorproviderregistry.sip.in | 2 +- .../qgssubstitutionlistwidget.sip.in | 4 +- .../gui/auto_generated/qgssymbolbutton.sip.in | 2 +- .../auto_generated/qgstablewidgetbase.sip.in | 2 +- .../auto_generated/qgstablewidgetitem.sip.in | 2 +- python/gui/auto_generated/qgstabwidget.sip.in | 2 +- .../qgstaskmanagerwidget.sip.in | 2 +- .../qgstemporalcontrollerwidget.sip.in | 2 +- .../auto_generated/qgstextformatwidget.sip.in | 6 +- .../gui/auto_generated/qgstextpreview.sip.in | 2 +- .../auto_generated/qgstreewidgetitem.sip.in | 4 +- .../qgsunitselectionwidget.sip.in | 6 +- .../auto_generated/qgsuserinputwidget.sip.in | 2 +- .../qgsvaliditycheckresultswidget.sip.in | 4 +- .../qgsvariableeditorwidget.sip.in | 2 +- ...vectorlayertemporalpropertieswidget.sip.in | 2 +- .../gui/auto_generated/qgsvertexmarker.sip.in | 2 +- .../gui/auto_generated/qgsvscrollarea.sip.in | 2 +- .../qgswindowmanagerinterface.sip.in | 2 +- .../raster/qgscolorrampshaderwidget.sip.in | 2 +- .../raster/qgshillshaderendererwidget.sip.in | 2 +- .../raster/qgsrasterbandcombobox.sip.in | 2 +- .../qgsrastercontourrendererwidget.sip.in | 2 +- .../raster/qgsrasterhistogramwidget.sip.in | 2 +- .../raster/qgsrasterlayerproperties.sip.in | 2 +- ...rasterlayertemporalpropertieswidget.sip.in | 2 +- .../raster/qgsrastertransparencywidget.sip.in | 2 +- ...singlebandpseudocolorrendererwidget.sip.in | 2 +- .../symbology/characterwidget.sip.in | 2 +- .../qgscptcitycolorrampdialog.sip.in | 2 +- .../symbology/qgsdashspacedialog.sip.in | 4 +- .../qgsdatadefinedsizelegendwidget.sip.in | 2 +- .../qgsembeddedsymbolrendererwidget.sip.in | 2 +- .../qgsgraduatedhistogramwidget.sip.in | 2 +- .../qgsinvertedpolygonrendererwidget.sip.in | 2 +- .../symbology/qgsmasksymbollayerwidget.sip.in | 2 +- .../qgsmergedfeaturerendererwidget.sip.in | 2 +- .../qgsnullsymbolrendererwidget.sip.in | 2 +- .../qgspointclusterrendererwidget.sip.in | 2 +- .../symbology/qgsrendererwidget.sip.in | 4 +- .../qgsrulebasedrendererwidget.sip.in | 2 +- .../symbology/qgsstylemanagerdialog.sip.in | 2 +- .../symbology/qgsstylesavedialog.sip.in | 2 +- .../symbology/qgssvgselectorwidget.sip.in | 6 +- .../symbology/qgssymbollayerwidget.sip.in | 8 +- .../symbology/qgssymbollevelsdialog.sip.in | 4 +- .../symbology/qgssymbolselectordialog.sip.in | 2 +- .../symbology/qgssymbolwidgetcontext.sip.in | 2 +- .../tableeditor/qgstableeditordialog.sip.in | 2 +- .../tableeditor/qgstableeditorwidget.sip.in | 2 +- .../vector/qgsvectorlayerproperties.sip.in | 2 +- .../auto_generated/qgsaccesscontrol.sip.in | 2 +- .../qgsaccesscontrolfilter.sip.in | 2 +- .../qgsbufferserverrequest.sip.in | 2 +- .../qgsbufferserverresponse.sip.in | 2 +- .../qgscapabilitiescache.sip.in | 2 +- .../auto_generated/qgsconfigcache.sip.in | 2 +- .../qgsfcgiserverrequest.sip.in | 2 +- .../auto_generated/qgsfeaturefilter.sip.in | 2 +- .../qgsfeaturefilterprovidergroup.sip.in | 2 +- .../auto_generated/qgsrequesthandler.sip.in | 2 +- python/server/auto_generated/qgsserver.sip.in | 2 +- .../server/auto_generated/qgsserverapi.sip.in | 2 +- .../auto_generated/qgsserverapicontext.sip.in | 2 +- .../auto_generated/qgsserverapiutils.sip.in | 2 +- .../qgsservercachefilter.sip.in | 2 +- .../qgsservercachemanager.sip.in | 2 +- .../auto_generated/qgsserverexception.sip.in | 4 +- .../auto_generated/qgsserverfilter.sip.in | 2 +- .../auto_generated/qgsserverinterface.sip.in | 2 +- .../auto_generated/qgsserverlogger.sip.in | 2 +- .../auto_generated/qgsserverogcapi.sip.in | 2 +- .../qgsserverogcapihandler.sip.in | 2 +- .../auto_generated/qgsserverparameters.sip.in | 6 +- .../qgsserverquerystringparameter.sip.in | 2 +- .../auto_generated/qgsserversettings.sip.in | 4 +- .../qgsserverstatichandler.sip.in | 2 +- .../server/auto_generated/qgsservice.sip.in | 2 +- .../auto_generated/qgsservicemodule.sip.in | 2 +- .../auto_generated/qgsserviceregistry.sip.in | 2 +- .../qgsstorebadlayerinfo.sip.in | 2 +- 1065 files changed, 1545 insertions(+), 1545 deletions(-) diff --git a/python/3d/auto_generated/materials/qgsabstractmaterialsettings.sip.in b/python/3d/auto_generated/materials/qgsabstractmaterialsettings.sip.in index 92d0e028b60e..8a8274e351e5 100644 --- a/python/3d/auto_generated/materials/qgsabstractmaterialsettings.sip.in +++ b/python/3d/auto_generated/materials/qgsabstractmaterialsettings.sip.in @@ -25,7 +25,7 @@ enum class QgsMaterialSettingsRenderingTechnique class QgsMaterialContext { -%Docstring +%Docstring(signature="appended") Context settings for a material. .. warning:: @@ -74,7 +74,7 @@ Sets the color for representing materials in a selected state. class QgsAbstractMaterialSettings /Abstract/ { -%Docstring +%Docstring(signature="appended") Abstract base class for material settings. .. warning:: diff --git a/python/3d/auto_generated/materials/qgsgoochmaterialsettings.sip.in b/python/3d/auto_generated/materials/qgsgoochmaterialsettings.sip.in index c3c4c63b6360..69cd9783a195 100644 --- a/python/3d/auto_generated/materials/qgsgoochmaterialsettings.sip.in +++ b/python/3d/auto_generated/materials/qgsgoochmaterialsettings.sip.in @@ -12,7 +12,7 @@ class QgsGoochMaterialSettings : QgsAbstractMaterialSettings { -%Docstring +%Docstring(signature="appended") Basic shading material used for rendering based on the Phong shading model with three color components: ambient, diffuse and specular. diff --git a/python/3d/auto_generated/materials/qgsmaterialregistry.sip.in b/python/3d/auto_generated/materials/qgsmaterialregistry.sip.in index bb5c3bc9d983..bea12c3dad94 100644 --- a/python/3d/auto_generated/materials/qgsmaterialregistry.sip.in +++ b/python/3d/auto_generated/materials/qgsmaterialregistry.sip.in @@ -13,7 +13,7 @@ class QgsMaterialSettingsWidget /External/; class QgsMaterialSettingsAbstractMetadata { -%Docstring +%Docstring(signature="appended") Stores metadata about one 3D material settings class. .. note:: @@ -75,7 +75,7 @@ Returns ``True`` if the material type supports the specified rendering ``techniq class QgsMaterialRegistry { -%Docstring +%Docstring(signature="appended") Registry of available 3d material settings classes. :py:class:`QgsMaterialRegistry` is not usually directly created, but rather accessed through diff --git a/python/3d/auto_generated/materials/qgsnullmaterialsettings.sip.in b/python/3d/auto_generated/materials/qgsnullmaterialsettings.sip.in index 896cf565c60f..9952ee01fe84 100644 --- a/python/3d/auto_generated/materials/qgsnullmaterialsettings.sip.in +++ b/python/3d/auto_generated/materials/qgsnullmaterialsettings.sip.in @@ -13,7 +13,7 @@ class QgsNullMaterialSettings : QgsAbstractMaterialSettings { -%Docstring +%Docstring(signature="appended") Null shading material used for rendering models and scenes with native textures. .. warning:: diff --git a/python/3d/auto_generated/materials/qgsphongmaterialsettings.sip.in b/python/3d/auto_generated/materials/qgsphongmaterialsettings.sip.in index 5f5c299b5f0a..9f529c00a735 100644 --- a/python/3d/auto_generated/materials/qgsphongmaterialsettings.sip.in +++ b/python/3d/auto_generated/materials/qgsphongmaterialsettings.sip.in @@ -13,7 +13,7 @@ class QgsPhongMaterialSettings : QgsAbstractMaterialSettings { -%Docstring +%Docstring(signature="appended") Basic shading material used for rendering based on the Phong shading model with three color components: ambient, diffuse and specular. diff --git a/python/3d/auto_generated/materials/qgsphongtexturedmaterialsettings.sip.in b/python/3d/auto_generated/materials/qgsphongtexturedmaterialsettings.sip.in index 6a75b191bb83..d9e7d025565f 100644 --- a/python/3d/auto_generated/materials/qgsphongtexturedmaterialsettings.sip.in +++ b/python/3d/auto_generated/materials/qgsphongtexturedmaterialsettings.sip.in @@ -12,7 +12,7 @@ class QgsPhongTexturedMaterialSettings : QgsAbstractMaterialSettings { -%Docstring +%Docstring(signature="appended") A phong shading model with diffuse texture map. .. warning:: diff --git a/python/3d/auto_generated/materials/qgssimplelinematerialsettings.sip.in b/python/3d/auto_generated/materials/qgssimplelinematerialsettings.sip.in index 9e0cd1a74233..ae81af62230c 100644 --- a/python/3d/auto_generated/materials/qgssimplelinematerialsettings.sip.in +++ b/python/3d/auto_generated/materials/qgssimplelinematerialsettings.sip.in @@ -13,7 +13,7 @@ class QgsSimpleLineMaterialSettings : QgsAbstractMaterialSettings { -%Docstring +%Docstring(signature="appended") Basic shading material used for rendering simple lines as solid line components. .. warning:: diff --git a/python/3d/auto_generated/processing/qgs3dalgorithms.sip.in b/python/3d/auto_generated/processing/qgs3dalgorithms.sip.in index a3dc4b52e300..e99c91b366d1 100644 --- a/python/3d/auto_generated/processing/qgs3dalgorithms.sip.in +++ b/python/3d/auto_generated/processing/qgs3dalgorithms.sip.in @@ -11,7 +11,7 @@ class Qgs3DAlgorithms: QgsProcessingProvider { -%Docstring +%Docstring(signature="appended") QGIS 3D processing algorithm provider. .. versionadded:: 3.0 diff --git a/python/3d/auto_generated/qgs3d.sip.in b/python/3d/auto_generated/qgs3d.sip.in index 49f53f273b19..b489a228c9ec 100644 --- a/python/3d/auto_generated/qgs3d.sip.in +++ b/python/3d/auto_generated/qgs3d.sip.in @@ -12,7 +12,7 @@ class Qgs3D { -%Docstring +%Docstring(signature="appended") Qgs3D is a singleton class containing various registries and other global members related to 3D classes. diff --git a/python/3d/auto_generated/qgs3dmapexportsettings.sip.in b/python/3d/auto_generated/qgs3dmapexportsettings.sip.in index 696372e504f6..03e1c5272e65 100644 --- a/python/3d/auto_generated/qgs3dmapexportsettings.sip.in +++ b/python/3d/auto_generated/qgs3dmapexportsettings.sip.in @@ -11,7 +11,7 @@ class Qgs3DMapExportSettings { -%Docstring +%Docstring(signature="appended") Manages the various settings the user can choose from when exporting a 3D scene .. versionadded:: 3.16 diff --git a/python/3d/auto_generated/qgs3dmapsettings.sip.in b/python/3d/auto_generated/qgs3dmapsettings.sip.in index 883cb70f757d..3d3ccb0971f2 100644 --- a/python/3d/auto_generated/qgs3dmapsettings.sip.in +++ b/python/3d/auto_generated/qgs3dmapsettings.sip.in @@ -17,7 +17,7 @@ class Qgs3DMapSettings : QObject, QgsTemporalRangeObject { -%Docstring +%Docstring(signature="appended") Definition of the world. .. versionadded:: 3.0 diff --git a/python/3d/auto_generated/qgs3dtypes.sip.in b/python/3d/auto_generated/qgs3dtypes.sip.in index 5672c3731349..c76903525249 100644 --- a/python/3d/auto_generated/qgs3dtypes.sip.in +++ b/python/3d/auto_generated/qgs3dtypes.sip.in @@ -10,7 +10,7 @@ class Qgs3DTypes { -%Docstring +%Docstring(signature="appended") Defines enumerations and other auxiliary types for QGIS 3D .. warning:: diff --git a/python/3d/auto_generated/qgsabstractvectorlayer3drenderer.sip.in b/python/3d/auto_generated/qgsabstractvectorlayer3drenderer.sip.in index df218695fb87..b0dcaac1b293 100644 --- a/python/3d/auto_generated/qgsabstractvectorlayer3drenderer.sip.in +++ b/python/3d/auto_generated/qgsabstractvectorlayer3drenderer.sip.in @@ -12,7 +12,7 @@ class QgsVectorLayer3DTilingSettings { -%Docstring +%Docstring(signature="appended") This class defines configuration of how a vector layer gets tiled for 3D rendering. Zoom levels count tells how deep will be the quadtree and thus how many tiles will @@ -64,7 +64,7 @@ Reads content of the object from XML class QgsAbstractVectorLayer3DRenderer : QgsAbstract3DRenderer /Abstract/ { -%Docstring +%Docstring(signature="appended") Base class for 3D renderers that are based on vector layers. .. versionadded:: 3.12 diff --git a/python/3d/auto_generated/qgscamerapose.sip.in b/python/3d/auto_generated/qgscamerapose.sip.in index 0e4bc5e1d55d..55756e259ccc 100644 --- a/python/3d/auto_generated/qgscamerapose.sip.in +++ b/python/3d/auto_generated/qgscamerapose.sip.in @@ -13,7 +13,7 @@ class QgsCameraPose { -%Docstring +%Docstring(signature="appended") Class that encapsulates camera pose in a 3D scene. The pose is defined with the following parameters: diff --git a/python/3d/auto_generated/qgsdirectionallightsettings.sip.in b/python/3d/auto_generated/qgsdirectionallightsettings.sip.in index 07e6698d25a5..4e4c367f1384 100644 --- a/python/3d/auto_generated/qgsdirectionallightsettings.sip.in +++ b/python/3d/auto_generated/qgsdirectionallightsettings.sip.in @@ -11,7 +11,7 @@ class QgsDirectionalLightSettings { -%Docstring +%Docstring(signature="appended") Definition of a directional light in a 3D map scene .. versionadded:: 3.16 diff --git a/python/3d/auto_generated/qgslayoutitem3dmap.sip.in b/python/3d/auto_generated/qgslayoutitem3dmap.sip.in index b65a9a1045ec..1304f4bd1542 100644 --- a/python/3d/auto_generated/qgslayoutitem3dmap.sip.in +++ b/python/3d/auto_generated/qgslayoutitem3dmap.sip.in @@ -18,7 +18,7 @@ class QgsLayoutItem3DMap : QgsLayoutItem, QgsTemporalRangeObject { -%Docstring +%Docstring(signature="appended") Implements support of 3D map views in print layouts diff --git a/python/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in b/python/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in index 6e7e74e1c496..7e94ab060781 100644 --- a/python/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in +++ b/python/3d/auto_generated/qgspointcloudlayer3drenderer.sip.in @@ -14,7 +14,7 @@ class QgsPointCloudLayer3DRenderer : QgsAbstract3DRenderer { -%Docstring +%Docstring(signature="appended") 3D renderer that renders all points from a point cloud layer .. versionadded:: 3.18 diff --git a/python/3d/auto_generated/qgspointlightsettings.sip.in b/python/3d/auto_generated/qgspointlightsettings.sip.in index bc15baedb292..1dce48001bfb 100644 --- a/python/3d/auto_generated/qgspointlightsettings.sip.in +++ b/python/3d/auto_generated/qgspointlightsettings.sip.in @@ -12,7 +12,7 @@ class QgsPointLightSettings { -%Docstring +%Docstring(signature="appended") Definition of a point light in a 3D map scene Total light at the distance D from a point light with intensity I diff --git a/python/3d/auto_generated/qgsrulebased3drenderer.sip.in b/python/3d/auto_generated/qgsrulebased3drenderer.sip.in index 765b3f4ccd3c..d6998bf851e8 100644 --- a/python/3d/auto_generated/qgsrulebased3drenderer.sip.in +++ b/python/3d/auto_generated/qgsrulebased3drenderer.sip.in @@ -13,7 +13,7 @@ class QgsRuleBased3DRendererMetadata : Qgs3DRendererAbstractMetadata { -%Docstring +%Docstring(signature="appended") Metadata for rule-based 3D renderer to allow creation of its instances from XML .. warning:: @@ -40,7 +40,7 @@ Creates an instance of a 3D renderer based on a DOM element with renderer config class QgsRuleBased3DRenderer : QgsAbstractVectorLayer3DRenderer { -%Docstring +%Docstring(signature="appended") Rule-based 3D renderer. Similar to rule-based 2D renderer and rule-based labeling, it allows specification of rules for 3D symbols. @@ -63,7 +63,7 @@ Similar to rule-based 2D renderer and rule-based labeling, it allows specificati class Rule { -%Docstring +%Docstring(signature="appended") A child rule for a QgsRuleBased3DRenderer .. versionadded:: 3.6 diff --git a/python/3d/auto_generated/qgsvectorlayer3drenderer.sip.in b/python/3d/auto_generated/qgsvectorlayer3drenderer.sip.in index bb1dbf4a5a8e..91ecea2c482c 100644 --- a/python/3d/auto_generated/qgsvectorlayer3drenderer.sip.in +++ b/python/3d/auto_generated/qgsvectorlayer3drenderer.sip.in @@ -15,7 +15,7 @@ class QgsVectorLayer3DRendererMetadata : Qgs3DRendererAbstractMetadata { -%Docstring +%Docstring(signature="appended") Metadata for vector layer 3D renderer to allow creation of its instances from XML. .. warning:: @@ -42,7 +42,7 @@ Creates an instance of a 3D renderer based on a DOM element with renderer config class QgsVectorLayer3DRenderer : QgsAbstractVectorLayer3DRenderer { -%Docstring +%Docstring(signature="appended") 3D renderer that renders all features of a vector layer with the same 3D symbol. The appearance is completely defined by the symbol. diff --git a/python/3d/auto_generated/symbols/qgsline3dsymbol.sip.in b/python/3d/auto_generated/symbols/qgsline3dsymbol.sip.in index 442d4cfc55e8..5f321da7403c 100644 --- a/python/3d/auto_generated/symbols/qgsline3dsymbol.sip.in +++ b/python/3d/auto_generated/symbols/qgsline3dsymbol.sip.in @@ -12,7 +12,7 @@ class QgsLine3DSymbol : QgsAbstract3DSymbol /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") 3D symbol that draws linestring geometries as planar polygons (created from lines using a buffer with given thickness). .. warning:: diff --git a/python/3d/auto_generated/symbols/qgspoint3dsymbol.sip.in b/python/3d/auto_generated/symbols/qgspoint3dsymbol.sip.in index 4aae9ed389d9..73371bcf0ec4 100644 --- a/python/3d/auto_generated/symbols/qgspoint3dsymbol.sip.in +++ b/python/3d/auto_generated/symbols/qgspoint3dsymbol.sip.in @@ -13,7 +13,7 @@ class QgsPoint3DSymbol : QgsAbstract3DSymbol /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") 3D symbol that draws point geometries as 3D objects using one of the predefined shapes. .. warning:: diff --git a/python/3d/auto_generated/symbols/qgspointcloud3dsymbol.sip.in b/python/3d/auto_generated/symbols/qgspointcloud3dsymbol.sip.in index db5adced7666..b2395af9fcb8 100644 --- a/python/3d/auto_generated/symbols/qgspointcloud3dsymbol.sip.in +++ b/python/3d/auto_generated/symbols/qgspointcloud3dsymbol.sip.in @@ -12,7 +12,7 @@ class QgsPointCloud3DSymbol : QgsAbstract3DSymbol /Abstract/ { -%Docstring +%Docstring(signature="appended") 3D symbol that draws point cloud geometries as 3D objects. .. warning:: @@ -77,7 +77,7 @@ Returns the byte stride for the geometries used to for the vertex buffer class QgsSingleColorPointCloud3DSymbol : QgsPointCloud3DSymbol { -%Docstring +%Docstring(signature="appended") 3D symbol that draws point cloud geometries as 3D objects.using one color .. warning:: @@ -128,7 +128,7 @@ Sets the color used by the renderer when using SingleColor rendering mode class QgsColorRampPointCloud3DSymbol : QgsPointCloud3DSymbol { -%Docstring +%Docstring(signature="appended") 3D symbol that draws point cloud geometries as 3D objects.using color ramp shader .. warning:: @@ -213,7 +213,7 @@ Sets the minimum and maximum values used when classifying colors in the color ra class QgsRgbPointCloud3DSymbol : QgsPointCloud3DSymbol { -%Docstring +%Docstring(signature="appended") 3D symbol that draws point cloud geometries as 3D objects using RGB colors in the dataset .. warning:: @@ -394,7 +394,7 @@ Ownership of ``enhancement`` is transferred. class QgsClassificationPointCloud3DSymbol : QgsPointCloud3DSymbol { -%Docstring +%Docstring(signature="appended") 3D symbol that draws point cloud geometries as 3D objects using classification of the dataset .. warning:: diff --git a/python/3d/auto_generated/symbols/qgspolygon3dsymbol.sip.in b/python/3d/auto_generated/symbols/qgspolygon3dsymbol.sip.in index 4106f66b51c5..b2c4c2d2ba20 100644 --- a/python/3d/auto_generated/symbols/qgspolygon3dsymbol.sip.in +++ b/python/3d/auto_generated/symbols/qgspolygon3dsymbol.sip.in @@ -13,7 +13,7 @@ class QgsPolygon3DSymbol : QgsAbstract3DSymbol /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") 3D symbol that draws polygon geometries as planar polygons, optionally extruded (with added walls). .. warning:: diff --git a/python/analysis/auto_generated/georeferencing/qgsgcpgeometrytransformer.sip.in b/python/analysis/auto_generated/georeferencing/qgsgcpgeometrytransformer.sip.in index 16f1466201a4..0cf2b2b57e5d 100644 --- a/python/analysis/auto_generated/georeferencing/qgsgcpgeometrytransformer.sip.in +++ b/python/analysis/auto_generated/georeferencing/qgsgcpgeometrytransformer.sip.in @@ -12,7 +12,7 @@ class QgsGcpGeometryTransformer : QgsAbstractGeometryTransformer { -%Docstring +%Docstring(signature="appended") A geometry transformer which uses an underlying Ground Control Points (GCP) based transformation to modify geometries. .. versionadded:: 3.18 diff --git a/python/analysis/auto_generated/georeferencing/qgsgcptransformer.sip.in b/python/analysis/auto_generated/georeferencing/qgsgcptransformer.sip.in index 0ec5ec3ddb1d..b5a6bcbbddb8 100644 --- a/python/analysis/auto_generated/georeferencing/qgsgcptransformer.sip.in +++ b/python/analysis/auto_generated/georeferencing/qgsgcptransformer.sip.in @@ -10,7 +10,7 @@ class QgsGcpTransformerInterface /Abstract/ { -%Docstring +%Docstring(signature="appended") An interface for Ground Control Points (GCP) based transformations. :py:class:`QgsGcpTransformerInterface` implementations are able to transform point locations diff --git a/python/analysis/auto_generated/interpolation/qgsgridfilewriter.sip.in b/python/analysis/auto_generated/interpolation/qgsgridfilewriter.sip.in index a585697f1947..c33fae68bb67 100644 --- a/python/analysis/auto_generated/interpolation/qgsgridfilewriter.sip.in +++ b/python/analysis/auto_generated/interpolation/qgsgridfilewriter.sip.in @@ -13,7 +13,7 @@ class QgsGridFileWriter { -%Docstring +%Docstring(signature="appended") A class that does interpolation to a grid and writes the results to an ascii grid. %End diff --git a/python/analysis/auto_generated/interpolation/qgsidwinterpolator.sip.in b/python/analysis/auto_generated/interpolation/qgsidwinterpolator.sip.in index 6abf2409a438..9eb9e782f676 100644 --- a/python/analysis/auto_generated/interpolation/qgsidwinterpolator.sip.in +++ b/python/analysis/auto_generated/interpolation/qgsidwinterpolator.sip.in @@ -11,7 +11,7 @@ class QgsIDWInterpolator: QgsInterpolator { -%Docstring +%Docstring(signature="appended") Inverse distance weight interpolator. %End diff --git a/python/analysis/auto_generated/interpolation/qgsinterpolator.sip.in b/python/analysis/auto_generated/interpolation/qgsinterpolator.sip.in index d2b3770b2866..14153f1452b4 100644 --- a/python/analysis/auto_generated/interpolation/qgsinterpolator.sip.in +++ b/python/analysis/auto_generated/interpolation/qgsinterpolator.sip.in @@ -32,7 +32,7 @@ Constructor for :py:class:`QgsInterpolatorVertexData` class QgsInterpolator { -%Docstring +%Docstring(signature="appended") Interface class for interpolations. Interpolators take diff --git a/python/analysis/auto_generated/interpolation/qgstininterpolator.sip.in b/python/analysis/auto_generated/interpolation/qgstininterpolator.sip.in index 2959596f15ba..2d7d93653722 100644 --- a/python/analysis/auto_generated/interpolation/qgstininterpolator.sip.in +++ b/python/analysis/auto_generated/interpolation/qgstininterpolator.sip.in @@ -12,7 +12,7 @@ class QgsTinInterpolator: QgsInterpolator { -%Docstring +%Docstring(signature="appended") Interpolation in a triangular irregular network .. versionadded:: 3.0 diff --git a/python/analysis/auto_generated/mesh/qgsmeshcontours.sip.in b/python/analysis/auto_generated/mesh/qgsmeshcontours.sip.in index 37c1ba2e0262..3e3cd8e2a242 100644 --- a/python/analysis/auto_generated/mesh/qgsmeshcontours.sip.in +++ b/python/analysis/auto_generated/mesh/qgsmeshcontours.sip.in @@ -13,7 +13,7 @@ class QgsMeshContours { -%Docstring +%Docstring(signature="appended") Exporter of contours lines or polygons from a mesh layer. diff --git a/python/analysis/auto_generated/mesh/qgsmeshtriangulation.sip.in b/python/analysis/auto_generated/mesh/qgsmeshtriangulation.sip.in index 4315b3d52c47..c2dab5ccf68e 100644 --- a/python/analysis/auto_generated/mesh/qgsmeshtriangulation.sip.in +++ b/python/analysis/auto_generated/mesh/qgsmeshtriangulation.sip.in @@ -13,7 +13,7 @@ class QgsMeshTriangulation : QObject { -%Docstring +%Docstring(signature="appended") Class that handles mesh creation with Delaunay constrained triangulation @@ -75,7 +75,7 @@ Sets the coordinate reference system used for the triangulation class QgsMeshZValueDatasetGroup: QgsMeshDatasetGroup { -%Docstring +%Docstring(signature="appended") Convenient class that can be used to obtain a datasetgroup on vertices that represents the Z value of the mesh vertices diff --git a/python/analysis/auto_generated/network/qgsgraph.sip.in b/python/analysis/auto_generated/network/qgsgraph.sip.in index b339257734de..614d68141610 100644 --- a/python/analysis/auto_generated/network/qgsgraph.sip.in +++ b/python/analysis/auto_generated/network/qgsgraph.sip.in @@ -13,7 +13,7 @@ class QgsGraphEdge { -%Docstring +%Docstring(signature="appended") This class implements a graph edge .. versionadded:: 3.0 @@ -62,7 +62,7 @@ typedef QList< int > QgsGraphEdgeIds; class QgsGraphVertex { -%Docstring +%Docstring(signature="appended") This class implements a graph vertex .. versionadded:: 3.0 @@ -108,7 +108,7 @@ Returns point associated with graph vertex. class QgsGraph { -%Docstring +%Docstring(signature="appended") Mathematical graph representation .. versionadded:: 3.0 diff --git a/python/analysis/auto_generated/network/qgsgraphanalyzer.sip.in b/python/analysis/auto_generated/network/qgsgraphanalyzer.sip.in index c11ef4117a53..eb7cbc8103d1 100644 --- a/python/analysis/auto_generated/network/qgsgraphanalyzer.sip.in +++ b/python/analysis/auto_generated/network/qgsgraphanalyzer.sip.in @@ -13,7 +13,7 @@ class QgsGraphAnalyzer { -%Docstring +%Docstring(signature="appended") This class performs graph analysis, e.g. calculates shortest path between two points using different strategies with Dijkstra algorithm %End diff --git a/python/analysis/auto_generated/network/qgsgraphbuilder.sip.in b/python/analysis/auto_generated/network/qgsgraphbuilder.sip.in index c4c88dd12d4a..20e8e1df8b33 100644 --- a/python/analysis/auto_generated/network/qgsgraphbuilder.sip.in +++ b/python/analysis/auto_generated/network/qgsgraphbuilder.sip.in @@ -13,7 +13,7 @@ class QgsGraphBuilder : QgsGraphBuilderInterface /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") This class used for making the :py:class:`QgsGraph` object %End diff --git a/python/analysis/auto_generated/network/qgsgraphbuilderinterface.sip.in b/python/analysis/auto_generated/network/qgsgraphbuilderinterface.sip.in index f8a9721f92d0..ceea140d6825 100644 --- a/python/analysis/auto_generated/network/qgsgraphbuilderinterface.sip.in +++ b/python/analysis/auto_generated/network/qgsgraphbuilderinterface.sip.in @@ -16,7 +16,7 @@ class QgsGraphBuilderInterface { -%Docstring +%Docstring(signature="appended") Determine interface for creating a graph. Contains the settings of the graph. :py:class:`QgsGraphBuilder` and :py:class:`QgsGraphDirector` both use a "builder" design pattern %End diff --git a/python/analysis/auto_generated/network/qgsgraphdirector.sip.in b/python/analysis/auto_generated/network/qgsgraphdirector.sip.in index 6061d576c0f0..42edfe59ff9c 100644 --- a/python/analysis/auto_generated/network/qgsgraphdirector.sip.in +++ b/python/analysis/auto_generated/network/qgsgraphdirector.sip.in @@ -16,7 +16,7 @@ class QgsGraphDirector : QObject { -%Docstring +%Docstring(signature="appended") Determine making the graph. :py:class:`QgsGraphBuilder` and :py:class:`QgsGraphDirector` implemented using "builder" design patter. %End diff --git a/python/analysis/auto_generated/network/qgsnetworkdistancestrategy.sip.in b/python/analysis/auto_generated/network/qgsnetworkdistancestrategy.sip.in index 112c2a78da05..60d93665864c 100644 --- a/python/analysis/auto_generated/network/qgsnetworkdistancestrategy.sip.in +++ b/python/analysis/auto_generated/network/qgsnetworkdistancestrategy.sip.in @@ -10,7 +10,7 @@ class QgsNetworkDistanceStrategy : QgsNetworkStrategy { -%Docstring +%Docstring(signature="appended") Strategy for calculating edge cost based on its length. Should be used for finding shortest path between two points. diff --git a/python/analysis/auto_generated/network/qgsnetworkspeedstrategy.sip.in b/python/analysis/auto_generated/network/qgsnetworkspeedstrategy.sip.in index 0c7d542973b6..919108ca485d 100644 --- a/python/analysis/auto_generated/network/qgsnetworkspeedstrategy.sip.in +++ b/python/analysis/auto_generated/network/qgsnetworkspeedstrategy.sip.in @@ -10,7 +10,7 @@ class QgsNetworkSpeedStrategy : QgsNetworkStrategy { -%Docstring +%Docstring(signature="appended") Strategy for calculating edge cost based on travel time. Should be used for finding fastest path between two points. diff --git a/python/analysis/auto_generated/network/qgsnetworkstrategy.sip.in b/python/analysis/auto_generated/network/qgsnetworkstrategy.sip.in index a8e59e8ff98c..c37ef6ce9f6a 100644 --- a/python/analysis/auto_generated/network/qgsnetworkstrategy.sip.in +++ b/python/analysis/auto_generated/network/qgsnetworkstrategy.sip.in @@ -17,7 +17,7 @@ class QgsNetworkStrategy { -%Docstring +%Docstring(signature="appended") :py:class:`QgsNetworkStrategy` defines strategy used for calculation of the edge cost. For example it can take into account travel distance, amount of time or money. Currently there are two strategies implemented in the analysis library: :py:class:`QgsNetworkDistanceStrategy` and :py:class:`QgsNetworkSpeedStrategy`. diff --git a/python/analysis/auto_generated/network/qgsvectorlayerdirector.sip.in b/python/analysis/auto_generated/network/qgsvectorlayerdirector.sip.in index 8d32a0d49c6a..137b493ce955 100644 --- a/python/analysis/auto_generated/network/qgsvectorlayerdirector.sip.in +++ b/python/analysis/auto_generated/network/qgsvectorlayerdirector.sip.in @@ -12,7 +12,7 @@ class QgsVectorLayerDirector : QgsGraphDirector { -%Docstring +%Docstring(signature="appended") Determine making the graph from vector line layer .. versionadded:: 3.0 diff --git a/python/analysis/auto_generated/processing/qgsalgorithmbatchgeocode.sip.in b/python/analysis/auto_generated/processing/qgsalgorithmbatchgeocode.sip.in index bbfec261a59d..83020ec9a278 100644 --- a/python/analysis/auto_generated/processing/qgsalgorithmbatchgeocode.sip.in +++ b/python/analysis/auto_generated/processing/qgsalgorithmbatchgeocode.sip.in @@ -12,7 +12,7 @@ class QgsBatchGeocodeAlgorithm : QgsProcessingFeatureBasedAlgorithm { -%Docstring +%Docstring(signature="appended") A base class for batch geocoder algorithms, which takes a :py:class:`QgsGeocoderInterface` object and exposes it as a Processing algorithm for batch geocoding operations. diff --git a/python/analysis/auto_generated/processing/qgsnativealgorithms.sip.in b/python/analysis/auto_generated/processing/qgsnativealgorithms.sip.in index c1c352f25cc2..718e624e4540 100644 --- a/python/analysis/auto_generated/processing/qgsnativealgorithms.sip.in +++ b/python/analysis/auto_generated/processing/qgsnativealgorithms.sip.in @@ -11,7 +11,7 @@ class QgsNativeAlgorithms: QgsProcessingProvider { -%Docstring +%Docstring(signature="appended") Native c++ processing algorithm provider. .. versionadded:: 3.0 diff --git a/python/analysis/auto_generated/qgsanalysis.sip.in b/python/analysis/auto_generated/qgsanalysis.sip.in index 9467ed5cdfe6..83e3eabaffc4 100644 --- a/python/analysis/auto_generated/qgsanalysis.sip.in +++ b/python/analysis/auto_generated/qgsanalysis.sip.in @@ -13,7 +13,7 @@ class QgsAnalysis { -%Docstring +%Docstring(signature="appended") :py:class:`QgsAnalysis` is a singleton class containing various registry and other global members related to analysis classes. diff --git a/python/analysis/auto_generated/raster/qgsalignraster.sip.in b/python/analysis/auto_generated/raster/qgsalignraster.sip.in index 145d29c5fd31..232fe965922a 100644 --- a/python/analysis/auto_generated/raster/qgsalignraster.sip.in +++ b/python/analysis/auto_generated/raster/qgsalignraster.sip.in @@ -13,7 +13,7 @@ class QgsAlignRaster { -%Docstring +%Docstring(signature="appended") :py:class:`QgsAlignRaster` takes one or more raster layers and warps (resamples) them so they have the same: diff --git a/python/analysis/auto_generated/raster/qgsaspectfilter.sip.in b/python/analysis/auto_generated/raster/qgsaspectfilter.sip.in index a713fb4ea708..f246d4b322af 100644 --- a/python/analysis/auto_generated/raster/qgsaspectfilter.sip.in +++ b/python/analysis/auto_generated/raster/qgsaspectfilter.sip.in @@ -11,7 +11,7 @@ class QgsAspectFilter: QgsDerivativeFilter { -%Docstring +%Docstring(signature="appended") Calculates aspect values in a window of 3x3 cells based on first order derivatives in x- and y- directions. Direction is clockwise starting from north. diff --git a/python/analysis/auto_generated/raster/qgsderivativefilter.sip.in b/python/analysis/auto_generated/raster/qgsderivativefilter.sip.in index ab9c922b9ffc..4e6a4590c7ef 100644 --- a/python/analysis/auto_generated/raster/qgsderivativefilter.sip.in +++ b/python/analysis/auto_generated/raster/qgsderivativefilter.sip.in @@ -11,7 +11,7 @@ class QgsDerivativeFilter : QgsNineCellFilter { -%Docstring +%Docstring(signature="appended") Adds the ability to calculate derivatives in x- and y-directions. Needs to be subclassed (e.g. for slope and aspect). diff --git a/python/analysis/auto_generated/raster/qgsexiftools.sip.in b/python/analysis/auto_generated/raster/qgsexiftools.sip.in index 8a03e56add09..34d272d7aeeb 100644 --- a/python/analysis/auto_generated/raster/qgsexiftools.sip.in +++ b/python/analysis/auto_generated/raster/qgsexiftools.sip.in @@ -11,7 +11,7 @@ class QgsExifTools { -%Docstring +%Docstring(signature="appended") Contains utilities for working with EXIF tags in images. .. versionadded:: 3.6 @@ -47,7 +47,7 @@ Returns ``True`` if the image at ``imagePath`` contains a valid geotag. class GeoTagDetails { -%Docstring +%Docstring(signature="appended") Extended image geotag details. .. versionadded:: 3.6 diff --git a/python/analysis/auto_generated/raster/qgshillshadefilter.sip.in b/python/analysis/auto_generated/raster/qgshillshadefilter.sip.in index edf82b2f9f14..ce940ef5b0b6 100644 --- a/python/analysis/auto_generated/raster/qgshillshadefilter.sip.in +++ b/python/analysis/auto_generated/raster/qgshillshadefilter.sip.in @@ -11,7 +11,7 @@ class QgsHillshadeFilter: QgsDerivativeFilter { -%Docstring +%Docstring(signature="appended") A hillshade filter. %End diff --git a/python/analysis/auto_generated/raster/qgskde.sip.in b/python/analysis/auto_generated/raster/qgskde.sip.in index 7cc732e697e2..2679c6ae8f2f 100644 --- a/python/analysis/auto_generated/raster/qgskde.sip.in +++ b/python/analysis/auto_generated/raster/qgskde.sip.in @@ -13,7 +13,7 @@ class QgsKernelDensityEstimation { -%Docstring +%Docstring(signature="appended") Performs Kernel Density Estimation ("heatmap") calculations on a vector layer. .. versionadded:: 3.0 diff --git a/python/analysis/auto_generated/raster/qgsninecellfilter.sip.in b/python/analysis/auto_generated/raster/qgsninecellfilter.sip.in index ae162bb9e94f..cef6e3f62254 100644 --- a/python/analysis/auto_generated/raster/qgsninecellfilter.sip.in +++ b/python/analysis/auto_generated/raster/qgsninecellfilter.sip.in @@ -12,7 +12,7 @@ class QgsNineCellFilter { -%Docstring +%Docstring(signature="appended") Base class for raster analysis methods that work with a 3x3 cell filter and calculate the value of each cell based on the cell value and the eight neighbour cells. Common examples are slope and aspect calculation in DEMs. Subclasses only implement diff --git a/python/analysis/auto_generated/raster/qgsrastercalcnode.sip.in b/python/analysis/auto_generated/raster/qgsrastercalcnode.sip.in index b192f94e599f..61dcf576a0da 100644 --- a/python/analysis/auto_generated/raster/qgsrastercalcnode.sip.in +++ b/python/analysis/auto_generated/raster/qgsrastercalcnode.sip.in @@ -12,7 +12,7 @@ class QgsRasterCalcNode { -%Docstring +%Docstring(signature="appended") Represents a node in a raster calculator. %End diff --git a/python/analysis/auto_generated/raster/qgsrastercalculator.sip.in b/python/analysis/auto_generated/raster/qgsrastercalculator.sip.in index c928fa548518..4ed8a937c2df 100644 --- a/python/analysis/auto_generated/raster/qgsrastercalculator.sip.in +++ b/python/analysis/auto_generated/raster/qgsrastercalculator.sip.in @@ -12,7 +12,7 @@ class QgsRasterCalculatorEntry { -%Docstring +%Docstring(signature="appended") Represents an individual raster layer/band number entry within a raster calculation. .. versionadded:: 2.18 @@ -45,7 +45,7 @@ also handled by appending an _n integer to the base name. class QgsRasterCalculator { -%Docstring +%Docstring(signature="appended") Performs raster layer calculations. %End diff --git a/python/analysis/auto_generated/raster/qgsrastermatrix.sip.in b/python/analysis/auto_generated/raster/qgsrastermatrix.sip.in index efbb2b6129f1..c364c8f73656 100644 --- a/python/analysis/auto_generated/raster/qgsrastermatrix.sip.in +++ b/python/analysis/auto_generated/raster/qgsrastermatrix.sip.in @@ -11,7 +11,7 @@ class QgsRasterMatrix { -%Docstring +%Docstring(signature="appended") Represents a matrix in a raster calculator operation. %End diff --git a/python/analysis/auto_generated/raster/qgsrelief.sip.in b/python/analysis/auto_generated/raster/qgsrelief.sip.in index 509331f2b847..a3ece49d0673 100644 --- a/python/analysis/auto_generated/raster/qgsrelief.sip.in +++ b/python/analysis/auto_generated/raster/qgsrelief.sip.in @@ -12,7 +12,7 @@ class QgsRelief { -%Docstring +%Docstring(signature="appended") Produces colored relief rasters from DEM. %End diff --git a/python/analysis/auto_generated/raster/qgsruggednessfilter.sip.in b/python/analysis/auto_generated/raster/qgsruggednessfilter.sip.in index 0d3e45ed0286..22be0dd85c5d 100644 --- a/python/analysis/auto_generated/raster/qgsruggednessfilter.sip.in +++ b/python/analysis/auto_generated/raster/qgsruggednessfilter.sip.in @@ -11,7 +11,7 @@ class QgsRuggednessFilter: QgsNineCellFilter { -%Docstring +%Docstring(signature="appended") Calculates the ruggedness index based on a 3x3 moving window. Algorithm from Riley et al. 1999: A terrain ruggedness index that quantifies topographic heterogeneity diff --git a/python/analysis/auto_generated/raster/qgsslopefilter.sip.in b/python/analysis/auto_generated/raster/qgsslopefilter.sip.in index b178ce5ce8c6..b770d41990c2 100644 --- a/python/analysis/auto_generated/raster/qgsslopefilter.sip.in +++ b/python/analysis/auto_generated/raster/qgsslopefilter.sip.in @@ -11,7 +11,7 @@ class QgsSlopeFilter: QgsDerivativeFilter { -%Docstring +%Docstring(signature="appended") Calculates slope values in a window of 3x3 cells based on first order derivatives in x- and y- directions. %End diff --git a/python/analysis/auto_generated/raster/qgstotalcurvaturefilter.sip.in b/python/analysis/auto_generated/raster/qgstotalcurvaturefilter.sip.in index 12b72ab170e2..2bc8aebffea4 100644 --- a/python/analysis/auto_generated/raster/qgstotalcurvaturefilter.sip.in +++ b/python/analysis/auto_generated/raster/qgstotalcurvaturefilter.sip.in @@ -11,7 +11,7 @@ class QgsTotalCurvatureFilter: QgsNineCellFilter { -%Docstring +%Docstring(signature="appended") Calculates total curvature as described by Wilson, Gallant (2000): terrain analysis. %End diff --git a/python/analysis/auto_generated/vector/geometry_checker/qgsfeaturepool.sip.in b/python/analysis/auto_generated/vector/geometry_checker/qgsfeaturepool.sip.in index ba1dd5e3d4f5..6dfc9531ec36 100644 --- a/python/analysis/auto_generated/vector/geometry_checker/qgsfeaturepool.sip.in +++ b/python/analysis/auto_generated/vector/geometry_checker/qgsfeaturepool.sip.in @@ -12,7 +12,7 @@ class QgsFeaturePool : QgsFeatureSink /Abstract/ { -%Docstring +%Docstring(signature="appended") A feature pool is based on a vector layer and caches features. .. note:: diff --git a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheck.sip.in b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheck.sip.in index 94944e8e93fa..6465c4a65965 100644 --- a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheck.sip.in +++ b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheck.sip.in @@ -12,7 +12,7 @@ class QgsGeometryCheck { -%Docstring +%Docstring(signature="appended") This class implements a geometry check. Geometry checks run over a set of features and can detect errors like topological diff --git a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckcontext.sip.in b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckcontext.sip.in index a964f8a846a9..0f1f8b62166d 100644 --- a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckcontext.sip.in +++ b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckcontext.sip.in @@ -10,7 +10,7 @@ class QgsGeometryCheckContext { -%Docstring +%Docstring(signature="appended") Base configuration for geometry checks. .. note:: diff --git a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckerror.sip.in b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckerror.sip.in index ecbfa90de566..ff5d608c8b0f 100644 --- a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckerror.sip.in +++ b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckerror.sip.in @@ -13,7 +13,7 @@ class QgsGeometryCheckError { -%Docstring +%Docstring(signature="appended") This represents an error reported by a geometry check. .. note:: diff --git a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckerutils.sip.in b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckerutils.sip.in index 62019eddb242..d50f0d06b7c0 100644 --- a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckerutils.sip.in +++ b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckerutils.sip.in @@ -12,7 +12,7 @@ class QgsGeometryCheckerUtils { -%Docstring +%Docstring(signature="appended") Contains utilities required for geometry checks. @@ -30,7 +30,7 @@ Contains utilities required for geometry checks. class LayerFeature { -%Docstring +%Docstring(signature="appended") A layer feature combination to uniquely identify and access a feature in a set of layers. @@ -86,7 +86,7 @@ Returns if the geometry is reprojected to the map CRS or not. class LayerFeatures { -%Docstring +%Docstring(signature="appended") Contains a set of layers and feature ids in those layers to pass to a geometry check. diff --git a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckfactory.sip.in b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckfactory.sip.in index f3bd002848e8..4a9315676676 100644 --- a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckfactory.sip.in +++ b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckfactory.sip.in @@ -14,7 +14,7 @@ class QgsGeometryCheckFactory /Abstract/ { -%Docstring +%Docstring(signature="appended") A factory for geometry checks. @@ -66,7 +66,7 @@ The type of this check. template class QgsGeometryCheckFactoryT : QgsGeometryCheckFactory { -%Docstring +%Docstring(signature="appended") Template to create a factory for a geometry check. .. note:: diff --git a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckregistry.sip.in b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckregistry.sip.in index cc3e2138c3d9..d7c6f418fbfa 100644 --- a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckregistry.sip.in +++ b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckregistry.sip.in @@ -13,7 +13,7 @@ class QgsGeometryCheckRegistry { -%Docstring +%Docstring(signature="appended") This class manages all known geometry check factories. :py:class:`QgsGeometryCheckRegistry` is not usually directly created, but rather accessed through diff --git a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckresolutionmethod.sip.in b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckresolutionmethod.sip.in index 829bb54e0a10..37358eee174c 100644 --- a/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckresolutionmethod.sip.in +++ b/python/analysis/auto_generated/vector/geometry_checker/qgsgeometrycheckresolutionmethod.sip.in @@ -10,7 +10,7 @@ class QgsGeometryCheckResolutionMethod { -%Docstring +%Docstring(signature="appended") This class implements a resolution for problems detected in geometry checks. .. versionadded:: 3.12 diff --git a/python/analysis/auto_generated/vector/geometry_checker/qgssinglegeometrycheck.sip.in b/python/analysis/auto_generated/vector/geometry_checker/qgssinglegeometrycheck.sip.in index 104c0f71e5c1..3dfcc3337681 100644 --- a/python/analysis/auto_generated/vector/geometry_checker/qgssinglegeometrycheck.sip.in +++ b/python/analysis/auto_generated/vector/geometry_checker/qgssinglegeometrycheck.sip.in @@ -13,7 +13,7 @@ class QgsSingleGeometryCheckError { -%Docstring +%Docstring(signature="appended") An error from a :py:class:`QgsSingleGeometryCheck`. @@ -81,7 +81,7 @@ The vertex id of the error. May be invalid depending on the check. class QgsGeometryCheckErrorSingle : QgsGeometryCheckError { -%Docstring +%Docstring(signature="appended") Wraps a :py:class:`QgsSingleGeometryError` into a standard :py:class:`QgsGeometryCheckError`. The single error can be obtained via singleError. @@ -115,7 +115,7 @@ The underlying single error. class QgsSingleGeometryCheck : QgsGeometryCheck { -%Docstring +%Docstring(signature="appended") Base class for geometry checks for a single geometry without any context of the layer or other layers in the project. Classic examples are validity checks like self-intersection. diff --git a/python/analysis/auto_generated/vector/qgsgeometrysnapper.sip.in b/python/analysis/auto_generated/vector/qgsgeometrysnapper.sip.in index 5b4b1ca61536..a30cfad4dbb2 100644 --- a/python/analysis/auto_generated/vector/qgsgeometrysnapper.sip.in +++ b/python/analysis/auto_generated/vector/qgsgeometrysnapper.sip.in @@ -12,7 +12,7 @@ class QgsGeometrySnapper : QObject { -%Docstring +%Docstring(signature="appended") :py:class:`QgsGeometrySnapper` allows a geometry to be snapped to the geometries within a different reference layer. Vertices in the geometries will be modified to match the reference layer features within a specified snap tolerance. @@ -74,7 +74,7 @@ Emitted each time a feature has been processed when calling :py:func:`~QgsGeomet class QgsInternalGeometrySnapper { -%Docstring +%Docstring(signature="appended") :py:class:`QgsInternalGeometrySnapper` allows a set of geometries to be snapped to each other. It can be used to close gaps in layers. To use :py:class:`QgsInternalGeometrySnapper`, first construct the snapper using the desired snap parameters. Then, diff --git a/python/analysis/auto_generated/vector/qgsgeometrysnappersinglesource.sip.in b/python/analysis/auto_generated/vector/qgsgeometrysnappersinglesource.sip.in index d5a0e10acc54..a5fe8e7b8e2e 100644 --- a/python/analysis/auto_generated/vector/qgsgeometrysnappersinglesource.sip.in +++ b/python/analysis/auto_generated/vector/qgsgeometrysnappersinglesource.sip.in @@ -11,7 +11,7 @@ class QgsGeometrySnapperSingleSource { -%Docstring +%Docstring(signature="appended") Makes sure that any two vertices of the vector layer are at least at distance given by the threshold value. diff --git a/python/analysis/auto_generated/vector/qgszonalstatistics.sip.in b/python/analysis/auto_generated/vector/qgszonalstatistics.sip.in index 108b9b5d7bf6..ac0450578e96 100644 --- a/python/analysis/auto_generated/vector/qgszonalstatistics.sip.in +++ b/python/analysis/auto_generated/vector/qgszonalstatistics.sip.in @@ -14,7 +14,7 @@ class QgsZonalStatistics { -%Docstring +%Docstring(signature="appended") A class that calculates raster statistics (count, sum, mean) for a polygon or multipolygon layer and appends the results as attributes. %End diff --git a/python/core/auto_generated/3d/qgs3drendererregistry.sip.in b/python/core/auto_generated/3d/qgs3drendererregistry.sip.in index cc8716df759c..9b88283a4f6c 100644 --- a/python/core/auto_generated/3d/qgs3drendererregistry.sip.in +++ b/python/core/auto_generated/3d/qgs3drendererregistry.sip.in @@ -13,7 +13,7 @@ class Qgs3DRendererAbstractMetadata { -%Docstring +%Docstring(signature="appended") Base metadata class for 3D renderers. Instances of derived classes may be registered in Qgs3DRendererRegistry. .. versionadded:: 3.0 @@ -50,7 +50,7 @@ Constructor of the base class class Qgs3DRendererRegistry { -%Docstring +%Docstring(signature="appended") Keeps track of available 3D renderers. Should be accessed through :py:func:`QgsApplication.renderer3DRegistry()` singleton. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/3d/qgs3dsymbolregistry.sip.in b/python/core/auto_generated/3d/qgs3dsymbolregistry.sip.in index 4777dcb70f72..aa6386696e55 100644 --- a/python/core/auto_generated/3d/qgs3dsymbolregistry.sip.in +++ b/python/core/auto_generated/3d/qgs3dsymbolregistry.sip.in @@ -12,7 +12,7 @@ class Qgs3DSymbolAbstractMetadata { -%Docstring +%Docstring(signature="appended") Stores metadata about one 3D symbol class. .. note:: @@ -62,7 +62,7 @@ Caller takes ownership of the returned symbol. class Qgs3DSymbolRegistry { -%Docstring +%Docstring(signature="appended") Registry of available 3D symbol classes. Qgs3DSymbolRegistry is not usually directly created, but rather accessed through diff --git a/python/core/auto_generated/3d/qgsabstract3drenderer.sip.in b/python/core/auto_generated/3d/qgsabstract3drenderer.sip.in index ddf4b8dbf27f..0a182600945d 100644 --- a/python/core/auto_generated/3d/qgsabstract3drenderer.sip.in +++ b/python/core/auto_generated/3d/qgsabstract3drenderer.sip.in @@ -13,7 +13,7 @@ class QgsAbstract3DRenderer /Abstract/ { -%Docstring +%Docstring(signature="appended") Base class for all renderers that may to participate in 3D view. 3D renderers implement the method :py:func:`~createEntity` that returns a new 3D entity - that entity diff --git a/python/core/auto_generated/3d/qgsabstract3dsymbol.sip.in b/python/core/auto_generated/3d/qgsabstract3dsymbol.sip.in index 03f5c5f717bb..d5fc046a3fee 100644 --- a/python/core/auto_generated/3d/qgsabstract3dsymbol.sip.in +++ b/python/core/auto_generated/3d/qgsabstract3dsymbol.sip.in @@ -14,7 +14,7 @@ class QgsAbstract3DSymbol { -%Docstring +%Docstring(signature="appended") Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects. 3D symbol objects define appearance of GIS data. diff --git a/python/core/auto_generated/annotations/qgsannotation.sip.in b/python/core/auto_generated/annotations/qgsannotation.sip.in index 0d3bfb4d4a03..9b0dd29a3dde 100644 --- a/python/core/auto_generated/annotations/qgsannotation.sip.in +++ b/python/core/auto_generated/annotations/qgsannotation.sip.in @@ -14,7 +14,7 @@ class QgsAnnotation : QObject { -%Docstring +%Docstring(signature="appended") Abstract base class for annotation items which are drawn over a map. diff --git a/python/core/auto_generated/annotations/qgsannotationitem.sip.in b/python/core/auto_generated/annotations/qgsannotationitem.sip.in index 63f62e5ef89a..4f85aaedb890 100644 --- a/python/core/auto_generated/annotations/qgsannotationitem.sip.in +++ b/python/core/auto_generated/annotations/qgsannotationitem.sip.in @@ -12,7 +12,7 @@ class QgsAnnotationItem { -%Docstring +%Docstring(signature="appended") Abstract base class for annotation items which are drawn with :py:class:`QgsAnnotationLayers`. .. versionadded:: 3.16 diff --git a/python/core/auto_generated/annotations/qgsannotationitemregistry.sip.in b/python/core/auto_generated/annotations/qgsannotationitemregistry.sip.in index c54f2fcf7b3e..442e0591f0e4 100644 --- a/python/core/auto_generated/annotations/qgsannotationitemregistry.sip.in +++ b/python/core/auto_generated/annotations/qgsannotationitemregistry.sip.in @@ -10,7 +10,7 @@ class QgsAnnotationItemAbstractMetadata { -%Docstring +%Docstring(signature="appended") Stores metadata about one annotation item class. A companion class, :py:class:`QgsAnnotationItemAbstractGuiMetadata`, handles the @@ -67,7 +67,7 @@ Creates a new, default, annotation item of this class. class QgsAnnotationItemRegistry : QObject { -%Docstring +%Docstring(signature="appended") Registry of available annotation item types. :py:class:`QgsAnnotationItemRegistry` is not usually directly created, but rather accessed through diff --git a/python/core/auto_generated/annotations/qgsannotationlayer.sip.in b/python/core/auto_generated/annotations/qgsannotationlayer.sip.in index 2a1c42769a8d..1d6675a7fcb1 100644 --- a/python/core/auto_generated/annotations/qgsannotationlayer.sip.in +++ b/python/core/auto_generated/annotations/qgsannotationlayer.sip.in @@ -13,7 +13,7 @@ class QgsAnnotationLayer : QgsMapLayer { -%Docstring +%Docstring(signature="appended") Represents a map layer containing a set of georeferenced annotations, e.g. markers, lines, polygons or text items. diff --git a/python/core/auto_generated/annotations/qgsannotationlineitem.sip.in b/python/core/auto_generated/annotations/qgsannotationlineitem.sip.in index 6528da44ecb1..9f2c080b5680 100644 --- a/python/core/auto_generated/annotations/qgsannotationlineitem.sip.in +++ b/python/core/auto_generated/annotations/qgsannotationlineitem.sip.in @@ -12,7 +12,7 @@ class QgsAnnotationLineItem : QgsAnnotationItem { -%Docstring +%Docstring(signature="appended") An annotation item which renders a line symbol along a line geometry. .. versionadded:: 3.16 diff --git a/python/core/auto_generated/annotations/qgsannotationmanager.sip.in b/python/core/auto_generated/annotations/qgsannotationmanager.sip.in index 04ce42efe4c7..b3d170eb27b4 100644 --- a/python/core/auto_generated/annotations/qgsannotationmanager.sip.in +++ b/python/core/auto_generated/annotations/qgsannotationmanager.sip.in @@ -11,7 +11,7 @@ class QgsAnnotationManager : QObject { -%Docstring +%Docstring(signature="appended") Manages storage of a set of :py:class:`QgsAnnotation` annotation objects. diff --git a/python/core/auto_generated/annotations/qgsannotationmarkeritem.sip.in b/python/core/auto_generated/annotations/qgsannotationmarkeritem.sip.in index 9f2221702cbd..fb00ad66b6a4 100644 --- a/python/core/auto_generated/annotations/qgsannotationmarkeritem.sip.in +++ b/python/core/auto_generated/annotations/qgsannotationmarkeritem.sip.in @@ -12,7 +12,7 @@ class QgsAnnotationMarkerItem : QgsAnnotationItem { -%Docstring +%Docstring(signature="appended") An annotation item which renders a marker symbol at a point location. .. versionadded:: 3.16 diff --git a/python/core/auto_generated/annotations/qgsannotationpointtextitem.sip.in b/python/core/auto_generated/annotations/qgsannotationpointtextitem.sip.in index 8174da712a96..ea70a78c1080 100644 --- a/python/core/auto_generated/annotations/qgsannotationpointtextitem.sip.in +++ b/python/core/auto_generated/annotations/qgsannotationpointtextitem.sip.in @@ -12,7 +12,7 @@ class QgsAnnotationPointTextItem : QgsAnnotationItem { -%Docstring +%Docstring(signature="appended") An annotation item which renders a text string at a point location. .. versionadded:: 3.16 diff --git a/python/core/auto_generated/annotations/qgsannotationpolygonitem.sip.in b/python/core/auto_generated/annotations/qgsannotationpolygonitem.sip.in index 5aac42a4f311..e53d658c22d4 100644 --- a/python/core/auto_generated/annotations/qgsannotationpolygonitem.sip.in +++ b/python/core/auto_generated/annotations/qgsannotationpolygonitem.sip.in @@ -12,7 +12,7 @@ class QgsAnnotationPolygonItem : QgsAnnotationItem { -%Docstring +%Docstring(signature="appended") An annotation item which renders a fill symbol for a polygon geometry. .. versionadded:: 3.16 diff --git a/python/core/auto_generated/annotations/qgshtmlannotation.sip.in b/python/core/auto_generated/annotations/qgshtmlannotation.sip.in index 459df194c2fe..251a68b4c88c 100644 --- a/python/core/auto_generated/annotations/qgshtmlannotation.sip.in +++ b/python/core/auto_generated/annotations/qgshtmlannotation.sip.in @@ -14,7 +14,7 @@ class QgsHtmlAnnotation: QgsAnnotation { -%Docstring +%Docstring(signature="appended") An annotation item that embeds HTML content. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/annotations/qgssvgannotation.sip.in b/python/core/auto_generated/annotations/qgssvgannotation.sip.in index 64935b5f1d52..4ea4081bb57a 100644 --- a/python/core/auto_generated/annotations/qgssvgannotation.sip.in +++ b/python/core/auto_generated/annotations/qgssvgannotation.sip.in @@ -11,7 +11,7 @@ class QgsSvgAnnotation: QgsAnnotation { -%Docstring +%Docstring(signature="appended") An annotation which renders the contents of an SVG file. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/annotations/qgstextannotation.sip.in b/python/core/auto_generated/annotations/qgstextannotation.sip.in index 5d34c049944e..c901050b1b9e 100644 --- a/python/core/auto_generated/annotations/qgstextannotation.sip.in +++ b/python/core/auto_generated/annotations/qgstextannotation.sip.in @@ -11,7 +11,7 @@ class QgsTextAnnotation: QgsAnnotation { -%Docstring +%Docstring(signature="appended") An annotation item that displays formatted text from a QTextDocument document. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/auth/qgsauthcertutils.sip.in b/python/core/auto_generated/auth/qgsauthcertutils.sip.in index e8f028eaa591..f34845a2c122 100644 --- a/python/core/auto_generated/auth/qgsauthcertutils.sip.in +++ b/python/core/auto_generated/auth/qgsauthcertutils.sip.in @@ -15,7 +15,7 @@ class QgsAuthCertUtils { -%Docstring +%Docstring(signature="appended") Utilities for working with certificates and keys %End diff --git a/python/core/auto_generated/auth/qgsauthconfig.sip.in b/python/core/auto_generated/auth/qgsauthconfig.sip.in index d4ac31b6fe80..87eb33942e2a 100644 --- a/python/core/auto_generated/auth/qgsauthconfig.sip.in +++ b/python/core/auto_generated/auth/qgsauthconfig.sip.in @@ -13,7 +13,7 @@ class QgsAuthMethodConfig { -%Docstring +%Docstring(signature="appended") Configuration storage class for authentication method configurations %End @@ -194,7 +194,7 @@ typedef QHash QgsAuthMethodConfigsMap; class QgsPkiBundle { -%Docstring +%Docstring(signature="appended") Storage set for PKI bundle: SSL certificate, key, optional CA cert chain .. note:: @@ -287,7 +287,7 @@ Sets chain of Certificate Authorities for client certificate class QgsPkiConfigBundle { -%Docstring +%Docstring(signature="appended") Storage set for constructed SSL certificate, key, associated with an authentication config %End @@ -413,7 +413,7 @@ setCaChain set the CA chain class QgsAuthConfigSslServer { -%Docstring +%Docstring(signature="appended") Configuration container for SSL server connection exceptions or overrides %End diff --git a/python/core/auto_generated/auth/qgsauthmanager.sip.in b/python/core/auto_generated/auth/qgsauthmanager.sip.in index bb5498201794..7f6e471f7327 100644 --- a/python/core/auto_generated/auth/qgsauthmanager.sip.in +++ b/python/core/auto_generated/auth/qgsauthmanager.sip.in @@ -15,7 +15,7 @@ class QgsAuthManager : QObject { -%Docstring +%Docstring(signature="appended") Singleton offering an interface to manage the authentication configuration database and to utilize configurations through various authentication method plugins diff --git a/python/core/auto_generated/auth/qgsauthmethod.sip.in b/python/core/auto_generated/auth/qgsauthmethod.sip.in index 9b4b1ff43d41..65bba23e5cb5 100644 --- a/python/core/auto_generated/auth/qgsauthmethod.sip.in +++ b/python/core/auto_generated/auth/qgsauthmethod.sip.in @@ -12,7 +12,7 @@ class QgsAuthMethod : QObject { -%Docstring +%Docstring(signature="appended") Abstract base class for authentication method plugins %End diff --git a/python/core/auto_generated/callouts/qgscallout.sip.in b/python/core/auto_generated/callouts/qgscallout.sip.in index 77506411d95b..e6a9ebfeeb49 100644 --- a/python/core/auto_generated/callouts/qgscallout.sip.in +++ b/python/core/auto_generated/callouts/qgscallout.sip.in @@ -12,7 +12,7 @@ class QgsCallout { -%Docstring +%Docstring(signature="appended") Abstract base class for callout renderers. Implementations of :py:class:`QgsCallout` are responsible for performing the actual render of @@ -201,7 +201,7 @@ The default order is QgsCallout.OrderBelowIndividualLabels. class QgsCalloutContext { -%Docstring +%Docstring(signature="appended") Contains additional contextual information about the context in which a callout is being rendered. @@ -446,7 +446,7 @@ The ``pinned`` argument will be set to ``True`` if the callout anchor point is p class QgsSimpleLineCallout : QgsCallout { -%Docstring +%Docstring(signature="appended") A simple direct line callout style. .. versionadded:: 3.10 @@ -710,7 +710,7 @@ The base class method returns a straight line. class QgsManhattanLineCallout : QgsSimpleLineCallout { -%Docstring +%Docstring(signature="appended") Draws straight (right angled) lines as callouts. .. versionadded:: 3.10 @@ -748,7 +748,7 @@ serialized in the ``properties`` map (corresponding to the output from class QgsCurvedLineCallout : QgsSimpleLineCallout { -%Docstring +%Docstring(signature="appended") Draws curved lines as callouts. .. versionadded:: 3.20 @@ -827,7 +827,7 @@ Sets the callout line's curve ``orientation``. class QgsBalloonCallout : QgsCallout { -%Docstring +%Docstring(signature="appended") A cartoon talking bubble callout style. .. versionadded:: 3.20 diff --git a/python/core/auto_generated/callouts/qgscalloutsregistry.sip.in b/python/core/auto_generated/callouts/qgscalloutsregistry.sip.in index 2d543536abfc..3a701c279490 100644 --- a/python/core/auto_generated/callouts/qgscalloutsregistry.sip.in +++ b/python/core/auto_generated/callouts/qgscalloutsregistry.sip.in @@ -12,7 +12,7 @@ class QgsCalloutWidget /External/; class QgsCalloutAbstractMetadata { -%Docstring +%Docstring(signature="appended") Stores metadata about one callout renderer class. .. note:: @@ -87,7 +87,7 @@ Ownership of the widget is transferred to the caller. class QgsCalloutMetadata : QgsCalloutAbstractMetadata { -%Docstring +%Docstring(signature="appended") Convenience metadata class that uses static functions to create callouts and their widgets. .. versionadded:: 3.10 @@ -115,7 +115,7 @@ Convenience metadata class that uses static functions to create callouts and the class QgsCalloutRegistry { -%Docstring +%Docstring(signature="appended") Registry of available callout classes. :py:class:`QgsCalloutRegistry` is not usually directly created, but rather accessed through diff --git a/python/core/auto_generated/classification/qgsclassificationcustom.sip.in b/python/core/auto_generated/classification/qgsclassificationcustom.sip.in index 659a413e149b..2b657c733abb 100644 --- a/python/core/auto_generated/classification/qgsclassificationcustom.sip.in +++ b/python/core/auto_generated/classification/qgsclassificationcustom.sip.in @@ -11,7 +11,7 @@ class QgsClassificationCustom : QgsClassificationMethod { -%Docstring +%Docstring(signature="appended") :py:class:`QgsClassificationCustom` is a dummy implementation of :py:class:`QgsClassification` which does not compute any break. diff --git a/python/core/auto_generated/classification/qgsclassificationequalinterval.sip.in b/python/core/auto_generated/classification/qgsclassificationequalinterval.sip.in index f0d2d225121d..0a618706e4dc 100644 --- a/python/core/auto_generated/classification/qgsclassificationequalinterval.sip.in +++ b/python/core/auto_generated/classification/qgsclassificationequalinterval.sip.in @@ -10,7 +10,7 @@ class QgsClassificationEqualInterval : QgsClassificationMethod { -%Docstring +%Docstring(signature="appended") :py:class:`QgsClassificationEqualInterval` is an implementation of :py:class:`QgsClassificationMethod` for equal intervals diff --git a/python/core/auto_generated/classification/qgsclassificationjenks.sip.in b/python/core/auto_generated/classification/qgsclassificationjenks.sip.in index ee6aecb08468..fdac1e06a664 100644 --- a/python/core/auto_generated/classification/qgsclassificationjenks.sip.in +++ b/python/core/auto_generated/classification/qgsclassificationjenks.sip.in @@ -10,7 +10,7 @@ class QgsClassificationJenks : QgsClassificationMethod { -%Docstring +%Docstring(signature="appended") :py:class:`QgsClassificationJenks` is an implementation of :py:class:`QgsClassificationMethod` for natural breaks based on Jenks method diff --git a/python/core/auto_generated/classification/qgsclassificationlogarithmic.sip.in b/python/core/auto_generated/classification/qgsclassificationlogarithmic.sip.in index 116c601e4372..64790c865124 100644 --- a/python/core/auto_generated/classification/qgsclassificationlogarithmic.sip.in +++ b/python/core/auto_generated/classification/qgsclassificationlogarithmic.sip.in @@ -11,7 +11,7 @@ class QgsClassificationLogarithmic : QgsClassificationMethod { -%Docstring +%Docstring(signature="appended") Implementation of a logarithmic scale method .. versionadded:: 3.10 diff --git a/python/core/auto_generated/classification/qgsclassificationmethod.sip.in b/python/core/auto_generated/classification/qgsclassificationmethod.sip.in index 579d6cf1be30..e120f55c7f7a 100644 --- a/python/core/auto_generated/classification/qgsclassificationmethod.sip.in +++ b/python/core/auto_generated/classification/qgsclassificationmethod.sip.in @@ -25,7 +25,7 @@ class QgsClassificationRange { -%Docstring +%Docstring(signature="appended") :py:class:`QgsClassificationRange` contains the information about a classification range .. versionadded:: 3.10 @@ -65,7 +65,7 @@ Returns the lower bound class QgsClassificationMethod /Abstract/ { -%Docstring +%Docstring(signature="appended") :py:class:`QgsClassificationMethod` is an abstract class for implementations of classification methods .. seealso:: :py:class:`QgsClassificationMethodRegistry` diff --git a/python/core/auto_generated/classification/qgsclassificationmethodregistry.sip.in b/python/core/auto_generated/classification/qgsclassificationmethodregistry.sip.in index 10e17ad7a3d9..640722966b77 100644 --- a/python/core/auto_generated/classification/qgsclassificationmethodregistry.sip.in +++ b/python/core/auto_generated/classification/qgsclassificationmethodregistry.sip.in @@ -14,7 +14,7 @@ class QgsClassificationMethodRegistry { -%Docstring +%Docstring(signature="appended") This class manages all known classification methods :py:class:`QgsClassificationMethodRegistry` is not usually directly created, but rather accessed through diff --git a/python/core/auto_generated/classification/qgsclassificationprettybreaks.sip.in b/python/core/auto_generated/classification/qgsclassificationprettybreaks.sip.in index f367694cd183..ddc0a5d10fa9 100644 --- a/python/core/auto_generated/classification/qgsclassificationprettybreaks.sip.in +++ b/python/core/auto_generated/classification/qgsclassificationprettybreaks.sip.in @@ -10,7 +10,7 @@ class QgsClassificationPrettyBreaks : QgsClassificationMethod { -%Docstring +%Docstring(signature="appended") :py:class:`QgsClassificationPrettyBreaks` is an implementation of :py:class:`QgsClassificationMethod` for pretty breaks diff --git a/python/core/auto_generated/classification/qgsclassificationquantile.sip.in b/python/core/auto_generated/classification/qgsclassificationquantile.sip.in index 8cb008e613cd..5b0512f8349e 100644 --- a/python/core/auto_generated/classification/qgsclassificationquantile.sip.in +++ b/python/core/auto_generated/classification/qgsclassificationquantile.sip.in @@ -11,7 +11,7 @@ class QgsClassificationQuantile : QgsClassificationMethod { -%Docstring +%Docstring(signature="appended") :py:class:`QgsClassificationQuantile` is an implementation of :py:class:`QgsClassificationMethod` based on quantiles diff --git a/python/core/auto_generated/classification/qgsclassificationstandarddeviation.sip.in b/python/core/auto_generated/classification/qgsclassificationstandarddeviation.sip.in index 88bd573b6bf8..11ce7892ff19 100644 --- a/python/core/auto_generated/classification/qgsclassificationstandarddeviation.sip.in +++ b/python/core/auto_generated/classification/qgsclassificationstandarddeviation.sip.in @@ -10,7 +10,7 @@ class QgsClassificationStandardDeviation : QgsClassificationMethod { -%Docstring +%Docstring(signature="appended") :py:class:`QgsClassificationCustom` is an implementation of :py:class:`QgsClassificationMethod` based on standard deviation diff --git a/python/core/auto_generated/diagram/qgsdiagram.sip.in b/python/core/auto_generated/diagram/qgsdiagram.sip.in index c04f176f4f26..b3015203709e 100644 --- a/python/core/auto_generated/diagram/qgsdiagram.sip.in +++ b/python/core/auto_generated/diagram/qgsdiagram.sip.in @@ -11,7 +11,7 @@ class QgsDiagram /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") Base class for all diagram types. %End diff --git a/python/core/auto_generated/diagram/qgshistogramdiagram.sip.in b/python/core/auto_generated/diagram/qgshistogramdiagram.sip.in index add1b68977ff..22dd17f30be9 100644 --- a/python/core/auto_generated/diagram/qgshistogramdiagram.sip.in +++ b/python/core/auto_generated/diagram/qgshistogramdiagram.sip.in @@ -13,7 +13,7 @@ class QgsHistogramDiagram: QgsDiagram /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A histogram style diagram. %End diff --git a/python/core/auto_generated/diagram/qgspiediagram.sip.in b/python/core/auto_generated/diagram/qgspiediagram.sip.in index f7b2e5282afc..c80466a18bb9 100644 --- a/python/core/auto_generated/diagram/qgspiediagram.sip.in +++ b/python/core/auto_generated/diagram/qgspiediagram.sip.in @@ -11,7 +11,7 @@ class QgsPieDiagram: QgsDiagram /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A pie chart diagram. %End diff --git a/python/core/auto_generated/diagram/qgsstackedbardiagram.sip.in b/python/core/auto_generated/diagram/qgsstackedbardiagram.sip.in index 2bf9a12e7bf7..262d300b5199 100644 --- a/python/core/auto_generated/diagram/qgsstackedbardiagram.sip.in +++ b/python/core/auto_generated/diagram/qgsstackedbardiagram.sip.in @@ -13,7 +13,7 @@ class QgsStackedBarDiagram: QgsDiagram /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A stacked bar chart diagram. diff --git a/python/core/auto_generated/diagram/qgstextdiagram.sip.in b/python/core/auto_generated/diagram/qgstextdiagram.sip.in index c2a846ef4b6f..2a2a54067c49 100644 --- a/python/core/auto_generated/diagram/qgstextdiagram.sip.in +++ b/python/core/auto_generated/diagram/qgstextdiagram.sip.in @@ -11,7 +11,7 @@ class QgsTextDiagram: QgsDiagram /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A text based diagram. %End diff --git a/python/core/auto_generated/dxf/qgsdxfexport.sip.in b/python/core/auto_generated/dxf/qgsdxfexport.sip.in index 2fcabfa55319..4c27716f83c7 100644 --- a/python/core/auto_generated/dxf/qgsdxfexport.sip.in +++ b/python/core/auto_generated/dxf/qgsdxfexport.sip.in @@ -16,7 +16,7 @@ class QgsDxfExport { -%Docstring +%Docstring(signature="appended") Exports QGIS layers to the DXF format. %End diff --git a/python/core/auto_generated/editform/qgsattributeeditorcontainer.sip.in b/python/core/auto_generated/editform/qgsattributeeditorcontainer.sip.in index e76784f4ac9e..0a919b448762 100644 --- a/python/core/auto_generated/editform/qgsattributeeditorcontainer.sip.in +++ b/python/core/auto_generated/editform/qgsattributeeditorcontainer.sip.in @@ -9,7 +9,7 @@ class QgsAttributeEditorContainer : QgsAttributeEditorElement { -%Docstring +%Docstring(signature="appended") This is a container for attribute editors, used to group them visually in the attribute form if it is set to the drag and drop designer. %End diff --git a/python/core/auto_generated/editform/qgsattributeeditorelement.sip.in b/python/core/auto_generated/editform/qgsattributeeditorelement.sip.in index 5979fa45ef76..47aeba4fb558 100644 --- a/python/core/auto_generated/editform/qgsattributeeditorelement.sip.in +++ b/python/core/auto_generated/editform/qgsattributeeditorelement.sip.in @@ -10,7 +10,7 @@ class QgsAttributeEditorElement /Abstract/ { -%Docstring +%Docstring(signature="appended") This is an abstract base class for any elements of a drag and drop form. This can either be a container which will be represented on the screen diff --git a/python/core/auto_generated/editform/qgsattributeeditorfield.sip.in b/python/core/auto_generated/editform/qgsattributeeditorfield.sip.in index 5e2302110580..d945fda827e9 100644 --- a/python/core/auto_generated/editform/qgsattributeeditorfield.sip.in +++ b/python/core/auto_generated/editform/qgsattributeeditorfield.sip.in @@ -10,7 +10,7 @@ class QgsAttributeEditorField : QgsAttributeEditorElement { -%Docstring +%Docstring(signature="appended") This element will load a field's widget onto the form. %End diff --git a/python/core/auto_generated/editform/qgsattributeeditorhtmlelement.sip.in b/python/core/auto_generated/editform/qgsattributeeditorhtmlelement.sip.in index f4bfa294070e..905844ff13cf 100644 --- a/python/core/auto_generated/editform/qgsattributeeditorhtmlelement.sip.in +++ b/python/core/auto_generated/editform/qgsattributeeditorhtmlelement.sip.in @@ -11,7 +11,7 @@ class QgsAttributeEditorHtmlElement : QgsAttributeEditorElement { -%Docstring +%Docstring(signature="appended") An attribute editor widget that will represent arbitrary HTML code. .. versionadded:: 3.4 diff --git a/python/core/auto_generated/editform/qgsattributeeditorqmlelement.sip.in b/python/core/auto_generated/editform/qgsattributeeditorqmlelement.sip.in index a9f4d0eb90fa..238cd665405d 100644 --- a/python/core/auto_generated/editform/qgsattributeeditorqmlelement.sip.in +++ b/python/core/auto_generated/editform/qgsattributeeditorqmlelement.sip.in @@ -9,7 +9,7 @@ class QgsAttributeEditorQmlElement : QgsAttributeEditorElement { -%Docstring +%Docstring(signature="appended") An attribute editor widget that will represent arbitrary QML code. .. versionadded:: 3.4 diff --git a/python/core/auto_generated/editform/qgsattributeeditorrelation.sip.in b/python/core/auto_generated/editform/qgsattributeeditorrelation.sip.in index 2997e89ea701..6e6702a1b5dc 100644 --- a/python/core/auto_generated/editform/qgsattributeeditorrelation.sip.in +++ b/python/core/auto_generated/editform/qgsattributeeditorrelation.sip.in @@ -10,7 +10,7 @@ class QgsAttributeEditorRelation : QgsAttributeEditorElement { -%Docstring +%Docstring(signature="appended") This element will load a relation editor onto the form. %End diff --git a/python/core/auto_generated/editform/qgseditformconfig.sip.in b/python/core/auto_generated/editform/qgseditformconfig.sip.in index de55272eeed8..d9231411f5c3 100644 --- a/python/core/auto_generated/editform/qgseditformconfig.sip.in +++ b/python/core/auto_generated/editform/qgseditformconfig.sip.in @@ -13,7 +13,7 @@ class QgsEditFormConfig { -%Docstring +%Docstring(signature="appended") Contains configuration settings for an editor form. %End diff --git a/python/core/auto_generated/effects/qgsblureffect.sip.in b/python/core/auto_generated/effects/qgsblureffect.sip.in index 6b79c0bd0432..0c1f2ce8c7ac 100644 --- a/python/core/auto_generated/effects/qgsblureffect.sip.in +++ b/python/core/auto_generated/effects/qgsblureffect.sip.in @@ -11,7 +11,7 @@ class QgsBlurEffect : QgsPaintEffect /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A paint effect which blurs a source picture, using a number of different blur methods. diff --git a/python/core/auto_generated/effects/qgscoloreffect.sip.in b/python/core/auto_generated/effects/qgscoloreffect.sip.in index 654fb6d89f41..cda82501bbde 100644 --- a/python/core/auto_generated/effects/qgscoloreffect.sip.in +++ b/python/core/auto_generated/effects/qgscoloreffect.sip.in @@ -11,7 +11,7 @@ class QgsColorEffect : QgsPaintEffect /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A paint effect which alters the colors (e.g., brightness, contrast) in a source picture. diff --git a/python/core/auto_generated/effects/qgseffectstack.sip.in b/python/core/auto_generated/effects/qgseffectstack.sip.in index 9553f5a5e5b0..32f9908ad184 100644 --- a/python/core/auto_generated/effects/qgseffectstack.sip.in +++ b/python/core/auto_generated/effects/qgseffectstack.sip.in @@ -11,7 +11,7 @@ class QgsEffectStack : QgsPaintEffect /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A paint effect which consists of a stack of other chained paint effects Effect stacks can be used to apply multiple paint effects to a QPicture. For diff --git a/python/core/auto_generated/effects/qgsgloweffect.sip.in b/python/core/auto_generated/effects/qgsgloweffect.sip.in index 25774c8591dd..fabbbd85efc9 100644 --- a/python/core/auto_generated/effects/qgsgloweffect.sip.in +++ b/python/core/auto_generated/effects/qgsgloweffect.sip.in @@ -13,7 +13,7 @@ class QgsGlowEffect : QgsPaintEffect { -%Docstring +%Docstring(signature="appended") Base class for paint effect which draw a glow inside or outside a picture. @@ -348,7 +348,7 @@ the picture. class QgsOuterGlowEffect : QgsGlowEffect { -%Docstring +%Docstring(signature="appended") A paint effect which draws a glow outside of a picture. .. versionadded:: 2.9 @@ -384,7 +384,7 @@ Creates a new QgsOuterGlowEffect effect from a properties string map. class QgsInnerGlowEffect : QgsGlowEffect { -%Docstring +%Docstring(signature="appended") A paint effect which draws a glow within a picture. .. versionadded:: 2.9 diff --git a/python/core/auto_generated/effects/qgsimageoperation.sip.in b/python/core/auto_generated/effects/qgsimageoperation.sip.in index 4c8c49aa683c..f6b9db251f76 100644 --- a/python/core/auto_generated/effects/qgsimageoperation.sip.in +++ b/python/core/auto_generated/effects/qgsimageoperation.sip.in @@ -13,7 +13,7 @@ class QgsImageOperation { -%Docstring +%Docstring(signature="appended") Contains operations and filters which apply to QImages A set of optimised pixel manipulation operations and filters which can be applied diff --git a/python/core/auto_generated/effects/qgspainteffect.sip.in b/python/core/auto_generated/effects/qgspainteffect.sip.in index 01c4f220b64d..dacdf881c4e1 100644 --- a/python/core/auto_generated/effects/qgspainteffect.sip.in +++ b/python/core/auto_generated/effects/qgspainteffect.sip.in @@ -12,7 +12,7 @@ class QgsPaintEffect /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") Base class for visual effects which can be applied to QPicture drawings :py:class:`QgsPaintEffect` objects can be used to modify QPicture drawings prior to rendering @@ -321,7 +321,7 @@ to rendering results onto a painter. class QgsDrawSourceEffect : QgsPaintEffect /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A paint effect which draws the source picture with minor or no alterations The draw source effect can be used to draw an unaltered copy of the original source @@ -408,7 +408,7 @@ Returns the blend mode for the effect class QgsEffectPainter { -%Docstring +%Docstring(signature="appended") A class to manager painter saving and restoring required for effect drawing .. versionadded:: 3.0 diff --git a/python/core/auto_generated/effects/qgspainteffectregistry.sip.in b/python/core/auto_generated/effects/qgspainteffectregistry.sip.in index d7b0a3b5d267..59cbeedc6878 100644 --- a/python/core/auto_generated/effects/qgspainteffectregistry.sip.in +++ b/python/core/auto_generated/effects/qgspainteffectregistry.sip.in @@ -12,7 +12,7 @@ class QgsPaintEffectWidget /External/; class QgsPaintEffectAbstractMetadata { -%Docstring +%Docstring(signature="appended") Stores metadata about a paint effect class. .. note:: @@ -83,7 +83,7 @@ if there's no GUI for the paint effect class. class QgsPaintEffectRegistry { -%Docstring +%Docstring(signature="appended") Registry of available paint effects. :py:class:`QgsPaintEffectRegistry` is not usually directly created, but rather accessed through diff --git a/python/core/auto_generated/effects/qgsshadoweffect.sip.in b/python/core/auto_generated/effects/qgsshadoweffect.sip.in index 65d03c51f673..f51ed3172d85 100644 --- a/python/core/auto_generated/effects/qgsshadoweffect.sip.in +++ b/python/core/auto_generated/effects/qgsshadoweffect.sip.in @@ -11,7 +11,7 @@ class QgsShadowEffect : QgsPaintEffect /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") Base class for paint effects which offset, blurred shadows .. versionadded:: 2.9 @@ -297,7 +297,7 @@ the picture. class QgsDropShadowEffect : QgsShadowEffect /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A paint effect which draws an offset and optionally blurred drop shadow .. versionadded:: 2.9 @@ -333,7 +333,7 @@ Creates a new QgsDropShadowEffect effect from a properties string map. class QgsInnerShadowEffect : QgsShadowEffect /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A paint effect which draws an offset and optionally blurred drop shadow within a picture. diff --git a/python/core/auto_generated/effects/qgstransformeffect.sip.in b/python/core/auto_generated/effects/qgstransformeffect.sip.in index 25df06b3a155..aa4d927c3985 100644 --- a/python/core/auto_generated/effects/qgstransformeffect.sip.in +++ b/python/core/auto_generated/effects/qgstransformeffect.sip.in @@ -11,7 +11,7 @@ class QgsTransformEffect : QgsPaintEffect /NoDefaultCtors/ { -%Docstring +%Docstring(signature="appended") A paint effect which applies transformations (such as move, scale and rotate) to a picture. diff --git a/python/core/auto_generated/expression/qgsexpression.sip.in b/python/core/auto_generated/expression/qgsexpression.sip.in index f819670a722d..f528aa4fcf2a 100644 --- a/python/core/auto_generated/expression/qgsexpression.sip.in +++ b/python/core/auto_generated/expression/qgsexpression.sip.in @@ -13,7 +13,7 @@ class QgsExpression { -%Docstring +%Docstring(signature="appended") Class for parsing and evaluation of expressions (formerly called "search strings"). The expressions try to follow both syntax and semantics of SQL expressions. diff --git a/python/core/auto_generated/expression/qgsexpressioncontextutils.sip.in b/python/core/auto_generated/expression/qgsexpressioncontextutils.sip.in index 1ed723b61884..f1d799520fef 100644 --- a/python/core/auto_generated/expression/qgsexpressioncontextutils.sip.in +++ b/python/core/auto_generated/expression/qgsexpressioncontextutils.sip.in @@ -11,7 +11,7 @@ class QgsExpressionContextUtils { -%Docstring +%Docstring(signature="appended") Contains utilities for working with :py:class:`QgsExpressionContext` objects, including methods for creating scopes for specific uses (e.g., project scopes, layer scopes). diff --git a/python/core/auto_generated/expression/qgsexpressionfunction.sip.in b/python/core/auto_generated/expression/qgsexpressionfunction.sip.in index 953e90747b8d..eaf8f08cb51f 100644 --- a/python/core/auto_generated/expression/qgsexpressionfunction.sip.in +++ b/python/core/auto_generated/expression/qgsexpressionfunction.sip.in @@ -13,7 +13,7 @@ class QgsExpressionFunction { -%Docstring +%Docstring(signature="appended") A abstract base class for defining :py:class:`QgsExpression` functions. %End @@ -25,7 +25,7 @@ A abstract base class for defining :py:class:`QgsExpression` functions. class Parameter { -%Docstring +%Docstring(signature="appended") Represents a single parameter passed to a function. .. versionadded:: 2.16 diff --git a/python/core/auto_generated/expression/qgsexpressionnode.sip.in b/python/core/auto_generated/expression/qgsexpressionnode.sip.in index bc4cc98f3d6e..94943009f7e1 100644 --- a/python/core/auto_generated/expression/qgsexpressionnode.sip.in +++ b/python/core/auto_generated/expression/qgsexpressionnode.sip.in @@ -13,7 +13,7 @@ class QgsExpressionNode /Abstract/ { -%Docstring +%Docstring(signature="appended") Abstract base class for all nodes that can appear in an expression. %End @@ -84,7 +84,7 @@ Constructor for NamedNode class NodeList { -%Docstring +%Docstring(signature="appended") A list of expression nodes. %End diff --git a/python/core/auto_generated/expression/qgsexpressionnodeimpl.sip.in b/python/core/auto_generated/expression/qgsexpressionnodeimpl.sip.in index 1670525539bc..14ad54dfbd9b 100644 --- a/python/core/auto_generated/expression/qgsexpressionnodeimpl.sip.in +++ b/python/core/auto_generated/expression/qgsexpressionnodeimpl.sip.in @@ -11,7 +11,7 @@ class QgsExpressionNodeUnaryOperator : QgsExpressionNode { -%Docstring +%Docstring(signature="appended") A unary node is either negative as in boolean (not) or as in numbers (minus). %End @@ -73,7 +73,7 @@ I.e. "NOT" or "-" class QgsExpressionNodeBinaryOperator : QgsExpressionNode { -%Docstring +%Docstring(signature="appended") A binary expression operator, which operates on two values. %End @@ -183,7 +183,7 @@ I.e. "AND", "OR", ... class QgsExpressionNodeIndexOperator : QgsExpressionNode { -%Docstring +%Docstring(signature="appended") A indexing expression operator, which allows use of square brackets [] to reference map and array items. .. versionadded:: 3.6 @@ -240,7 +240,7 @@ Returns the index node, representing an array element index or map key. class QgsExpressionNodeInOperator : QgsExpressionNode { -%Docstring +%Docstring(signature="appended") An expression node for value IN or NOT IN clauses. %End @@ -294,7 +294,7 @@ Returns the list of nodes to search for matching values within. class QgsExpressionNodeFunction : QgsExpressionNode { -%Docstring +%Docstring(signature="appended") An expression node for expression functions. %End @@ -351,7 +351,7 @@ Tests whether the provided argument list is valid for the matching function class QgsExpressionNodeLiteral : QgsExpressionNode { -%Docstring +%Docstring(signature="appended") An expression node for literal values. %End @@ -395,7 +395,7 @@ The value of the literal. class QgsExpressionNodeColumnRef : QgsExpressionNode { -%Docstring +%Docstring(signature="appended") An expression node which takes it value from a feature's field. %End @@ -442,7 +442,7 @@ The name of the column. class QgsExpressionNodeCondition : QgsExpressionNode { -%Docstring +%Docstring(signature="appended") An expression node for CASE WHEN clauses. %End @@ -453,7 +453,7 @@ An expression node for CASE WHEN clauses. class WhenThen { -%Docstring +%Docstring(signature="appended") Represents a "WHEN... THEN..." portation of a CASE WHEN clause in an expression. %End diff --git a/python/core/auto_generated/fieldformatter/qgscheckboxfieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgscheckboxfieldformatter.sip.in index 86fb3b838b4e..9c365478369c 100644 --- a/python/core/auto_generated/fieldformatter/qgscheckboxfieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgscheckboxfieldformatter.sip.in @@ -10,7 +10,7 @@ class QgsCheckBoxFieldFormatter : QgsFieldFormatter { -%Docstring +%Docstring(signature="appended") Field formatter for a checkbox field. .. versionadded:: 3.10 diff --git a/python/core/auto_generated/fieldformatter/qgsdatetimefieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgsdatetimefieldformatter.sip.in index 8993b7035cba..01e52650ed02 100644 --- a/python/core/auto_generated/fieldformatter/qgsdatetimefieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgsdatetimefieldformatter.sip.in @@ -9,7 +9,7 @@ class QgsDateTimeFieldFormatter : QgsFieldFormatter { -%Docstring +%Docstring(signature="appended") Field formatter for a date time field. This represents a date, time or datetime value based on diff --git a/python/core/auto_generated/fieldformatter/qgsfallbackfieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgsfallbackfieldformatter.sip.in index 980c673eff40..38cd02f3f0e1 100644 --- a/python/core/auto_generated/fieldformatter/qgsfallbackfieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgsfallbackfieldformatter.sip.in @@ -9,7 +9,7 @@ class QgsFallbackFieldFormatter : QgsFieldFormatter { -%Docstring +%Docstring(signature="appended") A default fallback field formatter in case no specialized field formatter is defined. The values will be returned unmodified. diff --git a/python/core/auto_generated/fieldformatter/qgskeyvaluefieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgskeyvaluefieldformatter.sip.in index df8b646eda6c..5af8b19d1680 100644 --- a/python/core/auto_generated/fieldformatter/qgskeyvaluefieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgskeyvaluefieldformatter.sip.in @@ -9,7 +9,7 @@ class QgsKeyValueFieldFormatter : QgsFieldFormatter { -%Docstring +%Docstring(signature="appended") Field formatter for a key value field. This represents a list type value. diff --git a/python/core/auto_generated/fieldformatter/qgslistfieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgslistfieldformatter.sip.in index 02d24ef69905..ac886c3916f5 100644 --- a/python/core/auto_generated/fieldformatter/qgslistfieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgslistfieldformatter.sip.in @@ -9,7 +9,7 @@ class QgsListFieldFormatter : QgsFieldFormatter { -%Docstring +%Docstring(signature="appended") Field formatter for a list field. This represents a list type value. diff --git a/python/core/auto_generated/fieldformatter/qgsrangefieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgsrangefieldformatter.sip.in index 0e314ddf3869..f1e5315010bb 100644 --- a/python/core/auto_generated/fieldformatter/qgsrangefieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgsrangefieldformatter.sip.in @@ -9,7 +9,7 @@ class QgsRangeFieldFormatter : QgsFieldFormatter { -%Docstring +%Docstring(signature="appended") Field formatter for a range (double) field with precision and locale. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/fieldformatter/qgsrelationreferencefieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgsrelationreferencefieldformatter.sip.in index b47f20fd1500..828d162c51b6 100644 --- a/python/core/auto_generated/fieldformatter/qgsrelationreferencefieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgsrelationreferencefieldformatter.sip.in @@ -9,7 +9,7 @@ class QgsRelationReferenceFieldFormatter : QgsFieldFormatter { -%Docstring +%Docstring(signature="appended") Field formatter for a relation reference field. A value relation field formatter looks up the values from diff --git a/python/core/auto_generated/fieldformatter/qgsvaluemapfieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgsvaluemapfieldformatter.sip.in index 6f28867f3d93..e10ca2e2595f 100644 --- a/python/core/auto_generated/fieldformatter/qgsvaluemapfieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgsvaluemapfieldformatter.sip.in @@ -9,7 +9,7 @@ class QgsValueMapFieldFormatter : QgsFieldFormatter { -%Docstring +%Docstring(signature="appended") Field formatter for a ValueMap field. A value relation field formatter looks up the values a map. diff --git a/python/core/auto_generated/fieldformatter/qgsvaluerelationfieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgsvaluerelationfieldformatter.sip.in index 3729f5409db4..1f2e05514593 100644 --- a/python/core/auto_generated/fieldformatter/qgsvaluerelationfieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgsvaluerelationfieldformatter.sip.in @@ -11,7 +11,7 @@ class QgsValueRelationFieldFormatter : QgsFieldFormatter { -%Docstring +%Docstring(signature="appended") Field formatter for a value relation field. A value relation field formatter looks up the values from diff --git a/python/core/auto_generated/geocms/geonode/qgsgeonodeconnection.sip.in b/python/core/auto_generated/geocms/geonode/qgsgeonodeconnection.sip.in index 979449b19ac6..819d6be7a393 100644 --- a/python/core/auto_generated/geocms/geonode/qgsgeonodeconnection.sip.in +++ b/python/core/auto_generated/geocms/geonode/qgsgeonodeconnection.sip.in @@ -10,7 +10,7 @@ class QgsGeoNodeConnection { -%Docstring +%Docstring(signature="appended") Encapsulates settings related to a single GeoNode connection. .. versionadded:: 3.0 @@ -72,7 +72,7 @@ Adds uri parameters relating to the settings for a WFS layer on the connection t class QgsGeoNodeConnectionUtils { -%Docstring +%Docstring(signature="appended") Contains various utilities for managing the known collection of GeoNode servers associated with a QGIS install. diff --git a/python/core/auto_generated/geocms/geonode/qgsgeonoderequest.sip.in b/python/core/auto_generated/geocms/geonode/qgsgeonoderequest.sip.in index d49452e93fb9..a48ac62271fc 100644 --- a/python/core/auto_generated/geocms/geonode/qgsgeonoderequest.sip.in +++ b/python/core/auto_generated/geocms/geonode/qgsgeonoderequest.sip.in @@ -26,7 +26,7 @@ struct QgsGeoNodeStyle class QgsGeoNodeRequest : QObject { -%Docstring +%Docstring(signature="appended") Request handler for GeoNode servers. :py:class:`QgsGeoNodeRequest` handles requesting and parsing service details from a GeoNode diff --git a/python/core/auto_generated/geocoding/qgsabstractgeocoderlocatorfilter.sip.in b/python/core/auto_generated/geocoding/qgsabstractgeocoderlocatorfilter.sip.in index 9bf3ea7fd53b..701d9dc62a8e 100644 --- a/python/core/auto_generated/geocoding/qgsabstractgeocoderlocatorfilter.sip.in +++ b/python/core/auto_generated/geocoding/qgsabstractgeocoderlocatorfilter.sip.in @@ -11,7 +11,7 @@ class QgsAbstractGeocoderLocatorFilter : QgsLocatorFilter /Abstract/ { -%Docstring +%Docstring(signature="appended") An abstract base class which implements a locator filter populated from a :py:class:`QgsGeocoderInterface`. This base class implements the required logic to bridge a class which implements the diff --git a/python/core/auto_generated/geocoding/qgsgeocoder.sip.in b/python/core/auto_generated/geocoding/qgsgeocoder.sip.in index 426d9714c9cb..acb5e7342c03 100644 --- a/python/core/auto_generated/geocoding/qgsgeocoder.sip.in +++ b/python/core/auto_generated/geocoding/qgsgeocoder.sip.in @@ -11,7 +11,7 @@ class QgsGeocoderInterface { -%Docstring +%Docstring(signature="appended") Interface for geocoders. :py:class:`QgsGeocoderInterface` implementations are able to take either a :py:class:`QgsFeature` or a free-form string diff --git a/python/core/auto_generated/geocoding/qgsgeocodercontext.sip.in b/python/core/auto_generated/geocoding/qgsgeocodercontext.sip.in index 53f13d6278a3..125a56a226c8 100644 --- a/python/core/auto_generated/geocoding/qgsgeocodercontext.sip.in +++ b/python/core/auto_generated/geocoding/qgsgeocodercontext.sip.in @@ -11,7 +11,7 @@ class QgsGeocoderContext { -%Docstring +%Docstring(signature="appended") Encapsulates the context of a geocoding operation. .. versionadded:: 3.18 diff --git a/python/core/auto_generated/geocoding/qgsgeocoderresult.sip.in b/python/core/auto_generated/geocoding/qgsgeocoderresult.sip.in index 218c52139dc3..099b3a753257 100644 --- a/python/core/auto_generated/geocoding/qgsgeocoderresult.sip.in +++ b/python/core/auto_generated/geocoding/qgsgeocoderresult.sip.in @@ -12,7 +12,7 @@ class QgsGeocoderResult { -%Docstring +%Docstring(signature="appended") Represents a matching result from a geocoder search. :py:class:`QgsGeocoderResult` objects may represent valid matches, or an invalid diff --git a/python/core/auto_generated/geocoding/qgsgooglemapsgeocoder.sip.in b/python/core/auto_generated/geocoding/qgsgooglemapsgeocoder.sip.in index 3ee60a6e5fa6..2dd2c8fcd3cd 100644 --- a/python/core/auto_generated/geocoding/qgsgooglemapsgeocoder.sip.in +++ b/python/core/auto_generated/geocoding/qgsgooglemapsgeocoder.sip.in @@ -11,7 +11,7 @@ class QgsGoogleMapsGeocoder : QgsGeocoderInterface { -%Docstring +%Docstring(signature="appended") A geocoder which uses the Google Map geocoding API to retrieve results. This geocoder utilizes the Google Maps "geocoding" API in order to geocode diff --git a/python/core/auto_generated/geocoding/qgsnominatimgeocoder.sip.in b/python/core/auto_generated/geocoding/qgsnominatimgeocoder.sip.in index 996e68b8259e..4c81865e84fc 100644 --- a/python/core/auto_generated/geocoding/qgsnominatimgeocoder.sip.in +++ b/python/core/auto_generated/geocoding/qgsnominatimgeocoder.sip.in @@ -11,7 +11,7 @@ class QgsNominatimGeocoder : QgsGeocoderInterface { -%Docstring +%Docstring(signature="appended") A geocoder which uses the Nominatim geocoding API to retrieve results. This geocoder utilizes the Nominatim geocoding API in order to geocode diff --git a/python/core/auto_generated/geometry/qgsabstractgeometry.sip.in b/python/core/auto_generated/geometry/qgsabstractgeometry.sip.in index cf33d9006880..912b5ba9f741 100644 --- a/python/core/auto_generated/geometry/qgsabstractgeometry.sip.in +++ b/python/core/auto_generated/geometry/qgsabstractgeometry.sip.in @@ -19,7 +19,7 @@ typedef QVector< QVector< QVector< QgsPoint > > > QgsCoordinateSequence; class QgsAbstractGeometry { -%Docstring +%Docstring(signature="appended") Abstract base class for all geometries .. note:: @@ -938,7 +938,7 @@ Returns ``True`` if this vertex ID is valid for the specified ``geom``. class QgsVertexIterator { -%Docstring +%Docstring(signature="appended") Java-style iterator for traversal of vertices of a geometry .. versionadded:: 3.0 @@ -985,7 +985,7 @@ Returns next vertex of the geometry (undefined behavior if :py:func:`~QgsVertexI class QgsGeometryPartIterator { -%Docstring +%Docstring(signature="appended") Java-style iterator for traversal of parts of a geometry .. versionadded:: 3.6 @@ -1033,7 +1033,7 @@ Returns next part of the geometry (undefined behavior if :py:func:`~QgsGeometryP class QgsGeometryConstPartIterator { -%Docstring +%Docstring(signature="appended") Java-style iterator for const traversal of parts of a geometry .. versionadded:: 3.6 diff --git a/python/core/auto_generated/geometry/qgsbox3d.sip.in b/python/core/auto_generated/geometry/qgsbox3d.sip.in index 7a3c855ef171..5cf30f34c71a 100644 --- a/python/core/auto_generated/geometry/qgsbox3d.sip.in +++ b/python/core/auto_generated/geometry/qgsbox3d.sip.in @@ -13,7 +13,7 @@ class QgsBox3d { -%Docstring +%Docstring(signature="appended") A 3-dimensional box composed of x, y, z coordinates. A box composed of x/y/z minimum and maximum values. It is often used to return the 3D diff --git a/python/core/auto_generated/geometry/qgscircle.sip.in b/python/core/auto_generated/geometry/qgscircle.sip.in index 252f623a5013..609dbe4791b4 100644 --- a/python/core/auto_generated/geometry/qgscircle.sip.in +++ b/python/core/auto_generated/geometry/qgscircle.sip.in @@ -16,7 +16,7 @@ class QgsCircle : QgsEllipse { -%Docstring +%Docstring(signature="appended") Circle geometry type. A circle is defined by a center point with a radius and an azimuth. diff --git a/python/core/auto_generated/geometry/qgscircularstring.sip.in b/python/core/auto_generated/geometry/qgscircularstring.sip.in index e056b4f43eab..00dbe18e8956 100644 --- a/python/core/auto_generated/geometry/qgscircularstring.sip.in +++ b/python/core/auto_generated/geometry/qgscircularstring.sip.in @@ -13,7 +13,7 @@ class QgsCircularString: QgsCurve { -%Docstring +%Docstring(signature="appended") Circular string geometry type .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgscompoundcurve.sip.in b/python/core/auto_generated/geometry/qgscompoundcurve.sip.in index 4362c2f53177..52a7fba7ea93 100644 --- a/python/core/auto_generated/geometry/qgscompoundcurve.sip.in +++ b/python/core/auto_generated/geometry/qgscompoundcurve.sip.in @@ -11,7 +11,7 @@ class QgsCompoundCurve: QgsCurve { -%Docstring +%Docstring(signature="appended") Compound curve geometry type .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgscurve.sip.in b/python/core/auto_generated/geometry/qgscurve.sip.in index abec8f3a345d..54f36c7fe215 100644 --- a/python/core/auto_generated/geometry/qgscurve.sip.in +++ b/python/core/auto_generated/geometry/qgscurve.sip.in @@ -12,7 +12,7 @@ class QgsCurve: QgsAbstractGeometry { -%Docstring +%Docstring(signature="appended") Abstract base class for curved geometry type .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgscurvepolygon.sip.in b/python/core/auto_generated/geometry/qgscurvepolygon.sip.in index f3c8c3e71a75..59cac4689728 100644 --- a/python/core/auto_generated/geometry/qgscurvepolygon.sip.in +++ b/python/core/auto_generated/geometry/qgscurvepolygon.sip.in @@ -12,7 +12,7 @@ class QgsCurvePolygon: QgsSurface { -%Docstring +%Docstring(signature="appended") Curve polygon geometry type .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgsellipse.sip.in b/python/core/auto_generated/geometry/qgsellipse.sip.in index 380929ebde5f..223c14e2c9fb 100644 --- a/python/core/auto_generated/geometry/qgsellipse.sip.in +++ b/python/core/auto_generated/geometry/qgsellipse.sip.in @@ -12,7 +12,7 @@ class QgsEllipse { -%Docstring +%Docstring(signature="appended") Ellipse geometry type. An ellipse is defined by a center point with a semi-major axis, a semi-minor axis and an azimuth. diff --git a/python/core/auto_generated/geometry/qgsgeometry.sip.in b/python/core/auto_generated/geometry/qgsgeometry.sip.in index c19b2cca0916..b423e71636de 100644 --- a/python/core/auto_generated/geometry/qgsgeometry.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometry.sip.in @@ -31,7 +31,7 @@ typedef QVector>> QgsMultiPolygonXY; class QgsGeometry { -%Docstring +%Docstring(signature="appended") A geometry is the spatial representation of a feature. :py:class:`QgsGeometry` acts as a generic container for geometry objects. :py:class:`QgsGeometry` objects are implicitly shared, @@ -1960,7 +1960,7 @@ and the interior rings in a counter-clockwise direction. class Error { -%Docstring +%Docstring(signature="appended") A geometry error. %End diff --git a/python/core/auto_generated/geometry/qgsgeometrycollection.sip.in b/python/core/auto_generated/geometry/qgsgeometrycollection.sip.in index 369b0827da2b..3002b1007147 100644 --- a/python/core/auto_generated/geometry/qgsgeometrycollection.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometrycollection.sip.in @@ -14,7 +14,7 @@ class QgsGeometryCollection: QgsAbstractGeometry { -%Docstring +%Docstring(signature="appended") Geometry collection .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgsgeometryengine.sip.in b/python/core/auto_generated/geometry/qgsgeometryengine.sip.in index 7d10caf0f81d..9405713c4641 100644 --- a/python/core/auto_generated/geometry/qgsgeometryengine.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometryengine.sip.in @@ -12,7 +12,7 @@ class QgsGeometryEngine { -%Docstring +%Docstring(signature="appended") Contains geometry relation and modification algorithms. .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgsgeometrytransformer.sip.in b/python/core/auto_generated/geometry/qgsgeometrytransformer.sip.in index 79bf40877b1f..6910cd25d9e2 100644 --- a/python/core/auto_generated/geometry/qgsgeometrytransformer.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometrytransformer.sip.in @@ -11,7 +11,7 @@ class QgsAbstractGeometryTransformer { -%Docstring +%Docstring(signature="appended") An abstract base class for classes which transform geometries by transforming input points to output points. diff --git a/python/core/auto_generated/geometry/qgsgeometryutils.sip.in b/python/core/auto_generated/geometry/qgsgeometryutils.sip.in index 50c46432ad34..ee68f923ac63 100644 --- a/python/core/auto_generated/geometry/qgsgeometryutils.sip.in +++ b/python/core/auto_generated/geometry/qgsgeometryutils.sip.in @@ -13,7 +13,7 @@ class QgsGeometryUtils { -%Docstring +%Docstring(signature="appended") Contains various geometry utility functions. .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgslinesegment.sip.in b/python/core/auto_generated/geometry/qgslinesegment.sip.in index 7a0016068c55..3dcaf471c590 100644 --- a/python/core/auto_generated/geometry/qgslinesegment.sip.in +++ b/python/core/auto_generated/geometry/qgslinesegment.sip.in @@ -12,7 +12,7 @@ class QgsLineSegment2D { -%Docstring +%Docstring(signature="appended") Represents a single 2D line segment, consisting of a 2D start and end vertex only. .. versionadded:: 3.2 diff --git a/python/core/auto_generated/geometry/qgslinestring.sip.in b/python/core/auto_generated/geometry/qgslinestring.sip.in index 11a0c665181b..292028b24410 100644 --- a/python/core/auto_generated/geometry/qgslinestring.sip.in +++ b/python/core/auto_generated/geometry/qgslinestring.sip.in @@ -15,7 +15,7 @@ class QgsLineString: QgsCurve { -%Docstring +%Docstring(signature="appended") Line string geometry type, with support for z-dimension and m-values. .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgsmulticurve.sip.in b/python/core/auto_generated/geometry/qgsmulticurve.sip.in index 282444db16fc..25c0e3fcb285 100644 --- a/python/core/auto_generated/geometry/qgsmulticurve.sip.in +++ b/python/core/auto_generated/geometry/qgsmulticurve.sip.in @@ -10,7 +10,7 @@ class QgsMultiCurve: QgsGeometryCollection { -%Docstring +%Docstring(signature="appended") Multi curve geometry collection. .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgsmultilinestring.sip.in b/python/core/auto_generated/geometry/qgsmultilinestring.sip.in index c686639c7a67..4dce019c38e7 100644 --- a/python/core/auto_generated/geometry/qgsmultilinestring.sip.in +++ b/python/core/auto_generated/geometry/qgsmultilinestring.sip.in @@ -11,7 +11,7 @@ class QgsMultiLineString: QgsMultiCurve { -%Docstring +%Docstring(signature="appended") Multi line string geometry collection. .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgsmultipoint.sip.in b/python/core/auto_generated/geometry/qgsmultipoint.sip.in index 22fb624cbdc4..aa5d0a6a0b95 100644 --- a/python/core/auto_generated/geometry/qgsmultipoint.sip.in +++ b/python/core/auto_generated/geometry/qgsmultipoint.sip.in @@ -10,7 +10,7 @@ class QgsMultiPoint: QgsGeometryCollection { -%Docstring +%Docstring(signature="appended") Multi point geometry collection. .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgsmultipolygon.sip.in b/python/core/auto_generated/geometry/qgsmultipolygon.sip.in index 745d9b49eac5..5be5aacb96eb 100644 --- a/python/core/auto_generated/geometry/qgsmultipolygon.sip.in +++ b/python/core/auto_generated/geometry/qgsmultipolygon.sip.in @@ -11,7 +11,7 @@ class QgsMultiPolygon: QgsMultiSurface { -%Docstring +%Docstring(signature="appended") Multi polygon geometry collection. .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgsmultisurface.sip.in b/python/core/auto_generated/geometry/qgsmultisurface.sip.in index cb3c21a9a0b3..b7416bd900d9 100644 --- a/python/core/auto_generated/geometry/qgsmultisurface.sip.in +++ b/python/core/auto_generated/geometry/qgsmultisurface.sip.in @@ -12,7 +12,7 @@ class QgsMultiSurface: QgsGeometryCollection { -%Docstring +%Docstring(signature="appended") Multi surface geometry collection. .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgspoint.sip.in b/python/core/auto_generated/geometry/qgspoint.sip.in index b6db95384e6a..36df36e49b50 100644 --- a/python/core/auto_generated/geometry/qgspoint.sip.in +++ b/python/core/auto_generated/geometry/qgspoint.sip.in @@ -12,7 +12,7 @@ class QgsPoint: QgsAbstractGeometry { -%Docstring +%Docstring(signature="appended") Point geometry type, with support for z-dimension and m-values. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/geometry/qgspolygon.sip.in b/python/core/auto_generated/geometry/qgspolygon.sip.in index d02662cf48e4..aa86a66431f6 100644 --- a/python/core/auto_generated/geometry/qgspolygon.sip.in +++ b/python/core/auto_generated/geometry/qgspolygon.sip.in @@ -12,7 +12,7 @@ class QgsPolygon: QgsCurvePolygon { -%Docstring +%Docstring(signature="appended") Polygon geometry type. .. versionadded:: 2.10 diff --git a/python/core/auto_generated/geometry/qgsquadrilateral.sip.in b/python/core/auto_generated/geometry/qgsquadrilateral.sip.in index 7319f489b8f4..f6a840a1bb28 100644 --- a/python/core/auto_generated/geometry/qgsquadrilateral.sip.in +++ b/python/core/auto_generated/geometry/qgsquadrilateral.sip.in @@ -12,7 +12,7 @@ class QgsQuadrilateral { -%Docstring +%Docstring(signature="appended") Quadrilateral geometry type. A quadrilateral is a polygon with four edges (or sides) and four vertices or corners. diff --git a/python/core/auto_generated/geometry/qgsray3d.sip.in b/python/core/auto_generated/geometry/qgsray3d.sip.in index ffa7982b32fd..ddb648aaf338 100644 --- a/python/core/auto_generated/geometry/qgsray3d.sip.in +++ b/python/core/auto_generated/geometry/qgsray3d.sip.in @@ -10,7 +10,7 @@ class QgsRay3D { -%Docstring +%Docstring(signature="appended") A representation of a ray in 3D. A ray is composed of an origin point (the start of the ray) and a direction vector. diff --git a/python/core/auto_generated/geometry/qgsrectangle.sip.in b/python/core/auto_generated/geometry/qgsrectangle.sip.in index b8ebdb857794..0f748e2aef62 100644 --- a/python/core/auto_generated/geometry/qgsrectangle.sip.in +++ b/python/core/auto_generated/geometry/qgsrectangle.sip.in @@ -13,7 +13,7 @@ class QgsRectangle { -%Docstring +%Docstring(signature="appended") A rectangle specified with double values. :py:class:`QgsRectangle` is used to store a rectangle when double values are required. diff --git a/python/core/auto_generated/geometry/qgsreferencedgeometry.sip.in b/python/core/auto_generated/geometry/qgsreferencedgeometry.sip.in index 8b454b0a7f77..a4943a20c4c3 100644 --- a/python/core/auto_generated/geometry/qgsreferencedgeometry.sip.in +++ b/python/core/auto_generated/geometry/qgsreferencedgeometry.sip.in @@ -11,7 +11,7 @@ class QgsReferencedGeometryBase { -%Docstring +%Docstring(signature="appended") A base class for geometry primitives which are stored with an associated reference system. :py:class:`QgsReferencedGeometryBase` classes represent some form of geometry primitive @@ -53,7 +53,7 @@ no reference system is required. class QgsReferencedRectangle : QgsRectangle, QgsReferencedGeometryBase { -%Docstring +%Docstring(signature="appended") A :py:class:`QgsRectangle` with associated coordinate reference system. .. versionadded:: 3.0 @@ -91,7 +91,7 @@ Constructor for QgsReferencedRectangle. class QgsReferencedPointXY : QgsPointXY, QgsReferencedGeometryBase { -%Docstring +%Docstring(signature="appended") A :py:class:`QgsPointXY` with associated coordinate reference system. .. versionadded:: 3.0 @@ -129,7 +129,7 @@ Constructor for QgsReferencedPointXY. class QgsReferencedGeometry : QgsGeometry, QgsReferencedGeometryBase { -%Docstring +%Docstring(signature="appended") A :py:class:`QgsGeometry` with associated coordinate reference system. .. versionadded:: 3.16 diff --git a/python/core/auto_generated/geometry/qgsregularpolygon.sip.in b/python/core/auto_generated/geometry/qgsregularpolygon.sip.in index 7ff438050952..249a8d0b07ca 100644 --- a/python/core/auto_generated/geometry/qgsregularpolygon.sip.in +++ b/python/core/auto_generated/geometry/qgsregularpolygon.sip.in @@ -13,7 +13,7 @@ class QgsRegularPolygon { -%Docstring +%Docstring(signature="appended") Regular Polygon geometry type. A regular polygon is a polygon that is equiangular (all angles are equal in measure) and equilateral (all sides have the same length). diff --git a/python/core/auto_generated/geometry/qgssurface.sip.in b/python/core/auto_generated/geometry/qgssurface.sip.in index 236e04e6bf18..f599a9a44235 100644 --- a/python/core/auto_generated/geometry/qgssurface.sip.in +++ b/python/core/auto_generated/geometry/qgssurface.sip.in @@ -12,7 +12,7 @@ class QgsSurface: QgsAbstractGeometry { -%Docstring +%Docstring(signature="appended") Surface geometry type. %End diff --git a/python/core/auto_generated/geometry/qgstriangle.sip.in b/python/core/auto_generated/geometry/qgstriangle.sip.in index 42423e0edd84..13d0324c712f 100644 --- a/python/core/auto_generated/geometry/qgstriangle.sip.in +++ b/python/core/auto_generated/geometry/qgstriangle.sip.in @@ -11,7 +11,7 @@ class QgsTriangle : QgsPolygon { -%Docstring +%Docstring(signature="appended") Triangle geometry type. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/geometry/qgswkbptr.sip.in b/python/core/auto_generated/geometry/qgswkbptr.sip.in index a70d9f742f80..41a2da707704 100644 --- a/python/core/auto_generated/geometry/qgswkbptr.sip.in +++ b/python/core/auto_generated/geometry/qgswkbptr.sip.in @@ -11,7 +11,7 @@ class QgsWkbPtr { -%Docstring +%Docstring(signature="appended") WKB pointer handler. %End @@ -33,7 +33,7 @@ WKB pointer handler. class QgsConstWkbPtr { -%Docstring +%Docstring(signature="appended") A const WKB pointer. %End diff --git a/python/core/auto_generated/geometry/qgswkbtypes.sip.in b/python/core/auto_generated/geometry/qgswkbtypes.sip.in index a4fcda6b3dc7..44b7a56b191e 100644 --- a/python/core/auto_generated/geometry/qgswkbtypes.sip.in +++ b/python/core/auto_generated/geometry/qgswkbtypes.sip.in @@ -14,7 +14,7 @@ class QgsWkbTypes { -%Docstring +%Docstring(signature="appended") Handles storage of information regarding WKB types and their properties. .. versionadded:: 2.10 diff --git a/python/core/auto_generated/gps/qgsgpsconnection.sip.in b/python/core/auto_generated/gps/qgsgpsconnection.sip.in index e24fb797c3de..f2d8c6d8eb55 100644 --- a/python/core/auto_generated/gps/qgsgpsconnection.sip.in +++ b/python/core/auto_generated/gps/qgsgpsconnection.sip.in @@ -17,7 +17,7 @@ class QgsSatelliteInfo { -%Docstring +%Docstring(signature="appended") Encapsulates information relating to a GPS satellite. %End @@ -41,7 +41,7 @@ Encapsulates information relating to a GPS satellite. class QgsGpsInformation { -%Docstring +%Docstring(signature="appended") Encapsulates information relating to a GPS position fix. %End @@ -126,7 +126,7 @@ Returns a descriptive string for the signal quality. class QgsGpsConnection : QObject { -%Docstring +%Docstring(signature="appended") Abstract base class for connection to a GPS device %End diff --git a/python/core/auto_generated/gps/qgsgpsconnectionregistry.sip.in b/python/core/auto_generated/gps/qgsgpsconnectionregistry.sip.in index 17e9e3ce7ec0..4c3d07e65b48 100644 --- a/python/core/auto_generated/gps/qgsgpsconnectionregistry.sip.in +++ b/python/core/auto_generated/gps/qgsgpsconnectionregistry.sip.in @@ -13,7 +13,7 @@ class QgsGpsConnectionRegistry { -%Docstring +%Docstring(signature="appended") A class to register / unregister existing GPS connections such that the information is available to all classes and plugins. diff --git a/python/core/auto_generated/gps/qgsgpsdconnection.sip.in b/python/core/auto_generated/gps/qgsgpsdconnection.sip.in index 7a92588d41b1..20455c5352e7 100644 --- a/python/core/auto_generated/gps/qgsgpsdconnection.sip.in +++ b/python/core/auto_generated/gps/qgsgpsdconnection.sip.in @@ -12,7 +12,7 @@ class QgsGpsdConnection: QgsNmeaConnection { -%Docstring +%Docstring(signature="appended") Evaluates NMEA sentences coming from gpsd %End diff --git a/python/core/auto_generated/gps/qgsgpsdetector.sip.in b/python/core/auto_generated/gps/qgsgpsdetector.sip.in index 2cdb2ab4a71e..4339dac18534 100644 --- a/python/core/auto_generated/gps/qgsgpsdetector.sip.in +++ b/python/core/auto_generated/gps/qgsgpsdetector.sip.in @@ -13,7 +13,7 @@ class QgsGpsDetector : QObject { -%Docstring +%Docstring(signature="appended") Class to detect the GPS port %End diff --git a/python/core/auto_generated/gps/qgsnmeaconnection.sip.in b/python/core/auto_generated/gps/qgsnmeaconnection.sip.in index 85c00e1386e1..51e40dc2c591 100644 --- a/python/core/auto_generated/gps/qgsnmeaconnection.sip.in +++ b/python/core/auto_generated/gps/qgsnmeaconnection.sip.in @@ -11,7 +11,7 @@ class QgsNmeaConnection: QgsGpsConnection { -%Docstring +%Docstring(signature="appended") Evaluates NMEA sentences coming from a GPS device .. versionadded:: 1.4 diff --git a/python/core/auto_generated/gps/qgsqtlocationconnection.sip.in b/python/core/auto_generated/gps/qgsqtlocationconnection.sip.in index dd7d415c85af..6a7e236d820b 100644 --- a/python/core/auto_generated/gps/qgsqtlocationconnection.sip.in +++ b/python/core/auto_generated/gps/qgsqtlocationconnection.sip.in @@ -17,7 +17,7 @@ class QgsQtLocationConnection: QgsGpsConnection { -%Docstring +%Docstring(signature="appended") A GPS connection subclass based on the Qt Location libraries. .. note:: diff --git a/python/core/auto_generated/labeling/qgscalloutposition.sip.in b/python/core/auto_generated/labeling/qgscalloutposition.sip.in index ca12469c04d0..12262e628ea5 100644 --- a/python/core/auto_generated/labeling/qgscalloutposition.sip.in +++ b/python/core/auto_generated/labeling/qgscalloutposition.sip.in @@ -12,7 +12,7 @@ class QgsCalloutPosition { -%Docstring +%Docstring(signature="appended") Represents the calculated placement of a map label callout line. .. versionadded:: 3.20 diff --git a/python/core/auto_generated/labeling/qgslabeling.sip.in b/python/core/auto_generated/labeling/qgslabeling.sip.in index bb2d65409e5b..a51f6b01e8e6 100644 --- a/python/core/auto_generated/labeling/qgslabeling.sip.in +++ b/python/core/auto_generated/labeling/qgslabeling.sip.in @@ -10,7 +10,7 @@ class QgsLabeling { -%Docstring +%Docstring(signature="appended") Contains constants and enums relating to labeling. diff --git a/python/core/auto_generated/labeling/qgslabelingenginesettings.sip.in b/python/core/auto_generated/labeling/qgslabelingenginesettings.sip.in index 1b2d8d583523..20d528c86e34 100644 --- a/python/core/auto_generated/labeling/qgslabelingenginesettings.sip.in +++ b/python/core/auto_generated/labeling/qgslabelingenginesettings.sip.in @@ -10,7 +10,7 @@ class QgsLabelingEngineSettings { -%Docstring +%Docstring(signature="appended") Stores global configuration for labeling engine .. versionadded:: 3.0 diff --git a/python/core/auto_generated/labeling/qgslabelingresults.sip.in b/python/core/auto_generated/labeling/qgslabelingresults.sip.in index 7537911512f2..3d5c38844634 100644 --- a/python/core/auto_generated/labeling/qgslabelingresults.sip.in +++ b/python/core/auto_generated/labeling/qgslabelingresults.sip.in @@ -11,7 +11,7 @@ class QgsLabelingResults { -%Docstring +%Docstring(signature="appended") Class that stores computed placement from labeling engine. .. versionadded:: 2.4 diff --git a/python/core/auto_generated/labeling/qgslabellinesettings.sip.in b/python/core/auto_generated/labeling/qgslabellinesettings.sip.in index adf7b0612a7d..2876cb1c3834 100644 --- a/python/core/auto_generated/labeling/qgslabellinesettings.sip.in +++ b/python/core/auto_generated/labeling/qgslabellinesettings.sip.in @@ -11,7 +11,7 @@ class QgsLabelLineSettings { -%Docstring +%Docstring(signature="appended") Contains settings related to how the label engine places and formats labels for line features (or polygon features which are labeled in diff --git a/python/core/auto_generated/labeling/qgslabelobstaclesettings.sip.in b/python/core/auto_generated/labeling/qgslabelobstaclesettings.sip.in index bab59fa0ea09..323800c5bba8 100644 --- a/python/core/auto_generated/labeling/qgslabelobstaclesettings.sip.in +++ b/python/core/auto_generated/labeling/qgslabelobstaclesettings.sip.in @@ -11,7 +11,7 @@ class QgsLabelObstacleSettings { -%Docstring +%Docstring(signature="appended") Contains settings related to how the label engine treats features as obstacles diff --git a/python/core/auto_generated/labeling/qgslabelposition.sip.in b/python/core/auto_generated/labeling/qgslabelposition.sip.in index 6c8c8b7cd9ee..ecb564f3adf3 100644 --- a/python/core/auto_generated/labeling/qgslabelposition.sip.in +++ b/python/core/auto_generated/labeling/qgslabelposition.sip.in @@ -12,7 +12,7 @@ class QgsLabelPosition { -%Docstring +%Docstring(signature="appended") Represents the calculated placement of a map label. %End diff --git a/python/core/auto_generated/labeling/qgslabelsearchtree.sip.in b/python/core/auto_generated/labeling/qgslabelsearchtree.sip.in index 525c499d9a95..5cb72a697b79 100644 --- a/python/core/auto_generated/labeling/qgslabelsearchtree.sip.in +++ b/python/core/auto_generated/labeling/qgslabelsearchtree.sip.in @@ -14,7 +14,7 @@ class QgsLabelSearchTree { -%Docstring +%Docstring(signature="appended") A class to query the labeling structure at a given point (small wrapper around pal RTree class) %End diff --git a/python/core/auto_generated/labeling/qgslabelthinningsettings.sip.in b/python/core/auto_generated/labeling/qgslabelthinningsettings.sip.in index ebfcdc00c917..ea8bd64c17f8 100644 --- a/python/core/auto_generated/labeling/qgslabelthinningsettings.sip.in +++ b/python/core/auto_generated/labeling/qgslabelthinningsettings.sip.in @@ -11,7 +11,7 @@ class QgsLabelThinningSettings { -%Docstring +%Docstring(signature="appended") Contains settings related to how the label engine removes candidate label positions and reduces the number of displayed labels. diff --git a/python/core/auto_generated/labeling/qgspallabeling.sip.in b/python/core/auto_generated/labeling/qgspallabeling.sip.in index f21a40f22e59..f36f65b33507 100644 --- a/python/core/auto_generated/labeling/qgspallabeling.sip.in +++ b/python/core/auto_generated/labeling/qgspallabeling.sip.in @@ -14,7 +14,7 @@ class QgsPalLayerSettings { -%Docstring +%Docstring(signature="appended") Contains settings for how a map layer will be labeled. %End @@ -661,7 +661,7 @@ Returns a pixmap preview for label ``settings``. class QgsLabelCandidate { -%Docstring +%Docstring(signature="appended") Represents a label candidate. %End @@ -677,7 +677,7 @@ Represents a label candidate. class QgsPalLabeling { -%Docstring +%Docstring(signature="appended") PAL labeling utilities. %End diff --git a/python/core/auto_generated/labeling/qgsrulebasedlabeling.sip.in b/python/core/auto_generated/labeling/qgsrulebasedlabeling.sip.in index 8d7c3656f875..97d525104640 100644 --- a/python/core/auto_generated/labeling/qgsrulebasedlabeling.sip.in +++ b/python/core/auto_generated/labeling/qgsrulebasedlabeling.sip.in @@ -12,7 +12,7 @@ class QgsRuleBasedLabeling : QgsAbstractVectorLayerLabeling { -%Docstring +%Docstring(signature="appended") Rule based labeling for a vector layer. .. versionadded:: 3.0 @@ -27,7 +27,7 @@ Rule based labeling for a vector layer. class Rule { -%Docstring +%Docstring(signature="appended") A child rule for QgsRuleBasedLabeling. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/labeling/qgsvectorlayerlabeling.sip.in b/python/core/auto_generated/labeling/qgsvectorlayerlabeling.sip.in index 767002d268a5..dc0cc8619683 100644 --- a/python/core/auto_generated/labeling/qgsvectorlayerlabeling.sip.in +++ b/python/core/auto_generated/labeling/qgsvectorlayerlabeling.sip.in @@ -13,7 +13,7 @@ class QgsAbstractVectorLayerLabeling { -%Docstring +%Docstring(signature="appended") Abstract base class - its implementations define different approaches to the labeling of a vector layer. .. versionadded:: 3.0 @@ -122,7 +122,7 @@ Writes a TextSymbolizer element contents based on the provided labeling settings class QgsVectorLayerSimpleLabeling : QgsAbstractVectorLayerLabeling { -%Docstring +%Docstring(signature="appended") Basic implementation of the labeling interface. The configuration is kept in layer's custom properties for backward compatibility. diff --git a/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in b/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in index 2bca8d266c76..71263732393a 100644 --- a/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in +++ b/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in @@ -10,7 +10,7 @@ class QgsColorRampLegendNode : QgsLayerTreeModelLegendNode { -%Docstring +%Docstring(signature="appended") A legend node which renders a color ramp. .. versionadded:: 3.18 diff --git a/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in b/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in index 84f98fc6f64f..c1806e2becc6 100644 --- a/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in +++ b/python/core/auto_generated/layertree/qgscolorramplegendnodesettings.sip.in @@ -12,7 +12,7 @@ class QgsColorRampLegendNodeSettings { -%Docstring +%Docstring(signature="appended") Settings for a color ramp legend node. .. versionadded:: 3.18 diff --git a/python/core/auto_generated/layertree/qgslayertree.sip.in b/python/core/auto_generated/layertree/qgslayertree.sip.in index d74f3d106de0..17b64157211c 100644 --- a/python/core/auto_generated/layertree/qgslayertree.sip.in +++ b/python/core/auto_generated/layertree/qgslayertree.sip.in @@ -10,7 +10,7 @@ class QgsLayerTree : QgsLayerTreeGroup { -%Docstring +%Docstring(signature="appended") Namespace with helper functions for layer tree operations. Only generally useful routines should be here. Miscellaneous utility functions for work diff --git a/python/core/auto_generated/layertree/qgslayertreefilterproxymodel.sip.in b/python/core/auto_generated/layertree/qgslayertreefilterproxymodel.sip.in index 5acb8ba8fc65..1a40044e7066 100644 --- a/python/core/auto_generated/layertree/qgslayertreefilterproxymodel.sip.in +++ b/python/core/auto_generated/layertree/qgslayertreefilterproxymodel.sip.in @@ -12,7 +12,7 @@ class QgsLayerTreeFilterProxyModel : QSortFilterProxyModel { -%Docstring +%Docstring(signature="appended") :py:class:`QgsLayerTreeFilterProxyModel` is a sort filter proxy model to easily reproduce the legend/layer tree in a tree view. Layers are checkable by default. diff --git a/python/core/auto_generated/layertree/qgslayertreegroup.sip.in b/python/core/auto_generated/layertree/qgslayertreegroup.sip.in index 63ada6a45e30..26ecec4bea58 100644 --- a/python/core/auto_generated/layertree/qgslayertreegroup.sip.in +++ b/python/core/auto_generated/layertree/qgslayertreegroup.sip.in @@ -11,7 +11,7 @@ class QgsLayerTreeGroup : QgsLayerTreeNode { -%Docstring +%Docstring(signature="appended") Layer tree group node serves as a container for layers and further groups. Group names do not need to be unique within one tree nor within one parent. diff --git a/python/core/auto_generated/layertree/qgslayertreelayer.sip.in b/python/core/auto_generated/layertree/qgslayertreelayer.sip.in index 8a49d1309496..94e7c3abedda 100644 --- a/python/core/auto_generated/layertree/qgslayertreelayer.sip.in +++ b/python/core/auto_generated/layertree/qgslayertreelayer.sip.in @@ -11,7 +11,7 @@ class QgsLayerTreeLayer : QgsLayerTreeNode { -%Docstring +%Docstring(signature="appended") Layer tree node points to a map layer. The node can exist also without a valid instance of a layer (just ID). That diff --git a/python/core/auto_generated/layertree/qgslayertreemodel.sip.in b/python/core/auto_generated/layertree/qgslayertreemodel.sip.in index 305f547815d7..222da5917790 100644 --- a/python/core/auto_generated/layertree/qgslayertreemodel.sip.in +++ b/python/core/auto_generated/layertree/qgslayertreemodel.sip.in @@ -12,7 +12,7 @@ class QgsLayerTreeModel : QAbstractItemModel { -%Docstring +%Docstring(signature="appended") The :py:class:`QgsLayerTreeModel` class is model implementation for Qt item views framework. The model can be used in any QTreeView, it is however recommended to use it diff --git a/python/core/auto_generated/layertree/qgslayertreemodellegendnode.sip.in b/python/core/auto_generated/layertree/qgslayertreemodellegendnode.sip.in index d3caf4eb6e0c..5d1ccac53ea7 100644 --- a/python/core/auto_generated/layertree/qgslayertreemodellegendnode.sip.in +++ b/python/core/auto_generated/layertree/qgslayertreemodellegendnode.sip.in @@ -13,7 +13,7 @@ class QgsLayerTreeModelLegendNode : QObject { -%Docstring +%Docstring(signature="appended") The :py:class:`QgsLegendRendererItem` class is abstract interface for legend items returned from :py:class:`QgsMapLayerLegend` implementation. @@ -294,7 +294,7 @@ Returns a temporary context or ``None`` if legendMapViewData are not valid class QgsSymbolLegendNode : QgsLayerTreeModelLegendNode { -%Docstring +%Docstring(signature="appended") Implementation of legend node interface for displaying preview of vector symbols and their labels and allowing interaction with the symbol / renderer. @@ -487,7 +487,7 @@ Evaluates and returns the text label of the current node class QgsSimpleLegendNode : QgsLayerTreeModelLegendNode { -%Docstring +%Docstring(signature="appended") Implementation of legend node interface for displaying arbitrary label with icon. .. versionadded:: 2.6 @@ -517,7 +517,7 @@ Constructor for QgsSimpleLegendNode. class QgsImageLegendNode : QgsLayerTreeModelLegendNode { -%Docstring +%Docstring(signature="appended") Implementation of legend node interface for displaying arbitrary raster image .. versionadded:: 2.6 @@ -550,7 +550,7 @@ Constructor for QgsImageLegendNode. class QgsRasterSymbolLegendNode : QgsLayerTreeModelLegendNode { -%Docstring +%Docstring(signature="appended") Implementation of legend node interface for displaying raster legend entries .. versionadded:: 2.6 @@ -603,7 +603,7 @@ Returns whether the item is user-checkable - whether renderer supports enabling/ class QgsWmsLegendNode : QgsLayerTreeModelLegendNode { -%Docstring +%Docstring(signature="appended") Implementation of legend node interface for displaying WMS legend entries .. versionadded:: 2.8 @@ -641,7 +641,7 @@ Constructor for QgsWmsLegendNode. class QgsDataDefinedSizeLegendNode : QgsLayerTreeModelLegendNode { -%Docstring +%Docstring(signature="appended") Produces legend node with a marker symbol .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layertree/qgslayertreenode.sip.in b/python/core/auto_generated/layertree/qgslayertreenode.sip.in index 33b950c359b6..918d05d4aa4b 100644 --- a/python/core/auto_generated/layertree/qgslayertreenode.sip.in +++ b/python/core/auto_generated/layertree/qgslayertreenode.sip.in @@ -13,7 +13,7 @@ class QgsLayerTreeNode : QObject { -%Docstring +%Docstring(signature="appended") This class is a base class for nodes in a layer tree. Layer tree is a hierarchical structure consisting of group and layer nodes: diff --git a/python/core/auto_generated/layertree/qgslayertreeregistrybridge.sip.in b/python/core/auto_generated/layertree/qgslayertreeregistrybridge.sip.in index 524db132d1cb..b167cdbe2217 100644 --- a/python/core/auto_generated/layertree/qgslayertreeregistrybridge.sip.in +++ b/python/core/auto_generated/layertree/qgslayertreeregistrybridge.sip.in @@ -13,7 +13,7 @@ class QgsLayerTreeRegistryBridge : QObject { -%Docstring +%Docstring(signature="appended") Listens to the updates in map layer registry and does changes in layer tree. When connected to a layer tree, any layers added to the map layer registry diff --git a/python/core/auto_generated/layertree/qgslayertreeutils.sip.in b/python/core/auto_generated/layertree/qgslayertreeutils.sip.in index a0ba748a6a25..9fa9a4a11612 100644 --- a/python/core/auto_generated/layertree/qgslayertreeutils.sip.in +++ b/python/core/auto_generated/layertree/qgslayertreeutils.sip.in @@ -12,7 +12,7 @@ class QgsLayerTreeUtils { -%Docstring +%Docstring(signature="appended") Assorted functions for dealing with layer trees. .. versionadded:: 2.4 diff --git a/python/core/auto_generated/layertree/qgslegendpatchshape.sip.in b/python/core/auto_generated/layertree/qgslegendpatchshape.sip.in index 4d82d1c0487b..e3e416e910c2 100644 --- a/python/core/auto_generated/layertree/qgslegendpatchshape.sip.in +++ b/python/core/auto_generated/layertree/qgslegendpatchshape.sip.in @@ -10,7 +10,7 @@ class QgsLegendPatchShape { -%Docstring +%Docstring(signature="appended") Represents a patch shape for use in map legends. .. versionadded:: 3.14 diff --git a/python/core/auto_generated/layout/qgsabstractlayoutiterator.sip.in b/python/core/auto_generated/layout/qgsabstractlayoutiterator.sip.in index cdcf67b8e3db..aef352cea30f 100644 --- a/python/core/auto_generated/layout/qgsabstractlayoutiterator.sip.in +++ b/python/core/auto_generated/layout/qgsabstractlayoutiterator.sip.in @@ -10,7 +10,7 @@ class QgsAbstractLayoutIterator { -%Docstring +%Docstring(signature="appended") An abstract base class for :py:class:`QgsLayout` based classes which can be exported by :py:class:`QgsLayoutExporter`. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgsabstractreportsection.sip.in b/python/core/auto_generated/layout/qgsabstractreportsection.sip.in index 6be3068c824e..85139056795c 100644 --- a/python/core/auto_generated/layout/qgsabstractreportsection.sip.in +++ b/python/core/auto_generated/layout/qgsabstractreportsection.sip.in @@ -12,7 +12,7 @@ class QgsReportSectionContext { -%Docstring +%Docstring(signature="appended") Current context for a report section. .. warning:: @@ -37,7 +37,7 @@ Current context for a report section. class QgsAbstractReportSection : QgsAbstractLayoutIterator { -%Docstring +%Docstring(signature="appended") An abstract base class for :py:class:`QgsReport` subsections. .. warning:: diff --git a/python/core/auto_generated/layout/qgslayout.sip.in b/python/core/auto_generated/layout/qgslayout.sip.in index 2930046bea43..cd416a440139 100644 --- a/python/core/auto_generated/layout/qgslayout.sip.in +++ b/python/core/auto_generated/layout/qgslayout.sip.in @@ -10,7 +10,7 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator, QgsLayoutUndoObjectInterface { -%Docstring +%Docstring(signature="appended") Base class for layouts, which can contain items such as maps, labels, scalebars, etc. While the raw QGraphicsScene API can be used to render the contents of a :py:class:`QgsLayout` diff --git a/python/core/auto_generated/layout/qgslayoutaligner.sip.in b/python/core/auto_generated/layout/qgslayoutaligner.sip.in index 92c7a1ae4294..62078f57b8cd 100644 --- a/python/core/auto_generated/layout/qgslayoutaligner.sip.in +++ b/python/core/auto_generated/layout/qgslayoutaligner.sip.in @@ -10,7 +10,7 @@ class QgsLayoutAligner { -%Docstring +%Docstring(signature="appended") Handles aligning and distributing sets of layout items. :py:class:`QgsLayoutAligner` contains methods for automatically aligning and distributing diff --git a/python/core/auto_generated/layout/qgslayoutatlas.sip.in b/python/core/auto_generated/layout/qgslayoutatlas.sip.in index a65cf8e5e15e..e075ecf2ed84 100644 --- a/python/core/auto_generated/layout/qgslayoutatlas.sip.in +++ b/python/core/auto_generated/layout/qgslayoutatlas.sip.in @@ -10,7 +10,7 @@ class QgsLayoutAtlas : QObject, QgsAbstractLayoutIterator, QgsLayoutSerializableObject, QgsExpressionContextGenerator { -%Docstring +%Docstring(signature="appended") Class used to render :py:class:`QgsLayout` as an atlas, by iterating over the features from an associated vector layer. :py:class:`QgsLayoutAtlas` implement the :py:class:`QgsAbstractLayoutIterator` interface, allowing them to be used diff --git a/python/core/auto_generated/layout/qgslayouteffect.sip.in b/python/core/auto_generated/layout/qgslayouteffect.sip.in index 82e4741c04a7..38fe490a5882 100644 --- a/python/core/auto_generated/layout/qgslayouteffect.sip.in +++ b/python/core/auto_generated/layout/qgslayouteffect.sip.in @@ -12,7 +12,7 @@ class QgsLayoutEffect : QGraphicsEffect { -%Docstring +%Docstring(signature="appended") A QGraphicsEffect subclass used for rendering layout items onto a scene with custom composition modes. diff --git a/python/core/auto_generated/layout/qgslayoutexporter.sip.in b/python/core/auto_generated/layout/qgslayoutexporter.sip.in index 819f2b5ffbbe..6b9155019919 100644 --- a/python/core/auto_generated/layout/qgslayoutexporter.sip.in +++ b/python/core/auto_generated/layout/qgslayoutexporter.sip.in @@ -11,7 +11,7 @@ class QgsLayoutExporter { -%Docstring +%Docstring(signature="appended") Handles rendering and exports of layouts to various formats. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutframe.sip.in b/python/core/auto_generated/layout/qgslayoutframe.sip.in index 738062e42827..d3678dfa761f 100644 --- a/python/core/auto_generated/layout/qgslayoutframe.sip.in +++ b/python/core/auto_generated/layout/qgslayoutframe.sip.in @@ -11,7 +11,7 @@ class QgsLayoutFrame: QgsLayoutItem { -%Docstring +%Docstring(signature="appended") Base class for frame items, which form a layout multiframe item. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutgridsettings.sip.in b/python/core/auto_generated/layout/qgslayoutgridsettings.sip.in index 2a6b59d3275c..72cdc11f87a4 100644 --- a/python/core/auto_generated/layout/qgslayoutgridsettings.sip.in +++ b/python/core/auto_generated/layout/qgslayoutgridsettings.sip.in @@ -10,7 +10,7 @@ class QgsLayoutGridSettings : QgsLayoutSerializableObject { -%Docstring +%Docstring(signature="appended") Contains settings relating to the appearance, spacing and offset for layout grids. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutguidecollection.sip.in b/python/core/auto_generated/layout/qgslayoutguidecollection.sip.in index 2909d43a6e7d..d99284e20650 100644 --- a/python/core/auto_generated/layout/qgslayoutguidecollection.sip.in +++ b/python/core/auto_generated/layout/qgslayoutguidecollection.sip.in @@ -10,7 +10,7 @@ class QgsLayoutGuide : QObject { -%Docstring +%Docstring(signature="appended") Contains the configuration for a single snap guide used by a layout. .. versionadded:: 3.0 @@ -126,7 +126,7 @@ Emitted when the guide's position is changed. class QgsLayoutGuideCollection : QAbstractTableModel, QgsLayoutSerializableObject { -%Docstring +%Docstring(signature="appended") Stores and manages the snap guides used by a layout. .. versionadded:: 3.0 @@ -264,7 +264,7 @@ Sets the collection's state from a DOM element. collectionElement is the DOM nod class QgsLayoutGuideProxyModel : QSortFilterProxyModel { -%Docstring +%Docstring(signature="appended") Filters QgsLayoutGuideCollection models to guides of a single orientation (horizontal or vertical). .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitem.sip.in b/python/core/auto_generated/layout/qgslayoutitem.sip.in index d0f207d2767f..bd310430ca16 100644 --- a/python/core/auto_generated/layout/qgslayoutitem.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitem.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemRenderContext { -%Docstring +%Docstring(signature="appended") Contains settings and helpers relating to a render of a :py:class:`QgsLayoutItem`. .. versionadded:: 3.0 @@ -63,7 +63,7 @@ scaled by 50% in order to have a constant visible size. class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInterface { -%Docstring +%Docstring(signature="appended") Base class for graphical items within a :py:class:`QgsLayout`. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitemattributetable.sip.in b/python/core/auto_generated/layout/qgslayoutitemattributetable.sip.in index 95d2b22d0682..0a8b346c3b70 100644 --- a/python/core/auto_generated/layout/qgslayoutitemattributetable.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemattributetable.sip.in @@ -12,7 +12,7 @@ class QgsLayoutItemAttributeTable: QgsLayoutTable { -%Docstring +%Docstring(signature="appended") A layout table subclass that displays attributes from a vector layer. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitemgroup.sip.in b/python/core/auto_generated/layout/qgslayoutitemgroup.sip.in index 3997fa2743b4..264fb647215b 100644 --- a/python/core/auto_generated/layout/qgslayoutitemgroup.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemgroup.sip.in @@ -10,7 +10,7 @@ class QgsLayoutItemGroup: QgsLayoutItem { -%Docstring +%Docstring(signature="appended") A container for grouping several :py:class:`QgsLayoutItems`. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitemhtml.sip.in b/python/core/auto_generated/layout/qgslayoutitemhtml.sip.in index c05f58a57ab2..84c7348fb956 100644 --- a/python/core/auto_generated/layout/qgslayoutitemhtml.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemhtml.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemHtml: QgsLayoutMultiFrame { -%Docstring +%Docstring(signature="appended") A layout multiframe subclass for HTML content. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitemlabel.sip.in b/python/core/auto_generated/layout/qgslayoutitemlabel.sip.in index e0c208dc82a6..f99c44037a82 100644 --- a/python/core/auto_generated/layout/qgslayoutitemlabel.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemlabel.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemLabel: QgsLayoutItem { -%Docstring +%Docstring(signature="appended") A layout item subclass for text labels. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitemlegend.sip.in b/python/core/auto_generated/layout/qgslayoutitemlegend.sip.in index 23d3f2c4f6cc..c54392f20b8b 100644 --- a/python/core/auto_generated/layout/qgslayoutitemlegend.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemlegend.sip.in @@ -12,7 +12,7 @@ class QgsLegendModel : QgsLayerTreeModel { -%Docstring +%Docstring(signature="appended") Item model implementation based on layer tree model for layout legend. Overrides some functionality of :py:class:`QgsLayerTreeModel` to better fit the needs of layout legends. @@ -63,7 +63,7 @@ Emitted to refresh the legend. class QgsLayoutItemLegend : QgsLayoutItem { -%Docstring +%Docstring(signature="appended") A layout item subclass for map legends. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitemmanualtable.sip.in b/python/core/auto_generated/layout/qgslayoutitemmanualtable.sip.in index 3eac43262cf3..20f5793ccf98 100644 --- a/python/core/auto_generated/layout/qgslayoutitemmanualtable.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemmanualtable.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemManualTable: QgsLayoutTable { -%Docstring +%Docstring(signature="appended") A layout table subclass that displays manually entered (and formatted) content. .. versionadded:: 3.12 diff --git a/python/core/auto_generated/layout/qgslayoutitemmap.sip.in b/python/core/auto_generated/layout/qgslayoutitemmap.sip.in index 82409b8341fa..c07ccab28133 100644 --- a/python/core/auto_generated/layout/qgslayoutitemmap.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemmap.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemMapAtlasClippingSettings : QObject { -%Docstring +%Docstring(signature="appended") Contains settings relating to clipping a layout map by the current atlas feature. .. versionadded:: 3.16 @@ -141,7 +141,7 @@ Emitted when the atlas clipping settings are changed. class QgsLayoutItemMapItemClipPathSettings : QObject { -%Docstring +%Docstring(signature="appended") Contains settings relating to clipping a layout map by another layout item. .. versionadded:: 3.16 @@ -287,7 +287,7 @@ Emitted when the item clipping settings are changed. class QgsLayoutItemMap : QgsLayoutItem, QgsTemporalRangeObject { -%Docstring +%Docstring(signature="appended") Layout graphical items for displaying a map. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitemmapgrid.sip.in b/python/core/auto_generated/layout/qgslayoutitemmapgrid.sip.in index 3b8677536adc..17f5ef1ff681 100644 --- a/python/core/auto_generated/layout/qgslayoutitemmapgrid.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemmapgrid.sip.in @@ -12,7 +12,7 @@ class QgsLayoutItemMapGridStack : QgsLayoutItemMapItemStack { -%Docstring +%Docstring(signature="appended") A collection of grids which is drawn above the map content in a :py:class:`QgsLayoutItemMap`. The grid stack controls which grids are drawn and the order they are drawn in. @@ -123,7 +123,7 @@ map item separately. class QgsLayoutItemMapGrid : QgsLayoutItemMapItem { -%Docstring +%Docstring(signature="appended") An individual grid which is drawn above the map content in a :py:class:`QgsLayoutItemMap`. diff --git a/python/core/auto_generated/layout/qgslayoutitemmapitem.sip.in b/python/core/auto_generated/layout/qgslayoutitemmapitem.sip.in index cfc78489318d..159f6fe580dd 100644 --- a/python/core/auto_generated/layout/qgslayoutitemmapitem.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemmapitem.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemMapItem : QgsLayoutObject { -%Docstring +%Docstring(signature="appended") An item which is drawn inside a :py:class:`QgsLayoutItemMap`, e.g., a grid or map overview. .. versionadded:: 3.0 @@ -209,7 +209,7 @@ Returns the internal map layer used by this item, if available. class QgsLayoutItemMapItemStack { -%Docstring +%Docstring(signature="appended") A collection of map items which are drawn above the map content in a :py:class:`QgsLayoutItemMap`. The item stack controls which items are drawn and the order they are drawn in. diff --git a/python/core/auto_generated/layout/qgslayoutitemmapoverview.sip.in b/python/core/auto_generated/layout/qgslayoutitemmapoverview.sip.in index 9bd27e77edcf..36f259800c43 100644 --- a/python/core/auto_generated/layout/qgslayoutitemmapoverview.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemmapoverview.sip.in @@ -12,7 +12,7 @@ class QgsLayoutItemMapOverviewStack : QgsLayoutItemMapItemStack { -%Docstring +%Docstring(signature="appended") A collection of overviews which are drawn above the map content in a :py:class:`QgsLayoutItemMap`. The overview stack controls which overviews are drawn and the order they are drawn in. @@ -114,7 +114,7 @@ temporary layers which represent overview extents as required. class QgsLayoutItemMapOverview : QgsLayoutItemMapItem { -%Docstring +%Docstring(signature="appended") An individual overview which is drawn above the map content in a :py:class:`QgsLayoutItemMap`, and shows the extent of another :py:class:`QgsLayoutItemMap`. diff --git a/python/core/auto_generated/layout/qgslayoutitemmarker.sip.in b/python/core/auto_generated/layout/qgslayoutitemmarker.sip.in index 8e195ff72a74..4738ad85a0ec 100644 --- a/python/core/auto_generated/layout/qgslayoutitemmarker.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemmarker.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemMarker : QgsLayoutItem { -%Docstring +%Docstring(signature="appended") A layout item for showing marker symbols. .. versionadded:: 3.14 diff --git a/python/core/auto_generated/layout/qgslayoutitemnodeitem.sip.in b/python/core/auto_generated/layout/qgslayoutitemnodeitem.sip.in index 5971524eb60f..622d6d6c4cfb 100644 --- a/python/core/auto_generated/layout/qgslayoutitemnodeitem.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemnodeitem.sip.in @@ -11,7 +11,7 @@ class QgsLayoutNodesItem: QgsLayoutItem { -%Docstring +%Docstring(signature="appended") An abstract layout item that provides generic methods for node based shapes such as polygon or polylines. diff --git a/python/core/auto_generated/layout/qgslayoutitempage.sip.in b/python/core/auto_generated/layout/qgslayoutitempage.sip.in index 547279cd469e..9916eb2b546e 100644 --- a/python/core/auto_generated/layout/qgslayoutitempage.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitempage.sip.in @@ -12,7 +12,7 @@ class QgsLayoutItemPage : QgsLayoutItem { -%Docstring +%Docstring(signature="appended") Item representing the paper in a layout. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitempicture.sip.in b/python/core/auto_generated/layout/qgslayoutitempicture.sip.in index c477a27b23d8..0f0187357a8d 100644 --- a/python/core/auto_generated/layout/qgslayoutitempicture.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitempicture.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemPicture: QgsLayoutItem { -%Docstring +%Docstring(signature="appended") A layout item subclass that displays SVG files or raster format images (jpg, png, ...). .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitempolygon.sip.in b/python/core/auto_generated/layout/qgslayoutitempolygon.sip.in index 389f81e089d2..a2454fe13cfe 100644 --- a/python/core/auto_generated/layout/qgslayoutitempolygon.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitempolygon.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemPolygon: QgsLayoutNodesItem { -%Docstring +%Docstring(signature="appended") Layout item for node based polygon shapes. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitempolyline.sip.in b/python/core/auto_generated/layout/qgslayoutitempolyline.sip.in index 6e869f5f56a4..6d4c5f7d4725 100644 --- a/python/core/auto_generated/layout/qgslayoutitempolyline.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitempolyline.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemPolyline: QgsLayoutNodesItem { -%Docstring +%Docstring(signature="appended") Layout item for node based polyline shapes. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitemregistry.sip.in b/python/core/auto_generated/layout/qgslayoutitemregistry.sip.in index 5c68ec2566b9..060cc5ec9f8a 100644 --- a/python/core/auto_generated/layout/qgslayoutitemregistry.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemregistry.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemAbstractMetadata { -%Docstring +%Docstring(signature="appended") Stores metadata about one layout item class. A companion class, :py:class:`QgsLayoutItemAbstractGuiMetadata`, handles the @@ -80,7 +80,7 @@ instances the paths are always absolute. class QgsLayoutMultiFrameAbstractMetadata { -%Docstring +%Docstring(signature="appended") Stores metadata about one layout multiframe class. A companion class, :py:class:`QgsLayoutMultiFrameAbstractGuiMetadata`, handles the @@ -144,7 +144,7 @@ instances the paths are always absolute. class QgsLayoutItemRegistry : QObject { -%Docstring +%Docstring(signature="appended") Registry of available layout item types. :py:class:`QgsLayoutItemRegistry` is not usually directly created, but rather accessed through diff --git a/python/core/auto_generated/layout/qgslayoutitemscalebar.sip.in b/python/core/auto_generated/layout/qgslayoutitemscalebar.sip.in index 5b2e8308f251..910d17e585be 100644 --- a/python/core/auto_generated/layout/qgslayoutitemscalebar.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemscalebar.sip.in @@ -10,7 +10,7 @@ class QgsLayoutItemScaleBar: QgsLayoutItem { -%Docstring +%Docstring(signature="appended") A layout item subclass for scale bars. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitemshape.sip.in b/python/core/auto_generated/layout/qgslayoutitemshape.sip.in index 47e491685ba3..1eddda6be0c8 100644 --- a/python/core/auto_generated/layout/qgslayoutitemshape.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemshape.sip.in @@ -10,7 +10,7 @@ class QgsLayoutItemShape : QgsLayoutItem { -%Docstring +%Docstring(signature="appended") Layout item for basic filled shapes (e.g. rectangles, ellipses). .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutitemtexttable.sip.in b/python/core/auto_generated/layout/qgslayoutitemtexttable.sip.in index 840b6729c283..55b2294f4d9c 100644 --- a/python/core/auto_generated/layout/qgslayoutitemtexttable.sip.in +++ b/python/core/auto_generated/layout/qgslayoutitemtexttable.sip.in @@ -11,7 +11,7 @@ class QgsLayoutItemTextTable : QgsLayoutTable { -%Docstring +%Docstring(signature="appended") A text table item that reads text from string lists .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutmanager.sip.in b/python/core/auto_generated/layout/qgslayoutmanager.sip.in index dd0d8a29bc4b..77f57d57702d 100644 --- a/python/core/auto_generated/layout/qgslayoutmanager.sip.in +++ b/python/core/auto_generated/layout/qgslayoutmanager.sip.in @@ -11,7 +11,7 @@ class QgsLayoutManager : QObject { -%Docstring +%Docstring(signature="appended") Manages storage of a set of layouts. @@ -158,7 +158,7 @@ Emitted when a layout is renamed class QgsLayoutManagerModel : QAbstractListModel { -%Docstring +%Docstring(signature="appended") List model representing the print layouts and reports available in a layout manager. @@ -223,7 +223,7 @@ Returns ``True`` if the model allows the empty layout ("not set") choice. class QgsLayoutManagerProxyModel : QSortFilterProxyModel { -%Docstring +%Docstring(signature="appended") QSortFilterProxyModel subclass for QgsLayoutManagerModel diff --git a/python/core/auto_generated/layout/qgslayoutmeasurement.sip.in b/python/core/auto_generated/layout/qgslayoutmeasurement.sip.in index ce1d0e08d0fc..87b494cada6c 100644 --- a/python/core/auto_generated/layout/qgslayoutmeasurement.sip.in +++ b/python/core/auto_generated/layout/qgslayoutmeasurement.sip.in @@ -12,7 +12,7 @@ class QgsLayoutMeasurement { -%Docstring +%Docstring(signature="appended") This class provides a method of storing measurements for use in QGIS layouts using a variety of different measurement units. diff --git a/python/core/auto_generated/layout/qgslayoutmeasurementconverter.sip.in b/python/core/auto_generated/layout/qgslayoutmeasurementconverter.sip.in index e657f1bb15cf..31ea8c344ff8 100644 --- a/python/core/auto_generated/layout/qgslayoutmeasurementconverter.sip.in +++ b/python/core/auto_generated/layout/qgslayoutmeasurementconverter.sip.in @@ -12,7 +12,7 @@ class QgsLayoutMeasurementConverter { -%Docstring +%Docstring(signature="appended") This class provides a method of converting :py:class:`QgsLayoutMeasurements` from one unit to another. Conversion to or from pixel units utilizes a specified dots per inch (DPI) property for the converter. Converters default to using diff --git a/python/core/auto_generated/layout/qgslayoutmodel.sip.in b/python/core/auto_generated/layout/qgslayoutmodel.sip.in index 33402fdd0e82..6fc2dce2d347 100644 --- a/python/core/auto_generated/layout/qgslayoutmodel.sip.in +++ b/python/core/auto_generated/layout/qgslayoutmodel.sip.in @@ -14,7 +14,7 @@ class QgsLayoutModel: QAbstractItemModel { -%Docstring +%Docstring(signature="appended") A model for items attached to a layout. The model also maintains the z-order for the layout, and must be notified whenever item stacking changes. @@ -97,7 +97,7 @@ Returns the QModelIndex corresponding to a :py:class:`QgsLayoutItem` ``item`` an class QgsLayoutProxyModel: QSortFilterProxyModel { -%Docstring +%Docstring(signature="appended") Allows for filtering a QgsLayoutModel by item type. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutmultiframe.sip.in b/python/core/auto_generated/layout/qgslayoutmultiframe.sip.in index 819fbef3f8c8..c5b9dfdda5af 100644 --- a/python/core/auto_generated/layout/qgslayoutmultiframe.sip.in +++ b/python/core/auto_generated/layout/qgslayoutmultiframe.sip.in @@ -12,7 +12,7 @@ class QgsLayoutMultiFrame: QgsLayoutObject, QgsLayoutUndoObjectInterface { -%Docstring +%Docstring(signature="appended") Abstract base class for layout items with the ability to distribute the content to several frames (:py:class:`QgsLayoutFrame` items). diff --git a/python/core/auto_generated/layout/qgslayoutnortharrowhandler.sip.in b/python/core/auto_generated/layout/qgslayoutnortharrowhandler.sip.in index 374eee17d35b..04ea0c36f62e 100644 --- a/python/core/auto_generated/layout/qgslayoutnortharrowhandler.sip.in +++ b/python/core/auto_generated/layout/qgslayoutnortharrowhandler.sip.in @@ -11,7 +11,7 @@ class QgsLayoutNorthArrowHandler: QObject { -%Docstring +%Docstring(signature="appended") An object which handles north-arrow type behavior for layout items. .. versionadded:: 3.14 diff --git a/python/core/auto_generated/layout/qgslayoutobject.sip.in b/python/core/auto_generated/layout/qgslayoutobject.sip.in index 9756f6631329..b9f9c365ac5e 100644 --- a/python/core/auto_generated/layout/qgslayoutobject.sip.in +++ b/python/core/auto_generated/layout/qgslayoutobject.sip.in @@ -11,7 +11,7 @@ class QgsLayoutObject: QObject, QgsExpressionContextGenerator { -%Docstring +%Docstring(signature="appended") A base class for objects which belong to a layout. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutpagecollection.sip.in b/python/core/auto_generated/layout/qgslayoutpagecollection.sip.in index 61d9cc9a4c8a..d7a00b4012a7 100644 --- a/python/core/auto_generated/layout/qgslayoutpagecollection.sip.in +++ b/python/core/auto_generated/layout/qgslayoutpagecollection.sip.in @@ -11,7 +11,7 @@ class QgsLayoutPageCollection : QObject, QgsLayoutSerializableObject { -%Docstring +%Docstring(signature="appended") A manager for a collection of pages in a layout. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutpoint.sip.in b/python/core/auto_generated/layout/qgslayoutpoint.sip.in index f4df567d6a30..88b567a9adc8 100644 --- a/python/core/auto_generated/layout/qgslayoutpoint.sip.in +++ b/python/core/auto_generated/layout/qgslayoutpoint.sip.in @@ -11,7 +11,7 @@ class QgsLayoutPoint { -%Docstring +%Docstring(signature="appended") This class provides a method of storing points, consisting of an x and y coordinate, for use in QGIS layouts. Measurement units are stored alongside the position. diff --git a/python/core/auto_generated/layout/qgslayoutrendercontext.sip.in b/python/core/auto_generated/layout/qgslayoutrendercontext.sip.in index 1c5ca25d4b5c..90d7a0c13ff5 100644 --- a/python/core/auto_generated/layout/qgslayoutrendercontext.sip.in +++ b/python/core/auto_generated/layout/qgslayoutrendercontext.sip.in @@ -10,7 +10,7 @@ class QgsLayoutRenderContext : QObject { -%Docstring +%Docstring(signature="appended") Stores information relating to the current rendering settings for a layout. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutreportcontext.sip.in b/python/core/auto_generated/layout/qgslayoutreportcontext.sip.in index ff83eb9a7e64..c79e3d863fae 100644 --- a/python/core/auto_generated/layout/qgslayoutreportcontext.sip.in +++ b/python/core/auto_generated/layout/qgslayoutreportcontext.sip.in @@ -10,7 +10,7 @@ class QgsLayoutReportContext : QObject { -%Docstring +%Docstring(signature="appended") Stores information relating to the current reporting context for a layout. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutserializableobject.sip.in b/python/core/auto_generated/layout/qgslayoutserializableobject.sip.in index 0c86e3954764..b3028ef95bb7 100644 --- a/python/core/auto_generated/layout/qgslayoutserializableobject.sip.in +++ b/python/core/auto_generated/layout/qgslayoutserializableobject.sip.in @@ -12,7 +12,7 @@ class QgsLayoutSerializableObject : QgsLayoutUndoObjectInterface { -%Docstring +%Docstring(signature="appended") An interface for layout objects which can be stored and read from DOM elements. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutsize.sip.in b/python/core/auto_generated/layout/qgslayoutsize.sip.in index 65497a9854f8..37e94860a038 100644 --- a/python/core/auto_generated/layout/qgslayoutsize.sip.in +++ b/python/core/auto_generated/layout/qgslayoutsize.sip.in @@ -12,7 +12,7 @@ class QgsLayoutSize { -%Docstring +%Docstring(signature="appended") This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layouts. Measurement units are stored alongside the size. diff --git a/python/core/auto_generated/layout/qgslayoutsnapper.sip.in b/python/core/auto_generated/layout/qgslayoutsnapper.sip.in index 845825796466..341ca592ef31 100644 --- a/python/core/auto_generated/layout/qgslayoutsnapper.sip.in +++ b/python/core/auto_generated/layout/qgslayoutsnapper.sip.in @@ -10,7 +10,7 @@ class QgsLayoutSnapper: QgsLayoutSerializableObject { -%Docstring +%Docstring(signature="appended") Manages snapping grids and preset snap lines in a layout, and handles snapping points to the nearest grid coordinate/snap line when possible. diff --git a/python/core/auto_generated/layout/qgslayouttable.sip.in b/python/core/auto_generated/layout/qgslayouttable.sip.in index 3f5150ab99db..f103694dd07e 100644 --- a/python/core/auto_generated/layout/qgslayouttable.sip.in +++ b/python/core/auto_generated/layout/qgslayouttable.sip.in @@ -24,7 +24,7 @@ typedef QVector QgsLayoutTableSortColumns; class QgsLayoutTableStyle { -%Docstring +%Docstring(signature="appended") Styling option for a layout table cell .. versionadded:: 3.0 @@ -67,7 +67,7 @@ Reads the style's properties from XML. class QgsLayoutTable: QgsLayoutMultiFrame { -%Docstring +%Docstring(signature="appended") A class to display a table in the print layout, and allow the table to span over multiple frames diff --git a/python/core/auto_generated/layout/qgslayouttablecolumn.sip.in b/python/core/auto_generated/layout/qgslayouttablecolumn.sip.in index 72ce965cd495..d0753badbcae 100644 --- a/python/core/auto_generated/layout/qgslayouttablecolumn.sip.in +++ b/python/core/auto_generated/layout/qgslayouttablecolumn.sip.in @@ -12,7 +12,7 @@ class QgsLayoutTableColumn { -%Docstring +%Docstring(signature="appended") Stores properties of a column for a :py:class:`QgsLayoutTable`. Some properties of a :py:class:`QgsLayoutTableColumn` are applicable only in certain contexts. diff --git a/python/core/auto_generated/layout/qgslayoutundocommand.sip.in b/python/core/auto_generated/layout/qgslayoutundocommand.sip.in index 000236da193d..607cc7421936 100644 --- a/python/core/auto_generated/layout/qgslayoutundocommand.sip.in +++ b/python/core/auto_generated/layout/qgslayoutundocommand.sip.in @@ -13,7 +13,7 @@ class QgsAbstractLayoutUndoCommand: QUndoCommand { -%Docstring +%Docstring(signature="appended") Base class for commands to undo/redo layout and layout object changes. .. versionadded:: 3.0 @@ -108,7 +108,7 @@ Manually sets the after state for the command. Generally this should not be call class QgsLayoutUndoObjectInterface { -%Docstring +%Docstring(signature="appended") Interface for layout objects which support undo/redo commands. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoutundostack.sip.in b/python/core/auto_generated/layout/qgslayoutundostack.sip.in index 4d4ff4f5767c..fae4e8c94ae3 100644 --- a/python/core/auto_generated/layout/qgslayoutundostack.sip.in +++ b/python/core/auto_generated/layout/qgslayoutundostack.sip.in @@ -13,7 +13,7 @@ class QgsLayoutUndoStack : QObject { -%Docstring +%Docstring(signature="appended") An undo stack for :py:class:`QgsLayouts`. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgslayoututils.sip.in b/python/core/auto_generated/layout/qgslayoututils.sip.in index 230f8f60a68c..4e41cf037ff4 100644 --- a/python/core/auto_generated/layout/qgslayoututils.sip.in +++ b/python/core/auto_generated/layout/qgslayoututils.sip.in @@ -11,7 +11,7 @@ class QgsLayoutUtils { -%Docstring +%Docstring(signature="appended") Utilities for layouts. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgsmasterlayoutinterface.sip.in b/python/core/auto_generated/layout/qgsmasterlayoutinterface.sip.in index afe9ac6fe5bc..84330bdc74ed 100644 --- a/python/core/auto_generated/layout/qgsmasterlayoutinterface.sip.in +++ b/python/core/auto_generated/layout/qgsmasterlayoutinterface.sip.in @@ -15,7 +15,7 @@ class QgsMasterLayoutInterface { -%Docstring +%Docstring(signature="appended") Interface for master layout type objects, such as print layouts and reports. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgspagesizeregistry.sip.in b/python/core/auto_generated/layout/qgspagesizeregistry.sip.in index dbe358c84171..d6a8d109e300 100644 --- a/python/core/auto_generated/layout/qgspagesizeregistry.sip.in +++ b/python/core/auto_generated/layout/qgspagesizeregistry.sip.in @@ -11,7 +11,7 @@ class QgsPageSize { -%Docstring +%Docstring(signature="appended") A named page size for layouts. .. versionadded:: 3.0 @@ -47,7 +47,7 @@ Constructor for QgsPageSize, accepting a page ``size``. class QgsPageSizeRegistry { -%Docstring +%Docstring(signature="appended") A registry for known page sizes. :py:class:`QgsPageSizeRegistry` is not usually directly created, but rather accessed through diff --git a/python/core/auto_generated/layout/qgsprintlayout.sip.in b/python/core/auto_generated/layout/qgsprintlayout.sip.in index d103afa4e276..73371cd69394 100644 --- a/python/core/auto_generated/layout/qgsprintlayout.sip.in +++ b/python/core/auto_generated/layout/qgsprintlayout.sip.in @@ -10,7 +10,7 @@ class QgsPrintLayout : QgsLayout, QgsMasterLayoutInterface { -%Docstring +%Docstring(signature="appended") Print layout, a :py:class:`QgsLayout` subclass for static or atlas-based layouts. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/layout/qgsreport.sip.in b/python/core/auto_generated/layout/qgsreport.sip.in index d9fafffc2e78..3112017364db 100644 --- a/python/core/auto_generated/layout/qgsreport.sip.in +++ b/python/core/auto_generated/layout/qgsreport.sip.in @@ -11,7 +11,7 @@ class QgsReport : QObject, QgsAbstractReportSection, QgsMasterLayoutInterface { -%Docstring +%Docstring(signature="appended") Represents a report for use with the :py:class:`QgsLayout` engine. Reports consist of multiple sections, represented by :py:class:`QgsAbstractReportSection` diff --git a/python/core/auto_generated/layout/qgsreportsectionfieldgroup.sip.in b/python/core/auto_generated/layout/qgsreportsectionfieldgroup.sip.in index cf9763bcc7f3..c11ccbcfa7d0 100644 --- a/python/core/auto_generated/layout/qgsreportsectionfieldgroup.sip.in +++ b/python/core/auto_generated/layout/qgsreportsectionfieldgroup.sip.in @@ -12,7 +12,7 @@ class QgsReportSectionFieldGroup : QgsAbstractReportSection { -%Docstring +%Docstring(signature="appended") A report section consisting of a features .. warning:: diff --git a/python/core/auto_generated/layout/qgsreportsectionlayout.sip.in b/python/core/auto_generated/layout/qgsreportsectionlayout.sip.in index 8eabbb97f842..acd99b790474 100644 --- a/python/core/auto_generated/layout/qgsreportsectionlayout.sip.in +++ b/python/core/auto_generated/layout/qgsreportsectionlayout.sip.in @@ -11,7 +11,7 @@ class QgsReportSectionLayout : QgsAbstractReportSection { -%Docstring +%Docstring(signature="appended") A report section consisting of a single :py:class:`QgsLayout` body. .. warning:: diff --git a/python/core/auto_generated/locator/qgslocator.sip.in b/python/core/auto_generated/locator/qgslocator.sip.in index 49d0b983e2b5..65b99f05b808 100644 --- a/python/core/auto_generated/locator/qgslocator.sip.in +++ b/python/core/auto_generated/locator/qgslocator.sip.in @@ -13,7 +13,7 @@ class QgsLocator : QObject { -%Docstring +%Docstring(signature="appended") Handles the management of :py:class:`QgsLocatorFilter` objects and async collection of search results from them. :py:class:`QgsLocator` acts as both a registry for :py:class:`QgsLocatorFilter` objects and a means of firing up diff --git a/python/core/auto_generated/locator/qgslocatorcontext.sip.in b/python/core/auto_generated/locator/qgslocatorcontext.sip.in index 0b9521bf95c6..7f7f0d64d369 100644 --- a/python/core/auto_generated/locator/qgslocatorcontext.sip.in +++ b/python/core/auto_generated/locator/qgslocatorcontext.sip.in @@ -11,7 +11,7 @@ class QgsLocatorContext { -%Docstring +%Docstring(signature="appended") Encapsulates the properties relating to the context of a locator search. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/locator/qgslocatorfilter.sip.in b/python/core/auto_generated/locator/qgslocatorfilter.sip.in index 53022832b040..5ef67bd29ce4 100644 --- a/python/core/auto_generated/locator/qgslocatorfilter.sip.in +++ b/python/core/auto_generated/locator/qgslocatorfilter.sip.in @@ -13,7 +13,7 @@ class QgsLocatorResult { -%Docstring +%Docstring(signature="appended") Encapsulates properties of an individual matching result found by a :py:class:`QgsLocatorFilter`. .. versionadded:: 3.0 @@ -83,7 +83,7 @@ normally. class QgsLocatorFilter : QObject { -%Docstring +%Docstring(signature="appended") Abstract base class for filters which collect locator results. .. note:: diff --git a/python/core/auto_generated/locator/qgslocatormodel.sip.in b/python/core/auto_generated/locator/qgslocatormodel.sip.in index 9a34aeacc07c..1020fb0e7c0d 100644 --- a/python/core/auto_generated/locator/qgslocatormodel.sip.in +++ b/python/core/auto_generated/locator/qgslocatormodel.sip.in @@ -12,7 +12,7 @@ class QgsLocatorModel : QAbstractTableModel { -%Docstring +%Docstring(signature="appended") An abstract list model for displaying the results of locator searches. Note that this class should generally be used with a :py:class:`QgsLocatorProxyModel` @@ -82,7 +82,7 @@ Adds a new ``result`` to the model. class QgsLocatorAutomaticModel : QgsLocatorModel { -%Docstring +%Docstring(signature="appended") A QgsLocatorModel which has is associated directly with a :py:class:`QgsLocator`, and is automatically populated with results from locator searches. @@ -138,7 +138,7 @@ this method to implement custom context creation logic. class QgsLocatorProxyModel : QSortFilterProxyModel { -%Docstring +%Docstring(signature="appended") A sort proxy model for :py:class:`QgsLocatorModel`, which automatically sorts results by precedence. diff --git a/python/core/auto_generated/locator/qgslocatormodelbridge.sip.in b/python/core/auto_generated/locator/qgslocatormodelbridge.sip.in index 484e979f749c..014db2179a24 100644 --- a/python/core/auto_generated/locator/qgslocatormodelbridge.sip.in +++ b/python/core/auto_generated/locator/qgslocatormodelbridge.sip.in @@ -15,7 +15,7 @@ class QgsLocatorModelBridge : QObject { -%Docstring +%Docstring(signature="appended") The :py:class:`QgsLocatorModelBridge` class provides the core functionality to be used in a locator widget. diff --git a/python/core/auto_generated/mesh/qgsmesh3daveraging.sip.in b/python/core/auto_generated/mesh/qgsmesh3daveraging.sip.in index c9a9ab3eab0b..4664bd9d050d 100644 --- a/python/core/auto_generated/mesh/qgsmesh3daveraging.sip.in +++ b/python/core/auto_generated/mesh/qgsmesh3daveraging.sip.in @@ -13,7 +13,7 @@ class QgsMesh3dAveragingMethod /Abstract/ { -%Docstring +%Docstring(signature="appended") Abstract class to interpolate 3d stacked mesh data to 2d data .. versionadded:: 3.12 @@ -113,7 +113,7 @@ Returns type of averaging method class QgsMeshMultiLevelsAveragingMethod: QgsMesh3dAveragingMethod { -%Docstring +%Docstring(signature="appended") Multi level averaging method specifies limits of vertical layers from the top layer down or reversed. @@ -195,7 +195,7 @@ Returns whether the averaging method selects only a single vertical level class QgsMeshSigmaAveragingMethod: QgsMesh3dAveragingMethod { -%Docstring +%Docstring(signature="appended") Sigma averages over the values between 0 (bed level) and 1 (surface). @@ -252,7 +252,7 @@ Always higher or equal than :py:func:`~QgsMeshSigmaAveragingMethod.startFraction class QgsMeshRelativeHeightAveragingMethod: QgsMesh3dAveragingMethod { -%Docstring +%Docstring(signature="appended") Relative height averaging method averages the values based on range defined relative to bed elevation or surface (when :py:func:`~QgsMeshSigmaAveragingMethod.countedFromTop`) The range is defined in the same length units as defined by model (e.g. meters) @@ -321,7 +321,7 @@ Returns whether the start and end vertical levels are relative to top (surface) class QgsMeshElevationAveragingMethod: QgsMesh3dAveragingMethod { -%Docstring +%Docstring(signature="appended") Elevation averaging method averages the values based on range defined absolute value to the model's datum The range is defined in the same length units as defined by model (e.g. meters) diff --git a/python/core/auto_generated/mesh/qgsmeshcalculator.sip.in b/python/core/auto_generated/mesh/qgsmeshcalculator.sip.in index 52744bd81c69..a0e20afdd511 100644 --- a/python/core/auto_generated/mesh/qgsmeshcalculator.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshcalculator.sip.in @@ -12,7 +12,7 @@ class QgsMeshCalculator { -%Docstring +%Docstring(signature="appended") Performs mesh layer calculations. Mesh calculator can do various mathematical operations diff --git a/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in b/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in index a518812afbee..af8f27de6b46 100644 --- a/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in @@ -86,7 +86,7 @@ Compare two faces, return ``True`` if they are equivalent : same indexes and sam class QgsMeshDataSourceInterface /Abstract/ { -%Docstring +%Docstring(signature="appended") Interface for mesh data sources @@ -152,7 +152,7 @@ Populates the mesh vertices, edges and faces class QgsMeshDatasetSourceInterface /Abstract/ { -%Docstring +%Docstring(signature="appended") Interface for mesh datasets and dataset groups Dataset is a collection of vector or scalar values on vertices or faces of the mesh. @@ -377,7 +377,7 @@ Returns the dataset index of the dataset in a specific dataet group at ``time`` class QgsMeshDataProvider: QgsDataProvider, QgsMeshDataSourceInterface, QgsMeshDatasetSourceInterface { -%Docstring +%Docstring(signature="appended") Base class for providing data for :py:class:`QgsMeshLayer` Responsible for reading native mesh data diff --git a/python/core/auto_generated/mesh/qgsmeshdataprovidertemporalcapabilities.sip.in b/python/core/auto_generated/mesh/qgsmeshdataprovidertemporalcapabilities.sip.in index 665fb5f0e602..640819455359 100644 --- a/python/core/auto_generated/mesh/qgsmeshdataprovidertemporalcapabilities.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshdataprovidertemporalcapabilities.sip.in @@ -12,7 +12,7 @@ class QgsMeshDataProviderTemporalCapabilities: QgsDataProviderTemporalCapabilities { -%Docstring +%Docstring(signature="appended") Class for handling properties relating to a mesh data provider's temporal capabilities. .. versionadded:: 3.14 diff --git a/python/core/auto_generated/mesh/qgsmeshdataset.sip.in b/python/core/auto_generated/mesh/qgsmeshdataset.sip.in index f0181b8a4122..ef1848a9deb2 100644 --- a/python/core/auto_generated/mesh/qgsmeshdataset.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshdataset.sip.in @@ -14,7 +14,7 @@ class QgsMeshDatasetIndex { -%Docstring +%Docstring(signature="appended") :py:class:`QgsMeshDatasetIndex` is index that identifies the dataset group (e.g. wind speed) and a dataset in this group (e.g. magnitude of wind speed in particular time) @@ -52,7 +52,7 @@ Returns whether index is valid, ie at least groups is set class QgsMeshDatasetValue { -%Docstring +%Docstring(signature="appended") :py:class:`QgsMeshDatasetValue` represents single dataset value. @@ -123,7 +123,7 @@ Returns y value class QgsMeshDataBlock { -%Docstring +%Docstring(signature="appended") :py:class:`QgsMeshDataBlock` is a block of integers/doubles that can be used to retrieve: @@ -244,7 +244,7 @@ Sets block validity class QgsMesh3dDataBlock { -%Docstring +%Docstring(signature="appended") :py:class:`QgsMesh3dDataBlock` is a block of 3d stacked mesh data related N faces defined on base mesh frame. @@ -367,7 +367,7 @@ For vector datasets the number of values is doubled (x1, y1, x2, y2, ... ) class QgsMeshDatasetGroupMetadata { -%Docstring +%Docstring(signature="appended") :py:class:`QgsMeshDatasetGroupMetadata` is a collection of dataset group metadata such as whether the data is vector or scalar, name @@ -489,7 +489,7 @@ Returns the reference time class QgsMeshDatasetMetadata { -%Docstring +%Docstring(signature="appended") :py:class:`QgsMeshDatasetMetadata` is a collection of mesh dataset metadata such as whether the data is valid or associated time for the dataset @@ -558,7 +558,7 @@ Returns maximum number of vertical levels for 3d stacked meshes class QgsMeshDataset { -%Docstring +%Docstring(signature="appended") Abstract class that represents a dataset @@ -609,7 +609,7 @@ Returns the values count class QgsMeshDatasetGroup { -%Docstring +%Docstring(signature="appended") Abstract class that represents a dataset group @@ -768,7 +768,7 @@ Sets the reference time of the dataset group class QgsMeshDatasetGroupTreeItem { -%Docstring +%Docstring(signature="appended") Tree item for display of the mesh dataset groups. Dataset group is set of datasets with the same name, diff --git a/python/core/auto_generated/mesh/qgsmeshlayer.sip.in b/python/core/auto_generated/mesh/qgsmeshlayer.sip.in index f0e5de477290..0d4527e0f6ae 100644 --- a/python/core/auto_generated/mesh/qgsmeshlayer.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshlayer.sip.in @@ -13,7 +13,7 @@ class QgsMeshLayer : QgsMapLayer { -%Docstring +%Docstring(signature="appended") Represents a mesh layer supporting display of data on structured or unstructured meshes diff --git a/python/core/auto_generated/mesh/qgsmeshlayertemporalproperties.sip.in b/python/core/auto_generated/mesh/qgsmeshlayertemporalproperties.sip.in index b115537e0440..7f044dbe6415 100644 --- a/python/core/auto_generated/mesh/qgsmeshlayertemporalproperties.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshlayertemporalproperties.sip.in @@ -13,7 +13,7 @@ class QgsMeshLayerTemporalProperties : QgsMapLayerTemporalProperties { -%Docstring +%Docstring(signature="appended") Implementation of map layer temporal properties for mesh layers. The time in a mesh layer is defined by : diff --git a/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in b/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in index 4efc0737d498..60e020d0424f 100644 --- a/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in @@ -12,7 +12,7 @@ class QgsMeshRendererMeshSettings { -%Docstring +%Docstring(signature="appended") Represents a mesh renderer settings for mesh object @@ -81,7 +81,7 @@ Reads configuration from the given DOM element class QgsMeshRendererScalarSettings { -%Docstring +%Docstring(signature="appended") Represents a mesh renderer settings for scalar datasets @@ -193,7 +193,7 @@ Reads configuration from the given DOM element class QgsMeshRendererVectorArrowSettings { -%Docstring +%Docstring(signature="appended") Represents a mesh renderer settings for vector datasets displayed with arrows @@ -315,7 +315,7 @@ Reads configuration from the given DOM element class QgsMeshRendererVectorStreamlineSettings { -%Docstring +%Docstring(signature="appended") Represents a streamline renderer settings for vector datasets displayed by streamlines @@ -367,7 +367,7 @@ Writes configuration to a new DOM element class QgsMeshRendererVectorTracesSettings { -%Docstring +%Docstring(signature="appended") Represents a trace renderer settings for vector datasets displayed by particle traces @@ -423,7 +423,7 @@ Writes configuration to a new DOM element class QgsMeshRendererVectorSettings { -%Docstring +%Docstring(signature="appended") Represents a renderer settings for vector datasets @@ -626,7 +626,7 @@ Reads configuration from the given DOM element class QgsMeshRendererSettings { -%Docstring +%Docstring(signature="appended") Represents all mesh renderer settings diff --git a/python/core/auto_generated/mesh/qgsmeshspatialindex.sip.in b/python/core/auto_generated/mesh/qgsmeshspatialindex.sip.in index d68554b066d5..941a22397454 100644 --- a/python/core/auto_generated/mesh/qgsmeshspatialindex.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshspatialindex.sip.in @@ -13,7 +13,7 @@ class QgsMeshSpatialIndex { -%Docstring +%Docstring(signature="appended") A spatial index for :py:class:`QgsMeshFace` or :py:class:`QgsMeshEdge` objects. diff --git a/python/core/auto_generated/mesh/qgsmeshtimesettings.sip.in b/python/core/auto_generated/mesh/qgsmeshtimesettings.sip.in index 2ef65eb5dd73..88524fa118bd 100644 --- a/python/core/auto_generated/mesh/qgsmeshtimesettings.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshtimesettings.sip.in @@ -12,7 +12,7 @@ class QgsMeshTimeSettings { -%Docstring +%Docstring(signature="appended") Represents a mesh time settings for mesh datasets diff --git a/python/core/auto_generated/mesh/qgsmeshtracerenderer.sip.in b/python/core/auto_generated/mesh/qgsmeshtracerenderer.sip.in index e68e12abe79d..85de1058641c 100644 --- a/python/core/auto_generated/mesh/qgsmeshtracerenderer.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshtracerenderer.sip.in @@ -16,7 +16,7 @@ class QgsMeshVectorTraceAnimationGenerator { -%Docstring +%Docstring(signature="appended") A wrapper for :py:class:`QgsMeshParticuleTracesField` used to render the particles. Available for Python binding diff --git a/python/core/auto_generated/metadata/qgsabstractmetadatabase.sip.in b/python/core/auto_generated/metadata/qgsabstractmetadatabase.sip.in index 643fd05ed2d3..5113f0817520 100644 --- a/python/core/auto_generated/metadata/qgsabstractmetadatabase.sip.in +++ b/python/core/auto_generated/metadata/qgsabstractmetadatabase.sip.in @@ -12,7 +12,7 @@ class QgsAbstractMetadataBase { -%Docstring +%Docstring(signature="appended") An abstract base class for metadata stores. :py:class:`QgsAbstractMetadataBase` is the base class for handling storage and management of the metadata diff --git a/python/core/auto_generated/metadata/qgslayermetadata.sip.in b/python/core/auto_generated/metadata/qgslayermetadata.sip.in index 5e13a48b3f95..fd25cbd38c92 100644 --- a/python/core/auto_generated/metadata/qgslayermetadata.sip.in +++ b/python/core/auto_generated/metadata/qgslayermetadata.sip.in @@ -12,7 +12,7 @@ class QgsLayerMetadata : QgsAbstractMetadataBase { -%Docstring +%Docstring(signature="appended") A structured metadata store for a map layer. :py:class:`QgsLayerMetadata` handles storage and management of the metadata diff --git a/python/core/auto_generated/metadata/qgslayermetadataformatter.sip.in b/python/core/auto_generated/metadata/qgslayermetadataformatter.sip.in index 5e1ad4eb54a1..cbf67ebd920f 100644 --- a/python/core/auto_generated/metadata/qgslayermetadataformatter.sip.in +++ b/python/core/auto_generated/metadata/qgslayermetadataformatter.sip.in @@ -12,7 +12,7 @@ class QgsLayerMetadataFormatter { -%Docstring +%Docstring(signature="appended") Class for metadata formatter. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in b/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in index 35c4a919b434..da495036ebba 100644 --- a/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in +++ b/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in @@ -13,7 +13,7 @@ class QgsAbstractMetadataBaseValidator { -%Docstring +%Docstring(signature="appended") Abstract base class for metadata validators. .. versionadded:: 3.0 @@ -26,7 +26,7 @@ Abstract base class for metadata validators. class ValidationResult { -%Docstring +%Docstring(signature="appended") Contains the parameters describing a metadata validation failure. .. versionadded:: 3.0 @@ -83,7 +83,7 @@ to fix the metadata. class QgsNativeMetadataBaseValidator : QgsAbstractMetadataBaseValidator { -%Docstring +%Docstring(signature="appended") A validator for the native base QGIS metadata schema definition. .. versionadded:: 3.2 @@ -108,7 +108,7 @@ Constructor for QgsNativeMetadataBaseValidator. class QgsNativeMetadataValidator : QgsNativeMetadataBaseValidator { -%Docstring +%Docstring(signature="appended") A validator for the native QGIS layer metadata schema definition. .. versionadded:: 3.0 @@ -132,7 +132,7 @@ Constructor for QgsNativeMetadataValidator. class QgsNativeProjectMetadataValidator : QgsNativeMetadataBaseValidator { -%Docstring +%Docstring(signature="appended") A validator for the native QGIS project metadata schema definition. .. versionadded:: 3.2 diff --git a/python/core/auto_generated/metadata/qgsprojectmetadata.sip.in b/python/core/auto_generated/metadata/qgsprojectmetadata.sip.in index c8e09d011268..cee886cbe337 100644 --- a/python/core/auto_generated/metadata/qgsprojectmetadata.sip.in +++ b/python/core/auto_generated/metadata/qgsprojectmetadata.sip.in @@ -12,7 +12,7 @@ class QgsProjectMetadata : QgsAbstractMetadataBase { -%Docstring +%Docstring(signature="appended") A structured metadata store for a map layer. :py:class:`QgsProjectMetadata` handles storage and management of the metadata diff --git a/python/core/auto_generated/network/qgsblockingnetworkrequest.sip.in b/python/core/auto_generated/network/qgsblockingnetworkrequest.sip.in index 81072f4fcf7b..75f1f2d3b2cf 100644 --- a/python/core/auto_generated/network/qgsblockingnetworkrequest.sip.in +++ b/python/core/auto_generated/network/qgsblockingnetworkrequest.sip.in @@ -10,7 +10,7 @@ class QgsBlockingNetworkRequest : QObject { -%Docstring +%Docstring(signature="appended") A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy and authentication settings. diff --git a/python/core/auto_generated/network/qgsfiledownloader.sip.in b/python/core/auto_generated/network/qgsfiledownloader.sip.in index 63684bc1de3a..b847694187dc 100644 --- a/python/core/auto_generated/network/qgsfiledownloader.sip.in +++ b/python/core/auto_generated/network/qgsfiledownloader.sip.in @@ -12,7 +12,7 @@ class QgsFileDownloader : QObject { -%Docstring +%Docstring(signature="appended") :py:class:`QgsFileDownloader` is a utility class for downloading files. To use this class, it is necessary to pass the URL and an output file name as diff --git a/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in b/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in index c4259c3499fc..207d2594e174 100644 --- a/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in +++ b/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in @@ -14,7 +14,7 @@ class QgsNetworkRequestParameters { -%Docstring +%Docstring(signature="appended") Encapsulates parameters and properties of a network request. .. versionadded:: 3.6 @@ -102,7 +102,7 @@ QgsNetworkRequestParameters.AttributeInitiatorRequestId attribute set. class QgsNetworkAccessManager : QNetworkAccessManager { -%Docstring +%Docstring(signature="appended") network access manager for QGIS This class implements the QGIS network access manager. It's a singleton diff --git a/python/core/auto_generated/network/qgsnetworkcontentfetcher.sip.in b/python/core/auto_generated/network/qgsnetworkcontentfetcher.sip.in index ea7f38226365..83972dd96a8d 100644 --- a/python/core/auto_generated/network/qgsnetworkcontentfetcher.sip.in +++ b/python/core/auto_generated/network/qgsnetworkcontentfetcher.sip.in @@ -13,7 +13,7 @@ class QgsNetworkContentFetcher : QObject { -%Docstring +%Docstring(signature="appended") HTTP network content fetcher. A simple method for fetching remote HTTP content and converting the content to standard formats. Url redirects are automatically handled. diff --git a/python/core/auto_generated/network/qgsnetworkcontentfetcherregistry.sip.in b/python/core/auto_generated/network/qgsnetworkcontentfetcherregistry.sip.in index 34dcf5af6452..82710dd6c6ab 100644 --- a/python/core/auto_generated/network/qgsnetworkcontentfetcherregistry.sip.in +++ b/python/core/auto_generated/network/qgsnetworkcontentfetcherregistry.sip.in @@ -12,7 +12,7 @@ class QgsFetchedContent : QObject { -%Docstring +%Docstring(signature="appended") FetchedContent holds useful information about a network content being fetched .. seealso:: :py:class:`QgsNetworkContentFetcherRegistry` @@ -80,7 +80,7 @@ Emitted when the file is fetched and accessible class QgsNetworkContentFetcherRegistry : QObject { -%Docstring +%Docstring(signature="appended") Registry for temporary fetched files This provides a simple way of downloading and accessing diff --git a/python/core/auto_generated/network/qgsnetworkcontentfetchertask.sip.in b/python/core/auto_generated/network/qgsnetworkcontentfetchertask.sip.in index 8fbef1626d52..147d29f328af 100644 --- a/python/core/auto_generated/network/qgsnetworkcontentfetchertask.sip.in +++ b/python/core/auto_generated/network/qgsnetworkcontentfetchertask.sip.in @@ -13,7 +13,7 @@ class QgsNetworkContentFetcherTask : QgsTask { -%Docstring +%Docstring(signature="appended") Handles HTTP network content fetching in a background task. Provides a simple method for fetching remote HTTP content in a :py:class:`QgsTask`. diff --git a/python/core/auto_generated/network/qgsnetworkreply.sip.in b/python/core/auto_generated/network/qgsnetworkreply.sip.in index d69ba192c7d2..f5d705fc792d 100644 --- a/python/core/auto_generated/network/qgsnetworkreply.sip.in +++ b/python/core/auto_generated/network/qgsnetworkreply.sip.in @@ -10,7 +10,7 @@ class QgsNetworkReplyContent { -%Docstring +%Docstring(signature="appended") Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between threads. .. versionadded:: 3.6 diff --git a/python/core/auto_generated/network/qgsnewsfeedmodel.sip.in b/python/core/auto_generated/network/qgsnewsfeedmodel.sip.in index 6084d8a4114f..7f6af9324366 100644 --- a/python/core/auto_generated/network/qgsnewsfeedmodel.sip.in +++ b/python/core/auto_generated/network/qgsnewsfeedmodel.sip.in @@ -9,7 +9,7 @@ class QgsNewsFeedModel : QAbstractItemModel { -%Docstring +%Docstring(signature="appended") A model for published QGIS news feeds. This class is designed to work with :py:class:`QgsNewsFeedParser`, for displaying @@ -59,7 +59,7 @@ must exist for the lifetime of this model. class QgsNewsFeedProxyModel : QSortFilterProxyModel { -%Docstring +%Docstring(signature="appended") A proxy model for use with QgsNewsFeedModel. :py:class:`QgsNewsFeedProxyModel` applies custom sorting to the entries in a :py:class:`QgsNewsFeedModel`. diff --git a/python/core/auto_generated/network/qgsnewsfeedparser.sip.in b/python/core/auto_generated/network/qgsnewsfeedparser.sip.in index 6e55b37a0dcd..f3169fa7c025 100644 --- a/python/core/auto_generated/network/qgsnewsfeedparser.sip.in +++ b/python/core/auto_generated/network/qgsnewsfeedparser.sip.in @@ -10,7 +10,7 @@ class QgsNewsFeedParser : QObject { -%Docstring +%Docstring(signature="appended") Parser for published QGIS news feeds. This class is designed to work with the specialized QGIS news feed API. See @@ -26,7 +26,7 @@ https://github.com/elpaso/qgis-feed. class Entry { -%Docstring +%Docstring(signature="appended") Represents a single entry from a news feed. .. versionadded:: 3.10 diff --git a/python/core/auto_generated/numericformats/qgsbasicnumericformat.sip.in b/python/core/auto_generated/numericformats/qgsbasicnumericformat.sip.in index 6a509ab6b212..3a5ddf4bf6bd 100644 --- a/python/core/auto_generated/numericformats/qgsbasicnumericformat.sip.in +++ b/python/core/auto_generated/numericformats/qgsbasicnumericformat.sip.in @@ -9,7 +9,7 @@ class QgsBasicNumericFormat : QgsNumericFormat { -%Docstring +%Docstring(signature="appended") A numeric formatter which returns a simple text representation of a value. .. versionadded:: 3.12 diff --git a/python/core/auto_generated/numericformats/qgsbearingnumericformat.sip.in b/python/core/auto_generated/numericformats/qgsbearingnumericformat.sip.in index d759d81a791a..5d2406c64a08 100644 --- a/python/core/auto_generated/numericformats/qgsbearingnumericformat.sip.in +++ b/python/core/auto_generated/numericformats/qgsbearingnumericformat.sip.in @@ -9,7 +9,7 @@ class QgsBearingNumericFormat : QgsBasicNumericFormat { -%Docstring +%Docstring(signature="appended") A numeric formatter which returns a text representation of a direction/bearing. .. versionadded:: 3.12 diff --git a/python/core/auto_generated/numericformats/qgscurrencynumericformat.sip.in b/python/core/auto_generated/numericformats/qgscurrencynumericformat.sip.in index 27a61d647831..c7fbd1dffa5a 100644 --- a/python/core/auto_generated/numericformats/qgscurrencynumericformat.sip.in +++ b/python/core/auto_generated/numericformats/qgscurrencynumericformat.sip.in @@ -9,7 +9,7 @@ class QgsCurrencyNumericFormat : QgsBasicNumericFormat { -%Docstring +%Docstring(signature="appended") A numeric formatter which returns a text representation of a currency value. .. versionadded:: 3.12 diff --git a/python/core/auto_generated/numericformats/qgsfallbacknumericformat.sip.in b/python/core/auto_generated/numericformats/qgsfallbacknumericformat.sip.in index da0321f9c781..f4176a514ea5 100644 --- a/python/core/auto_generated/numericformats/qgsfallbacknumericformat.sip.in +++ b/python/core/auto_generated/numericformats/qgsfallbacknumericformat.sip.in @@ -9,7 +9,7 @@ class QgsFallbackNumericFormat : QgsNumericFormat { -%Docstring +%Docstring(signature="appended") A basic numeric formatter which returns a simple text representation of a value. .. versionadded:: 3.12 diff --git a/python/core/auto_generated/numericformats/qgsfractionnumericformat.sip.in b/python/core/auto_generated/numericformats/qgsfractionnumericformat.sip.in index 5a9c776191da..6b18ec06599e 100644 --- a/python/core/auto_generated/numericformats/qgsfractionnumericformat.sip.in +++ b/python/core/auto_generated/numericformats/qgsfractionnumericformat.sip.in @@ -9,7 +9,7 @@ class QgsFractionNumericFormat : QgsNumericFormat { -%Docstring +%Docstring(signature="appended") A numeric formatter which returns a vulgar fractional representation of a decimal value (e.g. "1/2" instead of 0.5). .. versionadded:: 3.14 diff --git a/python/core/auto_generated/numericformats/qgsnumericformat.sip.in b/python/core/auto_generated/numericformats/qgsnumericformat.sip.in index a58583ffc8f3..d9661bbd4b30 100644 --- a/python/core/auto_generated/numericformats/qgsnumericformat.sip.in +++ b/python/core/auto_generated/numericformats/qgsnumericformat.sip.in @@ -12,7 +12,7 @@ class QgsNumericFormatContext { -%Docstring +%Docstring(signature="appended") A context for numeric formats .. versionadded:: 3.12 @@ -142,7 +142,7 @@ Sets the exponential ``character``. class QgsNumericFormat { -%Docstring +%Docstring(signature="appended") A numeric formatter allows for formatting a numeric value for display, using a variety of different formatting techniques (e.g. as scientific notation, currency values, percentage values, etc) diff --git a/python/core/auto_generated/numericformats/qgsnumericformatregistry.sip.in b/python/core/auto_generated/numericformats/qgsnumericformatregistry.sip.in index b2e7bf0081bf..807bf6e1985c 100644 --- a/python/core/auto_generated/numericformats/qgsnumericformatregistry.sip.in +++ b/python/core/auto_generated/numericformats/qgsnumericformatregistry.sip.in @@ -11,7 +11,7 @@ class QgsNumericFormatRegistry { -%Docstring +%Docstring(signature="appended") The :py:class:`QgsNumericFormatRegistry` manages registered classes of :py:class:`QgsNumericFormat`. A reference to the :py:class:`QgsFieldFormatterRegistry` can be obtained from diff --git a/python/core/auto_generated/numericformats/qgspercentagenumericformat.sip.in b/python/core/auto_generated/numericformats/qgspercentagenumericformat.sip.in index e49e6f24867f..90a5f90394df 100644 --- a/python/core/auto_generated/numericformats/qgspercentagenumericformat.sip.in +++ b/python/core/auto_generated/numericformats/qgspercentagenumericformat.sip.in @@ -9,7 +9,7 @@ class QgsPercentageNumericFormat : QgsBasicNumericFormat { -%Docstring +%Docstring(signature="appended") A numeric formatter which returns a text representation of a percentage value. .. versionadded:: 3.12 diff --git a/python/core/auto_generated/numericformats/qgsscientificnumericformat.sip.in b/python/core/auto_generated/numericformats/qgsscientificnumericformat.sip.in index fbcaf710bef8..4b263cabf659 100644 --- a/python/core/auto_generated/numericformats/qgsscientificnumericformat.sip.in +++ b/python/core/auto_generated/numericformats/qgsscientificnumericformat.sip.in @@ -9,7 +9,7 @@ class QgsScientificNumericFormat : QgsBasicNumericFormat { -%Docstring +%Docstring(signature="appended") A numeric formatter which returns a scientific notation representation of a value. .. versionadded:: 3.12 diff --git a/python/core/auto_generated/pointcloud/qgspointcloudattribute.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudattribute.sip.in index e750d3eb7329..b097c1b7a347 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudattribute.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudattribute.sip.in @@ -13,7 +13,7 @@ class QgsPointCloudAttribute { -%Docstring +%Docstring(signature="appended") Attribute for point cloud data pair of name and size in bytes @@ -94,7 +94,7 @@ Returns ``True`` if the specified data ``type`` is numeric. class QgsPointCloudAttributeCollection { -%Docstring +%Docstring(signature="appended") Collection of point cloud attributes diff --git a/python/core/auto_generated/pointcloud/qgspointcloudattributebyramprenderer.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudattributebyramprenderer.sip.in index 203fb391f027..82b2a218e8cd 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudattributebyramprenderer.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudattributebyramprenderer.sip.in @@ -11,7 +11,7 @@ class QgsPointCloudAttributeByRampRenderer : QgsPointCloudRenderer { -%Docstring +%Docstring(signature="appended") An RGB renderer for 2d visualisation of point clouds using embedded red, green and blue attributes. .. versionadded:: 3.18 diff --git a/python/core/auto_generated/pointcloud/qgspointcloudattributemodel.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudattributemodel.sip.in index 36c9395f3769..13be913242ca 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudattributemodel.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudattributemodel.sip.in @@ -13,7 +13,7 @@ class QgsPointCloudAttributeModel : QAbstractItemModel { -%Docstring +%Docstring(signature="appended") A model for display of available attributes from a point cloud. @@ -116,7 +116,7 @@ Returns an icon corresponding to an attribute ``type`` class QgsPointCloudAttributeProxyModel : QSortFilterProxyModel { -%Docstring +%Docstring(signature="appended") A proxy model for filtering available attributes from a point cloud attribute model. diff --git a/python/core/auto_generated/pointcloud/qgspointcloudblock.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudblock.sip.in index 9ba7beaa7406..e7157da6abcd 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudblock.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudblock.sip.in @@ -12,7 +12,7 @@ class QgsPointCloudBlock { -%Docstring +%Docstring(signature="appended") Base class for storing raw data from point cloud nodes .. note:: diff --git a/python/core/auto_generated/pointcloud/qgspointcloudclassifiedrenderer.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudclassifiedrenderer.sip.in index 510aee9e40bc..c445b7653889 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudclassifiedrenderer.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudclassifiedrenderer.sip.in @@ -12,7 +12,7 @@ class QgsPointCloudCategory { -%Docstring +%Docstring(signature="appended") Represents an individual category (class) from a :py:class:`QgsPointCloudClassifiedRenderer`. .. versionadded:: 3.18 @@ -103,7 +103,7 @@ typedef QList QgsPointCloudCategoryList; class QgsPointCloudClassifiedRenderer : QgsPointCloudRenderer { -%Docstring +%Docstring(signature="appended") Renders point clouds by a classification attribute. .. versionadded:: 3.18 diff --git a/python/core/auto_generated/pointcloud/qgspointclouddataprovider.sip.in b/python/core/auto_generated/pointcloud/qgspointclouddataprovider.sip.in index c92df9c31743..1b732440ef47 100644 --- a/python/core/auto_generated/pointcloud/qgspointclouddataprovider.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointclouddataprovider.sip.in @@ -12,7 +12,7 @@ class QgsPointCloudDataProvider: QgsDataProvider { -%Docstring +%Docstring(signature="appended") Base class for providing data for :py:class:`QgsPointCloudLayer` Responsible for reading native point cloud data and returning the indexed data. diff --git a/python/core/auto_generated/pointcloud/qgspointcloudextentrenderer.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudextentrenderer.sip.in index c9a85a61effc..0c20d2a88fa1 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudextentrenderer.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudextentrenderer.sip.in @@ -12,7 +12,7 @@ class QgsPointCloudExtentRenderer : QgsPointCloudRenderer { -%Docstring +%Docstring(signature="appended") A renderer for 2d visualisation of point clouds which shows the dataset's extents using a fill symbol. .. versionadded:: 3.18 diff --git a/python/core/auto_generated/pointcloud/qgspointcloudlayer.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudlayer.sip.in index bd4f1665a98f..52a3edfacca3 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudlayer.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudlayer.sip.in @@ -14,7 +14,7 @@ class QgsPointCloudLayer : QgsMapLayer { -%Docstring +%Docstring(signature="appended") Represents a map layer supporting display of point clouds diff --git a/python/core/auto_generated/pointcloud/qgspointcloudlayerelevationproperties.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudlayerelevationproperties.sip.in index 9118bd3b31ac..cf3f9b5ac497 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudlayerelevationproperties.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudlayerelevationproperties.sip.in @@ -12,7 +12,7 @@ class QgsPointCloudLayerElevationProperties : QgsMapLayerElevationProperties { -%Docstring +%Docstring(signature="appended") Point cloud layer specific subclass of :py:class:`QgsMapLayerElevationProperties`. .. versionadded:: 3.18 diff --git a/python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in index 96aceadc9e7f..f6eb3e6d64f0 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in @@ -13,7 +13,7 @@ class QgsPointCloudRenderContext { -%Docstring +%Docstring(signature="appended") Encapsulates the render context for a 2D point cloud rendering operation. @@ -143,7 +143,7 @@ Returns any constant offset which must be applied to z values taken from the poi class QgsPointCloudRenderer { -%Docstring +%Docstring(signature="appended") Abstract base class for 2d point cloud renderers. diff --git a/python/core/auto_generated/pointcloud/qgspointcloudrendererregistry.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudrendererregistry.sip.in index 15e8cc77b6e1..5407134c662b 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudrendererregistry.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudrendererregistry.sip.in @@ -11,7 +11,7 @@ class QgsPointCloudRendererAbstractMetadata { -%Docstring +%Docstring(signature="appended") Stores metadata about one point cloud renderer class. .. note:: @@ -78,7 +78,7 @@ Pure virtual function: must be implemented in derived classes. class QgsPointCloudRendererMetadata : QgsPointCloudRendererAbstractMetadata { -%Docstring +%Docstring(signature="appended") Convenience metadata class that uses static functions to create point cloud renderer and its widget. .. versionadded:: 3.18 @@ -104,7 +104,7 @@ Convenience metadata class that uses static functions to create point cloud rend class QgsPointCloudRendererRegistry { -%Docstring +%Docstring(signature="appended") Registry of 2D renderers for point clouds. :py:class:`QgsPointCloudRendererRegistry` is not usually directly created, but rather accessed through diff --git a/python/core/auto_generated/pointcloud/qgspointcloudrgbrenderer.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudrgbrenderer.sip.in index ace5633eb0fc..a87ca613a8eb 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudrgbrenderer.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudrgbrenderer.sip.in @@ -12,7 +12,7 @@ class QgsPointCloudRgbRenderer : QgsPointCloudRenderer { -%Docstring +%Docstring(signature="appended") An RGB renderer for 2d visualisation of point clouds using embedded red, green and blue attributes. .. versionadded:: 3.18 diff --git a/python/core/auto_generated/processing/models/qgsprocessingmodelalgorithm.sip.in b/python/core/auto_generated/processing/models/qgsprocessingmodelalgorithm.sip.in index 2169e900b7fb..01b31f0e8290 100644 --- a/python/core/auto_generated/processing/models/qgsprocessingmodelalgorithm.sip.in +++ b/python/core/auto_generated/processing/models/qgsprocessingmodelalgorithm.sip.in @@ -12,7 +12,7 @@ class QgsProcessingModelAlgorithm : QgsProcessingAlgorithm { -%Docstring +%Docstring(signature="appended") Model based algorithm with processing. .. versionadded:: 3.0 @@ -457,7 +457,7 @@ sources to those with compatible data types for the parameter/outputs. class VariableDefinition { -%Docstring +%Docstring(signature="appended") Definition of a expression context variable available during model execution. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/processing/models/qgsprocessingmodelchildalgorithm.sip.in b/python/core/auto_generated/processing/models/qgsprocessingmodelchildalgorithm.sip.in index 525fce220195..17e48bab4b5e 100644 --- a/python/core/auto_generated/processing/models/qgsprocessingmodelchildalgorithm.sip.in +++ b/python/core/auto_generated/processing/models/qgsprocessingmodelchildalgorithm.sip.in @@ -13,7 +13,7 @@ class QgsProcessingModelChildAlgorithm : QgsProcessingModelComponent { -%Docstring +%Docstring(signature="appended") Child algorithm representing a single component of a :py:class:`QgsProcessingModelAlgorithm`. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/processing/models/qgsprocessingmodelchilddependency.sip.in b/python/core/auto_generated/processing/models/qgsprocessingmodelchilddependency.sip.in index 6e565b48409d..9ce5adfc1439 100644 --- a/python/core/auto_generated/processing/models/qgsprocessingmodelchilddependency.sip.in +++ b/python/core/auto_generated/processing/models/qgsprocessingmodelchilddependency.sip.in @@ -13,7 +13,7 @@ class QgsProcessingModelChildDependency { -%Docstring +%Docstring(signature="appended") Contains details of a child algorithm dependency. .. versionadded:: 3.14 diff --git a/python/core/auto_generated/processing/models/qgsprocessingmodelchildparametersource.sip.in b/python/core/auto_generated/processing/models/qgsprocessingmodelchildparametersource.sip.in index d02f03398820..95c1a593b9d2 100644 --- a/python/core/auto_generated/processing/models/qgsprocessingmodelchildparametersource.sip.in +++ b/python/core/auto_generated/processing/models/qgsprocessingmodelchildparametersource.sip.in @@ -12,7 +12,7 @@ class QgsProcessingModelChildParameterSource { -%Docstring +%Docstring(signature="appended") Source for the value of a parameter for a child algorithm within a model. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/processing/models/qgsprocessingmodelcomment.sip.in b/python/core/auto_generated/processing/models/qgsprocessingmodelcomment.sip.in index b1c00441f5b5..8af918ceebb7 100644 --- a/python/core/auto_generated/processing/models/qgsprocessingmodelcomment.sip.in +++ b/python/core/auto_generated/processing/models/qgsprocessingmodelcomment.sip.in @@ -12,7 +12,7 @@ class QgsProcessingModelComment : QgsProcessingModelComponent { -%Docstring +%Docstring(signature="appended") Represents a comment in a model. .. versionadded:: 3.14 diff --git a/python/core/auto_generated/processing/models/qgsprocessingmodelcomponent.sip.in b/python/core/auto_generated/processing/models/qgsprocessingmodelcomponent.sip.in index 0de7ed00de7a..e375686da230 100644 --- a/python/core/auto_generated/processing/models/qgsprocessingmodelcomponent.sip.in +++ b/python/core/auto_generated/processing/models/qgsprocessingmodelcomponent.sip.in @@ -13,7 +13,7 @@ class QgsProcessingModelComponent { -%Docstring +%Docstring(signature="appended") Represents a component of a model algorithm. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/processing/models/qgsprocessingmodelgroupbox.sip.in b/python/core/auto_generated/processing/models/qgsprocessingmodelgroupbox.sip.in index 8d3172ae09d1..f15efd5c462e 100644 --- a/python/core/auto_generated/processing/models/qgsprocessingmodelgroupbox.sip.in +++ b/python/core/auto_generated/processing/models/qgsprocessingmodelgroupbox.sip.in @@ -12,7 +12,7 @@ class QgsProcessingModelGroupBox : QgsProcessingModelComponent { -%Docstring +%Docstring(signature="appended") Represents a group box in a model. .. versionadded:: 3.14 diff --git a/python/core/auto_generated/processing/models/qgsprocessingmodeloutput.sip.in b/python/core/auto_generated/processing/models/qgsprocessingmodeloutput.sip.in index dfa373e25911..04db61cf9c65 100644 --- a/python/core/auto_generated/processing/models/qgsprocessingmodeloutput.sip.in +++ b/python/core/auto_generated/processing/models/qgsprocessingmodeloutput.sip.in @@ -12,7 +12,7 @@ class QgsProcessingModelOutput : QgsProcessingModelComponent { -%Docstring +%Docstring(signature="appended") Represents a final output created by the model. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/processing/models/qgsprocessingmodelparameter.sip.in b/python/core/auto_generated/processing/models/qgsprocessingmodelparameter.sip.in index cb30079323f4..4542141f6c4c 100644 --- a/python/core/auto_generated/processing/models/qgsprocessingmodelparameter.sip.in +++ b/python/core/auto_generated/processing/models/qgsprocessingmodelparameter.sip.in @@ -13,7 +13,7 @@ class QgsProcessingModelParameter : QgsProcessingModelComponent { -%Docstring +%Docstring(signature="appended") Represents an input parameter used by the model. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/processing/qgsprocessing.sip.in b/python/core/auto_generated/processing/qgsprocessing.sip.in index 52bdf4a56e48..de33821c12eb 100644 --- a/python/core/auto_generated/processing/qgsprocessing.sip.in +++ b/python/core/auto_generated/processing/qgsprocessing.sip.in @@ -13,7 +13,7 @@ class QgsProcessing { -%Docstring +%Docstring(signature="appended") Contains enumerations and other constants for use in processing algorithms and parameters. diff --git a/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in b/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in index 3cd42bdf443b..3b4fadafbbb9 100644 --- a/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in @@ -16,7 +16,7 @@ class QgsProcessingAlgorithm { -%Docstring +%Docstring(signature="appended") Abstract base class for processing algorithms. .. versionadded:: 3.0 @@ -1048,7 +1048,7 @@ QFlags operator|(QgsProcessingAlgorithm::Flag f1, class QgsProcessingFeatureBasedAlgorithm : QgsProcessingAlgorithm { -%Docstring +%Docstring(signature="appended") An abstract QgsProcessingAlgorithm base class for processing algorithms which operate "feature-by-feature". Feature based algorithms are algorithms which operate on individual features in isolation. These diff --git a/python/core/auto_generated/processing/qgsprocessingalgrunnertask.sip.in b/python/core/auto_generated/processing/qgsprocessingalgrunnertask.sip.in index 2c51f433d405..62bcda71c779 100644 --- a/python/core/auto_generated/processing/qgsprocessingalgrunnertask.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingalgrunnertask.sip.in @@ -12,7 +12,7 @@ class QgsProcessingAlgRunnerTask : QgsTask { -%Docstring +%Docstring(signature="appended") :py:class:`QgsTask` task which runs a :py:class:`QgsProcessingAlgorithm` in a background task. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/processing/qgsprocessingcontext.sip.in b/python/core/auto_generated/processing/qgsprocessingcontext.sip.in index ad254f5a9414..77c8dd9c448f 100644 --- a/python/core/auto_generated/processing/qgsprocessingcontext.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingcontext.sip.in @@ -14,7 +14,7 @@ class QgsProcessingContext { -%Docstring +%Docstring(signature="appended") Contains information about the context in which a processing algorithm is executed. Contextual information includes settings such as the associated project, and @@ -208,7 +208,7 @@ algorithm execution. class LayerDetails { -%Docstring +%Docstring(signature="appended") Details for layers to load into projects. .. versionadded:: 3.0 @@ -595,7 +595,7 @@ QFlags operator|(QgsProcessingContext::Flag f1, QFla class QgsProcessingLayerPostProcessorInterface { -%Docstring +%Docstring(signature="appended") An interface for layer post-processing handlers for execution following a processing algorithm operation. Note that post-processing of a layer will ONLY occur if that layer is set to be loaded into a QGIS project diff --git a/python/core/auto_generated/processing/qgsprocessingfeedback.sip.in b/python/core/auto_generated/processing/qgsprocessingfeedback.sip.in index daf9bec8fd37..a8fb0d82b92f 100644 --- a/python/core/auto_generated/processing/qgsprocessingfeedback.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingfeedback.sip.in @@ -12,7 +12,7 @@ class QgsProcessingFeedback : QgsFeedback { -%Docstring +%Docstring(signature="appended") Base class for providing feedback from a processing algorithm. This base class implementation silently ignores all feedback reported by algorithms. @@ -156,7 +156,7 @@ Returns the plain text contents of the log, which contains all messages pushed t class QgsProcessingMultiStepFeedback : QgsProcessingFeedback { -%Docstring +%Docstring(signature="appended") Processing feedback object for multi-step operations. diff --git a/python/core/auto_generated/processing/qgsprocessingoutputs.sip.in b/python/core/auto_generated/processing/qgsprocessingoutputs.sip.in index 34cb9d439b16..7c44a3495271 100644 --- a/python/core/auto_generated/processing/qgsprocessingoutputs.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingoutputs.sip.in @@ -13,7 +13,7 @@ class QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") Base class for the definition of processing outputs. @@ -129,7 +129,7 @@ typedef QList< const QgsProcessingOutputDefinition * > QgsProcessingOutputDefini class QgsProcessingOutputMapLayer : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A map layer output for processing algorithms, where layers may be either vector or raster. If the actual layer output type is known (e.g. always vector or always raster), use @@ -160,7 +160,7 @@ Returns the type name for the output class. class QgsProcessingOutputVectorLayer : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A vector layer output for processing algorithms. .. versionadded:: 3.0 @@ -200,7 +200,7 @@ Sets the layer ``type`` for the output layer. class QgsProcessingOutputRasterLayer : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A raster layer output for processing algorithms. .. versionadded:: 3.0 @@ -227,7 +227,7 @@ Returns the type name for the output class. class QgsProcessingOutputMultipleLayers : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A multi-layer output for processing algorithms which create map layers, when the number and nature of the output layers is not predefined. @@ -263,7 +263,7 @@ Returns the type name for the output class. class QgsProcessingOutputHtml : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A HTML file output for processing algorithms. .. versionadded:: 3.0 @@ -289,7 +289,7 @@ Returns the type name for the output class. class QgsProcessingOutputNumber : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A numeric output for processing algorithms. .. versionadded:: 3.0 @@ -314,7 +314,7 @@ Returns the type name for the output class. class QgsProcessingOutputString : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A string output for processing algorithms. .. versionadded:: 3.0 @@ -340,7 +340,7 @@ Returns the type name for the output class. class QgsProcessingOutputBoolean : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A boolean output for processing algorithms. .. versionadded:: 3.8 @@ -365,7 +365,7 @@ Returns the type name for the output class. class QgsProcessingOutputFolder : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A folder output for processing algorithms. .. versionadded:: 3.0 @@ -392,7 +392,7 @@ Returns the type name for the output class. class QgsProcessingOutputFile : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A file output for processing algorithms. .. versionadded:: 3.0 @@ -418,7 +418,7 @@ Returns the type name for the output class. class QgsProcessingOutputConditionalBranch : QgsProcessingOutputDefinition { -%Docstring +%Docstring(signature="appended") A conditional branch output for processing algorithms, which represents a possible model logic flow which branches out from this algorithm. diff --git a/python/core/auto_generated/processing/qgsprocessingparameteraggregate.sip.in b/python/core/auto_generated/processing/qgsprocessingparameteraggregate.sip.in index 5caaee729b68..cc8fee0c69b9 100644 --- a/python/core/auto_generated/processing/qgsprocessingparameteraggregate.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingparameteraggregate.sip.in @@ -10,7 +10,7 @@ class QgsProcessingParameterAggregate : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A parameter for "aggregate" configurations, which consist of a definition of desired output fields, types, and aggregate used to populate then. diff --git a/python/core/auto_generated/processing/qgsprocessingparameterdxflayers.sip.in b/python/core/auto_generated/processing/qgsprocessingparameterdxflayers.sip.in index a02de7963648..68e27c012725 100644 --- a/python/core/auto_generated/processing/qgsprocessingparameterdxflayers.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingparameterdxflayers.sip.in @@ -10,7 +10,7 @@ class QgsProcessingParameterDxfLayers : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A parameter for Processing algorithms that need a list of input vector layers to export as DXF file - this parameter provides Processing framework's adapter for QList<:py:class:`QgsDxfExport`.DxfLayer>. diff --git a/python/core/auto_generated/processing/qgsprocessingparameterfieldmap.sip.in b/python/core/auto_generated/processing/qgsprocessingparameterfieldmap.sip.in index a5b150fb3738..d206cc921b70 100644 --- a/python/core/auto_generated/processing/qgsprocessingparameterfieldmap.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingparameterfieldmap.sip.in @@ -10,7 +10,7 @@ class QgsProcessingParameterFieldMapping : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A parameter for "field mapping" configurations, which consist of a definition of desired output fields, types, and expressions used to populate then. diff --git a/python/core/auto_generated/processing/qgsprocessingparametermeshdataset.sip.in b/python/core/auto_generated/processing/qgsprocessingparametermeshdataset.sip.in index 32534e63d3f8..215c0764c821 100644 --- a/python/core/auto_generated/processing/qgsprocessingparametermeshdataset.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingparametermeshdataset.sip.in @@ -10,7 +10,7 @@ class QgsProcessingParameterMeshDatasetGroups : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A parameter for processing algorithms that need a list of mesh dataset groups. A valid value for this parameter is a list (QVariantList) of dataset groups index in the mesh layer scope @@ -81,7 +81,7 @@ Returns the ``value`` as a list if dataset group indexes class QgsProcessingParameterMeshDatasetTime : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A parameter for processing algorithms that need a list of mesh dataset index from time parameter. A valid value for this parameter is a map (QVariantMap) with in this form: diff --git a/python/core/auto_generated/processing/qgsprocessingparameters.sip.in b/python/core/auto_generated/processing/qgsprocessingparameters.sip.in index 6f679de2032d..a997883d33f9 100644 --- a/python/core/auto_generated/processing/qgsprocessingparameters.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingparameters.sip.in @@ -13,7 +13,7 @@ class QgsProcessingFeatureSourceDefinition { -%Docstring +%Docstring(signature="appended") Encapsulates settings relating to a feature source input to a processing algorithm. @@ -109,7 +109,7 @@ QFlags operator|(QgsProcessingFeatur class QgsProcessingOutputLayerDefinition { -%Docstring +%Docstring(signature="appended") Encapsulates settings relating to a feature sink or output raster layer for a processing algorithm. @@ -211,7 +211,7 @@ You can use :py:class:`QgsXmlUtils`.readVariant to load it from an XML document. class QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") Base class for the definition of processing parameters. @@ -726,7 +726,7 @@ typedef QList< const QgsProcessingParameterDefinition * > QgsProcessingParameter class QgsProcessingParameters { -%Docstring +%Docstring(signature="appended") A collection of utilities for working with parameters when running a processing algorithm. @@ -1531,7 +1531,7 @@ The caller takes responsibility for deleting the returned object. class QgsProcessingParameterBoolean : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A boolean parameter for processing algorithms. .. versionadded:: 3.0 @@ -1568,7 +1568,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterCrs : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A coordinate reference system parameter for processing algorithms. .. versionadded:: 3.0 @@ -1606,7 +1606,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterExtent : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A rectangular map extent parameter for processing algorithms. .. versionadded:: 3.0 @@ -1645,7 +1645,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterPoint : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A point parameter for processing algorithms. .. versionadded:: 3.0 @@ -1683,7 +1683,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterGeometry : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A geometry parameter for processing algorithms. .. versionadded:: 3.16 @@ -1745,7 +1745,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterFile : QgsProcessingParameterDefinition, QgsFileFilterGenerator { -%Docstring +%Docstring(signature="appended") An input file or folder parameter for processing algorithms. .. versionadded:: 3.0 @@ -1864,7 +1864,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterMatrix : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A table (matrix) parameter for processing algorithms. .. versionadded:: 3.0 @@ -1963,7 +1963,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterMultipleLayers : QgsProcessingParameterDefinition, QgsFileFilterGenerator { -%Docstring +%Docstring(signature="appended") A parameter for processing algorithms which accepts multiple map layers. .. versionadded:: 3.0 @@ -2043,7 +2043,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterNumber : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A numeric parameter for processing algorithms. For numeric parameters with a :py:func:`~QgsProcessingParameterMultipleLayers.dataType` of Double, the number of decimals places @@ -2154,7 +2154,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterDistance : QgsProcessingParameterNumber { -%Docstring +%Docstring(signature="appended") A double numeric parameter for distance values. Linked to a source layer or CRS parameter to determine what units the distance values are in. @@ -2243,7 +2243,7 @@ Sets the default distance ``unit`` for the parameter. class QgsProcessingParameterScale : QgsProcessingParameterNumber { -%Docstring +%Docstring(signature="appended") A double numeric parameter for map scale values. :py:class:`QgsProcessingParameterScale` should be evaluated by calling :py:func:`QgsProcessingAlgorithm.parameterAsDouble()`, @@ -2286,7 +2286,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterRange : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A numeric range parameter for processing algorithms. .. versionadded:: 3.0 @@ -2347,7 +2347,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterRasterLayer : QgsProcessingParameterDefinition, QgsFileFilterGenerator { -%Docstring +%Docstring(signature="appended") A raster layer parameter for processing algorithms. .. versionadded:: 3.0 @@ -2387,7 +2387,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterEnum : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") An enum based parameter for processing algorithms, allowing for selection from predefined values. .. versionadded:: 3.0 @@ -2485,7 +2485,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterString : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A string parameter for processing algorithms. .. versionadded:: 3.0 @@ -2546,7 +2546,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterAuthConfig : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A string parameter for authentication configuration ID values. This parameter allows for users to select from available authentication configurations, @@ -2589,7 +2589,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterExpression : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") An expression parameter for processing algorithms. .. versionadded:: 3.0 @@ -2650,7 +2650,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterLimitedDataTypes { -%Docstring +%Docstring(signature="appended") Can be inherited by parameters which require limits to their acceptable data types. .. versionadded:: 3.0 @@ -2686,7 +2686,7 @@ Sets the geometry ``types`` for sources acceptable by the parameter. class QgsProcessingParameterVectorLayer : QgsProcessingParameterDefinition, QgsProcessingParameterLimitedDataTypes, QgsFileFilterGenerator { -%Docstring +%Docstring(signature="appended") A vector layer (with or without geometry) parameter for processing algorithms. Consider using the more versatile :py:class:`QgsProcessingParameterFeatureSource` wherever possible. @@ -2737,7 +2737,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterMeshLayer : QgsProcessingParameterDefinition, QgsFileFilterGenerator { -%Docstring +%Docstring(signature="appended") A mesh layer parameter for processing algorithms. .. versionadded:: 3.6 @@ -2778,7 +2778,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterMapLayer : QgsProcessingParameterDefinition, QgsProcessingParameterLimitedDataTypes, QgsFileFilterGenerator { -%Docstring +%Docstring(signature="appended") A map layer parameter for processing algorithms. .. versionadded:: 3.0 @@ -2828,7 +2828,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterField : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A vector layer or feature source field parameter for processing algorithms. .. versionadded:: 3.0 @@ -2956,7 +2956,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterFeatureSource : QgsProcessingParameterDefinition, QgsProcessingParameterLimitedDataTypes, QgsFileFilterGenerator { -%Docstring +%Docstring(signature="appended") An input feature source (such as vector layers) parameter for processing algorithms. .. versionadded:: 3.0 @@ -3006,7 +3006,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingDestinationParameter : QgsProcessingParameterDefinition, QgsFileFilterGenerator { -%Docstring +%Docstring(signature="appended") Base class for all parameter definitions which represent file or layer destinations, e.g. parameters which are used for the destination for layers output by an algorithm. @@ -3123,7 +3123,7 @@ the model provider) class QgsProcessingParameterFeatureSink : QgsProcessingDestinationParameter { -%Docstring +%Docstring(signature="appended") A feature sink output for processing algorithms. A parameter which represents the destination feature sink for features created by an algorithm. @@ -3237,7 +3237,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterVectorDestination : QgsProcessingDestinationParameter { -%Docstring +%Docstring(signature="appended") A vector layer destination parameter, for specifying the destination path for a vector layer created by the algorithm. @@ -3329,7 +3329,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterRasterDestination : QgsProcessingDestinationParameter { -%Docstring +%Docstring(signature="appended") A raster layer destination parameter, for specifying the destination path for a raster layer created by the algorithm. @@ -3387,7 +3387,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterFileDestination : QgsProcessingDestinationParameter { -%Docstring +%Docstring(signature="appended") A generic file based destination parameter, for specifying the destination path for a file (non-map layer) created by the algorithm. @@ -3473,7 +3473,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterFolderDestination : QgsProcessingDestinationParameter { -%Docstring +%Docstring(signature="appended") A folder destination parameter, for specifying the destination path for a folder created by the algorithm or used for creating new files within the algorithm. @@ -3516,7 +3516,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterBand : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A raster band parameter for Processing algorithms. .. versionadded:: 3.0 @@ -3599,7 +3599,7 @@ Sets whether multiple band selections are permitted. class QgsProcessingParameterLayout : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A print layout parameter, allowing users to select a print layout. :py:class:`QgsProcessingParameterLayout` should be evaluated by calling :py:func:`QgsProcessingAlgorithm.parameterAsLayout()`. @@ -3643,7 +3643,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterLayoutItem : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A print layout item parameter, allowing users to select a particular item from a print layout. :py:class:`QgsProcessingParameterLayoutItem` should be evaluated by calling :py:func:`QgsProcessingAlgorithm.parameterAsLayoutItem()`. @@ -3727,7 +3727,7 @@ These values correspond to the registered item types from :py:class:`QgsLayoutIt class QgsProcessingParameterColor : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A color parameter for processing algorithms. :py:class:`QgsProcessingParameterColor` should be evaluated by calling :py:func:`QgsProcessingAlgorithm.parameterAsColor()`. @@ -3797,7 +3797,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterCoordinateOperation : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A coordinate operation parameter for processing algorithms, for selection between available coordinate operations to use when projecting between a source and destination coordinate reference system. @@ -3922,7 +3922,7 @@ Sets the static destination ``crs``. class QgsProcessingParameterMapTheme : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A map theme parameter for processing algorithms, allowing users to select an existing map theme from a project. :py:class:`QgsProcessingParameterMapTheme` should be evaluated by calling :py:func:`QgsProcessingAlgorithm.parameterAsString()`. @@ -3971,7 +3971,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterDateTime : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A datetime (or pure date or time) parameter for processing algorithms. :py:class:`QgsProcessingParameterDateTime` should be evaluated by calling :py:func:`QgsProcessingAlgorithm.parameterAsDateTime()`, @@ -4092,7 +4092,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterProviderConnection : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A data provider connection parameter for processing algorithms, allowing users to select from available registered connections for a particular data provider. @@ -4161,7 +4161,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterDatabaseSchema : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A database schema parameter for processing algorithms, allowing users to select from existing schemas on a registered database connection. @@ -4234,7 +4234,7 @@ Creates a new parameter using the definition from a script code. class QgsProcessingParameterDatabaseTable : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A database table name parameter for processing algorithms, allowing users to select from existing database tables on a registered database connection (or optionally to enter a new table name). diff --git a/python/core/auto_generated/processing/qgsprocessingparametertininputlayers.sip.in b/python/core/auto_generated/processing/qgsprocessingparametertininputlayers.sip.in index faf8702a182a..9fc11ebbc1dd 100644 --- a/python/core/auto_generated/processing/qgsprocessingparametertininputlayers.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingparametertininputlayers.sip.in @@ -10,7 +10,7 @@ class QgsProcessingParameterTinInputLayers: QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A parameter for processing algorithms that need a list of input vector layers to construct a TIN. A valid value for this parameter is a list (QVariantList), where each item is a map (QVariantMap) in this form: diff --git a/python/core/auto_generated/processing/qgsprocessingparametertype.sip.in b/python/core/auto_generated/processing/qgsprocessingparametertype.sip.in index 714de9e411b0..23e103c37a72 100644 --- a/python/core/auto_generated/processing/qgsprocessingparametertype.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingparametertype.sip.in @@ -12,7 +12,7 @@ class QgsProcessingParameterType { -%Docstring +%Docstring(signature="appended") Makes metadata of processing parameters available. .. versionadded:: 3.2 diff --git a/python/core/auto_generated/processing/qgsprocessingparametervectortilewriterlayers.sip.in b/python/core/auto_generated/processing/qgsprocessingparametervectortilewriterlayers.sip.in index fc2e71bca216..d4bdce22d615 100644 --- a/python/core/auto_generated/processing/qgsprocessingparametervectortilewriterlayers.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingparametervectortilewriterlayers.sip.in @@ -11,7 +11,7 @@ class QgsProcessingParameterVectorTileWriterLayers : QgsProcessingParameterDefinition { -%Docstring +%Docstring(signature="appended") A parameter for processing algorithms that need a list of input vector layers for writing of vector tiles - this parameter provides processing framework's adapter for QList<:py:class:`QgsVectorTileWriter`.Layer>. diff --git a/python/core/auto_generated/processing/qgsprocessingprovider.sip.in b/python/core/auto_generated/processing/qgsprocessingprovider.sip.in index 0d194dd04545..2a9751839944 100644 --- a/python/core/auto_generated/processing/qgsprocessingprovider.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingprovider.sip.in @@ -11,7 +11,7 @@ class QgsProcessingProvider : QObject { -%Docstring +%Docstring(signature="appended") Abstract base class for processing providers. An algorithm provider is a set of related algorithms, typically from the same external application or related diff --git a/python/core/auto_generated/processing/qgsprocessingregistry.sip.in b/python/core/auto_generated/processing/qgsprocessingregistry.sip.in index d3aac0b1b5d6..6502e828fa5c 100644 --- a/python/core/auto_generated/processing/qgsprocessingregistry.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingregistry.sip.in @@ -12,7 +12,7 @@ class QgsProcessingRegistry : QObject { -%Docstring +%Docstring(signature="appended") Registry for various processing components, including providers, algorithms and various parameters and outputs. diff --git a/python/core/auto_generated/processing/qgsprocessingutils.sip.in b/python/core/auto_generated/processing/qgsprocessingutils.sip.in index 68f83b57c755..8b180142ecf5 100644 --- a/python/core/auto_generated/processing/qgsprocessingutils.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingutils.sip.in @@ -14,7 +14,7 @@ class QgsProcessingUtils { -%Docstring +%Docstring(signature="appended") Utility functions for use with processing classes. .. versionadded:: 3.0 @@ -387,7 +387,7 @@ a fallback value of "tif". class QgsProcessingFeatureSource : QgsFeatureSource { -%Docstring +%Docstring(signature="appended") :py:class:`QgsFeatureSource` subclass which proxies methods to an underlying :py:class:`QgsFeatureSource`, modifying results according to the settings in a :py:class:`QgsProcessingContext`. diff --git a/python/core/auto_generated/project/qgsproject.sip.in b/python/core/auto_generated/project/qgsproject.sip.in index 9a3aa9562b58..92bca949f3ce 100644 --- a/python/core/auto_generated/project/qgsproject.sip.in +++ b/python/core/auto_generated/project/qgsproject.sip.in @@ -17,7 +17,7 @@ class QgsProject : QObject, QgsExpressionContextGenerator, QgsExpressionContextScopeGenerator, QgsProjectTranslator { -%Docstring +%Docstring(signature="appended") Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc. @@ -1891,7 +1891,7 @@ QFlags operator|(QgsProject::ReadFlag f1, QFlags QgsGradientStopsList; class QgsGradientColorRamp : QgsColorRamp { -%Docstring +%Docstring(signature="appended") Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra color stops. @@ -299,7 +299,7 @@ Copy color ramp stops to a QGradient class QgsLimitedRandomColorRamp : QgsColorRamp { -%Docstring +%Docstring(signature="appended") Constrained random color ramp, which returns random colors based on preset parameters. .. versionadded:: 3.0 @@ -466,7 +466,7 @@ Sets the maximum value for generated colors class QgsRandomColorRamp: QgsColorRamp { -%Docstring +%Docstring(signature="appended") Totally random color ramp. Returns colors generated at random, but constrained to some hardcoded saturation and value ranges to prevent ugly color generation. @@ -527,7 +527,7 @@ Returns the string identifier for QgsRandomColorRamp. class QgsPresetSchemeColorRamp : QgsColorRamp, QgsColorScheme { -%Docstring +%Docstring(signature="appended") A scheme based color ramp consisting of a list of predefined colors. .. versionadded:: 3.0 @@ -612,7 +612,7 @@ Returns the string identifier for QgsPresetSchemeColorRamp. class QgsColorBrewerColorRamp : QgsColorRamp { -%Docstring +%Docstring(signature="appended") Color ramp utilising "Color Brewer" preset color schemes. .. versionadded:: 3.0 diff --git a/python/core/auto_generated/qgscolorscheme.sip.in b/python/core/auto_generated/qgscolorscheme.sip.in index 915fbbe77184..3f1ec51f9591 100644 --- a/python/core/auto_generated/qgscolorscheme.sip.in +++ b/python/core/auto_generated/qgscolorscheme.sip.in @@ -14,7 +14,7 @@ typedef QList< QPair< QColor, QString > > QgsNamedColorList; class QgsColorScheme { -%Docstring +%Docstring(signature="appended") Abstract base class for color schemes A color scheme for display in :py:class:`QgsColorButton`. Color schemes return lists @@ -124,7 +124,7 @@ QFlags operator|(QgsColorScheme::SchemeFlag f1, QFla class QgsGplColorScheme : QgsColorScheme { -%Docstring +%Docstring(signature="appended") A color scheme which stores its colors in a gpl palette file. .. versionadded:: 2.5 @@ -159,7 +159,7 @@ Returns the file path for the associated gpl palette file class QgsUserColorScheme : QgsGplColorScheme { -%Docstring +%Docstring(signature="appended") A color scheme which stores its colors in a gpl palette file within the "palettes" subfolder off the user's QGIS settings folder. @@ -224,7 +224,7 @@ Sets whether a this scheme should be shown in color button menus. class QgsRecentColorScheme : QgsColorScheme { -%Docstring +%Docstring(signature="appended") A color scheme which contains the most recently used colors. .. versionadded:: 2.5 @@ -273,7 +273,7 @@ Returns the most recently used color. class QgsCustomColorScheme : QgsColorScheme { -%Docstring +%Docstring(signature="appended") A color scheme which contains custom colors set through QGIS app options dialog. .. versionadded:: 2.5 @@ -307,7 +307,7 @@ Constructor for QgsCustomColorScheme. class QgsProjectColorScheme : QgsColorScheme { -%Docstring +%Docstring(signature="appended") A color scheme which contains project specific colors set through project properties dialog. .. versionadded:: 2.5 diff --git a/python/core/auto_generated/qgscolorschemeregistry.sip.in b/python/core/auto_generated/qgscolorschemeregistry.sip.in index fb1f6cc29286..b1235e3b8100 100644 --- a/python/core/auto_generated/qgscolorschemeregistry.sip.in +++ b/python/core/auto_generated/qgscolorschemeregistry.sip.in @@ -11,7 +11,7 @@ class QgsColorSchemeRegistry { -%Docstring +%Docstring(signature="appended") Registry of color schemes A registry of :py:class:`QgsColorScheme` color schemes. This class can be created directly, or diff --git a/python/core/auto_generated/qgsconditionalstyle.sip.in b/python/core/auto_generated/qgsconditionalstyle.sip.in index 652538429218..ac74afc401d9 100644 --- a/python/core/auto_generated/qgsconditionalstyle.sip.in +++ b/python/core/auto_generated/qgsconditionalstyle.sip.in @@ -14,7 +14,7 @@ typedef QList QgsConditionalStyles; class QgsConditionalLayerStyles : QObject { -%Docstring +%Docstring(signature="appended") The :py:class:`QgsConditionalLayerStyles` class holds conditional style information for a layer. This includes field styles and full row styles. %End @@ -87,7 +87,7 @@ Emitted when the conditional styles are changed. class QgsConditionalStyle { -%Docstring +%Docstring(signature="appended") Conditional styling for a rule. %End diff --git a/python/core/auto_generated/qgsconnectionregistry.sip.in b/python/core/auto_generated/qgsconnectionregistry.sip.in index 0a63f927517f..f72236a2e218 100644 --- a/python/core/auto_generated/qgsconnectionregistry.sip.in +++ b/python/core/auto_generated/qgsconnectionregistry.sip.in @@ -13,7 +13,7 @@ class QgsConnectionRegistry : QObject { -%Docstring +%Docstring(signature="appended") A registry for saved data provider connections, allowing retrieval of saved connections by name and provider type. diff --git a/python/core/auto_generated/qgscoordinateformatter.sip.in b/python/core/auto_generated/qgscoordinateformatter.sip.in index 3fa5b6b3efd7..076bb06c5c88 100644 --- a/python/core/auto_generated/qgscoordinateformatter.sip.in +++ b/python/core/auto_generated/qgscoordinateformatter.sip.in @@ -12,7 +12,7 @@ class QgsCoordinateFormatter { -%Docstring +%Docstring(signature="appended") Contains methods for converting coordinates for display in various formats. :py:class:`QgsCoordinateFormatter` contains static methods for converting numeric coordinates into different diff --git a/python/core/auto_generated/qgscoordinatereferencesystem.sip.in b/python/core/auto_generated/qgscoordinatereferencesystem.sip.in index 7ab5a17388f1..e1761e280aeb 100644 --- a/python/core/auto_generated/qgscoordinatereferencesystem.sip.in +++ b/python/core/auto_generated/qgscoordinatereferencesystem.sip.in @@ -18,7 +18,7 @@ class QgsCoordinateReferenceSystem { -%Docstring +%Docstring(signature="appended") This class represents a coordinate reference system (CRS). Coordinate reference system object defines a specific map projection, as well as transformations diff --git a/python/core/auto_generated/qgscoordinatereferencesystemregistry.sip.in b/python/core/auto_generated/qgscoordinatereferencesystemregistry.sip.in index 2f7db956a789..104769ac497e 100644 --- a/python/core/auto_generated/qgscoordinatereferencesystemregistry.sip.in +++ b/python/core/auto_generated/qgscoordinatereferencesystemregistry.sip.in @@ -11,7 +11,7 @@ class QgsCoordinateReferenceSystemRegistry : QObject { -%Docstring +%Docstring(signature="appended") A registry for known coordinate reference system (CRS) definitions, including any user-defined CRSes. @@ -33,7 +33,7 @@ Constructor for QgsCoordinateReferenceSystemRegistry, with the specified ``paren class UserCrsDetails { -%Docstring +%Docstring(signature="appended") Contains details of a custom (user defined) CRS. .. versionadded:: 3.18 diff --git a/python/core/auto_generated/qgscoordinatetransform.sip.in b/python/core/auto_generated/qgscoordinatetransform.sip.in index 1841b7526a17..4359b2951829 100644 --- a/python/core/auto_generated/qgscoordinatetransform.sip.in +++ b/python/core/auto_generated/qgscoordinatetransform.sip.in @@ -12,7 +12,7 @@ class QgsCoordinateTransform { -%Docstring +%Docstring(signature="appended") Class for doing transforms between two map coordinate systems. This class can convert map coordinates to a different coordinate reference system. diff --git a/python/core/auto_generated/qgscoordinatetransformcontext.sip.in b/python/core/auto_generated/qgscoordinatetransformcontext.sip.in index 3c52f642d631..e6add5c704e2 100644 --- a/python/core/auto_generated/qgscoordinatetransformcontext.sip.in +++ b/python/core/auto_generated/qgscoordinatetransformcontext.sip.in @@ -14,7 +14,7 @@ class QgsCoordinateTransformContext { -%Docstring +%Docstring(signature="appended") Contains information about the context in which a coordinate transform is executed. The context stores various information regarding which coordinate operations should diff --git a/python/core/auto_generated/qgscredentials.sip.in b/python/core/auto_generated/qgscredentials.sip.in index 3a1c703d9951..7bf746d0b6df 100644 --- a/python/core/auto_generated/qgscredentials.sip.in +++ b/python/core/auto_generated/qgscredentials.sip.in @@ -12,7 +12,7 @@ class QgsCredentials { -%Docstring +%Docstring(signature="appended") Interface for requesting credentials in QGIS in GUI independent way. This class provides abstraction of a dialog for requesting credentials to the user. @@ -124,7 +124,7 @@ register instance class QgsCredentialsNone : QObject, QgsCredentials { -%Docstring +%Docstring(signature="appended") Default implementation of credentials interface This class doesn't prompt or return credentials @@ -152,7 +152,7 @@ signals that object will be destroyed and shouldn't be used anymore class QgsCredentialsConsole : QObject, QgsCredentials { -%Docstring +%Docstring(signature="appended") Implementation of credentials interface for the console This class outputs message to the standard output and retrieves input from diff --git a/python/core/auto_generated/qgsdatabaseschemamodel.sip.in b/python/core/auto_generated/qgsdatabaseschemamodel.sip.in index 1941dae2ff9b..817a503dc0fe 100644 --- a/python/core/auto_generated/qgsdatabaseschemamodel.sip.in +++ b/python/core/auto_generated/qgsdatabaseschemamodel.sip.in @@ -12,7 +12,7 @@ class QgsDatabaseSchemaModel : QAbstractItemModel { -%Docstring +%Docstring(signature="appended") A model containing schemas from a database connection. This class does not automatically subscribe to database updates. Schemas are queried diff --git a/python/core/auto_generated/qgsdatabasetablemodel.sip.in b/python/core/auto_generated/qgsdatabasetablemodel.sip.in index 53fcba5e799b..4bd05e14855f 100644 --- a/python/core/auto_generated/qgsdatabasetablemodel.sip.in +++ b/python/core/auto_generated/qgsdatabasetablemodel.sip.in @@ -11,7 +11,7 @@ class QgsDatabaseTableModel : QAbstractItemModel { -%Docstring +%Docstring(signature="appended") A model containing tables from a database connection. This class does not automatically subscribe to database updates. Tables are queried diff --git a/python/core/auto_generated/qgsdatadefinedsizelegend.sip.in b/python/core/auto_generated/qgsdatadefinedsizelegend.sip.in index 6d01ad4d014c..4773c072fe27 100644 --- a/python/core/auto_generated/qgsdatadefinedsizelegend.sip.in +++ b/python/core/auto_generated/qgsdatadefinedsizelegend.sip.in @@ -13,7 +13,7 @@ class QgsDataDefinedSizeLegend { -%Docstring +%Docstring(signature="appended") Object that keeps configuration of appearance of marker symbol's data-defined size in legend. For example: the list of classes (size values), whether the classes should appear in separate diff --git a/python/core/auto_generated/qgsdataitem.sip.in b/python/core/auto_generated/qgsdataitem.sip.in index 25bf39f0a430..396f595e4a19 100644 --- a/python/core/auto_generated/qgsdataitem.sip.in +++ b/python/core/auto_generated/qgsdataitem.sip.in @@ -13,7 +13,7 @@ class QgsDataItem : QObject { -%Docstring +%Docstring(signature="appended") Base class for all items in the model. Parent/children hierarchy is not based on QObject. @@ -517,7 +517,7 @@ QFlags operator|(QgsDataItem::Capability f1, QFlags

    Change history for the QGIS Project

    +

    What’s new in Version 3.18 ‘Zürich’?

    +

    This release has following new features:

    +
      +
    • General: QGIS 3.18 highlights (changelog)
    • +
    • User Interface: Hide derived attributes from the Identify results
    • +
    • User Interface: Close all tabs at once from message logs interface
    • +
    • User Interface: API for layer source widgets
    • +
    • User Interface: GUI for dynamic SVGs
    • +
    • User Interface: Zoom and pan to selection for multiple layers
    • +
    • User Interface: Zoom in/out by scrolling mouse wheel over map overview panel
    • +
    • Accessibility: Improved color vision deficiency simulation
    • +
    • Accessibility: Rotation widget for the Georeferencer
    • +
    • Symbology: Data defined overall symbol opacity
    • +
    • Symbology: Open the style gallery from the style manager
    • +
    • Mesh: New mesh export algorithms
    • +
    • Mesh: Native export for mesh layers
    • +
    • Mesh: Mesh simplification for 3D
    • +
    • Mesh: Multiple native mesh processing algorithms
    • +
    • Rendering: “Merged feature” renderer for polygon and line layers
    • +
    • Rendering: Smarter Map Redraws
    • +
    • 3D Features: Eye dome lighting
    • +
    • 3D Features: Data defined 3D material colors
    • +
    • 3D Features: 3D Orthographic projection support
    • +
    • Point Clouds: Point Cloud Support
    • +
    • Point Clouds: Add point clouds to browser
    • +
    • Point Clouds: Untwine PDAL Provider Integration
    • +
    • Print Layouts: Gradient ramp based legends
    • +
    • Print Layouts: Color ramp legend improvements
    • +
    • Print Layouts: Dynamic text presets
    • +
    • Expressions: Optional formatting of UUID results
    • +
    • Expressions: Layer CRS variable for expressions
    • +
    • Expressions: Support for min, max, majority, sum, mean, and median functions on numerical arrays
    • +
    • Expressions: Negative index for array_get function
    • +
    • Expressions: Add map_credits function
    • +
    • Digitising: Select features context menu
    • +
    • Digitising: Curve tracing settings added to UI
    • +
    • Digitising: Feature scaling tool
    • +
    • Data Management: New export to spreadsheet algorithm
    • +
    • Data Management: Reproject coordinates in the Georeferencer
    • +
    • Data Management: Polymorphic relations/ Document management system
    • +
    • Forms and Widgets: Soft and hard constraints in forms
    • +
    • Analysis Tools: Nominatim geocoder API
    • +
    • Processing: Allow expression for order fields in PointsToPath algorithm
    • +
    • Processing: Override CRS for Clip Raster by extent output
    • +
    • Processing: Add “retain fields” algorithm
    • +
    • Processing: Reference common field parameter for multiple layers
    • +
    • Processing: Extend import geotagged photos to include exif_orientation
    • +
    • Processing: Export layer information algorithm
    • +
    • Processing: Cell stack percentile and percentrank algorithms
    • +
    • Processing: Points to lines processing algorithm
    • +
    • Application and Project Options: Hidden layers
    • +
    • Application and Project Options: Custom “Full Extent” definition
    • +
    • Application and Project Options: Toggle network caching to QgsNetworkAccessManager
    • +
    • Browser: Unify ArcGis Feature Service and ArcGIS Map Service connections in browser
    • +
    • Browser: Allow browsing ArcGIS REST by content groups
    • +
    • Data Providers: Native DXF export algorithm
    • +
    • Data Providers: Additional geometry types for PostGIS Export
    • +
    • Data Providers: Improved network requests with GDAL
    • +
    • Data Providers: Read only generated fields
    • +
    • Data Providers: Improve MSSQL loading with predefined parameters
    • +
    • Data Providers: Filter schemas for MS SQL
    • +
    • Data Providers: SAP HANA database support
    • +
    • Data Providers: Deprecate support for DB2
    • +
    • Data Providers: Oracle connection API
    • +
    • Data Providers: Add advanced options for raster data imports
    • +
    • QGIS Server: GetLegendGraphics Symbol Scale
    • +
    • QGIS Server: Drag and drop for WMS GetFeatureInfo response
    • +
    • Programmability: Run multiple items from command history dialog
    • +
    • Programmability: Enable or disable plugins from the command line
    • +
    • Notable Fixes: Bug fixes by Alessandro Pasotti
    • +
    • Notable Fixes: Bug fixes by Peter Petrik
    • +
    • Notable Fixes: Bug fixes by Even Rouault
    • +
    • Notable Fixes: Bug fixes by Julien Cabieces
    • +
    • Notable Fixes: Bug fixes by Nyall Dawson
    • +
    • +
    +

    What’s new in Version 3.16 ‘Hannover’?

    +

    This release has following new features:

    +
      +
    • General: Add user groups easter egg
    • +
    • General: QGIS 3.16 Highlights (changelog)
    • +
    • Temporal: Ability to export temporal animation frames
    • +
    • Map Tools: Go-To locator
    • +
    • User Interface: Add context menu to map canvas
    • +
    • Symbology: Vector tile styling improvements
    • +
    • Symbology: Allow users to optionally specify the URL for the default style on vector tile connections
    • +
    • Symbology: Allow data-defined offset for fill symbol layers
    • +
    • Symbology: Import MapBox GL JSON styles for vector tile layers
    • +
    • Symbology: Expose option to offset simple line dash patterns by a preset amount
    • +
    • Symbology: Add options to dynamically tweak dash pattern in simple line symbol layers
    • +
    • Symbology: Manage 3D symbols through style manager
    • +
    • Labelling: Add option to allow users to control the placement of labels along line features
    • +
    • Labelling: Control anchor point for line labels
    • +
    • Diagrams: Render axis for stacked bar diagram
    • +
    • Mesh: In-memory mesh datasets with persistence
    • +
    • Mesh: Multi identify for mesh layer
    • +
    • Mesh: Virtual dataset groups for mesh layer
    • +
    • Mesh: Add export to QgsMesh method
    • +
    • Mesh: TIN Mesh creation
    • +
    • Rendering: Gamma correction filter for raster layers
    • +
    • 3D Features: Allow 3D material texture files to be embedded in style/project
    • +
    • 3D Features: Shadow rendering
    • +
    • 3D Features: Export 3D scenes
    • +
    • 3D Features: Directional lighting support for QGIS 3D
    • +
    • 3D Features: Texturing support for vector layer
    • +
    • 3D Features: Enable embedded and remote 3D models for 3D point symbols
    • +
    • 3D Features: Add option to show light source origins
    • +
    • 3D Features: Improvements for material handling
    • +
    • Print Layouts: Expose control over text format and alignment for individual cells in manual text tables
    • +
    • Print Layouts: Use QgsTextRenderer to render attribute table text
    • +
    • Print Layouts: Use QgsTextRenderer for drawing map grid text in layouts
    • +
    • Print Layouts: Expose option to control PDF image compression method when exporting layouts to PDF
    • +
    • Print Layouts: Add automatic clipping settings for atlas maps
    • +
    • Print Layouts: Add API to QgsMapSettings for specifying clipping regions to apply while rendering maps
    • +
    • Print Layouts: Layout legend maximum marker size
    • +
    • Print Layouts: Allow cells in manual text tables to have expression based contents
    • +
    • Print Layouts: Clip layout maps to shape
    • +
    • Print Layouts: Support for rotated ticks/annotation
    • +
    • Print Layouts: Add page offset expression for Y positions
    • +
    • Expressions: Add to_decimal() function to convert DMS to DD
    • +
    • Expressions: Add “main_angle” function to return the estimated main angle of a geometry
    • +
    • Expressions: Port refFunctions to core
    • +
    • Digitising: Add option to calculate bearing based on travel direction
    • +
    • Digitising: Digitizing and splitting curved features
    • +
    • Data Management: Rescale raster algorithm for Processing
    • +
    • Forms and Widgets: Multiple widgets for a single relation
    • +
    • Forms and Widgets: Show related features in identify results tree
    • +
    • Forms and Widgets: Filter expressions in relation reference widget
    • +
    • Analysis Tools: Add project load profile times to debugging tools dock
    • +
    • Analysis Tools: New Cell statistics algorithm
    • +
    • Analysis Tools: New Equal to frequency algorithm
    • +
    • Analysis Tools: New Greater than frequency algorithm
    • +
    • Analysis Tools: New Less than frequency algorithm
    • +
    • Analysis Tools: New Lowest position in raster stack algorithm
    • +
    • Analysis Tools: New Highest position in raster stack algorithm
    • +
    • Analysis Tools: New “Highest/Lowest position in raster stack” algorithms
    • +
    • Processing: Add help string for parameters
    • +
    • Processing: New “Align points to features” algorithm
    • +
    • Processing: Add modeler algorithm to create directories
    • +
    • Processing: Add modeler algorithm to set a project expression variable
    • +
    • Processing: Add processing algorithms to export a print layout as PDF/image
    • +
    • Processing: Add a save features to file algorithm
    • +
    • Processing: Export layout atlas as PDF algorithm
    • +
    • Processing: New “Flatten Relationship” algorithm
    • +
    • Processing: Export atlas layout as image algorithm
    • +
    • Processing: Load processing results to layer group
    • +
    • Processing: Add zonal statistics algorithm which creates new output
    • +
    • Processing: Add geometry processing parameter
    • +
    • Processing: Add an interface to determine whether it is safe for the application to exit
    • +
    • Application and Project Options: List available GDAL vector drivers
    • +
    • Application and Project Options: Detect GRASS installation folder on MacOS
    • +
    • Browser: Expose fields in the Browser
    • +
    • Data Providers: ArcGIS Vector Tile Service connections
    • +
    • Data Providers: Trust layer metadata propagation
    • +
    • Data Providers: Add support for virtual columns in Oracle
    • +
    • Data Providers: Add advanced options for data imports
    • +
    • QGIS Server: QGIS Server WFS3 API Sorting
    • +
    • QGIS Server: QGIS Server landing page
    • +
    • QGIS Server: Environment variable to disable GetPrint and to not load layouts
    • +
    • QGIS Server: Environment variable to trust layer metadata with server settings
    • +
    • Notable Fixes: Bug fixes by Even Rouault
    • +
    • Notable Fixes: Bug fixes by Alessandro Pasotti
    • +
    • Notable Fixes: Bug fixes by Peter Petrik
    • +
    • Notable Fixes: Bug fixes by Paul Blottiere
    • +
    • Notable Fixes: Bug fixes by Matthias Kuhn
    • +
    • Notable Fixes: Bug fixes by Julien Cabieces
    • +
    • Notable Fixes: Bug fixes by Denis Rouzaud
    • +
    • Notable Fixes: Bug fixes by Olivier Dalang
    • +
    • Notable Fixes: Bug fixes by Nyall Dawson
    • +
    • +
    +

    What’s new in Version 3.14 ‘Pi’?

    +

    This release has following new features:

    +
      +
    • General: New grid decoration annotations font settings
    • +
    • General: QGIS 3.14 Highlights (changelog)
    • +
    • Temporal: Cumulative temporal range setting in temporal controller
    • +
    • Temporal: Add a new “Redraw Layer Only” mode for temporal vector layers
    • +
    • Temporal: Add basic temporal handling support for vector layers
    • +
    • Temporal: Postgres raster temporal API support
    • +
    • Temporal: QGIS Project temporal settings
    • +
    • Temporal: WMS-T layers temporal constraints support
    • +
    • Temporal: Temporal API
    • +
    • Map Tools: Identify Tool Support for QGIS vector tile layers.
    • +
    • Map Tools: Show a menu next to scale widget buttons, to allow setting the widget directly to a scale from a print layout map
    • +
    • Map Tools: Add tool button to “Deselect Features from the Current Active layer”
    • +
    • User Interface: Allow the drag and drop of a layer across several QGIS instances
    • +
    • User Interface: Open attribute tables as tabs
    • +
    • Symbology: Raster Layer Contour Renderer
    • +
    • Symbology: Add percentage size unit for Raster Image Marker and Raster fill layers symbology.
    • +
    • Symbology: Add data-defined property to font family/style for font markers
    • +
    • Symbology: New font style setting for font markers
    • +
    • Labelling: Respect HTML colors in labels
    • +
    • Labelling: Automatic placement of labels outside polygons
    • +
    • Labelling: Vector tile layer - part 4 (labeling)
    • +
    • Labelling: Add control over anchor point for callout on label
    • +
    • Mesh: Use only specified dataset group
    • +
    • Mesh: Scalar color settings depending on classification
    • +
    • Mesh: Snap on mesh elements
    • +
    • Mesh: 1D mesh width/color varying
    • +
    • Mesh: Support for multiple mesh (since MDAL 0.5.91)
    • +
    • Mesh: Plug mesh layer to QGIS temporal framework
    • +
    • Mesh: Resampling from vertex values to face values
    • +
    • Mesh: Coloring mesh vector dataset with color ramp shader
    • +
    • Mesh: Save style for mesh layer
    • +
    • Mesh: Mesh 1D Renderer
    • +
    • Mesh: Mesh simplification
    • +
    • 3D Features: Arrows for 3D mesh layer dataset rendering
    • +
    • Print Layouts: Temporal settings for layout map items
    • +
    • Print Layouts: Allow sorting attribute table by field not listed in the table
    • +
    • Print Layouts: Expose control over layer legend splitting behavior on a layer-by-layer basis
    • +
    • Print Layouts: Allow customisation of division and subdivision symbols as distinct from scalebar tick horizontal symbol
    • +
    • Print Layouts: Allow overriding the default symbol for a legend node
    • +
    • Print Layouts: Allow placing manual column breaks in legends
    • +
    • Print Layouts: Add subdivisions in ticks scalebar right segments
    • +
    • Print Layouts: Allow overriding the legend patch size on a per-item basis
    • +
    • Print Layouts: Allow control over the horizontal spacing before legend group/subgroup/symbols
    • +
    • Print Layouts: Manage legend patch shapes through style manager
    • +
    • Print Layouts: Allow configuring legend patch shapes by double-clicking on legend items
    • +
    • Print Layouts: Support pasting pictures directly into layouts
    • +
    • Print Layouts: Allow marker items to sync rotation with maps
    • +
    • Print Layouts: New item type for marker symbols
    • +
    • Print Layouts: Add import content from clipboard for fixed table items
    • +
    • Print Layouts: Add numeric formatter “fraction” style
    • +
    • Print Layouts: Add “stepped line” and “hollow” scalebar styles
    • +
    • Print Layouts: Allow scalebar line style to be set using standard QGIS line symbols
    • +
    • Print Layouts: Rework picture item UI and behavior
    • +
    • Print Layouts: Make CRS controlable by a variable
    • +
    • Expressions: New expressions
    • +
    • Expressions: Feature browser for preview in expression builder
    • +
    • Expressions: Ability to remove custom functions
    • +
    • Expressions: Add ability to edit, import and export user expressions
    • +
    • Digitising: Dedicated avoid geometry intersection/overlap mode
    • +
    • Digitising: New snapping modes: Centroid and middle of a segment (midpoint)
    • +
    • Digitising: Snapping to the currently digitized feature
    • +
    • Digitising: Tracing now supports curved geometries
    • +
    • Forms and Widgets: Allow editing of links in file widget
    • +
    • Forms and Widgets: Expression controlled labels (aliases)
    • +
    • Forms and Widgets: Add description to value relation widget
    • +
    • Forms and Widgets: New database table name widget
    • +
    • Forms and Widgets: Get current parent form values in child forms
    • +
    • Forms and Widgets: Relation widget: add checkbox to hide save child edits button
    • +
    • Forms and Widgets: Relation widget force suppress popup
    • +
    • Layer Legend: Added move to bottom in layertreeview context menu
    • +
    • Layer Legend: Make Add Group button act as Group Selected if selected layers >= 2
    • +
    • Layer Legend: Allow renaming of the current map theme
    • +
    • Layer Legend: Turn on/off ALL selected layers with “Space” button
    • +
    • Analysis Tools: Network logger - more functionality
    • +
    • Analysis Tools: Inbuilt network logging tool
    • +
    • Processing: Collection of random raster generation algorithms
    • +
    • Processing: Vector tile layer - part 8 (writer in Processing)
    • +
    • Processing: New modeler algorithm for creating conditional branches
    • +
    • Processing: Allow reordering model inputs
    • +
    • Processing: Defer model validation
    • +
    • Processing: Added support for different raster data types in Create constant raster layer algorithm
    • +
    • Processing: Added Round raster algorithm
    • +
    • Processing: Allow copying/cut/paste of model components
    • +
    • Processing: Allow appending processing results to existing layers
    • +
    • Processing: Allow creation of group boxes in models
    • +
    • Processing: Processing: show input and output values for children after running model through designer
    • +
    • Processing: Add “Save Log to File” algorithm for models
    • +
    • Processing: Allow running algorithms directly on database (and other non-disk) sources without loading into projects first
    • +
    • Processing: Expose per-feature-source advanced options for processing inputs
    • +
    • Processing: Enable snapping to grid for models in designer
    • +
    • Processing: Add “filter by geometry type” and “filter by layer type” algorithms to processing
    • +
    • Processing: “Remove Null Geometries” algorithm can also remove EMPTY geometries
    • +
    • Processing: Add multi-selection handling to model designer, interactive resizing
    • +
    • Processing: Add undo/redo support to model designer
    • +
    • Processing: Remember parameter values between model designer runs
    • +
    • Processing: Comments in Processing Models
    • +
    • Processing: New standalone console tool for running processing algorithms
    • +
    • Processing: New parameter type for datetime (or date, or time) values
    • +
    • Processing: Add algorithms for raising warnings and exceptions from models
    • +
    • Processing: Add Fill NoData cells algorithm
    • +
    • Processing: Various fixes for Processing
    • +
    • Processing: Show “template layer” field constraints in the “Refactor Fields” algorithm interface
    • +
    • Processing: New convert to curves algorithm
    • +
    • Application and Project Options: Add @layers, @layer_ids project scope variables
    • +
    • Data Providers: Allow adding attributes in the New Scratch Layer dialog
    • +
    • Data Providers: Allow creating geometryless DBF tables from the New Shapefile dialog
    • +
    • Data Providers: Allow filtering WM(T)S list in source dialog
    • +
    • Data Providers: Add vector tiles to Datasource manager dialog and Layers menu
    • +
    • Data Providers: Import/export for ArcGIS Map and FeatureServer connections
    • +
    • Data Providers: Add XYZ tiles to Datasource manager dialog and Layers menu
    • +
    • Data Providers: Spatialite transaction group
    • +
    • Data Providers: Allowing saving outputs direct to more database formats (and other nice stuff)
    • +
    • Data Providers: Add dedicated parameter type for database connections
    • +
    • Data Providers: PG: expose foreign tables
    • +
    • Data Providers: PG raster expose set filter to app
    • +
    • Data Providers: Postgres: save features into tables with generated fields
    • +
    • Data Providers: Date and DateTime field types support added to Spatialite and Delimited Text providers
    • +
    • QGIS Server: Add QGIS_SERVER_IGNORE_BAD_LAYERS config option
    • +
    • QGIS Server: Server project settings, add ‘expanded’ attribute
    • +
    • QGIS Server: Add DXF server export params NO_MTEXT and FORCE_2D
    • +
    • QGIS Server: WMS project validator
    • +
    • QGIS Server: Webp
    • +
    • Plugins: Allow plugins to register custom “Project Open” handlers
    • +
    • Plugins: Allow users to install stable or experimental plugins
    • +
    • Programmability: Support for adding dock widgets as tabs: addTabifyDockWidget()
    • +
    • Programmability: Port output parameter wrappers to new API
    • +
    • Programmability: Port last remaining input parameters to new API
    • +
    • Programmability: Port Feature Source, Raster, Vector and Mesh Layer parameters to new API
    • +
    • Programmability: Vector tile layer - part 1
    • +
    • Programmability: Port processing extent parameter to new api, many other improvements
    • +
    • Programmability: Interface and API for unified development/debugging tools
    • +
    • Programmability: Data type support for QgsProcessingParameterMapLayer
    • +
    • Programmability: Add processing parameter types for database schema and table name
    • +
    • Notable Fixes: Bug fixes by Alessandro Pasotti
    • +
    • Notable Fixes: Bug fixes by Loïc Bartoletti
    • +
    • Notable Fixes: Bug fixes by Even Rouault
    • +
    • Notable Fixes: Bug fixes by Paul Blottiere
    • +
    • Notable Fixes: Bug fixes by Julien Cabieces
    • +
    • Notable Fixes: Bug fixes by Bertrand Rix
    • +
    • Notable Fixes: Bug fixes by Sebastien Peillet
    • +
    • Notable Fixes: Bug fixes by Alexander Bruy
    • +
    • Notable Fixes: Bug fixes by Nyall Dawson
    • +
    • Notable Fixes: Bug fixes by Denis Rouzaud
    • +
    • +

    What’s new in Version 3.12 ‘București’?

    This release has following new features: