Coverage for larch/wxlib/gui_utils.py: 22%

129 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 wx 

5from wx.lib.dialogs import ScrolledMessageDialog 

6 

7import time 

8import os 

9import locale 

10 

11from ..larchlib import ensuremod 

12from .larchfilling import Filling 

13from ..utils import get_cwd, format_exception 

14 

15DEF_CHOICES = [('All Files', '*.*')] 

16 

17# def ExceptionPopup(parent, title, lines, with_traceback=True, 

18# style=None, **kws): 

19# """Modal message dialog with current Python Exception""" 

20# if style is None: 

21# style = wx.OK|wx.ICON_INFORMATION 

22# lines.extend(format_exception(with_traceback=with_traceback)) 

23# message = '\n'.join(lines) 

24# 

25# dkws = {'size': (700, 350)} 

26# dkws.update(kws) 

27# dlg = ScrolledMessageDialog(parent, message, title, **dkws) 

28# dlg.ShowModal() 

29# dlg.Destroy() 

30 

31class LarchWxApp(wx.App, wx.lib.mixins.inspection.InspectionMixin): 

32 """wrapper for wx apps, with the following arguments and features: 

33 

34 _larch (None or Interpreter): instance of Larch Interpreter [None] 

35 version_info (None or string): larch version to check for updates [None] 

36 with_inspect (bool): use wx inspection tool for debugging [False] 

37 with_c_locale (bool): whether to force C locale [True] 

38 

39 """ 

40 def __init__(self, _larch=None, version_info=None, with_inspect=False, 

41 with_c_locale=True, **kws): 

42 self._larch = _larch 

43 self.version_info = version_info 

44 self.with_inspect = with_inspect 

45 self.with_c_locale = with_c_locale 

46 wx.App.__init__(self, **kws) 

47 

48 def OnInit(self): 

49 self.createApp() 

50 if self.with_inspect: 

51 self.ShowInspectionTool() 

52 return True 

53 

54 def createApp(self): 

55 return True 

56 

57 def InitLocale(self): 

58 """over-ride wxPython default initial locale""" 

59 if self.with_c_locale: 

60 self._initial_locale = None 

61 locale.setlocale(locale.LC_ALL, 'C') 

62 else: 

63 lang, enc = locale.getdefaultlocale() 

64 self._initial_locale = wx.Locale(lang, lang[:2], lang) 

65 locale.setlocale(locale.LC_ALL, lang) 

66 

67 def run(self): 

68 self.MainLoop() 

69 

70def wx_update(_larch=None, **kws): 

71 """force an update of wxPython windows""" 

72 symtable = ensuremod(_larch, '_sys') 

73 symtable = ensuremod(_larch, '_sys.wx') 

74 input_handler = symtable.get_symbol('_sys.wx.inputhook') ##.input_handler 

75 wxping = symtable.get_symbol('_sys.wx.ping') 

76 if input_handler is not None: 

77 symtable.set_symbol("_sys.wx.force_wxupdate", True) 

78 wxping(0.002) 

79 

80class wxLarchTimer(wx.MiniFrame): 

81 """hidden wx frame that contains only a timer widget. 

82 This timer widget will periodically force a wx update 

83 """ 

84 def __init__(self, parent, _larch, polltime=50): 

85 wx.MiniFrame.__init__(self, parent, -1, '') 

86 self.Show(False) 

87 self.polltime = polltime 

88 self.timer = wx.Timer(self) 

89 self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) 

90 self.symtable = _larch.symtable 

91 self.wxping =self.symtable.get_symbol('_sys.wx.ping') 

92 

93 def Start(self, polltime = None): 

94 if polltime is None: polltime = self.polltime 

95 if polltime is None: polltime = 500 

96 self.timer.Start(polltime) 

97 

98 def Stop(self): 

99 self.wxping(0.005) 

100 self.symtable.set_symbol("_sys.wx.force_wxupdate", True) 

101 self.timer.Stop() 

102 self.Destroy() 

103 

104 def OnTimer(self, event=None): 

105 """timer events -- here we execute any un-executed shell code""" 

106 self.symtable.set_symbol('_sys.wx.force_wxupdate', True) 

107 self.wxping(0.001) 

108 time.sleep(0.001) 

109 print(" ..") 

110 

111# def gcd(wxparent=None, _larch=None, **kws): 

112# """Directory Browser to Change Directory""" 

113# parent = _larch.symtable.get_symbol('_sys.wx.wxapp') 

114# if parent is None: 

115# _larch.raise_exception(None, msg='wx not supported') 

