mwxlib 1.4.6__py3-none-any.whl → 1.4.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mwxlib might be problematic. Click here for more details.

mwx/controls.py CHANGED
@@ -2,6 +2,7 @@
2
2
  """mwxlib param controller and wx custom controls.
3
3
  """
4
4
  from itertools import chain
5
+ import inspect
5
6
  import wx
6
7
  import wx.lib.platebtn as pb
7
8
  import wx.lib.scrolledpanel as scrolled
@@ -68,7 +69,8 @@ class Param:
68
69
  'overflow' : [],
69
70
  'underflow' : [],
70
71
  })
71
- self._tooltip = _Tip(handler.__doc__, updater.__doc__)
72
+ self._tooltip = _Tip(handler.__doc__,
73
+ updater.__doc__)
72
74
 
73
75
  def __str__(self, v=None):
74
76
  if v is None:
@@ -137,6 +139,10 @@ class Param:
137
139
  for knob in self.knobs:
138
140
  knob.update_ctrl(None)
139
141
  return
142
+ elif v == self.__value:
143
+ for knob in self.knobs:
144
+ knob.update_ctrl()
145
+ return
140
146
 
141
147
  ## If the value is out of range, it will be modified.
142
148
  valid = (self.min <= v <= self.max)
@@ -293,7 +299,6 @@ class Knob(wx.Panel):
293
299
  style : style of label
294
300
  None -> static text (default)
295
301
  button -> label with flat button
296
- chkbox -> label with checkbox
297
302
  checkbox -> label with checkbox
298
303
  cw : width of control
299
304
  lw : width of label
@@ -313,6 +318,15 @@ class Knob(wx.Panel):
313
318
  self.update_range()
314
319
  self.update_ctrl()
315
320
 
321
+ @property
322
+ def button(self):
323
+ if isinstance(self._label, pb.PlateButton):
324
+ return self._label
325
+
326
+ @property
327
+ def control(self):
328
+ return self._ctrl
329
+
316
330
  def __init__(self, parent, param, type=None,
317
331
  style=None, cw=-1, lw=-1, tw=-1, h=22, **kwargs):
318
332
  wx.Panel.__init__(self, parent, **kwargs)
@@ -335,9 +349,11 @@ class Knob(wx.Panel):
335
349
  label = self.__par.name + ' '
336
350
 
337
351
  if style == 'chkbox' or style == 'checkbox':
352
+ ## Keep margin for the checkbox: lw += 16
338
353
  self._label = wx.CheckBox(self, label=label, size=(lw,-1))
339
354
  self._label.Bind(wx.EVT_CHECKBOX, self.OnCheck)
340
355
  elif style == 'button':
356
+ ## Keep margin for the button: lw += 16
341
357
  self._label = pb.PlateButton(self, label=label, size=(lw,-1),
342
358
  style=pb.PB_STYLE_DEFAULT|pb.PB_STYLE_SQUARE)
343
359
  self._label.Bind(wx.EVT_BUTTON, self.OnPress)
@@ -668,17 +684,18 @@ class KnobCtrlPanel(scrolled.ScrolledPanel):
668
684
 
669
685
  self.Sizer.Add(sizer, expand>1, p | wx.ALL, border)
670
686
 
671
- ## Register object and parameter groups
672
- def _flatiter(a):
673
- for c in a:
687
+ ## Register objects and parameter groups
688
+ def _flatiter(objects):
689
+ for c in objects:
674
690
  if isinstance(c, tuple):
675
691
  yield from _flatiter(c)
676
692
  elif isinstance(c, wx.Object):
677
693
  yield c
678
694
  self.__groups.append(list(_flatiter(objs)))
679
695
 
680
- def _variter(a):
681
- for c in a:
696
+ ## Parameters : Knob.param or widgets that have a `value`.
697
+ def _variter(objects):
698
+ for c in objects:
682
699
  if isinstance(c, Knob):
683
700
  yield c.param
684
701
  elif hasattr(c, 'value'):
@@ -689,6 +706,8 @@ class KnobCtrlPanel(scrolled.ScrolledPanel):
689
706
  self.show(-1, visible)
690
707
  self.fold(-1, not show)
691
708
  self.Sizer.Fit(self)
709
+
710
+ return self.__groups[-1]
692
711
 
693
712
  ## --------------------------------
694
713
  ## 外部入出力/クリップボード通信
@@ -836,7 +855,7 @@ class Icon(wx.Bitmap):
836
855
  If the key is empty it returns a transparent bitmap, otherwise NullBitmap.
837
856
 
838
857
  Note:
