diff --git a/lizmap/dialogs/main.py b/lizmap/dialogs/main.py index ef733a2f..d7ac800b 100755 --- a/lizmap/dialogs/main.py +++ b/lizmap/dialogs/main.py @@ -85,12 +85,15 @@ class LizmapDialog(QDialog, FORM_CLASS): - def __init__(self, parent=None, is_dev_version=True): + def __init__(self, parent=None, is_dev_version=True, lwc_version: LwcVersions = None): """Constructor.""" super().__init__(parent) self.setupUi(self) self.project = QgsProject.instance() + # Should only be used in tests + self._lwc_version = lwc_version + self.mOptionsStackedWidget.currentChanged.connect(self.panel_changed) self.is_dev_version = is_dev_version @@ -119,12 +122,10 @@ def __init__(self, parent=None, is_dev_version=True): # Scales self.use_native_zoom.toggled.connect(self.native_scales_toggled) - self.inMapScales.editingFinished.connect(self.get_min_max_scales) self.min_scale_pic.setPixmap(QPixmap(":images/themes/default/mActionZoomOut.svg")) self.min_scale_pic.setText('') self.max_scale_pic.setPixmap(QPixmap(":images/themes/default/mActionZoomIn.svg")) self.max_scale_pic.setText('') - self.native_scales_toggled() self.dataviz_feature_picker = QgsFeaturePickerWidget() @@ -621,6 +622,11 @@ def current_lwc_version(self) -> Optional[LwcVersions]: if metadata and metadata.get('info'): return LwcVersions.find(metadata['info']['version']) + if self._lwc_version: + return self._lwc_version + + return None + def current_repository(self, role=RepositoryComboData.Id) -> str: """ Fetch the current directory on the server if available. """ if not self.repository_combo.isVisible(): @@ -924,15 +930,15 @@ def setup_icons(self): def native_scales_toggled(self): """ When the checkbox native scales is toggled. """ if self.current_lwc_version() <= LwcVersions.Lizmap_3_6: - self.inMinScale.setReadOnly(True) - self.inMaxScale.setReadOnly(True) - # self.inMapScales connect + self.minimum_scale.setReadOnly(True) + self.maximum_scale.setReadOnly(True) + # self.list_map_scales connect return use_native = self.use_native_zoom.isChecked() - self.inMinScale.setReadOnly(not use_native) - self.inMaxScale.setReadOnly(not use_native) - self.inMapScales.setVisible(not use_native) + self.minimum_scale.setReadOnly(not use_native) + self.maximum_scale.setReadOnly(not use_native) + self.list_map_scales.setVisible(not use_native) self.label_scales.setVisible(not use_native) if use_native: @@ -944,8 +950,8 @@ def native_scales_toggled(self): self.label_max_scale, self.min_scale_pic, self.max_scale_pic, - self.inMinScale, - self.inMaxScale, + self.minimum_scale, + self.maximum_scale, ) for item in ui_items: item.setToolTip(msg) @@ -954,7 +960,7 @@ def get_min_max_scales(self): """Get Min Max Scales from scales input field.""" min_scale = 1 max_scale = 1000000000 - in_map_scales = self.inMapScales.text() + in_map_scales = self.list_map_scales.text() map_scales = [int(a.strip(' \t')) for a in in_map_scales.split(',') if str(a.strip(' \t')).isdigit()] # Remove scales which are lower or equal to 0 map_scales = [i for i in map_scales if int(i) > 0] @@ -970,9 +976,9 @@ def get_min_max_scales(self): else: min_scale = min(map_scales) max_scale = max(map_scales) - self.inMinScale.setText(str(min_scale)) - self.inMaxScale.setText(str(max_scale)) - self.inMapScales.setText(', '.join(map(str, map_scales))) + self.minimum_scale.setText(str(min_scale)) + self.maximum_scale.setText(str(max_scale)) + self.list_map_scales.setText(', '.join(map(str, map_scales))) def project_crs_3857(self): """ When the project CRS is EPSG:3857 and LWC 3.7. """ diff --git a/lizmap/plugin.py b/lizmap/plugin.py index 041c2ba7..573069a6 100755 --- a/lizmap/plugin.py +++ b/lizmap/plugin.py @@ -14,6 +14,7 @@ from shutil import copyfile from typing import Dict, List, Optional, Tuple +from qgis._core import QgsCoordinateReferenceSystem from qgis.core import ( Qgis, QgsApplication, @@ -262,7 +263,7 @@ def __init__(self, iface, lwc_version: LwcVersions = None): self.version = version() self.is_dev_version = any(item in self.version for item in UNSTABLE_VERSION_PREFIX) - self.dlg = LizmapDialog(is_dev_version=self.is_dev_version) + self.dlg = LizmapDialog(is_dev_version=self.is_dev_version, lwc_version=self._version) self.dock_html_preview = None self.version_checker = None if self.is_dev_version: @@ -424,9 +425,10 @@ def write_log_message(message, tag, level): # Add widgets (not done in lizmap_var to avoid dependencies on ui) self.global_options['fixed_scale_overview_map']['widget'] = self.dlg.checkbox_scale_overview_map - self.global_options['mapScales']['widget'] = self.dlg.inMapScales - self.global_options['minScale']['widget'] = self.dlg.inMinScale - self.global_options['maxScale']['widget'] = self.dlg.inMaxScale + # Because of the logic with LWC 3.7, we are mananging manually these widgets + # self.global_options['mapScales']['widget'] = self.dlg.list_map_scales + # self.global_options['minScale']['widget'] = self.dlg.minimum_scale + # self.global_options['maxScale']['widget'] = self.dlg.maximum_scale self.global_options['use_native_zoom_levels']['widget'] = self.dlg.use_native_zoom self.global_options['hide_numeric_scale_value']['widget'] = self.dlg.hide_numeric_scale_value self.global_options['acl']['widget'] = self.dlg.inAcl @@ -1668,6 +1670,15 @@ def read_cfg_file(self, skip_tables=False) -> dict: if index: item['widget'].setCurrentIndex(index) + map_scales = json_options.get('mapScales') + min_scale = json_options.get('minScale') + max_scale = json_options.get('maxScale') + use_native = json_options.get('use_native_zoom_levels') + project_crs = json_options.get('projection') + if project_crs: + project_crs = project_crs.get('ref') + self.set_map_scales_in_ui(project_crs, use_native, map_scales, min_scale, max_scale) + # Set layer combobox for key, item in self.global_options.items(): if item.get('widget'): @@ -3265,7 +3276,13 @@ def project_config_file( if not item.get('always_export'): continue - liz2json["options"][key] = input_value + # Because of LWC 3.7, we are managing manually these values + if key == 'mapScales': + liz2json["options"][key] = self.map_scales_list() + if key == 'minScale': + liz2json["options"][key] = self.minimum_scale() + if key == 'maxScale': + liz2json["options"][key] = self.maximum_scale() for key in self.layers_table.keys(): manager = self.layers_table[key].get('manager') @@ -3531,6 +3548,55 @@ def clean_project(self): # noinspection PyUnresolvedReferences self.iface.messageBar().pushMessage('Lizmap', message, level=Qgis.Warning, duration=DURATION_WARNING_BAR) + def set_map_scales_in_ui( + self, project_crs: str, use_native: bool, map_scales: list, min_scale: int, max_scale: int): + """ Set map scales in the UI according to CFG content and context. """ + # Function introduced with Lizmap Web Client 3.7 because of the map projection behavior + if map_scales is None or len(map_scales) <= 1: + map_scales = self.global_options['mapScales']['default'] + map_scales = [str(i) for i in map_scales] + + if self.current_lwc_version() <= LwcVersions.Lizmap_3_6: + self.dlg.list_map_scales.setText(', '.join(map_scales)) + self.dlg.minimum_scale.setText(min_scale) + self.dlg.maximum_scale.setText(max_scale) + self.dlg.use_native_zoom.setChecked(False) + self.dlg.get_min_max_scales() + self.connect_scale_list_to_min_max() + return + + # We are now on LWC 3.7, but maybe an old CFG file without the checkbox + if use_native is None: + crs = QgsCoordinateReferenceSystem(project_crs) + if crs in (QgsCoordinateReferenceSystem('EPSG:3857'), QgsCoordinateReferenceSystem('ESPG:900913')): + self.dlg.use_native_zoom.setChecked(True) + + crs = QgsCoordinateReferenceSystem(project_crs) + if crs in (QgsCoordinateReferenceSystem('EPSG:3857'), QgsCoordinateReferenceSystem('ESPG:900913')): + self.dlg.use_native_zoom.setChecked(True) + # Starting with LWC 3.7, we must have the checkbox + + # self.dlg.native_scales_toggled() + + def connect_scale_list_to_min_max(self): + print("connect") + self.dlg.list_map_scales.editingFinished.connect(self.dlg.get_min_max_scales) + + def disconnect_scale_list_to_min_max(self): + print("disconnect") + self.dlg.list_map_scales.editingFinished.disconnect(self.dlg.get_min_max_scales) + + def map_scales_list(self) -> List[int]: + return self.dlg.list_map_scales.text().split(",") + + def minimum_scale(self) -> int: + print("DEBUG") + print(self.dlg.minimum_scale.text()) + return int(self.dlg.minimum_scale.text()) + + def maximum_scale(self) -> int: + return int(self.dlg.maximum_scale.text()) + def check_project_validity(self): """Project checker about issues that the user might hae when running in LWC.""" # Import must be done after QTranslator @@ -4118,18 +4184,21 @@ def run(self) -> bool: # Go back to the first panel because no project loaded. # Otherwise, the plugin opens the latest valid panel before the previous project has been closed. self.dlg.mOptionsListWidget.setCurrentRow(Panels.Information) + else: + # Starting from LWC 3.7, we need to know the server BEFORE reading the CFG file + # So we do not read CFG file if the navigation is not OK - self.dlg.show() + # Reading the CFG will trigger signals with input text and the plugin will check the validity + # We do not that. + # https://github.com/3liz/lizmap-plugin/issues/513 + self.dlg.block_signals_address(True) - # Reading the CFG will trigger signals with input text and the plugin will check the validity - # We do not that. - # https://github.com/3liz/lizmap-plugin/issues/513 - self.dlg.block_signals_address(True) + # Get config file data + self.read_cfg_file() - # Get config file data - self.read_cfg_file() + self.dlg.block_signals_address(False) - self.dlg.block_signals_address(False) + self.dlg.show() auto_save = QgsSettings().value('lizmap/auto_save_project', False, bool) self.dlg.checkbox_save_project.setChecked(auto_save) diff --git a/lizmap/resources/ui/ui_lizmap.ui b/lizmap/resources/ui/ui_lizmap.ui index 141acdb2..463ea914 100755 --- a/lizmap/resources/ui/ui_lizmap.ui +++ b/lizmap/resources/ui/ui_lizmap.ui @@ -973,7 +973,7 @@ QListWidget::item::selected { - + true @@ -1006,7 +1006,7 @@ QListWidget::item::selected { - + true @@ -1050,7 +1050,7 @@ QListWidget::item::selected { - + 0 @@ -5222,9 +5222,9 @@ This is different to the map maximum extent (defined in QGIS project properties, inPointTolerance inLineTolerance inPolygonTolerance - inMapScales - inMinScale - inMaxScale + list_map_scales + minimum_scale + maximum_scale btSetExtentFromProject cbHideHeader cbHideMenu diff --git a/lizmap/test/test_ui.py b/lizmap/test/test_ui.py index 2256cabe..177fcf12 100755 --- a/lizmap/test/test_ui.py +++ b/lizmap/test/test_ui.py @@ -86,14 +86,14 @@ def test_legend_options(self): self.assertIsNone(output['layers']['legend_displayed_startup'].get('legend_image_option')) self.assertEqual(output['layers']['legend_displayed_startup']['noLegendImage'], str(False)) - def _setup_empty_project(self): + def _setup_empty_project(self, lwc_version=LwcVersions.latest()): """ Internal function to add a layer and a basic check. """ project = QgsProject.instance() layer = QgsVectorLayer(plugin_test_data_path('lines.geojson'), 'lines', 'ogr') project.addMapLayer(layer) project.setFileName(temporary_file_path()) - lizmap = Lizmap(get_iface(), lwc_version=LwcVersions.latest()) + lizmap = Lizmap(get_iface(), lwc_version=lwc_version) baselayers = lizmap._add_group_legend('baselayers', parent=None, project=project) lizmap._add_group_legend('project-background-color', baselayers, project=project) @@ -172,32 +172,25 @@ def test_lizmap_layer_properties(self): self.assertIsNone(output['layers']['lines'].get('externalWmsToggle')) self.assertIsNone(output['layers']['lines'].get('metatileSize')) - def test_general_scales_properties(self): - """ Test some UI settings about general properties. """ - lizmap = self._setup_empty_project() + def test_general_scales_properties_lwc_3_6(self): + """ Test some UI settings about general properties before LWC 3.7. """ + lizmap = self._setup_empty_project(LwcVersions.Lizmap_3_6) # Check default values - self.assertEqual('10000, 25000, 50000, 100000, 250000, 500000', lizmap.dlg.inMapScales.text()) - - # Default values from config.py at the beginning only - self.assertEqual('1', lizmap.dlg.inMinScale.text()) - self.assertEqual('1000000000', lizmap.dlg.inMaxScale.text()) - - # Trigger the signal - lizmap.dlg.get_min_max_scales() + self.assertEqual('10000, 25000, 50000, 100000, 250000, 500000', lizmap.dlg.list_map_scales.text()) # Values from the UI - self.assertEqual('10000', lizmap.dlg.inMinScale.text()) - self.assertEqual('500000', lizmap.dlg.inMaxScale.text()) + self.assertEqual('10000', lizmap.dlg.minimum_scale.text()) + self.assertEqual('500000', lizmap.dlg.maximum_scale.text()) scales = '1000, 5000, 15000' # Fill scales - lizmap.dlg.inMapScales.setText(scales) + lizmap.dlg.list_map_scales.setText(scales) lizmap.dlg.get_min_max_scales() - self.assertEqual('1000', lizmap.dlg.inMinScale.text()) - self.assertEqual('15000', lizmap.dlg.inMaxScale.text()) - self.assertEqual(scales, lizmap.dlg.inMapScales.text()) + self.assertEqual('1000', lizmap.dlg.minimum_scale.text()) + self.assertEqual('15000', lizmap.dlg.maximum_scale.text()) + self.assertEqual(scales, lizmap.dlg.list_map_scales.text()) # Check new values in the output config output = lizmap.project_config_file(LwcVersions.latest(), check_server=False, ignore_error=True)