From 298fdf1b80ea7cd618f91973e8bf2d628883b673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:33:32 +0000 Subject: [PATCH 01/21] gui(core.layerlist): Fix returning active layers in GetSelectedLayers() The previous code was appending the selected layer whether it was active or not --- gui/wxpython/core/layerlist.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gui/wxpython/core/layerlist.py b/gui/wxpython/core/layerlist.py index c09ea203326..43b1a4d118d 100644 --- a/gui/wxpython/core/layerlist.py +++ b/gui/wxpython/core/layerlist.py @@ -38,8 +38,9 @@ def GetSelectedLayers(self, activeOnly=True): layers = [] for layer in self._list: if layer.IsSelected(): - if activeOnly and layer.IsActive(): - layers.append(layer) + if activeOnly: + if layer.IsActive(): + layers.append(layer) else: layers.append(layer) return layers From 790a8ad56f73f47bc036baf3b2ff5fd5384c7849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:20:50 +0000 Subject: [PATCH 02/21] gui: Use context manager for opening files and temporary files --- gui/wxpython/core/render.py | 8 +- gui/wxpython/gmodeler/model.py | 13 +-- gui/wxpython/gmodeler/panels.py | 77 ++++++------- gui/wxpython/gui_core/ghelp.py | 14 +-- gui/wxpython/gui_core/gselect.py | 18 ++- gui/wxpython/image2target/ii2t_gis_set.py | 5 +- gui/wxpython/lmgr/workspace.py | 51 ++++----- gui/wxpython/location_wizard/wizard.py | 133 +++++++++++----------- gui/wxpython/mapdisp/main.py | 19 ++-- gui/wxpython/modules/colorrules.py | 20 +--- gui/wxpython/psmap/frame.py | 37 +++--- gui/wxpython/rdigit/controller.py | 5 +- gui/wxpython/rlisetup/sampling_frame.py | 22 ++-- gui/wxpython/rlisetup/wizard.py | 9 +- gui/wxpython/tools/update_menudata.py | 45 ++++---- gui/wxpython/vdigit/mapwindow.py | 63 +++++----- 16 files changed, 243 insertions(+), 296 deletions(-) diff --git a/gui/wxpython/core/render.py b/gui/wxpython/core/render.py index 26a984990e7..67e7561c4e7 100644 --- a/gui/wxpython/core/render.py +++ b/gui/wxpython/core/render.py @@ -51,10 +51,10 @@ def get_tempfile_name(suffix, create=False): # which may mitigate problems (like not cleaning files) in case we # go little beyond what is in the documentation in terms of opening # closing and removing the tmp file - tmp = tempfile.NamedTemporaryFile(suffix=suffix, delete=False) - # we don't want it open, we just need the name - name = tmp.name - tmp.close() + with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp: + # we don't want it open, we just need the name + name = tmp.name + if not create: # remove empty file to have a clean state later os.remove(name) diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index 1f85af66ded..e31e52c8c04 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -542,11 +542,9 @@ def _substituteFile(self, item, params=None, checkOnly=False): for finput in self.fileInput: # read lines - fd = open(finput) - try: - data = self.fileInput[finput] = fd.read() - finally: - fd.close() + with open(finput) as fd: + data = fd.read() + self.fileInput[finput] = data # substitute variables write = False @@ -579,11 +577,8 @@ def _substituteFile(self, item, params=None, checkOnly=False): if not checkOnly: if write: - fd = open(finput, "w") - try: + with open(finput, "w") as fd: fd.write(data) - finally: - fd.close() else: self.fileInput[finput] = None diff --git a/gui/wxpython/gmodeler/panels.py b/gui/wxpython/gmodeler/panels.py index fbdc2048620..6390da92deb 100644 --- a/gui/wxpython/gmodeler/panels.py +++ b/gui/wxpython/gmodeler/panels.py @@ -401,11 +401,8 @@ def OnModelDone(self, event): if not data: continue - fd = open(finput, "w") - try: + with open(finput, "w") as fd: fd.write(data) - finally: - fd.close() del self.model.fileInput # delete intermediate data @@ -671,31 +668,28 @@ def WriteModelFile(self, filename): :return: False on failure """ self.ModelChanged(False) - tmpfile = tempfile.TemporaryFile(mode="w+") - try: - WriteModelFile(fd=tmpfile, model=self.model) - except Exception: - GError( - parent=self, message=_("Writing current settings to model file failed.") - ) - return False - - try: - mfile = open(filename, "w") - tmpfile.seek(0) - for line in tmpfile.readlines(): - mfile.write(line) - except OSError: - wx.MessageBox( - parent=self, - message=_("Unable to open file <%s> for writing.") % filename, - caption=_("Error"), - style=wx.OK | wx.ICON_ERROR | wx.CENTRE, - ) - return False - - mfile.close() - + with tempfile.TemporaryFile(mode="w+") as tmpfile: + try: + WriteModelFile(fd=tmpfile, model=self.model) + except Exception: + GError( + parent=self, + message=_("Writing current settings to model file failed."), + ) + return False + try: + with open(filename, "w") as mfile: + tmpfile.seek(0) + for line in tmpfile.readlines(): + mfile.write(line) + except OSError: + wx.MessageBox( + parent=self, + message=_("Unable to open file <%s> for writing.") % filename, + caption=_("Error"), + style=wx.OK | wx.ICON_ERROR | wx.CENTRE, + ) + return False return True def DefineLoop(self, loop): @@ -1702,17 +1696,15 @@ def RefreshScript(self): if ret == wx.ID_NO: return False - fd = tempfile.TemporaryFile(mode="r+") grassAPI = UserSettings.Get(group="modeler", key="grassAPI", subkey="selection") - self.write_object( - fd, - self.parent.GetModel(), - grassAPI="script" if grassAPI == 0 else "pygrass", - ) - - fd.seek(0) - self.body.SetText(fd.read()) - fd.close() + with tempfile.TemporaryFile(mode="r+") as fd: + self.write_object( + fd, + self.parent.GetModel(), + grassAPI="script" if grassAPI == 0 else "pygrass", + ) + fd.seek(0) + self.body.SetText(fd.read()) self.body.modified = False @@ -1765,18 +1757,13 @@ def SaveAs(self, force=False): dlg.Destroy() - fd = open(filename, "w") - try: + with open(filename, "w") as fd: if force: self.write_object(fd, self.parent.GetModel()) else: fd.write(self.body.GetText()) - finally: - fd.close() - # executable file os.chmod(filename, stat.S_IRWXU | stat.S_IWUSR) - return filename def OnRun(self, event): diff --git a/gui/wxpython/gui_core/ghelp.py b/gui/wxpython/gui_core/ghelp.py index 0c4f6cdadfb..fd3991e1e6d 100644 --- a/gui/wxpython/gui_core/ghelp.py +++ b/gui/wxpython/gui_core/ghelp.py @@ -274,9 +274,8 @@ def _pageCopyright(self): """Copyright information""" copyfile = os.path.join(os.getenv("GISBASE"), "COPYING") if os.path.exists(copyfile): - copyrightFile = open(copyfile) - copytext = copyrightFile.read() - copyrightFile.close() + with open(copyfile) as copyrightFile: + copytext = copyrightFile.read() else: copytext = _("%s file missing") % "COPYING" @@ -303,9 +302,8 @@ def _pageLicense(self): """Licence about""" licfile = os.path.join(os.getenv("GISBASE"), "GPL.TXT") if os.path.exists(licfile): - licenceFile = open(licfile) - license = "".join(licenceFile.readlines()) - licenceFile.close() + with open(licfile) as licenceFile: + license = "".join(licenceFile.readlines()) else: license = _("%s file missing") % "GPL.TXT" # put text into a scrolling panel @@ -650,10 +648,10 @@ def _pageStats(self): fname = "translation_status.json" statsfile = os.path.join(os.getenv("GISBASE"), fname) if os.path.exists(statsfile): - statsFile = open(statsfile) import json - jsStats = json.load(statsFile) + with open(statsfile) as statsFile: + jsStats = json.load(statsFile) else: jsStats = None self.statswin = ScrolledPanel(self.aboutNotebook) diff --git a/gui/wxpython/gui_core/gselect.py b/gui/wxpython/gui_core/gselect.py index 248d40de073..729f38a5d30 100644 --- a/gui/wxpython/gui_core/gselect.py +++ b/gui/wxpython/gui_core/gselect.py @@ -832,17 +832,15 @@ def __init__(self, map): def _CheckDBConnection(self): """Check DB connection""" - nuldev = open(os.devnull, "w+") - # if map is not defined (happens with vnet initialization) or it - # doesn't exist - try: - self.layers = gs.vector_db(map=self.map, stderr=nuldev) - except CalledModuleError: - return False - finally: # always close nuldev - nuldev.close() + with open(os.devnull, "w+") as nuldev: + # if map is not defined (happens with vnet initialization) or it + # doesn't exist + try: + self.layers = gs.vector_db(map=self.map, stderr=nuldev) + except CalledModuleError: + return False - return bool(len(self.layers.keys()) > 0) + return bool(len(self.layers.keys()) > 0) def _DescribeTables(self): """Describe linked tables""" diff --git a/gui/wxpython/image2target/ii2t_gis_set.py b/gui/wxpython/image2target/ii2t_gis_set.py index 0329516e04a..44752e0e384 100644 --- a/gui/wxpython/image2target/ii2t_gis_set.py +++ b/gui/wxpython/image2target/ii2t_gis_set.py @@ -104,9 +104,8 @@ def __init__(self, parent=None, id=wx.ID_ANY, style=wx.DEFAULT_FRAME_STYLE): # labels # crashes when LOCATION doesn't exist # get version & revision - versionFile = open(os.path.join(globalvar.ETCDIR, "VERSIONNUMBER")) - versionLine = versionFile.readline().rstrip("\n") - versionFile.close() + with open(os.path.join(globalvar.ETCDIR, "VERSIONNUMBER")) as versionFile: + versionLine = versionFile.readline().rstrip("\n") try: grassVersion, grassRevision = versionLine.split(" ", 1) if grassVersion.endswith("dev"): diff --git a/gui/wxpython/lmgr/workspace.py b/gui/wxpython/lmgr/workspace.py index dd83c1a6f22..29b60443223 100644 --- a/gui/wxpython/lmgr/workspace.py +++ b/gui/wxpython/lmgr/workspace.py @@ -431,36 +431,31 @@ def SaveToFile(self, filename): """Save layer tree layout to workspace file :return: True on success, False on error """ - tmpfile = tempfile.TemporaryFile(mode="w+b") - try: - WriteWorkspaceFile(lmgr=self.lmgr, file=tmpfile) - except Exception as e: - GError( - parent=self.lmgr, - message=_( - "Writing current settings to workspace file <%s> failed.\n" - "Error details: %s" + with tempfile.TemporaryFile(mode="w+b") as tmpfile: + try: + WriteWorkspaceFile(lmgr=self.lmgr, file=tmpfile) + except Exception as e: + GError( + parent=self.lmgr, + message=_( + "Writing current settings to workspace file <%s> failed.\n" + "Error details: %s" + ) + % (tmpfile, str(e)), ) - % (tmpfile, str(e)), - ) - return False - - try: - mfile = open(filename, "wb") - tmpfile.seek(0) - for line in tmpfile.readlines(): - mfile.write(line) - except OSError: - GError( - parent=self.lmgr, - message=_("Unable to open file <%s> for writing.") % filename, - ) - return False - - mfile.close() - + return False + try: + with open(filename, "wb") as mfile: + tmpfile.seek(0) + for line in tmpfile.readlines(): + mfile.write(line) + except OSError: + GError( + parent=self.lmgr, + message=_("Unable to open file <%s> for writing.") % filename, + ) + return False self.AddFileToHistory(file_path=filename) - return True def CanClosePage(self, caption): diff --git a/gui/wxpython/location_wizard/wizard.py b/gui/wxpython/location_wizard/wizard.py index c12fb22860f..fef439d885c 100644 --- a/gui/wxpython/location_wizard/wizard.py +++ b/gui/wxpython/location_wizard/wizard.py @@ -2540,89 +2540,86 @@ def __readData(self): """Get georeferencing information from tables in $GISBASE/etc/proj""" # read projection and parameters - f = open(os.path.join(globalvar.ETCDIR, "proj", "parms.table")) self.projections = {} self.projdesc = {} - for line in f: - line = line.strip() - try: - proj, projdesc, params = line.split(":") - paramslist = params.split(";") - plist = [] - for p in paramslist: - if p == "": - continue - p1, pdefault = p.split(",") - pterm, pask = p1.split("=") - p = [pterm.strip(), pask.strip(), pdefault.strip()] - plist.append(p) - self.projections[proj.lower().strip()] = (projdesc.strip(), plist) - self.projdesc[proj.lower().strip()] = projdesc.strip() - except: - continue - f.close() + with open(os.path.join(globalvar.ETCDIR, "proj", "parms.table")) as f: + for line in f: + line = line.strip() + try: + proj, projdesc, params = line.split(":") + paramslist = params.split(";") + plist = [] + for p in paramslist: + if p == "": + continue + p1, pdefault = p.split(",") + pterm, pask = p1.split("=") + p = [pterm.strip(), pask.strip(), pdefault.strip()] + plist.append(p) + self.projections[proj.lower().strip()] = (projdesc.strip(), plist) + self.projdesc[proj.lower().strip()] = projdesc.strip() + except: + continue # read datum definitions - f = open(os.path.join(globalvar.ETCDIR, "proj", "datum.table")) self.datums = {} paramslist = [] - for line in f: - line = line.expandtabs(1) - line = line.strip() - if line == "" or line[0] == "#": - continue - datum, info = line.split(" ", 1) - info = info.strip() - datumdesc, params = info.split(" ", 1) - datumdesc = datumdesc.strip('"') - paramlist = params.split() - ellipsoid = paramlist.pop(0) - self.datums[datum] = (ellipsoid, datumdesc.replace("_", " "), paramlist) - f.close() + with open(os.path.join(globalvar.ETCDIR, "proj", "datum.table")) as f: + for line in f: + line = line.expandtabs(1) + line = line.strip() + if line == "" or line[0] == "#": + continue + datum, info = line.split(" ", 1) + info = info.strip() + datumdesc, params = info.split(" ", 1) + datumdesc = datumdesc.strip('"') + paramlist = params.split() + ellipsoid = paramlist.pop(0) + self.datums[datum] = (ellipsoid, datumdesc.replace("_", " "), paramlist) # read Earth-based ellipsiod definitions - f = open(os.path.join(globalvar.ETCDIR, "proj", "ellipse.table")) self.ellipsoids = {} - for line in f: - line = line.expandtabs(1) - line = line.strip() - if line == "" or line[0] == "#": - continue - ellipse, rest = line.split(" ", 1) - rest = rest.strip('" ') - desc, params = rest.split('"', 1) - desc = desc.strip('" ') - paramslist = params.split() - self.ellipsoids[ellipse] = (desc, paramslist) - f.close() + with open(os.path.join(globalvar.ETCDIR, "proj", "ellipse.table")) as f: + for line in f: + line = line.expandtabs(1) + line = line.strip() + if line == "" or line[0] == "#": + continue + ellipse, rest = line.split(" ", 1) + rest = rest.strip('" ') + desc, params = rest.split('"', 1) + desc = desc.strip('" ') + paramslist = params.split() + self.ellipsoids[ellipse] = (desc, paramslist) # read Planetary ellipsiod definitions - f = open(os.path.join(globalvar.ETCDIR, "proj", "ellipse.table.solar.system")) self.planetary_ellipsoids = {} - for line in f: - line = line.expandtabs(1) - line = line.strip() - if line == "" or line[0] == "#": - continue - ellipse, rest = line.split(" ", 1) - rest = rest.strip('" ') - desc, params = rest.split('"', 1) - desc = desc.strip('" ') - paramslist = params.split() - self.planetary_ellipsoids[ellipse] = (desc, paramslist) - f.close() + with open( + os.path.join(globalvar.ETCDIR, "proj", "ellipse.table.solar.system") + ) as f: + for line in f: + line = line.expandtabs(1) + line = line.strip() + if line == "" or line[0] == "#": + continue + ellipse, rest = line.split(" ", 1) + rest = rest.strip('" ') + desc, params = rest.split('"', 1) + desc = desc.strip('" ') + paramslist = params.split() + self.planetary_ellipsoids[ellipse] = (desc, paramslist) # read projection parameter description and parsing table - f = open(os.path.join(globalvar.ETCDIR, "proj", "desc.table")) self.paramdesc = {} - for line in f: - line = line.strip() - try: - pparam, datatype, proj4term, desc = line.split(":") - self.paramdesc[pparam] = (datatype, proj4term, desc) - except: - continue - f.close() + with open(os.path.join(globalvar.ETCDIR, "proj", "desc.table")) as f: + for line in f: + line = line.strip() + try: + pparam, datatype, proj4term, desc = line.split(":") + self.paramdesc[pparam] = (datatype, proj4term, desc) + except: + continue def OnWizFinished(self): """Wizard finished, create new location diff --git a/gui/wxpython/mapdisp/main.py b/gui/wxpython/mapdisp/main.py index 6449bc35d7c..8765bd770f8 100644 --- a/gui/wxpython/mapdisp/main.py +++ b/gui/wxpython/mapdisp/main.py @@ -133,9 +133,8 @@ def GetLayersFromCmdFile(self): "d.to.rast" ): dCmd = lines[-1].strip() - fd = open(self.cmdfile, "w") - fd.writelines(lines[:-1]) - fd.close() + with open(self.cmdfile, "w") as fd: + fd.writelines(lines[:-1]) if lines[-1].startswith("d.out.file"): self.saveToFile.emit(cmd=utils.split(dCmd)) else: @@ -143,9 +142,8 @@ def GetLayersFromCmdFile(self): return if lines[-1].startswith("d.what"): dWhatCmd = lines[-1].strip() - fd = open(self.cmdfile, "w") - fd.writelines(lines[:-1]) - fd.close() + with open(self.cmdfile, "w") as fd: + fd.writelines(lines[:-1]) if "=" in utils.split(dWhatCmd)[1]: maps = utils.split(dWhatCmd)[1].split("=")[1].split(",") else: @@ -655,11 +653,10 @@ def GetMapDisplay(self): # create pid file pidFile = os.path.join(monPath, "pid") - fd = open(pidFile, "w") - if not fd: - grass.fatal(_("Unable to create file <%s>") % pidFile) - fd.write("%s\n" % os.getpid()) - fd.close() + with open(pidFile, "w") as fd: + if not fd: + grass.fatal(_("Unable to create file <%s>") % pidFile) + fd.write("%s\n" % os.getpid()) RunCommand("g.gisenv", set="MONITOR_%s_PID=%d" % (monName.upper(), os.getpid())) diff --git a/gui/wxpython/modules/colorrules.py b/gui/wxpython/modules/colorrules.py index d5d74eaf08e..8b5fabbec00 100644 --- a/gui/wxpython/modules/colorrules.py +++ b/gui/wxpython/modules/colorrules.py @@ -687,9 +687,8 @@ def OnSaveRulesFile(self, event): GMessage(message=_("Nothing to save."), parent=self) return - fd = open(path, "w") - fd.write(rulestxt) - fd.close() + with open(path, "w") as fd: + fd.write(rulestxt) def OnLoadRulesFile(self, event): """Load color table from file""" @@ -699,9 +698,8 @@ def OnLoadRulesFile(self, event): self.rulesPanel.Clear() - fd = open(path) - self.ReadColorTable(ctable=fd.read()) - fd.close() + with open(path) as fd: + self.ReadColorTable(ctable=fd.read()) def ReadColorTable(self, ctable): """Read color table @@ -801,11 +799,8 @@ def CreateColorTable(self, tmp=False) -> bool: return False gtemp = utils.GetTempfile() - output = open(gtemp, "w") - try: + with open(gtemp, "w") as output: output.write(rulestxt) - finally: - output.close() cmd = [ "%s.colors" % self.mapType[0], # r.colors/v.colors @@ -1826,11 +1821,8 @@ def UpdateColorColumn(self, tmp): return False gtemp = utils.GetTempfile() - output = open(gtemp, "w") - try: + with open(gtemp, "w") as output: output.write(rulestxt) - finally: - output.close() RunCommand("db.execute", parent=self, input=gtemp) return True diff --git a/gui/wxpython/psmap/frame.py b/gui/wxpython/psmap/frame.py index bb71fd856a5..c06396051a8 100644 --- a/gui/wxpython/psmap/frame.py +++ b/gui/wxpython/psmap/frame.py @@ -358,13 +358,12 @@ def OnPreview(self, event): def PSFile(self, filename=None, pdf=False): """Create temporary instructions file and run ps.map with output = filename""" instrFile = gs.tempfile() - instrFileFd = open(instrFile, mode="wb") - content = self.InstructionFile() - if not content: - return - instrFileFd.write(content) - instrFileFd.flush() - instrFileFd.close() + with open(instrFile, mode="wb") as instrFileFd: + content = self.InstructionFile() + if not content: + return + instrFileFd.write(content) + instrFileFd.flush() temp = False regOld = gs.region(env=self.env) @@ -598,12 +597,11 @@ def OnInstructionFile(self, event): wildcard="*.psmap|*.psmap|Text file(*.txt)|*.txt|All files(*.*)|*.*" ) if filename: - instrFile = open(filename, "wb") - content = self.InstructionFile() - if not content: - return - instrFile.write(content) - instrFile.close() + with open(filename, "wb") as instrFile: + content = self.InstructionFile() + if not content: + return + instrFile.write(content) def OnLoadFile(self, event): """Launch file dialog and load selected file""" @@ -1068,13 +1066,12 @@ def getInitMap(self): """Create default map frame when no map is selected, needed for coordinates in map units""" instrFile = gs.tempfile() - instrFileFd = open(instrFile, mode="wb") - content = self.InstructionFile() - if not content: - return - instrFileFd.write(content) - instrFileFd.flush() - instrFileFd.close() + with open(instrFile, mode="wb") as instrFileFd: + content = self.InstructionFile() + if not content: + return + instrFileFd.write(content) + instrFileFd.flush() page = self.instruction.FindInstructionByType("page") mapInitRect = GetMapBounds( diff --git a/gui/wxpython/rdigit/controller.py b/gui/wxpython/rdigit/controller.py index 9b70a2cc468..9617e1d5178 100644 --- a/gui/wxpython/rdigit/controller.py +++ b/gui/wxpython/rdigit/controller.py @@ -648,9 +648,8 @@ def _rasterize(self, text, bufferDist, mapType, tempRaster): :return: output raster map name as a result of digitization """ output = "x" + str(uuid.uuid4())[:8] - asciiFile = tempfile.NamedTemporaryFile(mode="w", delete=False) - asciiFile.write("\n".join(text)) - asciiFile.close() + with tempfile.NamedTemporaryFile(mode="w", delete=False) as asciiFile: + asciiFile.write("\n".join(text)) if bufferDist: bufferDist /= 2.0 diff --git a/gui/wxpython/rlisetup/sampling_frame.py b/gui/wxpython/rlisetup/sampling_frame.py index bc6f71f16c5..e62737449e6 100644 --- a/gui/wxpython/rlisetup/sampling_frame.py +++ b/gui/wxpython/rlisetup/sampling_frame.py @@ -255,18 +255,16 @@ def nextRegion(self, next=True, area=None): ) def writeArea(self, coords, rasterName): - polyfile = tempfile.NamedTemporaryFile(delete=False) - polyfile.write("AREA\n") - for coor in coords: - east, north = coor - point = " %s %s\n" % (east, north) - polyfile.write(point) - - catbuf = "=%d a\n" % self.catId - polyfile.write(catbuf) - self.catId += 1 - - polyfile.close() + with tempfile.NamedTemporaryFile(delete=False) as polyfile: + polyfile.write("AREA\n") + for coor in coords: + east, north = coor + point = " %s %s\n" % (east, north) + polyfile.write(point) + catbuf = "=%d a\n" % self.catId + polyfile.write(catbuf) + self.catId += 1 + region_settings = grass.parse_command("g.region", flags="p", delimiter=":") pname = polyfile.name.split("/")[-1] tmpraster = "rast_" + pname diff --git a/gui/wxpython/rlisetup/wizard.py b/gui/wxpython/rlisetup/wizard.py index fb23affbd25..46c7f3eae6a 100644 --- a/gui/wxpython/rlisetup/wizard.py +++ b/gui/wxpython/rlisetup/wizard.py @@ -158,11 +158,10 @@ def __init__(self, parent): def _write_confile(self): """Write the configuration file""" - f = open(os.path.join(self.rlipath, self.startpage.conf_name), "w") - self.rasterinfo = grast.raster_info(self.startpage.rast) - self._write_region(f) - self._write_area(f) - f.close() + with open(os.path.join(self.rlipath, self.startpage.conf_name), "w") as f: + self.rasterinfo = grast.raster_info(self.startpage.rast) + self._write_region(f) + self._write_area(f) def _temp_region(self): # save current settings: diff --git a/gui/wxpython/tools/update_menudata.py b/gui/wxpython/tools/update_menudata.py index 18c542c71f2..99dcde2a72e 100644 --- a/gui/wxpython/tools/update_menudata.py +++ b/gui/wxpython/tools/update_menudata.py @@ -140,31 +140,30 @@ def main(argv=None): print(sys.stderr, __doc__, file=sys.stderr) return 1 - nuldev = open(os.devnull, "w+") grass.info("Step 1: running make...") - grass.call(["make"], stderr=nuldev) - grass.info("Step 2: parsing modules...") - modules = {} - modules = parseModules() - grass.info("Step 3: reading menu data...") - data = LayerManagerMenuData() - grass.info("Step 4: updating menu data...") - updateData(data, modules) - - if printDiff: - tempFile = tempfile.NamedTemporaryFile() - grass.info("Step 5: diff menu data...") - writeData(data, tempFile.name) - - grass.call( - ["diff", "-u", os.path.join("xml", "menudata.xml"), tempFile.name], - stderr=nuldev, - ) - else: - grass.info("Step 5: writing menu data (menudata.xml)...") - writeData(data) + with open(os.devnull, "w+") as nuldev: + grass.call(["make"], stderr=nuldev) + grass.info("Step 2: parsing modules...") + modules = {} + modules = parseModules() + grass.info("Step 3: reading menu data...") + data = LayerManagerMenuData() + grass.info("Step 4: updating menu data...") + updateData(data, modules) + + if printDiff: + with tempfile.NamedTemporaryFile() as tempFile: + grass.info("Step 5: diff menu data...") + writeData(data, tempFile.name) + grass.call( + ["diff", "-u", os.path.join("xml", "menudata.xml"), tempFile.name], + stderr=nuldev, + ) + else: + grass.info("Step 5: writing menu data (menudata.xml)...") + writeData(data) - return 0 + return 0 if __name__ == "__main__": diff --git a/gui/wxpython/vdigit/mapwindow.py b/gui/wxpython/vdigit/mapwindow.py index 08a86857c12..d3c8882354a 100644 --- a/gui/wxpython/vdigit/mapwindow.py +++ b/gui/wxpython/vdigit/mapwindow.py @@ -394,40 +394,37 @@ def _geomAttrbUpdate(self, fids): return dbInfo = gselect.VectorDBInfo(vectorName) - sqlfile = tempfile.NamedTemporaryFile(mode="w") - for fid in fids: - for layer, cats in self.digit.GetLineCats(fid).items(): - table = dbInfo.GetTable(layer) - for attrb, item in vdigit["geomAttr"].items(): - val = -1 - if attrb == "length": - val = self.digit.GetLineLength(fid) - type = attrb - elif attrb == "area": - val = self.digit.GetAreaSize(fid) - type = attrb - elif attrb == "perimeter": - val = self.digit.GetAreaPerimeter(fid) - type = "length" - - if val < 0: - continue - val = UnitsConvertValue(val, type, item["units"]) - - for cat in cats: - sqlfile.write( - "UPDATE %s SET %s = %f WHERE %s = %d;\n" - % ( - table, - item["column"], - val, - dbInfo.GetKeyColumn(layer), - cat, + with tempfile.NamedTemporaryFile(mode="w") as sqlfile: + for fid in fids: + for layer, cats in self.digit.GetLineCats(fid).items(): + table = dbInfo.GetTable(layer) + for attrb, item in vdigit["geomAttr"].items(): + val = -1 + if attrb == "length": + val = self.digit.GetLineLength(fid) + type = attrb + elif attrb == "area": + val = self.digit.GetAreaSize(fid) + type = attrb + elif attrb == "perimeter": + val = self.digit.GetAreaPerimeter(fid) + type = "length" + if val < 0: + continue + val = UnitsConvertValue(val, type, item["units"]) + for cat in cats: + sqlfile.write( + "UPDATE %s SET %s = %f WHERE %s = %d;\n" + % ( + table, + item["column"], + val, + dbInfo.GetKeyColumn(layer), + cat, + ) ) - ) - - sqlfile.file.flush() - RunCommand("db.execute", parent=True, quiet=True, input=sqlfile.name) + sqlfile.file.flush() + RunCommand("db.execute", parent=True, quiet=True, input=sqlfile.name) def _updateATM(self): """Update open Attribute Table Manager From 44f9874f6c3990a7030227f231f6f2b82765ffb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sat, 4 Jan 2025 00:38:09 +0000 Subject: [PATCH 03/21] gui: Use context manager for opening files and temporary files --- gui/wxpython/animation/temporal_manager.py | 100 +++++++------- gui/wxpython/core/toolboxes.py | 5 +- gui/wxpython/dbmgr/base.py | 21 +-- gui/wxpython/gcp/manager.py | 149 ++++++++------------- gui/wxpython/gui_core/ghelp.py | 128 +++++++++--------- gui/wxpython/gui_core/widgets.py | 35 +++-- gui/wxpython/image2target/ii2t_gis_set.py | 5 +- gui/wxpython/image2target/ii2t_manager.py | 33 +---- gui/wxpython/mapdisp/main.py | 5 +- gui/wxpython/modules/mcalc_builder.py | 10 +- gui/wxpython/photo2image/ip2i_manager.py | 11 +- gui/wxpython/rlisetup/frame.py | 12 +- gui/wxpython/vnet/vnet_core.py | 52 ++++--- gui/wxpython/vnet/vnet_data.py | 42 +++--- gui/wxpython/vnet/widgets.py | 12 +- 15 files changed, 264 insertions(+), 356 deletions(-) diff --git a/gui/wxpython/animation/temporal_manager.py b/gui/wxpython/animation/temporal_manager.py index 814a48fcac1..136c154a5cb 100644 --- a/gui/wxpython/animation/temporal_manager.py +++ b/gui/wxpython/animation/temporal_manager.py @@ -411,28 +411,26 @@ def createAbsoluteInterval(): gs.mapcalc(exp="temp_6 = rand(0, 650)", overwrite=True) n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() - fd = open(n1, "w") - fd.write( - "prec_1|2001-01-01|2001-02-01\n" - "prec_2|2001-04-01|2001-05-01\n" - "prec_3|2001-05-01|2001-09-01\n" - "prec_4|2001-09-01|2002-01-01\n" - "prec_5|2002-01-01|2002-05-01\n" - "prec_6|2002-05-01|2002-07-01\n" - ) - fd.close() + with open(n1, "w") as fd: + fd.write( + "prec_1|2001-01-01|2001-02-01\n" + "prec_2|2001-04-01|2001-05-01\n" + "prec_3|2001-05-01|2001-09-01\n" + "prec_4|2001-09-01|2002-01-01\n" + "prec_5|2002-01-01|2002-05-01\n" + "prec_6|2002-05-01|2002-07-01\n" + ) n2 = gs.read_command("g.tempfile", pid=2, flags="d").strip() - fd = open(n2, "w") - fd.write( - "temp_1|2000-10-01|2001-01-01\n" - "temp_2|2001-04-01|2001-05-01\n" - "temp_3|2001-05-01|2001-09-01\n" - "temp_4|2001-09-01|2002-01-01\n" - "temp_5|2002-01-01|2002-05-01\n" - "temp_6|2002-05-01|2002-07-01\n" - ) - fd.close() + with open(n2, "w") as fd: + fd.write( + "temp_1|2000-10-01|2001-01-01\n" + "temp_2|2001-04-01|2001-05-01\n" + "temp_3|2001-05-01|2001-09-01\n" + "temp_4|2001-09-01|2002-01-01\n" + "temp_5|2002-01-01|2002-05-01\n" + "temp_6|2002-05-01|2002-07-01\n" + ) name1 = "absinterval1" name2 = "absinterval2" gs.run_command( @@ -486,28 +484,26 @@ def createRelativeInterval(): gs.mapcalc(exp="temp_6 = rand(0, 650)", overwrite=True) n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() - fd = open(n1, "w") - fd.write( - "prec_1|1|4\n" - "prec_2|6|7\n" - "prec_3|7|10\n" - "prec_4|10|11\n" - "prec_5|11|14\n" - "prec_6|14|17\n" - ) - fd.close() + with open(n1, "w") as fd: + fd.write( + "prec_1|1|4\n" + "prec_2|6|7\n" + "prec_3|7|10\n" + "prec_4|10|11\n" + "prec_5|11|14\n" + "prec_6|14|17\n" + ) n2 = gs.read_command("g.tempfile", pid=2, flags="d").strip() - fd = open(n2, "w") - fd.write( - "temp_1|5|6\n" - "temp_2|6|7\n" - "temp_3|7|10\n" - "temp_4|10|11\n" - "temp_5|11|18\n" - "temp_6|19|22\n" - ) - fd.close() + with open(n2, "w") as fd: + fd.write( + "temp_1|5|6\n" + "temp_2|6|7\n" + "temp_3|7|10\n" + "temp_4|10|11\n" + "temp_5|11|18\n" + "temp_6|19|22\n" + ) name1 = "relinterval1" name2 = "relinterval2" gs.run_command( @@ -560,16 +556,15 @@ def createAbsolutePoint(): gs.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() - fd = open(n1, "w") - fd.write( - "prec_1|2001-01-01\n" - "prec_2|2001-03-01\n" - "prec_3|2001-04-01\n" - "prec_4|2001-05-01\n" - "prec_5|2001-08-01\n" - "prec_6|2001-09-01\n" - ) - fd.close() + with open(n1, "w") as fd: + fd.write( + "prec_1|2001-01-01\n" + "prec_2|2001-03-01\n" + "prec_3|2001-04-01\n" + "prec_4|2001-05-01\n" + "prec_5|2001-08-01\n" + "prec_6|2001-09-01\n" + ) name = "abspoint" gs.run_command( "t.create", @@ -608,9 +603,8 @@ def createRelativePoint(): gs.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() - fd = open(n1, "w") - fd.write("prec_1|1\nprec_2|3\nprec_3|5\nprec_4|7\nprec_5|11\nprec_6|13\n") - fd.close() + with open(n1, "w") as fd: + fd.write("prec_1|1\nprec_2|3\nprec_3|5\nprec_4|7\nprec_5|11\nprec_6|13\n") name = "relpoint" gs.run_command( "t.create", diff --git a/gui/wxpython/core/toolboxes.py b/gui/wxpython/core/toolboxes.py index d3b50cb1ea5..928c6cd835f 100644 --- a/gui/wxpython/core/toolboxes.py +++ b/gui/wxpython/core/toolboxes.py @@ -205,9 +205,8 @@ def getMenudataFile(userRootFile, newFile, fallback): try: xml = _getXMLString(tree.getroot()) - fh = open(menudataFile, "w") - fh.write(xml) - fh.close() + with open(menudataFile, "w") as fh: + fh.write(xml) return menudataFile except Exception: _debug( diff --git a/gui/wxpython/dbmgr/base.py b/gui/wxpython/dbmgr/base.py index 20ddbc47f25..348e4555641 100644 --- a/gui/wxpython/dbmgr/base.py +++ b/gui/wxpython/dbmgr/base.py @@ -4008,17 +4008,18 @@ def Update(self, driver, database, table, column): return fd, sqlFilePath = tempfile.mkstemp(text=True) - sqlFile = open(sqlFilePath, "w") stats = ["count", "min", "max", "avg", "sum", "null"] - for fn in stats: - if fn == "null": - sqlFile.write( - "select count(*) from %s where %s is null;%s" - % (table, column, "\n") - ) - else: - sqlFile.write("select %s(%s) from %s;%s" % (fn, column, table, "\n")) - sqlFile.close() + with open(sqlFilePath, "w") as sqlFile: + for fn in stats: + if fn == "null": + sqlFile.write( + "select count(*) from %s where %s is null;%s" + % (table, column, "\n") + ) + else: + sqlFile.write( + "select %s(%s) from %s;%s" % (fn, column, table, "\n") + ) dataStr = RunCommand( "db.select", diff --git a/gui/wxpython/gcp/manager.py b/gui/wxpython/gcp/manager.py index 43bbfdc1b8e..78749f762c5 100644 --- a/gui/wxpython/gcp/manager.py +++ b/gui/wxpython/gcp/manager.py @@ -86,21 +86,14 @@ def getSmallUpArrowImage(): - stream = open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") - try: + with open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") as stream: img = wx.Image(stream) - finally: - stream.close() - return img + return img def getSmallDnArrowImage(): - stream = open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb") - try: + with open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb") as stream: img = wx.Image(stream) - finally: - stream.close() - stream.close() return img @@ -123,16 +116,13 @@ def __init__(self, parent, giface): # self.target_gisrc = os.environ["GISRC"] self.gisrc_dict = {} - try: - f = open(self.target_gisrc) + with open(self.target_gisrc) as f: for line in f: line = line.replace("\n", "").strip() if len(line) < 1: continue key, value = line.split(":", 1) self.gisrc_dict[key.strip()] = value.strip() - finally: - f.close() self.currentlocation = self.gisrc_dict["LOCATION_NAME"] self.currentmapset = self.gisrc_dict["MAPSET"] @@ -345,13 +335,9 @@ def SetSrcEnv(self, location, mapset): self.source_gisrc = utils.GetTempfile() - try: - f = open(self.source_gisrc, mode="w") + with open(self.source_gisrc, mode="w") as f: for line in self.gisrc_dict.items(): f.write(line[0] + ": " + line[1] + "\n") - finally: - f.close() - return True def SwitchEnv(self, grc): @@ -1515,41 +1501,41 @@ def SaveGCPs(self, event): """ self.GCPcount = 0 try: - f = open(self.file["points"], mode="w") - # use os.linesep or '\n' here ??? - f.write("# Ground Control Points File\n") - f.write("# \n") - f.write("# target location: " + self.currentlocation + "\n") - f.write("# target mapset: " + self.currentmapset + "\n") - f.write("#\tsource\t\ttarget\t\tstatus\n") - f.write("#\teast\tnorth\teast\tnorth\t(1=ok, 0=ignore)\n") - f.write( - "#----------------------- ----------------------- ---------------\n" # noqa: E501 - ) - - for index in range(self.list.GetItemCount()): - if self.list.IsItemChecked(index): - check = "1" - self.GCPcount += 1 - else: - check = "0" - coord0 = self.list.GetItem(index, 1).GetText() - coord1 = self.list.GetItem(index, 2).GetText() - coord2 = self.list.GetItem(index, 3).GetText() - coord3 = self.list.GetItem(index, 4).GetText() + with open(self.file["points"], mode="w") as f: + # use os.linesep or '\n' here ??? + f.write("# Ground Control Points File\n") + f.write("# \n") + f.write("# target location: " + self.currentlocation + "\n") + f.write("# target mapset: " + self.currentmapset + "\n") + f.write("#\tsource\t\ttarget\t\tstatus\n") + f.write("#\teast\tnorth\teast\tnorth\t(1=ok, 0=ignore)\n") f.write( - coord0 - + " " - + coord1 - + " " - + coord2 - + " " - + coord3 - + " " - + check - + "\n" + "#----------------------- ----------------------- ---------------\n" # noqa: E501 ) + for index in range(self.list.GetItemCount()): + if self.list.IsItemChecked(index): + check = "1" + self.GCPcount += 1 + else: + check = "0" + coord0 = self.list.GetItem(index, 1).GetText() + coord1 = self.list.GetItem(index, 2).GetText() + coord2 = self.list.GetItem(index, 3).GetText() + coord3 = self.list.GetItem(index, 4).GetText() + f.write( + coord0 + + " " + + coord1 + + " " + + coord2 + + " " + + coord3 + + " " + + check + + "\n" + ) + except OSError as err: GError( parent=self, @@ -1563,8 +1549,6 @@ def SaveGCPs(self, event): ) return - f.close() - # if event != None save also to backup file if event: shutil.copy(self.file["points"], self.file["points_bak"]) @@ -1588,27 +1572,26 @@ def ReadGCPs(self): GError(parent=self, message=_("target mapwin not defined")) try: - f = open(self.file["points"]) GCPcnt = 0 + with open(self.file["points"]) as f: + for line in f: + if line[0] == "#" or line == "": + continue + line = line.replace("\n", "").strip() + coords = list(map(float, line.split())) + if coords[4] == 1: + check = True + self.GCPcount += 1 + else: + check = False - for line in f: - if line[0] == "#" or line == "": - continue - line = line.replace("\n", "").strip() - coords = list(map(float, line.split())) - if coords[4] == 1: - check = True - self.GCPcount += 1 - else: - check = False - - self.AddGCP(event=None) - self.SetGCPData("source", (coords[0], coords[1]), sourceMapWin) - self.SetGCPData("target", (coords[2], coords[3]), targetMapWin) - index = self.list.GetSelected() - if index != wx.NOT_FOUND: - self.list.CheckItem(index, check) - GCPcnt += 1 + self.AddGCP(event=None) + self.SetGCPData("source", (coords[0], coords[1]), sourceMapWin) + self.SetGCPData("target", (coords[2], coords[3]), targetMapWin) + index = self.list.GetSelected() + if index != wx.NOT_FOUND: + self.list.CheckItem(index, check) + GCPcnt += 1 except OSError as err: GError( @@ -1623,8 +1606,6 @@ def ReadGCPs(self): ) return - f.close() - if GCPcnt == 0: # 3 gcp is minimum for i in range(3): @@ -1830,16 +1811,13 @@ def OnGeorect(self, event): self.grwiz.SwitchEnv("source") # make list of vectors to georectify from VREF - f = open(self.file["vgrp"]) vectlist = [] - try: + with open(self.file["vgrp"]) as f: for vect in f: vect = vect.strip("\n") if len(vect) < 1: continue vectlist.append(vect) - finally: - f.close() # georectify each vector in VREF using v.rectify for vect in vectlist: @@ -2118,8 +2096,7 @@ def GetNewExtent(self, region, map=None): "w": 0.0, } - try: - f = open(coord_file, mode="w") + with open(coord_file, mode="w") as f: # NW corner f.write(str(region["e"]) + " " + str(region["n"]) + "\n") # NE corner @@ -2128,8 +2105,6 @@ def GetNewExtent(self, region, map=None): f.write(str(region["w"]) + " " + str(region["n"]) + "\n") # SE corner f.write(str(region["w"]) + " " + str(region["s"]) + "\n") - finally: - f.close() # save GCPs to points file to make sure that all checked GCPs are used self.SaveGCPs(None) @@ -2693,8 +2668,7 @@ def __init__( self.listMap = CheckListBox(parent=self, id=wx.ID_ANY, choices=vectlist) if os.path.isfile(self.vgrpfile): - f = open(self.vgrpfile) - try: + with open(self.vgrpfile) as f: checked = [] for line in f: line = line.replace("\n", "") @@ -2702,8 +2676,6 @@ def __init__( continue checked.append(line.split("@")[0]) self.listMap.SetCheckedStrings(checked) - finally: - f.close() line = wx.StaticLine( parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL @@ -2767,12 +2739,9 @@ def MakeVGroup(self): if not os.path.exists(dirname): os.makedirs(dirname) - f = open(self.vgrpfile, mode="w") - try: + with open(self.vgrpfile, mode="w") as f: for vect in vgrouplist: f.write(vect + "\n") - finally: - f.close() class EditGCP(wx.Dialog): diff --git a/gui/wxpython/gui_core/ghelp.py b/gui/wxpython/gui_core/ghelp.py index fd3991e1e6d..63f7eff2280 100644 --- a/gui/wxpython/gui_core/ghelp.py +++ b/gui/wxpython/gui_core/ghelp.py @@ -382,33 +382,31 @@ def _pageContributors(self, extra=False): else: contribfile = os.path.join(os.getenv("GISBASE"), "contributors.csv") if os.path.exists(contribfile): - contribFile = codecs.open(contribfile, encoding="utf-8", mode="r") contribs = [] errLines = [] - for line in contribFile.readlines()[1:]: - line = line.rstrip("\n") - try: + with codecs.open(contribfile, encoding="utf-8", mode="r") as contribFile: + for line in contribFile.readlines()[1:]: + line = line.rstrip("\n") + try: + if extra: + name, email, country, rfc2_agreed = line.split(",") + else: + ( + cvs_id, + name, + email, + country, + osgeo_id, + rfc2_agreed, + orcid, + ) = line.split(",") + except ValueError: + errLines.append(line) + continue if extra: - name, email, country, rfc2_agreed = line.split(",") + contribs.append((name, email, country)) else: - ( - cvs_id, - name, - email, - country, - osgeo_id, - rfc2_agreed, - orcid, - ) = line.split(",") - except ValueError: - errLines.append(line) - continue - if extra: - contribs.append((name, email, country)) - else: - contribs.append((name, email, country, osgeo_id, orcid)) - - contribFile.close() + contribs.append((name, email, country, osgeo_id, orcid)) if errLines: GError( @@ -467,21 +465,20 @@ def _pageTranslators(self): """Translators info""" translatorsfile = os.path.join(os.getenv("GISBASE"), "translators.csv") if os.path.exists(translatorsfile): - translatorsFile = codecs.open(translatorsfile, encoding="utf-8", mode="r") translators = {} errLines = [] - for line in translatorsFile.readlines()[1:]: - line = line.rstrip("\n") - try: - name, email, languages = line.split(",") - except ValueError: - errLines.append(line) - continue - for language in languages.split(" "): - if language not in translators: - translators[language] = [] - translators[language].append((name, email)) - translatorsFile.close() + with codecs.open(translatorsfile, encoding="utf-8", mode="r") as fd: + for line in fd.readlines()[1:]: + line = line.rstrip("\n") + try: + name, email, languages = line.split(",") + except ValueError: + errLines.append(line) + continue + for language in languages.split(" "): + if language not in translators: + translators[language] = [] + translators[language].append((name, email)) if errLines: GError( @@ -808,38 +805,39 @@ def fillContentsFromFile(self, htmlFile, skipDescription=True): try: contents = [] skip = False - for line in open(htmlFile, "rb"): - if "DESCRIPTION" in line: - skip = False - if not skip: - # do skip the options description if requested - if "SYNOPSIS" in line: - skip = skipDescription - else: - # FIXME: find only first item - findALink = aLink.search(line) - if findALink is not None: - contents.append( - aLink.sub( - findALink.group(1) - + self.fspath - + findALink.group(2), - line, + with open(htmlFile, "rb") as fd: + for line in fd: + if "DESCRIPTION" in line: + skip = False + if not skip: + # do skip the options description if requested + if "SYNOPSIS" in line: + skip = skipDescription + else: + # FIXME: find only first item + findALink = aLink.search(line) + if findALink is not None: + contents.append( + aLink.sub( + findALink.group(1) + + self.fspath + + findALink.group(2), + line, + ) ) - ) - findImgLink = imgLink.search(line) - if findImgLink is not None: - contents.append( - imgLink.sub( - findImgLink.group(1) - + self.fspath - + findImgLink.group(2), - line, + findImgLink = imgLink.search(line) + if findImgLink is not None: + contents.append( + imgLink.sub( + findImgLink.group(1) + + self.fspath + + findImgLink.group(2), + line, + ) ) - ) - if findALink is None and findImgLink is None: - contents.append(line) + if findALink is None and findImgLink is None: + contents.append(line) self.SetPage("".join(contents)) self.loaded = True except Exception: # The Manual file was not found diff --git a/gui/wxpython/gui_core/widgets.py b/gui/wxpython/gui_core/widgets.py index 40c9e6c5e19..47bd3a1957c 100644 --- a/gui/wxpython/gui_core/widgets.py +++ b/gui/wxpython/gui_core/widgets.py @@ -1520,30 +1520,29 @@ def _writeSettings(self): :return: -1 on failure """ try: - fd = open(self.settingsFile, "w") - fd.write("format_version=2.0\n") - for key, values in self._settings.items(): - first = True - for v in values: - # escaping characters - for e_ch in self.esc_chars: - v = v.replace(e_ch, self.esc_chars[self.e_char_i] + e_ch) - if first: + with open(self.settingsFile, "w") as fd: + fd.write("format_version=2.0\n") + for key, values in self._settings.items(): + first = True + for v in values: # escaping characters for e_ch in self.esc_chars: - key = key.replace( - e_ch, self.esc_chars[self.e_char_i] + e_ch - ) - fd.write("%s;%s;" % (key, v)) - first = False - else: - fd.write("%s;" % (v)) - fd.write("\n") + v = v.replace(e_ch, self.esc_chars[self.e_char_i] + e_ch) + if first: + # escaping characters + for e_ch in self.esc_chars: + key = key.replace( + e_ch, self.esc_chars[self.e_char_i] + e_ch + ) + fd.write("%s;%s;" % (key, v)) + first = False + else: + fd.write("%s;" % (v)) + fd.write("\n") except OSError: GError(parent=self, message=_("Unable to save settings")) return -1 - fd.close() return 0 diff --git a/gui/wxpython/image2target/ii2t_gis_set.py b/gui/wxpython/image2target/ii2t_gis_set.py index 44752e0e384..dcc8744f469 100644 --- a/gui/wxpython/image2target/ii2t_gis_set.py +++ b/gui/wxpython/image2target/ii2t_gis_set.py @@ -541,8 +541,7 @@ def _readGisRC(self): gisrc = os.getenv("GISRC") if gisrc and os.path.isfile(gisrc): - try: - rc = open(gisrc) + with open(gisrc) as rc: for line in rc: try: key, val = line.split(":", 1) @@ -551,8 +550,6 @@ def _readGisRC(self): _("Invalid line in GISRC file (%s):%s\n") % (e, line) ) grassrc[key.strip()] = DecodeString(val.strip()) - finally: - rc.close() return grassrc diff --git a/gui/wxpython/image2target/ii2t_manager.py b/gui/wxpython/image2target/ii2t_manager.py index 56adf91775b..5277711aa26 100644 --- a/gui/wxpython/image2target/ii2t_manager.py +++ b/gui/wxpython/image2target/ii2t_manager.py @@ -90,21 +90,14 @@ def getSmallUpArrowImage(): - stream = open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") - try: + with open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") as stream: img = wx.Image(stream) - finally: - stream.close() - return img + return img def getSmallDnArrowImage(): - stream = open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb") - try: + with open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb") as stream: img = wx.Image(stream) - finally: - stream.close() - stream.close() return img @@ -949,15 +942,12 @@ def OnEnterPage(self, event: WizardEvent | None = None) -> None: "VREF", ) - f = open(vgrpfile) - try: + with open(vgrpfile) as f: for vect in f: vect = vect.strip("\n") if len(vect) < 1: continue self.parent.src_maps.append(vect) - finally: - f.close() if len(self.parent.src_maps) < 1: GError( @@ -1782,16 +1772,13 @@ def OnGeorect(self, event): self.grwiz.SwitchEnv("source") # make list of vectors to georectify from VREF - f = open(self.file["vgrp"]) vectlist = [] - try: + with open(self.file["vgrp"]) as f: for vect in f: vect = vect.strip("\n") if len(vect) < 1: continue vectlist.append(vect) - finally: - f.close() # georectify each vector in VREF using v.rectify for vect in vectlist: @@ -2638,8 +2625,7 @@ def __init__( self.listMap = CheckListBox(parent=self, id=wx.ID_ANY, choices=vectlist) if os.path.isfile(self.vgrpfile): - f = open(self.vgrpfile) - try: + with open(self.vgrpfile) as f: checked = [] for line in f: line = line.replace("\n", "") @@ -2647,8 +2633,6 @@ def __init__( continue checked.append(line) self.listMap.SetCheckedStrings(checked) - finally: - f.close() line = wx.StaticLine( parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL @@ -2707,12 +2691,9 @@ def MakeVGroup(self): continue vgrouplist.append(self.listMap.GetString(item) + "@" + self.xymapset) - f = open(self.vgrpfile, mode="w") - try: + with open(self.vgrpfile, mode="w") as f: for vect in vgrouplist: f.write(vect + "\n") - finally: - f.close() class EditGCP(wx.Dialog): diff --git a/gui/wxpython/mapdisp/main.py b/gui/wxpython/mapdisp/main.py index 8765bd770f8..2083f49033a 100644 --- a/gui/wxpython/mapdisp/main.py +++ b/gui/wxpython/mapdisp/main.py @@ -123,9 +123,8 @@ def GetLayersFromCmdFile(self): nlayers = 0 try: - fd = open(self.cmdfile) - lines = fd.readlines() - fd.close() + with open(self.cmdfile) as fd: + lines = fd.readlines() # detect d.out.file, delete the line from the cmd file and export # graphics if len(lines) > 0: diff --git a/gui/wxpython/modules/mcalc_builder.py b/gui/wxpython/modules/mcalc_builder.py index 4294a9730de..d380da515a2 100644 --- a/gui/wxpython/modules/mcalc_builder.py +++ b/gui/wxpython/modules/mcalc_builder.py @@ -733,11 +733,8 @@ def OnSaveExpression(self, event): dlg.Destroy() return - try: - fobj = open(path, "w") + with open(path, "w") as fobj: fobj.write(mctxt) - finally: - fobj.close() dlg.Destroy() @@ -755,11 +752,8 @@ def OnLoadExpression(self, event): dlg.Destroy() return - try: - fobj = open(path) + with open(path) as fobj: mctxt = fobj.read() - finally: - fobj.close() try: result, exp = mctxt.split("=", 1) diff --git a/gui/wxpython/photo2image/ip2i_manager.py b/gui/wxpython/photo2image/ip2i_manager.py index dc5713e961a..0033944be94 100644 --- a/gui/wxpython/photo2image/ip2i_manager.py +++ b/gui/wxpython/photo2image/ip2i_manager.py @@ -67,21 +67,14 @@ def getSmallUpArrowImage(): - stream = open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") - try: + with open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") as stream: img = wx.Image(stream) - finally: - stream.close() return img def getSmallDnArrowImage(): - stream = open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb") - try: + with open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb") as stream: img = wx.Image(stream) - finally: - stream.close() - stream.close() return img diff --git a/gui/wxpython/rlisetup/frame.py b/gui/wxpython/rlisetup/frame.py index dd93e607cea..3563590d561 100644 --- a/gui/wxpython/rlisetup/frame.py +++ b/gui/wxpython/rlisetup/frame.py @@ -48,9 +48,8 @@ def __init__( parent=self.panel, id=wx.ID_ANY, style=wx.TE_MULTILINE, size=(-1, 75) ) self.textCtrl.Bind(wx.EVT_TEXT, self.OnFileText) - f = open(self.pathfile) - self.textCtrl.SetValue("".join(f.readlines())) - f.close() + with open(self.pathfile) as f: + self.textCtrl.SetValue("".join(f.readlines())) # BUTTONS #definition self.btn_close = Button(parent=self, id=wx.ID_EXIT) self.btn_ok = Button(parent=self, id=wx.ID_SAVE) @@ -107,11 +106,10 @@ def OnOk(self, event): ) if dlg.ShowModal() == wx.ID_YES: - f = codecs.open( + with codecs.open( self.pathfile, encoding=self.enc, mode="w", errors="replace" - ) - f.write(self.text + os.linesep) - f.close() + ) as f: + f.write(self.text + os.linesep) dlg.Destroy() self.Destroy() diff --git a/gui/wxpython/vnet/vnet_core.py b/gui/wxpython/vnet/vnet_core.py index b019256bb75..f4cfdbaea93 100644 --- a/gui/wxpython/vnet/vnet_core.py +++ b/gui/wxpython/vnet/vnet_core.py @@ -449,9 +449,8 @@ def _vnetPathRunAn(self, analysis, output, params, flags, catPts): ) self.coordsTmpFile = grass.tempfile() - coordsTmpFileOpened = open(self.coordsTmpFile, "w") - coordsTmpFileOpened.write(inpPoints) - coordsTmpFileOpened.close() + with open(self.coordsTmpFile, "w") as coordsTmpFileOpened: + coordsTmpFileOpened.write(inpPoints) if flags["t"]: cmdParams.append("-t") @@ -579,28 +578,26 @@ def _updateTtbByGlobalCosts(self, vectMapName, tlayer): driver, database = dbInfo.GetDbSettings(tlayer) sqlFile = grass.tempfile() - sqlFile_f = open(sqlFile, "w") - - for ival in intervals: - from_angle = ival[0] - to_angle = ival[1] - cost = ival[2] - - if to_angle < from_angle: - to_angle = math.pi * 2 + to_angle - # if angle < from_angle: - # angle = math.pi * 2 + angle - - where = ( - " WHERE (((angle < {0}) AND ({2} + angle >= {0} AND {2} + angle < {1}))" - " OR ((angle >= {0}) AND (angle >= {0} AND angle < {1})))" - " AND cost==0.0 " - ).format(str(from_angle), str(to_angle), str(math.pi * 2)) - - stm = ("UPDATE %s SET cost=%f " % (table, cost)) + where + ";\n" - sqlFile_f.write(stm) - - sqlFile_f.close() + with open(sqlFile, "w") as sqlFile_f: + for ival in intervals: + from_angle = ival[0] + to_angle = ival[1] + cost = ival[2] + + if to_angle < from_angle: + to_angle = math.pi * 2 + to_angle + # if angle < from_angle: + # angle = math.pi * 2 + angle + + where = ( + " WHERE" + " (((angle < {0}) AND ({2} + angle >= {0} AND {2} + angle < {1}))" + " OR ((angle >= {0}) AND (angle >= {0} AND angle < {1})))" + " AND cost==0.0 " + ).format(str(from_angle), str(to_angle), str(math.pi * 2)) + + stm = ("UPDATE %s SET cost=%f " % (table, cost)) + where + ";\n" + sqlFile_f.write(stm) # TODO improve parser and run in thread @@ -671,9 +668,8 @@ def _runAn(self, analysis, output, params, flags, catPts): # TODO better tmp files cleanup (make class for managing tmp files) self.tmpPtsAsciiFile = grass.tempfile() - tmpPtsAsciiFileOpened = open(self.tmpPtsAsciiFile, "w") - tmpPtsAsciiFileOpened.write(pt_ascii) - tmpPtsAsciiFileOpened.close() + with open(self.tmpPtsAsciiFile, "w") as tmpPtsAsciiFileOpened: + tmpPtsAsciiFileOpened.write(pt_ascii) self.tmpInPts = AddTmpMapAnalysisMsg("vnet_tmp_in_pts", self.tmp_maps) if not self.tmpInPts: diff --git a/gui/wxpython/vnet/vnet_data.py b/gui/wxpython/vnet/vnet_data.py index 9dd1bff4f66..e8e05839e70 100644 --- a/gui/wxpython/vnet/vnet_data.py +++ b/gui/wxpython/vnet/vnet_data.py @@ -1144,15 +1144,11 @@ def SaveHistStep(self): self.currHistStep = 0 newHistFile = grass.tempfile() - newHist = open(newHistFile, "w") + with open(newHistFile, "w") as newHist: + self._saveNewHistStep(newHist) + with open(self.histFile) as oldHist: + removedHistData = self._savePreviousHist(newHist, oldHist) - self._saveNewHistStep(newHist) - - oldHist = open(self.histFile) - removedHistData = self._savePreviousHist(newHist, oldHist) - - oldHist.close() - newHist.close() try_remove(self.histFile) self.histFile = newHistFile @@ -1275,27 +1271,25 @@ def _castValue(self, value): def _getHistStepData(self, histStep): """Load data saved in history step""" - hist = open(self.histFile) histStepData = {} - newHistStep = False isSearchedHistStep = False - for line in hist: - if not line.strip() and isSearchedHistStep: - break - if not line.strip(): - newHistStep = True - continue - if isSearchedHistStep: - self._parseLine(line, histStepData) + with open(self.histFile) as hist: + for line in hist: + if not line.strip() and isSearchedHistStep: + break + if not line.strip(): + newHistStep = True + continue + if isSearchedHistStep: + self._parseLine(line, histStepData) - if newHistStep: - line = line.split("=") - if int(line[1]) == histStep: - isSearchedHistStep = True - newHistStep = False + if newHistStep: + line = line.split("=") + if int(line[1]) == histStep: + isSearchedHistStep = True + newHistStep = False - hist.close() return histStepData def _parseLine(self, line, histStepData): diff --git a/gui/wxpython/vnet/widgets.py b/gui/wxpython/vnet/widgets.py index d8926f96fae..6a20f28ca9e 100644 --- a/gui/wxpython/vnet/widgets.py +++ b/gui/wxpython/vnet/widgets.py @@ -439,20 +439,16 @@ def OnItemSelected(self, event): def getSmallUpArrowImage(self): """Get arrow up symbol for indication of sorting""" - stream = open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") - try: + with open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") as stream: img = wx.Image(stream) - finally: - stream.close() return img def getSmallDnArrowImage(self): """Get arrow down symbol for indication of sorting""" - stream = open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb") - try: + with open( + os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb" + ) as stream: img = wx.Image(stream) - finally: - stream.close() return img def _getColumnNum(self, colName): From 48e04135fb5a3758969d91359512a24ceecca3f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:31:33 +0000 Subject: [PATCH 04/21] gui: Early exit loops when possible Flattens nested conditionals and moves error messages or returns near the top --- gui/wxpython/animation/provider.py | 17 +- gui/wxpython/animation/utils.py | 53 ++-- gui/wxpython/core/gcmd.py | 38 +-- gui/wxpython/core/toolboxes.py | 30 +- gui/wxpython/core/utils.py | 5 +- gui/wxpython/gcp/manager.py | 13 +- gui/wxpython/gmodeler/model.py | 327 +++++++++++----------- gui/wxpython/gmodeler/panels.py | 20 +- gui/wxpython/gui_core/forms.py | 217 +++++++------- gui/wxpython/gui_core/goutput.py | 13 +- gui/wxpython/gui_core/gselect.py | 105 +++---- gui/wxpython/gui_core/menu.py | 8 +- gui/wxpython/image2target/ii2t_manager.py | 13 +- gui/wxpython/iscatt/controllers.py | 19 +- gui/wxpython/iscatt/frame.py | 15 +- gui/wxpython/lmgr/workspace.py | 52 ++-- gui/wxpython/mapdisp/main.py | 34 +-- gui/wxpython/mapwin/buffered.py | 19 +- gui/wxpython/modules/extensions.py | 36 +-- gui/wxpython/nviz/animation.py | 35 ++- gui/wxpython/nviz/mapwindow.py | 22 +- gui/wxpython/nviz/tools.py | 25 +- gui/wxpython/psmap/frame.py | 40 +-- gui/wxpython/psmap/instructions.py | 78 +++--- gui/wxpython/rlisetup/sampling_frame.py | 68 +++-- gui/wxpython/tplot/frame.py | 116 ++++---- gui/wxpython/vdigit/dialogs.py | 48 ++-- gui/wxpython/vdigit/wxdigit.py | 170 +++++------ gui/wxpython/vdigit/wxdisplay.py | 17 +- gui/wxpython/vnet/dialogs.py | 19 +- gui/wxpython/wxplot/profile.py | 18 +- 31 files changed, 862 insertions(+), 828 deletions(-) diff --git a/gui/wxpython/animation/provider.py b/gui/wxpython/animation/provider.py index 1b07f63841f..1c7db7423da 100644 --- a/gui/wxpython/animation/provider.py +++ b/gui/wxpython/animation/provider.py @@ -757,14 +757,15 @@ def Clear(self): Debug.msg(4, "MapFilesPool.Clear") for key in list(self.dictionary.keys()): - if self.referenceCount[key] <= 0: - name, ext = os.path.splitext(self.dictionary[key]) - os.remove(self.dictionary[key]) - if ext == ".ppm": - os.remove(name + ".pgm") - del self.dictionary[key] - del self.referenceCount[key] - del self.size[key] + if self.referenceCount[key] > 0: + continue + name, ext = os.path.splitext(self.dictionary[key]) + os.remove(self.dictionary[key]) + if ext == ".ppm": + os.remove(name + ".pgm") + del self.dictionary[key] + del self.referenceCount[key] + del self.size[key] class BitmapPool(DictRefCounter): diff --git a/gui/wxpython/animation/utils.py b/gui/wxpython/animation/utils.py index 54aafa3532f..cf49e3fd974 100644 --- a/gui/wxpython/animation/utils.py +++ b/gui/wxpython/animation/utils.py @@ -92,18 +92,18 @@ def validateMapNames(names, etype): for name in names: if name.find("@") >= 0: nameShort, mapset = name.split("@", 1) - if nameShort in mapDict[mapset]: - newNames.append(name) - else: - raise GException(_("Map <%s> not found.") % name) - else: - found = False - for mapset, mapNames in mapDict.items(): - if name in mapNames: - found = True - newNames.append(name + "@" + mapset) - if not found: + if nameShort not in mapDict[mapset]: raise GException(_("Map <%s> not found.") % name) + newNames.append(name) + + continue + found = False + for mapset, mapNames in mapDict.items(): + if name in mapNames: + found = True + newNames.append(name + "@" + mapset) + if not found: + raise GException(_("Map <%s> not found.") % name) return newNames @@ -331,21 +331,22 @@ def layerListToCmdsMatrix(layerList): continue if hasattr(layer, "maps"): for i, part in enumerate(layer.cmd): - if part.startswith("map="): - cmd = layer.cmd[:] - cmds = [] - for map_ in layer.maps: - # check if dataset uses layers instead of maps - mapName, mapLayer = getNameAndLayer(map_) - cmd[i] = "map={name}".format(name=mapName) - if mapLayer: - try: - idx = cmd.index("layer") - cmd[idx] = "layer={layer}".format(layer=mapLayer) - except ValueError: - cmd.append("layer={layer}".format(layer=mapLayer)) - cmds.append(cmd[:]) - cmdsForComposition.append(cmds) + if not part.startswith("map="): + continue + cmd = layer.cmd[:] + cmds = [] + for map_ in layer.maps: + # check if dataset uses layers instead of maps + mapName, mapLayer = getNameAndLayer(map_) + cmd[i] = "map={name}".format(name=mapName) + if mapLayer: + try: + idx = cmd.index("layer") + cmd[idx] = "layer={layer}".format(layer=mapLayer) + except ValueError: + cmd.append("layer={layer}".format(layer=mapLayer)) + cmds.append(cmd[:]) + cmdsForComposition.append(cmds) else: cmdsForComposition.append([layer.cmd] * count) diff --git a/gui/wxpython/core/gcmd.py b/gui/wxpython/core/gcmd.py index d8254b4184f..e0d06dc494c 100644 --- a/gui/wxpython/core/gcmd.py +++ b/gui/wxpython/core/gcmd.py @@ -160,25 +160,25 @@ def __init__(self, args, **kwargs): # "^" must be the first character in the list to avoid double # escaping. for c in ("^", "|", "&", "<", ">"): - if c in args[i]: - if "=" in args[i]: - a = args[i].split("=") - k = a[0] + "=" - v = "=".join(a[1 : len(a)]) - else: - k = "" - v = args[i] - - # If there are spaces, the argument was already - # esscaped with double quotes, so don't escape it - # again. - if c in v and " " not in v: - # Here, we escape each ^ in ^^^ with ^^ and a - # with ^ + , - # so we need 7 carets. - - v = v.replace(c, "^^^^^^^" + c) - args[i] = k + v + if c not in args[i]: + continue + if "=" in args[i]: + a = args[i].split("=") + k = a[0] + "=" + v = "=".join(a[1 : len(a)]) + else: + k = "" + v = args[i] + + # If there are spaces, the argument was already + # escaped with double quotes, so don't escape it + # again. + if c in v and " " not in v: + # Here, we escape each ^ in ^^^ with ^^ and a + # with ^ + , + # so we need 7 carets. + v = v.replace(c, "^^^^^^^" + c) + args[i] = k + v subprocess.Popen.__init__(self, args, **kwargs) diff --git a/gui/wxpython/core/toolboxes.py b/gui/wxpython/core/toolboxes.py index 928c6cd835f..9b5d83444d7 100644 --- a/gui/wxpython/core/toolboxes.py +++ b/gui/wxpython/core/toolboxes.py @@ -615,21 +615,23 @@ def _expandRuntimeModules(node, loadMetadata=True): n = ET.SubElement(module, "module") n.text = name - if module.find("description") is None: - if loadMetadata: - # not all modules are always compiled (e.g., r.in.lidar) - if shutil.which(name): - desc, keywords = _loadMetadata(name) - if not desc: - hasErrors = True - else: - desc, keywords = _("Module not installed"), "" + if module.find("description") is not None: + continue + + if loadMetadata: + # not all modules are always compiled (e.g., r.in.lidar) + if shutil.which(name): + desc, keywords = _loadMetadata(name) + if not desc: + hasErrors = True else: - desc, keywords = "", "" - n = ET.SubElement(module, "description") - n.text = _escapeXML(desc) - n = ET.SubElement(module, "keywords") - n.text = _escapeXML(",".join(keywords)) + desc, keywords = (_("Module not installed"), "") + else: + desc, keywords = ("", "") + n = ET.SubElement(module, "description") + n.text = _escapeXML(desc) + n = ET.SubElement(module, "keywords") + n.text = _escapeXML(",".join(keywords)) if hasErrors: # not translatable until toolboxes compilation on Mac is fixed diff --git a/gui/wxpython/core/utils.py b/gui/wxpython/core/utils.py index 47fd14003b3..0f894b43a60 100644 --- a/gui/wxpython/core/utils.py +++ b/gui/wxpython/core/utils.py @@ -258,10 +258,9 @@ def ListOfCatsToRange(cats): next = 0 j = i + 1 while j < len(cats): - if cats[i + next] == cats[j] - 1: - next += 1 - else: + if cats[i + next] != cats[j] - 1: break + next += 1 j += 1 if next > 1: diff --git a/gui/wxpython/gcp/manager.py b/gui/wxpython/gcp/manager.py index 78749f762c5..a55e71b8430 100644 --- a/gui/wxpython/gcp/manager.py +++ b/gui/wxpython/gcp/manager.py @@ -2056,12 +2056,13 @@ def RMSError(self, xygroup, order): sumsq_bkw_err += float(bkw_err) ** 2 sum_fwd_err += float(fwd_err) GCPcount += 1 - else: - self.list.SetItem(index, 5, "") - self.list.SetItem(index, 6, "") - self.mapcoordlist[key][5] = 0.0 - self.mapcoordlist[key][6] = 0.0 - self.list.SetItemTextColour(index, wx.BLACK) + continue + + self.list.SetItem(index, 5, "") + self.list.SetItem(index, 6, "") + self.mapcoordlist[key][5] = 0.0 + self.mapcoordlist[key][6] = 0.0 + self.list.SetItemTextColour(index, wx.BLACK) # SD if GCPcount > 0: diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index e31e52c8c04..1ce96ea4826 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -494,25 +494,25 @@ def Validate(self): continue key, value = opt.split("=", 1) sval = pattern.search(value) - if sval: - var = sval.group(2).strip()[1:] # strip '%' from beginning - found = False - for v in variables: - if var.startswith(v): - found = True - break - if not found: - report = True - for item in filter( - lambda x: isinstance(x, ModelLoop), action.GetBlock() - ): - if var in item.GetLabel(): - report = False - break - if report: - errList.append( - cmd[0] + ": " + _("undefined variable '%s'") % var - ) + if not sval: + continue + var = sval.group(2).strip()[1:] # strip '%' from beginning + found = False + for v in variables: + if var.startswith(v): + found = True + break + if found: + continue + report = True + for item in filter( + lambda x: isinstance(x, ModelLoop), action.GetBlock() + ): + if var in item.GetLabel(): + report = False + break + if report: + errList.append(cmd[0] + ": " + _("undefined variable '%s'") % var) # TODO: check variables in file only optionally # errList += self._substituteFile(action, checkOnly = True) @@ -703,24 +703,24 @@ def Run(self, log, onDone, parent=None): variables = self.GetVariables() for variable in variables: pattern = re.compile("%" + variable) - if pattern.search(cond): - value = "" - if params and "variables" in params: - for p in params["variables"]["params"]: - if variable == p.get("name", ""): - value = p.get("value", "") - break - - if not value: - value = variables[variable].get("value", "") - - if not value: - continue + if not pattern.search(cond): + continue + value = "" + if params and "variables" in params: + for p in params["variables"]["params"]: + if variable == p.get("name", ""): + value = p.get("value", "") + break + + if not value: + value = variables[variable].get("value", "") - vtype = variables[variable].get("type", "string") - if vtype == "string": - value = '"' + value + '"' - cond = pattern.sub(value, cond) + if not value: + continue + vtype = variables[variable].get("type", "string") + if vtype == "string": + value = '"' + value + '"' + cond = pattern.sub(value, cond) # split condition # TODO: this part needs some better solution @@ -2781,23 +2781,23 @@ def _getPythonActionCmd(self, item, task, cmdIndent, variables={}): name = p.get("name", None) value = p.get("value", None) - if (name and value) or (name in parameterizedParams): - - if name in parameterizedParams: - parameterizedParam = self._getParamName(name, item) - default_val = p.get("value", "") + if (not name or not value) and name not in parameterizedParams: + continue - if len(default_val) > 0: - parameterizedParam += f"|default({default_val})" + if name in parameterizedParams: + parameterizedParam = self._getParamName(name, item) + default_val = p.get("value", "") - value = f"{{{{ {parameterizedParam} }}}}" + if len(default_val) > 0: + parameterizedParam += f"|default({default_val})" + value = f"{{{{ {parameterizedParam} }}}}" - param_string = f'{{"param": "{name}", "value": "{value}"}}' - age = p.get("age", "old") - if age == "new": - outputs.append(param_string) - else: - inputs.append(param_string) + param_string = f'{{"param": "{name}", "value": "{value}"}}' + age = p.get("age", "old") + if age == "new": + outputs.append(param_string) + else: + inputs.append(param_string) ret += f'{" " * self.indent * 4}"module": "{task.get_name()}",\n' ret += f'{" " * self.indent * 4}"id": "{self._getModuleNickname(item)}",\n' @@ -2998,19 +2998,20 @@ def _write_input_outputs(self, item, intermediates): # ComplexOutput if: outputting a new non-intermediate layer and # either not empty or parameterized if ( - age == "new" - and not any(value in i for i in intermediates) - and (value != "" or param in item.GetParameterizedParams()["params"]) - ): - io_data = "outputs" - object_type = "ComplexOutput" - format_spec = self._getSupportedFormats(param["prompt"]) - - self._write_input_output_object( - io_data, object_type, param["name"], item, desc, format_spec, "" + age != "new" + or any(value in i for i in intermediates) + or ( + value == "" and param not in item.GetParameterizedParams()["params"] ) - - self.fd.write("\n") + ): + continue + io_data = "outputs" + object_type = "ComplexOutput" + format_spec = self._getSupportedFormats(param["prompt"]) + self._write_input_output_object( + io_data, object_type, param["name"], item, desc, format_spec, "" + ) + self.fd.write("\n") def _write_input_output_object( self, @@ -3062,45 +3063,49 @@ def _writePythonAction(self, item, variables={}, intermediates=None): # output if: outputting a new non-intermediate layer and # either not empty or parameterized if ( - age == "new" - and not any(value in i for i in intermediates) - and (value != "" or param in item.GetParameterizedParams()["params"]) + age != "new" + or any(value in i for i in intermediates) + or ( + value == "" and param not in item.GetParameterizedParams()["params"] + ) ): - if param["prompt"] == "vector": - command = "v.out.ogr" - format = '"GML"' - extension = ".gml" - elif param["prompt"] == "raster": - command = "r.out.gdal" - format = '"GTiff"' - extension = ".tif" - else: - # TODO: Support 3D - command = "WRITE YOUR EXPORT COMMAND" - format = '"WRITE YOUR EXPORT FORMAT"' - extension = "WRITE YOUR EXPORT EXTENSION" + continue - n = param.get("name", None) - param_name = self._getParamName(n, item) + if param["prompt"] == "vector": + command = "v.out.ogr" + format = '"GML"' + extension = ".gml" + elif param["prompt"] == "raster": + command = "r.out.gdal" + format = '"GTiff"' + extension = ".tif" + else: + # TODO: Support 3D + command = "WRITE YOUR EXPORT COMMAND" + format = '"WRITE YOUR EXPORT FORMAT"' + extension = "WRITE YOUR EXPORT EXTENSION" - keys = param.keys() - if "parameterized" in keys and param["parameterized"] is True: - param_request = 'request.inputs["{}"][0].data'.format(param_name) - else: - param_request = '"{}"'.format(param["value"]) + n = param.get("name", None) + param_name = self._getParamName(n, item) - # if True, write the overwrite parameter to the model command - overwrite = self.model.GetProperties().get("overwrite", False) - if overwrite is True: - overwrite_string = ",\n{}overwrite=True".format( - " " * (self.indent + 12) - ) - else: - overwrite_string = "" + keys = param.keys() + if "parameterized" in keys and param["parameterized"] is True: + param_request = 'request.inputs["{}"][0].data'.format(param_name) + else: + param_request = '"{}"'.format(param["value"]) - strcmd_len = len(strcmd.strip()) - self.fd.write( - """ + # if True, write the overwrite parameter to the model command + overwrite = self.model.GetProperties().get("overwrite", False) + if overwrite is True: + overwrite_string = ",\n{}overwrite=True".format( + " " * (self.indent + 12) + ) + else: + overwrite_string = "" + + strcmd_len = len(strcmd.strip()) + self.fd.write( + """ {run_command}"{cmd}", {indent1}input={input}, {indent2}output=os.path.join( @@ -3108,37 +3113,35 @@ def _writePythonAction(self, item, variables={}, intermediates=None): {indent4}{out} + "{format_ext}"), {indent5}format={format}{overwrite_string}) """.format( - run_command=strcmd, - cmd=command, - indent1=" " * (self.indent + strcmd_len), - input=param_request, - indent2=" " * (self.indent + strcmd_len), - indent3=" " * (self.indent * 2 + strcmd_len), - indent4=" " * (self.indent * 2 + strcmd_len), - out=param_request, - format_ext=extension, - indent5=" " * (self.indent + strcmd_len), - format=format, - overwrite_string=overwrite_string, - ) + run_command=strcmd, + cmd=command, + indent1=" " * (self.indent + strcmd_len), + input=param_request, + indent2=" " * (self.indent + strcmd_len), + indent3=" " * (self.indent * 2 + strcmd_len), + indent4=" " * (self.indent * 2 + strcmd_len), + out=param_request, + format_ext=extension, + indent5=" " * (self.indent + strcmd_len), + format=format, + overwrite_string=overwrite_string, ) + ) - left_side_out = 'response.outputs["{}"].file'.format(param_name) - right_side_out = ( - "os.path.join(\n{indent1}" - 'tempfile.gettempdir(),\n{indent2}{out} + "' - '{format_ext}")'.format( - indent1=" " * (self.indent + 4), - indent2=" " * (self.indent + 4), - out=param_request, - format_ext=extension, - ) - ) - self.fd.write( - "\n{}{} = {}".format( - " " * self.indent, left_side_out, right_side_out - ) + left_side_out = 'response.outputs["{}"].file'.format(param_name) + right_side_out = ( + "os.path.join(\n{indent1}" + 'tempfile.gettempdir(),\n{indent2}{out} + "' + '{format_ext}")'.format( + indent1=" " * (self.indent + 4), + indent2=" " * (self.indent + 4), + out=param_request, + format_ext=extension, ) + ) + self.fd.write( + "\n{}{} = {}".format(" " * self.indent, left_side_out, right_side_out) + ) def _getPythonActionCmd(self, item, task, cmdIndent, variables={}): opts = task.get_options() @@ -3156,25 +3159,26 @@ def _getPythonActionCmd(self, item, task, cmdIndent, variables={}): name = p.get("name", None) value = p.get("value", None) - if (name and value) or (name in parameterizedParams): - ptype = p.get("type", "string") - foundVar = False + if (not name or not value) and name not in parameterizedParams: + continue - if name in parameterizedParams: - foundVar = True - if "input" in name: - value = 'request.inputs["{}"][0].file'.format( - self._getParamName(name, item) - ) - else: - value = 'request.inputs["{}"][0].data'.format( - self._getParamName(name, item) - ) + ptype = p.get("type", "string") + foundVar = False - if foundVar or ptype != "string": - params.append("{}={}".format(name, value)) + if name in parameterizedParams: + foundVar = True + if "input" in name: + value = 'request.inputs["{}"][0].file'.format( + self._getParamName(name, item) + ) else: - params.append('{}="{}"'.format(name, value)) + value = 'request.inputs["{}"][0].data'.format( + self._getParamName(name, item) + ) + if foundVar or ptype != "string": + params.append("{}={}".format(name, value)) + else: + params.append('{}="{}"'.format(name, value)) ret += '"%s"' % task.get_name() if flags: @@ -3545,28 +3549,29 @@ def _getPythonActionCmd(self, item, task, cmdIndent, variables={}): elif ptype == "float": value = list(map(float, value)) - if (name and value) or (name in parameterizedParams): - if isinstance(value, list): - foundVar = False - for idx in range(len(value)): - foundVar_, value[idx] = self._substitutePythonParamValue( - value[idx], name, parameterizedParams, variables, item - ) - if foundVar_ is True: - foundVar = True - else: - foundVar, value = self._substitutePythonParamValue( - value, name, parameterizedParams, variables, item - ) + if (not name or not value) and name not in parameterizedParams: + continue - if ( - foundVar - or isinstance(value, list) - or (ptype != "string" and len(p.get("key_desc", [])) < 2) - ): - params.append("{}={}".format(name, value)) - else: - params.append('{}="{}"'.format(name, value)) + if isinstance(value, list): + foundVar = False + for idx in range(len(value)): + foundVar_, value[idx] = self._substitutePythonParamValue( + value[idx], name, parameterizedParams, variables, item + ) + if foundVar_ is True: + foundVar = True + else: + foundVar, value = self._substitutePythonParamValue( + value, name, parameterizedParams, variables, item + ) + if ( + foundVar + or isinstance(value, list) + or (ptype != "string" and len(p.get("key_desc", [])) < 2) + ): + params.append("{}={}".format(name, value)) + else: + params.append('{}="{}"'.format(name, value)) ret += '"%s"' % task.get_name() if flags: diff --git a/gui/wxpython/gmodeler/panels.py b/gui/wxpython/gmodeler/panels.py index 6390da92deb..e7c46239fd8 100644 --- a/gui/wxpython/gmodeler/panels.py +++ b/gui/wxpython/gmodeler/panels.py @@ -531,16 +531,18 @@ def GetOptData(self, dcmd, layer, params, propwin): data.Update() # remove dead data items - if not p.get("value", ""): - data = layer.FindData(p.get("name", "")) - if data: - remList, upList = self.model.RemoveItem(data, layer) - for item in remList: - self.canvas.diagram.RemoveShape(item) - item.__del__() # noqa: PLC2801, C2801 + if p.get("value", ""): + continue + data = layer.FindData(p.get("name", "")) + if not data: + continue + remList, upList = self.model.RemoveItem(data, layer) + for item in remList: + self.canvas.diagram.RemoveShape(item) + item.__del__() # noqa: PLC2801, C2801 - for item in upList: - item.Update() + for item in upList: + item.Update() # valid / parameterized ? layer.SetValid(params) diff --git a/gui/wxpython/gui_core/forms.py b/gui/wxpython/gui_core/forms.py index 389ae6f2c30..0ff0ebcfdaf 100644 --- a/gui/wxpython/gui_core/forms.py +++ b/gui/wxpython/gui_core/forms.py @@ -2774,38 +2774,43 @@ def _switchPage(self, notification): def OnColorChange(self, event): myId = event.GetId() for p in self.task.params: - if "wxId" in p and myId in p["wxId"]: - multiple = p["wxId"][1] is not None # multiple colors - hasTansp = p["wxId"][2] is not None - if multiple: - # selected color is added at the end of textCtrl - colorchooser = wx.FindWindowById(p["wxId"][0]) - new_color = colorchooser.GetValue()[:] - new_label = utils.rgb2str.get( - new_color, ":".join(list(map(str, new_color))) - ) - textCtrl = wx.FindWindowById(p["wxId"][1]) - val = textCtrl.GetValue() - sep = "," - if val and val[-1] != sep: - val += sep - val += new_label - textCtrl.SetValue(val) - p["value"] = val - elif hasTansp and wx.FindWindowById(p["wxId"][2]).GetValue(): - p["value"] = "none" - else: - colorchooser = wx.FindWindowById(p["wxId"][0]) - new_color = colorchooser.GetValue()[:] - # This is weird: new_color is a 4-tuple and new_color[:] is - # a 3-tuple under wx2.8.1 - new_label = utils.rgb2str.get( - new_color, ":".join(list(map(str, new_color))) - ) - colorchooser.SetLabel(new_label) - colorchooser.SetColour(new_color) - colorchooser.Refresh() - p["value"] = colorchooser.GetLabel() + if "wxId" not in p or myId not in p["wxId"]: + continue + + multiple = p["wxId"][1] is not None # multiple colors + hasTansp = p["wxId"][2] is not None + if multiple: + # selected color is added at the end of textCtrl + colorchooser = wx.FindWindowById(p["wxId"][0]) + new_color = colorchooser.GetValue()[:] + new_label = utils.rgb2str.get( + new_color, ":".join(list(map(str, new_color))) + ) + textCtrl = wx.FindWindowById(p["wxId"][1]) + val = textCtrl.GetValue() + sep = "," + if val and val[-1] != sep: + val += sep + val += new_label + textCtrl.SetValue(val) + p["value"] = val + + continue + if hasTansp and wx.FindWindowById(p["wxId"][2]).GetValue(): + p["value"] = "none" + continue + + colorchooser = wx.FindWindowById(p["wxId"][0]) + new_color = colorchooser.GetValue()[:] + # This is weird: new_color is a 4-tuple and new_color[:] is + # a 3-tuple under wx2.8.1 + new_label = utils.rgb2str.get( + new_color, ":".join(list(map(str, new_color))) + ) + colorchooser.SetLabel(new_label) + colorchooser.SetColour(new_color) + colorchooser.Refresh() + p["value"] = colorchooser.GetLabel() self.OnUpdateValues() def OnUpdateValues(self, event=None): @@ -2897,25 +2902,24 @@ def OnSetSymbol(self, event): myId = event.GetId() for p in self.task.params: - if "wxId" in p and myId in p["wxId"]: - from gui_core.dialogs import SymbolDialog - - dlg = SymbolDialog( - self, symbolPath=globalvar.SYMBDIR, currentSymbol=p["value"] - ) - if dlg.ShowModal() == wx.ID_OK: - img = dlg.GetSelectedSymbolPath() - p["value"] = dlg.GetSelectedSymbolName() - - bitmapButton = wx.FindWindowById(p["wxId"][0]) - label = wx.FindWindowById(p["wxId"][1]) + if "wxId" not in p or myId not in p["wxId"]: + continue + from gui_core.dialogs import SymbolDialog - bitmapButton.SetBitmapLabel(wx.Bitmap(img + ".png")) - label.SetLabel(p["value"]) + dlg = SymbolDialog( + self, symbolPath=globalvar.SYMBDIR, currentSymbol=p["value"] + ) + if dlg.ShowModal() == wx.ID_OK: + img = dlg.GetSelectedSymbolPath() + p["value"] = dlg.GetSelectedSymbolName() + bitmapButton = wx.FindWindowById(p["wxId"][0]) + label = wx.FindWindowById(p["wxId"][1]) + bitmapButton.SetBitmapLabel(wx.Bitmap(img + ".png")) + label.SetLabel(p["value"]) - self.OnUpdateValues(event) + self.OnUpdateValues(event) - dlg.Destroy() + dlg.Destroy() def OnTimelineTool(self, event): """Show Timeline Tool with dataset(s) from gselect. @@ -2926,35 +2930,37 @@ def OnTimelineTool(self, event): myId = event.GetId() for p in self.task.params: - if "wxId" in p and myId in p["wxId"]: - select = self.FindWindowById(p["wxId"][0]) - if not select.GetValue(): - gcmd.GMessage(parent=self, message=_("No dataset given.")) - return - datasets = select.GetValue().split(",") - from timeline import frame + if "wxId" not in p or myId not in p["wxId"]: + continue + select = self.FindWindowById(p["wxId"][0]) + if not select.GetValue(): + gcmd.GMessage(parent=self, message=_("No dataset given.")) + return + datasets = select.GetValue().split(",") + from timeline import frame - frame.run(parent=self, datasets=datasets) + frame.run(parent=self, datasets=datasets) def OnSelectFont(self, event): """Select font using font dialog""" myId = event.GetId() for p in self.task.params: - if "wxId" in p and myId in p["wxId"]: - from gui_core.dialogs import DefaultFontDialog - - dlg = DefaultFontDialog( - parent=self, - title=_("Select font"), - style=wx.DEFAULT_DIALOG_STYLE, - type="font", - ) - if dlg.ShowModal() == wx.ID_OK: - if dlg.font: - p["value"] = dlg.font - self.FindWindowById(p["wxId"][1]).SetValue(dlg.font) - self.OnUpdateValues(event) - dlg.Destroy() + if "wxId" not in p or myId not in p["wxId"]: + continue + from gui_core.dialogs import DefaultFontDialog + + dlg = DefaultFontDialog( + parent=self, + title=_("Select font"), + style=wx.DEFAULT_DIALOG_STYLE, + type="font", + ) + if dlg.ShowModal() == wx.ID_OK: + if dlg.font: + p["value"] = dlg.font + self.FindWindowById(p["wxId"][1]).SetValue(dlg.font) + self.OnUpdateValues(event) + dlg.Destroy() def OnUpdateSelection(self, event): """Update dialog (layers, tables, columns, etc.)""" @@ -3103,32 +3109,34 @@ def ParseCommand(self, cmd, completed=None): else: self.grass_task.set_flag(option[1], True) cmd_validated.append(option) - else: # parameter - try: - key, value = option.split("=", 1) - except ValueError: - if self.grass_task.firstParam: - if i == 0: # add key name of first parameter if not given - key = self.grass_task.firstParam - value = option - else: - raise gcmd.GException( - _("Unable to parse command '%s'") % " ".join(cmd) - ) - else: - continue + continue - task = self.grass_task.get_param(key, raiseError=False) - if not task: - err.append( - _("%(cmd)s: parameter '%(key)s' not available") - % {"cmd": cmd[0], "key": key} - ) + # parameter + try: + key, value = option.split("=", 1) + except ValueError: + if self.grass_task.firstParam: + if i == 0: # add key name of first parameter if not given + key = self.grass_task.firstParam + value = option + else: + raise gcmd.GException( + _("Unable to parse command '%s'") % " ".join(cmd) + ) + else: continue - self.grass_task.set_param(key, value) - cmd_validated.append(key + "=" + value) - i += 1 + task = self.grass_task.get_param(key, raiseError=False) + if not task: + err.append( + _("%(cmd)s: parameter '%(key)s' not available") + % {"cmd": cmd[0], "key": key} + ) + continue + + self.grass_task.set_param(key, value) + cmd_validated.append(key + "=" + value) + i += 1 # update original command list cmd = cmd_validated @@ -3180,16 +3188,17 @@ def GetCommandInputMapParamKey(self, cmd): self.grass_task = gtask.processTask(tree).get_task() for p in self.grass_task.params: - if p.get("name", "") in {"input", "map"}: - age = p.get("age", "") - prompt = p.get("prompt", "") - element = p.get("element", "") - if ( - age == "old" - and element in {"cell", "grid3", "vector"} - and prompt in {"raster", "raster_3d", "vector"} - ): - return p.get("name", None) + if p.get("name", "") not in {"input", "map"}: + continue + age = p.get("age", "") + prompt = p.get("prompt", "") + element = p.get("element", "") + if ( + age == "old" + and (element in {"cell", "grid3", "vector"}) + and (prompt in {"raster", "raster_3d", "vector"}) + ): + return p.get("name", None) return None diff --git a/gui/wxpython/gui_core/goutput.py b/gui/wxpython/gui_core/goutput.py index 6676eb69935..75a1edb8fea 100644 --- a/gui/wxpython/gui_core/goutput.py +++ b/gui/wxpython/gui_core/goutput.py @@ -619,12 +619,13 @@ def AddStyledMessage(self, message, style=None): for c in message: if c == "\b": self.linePos -= 1 - else: - self.SetCurrentPos(self.linePos) - self.ReplaceSelection(c) - self.linePos = self.GetCurrentPos() - if c != " ": - last_c = c + continue + + self.SetCurrentPos(self.linePos) + self.ReplaceSelection(c) + self.linePos = self.GetCurrentPos() + if c != " ": + last_c = c if last_c not in (digits): self.AddTextWrapped("\n", wrap=None) self.linePos = -1 diff --git a/gui/wxpython/gui_core/gselect.py b/gui/wxpython/gui_core/gselect.py index 729f38a5d30..fe5b644df0f 100644 --- a/gui/wxpython/gui_core/gselect.py +++ b/gui/wxpython/gui_core/gselect.py @@ -596,30 +596,32 @@ def _getElementList(self, element, mapsets=None, elements=None, exclude=False): sys.stderr.write(_("GSelect: invalid item: %s") % e) continue - if self.seltree.ItemHasChildren(mapset_node): - sel = UserSettings.Get( - group="appearance", key="elementListExpand", subkey="selection" - ) - collapse = True - - if sel == 0: # collapse all except PERMANENT and current - if mapset in {"PERMANENT", curr_mapset}: - collapse = False - elif sel == 1: # collapse all except PERMANENT - if mapset == "PERMANENT": - collapse = False - elif sel == 2: # collapse all except current - if mapset == curr_mapset: - collapse = False - elif sel == 3: # collapse all - pass - elif sel == 4: # expand all + if not self.seltree.ItemHasChildren(mapset_node): + continue + + sel = UserSettings.Get( + group="appearance", key="elementListExpand", subkey="selection" + ) + collapse = True + + if sel == 0: # collapse all except PERMANENT and current + if mapset in {"PERMANENT", curr_mapset}: + collapse = False + elif sel == 1: # collapse all except PERMANENT + if mapset == "PERMANENT": collapse = False + elif sel == 2: # collapse all except current + if mapset == curr_mapset: + collapse = False + elif sel == 3: # collapse all + pass + elif sel == 4: # expand all + collapse = False - if collapse: - self.seltree.CollapseAllChildren(mapset_node) - else: - self.seltree.ExpandAllChildren(mapset_node) + if collapse: + self.seltree.CollapseAllChildren(mapset_node) + else: + self.seltree.ExpandAllChildren(mapset_node) if first_mapset: # select first mapset (MSW hack) @@ -637,22 +639,24 @@ def _addItems(self, elist, elements, mapset, exclude, node): """ elist = gs.naturally_sorted(elist) for elem in elist: - if elem != "": - fullqElem = elem + "@" + mapset - if self.filterItems and fullqElem not in self.filterItems: - continue # skip items missed in self.filterItems - - if elements is not None: - if (exclude and fullqElem in elements) or ( - not exclude and fullqElem not in elements - ): - continue + if elem == "": + continue - if self.filterElements: - if self.filterElements(fullqElem): - self.AddItem(elem, mapset=mapset, node=False, parent=node) - else: + fullqElem = elem + "@" + mapset + if self.filterItems and fullqElem not in self.filterItems: + continue # skip items missed in self.filterItems + + if elements is not None: + if (exclude and fullqElem in elements) or ( + not exclude and fullqElem not in elements + ): + continue + + if self.filterElements: + if self.filterElements(fullqElem): self.AddItem(elem, mapset=mapset, node=False, parent=node) + else: + self.AddItem(elem, mapset=mapset, node=False, parent=node) def AddItem(self, value, mapset=None, node=True, parent=None): if not parent: @@ -2091,20 +2095,21 @@ def GetDsn(self): connection_string = None for conn in ret.splitlines(): db_login = conn.split("|") - if db_login[0] == "pg": - user, password, host, port = db_login[2:] - connection_string = ( - f"PG:dbname={self.dbWidgets['choice'].GetStringSelection()}" - ) - if user: - connection_string += f" user={user}" - if password: - connection_string += f" password={password}" - if host: - connection_string += f" host={host}" - if port: - connection_string += f" port={port}" - return connection_string + if db_login[0] != "pg": + continue + user, password, host, port = db_login[2:] + connection_string = ( + f"PG:dbname={self.dbWidgets['choice'].GetStringSelection()}" + ) + if user: + connection_string += f" user={user}" + if password: + connection_string += f" password={password}" + if host: + connection_string += f" host={host}" + if port: + connection_string += f" port={port}" + return connection_string if not connection_string: GError(parent=self, message=message) return diff --git a/gui/wxpython/gui_core/menu.py b/gui/wxpython/gui_core/menu.py index a512b6eea19..2f462625dbd 100644 --- a/gui/wxpython/gui_core/menu.py +++ b/gui/wxpython/gui_core/menu.py @@ -62,11 +62,11 @@ def _createMenu(self, node): label = child.label subMenu = self._createMenu(child) menu.AppendMenu(wx.ID_ANY, label, subMenu) - else: - data = child.data.copy() - data.pop("label") + continue + data = child.data.copy() + data.pop("label") - self._createMenuItem(menu, label=child.label, **data) + self._createMenuItem(menu, label=child.label, **data) return menu diff --git a/gui/wxpython/image2target/ii2t_manager.py b/gui/wxpython/image2target/ii2t_manager.py index 5277711aa26..ff51b0f87aa 100644 --- a/gui/wxpython/image2target/ii2t_manager.py +++ b/gui/wxpython/image2target/ii2t_manager.py @@ -2004,12 +2004,13 @@ def RMSError(self, xygroup, order): sumsq_bkw_err += float(bkw_err) ** 2 sum_fwd_err += float(fwd_err) GCPcount += 1 - else: - self.list.SetItem(index, 7, "") - self.list.SetItem(index, 8, "") - self.mapcoordlist[key][7] = 0.0 - self.mapcoordlist[key][8] = 0.0 - self.list.SetItemTextColour(index, wx.BLACK) + continue + + self.list.SetItem(index, 7, "") + self.list.SetItem(index, 8, "") + self.mapcoordlist[key][7] = 0.0 + self.mapcoordlist[key][8] = 0.0 + self.list.SetItemTextColour(index, wx.BLACK) # SD if GCPcount > 0: diff --git a/gui/wxpython/iscatt/controllers.py b/gui/wxpython/iscatt/controllers.py index f87569b2698..873ddf02071 100644 --- a/gui/wxpython/iscatt/controllers.py +++ b/gui/wxpython/iscatt/controllers.py @@ -957,16 +957,15 @@ def SetData(self): bands = [] while True: - if dlg.ShowModal() == wx.ID_OK: - bands = dlg.GetGroupBandsErr(parent=self.scatt_mgr.guiparent) - if bands: - name, s = dlg.GetData() - group = gs.find_file(name=name, element="group") - self.set_g["group"] = group["name"] - self.set_g["subg"] = s - - break - else: + if dlg.ShowModal() != wx.ID_OK: + break + bands = dlg.GetGroupBandsErr(parent=self.scatt_mgr.guiparent) + if bands: + name, s = dlg.GetData() + group = gs.find_file(name=name, element="group") + self.set_g["group"] = group["name"] + self.set_g["subg"] = s + break dlg.Destroy() diff --git a/gui/wxpython/iscatt/frame.py b/gui/wxpython/iscatt/frame.py index 542d8acc2c3..46a4f1c6547 100644 --- a/gui/wxpython/iscatt/frame.py +++ b/gui/wxpython/iscatt/frame.py @@ -694,16 +694,15 @@ def OnRename(self, event): dlg.CentreOnParent() while True: - if dlg.ShowModal() == wx.ID_OK: - name = dlg.GetNewName().strip() - if not name: - GMessage(parent=self, message=_("Empty name was inserted.")) - else: - self.cats_mgr.SetCategoryAttrs(cat_id, {"name": name}) - break - else: + if dlg.ShowModal() != wx.ID_OK: break + name = dlg.GetNewName().strip() + if name: + self.cats_mgr.SetCategoryAttrs(cat_id, {"name": name}) + break + GMessage(parent=self, message=_("Empty name was inserted.")) + dlg.Destroy() def _setCatAttrs(self, cat_id, attrs): diff --git a/gui/wxpython/lmgr/workspace.py b/gui/wxpython/lmgr/workspace.py index 29b60443223..41eba540492 100644 --- a/gui/wxpython/lmgr/workspace.py +++ b/gui/wxpython/lmgr/workspace.py @@ -317,35 +317,37 @@ def Load(self, filename): for overlay in gxwXml.overlays: # overlay["cmd"][0] name of command e.g. d.barscale, d.legend # overlay["cmd"][1:] parameters and flags - if overlay["display"] == i: - if overlay["cmd"][0] == "d.legend.vect": - mapdisplay[i].AddLegendVect(overlay["cmd"]) - if overlay["cmd"][0] == "d.legend": - mapdisplay[i].AddLegendRast(overlay["cmd"]) - if overlay["cmd"][0] == "d.barscale": - mapdisplay[i].AddBarscale(overlay["cmd"]) - if overlay["cmd"][0] == "d.northarrow": - mapdisplay[i].AddArrow(overlay["cmd"]) - if overlay["cmd"][0] == "d.text": - mapdisplay[i].AddDtext(overlay["cmd"]) + if overlay["display"] != i: + continue + if overlay["cmd"][0] == "d.legend.vect": + mapdisplay[i].AddLegendVect(overlay["cmd"]) + if overlay["cmd"][0] == "d.legend": + mapdisplay[i].AddLegendRast(overlay["cmd"]) + if overlay["cmd"][0] == "d.barscale": + mapdisplay[i].AddBarscale(overlay["cmd"]) + if overlay["cmd"][0] == "d.northarrow": + mapdisplay[i].AddArrow(overlay["cmd"]) + if overlay["cmd"][0] == "d.text": + mapdisplay[i].AddDtext(overlay["cmd"]) # avoid double-rendering when loading workspace # mdisp.MapWindow2D.UpdateMap() # nviz - if gxwXml.displays[i]["viewMode"] == "3d": - mapdisplay[i].AddNviz() - self.lmgr.nvizUpdateState( - view=gxwXml.nviz_state["view"], - iview=gxwXml.nviz_state["iview"], - light=gxwXml.nviz_state["light"], - ) - mapdisplay[i].MapWindow3D.constants = gxwXml.nviz_state["constants"] - for idx, constant in enumerate(mapdisplay[i].MapWindow3D.constants): - mapdisplay[i].MapWindow3D.AddConstant(constant, i + 1) - for page in ("view", "light", "fringe", "constant", "cplane"): - self.lmgr.nvizUpdatePage(page) - self.lmgr.nvizUpdateSettings() - mapdisplay[i].toolbars["map"].combo.SetSelection(1) + if gxwXml.displays[i]["viewMode"] != "3d": + continue + mapdisplay[i].AddNviz() + self.lmgr.nvizUpdateState( + view=gxwXml.nviz_state["view"], + iview=gxwXml.nviz_state["iview"], + light=gxwXml.nviz_state["light"], + ) + mapdisplay[i].MapWindow3D.constants = gxwXml.nviz_state["constants"] + for idx, constant in enumerate(mapdisplay[i].MapWindow3D.constants): + mapdisplay[i].MapWindow3D.AddConstant(constant, i + 1) + for page in ("view", "light", "fringe", "constant", "cplane"): + self.lmgr.nvizUpdatePage(page) + self.lmgr.nvizUpdateSettings() + mapdisplay[i].toolbars["map"].combo.SetSelection(1) # # load layout diff --git a/gui/wxpython/mapdisp/main.py b/gui/wxpython/mapdisp/main.py index 2083f49033a..dd91a33178d 100644 --- a/gui/wxpython/mapdisp/main.py +++ b/gui/wxpython/mapdisp/main.py @@ -216,24 +216,26 @@ def GetLayersFromCmdFile(self): exists = False for i, layer in enumerate(existingLayers): - if layer.GetCmd(string=True) == utils.GetCmdString( + if layer.GetCmd(string=True) != utils.GetCmdString( cmdlist_to_tuple(cmd) ): - exists = True - - if layersOrder[i] == -1: - layersOrder[i] = next_layer - next_layer += 1 - # layer must be put higher in render order (same cmd was - # insered more times) - # TODO delete rendurant cmds from cmd file? - else: - for j, l_order in enumerate(layersOrder): - if l_order > layersOrder[i]: - layersOrder[j] -= 1 - layersOrder[i] = next_layer - 1 - - break + continue + + exists = True + + if layersOrder[i] == -1: + layersOrder[i] = next_layer + next_layer += 1 + # layer must be put higher in render order (same cmd was + # insered more times) + # TODO delete rendurant cmds from cmd file? + else: + for j, l_order in enumerate(layersOrder): + if l_order > layersOrder[i]: + layersOrder[j] -= 1 + layersOrder[i] = next_layer - 1 + + break if exists: continue diff --git a/gui/wxpython/mapwin/buffered.py b/gui/wxpython/mapwin/buffered.py index 7e42ebc57c9..be6e87e32d9 100644 --- a/gui/wxpython/mapwin/buffered.py +++ b/gui/wxpython/mapwin/buffered.py @@ -796,18 +796,19 @@ def GetOverlay(self): imgs = [] for overlay in self.Map.GetListOfLayers(ltype="overlay", active=True): if ( - overlay.mapfile is not None - and os.path.isfile(overlay.mapfile) - and os.path.getsize(overlay.mapfile) + overlay.mapfile is None + or not os.path.isfile(overlay.mapfile) + or (not os.path.getsize(overlay.mapfile)) ): - img = utils.autoCropImageFromFile(overlay.mapfile) + continue + img = utils.autoCropImageFromFile(overlay.mapfile) - for key in list(self.imagedict.keys()): - if self.imagedict[key]["id"] == overlay.id: - del self.imagedict[key] + for key in list(self.imagedict.keys()): + if self.imagedict[key]["id"] == overlay.id: + del self.imagedict[key] - self.imagedict[img] = {"id": overlay.id, "layer": overlay} - imgs.append(img) + self.imagedict[img] = {"id": overlay.id, "layer": overlay} + imgs.append(img) return imgs diff --git a/gui/wxpython/modules/extensions.py b/gui/wxpython/modules/extensions.py index 7837a92589d..9d65b8431a3 100644 --- a/gui/wxpython/modules/extensions.py +++ b/gui/wxpython/modules/extensions.py @@ -383,23 +383,25 @@ def Load(self, url, full=True): currentNode.data = {"command": value} elif currentNode is not None: currentNode.data[key] = value - else: - try: - prefix, name = line.strip().split(".", 1) - except ValueError: - prefix = "" - name = line.strip() - - if self._expandPrefix(prefix) == prefix: - prefix = "" - module = prefix + "." + name - mainNode = self.mainNodes[self._expandPrefix(prefix)] - currentNode = self.model.AppendNode(parent=mainNode, label=module) - currentNode.data = { - "command": module, - "keywords": "", - "description": "", - } + + continue + + try: + prefix, name = line.strip().split(".", 1) + except ValueError: + prefix = "" + name = line.strip() + + if self._expandPrefix(prefix) == prefix: + prefix = "" + module = prefix + "." + name + mainNode = self.mainNodes[self._expandPrefix(prefix)] + currentNode = self.model.AppendNode(parent=mainNode, label=module) + currentNode.data = { + "command": module, + "keywords": "", + "description": "", + } class ManageExtensionWindow(wx.Frame): diff --git a/gui/wxpython/nviz/animation.py b/gui/wxpython/nviz/animation.py index 1eeb8d1aea8..fbc4bbed761 100644 --- a/gui/wxpython/nviz/animation.py +++ b/gui/wxpython/nviz/animation.py @@ -196,26 +196,25 @@ def SaveAnimationFile(self, path, prefix, format): self.currentFrame = 0 self.mode = "save" for params in self.animationList: - if not self.stopSaving: - self.UpdateView(params) - number = ("{frame" + formatter + "}").format(frame=self.currentFrame) - filename = "{prefix}_{number}.{ext}".format( - prefix=prefix, number=number, ext=self.formats[format] - ) - filepath = os.path.join(path, filename) - self.mapWindow.SaveToFile( - FileName=filepath, - FileType=self.formats[format], - width=size[0], - height=size[1], - ) - self.currentFrame += 1 - - wx.GetApp().Yield() - toolWin.UpdateFrameIndex(index=self.currentFrame, goToFrame=False) - else: + if self.stopSaving: self.stopSaving = False break + self.UpdateView(params) + number = ("{frame" + formatter + "}").format(frame=self.currentFrame) + filename = "{prefix}_{number}.{ext}".format( + prefix=prefix, number=number, ext=self.formats[format] + ) + filepath = os.path.join(path, filename) + self.mapWindow.SaveToFile( + FileName=filepath, + FileType=self.formats[format], + width=size[0], + height=size[1], + ) + self.currentFrame += 1 + + wx.GetApp().Yield() + toolWin.UpdateFrameIndex(index=self.currentFrame, goToFrame=False) self.animationSaved = True self.PostFinishedEvent() diff --git a/gui/wxpython/nviz/mapwindow.py b/gui/wxpython/nviz/mapwindow.py index cf0bd87b740..d29924d4590 100644 --- a/gui/wxpython/nviz/mapwindow.py +++ b/gui/wxpython/nviz/mapwindow.py @@ -2543,16 +2543,18 @@ def NvizCmdCommand(self): cmdLColor += "%s," % nvizData["lines"]["color"]["value"] cmdLMode += "%s," % nvizData["lines"]["mode"]["type"] cmdLPos += "0,0,%d," % nvizData["lines"]["height"]["value"] - if (vInfo["points"] + vInfo["centroids"]) > 0: - cmdPoints += ( - "%s," % self.tree.GetLayerInfo(vector, key="maplayer").GetName() - ) - cmdPWidth += "%d," % nvizData["points"]["width"]["value"] - cmdPSize += "%d," % nvizData["points"]["size"]["value"] - cmdPColor += "%s," % nvizData["points"]["color"]["value"] - cmdPMarker += "%s," % markers[nvizData["points"]["marker"]["value"]] - cmdPPos += "0,0,%d," % nvizData["points"]["height"]["value"] - cmdPLayer += "1,1," + if vInfo["points"] + vInfo["centroids"] <= 0: + continue + cmdPoints += ( + "%s," % self.tree.GetLayerInfo(vector, key="maplayer").GetName() + ) + cmdPWidth += "%d," % nvizData["points"]["width"]["value"] + cmdPSize += "%d," % nvizData["points"]["size"]["value"] + cmdPColor += "%s," % nvizData["points"]["color"]["value"] + cmdPMarker += "%s," % markers[nvizData["points"]["marker"]["value"]] + cmdPPos += "0,0,%d," % nvizData["points"]["height"]["value"] + cmdPLayer += "1,1," + if cmdLines: cmd += "vline=" + cmdLines.strip(",") + " " cmd += "vline_width=" + cmdLWidth.strip(",") + " " diff --git a/gui/wxpython/nviz/tools.py b/gui/wxpython/nviz/tools.py index 49cbec8067e..95b7717e8ea 100644 --- a/gui/wxpython/nviz/tools.py +++ b/gui/wxpython/nviz/tools.py @@ -5457,18 +5457,19 @@ def UpdateVectorPage(self, layer, data, updateName=True): display.SetSelection(1) else: display.SetSelection(0) - if data[vtype]["mode"]["type"] == "surface": - rasters = self.mapWindow.GetLayerNames("raster") - constants = self.mapWindow.GetLayerNames("constant") - surfaces = rasters + constants - surfaceWin = self.FindWindowById(self.win["vector"][vtype]["surface"]) - surfaceWin.SetItems(surfaces) - for idx, surface in enumerate(surfaces): - try: # TODO fix this mess - selected = data[vtype]["mode"]["surface"]["show"][idx] - except (TypeError, IndexError, KeyError): - selected = False - surfaceWin.Check(idx, selected) + if data[vtype]["mode"]["type"] != "surface": + continue + rasters = self.mapWindow.GetLayerNames("raster") + constants = self.mapWindow.GetLayerNames("constant") + surfaces = rasters + constants + surfaceWin = self.FindWindowById(self.win["vector"][vtype]["surface"]) + surfaceWin.SetItems(surfaces) + for idx, surface in enumerate(surfaces): + try: # TODO fix this mess + selected = data[vtype]["mode"]["surface"]["show"][idx] + except (TypeError, IndexError, KeyError): + selected = False + surfaceWin.Check(idx, selected) for type in ("slider", "text"): win = self.FindWindowById(self.win["vector"]["lines"]["height"][type]) diff --git a/gui/wxpython/psmap/frame.py b/gui/wxpython/psmap/frame.py index c06396051a8..2913a2eb461 100644 --- a/gui/wxpython/psmap/frame.py +++ b/gui/wxpython/psmap/frame.py @@ -1299,26 +1299,26 @@ def DialogDataChanged(self, id): else: self.deleteObject(id) - if itype == "vectorLegend": - if not self.instruction.FindInstructionByType("vector"): - self.deleteObject(id) - elif self.instruction[id]["vLegend"]: - self.canvas.UpdateLabel(itype=itype, id=id) - drawRectangle = self.canvas.CanvasPaperCoordinates( - rect=self.instruction[id]["rect"], canvasToPaper=False - ) - self.canvas.Draw( - pen=self.pen[itype], - brush=self.brush[itype], - pdc=self.canvas.pdcObj, - drawid=id, - pdctype="rectText", - bb=drawRectangle, - ) - self.canvas.RedrawSelectBox(id) - - else: - self.deleteObject(id) + if itype != "vectorLegend": + continue + if not self.instruction.FindInstructionByType("vector"): + self.deleteObject(id) + elif self.instruction[id]["vLegend"]: + self.canvas.UpdateLabel(itype=itype, id=id) + drawRectangle = self.canvas.CanvasPaperCoordinates( + rect=self.instruction[id]["rect"], canvasToPaper=False + ) + self.canvas.Draw( + pen=self.pen[itype], + brush=self.brush[itype], + pdc=self.canvas.pdcObj, + drawid=id, + pdctype="rectText", + bb=drawRectangle, + ) + self.canvas.RedrawSelectBox(id) + else: + self.deleteObject(id) def OnPageChanged(self, event): """GNotebook page has changed""" diff --git a/gui/wxpython/psmap/instructions.py b/gui/wxpython/psmap/instructions.py index 4528e0a0d93..4b3f7d5c456 100644 --- a/gui/wxpython/psmap/instructions.py +++ b/gui/wxpython/psmap/instructions.py @@ -101,21 +101,22 @@ def __contains__(self, id): def __delitem__(self, id): """Delete instruction""" for each in self.instruction: - if each.id == id: - if each.type == "map": - # must remove raster, vector layers, labels too - vektor = self.FindInstructionByType("vector", list=True) - vProperties = self.FindInstructionByType("vProperties", list=True) - raster = self.FindInstructionByType("raster", list=True) - labels = self.FindInstructionByType("labels", list=True) - for item in vektor + vProperties + raster + labels: - if item in self.instruction: - self.instruction.remove(item) - - self.instruction.remove(each) - if id in self.objectsToDraw: - self.objectsToDraw.remove(id) - return + if each.id != id: + continue + if each.type == "map": + # must remove raster, vector layers, labels too + vektor = self.FindInstructionByType("vector", list=True) + vProperties = self.FindInstructionByType("vProperties", list=True) + raster = self.FindInstructionByType("raster", list=True) + labels = self.FindInstructionByType("labels", list=True) + for item in vektor + vProperties + raster + labels: + if item in self.instruction: + self.instruction.remove(item) + + self.instruction.remove(each) + if id in self.objectsToDraw: + self.objectsToDraw.remove(id) + return def AddInstruction(self, instruction): """Add instruction""" @@ -1937,29 +1938,30 @@ def Read(self, instruction, text, **kwargs): instr = {} for line in text: - if line.startswith(("vpoints", "vlines", "vareas")): - # subtype - if line.startswith("vpoints"): - subType = "points" - elif line.startswith("vlines"): - subType = "lines" - elif line.startswith("vareas"): - subType = "areas" - # name of vector map - vmap = line.split()[1] - try: - info = gs.find_file(vmap, element="vector") - except gs.ScriptError as e: - GError(message=e.value) - return False - vmap = info["fullname"] - # id - id = kwargs["id"] - # lpos - lpos = kwargs["vectorMapNumber"] - # label - label = "(".join(vmap.split("@")) + ")" - break + if not line.startswith(("vpoints", "vlines", "vareas")): + continue + # subtype + if line.startswith("vpoints"): + subType = "points" + elif line.startswith("vlines"): + subType = "lines" + elif line.startswith("vareas"): + subType = "areas" + # name of vector map + vmap = line.split()[1] + try: + info = gs.find_file(vmap, element="vector") + except gs.ScriptError as e: + GError(message=e.value) + return False + vmap = info["fullname"] + # id + id = kwargs["id"] + # lpos + lpos = kwargs["vectorMapNumber"] + # label + label = "(".join(vmap.split("@")) + ")" + break instr = [vmap, subType, id, lpos, label] if not self.instruction["list"]: self.instruction["list"] = [] diff --git a/gui/wxpython/rlisetup/sampling_frame.py b/gui/wxpython/rlisetup/sampling_frame.py index e62737449e6..bc61ef4f109 100644 --- a/gui/wxpython/rlisetup/sampling_frame.py +++ b/gui/wxpython/rlisetup/sampling_frame.py @@ -216,28 +216,26 @@ def createRegion(self): ) ret = dlg.ShowModal() while True: - if ret == wx.ID_OK: - raster = dlg.GetValue() - if checkMapExists(raster): - GMessage( - parent=self, - message=_( - "The raster file %s already exists, please change name" - ) - % raster, - ) - ret = dlg.ShowModal() - else: - dlg.Destroy() - marea = self.writeArea( - self._registeredGraphics.GetItem(0).GetCoords(), raster - ) - self.nextRegion(next=True, area=marea) - break - else: + if ret != wx.ID_OK: self.nextRegion(next=False) break + raster = dlg.GetValue() + if not checkMapExists(raster): + dlg.Destroy() + marea = self.writeArea( + self._registeredGraphics.GetItem(0).GetCoords(), raster + ) + self.nextRegion(next=True, area=marea) + break + + GMessage( + parent=self, + message=_("The raster file %s already exists, please change name") + % raster, + ) + ret = dlg.ShowModal() + def nextRegion(self, next=True, area=None): self.mapWindow.ClearLines() item = self._registeredGraphics.GetItem(0) @@ -336,26 +334,24 @@ def createCircle(self, c): ) ret = dlg.ShowModal() while True: - if ret == wx.ID_OK: - raster = dlg.GetValue() - if checkMapExists(raster): - GMessage( - parent=self, - message=_( - "The raster file %s already exists, please change name" - ) - % raster, - ) - ret = dlg.ShowModal() - else: - dlg.Destroy() - circle = self.writeCircle(c, raster) - self.nextCircle(next=True, circle=circle) - break - else: + if ret != wx.ID_OK: self.nextCircle(next=False) break + raster = dlg.GetValue() + if not checkMapExists(raster): + dlg.Destroy() + circle = self.writeCircle(c, raster) + self.nextCircle(next=True, circle=circle) + break + + GMessage( + parent=self, + message=_("The raster file %s already exists, please change name") + % raster, + ) + ret = dlg.ShowModal() + def nextCircle(self, next=True, circle=None): self.mapWindow.ClearLines() item = self._registeredGraphics.GetItem(0) diff --git a/gui/wxpython/tplot/frame.py b/gui/wxpython/tplot/frame.py index 831d06e93a8..6d93f0593ef 100755 --- a/gui/wxpython/tplot/frame.py +++ b/gui/wxpython/tplot/frame.py @@ -633,68 +633,64 @@ def _getSTVDData(self, timeseries): for i in range(len(rows)): row = rows[i] values = out[i] - if str(row["layer"]) == str(values["Layer"]): - lay = "{map}_{layer}".format( - map=row["name"], layer=values["Layer"] - ) - self.timeDataV[name][lay] = {} - self.timeDataV[name][lay]["start_datetime"] = row["start_time"] - self.timeDataV[name][lay]["end_datetime"] = row["start_time"] - self.timeDataV[name][lay]["value"] = values["Attributes"][ - attribute - ] - else: - wherequery = "" - cats = self._getExistingCategories(rows[0]["name"], cats) - totcat = len(cats) - ncat = 1 - for cat in cats: - if ncat == 1 and totcat != 1: - wherequery += "{k}={c} or".format(c=cat, k="{key}") - elif ncat == 1 and totcat == 1: - wherequery += "{k}={c}".format(c=cat, k="{key}") - elif ncat == totcat: - wherequery += " {k}={c}".format(c=cat, k="{key}") - else: - wherequery += " {k}={c} or".format(c=cat, k="{key}") + if str(row["layer"]) != str(values["Layer"]): + continue + lay = "{map}_{layer}".format(map=row["name"], layer=values["Layer"]) + self.timeDataV[name][lay] = {} + self.timeDataV[name][lay]["start_datetime"] = row["start_time"] + self.timeDataV[name][lay]["end_datetime"] = row["start_time"] + self.timeDataV[name][lay]["value"] = values["Attributes"][attribute] - catn = "cat{num}".format(num=cat) - self.plotNameListV.append("{na}+{cat}".format(na=name, cat=catn)) - self.timeDataV[name][catn] = OrderedDict() - ncat += 1 - for row in rows: - lay = int(row["layer"]) - catkey = self._parseVDbConn(row["name"], lay) - if not catkey: - GError( - parent=self, - showTraceback=False, - message=_( - "No connection between vector map {vmap} " - "and layer {la}" - ).format(vmap=row["name"], la=lay), - ) - return - vals = gs.vector_db_select( - map=row["name"], - layer=lay, - where=wherequery.format(key=catkey), - columns=attribute, + continue + + wherequery = "" + cats = self._getExistingCategories(rows[0]["name"], cats) + totcat = len(cats) + ncat = 1 + for cat in cats: + if ncat == 1 and totcat != 1: + wherequery += "{k}={c} or".format(c=cat, k="{key}") + elif ncat == 1 and totcat == 1: + wherequery += "{k}={c}".format(c=cat, k="{key}") + elif ncat == totcat: + wherequery += " {k}={c}".format(c=cat, k="{key}") + else: + wherequery += " {k}={c} or".format(c=cat, k="{key}") + + catn = "cat{num}".format(num=cat) + self.plotNameListV.append("{na}+{cat}".format(na=name, cat=catn)) + self.timeDataV[name][catn] = OrderedDict() + ncat += 1 + for row in rows: + lay = int(row["layer"]) + catkey = self._parseVDbConn(row["name"], lay) + if not catkey: + GError( + parent=self, + showTraceback=False, + message=_( + "No connection between vector map {vmap} and layer {la}" + ).format(vmap=row["name"], la=lay), ) - layn = "lay{num}".format(num=lay) - for cat in cats: - catn = "cat{num}".format(num=cat) - if layn not in self.timeDataV[name][catn].keys(): - self.timeDataV[name][catn][layn] = {} - self.timeDataV[name][catn][layn]["start_datetime"] = row[ - "start_time" - ] - self.timeDataV[name][catn][layn]["end_datetime"] = row[ - "end_time" - ] - self.timeDataV[name][catn][layn]["value"] = vals["values"][ - int(cat) - ][0] + return + vals = gs.vector_db_select( + map=row["name"], + layer=lay, + where=wherequery.format(key=catkey), + columns=attribute, + ) + layn = "lay{num}".format(num=lay) + for cat in cats: + catn = "cat{num}".format(num=cat) + if layn not in self.timeDataV[name][catn].keys(): + self.timeDataV[name][catn][layn] = {} + self.timeDataV[name][catn][layn]["start_datetime"] = row[ + "start_time" + ] + self.timeDataV[name][catn][layn]["end_datetime"] = row["end_time"] + self.timeDataV[name][catn][layn]["value"] = vals["values"][ + int(cat) + ][0] self.unit = unit self.temporalType = mode return diff --git a/gui/wxpython/vdigit/dialogs.py b/gui/wxpython/vdigit/dialogs.py index 27d34601459..5b87c74f02f 100644 --- a/gui/wxpython/vdigit/dialogs.py +++ b/gui/wxpython/vdigit/dialogs.py @@ -426,29 +426,31 @@ def ApplyChanges(self, fid): for cat in catsCurr[0][layer]: if layer not in catsCurr[1].keys() or cat not in catsCurr[1][layer]: catList.append(cat) - if catList != []: - add = action == "catadd" - - newfid = self.digit.SetLineCats(fid, layer, catList, add) - if len(self.cats.keys()) == 1: - self.fidText.SetLabel("%d" % newfid) - else: - choices = self.fidMulti.GetItems() - choices[choices.index(str(fid))] = str(newfid) - self.fidMulti.SetItems(choices) - self.fidMulti.SetStringSelection(str(newfid)) - - self.cats[newfid] = self.cats[fid] - del self.cats[fid] - - fid = newfid - if self.fid < 0: - wx.MessageBox( - parent=self, - message=_("Unable to update vector map."), - caption=_("Error"), - style=wx.OK | wx.ICON_ERROR, - ) + + if catList == []: + continue + + add = action == "catadd" + newfid = self.digit.SetLineCats(fid, layer, catList, add) + if len(self.cats.keys()) == 1: + self.fidText.SetLabel("%d" % newfid) + else: + choices = self.fidMulti.GetItems() + choices[choices.index(str(fid))] = str(newfid) + self.fidMulti.SetItems(choices) + self.fidMulti.SetStringSelection(str(newfid)) + + self.cats[newfid] = self.cats[fid] + del self.cats[fid] + + fid = newfid + if self.fid < 0: + wx.MessageBox( + parent=self, + message=_("Unable to update vector map."), + caption=_("Error"), + style=wx.OK | wx.ICON_ERROR, + ) self.cats_orig[fid] = copy.deepcopy(cats) diff --git a/gui/wxpython/vdigit/wxdigit.py b/gui/wxpython/vdigit/wxdigit.py index b4b7b0dfd7b..230d63351b2 100644 --- a/gui/wxpython/vdigit/wxdigit.py +++ b/gui/wxpython/vdigit/wxdigit.py @@ -738,13 +738,14 @@ def _getLineAreasCategories(self, ln_id): areas = [left.value, right.value] for i, a in enumerate(areas): - if a > 0: - centroid = Vect_get_area_centroid(self.poMapInfo, a) - if centroid <= 0: - continue - c = self._getCategories(centroid) - if c: - cats[i] = c + if a <= 0: + continue + centroid = Vect_get_area_centroid(self.poMapInfo, a) + if centroid <= 0: + continue + c = self._getCategories(centroid) + if c: + cats[i] = c return cats @@ -1268,95 +1269,94 @@ def CopyCats(self, fromId, toId, copyAttrb=False): if not copyAttrb: # duplicate category cat = catsFrom.cat[i] - else: - # duplicate attributes - cat = self.cats[catsFrom.field[i]] + 1 - self.cats[catsFrom.field[i]] = cat - poFi = Vect_get_field(self.poMapInfo, catsFrom.field[i]) - if not poFi: - self._error.DbLink(i) - return -1 + continue - fi = poFi.contents - driver = db_start_driver(fi.driver) - if not driver: - self._error.Driver(fi.driver) - return -1 + # duplicate attributes + cat = self.cats[catsFrom.field[i]] + 1 + self.cats[catsFrom.field[i]] = cat + poFi = Vect_get_field(self.poMapInfo, catsFrom.field[i]) + if not poFi: + self._error.DbLink(i) + return -1 - handle = dbHandle() - db_init_handle(byref(handle)) - db_set_handle(byref(handle), fi.database, None) - if db_open_database(driver, byref(handle)) != DB_OK: - db_shutdown_driver(driver) - self._error.Database(fi.driver, fi.database) - return -1 + fi = poFi.contents + driver = db_start_driver(fi.driver) + if not driver: + self._error.Driver(fi.driver) + return -1 - stmt = dbString() - db_init_string(byref(stmt)) - db_set_string( - byref(stmt), - "SELECT * FROM %s WHERE %s=%d" - % (fi.table, fi.key, catsFrom.cat[i]), + handle = dbHandle() + db_init_handle(byref(handle)) + db_set_handle(byref(handle), fi.database, None) + if db_open_database(driver, byref(handle)) != DB_OK: + db_shutdown_driver(driver) + self._error.Database(fi.driver, fi.database) + return -1 + + stmt = dbString() + db_init_string(byref(stmt)) + db_set_string( + byref(stmt), + "SELECT * FROM %s WHERE %s=%d" + % (fi.table, fi.key, catsFrom.cat[i]), + ) + + cursor = dbCursor() + if ( + db_open_select_cursor( + driver, byref(stmt), byref(cursor), DB_SEQUENTIAL ) + != DB_OK + ): + db_close_database_shutdown_driver(driver) + return -1 - cursor = dbCursor() - if ( - db_open_select_cursor( - driver, byref(stmt), byref(cursor), DB_SEQUENTIAL - ) - != DB_OK - ): + table = db_get_cursor_table(byref(cursor)) + ncols = db_get_table_number_of_columns(table) + + sql = "INSERT INTO %s VALUES (" % fi.table + # fetch the data + more = c_int() + while True: + if db_fetch(byref(cursor), DB_NEXT, byref(more)) != DB_OK: db_close_database_shutdown_driver(driver) return -1 - - table = db_get_cursor_table(byref(cursor)) - ncols = db_get_table_number_of_columns(table) - - sql = "INSERT INTO %s VALUES (" % fi.table - # fetch the data - more = c_int() - while True: - if db_fetch(byref(cursor), DB_NEXT, byref(more)) != DB_OK: - db_close_database_shutdown_driver(driver) - return -1 - if not more.value: - break - - value_string = dbString() - for col in range(ncols): - if col > 0: - sql += "," - - column = db_get_table_column(table, col) - if db_get_column_name(column) == fi.key: - sql += "%d" % cat - continue - - value = db_get_column_value(column) - db_convert_column_value_to_string( - column, byref(value_string) + if not more.value: + break + + value_string = dbString() + for col in range(ncols): + if col > 0: + sql += "," + + column = db_get_table_column(table, col) + if db_get_column_name(column) == fi.key: + sql += "%d" % cat + continue + + value = db_get_column_value(column) + db_convert_column_value_to_string( + column, byref(value_string) + ) + if db_test_value_isnull(value): + sql += "NULL" + else: + ctype = db_sqltype_to_Ctype( + db_get_column_sqltype(column) ) - if db_test_value_isnull(value): - sql += "NULL" + if ctype != DB_C_TYPE_STRING: + sql += db_get_string(byref(value_string)) else: - ctype = db_sqltype_to_Ctype( - db_get_column_sqltype(column) - ) - if ctype != DB_C_TYPE_STRING: - sql += db_get_string(byref(value_string)) - else: - sql += "'%s'" % db_get_string( - byref(value_string) - ) - - sql += ")" - db_set_string(byref(stmt), sql) - if db_execute_immediate(driver, byref(stmt)) != DB_OK: - db_close_database_shutdown_driver(driver) - return -1 + sql += "'%s'" % db_get_string(byref(value_string)) + sql += ")" + db_set_string(byref(stmt), sql) + if db_execute_immediate(driver, byref(stmt)) != DB_OK: db_close_database_shutdown_driver(driver) - G_free(poFi) + return -1 + + db_close_database_shutdown_driver(driver) + G_free(poFi) if Vect_cat_set(poCatsTo, catsFrom.field[i], cat) < 1: continue diff --git a/gui/wxpython/vdigit/wxdisplay.py b/gui/wxpython/vdigit/wxdisplay.py index 6679e5c5814..ce97d31b1db 100644 --- a/gui/wxpython/vdigit/wxdisplay.py +++ b/gui/wxpython/vdigit/wxdisplay.py @@ -1141,14 +1141,15 @@ def GetDuplicates(self): Vect_read_line(self.poMapInfo, BPoints, None, line2) - if Vect_line_check_duplicate(APoints, BPoints, WITHOUT_Z): - if i not in ids: - ids[i] = [] - ids[i].append((line1, self._getCatString(line1))) - self.selected["idsDupl"].append(line1) - - ids[i].append((line2, self._getCatString(line2))) - self.selected["idsDupl"].append(line2) + if not Vect_line_check_duplicate(APoints, BPoints, WITHOUT_Z): + continue + if i not in ids: + ids[i] = [] + ids[i].append((line1, self._getCatString(line1))) + self.selected["idsDupl"].append(line1) + + ids[i].append((line2, self._getCatString(line2))) + self.selected["idsDupl"].append(line2) Vect_destroy_line_struct(APoints) Vect_destroy_line_struct(BPoints) diff --git a/gui/wxpython/vnet/dialogs.py b/gui/wxpython/vnet/dialogs.py index ca928a6b164..19d8e6c8a93 100644 --- a/gui/wxpython/vnet/dialogs.py +++ b/gui/wxpython/vnet/dialogs.py @@ -1189,15 +1189,16 @@ def SetData(self, key, data): self.CheckItem(idx, True) elif not v and self.IsItemChecked(idx): self.CheckItem(idx, False) - else: - found = 0 - for col in self.colsData: - if k == col[0]: - found = 1 - break - - if found: - self.EditCellKey(key, k, v) + continue + + found = 0 + for col in self.colsData: + if k == col[0]: + found = 1 + break + + if found: + self.EditCellKey(key, k, v) def OnItemSelected(self, event): """Item selected""" diff --git a/gui/wxpython/wxplot/profile.py b/gui/wxpython/wxplot/profile.py index e0994f1a8a5..fa629f926cc 100644 --- a/gui/wxpython/wxplot/profile.py +++ b/gui/wxpython/wxplot/profile.py @@ -262,16 +262,18 @@ def SetupProfile(self): for r in self.raster.keys(): self.raster[r]["datalist"] = [] datalist = self.CreateDatalist(r, self.coordstr) - if len(datalist) > 0: - self.raster[r]["datalist"] = datalist + if len(datalist) <= 0: + continue + + self.raster[r]["datalist"] = datalist - # update ylabel to match units if they exist - if self.raster[r]["units"] != "": - self.ylabel += "%s (%d)," % (self.raster[r]["units"], i) - i += 1 + # update ylabel to match units if they exist + if self.raster[r]["units"] != "": + self.ylabel += "%s (%d)," % (self.raster[r]["units"], i) + i += 1 - # update title - self.ptitle += " %s ," % r.split("@")[0] + # update title + self.ptitle += " %s ," % r.split("@")[0] self.ptitle = self.ptitle.rstrip(",") From 67090db826cf0700fde103c32c6cc59e9fae3d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sat, 4 Jan 2025 00:42:49 +0000 Subject: [PATCH 05/21] gui: Early exit functions Flattens nested conditionals and moves error messages near the top --- gui/wxpython/animation/dialogs.py | 5 +- gui/wxpython/animation/nviztask.py | 6 +- gui/wxpython/core/render.py | 69 +++---- gui/wxpython/core/toolboxes.py | 182 ++++++++-------- gui/wxpython/core/utils.py | 55 +++-- gui/wxpython/dbmgr/vinfo.py | 7 +- gui/wxpython/gcp/manager.py | 48 ++--- gui/wxpython/gmodeler/model.py | 22 +- gui/wxpython/gui_core/dialogs.py | 16 +- gui/wxpython/gui_core/gselect.py | 38 ++-- gui/wxpython/gui_core/widgets.py | 24 +-- gui/wxpython/iclass/frame.py | 36 ++-- gui/wxpython/image2target/ii2t_gis_set.py | 57 +++-- gui/wxpython/image2target/ii2t_manager.py | 48 ++--- gui/wxpython/location_wizard/dialogs.py | 49 ++--- gui/wxpython/mapdisp/frame.py | 34 +-- gui/wxpython/mapdisp/statusbar.py | 40 ++-- gui/wxpython/mapwin/buffered.py | 28 +-- gui/wxpython/modules/import_export.py | 11 +- gui/wxpython/nviz/wxnviz.py | 14 +- gui/wxpython/photo2image/ip2i_manager.py | 56 +++-- gui/wxpython/psmap/dialogs.py | 241 +++++++++++----------- gui/wxpython/psmap/instructions.py | 18 +- gui/wxpython/psmap/utils.py | 38 ++-- gui/wxpython/startup/guiutils.py | 8 +- gui/wxpython/vdigit/toolbars.py | 48 ++--- gui/wxpython/vdigit/wxdigit.py | 10 +- gui/wxpython/vnet/vnet_core.py | 62 +++--- gui/wxpython/vnet/vnet_data.py | 14 +- gui/wxpython/vnet/vnet_utils.py | 26 ++- gui/wxpython/vnet/widgets.py | 29 ++- gui/wxpython/wxplot/base.py | 22 +- 32 files changed, 643 insertions(+), 718 deletions(-) diff --git a/gui/wxpython/animation/dialogs.py b/gui/wxpython/animation/dialogs.py index 5a634b3bb16..b4c8e2dabc5 100644 --- a/gui/wxpython/animation/dialogs.py +++ b/gui/wxpython/animation/dialogs.py @@ -727,10 +727,9 @@ def _update(self): if isStart: self.animationData.startRegion = isStart else: - if isStart: - self.animationData.startRegion = isStart - else: + if not isStart: raise GException(_("Region information is not complete")) + self.animationData.startRegion = isStart if isEnd: self.animationData.endRegion = self.endRegion.GetValue() self.animationData.zoomRegionValue = None diff --git a/gui/wxpython/animation/nviztask.py b/gui/wxpython/animation/nviztask.py index 5dbb1d3e982..caa02553db4 100644 --- a/gui/wxpython/animation/nviztask.py +++ b/gui/wxpython/animation/nviztask.py @@ -299,12 +299,10 @@ def GetCommandSeries(self, layerList, paramName): if len(layerList) > 1: raise GException(_("Please add only one layer in the list.")) - return layer = layerList[0] - if hasattr(layer, "maps"): - series = layer.maps - else: + if not hasattr(layer, "maps"): raise GException(_("No map series nor space-time dataset is added.")) + series = layer.maps for value in series: self.task.set_param(paramName, value) diff --git a/gui/wxpython/core/render.py b/gui/wxpython/core/render.py index 67e7561c4e7..0b9857fd072 100644 --- a/gui/wxpython/core/render.py +++ b/gui/wxpython/core/render.py @@ -217,15 +217,12 @@ def GetCmd(self, string=False): :return: command list/string """ - if string: - if self.type == "command": - scmd = [] - for c in self.cmd: - scmd.append(utils.GetCmdString(c)) - - return ";".join(scmd) - return utils.GetCmdString(self.cmd) - return self.cmd + if not string: + return self.cmd + if self.type == "command": + scmd = [utils.GetCmdString(c) for c in self.cmd] + return ";".join(scmd) + return utils.GetCmdString(self.cmd) def GetType(self): """Get map layer type""" @@ -1406,29 +1403,28 @@ def DeleteLayer(self, layer, overlay=False): list_ = self.overlays if overlay else self.layers - if layer in list_: - if layer.mapfile: - base, mapfile = os.path.split(layer.mapfile) - tempbase = mapfile.split(".")[0] - if base == "" or tempbase == "": - return None - basefile = os.path.join(base, tempbase) + r".*" - # this comes all the way from r28605, so leaving - # it as it is, although it does not really fit with the - # new system (but probably works well enough) - for f in glob.glob(basefile): - os.remove(f) - - if layer.GetType() in {"vector", "thememap"}: - if os.path.isfile(layer._legrow): - os.remove(layer._legrow) - - list_.remove(layer) - - self.layerRemoved.emit(layer=layer) - return layer + if layer not in list_: + return None + if layer.mapfile: + base, mapfile = os.path.split(layer.mapfile) + tempbase = mapfile.split(".")[0] + if base == "" or tempbase == "": + return None + basefile = os.path.join(base, tempbase) + r".*" + # this comes all the way from r28605, so leaving + # it as it is, although it does not really fit with the + # new system (but probably works well enough) + for f in glob.glob(basefile): + os.remove(f) - return None + if layer.GetType() in {"vector", "thememap"}: + if os.path.isfile(layer._legrow): + os.remove(layer._legrow) + + list_.remove(layer) + + self.layerRemoved.emit(layer=layer) + return layer def SetLayers(self, layers): self.layers = layers @@ -1653,12 +1649,11 @@ def GetOverlay(self, id, list=False): """ ovl = [overlay for overlay in self.overlays if overlay.id == id] - if not list: - if len(ovl) != 1: - return None - return ovl[0] - - return ovl + if list: + return ovl + if len(ovl) != 1: + return None + return ovl[0] def DeleteOverlay(self, overlay): """Delete overlay diff --git a/gui/wxpython/core/toolboxes.py b/gui/wxpython/core/toolboxes.py index 9b5d83444d7..91095d151e1 100644 --- a/gui/wxpython/core/toolboxes.py +++ b/gui/wxpython/core/toolboxes.py @@ -124,105 +124,101 @@ def getMenudataFile(userRootFile, newFile, fallback): # always create toolboxes directory if does not exist yet tbDir = _setupToolboxes() - if tbDir: - menudataFile = os.path.join(tbDir, newFile) - generateNew = False - # when any of main_menu.xml or toolboxes.xml are changed, - # generate new menudata.xml - - if os.path.exists(menudataFile): - # remove menu file when there is no main_menu and toolboxes - if not _getUserToolboxesFile() and not userRootFile: - os.remove(menudataFile) - _debug( - 2, - ( - "toolboxes.getMenudataFile: no user defined files, " - "menudata deleted" - ), - ) - return fallback - - if bool(_getUserToolboxesFile()) != bool(userRootFile): - # always generate new because we don't know if there has been - # any change - generateNew = True - _debug( - 2, - ( - "toolboxes.getMenudataFile: only one of the user " - "defined files" - ), - ) - else: - # if newer files -> generate new - menudataTime = os.path.getmtime(menudataFile) - if _getUserToolboxesFile(): - if os.path.getmtime(_getUserToolboxesFile()) > menudataTime: - _debug( - 2, - ( - "toolboxes.getMenudataFile: user toolboxes is newer " - "than menudata" - ), - ) - generateNew = True - if userRootFile: - if os.path.getmtime(userRootFile) > menudataTime: - _debug( - 2, - ( - "toolboxes.getMenudataFile: user root file is " - "newer than menudata" - ), - ) - generateNew = True - elif _getUserToolboxesFile() or userRootFile: - _debug(2, "toolboxes.getMenudataFile: no menudata") - generateNew = True - else: - _debug(2, "toolboxes.getMenudataFile: no user defined files") + if not tbDir: + _debug(2, "toolboxes.getMenudataFile: returning menudata fallback file") + return fallback + + menudataFile = os.path.join(tbDir, newFile) + generateNew = False + # when any of main_menu.xml or toolboxes.xml are changed, + # generate new menudata.xml + + if os.path.exists(menudataFile): + # remove menu file when there is no main_menu and toolboxes + if not _getUserToolboxesFile() and (not userRootFile): + os.remove(menudataFile) + _debug( + 2, + ( + "toolboxes.getMenudataFile: no user defined files, " + "menudata deleted" + ), + ) return fallback - if generateNew: - try: - # The case when user does not have custom root - # file but has toolboxes requires regeneration. - # Unfortunately, this is the case can be often: defined - # toolboxes but undefined module tree file. - _debug(2, "toolboxes.getMenudataFile: creating a tree") - tree = createTree( - distributionRootFile=distributionRootFile, userRootFile=userRootFile - ) - except ETREE_EXCEPTIONS: - _warning( - _( - "Unable to parse user toolboxes XML files. " - "Default files will be loaded." - ) - ) - return fallback - - try: - xml = _getXMLString(tree.getroot()) - with open(menudataFile, "w") as fh: - fh.write(xml) - return menudataFile - except Exception: - _debug( - 2, - ( - "toolboxes.getMenudataFile: writing menudata failed, " - "returning fallback file" - ), - ) - return fallback + if bool(_getUserToolboxesFile()) != bool(userRootFile): + # always generate new because we don't know if there has been + # any change + generateNew = True + _debug( + 2, + ("toolboxes.getMenudataFile: only one of the user defined files"), + ) else: - return menudataFile + # if newer files -> generate new + menudataTime = os.path.getmtime(menudataFile) + if _getUserToolboxesFile(): + if os.path.getmtime(_getUserToolboxesFile()) > menudataTime: + _debug( + 2, + ( + "toolboxes.getMenudataFile: user toolboxes is newer " + "than menudata" + ), + ) + generateNew = True + if userRootFile: + if os.path.getmtime(userRootFile) > menudataTime: + _debug( + 2, + ( + "toolboxes.getMenudataFile: user root file is " + "newer than menudata" + ), + ) + generateNew = True + elif _getUserToolboxesFile() or userRootFile: + _debug(2, "toolboxes.getMenudataFile: no menudata") + generateNew = True else: - _debug(2, "toolboxes.getMenudataFile: returning menudata fallback file") + _debug(2, "toolboxes.getMenudataFile: no user defined files") + return fallback + + if not generateNew: + return menudataFile + try: + # The case when user does not have custom root + # file but has toolboxes requires regeneration. + # Unfortunately, this is the case can be often: defined + # toolboxes but undefined module tree file. + _debug(2, "toolboxes.getMenudataFile: creating a tree") + tree = createTree( + distributionRootFile=distributionRootFile, userRootFile=userRootFile + ) + except ETREE_EXCEPTIONS: + _warning( + _( + "Unable to parse user toolboxes XML files. " + "Default files will be loaded." + ) + ) return fallback + try: + xml = _getXMLString(tree.getroot()) + with open(menudataFile, "w") as fh: + fh.write(xml) + return menudataFile + except Exception: + _debug( + 2, + ( + "toolboxes.getMenudataFile: writing menudata failed, " + "returning fallback file" + ), + ) + return fallback + def _setupToolboxes(): """Create 'toolboxes' directory if doesn't exist.""" diff --git a/gui/wxpython/core/utils.py b/gui/wxpython/core/utils.py index 0f894b43a60..f234b6b03c7 100644 --- a/gui/wxpython/core/utils.py +++ b/gui/wxpython/core/utils.py @@ -137,18 +137,18 @@ def GetLayerNameFromCmd(dcmd, fullyQualified=False, param=None, layerType=None): params.append((idx, p, v)) if len(params) < 1: - if len(dcmd) > 1: - i = 1 - while i < len(dcmd): - if "=" not in dcmd[i] and not dcmd[i].startswith("-"): - task = gtask.parse_interface(dcmd[0]) - # this expects the first parameter to be the right one - p = task.get_options()["params"][0].get("name", "") - params.append((i, p, dcmd[i])) - break - i += 1 - else: - return mapname, False + if len(dcmd) <= 1: + return (mapname, False) + + i = 1 + while i < len(dcmd): + if "=" not in dcmd[i] and (not dcmd[i].startswith("-")): + task = gtask.parse_interface(dcmd[0]) + # this expects the first parameter to be the right one + p = task.get_options()["params"][0].get("name", "") + params.append((i, p, dcmd[i])) + break + i += 1 if len(params) < 1: return mapname, False @@ -292,22 +292,21 @@ def ListOfMapsets(get="ordered"): if get == "all": return mapsets_all - if get in {"accessible", "ordered"}: - ret = RunCommand("g.mapsets", read=True, quiet=True, flags="p", sep="newline") - if not ret: - return [] - mapsets_accessible = ret.splitlines() - if get == "accessible": - return mapsets_accessible - - mapsets_ordered = mapsets_accessible.copy() - for mapset in mapsets_all: - if mapset not in mapsets_accessible: - mapsets_ordered.append(mapset) - return mapsets_ordered - - msg = "Invalid value for 'get' parameter of ListOfMapsets()" - raise ValueError(msg) + if get not in {"accessible", "ordered"}: + msg = "Invalid value for 'get' parameter of ListOfMapsets()" + raise ValueError(msg) + ret = RunCommand("g.mapsets", read=True, quiet=True, flags="p", sep="newline") + if not ret: + return [] + mapsets_accessible = ret.splitlines() + if get == "accessible": + return mapsets_accessible + + mapsets_ordered = mapsets_accessible.copy() + for mapset in mapsets_all: + if mapset not in mapsets_accessible: + mapsets_ordered.append(mapset) + return mapsets_ordered def ListSortLower(list): diff --git a/gui/wxpython/dbmgr/vinfo.py b/gui/wxpython/dbmgr/vinfo.py index 94dda140406..c8528dfc3ab 100644 --- a/gui/wxpython/dbmgr/vinfo.py +++ b/gui/wxpython/dbmgr/vinfo.py @@ -45,10 +45,9 @@ def GetDbEncoding(): then env variable), if not assumes unicode.""" enc = UserSettings.Get(group="atm", key="encoding", subkey="value") if not enc and "GRASS_DB_ENCODING" in os.environ: - enc = os.environ["GRASS_DB_ENCODING"] - else: - enc = "utf-8" # assuming UTF-8 - return enc + return os.environ["GRASS_DB_ENCODING"] + # assuming UTF-8 + return "utf-8" def CreateDbInfoDesc(panel, mapDBInfo, layer): diff --git a/gui/wxpython/gcp/manager.py b/gui/wxpython/gcp/manager.py index a55e71b8430..b759df4dd3a 100644 --- a/gui/wxpython/gcp/manager.py +++ b/gui/wxpython/gcp/manager.py @@ -905,9 +905,7 @@ def OnEnterPage(self, event: WizardEvent | None = None) -> None: flags="g", ) - if ret: - self.parent.src_maps = ret.splitlines() - else: + if not ret: GError( parent=self, message=_( @@ -917,6 +915,7 @@ def OnEnterPage(self, event: WizardEvent | None = None) -> None: % self.parent.grouppage.xygroup, ) return + self.parent.src_maps = ret.splitlines() elif maptype == "vector": grassdatabase = self.parent.grassdatabase @@ -1680,25 +1679,24 @@ def CheckGCPcount(self, msg=False): are active for the selected transformation order """ if ( - (self.GCPcount < 3 and self.gr_order == 1) - or (self.GCPcount < 6 and self.gr_order == 2) - or (self.GCPcount < 10 and self.gr_order == 3) + (self.GCPcount >= 3 or self.gr_order != 1) + and (self.GCPcount >= 6 or self.gr_order != 2) + and (self.GCPcount >= 10 or self.gr_order != 3) ): - if msg: - GWarning( - parent=self, - message=_( - "Insufficient points defined and active (checked) " - "for selected rectification method (order: %d).\n" - "3+ points needed for 1st order,\n" - "6+ points for 2nd order, and\n" - "10+ points for 3rd order." - ) - % self.gr_order, - ) - return False - else: return True + if msg: + GWarning( + parent=self, + message=_( + "Insufficient points defined and active (checked) " + "for selected rectification method (order: %d).\n" + "3+ points needed for 1st order,\n" + "6+ points for 2nd order, and\n" + "10+ points for 3rd order." + ) + % self.gr_order, + ) + return False def _getOverWriteDialog(self, maptype, overwrite): """Get overwrite confirm dialog @@ -2015,9 +2013,7 @@ def RMSError(self, xygroup, order): self.grwiz.SwitchEnv("target") - if ret: - errlist = ret.splitlines() - else: + if not ret: GError( parent=self, message=_( @@ -2026,6 +2022,7 @@ def RMSError(self, xygroup, order): ), ) return + errlist = ret.splitlines() # insert error values into GCP list for checked items sdfactor = float(UserSettings.Get(group="gcpman", key="rms", subkey="sdfactor")) @@ -2149,9 +2146,7 @@ def GetNewExtent(self, region, map=None): self.grwiz.SwitchEnv("target") - if ret: - errlist = ret.splitlines() - else: + if not ret: GError( parent=self, message=_( @@ -2160,6 +2155,7 @@ def GetNewExtent(self, region, map=None): ), ) return + errlist = ret.splitlines() # fist corner e, n = errlist[0].split() diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index 1ce96ea4826..47590759592 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -1212,12 +1212,11 @@ def GetLog(self, string=True, substitute=None): cmd[idx] = pattern.sub(value, cmd[idx]) idx += 1 - if string: - if cmd is None: - return "" - return " ".join(cmd) - - return cmd + if not string: + return cmd + if cmd is None: + return "" + return " ".join(cmd) def GetLabel(self): """Get name""" @@ -1976,12 +1975,11 @@ def _filterValue(self, value): def _getNodeText(self, node, tag, default=""): """Get node text""" p = node.find(tag) - if p is not None: - if p.text: - return utils.normalize_whitespace(p.text) - return "" - - return default + if p is None: + return default + if p.text: + return utils.normalize_whitespace(p.text) + return "" def _processWindow(self): """Process window properties""" diff --git a/gui/wxpython/gui_core/dialogs.py b/gui/wxpython/gui_core/dialogs.py index ca412808a57..9a2cad1eda9 100644 --- a/gui/wxpython/gui_core/dialogs.py +++ b/gui/wxpython/gui_core/dialogs.py @@ -280,12 +280,11 @@ def GetName(self, full=False): :param full: True to get fully qualified name """ name = self.element.GetValue() - if full: - if "@" in name: - return name - return name + "@" + grass.gisenv()["MAPSET"] - - return name.split("@", 1)[0] + if not full: + return name.split("@", 1)[0] + if "@" in name: + return name + return name + "@" + grass.gisenv()["MAPSET"] class NewVectorDialog(VectorDialog): @@ -532,12 +531,11 @@ def CreateNewVector( caption=_("Overwrite?"), style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION, ) - if dlgOw.ShowModal() == wx.ID_YES: - overwrite = True - else: + if dlgOw.ShowModal() != wx.ID_YES: dlgOw.Destroy() dlg.Destroy() return None + overwrite = True if UserSettings.Get(group="cmd", key="overwrite", subkey="enabled"): overwrite = True diff --git a/gui/wxpython/gui_core/gselect.py b/gui/wxpython/gui_core/gselect.py index fe5b644df0f..f164b39fc54 100644 --- a/gui/wxpython/gui_core/gselect.py +++ b/gui/wxpython/gui_core/gselect.py @@ -2974,26 +2974,26 @@ def _isMapSelected(self): def _chckMap(self): """Check if selected map in 'input' widget is the same as selected map in lmgr""" - if self._isMapSelected(): - layerList = self.giface.GetLayerList() - layerSelected = layerList.GetSelectedLayer() - # d.vect module - inputName = self.task.get_param(value="map", raiseError=False) - if not inputName: - inputName = self.task.get_param("input") - if inputName["value"] != str(layerSelected): - if inputName["value"] == "" or inputName["value"] is None: - GWarning(_("Input vector map is not selected")) - return False - GWarning( - _( - "Input vector map <%s> and selected map <%s> in layer manager " - "are different. Operation canceled." - ) - % (inputName["value"], str(layerSelected)) - ) - return False + if not self._isMapSelected(): + return False + layerList = self.giface.GetLayerList() + layerSelected = layerList.GetSelectedLayer() + # d.vect module + inputName = self.task.get_param(value="map", raiseError=False) + if not inputName: + inputName = self.task.get_param("input") + if inputName["value"] == str(layerSelected): return True + if inputName["value"] == "" or inputName["value"] is None: + GWarning(_("Input vector map is not selected")) + return False + GWarning( + _( + "Input vector map <%s> and selected map <%s> in layer manager " + "are different. Operation canceled." + ) + % (inputName["value"], str(layerSelected)) + ) return False def _onClick(self, evt=None): diff --git a/gui/wxpython/gui_core/widgets.py b/gui/wxpython/gui_core/widgets.py index 47bd3a1957c..3c84af4ecbc 100644 --- a/gui/wxpython/gui_core/widgets.py +++ b/gui/wxpython/gui_core/widgets.py @@ -183,12 +183,12 @@ def DeletePage(self, page): :return bool: True if page was deleted, False if not exists """ delPageIndex = self.GetPageIndexByName(page) - if delPageIndex != -1: - ret = self.classObject.DeletePage(self.widget, delPageIndex) - if ret: - del self.notebookPages[page] - return ret - return False + if delPageIndex == -1: + return False + ret = self.classObject.DeletePage(self.widget, delPageIndex) + if ret: + del self.notebookPages[page] + return ret def RemovePage(self, page): """Delete page without deleting the associated window. @@ -197,12 +197,12 @@ def RemovePage(self, page): :return: True if page was deleted, False if not exists """ delPageIndex = self.GetPageIndexByName(page) - if delPageIndex != -1: - ret = self.classObject.RemovePage(self.widget, delPageIndex) - if ret: - del self.notebookPages[page] - return ret - return False + if delPageIndex == -1: + return False + ret = self.classObject.RemovePage(self.widget, delPageIndex) + if ret: + del self.notebookPages[page] + return ret def SetSelectionByName(self, page): """Set active notebook page. diff --git a/gui/wxpython/iclass/frame.py b/gui/wxpython/iclass/frame.py index 4bb9e66b6c4..9901ccf3322 100644 --- a/gui/wxpython/iclass/frame.py +++ b/gui/wxpython/iclass/frame.py @@ -792,25 +792,25 @@ def ImportClasses(self, vector): for cat in cats: listCtrl.AddCategory(cat=cat, name="class_%d" % cat, color="0:0:0") + + return + # connection, table and columns exists - else: - columns = ["cat", "class", "color"] - ret = RunCommand( - "v.db.select", - quiet=True, - parent=self, - flags="c", - map=vector, - layer=1, - columns=",".join(columns), - read=True, - ) - records = ret.strip().splitlines() - for record in records: - record = record.split("|") - listCtrl.AddCategory( - cat=int(record[0]), name=record[1], color=record[2] - ) + columns = ["cat", "class", "color"] + ret = RunCommand( + "v.db.select", + quiet=True, + parent=self, + flags="c", + map=vector, + layer=1, + columns=",".join(columns), + read=True, + ) + records = ret.strip().splitlines() + for record in records: + record = record.split("|") + listCtrl.AddCategory(cat=int(record[0]), name=record[1], color=record[2]) def OnExportAreas(self, event): """Export training areas""" diff --git a/gui/wxpython/image2target/ii2t_gis_set.py b/gui/wxpython/image2target/ii2t_gis_set.py index dcc8744f469..2a3deed26f4 100644 --- a/gui/wxpython/image2target/ii2t_gis_set.py +++ b/gui/wxpython/image2target/ii2t_gis_set.py @@ -345,12 +345,11 @@ def _set_properties(self, version, revision): sys.stderr.write( _("ERROR: Location <%s> not found\n") % self.GetRCValue("LOCATION_NAME") ) - if len(self.listOfLocations) > 0: - self.lblocations.SetSelection(0, force=True) - self.lblocations.EnsureVisible(0) - location = self.listOfLocations[0] - else: + if len(self.listOfLocations) <= 0: return + self.lblocations.SetSelection(0, force=True) + self.lblocations.EnsureVisible(0) + location = self.listOfLocations[0] # list of mapsets self.UpdateMapsets(os.path.join(self.gisdbase, location)) @@ -1112,34 +1111,32 @@ def OnStart(self, event): ret = dlg.ShowModal() dlg.Destroy() - if ret == wx.ID_YES: - dlg1 = wx.MessageDialog( - parent=self, - message=_( - "ARE YOU REALLY SURE?\n\n" - "If you really are running another GRASS session doing this " - "could corrupt your data. Have another look in the processor " - "manager just to be sure..." - ), - caption=_("Lock file found"), - style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.CENTRE, - ) + if ret != wx.ID_YES: + return - ret = dlg1.ShowModal() - dlg1.Destroy() + dlg1 = wx.MessageDialog( + parent=self, + message=_( + "ARE YOU REALLY SURE?\n\n" + "If you really are running another GRASS session doing this " + "could corrupt your data. Have another look in the processor " + "manager just to be sure..." + ), + caption=_("Lock file found"), + style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.CENTRE, + ) + ret = dlg1.ShowModal() + dlg1.Destroy() - if ret == wx.ID_YES: - try: - os.remove(lockfile) - except OSError as e: - GError( - _("Unable to remove '%(lock)s'.\n\nDetails: %(reason)s") - % {"lock": lockfile, "reason": e} - ) - else: - return - else: + if ret != wx.ID_YES: return + try: + os.remove(lockfile) + except OSError as e: + GError( + _("Unable to remove '%(lock)s'.\n\nDetails: %(reason)s") + % {"lock": lockfile, "reason": e} + ) self.SetLocation(dbase, location, mapset) self.ExitSuccessfully() diff --git a/gui/wxpython/image2target/ii2t_manager.py b/gui/wxpython/image2target/ii2t_manager.py index ff51b0f87aa..ab2ac30ae88 100644 --- a/gui/wxpython/image2target/ii2t_manager.py +++ b/gui/wxpython/image2target/ii2t_manager.py @@ -914,9 +914,7 @@ def OnEnterPage(self, event: WizardEvent | None = None) -> None: flags="g", ) - if ret: - self.parent.src_maps = ret.splitlines() - else: + if not ret: GError( parent=self, message=_( @@ -926,6 +924,7 @@ def OnEnterPage(self, event: WizardEvent | None = None) -> None: % self.parent.grouppage.xygroup, ) return + self.parent.src_maps = ret.splitlines() elif maptype == "vector": grassdatabase = self.parent.grassdatabase @@ -1713,25 +1712,24 @@ def CheckGCPcount(self, msg=False): are active for the selected transformation order """ if ( - (self.GCPcount < 3 and self.gr_order == 1) - or (self.GCPcount < 6 and self.gr_order == 2) - or (self.GCPcount < 10 and self.gr_order == 3) + (self.GCPcount >= 3 or self.gr_order != 1) + and (self.GCPcount >= 6 or self.gr_order != 2) + and (self.GCPcount >= 10 or self.gr_order != 3) ): - if msg: - GWarning( - parent=self, - message=_( - "Insufficient points defined and active (checked) " - "for selected rectification method (order: %d).\n" - "3+ points needed for 1st order,\n" - "6+ points for 2nd order, and\n" - "10+ points for 3rd order." - ) - % self.gr_order, - ) - return False - else: return True + if msg: + GWarning( + parent=self, + message=_( + "Insufficient points defined and active (checked) " + "for selected rectification method (order: %d).\n" + "3+ points needed for 1st order,\n" + "6+ points for 2nd order, and\n" + "10+ points for 3rd order." + ) + % self.gr_order, + ) + return False def OnGeorect(self, event): """ @@ -1963,9 +1961,7 @@ def RMSError(self, xygroup, order): self.grwiz.SwitchEnv("target") - if ret: - errlist = ret.splitlines() - else: + if not ret: GError( parent=self, message=_( @@ -1974,6 +1970,7 @@ def RMSError(self, xygroup, order): ), ) return + errlist = ret.splitlines() # insert error values into GCP list for checked items sdfactor = float(UserSettings.Get(group="gcpman", key="rms", subkey="sdfactor")) @@ -2098,9 +2095,7 @@ def GetNewExtent(self, region, map=None): self.grwiz.SwitchEnv("target") - if ret: - errlist = ret.splitlines() - else: + if not ret: GError( parent=self, message=_( @@ -2109,6 +2104,7 @@ def GetNewExtent(self, region, map=None): ), ) return + errlist = ret.splitlines() # fist corner e, n = errlist[0].split() diff --git a/gui/wxpython/location_wizard/dialogs.py b/gui/wxpython/location_wizard/dialogs.py index 74a59cca525..6573aeb717a 100644 --- a/gui/wxpython/location_wizard/dialogs.py +++ b/gui/wxpython/location_wizard/dialogs.py @@ -50,9 +50,7 @@ def __init__( self.parent = parent self.location = location - # # default values - # # 2D self.north = 1.0 self.south = 0.0 @@ -67,9 +65,7 @@ def __init__( # self.ewres3 = 1.0 self.tbres = 1.0 - # # inputs - # # 2D self.tnorth = self.MakeTextCtrl( text=str(self.north), size=(150, -1), parent=panel @@ -80,43 +76,26 @@ def __init__( self.tnsres = self.MakeTextCtrl(str(self.nsres), size=(150, -1), parent=panel) self.tewres = self.MakeTextCtrl(str(self.ewres), size=(150, -1), parent=panel) - # # labels - # self.lrows = self.MakeLabel(parent=panel) self.lcols = self.MakeLabel(parent=panel) self.lcells = self.MakeLabel(parent=panel) - # # buttons - # self.bset = self.MakeButton(text=_("&Set region"), id=wx.ID_OK, parent=panel) self.bcancel = Button(panel, id=wx.ID_CANCEL) self.bset.SetDefault() - # # image - # self.img = wx.Image( os.path.join(globalvar.IMGDIR, "qgis_world.png"), wx.BITMAP_TYPE_PNG ).ConvertToBitmap() - # # set current working environment to PERMANENT mapset # in selected location in order to set default region (WIND) - # envval = {} ret = RunCommand("g.gisenv", read=True) - if ret: - for line in ret.splitlines(): - key, val = line.split("=") - envval[key] = val - self.currlocation = envval["LOCATION_NAME"].strip("';") - self.currmapset = envval["MAPSET"].strip("';") - if self.currlocation != self.location or self.currmapset != "PERMANENT": - RunCommand("g.gisenv", set="LOCATION_NAME=%s" % self.location) - RunCommand("g.gisenv", set="MAPSET=PERMANENT") - else: + if not ret: dlg = wx.MessageBox( parent=self, message=_("Invalid location selected."), @@ -124,17 +103,19 @@ def __init__( style=wx.ID_OK | wx.ICON_ERROR, ) return + for line in ret.splitlines(): + key, val = line.split("=") + envval[key] = val + self.currlocation = envval["LOCATION_NAME"].strip("';") + self.currmapset = envval["MAPSET"].strip("';") + if self.currlocation != self.location or self.currmapset != "PERMANENT": + RunCommand("g.gisenv", set="LOCATION_NAME=%s" % self.location) + RunCommand("g.gisenv", set="MAPSET=PERMANENT") - # # get current region settings - # region = {} ret = RunCommand("g.region", read=True, flags="gp3") - if ret: - for line in ret.splitlines(): - key, val = line.split("=") - region[key] = float(val) - else: + if not ret: dlg = wx.MessageBox( parent=self, message=_("Invalid region"), @@ -144,8 +125,10 @@ def __init__( dlg.ShowModal() dlg.Destroy() return + for line in ret.splitlines(): + key, val = line.split("=") + region[key] = float(val) - # # update values # 2D self.north = float(region["n"]) @@ -166,9 +149,7 @@ def __init__( self.depth = int(region["depths"]) self.cells3 = int(region["cells3"]) - # # 3D box collapsible - # self.infoCollapseLabelExp = _("Click here to show 3D settings") self.infoCollapseLabelCol = _("Click here to hide 3D settings") self.settings3D = wx.CollapsiblePane( @@ -184,9 +165,7 @@ def __init__( self.settings3D, ) - # # set current region settings - # self.tnorth.SetValue(str(self.north)) self.tsouth.SetValue(str(self.south)) self.twest.SetValue(str(self.west)) @@ -202,9 +181,7 @@ def __init__( self.lcols.SetLabel(_("Cols: %d") % self.cols) self.lcells.SetLabel(_("Cells: %d") % self.cells) - # # bindings - # self.Bind(wx.EVT_BUTTON, self.OnSetButton, self.bset) self.Bind(wx.EVT_BUTTON, self.OnCancel, self.bcancel) self.tnorth.Bind(wx.EVT_TEXT, self.OnValue) diff --git a/gui/wxpython/mapdisp/frame.py b/gui/wxpython/mapdisp/frame.py index 0be010f3432..f91cea76e72 100644 --- a/gui/wxpython/mapdisp/frame.py +++ b/gui/wxpython/mapdisp/frame.py @@ -1215,23 +1215,23 @@ def AddTmpVectorMapLayer( cmd[-1].append("layer=%d" % layer) cmd[-1].append("cats=%s" % ListOfCatsToRange(lcats)) - if addLayer: - args = {} - if useId: - args["ltype"] = "vector" - else: - args["ltype"] = "command" - - return self.Map.AddLayer( - name=globalvar.QUERYLAYER, - command=cmd, - active=True, - hidden=True, - opacity=1.0, - render=True, - **args, - ) - return cmd + if not addLayer: + return cmd + + args = {} + if useId: + args["ltype"] = "vector" + else: + args["ltype"] = "command" + return self.Map.AddLayer( + name=globalvar.QUERYLAYER, + command=cmd, + active=True, + hidden=True, + opacity=1.0, + render=True, + **args, + ) def OnMeasureDistance(self, event): self._onMeasure(MeasureDistanceController) diff --git a/gui/wxpython/mapdisp/statusbar.py b/gui/wxpython/mapdisp/statusbar.py index 7e60e762281..ae0b3b832d0 100644 --- a/gui/wxpython/mapdisp/statusbar.py +++ b/gui/wxpython/mapdisp/statusbar.py @@ -626,11 +626,11 @@ def GetCenterString(self, map): projOut=projection, flags="d", ) - if coord: - if proj in {"ll", "latlong", "longlat"} and format == "DMS": - return "%s" % utils.Deg2DMS(coord[0], coord[1], precision=precision) - return "%.*f; %.*f" % (precision, coord[0], precision, coord[1]) - raise SbException(_("Error in projection (check the settings)")) + if not coord: + raise SbException(_("Error in projection (check the settings)")) + if proj in {"ll", "latlong", "longlat"} and format == "DMS": + return "%s" % utils.Deg2DMS(coord[0], coord[1], precision=precision) + return "%.*f; %.*f" % (precision, coord[0], precision, coord[1]) if self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS": return "%s" % utils.Deg2DMS( region["center_easting"], @@ -786,23 +786,21 @@ def ReprojectENFromMap(self, e, n, useDefinedProjection, precision, format): @throws SbException if useDefinedProjection is True and projection is not defined in UserSettings """ - if useDefinedProjection: - settings = UserSettings.Get( - group="projection", key="statusbar", subkey="proj4" - ) - if not settings: - raise SbException(_("Projection not defined (check the settings)")) - # reproject values - proj, coord = utils.ReprojectCoordinates( - coord=(e, n), projOut=settings, flags="d" - ) - if coord: - e, n = coord - if proj in {"ll", "latlong", "longlat"} and format == "DMS": - return utils.Deg2DMS(e, n, precision=precision) - return "%.*f; %.*f" % (precision, e, precision, n) + if not useDefinedProjection: + if self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS": + return utils.Deg2DMS(e, n, precision=precision) + return "%.*f; %.*f" % (precision, e, precision, n) + settings = UserSettings.Get(group="projection", key="statusbar", subkey="proj4") + if not settings: + raise SbException(_("Projection not defined (check the settings)")) + # reproject values + proj, coord = utils.ReprojectCoordinates( + coord=(e, n), projOut=settings, flags="d" + ) + if not coord: raise SbException(_("Error in projection (check the settings)")) - if self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS": + e, n = coord + if proj in {"ll", "latlong", "longlat"} and format == "DMS": return utils.Deg2DMS(e, n, precision=precision) return "%.*f; %.*f" % (precision, e, precision, n) diff --git a/gui/wxpython/mapwin/buffered.py b/gui/wxpython/mapwin/buffered.py index be6e87e32d9..b1bfe5714fd 100644 --- a/gui/wxpython/mapwin/buffered.py +++ b/gui/wxpython/mapwin/buffered.py @@ -1220,23 +1220,17 @@ def DrawLines(self, pdc=None, polycoords=None): if not polycoords: polycoords = self.polycoords - if len(polycoords) > 0: - self.plineid = wx.ID_NEW + 1 - # convert from EN to XY - coords = [] - for p in polycoords: - coords.append(self.Cell2Pixel(p)) - - self.Draw(pdc, drawid=self.plineid, pdctype="polyline", coords=coords) - - Debug.msg( - 4, - "BufferedWindow.DrawLines(): coords=%s, id=%s" % (coords, self.plineid), - ) - - return self.plineid - - return -1 + if len(polycoords) <= 0: + return -1 + self.plineid = wx.ID_NEW + 1 + # convert from EN to XY + coords = [self.Cell2Pixel(p) for p in polycoords] + self.Draw(pdc, drawid=self.plineid, pdctype="polyline", coords=coords) + Debug.msg( + 4, + "BufferedWindow.DrawLines(): coords=%s, id=%s" % (coords, self.plineid), + ) + return self.plineid def DrawPolylines(self, pdc, coords, pen, drawid=None): """Draw polyline in PseudoDC. diff --git a/gui/wxpython/modules/import_export.py b/gui/wxpython/modules/import_export.py index c6e3b9c6d42..a0d6c5ac665 100644 --- a/gui/wxpython/modules/import_export.py +++ b/gui/wxpython/modules/import_export.py @@ -398,13 +398,12 @@ def _getLayersToReprojetion(self, projMatch_idx, grassName_idx): ret = dlg.ShowModal() - if ret == wx.ID_OK: - # do not import unchecked layers - for itm in reversed(list(dlg.GetData(checked=False))): - idx = itm[-1] - layers.pop(idx) - else: + if ret != wx.ID_OK: return None + # do not import unchecked layers + for itm in reversed(list(dlg.GetData(checked=False))): + idx = itm[-1] + layers.pop(idx) return layers diff --git a/gui/wxpython/nviz/wxnviz.py b/gui/wxpython/nviz/wxnviz.py index 63be18a69c1..07eb60526e0 100644 --- a/gui/wxpython/nviz/wxnviz.py +++ b/gui/wxpython/nviz/wxnviz.py @@ -429,13 +429,13 @@ def LookAtCenter(self): def GetFocus(self): """Get focus""" Debug.msg(3, "Nviz::GetFocus()") - if Nviz_has_focus(self.data): - x = c_float() - y = c_float() - z = c_float() - Nviz_get_focus(self.data, byref(x), byref(y), byref(z)) - return x.value, y.value, z.value - return -1, -1, -1 + if not Nviz_has_focus(self.data): + return (-1, -1, -1) + x = c_float() + y = c_float() + z = c_float() + Nviz_get_focus(self.data, byref(x), byref(y), byref(z)) + return (x.value, y.value, z.value) def SetFocus(self, x: float, y: float, z: float) -> None: """Set focus""" diff --git a/gui/wxpython/photo2image/ip2i_manager.py b/gui/wxpython/photo2image/ip2i_manager.py index 0033944be94..273b6dce28f 100644 --- a/gui/wxpython/photo2image/ip2i_manager.py +++ b/gui/wxpython/photo2image/ip2i_manager.py @@ -1055,25 +1055,24 @@ def CheckGCPcount(self, msg=False): are active for the selected transformation order """ if ( - (self.GCPcount < 3 and self.gr_order == 1) - or (self.GCPcount < 6 and self.gr_order == 2) - or (self.GCPcount < 10 and self.gr_order == 3) + (self.GCPcount >= 3 or self.gr_order != 1) + and (self.GCPcount >= 6 or self.gr_order != 2) + and (self.GCPcount >= 10 or self.gr_order != 3) ): - if msg: - GWarning( - parent=self, - message=_( - "Insufficient points defined and active (checked) " - "for selected rectification method (order: %d).\n" - "3+ points needed for 1st order,\n" - "6+ points for 2nd order, and\n" - "10+ points for 3rd order." - ) - % self.gr_order, - ) - return False - else: return True + if msg: + GWarning( + parent=self, + message=_( + "Insufficient points defined and active (checked) " + "for selected rectification method (order: %d).\n" + "3+ points needed for 1st order,\n" + "6+ points for 2nd order, and\n" + "10+ points for 3rd order." + ) + % self.gr_order, + ) + return False def OnGeorect(self, event): """ @@ -1267,9 +1266,7 @@ def RMSError(self, xygroup, order): self.grwiz.SwitchEnv("target") - if ret: - errlist = ret.splitlines() - else: + if not ret: GError( parent=self, message=_( @@ -1278,6 +1275,7 @@ def RMSError(self, xygroup, order): ), ) return + errlist = ret.splitlines() # insert error values into GCP list for checked items sdfactor = float(UserSettings.Get(group="gcpman", key="rms", subkey="sdfactor")) @@ -1308,12 +1306,13 @@ def RMSError(self, xygroup, order): sumsq_bkw_err += float(bkw_err) ** 2 sum_fwd_err += float(fwd_err) GCPcount += 1 - else: - self.list.SetItem(index, 5, "") - self.list.SetItem(index, 6, "") - self.mapcoordlist[key][5] = 0.0 - self.mapcoordlist[key][6] = 0.0 - self.list.SetItemTextColour(index, wx.BLACK) + + continue + self.list.SetItem(index, 5, "") + self.list.SetItem(index, 6, "") + self.mapcoordlist[key][5] = 0.0 + self.mapcoordlist[key][6] = 0.0 + self.list.SetItemTextColour(index, wx.BLACK) # SD if GCPcount > 0: @@ -1403,9 +1402,7 @@ def GetNewExtent(self, region, map=None): self.grwiz.SwitchEnv("target") - if ret: - errlist = ret.splitlines() - else: + if not ret: GError( parent=self, message=_( @@ -1414,6 +1411,7 @@ def GetNewExtent(self, region, map=None): ), ) return + errlist = ret.splitlines() # fist corner e, n = errlist[0].split() diff --git a/gui/wxpython/psmap/dialogs.py b/gui/wxpython/psmap/dialogs.py index 25319e21976..68e0adca71c 100644 --- a/gui/wxpython/psmap/dialogs.py +++ b/gui/wxpython/psmap/dialogs.py @@ -1394,138 +1394,114 @@ def update(self): mapFrameDict["scaleType"] = scaleType if mapFrameDict["scaleType"] == 0: - if self.select.GetValue(): - mapFrameDict["drawMap"] = self.drawMap.GetValue() - mapFrameDict["map"] = self.select.GetValue() - mapFrameDict["mapType"] = self.mapType - mapFrameDict["region"] = None - - if mapFrameDict["drawMap"]: - if mapFrameDict["mapType"] == "raster": - mapFile = gs.find_file(mapFrameDict["map"], element="cell") - if mapFile["file"] == "": - GMessage("Raster %s not found" % mapFrameDict["map"]) - return False - raster = self.instruction.FindInstructionByType("raster") - if raster: - raster["raster"] = mapFrameDict["map"] - else: - raster = Raster(NewId(), env=self.env) - raster["raster"] = mapFrameDict["map"] - raster["isRaster"] = True - self.instruction.AddInstruction(raster) - - elif mapFrameDict["mapType"] == "vector": - mapFile = gs.find_file(mapFrameDict["map"], element="vector") - if mapFile["file"] == "": - GMessage("Vector %s not found" % mapFrameDict["map"]) - return False - - vector = self.instruction.FindInstructionByType("vector") - isAdded = False - if vector: - for each in vector["list"]: - if each[0] == mapFrameDict["map"]: - isAdded = True - if not isAdded: - topoInfo = gs.vector_info_topo(map=mapFrameDict["map"]) - if topoInfo: - if bool(topoInfo["areas"]): - topoType = "areas" - elif bool(topoInfo["lines"]): - topoType = "lines" - else: - topoType = "points" - label = "(".join(mapFrameDict["map"].split("@")) + ")" - - if not vector: - vector = Vector(NewId(), env=self.env) - vector["list"] = [] - self.instruction.AddInstruction(vector) - id = NewId() - vector["list"].insert( - 0, [mapFrameDict["map"], topoType, id, 1, label] - ) - vProp = VProperties(id, topoType, env=self.env) - vProp["name"], vProp["label"], vProp["lpos"] = ( - mapFrameDict["map"], - label, - 1, - ) - self.instruction.AddInstruction(vProp) - else: - return False - - self.scale[0], self.center[0], self.rectAdjusted = AutoAdjust( - self, - scaleType=0, - map=mapFrameDict["map"], - env=self.env, - mapType=self.mapType, - rect=self.mapFrameDict["rect"], + if not self.select.GetValue(): + wx.MessageBox( + message=_("No map selected!"), + caption=_("Invalid input"), + style=wx.OK | wx.ICON_ERROR, ) + return False - if self.rectAdjusted: - mapFrameDict["rect"] = self.rectAdjusted - else: - mapFrameDict["rect"] = self.mapFrameDict["rect"] - - mapFrameDict["scale"] = self.scale[0] + mapFrameDict["drawMap"] = self.drawMap.GetValue() + mapFrameDict["map"] = self.select.GetValue() + mapFrameDict["mapType"] = self.mapType + mapFrameDict["region"] = None - mapFrameDict["center"] = self.center[0] - # set region - if self.mapType == "raster": - self.env["GRASS_REGION"] = gs.region_env( - raster=mapFrameDict["map"], env=self.env - ) - if self.mapType == "vector": + if mapFrameDict["drawMap"]: + if mapFrameDict["mapType"] == "raster": + mapFile = gs.find_file(mapFrameDict["map"], element="cell") + if mapFile["file"] == "": + GMessage("Raster %s not found" % mapFrameDict["map"]) + return False raster = self.instruction.FindInstructionByType("raster") - rasterId = raster.id if raster else None - - if rasterId: - self.env["GRASS_REGION"] = gs.region_env( - vector=mapFrameDict["map"], - raster=self.instruction[rasterId]["raster"], - env=self.env, - ) + if raster: + raster["raster"] = mapFrameDict["map"] else: - self.env["GRASS_REGION"] = gs.region_env( - vector=mapFrameDict["map"], env=self.env - ) + raster = Raster(NewId(), env=self.env) + raster["raster"] = mapFrameDict["map"] + raster["isRaster"] = True + self.instruction.AddInstruction(raster) + + elif mapFrameDict["mapType"] == "vector": + mapFile = gs.find_file(mapFrameDict["map"], element="vector") + if mapFile["file"] == "": + GMessage("Vector %s not found" % mapFrameDict["map"]) + return False + + vector = self.instruction.FindInstructionByType("vector") + isAdded = False + if vector: + for each in vector["list"]: + if each[0] == mapFrameDict["map"]: + isAdded = True + if not isAdded: + topoInfo = gs.vector_info_topo(map=mapFrameDict["map"]) + if topoInfo: + if bool(topoInfo["areas"]): + topoType = "areas" + elif bool(topoInfo["lines"]): + topoType = "lines" + else: + topoType = "points" + label = "(".join(mapFrameDict["map"].split("@")) + ")" + + if not vector: + vector = Vector(NewId(), env=self.env) + vector["list"] = [] + self.instruction.AddInstruction(vector) + id = NewId() + vector["list"].insert( + 0, [mapFrameDict["map"], topoType, id, 1, label] + ) + vProp = VProperties(id, topoType, env=self.env) + vProp["name"], vProp["label"], vProp["lpos"] = ( + mapFrameDict["map"], + label, + 1, + ) + self.instruction.AddInstruction(vProp) + else: + return False + + self.scale[0], self.center[0], self.rectAdjusted = AutoAdjust( + self, + scaleType=0, + map=mapFrameDict["map"], + env=self.env, + mapType=self.mapType, + rect=self.mapFrameDict["rect"], + ) + if self.rectAdjusted: + mapFrameDict["rect"] = self.rectAdjusted else: - wx.MessageBox( - message=_("No map selected!"), - caption=_("Invalid input"), - style=wx.OK | wx.ICON_ERROR, - ) - return False + mapFrameDict["rect"] = self.mapFrameDict["rect"] - elif mapFrameDict["scaleType"] == 1: - if self.select.GetValue(): - mapFrameDict["drawMap"] = False - mapFrameDict["map"] = None - mapFrameDict["mapType"] = None - mapFrameDict["region"] = self.select.GetValue() - self.scale[1], self.center[1], self.rectAdjusted = AutoAdjust( - self, - scaleType=1, - region=mapFrameDict["region"], - rect=self.mapFrameDict["rect"], - env=self.env, - ) - if self.rectAdjusted: - mapFrameDict["rect"] = self.rectAdjusted - else: - mapFrameDict["rect"] = self.mapFrameDict["rect"] + mapFrameDict["scale"] = self.scale[0] - mapFrameDict["scale"] = self.scale[1] - mapFrameDict["center"] = self.center[1] - # set region + mapFrameDict["center"] = self.center[0] + # set region + if self.mapType == "raster": self.env["GRASS_REGION"] = gs.region_env( - region=mapFrameDict["region"], env=self.env + raster=mapFrameDict["map"], env=self.env ) - else: + if self.mapType == "vector": + raster = self.instruction.FindInstructionByType("raster") + rasterId = raster.id if raster else None + + if rasterId: + self.env["GRASS_REGION"] = gs.region_env( + vector=mapFrameDict["map"], + raster=self.instruction[rasterId]["raster"], + env=self.env, + ) + else: + self.env["GRASS_REGION"] = gs.region_env( + vector=mapFrameDict["map"], env=self.env + ) + + elif mapFrameDict["scaleType"] == 1: + if not self.select.GetValue(): wx.MessageBox( message=_("No region selected!"), caption=_("Invalid input"), @@ -1533,6 +1509,29 @@ def update(self): ) return False + mapFrameDict["drawMap"] = False + mapFrameDict["map"] = None + mapFrameDict["mapType"] = None + mapFrameDict["region"] = self.select.GetValue() + self.scale[1], self.center[1], self.rectAdjusted = AutoAdjust( + self, + scaleType=1, + region=mapFrameDict["region"], + rect=self.mapFrameDict["rect"], + env=self.env, + ) + if self.rectAdjusted: + mapFrameDict["rect"] = self.rectAdjusted + else: + mapFrameDict["rect"] = self.mapFrameDict["rect"] + + mapFrameDict["scale"] = self.scale[1] + mapFrameDict["center"] = self.center[1] + # set region + self.env["GRASS_REGION"] = gs.region_env( + region=mapFrameDict["region"], env=self.env + ) + elif scaleType == 2: mapFrameDict["drawMap"] = False mapFrameDict["map"] = None diff --git a/gui/wxpython/psmap/instructions.py b/gui/wxpython/psmap/instructions.py index 4b3f7d5c456..052d7da3da3 100644 --- a/gui/wxpython/psmap/instructions.py +++ b/gui/wxpython/psmap/instructions.py @@ -1213,21 +1213,21 @@ def GetImageOrigSize(self, imagePath): If eps, size is read from image header. """ fileName = os.path.split(imagePath)[1] + if os.path.splitext(fileName)[1].lower() != ".eps": + # we can use wx.Image + img = wx.Image(fileName, type=wx.BITMAP_TYPE_ANY) + return (img.GetWidth(), img.GetHeight()) + # if eps, read info from header - if os.path.splitext(fileName)[1].lower() == ".eps": - bbInfo = "%%BoundingBox" - file = open(imagePath) - w = h = 0 + bbInfo = "%%BoundingBox" + w = h = 0 + with open(imagePath) as file: while file: line = file.readline() if line.find(bbInfo) == 0: w, h = line.split()[3:5] break - file.close() - return float(w), float(h) - # we can use wx.Image - img = wx.Image(fileName, type=wx.BITMAP_TYPE_ANY) - return img.GetWidth(), img.GetHeight() + return (float(w), float(h)) class NorthArrow(Image): diff --git a/gui/wxpython/psmap/utils.py b/gui/wxpython/psmap/utils.py index 10b10f96297..be63f5cd403 100644 --- a/gui/wxpython/psmap/utils.py +++ b/gui/wxpython/psmap/utils.py @@ -195,26 +195,24 @@ def PaperMapCoordinates(mapInstr, x, y, paperToMap=True, env=None): mapWidthEN = region["e"] - region["w"] mapHeightEN = region["n"] - region["s"] - if paperToMap: - diffX = x - mapInstr["rect"].GetX() - diffY = y - mapInstr["rect"].GetY() - diffEW = diffX * mapWidthEN / mapWidthPaper - diffNS = diffY * mapHeightEN / mapHeightPaper - e = region["w"] + diffEW - n = region["n"] - diffNS - - if projInfo()["proj"] == "ll": - return e, n - return int(e), int(n) - - diffEW = x - region["w"] - diffNS = region["n"] - y - diffX = mapWidthPaper * diffEW / mapWidthEN - diffY = mapHeightPaper * diffNS / mapHeightEN - xPaper = mapInstr["rect"].GetX() + diffX - yPaper = mapInstr["rect"].GetY() + diffY - - return xPaper, yPaper + if not paperToMap: + diffEW = x - region["w"] + diffNS = region["n"] - y + diffX = mapWidthPaper * diffEW / mapWidthEN + diffY = mapHeightPaper * diffNS / mapHeightEN + xPaper = mapInstr["rect"].GetX() + diffX + yPaper = mapInstr["rect"].GetY() + diffY + return (xPaper, yPaper) + + diffX = x - mapInstr["rect"].GetX() + diffY = y - mapInstr["rect"].GetY() + diffEW = diffX * mapWidthEN / mapWidthPaper + diffNS = diffY * mapHeightEN / mapHeightPaper + e = region["w"] + diffEW + n = region["n"] - diffNS + if projInfo()["proj"] == "ll": + return (e, n) + return (int(e), int(n)) def AutoAdjust(self, scaleType, rect, env, map=None, mapType=None, region=None): diff --git a/gui/wxpython/startup/guiutils.py b/gui/wxpython/startup/guiutils.py index fa4d0a8760a..2d228c5e7ac 100644 --- a/gui/wxpython/startup/guiutils.py +++ b/gui/wxpython/startup/guiutils.py @@ -199,11 +199,9 @@ def create_location_interactively(guiparent, grassdb): ) # Returns database and location created by user # and a mapset user may want to switch to - gWizard_output = (gWizard.grassdatabase, gWizard.location, mapset) - else: - # Returns PERMANENT mapset when user mapset not defined - gWizard_output = (gWizard.grassdatabase, gWizard.location, "PERMANENT") - return gWizard_output + return (gWizard.grassdatabase, gWizard.location, mapset) + # Returns PERMANENT mapset when user mapset not defined + return (gWizard.grassdatabase, gWizard.location, "PERMANENT") def rename_mapset_interactively(guiparent, grassdb, location, mapset): diff --git a/gui/wxpython/vdigit/toolbars.py b/gui/wxpython/vdigit/toolbars.py index 61b79235193..1e81ea6b4cb 100644 --- a/gui/wxpython/vdigit/toolbars.py +++ b/gui/wxpython/vdigit/toolbars.py @@ -995,31 +995,32 @@ def OnSelectMap(self, event): disableAdd=True, ) - if dlg and dlg.GetName(): - # add layer to map layer tree/map display - mapName = dlg.GetName() + "@" + gs.gisenv()["MAPSET"] - self._giface.GetLayerList().AddLayer( - ltype="vector", - name=mapName, - checked=True, - cmd=["d.vect", "map=%s" % mapName], - ) - - vectLayers = self.UpdateListOfLayers(updateTool=True) - selection = vectLayers.index(mapName) - - # create table ? - if dlg.IsChecked("table"): - # TODO: starting of tools such as atm, iclass, - # plots etc. should be handled in some better way - # than starting randomly from mapdisp and lmgr - self.openATM.emit(selection="table") - dlg.Destroy() - else: + if not dlg or not dlg.GetName(): self.combo.SetValue(_("Select vector map")) if dlg: dlg.Destroy() return + + # add layer to map layer tree/map display + mapName = dlg.GetName() + "@" + gs.gisenv()["MAPSET"] + self._giface.GetLayerList().AddLayer( + ltype="vector", + name=mapName, + checked=True, + cmd=["d.vect", "map=%s" % mapName], + ) + + vectLayers = self.UpdateListOfLayers(updateTool=True) + selection = vectLayers.index(mapName) + + # create table ? + if dlg.IsChecked("table"): + # TODO: starting of tools such as atm, iclass, + # plots etc. should be handled in some better way + # than starting randomly from mapdisp and lmgr + self.openATM.emit(selection="table") + dlg.Destroy() + else: selection = event.GetSelection() - 1 # first option is 'New vector map' @@ -1058,10 +1059,9 @@ def StartEditing(self, mapLayer): caption=_("Digitizer error"), style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION | wx.CENTRE, ) - if dlg.ShowModal() == wx.ID_YES: - RunCommand("v.build", map=mapLayer.GetName()) - else: + if dlg.ShowModal() != wx.ID_YES: return + RunCommand("v.build", map=mapLayer.GetName()) # deactivate layer self.Map.ChangeLayerActive(mapLayer, False) diff --git a/gui/wxpython/vdigit/wxdigit.py b/gui/wxpython/vdigit/wxdigit.py index 230d63351b2..79e194a0dc4 100644 --- a/gui/wxpython/vdigit/wxdigit.py +++ b/gui/wxpython/vdigit/wxdigit.py @@ -291,11 +291,11 @@ def _getSnapMode(self): :return: snap mode """ threshold = self._display.GetThreshold() - if threshold > 0.0: - if UserSettings.Get(group="vdigit", key="snapToVertex", subkey="enabled"): - return SNAPVERTEX - return SNAP - return NO_SNAP + if threshold <= 0.0: + return NO_SNAP + if UserSettings.Get(group="vdigit", key="snapToVertex", subkey="enabled"): + return SNAPVERTEX + return SNAP def _getNewFeaturesLayer(self): """Returns layer of new feature (from settings)""" diff --git a/gui/wxpython/vnet/vnet_core.py b/gui/wxpython/vnet/vnet_core.py index f4cfdbaea93..baf8dea9aed 100644 --- a/gui/wxpython/vnet/vnet_core.py +++ b/gui/wxpython/vnet/vnet_core.py @@ -1092,42 +1092,40 @@ def ComputeNodes(self, activate): inpName, mapSet = inpFullName.split("@") computeNodes = True - if "inputMap" not in self.snapData: - pass - elif inpFullName != self.snapData["inputMap"].GetVectMapName(): - self.snapData["inputMap"] = VectMap(None, inpFullName) - elif self.snapData["inputMap"].VectMapState() == 1: - computeNodes = False + if "inputMap" in self.snapData: + if inpFullName != self.snapData["inputMap"].GetVectMapName(): + self.snapData["inputMap"] = VectMap(None, inpFullName) + elif self.snapData["inputMap"].VectMapState() == 1: + computeNodes = False + + if not computeNodes: + # map is already created and up to date for input data + self.snapPts.AddRenderLayer() + self.giface.updateMap.emit(render=True, renderVector=True) + self.snapping.emit(evt="computing_points_done") + return 1 # new map needed - if computeNodes: - if "cmdThread" not in self.snapData: - self.snapData["cmdThread"] = CmdThread(self) - else: - self.snapData["cmdThread"].abort() - - cmd = [ - "v.to.points", - "input=" + params["input"], - "output=" + self.snapPts.GetVectMapName(), - "use=node", - "--overwrite", - ] - # process GRASS command with argument - self.snapData["inputMap"] = VectMap(None, inpFullName) - self.snapData["inputMap"].SaveVectMapState() - - self.Bind(EVT_CMD_DONE, self._onNodesDone) - self.snapData["cmdThread"].RunCmd(cmd) + if "cmdThread" not in self.snapData: + self.snapData["cmdThread"] = CmdThread(self) + else: + self.snapData["cmdThread"].abort() + cmd = [ + "v.to.points", + "input=" + params["input"], + "output=" + self.snapPts.GetVectMapName(), + "use=node", + "--overwrite", + ] + # process GRASS command with argument + self.snapData["inputMap"] = VectMap(None, inpFullName) + self.snapData["inputMap"].SaveVectMapState() - self.snapping.emit(evt="computing_points") + self.Bind(EVT_CMD_DONE, self._onNodesDone) + self.snapData["cmdThread"].RunCmd(cmd) + self.snapping.emit(evt="computing_points") - return 0 - # map is already created and up to date for input data - self.snapPts.AddRenderLayer() - self.giface.updateMap.emit(render=True, renderVector=True) - self.snapping.emit(evt="computing_points_done") - return 1 + return 0 def _onNodesDone(self, event): """Update map window, when map with nodes to snap is created""" diff --git a/gui/wxpython/vnet/vnet_data.py b/gui/wxpython/vnet/vnet_data.py index e8e05839e70..137840879c8 100644 --- a/gui/wxpython/vnet/vnet_data.py +++ b/gui/wxpython/vnet/vnet_data.py @@ -928,14 +928,12 @@ def DeleteTmpMap(self, vectMap): :return: True if was removed :return: False if does not contain the map """ - if vectMap: - vectMap.DeleteRenderLayer() - RunCommand( - "g.remove", flags="f", type="vector", name=vectMap.GetVectMapName() - ) - self.RemoveFromTmpMaps(vectMap) - return True - return False + if not vectMap: + return False + vectMap.DeleteRenderLayer() + RunCommand("g.remove", flags="f", type="vector", name=vectMap.GetVectMapName()) + self.RemoveFromTmpMaps(vectMap) + return True def DeleteAllTmpMaps(self): """Delete all temporary maps in the class""" diff --git a/gui/wxpython/vnet/vnet_utils.py b/gui/wxpython/vnet/vnet_utils.py index 7157ac8a20e..2f32fd2b94d 100644 --- a/gui/wxpython/vnet/vnet_utils.py +++ b/gui/wxpython/vnet/vnet_utils.py @@ -73,15 +73,14 @@ def SnapToNode(e, n, tresh, vectMap): vectlib.WITHOUT_Z, ) - if nodeNum > 0: - e = c_double(0) - n = c_double(0) - vectlib.Vect_get_node_coor(openedMap, nodeNum, byref(e), byref(n), None) # z - e = e.value - n = n.value - else: + if nodeNum <= 0: vectlib.Vect_close(openedMap) return False + e = c_double(0) + n = c_double(0) + vectlib.Vect_get_node_coor(openedMap, nodeNum, byref(e), byref(n), None) + e = e.value + n = n.value return e, n @@ -110,15 +109,14 @@ def GetNearestNodeCat(e, n, layer, tresh, vectMap): vectlib.WITHOUT_Z, ) - if nodeNum > 0: - e = c_double(0) - n = c_double(0) - vectlib.Vect_get_node_coor(openedMap, nodeNum, byref(e), byref(n), None) # z - e = e.value - n = n.value - else: + if nodeNum <= 0: vectlib.Vect_close(openedMap) return -1 + e = c_double(0) + n = c_double(0) + vectlib.Vect_get_node_coor(openedMap, nodeNum, byref(e), byref(n), None) + e = e.value + n = n.value box = vectlib.bound_box() List = POINTER(vectlib.boxlist) diff --git a/gui/wxpython/vnet/widgets.py b/gui/wxpython/vnet/widgets.py index 6a20f28ca9e..66ffcf8ad1c 100644 --- a/gui/wxpython/vnet/widgets.py +++ b/gui/wxpython/vnet/widgets.py @@ -509,22 +509,19 @@ def ShowColumn(self, colName, pos): """ if pos < 0 or pos >= self.GetColumnCount(): return False - if colName in self.hiddenCols: - col = self.hiddenCols[colName] - - for item in enumerate(self.itemDataMap): - item[1].insert(pos, col["itemDataMap"][item[0]]) - for item in enumerate(self.selIdxs): - item[1].insert(pos, col["selIdxs"][item[0]]) - - self.colsData.insert(pos, col["colsData"]) - - self.InsertColumnItem(pos, col["wxCol"]) - self.ResizeColumns() - del self.hiddenCols[colName] - return True - - return False + if colName not in self.hiddenCols: + return False + col = self.hiddenCols[colName] + + for item in enumerate(self.itemDataMap): + item[1].insert(pos, col["itemDataMap"][item[0]]) + for item in enumerate(self.selIdxs): + item[1].insert(pos, col["selIdxs"][item[0]]) + self.colsData.insert(pos, col["colsData"]) + self.InsertColumnItem(pos, col["wxCol"]) + self.ResizeColumns() + del self.hiddenCols[colName] + return True def IsShown(self, colName) -> bool: """Is column shown diff --git a/gui/wxpython/wxplot/base.py b/gui/wxpython/wxplot/base.py index 057894c0250..21d4a442a77 100755 --- a/gui/wxpython/wxplot/base.py +++ b/gui/wxpython/wxplot/base.py @@ -247,11 +247,12 @@ def InitRasterOpts(self, rasterList, plottype): rdict[r]["pcolor"] = self.colorDict[self.colorList[idx]] else: rdict[r]["pcolor"] = self.colorDict[self.colorList[idx]] - else: - r = randint(0, 255) - b = randint(0, 255) - g = randint(0, 255) - rdict[r]["pcolor"] = (r, g, b, 255) + continue + + r = randint(0, 255) + b = randint(0, 255) + g = randint(0, 255) + rdict[r]["pcolor"] = (r, g, b, 255) return rdict @@ -322,11 +323,12 @@ def InitRasterPairs(self, rasterList, plottype): if idx <= len(self.colorList): rdict[rpair]["pcolor"] = self.colorDict[self.colorList[idx]] - else: - r = randint(0, 255) - b = randint(0, 255) - g = randint(0, 255) - rdict[rpair]["pcolor"] = (r, g, b, 255) + continue + + r = randint(0, 255) + b = randint(0, 255) + g = randint(0, 255) + rdict[rpair]["pcolor"] = (r, g, b, 255) return rdict From c15760d4c50782e80eacc911c77829f1d6793766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:59:26 +0000 Subject: [PATCH 06/21] gui: Use filter() to replace a simple condition inside a loop --- gui/wxpython/gcp/manager.py | 4 +--- gui/wxpython/gui_core/mapdisp.py | 5 ++--- gui/wxpython/iclass/frame.py | 5 ++--- gui/wxpython/image2target/ii2t_manager.py | 5 ++--- gui/wxpython/modules/extensions.py | 12 +++++++----- gui/wxpython/rlisetup/sampling_frame.py | 7 ++----- 6 files changed, 16 insertions(+), 22 deletions(-) diff --git a/gui/wxpython/gcp/manager.py b/gui/wxpython/gcp/manager.py index b759df4dd3a..bcd3bb14767 100644 --- a/gui/wxpython/gcp/manager.py +++ b/gui/wxpython/gcp/manager.py @@ -2726,9 +2726,7 @@ def __init__( def MakeVGroup(self): """Create VREF file""" vgrouplist = [] - for item in range(self.listMap.GetCount()): - if not self.listMap.IsChecked(item): - continue + for item in filter(self.listMap.IsChecked, range(self.listMap.GetCount())): vgrouplist.append(self.listMap.GetString(item) + "@" + self.xymapset) dirname = os.path.dirname(self.vgrpfile) diff --git a/gui/wxpython/gui_core/mapdisp.py b/gui/wxpython/gui_core/mapdisp.py index 515900959c7..b87724643c6 100644 --- a/gui/wxpython/gui_core/mapdisp.py +++ b/gui/wxpython/gui_core/mapdisp.py @@ -379,9 +379,8 @@ def StatusbarReposition(self): def StatusbarEnableLongHelp(self, enable=True): """Enable/disable toolbars long help""" - for toolbar in self.toolbars.values(): - if toolbar: - toolbar.EnableLongHelp(enable) + for toolbar in filter(None, self.toolbars.values()): + toolbar.EnableLongHelp(enable) def ShowAllToolbars(self, show=True): action = self.RemoveToolbar if not show else self.AddToolbar diff --git a/gui/wxpython/iclass/frame.py b/gui/wxpython/iclass/frame.py index 9901ccf3322..7d3aa18afdf 100644 --- a/gui/wxpython/iclass/frame.py +++ b/gui/wxpython/iclass/frame.py @@ -754,9 +754,8 @@ def ImportClasses(self, vector): # we use first layer with table, TODO: user should choose layer = None - for key in dbInfo.layers.keys(): - if dbInfo.GetTable(key): - layer = key + for key in filter(dbInfo.GetTable, dbInfo.layers.keys()): + layer = key # get columns to check if we can use them # TODO: let user choose which columns mean what diff --git a/gui/wxpython/image2target/ii2t_manager.py b/gui/wxpython/image2target/ii2t_manager.py index ab2ac30ae88..37847a933ee 100644 --- a/gui/wxpython/image2target/ii2t_manager.py +++ b/gui/wxpython/image2target/ii2t_manager.py @@ -2683,9 +2683,8 @@ def __init__( def MakeVGroup(self): """Create VREF file""" vgrouplist = [] - for item in range(self.listMap.GetCount()): - if not self.listMap.IsChecked(item): - continue + + for item in filter(self.listMap.IsChecked, range(self.listMap.GetCount())): vgrouplist.append(self.listMap.GetString(item) + "@" + self.xymapset) with open(self.vgrpfile, mode="w") as f: diff --git a/gui/wxpython/modules/extensions.py b/gui/wxpython/modules/extensions.py index 9d65b8431a3..760ce1d8102 100644 --- a/gui/wxpython/modules/extensions.py +++ b/gui/wxpython/modules/extensions.py @@ -545,11 +545,13 @@ def __init__(self, parent): def LoadData(self): """Load data into list""" self.DeleteAllItems() - for ext in RunCommand( - "g.extension", quiet=True, parent=self, read=True, flags="a" - ).splitlines(): - if ext: - self.InsertItem(self.GetItemCount(), ext) + for ext in filter( + None, + RunCommand( + "g.extension", quiet=True, parent=self, read=True, flags="a" + ).splitlines(), + ): + self.InsertItem(self.GetItemCount(), ext) def GetExtensions(self): """Get extensions to be un-installed""" diff --git a/gui/wxpython/rlisetup/sampling_frame.py b/gui/wxpython/rlisetup/sampling_frame.py index bc61ef4f109..f55544fe22f 100644 --- a/gui/wxpython/rlisetup/sampling_frame.py +++ b/gui/wxpython/rlisetup/sampling_frame.py @@ -476,11 +476,8 @@ def __init__(self, parent, toolSwitcher): else: self._default = self.draw - for tool in (self._default, self.pan, self.zoomIn, self.zoomOut): - if tool: - self.toolSwitcher.AddToolToGroup( - group="mouseUse", toolbar=self, tool=tool - ) + for tool in filter(None, (self._default, self.pan, self.zoomIn, self.zoomOut)): + self.toolSwitcher.AddToolToGroup(group="mouseUse", toolbar=self, tool=tool) # realize the toolbar self.Realize() From 7224c74523ef925080795bb7245e880a94fc0129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:47:48 +0000 Subject: [PATCH 07/21] style: Extract constant from loop --- gui/wxpython/animation/nviztask.py | 15 ++++++++------- gui/wxpython/core/utils.py | 3 +-- gui/wxpython/gmodeler/model.py | 11 +++++------ gui/wxpython/gui_core/dialogs.py | 5 +---- gui/wxpython/location_wizard/wizard.py | 3 +-- gui/wxpython/modules/colorrules.py | 4 +--- gui/wxpython/photo2image/ip2i_manager.py | 4 ++-- 7 files changed, 19 insertions(+), 26 deletions(-) diff --git a/gui/wxpython/animation/nviztask.py b/gui/wxpython/animation/nviztask.py index caa02553db4..dd0fc03de7e 100644 --- a/gui/wxpython/animation/nviztask.py +++ b/gui/wxpython/animation/nviztask.py @@ -175,14 +175,15 @@ def _processVolume(self, volume, mapName): if isosurfaces: res_value = volume["draw"]["resolution"]["isosurface"]["value"] self._setMultiTaskParam("volume_resolution", res_value) + attributes = ("topo", "color", "shine", "transp") + + parameters = ( + (None, "isosurf_level"), + ("isosurf_color_map", "isosurf_color_value"), + ("isosurf_shininess_map", "isosurf_shininess_value"), + ("isosurf_transparency_map", "isosurf_transparency_value"), + ) for isosurface in isosurfaces: - attributes = ("topo", "color", "shine", "transp") - parameters = ( - (None, "isosurf_level"), - ("isosurf_color_map", "isosurf_color_value"), - ("isosurf_shininess_map", "isosurf_shininess_value"), - ("isosurf_transparency_map", "isosurf_transparency_value"), - ) for attr, params in zip(attributes, parameters): mapname = None const = None diff --git a/gui/wxpython/core/utils.py b/gui/wxpython/core/utils.py index f234b6b03c7..255778d3360 100644 --- a/gui/wxpython/core/utils.py +++ b/gui/wxpython/core/utils.py @@ -1017,8 +1017,8 @@ def PilImageToWxImage(pilImage, copyAlpha=True): from gui_core.wrap import EmptyImage hasAlpha = pilImage.mode[-1] == "A" + wxImage = EmptyImage(*pilImage.size) if copyAlpha and hasAlpha: # Make sure there is an alpha layer copy. - wxImage = EmptyImage(*pilImage.size) pilImageCopyRGBA = pilImage.copy() pilImageCopyRGB = pilImageCopyRGBA.convert("RGB") # RGBA --> RGB wxImage.SetData(pilImageCopyRGB.tobytes()) @@ -1029,7 +1029,6 @@ def PilImageToWxImage(pilImage, copyAlpha=True): wxImage.SetAlphaData(pilImageCopyRGBA.tobytes()[3::4]) else: # The resulting image will not have alpha. - wxImage = EmptyImage(*pilImage.size) pilImageCopy = pilImage.copy() # Discard any alpha from the PIL image. pilImageCopyRGB = pilImageCopy.convert("RGB") diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index 47590759592..93087cc8608 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -2936,6 +2936,10 @@ def getParameterizedFlags(paramFlags, itemFlags): def _write_input_outputs(self, item, intermediates): parameterized_params = item.GetParameterizedParams() + io_data = "inputs" + object_type = "LiteralInput" + format_spec = 'data_type="string",' + for flag in parameterized_params["flags"]: desc = flag["label"] or flag["description"] @@ -2946,10 +2950,6 @@ def _write_input_outputs(self, item, intermediates): else: value = '\n{}default="False"'.format(" " * (self.indent + 4)) - io_data = "inputs" - object_type = "LiteralInput" - format_spec = 'data_type="string",' - self._write_input_output_object( io_data, object_type, @@ -2962,16 +2962,15 @@ def _write_input_outputs(self, item, intermediates): self.fd.write("\n") + io_data = "inputs" for param in parameterized_params["params"]: desc = self._getParamDesc(param) value = self._getParamValue(param) if "input" in param["name"]: - io_data = "inputs" object_type = "ComplexInput" format_spec = self._getSupportedFormats(param["prompt"]) else: - io_data = "inputs" object_type = "LiteralInput" format_spec = 'data_type="{}"'.format(param["type"]) diff --git a/gui/wxpython/gui_core/dialogs.py b/gui/wxpython/gui_core/dialogs.py index 9a2cad1eda9..146475025d4 100644 --- a/gui/wxpython/gui_core/dialogs.py +++ b/gui/wxpython/gui_core/dialogs.py @@ -1053,14 +1053,11 @@ def OnSubgChbox(self, event): def SubgChbox(self, edit_subg): self._checkChange() + self.edit_subg = edit_subg if edit_subg: - self.edit_subg = edit_subg - self.SubGroupSelected() self._subgroupLayout() else: - self.edit_subg = edit_subg - self.GroupSelected() self._groupLayout() diff --git a/gui/wxpython/location_wizard/wizard.py b/gui/wxpython/location_wizard/wizard.py index fef439d885c..d36d9b659ec 100644 --- a/gui/wxpython/location_wizard/wizard.py +++ b/gui/wxpython/location_wizard/wizard.py @@ -2501,8 +2501,8 @@ def __init__(self, parent, grassdatabase): # if self.wizard.RunWizard(self.startpage): msg = self.OnWizFinished() + self.wizard.Destroy() if not msg: - self.wizard.Destroy() self.location = self.startpage.location self.grassdatabase = self.startpage.grassdatabase self.georeffile = self.filepage.georeffile @@ -2510,7 +2510,6 @@ def __init__(self, parent, grassdatabase): # if self.altdb is False: else: # -> error - self.wizard.Destroy() GError( parent=self.parent, message="%s" diff --git a/gui/wxpython/modules/colorrules.py b/gui/wxpython/modules/colorrules.py index 8b5fabbec00..266e9de7e34 100644 --- a/gui/wxpython/modules/colorrules.py +++ b/gui/wxpython/modules/colorrules.py @@ -334,12 +334,10 @@ def LoadRules(self): def SQLConvert(self, vals): """Prepare value for SQL query""" + sqlrule = "%s=%s" % (self.properties["sourceColumn"], vals[0]) if vals[0].isdigit(): - sqlrule = "%s=%s" % (self.properties["sourceColumn"], vals[0]) if vals[1]: sqlrule += " AND %s<%s" % (self.properties["sourceColumn"], vals[1]) - else: - sqlrule = "%s=%s" % (self.properties["sourceColumn"], vals[0]) return sqlrule diff --git a/gui/wxpython/photo2image/ip2i_manager.py b/gui/wxpython/photo2image/ip2i_manager.py index 273b6dce28f..c2d4f202d3e 100644 --- a/gui/wxpython/photo2image/ip2i_manager.py +++ b/gui/wxpython/photo2image/ip2i_manager.py @@ -467,9 +467,9 @@ def __init__( ) check = "0" + coordX0 = "0" + coordY0 = "0" for index in range(numberOfFiducial): - coordX0 = "0" - coordY0 = "0" coordX1 = dataFiducialX[index] coordY1 = dataFiducialY[index] f.write( From ecd3ded8933ba7da34885b1f350a07e2c147eb39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 21:29:00 +0000 Subject: [PATCH 08/21] style: Factor out commonly used text into a constant --- gui/wxpython/animation/temporal_manager.py | 18 ++++++++------- gui/wxpython/location_wizard/wizard.py | 20 +++++++++-------- gui/wxpython/psmap/instructions.py | 26 ++++++++++++---------- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/gui/wxpython/animation/temporal_manager.py b/gui/wxpython/animation/temporal_manager.py index 136c154a5cb..46f33dd1b79 100644 --- a/gui/wxpython/animation/temporal_manager.py +++ b/gui/wxpython/animation/temporal_manager.py @@ -26,6 +26,8 @@ from core.settings import UserSettings from animation.utils import validateTimeseriesName, TemporalType +A_TEST_WITH_INPUT_FILES = "A test with input files" + class DataMode: SIMPLE = 1 @@ -446,8 +448,8 @@ def createAbsoluteInterval(): type="strds", temporaltype="absolute", output=name, - title="A test with input files", - descr="A test with input files", + title=A_TEST_WITH_INPUT_FILES, + descr=A_TEST_WITH_INPUT_FILES, ) gs.run_command("t.register", flags="i", input=name, file=fname, overwrite=True) @@ -519,8 +521,8 @@ def createRelativeInterval(): type="strds", temporaltype="relative", output=name, - title="A test with input files", - descr="A test with input files", + title=A_TEST_WITH_INPUT_FILES, + descr=A_TEST_WITH_INPUT_FILES, ) gs.run_command( "t.register", @@ -572,8 +574,8 @@ def createAbsolutePoint(): type="strds", temporaltype="absolute", output=name, - title="A test with input files", - descr="A test with input files", + title=A_TEST_WITH_INPUT_FILES, + descr=A_TEST_WITH_INPUT_FILES, ) gs.run_command("t.register", flags="i", input=name, file=n1, overwrite=True) @@ -612,8 +614,8 @@ def createRelativePoint(): type="strds", temporaltype="relative", output=name, - title="A test with input files", - descr="A test with input files", + title=A_TEST_WITH_INPUT_FILES, + descr=A_TEST_WITH_INPUT_FILES, ) gs.run_command("t.register", unit="day", input=name, file=n1, overwrite=True) diff --git a/gui/wxpython/location_wizard/wizard.py b/gui/wxpython/location_wizard/wizard.py index d36d9b659ec..b75369525f1 100644 --- a/gui/wxpython/location_wizard/wizard.py +++ b/gui/wxpython/location_wizard/wizard.py @@ -88,6 +88,8 @@ if TYPE_CHECKING: from wx.adv import WizardEvent +DATUM_TRANSFORM_IS_REQUIRED = "Datum transform is required." + class TitledPage(WizardPageSimple): """Class to make wizard pages. Generic methods to make labels, @@ -1062,7 +1064,7 @@ def __init__(self, wizard, parent): self.searchb = SearchCtrl(self, size=(200, -1), style=wx.TE_PROCESS_ENTER) self.searchb.ShowCancelButton(True) - # create list control for datum/elipsoid list + # create list control for datum/ellipsoid list data = [ [key, datum[0], datum[1]] for (key, datum) in self.parent.datums.items() ] @@ -1149,11 +1151,11 @@ def OnPageChanging(self, event: WizardEvent): if dtrans == "": dlg.Destroy() event.Veto() - return "Datum transform is required." + return DATUM_TRANSFORM_IS_REQUIRED else: dlg.Destroy() event.Veto() - return "Datum transform is required." + return DATUM_TRANSFORM_IS_REQUIRED self.parent.datum_trans = dtrans @@ -1678,11 +1680,11 @@ def OnPageChanging(self, event: WizardEvent): if dtrans == "": dlg.Destroy() event.Veto() - return "Datum transform is required." + return DATUM_TRANSFORM_IS_REQUIRED else: dlg.Destroy() event.Veto() - return "Datum transform is required." + return DATUM_TRANSFORM_IS_REQUIRED self.parent.datum_trans = dtrans self.GetNext().SetPrev(self) @@ -1902,11 +1904,11 @@ def OnPageChanging(self, event: WizardEvent): if dtrans == "": dlg.Destroy() event.Veto() - return "Datum transform is required." + return DATUM_TRANSFORM_IS_REQUIRED else: dlg.Destroy() event.Veto() - return "Datum transform is required." + return DATUM_TRANSFORM_IS_REQUIRED self.parent.datum_trans = dtrans self.parent.epsgcode = self.epsgcode @@ -2121,11 +2123,11 @@ def OnPageChanging(self, event: WizardEvent): if dtrans == "": dlg.Destroy() event.Veto() - return _("Datum transform is required.") + return _(DATUM_TRANSFORM_IS_REQUIRED) else: dlg.Destroy() event.Veto() - return _("Datum transform is required.") + return _(DATUM_TRANSFORM_IS_REQUIRED) self.parent.datum_trans = dtrans diff --git a/gui/wxpython/psmap/instructions.py b/gui/wxpython/psmap/instructions.py index 052d7da3da3..3c3f6991602 100644 --- a/gui/wxpython/psmap/instructions.py +++ b/gui/wxpython/psmap/instructions.py @@ -57,6 +57,8 @@ projInfo, ) +FAILED_TO_READ_INSTRUCTION_S = "Failed to read instruction %s" + def NewId(): return int(wxNewId()) @@ -703,7 +705,7 @@ def Read(self, instruction, text, **kwargs): elif line.startswith("color"): instr["color"] = line.split()[1] except IndexError: - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False elif instruction == "scale": @@ -926,7 +928,7 @@ def Read(self, instruction, text): elif sub[0] == "where": instr["where"] = float(sub[1].split()[0]), float(sub[1].split()[1]) except (ValueError, IndexError): - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False self.instruction.update(instr) self.instruction["rect"] = self.EstimateRect(mapinfoDict=self.instruction) @@ -1054,7 +1056,7 @@ def Read(self, instruction, text, **kwargs): instr["background"] = "none" except (IndexError, ValueError): - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False instr["where"] = PaperMapCoordinates( mapInstr=map, @@ -1129,7 +1131,7 @@ def Read(self, instruction, text, **kwargs): instr["scale"] = float(line.split(None, 1)[1]) except (IndexError, ValueError): - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False if not os.path.exists(instr["epsfile"]): GError( @@ -1314,7 +1316,7 @@ def Read(self, instruction, text, **kwargs): instr["fcolor"] = line.split(None, 1)[1] except (IndexError, ValueError): - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False self.instruction.update(instr) @@ -1389,7 +1391,7 @@ def Read(self, instruction, text, **kwargs): instr["color"] = line.split(None, 1)[1] except (IndexError, ValueError): - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False self.instruction.update(instr) @@ -1467,7 +1469,7 @@ def Read(self, instruction, text, **kwargs): instr["fcolor"] = line.split(None, 1)[1] except (IndexError, ValueError): - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False self.instruction.update(instr) @@ -1573,7 +1575,7 @@ def Read(self, instruction, text, **kwargs): elif line.split()[1].strip().lower() in {"n", "no", "none"}: instr["background"] = "n" except (IndexError, ValueError): - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False self.instruction.update(instr) @@ -1714,7 +1716,7 @@ def Read(self, instruction, text, **kwargs): instr["discrete"] = "n" except (IndexError, ValueError): - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False if "raster" in instr: @@ -1856,7 +1858,7 @@ def Read(self, instruction, text, **kwargs): instr["border"] = line.split()[1] except (IndexError, ValueError): - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False self.instruction.update(instr) @@ -1906,7 +1908,7 @@ def Read(self, instruction, text): try: map = text.split()[1] except IndexError: - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False try: info = gs.find_file(map, element="cell") @@ -2258,7 +2260,7 @@ def Read(self, instruction, text, **kwargs): labels = line.split(None, 1)[1] self.instruction["labels"].append(labels) except (IndexError, ValueError): - GError(_("Failed to read instruction %s") % instruction) + GError(_(FAILED_TO_READ_INSTRUCTION_S) % instruction) return False return True From cf745568c547254dccc36406d5540cbe67461efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 21:40:57 +0000 Subject: [PATCH 09/21] gui: Simplify conditions --- gui/wxpython/psmap/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/wxpython/psmap/frame.py b/gui/wxpython/psmap/frame.py index 2913a2eb461..edde56bc1ee 100644 --- a/gui/wxpython/psmap/frame.py +++ b/gui/wxpython/psmap/frame.py @@ -370,7 +370,7 @@ def PSFile(self, filename=None, pdf=False): pdfname = filename if pdf else None # preview or pdf - if not filename or (filename and pdf): + if pdf or not filename: temp = True filename = gs.tempfile() if not pdf: # lower resolution for preview From 335811e0046d94262584a69807c67328988ee550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 21:33:40 +0000 Subject: [PATCH 10/21] gui: Simplify boolean assignment --- gui/wxpython/gcp/manager.py | 5 +---- gui/wxpython/gui_core/dialogs.py | 5 +---- gui/wxpython/gui_core/forms.py | 10 ++-------- gui/wxpython/gui_core/mapdisp.py | 7 +++---- gui/wxpython/image2target/ii2t_manager.py | 5 +---- gui/wxpython/modules/import_export.py | 5 +---- gui/wxpython/photo2image/ip2i_manager.py | 5 +---- gui/wxpython/psmap/dialogs.py | 10 ++-------- gui/wxpython/vdigit/wxdisplay.py | 5 +---- 9 files changed, 13 insertions(+), 44 deletions(-) diff --git a/gui/wxpython/gcp/manager.py b/gui/wxpython/gcp/manager.py index bcd3bb14767..b1a2645523c 100644 --- a/gui/wxpython/gcp/manager.py +++ b/gui/wxpython/gcp/manager.py @@ -1021,10 +1021,7 @@ def __init__( self.grwiz = grwiz # GR Wizard self._giface = giface - if tgt_map["raster"] == "" and tgt_map["vector"] == "": - self.show_target = False - else: - self.show_target = True + self.show_target = not (tgt_map["raster"] == "" and tgt_map["vector"] == "") # wx.Frame.__init__(self, parent, id, title, size = size, name = "GCPFrame") MapPanel.__init__( diff --git a/gui/wxpython/gui_core/dialogs.py b/gui/wxpython/gui_core/dialogs.py index 146475025d4..8b4d38ecf8e 100644 --- a/gui/wxpython/gui_core/dialogs.py +++ b/gui/wxpython/gui_core/dialogs.py @@ -1173,10 +1173,7 @@ def SubGroupSelected(self): if subgroup: maps = self.GetGroupLayers(group, subgroup) for m in maps: - if m in gmaps: - self.subgmaps[m] = True - else: - self.subgmaps[m] = False + self.subgmaps[m] = m in gmaps gmaps = self._filter(gmaps) self.subgListBox.Set(gmaps) diff --git a/gui/wxpython/gui_core/forms.py b/gui/wxpython/gui_core/forms.py index 0ff0ebcfdaf..9f88be5616e 100644 --- a/gui/wxpython/gui_core/forms.py +++ b/gui/wxpython/gui_core/forms.py @@ -510,10 +510,7 @@ def __init__( guisizer = wx.BoxSizer(wx.VERTICAL) # set appropriate output window - if self.parent: - self.standalone = False - else: - self.standalone = True + self.standalone = not self.parent # logo + description topsizer = wx.BoxSizer(wx.HORIZONTAL) @@ -3050,10 +3047,7 @@ def __init__( self.cmd = [] global _blackList - if self.parent: - _blackList["enabled"] = True - else: - _blackList["enabled"] = False + _blackList["enabled"] = bool(self.parent) def GetCmd(self): """Get validated command""" diff --git a/gui/wxpython/gui_core/mapdisp.py b/gui/wxpython/gui_core/mapdisp.py index b87724643c6..365b071a7d9 100644 --- a/gui/wxpython/gui_core/mapdisp.py +++ b/gui/wxpython/gui_core/mapdisp.py @@ -428,10 +428,9 @@ def OnRender(self, event): def OnEnableDisableRender(self, event): """Enable/disable auto-rendering map composition (each map layer)""" - if self.MapWindow.parent.mapWindowProperties.autoRender: - self.MapWindow.parent.mapWindowProperties.autoRender = False - else: - self.MapWindow.parent.mapWindowProperties.autoRender = True + self.MapWindow.parent.mapWindowProperties.autoRender = ( + not self.MapWindow.parent.mapWindowProperties.autoRender + ) def OnDraw(self, event): """Re-display current map composition""" diff --git a/gui/wxpython/image2target/ii2t_manager.py b/gui/wxpython/image2target/ii2t_manager.py index 37847a933ee..e753fc825d1 100644 --- a/gui/wxpython/image2target/ii2t_manager.py +++ b/gui/wxpython/image2target/ii2t_manager.py @@ -999,10 +999,7 @@ def __init__( self.grwiz = grwiz # GR Wizard self._giface = giface - if tgt_map["raster"] == "" and tgt_map["vector"] == "": - self.show_target = False - else: - self.show_target = True + self.show_target = not (tgt_map["raster"] == "" and tgt_map["vector"] == "") # wx.Frame.__init__(self, parent, id, title, size = size, name = "GCPFrame") MapPanel.__init__( diff --git a/gui/wxpython/modules/import_export.py b/gui/wxpython/modules/import_export.py index a0d6c5ac665..3799027f3d7 100644 --- a/gui/wxpython/modules/import_export.py +++ b/gui/wxpython/modules/import_export.py @@ -311,10 +311,7 @@ def OnRun(self, event): def OnCheckOverwrite(self, event): """Check/uncheck overwrite checkbox widget""" - if self.overwrite.IsChecked(): - self.list.validate = False - else: - self.list.validate = True + self.list.validate = not self.overwrite.IsChecked() def AddLayers(self, returncode, cmd=None, userData=None): """Add imported/linked layers into layer tree""" diff --git a/gui/wxpython/photo2image/ip2i_manager.py b/gui/wxpython/photo2image/ip2i_manager.py index c2d4f202d3e..4f2bac9b788 100644 --- a/gui/wxpython/photo2image/ip2i_manager.py +++ b/gui/wxpython/photo2image/ip2i_manager.py @@ -305,10 +305,7 @@ def __init__( self.grwiz = grwiz # GR Wizard self._giface = giface - if tgt_map == "": - self.show_target = False - else: - self.show_target = True + self.show_target = tgt_map != "" self.camera = camera diff --git a/gui/wxpython/psmap/dialogs.py b/gui/wxpython/psmap/dialogs.py index 68e0adca71c..b644da0cb18 100644 --- a/gui/wxpython/psmap/dialogs.py +++ b/gui/wxpython/psmap/dialogs.py @@ -4168,10 +4168,7 @@ def updateRasterLegend(self): """Save information from raster legend dialog to dictionary""" # is raster legend - if not self.isRLegend.GetValue(): - self.rLegendDict["rLegend"] = False - else: - self.rLegendDict["rLegend"] = True + self.rLegendDict["rLegend"] = bool(self.isRLegend.GetValue()) # units currUnit = self.unitConv.findUnit( self.panelRaster.units["unitsCtrl"].GetStringSelection() @@ -4308,10 +4305,7 @@ def updateVectorLegend(self): self.vectorId = None # is vector legend - if not self.isVLegend.GetValue(): - self.vLegendDict["vLegend"] = False - else: - self.vLegendDict["vLegend"] = True + self.vLegendDict["vLegend"] = bool(self.isVLegend.GetValue()) if self.vLegendDict["vLegend"] and self.vectorId is not None: # labels # reindex order diff --git a/gui/wxpython/vdigit/wxdisplay.py b/gui/wxpython/vdigit/wxdisplay.py index ce97d31b1db..7e146ed814a 100644 --- a/gui/wxpython/vdigit/wxdisplay.py +++ b/gui/wxpython/vdigit/wxdisplay.py @@ -803,10 +803,7 @@ def SetSelected(self, ids, layer=-1): :param list: of ids (None to unselect features) :param layer: layer number for features selected based on category number """ - if ids: - self._drawSelected = True - else: - self._drawSelected = False + self._drawSelected = bool(ids) self.selected["field"] = layer if layer > 0: From 3a97fee971b5a53ffee70f1e3b9f053f83fed6f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 21:08:23 +0000 Subject: [PATCH 11/21] style: Use parentheses when assigning tuples --- gui/wxpython/gmodeler/model.py | 6 ++---- gui/wxpython/gui_core/dialogs.py | 3 +-- gui/wxpython/nviz/tools.py | 4 ++-- gui/wxpython/nviz/wxnviz.py | 2 +- gui/wxpython/psmap/frame.py | 2 +- gui/wxpython/vnet/dialogs.py | 3 +-- 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index 93087cc8608..308b26d126a 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -2087,8 +2087,7 @@ def _getDim(self, node): size = (sizeVal[0], sizeVal[1]) except IndexError: size = None - - return pos, size + return (pos, size) def _processData(self): """Process model file""" @@ -2680,8 +2679,7 @@ def _getItemFlags(self, item, opts, variables): item_true_flags += name item_parameterized_flags = ", ".join(item_parameterized_flags) - - return item_true_flags, item_parameterized_flags, item_params + return (item_true_flags, item_parameterized_flags, item_params) class WriteActiniaFile(WriteScriptFile): diff --git a/gui/wxpython/gui_core/dialogs.py b/gui/wxpython/gui_core/dialogs.py index 8b4d38ecf8e..5c331f43368 100644 --- a/gui/wxpython/gui_core/dialogs.py +++ b/gui/wxpython/gui_core/dialogs.py @@ -2567,8 +2567,7 @@ def GetFonts(self): fontdict[longname] = shortname fontdict_reverse[shortname] = longname fontlist = naturally_sorted(list(set(fontlist))) - - return fontdict, fontdict_reverse, fontlist + return (fontdict, fontdict_reverse, fontlist) def RenderText(self, font, text, size): """Renders an example text with the selected font and resets the bitmap diff --git a/gui/wxpython/nviz/tools.py b/gui/wxpython/nviz/tools.py index 95b7717e8ea..8b644c29c3b 100644 --- a/gui/wxpython/nviz/tools.py +++ b/gui/wxpython/nviz/tools.py @@ -5819,7 +5819,7 @@ def UpdatePos(self, xcoord, ycoord): return x, y def TransformCoordinates(self, x, y, toLight=True): - return x, y + return (x, y) def OnMouse(self, event): # use focus instead of viewdir @@ -5866,7 +5866,7 @@ def TransformCoordinates(self, x, y, toLight=True): else: x = (x + 1) / 2 y = (1 - y) / 2 - return x, y + return (x, y) def PostDraw(self): event = wxUpdateLight(refresh=True) diff --git a/gui/wxpython/nviz/wxnviz.py b/gui/wxpython/nviz/wxnviz.py index 07eb60526e0..d56148f18d1 100644 --- a/gui/wxpython/nviz/wxnviz.py +++ b/gui/wxpython/nviz/wxnviz.py @@ -448,7 +448,7 @@ def GetViewdir(self) -> tuple[float, float, float]: dir = (c_float * 3)() GS_get_viewdir(byref(dir)) - return dir[0], dir[1], dir[2] + return (dir[0], dir[1], dir[2]) def SetViewdir(self, x: float, y: float, z: float) -> None: """Set viewdir""" diff --git a/gui/wxpython/psmap/frame.py b/gui/wxpython/psmap/frame.py index edde56bc1ee..7ab3bab6eae 100644 --- a/gui/wxpython/psmap/frame.py +++ b/gui/wxpython/psmap/frame.py @@ -998,7 +998,7 @@ def getModifiedTextBounds(self, x, y, textExtent, rotation): rotation = float(rotation) / 180 * pi H = float(w) * sin(rotation) W = float(w) * cos(rotation) - X, Y = x, y + X, Y = (x, y) if pi / 2 < rotation <= 3 * pi / 2: X = x + W if 0 < rotation < pi: diff --git a/gui/wxpython/vnet/dialogs.py b/gui/wxpython/vnet/dialogs.py index 19d8e6c8a93..3bce0fa07f1 100644 --- a/gui/wxpython/vnet/dialogs.py +++ b/gui/wxpython/vnet/dialogs.py @@ -840,8 +840,7 @@ def _parseMapStr(self, vectMapStr): mapValSpl = vectMapStr.strip().split("@") mapSet = mapValSpl[1] if len(mapValSpl) > 1 else grass.gisenv()["MAPSET"] mapName = mapValSpl[0] - - return mapName, mapSet + return (mapName, mapSet) def OnCloseDialog(self, event=None): """Cancel dialog""" From 747acd57b508c65ae786c2264f3623cefc30effd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 21:03:48 +0000 Subject: [PATCH 12/21] style: Remove useless parentheses --- gui/wxpython/history/browser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/wxpython/history/browser.py b/gui/wxpython/history/browser.py index 9589cee3f0d..3d2e3773b5e 100644 --- a/gui/wxpython/history/browser.py +++ b/gui/wxpython/history/browser.py @@ -165,7 +165,7 @@ def _createRegionSettingsBox(self): def _general_info_filter(self, key, value): filter_keys = ["timestamp", "runtime", "status"] - return key in filter_keys or ((key in {"mask2d", "mask3d"}) and value is True) + return key in filter_keys or (key in {"mask2d", "mask3d"} and value is True) def _region_settings_filter(self, key): return key not in {"projection", "zone", "cells"} From 0154cea657419678908a277b19f691d802c4ddfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 21:42:06 +0000 Subject: [PATCH 13/21] style: add parenthesis for clarity --- gui/wxpython/modules/colorrules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/wxpython/modules/colorrules.py b/gui/wxpython/modules/colorrules.py index 266e9de7e34..24bd31a8001 100644 --- a/gui/wxpython/modules/colorrules.py +++ b/gui/wxpython/modules/colorrules.py @@ -808,7 +808,7 @@ def CreateColorTable(self, tmp=False) -> bool: if ( self.mapType == "vector" and self.properties["sourceColumn"] - and self.properties["sourceColumn"] != "cat" + and (self.properties["sourceColumn"] != "cat") ): cmd.append("column=%s" % self.properties["sourceColumn"]) From 762aa4077279bb56a607e0b625c964f9101f0b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:30:27 +0000 Subject: [PATCH 14/21] style: Membership test using a set --- gui/wxpython/iclass/plots.py | 2 +- gui/wxpython/iscatt/plots.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gui/wxpython/iclass/plots.py b/gui/wxpython/iclass/plots.py index 510953bb5b1..ca56eb58ba8 100644 --- a/gui/wxpython/iclass/plots.py +++ b/gui/wxpython/iclass/plots.py @@ -101,7 +101,7 @@ def _createScatterPlotPanel(self): def OnPlotTypeSelected(self, event): """Plot type selected""" - if self.plotSwitch.GetSelection() in [0, 1]: + if self.plotSwitch.GetSelection() in {0, 1}: self.SetupScrolling(scroll_x=False, scroll_y=True) if self.iscatt_panel: self.iscatt_panel.Hide() diff --git a/gui/wxpython/iscatt/plots.py b/gui/wxpython/iscatt/plots.py index 1c081958fed..eed88c43a2a 100644 --- a/gui/wxpython/iscatt/plots.py +++ b/gui/wxpython/iscatt/plots.py @@ -766,7 +766,7 @@ def OnButtonPressed(self, event): if not event.inaxes: return - if event.button in [2, 3]: + if event.button in {2, 3}: return if self.mode == "delete_vertex": From 1d819a799ed5c298ddd168f511a8d5716235a9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 21:41:42 +0000 Subject: [PATCH 15/21] style: Membership test without a list --- gui/wxpython/iclass/frame.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gui/wxpython/iclass/frame.py b/gui/wxpython/iclass/frame.py index 7d3aa18afdf..810892c2055 100644 --- a/gui/wxpython/iclass/frame.py +++ b/gui/wxpython/iclass/frame.py @@ -1469,9 +1469,9 @@ def AddLayer(self, name, alias=None, resultsLayer=False): :param str resultsLayer: True if layer is temp. raster showing the results of computation """ - if resultsLayer and name in [ + if resultsLayer and name in ( layer.GetName() for layer in self.map.GetListOfLayers(name=name) - ]: + ): self.frame.Render(self.mapWindow) return From 643e2ee956e60ba72a997a64576837331f9d19b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sat, 4 Jan 2025 00:40:06 +0000 Subject: [PATCH 16/21] gui: Remove dead ifs --- gui/wxpython/gcp/manager.py | 67 ++++++++++---------- gui/wxpython/image2target/ii2t_manager.py | 75 +++++++++++------------ gui/wxpython/mapdisp/statusbar.py | 4 +- gui/wxpython/photo2image/ip2i_manager.py | 67 ++++++++++---------- gui/wxpython/vnet/dialogs.py | 8 +-- gui/wxpython/vnet/widgets.py | 37 ++++++----- 6 files changed, 126 insertions(+), 132 deletions(-) diff --git a/gui/wxpython/gcp/manager.py b/gui/wxpython/gcp/manager.py index b1a2645523c..8ebc3a04bb5 100644 --- a/gui/wxpython/gcp/manager.py +++ b/gui/wxpython/gcp/manager.py @@ -2389,40 +2389,39 @@ def __init__( self.selectedkey = -1 def _Create(self): - if 0: - # normal, simple columns - idx_col = 0 - for col in ( - _("use"), - _("source E"), - _("source N"), - _("target E"), - _("target N"), - _("Forward error"), - _("Backward error"), - ): - self.InsertColumn(idx_col, col) - idx_col += 1 - else: - # the hard way: we want images on the column header - info = wx.ListItem() - info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT) - info.SetImage(-1) - info.m_format = wx.LIST_FORMAT_LEFT - - idx_col = 0 - for lbl in ( - _("use"), - _("source E"), - _("source N"), - _("target E"), - _("target N"), - _("Forward error"), - _("Backward error"), - ): - info.SetText(lbl) - self.InsertColumn(idx_col, info) - idx_col += 1 + # # normal, simple columns + # idx_col = 0 + # for col in ( + # _("use"), + # _("source E"), + # _("source N"), + # _("target E"), + # _("target N"), + # _("Forward error"), + # _("Backward error"), + # ): + # self.InsertColumn(idx_col, col) + # idx_col += 1 + + # the hard way: we want images on the column header + info = wx.ListItem() + info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT) + info.SetImage(-1) + info.m_format = wx.LIST_FORMAT_LEFT + + idx_col = 0 + for lbl in ( + _("use"), + _("source E"), + _("source N"), + _("target E"), + _("target N"), + _("Forward error"), + _("Backward error"), + ): + info.SetText(lbl) + self.InsertColumn(idx_col, info) + idx_col += 1 def LoadData(self): """Load data into list""" diff --git a/gui/wxpython/image2target/ii2t_manager.py b/gui/wxpython/image2target/ii2t_manager.py index e753fc825d1..e4212fe3783 100644 --- a/gui/wxpython/image2target/ii2t_manager.py +++ b/gui/wxpython/image2target/ii2t_manager.py @@ -2338,44 +2338,43 @@ def __init__( self.selectedkey = -1 def _Create(self): - if 0: - # normal, simple columns - idx_col = 0 - for col in ( - _("use"), - _("source E"), - _("source N"), - _("source Z"), - _("target E"), - _("target N"), - _("target Z"), - _("Forward error"), - _("Backward error"), - ): - self.InsertColumn(idx_col, col) - idx_col += 1 - else: - # the hard way: we want images on the column header - info = wx.ListItem() - info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT) - info.SetImage(-1) - info.m_format = wx.LIST_FORMAT_LEFT - - idx_col = 0 - for lbl in ( - _("use"), - _("source E"), - _("source N"), - _("source Z"), - _("target E"), - _("target N"), - _("target Z"), - _("Forward error"), - _("Backward error"), - ): - info.SetText(lbl) - self.InsertColumn(idx_col, info) - idx_col += 1 + # # normal, simple columns + # idx_col = 0 + # for col in ( + # _("use"), + # _("source E"), + # _("source N"), + # _("source Z"), + # _("target E"), + # _("target N"), + # _("target Z"), + # _("Forward error"), + # _("Backward error"), + # ): + # self.InsertColumn(idx_col, col) + # idx_col += 1 + + # the hard way: we want images on the column header + info = wx.ListItem() + info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT) + info.SetImage(-1) + info.m_format = wx.LIST_FORMAT_LEFT + + idx_col = 0 + for lbl in ( + _("use"), + _("source E"), + _("source N"), + _("source Z"), + _("target E"), + _("target N"), + _("target Z"), + _("Forward error"), + _("Backward error"), + ): + info.SetText(lbl) + self.InsertColumn(idx_col, info) + idx_col += 1 def LoadData(self): """Load data into list""" diff --git a/gui/wxpython/mapdisp/statusbar.py b/gui/wxpython/mapdisp/statusbar.py index ae0b3b832d0..184a46b1ac5 100644 --- a/gui/wxpython/mapdisp/statusbar.py +++ b/gui/wxpython/mapdisp/statusbar.py @@ -210,9 +210,7 @@ def Update(self): else: item.Update() # render - if self.progressbar.IsShown(): - pass - else: + if not self.progressbar.IsShown(): item = list(self.statusbarItems.values())[self.GetMode()] item.Update() diff --git a/gui/wxpython/photo2image/ip2i_manager.py b/gui/wxpython/photo2image/ip2i_manager.py index 4f2bac9b788..3427319f77e 100644 --- a/gui/wxpython/photo2image/ip2i_manager.py +++ b/gui/wxpython/photo2image/ip2i_manager.py @@ -1646,40 +1646,39 @@ def __init__( self.selectedkey = -1 def _Create(self): - if 0: - # normal, simple columns - idx_col = 0 - for col in ( - _("use"), - _("source X"), - _("source Y"), - _("target X"), - _("target Y"), - _("Forward error"), - _("Backward error"), - ): - self.InsertColumn(idx_col, col) - idx_col += 1 - else: - # the hard way: we want images on the column header - info = wx.ListItem() - info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT) - info.SetImage(-1) - info.m_format = wx.LIST_FORMAT_LEFT - - idx_col = 0 - for lbl in ( - _("use"), - _("source X"), - _("source Y"), - _("target X"), - _("target Y"), - _("Forward error"), - _("Backward error"), - ): - info.SetText(lbl) - self.InsertColumn(idx_col, info) - idx_col += 1 + # # normal, simple columns + # idx_col = 0 + # for col in ( + # _("use"), + # _("source X"), + # _("source Y"), + # _("target X"), + # _("target Y"), + # _("Forward error"), + # _("Backward error"), + # ): + # self.InsertColumn(idx_col, col) + # idx_col += 1 + + # the hard way: we want images on the column header + info = wx.ListItem() + info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT) + info.SetImage(-1) + info.m_format = wx.LIST_FORMAT_LEFT + + idx_col = 0 + for lbl in ( + _("use"), + _("source X"), + _("source Y"), + _("target X"), + _("target Y"), + _("Forward error"), + _("Backward error"), + ): + info.SetText(lbl) + self.InsertColumn(idx_col, info) + idx_col += 1 def LoadData(self): """Load data into list""" diff --git a/gui/wxpython/vnet/dialogs.py b/gui/wxpython/vnet/dialogs.py index 3bce0fa07f1..fffe04832fe 100644 --- a/gui/wxpython/vnet/dialogs.py +++ b/gui/wxpython/vnet/dialogs.py @@ -682,10 +682,10 @@ def OnToTreeBtn(self, event): cmd = ["d.vect", "map=" + vectorMap] - if True: - self.giface.GetLayerList().AddLayer( - ltype="vector", cmd=cmd, name=vectorMap, checked=True - ) + self.giface.GetLayerList().AddLayer( + ltype="vector", cmd=cmd, name=vectorMap, checked=True + ) + # d.mon case is not need giface implementation should solve it for us def UseTurns(self): diff --git a/gui/wxpython/vnet/widgets.py b/gui/wxpython/vnet/widgets.py index 66ffcf8ad1c..eb4e4c8a83a 100644 --- a/gui/wxpython/vnet/widgets.py +++ b/gui/wxpython/vnet/widgets.py @@ -147,28 +147,27 @@ def __init__( def _createCols(self): """Creates columns in list""" - if 0: - # normal, simple columns - for col in enumerate(self.colsData): - iLabel = self.dataTypes["colLabel"] - self.InsertColumn(col[0], col[1][iLabel]) + # # normal, simple columns + # for col in enumerate(self.colsData): + # iLabel = self.dataTypes["colLabel"] + # self.InsertColumn(col[0], col[1][iLabel]) + + # the hard way: we want images on the column header + info = wx.ListItem() + info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT) + info.SetImage(-1) + if globalvar.wxPythonPhoenix: + info.Format = wx.LIST_FORMAT_LEFT else: - # the hard way: we want images on the column header - info = wx.ListItem() - info.SetMask(wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT) - info.SetImage(-1) + info.m_format = wx.LIST_FORMAT_LEFT + + for col in enumerate(self.colsData): + iLabel = self.dataTypes["colLabel"] + info.SetText(col[1][iLabel]) if globalvar.wxPythonPhoenix: - info.Format = wx.LIST_FORMAT_LEFT + self.InsertColumn(col[0], info) else: - info.m_format = wx.LIST_FORMAT_LEFT - - for col in enumerate(self.colsData): - iLabel = self.dataTypes["colLabel"] - info.SetText(col[1][iLabel]) - if globalvar.wxPythonPhoenix: - self.InsertColumn(col[0], info) - else: - self.InsertColumnInfo(col[0], info) + self.InsertColumnInfo(col[0], info) def AddItem(self): """Appends an item to list with default values""" From 189d0397761bc899f12739be8860750c0aaf5d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 23:24:38 +0000 Subject: [PATCH 17/21] gui: Use dict.items() in loop --- gui/wxpython/wxplot/base.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/gui/wxpython/wxplot/base.py b/gui/wxpython/wxplot/base.py index 21d4a442a77..7045146ba47 100755 --- a/gui/wxpython/wxplot/base.py +++ b/gui/wxpython/wxplot/base.py @@ -117,13 +117,10 @@ def _createColorDict(self): for assigning colors to images in imagery groups""" self.colorDict = {} - for clr in gs.named_colors.keys(): + for clr, (r, g, b) in gs.named_colors.items(): if clr == "white": continue - r = int(gs.named_colors[clr][0] * 255) - g = int(gs.named_colors[clr][1] * 255) - b = int(gs.named_colors[clr][2] * 255) - self.colorDict[clr] = (r, g, b, 255) + self.colorDict[clr] = (int(r * 255), int(g * 255), int(b * 255), 255) def InitPlotOpts(self, plottype): """Initialize options for entire plot""" From 833baaac99ae598af4401a9996fa6f5c5dc90bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sat, 4 Jan 2025 03:56:38 +0000 Subject: [PATCH 18/21] style: Fix RET504 [*] Unnecessary assignment to `img` before `return` statement --- gui/wxpython/gcp/manager.py | 6 ++---- gui/wxpython/image2target/ii2t_manager.py | 6 ++---- gui/wxpython/photo2image/ip2i_manager.py | 6 ++---- gui/wxpython/vnet/widgets.py | 6 ++---- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/gui/wxpython/gcp/manager.py b/gui/wxpython/gcp/manager.py index 8ebc3a04bb5..555157b3ddb 100644 --- a/gui/wxpython/gcp/manager.py +++ b/gui/wxpython/gcp/manager.py @@ -87,14 +87,12 @@ def getSmallUpArrowImage(): with open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") as stream: - img = wx.Image(stream) - return img + return wx.Image(stream) def getSmallDnArrowImage(): with open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb") as stream: - img = wx.Image(stream) - return img + return wx.Image(stream) class GCPWizard: diff --git a/gui/wxpython/image2target/ii2t_manager.py b/gui/wxpython/image2target/ii2t_manager.py index e4212fe3783..e1b72169cd9 100644 --- a/gui/wxpython/image2target/ii2t_manager.py +++ b/gui/wxpython/image2target/ii2t_manager.py @@ -91,14 +91,12 @@ def getSmallUpArrowImage(): with open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") as stream: - img = wx.Image(stream) - return img + return wx.Image(stream) def getSmallDnArrowImage(): with open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb") as stream: - img = wx.Image(stream) - return img + return wx.Image(stream) class GCPWizard: diff --git a/gui/wxpython/photo2image/ip2i_manager.py b/gui/wxpython/photo2image/ip2i_manager.py index 3427319f77e..5f41741e7b2 100644 --- a/gui/wxpython/photo2image/ip2i_manager.py +++ b/gui/wxpython/photo2image/ip2i_manager.py @@ -68,14 +68,12 @@ def getSmallUpArrowImage(): with open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") as stream: - img = wx.Image(stream) - return img + return wx.Image(stream) def getSmallDnArrowImage(): with open(os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb") as stream: - img = wx.Image(stream) - return img + return wx.Image(stream) class GCPWizard: diff --git a/gui/wxpython/vnet/widgets.py b/gui/wxpython/vnet/widgets.py index eb4e4c8a83a..1580465b9ac 100644 --- a/gui/wxpython/vnet/widgets.py +++ b/gui/wxpython/vnet/widgets.py @@ -439,16 +439,14 @@ def OnItemSelected(self, event): def getSmallUpArrowImage(self): """Get arrow up symbol for indication of sorting""" with open(os.path.join(globalvar.IMGDIR, "small_up_arrow.png"), "rb") as stream: - img = wx.Image(stream) - return img + return wx.Image(stream) def getSmallDnArrowImage(self): """Get arrow down symbol for indication of sorting""" with open( os.path.join(globalvar.IMGDIR, "small_down_arrow.png"), "rb" ) as stream: - img = wx.Image(stream) - return img + return wx.Image(stream) def _getColumnNum(self, colName): """Get position of column among showed columns From 4fb30433e94e766a852073dc9d7fa936e37c5b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 22:17:30 +0000 Subject: [PATCH 19/21] style: Fix new write-whole-file (FURB103) errors --- gui/wxpython/animation/temporal_manager.py | 91 +++++++++++----------- gui/wxpython/core/toolboxes.py | 3 +- gui/wxpython/gmodeler/model.py | 3 +- gui/wxpython/gmodeler/panels.py | 3 +- gui/wxpython/modules/colorrules.py | 9 +-- gui/wxpython/modules/mcalc_builder.py | 4 +- gui/wxpython/psmap/frame.py | 10 +-- gui/wxpython/vnet/vnet_core.py | 8 +- 8 files changed, 61 insertions(+), 70 deletions(-) diff --git a/gui/wxpython/animation/temporal_manager.py b/gui/wxpython/animation/temporal_manager.py index 46f33dd1b79..096dcac4f46 100644 --- a/gui/wxpython/animation/temporal_manager.py +++ b/gui/wxpython/animation/temporal_manager.py @@ -19,6 +19,7 @@ import datetime from operator import itemgetter +from pathlib import Path import grass.script as gs import grass.temporal as tgis @@ -413,26 +414,24 @@ def createAbsoluteInterval(): gs.mapcalc(exp="temp_6 = rand(0, 650)", overwrite=True) n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() - with open(n1, "w") as fd: - fd.write( - "prec_1|2001-01-01|2001-02-01\n" - "prec_2|2001-04-01|2001-05-01\n" - "prec_3|2001-05-01|2001-09-01\n" - "prec_4|2001-09-01|2002-01-01\n" - "prec_5|2002-01-01|2002-05-01\n" - "prec_6|2002-05-01|2002-07-01\n" - ) + Path(n1).write_text( + "prec_1|2001-01-01|2001-02-01\n" + "prec_2|2001-04-01|2001-05-01\n" + "prec_3|2001-05-01|2001-09-01\n" + "prec_4|2001-09-01|2002-01-01\n" + "prec_5|2002-01-01|2002-05-01\n" + "prec_6|2002-05-01|2002-07-01\n" + ) n2 = gs.read_command("g.tempfile", pid=2, flags="d").strip() - with open(n2, "w") as fd: - fd.write( - "temp_1|2000-10-01|2001-01-01\n" - "temp_2|2001-04-01|2001-05-01\n" - "temp_3|2001-05-01|2001-09-01\n" - "temp_4|2001-09-01|2002-01-01\n" - "temp_5|2002-01-01|2002-05-01\n" - "temp_6|2002-05-01|2002-07-01\n" - ) + Path(n2).write_text( + "temp_1|2000-10-01|2001-01-01\n" + "temp_2|2001-04-01|2001-05-01\n" + "temp_3|2001-05-01|2001-09-01\n" + "temp_4|2001-09-01|2002-01-01\n" + "temp_5|2002-01-01|2002-05-01\n" + "temp_6|2002-05-01|2002-07-01\n" + ) name1 = "absinterval1" name2 = "absinterval2" gs.run_command( @@ -486,26 +485,24 @@ def createRelativeInterval(): gs.mapcalc(exp="temp_6 = rand(0, 650)", overwrite=True) n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() - with open(n1, "w") as fd: - fd.write( - "prec_1|1|4\n" - "prec_2|6|7\n" - "prec_3|7|10\n" - "prec_4|10|11\n" - "prec_5|11|14\n" - "prec_6|14|17\n" - ) + Path(n1).write_text( + "prec_1|1|4\n" + "prec_2|6|7\n" + "prec_3|7|10\n" + "prec_4|10|11\n" + "prec_5|11|14\n" + "prec_6|14|17\n" + ) n2 = gs.read_command("g.tempfile", pid=2, flags="d").strip() - with open(n2, "w") as fd: - fd.write( - "temp_1|5|6\n" - "temp_2|6|7\n" - "temp_3|7|10\n" - "temp_4|10|11\n" - "temp_5|11|18\n" - "temp_6|19|22\n" - ) + Path(n2).write_text( + "temp_1|5|6\n" + "temp_2|6|7\n" + "temp_3|7|10\n" + "temp_4|10|11\n" + "temp_5|11|18\n" + "temp_6|19|22\n" + ) name1 = "relinterval1" name2 = "relinterval2" gs.run_command( @@ -558,15 +555,14 @@ def createAbsolutePoint(): gs.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() - with open(n1, "w") as fd: - fd.write( - "prec_1|2001-01-01\n" - "prec_2|2001-03-01\n" - "prec_3|2001-04-01\n" - "prec_4|2001-05-01\n" - "prec_5|2001-08-01\n" - "prec_6|2001-09-01\n" - ) + Path(n1).write_text( + "prec_1|2001-01-01\n" + "prec_2|2001-03-01\n" + "prec_3|2001-04-01\n" + "prec_4|2001-05-01\n" + "prec_5|2001-08-01\n" + "prec_6|2001-09-01\n" + ) name = "abspoint" gs.run_command( "t.create", @@ -605,8 +601,9 @@ def createRelativePoint(): gs.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() - with open(n1, "w") as fd: - fd.write("prec_1|1\nprec_2|3\nprec_3|5\nprec_4|7\nprec_5|11\nprec_6|13\n") + Path(n1).write_text( + "prec_1|1\nprec_2|3\nprec_3|5\nprec_4|7\nprec_5|11\nprec_6|13\n" + ) name = "relpoint" gs.run_command( "t.create", diff --git a/gui/wxpython/core/toolboxes.py b/gui/wxpython/core/toolboxes.py index 91095d151e1..cf1a8c40b0d 100644 --- a/gui/wxpython/core/toolboxes.py +++ b/gui/wxpython/core/toolboxes.py @@ -206,8 +206,7 @@ def getMenudataFile(userRootFile, newFile, fallback): try: xml = _getXMLString(tree.getroot()) - with open(menudataFile, "w") as fh: - fh.write(xml) + Path(menudataFile).write_text(xml) return menudataFile except Exception: _debug( diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index 308b26d126a..ae011f057f9 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -577,8 +577,7 @@ def _substituteFile(self, item, params=None, checkOnly=False): if not checkOnly: if write: - with open(finput, "w") as fd: - fd.write(data) + Path(finput).write_text(data) else: self.fileInput[finput] = None diff --git a/gui/wxpython/gmodeler/panels.py b/gui/wxpython/gmodeler/panels.py index e7c46239fd8..c0ba79673f0 100644 --- a/gui/wxpython/gmodeler/panels.py +++ b/gui/wxpython/gmodeler/panels.py @@ -401,8 +401,7 @@ def OnModelDone(self, event): if not data: continue - with open(finput, "w") as fd: - fd.write(data) + Path(finput).write_text(data) del self.model.fileInput # delete intermediate data diff --git a/gui/wxpython/modules/colorrules.py b/gui/wxpython/modules/colorrules.py index 24bd31a8001..f0d5953867a 100644 --- a/gui/wxpython/modules/colorrules.py +++ b/gui/wxpython/modules/colorrules.py @@ -685,8 +685,7 @@ def OnSaveRulesFile(self, event): GMessage(message=_("Nothing to save."), parent=self) return - with open(path, "w") as fd: - fd.write(rulestxt) + Path(path).write_text(rulestxt) def OnLoadRulesFile(self, event): """Load color table from file""" @@ -797,8 +796,7 @@ def CreateColorTable(self, tmp=False) -> bool: return False gtemp = utils.GetTempfile() - with open(gtemp, "w") as output: - output.write(rulestxt) + Path(gtemp).write_text(rulestxt) cmd = [ "%s.colors" % self.mapType[0], # r.colors/v.colors @@ -1819,8 +1817,7 @@ def UpdateColorColumn(self, tmp): return False gtemp = utils.GetTempfile() - with open(gtemp, "w") as output: - output.write(rulestxt) + Path(gtemp).write_text(rulestxt) RunCommand("db.execute", parent=self, input=gtemp) return True diff --git a/gui/wxpython/modules/mcalc_builder.py b/gui/wxpython/modules/mcalc_builder.py index d380da515a2..eb2dc7691f9 100644 --- a/gui/wxpython/modules/mcalc_builder.py +++ b/gui/wxpython/modules/mcalc_builder.py @@ -18,6 +18,7 @@ import os import re +from pathlib import Path import wx import grass.script as gs @@ -733,8 +734,7 @@ def OnSaveExpression(self, event): dlg.Destroy() return - with open(path, "w") as fobj: - fobj.write(mctxt) + Path(path).write_text(mctxt) dlg.Destroy() diff --git a/gui/wxpython/psmap/frame.py b/gui/wxpython/psmap/frame.py index 7ab3bab6eae..9684b2b45b6 100644 --- a/gui/wxpython/psmap/frame.py +++ b/gui/wxpython/psmap/frame.py @@ -19,6 +19,7 @@ import queue as Queue import sys from math import cos, pi, sin, sqrt +from pathlib import Path import wx @@ -597,11 +598,10 @@ def OnInstructionFile(self, event): wildcard="*.psmap|*.psmap|Text file(*.txt)|*.txt|All files(*.*)|*.*" ) if filename: - with open(filename, "wb") as instrFile: - content = self.InstructionFile() - if not content: - return - instrFile.write(content) + content = self.InstructionFile() + if not content: + return + Path(filename).write_bytes(content) def OnLoadFile(self, event): """Launch file dialog and load selected file""" diff --git a/gui/wxpython/vnet/vnet_core.py b/gui/wxpython/vnet/vnet_core.py index baf8dea9aed..eaf4874c86f 100644 --- a/gui/wxpython/vnet/vnet_core.py +++ b/gui/wxpython/vnet/vnet_core.py @@ -20,6 +20,8 @@ """ import math +from pathlib import Path + from grass.script.utils import try_remove from grass.script import core as grass from grass.script.task import cmdlist_to_tuple @@ -449,8 +451,7 @@ def _vnetPathRunAn(self, analysis, output, params, flags, catPts): ) self.coordsTmpFile = grass.tempfile() - with open(self.coordsTmpFile, "w") as coordsTmpFileOpened: - coordsTmpFileOpened.write(inpPoints) + Path(self.coordsTmpFile).write_text(inpPoints) if flags["t"]: cmdParams.append("-t") @@ -668,8 +669,7 @@ def _runAn(self, analysis, output, params, flags, catPts): # TODO better tmp files cleanup (make class for managing tmp files) self.tmpPtsAsciiFile = grass.tempfile() - with open(self.tmpPtsAsciiFile, "w") as tmpPtsAsciiFileOpened: - tmpPtsAsciiFileOpened.write(pt_ascii) + Path(self.tmpPtsAsciiFile).write_text(pt_ascii) self.tmpInPts = AddTmpMapAnalysisMsg("vnet_tmp_in_pts", self.tmp_maps) if not self.tmpInPts: From 1035478f7d6c7995ec119aaa9d22225984caaac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sat, 4 Jan 2025 04:09:22 +0000 Subject: [PATCH 20/21] style: Fix new read-whole-file (FURB101) errors --- gui/wxpython/gmodeler/model.py | 6 +++--- gui/wxpython/gui_core/ghelp.py | 6 ++++-- gui/wxpython/modules/colorrules.py | 4 +--- gui/wxpython/modules/mcalc_builder.py | 3 +-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index ae011f057f9..670afe17d90 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -39,6 +39,7 @@ import time import xml.etree.ElementTree as ET +from pathlib import Path from xml.sax import saxutils import wx @@ -542,9 +543,8 @@ def _substituteFile(self, item, params=None, checkOnly=False): for finput in self.fileInput: # read lines - with open(finput) as fd: - data = fd.read() - self.fileInput[finput] = data + data = Path(finput).read_text() + self.fileInput[finput] = data # substitute variables write = False diff --git a/gui/wxpython/gui_core/ghelp.py b/gui/wxpython/gui_core/ghelp.py index 63f7eff2280..b2a0d0500e9 100644 --- a/gui/wxpython/gui_core/ghelp.py +++ b/gui/wxpython/gui_core/ghelp.py @@ -23,6 +23,9 @@ import re import textwrap import sys + +from pathlib import Path + import wx from wx.html import HtmlWindow from operator import itemgetter @@ -274,8 +277,7 @@ def _pageCopyright(self): """Copyright information""" copyfile = os.path.join(os.getenv("GISBASE"), "COPYING") if os.path.exists(copyfile): - with open(copyfile) as copyrightFile: - copytext = copyrightFile.read() + copytext = Path(copyfile).read_text() else: copytext = _("%s file missing") % "COPYING" diff --git a/gui/wxpython/modules/colorrules.py b/gui/wxpython/modules/colorrules.py index f0d5953867a..08a6a6ebd52 100644 --- a/gui/wxpython/modules/colorrules.py +++ b/gui/wxpython/modules/colorrules.py @@ -694,9 +694,7 @@ def OnLoadRulesFile(self, event): return self.rulesPanel.Clear() - - with open(path) as fd: - self.ReadColorTable(ctable=fd.read()) + self.ReadColorTable(ctable=Path(path).read_text()) def ReadColorTable(self, ctable): """Read color table diff --git a/gui/wxpython/modules/mcalc_builder.py b/gui/wxpython/modules/mcalc_builder.py index eb2dc7691f9..5567d6bd66d 100644 --- a/gui/wxpython/modules/mcalc_builder.py +++ b/gui/wxpython/modules/mcalc_builder.py @@ -752,8 +752,7 @@ def OnLoadExpression(self, event): dlg.Destroy() return - with open(path) as fobj: - mctxt = fobj.read() + mctxt = Path(path).read_text() try: result, exp = mctxt.split("=", 1) From 198b0b3d3c7525543f82395cabc18b9b32b8735a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Fri, 3 Jan 2025 22:37:32 +0000 Subject: [PATCH 21/21] checks: Remove fixed Ruff SIM115 exclusions --- pyproject.toml | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2300282ad27..f9712ce2582 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -269,41 +269,35 @@ ignore = [ "**.py" = ["PYI066"] "*/testsuite/**.py" = ["PT009", "PT027"] "display/d.mon/render_cmd.py" = ["SIM115"] -"gui/wxpython/animation/temporal_manager.py" = ["SIM115"] -"gui/wxpython/core/*.py" = ["SIM115"] "gui/wxpython/core/globalvar.py" = ["PTH208"] -"gui/wxpython/core/settings.py" = ["PTH208"] +"gui/wxpython/core/render.py" = ["SIM115"] +"gui/wxpython/core/settings.py" = ["PTH208", "SIM115"] +"gui/wxpython/core/utils.py" = ["SIM115"] +"gui/wxpython/core/workspace.py" = ["SIM115"] "gui/wxpython/datacatalog/catalog.py" = ["PTH208"] "gui/wxpython/dbmgr/base.py" = ["SIM115"] -"gui/wxpython/gcp/manager.py" = ["PTH208", "SIM115"] -"gui/wxpython/gmodeler/*.py" = ["SIM115"] -"gui/wxpython/gui_core/*.py" = ["SIM115"] +"gui/wxpython/gcp/manager.py" = ["PTH208"] +"gui/wxpython/gmodeler/panels.py" = ["SIM115"] "gui/wxpython/gui_core/dialogs.py" = ["PTH208"] +"gui/wxpython/gui_core/forms.py" = ["SIM115"] +"gui/wxpython/gui_core/goutput.py" = ["SIM115"] +"gui/wxpython/gui_core/widgets.py" = ["SIM115"] "gui/wxpython/iclass/frame.py" = ["FLY002", "SIM115"] "gui/wxpython/iclass/statistics.py" = ["A005"] "gui/wxpython/icons/grass_icons.py" = ["PTH208"] -"gui/wxpython/image2target/*.py" = ["SIM115"] -"gui/wxpython/image2target/ii2t_manager.py" = ["PTH208"] -"gui/wxpython/lmgr/workspace.py" = ["SIM115"] -"gui/wxpython/location_wizard/wizard.py" = ["SIM115"] +"gui/wxpython/image2target/ii2t_manager.py" = ["PTH208", "SIM115"] "gui/wxpython/mapdisp/main.py" = ["SIM115"] "gui/wxpython/modules/colorrules.py" = ["SIM115"] "gui/wxpython/modules/mcalc_builder.py" = ["SIM115"] "gui/wxpython/photo2image/ip2i_manager.py" = ["SIM115"] "gui/wxpython/psmap/dialogs.py" = ["PTH208"] -"gui/wxpython/psmap/frame.py" = ["SIM115"] "gui/wxpython/psmap/instructions.py" = ["SIM115"] "gui/wxpython/psmap/utils.py" = ["PGH004"] -"gui/wxpython/rdigit/controller.py" = ["SIM115"] -"gui/wxpython/rlisetup/*.py" = ["SIM115"] "gui/wxpython/rlisetup/frame.py" = ["PTH208"] "gui/wxpython/timeline/frame.py" = ["FLY002"] "gui/wxpython/tools/update_menudata.py" = ["SIM115"] "gui/wxpython/tplot/frame.py" = ["FLY002"] -"gui/wxpython/vdigit/mapwindow.py" = ["SIM115"] -"gui/wxpython/vnet/vnet_core.py" = ["SIM115"] "gui/wxpython/vnet/vnet_data.py" = ["SIM115"] -"gui/wxpython/vnet/widgets.py" = ["SIM115"] "gui/wxpython/web_services/dialogs.py" = ["SIM115"] "gui/wxpython/wxplot/profile.py" = ["A005", "SIM115"] "imagery/i.atcorr/create_iwave.py" = ["SIM115"]