|
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.") |