blob: 119adfafb54d29c6d9cd69f9b5534e13a2a13d5c [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
8AskFileForOpen(...) -- Ask the user for an existing file
9AskFileForSave(...) -- 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)
14bar.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 Jansenf0d12da2003-01-17 16:04:39 +000030import Nav
Jack Jansena5a49811998-07-01 15:47:44 +000031import MacOS
32import string
Jack Jansen5a6fdcd2001-08-25 12:15:04 +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 Jansendde800e2002-11-07 23:07:05 +000037
Jack Jansen3032fe62003-01-21 14:38:32 +000038__all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel',
39 'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder',
40 'Progress']
41
Jack Jansendde800e2002-11-07 23:07:05 +000042_initialized = 0
43
44def _initialize():
45 global _initialized
46 if _initialized: return
47 macresource.need("DLOG", 260, "dialogs.rsrc", __name__)
48
Jack Jansena5a49811998-07-01 15:47:44 +000049
50def cr2lf(text):
51 if '\r' in text:
52 text = string.join(string.split(text, '\r'), '\n')
53 return text
54
55def lf2cr(text):
56 if '\n' in text:
57 text = string.join(string.split(text, '\n'), '\r')
Jack Jansend5af7bd1998-09-28 10:37:08 +000058 if len(text) > 253:
59 text = text[:253] + '\311'
Jack Jansena5a49811998-07-01 15:47:44 +000060 return text
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000061
Jack Jansencc386881999-12-12 22:57:51 +000062def Message(msg, id=260, ok=None):
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000063 """Display a MESSAGE string.
64
65 Return when the user clicks the OK button or presses Return.
66
67 The MESSAGE string can be at most 255 characters long.
68 """
Jack Jansendde800e2002-11-07 23:07:05 +000069 _initialize()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000070 d = GetNewDialog(id, -1)
71 if not d:
Jack Jansend05e1812002-08-02 11:03:19 +000072 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000073 return
Jack Jansencc386881999-12-12 22:57:51 +000074 h = d.GetDialogItemAsControl(2)
Jack Jansena5a49811998-07-01 15:47:44 +000075 SetDialogItemText(h, lf2cr(msg))
Jack Jansen208c15a1999-02-16 16:06:39 +000076 if ok != None:
Jack Jansencc386881999-12-12 22:57:51 +000077 h = d.GetDialogItemAsControl(1)
78 h.SetControlTitle(ok)
Jack Jansen3a87f5b1995-11-14 10:13:49 +000079 d.SetDialogDefaultItem(1)
Jack Jansenfca049d2000-01-18 13:36:02 +000080 d.AutoSizeDialog()
Jack Jansen0c1836f2000-08-25 22:06:19 +000081 d.GetDialogWindow().ShowWindow()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000082 while 1:
83 n = ModalDialog(None)
84 if n == 1:
85 return
86
87
Jack Jansencc386881999-12-12 22:57:51 +000088def AskString(prompt, default = "", id=261, ok=None, cancel=None):
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000089 """Display a PROMPT string and a text entry field with a DEFAULT string.
90
91 Return the contents of the text entry field when the user clicks the
92 OK button or presses Return.
93 Return None when the user clicks the Cancel button.
94
95 If omitted, DEFAULT is empty.
96
97 The PROMPT and DEFAULT strings, as well as the return value,
98 can be at most 255 characters long.
99 """
100
Jack Jansendde800e2002-11-07 23:07:05 +0000101 _initialize()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000102 d = GetNewDialog(id, -1)
103 if not d:
Jack Jansend05e1812002-08-02 11:03:19 +0000104 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000105 return
Jack Jansencc386881999-12-12 22:57:51 +0000106 h = d.GetDialogItemAsControl(3)
Jack Jansena5a49811998-07-01 15:47:44 +0000107 SetDialogItemText(h, lf2cr(prompt))
Jack Jansencc386881999-12-12 22:57:51 +0000108 h = d.GetDialogItemAsControl(4)
Jack Jansena5a49811998-07-01 15:47:44 +0000109 SetDialogItemText(h, lf2cr(default))
Jack Jansend61f92b1999-01-22 13:14:06 +0000110 d.SelectDialogItemText(4, 0, 999)
Jack Jansene4b40381995-07-17 13:25:15 +0000111# d.SetDialogItem(4, 0, 255)
Jack Jansen208c15a1999-02-16 16:06:39 +0000112 if ok != None:
Jack Jansencc386881999-12-12 22:57:51 +0000113 h = d.GetDialogItemAsControl(1)
114 h.SetControlTitle(ok)
Jack Jansen208c15a1999-02-16 16:06:39 +0000115 if cancel != None:
Jack Jansencc386881999-12-12 22:57:51 +0000116 h = d.GetDialogItemAsControl(2)
117 h.SetControlTitle(cancel)
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000118 d.SetDialogDefaultItem(1)
119 d.SetDialogCancelItem(2)
Jack Jansenfca049d2000-01-18 13:36:02 +0000120 d.AutoSizeDialog()
Jack Jansen0c1836f2000-08-25 22:06:19 +0000121 d.GetDialogWindow().ShowWindow()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000122 while 1:
123 n = ModalDialog(None)
124 if n == 1:
Jack Jansencc386881999-12-12 22:57:51 +0000125 h = d.GetDialogItemAsControl(4)
Jack Jansena5a49811998-07-01 15:47:44 +0000126 return cr2lf(GetDialogItemText(h))
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000127 if n == 2: return None
128
Jack Jansen60429e01999-12-13 16:07:01 +0000129def AskPassword(prompt, default='', id=264, ok=None, cancel=None):
Jack Jansenb92268a1999-02-10 22:38:44 +0000130 """Display a PROMPT string and a text entry field with a DEFAULT string.
131 The string is displayed as bullets only.
132
133 Return the contents of the text entry field when the user clicks the
134 OK button or presses Return.
135 Return None when the user clicks the Cancel button.
136
137 If omitted, DEFAULT is empty.
138
139 The PROMPT and DEFAULT strings, as well as the return value,
140 can be at most 255 characters long.
141 """
Jack Jansendde800e2002-11-07 23:07:05 +0000142 _initialize()
Jack Jansenb92268a1999-02-10 22:38:44 +0000143 d = GetNewDialog(id, -1)
144 if not d:
Jack Jansend05e1812002-08-02 11:03:19 +0000145 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
Jack Jansenb92268a1999-02-10 22:38:44 +0000146 return
Jack Jansen60429e01999-12-13 16:07:01 +0000147 h = d.GetDialogItemAsControl(3)
Jack Jansenb92268a1999-02-10 22:38:44 +0000148 SetDialogItemText(h, lf2cr(prompt))
Jack Jansen60429e01999-12-13 16:07:01 +0000149 pwd = d.GetDialogItemAsControl(4)
Jack Jansenb92268a1999-02-10 22:38:44 +0000150 bullets = '\245'*len(default)
Jack Jansen60429e01999-12-13 16:07:01 +0000151## SetControlData(pwd, kControlEditTextPart, kControlEditTextTextTag, bullets)
152 SetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag, default)
153 d.SelectDialogItemText(4, 0, 999)
Jack Jansen0c1836f2000-08-25 22:06:19 +0000154 Ctl.SetKeyboardFocus(d.GetDialogWindow(), pwd, kControlEditTextPart)
Jack Jansen60429e01999-12-13 16:07:01 +0000155 if ok != None:
156 h = d.GetDialogItemAsControl(1)
157 h.SetControlTitle(ok)
158 if cancel != None:
159 h = d.GetDialogItemAsControl(2)
160 h.SetControlTitle(cancel)
Jack Jansenb92268a1999-02-10 22:38:44 +0000161 d.SetDialogDefaultItem(Dialogs.ok)
162 d.SetDialogCancelItem(Dialogs.cancel)
Jack Jansenfca049d2000-01-18 13:36:02 +0000163 d.AutoSizeDialog()
Jack Jansen0c1836f2000-08-25 22:06:19 +0000164 d.GetDialogWindow().ShowWindow()
Jack Jansenb92268a1999-02-10 22:38:44 +0000165 while 1:
Jack Jansen60429e01999-12-13 16:07:01 +0000166 n = ModalDialog(None)
167 if n == 1:
168 h = d.GetDialogItemAsControl(4)
169 return cr2lf(GetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag))
170 if n == 2: return None
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000171
Jack Jansencc386881999-12-12 22:57:51 +0000172def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=262):
Jack Jansencf2efc61999-02-25 22:05:45 +0000173 """Display a QUESTION string which can be answered with Yes or No.
174
175 Return 1 when the user clicks the Yes button.
176 Return 0 when the user clicks the No button.
177 Return -1 when the user clicks the Cancel button.
178
179 When the user presses Return, the DEFAULT value is returned.
180 If omitted, this is 0 (No).
181
Just van Rossum639a7402001-06-26 06:57:12 +0000182 The QUESTION string can be at most 255 characters.
Jack Jansencf2efc61999-02-25 22:05:45 +0000183 """
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000184
Jack Jansendde800e2002-11-07 23:07:05 +0000185 _initialize()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000186 d = GetNewDialog(id, -1)
187 if not d:
Jack Jansend05e1812002-08-02 11:03:19 +0000188 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000189 return
190 # Button assignments:
191 # 1 = default (invisible)
192 # 2 = Yes
193 # 3 = No
194 # 4 = Cancel
195 # The question string is item 5
Jack Jansencc386881999-12-12 22:57:51 +0000196 h = d.GetDialogItemAsControl(5)
Jack Jansena5a49811998-07-01 15:47:44 +0000197 SetDialogItemText(h, lf2cr(question))
Jack Jansen3f5aef71997-06-20 16:23:37 +0000198 if yes != None:
Jack Jansen85743782000-02-10 16:15:53 +0000199 if yes == '':
200 d.HideDialogItem(2)
201 else:
202 h = d.GetDialogItemAsControl(2)
203 h.SetControlTitle(yes)
Jack Jansen3f5aef71997-06-20 16:23:37 +0000204 if no != None:
Jack Jansen85743782000-02-10 16:15:53 +0000205 if no == '':
206 d.HideDialogItem(3)
207 else:
208 h = d.GetDialogItemAsControl(3)
209 h.SetControlTitle(no)
Jack Jansen3f5aef71997-06-20 16:23:37 +0000210 if cancel != None:
Jack Jansen208c15a1999-02-16 16:06:39 +0000211 if cancel == '':
212 d.HideDialogItem(4)
213 else:
Jack Jansencc386881999-12-12 22:57:51 +0000214 h = d.GetDialogItemAsControl(4)
215 h.SetControlTitle(cancel)
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000216 d.SetDialogCancelItem(4)
Jack Jansen0b690db1996-04-10 14:49:41 +0000217 if default == 1:
218 d.SetDialogDefaultItem(2)
219 elif default == 0:
220 d.SetDialogDefaultItem(3)
221 elif default == -1:
222 d.SetDialogDefaultItem(4)
Jack Jansenfca049d2000-01-18 13:36:02 +0000223 d.AutoSizeDialog()
Jack Jansen0c1836f2000-08-25 22:06:19 +0000224 d.GetDialogWindow().ShowWindow()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000225 while 1:
226 n = ModalDialog(None)
227 if n == 1: return default
228 if n == 2: return 1
229 if n == 3: return 0
230 if n == 4: return -1
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000231
232
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000233
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000234
Jack Jansen362c7cd02002-11-30 00:01:29 +0000235screenbounds = Qd.GetQDGlobalsScreenBits().bounds
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000236screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
237 screenbounds[2]-4, screenbounds[3]-4
238
Jack Jansen911e87d2001-08-27 15:24:07 +0000239kControlProgressBarIndeterminateTag = 'inde' # from Controls.py
240
241
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000242class ProgressBar:
Jack Jansen911e87d2001-08-27 15:24:07 +0000243 def __init__(self, title="Working...", maxval=0, label="", id=263):
Jack Jansen5dd73622001-02-23 22:18:27 +0000244 self.w = None
245 self.d = None
Jack Jansendde800e2002-11-07 23:07:05 +0000246 _initialize()
Jack Jansen3f5aef71997-06-20 16:23:37 +0000247 self.d = GetNewDialog(id, -1)
Jack Jansen784c6112001-02-09 15:57:01 +0000248 self.w = self.d.GetDialogWindow()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000249 self.label(label)
Jack Jansenab48e902000-07-24 14:07:15 +0000250 self.title(title)
Jack Jansen911e87d2001-08-27 15:24:07 +0000251 self.set(0, maxval)
252 self.d.AutoSizeDialog()
Jack Jansen784c6112001-02-09 15:57:01 +0000253 self.w.ShowWindow()
Jack Jansencc386881999-12-12 22:57:51 +0000254 self.d.DrawDialog()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000255
256 def __del__( self ):
Jack Jansen5dd73622001-02-23 22:18:27 +0000257 if self.w:
258 self.w.BringToFront()
259 self.w.HideWindow()
Jack Jansen784c6112001-02-09 15:57:01 +0000260 del self.w
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000261 del self.d
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000262
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000263 def title(self, newstr=""):
264 """title(text) - Set title of progress window"""
Jack Jansen784c6112001-02-09 15:57:01 +0000265 self.w.BringToFront()
266 self.w.SetWTitle(newstr)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000267
268 def label( self, *newstr ):
269 """label(text) - Set text in progress box"""
Jack Jansen784c6112001-02-09 15:57:01 +0000270 self.w.BringToFront()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000271 if newstr:
Jack Jansena5a49811998-07-01 15:47:44 +0000272 self._label = lf2cr(newstr[0])
Jack Jansencc386881999-12-12 22:57:51 +0000273 text_h = self.d.GetDialogItemAsControl(2)
Jack Jansen911e87d2001-08-27 15:24:07 +0000274 SetDialogItemText(text_h, self._label)
275
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000276 def _update(self, value):
Jack Jansen58fa8181999-11-05 15:53:10 +0000277 maxval = self.maxval
Jack Jansen911e87d2001-08-27 15:24:07 +0000278 if maxval == 0: # an indeterminate bar
279 Ctl.IdleControls(self.w) # spin the barber pole
280 else: # a determinate bar
281 if maxval > 32767:
282 value = int(value/(maxval/32767.0))
283 maxval = 32767
284 progbar = self.d.GetDialogItemAsControl(3)
285 progbar.SetControlMaximum(maxval)
286 progbar.SetControlValue(value) # set the bar length
287
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000288 # Test for cancel button
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000289 ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1 )
Jack Jansen911e87d2001-08-27 15:24:07 +0000290 if ready :
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000291 what,msg,when,where,mod = ev
292 part = Win.FindWindow(where)[0]
293 if Dlg.IsDialogEvent(ev):
294 ds = Dlg.DialogSelect(ev)
295 if ds[0] and ds[1] == self.d and ds[-1] == 1:
Jack Jansen5dd73622001-02-23 22:18:27 +0000296 self.w.HideWindow()
297 self.w = None
298 self.d = None
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000299 raise KeyboardInterrupt, ev
300 else:
301 if part == 4: # inDrag
Jack Jansen8d2f3d62001-07-27 09:21:28 +0000302 self.w.DragWindow(where, screenbounds)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000303 else:
304 MacOS.HandleEvent(ev)
305
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000306
Jack Jansen58fa8181999-11-05 15:53:10 +0000307 def set(self, value, max=None):
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000308 """set(value) - Set progress bar position"""
Jack Jansen58fa8181999-11-05 15:53:10 +0000309 if max != None:
310 self.maxval = max
Jack Jansen911e87d2001-08-27 15:24:07 +0000311 bar = self.d.GetDialogItemAsControl(3)
312 if max <= 0: # indeterminate bar
313 bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x01')
314 else: # determinate bar
315 bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x00')
316 if value < 0:
317 value = 0
318 elif value > self.maxval:
319 value = self.maxval
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000320 self.curval = value
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000321 self._update(value)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000322
323 def inc(self, n=1):
324 """inc(amt) - Increment progress bar position"""
325 self.set(self.curval + n)
326
Jack Jansenf86eda52000-09-19 22:42:38 +0000327ARGV_ID=265
328ARGV_ITEM_OK=1
329ARGV_ITEM_CANCEL=2
330ARGV_OPTION_GROUP=3
331ARGV_OPTION_EXPLAIN=4
332ARGV_OPTION_VALUE=5
333ARGV_OPTION_ADD=6
334ARGV_COMMAND_GROUP=7
335ARGV_COMMAND_EXPLAIN=8
336ARGV_COMMAND_ADD=9
337ARGV_ADD_OLDFILE=10
338ARGV_ADD_NEWFILE=11
339ARGV_ADD_FOLDER=12
340ARGV_CMDLINE_GROUP=13
341ARGV_CMDLINE_DATA=14
342
343##def _myModalDialog(d):
344## while 1:
345## ready, ev = Evt.WaitNextEvent(0xffff, -1)
346## print 'DBG: WNE', ready, ev
347## if ready :
348## what,msg,when,where,mod = ev
349## part, window = Win.FindWindow(where)
350## if Dlg.IsDialogEvent(ev):
351## didit, dlgdone, itemdone = Dlg.DialogSelect(ev)
352## print 'DBG: DialogSelect', didit, dlgdone, itemdone, d
353## if didit and dlgdone == d:
354## return itemdone
355## elif window == d.GetDialogWindow():
356## d.GetDialogWindow().SelectWindow()
357## if part == 4: # inDrag
358## d.DragWindow(where, screenbounds)
359## else:
360## MacOS.HandleEvent(ev)
361## else:
362## MacOS.HandleEvent(ev)
363##
364def _setmenu(control, items):
Jack Jansene7bfc912001-01-09 22:22:58 +0000365 mhandle = control.GetControlData_Handle(Controls.kControlMenuPart,
Jack Jansenf86eda52000-09-19 22:42:38 +0000366 Controls.kControlPopupButtonMenuHandleTag)
367 menu = Menu.as_Menu(mhandle)
368 for item in items:
369 if type(item) == type(()):
370 label = item[0]
371 else:
372 label = item
373 if label[-1] == '=' or label[-1] == ':':
374 label = label[:-1]
375 menu.AppendMenu(label)
376## mhandle, mid = menu.getpopupinfo()
Jack Jansene7bfc912001-01-09 22:22:58 +0000377## control.SetControlData_Handle(Controls.kControlMenuPart,
Jack Jansenf86eda52000-09-19 22:42:38 +0000378## Controls.kControlPopupButtonMenuHandleTag, mhandle)
379 control.SetControlMinimum(1)
380 control.SetControlMaximum(len(items)+1)
381
382def _selectoption(d, optionlist, idx):
383 if idx < 0 or idx >= len(optionlist):
384 MacOS.SysBeep()
385 return
386 option = optionlist[idx]
Jack Jansen09c73432002-06-26 15:14:48 +0000387 if type(option) == type(()):
388 if len(option) == 4:
389 help = option[2]
390 elif len(option) > 1:
391 help = option[-1]
392 else:
393 help = ''
Jack Jansenf86eda52000-09-19 22:42:38 +0000394 else:
395 help = ''
396 h = d.GetDialogItemAsControl(ARGV_OPTION_EXPLAIN)
Jack Jansen09c73432002-06-26 15:14:48 +0000397 if help and len(help) > 250:
398 help = help[:250] + '...'
Jack Jansenf86eda52000-09-19 22:42:38 +0000399 Dlg.SetDialogItemText(h, help)
400 hasvalue = 0
401 if type(option) == type(()):
402 label = option[0]
403 else:
404 label = option
405 if label[-1] == '=' or label[-1] == ':':
406 hasvalue = 1
407 h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
408 Dlg.SetDialogItemText(h, '')
409 if hasvalue:
410 d.ShowDialogItem(ARGV_OPTION_VALUE)
411 d.SelectDialogItemText(ARGV_OPTION_VALUE, 0, 0)
412 else:
413 d.HideDialogItem(ARGV_OPTION_VALUE)
414
415
416def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID):
Jack Jansendde800e2002-11-07 23:07:05 +0000417 _initialize()
Jack Jansenf86eda52000-09-19 22:42:38 +0000418 d = GetNewDialog(id, -1)
419 if not d:
Jack Jansend05e1812002-08-02 11:03:19 +0000420 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
Jack Jansenf86eda52000-09-19 22:42:38 +0000421 return
422# h = d.GetDialogItemAsControl(3)
423# SetDialogItemText(h, lf2cr(prompt))
424# h = d.GetDialogItemAsControl(4)
425# SetDialogItemText(h, lf2cr(default))
426# d.SelectDialogItemText(4, 0, 999)
427# d.SetDialogItem(4, 0, 255)
428 if optionlist:
429 _setmenu(d.GetDialogItemAsControl(ARGV_OPTION_GROUP), optionlist)
430 _selectoption(d, optionlist, 0)
431 else:
432 d.GetDialogItemAsControl(ARGV_OPTION_GROUP).DeactivateControl()
433 if commandlist:
434 _setmenu(d.GetDialogItemAsControl(ARGV_COMMAND_GROUP), commandlist)
Jack Jansen0bb0a902000-09-21 22:01:08 +0000435 if type(commandlist[0]) == type(()) and len(commandlist[0]) > 1:
Jack Jansenf86eda52000-09-19 22:42:38 +0000436 help = commandlist[0][-1]
437 h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
438 Dlg.SetDialogItemText(h, help)
439 else:
440 d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).DeactivateControl()
441 if not addoldfile:
442 d.GetDialogItemAsControl(ARGV_ADD_OLDFILE).DeactivateControl()
443 if not addnewfile:
444 d.GetDialogItemAsControl(ARGV_ADD_NEWFILE).DeactivateControl()
445 if not addfolder:
446 d.GetDialogItemAsControl(ARGV_ADD_FOLDER).DeactivateControl()
447 d.SetDialogDefaultItem(ARGV_ITEM_OK)
448 d.SetDialogCancelItem(ARGV_ITEM_CANCEL)
449 d.GetDialogWindow().ShowWindow()
450 d.DrawDialog()
Jack Janseneb308432001-09-09 00:36:01 +0000451 if hasattr(MacOS, 'SchedParams'):
452 appsw = MacOS.SchedParams(1, 0)
Jack Jansenf86eda52000-09-19 22:42:38 +0000453 try:
454 while 1:
455 stringstoadd = []
456 n = ModalDialog(None)
457 if n == ARGV_ITEM_OK:
458 break
459 elif n == ARGV_ITEM_CANCEL:
460 raise SystemExit
461 elif n == ARGV_OPTION_GROUP:
462 idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
463 _selectoption(d, optionlist, idx)
464 elif n == ARGV_OPTION_VALUE:
465 pass
466 elif n == ARGV_OPTION_ADD:
467 idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
468 if 0 <= idx < len(optionlist):
Jack Jansen0bb0a902000-09-21 22:01:08 +0000469 option = optionlist[idx]
470 if type(option) == type(()):
471 option = option[0]
Jack Jansenf86eda52000-09-19 22:42:38 +0000472 if option[-1] == '=' or option[-1] == ':':
473 option = option[:-1]
474 h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
475 value = Dlg.GetDialogItemText(h)
476 else:
477 value = ''
478 if len(option) == 1:
479 stringtoadd = '-' + option
480 else:
481 stringtoadd = '--' + option
482 stringstoadd = [stringtoadd]
483 if value:
484 stringstoadd.append(value)
485 else:
486 MacOS.SysBeep()
487 elif n == ARGV_COMMAND_GROUP:
488 idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
Jack Jansen0bb0a902000-09-21 22:01:08 +0000489 if 0 <= idx < len(commandlist) and type(commandlist[idx]) == type(()) and \
Jack Jansenf86eda52000-09-19 22:42:38 +0000490 len(commandlist[idx]) > 1:
491 help = commandlist[idx][-1]
492 h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
493 Dlg.SetDialogItemText(h, help)
494 elif n == ARGV_COMMAND_ADD:
495 idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
496 if 0 <= idx < len(commandlist):
Jack Jansen0bb0a902000-09-21 22:01:08 +0000497 command = commandlist[idx]
498 if type(command) == type(()):
499 command = command[0]
500 stringstoadd = [command]
Jack Jansenf86eda52000-09-19 22:42:38 +0000501 else:
502 MacOS.SysBeep()
503 elif n == ARGV_ADD_OLDFILE:
Jack Jansen08a7a0d2003-01-21 13:56:34 +0000504 pathname = AskFileForOpen()
505 if pathname:
506 stringstoadd = [pathname]
Jack Jansenf86eda52000-09-19 22:42:38 +0000507 elif n == ARGV_ADD_NEWFILE:
Jack Jansen08a7a0d2003-01-21 13:56:34 +0000508 pathname = AskFileForSave()
509 if pathname:
510 stringstoadd = [pathname]
Jack Jansenf86eda52000-09-19 22:42:38 +0000511 elif n == ARGV_ADD_FOLDER:
Jack Jansen08a7a0d2003-01-21 13:56:34 +0000512 pathname = AskFolder()
513 if pathname:
514 stringstoadd = [pathname]
Jack Jansenf86eda52000-09-19 22:42:38 +0000515 elif n == ARGV_CMDLINE_DATA:
516 pass # Nothing to do
517 else:
518 raise RuntimeError, "Unknown dialog item %d"%n
519
520 for stringtoadd in stringstoadd:
521 if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
522 stringtoadd = `stringtoadd`
523 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
524 oldstr = GetDialogItemText(h)
525 if oldstr and oldstr[-1] != ' ':
526 oldstr = oldstr + ' '
527 oldstr = oldstr + stringtoadd
528 if oldstr[-1] != ' ':
529 oldstr = oldstr + ' '
530 SetDialogItemText(h, oldstr)
531 d.SelectDialogItemText(ARGV_CMDLINE_DATA, 0x7fff, 0x7fff)
532 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
533 oldstr = GetDialogItemText(h)
534 tmplist = string.split(oldstr)
535 newlist = []
536 while tmplist:
537 item = tmplist[0]
538 del tmplist[0]
539 if item[0] == '"':
540 while item[-1] != '"':
541 if not tmplist:
542 raise RuntimeError, "Unterminated quoted argument"
543 item = item + ' ' + tmplist[0]
544 del tmplist[0]
545 item = item[1:-1]
546 if item[0] == "'":
547 while item[-1] != "'":
548 if not tmplist:
549 raise RuntimeError, "Unterminated quoted argument"
550 item = item + ' ' + tmplist[0]
551 del tmplist[0]
552 item = item[1:-1]
553 newlist.append(item)
554 return newlist
555 finally:
Jack Janseneb308432001-09-09 00:36:01 +0000556 if hasattr(MacOS, 'SchedParams'):
557 apply(MacOS.SchedParams, appsw)
Jack Jansen0bb0a902000-09-21 22:01:08 +0000558 del d
Jack Jansenf0d12da2003-01-17 16:04:39 +0000559
Jack Jansen3032fe62003-01-21 14:38:32 +0000560def _process_Nav_args(dftflags, **args):
Jack Jansenf0d12da2003-01-17 16:04:39 +0000561 import aepack
562 import Carbon.AE
563 import Carbon.File
Jack Jansenf0d12da2003-01-17 16:04:39 +0000564 for k in args.keys():
Jack Jansen3032fe62003-01-21 14:38:32 +0000565 if args[k] is None:
566 del args[k]
Jack Jansenf0d12da2003-01-17 16:04:39 +0000567 # Set some defaults, and modify some arguments
568 if not args.has_key('dialogOptionFlags'):
569 args['dialogOptionFlags'] = dftflags
570 if args.has_key('defaultLocation') and \
571 not isinstance(args['defaultLocation'], Carbon.AE.AEDesc):
572 defaultLocation = args['defaultLocation']
573 if isinstance(defaultLocation, (Carbon.File.FSSpec, Carbon.File.FSRef)):
574 args['defaultLocation'] = aepack.pack(defaultLocation)
575 else:
576 defaultLocation = Carbon.File.FSRef(defaultLocation)
577 args['defaultLocation'] = aepack.pack(defaultLocation)
578 if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType):
579 typeList = args['typeList'].copy()
580 # Workaround for OSX typeless files:
581 if 'TEXT' in typeList and not '\0\0\0\0' in typeList:
582 typeList = typeList + ('\0\0\0\0',)
583 data = 'Pyth' + struct.pack("hh", 0, len(typeList))
584 for type in typeList:
585 data = data+type
586 args['typeList'] = Carbon.Res.Handle(data)
587 tpwanted = str
588 if args.has_key('wanted'):
589 tpwanted = args['wanted']
590 del args['wanted']
591 return args, tpwanted
592
Jack Jansen3032fe62003-01-21 14:38:32 +0000593def AskFileForOpen(
594 version=None,
595 defaultLocation=None,
596 dialogOptionFlags=None,
597 location=None,
598 clientName=None,
599 windowTitle=None,
600 actionButtonLabel=None,
601 cancelButtonLabel=None,
602 message=None,
603 preferenceKey=None,
604 popupExtension=None,
605 eventProc=None,
606 previewProc=None,
607 filterProc=None,
608 typeList=None,
609 wanted=None,
610 multiple=None):
611 """Display a dialog asking the user for a file to open.
612
613 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
614 the other arguments can be looked up in Apple's Navigation Services documentation"""
615
Jack Jansenf0d12da2003-01-17 16:04:39 +0000616 default_flags = 0x56 # Or 0xe4?
Jack Jansen3032fe62003-01-21 14:38:32 +0000617 args, tpwanted = _process_Nav_args(default_flags, version=version,
618 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
619 location=location,clientName=clientName,windowTitle=windowTitle,
620 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
621 message=message,preferenceKey=preferenceKey,
622 popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc,
623 filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000624 try:
625 rr = Nav.NavChooseFile(args)
626 good = 1
627 except Nav.error, arg:
628 if arg[0] != -128: # userCancelledErr
629 raise Nav.error, arg
630 return None
631 if not rr.validRecord or not rr.selection:
632 return None
633 if issubclass(tpwanted, Carbon.File.FSRef):
634 return tpwanted(rr.selection_fsr[0])
635 if issubclass(tpwanted, Carbon.File.FSSpec):
636 return tpwanted(rr.selection[0])
637 if issubclass(tpwanted, str):
638 return tpwanted(rr.selection_fsr[0].FSRefMakePath())
639 if issubclass(tpwanted, unicode):
640 return tpwanted(rr.selection_fsr[0].FSRefMakePath(), 'utf8')
641 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
642
Jack Jansen3032fe62003-01-21 14:38:32 +0000643def AskFileForSave(
644 version=None,
645 defaultLocation=None,
646 dialogOptionFlags=None,
647 location=None,
648 clientName=None,
649 windowTitle=None,
650 actionButtonLabel=None,
651 cancelButtonLabel=None,
652 savedFileName=None,
653 message=None,
654 preferenceKey=None,
655 popupExtension=None,
656 eventProc=None,
657 fileType=None,
658 fileCreator=None,
659 wanted=None,
660 multiple=None):
661 """Display a dialog asking the user for a filename to save to.
662
663 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
664 the other arguments can be looked up in Apple's Navigation Services documentation"""
665
666
Jack Jansenf0d12da2003-01-17 16:04:39 +0000667 default_flags = 0x07
Jack Jansen3032fe62003-01-21 14:38:32 +0000668 args, tpwanted = _process_Nav_args(default_flags, version=version,
669 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
670 location=location,clientName=clientName,windowTitle=windowTitle,
671 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
672 savedFileName=savedFileName,message=message,preferenceKey=preferenceKey,
673 popupExtension=popupExtension,fileType=fileType,fileCreator=fileCreator,
674 wanted=wanted,multiple=multiple)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000675 try:
676 rr = Nav.NavPutFile(args)
677 good = 1
678 except Nav.error, arg:
679 if arg[0] != -128: # userCancelledErr
680 raise Nav.error, arg
681 return None
682 if not rr.validRecord or not rr.selection:
683 return None
684 if issubclass(tpwanted, Carbon.File.FSRef):
685 raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave"
686 if issubclass(tpwanted, Carbon.File.FSSpec):
687 return tpwanted(rr.selection[0])
688 if issubclass(tpwanted, (str, unicode)):
689 # This is gross, and probably incorrect too
690 vrefnum, dirid, name = rr.selection[0].as_tuple()
691 pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, ''))
Jack Jansene58962a2003-01-17 23:13:03 +0000692 pardir_fsr = Carbon.File.FSRef(pardir_fss)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000693 pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8
694 name_utf8 = unicode(name, 'macroman').encode('utf8')
695 fullpath = os.path.join(pardir_path, name_utf8)
696 if issubclass(tpwanted, unicode):
697 return unicode(fullpath, 'utf8')
698 return tpwanted(fullpath)
699 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
700
Jack Jansen3032fe62003-01-21 14:38:32 +0000701def AskFolder(
702 version=None,
703 defaultLocation=None,
704 dialogOptionFlags=None,
705 location=None,
706 clientName=None,
707 windowTitle=None,
708 actionButtonLabel=None,
709 cancelButtonLabel=None,
710 message=None,
711 preferenceKey=None,
712 popupExtension=None,
713 eventProc=None,
714 filterProc=None,
715 wanted=None,
716 multiple=None):
717 """Display a dialog asking the user for select a folder.
718
719 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
720 the other arguments can be looked up in Apple's Navigation Services documentation"""
721
Jack Jansenf0d12da2003-01-17 16:04:39 +0000722 default_flags = 0x17
Jack Jansen3032fe62003-01-21 14:38:32 +0000723 args, tpwanted = _process_Nav_args(default_flags, version=version,
724 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
725 location=location,clientName=clientName,windowTitle=windowTitle,
726 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
727 message=message,preferenceKey=preferenceKey,
728 popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc,
729 wanted=wanted,multiple=multiple)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000730 try:
731 rr = Nav.NavChooseFolder(args)
732 good = 1
733 except Nav.error, arg:
734 if arg[0] != -128: # userCancelledErr
735 raise Nav.error, arg
736 return None
737 if not rr.validRecord or not rr.selection:
738 return None
739 if issubclass(tpwanted, Carbon.File.FSRef):
740 return tpwanted(rr.selection_fsr[0])
741 if issubclass(tpwanted, Carbon.File.FSSpec):
742 return tpwanted(rr.selection[0])
743 if issubclass(tpwanted, str):
744 return tpwanted(rr.selection_fsr[0].FSRefMakePath())
745 if issubclass(tpwanted, unicode):
746 return tpwanted(rr.selection_fsr[0].FSRefMakePath(), 'utf8')
747 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
748
749
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000750def test():
Jack Jansen08a7a0d2003-01-21 13:56:34 +0000751 import time, sys, macfs
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000752
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000753 Message("Testing EasyDialogs.")
Jack Jansenf86eda52000-09-19 22:42:38 +0000754 optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
755 ('flags=', 'Valued option'), ('f:', 'Short valued option'))
756 commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
757 argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000758 Message("Command line: %s"%' '.join(argv))
Jack Jansenf86eda52000-09-19 22:42:38 +0000759 for i in range(len(argv)):
760 print 'arg[%d] = %s'%(i, `argv[i]`)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000761 ok = AskYesNoCancel("Do you want to proceed?")
Jack Jansen60429e01999-12-13 16:07:01 +0000762 ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000763 if ok > 0:
Jack Jansend61f92b1999-01-22 13:14:06 +0000764 s = AskString("Enter your first name", "Joe")
Jack Jansen60429e01999-12-13 16:07:01 +0000765 s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
766 if not s2:
767 Message("%s has no secret nickname"%s)
768 else:
769 Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
Jack Jansenf0d12da2003-01-17 16:04:39 +0000770 else:
771 s = 'Anonymous'
772 rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=macfs.FSSpec)
773 Message("rv: %s"%rv)
774 rv = AskFileForSave(wanted=macfs.FSSpec, savedFileName="%s.txt"%s)
775 Message("rv.as_pathname: %s"%rv.as_pathname())
776 rv = AskFolder()
777 Message("Folder name: %s"%rv)
Jack Jansen911e87d2001-08-27 15:24:07 +0000778 text = ( "Working Hard...", "Hardly Working..." ,
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000779 "So far, so good!", "Keep on truckin'" )
Jack Jansen911e87d2001-08-27 15:24:07 +0000780 bar = ProgressBar("Progress, progress...", 0, label="Ramping up...")
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000781 try:
Jack Janseneb308432001-09-09 00:36:01 +0000782 if hasattr(MacOS, 'SchedParams'):
783 appsw = MacOS.SchedParams(1, 0)
Jack Jansen911e87d2001-08-27 15:24:07 +0000784 for i in xrange(20):
785 bar.inc()
786 time.sleep(0.05)
787 bar.set(0,100)
788 for i in xrange(100):
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000789 bar.set(i)
Jack Jansen911e87d2001-08-27 15:24:07 +0000790 time.sleep(0.05)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000791 if i % 10 == 0:
792 bar.label(text[(i/10) % 4])
793 bar.label("Done.")
Jack Jansen911e87d2001-08-27 15:24:07 +0000794 time.sleep(1.0) # give'em a chance to see "Done."
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000795 finally:
796 del bar
Jack Janseneb308432001-09-09 00:36:01 +0000797 if hasattr(MacOS, 'SchedParams'):
798 apply(MacOS.SchedParams, appsw)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000799
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000800if __name__ == '__main__':
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000801 try:
802 test()
803 except KeyboardInterrupt:
804 Message("Operation Canceled.")
805