symbian-qemu-0.9.1-12/python-2.6.1/Lib/plat-mac/EasyDialogs.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 
       
   247 screenbounds = Qd.GetQDGlobalsScreenBits().bounds
       
   248 screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
       
   249     screenbounds[2]-4, screenbounds[3]-4
       
   250 
       
   251 kControlProgressBarIndeterminateTag = 'inde'    # from Controls.py
       
   252 
       
   253 
       
   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()
       
   267 
       
   268     def __del__(self):
       
   269         if self.w:
       
   270             self.w.BringToFront()
       
   271             self.w.HideWindow()
       
   272         del self.w
       
   273         del self.d
       
   274 
       
   275     def title(self, newstr=""):
       
   276         """title(text) - Set title of progress window"""
       
   277         self.w.BringToFront()
       
   278         self.w.SetWTitle(newstr)
       
   279 
       
   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)
       
   287 
       
   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
       
   301 
       
   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)
       
   319 
       
   320 
       
   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)
       
   336 
       
   337     def inc(self, n=1):
       
   338         """inc(amt) - Increment progress bar position"""
       
   339         self.set(self.curval + n)
       
   340 
       
   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
       
   356 
       
   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)
       
   377 ##
       
   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)
       
   395 
       
   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)
       
   428 
       
   429 
       
   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
       
   534 
       
   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
       
   574 
       
   575 def _process_Nav_args(dftflags, **args):
       
   576     import aepack
       
   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, Carbon.File.FSRef)):
       
   589             args['defaultLocation'] = aepack.pack(defaultLocation)
       
   590         else:
       
   591             defaultLocation = Carbon.File.FSRef(defaultLocation)
       
   592             args['defaultLocation'] = aepack.pack(defaultLocation)
       
   593     if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType):
       
   594         typeList = args['typeList'][:]
       
   595         # Workaround for OSX typeless files:
       
   596         if 'TEXT' in typeList and not '\0\0\0\0' in typeList:
       
   597             typeList = typeList + ('\0\0\0\0',)
       
   598         data = 'Pyth' + struct.pack("hh", 0, len(typeList))
       
   599         for type in typeList:
       
   600             data = data+type
       
   601         args['typeList'] = Carbon.Res.Handle(data)
       
   602     tpwanted = str
       
   603     if args.has_key('wanted'):
       
   604         tpwanted = args['wanted']
       
   605         del args['wanted']
       
   606     return args, tpwanted
       
   607 
       
   608 def _dummy_Nav_eventproc(msg, data):
       
   609     pass
       
   610 
       
   611 _default_Nav_eventproc = _dummy_Nav_eventproc
       
   612 
       
   613 def SetDefaultEventProc(proc):
       
   614     global _default_Nav_eventproc
       
   615     rv = _default_Nav_eventproc
       
   616     if proc is None:
       
   617         proc = _dummy_Nav_eventproc
       
   618     _default_Nav_eventproc = proc
       
   619     return rv
       
   620 
       
   621 def AskFileForOpen(
       
   622         message=None,
       
   623         typeList=None,
       
   624         # From here on the order is not documented
       
   625         version=None,
       
   626         defaultLocation=None,
       
   627         dialogOptionFlags=None,
       
   628         location=None,
       
   629         clientName=None,
       
   630         windowTitle=None,
       
   631         actionButtonLabel=None,
       
   632         cancelButtonLabel=None,
       
   633         preferenceKey=None,
       
   634         popupExtension=None,
       
   635         eventProc=_dummy_Nav_eventproc,
       
   636         previewProc=None,
       
   637         filterProc=None,
       
   638         wanted=None,
       
   639         multiple=None):
       
   640     """Display a dialog asking the user for a file to open.
       
   641 
       
   642     wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
       
   643     the other arguments can be looked up in Apple's Navigation Services documentation"""
       
   644 
       
   645     default_flags = 0x56 # Or 0xe4?
       
   646     args, tpwanted = _process_Nav_args(default_flags, version=version,
       
   647         defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
       
   648         location=location,clientName=clientName,windowTitle=windowTitle,
       
   649         actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
       
   650         message=message,preferenceKey=preferenceKey,
       
   651         popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc,
       
   652         filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple)
       
   653     _interact()
       
   654     try:
       
   655         rr = Nav.NavChooseFile(args)
       
   656         good = 1
       
   657     except Nav.error, arg:
       
   658         if arg[0] != -128: # userCancelledErr
       
   659             raise Nav.error, arg
       
   660         return None
       
   661     if not rr.validRecord or not rr.selection:
       
   662         return None
       
   663     if issubclass(tpwanted, Carbon.File.FSRef):
       
   664         return tpwanted(rr.selection_fsr[0])
       
   665     if issubclass(tpwanted, Carbon.File.FSSpec):
       
   666         return tpwanted(rr.selection[0])
       
   667     if issubclass(tpwanted, str):
       
   668         return tpwanted(rr.selection_fsr[0].as_pathname())
       
   669     if issubclass(tpwanted, unicode):
       
   670         return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
       
   671     raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
       
   672 
       
   673 def AskFileForSave(
       
   674         message=None,
       
   675         savedFileName=None,
       
   676         # From here on the order is not documented
       
   677         version=None,
       
   678         defaultLocation=None,
       
   679         dialogOptionFlags=None,
       
   680         location=None,
       
   681         clientName=None,
       
   682         windowTitle=None,
       
   683         actionButtonLabel=None,
       
   684         cancelButtonLabel=None,
       
   685         preferenceKey=None,
       
   686         popupExtension=None,
       
   687         eventProc=_dummy_Nav_eventproc,
       
   688         fileType=None,
       
   689         fileCreator=None,
       
   690         wanted=None,
       
   691         multiple=None):
       
   692     """Display a dialog asking the user for a filename to save to.
       
   693 
       
   694     wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
       
   695     the other arguments can be looked up in Apple's Navigation Services documentation"""
       
   696 
       
   697 
       
   698     default_flags = 0x07
       
   699     args, tpwanted = _process_Nav_args(default_flags, version=version,
       
   700         defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
       
   701         location=location,clientName=clientName,windowTitle=windowTitle,
       
   702         actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
       
   703         savedFileName=savedFileName,message=message,preferenceKey=preferenceKey,
       
   704         popupExtension=popupExtension,eventProc=eventProc,fileType=fileType,
       
   705         fileCreator=fileCreator,wanted=wanted,multiple=multiple)
       
   706     _interact()
       
   707     try:
       
   708         rr = Nav.NavPutFile(args)
       
   709         good = 1
       
   710     except Nav.error, arg:
       
   711         if arg[0] != -128: # userCancelledErr
       
   712             raise Nav.error, arg
       
   713         return None
       
   714     if not rr.validRecord or not rr.selection:
       
   715         return None
       
   716     if issubclass(tpwanted, Carbon.File.FSRef):
       
   717         raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave"
       
   718     if issubclass(tpwanted, Carbon.File.FSSpec):
       
   719         return tpwanted(rr.selection[0])
       
   720     if issubclass(tpwanted, (str, unicode)):
       
   721         if sys.platform == 'mac':
       
   722             fullpath = rr.selection[0].as_pathname()
       
   723         else:
       
   724             # This is gross, and probably incorrect too
       
   725             vrefnum, dirid, name = rr.selection[0].as_tuple()
       
   726             pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, ''))
       
   727             pardir_fsr = Carbon.File.FSRef(pardir_fss)
       
   728             pardir_path = pardir_fsr.FSRefMakePath()  # This is utf-8
       
   729             name_utf8 = unicode(name, 'macroman').encode('utf8')
       
   730             fullpath = os.path.join(pardir_path, name_utf8)
       
   731         if issubclass(tpwanted, unicode):
       
   732             return unicode(fullpath, 'utf8')
       
   733         return tpwanted(fullpath)
       
   734     raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
       
   735 
       
   736 def AskFolder(
       
   737         message=None,
       
   738         # From here on the order is not documented
       
   739         version=None,
       
   740         defaultLocation=None,
       
   741         dialogOptionFlags=None,
       
   742         location=None,
       
   743         clientName=None,
       
   744         windowTitle=None,
       
   745         actionButtonLabel=None,
       
   746         cancelButtonLabel=None,
       
   747         preferenceKey=None,
       
   748         popupExtension=None,
       
   749         eventProc=_dummy_Nav_eventproc,
       
   750         filterProc=None,
       
   751         wanted=None,
       
   752         multiple=None):
       
   753     """Display a dialog asking the user for select a folder.
       
   754 
       
   755     wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
       
   756     the other arguments can be looked up in Apple's Navigation Services documentation"""
       
   757 
       
   758     default_flags = 0x17
       
   759     args, tpwanted = _process_Nav_args(default_flags, version=version,
       
   760         defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
       
   761         location=location,clientName=clientName,windowTitle=windowTitle,
       
   762         actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
       
   763         message=message,preferenceKey=preferenceKey,
       
   764         popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc,
       
   765         wanted=wanted,multiple=multiple)
       
   766     _interact()
       
   767     try:
       
   768         rr = Nav.NavChooseFolder(args)
       
   769         good = 1
       
   770     except Nav.error, arg:
       
   771         if arg[0] != -128: # userCancelledErr
       
   772             raise Nav.error, arg
       
   773         return None
       
   774     if not rr.validRecord or not rr.selection:
       
   775         return None
       
   776     if issubclass(tpwanted, Carbon.File.FSRef):
       
   777         return tpwanted(rr.selection_fsr[0])
       
   778     if issubclass(tpwanted, Carbon.File.FSSpec):
       
   779         return tpwanted(rr.selection[0])
       
   780     if issubclass(tpwanted, str):
       
   781         return tpwanted(rr.selection_fsr[0].as_pathname())
       
   782     if issubclass(tpwanted, unicode):
       
   783         return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
       
   784     raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
       
   785 
       
   786 
       
   787 def test():
       
   788     import time
       
   789 
       
   790     Message("Testing EasyDialogs.")
       
   791     optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
       
   792                 ('flags=', 'Valued option'), ('f:', 'Short valued option'))
       
   793     commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
       
   794     argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
       
   795     Message("Command line: %s"%' '.join(argv))
       
   796     for i in range(len(argv)):
       
   797         print 'arg[%d] = %r' % (i, argv[i])
       
   798     ok = AskYesNoCancel("Do you want to proceed?")
       
   799     ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
       
   800     if ok > 0:
       
   801         s = AskString("Enter your first name", "Joe")
       
   802         s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
       
   803         if not s2:
       
   804             Message("%s has no secret nickname"%s)
       
   805         else:
       
   806             Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
       
   807     else:
       
   808         s = 'Anonymous'
       
   809     rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=Carbon.File.FSSpec)
       
   810     Message("rv: %s"%rv)
       
   811     rv = AskFileForSave(wanted=Carbon.File.FSRef, savedFileName="%s.txt"%s)
       
   812     Message("rv.as_pathname: %s"%rv.as_pathname())
       
   813     rv = AskFolder()
       
   814     Message("Folder name: %s"%rv)
       
   815     text = ( "Working Hard...", "Hardly Working..." ,
       
   816             "So far, so good!", "Keep on truckin'" )
       
   817     bar = ProgressBar("Progress, progress...", 0, label="Ramping up...")
       
   818     try:
       
   819         if hasattr(MacOS, 'SchedParams'):
       
   820             appsw = MacOS.SchedParams(1, 0)
       
   821         for i in xrange(20):
       
   822             bar.inc()
       
   823             time.sleep(0.05)
       
   824         bar.set(0,100)
       
   825         for i in xrange(100):
       
   826             bar.set(i)
       
   827             time.sleep(0.05)
       
   828             if i % 10 == 0:
       
   829                 bar.label(text[(i/10) % 4])
       
   830         bar.label("Done.")
       
   831         time.sleep(1.0)     # give'em a chance to see "Done."
       
   832     finally:
       
   833         del bar
       
   834         if hasattr(MacOS, 'SchedParams'):
       
   835             MacOS.SchedParams(*appsw)
       
   836 
       
   837 if __name__ == '__main__':
       
   838     try:
       
   839         test()
       
   840     except KeyboardInterrupt:
       
   841         Message("Operation Canceled.")