Skip to content

Value relation rework & more small updates#4525

Open
tomasMizera wants to merge 11 commits into
masterfrom
fix/value-relation-2026
Open

Value relation rework & more small updates#4525
tomasMizera wants to merge 11 commits into
masterfrom
fix/value-relation-2026

Conversation

@tomasMizera

@tomasMizera tomasMizera commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Introduces a new way of handling value relation editors. Improves performance and stability.

Changes:

  • Created a utility class ValueRelationController that performs lookups from key to value, handles hot reload (filter expression) and conversions from/to QGIS format, e. g. "{1,2,3}" to [1,2,3]
  • Lookup on background thread
  • Reading only Key and Value attributes (compared to all attributes before), no geometry
  • Unified search UX with filters - drawer goes fullscreen if searchbar gets focus

Todos:

  • Test PG lookups
  • Test spatial filter expressions (@IvaKuklica) - filter expression like distance(@geometry, @current_geometry) <= 0.000135
  • Autotests finalization

Other updates:

  • Updated min required number of features to show searchbar in drawers from 5 to 8
  • Added clear button to value map and value relation editors
  • Refactored MMDrawerHeader and MMListMultiselectDrawer multiselect drawer to make their API easier to use
  • Anhanced UX for completers - searchbar is autofocused

Resolves #4255
Resolves #4497
Resolves #4443
Resolves #3297
Resolves #3737
Resolves #4508
Resolves #4505
Resolves #2148 (<- the only limitation is VR fields with filter expression)
Resolves (? needs to be tested) #4504

@tomasMizera tomasMizera requested a review from Withalion June 4, 2026 14:16
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

📦 Build Artifacts Ready

OS Status Build Info Workflow run
macOS Build Build failed or not found. #6885
linux Build Build failed or not found. #6911
win64 Build 📬 Mergin Maps 60791 win64 Expires: 02/09/2026 #6079
Android Build 📬 Mergin Maps 819551 APK [arm64-v8a] Expires: 02/09/2026 #8195
📬 Mergin Maps 819551 APK [arm64-v8a] Google Play Store #8195
Android Build 📬 Mergin Maps 819511 APK [armeabi-v7a] Expires: 02/09/2026 #8195
📬 Mergin Maps 819511 APK [armeabi-v7a] Google Play Store #8195
iOS Build 📬 Build number: 26.06.913711 #9137

@Withalion Withalion marked this pull request as ready for review June 8, 2026 13:26
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

📦 Build Artifacts Ready

OS Status Build Info Workflow run
macOS Build Build failed or not found. #6897
linux Build Build failed or not found. #6923
win64 Build Build failed or not found. #6091
Android Build 📬 Mergin Maps 820711 APK [armeabi-v7a] Expires: 07/09/2026 #8207
📬 Mergin Maps 820711 APK [armeabi-v7a] Google Play Store #8207
Android Build 📬 Mergin Maps 820751 APK [arm64-v8a] Expires: 07/09/2026 #8207
📬 Mergin Maps 820751 APK [arm64-v8a] Google Play Store #8207
iOS Build 📬 Build number: 26.06.914911 #9149

@Withalion Withalion left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great improvement!

Comment on lines +93 to +94
fontColor: __style.darkGreyColor
fontColorHover: __style.nightColor

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the text be red?

Comment on lines +80 to +81
fontColor: __style.darkGreyColor
fontColorHover: __style.nightColor

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the text be red?

for ( let i = 0; i < formsStack.depth; i++ ) {
let form = formsStack.get( i )
form.featureLayerPair = __inputUtils.createFeatureLayerPair()
form.featureLayerPair = __inputUtils.createFeatureLayerPair

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are passing reference to the function here, that doesn't seem right

return;
}

CoreUtils::log( u"Sync Manager"_s, u"Requested download of project %2"_s.arg( project.mergin.projectName ) );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CoreUtils::log( u"Sync Manager"_s, u"Requested download of project %2"_s.arg( project.mergin.projectName ) );
CoreUtils::log( QStringLiteral( "Sync Manager" ), QStringLiteral( "Requested download of project %2" ).arg( project.mergin.projectName ) );

return;
}

CoreUtils::log( u"Sync Manager"_s, u"Requested %1 sync of project %2"_s.arg( requestOrigin == SyncOptions::ManualRequest ? "manual" : "automatic" ).arg( project.projectName ) );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

}
}

return QStringList() << qgsValue.toString();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return QStringList() << qgsValue.toString();
return { qgsValue.toString() };

Comment on lines +139 to +148
if ( keyFieldDef.isNumeric() )
{
bool ok = false;
const qlonglong numVal = k.toLongLong( &ok );
if ( ok )
{
typedKey = QVariant( numVal );
}
}
quotedKeys << QgsExpression::quotedValue( typedKey );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we convert string -> number -> string?

Comment on lines +47 to +62
/**
* Parses a QGIS value-relation wire value into a list of key strings.
* allowMulti=true → "{1,2,3}" becomes ["1","2","3"]
* allowMulti=false → "1" becomes ["1"]
* An empty or null input always returns an empty list.
*/
Q_INVOKABLE QStringList qgisFormatToArray( const QVariant &qgsValue ) const;

/**
* Formats a list of key strings into the QGIS wire value "{k1,k2,...}".
* allowMulti=true → "["1","2","3"]" becomes ["1","2","3"]
* allowMulti=true → "["1"]" becomes "1"
* allowMulti=false → "1" becomes "1"
* An empty list produces "".
*/
Q_INVOKABLE QString arrayToQgisFormat( const QStringList &keys ) const;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think these should be just static utility functions, not tied to the class

Comment thread app/main.cpp
Comment on lines 335 to +336
qmlRegisterType< ValueRelationFeaturesModel >( "mm", 1, 0, "ValueRelationFeaturesModel" );
qmlRegisterType< ValueRelationController >( "mm", 1, 0, "ValueRelationController" );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
qmlRegisterType< ValueRelationFeaturesModel >( "mm", 1, 0, "ValueRelationFeaturesModel" );
qmlRegisterType< ValueRelationController >( "mm", 1, 0, "ValueRelationController" );

Let's do it the declarative way, by using QML_ELEMENT

#include "qgsexpressioncontextutils.h"
#include "qgsvectorlayer.h"

using namespace Qt::Literals;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as elsewhere

@Withalion Withalion changed the title WIP: Value relation rework & more small updates Value relation rework & more small updates Jun 15, 2026
@github-actions

Copy link
Copy Markdown

Coverage Report for CI Build 27562718106

Warning

No base build found for commit 029f9b7 on master.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 57.561%

Details

  • Patch coverage: No coverable lines changed in this PR.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 15547
Covered Lines: 8949
Line Coverage: 57.56%
Coverage Strength: 96.12 hits per line

💛 - Coveralls

@github-actions

Copy link
Copy Markdown

📦 Build Artifacts Ready

OS Status Build Info Workflow run
macOS Build 📬 Mergin Maps 69301 dmg Expires: 13/09/2026 #6930
linux Build 📬 Mergin Maps 69561 x86_64 Expires: 13/09/2026 #6956
win64 Build Build failed or not found. #6128
Android Build 📬 Mergin Maps 824051 APK [arm64-v8a] Expires: 13/09/2026 #8240
📬 Mergin Maps 824051 APK [arm64-v8a] Google Play Store #8240
Android Build 📬 Mergin Maps 824011 APK [armeabi-v7a] Expires: 13/09/2026 #8240
📬 Mergin Maps 824011 APK [armeabi-v7a] Google Play Store #8240
iOS Build 📬 Build number: 26.06.918211 #9182

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment