diff --git a/lizmap/dialogs/main.py b/lizmap/dialogs/main.py
index e0e291a1..fa39d9cf 100755
--- a/lizmap/dialogs/main.py
+++ b/lizmap/dialogs/main.py
@@ -7,7 +7,14 @@
from pathlib import Path
from typing import Optional
-from qgis.core import Qgis, QgsApplication, QgsProject, QgsSettings
+from qgis.core import (
+ Qgis,
+ QgsApplication,
+ QgsFieldProxyModel,
+ QgsMapLayerProxyModel,
+ QgsProject,
+ QgsSettings,
+)
from qgis.PyQt.QtCore import QSize, Qt
from qgis.PyQt.QtGui import QIcon, QImageReader, QPixmap
from qgis.PyQt.QtWidgets import (
@@ -82,6 +89,30 @@ def __init__(self, parent=None):
self.lwc_version_latest_changelog.setVisible(False)
self.lwc_version_oldest_changelog.setVisible(False)
+ # Filtering features
+ self.tab_filtering.setCurrentIndex(0)
+ self.helper_list_group.setReadOnly(True)
+ self.button_helper_group.setToolTip(tr('Select features having at least one group not matching on the server'))
+ self.button_helper_group.clicked.connect(self.select_unknown_features_group)
+ self.button_helper_group.setIcon(QIcon(":images/themes/default/mActionToggleSelectedLayers.svg"))
+ self.helper_layer_group.setFilters(QgsMapLayerProxyModel.VectorLayer)
+ tooltip = tr("The layer to check group IDs")
+ self.helper_layer_group.setToolTip(tooltip)
+ self.helper_field_group.setFilters(QgsFieldProxyModel.String)
+ self.helper_field_group.setLayer(self.helper_layer_group.currentLayer())
+ self.label_helper_layer_group.setToolTip(tooltip)
+ tooltip = tr("The field which must contains group IDs")
+ self.helper_field_group.setToolTip(tooltip)
+ self.helper_layer_group.layerChanged.connect(self.helper_field_group.setLayer)
+ self.label_helper_field_group.setToolTip(tooltip)
+
+ icon = QgsApplication.getThemeIcon("mActionToggleSelectedLayers.svg")
+ self.preview_attribute_filtering.setIcon(icon)
+ self.preview_attribute_filtering.setText("")
+ self.preview_attribute_filtering.setToolTip(tr("To have a preview of the attribute filtering tool"))
+ self.preview_attribute_filtering.setVisible(False)
+ # self.preview_attribute_filtering.clicked.connect(self.open_filter_preview)
+
# IGN and google
self.inIgnKey.textChanged.connect(self.check_ign_french_free_key)
self.inIgnKey.textChanged.connect(self.check_api_key_address)
@@ -98,6 +129,7 @@ def __init__(self, parent=None):
self.inLayerLink.setToolTip(tooltip)
self.log_panel = LogPanel(self.out_log)
+ self.button_clear_log.setIcon(QIcon(":images/themes/default/console/iconClearConsole.svg"))
self.button_clear_log.clicked.connect(self.log_panel.clear)
self.check_project_thumbnail()
@@ -644,21 +676,27 @@ def setup_icons(self):
i += 1
# Set stylesheet for QGroupBox
- self.gb_tree.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_layerSettings.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_ftp.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_project_thumbnail.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_visibleTools.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_Scales.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_extent.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_externalLayers.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_lizmapExternalBaselayers.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_generalOptions.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_interface.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.gb_baselayersOptions.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.predefined_groups_legend.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.predefined_groups.setStyleSheet(COMPLETE_STYLE_SHEET)
- self.predefined_baselayers.setStyleSheet(COMPLETE_STYLE_SHEET)
+ q_group_box = (
+ self.gb_tree,
+ self.gb_layerSettings,
+ self.gb_ftp,
+ self.gb_project_thumbnail,
+ self.gb_visibleTools,
+ self.gb_Scales,
+ self.gb_extent,
+ self.gb_externalLayers,
+ self.gb_lizmapExternalBaselayers,
+ self.gb_generalOptions,
+ self.gb_interface,
+ self.gb_baselayersOptions,
+ self.predefined_groups_legend,
+ self.predefined_groups,
+ self.predefined_baselayers,
+ self.attribute_filtering,
+ self.spatial_filtering,
+ )
+ for widget in q_group_box:
+ widget.setStyleSheet(COMPLETE_STYLE_SHEET)
def check_project_thumbnail(self):
""" Check the project thumbnail and display the metadata. """
@@ -739,6 +777,40 @@ def allow_navigation(self, allow_navigation: bool, message: str = ''):
self.label_warning_project.setVisible(True)
self.label_warning_project.set_text(message)
+ def select_unknown_features_group(self):
+ """ Select features where one group from the feature does not math one of the server. """
+ groups = self.helper_list_group.text()
+ if not groups:
+ return
+
+ layer = self.helper_layer_group.currentLayer()
+ if not layer:
+ return
+
+ field = self.helper_field_group.currentField()
+ if not field:
+ return
+
+ groups = ','.join(["'{}'".format(f) for f in groups.split(',')])
+ expression = (
+ "not("
+ " array_all("
+ " array({groups}),"
+ " string_to_array(\"{field}\")"
+ " )"
+ ")"
+ ).format(field=field, groups=groups)
+ layer.removeSelection()
+ LOGGER.debug("Expression used for checking groups not on the server :\n" + expression)
+ layer.selectByExpression(expression)
+ count = layer.selectedFeatureCount()
+ self.display_message_bar(
+ tr("Debug"),
+ tr("{count} feature(s) having at least one group not on the server").format(
+ count=count),
+ Qgis.Info if count >= 1 else Qgis.Success
+ )
+
def fix_project_ssl(self):
""" Fix the current project about SSL. """
self.enabled_ssl_button(False)
diff --git a/lizmap/plugin.py b/lizmap/plugin.py
index 10e55904..b5e520f0 100755
--- a/lizmap/plugin.py
+++ b/lizmap/plugin.py
@@ -821,6 +821,22 @@ def target_server_changed(self):
for item in self.lizmap_cloud:
item.setVisible(lizmap_cloud)
+ self.dlg.helper_list_group.setReadOnly(True)
+ if current_metadata:
+ acl = current_metadata.get('acl')
+ if not acl:
+ # Running a version < 3.6.1
+ tooltip = tr("Your server does not support this feature, please upgrade.")
+ self.dlg.helper_list_group.setText("")
+ else:
+ self.dlg.helper_list_group.setText(','.join(list(acl['groups'].keys())))
+ tooltip = (
+ tr("It cannot be edited. Existing groups on the server : ") + self.dlg.server_combo.currentText()
+ )
+
+ self.dlg.helper_list_group.setToolTip(tooltip)
+ self.dlg.label_helper_list_group.setToolTip(tooltip)
+
# For deprecated features in LWC 3.7 about base layers
self.check_visibility_crs_3857()
diff --git a/lizmap/resources/ui/ui_lizmap.ui b/lizmap/resources/ui/ui_lizmap.ui
index 5f738c6f..04228be7 100755
--- a/lizmap/resources/ui/ui_lizmap.ui
+++ b/lizmap/resources/ui/ui_lizmap.ui
@@ -3735,166 +3735,247 @@ This is different to the map maximum extent (defined in QGIS project properties,
-
-
-
- Attribute filtering
-
-
-
-
-
-
- You need to choose an attribute where Lizmap groups are stored for each feature to display or not. It's possible to filter for a specific login instead group by using the checkbox.
-
-
- true
-
-
-
- -
-
-
- -
-
-
-
-
-
- +
-
-
-
- -
-
-
- -
-
-
-
- -
-
-
- edit
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
-
-
- -
-
-
- Spatial filtering
+
+
+ 0
-
-
-
-
-
- First you need to choose a layer used for filtering, by specifying the field where Lizmap groups (or users) are stored. Then, you can define one or many layers to be filtered. For each of them, you can choose if you want a strict "contains" spatial relationship or a simple "intersection" with the filtering layer.
-
-
- true
-
-
-
- -
-
-
- Options
-
-
+
+
+ Attribute filtering
+
+
+
-
+
+
+ You need to choose an attribute where Lizmap groups are stored for each feature to display or not. It's possible to filter for a specific login instead group by using the checkbox.
+
+
+ true
+
+
+
+ -
+
+
+ -
+
-
-
-
-
-
-
- Layer
-
-
-
- -
-
-
- -
-
-
- Field
-
-
-
- -
-
-
- -
-
-
- Filter by
-
-
-
- -
-
-
-
+
+
+ +
+
+
+
+ -
+
+
+ -
+
+
+
+ -
+
+
+ edit
+
+
+
+ -
+
+
+ preview
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
-
-
- -
-
-
- -
-
-
-
-
-
- +
-
-
-
- -
-
-
- -
-
-
-
- -
-
-
- edit
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
+
+
+
+
+
+ Spatial filtering
+
+
+ -
+
+
+ First you need to choose a layer used for filtering, by specifying the field where Lizmap groups (or users) are stored. Then, you can define one or many layers to be filtered. For each of them, you can choose if you want a strict "contains" spatial relationship or a simple "intersection" with the filtering layer.
+
+
+ true
+
+
+
+ -
+
+
+ Options
+
+
+
-
+
+
-
+
+
+ Layer
+
+
+
+ -
+
+
+ -
+
+
+ Field
+
+
+
+ -
+
+
+ -
+
+
+ Filter by
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
-
+
+
+ +
+
+
+
+ -
+
+
+ -
+
+
+
+ -
+
+
+ edit
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+ Helper
+
+
+ -
+
+
+ This helper can help to detect features having at least one group not matching one on the server. The field must contain group IDS. NULL or empty string are not checked.
+
+
+ true
+
+
+
+ -
+
+
-
+
+
+ Layer
+
+
+
+ -
+
+
+ Field
+
+
+
+ -
+
+
+ Groups
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ Select
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 558
+
+
+
+
+
+
diff --git a/lizmap/resources/ui/ui_wizard_group.ui b/lizmap/resources/ui/ui_wizard_group.ui
index 7bdced07..cc34ea9e 100644
--- a/lizmap/resources/ui/ui_wizard_group.ui
+++ b/lizmap/resources/ui/ui_wizard_group.ui
@@ -24,7 +24,7 @@
-
- Existing group found on the server
+ Existing groups found on the server