From ebe9e30534ec9934eabe0ae7f0e58785a8c6c081 Mon Sep 17 00:00:00 2001 From: Capocchi L Date: Tue, 2 Mar 2021 18:51:27 +0100 Subject: [PATCH] Add external code editor. The choice is possible from preferences gui. --- Components.py | 45 +++++++++++++++++++++++-------------- PreferencesGUI.py | 56 +++++++++++++++++++++++++++++++++++++++++++---- devsimpy.py | 1 + requirements.txt | 2 ++ 4 files changed, 83 insertions(+), 21 deletions(-) diff --git a/Components.py b/Components.py index 67675542..12a232fb 100644 --- a/Components.py +++ b/Components.py @@ -758,28 +758,34 @@ def OnEditor(self, event): mainW = mainW.GetParent() if not builtins.__dict__['LOCAL_EDITOR'] and not zipfile.is_zipfile(model_path) and not python_path.startswith('http'): - dial = wx.MessageDialog(mainW, _('Do you want to use your local programmer software?\n\n If you always want use the DEVSimPy code editor\n change the option in Editor panel preferences.'), name, wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) + dial = wx.MessageDialog(mainW, _('Do you want to use your local code editor software?\n\n If you always want to always use the local DEVSimPy code editor\n change the option in the Editor panel preference.'), name, wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) val = dial.ShowModal() else: - val = wx.ID_NO + val = wx.ID_YES ### if local editor - if val == wx.ID_YES: + if val == wx.ID_NO: ### open with local editor if wx.Platform == '__WXMAC__': subprocess.call(" ".join(['open -a',python_path]), shell=True) elif "wxMSW" in wx.PlatformInfo: - ### TODO : select dialog to chose editor (spyder, pyzo, etc..) + editor = builtins.__dict__['EXTERNAL_EDITOR_NAME'] + + ### try to import the editor try: - import spyder + importlib.import_module(editor) + ### if not install it except ImportError: - if BuzyCursorNotification(install('spyder')): - dial = wx.MessageDialog(mainW, _('You need to restart DEVSimPy to use the Spyder code editor.'), name, wx.OK | wx.ICON_INFORMATION) + if BuzyCursorNotification(install(editor)): + dial = wx.MessageDialog(self.parent, _('You need to restart DEVSimPy to use the %s code editor.')%editor, name, wx.OK | wx.ICON_INFORMATION) val = dial.ShowModal() - else: + + ### open the editor + if editor == 'pyzo': + subprocess.Popen(['pyzo', python_path]) + elif editor == 'spyder': subprocess.Popen(['spyder', python_path, '--multithread']) - #os.startfile(python_path) elif "wxGTK" in wx.PlatformInfo: ### with gnome if os.system('pidof gedit') == 256: @@ -833,14 +839,14 @@ def OnEditor(self, event): else: ### if python_path is not found (because have an external origin) - if not os.path.exists(python_path): - if os.path.basename(DOMAIN_PATH) in python_path.split(os.sep): - python_path = os.path.join(HOME_PATH, python_path[python_path.index(os.path.basename(DOMAIN_PATH)):].strip('[]')) - self.python_path = python_path + if not os.path.exists(python_path) and os.path.basename( + DOMAIN_PATH) in python_path.split(os.sep): + python_path = os.path.join(HOME_PATH, python_path[python_path.index(os.path.basename(DOMAIN_PATH)):].strip('[]')) + self.python_path = python_path - # ### only with python 2.6 - # with codecs.open(python_path, 'r', 'utf-8') as f: - # text = f.read() + # ### only with python 2.6 + # with codecs.open(python_path, 'r', 'utf-8') as f: + # text = f.read() name = os.path.basename(python_path) @@ -852,7 +858,12 @@ def OnEditor(self, event): return editorFrame except Exception as info: - dlg = wx.MessageDialog(mainW, _('Editor frame not instanciated: %s\n'%info), name, wx.OK|wx.ICON_ERROR) + dlg = wx.MessageDialog( + mainW, + _('Editor frame not instanciated: %s\n' % info), + name, + wx.OK | wx.ICON_ERROR, + ) dlg.ShowModal() return False diff --git a/PreferencesGUI.py b/PreferencesGUI.py index a9080ba5..7f6b9f97 100644 --- a/PreferencesGUI.py +++ b/PreferencesGUI.py @@ -30,6 +30,8 @@ import configparser import copy import zipfile +import subprocess +import importlib import wx.lib.filebrowsebutton as filebrowse @@ -46,7 +48,8 @@ from HtmlWindow import HtmlFrame from PluginsGUI import PluginsPanel, GeneralPluginsList -from Utilities import playSound, GetUserConfigDir, GetWXVersionFromIni, AddToInitFile, DelToInitFile +from Utilities import playSound, GetUserConfigDir, GetWXVersionFromIni, AddToInitFile, DelToInitFile, install +from Decorators import BuzyCursorNotification import ReloadModule import Menu @@ -535,12 +538,16 @@ class EditorPanel(wx.Panel): """ Edition Panel. """ + EDITORS = ('spyder','pyzo') + def __init__(self, parent): """ Constructor. """ wx.Panel.__init__(self, parent) + self.parent = parent + self.InitUI() def InitUI(self): @@ -549,20 +556,61 @@ def InitUI(self): vbox = wx.BoxSizer(wx.VERTICAL) - self.cb = wx.CheckBox(self, wx.NewIdRef(), _("Use local programmer software")) + self.cb = wx.CheckBox(self, wx.NewIdRef(), _("Use the DEVSimPy local code editor software")) self.cb.SetValue(builtins.__dict__['LOCAL_EDITOR']) if wx.VERSION_STRING >= '4.0': self.cb.SetToolTipString = self.cb.SetToolTip - self.cb.SetToolTipString(_("This option don't work for the .amd and .cmd file. \n" + self.cb.SetToolTipString(_("This option is available only for the python file. \n" "Modification of python file during the simulation is disabled when this checkbox is checked.")) - vbox.Add(self.cb, 0, wx.ALL,10) + ### populte the choices array depending on the code editor installed + ### if the code editor is not installed, we propose to install it + choices = [] + + for editor in EditorPanel.EDITORS: + try: + importlib.import_module(editor) + except ImportError: + if BuzyCursorNotification(install(editor)): + dial = wx.MessageDialog(self.parent, _('You need to restart DEVSimPy to use the %s code editor.')%editor, _("Code Editor Installation"), wx.OK | wx.ICON_INFORMATION) + val = dial.ShowModal() + else: + choices.append(editor) + + ### add the choice object to select one external code editor + hbox = wx.BoxSizer(wx.HORIZONTAL) + txt = wx.StaticText(self, -1, _("Select an external code editor:")) + self.choice = wx.Choice(self, -1, choices=choices) + + ### if external editor name is never stored in config file (.devsimpy) + if builtins.__dict__['EXTERNAL_EDITOR_NAME'] == "": + self.choice.SetSelection(0) + else: + self.choice.SetSelection(EditorPanel.EDITORS.index(builtins.__dict__['EXTERNAL_EDITOR_NAME'])) + + self.choice.Enable(not self.cb.IsChecked()) + + hbox.Add(txt, 0, wx.ALL, 10) + hbox.Add(self.choice, 0, wx.ALL, 10) + + ### the checkbox and the choice objects + vbox.Add(self.cb, 0, wx.ALL, 10) + vbox.Add(hbox, 0, wx.ALL, 10) + + ### bid the checkbox in order to enable the choice object + self.Bind(wx.EVT_CHECKBOX, self.OnCheck, self.cb) self.SetSizer(vbox) + def OnCheck(self, event): + """ + """ + self.choice.Enable(not self.cb.IsChecked()) + def OnApply(self, evt): """ Apply changes. """ builtins.__dict__['LOCAL_EDITOR'] = self.cb.IsChecked() + builtins.__dict__['EXTERNAL_EDITOR_NAME'] = self.choice.GetString(self.choice.GetCurrentSelection()) if self.choice.IsEnabled() else "" ######################################################################## class Preferences(wx.Toolbook): diff --git a/devsimpy.py b/devsimpy.py index 45698f4d..071a36ab 100644 --- a/devsimpy.py +++ b/devsimpy.py @@ -149,6 +149,7 @@ 'PLUGINS_PATH': os.path.join(ABS_HOME_PATH, 'plugins'), # path of plug-ins directory 'FONT_SIZE': 12, # Block font size 'LOCAL_EDITOR': True, # for the use of local editor + 'EXTERNAL_EDITOR_NAME': "", # the name of the external code editor (only if LOCAL_EDITOR is False) 'LOG_FILE': os.devnull, # log file (null by default) 'DEFAULT_SIM_STRATEGY': 'bag-based', #choose the default simulation strategy for PyDEVS 'PYDEVS_SIM_STRATEGY_DICT' : {'original':'SimStrategy1', 'bag-based':'SimStrategy2', 'direct-coupling':'SimStrategy3'}, # list of available simulation strategy for PyDEVS package diff --git a/requirements.txt b/requirements.txt index 52b0e8d9..7354c851 100644 --- a/requirements.txt +++ b/requirements.txt @@ -236,6 +236,8 @@ whichpy >= 0.1 # PreferencesGUI.py: 6 #whratio >= 3.1.1 +spyder >=4.2.2 +pyzo >=4.11.2 # DEVSKernel\PyPDEVS\pypdevs221\src\templates\tracer.py: 1 #yang0textutils >= 0.0.1