Skip to content

Commit eb3cc97

Browse files
authored
Merge pull request #368 from capocchi/version-5.1
Version 5.1
2 parents 7c85db4 + 2a3638f commit eb3cc97

File tree

14 files changed

+89
-70
lines changed

14 files changed

+89
-70
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 979d708a184d342313cc7c2b6bd24225e475af3b

devsimpy/DetachedFrame.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def __init__(self, parent=None, ID=wx.NewIdRef(), title="", diagram=None, name="
9999
self.canvas.stockRedo = []
100100

101101
### Menu ToolBar
102-
toolbar = wx.ToolBar(self, wx.NewIdRef(), name='tb', style=wx.TB_HORIZONTAL | wx.NO_BORDER)
102+
toolbar = self.CreateToolBar()
103103
toolbar.SetToolBitmapSize((16,16))
104104

105105
if self.parent:

devsimpy/DiagramConstantsDialog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def GetData(self):
279279
def OnCancel(self,evt):
280280
""" Close dialog.
281281
"""
282-
self.Destroy()
282+
self.CallAfter(self.Destroy)
283283

284284
def OnHelp(self, event):
285285
""" Help message dialogue.

devsimpy/Domain/Basic/Object.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
#
1515
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1616

17-
#import collections
18-
19-
#Message = collections.namedtuple('Message', 'value time')
2017

2118
class Message:
2219
''' The class Message provide the activation of all DEVS components.
@@ -27,6 +24,7 @@ class Message:
2724
@type value: None
2825
@type operation: string
2926
'''
27+
__slots__ = ("value", "time", "name")
3028

3129
###
3230
def __init__(self, v=None, t=None):

devsimpy/Editor.py

Lines changed: 61 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,7 @@ def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize, styl
228228
"""
229229
stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
230230

231-
# Do we want to automatically pop up command completion options?
232-
231+
# Do we want to automatically pop up command completion options?
233232
self.autoComplete = True
234233
self.autoCompleteIncludeMagic = True
235234
self.autoCompleteIncludeSingle = True
@@ -469,34 +468,50 @@ def get_current_class(self, pos):
469468

470469
# ------------------ Événement frappe ------------------
471470
def on_key_up(self, event):
471+
"""On key up event handler for auto-completion.
472+
473+
Args:
474+
event: _key up event
475+
"""
472476
key = event.GetKeyCode()
473-
if (65 <= key <= 90) or (97 <= key <= 122) or key == ord('_') or key == ord('.'):
477+
478+
return
479+
480+
if (65 <= key <= 90) or (97 <= key <= 122) or key in (ord('_'), ord('.')):
474481
pos = self.GetCurrentPos()
475482
start = self.WordStartPosition(pos, True)
476483
length = pos - start
477484
current_word = self.GetTextRange(start, pos)
478485

479486
self.update_classes_and_instances()
480487

481-
suggestions = set(keyword.kwlist)
482-
words = set(self.GetText().split())
483-
suggestions |= words
484-
485-
if '.' in current_word:
486-
obj_name, prefix = current_word.rsplit('.', 1)
487-
if obj_name == 'self':
488-
cls_name = self.get_current_class(pos)
489-
if cls_name and cls_name in self.classes:
490-
suggestions |= self.classes[cls_name]
491-
length = len(prefix)
492-
else:
493-
cls_name = self.instances.get(obj_name)
494-
if cls_name and cls_name in self.classes:
495-
suggestions |= self.classes[cls_name]
496-
length = len(prefix)
488+
final_suggestions = []
497489

498-
# Affiche suggestions locales immédiatement
499-
self.AutoCompShow(length, " ".join(sorted(suggestions)))
490+
print(current_word)
491+
# --- CAS SPECIAL : self. ---
492+
if current_word.startswith("self."):
493+
prefix = current_word.split(".", 1)[1] # ce qui est après self.
494+
cls_name = self.get_current_class(pos)
495+
print(cls_name, prefix, self.classes)
496+
if cls_name and cls_name in self.classes:
497+
498+
candidates = self.classes[cls_name]
499+
# On ne garde que ce qui commence par le préfixe
500+
final_suggestions = sorted(
501+
[c for c in candidates if c.startswith(prefix)]
502+
)
503+
length = len(prefix)
504+
505+
# --- CAS GENERAL ---
506+
# else:
507+
# suggestions = set(keyword.kwlist)
508+
# words = set(re.findall(r"[A-Za-z_][A-Za-z0-9_]*", self.GetText()))
509+
# suggestions |= words
510+
# final_suggestions = sorted(suggestions)
511+
512+
# Affiche uniquement si on a quelque chose à proposer
513+
if final_suggestions:
514+
self.AutoCompShow(length, " ".join(final_suggestions))
500515

501516
# Appel IA avec délai pour ne pas spammer
502517
# self.last_key_time = time.time()
@@ -1615,11 +1630,13 @@ def CreateMenu(self):
16151630

16161631
return menubar
16171632

1618-
def CreateTB(self):
1633+
def CreateTB(self, tb=None):
16191634
""" Create tool-bar.
16201635
"""
16211636

1622-
tb = wx.ToolBar(self, wx.NewIdRef(), name='tb', style=wx.TB_HORIZONTAL | wx.NO_BORDER)
1637+
if not tb:
1638+
tb = wx.ToolBar(self, wx.NewIdRef(), name='tb', style=wx.TB_HORIZONTAL | wx.NO_BORDER)
1639+
16231640
tb.SetToolBitmapSize((16, 16))# this required for non-standard size buttons on MSW
16241641

16251642
ai_help = _('Generative AI based modification' if bool(getattr(builtins, 'SELECTED_IA')) else 'Check the AI settings in Preferences')
@@ -1647,11 +1664,10 @@ def CreateTB(self):
16471664
self.Bind(wx.EVT_TOOL, self.nb.OnPaste, id= self.paste.GetId())
16481665
self.Bind(wx.EVT_TOOL, self.OnAiHelp, id=self.ai.GetId())
16491666

1650-
tb.Realize()
1651-
1652-
### Add: A. Dominici
16531667
tb.EnableTool(self.ai.GetId(), bool(getattr(builtins,'SELECTED_IA')))
16541668

1669+
tb.Realize()
1670+
16551671
return tb
16561672

16571673
def DoSearch(self, text):
@@ -2121,6 +2137,8 @@ def __init__(self, parent, id, title):
21212137
""" Constructor.
21222138
"""
21232139

2140+
Base.__init__(self, parent, id, title)
2141+
21242142
### copy
21252143
self.parent = parent
21262144

@@ -2133,10 +2151,10 @@ def __init__(self, parent, id, title):
21332151
### create menu, toolbar and statusbar for the frame
21342152
self.menuBar = self.CreateMenu()
21352153
self.SetMenuBar(self.menuBar)
2136-
self.toolbar = self.CreateTB()
21372154
self.statusbar= self.GetStatusBar()
21382155

2139-
### set the tool bar
2156+
### create and set the tool bar
2157+
self.toolbar = self.CreateTB(self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER))
21402158
self.SetToolBar(self.toolbar)
21412159

