Skip to content

Commit

Permalink
port edition panel to be editable
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry committed Feb 7, 2020
1 parent 24361d6 commit f5148ac
Show file tree
Hide file tree
Showing 9 changed files with 462 additions and 279 deletions.
1 change: 1 addition & 0 deletions definitions/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class InputType(Enum):
Layer = 'Layer'
List = 'List'
SpinBox = 'SpinBox'
Text = 'Text'


class BaseDefinitions:
Expand Down
60 changes: 60 additions & 0 deletions definitions/edition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Definitions for edition."""

from .base import BaseDefinitions, InputType
from ..qgis_plugin_tools.tools.i18n import tr

__copyright__ = 'Copyright 2020, 3Liz'
__license__ = 'GPL version 3'
__email__ = 'info@3liz.org'
__revision__ = '$Format:%H$'


class EditionDefinitions(BaseDefinitions):

def __init__(self):
super().__init__()
self._layer_config['layerId'] = {
'type': InputType.Layer,
'header': tr('Layer'),
'default': None,
'tooltip': tr('The vector layer for the edition.')
}
self._layer_config['createFeature'] = {
'type': InputType.CheckBox,
'header': tr('Create'),
'default': False,
'tooltip': tr('If a new feature can be added.')
}
self._layer_config['modifyAttribute'] = {
'type': InputType.CheckBox,
'header': tr('Edit attributes'),
'default': False,
'tooltip': tr('If attributes can be edited.')
}
self._layer_config['modifyGeometry'] = {
'type': InputType.CheckBox,
'header': tr('Edit geometry'),
'default': False,
'tooltip': tr('If geometry can be edited.')
}
self._layer_config['deleteFeature'] = {
'type': InputType.CheckBox,
'header': tr('Remove'),
'default': False,
'tooltip': tr('If a feature can be removed.')
}
self._layer_config['acl'] = {
'type': InputType.Text,
'header': tr('Groups'),
'default': '',
'tooltip': tr(
'Use a comma separated list of Lizmap groups ids to restrict access '
'to this layer edition.')
}

@staticmethod
def primary_keys() -> tuple:
return 'layerId',

def key(self) -> str:
return 'editionLayers'
4 changes: 4 additions & 0 deletions forms/base_edition_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ def load_form(self, data: OrderedDict) -> None:
definition['widget'].setCurrentIndex(index)
elif definition['type'] == InputType.SpinBox:
definition['widget'].setValue(value)
elif definition['type'] == InputType.Text:
definition['widget'].setText(value)
else:
raise Exception('InputType "{}" not implemented'.format(definition['type']))

Expand Down Expand Up @@ -127,6 +129,8 @@ def save_form(self) -> OrderedDict:
value = definition['widget'].currentData()
elif definition['type'] == InputType.SpinBox:
value = definition['widget'].value()
elif definition['type'] == InputType.Text:
value = definition['widget'].text()
else:
raise Exception('InputType "{}" not implemented'.format(definition['type']))

Expand Down
84 changes: 84 additions & 0 deletions forms/edition_edition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""Dialog for edition layer edition."""

from qgis.PyQt.QtWidgets import QMessageBox
from qgis.core import QgsMapLayerProxyModel, QgsProject, QgsWkbTypes

from .base_edition_dialog import BaseEditionDialog
from ..definitions.edition import EditionDefinitions
from ..qgis_plugin_tools.tools.i18n import tr
from ..qgis_plugin_tools.tools.resources import load_ui
from ..tools import excluded_providers


__copyright__ = 'Copyright 2020, 3Liz'
__license__ = 'GPL version 3'
__email__ = 'info@3liz.org'
__revision__ = '$Format:%H$'


CLASS = load_ui('ui_form_edition.ui')


class EditionLayerDialog(BaseEditionDialog, CLASS):

def __init__(self, parent=None, unicity=None):
super().__init__(parent, unicity)
self.setupUi(self)
self.config = EditionDefinitions()
self.config.add_layer_widget('layerId', self.layer)
self.config.add_layer_widget('createFeature', self.create_feature)
self.config.add_layer_widget('modifyAttribute', self.edit_attributes)
self.config.add_layer_widget('modifyGeometry', self.edit_geometry)
self.config.add_layer_widget('deleteFeature', self.delete_feature)
self.config.add_layer_widget('acl', self.allowed_groups)

self.config.add_layer_label('layerId', self.label_layer)
self.config.add_layer_label('createFeature', self.label_create)
self.config.add_layer_label('modifyAttribute', self.label_edit_attributes)
self.config.add_layer_label('modifyGeometry', self.label_edit_geometry)
self.config.add_layer_label('deleteFeature', self.label_delete)
self.config.add_layer_label('acl', self.label_allowed_groups)

