diff --git a/gui/wxpython/core/settings.py b/gui/wxpython/core/settings.py index 05c6579e636..74f7080c830 100644 --- a/gui/wxpython/core/settings.py +++ b/gui/wxpython/core/settings.py @@ -764,6 +764,9 @@ def _defaultSettings(self): "nodata": {"enable": False}, }, }, + "rstudio": { + "path": "", + }, } # quick fix, https://trac.osgeo.org/grass/ticket/1233 diff --git a/gui/wxpython/gui_core/dialogs.py b/gui/wxpython/gui_core/dialogs.py index 19e430d605e..78a74b541b5 100644 --- a/gui/wxpython/gui_core/dialogs.py +++ b/gui/wxpython/gui_core/dialogs.py @@ -18,20 +18,23 @@ - :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 import re import wx +import wx.lib.filebrowsebutton as filebrowse from grass.script import core as grass from grass.script.utils import naturally_sorted, try_remove @@ -47,7 +50,13 @@ OgrTypeSelect, SubGroupSelect, ) -from gui_core.widgets import SingleSymbolPanel, SimpleValidator, MapValidator +from gui_core.widgets import ( + GenericValidator, + GListCtrl, + MapValidator, + SimpleValidator, + SingleSymbolPanel, +) from core.settings import UserSettings from core.debug import Debug from core.utils import is_shell_running @@ -2611,3 +2620,85 @@ 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 1b69a517717..5d81a1ba523 100644 --- a/gui/wxpython/lmgr/frame.py +++ b/gui/wxpython/lmgr/frame.py @@ -75,6 +75,7 @@ from lmgr.giface import LayerManagerGrassInterface from mapdisp.frame import MapDisplay from datacatalog.catalog import DataCatalog +from gui_core.dialogs import DirBrowseDialog from history.browser import HistoryBrowser from gui_core.forms import GUI from gui_core.wrap import Menu, TextEntryDialog @@ -758,6 +759,30 @@ def OnLocationWizard(self, event): show_confirmation=True, ) + 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 adb00836a1e..c92acaeea7d 100644 --- a/gui/wxpython/xml/toolboxes.xml +++ b/gui/wxpython/xml/toolboxes.xml @@ -617,6 +617,10 @@ + + + + diff --git a/gui/wxpython/xml/wxgui_items.xml b/gui/wxpython/xml/wxgui_items.xml index ba4b30fa840..7781ce1f131 100644 --- a/gui/wxpython/xml/wxgui_items.xml +++ b/gui/wxpython/xml/wxgui_items.xml @@ -306,6 +306,18 @@ Creates new mapset in the current project, changes current mapset. general,mapset,create + + + OnSetRStudioPath + Set RStudio path. + general,rstudio,path + + + + g.version -c + Displays version and copyright information. + general,version + g.proj -p