21422160
### binding
@@ -2148,7 +2166,6 @@ def __init__(self, parent, id, title):
21482166
e = wx.SizeEvent(self.GetSize())
21492167
self.ProcessEvent(e)
21502168

2151-
Base.__init__(self, parent, id, title)
21522169

21532170
class BlockBase(object):
21542171
###
@@ -2621,11 +2638,13 @@ def __init__(self, parent, id, title, block):
26212638
EditorFrame.__init__(self, parent, id, title)
26222639
BlockBase.__init__(self, parent, id, title, block)
26232640

2641+
# Icon
26242642
icon_bitmap = load_and_resize_image('py_file.png')
2625-
icon = wx.Icon()
2626-
icon.CopyFromBitmap(icon_bitmap)
2627-
self.SetIcon(icon)
2628-
2643+
if icon_bitmap and icon_bitmap.IsOk():
2644+
icon = wx.Icon()
2645+
icon.CopyFromBitmap(icon_bitmap)
2646+
self.SetIcon(icon)
2647+
26292648
self.ConfigureGUI()
26302649

26312650
###
@@ -2717,24 +2736,20 @@ def ConfigureGUI(self):
27172736
### insert new icon in toolbar (icon are not available in embeded editor (Show menu)
27182737
tb = self.GetToolBar()
27192738

2720-
tb.AddSeparator()
2721-
#tb.InsertSeparator(tb.GetToolsCount())
2739+
# tb.AddSeparator()
2740+
tb.InsertSeparator(tb.GetToolsCount())
27222741

2723-
### combo to insert tips text
2724-
cbID = wx.NewIdRef()
2742+
# ### combo to insert tips text
2743+
cbID = wx.NewIdRef()
27252744
tb.AddControl(wx.ComboBox(tb, cbID, _("Choose to insert in place"), choices=self.getChoices(),size=(160,-1), style=wx.CB_DROPDOWN))
2726-
2727-
### search text box
2745+
2746+
# ### search text box
27282747
tb.AddStretchableSpace()
27292748
finddlg = TestSearchCtrl(tb, size=(150,-1), doSearch=self.DoSearch)
27302749
tb.AddControl(finddlg)
27312750

2732-
try:
2733-
tb.Realize()
2734-
except:
2735-
sys.stdout.write(_("Toolbar not displayed on mac..."))
2736-
pass
2737-
2751+
tb.Realize()
2752+
27382753
if not self.cb.isCMD():
27392754
self.Bind(wx.EVT_MENU, self.OnInsertPeekPoke, id=peek.GetId())
27402755
self.Bind(wx.EVT_MENU, self.OnInsertPeekPoke, id=poke.GetId())
@@ -2760,6 +2775,7 @@ def ConfigureGUI(self):
27602775
self.Bind(wx.EVT_MENU, self.OnInsertDebug, id=debug.GetId())
27612776
self.Bind(wx.EVT_CLOSE, self.OnClose)
27622777

