diff --git a/Complexity.py b/Complexity.py index 991dac22..dca004af 100644 --- a/Complexity.py +++ b/Complexity.py @@ -21,45 +21,6 @@ ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## import os, sys -ABS_HOME_PATH = os.path.abspath(os.path.dirname(sys.argv[0])) - -import builtins -### specific built-in variables. (don't modify the default value. If you want to change it, go to the PreferencesGUI from devsimpy interface.) -builtin_dict = {'SPLASH_PNG': os.path.join(ABS_HOME_PATH, 'splash', 'splash.png'), # abslolute path - 'DEVSIMPY_PNG': 'iconDEVSimPy.png', # png file for devsimpy icon - 'HOME_PATH': ABS_HOME_PATH, - 'ICON_PATH': os.path.join(ABS_HOME_PATH, 'icons'), - 'ICON_PATH_16_16': os.path.join(ABS_HOME_PATH, 'icons', '16x16'), - 'SIMULATION_SUCCESS_SOUND_PATH': os.path.join(ABS_HOME_PATH,'sounds', 'Simulation-Success.wav'), - 'SIMULATION_ERROR_SOUND_PATH': os.path.join(ABS_HOME_PATH,'sounds', 'Simulation-Error.wav'), - 'DOMAIN_PATH': os.path.join(ABS_HOME_PATH, 'Domain'), # path of local lib directory - 'NB_OPENED_FILE': 5, # number of recent files - 'NB_HISTORY_UNDO': 5, # number of undo - 'OUT_DIR': 'out', # name of local output directory (composed by all .dat, .txt files) - '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 - '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 - 'PYPDEVS_SIM_STRATEGY_DICT' : {'classic':'SimStrategy4', 'distributed':'SimStrategy5', 'parallel':'SimStrategy6'}, # list of available simulation strategy for PyPDEVS package - 'HELP_PATH' : os.path.join('doc', 'html'), # path of help directory - 'NTL' : False, # No Time Limit for the simulation - 'DYNAMIC_STRUCTURE' : False, # Dynamic Structure for local PyPDEVS simulation - 'REAL_TIME': False, ### PyPDEVS threaded real time simulation - 'VERBOSE':False, - 'TRANSPARENCY' : True, # Transparancy for DetachedFrame - 'DEFAULT_PLOT_DYN_FREQ' : 100, # frequence of dynamic plot of QuickScope (to avoid overhead), - 'DEFAULT_DEVS_DIRNAME':'PyDEVS', # default DEVS Kernel directory - 'DEVS_DIR_PATH_DICT':{'PyDEVS':os.path.join(ABS_HOME_PATH,'DEVSKernel','PyDEVS'), - 'PyPDEVS_221':os.path.join(ABS_HOME_PATH,'DEVSKernel','PyPDEVS','pypdevs221' ,'src'), - 'PyPDEVS':os.path.join(ABS_HOME_PATH,'DEVSKernel','PyPDEVS','old')}, - 'GUI_FLAG':False - } - -# Sets the homepath variable to the directory where your application is located (sys.argv[0]). -builtins.__dict__.update(builtin_dict) - import inspect import Components import textwrap diff --git a/Container.py b/Container.py index 9bd0bc35..73984d83 100644 --- a/Container.py +++ b/Container.py @@ -109,7 +109,7 @@ ### for all dsp model build with old version of DEVSimPy sys.modules['Savable'] = sys.modules['Mixins.Savable'] -from Decorators import BuzyCursorNotification, StatusBarNotification, ProgressNotification, Pre_Undo, Post_Undo, cond_decorator +from Decorators import BuzyCursorNotification, StatusBarNotification, Pre_Undo, Post_Undo, cond_decorator from Utilities import HEXToRGB, RGBToHEX, relpath, GetActiveWindow, playSound, sendEvent, getInstance, FixedList, getObjectFromString, getTopLevelWindow, printOnStatusBar from Patterns.Observer import Subject, Observer @@ -591,7 +591,7 @@ def GetParent(self): def GetGrandParent(self): return self.GetParent().GetParent() - @cond_decorator(builtins.__dict__.get('GUI_FLAG',True), ProgressNotification("DEVSimPy open file")) + @BuzyCursorNotification def LoadFile(self, fileName = None): """ Function that load diagram from a file. """ diff --git a/Decorators.py b/Decorators.py index 02caa80e..12728e8f 100644 --- a/Decorators.py +++ b/Decorators.py @@ -102,10 +102,10 @@ def BuzyCursorNotification(f): """ Decorator which give the buzy cursor for long process """ def wrapper(*args): - wx.BeginBusyCursor() + wait = wx.BusyCursor() #wx.SafeYield() r = f(*args) - wx.EndBusyCursor() + del wait return r return wrapper @@ -142,24 +142,45 @@ def wrapper(*args): return wrapper +class ThreadWithReturnValue(threading.Thread): + def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None): + threading.Thread.__init__(self, group, target, name, args, kwargs, daemon=daemon) + + self._return = None + + def run(self): + if self._target is not None: + self._return = self._target(*self._args, **self._kwargs) + + def join(self): + threading.Thread.join(self) + return self._return + @decorator_with_args -def ProgressNotification(f,arg): +def ProgressNotification(f, arg): def wrapper(*args): - txt = arg - new_path = args[-1] - progress_dlg = wx.ProgressDialog(txt, - "Loading %s ..."%os.path.basename(new_path), parent=None, - style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) - progress_dlg.Pulse() + thread = ThreadWithReturnValue(target = f, args = args) + thread.start() - #wx.SafeYield() + title = arg + new_path = args[-1] + if isinstance(new_path, str) and os.path.isfile(new_path): + message = _("Loading %s ...")%os.path.basename(new_path) + else: + message = _('Please wait..') - r = f(*args) + progress_dlg = wx.ProgressDialog(title, message, style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) + + while thread.isAlive(): + wx.MilliSleep(300) + progress_dlg.Pulse() + wx.SafeYield() progress_dlg.Destroy() + + return thread.join() - return r return wrapper def print_timing(func): diff --git a/LibraryTree.py b/LibraryTree.py index 031ddc81..4f2681c4 100644 --- a/LibraryTree.py +++ b/LibraryTree.py @@ -1092,12 +1092,15 @@ def OnItemDocumentation(self, evt): else: doc = inspect.getdoc(module) + ### Add maccabe complexity measure + doc += "".join([_("\n\n MacCabe Complexity: %d")%elf.MetricDico[item]['mcc']]) + if doc: - dlg = wx.lib.dialogs.ScrolledMessageDialog(self, doc, name, style=wx.OK|wx.ICON_EXCLAMATION|wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER) + dlg = wx.lib.dialogs.ScrolledMessageDialog(self, doc, _("%s Documentation")%name, style=wx.OK|wx.ICON_EXCLAMATION|wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER) dlg.CenterOnParent(wx.BOTH) dlg.ShowModal() else: - wx.MessageBox(_('No documentation'), name, wx.OK|wx.ICON_INFORMATION) + wx.MessageBox(_("No documentation! \n Please define the documentation of the model %s in the header of its python file.")%name, _("%s Documentation")%name, wx.OK|wx.ICON_INFORMATION) ### def OnInfo(self, event): diff --git a/Menu.py b/Menu.py index 379b87f3..0dd45dbc 100644 --- a/Menu.py +++ b/Menu.py @@ -527,48 +527,49 @@ def OnOpenMenu(self, event): menu = event.GetMenu() - posm = self.FindMenu(menu.GetTitle()) - - ### if the opened menu is the File menu - if isinstance(menu, FileMenu): - - if wx.VERSION_STRING < '4.0': - ### Before Phoenix Transition - ### if item exist, we delete him - if menu.FindItemById(ID_RECENT):menu.Delete(ID_RECENT) - - ### we insert the recent files menu - menu.InsertMenu(1, ID_RECENT, _("Recent files"), RecentFileMenu(self)) - else: - if platform.system() == 'Windows': - ### After Pnoenix Transition - self.Replace(posm, FileMenu(self), _("&File")) + if menu: + posm = self.FindMenu(menu.GetTitle()) + + ### if the opened menu is the File menu + if isinstance(menu, FileMenu): + + if wx.VERSION_STRING < '4.0': + ### Before Phoenix Transition + ### if item exist, we delete him + if menu.FindItemById(ID_RECENT):menu.Delete(ID_RECENT) + + ### we insert the recent files menu + menu.InsertMenu(1, ID_RECENT, _("Recent files"), RecentFileMenu(self)) else: - label = _("Recent files") - ID = menu.FindItem(label) - item, pos = menu.FindChildItem(ID) - menu.Remove(ID) - menu.Insert(pos, ID, label, RecentFileMenu(self)) - - elif isinstance(menu, SettingsMenu): - - if wx.VERSION_STRING < '4.0': - ### Before Pnoenix Transition - ### if item exist, we delete him - if menu.FindItemById(ID_PROFILE): menu.Delete(ID_PROFILE) + if platform.system() == 'Windows': + ### After Pnoenix Transition + self.Replace(posm, FileMenu(self), _("&File")) + else: + label = _("Recent files") + ID = menu.FindItem(label) + item, pos = menu.FindChildItem(ID) + menu.Remove(ID) + menu.Insert(pos, ID, label, RecentFileMenu(self)) + + elif isinstance(menu, SettingsMenu): - ### we insert the profile files menu - menu.InsertMenu(1, ID_PROFILE, _('Profile'), ProfileFileMenu(self)) - else: - ### After Pnoenix Transition - if platform.system() == 'Windows': - self.Replace(posm, SettingsMenu(self), _("&Options")) + if wx.VERSION_STRING < '4.0': + ### Before Pnoenix Transition + ### if item exist, we delete him + if menu.FindItemById(ID_PROFILE): menu.Delete(ID_PROFILE) + + ### we insert the profile files menu + menu.InsertMenu(1, ID_PROFILE, _('Profile'), ProfileFileMenu(self)) else: - label = _('Profile') - ID = menu.FindItem(label) - item, pos = menu.FindChildItem(ID) - menu.Remove(ID) - menu.Insert(pos, ID, label, ProfileFileMenu(self)) + ### After Pnoenix Transition + if platform.system() == 'Windows': + self.Replace(posm, SettingsMenu(self), _("&Options")) + else: + label = _('Profile') + ID = menu.FindItem(label) + item, pos = menu.FindChildItem(ID) + menu.Remove(ID) + menu.Insert(pos, ID, label, ProfileFileMenu(self)) #def OnCloseMenu(self, event): diff --git a/Utilities.py b/Utilities.py index 089b4196..6012d621 100644 --- a/Utilities.py +++ b/Utilities.py @@ -181,13 +181,15 @@ def updatePackageWithPiP(): """ Update all installed package using pip """ + updatePiP() + if pip.__version__ > '10.0.1': import pkg_resources packages = [dist.project_name for dist in pkg_resources.working_set if 'PyPubSub' not in dist.project_name] - call("pip install --upgrade -r requirements.txt", shell=True) + call("pip install --user --upgrade -r requirements.txt", shell=True) else: packages = [dist.project_name for dist in pip.get_installed_distributions() if 'PyPubSub' not in dist.project_name] - call("pip install --upgrade " + ' '.join(packages), shell=True) + call("pip install --user --upgrade " + ' '.join(packages), shell=True) NotificationMessage(_('Information'), 'All pip packages have been updated!', None, timeout=5) diff --git a/devsimpy.py b/devsimpy.py index c36dcee8..ce0f78fe 100644 --- a/devsimpy.py +++ b/devsimpy.py @@ -188,7 +188,7 @@ from pluginmanager import load_plugins, enable_plugin from which import which from Utilities import GetUserConfigDir, install_and_import, updatePackageWithPiP -from Decorators import redirectStdout, BuzyCursorNotification +from Decorators import redirectStdout, BuzyCursorNotification, ProgressNotification, cond_decorator from DetachedFrame import DetachedFrame from LibraryTree import LibraryTree from LibPanel import LibPanel @@ -1998,6 +1998,7 @@ def OnHelp(self, event): else: self.help.Display(os.path.join('html','toc.html')) + @cond_decorator(builtins.__dict__.get('GUI_FLAG',True), ProgressNotification("DEVSimPy Update pip packages")) def OnUpdatePiPPackage(self, event): updatePackageWithPiP()