Coverage for larch/wxlib/readlinetextctrl.py: 12%
151 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
1#!/usr/bin/env python
2#
3import sys
4import time
5from pathlib import Path
7import wx
9from ..site_config import get_homedir
10DEFAULT_HISTORYFILE = '.wxlarch_hist'
11MAX_HISTORY = 5000
13class ReadlineTextCtrl(wx.TextCtrl):
14 def __init__(self, parent=None, value='', size=(400,-1),
15 historyfile=None,
16 style=wx.ALIGN_LEFT|wx.TE_PROCESS_ENTER, **kws):
17 wx.TextCtrl.__init__(self, parent, -1, value=value,
18 size=size, style=style, **kws)
20 self._val = value
22 self.hist_file = historyfile
23 self.hist_buff = []
24 if self.hist_file is None:
25 self.hist_file= Path(get_homedir(), DEFAULT_HISTORYFILE).as_posix()
26 # self.LoadHistory()
27 self.hist_mark = len(self.hist_buff)
28 self.hist_sessionstart = self.hist_mark
30 if sys.platform == 'darwin':
31 self.Bind(wx.EVT_KEY_UP, self.onChar)
32 else:
33 self.Bind(wx.EVT_CHAR, self.onChar)
35 self.Bind(wx.EVT_SET_FOCUS, self.onSetFocus)
36 self.Bind(wx.EVT_KILL_FOCUS, self.onKillFocus)
37 self.__GetMark()
38 self.notebooks = None
40 def __GetMark(self, event=None):
41 " keep track of cursor position within text"
42 try:
43 self.__mark = min(wx.TextCtrl.GetSelection(self)[0],
44 len(wx.TextCtrl.GetValue(self).strip()))
45 except:
46 self.__mark = 0
48 def __SetMark(self, m=None):
49 "set position of mark"
50 if m is None:
51 m = self.__mark
52 self.SetSelection(m,m)
54 def onKillFocus(self, event=None):
55 self.__GetMark()
58 def onSetFocus(self, event=None):
59 self.__SetMark()
62 def onChar(self, event):
63 """ on Character event"""
64 key = event.GetKeyCode()
65 entry = wx.TextCtrl.GetValue(self).strip()
66 pos = wx.TextCtrl.GetSelection(self)
67 do_skip = True
68 ctrl = event.ControlDown()
69 # really, the order here is important:
70 # 1. return sends to ValidateEntry
71 if key == wx.WXK_RETURN and len(entry) > 0:
72 pass
73 # 2. other non-text characters are passed without change
74 if key == wx.WXK_UP:
75 self.hist_mark = max(0, self.hist_mark-1)
76 try:
77 self.SetValue(self.hist_buff[self.hist_mark])
78 except:
79 pass
80 self.SetInsertionPointEnd()
81 do_skip = False
82 elif key == wx.WXK_DOWN:
83 self.hist_mark += 1
84 if self.hist_mark >= len(self.hist_buff):
85 self.SetValue('')
86 else:
87 self.SetValue(self.hist_buff[self.hist_mark])
88 self.SetInsertionPointEnd()
89 elif key == wx.WXK_TAB:
90 if self.notebooks is not None:
91 self.notebooks.AdvanceSelection()
92 self.SetFocus()
94 elif key == wx.WXK_HOME or (ctrl and key == 1): # ctrl-a
95 self.SetInsertionPoint(0)
96 self.SetSelection(0,0)
97 do_skip = False
98 elif key == wx.WXK_END or (ctrl and key == 5):
99 self.SetInsertionPointEnd()
100 elif ctrl and key == 2: # b
101 mark = max(1, self.GetSelection()[1])
102 self.SetSelection(mark-1, mark-1)
103 elif ctrl and key== 3: # c
104 cb_txt = wx.TextDataObject()
105 wx.TheClipboard.Open()
106 if wx.TheClipboard.IsOpened():
107 cb_txt.SetData(str(entry))
108 wx.TheClipboard.SetData(cb_txt)
109 wx.TheClipboard.Close()
110 elif ctrl and key == 4: # d
111 mark = self.GetSelection()[1]
112 self.SetValue("%s%s" % (entry[:mark], entry[mark+1:]))
113 self.SetSelection(mark, mark)
114 do_skip = False
115 elif ctrl and key == 6: # f
116 mark = self.GetSelection()[1]
117 self.SetSelection(mark+1, mark+1)
118 elif ctrl and key == 8: # h
119 mark = self.GetSelection()[1]
120 self.SetValue("%s%s" % (entry[:mark-1], entry[mark:]))
121 self.SetSelection(mark-1, mark-1)
122 elif ctrl and key == 11: # k
123 mark = self.GetSelection()[1]
124 self.SetValue("%s" % (entry[:mark]))
125 self.SetSelection(mark, mark)
126 elif ctrl and key == 22: # v
127 cb_txt = wx.TextDataObject()
128 wx.TheClipboard.Open()
129 if wx.TheClipboard.IsOpened():
130 wx.TheClipboard.GetData(cb_txt)
131 wx.TheClipboard.Close()
132 try:
133 self.SetValue(str(cb_txt.GetText()))
134 except TypeError:
135 pass
136 do_skip = False
137 elif ctrl and key == 24: # x
138 cb_txt = wx.TextDataObject()
139 wx.TheClipboard.Open()
140 if wx.TheClipboard.IsOpened():
141 cb_txt.SetData(str(entry))
142 wx.TheClipboard.GetData(cb_txt)
143 wx.TheClipboard.Close()
144 self.SetValue('')
145 elif ctrl:
146 pass
147 self.Refresh()
148 return
150 def AddToHistory(self, text=''):
151 if len(text.strip()) > 0:
152 self.hist_buff.append(text)
153 self.hist_mark = len(self.hist_buff)
155 def SaveHistory(self, filename=None, session_only=False):
156 if filename is None:
157 filename = self.hist_file
158 try:
159 fout = open(filename,'w', encoding=sys.getdefaultencoding())
160 except IOError:
161 print( 'Cannot save history ', filename)
163 fout.write("# wxlarch history saved %s\n\n" % time.ctime())
164 start_entry = -MAX_HISTORY
165 if session_only:
166 start_entry = self.hist_sessionstart
167 fout.write('\n'.join(self.hist_buff[start_entry:]))
168 fout.write("\n")
169 fout.close()
171 def LoadHistory(self):
172 if Path(self.hist_file).exists():
173 self.hist_buff = []
174 for txt in open(self.hist_file,'r').readlines():
175 stxt = txt.strip()
176 if len(stxt) > 0 and not stxt.startswith('#'):
177 self.hist_buff.append(txt[:-1])
179 def def_onText(self, event=None):
180 if event is None:
181 return
182 txt = event.GetString()
183 if len(txt.strip()) > 0:
184 self.hist_buff.append(txt)
185 self.hist_mark = len(self.hist_buff)
187 event.Skip()