116# 

117# dlg = wx.DirDialog(None, 'Choose Directory', 

118# defaultPath = get_cwd(), 

119# style = wx.DD_DEFAULT_STYLE) 

120# 

121# if dlg.ShowModal() == wx.ID_OK: 

122# os.chdir(dlg.GetPath()) 

123# dlg.Destroy() 

124# return get_cwd() 

125 

126 

127class DataBrowserFrame(wx.Frame): 

128 """Frame containing the Filling for Data browser.""" 

129 name = 'Filling Frame' 

130 def __init__(self, parent=None, id=-1, title='Larch Data Tree', 

131 pos=wx.DefaultPosition, size=(650, 450), 

132 style=wx.DEFAULT_FRAME_STYLE, _larch=None): 

133 """Create FillingFrame instance.""" 

134 wx.Frame.__init__(self, parent, id, title, pos, size, style) 

135 self.CreateStatusBar() 

136 self.SetStatusText('') 

137 

138 self.filling = Filling(parent=self, rootObject=_larch.symtable, 

139 rootLabel='_main', rootIsNamespace=False, 

140 static=False) 

141 

142 self.filling.tree.setStatusText = self.SetStatusText 

143 self.filling.tree.display() 

144 self.root = self.filling.tree.GetRootItem() 

145 self.filling.tree.Expand(self.root) 

146 self.Show() 

147 self.Raise() 

148 

149 def redraw(self): 

150 self.filling.tree.Collapse(self.root) 

151 self.filling.tree.Expand(self.root) 

152 

153def databrowser(_larch=None, **kws): 

154 """show DataBrowser window for exploring Larch Groups and Data""" 

155 parent = _larch.symtable.get_symbol('_sys.wx.wxapp') 

156 if parent is None: 

157 _larch.raise_exception(None, msg='wx not supported') 

158 return DataBrowserFrame(parent=parent, _larch=_larch) 

159 

160 

161def fileprompt(mode='open', multi=True, message = None, 

162 fname=None, choices=None, _larch=None, **kws): 

163 """show File Browser for opening or saving file. 

164 Returns name of selected file. 

165 

166 options: 

167 mode: one of 'open' or 'save' 

168 fname: default filename 

169 message: text to display in top window bar 

170 multi: whether multiple files are allowed [True] 

171 choices: list of (title, fileglob) to restrict choices 

172 

173 > x = fileprompt(choices=(('All Files', '*.*'), ('Python Files', '*.py'))) 

174 

175 """ 

176 symtable = ensuremod(_larch) 

177 

178 if fname is None: 

179 fname = '' 

180 try: 

181 fname = symtable.get_symbol("_sys.wx.default_filename") 

182 except: 

183 pass 

184 symtable.set_symbol("_sys.wx.default_filename", fname) 

185 

186 if choices is None or len(choices) < 1: 

187 choices = DEF_CHOICES 

188 try: 

189 choices = symtable.get_symbol("_sys.wx.ext_choices") 

190 except: 

191 pass 

192 symtable.set_symbol("_sys.wx.ext_choices", choices) 

193 

194 wildcard = [] 

195 for title, fglob in choices: 

196 wildcard.append('%s (%s)|%s' % (title, fglob, fglob)) 

197 wildcard = '|'.join(wildcard) 

198 

199 if mode == 'open': 

200 style = wx.FD_OPEN|wx.FD_CHANGE_DIR 

201 if multi: 

202 style = style|wx.FD_MULTIPLE 

203 if message is None: 

204 message = 'Open File ' 

205 else: 

206 style = wx.FD_SAVE|wx.FD_CHANGE_DIR 

207 if message is None: 

208 message = 'Save As ' 

209 

210 #parent.Start() 

211 parent = _larch.symtable.get_symbol('_sys.wx.wxapp') 

212 if parent is None: 

213 _larch.raise_exception(None, msg='wx not supported') 

214 if hasattr(parent, 'GetTopWindow'): 

215 parent = parent.GetTopWindow() 

216 timer = wxLarchTimer(parent, _larch) 

217 dlg = wx.FileDialog(parent=timer, message=message, 

218 defaultDir=get_cwd(), 

219 defaultFile=fname, 

220 wildcard =wildcard, 

221 style=style) 

222 path = None 

223 if dlg.ShowModal() == wx.ID_OK: 

224 path = dlg.GetPaths() 

225 if len(path) == 1: 

226 path = path[0] 

227 

228 dlg.Destroy() 

229 timer.Destroy() 

230 return path