839
- A null (0-shaped) bitmap fails with AssertionError from 4.1.1
858
+ A null (0-shaped) bitmap fails with AssertionError from wx ver 4.1.1.
840
859
  """
841
860
  provided_arts = {
842
861
  'cut' : wx.ART_CUT,
@@ -860,8 +879,8 @@ class Icon(wx.Bitmap):
860
879
  '!!!' : wx.ART_ERROR,
861
880
  '+' : wx.ART_PLUS,
862
881
  '-' : wx.ART_MINUS,
863
- 'x' : wx.ART_DELETE,
864
- 't' : wx.ART_TICK_MARK,
882
+ ## 'x' : wx.ART_DELETE,
883
+ ## 't' : wx.ART_TICK_MARK,
865
884
  '~' : wx.ART_GO_HOME,
866
885
  'undo' : wx.ART_UNDO,
867
886
  'redo' : wx.ART_REDO,
@@ -901,18 +920,17 @@ class Icon(wx.Bitmap):
901
920
  except Exception:
902
921
  art = Icon.provided_arts.get(key)
903
922
  bmp = wx.ArtProvider.GetBitmap(art or key, wx.ART_OTHER, size)
923
+ ## Note: The result could be a zero-shaped bitmap.
904
924
  return bmp
905
-
906
- ## Note: null (0-shaped) bitmap fails with AssertionError from 4.1.1
907
925
  elif key == '':
926
+ ## Note: A zero-shaped bitmap fails with AssertionError since wx ver 4.1.1.
908
927
  bmp = wx.Bitmap(size)
909
928
  with wx.MemoryDC(bmp) as dc:
910
929
  dc.SetBackground(wx.Brush('black'))
911
930
  dc.Clear()
912
931
  bmp.SetMaskColour('black') # return dummy-sized blank bitmap
913
932
  return bmp
914
-
915
- return wx.NullBitmap # The standard wx controls accept this,
933
+ return wx.NullBitmap # The standard wx controls accept this.
916
934
 
917
935
  @staticmethod
918
936
  def _getBitmap2(back, fore, size=None, subsize=3/4):
@@ -922,6 +940,8 @@ class Icon(wx.Bitmap):
922
940
  subsize = wx.Size(size) * subsize
923
941
  back = Icon._getBitmap1(back, size)
924
942
  fore = Icon._getBitmap1(fore, subsize)
943
+ if back.Size == (0, 0) or fore.Size == (0, 0):
944
+ return back
925
945
  x = size[0] - subsize[0]
926
946
  y = size[1] - subsize[1]
927
947
  with wx.MemoryDC(back) as dc:
@@ -975,8 +995,7 @@ class ClassicButton(wx.Button):
975
995
 
976
996
  if handler:
977
997
  self.Bind(wx.EVT_BUTTON, _F(handler))
978
-
979
- self.SetToolTip(_Tip(handler.__doc__))
998
+ self.SetToolTip(_Tip(handler.__doc__))
980
999
  if icon:
981
1000
  self.SetBitmap(Icon(icon))
982
1001
 
@@ -996,8 +1015,7 @@ class Button(pb.PlateButton):
996
1015
 
997
1016
  if handler:
998
1017
  self.Bind(wx.EVT_BUTTON, _F(handler))
999
-
1000
- self.SetToolTip(_Tip(handler.__doc__))
1018
+ self.SetToolTip(_Tip(handler.__doc__))
1001
1019
  if icon:
1002
1020
  self.SetBitmap(Icon(icon))
1003
1021
 
@@ -1029,8 +1047,7 @@ class ToggleButton(wx.ToggleButton):
1029
1047
 
1030
1048
  if handler:
1031
1049
  self.Bind(wx.EVT_TOGGLEBUTTON, _F(handler))
1032
-
1033
- self.SetToolTip(_Tip(handler.__doc__))
1050
+ self.SetToolTip(_Tip(handler.__doc__))
1034
1051
  if icon:
1035
1052
  try:
1036
1053
  self.SetBitmap(Icon(icon[0]))
@@ -1058,19 +1075,20 @@ class TextBox(wx.Control):
1058
1075
 
1059
1076
  value = Value #: internal use only
1060
1077
 
1078
+ button = property(lambda self: self._btn)
1079
+ control = property(lambda self: self._ctrl)
1080
+
1061
1081
  def __init__(self, parent, label='', handler=None, updater=None,
1062
1082
  icon=None, readonly=False, size=(-1,-1), **kwargs):
1063
1083
  wx.Control.__init__(self, parent, size=size, style=wx.BORDER_NONE)
1064
1084
 
1065
1085
  kwargs['style'] = (kwargs.get('style', 0)
1066
- | wx.TE_PROCESS_ENTER
1067
- | (wx.TE_READONLY if readonly else 0))
1086
+ | wx.TE_PROCESS_ENTER
1087
+ | (wx.TE_READONLY if readonly else 0))
1068
1088
 
1069
1089
  self._ctrl = wx.TextCtrl(self, **kwargs)
1070
1090
  self._btn = Button(self, label, None, icon,
1071
1091
  size=(-1,-1) if label or icon else (0,0))
1072
- self._ctrl.SetToolTip(_Tip(handler.__doc__))
1073
- self._btn.SetToolTip(_Tip(updater.__doc__))
1074
1092
 
1075
1093
  self.SetSizer(
1076
1094
  pack(self, (
@@ -1081,9 +1099,11 @@ class TextBox(wx.Control):
1081
1099
  if handler:
1082
1100
  self._handler = _F(handler)
1083
1101
  self._ctrl.Bind(wx.EVT_TEXT_ENTER, lambda v: self._handler(self))
1102
+ self._ctrl.SetToolTip(_Tip(handler.__doc__))
1084
1103
  if updater:
1085
1104
  self._updater = _F(updater)
1086
1105
  self._btn.Bind(wx.EVT_BUTTON, lambda v: self._updater(self))
1106
+ self._btn.SetToolTip(_Tip(updater.__doc__))
1087
1107
 
1088
1108
  self.Bind(wx.EVT_NAVIGATION_KEY, self.OnNavKey)
1089
1109
 
@@ -1134,19 +1154,20 @@ class Choice(wx.Control):
1134
1154
  lambda self,v: self._ctrl.SetItems(v),
1135
1155
  doc="combobox items:list")
1136
1156
 
1157
+ button = property(lambda self: self._btn)
1158
+ control = property(lambda self: self._ctrl)
1159
+
1137
1160
  def __init__(self, parent, label='', handler=None, updater=None,
1138
1161
  icon=None, readonly=False, size=(-1,-1), **kwargs):
1139
1162
  wx.Control.__init__(self, parent, size=size, style=wx.BORDER_NONE)
1140
1163
 
1141
1164
  kwargs['style'] = (kwargs.get('style', 0)
1142
- | wx.TE_PROCESS_ENTER
1143
- | (wx.CB_READONLY if readonly else 0))
1165
+ | wx.TE_PROCESS_ENTER
1166
+ | (wx.CB_READONLY if readonly else 0))
1144
1167
 
1145
1168
  self._ctrl = wx.ComboBox(self, **kwargs)
1146
1169
  self._btn = Button(self, label, None, icon,
1147
1170
  size=(-1,-1) if label or icon else (0,0))
1148
- self._ctrl.SetToolTip(_Tip(handler.__doc__))
1149
- self._btn.SetToolTip(_Tip(updater.__doc__))
1150
1171
 
1151
1172
  self.SetSizer(
1152
1173
  pack(self, (
@@ -1158,10 +1179,12 @@ class Choice(wx.Control):
1158
1179
  self._handler = _F(handler)
1159
1180
  self._ctrl.Bind(wx.EVT_TEXT_ENTER, lambda v: self._handler(self))
1160
1181
  self._ctrl.Bind(wx.EVT_COMBOBOX, lambda v: self._handler(self))
1182
+ self._ctrl.SetToolTip(_Tip(handler.__doc__))
1161
1183
  self._ctrl.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter)
1162
1184
  if updater:
1163
1185
  self._updater = _F(updater)
1164
1186
  self._btn.Bind(wx.EVT_BUTTON, lambda v: self._updater(self))
1187
+ self._btn.SetToolTip(_Tip(updater.__doc__))
1165
1188
 
1166
1189
  self.Bind(wx.EVT_NAVIGATION_KEY, self.OnNavKey)
1167
1190
 
mwx/framework.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #! python3
2
2
  """mwxlib framework.