2778+
27632779
def OnClose(self,event):
27642780
"""
27652781
"""

devsimpy/LibPanel.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ def BuildToolbar(self):
111111
"""
112112

113113
tb = wx.ToolBar(self, wx.NewIdRef())
114-
#self.ToolBar = tb
115114
tb.SetToolBitmapSize((16,16))# this required for non-standard size buttons on MSW
116115

117116
### Add tool

devsimpy/PlotGUI.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,6 @@ def BuildToolbar(self):
277277
"""
278278

279279
tb = self.CreateToolBar()
280-
#tb = wx.ToolBar(self, style=wx.TB_HORIZONTAL|wx.NO_BORDER|wx.TB_FLAT)
281280
tb.SetToolBitmapSize((16,16))
282281

283282
zoomLabel, zoomId = self.enableZoom.GetItemLabelText(), self.enableZoom.GetId()

devsimpy/SimulationGUI.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ def OnOk(self, event):
494494

495495
### clear all log file
496496
for fn in [f for f in os.listdir(gettempdir()) if f.endswith('.devsimpy.log')]:
497-
os.remove(os.path.join(gettempdir(),fn))
497+
os.remove(os.path.join(gettempdir(), fn))
498498

499499
self.mem_offset = get_process_memory()
500500

@@ -505,7 +505,8 @@ def OnOk(self, event):
505505
if self.thread.end_flag:
506506
self.OnTimer(event)
507507
else:
508-
self.timer.Start(-1)
508+
# Déclenchement quasi immédiat (1 ms)
509+
self.timer.Start(1)
509510

510511
### timer for real time
511512
if self.real_time_flag:

devsimpy/Utilities.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,18 @@
6767
@lru_cache(maxsize=128)
6868
def load_and_resize_image(filename, width=16, height=16):
6969
"""Charge une image et la redimensionne à width x height"""
70-
7170
image_path = os.path.join(ICON_PATH, filename)
7271

7372
if not os.path.isfile(image_path):
7473
raise FileNotFoundError(f"File not found: {image_path}")
7574

7675
bitmap = wx.Bitmap(image_path)
77-
image = bitmap.ConvertToImage() # Conversion en wx.Image
78-
image = image.Scale(width, height, wx.IMAGE_QUALITY_HIGH) # Redimensionner l'image
79-
return wx.Bitmap(image) # Reconvertir en wx.Bitmap
80-
76+
if not bitmap.IsOk(): # vérification essentielle sur macOS
77+
raise RuntimeError(f"Failed to load bitmap: {image_path}")
78+
79+
image = bitmap.ConvertToImage()
80+
image = image.Scale(width, height, wx.IMAGE_QUALITY_HIGH)
81+
return wx.Bitmap(image)
8182

8283
else:
8384
def load_and_resize_image(filename, width=16, height=16):

devsimpy/WizardGUI.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ def on_page_changing(self, evt):
321321
def on_cancel(self, evt):
322322
"""Cancel button has been pressed. Clean up and exit without continuing."""
323323
self.canceled_flag = True
324-
self.on_close(evt)
324+
wx.CallAfter(self.Destroy)
325325

326326
def on_finished(self, evt):
327327
"""Finish button has been pressed. Give the specified values
@@ -331,8 +331,8 @@ def on_finished(self, evt):
331331
def on_close(self, evt):
332332
""" Close button has been pressed. Destroy the wizard.
333333
"""
334-
self.canceled_flag = True
335-
self.Destroy()
334+
wx.CallAfter(self.Destroy)
335+
336336

337337
class ModelGeneratorWizard(Wizard):
338338
""" Model Generator Wizard Class.
@@ -343,11 +343,11 @@ def __init__(self, *args, **kwargs):
343343
"""
344344

345345
if 'specific_domain_path' in kwargs:
346-
domain_path = kwargs['specific_domain_path']
346+
domain_path = kwargs['specific_domain_path'] if kwargs['specific_domain_path'] else DOMAIN_PATH
347347
del kwargs['specific_domain_path']
348348
else:
349349
domain_path = DOMAIN_PATH
350-
350+
351351
Wizard.__init__(self, *args, **kwargs)
352352

353353
# properties of model
@@ -550,7 +550,8 @@ def plugin_path_call_back(evt):
550550
# Create a page 4_1
551551
page4_1 = CustomPage(self, _('Finish'))
552552
# save filebrowse
553-
init = os.path.join(domain_path, "%s.amd"%vbox2.GetItem(1).GetWindow().GetValue())
553+
filename = vbox2.GetItem(1).GetWindow().GetValue()
554+
init = os.path.join(domain_path, f"{filename}.amd")
554555
fb2 = filebrowse.FileBrowseButton( page4_1,
555556
wx.NewIdRef(),
556557
initialValue = init,

0 commit comments

Comments
 (0)