blob: 4c64839ed2c8de3e47b3d97141e322cd1d29e2b5 [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
Benjamin Peterson23681932008-05-12 21:42:13 +000021from warnings import warnpy3k
Benjamin Petersona6864e02008-07-14 17:42:17 +000022warnpy3k("In 3.x, the EasyDialogs module is removed.", stacklevel=2)
Benjamin Peterson23681932008-05-12 21:42:13 +000023
Jack Jansen5a6fdcd2001-08-25 12:15:04 +000024from Carbon.Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText, ModalDialog
25from Carbon import Qd
26from Carbon import QuickDraw
27from Carbon import Dialogs
28from Carbon import Windows
29from Carbon import Dlg,Win,Evt,Events # sdm7g
30from Carbon import Ctl
31from Carbon import Controls
32from Carbon import Menu
Jack Jansen7451e3b2003-03-03 12:25:02 +000033from Carbon import AE
Jack Jansenf0d12da2003-01-17 16:04:39 +000034import Nav
Jack Jansena5a49811998-07-01 15:47:44 +000035import MacOS
36import string
Raymond Hettingerff41c482003-04-06 09:01:11 +000037from Carbon.ControlAccessor import * # Also import Controls constants
Jack Jansenf0d12da2003-01-17 16:04:39 +000038import Carbon.File
Jack Jansendde800e2002-11-07 23:07:05 +000039import macresource
Jack Jansene58962a2003-01-17 23:13:03 +000040import os
Jack Jansen2b3ce3b2003-01-26 20:22:41 +000041import sys
Jack Jansendde800e2002-11-07 23:07:05 +000042
Jack Jansen3032fe62003-01-21 14:38:32 +000043__all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel',
Just van Rossum35b50e22003-06-21 14:41:32 +000044 'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder',
45 'ProgressBar']
Raymond Hettingerff41c482003-04-06 09:01:11 +000046
Jack Jansendde800e2002-11-07 23:07:05 +000047_initialized = 0
48
49def _initialize():
Just van Rossum35b50e22003-06-21 14:41:32 +000050 global _initialized
51 if _initialized: return
52 macresource.need("DLOG", 260, "dialogs.rsrc", __name__)
Raymond Hettingerff41c482003-04-06 09:01:11 +000053
Jack Jansen7451e3b2003-03-03 12:25:02 +000054def _interact():
Just van Rossum35b50e22003-06-21 14:41:32 +000055 """Make sure the application is in the foreground"""
56 AE.AEInteractWithUser(50000000)
Jack Jansena5a49811998-07-01 15:47:44 +000057
58def cr2lf(text):
Just van Rossum35b50e22003-06-21 14:41:32 +000059 if '\r' in text:
60 text = string.join(string.split(text, '\r'), '\n')
61 return text
Jack Jansena5a49811998-07-01 15:47:44 +000062
63def lf2cr(text):
Just van Rossum35b50e22003-06-21 14:41:32 +000064 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
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000069
Jack Jansencc386881999-12-12 22:57:51 +000070def Message(msg, id=260, ok=None):
Just van Rossum35b50e22003-06-21 14:41:32 +000071 """Display a MESSAGE string.
Raymond Hettingerff41c482003-04-06 09:01:11 +000072
Just van Rossum35b50e22003-06-21 14:41:32 +000073 Return when the user clicks the OK button or presses Return.
Raymond Hettingerff41c482003-04-06 09:01:11 +000074
Just van Rossum35b50e22003-06-21 14:41:32 +000075 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))
Benjamin Peterson5b63acd2008-03-29 15:24:25 +000085 if ok is not None:
Just van Rossum35b50e22003-06-21 14:41:32 +000086 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
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000095
96
Jack Jansencc386881999-12-12 22:57:51 +000097def AskString(prompt, default = "", id=261, ok=None, cancel=None):
Just van Rossum35b50e22003-06-21 14:41:32 +000098 """Display a PROMPT string and a text entry field with a DEFAULT string.
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000099
Just van Rossum35b50e22003-06-21 14:41:32 +0000100 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.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000103
Just van Rossum35b50e22003-06-21 14:41:32 +0000104 If omitted, DEFAULT is empty.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000105
Just van Rossum35b50e22003-06-21 14:41:32 +0000106 The PROMPT and DEFAULT strings, as well as the return value,
107 can be at most 255 characters long.
108 """
Raymond Hettingerff41c482003-04-06 09:01:11 +0000109
Just van Rossum35b50e22003-06-21 14:41:32 +0000110 _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)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000121# d.SetDialogItem(4, 0, 255)
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000122 if ok is not None:
Just van Rossum35b50e22003-06-21 14:41:32 +0000123 h = d.GetDialogItemAsControl(1)
124 h.SetControlTitle(ok)
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000125 if cancel is not None:
Just van Rossum35b50e22003-06-21 14:41:32 +0000126 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
Raymond Hettingerff41c482003-04-06 09:01:11 +0000138
139def AskPassword(prompt, default='', id=264, ok=None, cancel=None):
Just van Rossum35b50e22003-06-21 14:41:32 +0000140 """Display a PROMPT string and a text entry field with a DEFAULT string.
141 The string is displayed as bullets only.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000142
Just van Rossum35b50e22003-06-21 14:41:32 +0000143 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.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000146
Just van Rossum35b50e22003-06-21 14:41:32 +0000147 If omitted, DEFAULT is empty.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000148
Just van Rossum35b50e22003-06-21 14:41:32 +0000149 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)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000162## SetControlData(pwd, kControlEditTextPart, kControlEditTextTextTag, bullets)
Just van Rossum35b50e22003-06-21 14:41:32 +0000163 SetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag, default)
164 d.SelectDialogItemText(4, 0, 999)
165 Ctl.SetKeyboardFocus(d.GetDialogWindow(), pwd, kControlEditTextPart)
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000166 if ok is not None:
Just van Rossum35b50e22003-06-21 14:41:32 +0000167 h = d.GetDialogItemAsControl(1)
168 h.SetControlTitle(ok)
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000169 if cancel is not None:
Just van Rossum35b50e22003-06-21 14:41:32 +0000170 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
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000182
Jack Jansencc386881999-12-12 22:57:51 +0000183def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=262):
Just van Rossum35b50e22003-06-21 14:41:32 +0000184 """Display a QUESTION string which can be answered with Yes or No.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000185
Just van Rossum35b50e22003-06-21 14:41:32 +0000186 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.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000189
Just van Rossum35b50e22003-06-21 14:41:32 +0000190 When the user presses Return, the DEFAULT value is returned.
191 If omitted, this is 0 (No).
Raymond Hettingerff41c482003-04-06 09:01:11 +0000192
Just van Rossum35b50e22003-06-21 14:41:32 +0000193 The QUESTION string can be at most 255 characters.
194 """
Raymond Hettingerff41c482003-04-06 09:01:11 +0000195
Just van Rossum35b50e22003-06-21 14:41:32 +0000196 _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))
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000210 if yes is not None:
Just van Rossum35b50e22003-06-21 14:41:32 +0000211 if yes == '':
212 d.HideDialogItem(2)
213 else:
214 h = d.GetDialogItemAsControl(2)
215 h.SetControlTitle(yes)
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000216 if no is not None:
Just van Rossum35b50e22003-06-21 14:41:32 +0000217 if no == '':
218 d.HideDialogItem(3)
219 else:
220 h = d.GetDialogItemAsControl(3)
221 h.SetControlTitle(no)
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000222 if cancel is not None:
Just van Rossum35b50e22003-06-21 14:41:32 +0000223 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
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000243
244
Raymond Hettingerff41c482003-04-06 09:01:11 +0000245
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000246
Jack Jansen362c7cd2002-11-30 00:01:29 +0000247screenbounds = Qd.GetQDGlobalsScreenBits().bounds
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000248screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
Just van Rossum35b50e22003-06-21 14:41:32 +0000249 screenbounds[2]-4, screenbounds[3]-4
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000250
Raymond Hettingerff41c482003-04-06 09:01:11 +0000251kControlProgressBarIndeterminateTag = 'inde' # from Controls.py
Jack Jansen911e87d2001-08-27 15:24:07 +0000252
253
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000254class ProgressBar:
Just van Rossum35b50e22003-06-21 14:41:32 +0000255 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()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000267
Martin Blais215f13d2006-06-06 12:46:55 +0000268 def __del__(self):
Just van Rossum35b50e22003-06-21 14:41:32 +0000269 if self.w:
270 self.w.BringToFront()
271 self.w.HideWindow()
272 del self.w
273 del self.d
Jack Jansen911e87d2001-08-27 15:24:07 +0000274
Just van Rossum35b50e22003-06-21 14:41:32 +0000275 def title(self, newstr=""):
276 """title(text) - Set title of progress window"""
277 self.w.BringToFront()
278 self.w.SetWTitle(newstr)
Jack Jansen911e87d2001-08-27 15:24:07 +0000279
Martin Blais215f13d2006-06-06 12:46:55 +0000280 def label(self, *newstr):
Just van Rossum35b50e22003-06-21 14:41:32 +0000281 """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)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000287
Just van Rossum35b50e22003-06-21 14:41:32 +0000288 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
Raymond Hettingerff41c482003-04-06 09:01:11 +0000301
Just van Rossum35b50e22003-06-21 14:41:32 +0000302 # 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)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000319
320
Just van Rossum35b50e22003-06-21 14:41:32 +0000321 def set(self, value, max=None):
322 """set(value) - Set progress bar position"""
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000323 if max is not None:
Just van Rossum35b50e22003-06-21 14:41:32 +0000324 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)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000336
Just van Rossum35b50e22003-06-21 14:41:32 +0000337 def inc(self, n=1):
338 """inc(amt) - Increment progress bar position"""
339 self.set(self.curval + n)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000340
Jack Jansenf86eda52000-09-19 22:42:38 +0000341ARGV_ID=265
342ARGV_ITEM_OK=1
343ARGV_ITEM_CANCEL=2
344ARGV_OPTION_GROUP=3
345ARGV_OPTION_EXPLAIN=4
346ARGV_OPTION_VALUE=5
347ARGV_OPTION_ADD=6
348ARGV_COMMAND_GROUP=7
349ARGV_COMMAND_EXPLAIN=8
350ARGV_COMMAND_ADD=9
351ARGV_ADD_OLDFILE=10
352ARGV_ADD_NEWFILE=11
353ARGV_ADD_FOLDER=12
354ARGV_CMDLINE_GROUP=13
355ARGV_CMDLINE_DATA=14
356
357##def _myModalDialog(d):
Raymond Hettingerff41c482003-04-06 09:01:11 +0000358## while 1:
Just van Rossum35b50e22003-06-21 14:41:32 +0000359## 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)
Jack Jansenf86eda52000-09-19 22:42:38 +0000377##
378def _setmenu(control, items):
Tim Peters182b5ac2004-07-18 06:16:08 +0000379 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)
Just van Rossum35b50e22003-06-21 14:41:32 +0000390## mhandle, mid = menu.getpopupinfo()
391## control.SetControlData_Handle(Controls.kControlMenuPart,
392## Controls.kControlPopupButtonMenuHandleTag, mhandle)
Tim Peters182b5ac2004-07-18 06:16:08 +0000393 control.SetControlMinimum(1)
394 control.SetControlMaximum(len(items)+1)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000395
Jack Jansenf86eda52000-09-19 22:42:38 +0000396def _selectoption(d, optionlist, idx):
Just van Rossum35b50e22003-06-21 14:41:32 +0000397 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]
Raymond Hettingerff41c482003-04-06 09:01:11 +0000406 else:
Just van Rossum35b50e22003-06-21 14:41:32 +0000407 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)
Jack Jansenf86eda52000-09-19 22:42:38 +0000428
429
430def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID):
Just van Rossum35b50e22003-06-21 14:41:32 +0000431 _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
Raymond Hettingerff41c482003-04-06 09:01:11 +0000437# 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)
Just van Rossum35b50e22003-06-21 14:41:32 +0000443 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
Raymond Hettingerff41c482003-04-06 09:01:11 +0000534
Just van Rossum35b50e22003-06-21 14:41:32 +0000535 for stringtoadd in stringstoadd:
536 if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000537 stringtoadd = repr(stringtoadd)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000538 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
539 oldstr = GetDialogItemText(h)
Just van Rossum35b50e22003-06-21 14:41:32 +0000540 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
Jack Jansenf0d12da2003-01-17 16:04:39 +0000574
Jack Jansen3032fe62003-01-21 14:38:32 +0000575def _process_Nav_args(dftflags, **args):
Just van Rossum35b50e22003-06-21 14:41:32 +0000576 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
Raymond Hettingerff41c482003-04-06 09:01:11 +0000607
Jack Jansen2731c5c2003-02-07 15:45:40 +0000608def _dummy_Nav_eventproc(msg, data):
Just van Rossum35b50e22003-06-21 14:41:32 +0000609 pass
Raymond Hettingerff41c482003-04-06 09:01:11 +0000610
Jack Jansen2731c5c2003-02-07 15:45:40 +0000611_default_Nav_eventproc = _dummy_Nav_eventproc
612
613def SetDefaultEventProc(proc):
Just van Rossum35b50e22003-06-21 14:41:32 +0000614 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
Raymond Hettingerff41c482003-04-06 09:01:11 +0000620
Jack Jansen3032fe62003-01-21 14:38:32 +0000621def AskFileForOpen(
Just van Rossum35b50e22003-06-21 14:41:32 +0000622 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.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000641
Just van Rossum35b50e22003-06-21 14:41:32 +0000642 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"""
Raymond Hettingerff41c482003-04-06 09:01:11 +0000644
Just van Rossum35b50e22003-06-21 14:41:32 +0000645 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)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000672
Jack Jansen3032fe62003-01-21 14:38:32 +0000673def AskFileForSave(
Just van Rossum35b50e22003-06-21 14:41:32 +0000674 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.
Jack Jansen3032fe62003-01-21 14:38:32 +0000693
Just van Rossum35b50e22003-06-21 14:41:32 +0000694 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"""
Raymond Hettingerff41c482003-04-06 09:01:11 +0000696
697
Just van Rossum35b50e22003-06-21 14:41:32 +0000698 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)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000735
Jack Jansen3032fe62003-01-21 14:38:32 +0000736def AskFolder(
Just van Rossum35b50e22003-06-21 14:41:32 +0000737 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.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000754
Just van Rossum35b50e22003-06-21 14:41:32 +0000755 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"""
Raymond Hettingerff41c482003-04-06 09:01:11 +0000757
Just van Rossum35b50e22003-06-21 14:41:32 +0000758 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)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000785
Jack Jansenf0d12da2003-01-17 16:04:39 +0000786
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000787def test():
Just van Rossum35b50e22003-06-21 14:41:32 +0000788 import time
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000789
Just van Rossum35b50e22003-06-21 14:41:32 +0000790 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)):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000797 print 'arg[%d] = %r' % (i, argv[i])
Just van Rossum35b50e22003-06-21 14:41:32 +0000798 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)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000805 else:
Just van Rossum35b50e22003-06-21 14:41:32 +0000806 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)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000836
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000837if __name__ == '__main__':
Just van Rossum35b50e22003-06-21 14:41:32 +0000838 try:
839 test()
840 except KeyboardInterrupt:
841 Message("Operation Canceled.")