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

1#!/usr/bin/env python 

2# 

3import sys 

4import time 

5from pathlib import Path 

6 

7import wx 

8 

9from ..site_config import get_homedir 

10DEFAULT_HISTORYFILE = '.wxlarch_hist' 

11MAX_HISTORY = 5000 

12 

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) 

19 

20 self._val = value 

21 

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 

29 

30 if sys.platform == 'darwin': 

31 self.Bind(wx.EVT_KEY_UP, self.onChar) 

32 else: 

33 self.Bind(wx.EVT_CHAR, self.onChar) 

34 

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 

39 

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 

47 

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) 

53 

54 def onKillFocus(self, event=None): 

55 self.__GetMark() 

56 

57 

58 def onSetFocus(self, event=None): 

59 self.__SetMark() 

60 

61 

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() 

93 

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 

149 

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) 

154 

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) 

162 

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() 

170 

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]) 

178 

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) 

186 

187 event.Skip()