This should finally fix #6896. Let's watch the buildbots.
[python.git] / Lib / plat-mac / EasyDialogs.py
blobbd097bd83666a75193538a2a07e9ae237b9cef8c
1 """Easy to use dialogs.
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.
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 """
21 from warnings import warnpy3k
22 warnpy3k("In 3.x, the EasyDialogs module is removed.", stacklevel=2)
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
43 __all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel',
44 'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder',
45 'ProgressBar']
47 _initialized = 0
49 def _initialize():
50 global _initialized
51 if _initialized: return
52 macresource.need("DLOG", 260, "dialogs.rsrc", __name__)
54 def _interact():
55 """Make sure the application is in the foreground"""
56 AE.AEInteractWithUser(50000000)
58 def cr2lf(text):
59 if '\r' in text:
60 text = string.join(string.split(text, '\r'), '\n')
61 return text
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
70 def Message(msg, id=260, ok=None):
71 """Display a MESSAGE string.
73 Return when the user clicks the OK button or presses Return.
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
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.
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.
104 If omitted, DEFAULT is empty.
106 The PROMPT and DEFAULT strings, as well as the return value,
107 can be at most 255 characters long.
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
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.
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.
147 If omitted, DEFAULT is empty.
149 The PROMPT and DEFAULT strings, as well as the return value,
150 can be at most 255 characters long.
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
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.
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.
190 When the user presses Return, the DEFAULT value is returned.
191 If omitted, this is 0 (No).
193 The QUESTION string can be at most 255 characters.
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
247 screenbounds = Qd.GetQDGlobalsScreenBits().bounds
248 screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
249 screenbounds[2]-4, screenbounds[3]-4
251 kControlProgressBarIndeterminateTag = 'inde' # from Controls.py
254 class ProgressBar:
255 def __init__(self, title="Working...", maxval=0, label="", id=263):
256 self.w = None
257 self.d = None
258 _initialize()
259 self.d = GetNewDialog(id, -1)
260 self.w = self.d.GetDialogWindow()
261 self.label(label)
262 self.title(title)
263 self.set(0, maxval)
264 self.d.AutoSizeDialog()
265 self.w.ShowWindow()
266 self.d.DrawDialog()
268 def __del__(self):
269 if self.w:
270 self.w.BringToFront()
271 self.w.HideWindow()
272 del self.w
273 del self.d
275 def title(self, newstr=""):
276 """title(text) - Set title of progress window"""
277 self.w.BringToFront()
278 self.w.SetWTitle(newstr)
280 def label(self, *newstr):
281 """label(text) - Set text in progress box"""
282 self.w.BringToFront()
283 if newstr:
284 self._label = lf2cr(newstr[0])
285 text_h = self.d.GetDialogItemAsControl(2)
286 SetDialogItemText(text_h, self._label)
288 def _update(self, value):
289 maxval = self.maxval
290 if maxval == 0: # an indeterminate bar
291 Ctl.IdleControls(self.w) # spin the barber pole
292 else: # a determinate bar
293 if maxval > 32767:
294 value = int(value/(maxval/32767.0))
295 maxval = 32767
296 maxval = int(maxval)
297 value = int(value)
298 progbar = self.d.GetDialogItemAsControl(3)
299 progbar.SetControlMaximum(maxval)
300 progbar.SetControlValue(value) # set the bar length
302 # Test for cancel button
303 ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1 )
304 if ready :
305 what,msg,when,where,mod = ev
306 part = Win.FindWindow(where)[0]
307 if Dlg.IsDialogEvent(ev):
308 ds = Dlg.DialogSelect(ev)
309 if ds[0] and ds[1] == self.d and ds[-1] == 1:
310 self.w.HideWindow()
311 self.w = None
312 self.d = None
313 raise KeyboardInterrupt, ev
314 else:
315 if part == 4: # inDrag
316 self.w.DragWindow(where, screenbounds)
317 else:
318 MacOS.HandleEvent(ev)
321 def set(self, value, max=None):
322 """set(value) - Set progress bar position"""
323 if max is not None:
324 self.maxval = max
325 bar = self.d.GetDialogItemAsControl(3)
326 if max <= 0: # indeterminate bar
327 bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x01')
328 else: # determinate bar
329 bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x00')
330 if value < 0:
331 value = 0
332 elif value > self.maxval:
333 value = self.maxval
334 self.curval = value
335 self._update(value)
337 def inc(self, n=1):
338 """inc(amt) - Increment progress bar position"""
339 self.set(self.curval + n)
341 ARGV_ID=265
342 ARGV_ITEM_OK=1
343 ARGV_ITEM_CANCEL=2
344 ARGV_OPTION_GROUP=3
345 ARGV_OPTION_EXPLAIN=4
346 ARGV_OPTION_VALUE=5
347 ARGV_OPTION_ADD=6
348 ARGV_COMMAND_GROUP=7
349 ARGV_COMMAND_EXPLAIN=8
350 ARGV_COMMAND_ADD=9
351 ARGV_ADD_OLDFILE=10
352 ARGV_ADD_NEWFILE=11
353 ARGV_ADD_FOLDER=12
354 ARGV_CMDLINE_GROUP=13
355 ARGV_CMDLINE_DATA=14
357 ##def _myModalDialog(d):
358 ## while 1:
359 ## ready, ev = Evt.WaitNextEvent(0xffff, -1)
360 ## print 'DBG: WNE', ready, ev
361 ## if ready :
362 ## what,msg,when,where,mod = ev
363 ## part, window = Win.FindWindow(where)
364 ## if Dlg.IsDialogEvent(ev):
365 ## didit, dlgdone, itemdone = Dlg.DialogSelect(ev)
366 ## print 'DBG: DialogSelect', didit, dlgdone, itemdone, d
367 ## if didit and dlgdone == d:
368 ## return itemdone
369 ## elif window == d.GetDialogWindow():
370 ## d.GetDialogWindow().SelectWindow()
371 ## if part == 4: # inDrag
372 ## d.DragWindow(where, screenbounds)
373 ## else:
374 ## MacOS.HandleEvent(ev)
375 ## else:
376 ## MacOS.HandleEvent(ev)
378 def _setmenu(control, items):
379 mhandle = control.GetControlData_Handle(Controls.kControlMenuPart,
380 Controls.kControlPopupButtonMenuHandleTag)
381 menu = Menu.as_Menu(mhandle)
382 for item in items:
383 if type(item) == type(()):
384 label = item[0]
385 else:
386 label = item
387 if label[-1] == '=' or label[-1] == ':':
388 label = label[:-1]
389 menu.AppendMenu(label)
390 ## mhandle, mid = menu.getpopupinfo()
391 ## control.SetControlData_Handle(Controls.kControlMenuPart,
392 ## Controls.kControlPopupButtonMenuHandleTag, mhandle)
393 control.SetControlMinimum(1)
394 control.SetControlMaximum(len(items)+1)
396 def _selectoption(d, optionlist, idx):
397 if idx < 0 or idx >= len(optionlist):
398 MacOS.SysBeep()
399 return
400 option = optionlist[idx]
401 if type(option) == type(()):
402 if len(option) == 4:
403 help = option[2]
404 elif len(option) > 1:
405 help = option[-1]
406 else:
407 help = ''
408 else:
409 help = ''
410 h = d.GetDialogItemAsControl(ARGV_OPTION_EXPLAIN)
411 if help and len(help) > 250:
412 help = help[:250] + '...'
413 Dlg.SetDialogItemText(h, help)
414 hasvalue = 0
415 if type(option) == type(()):
416 label = option[0]
417 else:
418 label = option
419 if label[-1] == '=' or label[-1] == ':':
420 hasvalue = 1
421 h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
422 Dlg.SetDialogItemText(h, '')
423 if hasvalue:
424 d.ShowDialogItem(ARGV_OPTION_VALUE)
425 d.SelectDialogItemText(ARGV_OPTION_VALUE, 0, 0)
426 else:
427 d.HideDialogItem(ARGV_OPTION_VALUE)
430 def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID):
431 _initialize()
432 _interact()
433 d = GetNewDialog(id, -1)
434 if not d:
435 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
436 return
437 # h = d.GetDialogItemAsControl(3)
438 # SetDialogItemText(h, lf2cr(prompt))
439 # h = d.GetDialogItemAsControl(4)
440 # SetDialogItemText(h, lf2cr(default))
441 # d.SelectDialogItemText(4, 0, 999)
442 # d.SetDialogItem(4, 0, 255)
443 if optionlist:
444 _setmenu(d.GetDialogItemAsControl(ARGV_OPTION_GROUP), optionlist)
445 _selectoption(d, optionlist, 0)
446 else:
447 d.GetDialogItemAsControl(ARGV_OPTION_GROUP).DeactivateControl()
448 if commandlist:
449 _setmenu(d.GetDialogItemAsControl(ARGV_COMMAND_GROUP), commandlist)
450 if type(commandlist[0]) == type(()) and len(commandlist[0]) > 1:
451 help = commandlist[0][-1]
452 h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
453 Dlg.SetDialogItemText(h, help)
454 else:
455 d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).DeactivateControl()
456 if not addoldfile:
457 d.GetDialogItemAsControl(ARGV_ADD_OLDFILE).DeactivateControl()
458 if not addnewfile:
459 d.GetDialogItemAsControl(ARGV_ADD_NEWFILE).DeactivateControl()
460 if not addfolder:
461 d.GetDialogItemAsControl(ARGV_ADD_FOLDER).DeactivateControl()
462 d.SetDialogDefaultItem(ARGV_ITEM_OK)
463 d.SetDialogCancelItem(ARGV_ITEM_CANCEL)
464 d.GetDialogWindow().ShowWindow()
465 d.DrawDialog()
466 if hasattr(MacOS, 'SchedParams'):
467 appsw = MacOS.SchedParams(1, 0)
468 try:
469 while 1:
470 stringstoadd = []
471 n = ModalDialog(None)
472 if n == ARGV_ITEM_OK:
473 break
474 elif n == ARGV_ITEM_CANCEL:
475 raise SystemExit
476 elif n == ARGV_OPTION_GROUP:
477 idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
478 _selectoption(d, optionlist, idx)
479 elif n == ARGV_OPTION_VALUE:
480 pass
481 elif n == ARGV_OPTION_ADD:
482 idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
483 if 0 <= idx < len(optionlist):
484 option = optionlist[idx]
485 if type(option) == type(()):
486 option = option[0]
487 if option[-1] == '=' or option[-1] == ':':
488 option = option[:-1]
489 h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
490 value = Dlg.GetDialogItemText(h)
491 else:
492 value = ''
493 if len(option) == 1:
494 stringtoadd = '-' + option
495 else:
496 stringtoadd = '--' + option
497 stringstoadd = [stringtoadd]
498 if value:
499 stringstoadd.append(value)
500 else:
501 MacOS.SysBeep()
502 elif n == ARGV_COMMAND_GROUP:
503 idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
504 if 0 <= idx < len(commandlist) and type(commandlist[idx]) == type(()) and \
505 len(commandlist[idx]) > 1:
506 help = commandlist[idx][-1]
507 h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
508 Dlg.SetDialogItemText(h, help)
509 elif n == ARGV_COMMAND_ADD:
510 idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
511 if 0 <= idx < len(commandlist):
512 command = commandlist[idx]
513 if type(command) == type(()):
514 command = command[0]
515 stringstoadd = [command]
516 else:
517 MacOS.SysBeep()
518 elif n == ARGV_ADD_OLDFILE:
519 pathname = AskFileForOpen()
520 if pathname:
521 stringstoadd = [pathname]
522 elif n == ARGV_ADD_NEWFILE:
523 pathname = AskFileForSave()
524 if pathname:
525 stringstoadd = [pathname]
526 elif n == ARGV_ADD_FOLDER:
527 pathname = AskFolder()
528 if pathname:
529 stringstoadd = [pathname]
530 elif n == ARGV_CMDLINE_DATA:
531 pass # Nothing to do
532 else:
533 raise RuntimeError, "Unknown dialog item %d"%n
535 for stringtoadd in stringstoadd:
536 if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
537 stringtoadd = repr(stringtoadd)
538 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
539 oldstr = GetDialogItemText(h)
540 if oldstr and oldstr[-1] != ' ':
541 oldstr = oldstr + ' '
542 oldstr = oldstr + stringtoadd
543 if oldstr[-1] != ' ':
544 oldstr = oldstr + ' '
545 SetDialogItemText(h, oldstr)
546 d.SelectDialogItemText(ARGV_CMDLINE_DATA, 0x7fff, 0x7fff)
547 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
548 oldstr = GetDialogItemText(h)
549 tmplist = string.split(oldstr)
550 newlist = []
551 while tmplist:
552 item = tmplist[0]
553 del tmplist[0]
554 if item[0] == '"':
555 while item[-1] != '"':
556 if not tmplist:
557 raise RuntimeError, "Unterminated quoted argument"
558 item = item + ' ' + tmplist[0]
559 del tmplist[0]
560 item = item[1:-1]
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 newlist.append(item)
569 return newlist
570 finally:
571 if hasattr(MacOS, 'SchedParams'):
572 MacOS.SchedParams(*appsw)
573 del d
575 def _process_Nav_args(dftflags, **args):
576 import Carbon.AppleEvents
577 import Carbon.AE
578 import Carbon.File
579 for k in args.keys():
580 if args[k] is None:
581 del args[k]
582 # Set some defaults, and modify some arguments
583 if not args.has_key('dialogOptionFlags'):
584 args['dialogOptionFlags'] = dftflags
585 if args.has_key('defaultLocation') and \
586 not isinstance(args['defaultLocation'], Carbon.AE.AEDesc):
587 defaultLocation = args['defaultLocation']
588 if isinstance(defaultLocation, Carbon.File.FSSpec):
589 args['defaultLocation'] = Carbon.AE.AECreateDesc(
590 Carbon.AppleEvents.typeFSS, defaultLocation.data)
591 else:
592 if not isinstance(defaultLocation, Carbon.File.FSRef):
593 defaultLocation = Carbon.File.FSRef(defaultLocation)
594 args['defaultLocation'] = Carbon.AE.AECreateDesc(
595 Carbon.AppleEvents.typeFSRef, defaultLocation.data)
596 if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType):
597 typeList = args['typeList'][:]
598 # Workaround for OSX typeless files:
599 if 'TEXT' in typeList and not '\0\0\0\0' in typeList:
600 typeList = typeList + ('\0\0\0\0',)
601 data = 'Pyth' + struct.pack("hh", 0, len(typeList))
602 for type in typeList:
603 data = data+type
604 args['typeList'] = Carbon.Res.Handle(data)
605 tpwanted = str
606 if args.has_key('wanted'):
607 tpwanted = args['wanted']
608 del args['wanted']
609 return args, tpwanted
611 def _dummy_Nav_eventproc(msg, data):
612 pass
614 _default_Nav_eventproc = _dummy_Nav_eventproc
616 def SetDefaultEventProc(proc):
617 global _default_Nav_eventproc
618 rv = _default_Nav_eventproc
619 if proc is None:
620 proc = _dummy_Nav_eventproc
621 _default_Nav_eventproc = proc
622 return rv
624 def AskFileForOpen(
625 message=None,
626 typeList=None,
627 # From here on the order is not documented
628 version=None,
629 defaultLocation=None,
630 dialogOptionFlags=None,
631 location=None,
632 clientName=None,
633 windowTitle=None,
634 actionButtonLabel=None,
635 cancelButtonLabel=None,
636 preferenceKey=None,
637 popupExtension=None,
638 eventProc=_dummy_Nav_eventproc,
639 previewProc=None,
640 filterProc=None,
641 wanted=None,
642 multiple=None):
643 """Display a dialog asking the user for a file to open.
645 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
646 the other arguments can be looked up in Apple's Navigation Services documentation"""
648 default_flags = 0x56 # Or 0xe4?
649 args, tpwanted = _process_Nav_args(default_flags, version=version,
650 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
651 location=location,clientName=clientName,windowTitle=windowTitle,
652 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
653 message=message,preferenceKey=preferenceKey,
654 popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc,
655 filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple)
656 _interact()
657 try:
658 rr = Nav.NavChooseFile(args)
659 good = 1
660 except Nav.error, arg:
661 if arg[0] != -128: # userCancelledErr
662 raise Nav.error, arg
663 return None
664 if not rr.validRecord or not rr.selection:
665 return None
666 if issubclass(tpwanted, Carbon.File.FSRef):
667 return tpwanted(rr.selection_fsr[0])
668 if issubclass(tpwanted, Carbon.File.FSSpec):
669 return tpwanted(rr.selection[0])
670 if issubclass(tpwanted, str):
671 return tpwanted(rr.selection_fsr[0].as_pathname())
672 if issubclass(tpwanted, unicode):
673 return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
674 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
676 def AskFileForSave(
677 message=None,
678 savedFileName=None,
679 # From here on the order is not documented
680 version=None,
681 defaultLocation=None,
682 dialogOptionFlags=None,
683 location=None,
684 clientName=None,
685 windowTitle=None,
686 actionButtonLabel=None,
687 cancelButtonLabel=None,
688 preferenceKey=None,
689 popupExtension=None,
690 eventProc=_dummy_Nav_eventproc,
691 fileType=None,
692 fileCreator=None,
693 wanted=None,
694 multiple=None):
695 """Display a dialog asking the user for a filename to save to.
697 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
698 the other arguments can be looked up in Apple's Navigation Services documentation"""
701 default_flags = 0x07
702 args, tpwanted = _process_Nav_args(default_flags, version=version,
703 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
704 location=location,clientName=clientName,windowTitle=windowTitle,
705 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
706 savedFileName=savedFileName,message=message,preferenceKey=preferenceKey,
707 popupExtension=popupExtension,eventProc=eventProc,fileType=fileType,
708 fileCreator=fileCreator,wanted=wanted,multiple=multiple)
709 _interact()
710 try:
711 rr = Nav.NavPutFile(args)
712 good = 1
713 except Nav.error, arg:
714 if arg[0] != -128: # userCancelledErr
715 raise Nav.error, arg
716 return None
717 if not rr.validRecord or not rr.selection:
718 return None
719 if issubclass(tpwanted, Carbon.File.FSRef):
720 raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave"
721 if issubclass(tpwanted, Carbon.File.FSSpec):
722 return tpwanted(rr.selection[0])
723 if issubclass(tpwanted, (str, unicode)):
724 if sys.platform == 'mac':
725 fullpath = rr.selection[0].as_pathname()
726 else:
727 # This is gross, and probably incorrect too
728 vrefnum, dirid, name = rr.selection[0].as_tuple()
729 pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, ''))
730 pardir_fsr = Carbon.File.FSRef(pardir_fss)
731 pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8
732 name_utf8 = unicode(name, 'macroman').encode('utf8')
733 fullpath = os.path.join(pardir_path, name_utf8)
734 if issubclass(tpwanted, unicode):
735 return unicode(fullpath, 'utf8')
736 return tpwanted(fullpath)
737 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
739 def AskFolder(
740 message=None,
741 # From here on the order is not documented
742 version=None,
743 defaultLocation=None,
744 dialogOptionFlags=None,
745 location=None,
746 clientName=None,
747 windowTitle=None,
748 actionButtonLabel=None,
749 cancelButtonLabel=None,
750 preferenceKey=None,
751 popupExtension=None,
752 eventProc=_dummy_Nav_eventproc,
753 filterProc=None,
754 wanted=None,
755 multiple=None):
756 """Display a dialog asking the user for select a folder.
758 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
759 the other arguments can be looked up in Apple's Navigation Services documentation"""
761 default_flags = 0x17
762 args, tpwanted = _process_Nav_args(default_flags, version=version,
763 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
764 location=location,clientName=clientName,windowTitle=windowTitle,
765 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
766 message=message,preferenceKey=preferenceKey,
767 popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc,
768 wanted=wanted,multiple=multiple)
769 _interact()
770 try:
771 rr = Nav.NavChooseFolder(args)
772 good = 1
773 except Nav.error, arg:
774 if arg[0] != -128: # userCancelledErr
775 raise Nav.error, arg
776 return None
777 if not rr.validRecord or not rr.selection:
778 return None
779 if issubclass(tpwanted, Carbon.File.FSRef):
780 return tpwanted(rr.selection_fsr[0])
781 if issubclass(tpwanted, Carbon.File.FSSpec):
782 return tpwanted(rr.selection[0])
783 if issubclass(tpwanted, str):
784 return tpwanted(rr.selection_fsr[0].as_pathname())
785 if issubclass(tpwanted, unicode):
786 return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
787 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
790 def test():
791 import time
793 Message("Testing EasyDialogs.")
794 optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
795 ('flags=', 'Valued option'), ('f:', 'Short valued option'))
796 commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
797 argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
798 Message("Command line: %s"%' '.join(argv))
799 for i in range(len(argv)):
800 print 'arg[%d] = %r' % (i, argv[i])
801 ok = AskYesNoCancel("Do you want to proceed?")
802 ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
803 if ok > 0:
804 s = AskString("Enter your first name", "Joe")
805 s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
806 if not s2:
807 Message("%s has no secret nickname"%s)
808 else:
809 Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
810 else:
811 s = 'Anonymous'
812 rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=Carbon.File.FSSpec)
813 Message("rv: %s"%rv)
814 rv = AskFileForSave(wanted=Carbon.File.FSRef, savedFileName="%s.txt"%s)
815 Message("rv.as_pathname: %s"%rv.as_pathname())
816 rv = AskFolder()
817 Message("Folder name: %s"%rv)
818 text = ( "Working Hard...", "Hardly Working..." ,
819 "So far, so good!", "Keep on truckin'" )
820 bar = ProgressBar("Progress, progress...", 0, label="Ramping up...")
821 try:
822 if hasattr(MacOS, 'SchedParams'):
823 appsw = MacOS.SchedParams(1, 0)
824 for i in xrange(20):
825 bar.inc()
826 time.sleep(0.05)
827 bar.set(0,100)
828 for i in xrange(100):
829 bar.set(i)
830 time.sleep(0.05)
831 if i % 10 == 0:
832 bar.label(text[(i/10) % 4])
833 bar.label("Done.")
834 time.sleep(1.0) # give'em a chance to see "Done."
835 finally:
836 del bar
837 if hasattr(MacOS, 'SchedParams'):
838 MacOS.SchedParams(*appsw)
840 if __name__ == '__main__':
841 try:
842 test()
843 except KeyboardInterrupt:
844 Message("Operation Canceled.")