Skip to content

Commit

Permalink
wxGUI/import_export: improve output map name existence validation (OS…
Browse files Browse the repository at this point in the history
  • Loading branch information
tmszi authored Jul 4, 2020
1 parent 0f371c8 commit a44d242
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 2 deletions.
73 changes: 73 additions & 0 deletions gui/wxpython/gui_core/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- widgets::SimpleValidator
- widgets::GenericValidator
- widgets::GenericMultiValidator
- widgets::LayersListValidator
- widgets::GListCtrl
- widgets::SearchModuleWidget
- widgets::ManageSettingsWidget
Expand Down Expand Up @@ -979,6 +980,55 @@ def Select(self):
self.Refresh()


class LayersListValidator(GenericValidator):
"""This validator check output map existence"""

def __init__(self, condition, callback):
"""Standard constructor.
:param condition: function which accepts string value and returns T/F
:param callback: function which is called when condition is not fulfilled
"""
GenericValidator.__init__(self, condition, callback)

def Clone(self):
"""Standard cloner.
Note that every validator must implement the Clone() method.
"""
return LayersListValidator(self._condition, self._callback)

def Validate(self, win, validate_all=False):
"""Validate output map existence"""
mapset = grass.gisenv()['MAPSET']
maps = grass.list_grouped(type=self._condition)[mapset]

# Check all selected layers
if validate_all:
outputs = []
data = win.GetLayers()

if data is None:
return False

for layer, output, list_id in data:
if output in maps:
outputs.append(output)

if outputs:
win.output_map = outputs
self._callback(layers_list=win)
return False
else:
output_map = win.GetItemText(
win.col, win.row)
if output_map in maps:
win.output_map = output_map
self._callback(layers_list=win)
return False
return True


class GListCtrl(ListCtrl, listmix.ListCtrlAutoWidthMixin,
CheckListCtrlMixin):
"""Generic ListCtrl with popup menu to select/deselect all
Expand Down Expand Up @@ -1665,6 +1715,10 @@ def __init__(self, parent, columns, log=None):
GListCtrl.__init__(self, parent)

self.log = log
self.row = None
self.col = None
self.output_map = None
self.validate = True

# setup mixins
listmix.TextEditMixin.__init__(self)
Expand Down Expand Up @@ -1719,3 +1773,22 @@ def GetLayers(self):
layers.append((layer, output, itm[-1]))

return layers

def ValidateOutputMapName(self):
"""Validate output map name"""
wx.CallAfter(self.GetValidator().Validate, self)

def OpenEditor(self, row, col):
"""Open editor"""
self.col = col
self.row = row
super().OpenEditor(row, col)

def CloseEditor(self, event=None):
"""Close editor"""
if event:
if event.IsCommandEvent():
listmix.TextEditMixin.CloseEditor(self, event)
if self.validate:
self.ValidateOutputMapName()
event.Skip()
70 changes: 68 additions & 2 deletions gui/wxpython/modules/import_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@
from grass.script import core as grass
from grass.script import task as gtask

from core.gcmd import RunCommand, GMessage, GWarning
from core.gcmd import GError, GMessage, GWarning, RunCommand
from gui_core.forms import CmdPanel
from gui_core.gselect import OgrTypeSelect, GdalSelect, SubGroupSelect
from gui_core.widgets import LayersList, GListCtrl, GNotebook
from gui_core.widgets import GListCtrl, GNotebook, LayersList, \
LayersListValidator
from gui_core.wrap import Button, StaticText, StaticBox
from core.utils import GetValidLayerName
from core.settings import UserSettings, GetDisplayVectSettings
Expand Down Expand Up @@ -100,6 +101,7 @@ def __init__(self, parent, giface, itype,
group='cmd',
key='overwrite',
subkey='enabled'))
self.overwrite.Bind(wx.EVT_CHECKBOX, self.OnCheckOverwrite)

self.add = wx.CheckBox(parent=self.panel, id=wx.ID_ANY)
self.closeOnFinish = wx.CheckBox(parent=self.panel, id=wx.ID_ANY,
Expand Down Expand Up @@ -241,6 +243,36 @@ def _getBlackListedFlags(self):
"""Get flags which will not be showed in Settings page"""
raise NotImplementedError()

def _nameValidationFailed(self, layers_list):
"""Output map name validation callback
:param layers_list: LayersList class instance
"""
if isinstance(layers_list.output_map, list):
maps = [
'<{}>'.format(m) for m in layers_list.output_map]
message = _(
"Output map names %(names)s exist. "
) % {
'names': ', '.join(maps)}
else:
message = _(
"Output map name <%(name)s> exist. "
) % {
'name': layers_list.output_map}
GError(parent=self, message=message, caption=_("Invalid name"))

def _validateOutputMapName(self):
"""Enable/disable output map name validation according the
overwrite state"""
if not self.overwrite.IsChecked() or \
UserSettings.Get(group='cmd', key='overwrite',
subkey='enabled'):
if not self.list.GetValidator().\
Validate(win=self.list, validate_all=True):
return False
return True

def OnClose(self, event=None):
"""Close dialog"""
self.Close()
Expand All @@ -249,6 +281,13 @@ def OnRun(self, event):
"""Import/Link data (each layes as separate vector map)"""
pass

def OnCheckOverwrite(self, event):
"""Check/uncheck overwrite checkbox widget"""
if self.overwrite.IsChecked():
self.list.validate = False
else:
self.list.validate = True

def AddLayers(self, returncode, cmd=None, userData=None):
"""Add imported/linked layers into layer tree"""
if not self.add.IsChecked() or returncode != 0:
Expand Down Expand Up @@ -387,6 +426,12 @@ def __init__(self, parent, giface, link=False):
self.layersData = []

ImportDialog.__init__(self, parent, giface=giface, itype='gdal')

self.list.SetValidator(
LayersListValidator(
condition='raster',
callback=self._nameValidationFailed))

if link:
self.SetTitle(_("Link external raster data"))
else:
Expand Down Expand Up @@ -437,6 +482,9 @@ def OnRun(self, event):
parent=self)
return

if not self._validateOutputMapName():
return

dsn = self.dsnInput.GetDsn()
ext = self.dsnInput.GetFormatExt()

Expand Down Expand Up @@ -528,6 +576,12 @@ def __init__(self, parent, giface, link=False):
self.layersData = []

ImportDialog.__init__(self, parent, giface=giface, itype='ogr')

self.list.SetValidator(
LayersListValidator(
condition='vector',
callback=self._nameValidationFailed))

if link:
self.SetTitle(_("Link external vector data"))
else:
Expand Down Expand Up @@ -578,6 +632,9 @@ def OnRun(self, event):
parent=self)
return

if not self._validateOutputMapName():
return

dsn = self.dsnInput.GetDsn()
ext = self.dsnInput.GetFormatExt()

Expand Down Expand Up @@ -757,6 +814,12 @@ class DxfImportDialog(ImportDialog):
def __init__(self, parent, giface):
ImportDialog.__init__(self, parent, giface=giface, itype='dxf',
title=_("Import DXF layers"))

self.list.SetValidator(
LayersListValidator(
condition='vector',
callback=self._nameValidationFailed))

self._giface = giface
self.dsnInput = filebrowse.FileBrowseButton(
parent=self.panel,
Expand Down Expand Up @@ -787,6 +850,9 @@ def OnRun(self, event):
GMessage(_("No layers selected."), parent=self)
return

if not self._validateOutputMapName():
return

# hide dialog
self.Hide()

Expand Down

0 comments on commit a44d242

Please sign in to comment.