Skip to content
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ Input_keystore.keystore
CMakeLists.txt.user
.github/secrets/ios/LutraConsulting*.mobileprovision
google_play_key.json
fastlane/report.xml
fastlane/report.xml
CMakeUserPresets.json
2 changes: 2 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ set(MM_SRCS
streamingintervaltype.cpp
synchronizationerror.cpp
synchronizationmanager.cpp
valuerelationcontroller.cpp
valuerelationfeaturesmodel.cpp
variablesmanager.cpp
workspacesmodel.cpp
Expand Down Expand Up @@ -189,6 +190,7 @@ set(MM_HDRS
synchronizationerror.h
synchronizationmanager.h
synchronizationoptions.h
valuerelationcontroller.h
valuerelationfeaturesmodel.h
variablesmanager.h
workspacesmodel.h
Expand Down
3 changes: 2 additions & 1 deletion app/layerfeaturesmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class LayerFeaturesModel : public FeaturesModel

virtual void setupFeatureRequest( QgsFeatureRequest &request );

virtual QString buildSearchExpression();

virtual void populate();
void reset() override;

Expand All @@ -104,7 +106,6 @@ class LayerFeaturesModel : public FeaturesModel
void onFutureFinished();

private:
QString buildSearchExpression();

//! Performs getFeatures on layer. Takes ownership of \a layer and tries to move it to current thread.
QgsFeatureList fetchFeatures( QgsVectorLayerFeatureSource *layer, QgsFeatureRequest req, int searchId );
Expand Down
2 changes: 2 additions & 0 deletions app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
#include "relationreferencefeaturesmodel.h"
#include "fieldvalidator.h"
#include "valuerelationfeaturesmodel.h"
#include "valuerelationcontroller.h"
#include "snaputils.h"
#include "guidelinecontroller.h"
#include "multieditmanager.h"
Expand Down Expand Up @@ -332,6 +333,7 @@ void initDeclarative()
qmlRegisterType< LayerFeaturesModel >( "mm", 1, 0, "LayerFeaturesModel" );
qmlRegisterType< RelationFeaturesModel >( "mm", 1, 0, "RelationFeaturesModel" );
qmlRegisterType< ValueRelationFeaturesModel >( "mm", 1, 0, "ValueRelationFeaturesModel" );
qmlRegisterType< ValueRelationController >( "mm", 1, 0, "ValueRelationController" );
qmlRegisterType< RelationReferenceFeaturesModel >( "mm", 1, 0, "RelationReferenceFeaturesModel" );
qmlRegisterType< BluetoothDiscoveryModel >( "mm", 1, 0, "BluetoothDiscoveryModel" );
qmlRegisterType< PositionTrackingManager >( "mm", 1, 0, "PositionTrackingManager" );
Expand Down
6 changes: 4 additions & 2 deletions app/qml/components/MMButton.qml
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ Button {

implicitWidth: {
let margin = __style.margin20
if ( root.size === MMButton.Sizes.ExtraSmall ) margin = __style.margin8
if ( root.type === MMButton.Types.Tertiary ) margin = 0
else if ( root.size === MMButton.Sizes.ExtraSmall ) margin = __style.margin8
else if ( root.size === MMButton.Sizes.Small ) margin = __style.margin16
return row.paintedChildrenWidth + 2 * margin
}
Expand Down Expand Up @@ -214,7 +215,8 @@ Button {
property real paintedChildrenWidth: buttonIconLeft.paintedWidth + buttonContent.implicitWidth + buttonIconRight.paintedWidth + spacing
property real maxWidth: {
let margin = __style.margin20
if ( root.size === MMButton.Sizes.ExtraSmall ) margin = __style.margin8
if ( root.type === MMButton.Types.Tertiary ) margin = 0
else if ( root.size === MMButton.Sizes.ExtraSmall ) margin = __style.margin8
else if ( root.size === MMButton.Sizes.Small ) margin = __style.margin16
return parent.width - 2 * margin
}
Expand Down
11 changes: 9 additions & 2 deletions app/qml/components/MMDrawerHeader.qml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import QtQuick.Layouts

import "."

//! Best to use MMDrawerHeader as the header component for the MMPage object
//! Best to use MMDrawerHeader as the header component for the MMDrawer object

Rectangle {
id: root
Expand All @@ -25,6 +25,8 @@ Rectangle {

property alias closeButton: closeBtn
property alias topLeftItemContent: topLeftButtonGroup.children
property alias topLeftItem: topLeftButtonGroup
property alias titleComponent: headerTitleText

color: __style.transparentColor

Expand All @@ -36,11 +38,16 @@ Rectangle {
Item {
id: topLeftButtonGroup

x: __style.pageMargins + __style.safeAreaLeft
y: root.height / 2 - height / 2

width: childrenRect.width
height: parent.height
height: childrenRect.height
}

Text {
id: headerTitleText

property real leftMarginShift: {
return Math.max( internal.closeBtnRealWidth, topLeftButtonGroup.width ) + internal.headerSpacing + __style.pageMargins
}
Expand Down
10 changes: 9 additions & 1 deletion app/qml/components/MMListMultiselectDrawer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ MMDrawer {

property bool withSearch: true
property bool multiSelect: false
property bool isLoading: false
property var selected: [] // in/out property, contains a list of (pre-)selected item values

property bool showFullScreen: false
Expand Down Expand Up @@ -150,7 +151,9 @@ MMDrawer {
Component {
id: defaultEmptyStateComponent

MMListEmptyLoaderDelegate {}
MMListEmptyLoaderDelegate {
isLoading: root.isLoading
}
}

// QDate/QDateTime values get parsed to JS Date objects in QML, and they do strict comparison by default, which also
Expand All @@ -173,4 +176,9 @@ MMDrawer {
root.selected = root.selected.filter( x => !isEqualDate( x, value ) )
}
}

function focusSearchBar() {
root.showFullScreen = true
searchBar.textField.forceActiveFocus()
}
}
6 changes: 0 additions & 6 deletions app/qml/filters/MMFiltersDrawer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,6 @@ MMComponents.MMDrawer {
bgndColorHover: __style.grapeColor
fontColorHover: __style.negativeLightColor

anchors {
left: parent.left
leftMargin: __style.pageMargins + __style.safeAreaLeft
verticalCenter: parent.verticalCenter
}

onClicked: {
internal.filterValues = {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,10 @@ Column {
sourceComponent: MMComponents.MMListMultiselectDrawer {
drawerHeader.title: root.filterName

withSearch: uniqueValuesModel.count > 5
withSearch: uniqueValuesModel.count > 8
multiSelect: root.isMultiSelect

emptyStateDelegate: Component {
MMComponents.MMListEmptyLoaderDelegate {
isLoading: uniqueValuesModel.isLoading
}
}
isLoading: uniqueValuesModel.isLoading

list.model: MM.SearchProxyModel {
id: searchProxyModel
Expand Down
8 changes: 2 additions & 6 deletions app/qml/filters/components/MMFilterDropdownValueMapInput.qml
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,10 @@ Column {
sourceComponent: MMComponents.MMListMultiselectDrawer {
drawerHeader.title: root.filterName

withSearch: valueMapModel.count > 5
withSearch: valueMapModel.count > 8
multiSelect: root.isMultiSelect

emptyStateDelegate: Component {
MMComponents.MMListEmptyLoaderDelegate {
isLoading: valueMapModel.isLoading
}
}
isLoading: valueMapModel.isLoading

list.model: MM.SearchProxyModel {
id: searchProxyModel
Expand Down
37 changes: 27 additions & 10 deletions app/qml/filters/components/MMFilterDropdownValueRelationInput.qml
Original file line number Diff line number Diff line change
Expand Up @@ -65,30 +65,47 @@ Column {

active: false


sourceComponent: MMComponents.MMListMultiselectDrawer {
id: listDrawer

drawerHeader.title: root.filterName

withSearch: vrDropdownModel.count > 5
withSearch: vrDropdownModel.count > 8
multiSelect: root.isMultiSelect

emptyStateDelegate: Component {
MMComponents.MMListEmptyLoaderDelegate {
isLoading: vrDropdownModel.fetchingResults
}
}
isLoading: vrDropdownModel.fetchingResults

list.model: MM.ValueRelationFeaturesModel {
id: vrDropdownModel

config: root.widgetConfig

property bool firstFetchFinished: false

// We show search for lists with more then 8 features.
// We need to intentionally break the binding here because "count" changes
// when users search for something and that would hide the search bar
onFetchingResultsChanged: {
if ( !fetchingResults && !firstFetchFinished )
{
if ( count > 8 )
{
listDrawer.withSearch = true
}
else
{
listDrawer.withSearch = false
}

firstFetchFinished = true
}
}
}

textRole: "FeatureTitle"
valueRole: "Key"
textRole: "ValueColumn"
valueRole: "KeyColumn"

onSelectionFinished: function( selectedItems ) {

//
// Large fids could be converted to scientific notation on their way to cpp,
// so we convert them to string first in JS.
Expand Down
14 changes: 3 additions & 11 deletions app/qml/form/MMFormPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ Page {

property var fieldActiveProject: root.project
property var fieldAssociatedRelation: model.Relation
property var fieldFeatureLayerPair: root.controller.featureLayerPair
property MM.AttributeController fieldController: root.controller
property string fieldHomePath: root.project ? root.project.homePath : "" // for photo editor

property bool fieldRememberValueSupported: root.controller.rememberAttributesController.rememberValuesAllowed && root.state === "add" && model.EditorWidget !== "Hidden" && Type === MM.FormItem.Field
Expand Down Expand Up @@ -372,19 +372,11 @@ Page {
Connections {
target: root.controller

// Important for relation form editors // <--- TODO: remove me if all works, unused
function onFeatureLayerPairChanged() {
if ( formEditorsLoader.item && formEditorsLoader.item.featureLayerPairChanged )
{
formEditorsLoader.item.featureLayerPairChanged()
}
}

// Important for value relation form editors
function onFormRecalculated() {
if ( formEditorsLoader.item && formEditorsLoader.item.reload )
if ( formEditorsLoader.item && formEditorsLoader.item.hotReload )
{
formEditorsLoader.item.reload()
formEditorsLoader.item.hotReload()
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/qml/form/MMFormStackController.qml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Item {
// https://github.com/MerginMaps/mobile/issues/2879
for ( let i = 0; i < formsStack.depth; i++ ) {
let form = formsStack.get( i )
form.featureLayerPair = __inputUtils.createFeatureLayerPair()
form.featureLayerPair = __inputUtils.createFeatureLayerPair
form.relationToApply = null
form.controllerToApply = null
form.project = null
Expand Down
6 changes: 3 additions & 3 deletions app/qml/form/editors/MMFormGalleryEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import "../../components/private" as MMPrivateComponents
MMPrivateComponents.MMBaseInput {
id: root

property MM.AttributeController _fieldController: parent.fieldController
property var _fieldAssociatedRelation: parent.fieldAssociatedRelation
property var _fieldFeatureLayerPair: parent.fieldFeatureLayerPair
property var _fieldActiveProject: parent.fieldActiveProject

property bool _fieldShouldShowTitle: parent.fieldShouldShowTitle
Expand Down Expand Up @@ -48,7 +48,7 @@ MMPrivateComponents.MMBaseInput {
id: rmodel

relation: root._fieldAssociatedRelation
parentFeatureLayerPair: root._fieldFeatureLayerPair
parentFeatureLayerPair: root._fieldController.featureLayerPair
homePath: root._fieldActiveProject.homePath
}

Expand Down Expand Up @@ -97,7 +97,7 @@ MMPrivateComponents.MMBaseInput {

MMComponents.MMSingleClickMouseArea {
anchors.fill: parent
onSingleClicked: root.createLinkedFeature( root._fieldFeatureLayerPair, root._fieldAssociatedRelation )
onSingleClicked: root.createLinkedFeature( root._fieldController.featureLayerPair, root._fieldAssociatedRelation )
}
}

Expand Down
6 changes: 3 additions & 3 deletions app/qml/form/editors/MMFormPhotoEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ MMFormPhotoViewer {

property string _fieldHomePath: parent.fieldHomePath
property var _fieldActiveProject: parent.fieldActiveProject
property var _fieldFeatureLayerPair: parent.fieldFeatureLayerPair
property MM.AttributeController _fieldController: parent.fieldController

property bool _fieldShouldShowTitle: parent.fieldShouldShowTitle
property bool _fieldFormIsReadOnly: parent.fieldFormIsReadOnly
Expand Down Expand Up @@ -237,7 +237,7 @@ MMFormPhotoViewer {
property string targetDir: __inputUtils.resolveTargetDir(
root._fieldHomePath,
root._fieldConfig,
root._fieldFeatureLayerPair,
root._fieldController.featureLayerPair,
root._fieldActiveProject
)

Expand Down Expand Up @@ -417,7 +417,7 @@ MMFormPhotoViewer {
* which references another field in the same form, to save photos in certain directory.
*/
function updateTargetDir() {
targetDir = __inputUtils.resolveTargetDir( root._fieldHomePath, root._fieldConfig, root._fieldFeatureLayerPair, root._fieldActiveProject )
targetDir = __inputUtils.resolveTargetDir( root._fieldHomePath, root._fieldConfig, root._fieldController.featureLayerPair, root._fieldActiveProject )
}
}
}
8 changes: 4 additions & 4 deletions app/qml/form/editors/MMFormRelationEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ MMPrivateComponents.MMBaseInput {
id: root

property var _fieldAssociatedRelation: parent.fieldAssociatedRelation
property var _fieldFeatureLayerPair: parent.fieldFeatureLayerPair
property var _fieldActiveProject: parent.fieldActiveProject
property MM.AttributeController _fieldController: parent.fieldController

property string _fieldTitle: parent.fieldTitle
property bool _fieldShouldShowTitle: parent.fieldShouldShowTitle
Expand Down Expand Up @@ -97,7 +97,7 @@ MMPrivateComponents.MMBaseInput {
anchors.fill: parent
onSingleClicked: {
root.forceActiveFocus() // clear focus from all elements to prevent freezing #3483
root.createLinkedFeature( root._fieldFeatureLayerPair, root._fieldAssociatedRelation )
root.createLinkedFeature( root._fieldController.featureLayerPair, root._fieldAssociatedRelation )
}
}
}
Expand All @@ -111,7 +111,7 @@ MMPrivateComponents.MMBaseInput {
id: rmodel

relation: root._fieldAssociatedRelation
parentFeatureLayerPair: root._fieldFeatureLayerPair
parentFeatureLayerPair: root._fieldController.featureLayerPair
homePath: root._fieldActiveProject.homePath

onModelReset: {
Expand Down Expand Up @@ -217,7 +217,7 @@ MMPrivateComponents.MMBaseInput {
onClosed: listLoader.active = false
onFeatureClicked: ( featurePair ) => root.openLinkedFeature( featurePair )
onSearchTextChanged: ( searchText ) => rmodel.searchExpression = searchText
onButtonClicked: root.createLinkedFeature( root._fieldFeatureLayerPair, root._fieldAssociatedRelation )
onButtonClicked: root.createLinkedFeature( root._fieldController.featureLayerPair, root._fieldAssociatedRelation )

Component.onCompleted: open()
}
Expand Down
Loading
Loading