blob: 6d157f90a2d53275c43e29e527ff6f2c21f92103 [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
Raymond Hettingerff41c482003-04-06 09:01:11 +000033from Carbon.ControlAccessor import * # Also import Controls constants
Jack Jansenf0d12da2003-01-17 16:04:39 +000034import Carbon.File
Jack Jansendde800e2002-11-07 23:07:05 +000035import macresource
Jack Jansene58962a2003-01-17 23:13:03 +000036import os
Jack Jansen2b3ce3b2003-01-26 20:22:41 +000037import sys
Jack Jansendde800e2002-11-07 23:07:05 +000038
Jack Jansen3032fe62003-01-21 14:38:32 +000039__all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel',
Just van Rossum35b50e22003-06-21 14:41:32 +000040 'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder',
41 'ProgressBar']
Raymond Hettingerff41c482003-04-06 09:01:11 +000042
Jack Jansendde800e2002-11-07 23:07:05 +000043_initialized = 0
44
45def _initialize():
Just van Rossum35b50e22003-06-21 14:41:32 +000046 global _initialized
47 if _initialized: return
48 macresource.need("DLOG", 260, "dialogs.rsrc", __name__)
Raymond Hettingerff41c482003-04-06 09:01:11 +000049
Jack Jansen7451e3b2003-03-03 12:25:02 +000050def _interact():
Just van Rossum35b50e22003-06-21 14:41:32 +000051 """Make sure the application is in the foreground"""
52 AE.AEInteractWithUser(50000000)
Jack Jansena5a49811998-07-01 15:47:44 +000053
54def cr2lf(text):
Just van Rossum35b50e22003-06-21 14:41:32 +000055 if '\r' in text:
Neal Norwitz9d72bb42007-04-17 08:48:32 +000056 text = '\n'.join(text.split('\r'))
Just van Rossum35b50e22003-06-21 14:41:32 +000057 return text
Jack Jansena5a49811998-07-01 15:47:44 +000058
59def lf2cr(text):
Just van Rossum35b50e22003-06-21 14:41:32 +000060 if '\n' in text:
Neal Norwitz9d72bb42007-04-17 08:48:32 +000061 text = '\r'.join(text.split('\n'))
Just van Rossum35b50e22003-06-21 14:41:32 +000062 if len(text) > 253:
63 text = text[:253] + '\311'
64 return text
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000065
Jack Jansencc386881999-12-12 22:57:51 +000066def Message(msg, id=260, ok=None):
Just van Rossum35b50e22003-06-21 14:41:32 +000067 """Display a MESSAGE string.
Raymond Hettingerff41c482003-04-06 09:01:11 +000068
Just van Rossum35b50e22003-06-21 14:41:32 +000069 Return when the user clicks the OK button or presses Return.
Raymond Hettingerff41c482003-04-06 09:01:11 +000070
Just van Rossum35b50e22003-06-21 14:41:32 +000071 The MESSAGE string can be at most 255 characters long.
72 """
73 _initialize()
74 _interact()
75 d = GetNewDialog(id, -1)
76 if not d:
Guido van Rossumbe19ed72007-02-09 05:37:30 +000077 print("EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)")
Just van Rossum35b50e22003-06-21 14:41:32 +000078 return
79 h = d.GetDialogItemAsControl(2)
80 SetDialogItemText(h, lf2cr(msg))
81 if ok != None:
82 h = d.GetDialogItemAsControl(1)
83 h.SetControlTitle(ok)
84 d.SetDialogDefaultItem(1)
85 d.AutoSizeDialog()
86 d.GetDialogWindow().ShowWindow()
87 while 1:
88 n = ModalDialog(None)
89 if n == 1:
90 return
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000091
92
Jack Jansencc386881999-12-12 22:57:51 +000093def AskString(prompt, default = "", id=261, ok=None, cancel=None):
Just van Rossum35b50e22003-06-21 14:41:32 +000094 """Display a PROMPT string and a text entry field with a DEFAULT string.
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000095
Just van Rossum35b50e22003-06-21 14:41:32 +000096 Return the contents of the text entry field when the user clicks the
97 OK button or presses Return.
98 Return None when the user clicks the Cancel button.
Raymond Hettingerff41c482003-04-06 09:01:11 +000099
Just van Rossum35b50e22003-06-21 14:41:32 +0000100 If omitted, DEFAULT is empty.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000101
Just van Rossum35b50e22003-06-21 14:41:32 +0000102 The PROMPT and DEFAULT strings, as well as the return value,
103 can be at most 255 characters long.
104 """
Raymond Hettingerff41c482003-04-06 09:01:11 +0000105
Just van Rossum35b50e22003-06-21 14:41:32 +0000106 _initialize()
107 _interact()
108 d = GetNewDialog(id, -1)
109 if not d:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000110 print("EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)")
Just van Rossum35b50e22003-06-21 14:41:32 +0000111 return
112 h = d.GetDialogItemAsControl(3)
113 SetDialogItemText(h, lf2cr(prompt))
114 h = d.GetDialogItemAsControl(4)
115 SetDialogItemText(h, lf2cr(default))
116 d.SelectDialogItemText(4, 0, 999)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000117# d.SetDialogItem(4, 0, 255)
Just van Rossum35b50e22003-06-21 14:41:32 +0000118 if ok != None:
119 h = d.GetDialogItemAsControl(1)
120 h.SetControlTitle(ok)
121 if cancel != None:
122 h = d.GetDialogItemAsControl(2)
123 h.SetControlTitle(cancel)
124 d.SetDialogDefaultItem(1)
125 d.SetDialogCancelItem(2)
126 d.AutoSizeDialog()
127 d.GetDialogWindow().ShowWindow()
128 while 1:
129 n = ModalDialog(None)
130 if n == 1:
131 h = d.GetDialogItemAsControl(4)
132 return cr2lf(GetDialogItemText(h))
133 if n == 2: return None
Raymond Hettingerff41c482003-04-06 09:01:11 +0000134
135def AskPassword(prompt, default='', id=264, ok=None, cancel=None):
Just van Rossum35b50e22003-06-21 14:41:32 +0000136 """Display a PROMPT string and a text entry field with a DEFAULT string.
137 The string is displayed as bullets only.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000138
Just van Rossum35b50e22003-06-21 14:41:32 +0000139 Return the contents of the text entry field when the user clicks the
140 OK button or presses Return.
141 Return None when the user clicks the Cancel button.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000142
Just van Rossum35b50e22003-06-21 14:41:32 +0000143 If omitted, DEFAULT is empty.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000144
Just van Rossum35b50e22003-06-21 14:41:32 +0000145 The PROMPT and DEFAULT strings, as well as the return value,
146 can be at most 255 characters long.
147 """
148 _initialize()
149 _interact()
150 d = GetNewDialog(id, -1)
151 if not d:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000152 print("EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)")
Just van Rossum35b50e22003-06-21 14:41:32 +0000153 return
154 h = d.GetDialogItemAsControl(3)
155 SetDialogItemText(h, lf2cr(prompt))
156 pwd = d.GetDialogItemAsControl(4)
157 bullets = '\245'*len(default)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000158## SetControlData(pwd, kControlEditTextPart, kControlEditTextTextTag, bullets)
Just van Rossum35b50e22003-06-21 14:41:32 +0000159 SetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag, default)
160 d.SelectDialogItemText(4, 0, 999)
161 Ctl.SetKeyboardFocus(d.GetDialogWindow(), pwd, kControlEditTextPart)
162 if ok != None:
163 h = d.GetDialogItemAsControl(1)
164 h.SetControlTitle(ok)
165 if cancel != None:
166 h = d.GetDialogItemAsControl(2)
167 h.SetControlTitle(cancel)
168 d.SetDialogDefaultItem(Dialogs.ok)
169 d.SetDialogCancelItem(Dialogs.cancel)
170 d.AutoSizeDialog()
171 d.GetDialogWindow().ShowWindow()
172 while 1:
173 n = ModalDialog(None)
174 if n == 1:
175 h = d.GetDialogItemAsControl(4)
176 return cr2lf(GetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag))
177 if n == 2: return None
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000178
Jack Jansencc386881999-12-12 22:57:51 +0000179def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=262):
Just van Rossum35b50e22003-06-21 14:41:32 +0000180 """Display a QUESTION string which can be answered with Yes or No.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000181
Just van Rossum35b50e22003-06-21 14:41:32 +0000182 Return 1 when the user clicks the Yes button.
183 Return 0 when the user clicks the No button.
184 Return -1 when the user clicks the Cancel button.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000185
Just van Rossum35b50e22003-06-21 14:41:32 +0000186 When the user presses Return, the DEFAULT value is returned.
187 If omitted, this is 0 (No).
Raymond Hettingerff41c482003-04-06 09:01:11 +0000188
Just van Rossum35b50e22003-06-21 14:41:32 +0000189 The QUESTION string can be at most 255 characters.
190 """
Raymond Hettingerff41c482003-04-06 09:01:11 +0000191
Just van Rossum35b50e22003-06-21 14:41:32 +0000192 _initialize()
193 _interact()
194 d = GetNewDialog(id, -1)
195 if not d:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000196 print("EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)")
Just van Rossum35b50e22003-06-21 14:41:32 +0000197 return
198 # Button assignments:
199 # 1 = default (invisible)
200 # 2 = Yes
201 # 3 = No
202 # 4 = Cancel
203 # The question string is item 5
204 h = d.GetDialogItemAsControl(5)
205 SetDialogItemText(h, lf2cr(question))
206 if yes != None:
207 if yes == '':
208 d.HideDialogItem(2)
209 else:
210 h = d.GetDialogItemAsControl(2)
211 h.SetControlTitle(yes)
212 if no != None:
213 if no == '':
214 d.HideDialogItem(3)
215 else:
216 h = d.GetDialogItemAsControl(3)
217 h.SetControlTitle(no)
218 if cancel != None:
219 if cancel == '':
220 d.HideDialogItem(4)
221 else:
222 h = d.GetDialogItemAsControl(4)
223 h.SetControlTitle(cancel)
224 d.SetDialogCancelItem(4)
225 if default == 1:
226 d.SetDialogDefaultItem(2)
227 elif default == 0:
228 d.SetDialogDefaultItem(3)
229 elif default == -1:
230 d.SetDialogDefaultItem(4)
231 d.AutoSizeDialog()
232 d.GetDialogWindow().ShowWindow()
233 while 1:
234 n = ModalDialog(None)
235 if n == 1: return default
236 if n == 2: return 1
237 if n == 3: return 0
238 if n == 4: return -1
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000239
240
Raymond Hettingerff41c482003-04-06 09:01:11 +0000241
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000242
Jack Jansen362c7cd02002-11-30 00:01:29 +0000243screenbounds = Qd.GetQDGlobalsScreenBits().bounds
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000244screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
Just van Rossum35b50e22003-06-21 14:41:32 +0000245 screenbounds[2]-4, screenbounds[3]-4
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000246
Raymond Hettingerff41c482003-04-06 09:01:11 +0000247kControlProgressBarIndeterminateTag = 'inde' # from Controls.py
Jack Jansen911e87d2001-08-27 15:24:07 +0000248
249
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000250class ProgressBar:
Just van Rossum35b50e22003-06-21 14:41:32 +0000251 def __init__(self, title="Working...", maxval=0, label="", id=263):
252 self.w = None
253 self.d = None
254 _initialize()
255 self.d = GetNewDialog(id, -1)
256 self.w = self.d.GetDialogWindow()
257 self.label(label)
258 self.title(title)
259 self.set(0, maxval)
260 self.d.AutoSizeDialog()
261 self.w.ShowWindow()
262 self.d.DrawDialog()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000263
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000264 def __del__(self):
Just van Rossum35b50e22003-06-21 14:41:32 +0000265 if self.w:
266 self.w.BringToFront()
267 self.w.HideWindow()
268 del self.w
269 del self.d
Jack Jansen911e87d2001-08-27 15:24:07 +0000270
Just van Rossum35b50e22003-06-21 14:41:32 +0000271 def title(self, newstr=""):
272 """title(text) - Set title of progress window"""
273 self.w.BringToFront()
274 self.w.SetWTitle(newstr)
Jack Jansen911e87d2001-08-27 15:24:07 +0000275
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000276 def label(self, *newstr):
Just van Rossum35b50e22003-06-21 14:41:32 +0000277 """label(text) - Set text in progress box"""
278 self.w.BringToFront()
279 if newstr:
280 self._label = lf2cr(newstr[0])
281 text_h = self.d.GetDialogItemAsControl(2)
282 SetDialogItemText(text_h, self._label)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000283
Just van Rossum35b50e22003-06-21 14:41:32 +0000284 def _update(self, value):
285 maxval = self.maxval
286 if maxval == 0: # an indeterminate bar
287 Ctl.IdleControls(self.w) # spin the barber pole
288 else: # a determinate bar
289 if maxval > 32767:
290 value = int(value/(maxval/32767.0))
291 maxval = 32767
292 maxval = int(maxval)
293 value = int(value)
294 progbar = self.d.GetDialogItemAsControl(3)
295 progbar.SetControlMaximum(maxval)
296 progbar.SetControlValue(value) # set the bar length
Raymond Hettingerff41c482003-04-06 09:01:11 +0000297
Just van Rossum35b50e22003-06-21 14:41:32 +0000298 # Test for cancel button
299 ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1 )
300 if ready :
301 what,msg,when,where,mod = ev
302 part = Win.FindWindow(where)[0]
303 if Dlg.IsDialogEvent(ev):
304 ds = Dlg.DialogSelect(ev)
305 if ds[0] and ds[1] == self.d and ds[-1] == 1:
306 self.w.HideWindow()
307 self.w = None
308 self.d = None
309 raise KeyboardInterrupt, ev
310 else:
311 if part == 4: # inDrag
312 self.w.DragWindow(where, screenbounds)
313 else:
314 MacOS.HandleEvent(ev)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000315
316
Just van Rossum35b50e22003-06-21 14:41:32 +0000317 def set(self, value, max=None):
318 """set(value) - Set progress bar position"""
319 if max != None:
320 self.maxval = max
321 bar = self.d.GetDialogItemAsControl(3)
322 if max <= 0: # indeterminate bar
323 bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x01')
324 else: # determinate bar
325 bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x00')
326 if value < 0:
327 value = 0
328 elif value > self.maxval:
329 value = self.maxval
330 self.curval = value
331 self._update(value)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000332
Just van Rossum35b50e22003-06-21 14:41:32 +0000333 def inc(self, n=1):
334 """inc(amt) - Increment progress bar position"""
335 self.set(self.curval + n)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000336
Jack Jansenf86eda52000-09-19 22:42:38 +0000337ARGV_ID=265
338ARGV_ITEM_OK=1
339ARGV_ITEM_CANCEL=2
340ARGV_OPTION_GROUP=3
341ARGV_OPTION_EXPLAIN=4
342ARGV_OPTION_VALUE=5
343ARGV_OPTION_ADD=6
344ARGV_COMMAND_GROUP=7
345ARGV_COMMAND_EXPLAIN=8
346ARGV_COMMAND_ADD=9
347ARGV_ADD_OLDFILE=10
348ARGV_ADD_NEWFILE=11
349ARGV_ADD_FOLDER=12
350ARGV_CMDLINE_GROUP=13
351ARGV_CMDLINE_DATA=14
352
353##def _myModalDialog(d):
Raymond Hettingerff41c482003-04-06 09:01:11 +0000354## while 1:
Just van Rossum35b50e22003-06-21 14:41:32 +0000355## ready, ev = Evt.WaitNextEvent(0xffff, -1)
356## print 'DBG: WNE', ready, ev
357## if ready :
358## what,msg,when,where,mod = ev
359## part, window = Win.FindWindow(where)
360## if Dlg.IsDialogEvent(ev):
361## didit, dlgdone, itemdone = Dlg.DialogSelect(ev)
362## print 'DBG: DialogSelect', didit, dlgdone, itemdone, d
363## if didit and dlgdone == d:
364## return itemdone
365## elif window == d.GetDialogWindow():
366## d.GetDialogWindow().SelectWindow()
367## if part == 4: # inDrag
368## d.DragWindow(where, screenbounds)
369## else:
370## MacOS.HandleEvent(ev)
371## else:
372## MacOS.HandleEvent(ev)
Jack Jansenf86eda52000-09-19 22:42:38 +0000373##
374def _setmenu(control, items):
Tim Peters182b5ac2004-07-18 06:16:08 +0000375 mhandle = control.GetControlData_Handle(Controls.kControlMenuPart,
376 Controls.kControlPopupButtonMenuHandleTag)
377 menu = Menu.as_Menu(mhandle)
378 for item in items:
379 if type(item) == type(()):
380 label = item[0]
381 else:
382 label = item
383 if label[-1] == '=' or label[-1] == ':':
384 label = label[:-1]
385 menu.AppendMenu(label)
Just van Rossum35b50e22003-06-21 14:41:32 +0000386## mhandle, mid = menu.getpopupinfo()
387## control.SetControlData_Handle(Controls.kControlMenuPart,
388## Controls.kControlPopupButtonMenuHandleTag, mhandle)
Tim Peters182b5ac2004-07-18 06:16:08 +0000389 control.SetControlMinimum(1)
390 control.SetControlMaximum(len(items)+1)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000391
Jack Jansenf86eda52000-09-19 22:42:38 +0000392def _selectoption(d, optionlist, idx):
Just van Rossum35b50e22003-06-21 14:41:32 +0000393 if idx < 0 or idx >= len(optionlist):
394 MacOS.SysBeep()
395 return
396 option = optionlist[idx]
397 if type(option) == type(()):
398 if len(option) == 4:
399 help = option[2]
400 elif len(option) > 1:
401 help = option[-1]
Raymond Hettingerff41c482003-04-06 09:01:11 +0000402 else:
Just van Rossum35b50e22003-06-21 14:41:32 +0000403 help = ''
404 else:
405 help = ''
406 h = d.GetDialogItemAsControl(ARGV_OPTION_EXPLAIN)
407 if help and len(help) > 250:
408 help = help[:250] + '...'
409 Dlg.SetDialogItemText(h, help)
410 hasvalue = 0
411 if type(option) == type(()):
412 label = option[0]
413 else:
414 label = option
415 if label[-1] == '=' or label[-1] == ':':
416 hasvalue = 1
417 h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
418 Dlg.SetDialogItemText(h, '')
419 if hasvalue:
420 d.ShowDialogItem(ARGV_OPTION_VALUE)
421 d.SelectDialogItemText(ARGV_OPTION_VALUE, 0, 0)
422 else:
423 d.HideDialogItem(ARGV_OPTION_VALUE)
Jack Jansenf86eda52000-09-19 22:42:38 +0000424
425
426def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID):
Just van Rossum35b50e22003-06-21 14:41:32 +0000427 _initialize()
428 _interact()
429 d = GetNewDialog(id, -1)
430 if not d:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000431 print("EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)")
Just van Rossum35b50e22003-06-21 14:41:32 +0000432 return
Raymond Hettingerff41c482003-04-06 09:01:11 +0000433# h = d.GetDialogItemAsControl(3)
434# SetDialogItemText(h, lf2cr(prompt))
435# h = d.GetDialogItemAsControl(4)
436# SetDialogItemText(h, lf2cr(default))
437# d.SelectDialogItemText(4, 0, 999)
438# d.SetDialogItem(4, 0, 255)
Just van Rossum35b50e22003-06-21 14:41:32 +0000439 if optionlist:
440 _setmenu(d.GetDialogItemAsControl(ARGV_OPTION_GROUP), optionlist)
441 _selectoption(d, optionlist, 0)
442 else:
443 d.GetDialogItemAsControl(ARGV_OPTION_GROUP).DeactivateControl()
444 if commandlist:
445 _setmenu(d.GetDialogItemAsControl(ARGV_COMMAND_GROUP), commandlist)
446 if type(commandlist[0]) == type(()) and len(commandlist[0]) > 1:
447 help = commandlist[0][-1]
448 h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
449 Dlg.SetDialogItemText(h, help)
450 else:
451 d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).DeactivateControl()
452 if not addoldfile:
453 d.GetDialogItemAsControl(ARGV_ADD_OLDFILE).DeactivateControl()
454 if not addnewfile:
455 d.GetDialogItemAsControl(ARGV_ADD_NEWFILE).DeactivateControl()
456 if not addfolder:
457 d.GetDialogItemAsControl(ARGV_ADD_FOLDER).DeactivateControl()
458 d.SetDialogDefaultItem(ARGV_ITEM_OK)
459 d.SetDialogCancelItem(ARGV_ITEM_CANCEL)
460 d.GetDialogWindow().ShowWindow()
461 d.DrawDialog()
462 if hasattr(MacOS, 'SchedParams'):
463 appsw = MacOS.SchedParams(1, 0)
464 try:
465 while 1:
466 stringstoadd = []
467 n = ModalDialog(None)
468 if n == ARGV_ITEM_OK:
469 break
470 elif n == ARGV_ITEM_CANCEL:
471 raise SystemExit
472 elif n == ARGV_OPTION_GROUP:
473 idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
474 _selectoption(d, optionlist, idx)
475 elif n == ARGV_OPTION_VALUE:
476 pass
477 elif n == ARGV_OPTION_ADD:
478 idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
479 if 0 <= idx < len(optionlist):
480 option = optionlist[idx]
481 if type(option) == type(()):
482 option = option[0]
483 if option[-1] == '=' or option[-1] == ':':
484 option = option[:-1]
485 h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
486 value = Dlg.GetDialogItemText(h)
487 else:
488 value = ''
489 if len(option) == 1:
490 stringtoadd = '-' + option
491 else:
492 stringtoadd = '--' + option
493 stringstoadd = [stringtoadd]
494 if value:
495 stringstoadd.append(value)
496 else:
497 MacOS.SysBeep()
498 elif n == ARGV_COMMAND_GROUP:
499 idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
500 if 0 <= idx < len(commandlist) and type(commandlist[idx]) == type(()) and \
501 len(commandlist[idx]) > 1:
502 help = commandlist[idx][-1]
503 h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
504 Dlg.SetDialogItemText(h, help)
505 elif n == ARGV_COMMAND_ADD:
506 idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
507 if 0 <= idx < len(commandlist):
508 command = commandlist[idx]
509 if type(command) == type(()):
510 command = command[0]
511 stringstoadd = [command]
512 else:
513 MacOS.SysBeep()
514 elif n == ARGV_ADD_OLDFILE:
515 pathname = AskFileForOpen()
516 if pathname:
517 stringstoadd = [pathname]
518 elif n == ARGV_ADD_NEWFILE:
519 pathname = AskFileForSave()
520 if pathname:
521 stringstoadd = [pathname]
522 elif n == ARGV_ADD_FOLDER:
523 pathname = AskFolder()
524 if pathname:
525 stringstoadd = [pathname]
526 elif n == ARGV_CMDLINE_DATA:
527 pass # Nothing to do
528 else:
529 raise RuntimeError, "Unknown dialog item %d"%n
Raymond Hettingerff41c482003-04-06 09:01:11 +0000530
Just van Rossum35b50e22003-06-21 14:41:32 +0000531 for stringtoadd in stringstoadd:
532 if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000533 stringtoadd = repr(stringtoadd)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000534 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
535 oldstr = GetDialogItemText(h)
Just van Rossum35b50e22003-06-21 14:41:32 +0000536 if oldstr and oldstr[-1] != ' ':
537 oldstr = oldstr + ' '
538 oldstr = oldstr + stringtoadd
539 if oldstr[-1] != ' ':
540 oldstr = oldstr + ' '
541 SetDialogItemText(h, oldstr)
542 d.SelectDialogItemText(ARGV_CMDLINE_DATA, 0x7fff, 0x7fff)
543 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
544 oldstr = GetDialogItemText(h)
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000545 tmplist = oldstr.split()
Just van Rossum35b50e22003-06-21 14:41:32 +0000546 newlist = []
547 while tmplist:
548 item = tmplist[0]
549 del tmplist[0]
550 if item[0] == '"':
551 while item[-1] != '"':
552 if not tmplist:
553 raise RuntimeError, "Unterminated quoted argument"
554 item = item + ' ' + tmplist[0]
555 del tmplist[0]
556 item = item[1:-1]
557 if item[0] == "'":
558 while item[-1] != "'":
559 if not tmplist:
560 raise RuntimeError, "Unterminated quoted argument"
561 item = item + ' ' + tmplist[0]
562 del tmplist[0]
563 item = item[1:-1]
564 newlist.append(item)
565 return newlist
566 finally:
567 if hasattr(MacOS, 'SchedParams'):
568 MacOS.SchedParams(*appsw)
569 del d
Jack Jansenf0d12da2003-01-17 16:04:39 +0000570
Jack Jansen3032fe62003-01-21 14:38:32 +0000571def _process_Nav_args(dftflags, **args):
Just van Rossum35b50e22003-06-21 14:41:32 +0000572 import aepack
573 import Carbon.AE
574 import Carbon.File
575 for k in args.keys():
576 if args[k] is None:
577 del args[k]
578 # Set some defaults, and modify some arguments
Neal Norwitzf1a69c12006-08-20 16:25:10 +0000579 if 'dialogOptionFlags' not in args:
Just van Rossum35b50e22003-06-21 14:41:32 +0000580 args['dialogOptionFlags'] = dftflags
Neal Norwitzf1a69c12006-08-20 16:25:10 +0000581 if 'defaultLocation' in args and \
Just van Rossum35b50e22003-06-21 14:41:32 +0000582 not isinstance(args['defaultLocation'], Carbon.AE.AEDesc):
583 defaultLocation = args['defaultLocation']
584 if isinstance(defaultLocation, (Carbon.File.FSSpec, Carbon.File.FSRef)):
585 args['defaultLocation'] = aepack.pack(defaultLocation)
586 else:
587 defaultLocation = Carbon.File.FSRef(defaultLocation)
588 args['defaultLocation'] = aepack.pack(defaultLocation)
Neal Norwitzf1a69c12006-08-20 16:25:10 +0000589 if 'typeList' in args and not isinstance(args['typeList'], Carbon.Res.ResourceType):
Just van Rossum35b50e22003-06-21 14:41:32 +0000590 typeList = args['typeList'][:]
591 # Workaround for OSX typeless files:
592 if 'TEXT' in typeList and not '\0\0\0\0' in typeList:
593 typeList = typeList + ('\0\0\0\0',)
594 data = 'Pyth' + struct.pack("hh", 0, len(typeList))
595 for type in typeList:
596 data = data+type
597 args['typeList'] = Carbon.Res.Handle(data)
598 tpwanted = str
Neal Norwitzf1a69c12006-08-20 16:25:10 +0000599 if 'wanted' in args:
Just van Rossum35b50e22003-06-21 14:41:32 +0000600 tpwanted = args['wanted']
601 del args['wanted']
602 return args, tpwanted
Raymond Hettingerff41c482003-04-06 09:01:11 +0000603
Jack Jansen2731c5c2003-02-07 15:45:40 +0000604def _dummy_Nav_eventproc(msg, data):
Just van Rossum35b50e22003-06-21 14:41:32 +0000605 pass
Raymond Hettingerff41c482003-04-06 09:01:11 +0000606
Jack Jansen2731c5c2003-02-07 15:45:40 +0000607_default_Nav_eventproc = _dummy_Nav_eventproc
608
609def SetDefaultEventProc(proc):
Just van Rossum35b50e22003-06-21 14:41:32 +0000610 global _default_Nav_eventproc
611 rv = _default_Nav_eventproc
612 if proc is None:
613 proc = _dummy_Nav_eventproc
614 _default_Nav_eventproc = proc
615 return rv
Raymond Hettingerff41c482003-04-06 09:01:11 +0000616
Jack Jansen3032fe62003-01-21 14:38:32 +0000617def AskFileForOpen(
Just van Rossum35b50e22003-06-21 14:41:32 +0000618 message=None,
619 typeList=None,
620 # From here on the order is not documented
621 version=None,
622 defaultLocation=None,
623 dialogOptionFlags=None,
624 location=None,
625 clientName=None,
626 windowTitle=None,
627 actionButtonLabel=None,
628 cancelButtonLabel=None,
629 preferenceKey=None,
630 popupExtension=None,
631 eventProc=_dummy_Nav_eventproc,
632 previewProc=None,
633 filterProc=None,
634 wanted=None,
635 multiple=None):
636 """Display a dialog asking the user for a file to open.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000637
Just van Rossum35b50e22003-06-21 14:41:32 +0000638 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
639 the other arguments can be looked up in Apple's Navigation Services documentation"""
Raymond Hettingerff41c482003-04-06 09:01:11 +0000640
Just van Rossum35b50e22003-06-21 14:41:32 +0000641 default_flags = 0x56 # Or 0xe4?
642 args, tpwanted = _process_Nav_args(default_flags, version=version,
643 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
644 location=location,clientName=clientName,windowTitle=windowTitle,
645 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
646 message=message,preferenceKey=preferenceKey,
647 popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc,
648 filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple)
649 _interact()
650 try:
651 rr = Nav.NavChooseFile(args)
652 good = 1
Guido van Rossumb940e112007-01-10 16:19:56 +0000653 except Nav.error as arg:
Just van Rossum35b50e22003-06-21 14:41:32 +0000654 if arg[0] != -128: # userCancelledErr
655 raise Nav.error, arg
656 return None
657 if not rr.validRecord or not rr.selection:
658 return None
659 if issubclass(tpwanted, Carbon.File.FSRef):
660 return tpwanted(rr.selection_fsr[0])
661 if issubclass(tpwanted, Carbon.File.FSSpec):
662 return tpwanted(rr.selection[0])
663 if issubclass(tpwanted, str):
664 return tpwanted(rr.selection_fsr[0].as_pathname())
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000665 if issubclass(tpwanted, str):
Just van Rossum35b50e22003-06-21 14:41:32 +0000666 return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
667 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000668
Jack Jansen3032fe62003-01-21 14:38:32 +0000669def AskFileForSave(
Just van Rossum35b50e22003-06-21 14:41:32 +0000670 message=None,
671 savedFileName=None,
672 # From here on the order is not documented
673 version=None,
674 defaultLocation=None,
675 dialogOptionFlags=None,
676 location=None,
677 clientName=None,
678 windowTitle=None,
679 actionButtonLabel=None,
680 cancelButtonLabel=None,
681 preferenceKey=None,
682 popupExtension=None,
683 eventProc=_dummy_Nav_eventproc,
684 fileType=None,
685 fileCreator=None,
686 wanted=None,
687 multiple=None):
688 """Display a dialog asking the user for a filename to save to.
Jack Jansen3032fe62003-01-21 14:38:32 +0000689
Just van Rossum35b50e22003-06-21 14:41:32 +0000690 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
691 the other arguments can be looked up in Apple's Navigation Services documentation"""
Raymond Hettingerff41c482003-04-06 09:01:11 +0000692
693
Just van Rossum35b50e22003-06-21 14:41:32 +0000694 default_flags = 0x07
695 args, tpwanted = _process_Nav_args(default_flags, version=version,
696 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
697 location=location,clientName=clientName,windowTitle=windowTitle,
698 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
699 savedFileName=savedFileName,message=message,preferenceKey=preferenceKey,
700 popupExtension=popupExtension,eventProc=eventProc,fileType=fileType,
701 fileCreator=fileCreator,wanted=wanted,multiple=multiple)
702 _interact()
703 try:
704 rr = Nav.NavPutFile(args)
705 good = 1
Guido van Rossumb940e112007-01-10 16:19:56 +0000706 except Nav.error as arg:
Just van Rossum35b50e22003-06-21 14:41:32 +0000707 if arg[0] != -128: # userCancelledErr
708 raise Nav.error, arg
709 return None
710 if not rr.validRecord or not rr.selection:
711 return None
712 if issubclass(tpwanted, Carbon.File.FSRef):
713 raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave"
714 if issubclass(tpwanted, Carbon.File.FSSpec):
715 return tpwanted(rr.selection[0])
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000716 if issubclass(tpwanted, (str, str)):
Just van Rossum35b50e22003-06-21 14:41:32 +0000717 if sys.platform == 'mac':
718 fullpath = rr.selection[0].as_pathname()
719 else:
720 # This is gross, and probably incorrect too
721 vrefnum, dirid, name = rr.selection[0].as_tuple()
722 pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, ''))
723 pardir_fsr = Carbon.File.FSRef(pardir_fss)
724 pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000725 name_utf8 = str(name, 'macroman').encode('utf8')
Just van Rossum35b50e22003-06-21 14:41:32 +0000726 fullpath = os.path.join(pardir_path, name_utf8)
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000727 if issubclass(tpwanted, str):
728 return str(fullpath, 'utf8')
Just van Rossum35b50e22003-06-21 14:41:32 +0000729 return tpwanted(fullpath)
730 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000731
Jack Jansen3032fe62003-01-21 14:38:32 +0000732def AskFolder(
Just van Rossum35b50e22003-06-21 14:41:32 +0000733 message=None,
734 # From here on the order is not documented
735 version=None,
736 defaultLocation=None,
737 dialogOptionFlags=None,
738 location=None,
739 clientName=None,
740 windowTitle=None,
741 actionButtonLabel=None,
742 cancelButtonLabel=None,
743 preferenceKey=None,
744 popupExtension=None,
745 eventProc=_dummy_Nav_eventproc,
746 filterProc=None,
747 wanted=None,
748 multiple=None):
749 """Display a dialog asking the user for select a folder.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000750
Just van Rossum35b50e22003-06-21 14:41:32 +0000751 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
752 the other arguments can be looked up in Apple's Navigation Services documentation"""
Raymond Hettingerff41c482003-04-06 09:01:11 +0000753
Just van Rossum35b50e22003-06-21 14:41:32 +0000754 default_flags = 0x17
755 args, tpwanted = _process_Nav_args(default_flags, version=version,
756 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
757 location=location,clientName=clientName,windowTitle=windowTitle,
758 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
759 message=message,preferenceKey=preferenceKey,
760 popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc,
761 wanted=wanted,multiple=multiple)
762 _interact()
763 try:
764 rr = Nav.NavChooseFolder(args)
765 good = 1
Guido van Rossumb940e112007-01-10 16:19:56 +0000766 except Nav.error as arg:
Just van Rossum35b50e22003-06-21 14:41:32 +0000767 if arg[0] != -128: # userCancelledErr
768 raise Nav.error, arg
769 return None
770 if not rr.validRecord or not rr.selection:
771 return None
772 if issubclass(tpwanted, Carbon.File.FSRef):
773 return tpwanted(rr.selection_fsr[0])
774 if issubclass(tpwanted, Carbon.File.FSSpec):
775 return tpwanted(rr.selection[0])
776 if issubclass(tpwanted, str):
777 return tpwanted(rr.selection_fsr[0].as_pathname())
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000778 if issubclass(tpwanted, str):
Just van Rossum35b50e22003-06-21 14:41:32 +0000779 return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
780 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000781
Jack Jansenf0d12da2003-01-17 16:04:39 +0000782
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000783def test():
Just van Rossum35b50e22003-06-21 14:41:32 +0000784 import time
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000785
Just van Rossum35b50e22003-06-21 14:41:32 +0000786 Message("Testing EasyDialogs.")
787 optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
788 ('flags=', 'Valued option'), ('f:', 'Short valued option'))
789 commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
790 argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
791 Message("Command line: %s"%' '.join(argv))
792 for i in range(len(argv)):
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000793 print('arg[%d] = %r' % (i, argv[i]))
Just van Rossum35b50e22003-06-21 14:41:32 +0000794 ok = AskYesNoCancel("Do you want to proceed?")
795 ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
796 if ok > 0:
797 s = AskString("Enter your first name", "Joe")
798 s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
799 if not s2:
800 Message("%s has no secret nickname"%s)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000801 else:
Just van Rossum35b50e22003-06-21 14:41:32 +0000802 Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
803 else:
804 s = 'Anonymous'
805 rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=Carbon.File.FSSpec)
806 Message("rv: %s"%rv)
807 rv = AskFileForSave(wanted=Carbon.File.FSRef, savedFileName="%s.txt"%s)
808 Message("rv.as_pathname: %s"%rv.as_pathname())
809 rv = AskFolder()
810 Message("Folder name: %s"%rv)
811 text = ( "Working Hard...", "Hardly Working..." ,
812 "So far, so good!", "Keep on truckin'" )
813 bar = ProgressBar("Progress, progress...", 0, label="Ramping up...")
814 try:
815 if hasattr(MacOS, 'SchedParams'):
816 appsw = MacOS.SchedParams(1, 0)
817 for i in xrange(20):
818 bar.inc()
819 time.sleep(0.05)
820 bar.set(0,100)
821 for i in xrange(100):
822 bar.set(i)
823 time.sleep(0.05)
824 if i % 10 == 0:
825 bar.label(text[(i/10) % 4])
826 bar.label("Done.")
827 time.sleep(1.0) # give'em a chance to see "Done."
828 finally:
829 del bar
830 if hasattr(MacOS, 'SchedParams'):
831 MacOS.SchedParams(*appsw)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000832
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000833if __name__ == '__main__':
Just van Rossum35b50e22003-06-21 14:41:32 +0000834 try:
835 test()
836 except KeyboardInterrupt:
837 Message("Operation Canceled.")