Teach Windows build and installer about new _symtable module/DLL.
[python/dscho.git] / Mac / Lib / EasyDialogs.py
blobcfd55a16cbb4a7d0a64063706c4b3f363bf598a7
1 """Easy to use dialogs.
3 Message(msg) -- display a message and an OK button.
4 AskString(prompt, default) -- ask for a string, display OK and Cancel buttons.
5 AskPassword(prompt, default) -- like AskString(), but shows text as bullets.
6 AskYesNoCancel(question, default) -- display a question and Yes, No and Cancel buttons.
7 bar = Progress(label, maxvalue) -- Display a progress bar
8 bar.set(value) -- Set value
9 bar.inc( *amount ) -- increment value by amount (default=1)
10 bar.label( *newlabel ) -- get or set text label.
12 More documentation in each function.
13 This module uses DLOG resources 260 and on.
14 Based upon STDWIN dialogs with the same names and functions.
15 """
17 from Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText, ModalDialog
18 import Qd
19 import QuickDraw
20 import Dialogs
21 import Windows
22 import Dlg,Win,Evt,Events # sdm7g
23 import Ctl
24 import Controls
25 import Menu
26 import MacOS
27 import string
28 from ControlAccessor import * # Also import Controls constants
29 import macfs
31 def cr2lf(text):
32 if '\r' in text:
33 text = string.join(string.split(text, '\r'), '\n')
34 return text
36 def lf2cr(text):
37 if '\n' in text:
38 text = string.join(string.split(text, '\n'), '\r')
39 if len(text) > 253:
40 text = text[:253] + '\311'
41 return text
43 def Message(msg, id=260, ok=None):
44 """Display a MESSAGE string.
46 Return when the user clicks the OK button or presses Return.
48 The MESSAGE string can be at most 255 characters long.
49 """
51 d = GetNewDialog(id, -1)
52 if not d:
53 print "Can't get DLOG resource with id =", id
54 return
55 h = d.GetDialogItemAsControl(2)
56 SetDialogItemText(h, lf2cr(msg))
57 if ok != None:
58 h = d.GetDialogItemAsControl(1)
59 h.SetControlTitle(ok)
60 d.SetDialogDefaultItem(1)
61 d.AutoSizeDialog()
62 d.GetDialogWindow().ShowWindow()
63 while 1:
64 n = ModalDialog(None)
65 if n == 1:
66 return
69 def AskString(prompt, default = "", id=261, ok=None, cancel=None):
70 """Display a PROMPT string and a text entry field with a DEFAULT string.
72 Return the contents of the text entry field when the user clicks the
73 OK button or presses Return.
74 Return None when the user clicks the Cancel button.
76 If omitted, DEFAULT is empty.
78 The PROMPT and DEFAULT strings, as well as the return value,
79 can be at most 255 characters long.
80 """
82 d = GetNewDialog(id, -1)
83 if not d:
84 print "Can't get DLOG resource with id =", id
85 return
86 h = d.GetDialogItemAsControl(3)
87 SetDialogItemText(h, lf2cr(prompt))
88 h = d.GetDialogItemAsControl(4)
89 SetDialogItemText(h, lf2cr(default))
90 d.SelectDialogItemText(4, 0, 999)
91 # d.SetDialogItem(4, 0, 255)
92 if ok != None:
93 h = d.GetDialogItemAsControl(1)
94 h.SetControlTitle(ok)
95 if cancel != None:
96 h = d.GetDialogItemAsControl(2)
97 h.SetControlTitle(cancel)
98 d.SetDialogDefaultItem(1)
99 d.SetDialogCancelItem(2)
100 d.AutoSizeDialog()
101 d.GetDialogWindow().ShowWindow()
102 while 1:
103 n = ModalDialog(None)
104 if n == 1:
105 h = d.GetDialogItemAsControl(4)
106 return cr2lf(GetDialogItemText(h))
107 if n == 2: return None
109 def AskPassword(prompt, default='', id=264, ok=None, cancel=None):
110 """Display a PROMPT string and a text entry field with a DEFAULT string.
111 The string is displayed as bullets only.
113 Return the contents of the text entry field when the user clicks the
114 OK button or presses Return.
115 Return None when the user clicks the Cancel button.
117 If omitted, DEFAULT is empty.
119 The PROMPT and DEFAULT strings, as well as the return value,
120 can be at most 255 characters long.
122 d = GetNewDialog(id, -1)
123 if not d:
124 print "Can't get DLOG resource with id =", id
125 return
126 h = d.GetDialogItemAsControl(3)
127 SetDialogItemText(h, lf2cr(prompt))
128 pwd = d.GetDialogItemAsControl(4)
129 bullets = '\245'*len(default)
130 ## SetControlData(pwd, kControlEditTextPart, kControlEditTextTextTag, bullets)
131 SetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag, default)
132 d.SelectDialogItemText(4, 0, 999)
133 Ctl.SetKeyboardFocus(d.GetDialogWindow(), pwd, kControlEditTextPart)
134 if ok != None:
135 h = d.GetDialogItemAsControl(1)
136 h.SetControlTitle(ok)
137 if cancel != None:
138 h = d.GetDialogItemAsControl(2)
139 h.SetControlTitle(cancel)
140 d.SetDialogDefaultItem(Dialogs.ok)
141 d.SetDialogCancelItem(Dialogs.cancel)
142 d.AutoSizeDialog()
143 d.GetDialogWindow().ShowWindow()
144 while 1:
145 n = ModalDialog(None)
146 if n == 1:
147 h = d.GetDialogItemAsControl(4)
148 return cr2lf(GetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag))
149 if n == 2: return None
151 def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=262):
152 """Display a QUESTION string which can be answered with Yes or No.
154 Return 1 when the user clicks the Yes button.
155 Return 0 when the user clicks the No button.
156 Return -1 when the user clicks the Cancel button.
158 When the user presses Return, the DEFAULT value is returned.
159 If omitted, this is 0 (No).
161 The QUESTION strign ca be at most 255 characters.
164 d = GetNewDialog(id, -1)
165 if not d:
166 print "Can't get DLOG resource with id =", id
167 return
168 # Button assignments:
169 # 1 = default (invisible)
170 # 2 = Yes
171 # 3 = No
172 # 4 = Cancel
173 # The question string is item 5
174 h = d.GetDialogItemAsControl(5)
175 SetDialogItemText(h, lf2cr(question))
176 if yes != None:
177 if yes == '':
178 d.HideDialogItem(2)
179 else:
180 h = d.GetDialogItemAsControl(2)
181 h.SetControlTitle(yes)
182 if no != None:
183 if no == '':
184 d.HideDialogItem(3)
185 else:
186 h = d.GetDialogItemAsControl(3)
187 h.SetControlTitle(no)
188 if cancel != None:
189 if cancel == '':
190 d.HideDialogItem(4)
191 else:
192 h = d.GetDialogItemAsControl(4)
193 h.SetControlTitle(cancel)
194 d.SetDialogCancelItem(4)
195 if default == 1:
196 d.SetDialogDefaultItem(2)
197 elif default == 0:
198 d.SetDialogDefaultItem(3)
199 elif default == -1:
200 d.SetDialogDefaultItem(4)
201 d.AutoSizeDialog()
202 d.GetDialogWindow().ShowWindow()
203 while 1:
204 n = ModalDialog(None)
205 if n == 1: return default
206 if n == 2: return 1
207 if n == 3: return 0
208 if n == 4: return -1
213 screenbounds = Qd.qd.screenBits.bounds
214 screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
215 screenbounds[2]-4, screenbounds[3]-4
218 class ProgressBar:
219 def __init__(self, title="Working...", maxval=100, label="", id=263):
220 self.maxval = maxval
221 self.curval = -1
222 self.d = GetNewDialog(id, -1)
223 self.label(label)
224 self._update(0)
225 self.d.AutoSizeDialog()
226 self.title(title)
227 self.d.GetDialogWindow().ShowWindow()
228 self.d.DrawDialog()
230 def __del__( self ):
231 self.d.BringToFront()
232 self.d.HideWindow()
233 del self.d
235 def title(self, newstr=""):
236 """title(text) - Set title of progress window"""
237 w = self.d.GetDialogWindow()
238 w.BringToFront()
239 w.SetWTitle(newstr)
241 def label( self, *newstr ):
242 """label(text) - Set text in progress box"""
243 self.d.GetDialogWindow().BringToFront()
244 if newstr:
245 self._label = lf2cr(newstr[0])
246 text_h = self.d.GetDialogItemAsControl(2)
247 SetDialogItemText(text_h, self._label)
249 def _update(self, value):
250 maxval = self.maxval
251 if maxval == 0:
252 # XXXX Quick fix. Should probably display an unknown duration
253 value = 0
254 maxval = 1
255 if maxval > 32767:
256 value = int(value/(maxval/32767.0))
257 maxval = 32767
258 progbar = self.d.GetDialogItemAsControl(3)
259 progbar.SetControlMaximum(maxval)
260 progbar.SetControlValue(value)
261 # Test for cancel button
263 ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1 )
264 if ready :
265 what,msg,when,where,mod = ev
266 part = Win.FindWindow(where)[0]
267 if Dlg.IsDialogEvent(ev):
268 ds = Dlg.DialogSelect(ev)
269 if ds[0] and ds[1] == self.d and ds[-1] == 1:
270 raise KeyboardInterrupt, ev
271 else:
272 if part == 4: # inDrag
273 self.d.DragWindow(where, screenbounds)
274 else:
275 MacOS.HandleEvent(ev)
278 def set(self, value, max=None):
279 """set(value) - Set progress bar position"""
280 if max != None:
281 self.maxval = max
282 if value < 0: value = 0
283 if value > self.maxval: value = self.maxval
284 self.curval = value
285 self._update(value)
287 def inc(self, n=1):
288 """inc(amt) - Increment progress bar position"""
289 self.set(self.curval + n)
291 ARGV_ID=265
292 ARGV_ITEM_OK=1
293 ARGV_ITEM_CANCEL=2
294 ARGV_OPTION_GROUP=3
295 ARGV_OPTION_EXPLAIN=4
296 ARGV_OPTION_VALUE=5
297 ARGV_OPTION_ADD=6
298 ARGV_COMMAND_GROUP=7
299 ARGV_COMMAND_EXPLAIN=8
300 ARGV_COMMAND_ADD=9
301 ARGV_ADD_OLDFILE=10
302 ARGV_ADD_NEWFILE=11
303 ARGV_ADD_FOLDER=12
304 ARGV_CMDLINE_GROUP=13
305 ARGV_CMDLINE_DATA=14
307 ##def _myModalDialog(d):
308 ## while 1:
309 ## ready, ev = Evt.WaitNextEvent(0xffff, -1)
310 ## print 'DBG: WNE', ready, ev
311 ## if ready :
312 ## what,msg,when,where,mod = ev
313 ## part, window = Win.FindWindow(where)
314 ## if Dlg.IsDialogEvent(ev):
315 ## didit, dlgdone, itemdone = Dlg.DialogSelect(ev)
316 ## print 'DBG: DialogSelect', didit, dlgdone, itemdone, d
317 ## if didit and dlgdone == d:
318 ## return itemdone
319 ## elif window == d.GetDialogWindow():
320 ## d.GetDialogWindow().SelectWindow()
321 ## if part == 4: # inDrag
322 ## d.DragWindow(where, screenbounds)
323 ## else:
324 ## MacOS.HandleEvent(ev)
325 ## else:
326 ## MacOS.HandleEvent(ev)
328 def _setmenu(control, items):
329 mhandle = control.GetControlData_Handle(Controls.kControlMenuPart,
330 Controls.kControlPopupButtonMenuHandleTag)
331 menu = Menu.as_Menu(mhandle)
332 for item in items:
333 if type(item) == type(()):
334 label = item[0]
335 else:
336 label = item
337 if label[-1] == '=' or label[-1] == ':':
338 label = label[:-1]
339 menu.AppendMenu(label)
340 ## mhandle, mid = menu.getpopupinfo()
341 ## control.SetControlData_Handle(Controls.kControlMenuPart,
342 ## Controls.kControlPopupButtonMenuHandleTag, mhandle)
343 control.SetControlMinimum(1)
344 control.SetControlMaximum(len(items)+1)
346 def _selectoption(d, optionlist, idx):
347 if idx < 0 or idx >= len(optionlist):
348 MacOS.SysBeep()
349 return
350 option = optionlist[idx]
351 if type(option) == type(()) and \
352 len(option) > 1:
353 help = option[-1]
354 else:
355 help = ''
356 h = d.GetDialogItemAsControl(ARGV_OPTION_EXPLAIN)
357 Dlg.SetDialogItemText(h, help)
358 hasvalue = 0
359 if type(option) == type(()):
360 label = option[0]
361 else:
362 label = option
363 if label[-1] == '=' or label[-1] == ':':
364 hasvalue = 1
365 h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
366 Dlg.SetDialogItemText(h, '')
367 if hasvalue:
368 d.ShowDialogItem(ARGV_OPTION_VALUE)
369 d.SelectDialogItemText(ARGV_OPTION_VALUE, 0, 0)
370 else:
371 d.HideDialogItem(ARGV_OPTION_VALUE)
374 def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID):
375 d = GetNewDialog(id, -1)
376 if not d:
377 print "Can't get DLOG resource with id =", id
378 return
379 # h = d.GetDialogItemAsControl(3)
380 # SetDialogItemText(h, lf2cr(prompt))
381 # h = d.GetDialogItemAsControl(4)
382 # SetDialogItemText(h, lf2cr(default))
383 # d.SelectDialogItemText(4, 0, 999)
384 # d.SetDialogItem(4, 0, 255)
385 if optionlist:
386 _setmenu(d.GetDialogItemAsControl(ARGV_OPTION_GROUP), optionlist)
387 _selectoption(d, optionlist, 0)
388 else:
389 d.GetDialogItemAsControl(ARGV_OPTION_GROUP).DeactivateControl()
390 if commandlist:
391 _setmenu(d.GetDialogItemAsControl(ARGV_COMMAND_GROUP), commandlist)
392 if type(commandlist[0]) == type(()) and len(commandlist[0]) > 1:
393 help = commandlist[0][-1]
394 h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
395 Dlg.SetDialogItemText(h, help)
396 else:
397 d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).DeactivateControl()
398 if not addoldfile:
399 d.GetDialogItemAsControl(ARGV_ADD_OLDFILE).DeactivateControl()
400 if not addnewfile:
401 d.GetDialogItemAsControl(ARGV_ADD_NEWFILE).DeactivateControl()
402 if not addfolder:
403 d.GetDialogItemAsControl(ARGV_ADD_FOLDER).DeactivateControl()
404 d.SetDialogDefaultItem(ARGV_ITEM_OK)
405 d.SetDialogCancelItem(ARGV_ITEM_CANCEL)
406 d.GetDialogWindow().ShowWindow()
407 d.DrawDialog()
408 appsw = MacOS.SchedParams(1, 0)
409 try:
410 while 1:
411 stringstoadd = []
412 n = ModalDialog(None)
413 if n == ARGV_ITEM_OK:
414 break
415 elif n == ARGV_ITEM_CANCEL:
416 raise SystemExit
417 elif n == ARGV_OPTION_GROUP:
418 idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
419 _selectoption(d, optionlist, idx)
420 elif n == ARGV_OPTION_VALUE:
421 pass
422 elif n == ARGV_OPTION_ADD:
423 idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
424 if 0 <= idx < len(optionlist):
425 option = optionlist[idx]
426 if type(option) == type(()):
427 option = option[0]
428 if option[-1] == '=' or option[-1] == ':':
429 option = option[:-1]
430 h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
431 value = Dlg.GetDialogItemText(h)
432 else:
433 value = ''
434 if len(option) == 1:
435 stringtoadd = '-' + option
436 else:
437 stringtoadd = '--' + option
438 stringstoadd = [stringtoadd]
439 if value:
440 stringstoadd.append(value)
441 else:
442 MacOS.SysBeep()
443 elif n == ARGV_COMMAND_GROUP:
444 idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
445 if 0 <= idx < len(commandlist) and type(commandlist[idx]) == type(()) and \
446 len(commandlist[idx]) > 1:
447 help = commandlist[idx][-1]
448 h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
449 Dlg.SetDialogItemText(h, help)
450 elif n == ARGV_COMMAND_ADD:
451 idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
452 if 0 <= idx < len(commandlist):
453 command = commandlist[idx]
454 if type(command) == type(()):
455 command = command[0]
456 stringstoadd = [command]
457 else:
458 MacOS.SysBeep()
459 elif n == ARGV_ADD_OLDFILE:
460 fss, ok = macfs.StandardGetFile()
461 if ok:
462 stringstoadd = [fss.as_pathname()]
463 elif n == ARGV_ADD_NEWFILE:
464 fss, ok = macfs.StandardPutFile('')
465 if ok:
466 stringstoadd = [fss.as_pathname()]
467 elif n == ARGV_ADD_FOLDER:
468 fss, ok = macfs.GetDirectory()
469 if ok:
470 stringstoadd = [fss.as_pathname()]
471 elif n == ARGV_CMDLINE_DATA:
472 pass # Nothing to do
473 else:
474 raise RuntimeError, "Unknown dialog item %d"%n
476 for stringtoadd in stringstoadd:
477 if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
478 stringtoadd = `stringtoadd`
479 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
480 oldstr = GetDialogItemText(h)
481 if oldstr and oldstr[-1] != ' ':
482 oldstr = oldstr + ' '
483 oldstr = oldstr + stringtoadd
484 if oldstr[-1] != ' ':
485 oldstr = oldstr + ' '
486 SetDialogItemText(h, oldstr)
487 d.SelectDialogItemText(ARGV_CMDLINE_DATA, 0x7fff, 0x7fff)
488 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
489 oldstr = GetDialogItemText(h)
490 tmplist = string.split(oldstr)
491 newlist = []
492 while tmplist:
493 item = tmplist[0]
494 del tmplist[0]
495 if item[0] == '"':
496 while item[-1] != '"':
497 if not tmplist:
498 raise RuntimeError, "Unterminated quoted argument"
499 item = item + ' ' + tmplist[0]
500 del tmplist[0]
501 item = item[1:-1]
502 if item[0] == "'":
503 while item[-1] != "'":
504 if not tmplist:
505 raise RuntimeError, "Unterminated quoted argument"
506 item = item + ' ' + tmplist[0]
507 del tmplist[0]
508 item = item[1:-1]
509 newlist.append(item)
510 return newlist
511 finally:
512 apply(MacOS.SchedParams, appsw)
513 del d
515 def test():
516 import time, sys
518 Message("Testing EasyDialogs.")
519 optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
520 ('flags=', 'Valued option'), ('f:', 'Short valued option'))
521 commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
522 argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
523 for i in range(len(argv)):
524 print 'arg[%d] = %s'%(i, `argv[i]`)
525 print 'Type return to continue - ',
526 sys.stdin.readline()
527 ok = AskYesNoCancel("Do you want to proceed?")
528 ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
529 if ok > 0:
530 s = AskString("Enter your first name", "Joe")
531 s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
532 if not s2:
533 Message("%s has no secret nickname"%s)
534 else:
535 Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
536 text = ( "Working Hard...", "Hardly Working..." ,
537 "So far, so good!", "Keep on truckin'" )
538 bar = ProgressBar("Progress, progress...", 100)
539 try:
540 appsw = MacOS.SchedParams(1, 0)
541 for i in range(100):
542 bar.set(i)
543 time.sleep(0.1)
544 if i % 10 == 0:
545 bar.label(text[(i/10) % 4])
546 bar.label("Done.")
547 time.sleep(0.3) # give'em a chance to see the done.
548 finally:
549 del bar
550 apply(MacOS.SchedParams, appsw)
552 if __name__ == '__main__':
553 try:
554 test()
555 except KeyboardInterrupt:
556 Message("Operation Canceled.")