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
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
1#!/usr/bin/env python
3import sys
4import wx
5from wx.lib.dialogs import ScrolledMessageDialog
7import time
8import os
9import locale
11from ..larchlib import ensuremod
12from .larchfilling import Filling
13from ..utils import get_cwd, format_exception
15DEF_CHOICES = [('All Files', '*.*')]
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()
31class LarchWxApp(wx.App, wx.lib.mixins.inspection.InspectionMixin):
32 """wrapper for wx apps, with the following arguments and features:
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]
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)
48 def OnInit(self):
49 self.createApp()
50 if self.with_inspect:
51 self.ShowInspectionTool()
52 return True
54 def createApp(self):
55 return True
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)
67 def run(self):
68 self.MainLoop()
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)
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')
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)
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()
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(" ..")
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()
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('')
138 self.filling = Filling(parent=self, rootObject=_larch.symtable,
139 rootLabel='_main', rootIsNamespace=False,
140 static=False)
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()
149 def redraw(self):
150 self.filling.tree.Collapse(self.root)
151 self.filling.tree.Expand(self.root)
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)
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.
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
173 > x = fileprompt(choices=(('All Files', '*.*'), ('Python Files', '*.py')))
175 """
176 symtable = ensuremod(_larch)
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)
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)
194 wildcard = []
195 for title, fglob in choices:
196 wildcard.append('%s (%s)|%s' % (title, fglob, fglob))
197 wildcard = '|'.join(wildcard)
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 '
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]
228 dlg.Destroy()
229 timer.Destroy()
230 return path