Skip to content

Commit

Permalink
CFG - Keep config even if the layer is unavailable #527
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry committed Nov 20, 2023
1 parent 96fb007 commit dc03ced
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 21 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Add a new tool for checking the project against some rules :
* Possibility to set some safeguards, according to the user level and the server
* Some rules might be blocking the CFG file
* Following the previes featue about rules, add new buttons to auto fix the project :
* Following the previous features about rules, add new buttons to auto fix the project :
* Use estimated metadata
* Use geometry simplification
* Use project trust option
Expand All @@ -16,6 +16,9 @@
* Avoid a Python error about missing primary key
* Add a button for adding easily the French IGN orthophoto for French QGIS users
* Add attributions on layers which are provided by the plugin
* Possibility to open the plugin even if some layers are temporary unavailable and to no loose some Lizmap configuration
if the layer was used in a tool
* Display some warnings icons if the layer or the field was not loaded correctly or not existing anymore

## 3.18.1 - 2023-10-27

Expand Down
3 changes: 3 additions & 0 deletions lizmap/dialogs/dock_html_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ def __init__(self, parent, *__args):

def set_server_url(self, url: str):
""" Set the server URL according to the main dialog. """
if not url:
return

if not url.endswith('/'):
url += '/'
self._server_url = url
Expand Down
11 changes: 7 additions & 4 deletions lizmap/server_lwc.py
Original file line number Diff line number Diff line change
Expand Up @@ -623,9 +623,6 @@ def request_finished(self, row: int):
with open(self.cache_file_for_name(server_alias), 'w', encoding='utf8') as json_file:
json_file.write(json_file_content)

# TODO, I think there something wrong here
# action_text_cell.setData(Qt.UserRole, content)

# Add the JSON metadata in the server combobox
index = self.server_combo.findData(url, ServerComboData.ServerUrl.value)
self.server_combo.setItemData(index, content, ServerComboData.JsonMetadata.value)
Expand All @@ -643,6 +640,7 @@ def request_finished(self, row: int):
markdown += '* Lizmap plugin : {}\n'.format(version())
markdown += '* QGIS Desktop : {}\n'.format(Qgis.QGIS_VERSION.split('-')[0])
qgis_cell.setData(Qt.UserRole, markdown)
qgis_cell.setData(Qt.UserRole + 1, content)

# Only adding Lizmap saas if set to true
if is_lizmap_cloud(content):
Expand Down Expand Up @@ -1070,7 +1068,12 @@ def context_menu_requested(self, position: QPoint):
slot = partial(QDesktopServices.openUrl, QUrl(ServerWizard.url_server_info(url)))
open_server_info_url.triggered.connect(slot)

if any(item in version() for item in UNSTABLE_VERSION_PREFIX) or to_bool(os.getenv("LIZMAP_ADVANCED_USER")):
is_dev = (
any(
item in version() for item in UNSTABLE_VERSION_PREFIX
) or to_bool(os.getenv("LIZMAP_ADVANCED_USER"))
)
if is_dev:
open_url = menu.addAction(tr("Open raw JSON file URL") + "…")
left_item = self.table.item(item.row(), TableCell.Url.value)
url = left_item.data(Qt.UserRole)
Expand Down
55 changes: 45 additions & 10 deletions lizmap/table_manager/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ def edit_existing_row(self):

row = selection[0].row()

# Invalid layer
cell = self.table.item(row, 0)
value = cell.data(Qt.UserRole + 1)
if isinstance(value, bool) and not value:
# value is a boolean = False
# We can't edit a layer which is invalid,
# Maybe just the layer wasn't loaded in QGIS desktop because the file was missing
return

data = dict()
for i, key in enumerate(self.keys):
cell = self.table.item(row, i)
Expand Down Expand Up @@ -258,13 +267,29 @@ def _edit_row(self, row, data):
value = value(self._layer)

if input_type == InputType.Layer:
layer = self.project.mapLayer(value)
self._layer = layer
cell.setText(layer.name())
cell.setData(Qt.UserRole, layer.id())
cell.setData(Qt.ToolTipRole, '{} ({})'.format(layer.name(), layer.crs().authid()))
# noinspection PyArgumentList
cell.setIcon(QgsMapLayerModel.iconForLayer(layer))
self._layer = self.project.mapLayer(value)
cell.setData(Qt.UserRole, value)
if self._layer:
cell.setText(self._layer.name())
cell.setData(Qt.ToolTipRole, '{} ({})'.format(self._layer.name(), self._layer.crs().authid()))
if self._layer.isValid():
cell.setIcon(QgsMapLayerModel.iconForLayer(self._layer))
cell.setData(Qt.UserRole + 1, True)

