1 | """Easy to use dialogs.
|
---|
2 |
|
---|
3 | Message(msg) -- display a message and an OK button.
|
---|
4 | AskString(prompt, default) -- ask for a string, display OK and Cancel buttons.
|
---|
5 | AskPassword(prompt, default) -- like AskString(), but shows text as bullets.
|
---|
6 | AskYesNoCancel(question, default) -- display a question and Yes, No and Cancel buttons.
|
---|
7 | GetArgv(optionlist, commandlist) -- fill a sys.argv-like list using a dialog
|
---|
8 | AskFileForOpen(...) -- Ask the user for an existing file
|
---|
9 | AskFileForSave(...) -- Ask the user for an output file
|
---|
10 | AskFolder(...) -- Ask the user to select a folder
|
---|
11 | bar = Progress(label, maxvalue) -- Display a progress bar
|
---|
12 | bar.set(value) -- Set value
|
---|
13 | bar.inc( *amount ) -- increment value by amount (default=1)
|
---|
14 | bar.label( *newlabel ) -- get or set text label.
|
---|
15 |
|
---|
16 | More documentation in each function.
|
---|
17 | This module uses DLOG resources 260 and on.
|
---|
18 | Based upon STDWIN dialogs with the same names and functions.
|
---|
19 | """
|
---|
20 |
|
---|
21 | from warnings import warnpy3k
|
---|
22 | warnpy3k("In 3.x, the EasyDialogs module is removed.", stacklevel=2)
|
---|
23 |
|
---|
24 | from Carbon.Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText, ModalDialog
|
---|
25 | from Carbon import Qd
|
---|
26 | from Carbon import QuickDraw
|
---|
27 | from Carbon import Dialogs
|
---|
28 | from Carbon import Windows
|
---|
29 | from Carbon import Dlg,Win,Evt,Events # sdm7g
|
---|
30 | from Carbon import Ctl
|
---|
31 | from Carbon import Controls
|
---|
32 | from Carbon import Menu
|
---|
33 | from Carbon import AE
|
---|
34 | import Nav
|
---|
35 | import MacOS
|
---|
36 | import string
|
---|
37 | from Carbon.ControlAccessor import * # Also import Controls constants
|
---|
38 | import Carbon.File
|
---|
39 | import macresource
|
---|
40 | import os
|
---|
41 | import sys
|
---|
42 |
|
---|
43 | __all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel',
|
---|
44 | 'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder',
|
---|
45 | 'ProgressBar']
|
---|
46 |
|
---|
47 | _initialized = 0
|
---|
48 |
|
---|
49 | def _initialize():
|
---|
50 | global _initialized
|
---|
51 | if _initialized: return
|
---|
52 | macresource.need("DLOG", 260, "dialogs.rsrc", __name__)
|
---|
53 |
|
---|
54 | def _interact():
|
---|
55 | """Make sure the application is in the foreground"""
|
---|
56 | AE.AEInteractWithUser(50000000)
|
---|
57 |
|
---|
58 | def cr2lf(text):
|
---|
59 | if '\r' in text:
|
---|
60 | text = string.join(string.split(text, '\r'), '\n')
|
---|
61 | return text
|
---|
62 |
|
---|
63 | def lf2cr(text):
|
---|
64 | if '\n' in text:
|
---|
65 | text = string.join(string.split(text, '\n'), '\r')
|
---|
66 | if len(text) > 253:
|
---|
67 | text = text[:253] + '\311'
|
---|
68 | return text
|
---|
69 |
|
---|
70 | def Message(msg, id=260, ok=None):
|
---|
71 | """Display a MESSAGE string.
|
---|
72 |
|
---|
73 | Return when the user clicks the OK button or presses Return.
|
---|
74 |
|
---|
75 | The MESSAGE string can be at most 255 characters long.
|
---|
76 | """
|
---|
77 | _initialize()
|
---|
78 | _interact()
|
---|
79 | d = GetNewDialog(id, -1)
|
---|
80 | if not d:
|
---|
81 | print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
|
---|
82 | return
|
---|
83 | h = d.GetDialogItemAsControl(2)
|
---|
84 | SetDialogItemText(h, lf2cr(msg))
|
---|
85 | if ok is not None:
|
---|
86 | h = d.GetDialogItemAsControl(1)
|
---|
87 | h.SetControlTitle(ok)
|
---|
88 | d.SetDialogDefaultItem(1)
|
---|
89 | d.AutoSizeDialog()
|
---|
90 | d.GetDialogWindow().ShowWindow()
|
---|
91 | while 1:
|
---|
92 | n = ModalDialog(None)
|
---|
93 | if n == 1:
|
---|
94 | return
|
---|
95 |
|
---|
96 |
|
---|
97 | def AskString(prompt, default = "", id=261, ok=None, cancel=None):
|
---|
98 | """Display a PROMPT string and a text entry field with a DEFAULT string.
|
---|
99 |
|
---|
100 | Return the contents of the text entry field when the user clicks the
|
---|
101 | OK button or presses Return.
|
---|
102 | Return None when the user clicks the Cancel button.
|
---|
103 |
|
---|
104 | If omitted, DEFAULT is empty.
|
---|
105 |
|
---|
106 | The PROMPT and DEFAULT strings, as well as the return value,
|
---|
107 | can be at most 255 characters long.
|
---|
108 | """
|
---|
109 |
|
---|
110 | _initialize()
|
---|
111 | _interact()
|
---|
112 | d = GetNewDialog(id, -1)
|
---|
113 | if not d:
|
---|
114 | print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
|
---|
115 | return
|
---|
116 | h = d.GetDialogItemAsControl(3)
|
---|
117 | SetDialogItemText(h, lf2cr(prompt))
|
---|
118 | h = d.GetDialogItemAsControl(4)
|
---|
119 | SetDialogItemText(h, lf2cr(default))
|
---|
120 | d.SelectDialogItemText(4, 0, 999)
|
---|
121 | # d.SetDialogItem(4, 0, 255)
|
---|
122 | if ok is not None:
|
---|
123 | h = d.GetDialogItemAsControl(1)
|
---|
124 | h.SetControlTitle(ok)
|
---|
125 | if cancel is not None:
|
---|
126 | h = d.GetDialogItemAsControl(2)
|
---|
127 | h.SetControlTitle(cancel)
|
---|
128 | d.SetDialogDefaultItem(1)
|
---|
129 | d.SetDialogCancelItem(2)
|
---|
130 | d.AutoSizeDialog()
|
---|
131 | d.GetDialogWindow().ShowWindow()
|
---|
132 | while 1:
|
---|
133 | n = ModalDialog(None)
|
---|
134 | if n == 1:
|
---|
135 | h = d.GetDialogItemAsControl(4)
|
---|
136 | return cr2lf(GetDialogItemText(h))
|
---|
137 | if n == 2: return None
|
---|
138 |
|
---|
139 | def AskPassword(prompt, default='', id=264, ok=None, cancel=None):
|
---|
140 | """Display a PROMPT string and a text entry field with a DEFAULT string.
|
---|
141 | The string is displayed as bullets only.
|
---|
142 |
|
---|
143 | Return the contents of the text entry field when the user clicks the
|
---|
144 | OK button or presses Return.
|
---|
145 | Return None when the user clicks the Cancel button.
|
---|
146 |
|
---|
147 | If omitted, DEFAULT is empty.
|
---|
148 |
|
---|
149 | The PROMPT and DEFAULT strings, as well as the return value,
|
---|
150 | can be at most 255 characters long.
|
---|
151 | """
|
---|
152 | _initialize()
|
---|
153 | _interact()
|
---|
154 | d = GetNewDialog(id, -1)
|
---|
155 | if not d:
|
---|
156 | print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
|
---|
157 | return
|
---|
158 | h = d.GetDialogItemAsControl(3)
|
---|
159 | SetDialogItemText(h, lf2cr(prompt))
|
---|
160 | pwd = d.GetDialogItemAsControl(4)
|
---|
161 | bullets = '\245'*len(default)
|
---|
162 | ## SetControlData(pwd, kControlEditTextPart, kControlEditTextTextTag, bullets)
|
---|
163 | SetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag, default)
|
---|
164 | d.SelectDialogItemText(4, 0, 999)
|
---|
165 | Ctl.SetKeyboardFocus(d.GetDialogWindow(), pwd, kControlEditTextPart)
|
---|
166 | if ok is not None:
|
---|
167 | h = d.GetDialogItemAsControl(1)
|
---|
168 | h.SetControlTitle(ok)
|
---|
169 | if cancel is not None:
|
---|
170 | h = d.GetDialogItemAsControl(2)
|
---|
171 | h.SetControlTitle(cancel)
|
---|
172 | d.SetDialogDefaultItem(Dialogs.ok)
|
---|
173 | d.SetDialogCancelItem(Dialogs.cancel)
|
---|
174 | d.AutoSizeDialog()
|
---|
175 | d.GetDialogWindow().ShowWindow()
|
---|
176 | while 1:
|
---|
177 | n = ModalDialog(None)
|
---|
178 | if n == 1:
|
---|
179 | h = d.GetDialogItemAsControl(4)
|
---|
180 | return cr2lf(GetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag))
|
---|
181 | if n == 2: return None
|
---|
182 |
|
---|
183 | def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=262):
|
---|
184 | """Display a QUESTION string which can be answered with Yes or No.
|
---|
185 |
|
---|
186 | Return 1 when the user clicks the Yes button.
|
---|
187 | Return 0 when the user clicks the No button.
|
---|
188 | Return -1 when the user clicks the Cancel button.
|
---|
189 |
|
---|
190 | When the user presses Return, the DEFAULT value is returned.
|
---|
191 | If omitted, this is 0 (No).
|
---|
192 |
|
---|
193 | The QUESTION string can be at most 255 characters.
|
---|
194 | """
|
---|
195 |
|
---|
196 | _initialize()
|
---|
197 | _interact()
|
---|
198 | d = GetNewDialog(id, -1)
|
---|
199 | if not d:
|
---|
200 | print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
|
---|
201 | return
|
---|
202 | # Button assignments:
|
---|
203 | # 1 = default (invisible)
|
---|
204 | # 2 = Yes
|
---|
205 | # 3 = No
|
---|
206 | # 4 = Cancel
|
---|
207 | # The question string is item 5
|
---|
208 | h = d.GetDialogItemAsControl(5)
|
---|
209 | SetDialogItemText(h, lf2cr(question))
|
---|
210 | if yes is not None:
|
---|
211 | if yes == '':
|
---|
212 | d.HideDialogItem(2)
|
---|
213 | else:
|
---|
214 | h = d.GetDialogItemAsControl(2)
|
---|
215 | h.SetControlTitle(yes)
|
---|
216 | if no is not None:
|
---|
217 | if no == '':
|
---|
218 | d.HideDialogItem(3)
|
---|
219 | else:
|
---|
220 | h = d.GetDialogItemAsControl(3)
|
---|
221 | h.SetControlTitle(no)
|
---|
222 | if cancel is not None:
|
---|
223 | if cancel == '':
|
---|
224 | d.HideDialogItem(4)
|
---|
225 | else:
|
---|
226 | h = d.GetDialogItemAsControl(4)
|
---|
227 | h.SetControlTitle(cancel)
|
---|
228 | d.SetDialogCancelItem(4)
|
---|
229 | if default == 1:
|
---|
230 | d.SetDialogDefaultItem(2)
|
---|
231 | elif default == 0:
|
---|
232 | d.SetDialogDefaultItem(3)
|
---|
233 | elif default == -1:
|
---|
234 | d.SetDialogDefaultItem(4)
|
---|
235 | d.AutoSizeDialog()
|
---|
236 | d.GetDialogWindow().ShowWindow()
|
---|
237 | while 1:
|
---|
238 | n = ModalDialog(None)
|
---|
239 | if n == 1: return default
|
---|
240 | if n == 2: return 1
|
---|
241 | if n == 3: return 0
|
---|
242 | if n == 4: return -1
|
---|
243 |
|
---|
244 |
|
---|
245 |
|
---|
246 | # The deprecated Carbon QuickDraw APIs are no longer available as of
|
---|
247 | # OS X 10.8. Raise an ImportError here in that case so that callers
|
---|
248 | # of EasyDialogs, like BuildApplet, will do the right thing.
|
---|
249 |
|
---|
250 | try:
|
---|
251 | screenbounds = Qd.GetQDGlobalsScreenBits().bounds
|
---|
252 | except AttributeError:
|
---|
253 | raise ImportError("QuickDraw APIs not available")
|
---|
254 |
|
---|
255 | screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
|
---|
256 | screenbounds[2]-4, screenbounds[3]-4
|
---|
257 |
|
---|
258 | kControlProgressBarIndeterminateTag = 'inde' # from Controls.py
|
---|
259 |
|
---|
260 |
|
---|
261 | class ProgressBar:
|
---|
262 | def __init__(self, title="Working...", maxval=0, label="", id=263):
|
---|
263 | self.w = None
|
---|
264 | self.d = None
|
---|
265 | _initialize()
|
---|
266 | self.d = GetNewDialog(id, -1)
|
---|
267 | self.w = self.d.GetDialogWindow()
|
---|
268 | self.label(label)
|
---|
269 | self.title(title)
|
---|
270 | self.set(0, maxval)
|
---|
271 | self.d.AutoSizeDialog()
|
---|
272 | self.w.ShowWindow()
|
---|
273 | self.d.DrawDialog()
|
---|
274 |
|
---|
275 | def __del__(self):
|
---|
276 | if self.w:
|
---|
277 | self.w.BringToFront()
|
---|
278 | self.w.HideWindow()
|
---|
279 | del self.w
|
---|
280 | del self.d
|
---|
281 |
|
---|
282 | def title(self, newstr=""):
|
---|
283 | """title(text) - Set title of progress window"""
|
---|
284 | self.w.BringToFront()
|
---|
285 | self.w.SetWTitle(newstr)
|
---|
286 |
|
---|
287 | def label(self, *newstr):
|
---|
288 | """label(text) - Set text in progress box"""
|
---|
289 | self.w.BringToFront()
|
---|
290 | if newstr:
|
---|
291 | self._label = lf2cr(newstr[0])
|
---|
292 | text_h = self.d.GetDialogItemAsControl(2)
|
---|
293 | SetDialogItemText(text_h, self._label)
|
---|
294 |
|
---|
295 | def _update(self, value):
|
---|
296 | maxval = self.maxval
|
---|
297 | if maxval == 0: # an indeterminate bar
|
---|
298 | Ctl.IdleControls(self.w) # spin the barber pole
|
---|
299 | else: # a determinate bar
|
---|
300 | if maxval > 32767:
|
---|
301 | value = int(value/(maxval/32767.0))
|
---|
302 | maxval = 32767
|
---|
303 | maxval = int(maxval)
|
---|
304 | value = int(value)
|
---|
305 | progbar = self.d.GetDialogItemAsControl(3)
|
---|
306 | progbar.SetControlMaximum(maxval)
|
---|
307 | progbar.SetControlValue(value) # set the bar length
|
---|
308 |
|
---|
309 | # Test for cancel button
|
---|
310 | ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1 )
|
---|
311 | if ready :
|
---|
312 | what,msg,when,where,mod = ev
|
---|
313 | part = Win.FindWindow(where)[0]
|
---|
314 | if Dlg.IsDialogEvent(ev):
|
---|
315 | ds = Dlg.DialogSelect(ev)
|
---|
316 | if ds[0] and ds[1] == self.d and ds[-1] == 1:
|
---|
317 | self.w.HideWindow()
|
---|
318 | self.w = None
|
---|
319 | self.d = None
|
---|
320 | raise KeyboardInterrupt, ev
|
---|
321 | else:
|
---|
322 | if part == 4: # inDrag
|
---|
323 | self.w.DragWindow(where, screenbounds)
|
---|
324 | else:
|
---|
325 | MacOS.HandleEvent(ev)
|
---|
326 |
|
---|
327 |
|
---|
328 | def set(self, value, max=None):
|
---|
329 | """set(value) - Set progress bar position"""
|
---|
330 | if max is not None:
|
---|
331 | self.maxval = max
|
---|
332 | bar = self.d.GetDialogItemAsControl(3)
|
---|
333 | if max <= 0: # indeterminate bar
|
---|
334 | bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x01')
|
---|
335 | else: # determinate bar
|
---|
336 | bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x00')
|
---|
337 | if value < 0:
|
---|
338 | value = 0
|
---|
339 | elif value > self.maxval:
|
---|
340 | value = self.maxval
|
---|
341 | self.curval = value
|
---|
342 | self._update(value)
|
---|
343 |
|
---|
344 | def inc(self, n=1):
|
---|
345 | """inc(amt) - Increment progress bar position"""
|
---|
346 | self.set(self.curval + n)
|
---|
347 |
|
---|
348 | ARGV_ID=265
|
---|
349 | ARGV_ITEM_OK=1
|
---|
350 | ARGV_ITEM_CANCEL=2
|
---|
351 | ARGV_OPTION_GROUP=3
|
---|
352 | ARGV_OPTION_EXPLAIN=4
|
---|
353 | ARGV_OPTION_VALUE=5
|
---|
354 | ARGV_OPTION_ADD=6
|
---|
355 | ARGV_COMMAND_GROUP=7
|
---|
356 | ARGV_COMMAND_EXPLAIN=8
|
---|
357 | ARGV_COMMAND_ADD=9
|
---|
358 | ARGV_ADD_OLDFILE=10
|
---|
359 | ARGV_ADD_NEWFILE=11
|
---|
360 | ARGV_ADD_FOLDER=12
|
---|
361 | ARGV_CMDLINE_GROUP=13
|
---|
362 | ARGV_CMDLINE_DATA=14
|
---|
363 |
|
---|
364 | ##def _myModalDialog(d):
|
---|
365 | ## while 1:
|
---|
366 | ## ready, ev = Evt.WaitNextEvent(0xffff, -1)
|
---|
367 | ## print 'DBG: WNE', ready, ev
|
---|
368 | ## if ready :
|
---|
369 | ## what,msg,when,where,mod = ev
|
---|
370 | ## part, window = Win.FindWindow(where)
|
---|
371 | ## if Dlg.IsDialogEvent(ev):
|
---|
372 | ## didit, dlgdone, itemdone = Dlg.DialogSelect(ev)
|
---|
373 | ## print 'DBG: DialogSelect', didit, dlgdone, itemdone, d
|
---|
374 | ## if didit and dlgdone == d:
|
---|
375 | ## return itemdone
|
---|
376 | ## elif window == d.GetDialogWindow():
|
---|
377 | ## d.GetDialogWindow().SelectWindow()
|
---|
378 | ## if part == 4: # inDrag
|
---|
379 | ## d.DragWindow(where, screenbounds)
|
---|
380 | ## else:
|
---|
381 | ## MacOS.HandleEvent(ev)
|
---|
382 | ## else:
|
---|
383 | ## MacOS.HandleEvent(ev)
|
---|
384 | ##
|
---|
385 | def _setmenu(control, items):
|
---|
386 | mhandle = control.GetControlData_Handle(Controls.kControlMenuPart,
|
---|
387 | Controls.kControlPopupButtonMenuHandleTag)
|
---|
388 | menu = Menu.as_Menu(mhandle)
|
---|
389 | for item in items:
|
---|
390 | if type(item) == type(()):
|
---|
391 | label = item[0]
|
---|
392 | else:
|
---|
393 | label = item
|
---|
394 | if label[-1] == '=' or label[-1] == ':':
|
---|
395 | label = label[:-1]
|
---|
396 | menu.AppendMenu(label)
|
---|
397 | ## mhandle, mid = menu.getpopupinfo()
|
---|
398 | ## control.SetControlData_Handle(Controls.kControlMenuPart,
|
---|
399 | ## Controls.kControlPopupButtonMenuHandleTag, mhandle)
|
---|
400 | control.SetControlMinimum(1)
|
---|
401 | control.SetControlMaximum(len(items)+1)
|
---|
402 |
|
---|
403 | def _selectoption(d, optionlist, idx):
|
---|
404 | if idx < 0 or idx >= len(optionlist):
|
---|
405 | MacOS.SysBeep()
|
---|
406 | return
|
---|
407 | option = optionlist[idx]
|
---|
408 | if type(option) == type(()):
|
---|
409 | if len(option) == 4:
|
---|
410 | help = option[2]
|
---|
411 | elif len(option) > 1:
|
---|
412 | help = option[-1]
|
---|
413 | else:
|
---|
414 | help = ''
|
---|
415 | else:
|
---|
416 | help = ''
|
---|
417 | h = d.GetDialogItemAsControl(ARGV_OPTION_EXPLAIN)
|
---|
418 | if help and len(help) > 250:
|
---|
419 | help = help[:250] + '...'
|
---|
420 | Dlg.SetDialogItemText(h, help)
|
---|
421 | hasvalue = 0
|
---|
422 | if type(option) == type(()):
|
---|
423 | label = option[0]
|
---|
424 | else:
|
---|
425 | label = option
|
---|
426 | if label[-1] == '=' or label[-1] == ':':
|
---|
427 | hasvalue = 1
|
---|
428 | h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
|
---|
429 | Dlg.SetDialogItemText(h, '')
|
---|
430 | if hasvalue:
|
---|
431 | d.ShowDialogItem(ARGV_OPTION_VALUE)
|
---|
432 | d.SelectDialogItemText(ARGV_OPTION_VALUE, 0, 0)
|
---|
433 | else:
|
---|
434 | d.HideDialogItem(ARGV_OPTION_VALUE)
|
---|
435 |
|
---|
436 |
|
---|
437 | def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID):
|
---|
438 | _initialize()
|
---|
439 | _interact()
|
---|
440 | d = GetNewDialog(id, -1)
|
---|
441 | if not d:
|
---|
442 | print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
|
---|
443 | return
|
---|
444 | # h = d.GetDialogItemAsControl(3)
|
---|
445 | # SetDialogItemText(h, lf2cr(prompt))
|
---|
446 | # h = d.GetDialogItemAsControl(4)
|
---|
447 | # SetDialogItemText(h, lf2cr(default))
|
---|
448 | # d.SelectDialogItemText(4, 0, 999)
|
---|
449 | # d.SetDialogItem(4, 0, 255)
|
---|
450 | if optionlist:
|
---|
451 | _setmenu(d.GetDialogItemAsControl(ARGV_OPTION_GROUP), optionlist)
|
---|
452 | _selectoption(d, optionlist, 0)
|
---|
453 | else:
|
---|
454 | d.GetDialogItemAsControl(ARGV_OPTION_GROUP).DeactivateControl()
|
---|
455 | if commandlist:
|
---|
456 | _setmenu(d.GetDialogItemAsControl(ARGV_COMMAND_GROUP), commandlist)
|
---|
457 | if type(commandlist[0]) == type(()) and len(commandlist[0]) > 1:
|
---|
458 | help = commandlist[0][-1]
|
---|
459 | h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
|
---|
460 | Dlg.SetDialogItemText(h, help)
|
---|
461 | else:
|
---|
462 | d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).DeactivateControl()
|
---|
463 | if not addoldfile:
|
---|
464 | d.GetDialogItemAsControl(ARGV_ADD_OLDFILE).DeactivateControl()
|
---|
465 | if not addnewfile:
|
---|
466 | d.GetDialogItemAsControl(ARGV_ADD_NEWFILE).DeactivateControl()
|
---|
467 | if not addfolder:
|
---|
468 | d.GetDialogItemAsControl(ARGV_ADD_FOLDER).DeactivateControl()
|
---|
469 | d.SetDialogDefaultItem(ARGV_ITEM_OK)
|
---|
470 | d.SetDialogCancelItem(ARGV_ITEM_CANCEL)
|
---|
471 | d.GetDialogWindow().ShowWindow()
|
---|
472 | d.DrawDialog()
|
---|
473 | if hasattr(MacOS, 'SchedParams'):
|
---|
474 | appsw = MacOS.SchedParams(1, 0)
|
---|
475 | try:
|
---|
476 | while 1:
|
---|
477 | stringstoadd = []
|
---|
478 | n = ModalDialog(None)
|
---|
479 | if n == ARGV_ITEM_OK:
|
---|
480 | break
|
---|
481 | elif n == ARGV_ITEM_CANCEL:
|
---|
482 | raise SystemExit
|
---|
483 | elif n == ARGV_OPTION_GROUP:
|
---|
484 | idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
|
---|
485 | _selectoption(d, optionlist, idx)
|
---|
486 | elif n == ARGV_OPTION_VALUE:
|
---|
487 | pass
|
---|
488 | elif n == ARGV_OPTION_ADD:
|
---|
489 | idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
|
---|
490 | if 0 <= idx < len(optionlist):
|
---|
491 | option = optionlist[idx]
|
---|
492 | if type(option) == type(()):
|
---|
493 | option = option[0]
|
---|
494 | if option[-1] == '=' or option[-1] == ':':
|
---|
495 | option = option[:-1]
|
---|
496 | h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
|
---|
497 | value = Dlg.GetDialogItemText(h)
|
---|
498 | else:
|
---|
499 | value = ''
|
---|
500 | if len(option) == 1:
|
---|
501 | stringtoadd = '-' + option
|
---|
502 | else:
|
---|
503 | stringtoadd = '--' + option
|
---|
504 | stringstoadd = [stringtoadd]
|
---|
505 | if value:
|
---|
506 | stringstoadd.append(value)
|
---|
507 | else:
|
---|
508 | MacOS.SysBeep()
|
---|
509 | elif n == ARGV_COMMAND_GROUP:
|
---|
510 | idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
|
---|
511 | if 0 <= idx < len(commandlist) and type(commandlist[idx]) == type(()) and \
|
---|
512 | len(commandlist[idx]) > 1:
|
---|
513 | help = commandlist[idx][-1]
|
---|
514 | h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
|
---|
515 | Dlg.SetDialogItemText(h, help)
|
---|
516 | elif n == ARGV_COMMAND_ADD:
|
---|
517 | idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
|
---|
518 | if 0 <= idx < len(commandlist):
|
---|
519 | command = commandlist[idx]
|
---|
520 | if type(command) == type(()):
|
---|
521 | command = command[0]
|
---|
522 | stringstoadd = [command]
|
---|
523 | else:
|
---|
524 | MacOS.SysBeep()
|
---|
525 | elif n == ARGV_ADD_OLDFILE:
|
---|
526 | pathname = AskFileForOpen()
|
---|
527 | if pathname:
|
---|
528 | stringstoadd = [pathname]
|
---|
529 | elif n == ARGV_ADD_NEWFILE:
|
---|
530 | pathname = AskFileForSave()
|
---|
531 | if pathname:
|
---|
532 | stringstoadd = [pathname]
|
---|
533 | elif n == ARGV_ADD_FOLDER:
|
---|
534 | pathname = AskFolder()
|
---|
535 | if pathname:
|
---|
536 | stringstoadd = [pathname]
|
---|
537 | elif n == ARGV_CMDLINE_DATA:
|
---|
538 | pass # Nothing to do
|
---|
539 | else:
|
---|
540 | raise RuntimeError, "Unknown dialog item %d"%n
|
---|
541 |
|
---|
542 | for stringtoadd in stringstoadd:
|
---|
543 | if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
|
---|
544 | stringtoadd = repr(stringtoadd)
|
---|
545 | h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
|
---|
546 | oldstr = GetDialogItemText(h)
|
---|
547 | if oldstr and oldstr[-1] != ' ':
|
---|
548 | oldstr = oldstr + ' '
|
---|
549 | oldstr = oldstr + stringtoadd
|
---|
550 | if oldstr[-1] != ' ':
|
---|
551 | oldstr = oldstr + ' '
|
---|
552 | SetDialogItemText(h, oldstr)
|
---|
553 | d.SelectDialogItemText(ARGV_CMDLINE_DATA, 0x7fff, 0x7fff)
|
---|
554 | h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
|
---|
555 | oldstr = GetDialogItemText(h)
|
---|
556 | tmplist = string.split(oldstr)
|
---|
557 | newlist = []
|
---|
558 | while tmplist:
|
---|
559 | item = tmplist[0]
|
---|
560 | del tmplist[0]
|
---|
561 | if item[0] == '"':
|
---|
562 | while item[-1] != '"':
|
---|
563 | if not tmplist:
|
---|
564 | raise RuntimeError, "Unterminated quoted argument"
|
---|
565 | item = item + ' ' + tmplist[0]
|
---|
566 | del tmplist[0]
|
---|
567 | item = item[1:-1]
|
---|
568 | if item[0] == "'":
|
---|
569 | while item[-1] != "'":
|
---|
570 | if not tmplist:
|
---|
571 | raise RuntimeError, "Unterminated quoted argument"
|
---|
572 | item = item + ' ' + tmplist[0]
|
---|
573 | del tmplist[0]
|
---|
574 | item = item[1:-1]
|
---|
575 | newlist.append(item)
|
---|
576 | return newlist
|
---|
577 | finally:
|
---|
578 | if hasattr(MacOS, 'SchedParams'):
|
---|
579 | MacOS.SchedParams(*appsw)
|
---|
580 | del d
|
---|
581 |
|
---|
582 | def _process_Nav_args(dftflags, **args):
|
---|
583 | import Carbon.AppleEvents
|
---|
584 | import Carbon.AE
|
---|
585 | import Carbon.File
|
---|
586 | for k in args.keys():
|
---|
587 | if args[k] is None:
|
---|
588 | del args[k]
|
---|
589 | # Set some defaults, and modify some arguments
|
---|
590 | if 'dialogOptionFlags' not in args:
|
---|
591 | args['dialogOptionFlags'] = dftflags
|
---|
592 | if 'defaultLocation' in args and \
|
---|
593 | not isinstance(args['defaultLocation'], Carbon.AE.AEDesc):
|
---|
594 | defaultLocation = args['defaultLocation']
|
---|
595 | if isinstance(defaultLocation, Carbon.File.FSSpec):
|
---|
596 | args['defaultLocation'] = Carbon.AE.AECreateDesc(
|
---|
597 | Carbon.AppleEvents.typeFSS, defaultLocation.data)
|
---|
598 | else:
|
---|
599 | if not isinstance(defaultLocation, Carbon.File.FSRef):
|
---|
600 | defaultLocation = Carbon.File.FSRef(defaultLocation)
|
---|
601 | args['defaultLocation'] = Carbon.AE.AECreateDesc(
|
---|
602 | Carbon.AppleEvents.typeFSRef, defaultLocation.data)
|
---|
603 | if 'typeList' in args and not isinstance(args['typeList'], Carbon.Res.ResourceType):
|
---|
604 | typeList = args['typeList'][:]
|
---|
605 | # Workaround for OSX typeless files:
|
---|
606 | if 'TEXT' in typeList and not '\0\0\0\0' in typeList:
|
---|
607 | typeList = typeList + ('\0\0\0\0',)
|
---|
608 | data = 'Pyth' + struct.pack("hh", 0, len(typeList))
|
---|
609 | for type in typeList:
|
---|
610 | data = data+type
|
---|
611 | args['typeList'] = Carbon.Res.Handle(data)
|
---|
612 | tpwanted = str
|
---|
613 | if 'wanted' in args:
|
---|
614 | tpwanted = args['wanted']
|
---|
615 | del args['wanted']
|
---|
616 | return args, tpwanted
|
---|
617 |
|
---|
618 | def _dummy_Nav_eventproc(msg, data):
|
---|
619 | pass
|
---|
620 |
|
---|
621 | _default_Nav_eventproc = _dummy_Nav_eventproc
|
---|
622 |
|
---|
623 | def SetDefaultEventProc(proc):
|
---|
624 | global _default_Nav_eventproc
|
---|
625 | rv = _default_Nav_eventproc
|
---|
626 | if proc is None:
|
---|
627 | proc = _dummy_Nav_eventproc
|
---|
628 | _default_Nav_eventproc = proc
|
---|
629 | return rv
|
---|
630 |
|
---|
631 | def AskFileForOpen(
|
---|
632 | message=None,
|
---|
633 | typeList=None,
|
---|
634 | # From here on the order is not documented
|
---|
635 | version=None,
|
---|
636 | defaultLocation=None,
|
---|
637 | dialogOptionFlags=None,
|
---|
638 | location=None,
|
---|
639 | clientName=None,
|
---|
640 | windowTitle=None,
|
---|
641 | actionButtonLabel=None,
|
---|
642 | cancelButtonLabel=None,
|
---|
643 | preferenceKey=None,
|
---|
644 | popupExtension=None,
|
---|
645 | eventProc=_dummy_Nav_eventproc,
|
---|
646 | previewProc=None,
|
---|
647 | filterProc=None,
|
---|
648 | wanted=None,
|
---|
649 | multiple=None):
|
---|
650 | """Display a dialog asking the user for a file to open.
|
---|
651 |
|
---|
652 | wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
|
---|
653 | the other arguments can be looked up in Apple's Navigation Services documentation"""
|
---|
654 |
|
---|
655 | default_flags = 0x56 # Or 0xe4?
|
---|
656 | args, tpwanted = _process_Nav_args(default_flags, version=version,
|
---|
657 | defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
|
---|
658 | location=location,clientName=clientName,windowTitle=windowTitle,
|
---|
659 | actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
|
---|
660 | message=message,preferenceKey=preferenceKey,
|
---|
661 | popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc,
|
---|
662 | filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple)
|
---|
663 | _interact()
|
---|
664 | try:
|
---|
665 | rr = Nav.NavChooseFile(args)
|
---|
666 | good = 1
|
---|
667 | except Nav.error, arg:
|
---|
668 | if arg[0] != -128: # userCancelledErr
|
---|
669 | raise Nav.error, arg
|
---|
670 | return None
|
---|
671 | if not rr.validRecord or not rr.selection:
|
---|
672 | return None
|
---|
673 | if issubclass(tpwanted, Carbon.File.FSRef):
|
---|
674 | return tpwanted(rr.selection_fsr[0])
|
---|
675 | if issubclass(tpwanted, Carbon.File.FSSpec):
|
---|
676 | return tpwanted(rr.selection[0])
|
---|
677 | if issubclass(tpwanted, str):
|
---|
678 | return tpwanted(rr.selection_fsr[0].as_pathname())
|
---|
679 | if issubclass(tpwanted, unicode):
|
---|
680 | return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
|
---|
681 | raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
|
---|
682 |
|
---|
683 | def AskFileForSave(
|
---|
684 | message=None,
|
---|
685 | savedFileName=None,
|
---|
686 | # From here on the order is not documented
|
---|
687 | version=None,
|
---|
688 | defaultLocation=None,
|
---|
689 | dialogOptionFlags=None,
|
---|
690 | location=None,
|
---|
691 | clientName=None,
|
---|
692 | windowTitle=None,
|
---|
693 | actionButtonLabel=None,
|
---|
694 | cancelButtonLabel=None,
|
---|
695 | preferenceKey=None,
|
---|
696 | popupExtension=None,
|
---|
697 | eventProc=_dummy_Nav_eventproc,
|
---|
698 | fileType=None,
|
---|
699 | fileCreator=None,
|
---|
700 | wanted=None,
|
---|
701 | multiple=None):
|
---|
702 | """Display a dialog asking the user for a filename to save to.
|
---|
703 |
|
---|
704 | wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
|
---|
705 | the other arguments can be looked up in Apple's Navigation Services documentation"""
|
---|
706 |
|
---|
707 |
|
---|
708 | default_flags = 0x07
|
---|
709 | args, tpwanted = _process_Nav_args(default_flags, version=version,
|
---|
710 | defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
|
---|
711 | location=location,clientName=clientName,windowTitle=windowTitle,
|
---|
712 | actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
|
---|
713 | savedFileName=savedFileName,message=message,preferenceKey=preferenceKey,
|
---|
714 | popupExtension=popupExtension,eventProc=eventProc,fileType=fileType,
|
---|
715 | fileCreator=fileCreator,wanted=wanted,multiple=multiple)
|
---|
716 | _interact()
|
---|
717 | try:
|
---|
718 | rr = Nav.NavPutFile(args)
|
---|
719 | good = 1
|
---|
720 | except Nav.error, arg:
|
---|
721 | if arg[0] != -128: # userCancelledErr
|
---|
722 | raise Nav.error, arg
|
---|
723 | return None
|
---|
724 | if not rr.validRecord or not rr.selection:
|
---|
725 | return None
|
---|
726 | if issubclass(tpwanted, Carbon.File.FSRef):
|
---|
727 | raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave"
|
---|
728 | if issubclass(tpwanted, Carbon.File.FSSpec):
|
---|
729 | return tpwanted(rr.selection[0])
|
---|
730 | if issubclass(tpwanted, (str, unicode)):
|
---|
731 | # This is gross, and probably incorrect too
|
---|
732 | vrefnum, dirid, name = rr.selection[0].as_tuple()
|
---|
733 | pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, ''))
|
---|
734 | pardir_fsr = Carbon.File.FSRef(pardir_fss)
|
---|
735 | pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8
|
---|
736 | name_utf8 = unicode(name, 'macroman').encode('utf8')
|
---|
737 | fullpath = os.path.join(pardir_path, name_utf8)
|
---|
738 | if issubclass(tpwanted, unicode):
|
---|
739 | return unicode(fullpath, 'utf8')
|
---|
740 | return tpwanted(fullpath)
|
---|
741 | raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
|
---|
742 |
|
---|
743 | def AskFolder(
|
---|
744 | message=None,
|
---|
745 | # From here on the order is not documented
|
---|
746 | version=None,
|
---|
747 | defaultLocation=None,
|
---|
748 | dialogOptionFlags=None,
|
---|
749 | location=None,
|
---|
750 | clientName=None,
|
---|
751 | windowTitle=None,
|
---|
752 | actionButtonLabel=None,
|
---|
753 | cancelButtonLabel=None,
|
---|
754 | preferenceKey=None,
|
---|
755 | popupExtension=None,
|
---|
756 | eventProc=_dummy_Nav_eventproc,
|
---|
757 | filterProc=None,
|
---|
758 | wanted=None,
|
---|
759 | multiple=None):
|
---|
760 | """Display a dialog asking the user for select a folder.
|
---|
761 |
|
---|
762 | wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
|
---|
763 | the other arguments can be looked up in Apple's Navigation Services documentation"""
|
---|
764 |
|
---|
765 | default_flags = 0x17
|
---|
766 | args, tpwanted = _process_Nav_args(default_flags, version=version,
|
---|
767 | defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
|
---|
768 | location=location,clientName=clientName,windowTitle=windowTitle,
|
---|
769 | actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
|
---|
770 | message=message,preferenceKey=preferenceKey,
|
---|
771 | popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc,
|
---|
772 | wanted=wanted,multiple=multiple)
|
---|
773 | _interact()
|
---|
774 | try:
|
---|
775 | rr = Nav.NavChooseFolder(args)
|
---|
776 | good = 1
|
---|
777 | except Nav.error, arg:
|
---|
778 | if arg[0] != -128: # userCancelledErr
|
---|
779 | raise Nav.error, arg
|
---|
780 | return None
|
---|
781 | if not rr.validRecord or not rr.selection:
|
---|
782 | return None
|
---|
783 | if issubclass(tpwanted, Carbon.File.FSRef):
|
---|
784 | return tpwanted(rr.selection_fsr[0])
|
---|
785 | if issubclass(tpwanted, Carbon.File.FSSpec):
|
---|
786 | return tpwanted(rr.selection[0])
|
---|
787 | if issubclass(tpwanted, str):
|
---|
788 | return tpwanted(rr.selection_fsr[0].as_pathname())
|
---|
789 | if issubclass(tpwanted, unicode):
|
---|
790 | return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
|
---|
791 | raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
|
---|
792 |
|
---|
793 |
|
---|
794 | def test():
|
---|
795 | import time
|
---|
796 |
|
---|
797 | Message("Testing EasyDialogs.")
|
---|
798 | optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
|
---|
799 | ('flags=', 'Valued option'), ('f:', 'Short valued option'))
|
---|
800 | commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
|
---|
801 | argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
|
---|
802 | Message("Command line: %s"%' '.join(argv))
|
---|
803 | for i in range(len(argv)):
|
---|
804 | print 'arg[%d] = %r' % (i, argv[i])
|
---|
805 | ok = AskYesNoCancel("Do you want to proceed?")
|
---|
806 | ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
|
---|
807 | if ok > 0:
|
---|
808 | s = AskString("Enter your first name", "Joe")
|
---|
809 | s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
|
---|
810 | if not s2:
|
---|
811 | Message("%s has no secret nickname"%s)
|
---|
812 | else:
|
---|
813 | Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
|
---|
814 | else:
|
---|
815 | s = 'Anonymous'
|
---|
816 | rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=Carbon.File.FSSpec)
|
---|
817 | Message("rv: %s"%rv)
|
---|
818 | rv = AskFileForSave(wanted=Carbon.File.FSRef, savedFileName="%s.txt"%s)
|
---|
819 | Message("rv.as_pathname: %s"%rv.as_pathname())
|
---|
820 | rv = AskFolder()
|
---|
821 | Message("Folder name: %s"%rv)
|
---|
822 | text = ( "Working Hard...", "Hardly Working..." ,
|
---|
823 | "So far, so good!", "Keep on truckin'" )
|
---|
824 | bar = ProgressBar("Progress, progress...", 0, label="Ramping up...")
|
---|
825 | try:
|
---|
826 | if hasattr(MacOS, 'SchedParams'):
|
---|
827 | appsw = MacOS.SchedParams(1, 0)
|
---|
828 | for i in xrange(20):
|
---|
829 | bar.inc()
|
---|
830 | time.sleep(0.05)
|
---|
831 | bar.set(0,100)
|
---|
832 | for i in xrange(100):
|
---|
833 | bar.set(i)
|
---|
834 | time.sleep(0.05)
|
---|
835 | if i % 10 == 0:
|
---|
836 | bar.label(text[(i/10) % 4])
|
---|
837 | bar.label("Done.")
|
---|
838 | time.sleep(1.0) # give'em a chance to see "Done."
|
---|
839 | finally:
|
---|
840 | del bar
|
---|
841 | if hasattr(MacOS, 'SchedParams'):
|
---|
842 | MacOS.SchedParams(*appsw)
|
---|
843 |
|
---|
844 | if __name__ == '__main__':
|
---|
845 | try:
|
---|
846 | test()
|
---|
847 | except KeyboardInterrupt:
|
---|
848 | Message("Operation Canceled.")
|
---|