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