if not self._layer or not self._layer.isValid():
# Layer is not correctly loading in QGIS
cell.setData(Qt.UserRole + 1, False)
cell.setIcon(QIcon(":/images/themes/default/mIconWarning.svg"))
if self._layer:
tooltip_value = self._layer.name()
else:
tooltip_value = value
cell.setData(
Qt.ToolTipRole,
tr(
'Layer {} is unavailable in QGIS, it\'s not possible to edit its configuration.'
).format(tooltip_value)
)

elif input_type == InputType.Layers:
names = []
Expand Down Expand Up @@ -294,6 +319,13 @@ def _edit_row(self, row, data):
'Field "{}" not found in the layer. You should check this configuration or fix your '
'fields.'
).format(value))
else:
# No layer
cell.setIcon(QIcon(":/images/themes/default/mIconWarning.svg"))
cell.setData(
Qt.ToolTipRole,
tr("Not possible to check the field type if the layer is not loaded in QGIS").format(value)
)

elif input_type == InputType.Fields:
cell.setText(value)
Expand Down Expand Up @@ -962,11 +994,14 @@ def from_json(self, data: dict):
if definition['type'] == InputType.Layer:
vector_layer = self.project.mapLayer(value)
if not vector_layer or not vector_layer.isValid():
# A layer temporary not available will be found in the project, but "not valid".
# Some metadata like CRS was still imported from the QGS file, but not fields
LOGGER.warning(
'In Lizmap configuration file, section "{}", the layer with ID "{}" is invalid or '
'does not exist. Skipping that layer.'.format(
'In Lizmap configuration file, section "{}", the layer with ID "{}" is invalid or does '
'not exist. Trying to keep configuration.'.format(
self.definitions.key(), value))
valid_layer = False
# Let's try to keep the configuration
# valid_layer = False
layer_data[key] = value
elif definition['type'] == InputType.Layers:
layer_data[key] = value
Expand Down
27 changes: 21 additions & 6 deletions lizmap/test/test_table_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1185,17 +1185,16 @@ def test_locate_by_layer(self):
}
self.assertDictEqual(data, expected)

def test_fake_layer_id_table_manager(self):
"""Test we can skip a wrong layer id."""
def test_unavailable_layer_table_manager(self):
""" Test we can keep layer which is unavailable at the moment. """
table = QTableWidget()
definitions = AtlasDefinitions()

table_manager = TableManager(
None, definitions, AtlasEditionDialog, table, None, None, None, None)

self.assertEqual(table.columnCount(), len(definitions.layer_config.keys()))
self.assertEqual(table_manager.table.rowCount(), 0)

# JSON from LWC 3.4 and above
layer_1 = {
"layer": "ID_WHICH_DOES_NOT_EXIST",
"primaryKey": "id",
Expand All @@ -1213,9 +1212,25 @@ def test_fake_layer_id_table_manager(self):
layer_1
]
}
self.assertEqual(table_manager.table.rowCount(), 0)
table_manager.from_json(json)
self.assertEqual(table_manager.table.rowCount(), 0)
self.assertEqual(table_manager.table.rowCount(), 1)
data = table_manager.to_json(version=LwcVersions.Lizmap_3_6)

expected = {
'atlasLayer': 'ID_WHICH_DOES_NOT_EXIST',
'atlasPrimaryKey': 'id',
'atlasDisplayLayerDescription': 'False',
'atlasFeatureLabel': 'name',
'atlasSortField': 'name',
'atlasHighlightGeometry': 'True',
'atlasZoom': 'center',
'atlasDisplayPopup': 'True',
'atlasTriggerFilter': 'True',
'atlasDuration': 5,
'atlasEnabled': 'True',
'atlasMaxWidth': 25
}
self.assertDictEqual(expected, data)

def test_table_manager(self):
"""Test about the table manager.
Expand Down

0 comments on commit dc03ced

Please sign in to comment.