self.layer.setFilters(QgsMapLayerProxyModel.VectorLayer)
self.layer.setExcludedProviders(excluded_providers())

self.setup_ui()

def validate(self) -> str:
layer = self.layer.currentLayer()
if not layer:
return tr('A layer is compulsory.')

upstream = super().validate()
if upstream:
return upstream

wfs_layers_list = QgsProject.instance().readListEntry('WFSLayers', '')[0]
for wfs_layer in wfs_layers_list:
if layer.id() == wfs_layer:
break
else:
msg = tr(
'The layers you have chosen for this tool must be checked in the "WFS Capabilities"\n'
' option of the QGIS Server tab in the "Project Properties" dialog.')
return msg

create_feature = self.create_feature.isChecked()
modify_attribute = self.edit_attributes.isChecked()
modify_geometry = self.edit_geometry.isChecked()
delete_feature = self.delete_feature.isChecked()
if not create_feature and not modify_attribute and not modify_geometry and not delete_feature:
return tr('At least one action is compulsory.')

# Check Z or M values which will be lost when editing
geometry_type = layer.wkbType()
# noinspection PyArgumentList
has_m_values = QgsWkbTypes.hasM(geometry_type)
# noinspection PyArgumentList
has_z_values = QgsWkbTypes.hasZ(geometry_type)
if has_z_values or has_m_values:
QMessageBox.warning(
self,
tr('Editing Z/M Values'),
tr('Be careful, editing this layer with Lizmap will set the Z and M to 0.'),
)
40 changes: 38 additions & 2 deletions forms/table_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ def _edit_row(self, row, data):
cell.setText(str(value))
cell.setData(Qt.UserRole, value)

elif input_type == InputType.Text:
cell.setText(value)
cell.setData(Qt.UserRole, value)

else:
raise Exception('InputType "{}" not implemented'.format(input_type))

Expand Down Expand Up @@ -268,12 +272,30 @@ def to_json(self):
layer_data[key] = cell
elif input_type == InputType.List:
layer_data[key] = cell
elif input_type == InputType.Text:
layer_data[key] = cell
else:
raise Exception('InputType "{}" not implemented'.format(input_type))

if layer_data[key] == '':
layer_data.pop(key)

if self.definitions.key() == 'editionLayers':
capabilities_keys = ['createFeature', 'modifyAttribute', 'modifyGeometry', 'deleteFeature']
layer_data['capabilities'] = {key: layer_data[key] for key in capabilities_keys}
for key in capabilities_keys:
layer_data.pop(key)

geometry_type = {
0: 'point',
1: 'line',
2: 'polygon',
3: 'unknown',
4: 'none'
}
vector_layer = QgsProject.instance().mapLayer(layer_data['layerId'])
layer_data['geometryType'] = geometry_type[vector_layer.geometryType()]

if export_legacy_single_row:
if self.definitions.key() == 'atlas':
layer_data['atlasEnabled'] = 'True'
Expand All @@ -282,7 +304,7 @@ def to_json(self):

data['layers'].append(layer_data)

if self.definitions.key() in ['locateByLayer', 'loginFilteredLayers', 'tooltipLayers', 'attributeLayers']:
if self.definitions.key() in ['locateByLayer', 'loginFilteredLayers', 'tooltipLayers', 'attributeLayers', 'editionLayers']:
result = {}
for i, layer in enumerate(data['layers']):
layer_id = layer.get('layerId')
Expand Down Expand Up @@ -334,11 +356,23 @@ def layer_from_order(layers, row):

return new_data

@staticmethod
def _from_json_legacy_capabilities(data):
for layer in data.get('layers'):
capabilities = layer.get('capabilities')
layer.update(capabilities)
layer.pop('capabilities')
layer.pop('geometryType')
return data

def from_json(self, data):
"""Load JSON into the table."""
if self.definitions.key() in ['locateByLayer', 'loginFilteredLayers', 'tooltipLayers', 'attributeLayers']:
if self.definitions.key() in ['locateByLayer', 'loginFilteredLayers', 'tooltipLayers', 'attributeLayers', 'editionLayers']:
data = self._from_json_legacy_order(data)

if self.definitions.key() == 'editionLayers':
data = self._from_json_legacy_capabilities(data)

layers = data.get('layers')

if not layers:
Expand Down Expand Up @@ -371,6 +405,8 @@ def from_json(self, data):
layer_data[key] = value
elif definition['type'] == InputType.SpinBox:
layer_data[key] = value
elif definition['type'] == InputType.Text:
layer_data[key] = value
else:
raise Exception('InputType "{}" not implemented'.format(definition['type']))
else:
Expand Down
Loading

0 comments on commit f5148ac

Please sign in to comment.