From d83b60638827606af4975418eef1fcbfc55dcfa7 Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Fri, 27 Oct 2023 18:49:07 +0700 Subject: [PATCH 1/2] Patch QGIS to include exif orientation tag handling fix --- .../qgis-qt6/exif_orientation_fix.patch | 59 +++++++++++++++++++ vcpkg/overlay/qgis-qt6/portfile.cmake | 1 + 2 files changed, 60 insertions(+) create mode 100644 vcpkg/overlay/qgis-qt6/exif_orientation_fix.patch diff --git a/vcpkg/overlay/qgis-qt6/exif_orientation_fix.patch b/vcpkg/overlay/qgis-qt6/exif_orientation_fix.patch new file mode 100644 index 0000000000..3a85d3d939 --- /dev/null +++ b/vcpkg/overlay/qgis-qt6/exif_orientation_fix.patch @@ -0,0 +1,59 @@ +diff --git a/src/core/raster/qgsexiftools.cpp b/src/core/raster/qgsexiftools.cpp +index f883d7960c6..51a200d37e5 100644 +--- a/src/core/raster/qgsexiftools.cpp ++++ b/src/core/raster/qgsexiftools.cpp +@@ -472,6 +472,7 @@ bool QgsExifTools::tagImage( const QString &imagePath, const QString &tag, const + return false; + + QVariant actualValue; ++ bool actualValueIsUShort = false; + if ( tag == QLatin1String( "Exif.GPSInfo.GPSLatitude" ) || + tag == QLatin1String( "Exif.GPSInfo.GPSLongitude" ) || + tag == QLatin1String( "Exif.GPSInfo.GPSDestLatitude" ) || +@@ -483,6 +484,11 @@ bool QgsExifTools::tagImage( const QString &imagePath, const QString &tag, const + { + actualValue = QStringLiteral( "%1/1000" ).arg( static_cast< int>( std::floor( std::abs( value.toDouble() ) * 1000 ) ) ); + } ++ else if ( tag == QLatin1String( "Exif.Image.Orientation" ) ) ++ { ++ actualValueIsUShort = true; ++ actualValue = value; ++ } + else if ( value.type() == QVariant::DateTime ) + { + const QDateTime dateTime = value.toDateTime(); +@@ -529,8 +535,21 @@ bool QgsExifTools::tagImage( const QString &imagePath, const QString &tag, const + + const bool isXmp = tag.startsWith( QLatin1String( "Xmp." ) ); + image->readMetadata(); +- if ( actualValue.type() == QVariant::Int || +- actualValue.type() == QVariant::LongLong ) ++ if ( actualValueIsUShort ) ++ { ++ if ( isXmp ) ++ { ++ Exiv2::XmpData &xmpData = image->xmpData(); ++ xmpData[tag.toStdString()] = static_cast( actualValue.toLongLong() ); ++ } ++ else ++ { ++ Exiv2::ExifData &exifData = image->exifData(); ++ exifData[tag.toStdString()] = static_cast( actualValue.toLongLong() ); ++ } ++ } ++ else if ( actualValue.type() == QVariant::Int || ++ actualValue.type() == QVariant::LongLong ) + { + if ( isXmp ) + { +@@ -543,8 +562,8 @@ bool QgsExifTools::tagImage( const QString &imagePath, const QString &tag, const + exifData[tag.toStdString()] = static_cast( actualValue.toLongLong() ); + } + } +- if ( actualValue.type() == QVariant::UInt || +- actualValue.type() == QVariant::ULongLong ) ++ else if ( actualValue.type() == QVariant::UInt || ++ actualValue.type() == QVariant::ULongLong ) + { + if ( isXmp ) + { diff --git a/vcpkg/overlay/qgis-qt6/portfile.cmake b/vcpkg/overlay/qgis-qt6/portfile.cmake index 7991b5ff95..650f9dac6a 100644 --- a/vcpkg/overlay/qgis-qt6/portfile.cmake +++ b/vcpkg/overlay/qgis-qt6/portfile.cmake @@ -24,6 +24,7 @@ vcpkg_from_github( snapping_properties.patch # Remove when updating to QGIS 3.34 exiv2-0.28.patch # Remove when updating to QGIS 3.34 profiler.patch # Remove when updating to QGIS 3.34 + exif_orientation_fix.patch # Remove when updating to QGIS 3.34.1 ) file(REMOVE ${SOURCE_PATH}/cmake/FindQtKeychain.cmake) From 195cd778b2a55bc79c18a48c6d829e8bee027187 Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Fri, 27 Oct 2023 19:06:08 +0700 Subject: [PATCH 2/2] Fix compilation against QGIS 3.34 --- src/core/distancearea.cpp | 4 ++-- .../activelayerfeatureslocatorfilter.cpp | 21 +++++++++++++++++++ src/core/locator/bookmarklocatorfilter.cpp | 8 +++++++ .../expressioncalculatorlocatorfilter.cpp | 8 +++++++ src/core/locator/featureslocatorfilter.cpp | 8 +++++++ src/core/locator/gotolocatorfilter.cpp | 12 +++++++++++ src/core/qfieldcloudprojectsmodel.cpp | 2 +- 7 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/core/distancearea.cpp b/src/core/distancearea.cpp index c0e468d139..6e3174f2b6 100644 --- a/src/core/distancearea.cpp +++ b/src/core/distancearea.cpp @@ -156,7 +156,7 @@ bool DistanceArea::lengthValid() const return false; case Qgis::GeometryType::Line: - FALLTHROUGH + [[fallthrough]]; case Qgis::GeometryType::Polygon: return mRubberbandModel->vertexCount() >= 2; @@ -184,7 +184,7 @@ bool DistanceArea::perimeterValid() const switch ( mRubberbandModel->geometryType() ) { case Qgis::GeometryType::Point: - FALLTHROUGH + [[fallthrough]]; case Qgis::GeometryType::Line: return false; diff --git a/src/core/locator/activelayerfeatureslocatorfilter.cpp b/src/core/locator/activelayerfeatureslocatorfilter.cpp index 8feb41ca37..be6bcb2728 100644 --- a/src/core/locator/activelayerfeatureslocatorfilter.cpp +++ b/src/core/locator/activelayerfeatureslocatorfilter.cpp @@ -198,8 +198,13 @@ void ActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, cons result.displayString = QStringLiteral( "@%1" ).arg( field ); result.group = mLayerName; result.description = tr( "Limit the search to the field '%1'" ).arg( field ); +#if _QGIS_VERSION_INT >= 33300 + result.setUserData( QVariantMap( { { QStringLiteral( "type" ), QVariant::fromValue( ResultType::FieldRestriction ) }, + { QStringLiteral( "search_text" ), QStringLiteral( "%1 @%2 " ).arg( prefix(), field ) } } ) ); +#else result.userData = QVariantMap( { { QStringLiteral( "type" ), QVariant::fromValue( ResultType::FieldRestriction ) }, { QStringLiteral( "search_text" ), QStringLiteral( "%1 @%2 " ).arg( prefix(), field ) } } ); +#endif result.score = 1; emit resultFetched( result ); } @@ -220,7 +225,11 @@ void ActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, cons result.displayString = mDispExpression.evaluate( &mContext ).toString(); result.group = mLayerName; +#if _QGIS_VERSION_INT >= 33300 + result.setUserData( QVariantList() << f.id() << mLayerId ); +#else result.userData = QVariantList() << f.id() << mLayerId; +#endif result.score = static_cast( searchString.length() ) / result.displayString.size(); result.actions << QgsLocatorResult::ResultAction( OpenForm, tr( "Open form" ), QStringLiteral( "ic_baseline-list_alt-24px" ) ); if ( mLayerIsSpatial ) @@ -274,7 +283,11 @@ void ActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, cons continue; //not sure how this result slipped through... result.group = mLayerName; result.description = mDispExpression.evaluate( &mContext ).toString(); +#if _QGIS_VERSION_INT >= 33300 + result.setUserData( QVariantList() << f.id() << mLayerId ); +#else result.userData = QVariantList() << f.id() << mLayerId; +#endif result.score = static_cast( searchString.length() ) / result.displayString.size(); result.actions << QgsLocatorResult::ResultAction( OpenForm, tr( "Open form" ), QStringLiteral( "ic_baseline-list_alt-24px" ) ); if ( mLayerIsSpatial ) @@ -297,7 +310,11 @@ void ActiveLayerFeaturesLocatorFilter::triggerResult( const QgsLocatorResult &re void ActiveLayerFeaturesLocatorFilter::triggerResultFromAction( const QgsLocatorResult &result, const int actionId ) { +#if _QGIS_VERSION_INT >= 33300 + QVariantMap data = result.getUserData().toMap(); +#else QVariantMap data = result.userData.toMap(); +#endif switch ( data.value( QStringLiteral( "type" ) ).value() ) { case ResultType::FieldRestriction: @@ -308,7 +325,11 @@ void ActiveLayerFeaturesLocatorFilter::triggerResultFromAction( const QgsLocator case ResultType::Feature: { +#if _QGIS_VERSION_INT >= 33300 + QVariantList dataList = result.getUserData().toList(); +#else QVariantList dataList = result.userData.toList(); +#endif QgsFeatureId fid = dataList.at( 0 ).toLongLong(); QString layerId = dataList.at( 1 ).toString(); QgsVectorLayer *layer = qobject_cast( QgsProject::instance()->mapLayer( layerId ) ); diff --git a/src/core/locator/bookmarklocatorfilter.cpp b/src/core/locator/bookmarklocatorfilter.cpp index 0c9077a13a..b9ee0b254a 100644 --- a/src/core/locator/bookmarklocatorfilter.cpp +++ b/src/core/locator/bookmarklocatorfilter.cpp @@ -50,7 +50,11 @@ void BookmarkLocatorFilter::fetchResults( const QString &string, const QgsLocato if ( result.score > 0 ) { result.filter = this; +#if _QGIS_VERSION_INT >= 33300 + result.setUserData( i ); +#else result.userData = i; +#endif emit resultFetched( result ); } @@ -64,7 +68,11 @@ void BookmarkLocatorFilter::triggerResult( const QgsLocatorResult &result ) void BookmarkLocatorFilter::triggerResultFromAction( const QgsLocatorResult &result, const int ) { +#if _QGIS_VERSION_INT >= 33300 + const int row = result.getUserData().toInt(); +#else const int row = result.userData.toInt(); +#endif mLocatorBridge->bookmarks()->setExtentFromBookmark( mLocatorBridge->bookmarks()->index( row, 0 ) ); diff --git a/src/core/locator/expressioncalculatorlocatorfilter.cpp b/src/core/locator/expressioncalculatorlocatorfilter.cpp index 7f67c98cbc..28d9eebbfb 100644 --- a/src/core/locator/expressioncalculatorlocatorfilter.cpp +++ b/src/core/locator/expressioncalculatorlocatorfilter.cpp @@ -56,7 +56,11 @@ void ExpressionCalculatorLocatorFilter::fetchResults( const QString &string, con QgsLocatorResult result; result.filter = this; result.displayString = tr( "Copy “%1” to clipboard" ).arg( resultString ); +#if _QGIS_VERSION_INT >= 33300 + result.setUserData( resultString ); +#else result.userData = resultString; +#endif result.score = 1; emit resultFetched( result ); } @@ -72,7 +76,11 @@ void ExpressionCalculatorLocatorFilter::triggerResult( const QgsLocatorResult &r void ExpressionCalculatorLocatorFilter::triggerResultFromAction( const QgsLocatorResult &result, const int actionId ) { +#if _QGIS_VERSION_INT >= 33300 + QString resultString = result.getUserData().toString(); +#else QString resultString = result.userData.toString(); +#endif switch ( actionId ) { diff --git a/src/core/locator/featureslocatorfilter.cpp b/src/core/locator/featureslocatorfilter.cpp index 01b526bab4..3eb054d4bd 100644 --- a/src/core/locator/featureslocatorfilter.cpp +++ b/src/core/locator/featureslocatorfilter.cpp @@ -111,7 +111,11 @@ void FeaturesLocatorFilter::fetchResults( const QString &string, const QgsLocato result.displayString = preparedLayer->expression.evaluate( &( preparedLayer->context ) ).toString(); +#if _QGIS_VERSION_INT >= 33300 + result.setUserData( QVariantList() << f.id() << preparedLayer->layerId ); +#else result.userData = QVariantList() << f.id() << preparedLayer->layerId; +#endif result.icon = preparedLayer->layerIcon; result.score = static_cast( string.length() ) / result.displayString.size(); result.actions << QgsLocatorResult::ResultAction( OpenForm, tr( "Open form" ), QStringLiteral( "ic_baseline-list_alt-24px" ) ); @@ -139,7 +143,11 @@ void FeaturesLocatorFilter::triggerResult( const QgsLocatorResult &result ) void FeaturesLocatorFilter::triggerResultFromAction( const QgsLocatorResult &result, const int actionId ) { +#if _QGIS_VERSION_INT >= 33300 + QVariantList dataList = result.getUserData().toList(); +#else QVariantList dataList = result.userData.toList(); +#endif QgsFeatureId fid = dataList.at( 0 ).toLongLong(); QString layerId = dataList.at( 1 ).toString(); QgsVectorLayer *layer = qobject_cast( QgsProject::instance()->mapLayer( layerId ) ); diff --git a/src/core/locator/gotolocatorfilter.cpp b/src/core/locator/gotolocatorfilter.cpp index 4bfe5beae2..cfb4a62168 100644 --- a/src/core/locator/gotolocatorfilter.cpp +++ b/src/core/locator/gotolocatorfilter.cpp @@ -134,7 +134,11 @@ void GotoLocatorFilter::fetchResults( const QString &string, const QgsLocatorCon QgsLocatorResult result; result.filter = this; result.displayString = tr( "Go to %1%2 %3%4 (Map CRS, %5)" ).arg( locale.toString( firstNumber, 'g', 10 ), firstSuffix, locale.toString( secondNumber, 'g', 10 ), secondSuffix, currentCrs.userFriendlyIdentifier() ); +#if _QGIS_VERSION_INT >= 33300 + result.setUserData( data ); +#else result.userData = data; +#endif result.score = 0.9; emit resultFetched( result ); } @@ -165,7 +169,11 @@ void GotoLocatorFilter::fetchResults( const QString &string, const QgsLocatorCon QgsLocatorResult result; result.filter = this; result.displayString = tr( "Go to %1°N %2°E (%3)" ).arg( locale.toString( point.y(), 'g', 10 ), locale.toString( point.x(), 'g', 10 ), wgs84Crs.userFriendlyIdentifier() ); +#if _QGIS_VERSION_INT >= 33300 + result.setUserData( data ); +#else result.userData = data; +#endif result.score = 1.0; emit resultFetched( result ); } @@ -180,7 +188,11 @@ void GotoLocatorFilter::triggerResult( const QgsLocatorResult &result ) void GotoLocatorFilter::triggerResultFromAction( const QgsLocatorResult &result, const int actionId ) { +#if _QGIS_VERSION_INT >= 33300 + QVariantMap data = result.getUserData().toMap(); +#else QVariantMap data = result.userData.toMap(); +#endif QgsGeometry geom( QgsGeometry::fromPointXY( data[QStringLiteral( "point" )].value() ) ); if ( actionId == Navigation ) diff --git a/src/core/qfieldcloudprojectsmodel.cpp b/src/core/qfieldcloudprojectsmodel.cpp index af6c43b1c4..d34de94c5f 100644 --- a/src/core/qfieldcloudprojectsmodel.cpp +++ b/src/core/qfieldcloudprojectsmodel.cpp @@ -1347,7 +1347,7 @@ void QFieldCloudProjectsModel::projectUpload( const QString &projectId, const bo case DeltaLocalStatus: // delta file should be already sent!!! Q_ASSERT( 0 ); - FALLTHROUGH + [[fallthrough]]; case DeltaPendingStatus: case DeltaBusyStatus: // infinite retry, there should be one day, when we can get the status!