blob: bd097bd83666a75193538a2a07e9ae237b9cef8c [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):
Ronald Oussoren919697c2009-01-02 14:52:09 +0000576 import Carbon.AppleEvents
Just van Rossum35b50e22003-06-21 14:41:32 +0000577 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']
Ronald Oussoren919697c2009-01-02 14:52:09 +0000588 if isinstance(defaultLocation, Carbon.File.FSSpec):
589 args['defaultLocation'] = Carbon.AE.AECreateDesc(
590 Carbon.AppleEvents.typeFSS, defaultLocation.data)
Just van Rossum35b50e22003-06-21 14:41:32 +0000591 else:
Ronald Oussoren919697c2009-01-02 14:52:09 +0000592 if not isinstance(defaultLocation, Carbon.File.FSRef):
593 defaultLocation = Carbon.File.FSRef(defaultLocation)
594 args['defaultLocation'] = Carbon.AE.AECreateDesc(
595 Carbon.AppleEvents.typeFSRef, defaultLocation.data)
Just van Rossum35b50e22003-06-21 14:41:32 +0000596 if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType):
597 typeList = args['typeList'][:]
598 # Workaround for OSX typeless files:
599 if 'TEXT' in typeList and not '\0\0\0\0' in typeList:
600 typeList = typeList + ('\0\0\0\0',)
601 data = 'Pyth' + struct.pack("hh", 0, len(typeList))
602 for type in typeList:
603 data = data+type
604 args['typeList'] = Carbon.Res.Handle(data)
605 tpwanted = str
606 if args.has_key('wanted'):
607 tpwanted = args['wanted']
608 del args['wanted']
609 return args, tpwanted
Raymond Hettingerff41c482003-04-06 09:01:11 +0000610
Jack Jansen2731c5c2003-02-07 15:45:40 +0000611def _dummy_Nav_eventproc(msg, data):
Just van Rossum35b50e22003-06-21 14:41:32 +0000612 pass
Raymond Hettingerff41c482003-04-06 09:01:11 +0000613
Jack Jansen2731c5c2003-02-07 15:45:40 +0000614_default_Nav_eventproc = _dummy_Nav_eventproc
615
616def SetDefaultEventProc(proc):
Just van Rossum35b50e22003-06-21 14:41:32 +0000617 global _default_Nav_eventproc
618 rv = _default_Nav_eventproc
619 if proc is None:
620 proc = _dummy_Nav_eventproc
621 _default_Nav_eventproc = proc
622 return rv
Raymond Hettingerff41c482003-04-06 09:01:11 +0000623
Jack Jansen3032fe62003-01-21 14:38:32 +0000624def AskFileForOpen(
Just van Rossum35b50e22003-06-21 14:41:32 +0000625 message=None,
626 typeList=None,
627 # From here on the order is not documented
628 version=None,
629 defaultLocation=None,
630 dialogOptionFlags=None,
631 location=None,
632 clientName=None,
633 windowTitle=None,
634 actionButtonLabel=None,
635 cancelButtonLabel=None,
636 preferenceKey=None,
637 popupExtension=None,
638 eventProc=_dummy_Nav_eventproc,
639 previewProc=None,
640 filterProc=None,
641 wanted=None,
642 multiple=None):
643 """Display a dialog asking the user for a file to open.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000644
Just van Rossum35b50e22003-06-21 14:41:32 +0000645 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
646 the other arguments can be looked up in Apple's Navigation Services documentation"""
Raymond Hettingerff41c482003-04-06 09:01:11 +0000647
Just van Rossum35b50e22003-06-21 14:41:32 +0000648 default_flags = 0x56 # Or 0xe4?
649 args, tpwanted = _process_Nav_args(default_flags, version=version,
650 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
651 location=location,clientName=clientName,windowTitle=windowTitle,
652 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
653 message=message,preferenceKey=preferenceKey,
654 popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc,
655 filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple)
656 _interact()
657 try:
658 rr = Nav.NavChooseFile(args)
659 good = 1
660 except Nav.error, arg:
661 if arg[0] != -128: # userCancelledErr
662 raise Nav.error, arg
663 return None
664 if not rr.validRecord or not rr.selection:
665 return None
666 if issubclass(tpwanted, Carbon.File.FSRef):
667 return tpwanted(rr.selection_fsr[0])
668 if issubclass(tpwanted, Carbon.File.FSSpec):
669 return tpwanted(rr.selection[0])
670 if issubclass(tpwanted, str):
671 return tpwanted(rr.selection_fsr[0].as_pathname())
672 if issubclass(tpwanted, unicode):
673 return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
674 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000675
Jack Jansen3032fe62003-01-21 14:38:32 +0000676def AskFileForSave(
Just van Rossum35b50e22003-06-21 14:41:32 +0000677 message=None,
678 savedFileName=None,
679 # From here on the order is not documented
680 version=None,
681 defaultLocation=None,
682 dialogOptionFlags=None,
683 location=None,
684 clientName=None,
685 windowTitle=None,
686 actionButtonLabel=None,
687 cancelButtonLabel=None,
688 preferenceKey=None,
689 popupExtension=None,
690 eventProc=_dummy_Nav_eventproc,
691 fileType=None,
692 fileCreator=None,
693 wanted=None,
694 multiple=None):
695 """Display a dialog asking the user for a filename to save to.
Jack Jansen3032fe62003-01-21 14:38:32 +0000696
Just van Rossum35b50e22003-06-21 14:41:32 +0000697 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
698 the other arguments can be looked up in Apple's Navigation Services documentation"""
Raymond Hettingerff41c482003-04-06 09:01:11 +0000699
700
Just van Rossum35b50e22003-06-21 14:41:32 +0000701 default_flags = 0x07
702 args, tpwanted = _process_Nav_args(default_flags, version=version,
703 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
704 location=location,clientName=clientName,windowTitle=windowTitle,
705 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
706 savedFileName=savedFileName,message=message,preferenceKey=preferenceKey,
707 popupExtension=popupExtension,eventProc=eventProc,fileType=fileType,
708 fileCreator=fileCreator,wanted=wanted,multiple=multiple)
709 _interact()
710 try:
711 rr = Nav.NavPutFile(args)
712 good = 1
713 except Nav.error, arg:
714 if arg[0] != -128: # userCancelledErr
715 raise Nav.error, arg
716 return None
717 if not rr.validRecord or not rr.selection:
718 return None
719 if issubclass(tpwanted, Carbon.File.FSRef):
720 raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave"
721 if issubclass(tpwanted, Carbon.File.FSSpec):
722 return tpwanted(rr.selection[0])
723 if issubclass(tpwanted, (str, unicode)):
724 if sys.platform == 'mac':
725 fullpath = rr.selection[0].as_pathname()
726 else:
727 # This is gross, and probably incorrect too
728 vrefnum, dirid, name = rr.selection[0].as_tuple()
729 pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, ''))
730 pardir_fsr = Carbon.File.FSRef(pardir_fss)
731 pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8
732 name_utf8 = unicode(name, 'macroman').encode('utf8')
733 fullpath = os.path.join(pardir_path, name_utf8)
734 if issubclass(tpwanted, unicode):
735 return unicode(fullpath, 'utf8')
736 return tpwanted(fullpath)
737 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000738
Jack Jansen3032fe62003-01-21 14:38:32 +0000739def AskFolder(
Just van Rossum35b50e22003-06-21 14:41:32 +0000740 message=None,
741 # From here on the order is not documented
742 version=None,
743 defaultLocation=None,
744 dialogOptionFlags=None,
745 location=None,
746 clientName=None,
747 windowTitle=None,
748 actionButtonLabel=None,
749 cancelButtonLabel=None,
750 preferenceKey=None,
751 popupExtension=None,
752 eventProc=_dummy_Nav_eventproc,
753 filterProc=None,
754 wanted=None,
755 multiple=None):
756 """Display a dialog asking the user for select a folder.
Raymond Hettingerff41c482003-04-06 09:01:11 +0000757
Just van Rossum35b50e22003-06-21 14:41:32 +0000758 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
759 the other arguments can be looked up in Apple's Navigation Services documentation"""
Raymond Hettingerff41c482003-04-06 09:01:11 +0000760
Just van Rossum35b50e22003-06-21 14:41:32 +0000761 default_flags = 0x17
762 args, tpwanted = _process_Nav_args(default_flags, version=version,
763 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
764 location=location,clientName=clientName,windowTitle=windowTitle,
765 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
766 message=message,preferenceKey=preferenceKey,
767 popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc,
768 wanted=wanted,multiple=multiple)
769 _interact()
770 try:
771 rr = Nav.NavChooseFolder(args)
772 good = 1
773 except Nav.error, arg:
774 if arg[0] != -128: # userCancelledErr
775 raise Nav.error, arg
776 return None
777 if not rr.validRecord or not rr.selection:
778 return None
779 if issubclass(tpwanted, Carbon.File.FSRef):
780 return tpwanted(rr.selection_fsr[0])
781 if issubclass(tpwanted, Carbon.File.FSSpec):
782 return tpwanted(rr.selection[0])
783 if issubclass(tpwanted, str):
784 return tpwanted(rr.selection_fsr[0].as_pathname())
785 if issubclass(tpwanted, unicode):
786 return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
787 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000788
Jack Jansenf0d12da2003-01-17 16:04:39 +0000789
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000790def test():
Just van Rossum35b50e22003-06-21 14:41:32 +0000791 import time
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000792
Just van Rossum35b50e22003-06-21 14:41:32 +0000793 Message("Testing EasyDialogs.")
794 optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
795 ('flags=', 'Valued option'), ('f:', 'Short valued option'))
796 commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
797 argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
798 Message("Command line: %s"%' '.join(argv))
799 for i in range(len(argv)):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000800 print 'arg[%d] = %r' % (i, argv[i])
Just van Rossum35b50e22003-06-21 14:41:32 +0000801 ok = AskYesNoCancel("Do you want to proceed?")
802 ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
803 if ok > 0:
804 s = AskString("Enter your first name", "Joe")
805 s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
806 if not s2:
807 Message("%s has no secret nickname"%s)
Raymond Hettingerff41c482003-04-06 09:01:11 +0000808 else:
Just van Rossum35b50e22003-06-21 14:41:32 +0000809 Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
810 else:
811 s = 'Anonymous'
812 rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=Carbon.File.FSSpec)
813 Message("rv: %s"%rv)
814 rv = AskFileForSave(wanted=Carbon.File.FSRef, savedFileName="%s.txt"%s)
815 Message("rv.as_pathname: %s"%rv.as_pathname())
816 rv = AskFolder()
817 Message("Folder name: %s"%rv)
818 text = ( "Working Hard...", "Hardly Working..." ,
819 "So far, so good!", "Keep on truckin'" )
820 bar = ProgressBar("Progress, progress...", 0, label="Ramping up...")
821 try:
822 if hasattr(MacOS, 'SchedParams'):
823 appsw = MacOS.SchedParams(1, 0)
824 for i in xrange(20):
825 bar.inc()
826 time.sleep(0.05)
827 bar.set(0,100)
828 for i in xrange(100):
829 bar.set(i)
830 time.sleep(0.05)
831 if i % 10 == 0:
832 bar.label(text[(i/10) % 4])
833 bar.label("Done.")
834 time.sleep(1.0) # give'em a chance to see "Done."
835 finally:
836 del bar
837 if hasattr(MacOS, 'SchedParams'):
838 MacOS.SchedParams(*appsw)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000839
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000840if __name__ == '__main__':
Just van Rossum35b50e22003-06-21 14:41:32 +0000841 try:
842 test()
843 except KeyboardInterrupt:
844 Message("Operation Canceled.")