From 2ffc6e9de58049ec728c7296898406d34f209667 Mon Sep 17 00:00:00 2001 From: Tomas Zigo Date: Wed, 6 Jan 2021 22:05:54 +0100 Subject: [PATCH 1/2] wxGUI/lmgr: add menu item for launching dialog for setting RStudio path --- gui/wxpython/core/settings.py | 3 ++ gui/wxpython/gui_core/dialogs.py | 79 ++++++++++++++++++++++++++++++-- gui/wxpython/lmgr/frame.py | 25 ++++++++++ gui/wxpython/xml/toolboxes.xml | 2 + gui/wxpython/xml/wxgui_items.xml | 6 +++ 5 files changed, 112 insertions(+), 3 deletions(-) diff --git a/gui/wxpython/core/settings.py b/gui/wxpython/core/settings.py index a1441f76c6f..0204b6b9b43 100644 --- a/gui/wxpython/core/settings.py +++ b/gui/wxpython/core/settings.py @@ -919,6 +919,9 @@ def _defaultSettings(self): }, }, }, + 'rstudio': { + 'path': '', + }, } # quick fix, http://trac.osgeo.org/grass/ticket/1233 diff --git a/gui/wxpython/gui_core/dialogs.py b/gui/wxpython/gui_core/dialogs.py index 6e4a97e77ef..26cedde4f5a 100644 --- a/gui/wxpython/gui_core/dialogs.py +++ b/gui/wxpython/gui_core/dialogs.py @@ -18,14 +18,16 @@ - :class:`SymbolDialog` - :class:`QuitDialog` - :class:`DefaultFontDialog` + - :class:`DirBrowseDialog` -(C) 2008-2016 by the GRASS Development Team +(C) 2008-2021 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS for details. @author Martin Landa @author Anna Kratochvilova (GroupDialog, SymbolDialog) +@author Tomas Zigo (DirBrowseDialog) """ import os @@ -34,6 +36,7 @@ import six import wx +import wx.lib.filebrowsebutton as filebrowse from grass.script import core as grass from grass.script.utils import naturally_sorted, try_remove @@ -44,8 +47,10 @@ from core.gcmd import GError, RunCommand, GMessage from gui_core.gselect import LocationSelect, MapsetSelect, Select, \ OgrTypeSelect, SubGroupSelect -from gui_core.widgets import SingleSymbolPanel, GListCtrl, SimpleValidator, \ - MapValidator +from gui_core.widgets import ( + GenericValidator, GListCtrl, MapValidator, SimpleValidator, + SingleSymbolPanel, +) from core.settings import UserSettings from core.debug import Debug from gui_core.wrap import Button, CheckListBox, EmptyBitmap, HyperlinkCtrl, \ @@ -2609,3 +2614,71 @@ def RenderText(self, font, text, size): else: self.renderfont.SetBitmap(EmptyBitmap(size[0], size[1])) try_remove(self.tmp_file) + + +class DirBrowseDialog(wx.Dialog): + """Simple dialog with DirBrowseButton widget.""" + + def __init__( + self, parent, message, caption='', defaultValue='', + validator=wx.DefaultValidator, style=wx.OK | wx.CANCEL | wx.CENTRE, + textStyle=0, textSize=(300, -1), size=(400, -1), + **kwargs): + wx.Dialog.__init__( + self, + parent=parent, + id=wx.ID_ANY, + title=caption, + size=size, + **kwargs) + + vbox = wx.BoxSizer(wx.VERTICAL) + + stline = StaticText(self, id=wx.ID_ANY, label=message) + vbox.Add(stline, proportion=0, flag=wx.EXPAND | wx.ALL, border=10) + + self._dirBrowse = filebrowse.DirBrowseButton( + parent=self, id=wx.ID_ANY, labelText=_("Directory:"), + dialogTitle=_("Choose directory for export"), + buttonText=_("Browse"), + startDirectory=os.getcwd()) + self._dirBrowse.SetValidator( + GenericValidator(condition=self._pathExists, + callback=self._pathDoesNotExists)) + wx.CallAfter(self._dirBrowse.SetFocus) + + vbox.Add(self._dirBrowse, + proportion=0, + flag=wx.EXPAND | wx.LEFT | wx.RIGHT, + border=10) + + sizer = self.CreateSeparatedButtonSizer(style) + vbox.Add(sizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=10) + + self.SetSizerAndFit(vbox) + self.SetSizeHints(size[0], size[1], -1 , -1) + + self.Bind(wx.EVT_BUTTON, self.OnPathValidation, + self.FindWindow(id=wx.ID_OK)) + + def _pathExists(self, path): + return os.path.exists(path) + + def _pathDoesNotExists(self, ctrl): + GMessage(parent=self, + message=_("RStudio path <{}> doesn't exists. " + "Set correct path, please.".format(ctrl.GetValue()))) + + def OnPathValidation(self, event): + if self.Validate() and self.TransferDataFromWindow(): + if self.IsModal(): + self.EndModal(wx.ID_OK) + else: + self.SetReturnCode(wx.ID_OK) + self.Show(False) + + def GetValue(self): + return self._dirBrowse.GetValue() + + def SetValue(self, value): + self._dirBrowse.SetValue(value) diff --git a/gui/wxpython/lmgr/frame.py b/gui/wxpython/lmgr/frame.py index 4b88ce6a29b..cfc33b42983 100644 --- a/gui/wxpython/lmgr/frame.py +++ b/gui/wxpython/lmgr/frame.py @@ -67,6 +67,7 @@ from lmgr.pyshell import PyShellWindow from lmgr.giface import LayerManagerGrassInterface from datacatalog.catalog import DataCatalog +from gui_core.dialogs import DirBrowseDialog from gui_core.forms import GUI from gui_core.wrap import Menu, TextEntryDialog from grass.grassdb.checks import is_current_mapset_in_demolocation @@ -515,6 +516,30 @@ def OnLocationWizard(self, event): action='new', element='location') + def OnSetRStudioPath(self, event): + """Set RStudio path""" + dlg = DirBrowseDialog( + parent=self, + message=_("Set RStudio path:"), + caption=_("Set RStudio path"), + ) + + rstudio_path = UserSettings.Get(group='rstudio', key='path') + if rstudio_path: + dlg.SetValue(value=rstudio_path) + + if dlg.ShowModal() == wx.ID_OK: + rstudio_path = dlg.GetValue() + UserSettings.Set(group='rstudio', key='path', value=rstudio_path) + fileSettings = {} + UserSettings.ReadSettingsFile(settings=fileSettings) + fileSettings['rstudio'] = UserSettings.Get(group='rstudio') + UserSettings.SaveToFile(fileSettings) + if rstudio_path not in os.environ['PATH']: + os.environ['PATH'] += os.pathsep + rstudio_path + + dlg.Destroy() + def OnSettingsChanged(self): """Here can be functions which have to be called after receiving settingsChanged signal. diff --git a/gui/wxpython/xml/toolboxes.xml b/gui/wxpython/xml/toolboxes.xml index 6f36a884cb9..89fd2077fb5 100644 --- a/gui/wxpython/xml/toolboxes.xml +++ b/gui/wxpython/xml/toolboxes.xml @@ -610,6 +610,8 @@ + + diff --git a/gui/wxpython/xml/wxgui_items.xml b/gui/wxpython/xml/wxgui_items.xml index f9a7aef5667..24dbcf87807 100644 --- a/gui/wxpython/xml/wxgui_items.xml +++ b/gui/wxpython/xml/wxgui_items.xml @@ -311,6 +311,12 @@ Creates new mapset in the current location, changes current mapset. general,mapset,create + + + OnSetRStudioPath + Set RStudio path. + general,rstudio,path + g.version -c From 400c0e1615c7f91ab8e1136b609f09aa5a520f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Sat, 30 Mar 2024 22:19:05 -0400 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- gui/wxpython/core/settings.py | 4 +- gui/wxpython/gui_core/dialogs.py | 67 ++++++++++++++++++++------------ gui/wxpython/lmgr/frame.py | 10 ++--- 3 files changed, 49 insertions(+), 32 deletions(-) diff --git a/gui/wxpython/core/settings.py b/gui/wxpython/core/settings.py index 27eeec330cb..ad633209e28 100644 --- a/gui/wxpython/core/settings.py +++ b/gui/wxpython/core/settings.py @@ -761,8 +761,8 @@ def _defaultSettings(self): "nodata": {"enable": False}, }, }, - 'rstudio': { - 'path': '', + "rstudio": { + "path": "", }, } diff --git a/gui/wxpython/gui_core/dialogs.py b/gui/wxpython/gui_core/dialogs.py index ce711606618..038604de879 100644 --- a/gui/wxpython/gui_core/dialogs.py +++ b/gui/wxpython/gui_core/dialogs.py @@ -51,7 +51,10 @@ SubGroupSelect, ) from gui_core.widgets import ( - GenericValidator, GListCtrl, MapValidator, SimpleValidator, + GenericValidator, + GListCtrl, + MapValidator, + SimpleValidator, SingleSymbolPanel, ) from core.settings import UserSettings @@ -2637,17 +2640,21 @@ class DirBrowseDialog(wx.Dialog): """Simple dialog with DirBrowseButton widget.""" def __init__( - self, parent, message, caption='', defaultValue='', - validator=wx.DefaultValidator, style=wx.OK | wx.CANCEL | wx.CENTRE, - textStyle=0, textSize=(300, -1), size=(400, -1), - **kwargs): + self, + parent, + message, + caption="", + defaultValue="", + validator=wx.DefaultValidator, + style=wx.OK | wx.CANCEL | wx.CENTRE, + textStyle=0, + textSize=(300, -1), + size=(400, -1), + **kwargs, + ): wx.Dialog.__init__( - self, - parent=parent, - id=wx.ID_ANY, - title=caption, - size=size, - **kwargs) + self, parent=parent, id=wx.ID_ANY, title=caption, size=size, **kwargs + ) vbox = wx.BoxSizer(wx.VERTICAL) @@ -2655,36 +2662,46 @@ def __init__( vbox.Add(stline, proportion=0, flag=wx.EXPAND | wx.ALL, border=10) self._dirBrowse = filebrowse.DirBrowseButton( - parent=self, id=wx.ID_ANY, labelText=_("Directory:"), + parent=self, + id=wx.ID_ANY, + labelText=_("Directory:"), dialogTitle=_("Choose directory for export"), buttonText=_("Browse"), - startDirectory=os.getcwd()) + startDirectory=os.getcwd(), + ) self._dirBrowse.SetValidator( - GenericValidator(condition=self._pathExists, - callback=self._pathDoesNotExists)) + GenericValidator( + condition=self._pathExists, callback=self._pathDoesNotExists + ) + ) wx.CallAfter(self._dirBrowse.SetFocus) - vbox.Add(self._dirBrowse, - proportion=0, - flag=wx.EXPAND | wx.LEFT | wx.RIGHT, - border=10) + vbox.Add( + self._dirBrowse, + proportion=0, + flag=wx.EXPAND | wx.LEFT | wx.RIGHT, + border=10, + ) sizer = self.CreateSeparatedButtonSizer(style) vbox.Add(sizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=10) self.SetSizerAndFit(vbox) - self.SetSizeHints(size[0], size[1], -1 , -1) + self.SetSizeHints(size[0], size[1], -1, -1) - self.Bind(wx.EVT_BUTTON, self.OnPathValidation, - self.FindWindow(id=wx.ID_OK)) + self.Bind(wx.EVT_BUTTON, self.OnPathValidation, self.FindWindow(id=wx.ID_OK)) def _pathExists(self, path): return os.path.exists(path) def _pathDoesNotExists(self, ctrl): - GMessage(parent=self, - message=_("RStudio path <{}> doesn't exists. " - "Set correct path, please.".format(ctrl.GetValue()))) + GMessage( + parent=self, + message=_( + "RStudio path <{}> doesn't exists. " + "Set correct path, please.".format(ctrl.GetValue()) + ), + ) def OnPathValidation(self, event): if self.Validate() and self.TransferDataFromWindow(): diff --git a/gui/wxpython/lmgr/frame.py b/gui/wxpython/lmgr/frame.py index fd92f3bf828..69e727341a6 100644 --- a/gui/wxpython/lmgr/frame.py +++ b/gui/wxpython/lmgr/frame.py @@ -768,19 +768,19 @@ def OnSetRStudioPath(self, event): caption=_("Set RStudio path"), ) - rstudio_path = UserSettings.Get(group='rstudio', key='path') + rstudio_path = UserSettings.Get(group="rstudio", key="path") if rstudio_path: dlg.SetValue(value=rstudio_path) if dlg.ShowModal() == wx.ID_OK: rstudio_path = dlg.GetValue() - UserSettings.Set(group='rstudio', key='path', value=rstudio_path) + UserSettings.Set(group="rstudio", key="path", value=rstudio_path) fileSettings = {} UserSettings.ReadSettingsFile(settings=fileSettings) - fileSettings['rstudio'] = UserSettings.Get(group='rstudio') + fileSettings["rstudio"] = UserSettings.Get(group="rstudio") UserSettings.SaveToFile(fileSettings) - if rstudio_path not in os.environ['PATH']: - os.environ['PATH'] += os.pathsep + rstudio_path + if rstudio_path not in os.environ["PATH"]: + os.environ["PATH"] += os.pathsep + rstudio_path dlg.Destroy()