mwxlib 1.4.15__py3-none-any.whl → 1.5.0__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 +2 -1
- mwx/framework.py +46 -46
- mwx/graphman.py +26 -40
- mwx/matplot2.py +2 -2
- mwx/matplot2g.py +1 -1
- mwx/mgplt.py +2 -4
- mwx/nutshell.py +122 -54
- mwx/plugins/ffmpeg_view.py +5 -7
- mwx/plugins/frame_listview.py +2 -4
- mwx/utilus.py +17 -2
- mwx/wxmon.py +2 -1
- mwx/wxpdb.py +0 -2
- mwx/wxwit.py +11 -14
- {mwxlib-1.4.15.dist-info → mwxlib-1.5.0.dist-info}/METADATA +1 -1
- mwxlib-1.5.0.dist-info/RECORD +28 -0
- {mwxlib-1.4.15.dist-info → mwxlib-1.5.0.dist-info}/WHEEL +1 -1
- mwxlib-1.4.15.dist-info/RECORD +0 -28
- {mwxlib-1.4.15.dist-info → mwxlib-1.5.0.dist-info}/top_level.txt +0 -0
mwx/controls.py
CHANGED
|
@@ -14,7 +14,7 @@ from .utilus import funcall as _F
|
|
|
14
14
|
from .framework import pack, Menu, CtrlInterface
|
|
15
15
|
|
|
16
16
|
import numpy as np
|
|
17
|
-
from numpy import nan, inf # noqa
|
|
17
|
+
from numpy import nan, inf # noqa # necessary to eval
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def _Tip(*tips):
|
|
@@ -1035,6 +1035,7 @@ class Button(pb.PlateButton):
|
|
|
1035
1035
|
|
|
1036
1036
|
def SetBitmap(self, bmp):
|
|
1037
1037
|
"""Set the bitmap displayed in the button.
|
|
1038
|
+
|
|
1038
1039
|
(override) If it fails, it clears the bitmap.
|
|
1039
1040
|
"""
|
|
1040
1041
|
try:
|
mwx/framework.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#! python3
|
|
2
2
|
"""mwxlib framework.
|
|
3
3
|
"""
|
|
4
|
-
__version__ = "1.
|
|
4
|
+
__version__ = "1.5.0"
|
|
5
5
|
__author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
|
|
6
6
|
|
|
7
7
|
from contextlib import contextmanager
|
|
@@ -49,7 +49,7 @@ def deb(target=None, loop=True, locals=None, **kwargs):
|
|
|
49
49
|
kwargs.setdefault("execStartupScript", True)
|
|
50
50
|
kwargs.setdefault("ensureClose", True)
|
|
51
51
|
|
|
52
|
-
if "debrc" in kwargs:
|
|
52
|
+
if "debrc" in kwargs: # for backward compatibility
|
|
53
53
|
warn("Deprecated keyword: 'debrc'. Use 'session' instead.", DeprecationWarning)
|
|
54
54
|
kwargs.setdefault('session', kwargs.pop('debrc'))
|
|
55
55
|
|
|
@@ -618,8 +618,9 @@ class Menu(wx.Menu):
|
|
|
618
618
|
def Destroy(self):
|
|
619
619
|
try:
|
|
620
620
|
self._unbind()
|
|
621
|
-
|
|
622
|
-
|
|
621
|
+
except Exception:
|
|
622
|
+
pass
|
|
623
|
+
return wx.Menu.Destroy(self)
|
|
623
624
|
|
|
624
625
|
@staticmethod
|
|
625
626
|
def Popup(parent, menulist, *args, **kwargs):
|
|
@@ -795,11 +796,9 @@ class Frame(wx.Frame, KeyCtrlInterfaceMixin):
|
|
|
795
796
|
"About this software")
|
|
796
797
|
|
|
797
798
|
def Destroy(self):
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
finally:
|
|
802
|
-
return wx.Frame.Destroy(self)
|
|
799
|
+
self.timer.Stop()
|
|
800
|
+
self.shellframe.Destroy() # shellframe is not my child
|
|
801
|
+
return wx.Frame.Destroy(self)
|
|
803
802
|
|
|
804
803
|
|
|
805
804
|
class MiniFrame(wx.MiniFrame, KeyCtrlInterfaceMixin):
|
|
@@ -1255,9 +1254,9 @@ class ShellFrame(MiniFrame):
|
|
|
1255
1254
|
'* released' : (0, fork_debugger),
|
|
1256
1255
|
'C-g pressed' : (0, self.Quit, fork_debugger),
|
|
1257
1256
|
'f1 pressed' : (0, self.About),
|
|
1258
|
-
'C-f pressed' : (0, self.
|
|
1259
|
-
'f3 pressed' : (0, self.
|
|
1260
|
-
'S-f3 pressed' : (0, self.
|
|
1257
|
+
'C-f pressed' : (0, self.on_search_dialog),
|
|
1258
|
+
'f3 pressed' : (0, self.repeat_forward_search),
|
|
1259
|
+
'S-f3 pressed' : (0, self.repeat_backward_search),
|
|
1261
1260
|
'f11 pressed' : (0, _F(self.toggle_window, win=self.ghost, alias='toggle_ghost')),
|
|
1262
1261
|
'S-f11 pressed' : (0, _F(self.toggle_window, win=self.watcher, alias='toggle_watcher')),
|
|
1263
1262
|
'f12 pressed' : (0, _F(self.Close, alias="close")),
|
|
@@ -1413,12 +1412,11 @@ class ShellFrame(MiniFrame):
|
|
|
1413
1412
|
del builtins.highlight
|
|
1414
1413
|
except AttributeError:
|
|
1415
1414
|
pass
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
return MiniFrame.Destroy(self)
|
|
1415
|
+
|
|
1416
|
+
self.timer.Stop()
|
|
1417
|
+
self.save_session()
|
|
1418
|
+
self._mgr.UnInit()
|
|
1419
|
+
return MiniFrame.Destroy(self)
|
|
1422
1420
|
|
|
1423
1421
|
def OnClose(self, evt):
|
|
1424
1422
|
if self.debugger.busy:
|
|
@@ -1493,24 +1491,16 @@ class ShellFrame(MiniFrame):
|
|
|
1493
1491
|
evt.Skip()
|
|
1494
1492
|
|
|
1495
1493
|
def OnShow(self, evt):
|
|
1496
|
-
pane
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
self.inspector.watch()
|
|
1500
|
-
self.monitor.watch()
|
|
1501
|
-
else:
|
|
1502
|
-
if pane.IsDocked():
|
|
1503
|
-
self.inspector.unwatch()
|
|
1504
|
-
self.monitor.unwatch()
|
|
1494
|
+
for pane in self._mgr.GetAllPanes():
|
|
1495
|
+
## When the window is hidden, disable docking and keep child panes floating.
|
|
1496
|
+
pane.Dockable(evt.IsShown() or pane.IsDocked())
|
|
1505
1497
|
evt.Skip()
|
|
1506
1498
|
|
|
1507
1499
|
def OnGhostShow(self, evt):
|
|
1508
1500
|
if evt.IsShown():
|
|
1509
1501
|
self.inspector.watch()
|
|
1510
|
-
self.monitor.watch()
|
|
1511
1502
|
else:
|
|
1512
1503
|
self.inspector.unwatch()
|
|
1513
|
-
self.monitor.unwatch()
|
|
1514
1504
|
evt.Skip()
|
|
1515
1505
|
|
|
1516
1506
|
def OnConsolePageChanged(self, evt): #<wx._aui.AuiNotebookEvent>
|
|
@@ -1610,6 +1600,7 @@ class ShellFrame(MiniFrame):
|
|
|
1610
1600
|
|
|
1611
1601
|
def Quit(self, evt=None):
|
|
1612
1602
|
"""Stop debugger and monitor."""
|
|
1603
|
+
self.monitor.unwatch()
|
|
1613
1604
|
self.debugger.unwatch()
|
|
1614
1605
|
self.debugger.send_input('\n') # terminates the reader of threading pdb
|
|
1615
1606
|
shell = self.debugger.interactive_shell # reset interp locals
|
|
@@ -1951,13 +1942,13 @@ class ShellFrame(MiniFrame):
|
|
|
1951
1942
|
return next((x for x in self.get_all_editors() if x.IsShown()), self.Scratch)
|
|
1952
1943
|
|
|
1953
1944
|
## --------------------------------
|
|
1954
|
-
## Find text dialog
|
|
1945
|
+
## Find / Replace text dialog
|
|
1955
1946
|
## --------------------------------
|
|
1956
1947
|
## *** The following code is a modification of <wx.py.frame.Frame> ***
|
|
1957
1948
|
|
|
1958
1949
|
__find_target = None
|
|
1959
1950
|
|
|
1960
|
-
def
|
|
1951
|
+
def on_search_dialog(self, evt):
|
|
1961
1952
|
if self.findDlg is not None:
|
|
1962
1953
|
self.findDlg.SetFocus()
|
|
1963
1954
|
return
|
|
@@ -1967,29 +1958,38 @@ class ShellFrame(MiniFrame):
|
|
|
1967
1958
|
return
|
|
1968
1959
|
self.__find_target = wnd
|
|
1969
1960
|
self.findData.FindString = wnd.topic_at_caret
|
|
1970
|
-
self.
|
|
1971
|
-
|
|
1961
|
+
self.findData.Flags |= wx.FR_DOWN
|
|
1962
|
+
self.findDlg = wx.FindReplaceDialog(wnd, self.findData, "Find")
|
|
1972
1963
|
self.findDlg.Show()
|
|
1973
1964
|
|
|
1974
|
-
def
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1965
|
+
def repeat_forward_search(self, evt):
|
|
1966
|
+
self.OnFindNext(evt, direction=True)
|
|
1967
|
+
|
|
1968
|
+
def repeat_backward_search(self, evt):
|
|
1969
|
+
self.OnFindNext(evt, direction=False)
|
|
1970
|
+
|
|
1971
|
+
def OnFindNext(self, evt, direction=None): #<wx._core.FindDialogEvent>
|
|
1972
|
+
if not self.findData.FindString:
|
|
1973
|
+
self.message("No last search.")
|
|
1974
|
+
return
|
|
1975
|
+
|
|
1976
|
+
if direction is not None:
|
|
1977
|
+
## dir = self.findData.Flags & wx.FR_DOWN # 0:up, 1:down
|
|
1978
|
+
## if direction != dir:
|
|
1979
|
+
## self.findData.Flags ^= wx.FR_DOWN # toggle up/down flag
|
|
1980
|
+
if direction:
|
|
1981
|
+
self.findData.Flags |= wx.FR_DOWN
|
|
1982
|
+
else:
|
|
1983
|
+
self.findData.Flags &= ~wx.FR_DOWN
|
|
1979
1984
|
|
|
1980
1985
|
wnd = wx.Window.FindFocus()
|
|
1981
1986
|
if not isinstance(wnd, stc.StyledTextCtrl):
|
|
1982
1987
|
wnd = self.__find_target
|
|
1983
1988
|
if not wnd:
|
|
1984
1989
|
return
|
|
1985
|
-
wnd.DoFindNext(
|
|
1990
|
+
wnd.DoFindNext(self.findData, self.findDlg or wnd)
|
|
1986
1991
|
if self.findDlg:
|
|
1987
1992
|
self.OnFindClose(None)
|
|
1988
|
-
wnd.EnsureVisible(wnd.cline)
|
|
1989
|
-
wnd.ensureLineMoreOnScreen(wnd.cline)
|
|
1990
|
-
|
|
1991
|
-
def OnFindPrev(self, evt):
|
|
1992
|
-
self.OnFindNext(evt, backward=True)
|
|
1993
1993
|
|
|
1994
1994
|
def OnFindClose(self, evt): #<wx._core.FindDialogEvent>
|
|
1995
1995
|
self.findDlg.Destroy()
|
|
@@ -2003,7 +2003,7 @@ def filling(obj=None, **kwargs):
|
|
|
2003
2003
|
rootLabel=typename(obj),
|
|
2004
2004
|
pos=wx.GetMousePosition(),
|
|
2005
2005
|
**kwargs)
|
|
2006
|
-
frame.filling.text.WrapMode = 0
|
|
2007
|
-
frame.filling.text.Zoom = -1
|
|
2006
|
+
frame.filling.text.WrapMode = 0 # no wrap
|
|
2007
|
+
frame.filling.text.Zoom = -1 # zoom level of size of fonts
|
|
2008
2008
|
frame.Show()
|
|
2009
2009
|
return frame
|
mwx/graphman.py
CHANGED
|
@@ -30,10 +30,10 @@ from .utilus import funcall as _F
|
|
|
30
30
|
from .controls import KnobCtrlPanel, Icon
|
|
31
31
|
from .framework import CtrlInterface, AuiNotebook, Menu, FSM
|
|
32
32
|
|
|
33
|
-
from .matplot2 import MatplotPanel
|
|
33
|
+
from .matplot2 import MatplotPanel # noqa
|
|
34
34
|
from .matplot2g import GraphPlot
|
|
35
|
-
from .matplot2lg import LinePlot
|
|
36
|
-
from .matplot2lg import LineProfile
|
|
35
|
+
from .matplot2lg import LinePlot # noqa
|
|
36
|
+
from .matplot2lg import LineProfile # noqa
|
|
37
37
|
from .matplot2lg import Histogram
|
|
38
38
|
|
|
39
39
|
|
|
@@ -100,8 +100,6 @@ class Thread:
|
|
|
100
100
|
None : {
|
|
101
101
|
'thread_begin' : [ None ], # begin processing
|
|
102
102
|
'thread_end' : [ None ], # end processing
|
|
103
|
-
'thread_quit' : [ None ], # terminated by user
|
|
104
|
-
'thread_error' : [ None ], # failed in error
|
|
105
103
|
},
|
|
106
104
|
})
|
|
107
105
|
|
|
@@ -117,7 +115,6 @@ class Thread:
|
|
|
117
115
|
frame = inspect.currentframe().f_back.f_back
|
|
118
116
|
filename = frame.f_code.co_filename
|
|
119
117
|
name = frame.f_code.co_name
|
|
120
|
-
fname, _ = os.path.splitext(os.path.basename(filename))
|
|
121
118
|
|
|
122
119
|
## Other threads are not allowed to enter.
|
|
123
120
|
ct = threading.current_thread()
|
|
@@ -125,17 +122,18 @@ class Thread:
|
|
|
125
122
|
|
|
126
123
|
## The thread must be activated to enter.
|
|
127
124
|
## assert self.active, f"{self!r} must be activated to enter {name!r}."
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
125
|
+
yield self
|
|
126
|
+
|
|
127
|
+
def enters(self, f):
|
|
128
|
+
"""Decorator to register a one-time handler for the enter event."""
|
|
129
|
+
return self.handler.binds('thread_begin', f)
|
|
130
|
+
|
|
131
|
+
def exits(self, f):
|
|
132
|
+
"""Decorator to register a one-time handler for the exit event."""
|
|
133
|
+
return self.handler.binds('thread_end', f)
|
|
136
134
|
|
|
137
135
|
def wraps(self, f, *args, **kwargs):
|
|
138
|
-
"""Decorator
|
|
136
|
+
"""Decorator for a function that starts a new thread."""
|
|
139
137
|
@wraps(f)
|
|
140
138
|
def _f(*v, **kw):
|
|
141
139
|
return self.Start(f, *v, *args, **kw, **kwargs)
|
|
@@ -186,21 +184,20 @@ class Thread:
|
|
|
186
184
|
@wraps(f)
|
|
187
185
|
def _f(*v, **kw):
|
|
188
186
|
try:
|
|
189
|
-
self.handler
|
|
187
|
+
wx.CallAfter(self.handler, 'thread_begin', self)
|
|
190
188
|
self.result = f(*v, **kw)
|
|
191
189
|
except BdbQuit:
|
|
192
190
|
pass
|
|
193
191
|
except KeyboardInterrupt as e:
|
|
194
|
-
print("- Thread
|
|
195
|
-
|
|
196
|
-
print("- Thread execution failed:", e)
|
|
192
|
+
print("- Thread terminated by user:", e)
|
|
193
|
+
## wx.CallAfter(self.handler, 'thread_quit', self)
|
|
197
194
|
except Exception as e:
|
|
198
195
|
traceback.print_exc()
|
|
199
|
-
print("- Thread
|
|
200
|
-
self.handler
|
|
196
|
+
print("- Thread failed in error:", e)
|
|
197
|
+
## wx.CallAfter(self.handler, 'thread_error', self)
|
|
201
198
|
finally:
|
|
202
199
|
self.active = 0
|
|
203
|
-
self.handler
|
|
200
|
+
wx.CallAfter(self.handler, 'thread_end', self)
|
|
204
201
|
|
|
205
202
|
if self.running:
|
|
206
203
|
wx.MessageBox("The thread is running (Press [C-g] to quit).",
|
|
@@ -226,7 +223,6 @@ class Thread:
|
|
|
226
223
|
def _stop():
|
|
227
224
|
with wx.BusyInfo("One moment please, "
|
|
228
225
|
"waiting for threads to die..."):
|
|
229
|
-
self.handler('thread_quit', self)
|
|
230
226
|
self.worker.join(1)
|
|
231
227
|
if self.running:
|
|
232
228
|
self.active = 0
|
|
@@ -349,10 +345,6 @@ class LayerInterface(CtrlInterface):
|
|
|
349
345
|
|
|
350
346
|
self.handler.append({ # DNA<Layer>
|
|
351
347
|
None : {
|
|
352
|
-
'thread_begin' : [ None ], # begin processing
|
|
353
|
-
'thread_end' : [ None ], # end processing
|
|
354
|
-
'thread_quit' : [ None ], # terminated by user
|
|
355
|
-
'thread_error' : [ None ], # failed in error
|
|
356
348
|
'page_shown' : [ None, _F(self.Draw, show=True) ],
|
|
357
349
|
'page_closed' : [ None, _F(self.Draw, show=False) ],
|
|
358
350
|
'page_hidden' : [ None, _F(self.Draw, show=False) ],
|
|
@@ -898,8 +890,6 @@ class Frame(mwx.Frame):
|
|
|
898
890
|
evt.Skip()
|
|
899
891
|
|
|
900
892
|
def Destroy(self):
|
|
901
|
-
## for name in list(self.plugins):
|
|
902
|
-
## self.unload_plug(name) # => plug.Destroy
|
|
903
893
|
self._mgr.UnInit()
|
|
904
894
|
return mwx.Frame.Destroy(self)
|
|
905
895
|
|
|
@@ -1467,8 +1457,8 @@ class Frame(mwx.Frame):
|
|
|
1467
1457
|
@classmethod
|
|
1468
1458
|
def read_attributes(self, filename):
|
|
1469
1459
|
"""Read attributes file."""
|
|
1470
|
-
from numpy import nan, inf # noqa
|
|
1471
|
-
import datetime # noqa
|
|
1460
|
+
from numpy import nan, inf # noqa # necessary to eval
|
|
1461
|
+
import datetime # noqa # necessary to eval
|
|
1472
1462
|
try:
|
|
1473
1463
|
res = {}
|
|
1474
1464
|
mis = {}
|
|
@@ -1492,8 +1482,7 @@ class Frame(mwx.Frame):
|
|
|
1492
1482
|
except Exception as e:
|
|
1493
1483
|
print("- Failed to read attributes.", e)
|
|
1494
1484
|
wx.MessageBox(str(e), style=wx.ICON_ERROR)
|
|
1495
|
-
|
|
1496
|
-
return res, mis # finally raises no exception
|
|
1485
|
+
return res, mis
|
|
1497
1486
|
|
|
1498
1487
|
@classmethod
|
|
1499
1488
|
def write_attributes(self, filename, frames):
|
|
@@ -1504,7 +1493,6 @@ class Frame(mwx.Frame):
|
|
|
1504
1493
|
|
|
1505
1494
|
## `res` order may differ from that of given frames,
|
|
1506
1495
|
## so we take a few steps to merge `new` to be exported.
|
|
1507
|
-
|
|
1508
1496
|
res.update(new) # res updates to new info,
|
|
1509
1497
|
new.update(res) # copy res back keeping new order.
|
|
1510
1498
|
|
|
@@ -1514,8 +1502,7 @@ class Frame(mwx.Frame):
|
|
|
1514
1502
|
except Exception as e:
|
|
1515
1503
|
print("- Failed to write attributes.", e)
|
|
1516
1504
|
wx.MessageBox(str(e), style=wx.ICON_ERROR)
|
|
1517
|
-
|
|
1518
|
-
return new, mis # finally raises no exception
|
|
1505
|
+
return new, mis
|
|
1519
1506
|
|
|
1520
1507
|
def load_frame(self, paths=None, view=None):
|
|
1521
1508
|
"""Load frames from files to the view window.
|
|
@@ -1800,13 +1787,12 @@ class Frame(mwx.Frame):
|
|
|
1800
1787
|
o.write("self._mgr.LoadPerspective({!r})\n".format(self._mgr.SavePerspective()))
|
|
1801
1788
|
|
|
1802
1789
|
def _save(view):
|
|
1803
|
-
name = view.Name
|
|
1804
1790
|
paths = [x.pathname for x in view.all_frames if x.pathname]
|
|
1805
|
-
o.write(f"self.{
|
|
1806
|
-
o.write(f"self.load_frame({paths!r}, self.{
|
|
1791
|
+
o.write(f"self.{view.Name}.unit = {view.unit:g}\n")
|
|
1792
|
+
o.write(f"self.load_frame({paths!r}, self.{view.Name})\n")
|
|
1807
1793
|
try:
|
|
1808
1794
|
index = paths.index(view.frame.pathname)
|
|
1809
|
-
o.write(f"self.{
|
|
1795
|
+
o.write(f"self.{view.Name}.select({index})\n")
|
|
1810
1796
|
except Exception:
|
|
1811
1797
|
pass
|
|
1812
1798
|
|
mwx/matplot2.py
CHANGED
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
"""
|
|
4
4
|
import wx
|
|
5
5
|
|
|
6
|
-
import matplotlib; matplotlib.use('wxagg')
|
|
6
|
+
import matplotlib; matplotlib.use('wxagg') # noqa
|
|
7
7
|
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
|
|
8
8
|
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as Toolbar
|
|
9
9
|
from matplotlib.widgets import Cursor
|
|
10
10
|
from matplotlib.figure import Figure
|
|
11
|
-
from matplotlib import cm
|
|
12
11
|
import numpy as np
|
|
13
12
|
|
|
14
13
|
from . import framework as mwx
|
|
@@ -40,6 +39,7 @@ if 1:
|
|
|
40
39
|
class Cursor(Cursor):
|
|
41
40
|
def onmove(self, event):
|
|
42
41
|
"""Internal event handler to draw the cursor when the mouse moves.
|
|
42
|
+
|
|
43
43
|
(override) If the cursor is off the axes, the xdata and ydata will
|
|
44
44
|
be None, and will simply be cleared rather than drawn.
|
|
45
45
|
"""
|
mwx/matplot2g.py
CHANGED
|
@@ -13,7 +13,7 @@ from scipy import ndimage as ndi
|
|
|
13
13
|
|
|
14
14
|
from . import framework as mwx
|
|
15
15
|
from .framework import Menu
|
|
16
|
-
from .utilus import warn
|
|
16
|
+
## from .utilus import warn
|
|
17
17
|
from .utilus import funcall as _F
|
|
18
18
|
from .controls import Clipboard
|
|
19
19
|
from .matplot2 import MatplotPanel
|
mwx/mgplt.py
CHANGED
mwx/nutshell.py
CHANGED
|
@@ -61,6 +61,7 @@ class Stylus:
|
|
|
61
61
|
stc.STC_STYLE_BRACELIGHT : "fore:#000000,back:#ffffb8,bold",
|
|
62
62
|
stc.STC_STYLE_BRACEBAD : "fore:#000000,back:#ff0000,bold",
|
|
63
63
|
stc.STC_STYLE_CONTROLCHAR : "size:6",
|
|
64
|
+
stc.STC_STYLE_INDENTGUIDE : "",
|
|
64
65
|
stc.STC_STYLE_CARETLINE : "fore:#000000,back:#ffff7f,size:2", # optional
|
|
65
66
|
stc.STC_STYLE_ANNOTATION : "fore:#7f0000,back:#ff7f7f", # optional
|
|
66
67
|
stc.STC_P_DEFAULT : "fore:#000000",
|
|
@@ -69,11 +70,11 @@ class Stylus:
|
|
|
69
70
|
stc.STC_P_COMMENTLINE : "fore:#007f7f,back:#ffcfcf",
|
|
70
71
|
stc.STC_P_COMMENTBLOCK : "fore:#007f7f,back:#ffcfcf,eol",
|
|
71
72
|
stc.STC_P_NUMBER : "fore:#7f0000",
|
|
72
|
-
stc.STC_P_STRINGEOL : "fore:#000000,back:#ffcfcf",
|
|
73
73
|
stc.STC_P_CHARACTER : "fore:#7f7f7f",
|
|
74
74
|
stc.STC_P_STRING : "fore:#7f7f7f",
|
|
75
75
|
stc.STC_P_TRIPLE : "fore:#7f7f7f",
|
|
76
76
|
stc.STC_P_TRIPLEDOUBLE : "fore:#7f7f7f",
|
|
77
|
+
stc.STC_P_STRINGEOL : "fore:#000000,back:#ffcfcf,eol",
|
|
77
78
|
stc.STC_P_CLASSNAME : "fore:#7f00ff,bold",
|
|
78
79
|
stc.STC_P_DEFNAME : "fore:#0000ff,bold",
|
|
79
80
|
stc.STC_P_WORD : "fore:#0000ff",
|
|
@@ -87,6 +88,7 @@ class Stylus:
|
|
|
87
88
|
stc.STC_STYLE_BRACELIGHT : "fore:#000000,back:#cccccc,bold",
|
|
88
89
|
stc.STC_STYLE_BRACEBAD : "fore:#000000,back:#ff0000,bold",
|
|
89
90
|
stc.STC_STYLE_CONTROLCHAR : "size:6",
|
|
91
|
+
stc.STC_STYLE_INDENTGUIDE : "",
|
|
90
92
|
stc.STC_STYLE_CARETLINE : "fore:#000000,back:#f0f0ff,size:2", # optional
|
|
91
93
|
stc.STC_STYLE_ANNOTATION : "fore:#7f0000,back:#ff7f7f", # optional
|
|
92
94
|
stc.STC_P_DEFAULT : "fore:#000000",
|
|
@@ -95,11 +97,11 @@ class Stylus:
|
|
|
95
97
|
stc.STC_P_COMMENTLINE : "fore:#007f00,back:#f0fff0",
|
|
96
98
|
stc.STC_P_COMMENTBLOCK : "fore:#007f00,back:#f0fff0,eol",
|
|
97
99
|
stc.STC_P_NUMBER : "fore:#e02000",
|
|
98
|
-
stc.STC_P_STRINGEOL : "fore:#7f7f7f,back:#ffc0c0,eol",
|
|
99
100
|
stc.STC_P_CHARACTER : "fore:#7f7f7f",
|
|
100
101
|
stc.STC_P_STRING : "fore:#7f7f7f",
|
|
101
102
|
stc.STC_P_TRIPLE : "fore:#7f7f7f",
|
|
102
103
|
stc.STC_P_TRIPLEDOUBLE : "fore:#7f7f7f",
|
|
104
|
+
stc.STC_P_STRINGEOL : "fore:#7f7f7f,back:#ffc0c0,eol",
|
|
103
105
|
stc.STC_P_CLASSNAME : "fore:#7f00ff,bold",
|
|
104
106
|
stc.STC_P_DEFNAME : "fore:#0000ff,bold",
|
|
105
107
|
stc.STC_P_WORD : "fore:#0000ff",
|
|
@@ -113,6 +115,7 @@ class Stylus:
|
|
|
113
115
|
stc.STC_STYLE_BRACELIGHT : "fore:#ffffff,back:#202020,bold",
|
|
114
116
|
stc.STC_STYLE_BRACEBAD : "fore:#ffffff,back:#ff0000,bold",
|
|
115
117
|
stc.STC_STYLE_CONTROLCHAR : "size:6",
|
|
118
|
+
stc.STC_STYLE_INDENTGUIDE : "",
|
|
116
119
|
stc.STC_STYLE_CARETLINE : "fore:#ffffff,back:#123460,size:2", # optional
|
|
117
120
|
stc.STC_STYLE_ANNOTATION : "fore:#7f0000,back:#ff7f7f", # optional
|
|
118
121
|
stc.STC_P_DEFAULT : "fore:#cccccc",
|
|
@@ -121,11 +124,11 @@ class Stylus:
|
|
|
121
124
|
stc.STC_P_COMMENTLINE : "fore:#42c18c,back:#004040",
|
|
122
125
|
stc.STC_P_COMMENTBLOCK : "fore:#42c18c,back:#004040,eol",
|
|
123
126
|
stc.STC_P_NUMBER : "fore:#ffc080",
|
|
124
|
-
stc.STC_P_STRINGEOL : "fore:#cccccc,back:#004040,eol",
|
|
125
127
|
stc.STC_P_CHARACTER : "fore:#a0a0a0",
|
|
126
|
-
stc.STC_P_STRING : "fore:#
|
|
127
|
-
stc.STC_P_TRIPLE : "fore:#a0a0a0
|
|
128
|
-
stc.STC_P_TRIPLEDOUBLE : "fore:#
|
|
128
|
+
stc.STC_P_STRING : "fore:#a0c0ff",
|
|
129
|
+
stc.STC_P_TRIPLE : "fore:#a0a0a0",
|
|
130
|
+
stc.STC_P_TRIPLEDOUBLE : "fore:#a0c0ff",
|
|
131
|
+
stc.STC_P_STRINGEOL : "fore:#cccccc,back:#400000,eol",
|
|
129
132
|
stc.STC_P_CLASSNAME : "fore:#61d6d6,bold",
|
|
130
133
|
stc.STC_P_DEFNAME : "fore:#3a96ff,bold",
|
|
131
134
|
stc.STC_P_WORD : "fore:#80c0ff",
|
|
@@ -201,7 +204,10 @@ class AutoCompInterfaceMixin:
|
|
|
201
204
|
super().CallTipShow(pos, tip)
|
|
202
205
|
|
|
203
206
|
def autoCallTipShow(self, command, insertcalltip=True):
|
|
204
|
-
"""Display argument spec and docstring in a popup window.
|
|
207
|
+
"""Display argument spec and docstring in a popup window.
|
|
208
|
+
|
|
209
|
+
(override) Fix cursor position on calltip insertion.
|
|
210
|
+
"""
|
|
205
211
|
if self.CallTipActive():
|
|
206
212
|
self.CallTipCancel()
|
|
207
213
|
|
|
@@ -596,16 +602,16 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
596
602
|
## Global style for all languages
|
|
597
603
|
## font = wx.Font(9, wx.MODERN, wx.NORMAL, wx.NORMAL, False, "MS Gothic")
|
|
598
604
|
## self.StyleSetFont(stc.STC_STYLE_DEFAULT, font)
|
|
599
|
-
|
|
600
605
|
## self.StyleClearAll()
|
|
601
|
-
##
|
|
602
|
-
## self.SetSelBackground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT))
|
|
606
|
+
## => STC_STYLE_DEFAULT に設定したスタイルを他のスタイルに全適用する
|
|
603
607
|
|
|
604
608
|
## The magin style for line numbers and symbols
|
|
605
609
|
## [0] for markers, 10 pixels wide, mask 0b11111
|
|
606
610
|
## [1] for numbers, 32 pixels wide, mask 0x01ffffff (~stc.STC_MASK_FOLDERS)
|
|
607
611
|
## [2] for borders, 1 pixels wide, mask 0xfe000000 ( stc.STC_MASK_FOLDERS)
|
|
608
|
-
|
|
612
|
+
##
|
|
613
|
+
## cf. `EditWindow.setDisplayLineNumbers`
|
|
614
|
+
##
|
|
609
615
|
## 32 bit margin mask
|
|
610
616
|
## [0] 1111,1111,1111,1111,1111,1111,1111,1111 = -1 for all markers
|
|
611
617
|
## [1] 0000,0001,1111,1111,1111,1111,1111,1111 = 0x01ffffff for markers
|
|
@@ -628,7 +634,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
628
634
|
|
|
629
635
|
self.SetMarginLeft(2) # +1 margin at the left
|
|
630
636
|
|
|
631
|
-
self.SetFoldFlags(
|
|
637
|
+
self.SetFoldFlags(stc.STC_FOLDFLAG_LINEAFTER_CONTRACTED)
|
|
632
638
|
|
|
633
639
|
self.SetProperty('fold', '1') # Enable folder property
|
|
634
640
|
|
|
@@ -742,7 +748,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
742
748
|
|
|
743
749
|
def add_marker(self, line, n):
|
|
744
750
|
if self.MarkerAdd(line, n):
|
|
745
|
-
self.EnsureVisible(line)
|
|
751
|
+
self.EnsureVisible(line) # expand if folded
|
|
746
752
|
self.handler('{}_set'.format(self.marker_names[n]), line)
|
|
747
753
|
|
|
748
754
|
def del_marker(self, n):
|
|
@@ -754,7 +760,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
754
760
|
def goto_marker(self, markerMask, selection=False):
|
|
755
761
|
line = self.MarkerNext(0, markerMask)
|
|
756
762
|
if line != -1:
|
|
757
|
-
self.EnsureVisible(line)
|
|
763
|
+
self.EnsureVisible(line) # expand if folded
|
|
758
764
|
self.goto_line(line, selection)
|
|
759
765
|
self.recenter()
|
|
760
766
|
|
|
@@ -1199,6 +1205,9 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1199
1205
|
self.StyleSetSpec(stc.STC_STYLE_DEFAULT, default)
|
|
1200
1206
|
self.StyleClearAll()
|
|
1201
1207
|
|
|
1208
|
+
self.SetSelForeground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
|
|
1209
|
+
self.SetSelBackground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT))
|
|
1210
|
+
|
|
1202
1211
|
## Add style to the folding margin
|
|
1203
1212
|
item = _map(spec.get(stc.STC_STYLE_LINENUMBER, ''))
|
|
1204
1213
|
if item:
|
|
@@ -1216,10 +1225,12 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1216
1225
|
self.SetFoldMarginColour(True, item.get('fore'))
|
|
1217
1226
|
self.SetFoldMarginHiColour(True, item.get('fore'))
|
|
1218
1227
|
|
|
1228
|
+
self.SetCaretLineVisible(0)
|
|
1229
|
+
self.SetCaretForeground(_map(default).get('fore'))
|
|
1230
|
+
|
|
1219
1231
|
## Custom style for caret and line colour
|
|
1220
1232
|
item = _map(spec.pop(stc.STC_STYLE_CARETLINE, ''))
|
|
1221
1233
|
if item:
|
|
1222
|
-
self.SetCaretLineVisible(0)
|
|
1223
1234
|
if 'fore' in item:
|
|
1224
1235
|
self.SetCaretForeground(item['fore'])
|
|
1225
1236
|
if 'back' in item:
|
|
@@ -1311,6 +1322,48 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1311
1322
|
if not hl + offset < vl < hl + n - 1 - offset:
|
|
1312
1323
|
self.ScrollToLine(vl - n//2)
|
|
1313
1324
|
|
|
1325
|
+
def DoFindNext(self, findData, findDlg=None):
|
|
1326
|
+
"""Find the search text defined in `findData`.
|
|
1327
|
+
|
|
1328
|
+
If found, selects the matched text and scrolls to its line.
|
|
1329
|
+
Typically called from `wx.EVT_FIND` event handlers.
|
|
1330
|
+
|
|
1331
|
+
(override) Enables the whole word search.
|
|
1332
|
+
Returns True if a match is found, False otherwise.
|
|
1333
|
+
"""
|
|
1334
|
+
flags = 0
|
|
1335
|
+
if findData.Flags & wx.FR_MATCHCASE: flags |= wx.stc.STC_FIND_MATCHCASE
|
|
1336
|
+
if findData.Flags & wx.FR_WHOLEWORD: flags |= wx.stc.STC_FIND_WHOLEWORD
|
|
1337
|
+
self.SetSearchFlags(flags)
|
|
1338
|
+
|
|
1339
|
+
backward = not (findData.Flags & wx.FR_DOWN)
|
|
1340
|
+
findstring = findData.FindString
|
|
1341
|
+
if backward:
|
|
1342
|
+
self.TargetStart = self.anchor # backward anchor
|
|
1343
|
+
self.TargetEnd = 0
|
|
1344
|
+
else:
|
|
1345
|
+
self.TargetStart = self.cpos # forward anchor
|
|
1346
|
+
self.TargetEnd = self.TextLength
|
|
1347
|
+
loc = self.SearchInTarget(findstring)
|
|
1348
|
+
|
|
1349
|
+
## If it wasn't found then restart at beginning.
|
|
1350
|
+
if loc == -1:
|
|
1351
|
+
self.TargetStart = self.TextLength if backward else 0
|
|
1352
|
+
loc = self.SearchInTarget(findstring)
|
|
1353
|
+
|
|
1354
|
+
## Was it still not found?
|
|
1355
|
+
if loc == -1:
|
|
1356
|
+
wx.MessageBox("Unable to find the search text.",
|
|
1357
|
+
"Not found!", wx.OK|wx.ICON_INFORMATION)
|
|
1358
|
+
if findDlg:
|
|
1359
|
+
wx.CallAfter(findDlg.SetFocus)
|
|
1360
|
+
return False
|
|
1361
|
+
|
|
1362
|
+
self.SetSelection(loc, loc + len(findstring))
|
|
1363
|
+
self.EnsureVisible(self.cline) # expand if folded
|
|
1364
|
+
self.EnsureCaretVisible()
|
|
1365
|
+
return True
|
|
1366
|
+
|
|
1314
1367
|
## --------------------------------
|
|
1315
1368
|
## Search functions
|
|
1316
1369
|
## --------------------------------
|
|
@@ -1400,21 +1453,6 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1400
1453
|
def grep(self, pattern, flags=re.M):
|
|
1401
1454
|
yield from re.finditer(pattern.encode(), self.TextRaw, flags)
|
|
1402
1455
|
|
|
1403
|
-
def search_text(self, text, mode=True):
|
|
1404
|
-
"""Yields positions where `text` is found.
|
|
1405
|
-
If mode is True, search by word; otherwise, search by string.
|
|
1406
|
-
"""
|
|
1407
|
-
text = text.encode()
|
|
1408
|
-
pos = -1
|
|
1409
|
-
p = re.compile(r"[a-zA-Z0-9_]")
|
|
1410
|
-
while 1:
|
|
1411
|
-
pos = self.TextRaw.find(text, pos+1)
|
|
1412
|
-
if pos < 0:
|
|
1413
|
-
break
|
|
1414
|
-
if mode and p.search(self.get_char(pos-1) + self.get_char(pos+len(text))):
|
|
1415
|
-
continue
|
|
1416
|
-
yield pos
|
|
1417
|
-
|
|
1418
1456
|
def filter_text(self):
|
|
1419
1457
|
"""Show indicators for the selected text."""
|
|
1420
1458
|
self.__itextlines = []
|
|
@@ -1425,17 +1463,25 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1425
1463
|
if not text:
|
|
1426
1464
|
self.message("No words")
|
|
1427
1465
|
return
|
|
1428
|
-
|
|
1466
|
+
wholeword = (not self.SelectedText) # Enable or disable whole word search.
|
|
1467
|
+
pattern = re.escape(text)
|
|
1468
|
+
if wholeword:
|
|
1469
|
+
pattern = rf"\b{pattern}\b"
|
|
1429
1470
|
lines = []
|
|
1430
|
-
for
|
|
1471
|
+
for m in self.grep(pattern):
|
|
1472
|
+
p, q = m.span()
|
|
1431
1473
|
lines.append(self.LineFromPosition(p))
|
|
1432
1474
|
for i in (10, 11,):
|
|
1433
1475
|
self.SetIndicatorCurrent(i)
|
|
1434
|
-
self.IndicatorFillRange(p,
|
|
1435
|
-
self.__itextlines = sorted(set(lines))
|
|
1476
|
+
self.IndicatorFillRange(p, q-p)
|
|
1477
|
+
self.__itextlines = sorted(set(lines)) # keep order, no duplication
|
|
1436
1478
|
self.message("{}: {} found".format(text, len(lines)))
|
|
1437
1479
|
try:
|
|
1438
1480
|
self.TopLevelParent.findData.FindString = text
|
|
1481
|
+
if wholeword:
|
|
1482
|
+
self.TopLevelParent.findData.Flags |= wx.FR_WHOLEWORD
|
|
1483
|
+
else:
|
|
1484
|
+
self.TopLevelParent.findData.Flags &= ~wx.FR_WHOLEWORD
|
|
1439
1485
|
except AttributeError:
|
|
1440
1486
|
pass
|
|
1441
1487
|
|
|
@@ -1471,7 +1517,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1471
1517
|
evt.Skip()
|
|
1472
1518
|
return
|
|
1473
1519
|
line = self.__itextlines[i]
|
|
1474
|
-
self.EnsureVisible(line)
|
|
1520
|
+
self.EnsureVisible(line) # expand if folded
|
|
1475
1521
|
self.goto_line(line)
|
|
1476
1522
|
self.recenter()
|
|
1477
1523
|
self.on_itext_exit(evt)
|
|
@@ -1703,8 +1749,12 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1703
1749
|
@editable
|
|
1704
1750
|
def kill_line(self):
|
|
1705
1751
|
if not self.SelectedText:
|
|
1706
|
-
|
|
1707
|
-
|
|
1752
|
+
p = self.cpos
|
|
1753
|
+
if p == self.eol:
|
|
1754
|
+
## self.WordRightEndExtend() # Select cr/lf chunks
|
|
1755
|
+
if self.get_char(p) == '\r': p += 1
|
|
1756
|
+
if self.get_char(p) == '\n': p += 1
|
|
1757
|
+
self.cpos = p
|
|
1708
1758
|
else:
|
|
1709
1759
|
self.cpos = self.eol
|
|
1710
1760
|
self.ReplaceSelection('')
|
|
@@ -1712,8 +1762,12 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
|
|
|
1712
1762
|
@editable
|
|
1713
1763
|
def backward_kill_line(self):
|
|
1714
1764
|
if not self.SelectedText:
|
|
1715
|
-
|
|
1716
|
-
|
|
1765
|
+
p = self.cpos
|
|
1766
|
+
if p == self.bol:
|
|
1767
|
+
## self.WordLeftExtend() # Select cr/lf chunks
|
|
1768
|
+
if self.get_char(p-1) == '\n': p -= 1
|
|
1769
|
+
if self.get_char(p-1) == '\r': p -= 1
|
|
1770
|
+
self.cpos = p
|
|
1717
1771
|
else:
|
|
1718
1772
|
self.cpos = self.bol
|
|
1719
1773
|
self.ReplaceSelection('')
|
|
@@ -1904,6 +1958,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
1904
1958
|
'*button* pressed' : (0, skip, dispatch),
|
|
1905
1959
|
'escape pressed' : (-1, self.on_enter_escmap),
|
|
1906
1960
|
'C-h pressed' : (0, self.call_helpTip),
|
|
1961
|
+
'. pressed' : (2, self.OnEnterDot),
|
|
1907
1962
|
'C-. pressed' : (2, self.call_word_autocomp),
|
|
1908
1963
|
'C-/ pressed' : (3, self.call_apropos_autocomp),
|
|
1909
1964
|
'M-. pressed' : (2, self.call_word_autocomp),
|
|
@@ -2028,6 +2083,17 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2028
2083
|
self.update_caption()
|
|
2029
2084
|
evt.Skip()
|
|
2030
2085
|
|
|
2086
|
+
def OnEnterDot(self, evt):
|
|
2087
|
+
if not self.CanEdit():
|
|
2088
|
+
self.handler('quit', evt)
|
|
2089
|
+
return
|
|
2090
|
+
p = self.cpos
|
|
2091
|
+
lst = self.get_style(p-1)
|
|
2092
|
+
rst = self.get_style(p)
|
|
2093
|
+
if lst not in ('moji', 'word', 'rparen') or rst == 'word':
|
|
2094
|
+
self.handler('quit', evt) # don't enter autocomp
|
|
2095
|
+
evt.Skip()
|
|
2096
|
+
|
|
2031
2097
|
def on_activated(self, buf):
|
|
2032
2098
|
"""Called when the buffer is activated."""
|
|
2033
2099
|
self.update_caption()
|
|
@@ -2162,7 +2228,7 @@ class Buffer(EditorInterface, EditWindow):
|
|
|
2162
2228
|
lx = lines[-1] - 1
|
|
2163
2229
|
self.red_arrow = lx
|
|
2164
2230
|
self.goto_line(lx)
|
|
2165
|
-
self.EnsureVisible(lx)
|
|
2231
|
+
self.EnsureVisible(lx) # expand if folded
|
|
2166
2232
|
self.EnsureCaretVisible()
|
|
2167
2233
|
self.AnnotationSetStyle(lx, stc.STC_STYLE_ANNOTATION)
|
|
2168
2234
|
self.AnnotationSetText(lx, msg)
|
|
@@ -2490,7 +2556,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
|
|
|
2490
2556
|
return all([self.find_file(fn) for fn in dlg.Paths])
|
|
2491
2557
|
return None
|
|
2492
2558
|
retval = self.load_file(filename)
|
|
2493
|
-
if retval == False:
|
|
2559
|
+
if retval == False: # noqa # to check if not None
|
|
2494
2560
|
buf = self.create_buffer(filename)
|
|
2495
2561
|
self.swap_buffer(buf)
|
|
2496
2562
|
self.post_message("New file.")
|
|
@@ -3079,39 +3145,41 @@ class Nautilus(EditorInterface, Shell):
|
|
|
3079
3145
|
Backspace-guard from autocomp eating over a prompt whitespace.
|
|
3080
3146
|
"""
|
|
3081
3147
|
if self.cpos == self.bolc:
|
|
3082
|
-
self.handler('quit', evt) #
|
|
3148
|
+
self.handler('quit', evt) # Don't eat backward prompt
|
|
3083
3149
|
return
|
|
3084
3150
|
evt.Skip()
|
|
3085
3151
|
|
|
3086
3152
|
@editable
|
|
3087
|
-
def backward_kill_word(self):
|
|
3153
|
+
def backward_kill_word(self): # (override)
|
|
3088
3154
|
if not self.SelectedText:
|
|
3155
|
+
if self.cpos <= self.bolc:
|
|
3156
|
+
return
|
|
3089
3157
|
text, lp = self.CurLine
|
|
3090
3158
|
if text[:lp] == sys.ps2:
|
|
3091
|
-
self.cpos -= lp
|
|
3092
|
-
self.WordLeftExtend()
|
|
3159
|
+
self.cpos -= lp # Select ps2:prompt
|
|
3160
|
+
self.WordLeftExtend() # Select cr/lf chunks
|
|
3093
3161
|
else:
|
|
3094
|
-
q = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
|
|
3095
3162
|
self.WordLeftExtend()
|
|
3163
|
+
q = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
|
|
3096
3164
|
if self.cpos < q:
|
|
3097
|
-
self.cpos = q
|
|
3165
|
+
self.cpos = q # Don't skip back ps2:prompt
|
|
3098
3166
|
self.ReplaceSelection('')
|
|
3099
3167
|
|
|
3100
3168
|
@editable
|
|
3101
|
-
def backward_kill_line(self):
|
|
3169
|
+
def backward_kill_line(self): # (override)
|
|
3102
3170
|
if not self.SelectedText:
|
|
3171
|
+
if self.cpos <= self.bolc:
|
|
3172
|
+
return
|
|
3103
3173
|
text, lp = self.CurLine
|
|
3104
3174
|
if text[:lp] == sys.ps2:
|
|
3105
|
-
self.cpos -= lp
|
|
3106
|
-
self.WordLeftExtend()
|
|
3175
|
+
self.cpos -= lp # Select ps2:prompt
|
|
3176
|
+
self.WordLeftExtend() # Select cr/lf chunks
|
|
3107
3177
|
else:
|
|
3108
3178
|
q = max(self.bol, self.bolc) # for debugger mode: bol <= bolc
|
|
3109
|
-
if self.cpos
|
|
3110
|
-
return
|
|
3111
|
-
elif self.cpos > q:
|
|
3179
|
+
if self.cpos > q:
|
|
3112
3180
|
self.cpos = q
|
|
3113
3181
|
else:
|
|
3114
|
-
self.WordLeftExtend()
|
|
3182
|
+
self.WordLeftExtend() # Select cr/lf chunks
|
|
3115
3183
|
self.ReplaceSelection('')
|
|
3116
3184
|
|
|
3117
3185
|
def OnEnter(self, evt):
|
mwx/plugins/ffmpeg_view.py
CHANGED
|
@@ -157,20 +157,18 @@ class Plugin(Layer):
|
|
|
157
157
|
|
|
158
158
|
self.mc.Bind(wx.EVT_KEY_DOWN, self.on_hotkey_down)
|
|
159
159
|
self.mc.Bind(wx.EVT_KEY_UP, self.on_hotkey_up)
|
|
160
|
-
|
|
161
|
-
self.Bind(wx.EVT_SHOW, self.OnShow)
|
|
162
160
|
|
|
163
161
|
def Destroy(self):
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
162
|
+
self.parent.handler.unbind("unknown_format", self.load_media)
|
|
163
|
+
if self.mc:
|
|
164
|
+
self.mc.Destroy()
|
|
165
|
+
return Layer.Destroy(self)
|
|
168
166
|
|
|
169
167
|
def OnShow(self, evt):
|
|
170
168
|
if not evt.IsShown():
|
|
171
169
|
if self.mc:
|
|
172
170
|
self.mc.Stop()
|
|
173
|
-
|
|
171
|
+
Layer.OnShow(self, evt)
|
|
174
172
|
|
|
175
173
|
def OnMediaLoaded(self, evt):
|
|
176
174
|
self.ss.range = (0, self.video_dur, 0.01)
|
mwx/plugins/frame_listview.py
CHANGED
|
@@ -113,10 +113,8 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
|
|
|
113
113
|
lambda v: Menu.Popup(self, self.menu))
|
|
114
114
|
|
|
115
115
|
def Destroy(self):
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
finally:
|
|
119
|
-
return wx.ListCtrl.Destroy(self)
|
|
116
|
+
self.Target.handler.remove(self.context)
|
|
117
|
+
return wx.ListCtrl.Destroy(self)
|
|
120
118
|
|
|
121
119
|
def UpdateInfo(self, frame):
|
|
122
120
|
ls = ("{}".format(frame.index),
|
mwx/utilus.py
CHANGED
|
@@ -16,8 +16,7 @@ import fnmatch
|
|
|
16
16
|
import pkgutil
|
|
17
17
|
import pydoc
|
|
18
18
|
import inspect
|
|
19
|
-
from inspect import
|
|
20
|
-
isfunction, isgenerator, isframe, iscode, istraceback)
|
|
19
|
+
from inspect import isclass, ismodule, ismethod, isbuiltin, isfunction, isgenerator # noqa
|
|
21
20
|
from pprint import pprint
|
|
22
21
|
|
|
23
22
|
|
|
@@ -827,6 +826,22 @@ class FSM(dict):
|
|
|
827
826
|
f" The transaction must be a list, not a tuple.")
|
|
828
827
|
return action
|
|
829
828
|
|
|
829
|
+
def binds(self, event, action=None, state=None, state2=None):
|
|
830
|
+
"""Append a one-time transaction to the context.
|
|
831
|
+
|
|
832
|
+
Like `bind`, but unbinds itself after being called once.
|
|
833
|
+
"""
|
|
834
|
+
if action is None:
|
|
835
|
+
return lambda f: self.binds(event, f, state, state2)
|
|
836
|
+
|
|
837
|
+
@wraps(action)
|
|
838
|
+
def _act(*v, **kw):
|
|
839
|
+
try:
|
|
840
|
+
return action(*v, **kw)
|
|
841
|
+
finally:
|
|
842
|
+
self.unbind(event, _act, state)
|
|
843
|
+
return self.bind(event, _act, state, state2)
|
|
844
|
+
|
|
830
845
|
def unbind(self, event, action=None, state=None):
|
|
831
846
|
"""Remove a transaction from the context.
|
|
832
847
|
|
mwx/wxmon.py
CHANGED
|
@@ -107,7 +107,8 @@ class EventMonitor(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
|
|
|
107
107
|
return
|
|
108
108
|
if not isinstance(widget, wx.Object):
|
|
109
109
|
wx.MessageBox("Cannot watch the widget.\n\n"
|
|
110
|
-
"- {!r} is not a wx.Object.".format(widget)
|
|
110
|
+
"- {!r} is not a wx.Object.".format(widget),
|
|
111
|
+
self.__module__)
|
|
111
112
|
return
|
|
112
113
|
self._target = widget
|
|
113
114
|
self.target = widget
|
mwx/wxpdb.py
CHANGED
|
@@ -243,7 +243,6 @@ class Debugger(Pdb):
|
|
|
243
243
|
f"Debugger is closed.\n\n{e}")
|
|
244
244
|
finally:
|
|
245
245
|
self.set_quit()
|
|
246
|
-
return
|
|
247
246
|
|
|
248
247
|
def run(self, cmd, filename="<string>"):
|
|
249
248
|
"""Debug a statement executed via the exec() function.
|
|
@@ -270,7 +269,6 @@ class Debugger(Pdb):
|
|
|
270
269
|
f"Debugger is closed.\n\n{e}")
|
|
271
270
|
finally:
|
|
272
271
|
self.set_quit()
|
|
273
|
-
return
|
|
274
272
|
|
|
275
273
|
## --------------------------------
|
|
276
274
|
## Actions for handler
|
mwx/wxwit.py
CHANGED
|
@@ -8,7 +8,7 @@ import wx.lib.inspection as it
|
|
|
8
8
|
|
|
9
9
|
from .controls import Icon
|
|
10
10
|
from .utilus import typename
|
|
11
|
-
from .framework import CtrlInterface, Menu
|
|
11
|
+
from .framework import CtrlInterface, Menu
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class Inspector(it.InspectionTree, CtrlInterface):
|
|
@@ -77,19 +77,16 @@ class Inspector(it.InspectionTree, CtrlInterface):
|
|
|
77
77
|
## --------------------------------
|
|
78
78
|
|
|
79
79
|
def SetObj(self, obj):
|
|
80
|
-
"""Called from tree.toolFrame -> SetObj.
|
|
81
|
-
|
|
82
|
-
(override) Set target object.
|
|
83
|
-
"""
|
|
80
|
+
"""Called from tree.toolFrame -> SetObj."""
|
|
84
81
|
if self.target is obj:
|
|
85
82
|
return
|
|
86
83
|
self.target = obj
|
|
87
|
-
item = self.FindWidgetItem(obj)
|
|
84
|
+
item = self.FindWidgetItem(obj) # cf. it.InspectionTree.SelectObj
|
|
88
85
|
if item:
|
|
89
86
|
self.EnsureVisible(item)
|
|
90
87
|
self.SelectItem(item)
|
|
91
88
|
elif obj:
|
|
92
|
-
self.BuildTree(obj)
|
|
89
|
+
self.BuildTree(obj) # If the item for obj is missing, rebuild the tree.
|
|
93
90
|
|
|
94
91
|
def GetTextForWidget(self, obj):
|
|
95
92
|
"""Return the string to be used in the tree for a widget.
|
|
@@ -119,11 +116,11 @@ class Inspector(it.InspectionTree, CtrlInterface):
|
|
|
119
116
|
if obj is None:
|
|
120
117
|
item = self.Selection
|
|
121
118
|
if item:
|
|
122
|
-
obj = self.GetItemData(item)
|
|
123
|
-
|
|
124
|
-
if not isinstance(obj, wx.Window):
|
|
119
|
+
obj = self.GetItemData(item) # Restart
|
|
120
|
+
if not isinstance(obj, (wx.Window, type(None))):
|
|
125
121
|
wx.MessageBox("Cannot watch the widget.\n\n"
|
|
126
|
-
"- {!r} is not a wx.Object.".format(obj)
|
|
122
|
+
"- {!r} is not a wx.Object.".format(obj),
|
|
123
|
+
self.__module__)
|
|
127
124
|
return
|
|
128
125
|
self.SetObj(obj)
|
|
129
126
|
self.timer.Start(500)
|
|
@@ -137,7 +134,7 @@ class Inspector(it.InspectionTree, CtrlInterface):
|
|
|
137
134
|
## --------------------------------
|
|
138
135
|
|
|
139
136
|
def OnTimer(self, evt):
|
|
140
|
-
## wnd, pt = wx.FindWindowAtPointer()
|
|
137
|
+
## wnd, pt = wx.FindWindowAtPointer() # as HitTest
|
|
141
138
|
wnd = wx.Window.FindFocus()
|
|
142
139
|
if (wnd and wnd is not self.target
|
|
143
140
|
and wnd not in self._noWatchList):
|
|
@@ -187,8 +184,8 @@ class Inspector(it.InspectionTree, CtrlInterface):
|
|
|
187
184
|
|
|
188
185
|
|
|
189
186
|
def miniIcon(key, size=(16,16)):
|
|
190
|
-
if key == 'ShowFilling':
|
|
191
|
-
|
|
187
|
+
## if key == 'ShowFilling':
|
|
188
|
+
## return wx.py.filling.images.getPyImage().Scale(16,16).ConvertToBitmap()
|
|
192
189
|
art = getattr(it, key)
|
|
193
190
|
return art.GetImage().Scale(*size).ConvertToBitmap()
|
|
194
191
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
mwx/__init__.py,sha256=pS7ZG8QKRypiFFiaWAq_opBB6I_1viZ0zUMk2TbjzE0,667
|
|
2
|
+
mwx/bookshelf.py,sha256=XbJ9HUH5COUm-BVI7iLC7gr9Hj9l-sFjOoaCAqNS4aA,8178
|
|
3
|
+
mwx/controls.py,sha256=cgYEeBn1GD1s2YrDZd3jzhlACTc9IOZED_JOA8dqTJI,49914
|
|
4
|
+
mwx/framework.py,sha256=f5xAUMR05Y1Y_f1SDhZySOxGsfTcmW4H2JT2vHdfAg4,77030
|
|
5
|
+
mwx/graphman.py,sha256=xYaBzPZlA1OJ2suk29CEtVMGJJZd1krHwjXnyxThyuo,69643
|
|
6
|
+
mwx/images.py,sha256=Kkfy9QI_hMtwShSjUS4-ZpC_EkVuah_XhpBOR4wAKkM,49792
|
|
7
|
+
mwx/matplot2.py,sha256=U0axLQeZAR_ys5rXHykVKkvXLibnNwXS-gm-c0U2MGw,33003
|
|
8
|
+
mwx/matplot2g.py,sha256=foq-NdksvTV_I55UGxLzghp1YXaFfWgzTmigmnIe58E,65376
|
|
9
|
+
mwx/matplot2lg.py,sha256=cb0EZXivccDQu4oFj5ddSUF9pEE4f5UuFJJK2ELItww,27404
|
|
10
|
+
mwx/mgplt.py,sha256=KR7MWdl9J6hiiBdO0NB25Y37rP21aFdwBVsB9KZKXo8,5564
|
|
11
|
+
mwx/nutshell.py,sha256=ELpFChIZR4GgR8dyphqvrsJtgTDBGoQRaw7_F_1VDNc,146181
|
|
12
|
+
mwx/testsuite.py,sha256=Zk75onPSEn2tf0swS3l-vIn6yTXGB7allIyvJsPHj20,1229
|
|
13
|
+
mwx/utilus.py,sha256=vu-gzLabGEaY6wAN3ThJrmjTChlZtoKYozSF0om_MOk,38642
|
|
14
|
+
mwx/wxmon.py,sha256=NIksW_CZv7Kw4dod8tWVwakO4iJuvE8hJSAcjkYfLaE,12800
|
|
15
|
+
mwx/wxpdb.py,sha256=aZIH7Xs-9ahDLut2P4NmvbB2zHVpI95kx4je1ophNQM,18799
|
|
16
|
+
mwx/wxwil.py,sha256=hhyB1lPrF9ixeObxCOKQv0Theu-B-kpJg_yVU3EGSNg,5406
|
|
17
|
+
mwx/wxwit.py,sha256=mTH92bWw1F3ycaq4EoxVD_4hIxy2fbKZZbQg3f1ZD1Y,7350
|
|
18
|
+
mwx/plugins/__init__.py,sha256=jnJ-Sl9XJ_7BFDslD_r7dsbxsOT57q_IaEriV53XIGY,41
|
|
19
|
+
mwx/plugins/ffmpeg_view.py,sha256=-xf1Kmu4H5UZRCatqPLfstr2NbnJDZ2_xLfBLV4vczo,11001
|
|
20
|
+
mwx/plugins/fft_view.py,sha256=08A_Y73XirV7kXpwf-v0mUA0Hr0MOfdMXv3tvL1hvWA,2789
|
|
21
|
+
mwx/plugins/frame_listview.py,sha256=xH1au3lI-bZwCzmhVmvNTOHDoVQIBzH4p9_8Y36Qs5U,10380
|
|
22
|
+
mwx/plugins/line_profile.py,sha256=zzm6_7lnAnNepLbh07ordp3nRWDFQJtu719ZVjrVf8s,819
|
|
23
|
+
mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
|
|
24
|
+
mwx/py/filling.py,sha256=fumUG1F5M9TL-Dfqni4G85uk7TmvnUunTbdcPDV0vfo,16857
|
|
25
|
+
mwxlib-1.5.0.dist-info/METADATA,sha256=vbRM1kvarP86bPrshgFTy74zJ1U3NSvoEJhv6K_osHo,7381
|
|
26
|
+
mwxlib-1.5.0.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
|
27
|
+
mwxlib-1.5.0.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
|
|
28
|
+
mwxlib-1.5.0.dist-info/RECORD,,
|
mwxlib-1.4.15.dist-info/RECORD
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
mwx/__init__.py,sha256=pS7ZG8QKRypiFFiaWAq_opBB6I_1viZ0zUMk2TbjzE0,667
|
|
2
|
-
mwx/bookshelf.py,sha256=XbJ9HUH5COUm-BVI7iLC7gr9Hj9l-sFjOoaCAqNS4aA,8178
|
|
3
|
-
mwx/controls.py,sha256=TyXDovOo52XaiZQW4nW_JxOYPdszLsXUwPOY04KXOzM,49903
|
|
4
|
-
mwx/framework.py,sha256=0bNeso5KBFhb3keziq-Y8v-N2ko6KkxXLl7NCZ7L50c,76905
|
|
5
|
-
mwx/graphman.py,sha256=RlIQ_jhwv2870rC_R0xWCHFv5VsLzT8InidDKobKFes,70270
|
|
6
|
-
mwx/images.py,sha256=Kkfy9QI_hMtwShSjUS4-ZpC_EkVuah_XhpBOR4wAKkM,49792
|
|
7
|
-
mwx/matplot2.py,sha256=A2PbHI5UcuAvINfnm6GG7CXpbexhzvtyVLQOwcbRqnc,33015
|
|
8
|
-
mwx/matplot2g.py,sha256=3FD45UDkrWrypMDTUQx6SL5jU6fCdjXsJtH3k_GDUL0,65373
|
|
9
|
-
mwx/matplot2lg.py,sha256=cb0EZXivccDQu4oFj5ddSUF9pEE4f5UuFJJK2ELItww,27404
|
|
10
|
-
mwx/mgplt.py,sha256=8mXbHpCmm7lz3XbAxOg7IVC7DaSGBEby1UfTlMl9kjk,5604
|
|
11
|
-
mwx/nutshell.py,sha256=FNQ5GgXVnjDu9mmf9dyxk1TmuICUXF9tLWL6o5CssQQ,143418
|
|
12
|
-
mwx/testsuite.py,sha256=Zk75onPSEn2tf0swS3l-vIn6yTXGB7allIyvJsPHj20,1229
|
|
13
|
-
mwx/utilus.py,sha256=ObXYWsDVn5DmjvwVQgP2HGAhrdxlDrwL7g9pMCDbU7U,38127
|
|
14
|
-
mwx/wxmon.py,sha256=yzWqrbY6LzpfRwQeytYUeqFhFuLVm_XEvrVAL_k0HBQ,12756
|
|
15
|
-
mwx/wxpdb.py,sha256=ih2iLcOgYnUX849YXO4niIYue6amuoG7nWdpr-X1jFw,18839
|
|
16
|
-
mwx/wxwil.py,sha256=hhyB1lPrF9ixeObxCOKQv0Theu-B-kpJg_yVU3EGSNg,5406
|
|
17
|
-
mwx/wxwit.py,sha256=PNgCNDGgT-AWjISOSfPQWyQSZ7JW3d8FyndptQw6OIY,7293
|
|
18
|
-
mwx/plugins/__init__.py,sha256=jnJ-Sl9XJ_7BFDslD_r7dsbxsOT57q_IaEriV53XIGY,41
|
|
19
|
-
mwx/plugins/ffmpeg_view.py,sha256=r7cQPe8anAWoIn3HU_YyWRpsTJrvzji97LNIO1Gw0e0,11031
|
|
20
|
-
mwx/plugins/fft_view.py,sha256=08A_Y73XirV7kXpwf-v0mUA0Hr0MOfdMXv3tvL1hvWA,2789
|
|
21
|
-
mwx/plugins/frame_listview.py,sha256=gowjQ-ARNonMkDSXkQgPKq4U9YBJ-vQ0jK2krBVOdCs,10420
|
|
22
|
-
mwx/plugins/line_profile.py,sha256=zzm6_7lnAnNepLbh07ordp3nRWDFQJtu719ZVjrVf8s,819
|
|
23
|
-
mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
|
|
24
|
-
mwx/py/filling.py,sha256=fumUG1F5M9TL-Dfqni4G85uk7TmvnUunTbdcPDV0vfo,16857
|
|
25
|
-
mwxlib-1.4.15.dist-info/METADATA,sha256=th_Xs4HOK4txWRlzIGgFcMkWUJ6vO_ddbjfYFzN6COs,7382
|
|
26
|
-
mwxlib-1.4.15.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
|
27
|
-
mwxlib-1.4.15.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
|
|
28
|
-
mwxlib-1.4.15.dist-info/RECORD,,
|
|
File without changes
|