1"""Easy to use dialogs. 2 3Message(msg) -- display a message and an OK button. 4AskString(prompt, default) -- ask for a string, display OK and Cancel buttons. 5AskPassword(prompt, default) -- like AskString(), but shows text as bullets. 6AskYesNoCancel(question, default) -- display a question and Yes, No and Cancel buttons. 7GetArgv(optionlist, commandlist) -- fill a sys.argv-like list using a dialog 8AskFileForOpen(...) -- Ask the user for an existing file 9AskFileForSave(...) -- Ask the user for an output file 10AskFolder(...) -- Ask the user to select a folder 11bar = Progress(label, maxvalue) -- Display a progress bar 12bar.set(value) -- Set value 13bar.inc( *amount ) -- increment value by amount (default=1) 14bar.label( *newlabel ) -- get or set text label. 15 16More documentation in each function. 17This module uses DLOG resources 260 and on. 18Based upon STDWIN dialogs with the same names and functions. 19""" 20 21from warnings import warnpy3k 22warnpy3k("In 3.x, the EasyDialogs module is removed.", stacklevel=2) 23 24from Carbon.Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText, ModalDialog 25from Carbon import Qd 26from Carbon import QuickDraw 27from Carbon import Dialogs 28from Carbon import Windows 29from Carbon import Dlg,Win,Evt,Events # sdm7g 30from Carbon import Ctl 31from Carbon import Controls 32from Carbon import Menu 33from Carbon import AE 34import Nav 35import MacOS 36import string 37from Carbon.ControlAccessor import * # Also import Controls constants 38import Carbon.File 39import macresource 40import os 41import sys 42 43__all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel', 44 'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder', 45 'ProgressBar'] 46 47_initialized = 0 48 49def _initialize(): 50 global _initialized 51 if _initialized: return 52 macresource.need("DLOG", 260, "dialogs.rsrc", __name__) 53 54def _interact(): 55 """Make sure the application is in the foreground""" 56 AE.AEInteractWithUser(50000000) 57 58def cr2lf(text): 59 if '\r' in text: 60 text = string.join(string.split(text, '\r'), '\n') 61 return text 62 63def 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 70def 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 97def 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 139def 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 183def 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 250try: 251 screenbounds = Qd.GetQDGlobalsScreenBits().bounds 252except AttributeError: 253 raise ImportError("QuickDraw APIs not available") 254 255screenbounds = screenbounds[0]+4, screenbounds[1]+4, \ 256 screenbounds[2]-4, screenbounds[3]-4 257 258kControlProgressBarIndeterminateTag = 'inde' # from Controls.py 259 260 261class 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 348ARGV_ID=265 349ARGV_ITEM_OK=1 350ARGV_ITEM_CANCEL=2 351ARGV_OPTION_GROUP=3 352ARGV_OPTION_EXPLAIN=4 353ARGV_OPTION_VALUE=5 354ARGV_OPTION_ADD=6 355ARGV_COMMAND_GROUP=7 356ARGV_COMMAND_EXPLAIN=8 357ARGV_COMMAND_ADD=9 358ARGV_ADD_OLDFILE=10 359ARGV_ADD_NEWFILE=11 360ARGV_ADD_FOLDER=12 361ARGV_CMDLINE_GROUP=13 362ARGV_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## 385def _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 403def _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 437def 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 582def _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 618def _dummy_Nav_eventproc(msg, data): 619 pass 620 621_default_Nav_eventproc = _dummy_Nav_eventproc 622 623def 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 631def 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 683def 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 743def 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 794def 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 844if __name__ == '__main__': 845 try: 846 test() 847 except KeyboardInterrupt: 848 Message("Operation Canceled.") 849