3
3
  """
4
- __version__ = "1.4.6"
4
+ __version__ = "1.4.11"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from contextlib import contextmanager
@@ -290,7 +290,7 @@ class KeyCtrlInterfaceMixin:
290
290
  evt.Skip()
291
291
  post_command_hook.__name__ = str('exit')
292
292
 
293
- def define_key(self, keymap, action=None, *args, **kwargs):
293
+ def define_key(self, keymap, action=None, /, *args, **kwargs):
294
294
  """Define [map key (pressed)] action.
295
295
 
296
296
  If no action, it invalidates the key and returns @decor(binder).
@@ -1594,7 +1594,7 @@ class ShellFrame(MiniFrame):
1594
1594
 
1595
1595
  ## Modify the floating position of the pane when displayed.
1596
1596
  ## Note: This is a known bug in wxWidgets 3.17 -- 3.20,
1597
- ## and will be fixed in wxPython 4.2.1.
1597
+ ## and will be fixed in wx ver 4.2.1.
1598
1598
  if wx.Display.GetFromWindow(pane.window) == -1:
1599
1599
  pane.floating_pos = wx.GetMousePosition()
1600
1600
 
mwx/graphman.py CHANGED
@@ -6,7 +6,6 @@ from importlib import reload, import_module
6
6
  from contextlib import contextmanager
7
7
  from bdb import BdbQuit
8
8
  from pprint import pformat
9
- from subprocess import Popen
10
9
  import threading
11
10
  import traceback
12
11
  import inspect
@@ -257,7 +256,6 @@ class LayerInterface(CtrlInterface):
257
256
  caption = True
258
257
  category = None
259
258
  dockable = True
260
- editable = True # deprecated
261
259
  reloadable = True
262
260
  unloadable = True
263
261
 
@@ -381,10 +379,6 @@ class LayerInterface(CtrlInterface):
381
379
  lambda v: reset_params(v, checked_only=wx.GetKeyState(wx.WXK_SHIFT)),
382
380
  lambda v: v.Enable(bool(self.parameters))),
383
381
  (),
