Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QML locator filter framework for QField plugin #5841

Merged
merged 24 commits into from
Nov 27, 2024
Merged

Conversation

nirvn
Copy link
Member

@nirvn nirvn commented Nov 21, 2024

Much wisdom gained from these lines of code.

The PR adds a framework that allows for plugin authors to integrate into the search bar through a QML-driven locator filter.

Here's a sample plugin registering a QML locator filter being declared:

Item {
  id: plugin

  Component.onCompleted: {
    locatorBridge.registerQFieldLocatorFilter(testLocatorFilter);
  }

  QFieldLocatorFilter {
    id: testLocatorFilter

    name: "testlocator"
    displayName: "test locator!!!"
    prefix: "123"

    source: Qt.resolvedUrl('testlocator.qml')
    
    function triggerResult(result) {
      console.log(result)
    }
  }
}

The QFieldLocatorFilter item lives in the same thread and context as QField's mainWindow, and therefore can access the map canvas et al within the triggerResult function.

Notice the source property of QFieldLocatorFilter. This is a sidecar QML component file that lives next to the main plugin QML (i.e. main.qml for app-wide plugins and my_project_file_name.qml for project plugins). That component must be declared in its own file as everything in there will be happening in a separate QML engine altogether, in a separate thread.

Also notice the use of a new property named pluginFolder. This was added so plugins can load extra resource from their folder. To make use of it, simply declare a property var pluginFolder at the root of your plugin root Item {}. Note the use Qt.resolveUrl('my_file.qml') to resolve relative paths against the source file of the QML being loaded for the source property.

Moving on, here's a sample example of the source file (named testlocator.qml in the example above):

Item {
  signal prepareResult(var details)
  signal fetchResultsEnded()
  
  Timer {
    id: timer
    interval: 2000
    running: false
    repeat: false
    
    onTriggered: {
      let details = {
        "userData": GeometryUtils.point(0, 0),
        "displayString": "My title",
        "description": "My description...",
        "score": 0.5,
        "group": "My group",
        "groupScore": 0.5
      };
      prepareResult(details);
      fetchResultsEnded();
    }
  }
  
  function fetchResults(string, context) {
    timer.start();
  }
}

The use of the Timer here is merely to demonstrate how asynchronous result gathering happens. First, the function fetchResults(string, context) will be called. If the results can be computed right away, simply emit prepareResult(details) as many time as you want, and end the function by emitting fetchResultEnded(). However, it the very likely scenario the result fetching is waiting for some data (e.g. waiting for the response of an xmlhttprequest), the locator filter itself will wait until the fetchResultEnded() is emitted.

When all is done and understood, you'll get a beautiful integration:

0001-0208.webm

Here's a sample plugin that adds a GeoMapFish service into the search bar:

qfield-geomapfish-locator-v1.1.zip

Another sample plugin that adds OSM nominatim service into the search bar:

qfield-nominatim-locator-v1.1.zip

The framework also allows for plugins to add secondary actions to results. For example here, the search result has a secondary option to use the result geometry as destination:

0001-0220.webm

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

src/core/locator/qfieldlocatorfilter.cpp Outdated Show resolved Hide resolved
@qfield-fairy
Copy link
Collaborator

qfield-fairy commented Nov 21, 2024

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

src/core/locator/qfieldlocatorfilter.cpp Outdated Show resolved Hide resolved
@nirvn nirvn merged commit 6a0f143 into master Nov 27, 2024
24 checks passed
@nirvn nirvn deleted the qfield_locator_filters branch November 27, 2024 02:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants