Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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" );
Comment on lines 335 to +336

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

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

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

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