384
- (wx.ID_EDIT, "&Edit module", "Edit module", Icon('pen'),
385
- lambda v: self.parent.edit_plug(self.__module__),
386
- lambda v: v.Enable(self.editable)),
387
-
388
382
  (mwx.ID_(201), "&Reload module", "Reload module", Icon('load'),
389
383
  lambda v: self.parent.reload_plug(self.__module__),
390
384
  lambda v: v.Enable(self.reloadable
@@ -843,9 +837,6 @@ class Frame(mwx.Frame):
843
837
 
844
838
  ## Accepts DnD
845
839
  self.SetDropTarget(MyFileDropLoader(self.graph, self))
846
-
847
- ## Script editor for plugins (external call)
848
- EDITOR = "notepad"
849
840
 
850
841
  SYNC_SWITCH = True
851
842
 
@@ -983,7 +974,7 @@ class Frame(mwx.Frame):
983
974
 
984
975
  ## Modify the floating position of the pane when displayed.
985
976
  ## Note: This is a known bug in wxWidgets 3.17 -- 3.20,
986
- ## and will be fixed in wxPython 4.2.1.
977
+ ## and will be fixed in wx ver 4.2.1.
987
978
  if wx.Display.GetFromWindow(pane.window) == -1:
988
979
  pane.floating_pos = wx.GetMousePosition()
989
980
 
@@ -1339,14 +1330,6 @@ class Frame(mwx.Frame):
1339
1330
  if shell.target is plug:
1340
1331
  shell.handler('shell_activated', shell)
1341
1332
 
1342
- @ignore(ResourceWarning)
1343
- def edit_plug(self, name):
1344
- plug = self.get_plug(name)
1345
- if not plug:
1346
- return
1347
-
1348
- Popen([self.EDITOR, inspect.getmodule(plug).__file__])
1349
-
1350
1333
  def inspect_plug(self, name):
1351
1334
  """Dive into the process to inspect plugs in the shell.
1352
1335
  """
mwx/images.py CHANGED
@@ -652,6 +652,22 @@ w = PyEmbeddedImage(
652
652
  b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWfIwBngDGCYAAAAASUVO'
653
653
  b'RK5CYII=')
654
654
 
655
+ #----------------------------------------------------------------------
656
+ x = PyEmbeddedImage(
657
+ b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0'
658
+ b'RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIhSURBVDjLlZPrThNRFIWJicmJ'
659
+ b'z6BWiYbIkYDEG0JbBiitDQgm0PuFXqSAtKXtpE2hNuoPTXwSnwtExd6w0pl2OtPlrphKLSXh'
660
+ b'x07OZM769qy19wwAGLhM1ddC184+d18QMzoq3lfsD3LZ7Y3XbE5DL6Atzuyilc5Ciyd7IHVf'
661
+ b'gNcDYTQ2tvDr5crn6uLSvX+Av2Lk36FFpSVENDe3OxDZu8apO5rROJDLo30+Nlvj5RnTlVNA'
662
+ b'Ks1aCVFr7b4BPn6Cls21AWgEQlz2+Dl1h7IdA+i97A/geP65WhbmrnZZ0GIJpr6OqZqYAd5/'
663
+ b'gJpKox4Mg7pD2YoC2b0/54rJQuJZdm6Izcgma4TW1WZ0h+y8BfbyJMwBmSxkjw+VObNanp5h'
664
+ b'/adwGhaTXF4NWbLj9gEONyCmUZmd10pGgf1/vwcgOT3tUQE0DdicwIod2EmSbwsKE1P8QoDk'
665
+ b'cHPJ5YESjgBJkYQpIEZ2KEB51Y6y3ojvY+P8XEDN7uKS0w0ltA7QGCWHCxSWWpwyaCeLy0Bk'
666
+ b'A7UXyyg8fIzDoWHeBaDN4tQdSvAVdU1Aok+nsNTipIEVnkywo/FHatVkBoIhnFisOBoZxcGt'
667
+ b'Qd4B0GYJNZsDSiAEadUBCkstPtN3Avs2Msa+Dt9XfxoFSNYF/Bh9gP0bOqHLAm2WUF1YQskw'
668
+ b'rVFYPWkf3h1iXwbvqGfFPSGW9Eah8HSS9fuZDnS32f71m8KFY7xs/QZyu6TH2+2+FAAAAABJ'
669
+ b'RU5ErkJggg==')
670
+
655
671
  #----------------------------------------------------------------------
656
672
  xo = PyEmbeddedImage(
657
673
  b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAADAFBMVEWywNxcVlwcHhwUEhQE'
mwx/matplot2.py CHANGED
@@ -178,12 +178,10 @@ class MatplotPanel(wx.Panel):
178
178
  'axes_enter' : [ None, ],
179
179
  'axes_leave' : [ None, ],
180
180
  'home pressed' : [ None, self.OnHomePosition ],
181
- 'backspace pressed' : [ None, self.OnBackPosition ],
182
- 'M-backspace pressed' : [ None, self.OnForwardPosition ],
181
+ 'left pressed' : [ None, self.OnBackPosition ],
182
+ 'right pressed' : [ None, self.OnForwardPosition ],
183
183
  'Xbutton1 pressed' : [ None, self.OnBackPosition ],
184
184
  'Xbutton2 pressed' : [ None, self.OnForwardPosition ],
185
- 'M-p pressed' : [ None, self.OnBackPosition ],
186
- 'M-n pressed' : [ None, self.OnForwardPosition ],
187
185
  },
188
186
  NORMAL : {
189
187
  'art_picked' : (NORMAL, ),
mwx/matplot2g.py CHANGED
@@ -419,6 +419,8 @@ class GraphPlot(MatplotPanel):
419
419
  'M-down pressed' : [ None, self.OnPageDown ],
420
420
  'pageup pressed' : [ None, self.OnPageUp ],
421
421
  'pagedown pressed' : [ None, self.OnPageDown ],
422
+ 'home pressed' : [ None, _F(self.select, 0) ],
423
+ 'end pressed' : [ None, _F(self.select, -1) ],
422
424
  'M-a pressed' : [ None, _F(self.fit_to_canvas) ],
423
425
  'C-a pressed' : [ None, _F(self.fit_to_axes) ],
424
426
  'C-i pressed' : [ None, _F(self.invert_cmap) ],
@@ -681,7 +683,7 @@ class GraphPlot(MatplotPanel):
681
683
  if j != self.__index and self.__index is not None:
682
684
  self.handler('frame_hidden', self.frame)
683
685
 
684
- if j is not None:
686
+ if j is not None and self.__Arts:
685
687
  art = self.__Arts[j]
686
688
  art.set_visible(1)
687
689
  self.__index = j % len(self)
@@ -692,7 +694,6 @@ class GraphPlot(MatplotPanel):
692
694
  self.draw()
693
695
  self.writeln()
694
696
  self.trace_point(*self.selector)
695
-
696
697
  return self.frame
697
698
 
698
699
  def __iter__(self):
mwx/nutshell.py CHANGED
@@ -138,7 +138,7 @@ def skip(evt):
138
138
  evt.Skip()
139
139
 
140
140
 
141
- def can_edit(f):
141
+ def editable(f):
142
142
  @wraps(f)
143
143
  def _f(self, *v, **kw):
144
144
  if self.CanEdit():
@@ -404,6 +404,7 @@ class AutoCompInterfaceMixin:
404
404
  try:
405
405
  text, sep, hint = self._get_words_hint()
406
406
  obj = self.eval(text)
407
+ ## dir = introspect.getAttributeNames @TODO in wx ver 4.2.3
407
408
 
408
409
  P = re.compile(hint)
409
410
  p = re.compile(hint, re.I)
@@ -431,6 +432,7 @@ class AutoCompInterfaceMixin:
431
432
  try:
432
433
  text, sep, hint = self._get_words_hint()
433
434
  obj = self.eval(text)
435
+ ## dir = introspect.getAttributeNames @TODO in wx ver 4.2.3.
434
436
 
435
437
  P = re.compile(hint)
436
438
  p = re.compile(hint, re.I)
@@ -498,8 +500,10 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
498
500
  'C-S-f pressed' : (0, _F(self.set_mark)), # overrides mark
499
501
  'C-space pressed' : (0, _F(self.set_mark)),
500
502
  'C-S-space pressed' : (0, _F(self.set_pointer)),
501
- 'C-backspace pressed' : (0, skip),
503
+ 'C-backspace pressed' : (0, _F(self.backward_kill_word)),
502
504
  'S-backspace pressed' : (0, _F(self.backward_kill_line)),
505
+ 'C-delete pressed' : (0, _F(self.kill_word)),
506
+ 'S-delete pressed' : (0, _F(self.kill_line)),
503
507
  'C-tab pressed' : (0, _F(self.insert_space_like_tab)),
504
508
  'C-S-tab pressed' : (0, _F(self.delete_backward_space_like_tab)),
505
509
  'tab pressed' : (0, self.on_indent_line),
@@ -564,7 +568,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
564
568
  self.AutoCompSetMaxHeight(10)
565
569
 
566
570
  ## To prevent @filling crash (Never access to DropTarget)
567
- ## [BUG 4.1.1] Don't allow DnD of text, file, whatever.
571
+ ## [BUG ver 4.1.1] Don't allow DnD of text, file, whatever.
568
572
  ## self.SetDropTarget(None)
569
573
 
570
574
  self.Bind(stc.EVT_STC_START_DRAG, self.OnDrag)
@@ -912,15 +916,15 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
912
916
  def expr_at_caret(self):
913
917
  """A syntax unit (expression) at the caret-line."""
914
918
  p = q = self.cpos
915
- lsty = self.get_style(p-1)
916
- rsty = self.get_style(p)
917
- if lsty == rsty == 'moji': # inside string
919
+ lst = self.get_style(p-1)
920
+ rst = self.get_style(p)
921
+ if lst == rst == 'moji': # inside string
918
922
  ## styles = {'moji'}
919
923
  return ''
920
- elif lsty == 'suji' or rsty == 'suji':
924
+ elif lst == 'suji' or rst == 'suji':
921
925
  styles = {'suji'}
922
- elif lsty in ('word', 'dot', 'moji', 'rparen')\
923
- or rsty in ('word', 'dot', 'moji', 'lparen'):
926
+ elif lst in ('word', 'dot', 'moji', 'rparen')\
927
+ or rst in ('word', 'dot', 'moji', 'lparen'):
924
928
  styles = {'word', 'dot', 'moji', 'paren'}
925
929
  else:
926
930
  return ''
@@ -970,7 +974,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
970
974
  else:
971
975
  self.py_outdent_line()
972
976
 
973
- @can_edit
977
+ @editable
974
978
  def py_indent_line(self):
975
979
  """Indent the current line."""
976
980
  text = self.line_at_caret # w/ no-prompt
@@ -982,7 +986,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
982
986
  self.Replace(self.bol, p, ' '*indent)
983
987
  self.goto_char(self.bol + indent + offset)
984
988
 
985
- @can_edit
989
+ @editable
986
990
  def py_outdent_line(self):
987
991
  """Outdent the current line."""
988
992
  text = self.line_at_caret # w/ no-prompt
@@ -1006,7 +1010,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1006
1010
 
1007
1011
  def py_electric_indent(self):
1008
1012
  """Calculate indent spaces for the following line."""
1009
- ## [BUG 4.2.0] The last char is replaced with b'\x00'.
1013
+ ## [BUG ver 4.2.0] The last char is replaced with b'\x00'.
1010
1014
  ## text, lp = self.CurLineRaw
1011
1015
  ## return self.py_calc_indentation(text[:lp].decode())
1012
1016
  text, lp = self.CurLine
@@ -1605,7 +1609,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1605
1609
  ## --------------------------------
1606
1610
  comment_prefix = "## "
1607
1611
 
1608
- @can_edit
1612
+ @editable
1609
1613
  def comment_out_selection(self, from_=None, to_=None):
1610
1614
  """Comment out the selected text."""
1611
1615
  if from_ is not None: self.anchor = from_
@@ -1619,7 +1623,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1619
1623
  text = text[:-len(prefix)]
1620
1624
  self.ReplaceSelection(text)
1621
1625
 
1622
- @can_edit
1626
+ @editable
1623
1627
  def uncomment_selection(self, from_=None, to_=None):
1624
1628
  """Uncomment the selected text."""
1625
1629
  if from_ is not None: self.anchor = from_
@@ -1629,7 +1633,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1629
1633
  if text != self.SelectedText:
1630
1634
  self.ReplaceSelection(text)
1631
1635
 
1632
- @can_edit
1636
+ @editable
1633
1637
  def comment_out_line(self):
1634
1638
  if self.SelectedText:
1635
1639
  self.comment_out_selection()
@@ -1645,7 +1649,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1645
1649
  self.comment_out_selection(self.cpos, self.eol)
1646
1650
  self.LineDown()
1647
1651
 
1648
- @can_edit
1652
+ @editable
1649
1653
  def uncomment_line(self):
1650
1654
  if self.SelectedText:
1651
1655
  self.uncomment_selection()
@@ -1654,35 +1658,49 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1654
1658
  self.uncomment_selection(self.cpos, self.eol)
1655
1659
  self.LineDown()
1656
1660
 
1657
- @can_edit
1661
+ @editable
1658
1662
  def eat_white_forward(self):
1659
1663
  p = self.cpos
1660
1664
  self.skip_chars_forward(' \t')
1661
1665
  self.Replace(p, self.cpos, '')
1662
1666
 
1663
- @can_edit
1667
+ @editable
1664
1668
  def eat_white_backward(self):
1665
1669
  p = self.cpos
1666
1670
  self.skip_chars_backward(' \t')
1667
1671
  self.Replace(max(self.cpos, self.bol), p, '')
1668
1672
 
1669
- @can_edit
1673
+ @editable
1674
+ def kill_word(self):
1675
+ if not self.SelectedText:
1676
+ self.WordRightEndExtend()
1677
+ self.ReplaceSelection('')
1678
+
1679
+ @editable
1680
+ def backward_kill_word(self):
1681
+ if not self.SelectedText:
1682
+ self.WordLeftExtend()
1683
+ self.ReplaceSelection('')
1684
+
1685
+ @editable
1670
1686
  def kill_line(self):
1671
- p = self.eol
1672
- if p == self.cpos: # caret at end of line
1673
- if self.get_char(p) == '\r': p += 1
1674
- if self.get_char(p) == '\n': p += 1
1675
- self.Replace(self.cpos, p, '')
1687
+ if not self.SelectedText:
1688
+ if self.cpos == self.eol:
1689
+ self.WordRightEndExtend() # Select cr/lf
1690
+ else:
1691
+ self.cpos = self.eol
1692
+ self.ReplaceSelection('')
1676
1693
 
1677
- @can_edit
1694
+ @editable
1678
1695
  def backward_kill_line(self):
1679
- p = self.bol
1680
- if p == self.cpos > 0: # caret at beginning of line
1681
- if self.get_char(p-1) == '\n': p -= 1
1682
- if self.get_char(p-1) == '\r': p -= 1
1683
- self.Replace(p, self.cpos, '')
1696
+ if not self.SelectedText:
1697
+ if self.cpos == self.bol:
1698
+ self.WordLeftExtend() # Select cr/lf
1699
+ else:
1700
+ self.cpos = self.bol
1701
+ self.ReplaceSelection('')
1684
1702
 
1685
- @can_edit
1703
+ @editable
1686
1704
  def insert_space_like_tab(self):
1687
1705
  """Insert half-width spaces forward as if feeling like [tab].
1688
1706
  タブの気持ちになって半角スペースを入力する
@@ -1691,7 +1709,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1691
1709
  _text, lp = self.CurLine
1692
1710
  self.WriteText(' ' * (4 - lp % 4))
1693
1711
 
1694
- @can_edit
1712
+ @editable
1695
1713
  def delete_backward_space_like_tab(self):
1696
1714
  """Delete half-width spaces backward as if feeling like [S-tab].
1697
1715
  シフト+タブの気持ちになって半角スペースを消す
@@ -1833,7 +1851,7 @@ class Buffer(EditorInterface, EditWindow):
1833
1851
  ## *do not* clear autocomp, so that the event can skip to AutoComp properly.
1834
1852
  if self.CanEdit():
1835
1853
  with self.off_undocollection():
1836
- self.ReplaceSelection("")
1854
+ self.ReplaceSelection('')
1837
1855
  self.message("")
1838
1856
 
1839
1857
  def clear_autocomp(evt):
@@ -1874,6 +1892,8 @@ class Buffer(EditorInterface, EditWindow):
1874
1892
  'escape pressed' : (-1, self.on_enter_escmap),
1875
1893
  'C-h pressed' : (0, self.call_helpTip),
1876
1894
  '. pressed' : (2, self.OnEnterDot),
1895
+ 'C-. pressed' : (2, self.call_word_autocomp),
1896
+ 'C-/ pressed' : (3, self.call_apropos_autocomp),
1877
1897
  'M-. pressed' : (2, self.call_word_autocomp),
1878
1898
  'M-/ pressed' : (3, self.call_apropos_autocomp),
1879
1899
  },
@@ -1967,7 +1987,7 @@ class Buffer(EditorInterface, EditWindow):
1967
1987
  return
1968
1988
 
1969
1989
  pos = evt.Position
1970
- self.goto_char(pos) # Clear selection
1990
+ self.goto_char(pos)
1971
1991
  i = 2
1972
1992
  if self.IndicatorValueAt(i, pos): # [C-indic click]
1973
1993
  p = self.IndicatorStart(i, pos)
@@ -1998,9 +2018,9 @@ class Buffer(EditorInterface, EditWindow):
1998
2018
 
1999
2019
  def OnEnterDot(self, evt):
2000
2020
  p = self.cpos
2001
- st = self.get_style(p-1)
2021
+ lst = self.get_style(p-1)
2002
2022
  rst = self.get_style(p)
2003
- if st not in ('moji', 'word', 'rparen') or rst == 'word':
2023
+ if lst not in ('moji', 'word', 'rparen') or rst == 'word':
2004
2024
  self.handler('quit', evt) # don't enter autocomp
2005
2025
  evt.Skip()
2006
2026
 
@@ -2657,14 +2677,14 @@ class Nautilus(EditorInterface, Shell):
2657
2677
  C-up : [0] retrieve previous history
2658
2678
  C-down : [0] retrieve next history
2659
2679
  C-j : [0] tooltip of eval (for the selected or focused word)
2660
- C-h, M-h : [0] calltip of help (for the selected or focused func)
2680
+ C-h M-h : [0] calltip of help (for the selected or focused func)
2661
2681
  TAB : [1] history-comp
2662
2682
  M-p : [1] retrieve previous history in history-comp mode
2663
2683
  M-n : [1] retrieve next history in history-comp mode
2664
- M-. : [2] word-comp
2665
- M-/ : [3] apropos-comp
2666
- M-, : [4] text-comp
2667
- M-m : [5] module-comp
2684
+ M-. C-. : [2] word-comp
2685
+ M-/ C-/ : [3] apropos-comp
2686
+ M-, C-, : [4] text-comp
2687
+ M-m C-m : [5] module-comp
2668
2688
 
2669
2689
  Autocomps are incremental when pressed any alnums,
2670
2690
  and decremental when backspace.
@@ -2784,7 +2804,7 @@ class Nautilus(EditorInterface, Shell):
2784
2804
  ## *do not* clear autocomp, so that the event can skip to AutoComp properly.
2785
2805
  if self.CanEdit():
2786
2806
  with self.off_undocollection():
2787
- self.ReplaceSelection("")
2807
+ self.ReplaceSelection('')
2788
2808
  self.message("")
2789
2809
 
2790
2810
  def clear_autocomp(evt):
@@ -2827,8 +2847,6 @@ class Nautilus(EditorInterface, Shell):
2827
2847
  'escape pressed' : (-1, self.on_enter_escmap),
2828
2848
  'space pressed' : (0, self.OnSpace),
2829
2849
  '*backspace pressed' : (0, self.OnBackspace),
2830
- 'C-backspace pressed' : (0, _F(self.backward_kill_word)),
2831
- 'S-backspace pressed' : (0, _F(self.backward_kill_line)),
2832
2850
  'enter pressed' : (0, self.OnEnter),
2833
2851
  'C-enter pressed' : (0, _F(self.insertLineBreak)),
2834
2852
  'C-S-enter pressed' : (0, _F(self.insertLineBreak)),
@@ -2853,6 +2871,10 @@ class Nautilus(EditorInterface, Shell):
2853
2871
  'tab pressed' : (1, self.call_history_comp),
2854
2872
  'M-p pressed' : (1, self.call_history_comp),
2855
2873
  'M-n pressed' : (1, self.call_history_comp),
2874
+ 'C-. pressed' : (2, self.call_word_autocomp),
2875
+ 'C-/ pressed' : (3, self.call_apropos_autocomp),
2876
+ 'C-, pressed' : (4, self.call_text_autocomp),
2877
+ 'C-m pressed' : (5, self.call_module_autocomp),
2856
2878
  'M-. pressed' : (2, self.call_word_autocomp),
2857
2879
  'M-/ pressed' : (3, self.call_apropos_autocomp),
2858
2880
  'M-, pressed' : (4, self.call_text_autocomp),
@@ -3059,29 +3081,36 @@ class Nautilus(EditorInterface, Shell):
3059
3081
  return
3060
3082
  evt.Skip()
3061
3083
 
3062
- @can_edit
3063
- def backward_kill_line(self):
3064
- p = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
3065
- text, lp = self.CurLine
3066
- if text[:lp] == sys.ps2:
3067
- self.Replace(p - lp, p, '') # eats ps2:prompt
3068
- return
3069
- if p == self.cpos > 0: # caret at beginning of line
3070
- if self.get_char(p-1) == '\n': p -= 1
3071
- if self.get_char(p-1) == '\r': p -= 1
3072
- self.Replace(p, self.cpos, '')
3084
+ @editable
3085
+ def backward_kill_word(self): # (override)
3086
+ if not self.SelectedText:
3087
+ text, lp = self.CurLine
3088
+ if text[:lp] == sys.ps2:
3089
+ self.cpos -= lp # Select ps2:prompt
3090
+ self.WordLeftExtend() # Select cr/lf
3091
+ else:
3092
+ q = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
3093
+ self.WordLeftExtend()
3094
+ if self.cpos < q:
3095
+ self.cpos = q # Don't skip back prompt
3096
+ self.ReplaceSelection('')
3073
3097
 
3074
- @can_edit
3075
- def backward_kill_word(self):
3076
- p = self.cpos
3077
- text, lp = self.CurLine
3078
- if text[:lp] == sys.ps2:
3079
- self.goto_char(p - lp) # skips ps2:prompt
3080
- self.WordLeft()
3081
- q = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
3082
- if self.cpos < q:
3083
- self.goto_char(q) # Don't skip back prompt
3084
- self.Replace(self.cpos, p, '')
3098
+ @editable
3099
+ def backward_kill_line(self): # (override)
3100
+ if not self.SelectedText:
3101
+ text, lp = self.CurLine
3102
+ if text[:lp] == sys.ps2:
3103
+ self.cpos -= lp # Select ps2:prompt
3104
+ self.WordLeftExtend() # Select cr/lf
3105
+ else:
3106
+ q = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
3107
+ if self.cpos <= self.bolc:
3108
+ return
3109
+ elif self.cpos > q:
3110
+ self.cpos = q
3111
+ else:
3112
+ self.WordLeftExtend() # Select cr/lf
3113
+ self.ReplaceSelection('')
3085
3114
 
3086
3115
  def OnEnter(self, evt):
3087
3116
  """Called when enter pressed."""
@@ -3119,13 +3148,13 @@ class Nautilus(EditorInterface, Shell):
3119
3148
  self.handler('quit', evt)
3120
3149
  return
3121
3150
  p = self.cpos
3122
- st = self.get_style(p-1)
3151
+ lst = self.get_style(p-1)
3123
3152
  rst = self.get_style(p)
3124
3153
  if p == self.bolc:
3125
3154
  self.ReplaceSelection('self') # replace [.] --> [self.]
3126
- elif st in ('space', 'sep', 'lparen'):
3155
+ elif lst in ('space', 'sep', 'lparen'):
3127
3156
  self.ReplaceSelection('self')
3128
- elif st not in ('moji', 'word', 'rparen') or rst == 'word':
3157
+ elif lst not in ('moji', 'word', 'rparen') or rst == 'word':
3129
3158
  self.handler('quit', evt) # don't enter autocomp
3130
3159
  evt.Skip()
3131
3160
 
@@ -3363,7 +3392,7 @@ class Nautilus(EditorInterface, Shell):
3363
3392
 
3364
3393
  ## cf. getCommand() -> caret-line that starts with a prompt
3365
3394
  ## cf. getMultilineCommand() -> caret-multi-line that starts with a prompt
3366
- ## [BUG 4.1.1] Don't use for current prompt --> Fixed in 4.2.0.
3395
+ ## [BUG ver 4.1.1] Don't use for current prompt --> Fixed in wx ver 4.2.0.
3367
3396
 
3368
3397
  def getMultilineCommand(self, rstrip=True):
3369
3398
  """Extract a multi-line command which starts with a prompt.
@@ -3466,7 +3495,7 @@ class Nautilus(EditorInterface, Shell):
3466
3495
 
3467
3496
  (override) Remove ps1 and ps2 from the multi-line command to paste.
3468
3497
  Add offset in paste-rectangle mode.
3469
- Don't relplace the last crlf to ps.
3498
+ Don't relplace the last cr/lf to ps.
3470
3499
  """
3471
3500
  if self.CanPaste() and wx.TheClipboard.Open():
3472
3501
  data = wx.TextDataObject()
@@ -1,12 +1,11 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: mwxlib
3
- Version: 1.4.6
3
+ Version: 1.4.11
4
4
  Summary: A wrapper of matplotlib and wxPython (phoenix)
5
5
  Home-page: https://github.com/komoto48g/mwxlib
6
6
  Author: Kazuya O'moto
7
7
  Author-email: komoto@jeol.co.jp
8
8
  License: MIT
9
- Classifier: License :: OSI Approved :: MIT License
10
9
  Classifier: Programming Language :: Python :: 3
11
10
  Classifier: Programming Language :: Python :: 3.8
12
11
  Classifier: Programming Language :: Python :: 3.9
@@ -1,14 +1,14 @@
1
1
  mwx/__init__.py,sha256=pS7ZG8QKRypiFFiaWAq_opBB6I_1viZ0zUMk2TbjzE0,667
2
2
  mwx/bookshelf.py,sha256=MXjrm_ryRGHvOFKu8wb10qz_oka70xW2yFbYjBMYfns,8140
3
- mwx/controls.py,sha256=RssTROprNfgnRMiWVOoSSd8Fy0qwZ8DCrYM2f5Wgr4E,48610
4
- mwx/framework.py,sha256=hP2mhnYPOrSVFvA3CgoOR9-axWx_WLd83aXioUHodEk,76830
5
- mwx/graphman.py,sha256=_8_DaG3qhhZByoh5wboyYQlAsm7GlPoR8wT-RNMx4Cw,70627
6
- mwx/images.py,sha256=oxCn0P-emiWujSS2gUgU5TUnr5cPjix2jBcjOBDr24I,48701
7
- mwx/matplot2.py,sha256=Htwegq6N5G7oKSRCuajik5Dixd93i8PKVbkL7Azy99M,33150
8
- mwx/matplot2g.py,sha256=4BBHlvfhg1796hu1nTCsTA82YRkZhwUnfcHCBf5ZGO8,65083
3
+ mwx/controls.py,sha256=1zLWlPy0RTLHYlvxjz3ulDoTx3-uPUD3TqK7dGRA4wg,49563
4
+ mwx/framework.py,sha256=1p24_snigDnU-9CwjQJdQeEsS44z27IwvC67reS6zX8,76832
5
+ mwx/graphman.py,sha256=4hS3zBH1Ob9CcsWBsnPo5Tw6RTiE0vKjKpcjeZ5RSrU,70049
6
+ mwx/images.py,sha256=Kkfy9QI_hMtwShSjUS4-ZpC_EkVuah_XhpBOR4wAKkM,49792
7
+ mwx/matplot2.py,sha256=A2PbHI5UcuAvINfnm6GG7CXpbexhzvtyVLQOwcbRqnc,33015
8
+ mwx/matplot2g.py,sha256=HTSh0vd06-HhiwEZbhwFD6HGjfnwGQ7H6QQzTucOx3c,65220
9
9
  mwx/matplot2lg.py,sha256=cb0EZXivccDQu4oFj5ddSUF9pEE4f5UuFJJK2ELItww,27404
10
10
  mwx/mgplt.py,sha256=8mXbHpCmm7lz3XbAxOg7IVC7DaSGBEby1UfTlMl9kjk,5604
11
- mwx/nutshell.py,sha256=TNaZbMQcvSKDSHDnw3P8rpMM2yNG0HbVOej52L0EZgY,141903
11
+ mwx/nutshell.py,sha256=aZSXcWMsVF_til2ZCASwGwK1Jqq3qfGFJ6KJjK7TX6A,143091
12
12
  mwx/testsuite.py,sha256=Zk75onPSEn2tf0swS3l-vIn6yTXGB7allIyvJsPHj20,1229
13
13
  mwx/utilus.py,sha256=ObXYWsDVn5DmjvwVQgP2HGAhrdxlDrwL7g9pMCDbU7U,38127
14
14
  mwx/wxmon.py,sha256=yzWqrbY6LzpfRwQeytYUeqFhFuLVm_XEvrVAL_k0HBQ,12756
@@ -22,7 +22,7 @@ mwx/plugins/frame_listview.py,sha256=gowjQ-ARNonMkDSXkQgPKq4U9YBJ-vQ0jK2krBVOdCs
22
22
  mwx/plugins/line_profile.py,sha256=zzm6_7lnAnNepLbh07ordp3nRWDFQJtu719ZVjrVf8s,819
23
23
  mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
24
24
  mwx/py/filling.py,sha256=fumUG1F5M9TL-Dfqni4G85uk7TmvnUunTbdcPDV0vfo,16857
25
- mwxlib-1.4.6.dist-info/METADATA,sha256=hqiNPf-eNSU1H6H5huSCCToKcRvpXYWipmwzJc1r_xw,7433
26
- mwxlib-1.4.6.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
27
- mwxlib-1.4.6.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
- mwxlib-1.4.6.dist-info/RECORD,,
25
+ mwxlib-1.4.11.dist-info/METADATA,sha256=IZXZTnCIPRB-B1eTwiGW6uD5IYtlmaNzMdgOs89Qpko,7382
26
+ mwxlib-1.4.11.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
27
+ mwxlib-1.4.11.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
+ mwxlib-1.4.11.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.0.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5