blob: 83daff8e70b60bd29ca6b87810fc1da7be050522 [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 Jansen2b3ce3b2003-01-26 20:22:41 +000037import sys
Jack Jansendde800e2002-11-07 23:07:05 +000038
Jack Jansen3032fe62003-01-21 14:38:32 +000039__all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel',
40 'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder',
41 'Progress']
42
Jack Jansendde800e2002-11-07 23:07:05 +000043_initialized = 0
44
45def _initialize():
46 global _initialized
47 if _initialized: return
48 macresource.need("DLOG", 260, "dialogs.rsrc", __name__)
49
Jack Jansena5a49811998-07-01 15:47:44 +000050
51def cr2lf(text):
52 if '\r' in text:
53 text = string.join(string.split(text, '\r'), '\n')
54 return text
55
56def lf2cr(text):
57 if '\n' in text:
58 text = string.join(string.split(text, '\n'), '\r')
Jack Jansend5af7bd1998-09-28 10:37:08 +000059 if len(text) > 253:
60 text = text[:253] + '\311'
Jack Jansena5a49811998-07-01 15:47:44 +000061 return text
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000062
Jack Jansencc386881999-12-12 22:57:51 +000063def Message(msg, id=260, ok=None):
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000064 """Display a MESSAGE string.
65
66 Return when the user clicks the OK button or presses Return.
67
68 The MESSAGE string can be at most 255 characters long.
69 """
Jack Jansendde800e2002-11-07 23:07:05 +000070 _initialize()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000071 d = GetNewDialog(id, -1)
72 if not d:
Jack Jansend05e1812002-08-02 11:03:19 +000073 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000074 return
Jack Jansencc386881999-12-12 22:57:51 +000075 h = d.GetDialogItemAsControl(2)
Jack Jansena5a49811998-07-01 15:47:44 +000076 SetDialogItemText(h, lf2cr(msg))
Jack Jansen208c15a1999-02-16 16:06:39 +000077 if ok != None:
Jack Jansencc386881999-12-12 22:57:51 +000078 h = d.GetDialogItemAsControl(1)
79 h.SetControlTitle(ok)
Jack Jansen3a87f5b1995-11-14 10:13:49 +000080 d.SetDialogDefaultItem(1)
Jack Jansenfca049d2000-01-18 13:36:02 +000081 d.AutoSizeDialog()
Jack Jansen0c1836f2000-08-25 22:06:19 +000082 d.GetDialogWindow().ShowWindow()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000083 while 1:
84 n = ModalDialog(None)
85 if n == 1:
86 return
87
88
Jack Jansencc386881999-12-12 22:57:51 +000089def AskString(prompt, default = "", id=261, ok=None, cancel=None):
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000090 """Display a PROMPT string and a text entry field with a DEFAULT string.
91
92 Return the contents of the text entry field when the user clicks the
93 OK button or presses Return.
94 Return None when the user clicks the Cancel button.
95
96 If omitted, DEFAULT is empty.
97
98 The PROMPT and DEFAULT strings, as well as the return value,
99 can be at most 255 characters long.
100 """
101
Jack Jansendde800e2002-11-07 23:07:05 +0000102 _initialize()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000103 d = GetNewDialog(id, -1)
104 if not d:
Jack Jansend05e1812002-08-02 11:03:19 +0000105 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000106 return
Jack Jansencc386881999-12-12 22:57:51 +0000107 h = d.GetDialogItemAsControl(3)
Jack Jansena5a49811998-07-01 15:47:44 +0000108 SetDialogItemText(h, lf2cr(prompt))
Jack Jansencc386881999-12-12 22:57:51 +0000109 h = d.GetDialogItemAsControl(4)
Jack Jansena5a49811998-07-01 15:47:44 +0000110 SetDialogItemText(h, lf2cr(default))
Jack Jansend61f92b1999-01-22 13:14:06 +0000111 d.SelectDialogItemText(4, 0, 999)
Jack Jansene4b40381995-07-17 13:25:15 +0000112# d.SetDialogItem(4, 0, 255)
Jack Jansen208c15a1999-02-16 16:06:39 +0000113 if ok != None:
Jack Jansencc386881999-12-12 22:57:51 +0000114 h = d.GetDialogItemAsControl(1)
115 h.SetControlTitle(ok)
Jack Jansen208c15a1999-02-16 16:06:39 +0000116 if cancel != None:
Jack Jansencc386881999-12-12 22:57:51 +0000117 h = d.GetDialogItemAsControl(2)
118 h.SetControlTitle(cancel)
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000119 d.SetDialogDefaultItem(1)
120 d.SetDialogCancelItem(2)
Jack Jansenfca049d2000-01-18 13:36:02 +0000121 d.AutoSizeDialog()
Jack Jansen0c1836f2000-08-25 22:06:19 +0000122 d.GetDialogWindow().ShowWindow()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000123 while 1:
124 n = ModalDialog(None)
125 if n == 1:
Jack Jansencc386881999-12-12 22:57:51 +0000126 h = d.GetDialogItemAsControl(4)
Jack Jansena5a49811998-07-01 15:47:44 +0000127 return cr2lf(GetDialogItemText(h))
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000128 if n == 2: return None
129
Jack Jansen60429e01999-12-13 16:07:01 +0000130def AskPassword(prompt, default='', id=264, ok=None, cancel=None):
Jack Jansenb92268a1999-02-10 22:38:44 +0000131 """Display a PROMPT string and a text entry field with a DEFAULT string.
132 The string is displayed as bullets only.
133
134 Return the contents of the text entry field when the user clicks the
135 OK button or presses Return.
136 Return None when the user clicks the Cancel button.
137
138 If omitted, DEFAULT is empty.
139
140 The PROMPT and DEFAULT strings, as well as the return value,
141 can be at most 255 characters long.
142 """
Jack Jansendde800e2002-11-07 23:07:05 +0000143 _initialize()
Jack Jansenb92268a1999-02-10 22:38:44 +0000144 d = GetNewDialog(id, -1)
145 if not d:
Jack Jansend05e1812002-08-02 11:03:19 +0000146 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
Jack Jansenb92268a1999-02-10 22:38:44 +0000147 return
Jack Jansen60429e01999-12-13 16:07:01 +0000148 h = d.GetDialogItemAsControl(3)
Jack Jansenb92268a1999-02-10 22:38:44 +0000149 SetDialogItemText(h, lf2cr(prompt))
Jack Jansen60429e01999-12-13 16:07:01 +0000150 pwd = d.GetDialogItemAsControl(4)
Jack Jansenb92268a1999-02-10 22:38:44 +0000151 bullets = '\245'*len(default)
Jack Jansen60429e01999-12-13 16:07:01 +0000152## SetControlData(pwd, kControlEditTextPart, kControlEditTextTextTag, bullets)
153 SetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag, default)
154 d.SelectDialogItemText(4, 0, 999)
Jack Jansen0c1836f2000-08-25 22:06:19 +0000155 Ctl.SetKeyboardFocus(d.GetDialogWindow(), pwd, kControlEditTextPart)
Jack Jansen60429e01999-12-13 16:07:01 +0000156 if ok != None:
157 h = d.GetDialogItemAsControl(1)
158 h.SetControlTitle(ok)
159 if cancel != None:
160 h = d.GetDialogItemAsControl(2)
161 h.SetControlTitle(cancel)
Jack Jansenb92268a1999-02-10 22:38:44 +0000162 d.SetDialogDefaultItem(Dialogs.ok)
163 d.SetDialogCancelItem(Dialogs.cancel)
Jack Jansenfca049d2000-01-18 13:36:02 +0000164 d.AutoSizeDialog()
Jack Jansen0c1836f2000-08-25 22:06:19 +0000165 d.GetDialogWindow().ShowWindow()
Jack Jansenb92268a1999-02-10 22:38:44 +0000166 while 1:
Jack Jansen60429e01999-12-13 16:07:01 +0000167 n = ModalDialog(None)
168 if n == 1:
169 h = d.GetDialogItemAsControl(4)
170 return cr2lf(GetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag))
171 if n == 2: return None
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000172
Jack Jansencc386881999-12-12 22:57:51 +0000173def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=262):
Jack Jansencf2efc61999-02-25 22:05:45 +0000174 """Display a QUESTION string which can be answered with Yes or No.
175
176 Return 1 when the user clicks the Yes button.
177 Return 0 when the user clicks the No button.
178 Return -1 when the user clicks the Cancel button.
179
180 When the user presses Return, the DEFAULT value is returned.
181 If omitted, this is 0 (No).
182
Just van Rossum639a7402001-06-26 06:57:12 +0000183 The QUESTION string can be at most 255 characters.
Jack Jansencf2efc61999-02-25 22:05:45 +0000184 """
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000185
Jack Jansendde800e2002-11-07 23:07:05 +0000186 _initialize()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000187 d = GetNewDialog(id, -1)
188 if not d:
Jack Jansend05e1812002-08-02 11:03:19 +0000189 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000190 return
191 # Button assignments:
192 # 1 = default (invisible)
193 # 2 = Yes
194 # 3 = No
195 # 4 = Cancel
196 # The question string is item 5
Jack Jansencc386881999-12-12 22:57:51 +0000197 h = d.GetDialogItemAsControl(5)
Jack Jansena5a49811998-07-01 15:47:44 +0000198 SetDialogItemText(h, lf2cr(question))
Jack Jansen3f5aef71997-06-20 16:23:37 +0000199 if yes != None:
Jack Jansen85743782000-02-10 16:15:53 +0000200 if yes == '':
201 d.HideDialogItem(2)
202 else:
203 h = d.GetDialogItemAsControl(2)
204 h.SetControlTitle(yes)
Jack Jansen3f5aef71997-06-20 16:23:37 +0000205 if no != None:
Jack Jansen85743782000-02-10 16:15:53 +0000206 if no == '':
207 d.HideDialogItem(3)
208 else:
209 h = d.GetDialogItemAsControl(3)
210 h.SetControlTitle(no)
Jack Jansen3f5aef71997-06-20 16:23:37 +0000211 if cancel != None:
Jack Jansen208c15a1999-02-16 16:06:39 +0000212 if cancel == '':
213 d.HideDialogItem(4)
214 else:
Jack Jansencc386881999-12-12 22:57:51 +0000215 h = d.GetDialogItemAsControl(4)
216 h.SetControlTitle(cancel)
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000217 d.SetDialogCancelItem(4)
Jack Jansen0b690db1996-04-10 14:49:41 +0000218 if default == 1:
219 d.SetDialogDefaultItem(2)
220 elif default == 0:
221 d.SetDialogDefaultItem(3)
222 elif default == -1:
223 d.SetDialogDefaultItem(4)
Jack Jansenfca049d2000-01-18 13:36:02 +0000224 d.AutoSizeDialog()
Jack Jansen0c1836f2000-08-25 22:06:19 +0000225 d.GetDialogWindow().ShowWindow()
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000226 while 1:
227 n = ModalDialog(None)
228 if n == 1: return default
229 if n == 2: return 1
230 if n == 3: return 0
231 if n == 4: return -1
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000232
233
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000234
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000235
Jack Jansen362c7cd2002-11-30 00:01:29 +0000236screenbounds = Qd.GetQDGlobalsScreenBits().bounds
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000237screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
238 screenbounds[2]-4, screenbounds[3]-4
239
Jack Jansen911e87d2001-08-27 15:24:07 +0000240kControlProgressBarIndeterminateTag = 'inde' # from Controls.py
241
242
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000243class ProgressBar:
Jack Jansen911e87d2001-08-27 15:24:07 +0000244 def __init__(self, title="Working...", maxval=0, label="", id=263):
Jack Jansen5dd73622001-02-23 22:18:27 +0000245 self.w = None
246 self.d = None
Jack Jansendde800e2002-11-07 23:07:05 +0000247 _initialize()
Jack Jansen3f5aef71997-06-20 16:23:37 +0000248 self.d = GetNewDialog(id, -1)
Jack Jansen784c6112001-02-09 15:57:01 +0000249 self.w = self.d.GetDialogWindow()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000250 self.label(label)
Jack Jansenab48e902000-07-24 14:07:15 +0000251 self.title(title)
Jack Jansen911e87d2001-08-27 15:24:07 +0000252 self.set(0, maxval)
253 self.d.AutoSizeDialog()
Jack Jansen784c6112001-02-09 15:57:01 +0000254 self.w.ShowWindow()
Jack Jansencc386881999-12-12 22:57:51 +0000255 self.d.DrawDialog()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000256
257 def __del__( self ):
Jack Jansen5dd73622001-02-23 22:18:27 +0000258 if self.w:
259 self.w.BringToFront()
260 self.w.HideWindow()
Jack Jansen784c6112001-02-09 15:57:01 +0000261 del self.w
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000262 del self.d
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000263
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000264 def title(self, newstr=""):
265 """title(text) - Set title of progress window"""
Jack Jansen784c6112001-02-09 15:57:01 +0000266 self.w.BringToFront()
267 self.w.SetWTitle(newstr)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000268
269 def label( self, *newstr ):
270 """label(text) - Set text in progress box"""
Jack Jansen784c6112001-02-09 15:57:01 +0000271 self.w.BringToFront()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000272 if newstr:
Jack Jansena5a49811998-07-01 15:47:44 +0000273 self._label = lf2cr(newstr[0])
Jack Jansencc386881999-12-12 22:57:51 +0000274 text_h = self.d.GetDialogItemAsControl(2)
Jack Jansen911e87d2001-08-27 15:24:07 +0000275 SetDialogItemText(text_h, self._label)
276
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000277 def _update(self, value):
Jack Jansen58fa8181999-11-05 15:53:10 +0000278 maxval = self.maxval
Jack Jansen911e87d2001-08-27 15:24:07 +0000279 if maxval == 0: # an indeterminate bar
280 Ctl.IdleControls(self.w) # spin the barber pole
281 else: # a determinate bar
282 if maxval > 32767:
283 value = int(value/(maxval/32767.0))
284 maxval = 32767
285 progbar = self.d.GetDialogItemAsControl(3)
286 progbar.SetControlMaximum(maxval)
287 progbar.SetControlValue(value) # set the bar length
288
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000289 # Test for cancel button
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000290 ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1 )
Jack Jansen911e87d2001-08-27 15:24:07 +0000291 if ready :
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000292 what,msg,when,where,mod = ev
293 part = Win.FindWindow(where)[0]
294 if Dlg.IsDialogEvent(ev):
295 ds = Dlg.DialogSelect(ev)
296 if ds[0] and ds[1] == self.d and ds[-1] == 1:
Jack Jansen5dd73622001-02-23 22:18:27 +0000297 self.w.HideWindow()
298 self.w = None
299 self.d = None
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000300 raise KeyboardInterrupt, ev
301 else:
302 if part == 4: # inDrag
Jack Jansen8d2f3d62001-07-27 09:21:28 +0000303 self.w.DragWindow(where, screenbounds)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000304 else:
305 MacOS.HandleEvent(ev)
306
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000307
Jack Jansen58fa8181999-11-05 15:53:10 +0000308 def set(self, value, max=None):
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000309 """set(value) - Set progress bar position"""
Jack Jansen58fa8181999-11-05 15:53:10 +0000310 if max != None:
311 self.maxval = max
Jack Jansen911e87d2001-08-27 15:24:07 +0000312 bar = self.d.GetDialogItemAsControl(3)
313 if max <= 0: # indeterminate bar
314 bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x01')
315 else: # determinate bar
316 bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x00')
317 if value < 0:
318 value = 0
319 elif value > self.maxval:
320 value = self.maxval
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000321 self.curval = value
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000322 self._update(value)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000323
324 def inc(self, n=1):
325 """inc(amt) - Increment progress bar position"""
326 self.set(self.curval + n)
327
Jack Jansenf86eda52000-09-19 22:42:38 +0000328ARGV_ID=265
329ARGV_ITEM_OK=1
330ARGV_ITEM_CANCEL=2
331ARGV_OPTION_GROUP=3
332ARGV_OPTION_EXPLAIN=4
333ARGV_OPTION_VALUE=5
334ARGV_OPTION_ADD=6
335ARGV_COMMAND_GROUP=7
336ARGV_COMMAND_EXPLAIN=8
337ARGV_COMMAND_ADD=9
338ARGV_ADD_OLDFILE=10
339ARGV_ADD_NEWFILE=11
340ARGV_ADD_FOLDER=12
341ARGV_CMDLINE_GROUP=13
342ARGV_CMDLINE_DATA=14
343
344##def _myModalDialog(d):
345## while 1:
346## ready, ev = Evt.WaitNextEvent(0xffff, -1)
347## print 'DBG: WNE', ready, ev
348## if ready :
349## what,msg,when,where,mod = ev
350## part, window = Win.FindWindow(where)
351## if Dlg.IsDialogEvent(ev):
352## didit, dlgdone, itemdone = Dlg.DialogSelect(ev)
353## print 'DBG: DialogSelect', didit, dlgdone, itemdone, d
354## if didit and dlgdone == d:
355## return itemdone
356## elif window == d.GetDialogWindow():
357## d.GetDialogWindow().SelectWindow()
358## if part == 4: # inDrag
359## d.DragWindow(where, screenbounds)
360## else:
361## MacOS.HandleEvent(ev)
362## else:
363## MacOS.HandleEvent(ev)
364##
365def _setmenu(control, items):
Jack Jansene7bfc912001-01-09 22:22:58 +0000366 mhandle = control.GetControlData_Handle(Controls.kControlMenuPart,
Jack Jansenf86eda52000-09-19 22:42:38 +0000367 Controls.kControlPopupButtonMenuHandleTag)
368 menu = Menu.as_Menu(mhandle)
369 for item in items:
370 if type(item) == type(()):
371 label = item[0]
372 else:
373 label = item
374 if label[-1] == '=' or label[-1] == ':':
375 label = label[:-1]
376 menu.AppendMenu(label)
377## mhandle, mid = menu.getpopupinfo()
Jack Jansene7bfc912001-01-09 22:22:58 +0000378## control.SetControlData_Handle(Controls.kControlMenuPart,
Jack Jansenf86eda52000-09-19 22:42:38 +0000379## Controls.kControlPopupButtonMenuHandleTag, mhandle)
380 control.SetControlMinimum(1)
381 control.SetControlMaximum(len(items)+1)
382
383def _selectoption(d, optionlist, idx):
384 if idx < 0 or idx >= len(optionlist):
385 MacOS.SysBeep()
386 return
387 option = optionlist[idx]
Jack Jansen09c73432002-06-26 15:14:48 +0000388 if type(option) == type(()):
389 if len(option) == 4:
390 help = option[2]
391 elif len(option) > 1:
392 help = option[-1]
393 else:
394 help = ''
Jack Jansenf86eda52000-09-19 22:42:38 +0000395 else:
396 help = ''
397 h = d.GetDialogItemAsControl(ARGV_OPTION_EXPLAIN)
Jack Jansen09c73432002-06-26 15:14:48 +0000398 if help and len(help) > 250:
399 help = help[:250] + '...'
Jack Jansenf86eda52000-09-19 22:42:38 +0000400 Dlg.SetDialogItemText(h, help)
401 hasvalue = 0
402 if type(option) == type(()):
403 label = option[0]
404 else:
405 label = option
406 if label[-1] == '=' or label[-1] == ':':
407 hasvalue = 1
408 h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
409 Dlg.SetDialogItemText(h, '')
410 if hasvalue:
411 d.ShowDialogItem(ARGV_OPTION_VALUE)
412 d.SelectDialogItemText(ARGV_OPTION_VALUE, 0, 0)
413 else:
414 d.HideDialogItem(ARGV_OPTION_VALUE)
415
416
417def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID):
Jack Jansendde800e2002-11-07 23:07:05 +0000418 _initialize()
Jack Jansenf86eda52000-09-19 22:42:38 +0000419 d = GetNewDialog(id, -1)
420 if not d:
Jack Jansend05e1812002-08-02 11:03:19 +0000421 print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
Jack Jansenf86eda52000-09-19 22:42:38 +0000422 return
423# h = d.GetDialogItemAsControl(3)
424# SetDialogItemText(h, lf2cr(prompt))
425# h = d.GetDialogItemAsControl(4)
426# SetDialogItemText(h, lf2cr(default))
427# d.SelectDialogItemText(4, 0, 999)
428# d.SetDialogItem(4, 0, 255)
429 if optionlist:
430 _setmenu(d.GetDialogItemAsControl(ARGV_OPTION_GROUP), optionlist)
431 _selectoption(d, optionlist, 0)
432 else:
433 d.GetDialogItemAsControl(ARGV_OPTION_GROUP).DeactivateControl()
434 if commandlist:
435 _setmenu(d.GetDialogItemAsControl(ARGV_COMMAND_GROUP), commandlist)
Jack Jansen0bb0a902000-09-21 22:01:08 +0000436 if type(commandlist[0]) == type(()) and len(commandlist[0]) > 1:
Jack Jansenf86eda52000-09-19 22:42:38 +0000437 help = commandlist[0][-1]
438 h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
439 Dlg.SetDialogItemText(h, help)
440 else:
441 d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).DeactivateControl()
442 if not addoldfile:
443 d.GetDialogItemAsControl(ARGV_ADD_OLDFILE).DeactivateControl()
444 if not addnewfile:
445 d.GetDialogItemAsControl(ARGV_ADD_NEWFILE).DeactivateControl()
446 if not addfolder:
447 d.GetDialogItemAsControl(ARGV_ADD_FOLDER).DeactivateControl()
448 d.SetDialogDefaultItem(ARGV_ITEM_OK)
449 d.SetDialogCancelItem(ARGV_ITEM_CANCEL)
450 d.GetDialogWindow().ShowWindow()
451 d.DrawDialog()
Jack Janseneb308432001-09-09 00:36:01 +0000452 if hasattr(MacOS, 'SchedParams'):
453 appsw = MacOS.SchedParams(1, 0)
Jack Jansenf86eda52000-09-19 22:42:38 +0000454 try:
455 while 1:
456 stringstoadd = []
457 n = ModalDialog(None)
458 if n == ARGV_ITEM_OK:
459 break
460 elif n == ARGV_ITEM_CANCEL:
461 raise SystemExit
462 elif n == ARGV_OPTION_GROUP:
463 idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
464 _selectoption(d, optionlist, idx)
465 elif n == ARGV_OPTION_VALUE:
466 pass
467 elif n == ARGV_OPTION_ADD:
468 idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
469 if 0 <= idx < len(optionlist):
Jack Jansen0bb0a902000-09-21 22:01:08 +0000470 option = optionlist[idx]
471 if type(option) == type(()):
472 option = option[0]
Jack Jansenf86eda52000-09-19 22:42:38 +0000473 if option[-1] == '=' or option[-1] == ':':
474 option = option[:-1]
475 h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
476 value = Dlg.GetDialogItemText(h)
477 else:
478 value = ''
479 if len(option) == 1:
480 stringtoadd = '-' + option
481 else:
482 stringtoadd = '--' + option
483 stringstoadd = [stringtoadd]
484 if value:
485 stringstoadd.append(value)
486 else:
487 MacOS.SysBeep()
488 elif n == ARGV_COMMAND_GROUP:
489 idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
Jack Jansen0bb0a902000-09-21 22:01:08 +0000490 if 0 <= idx < len(commandlist) and type(commandlist[idx]) == type(()) and \
Jack Jansenf86eda52000-09-19 22:42:38 +0000491 len(commandlist[idx]) > 1:
492 help = commandlist[idx][-1]
493 h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
494 Dlg.SetDialogItemText(h, help)
495 elif n == ARGV_COMMAND_ADD:
496 idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
497 if 0 <= idx < len(commandlist):
Jack Jansen0bb0a902000-09-21 22:01:08 +0000498 command = commandlist[idx]
499 if type(command) == type(()):
500 command = command[0]
501 stringstoadd = [command]
Jack Jansenf86eda52000-09-19 22:42:38 +0000502 else:
503 MacOS.SysBeep()
504 elif n == ARGV_ADD_OLDFILE:
Jack Jansen08a7a0d2003-01-21 13:56:34 +0000505 pathname = AskFileForOpen()
506 if pathname:
507 stringstoadd = [pathname]
Jack Jansenf86eda52000-09-19 22:42:38 +0000508 elif n == ARGV_ADD_NEWFILE:
Jack Jansen08a7a0d2003-01-21 13:56:34 +0000509 pathname = AskFileForSave()
510 if pathname:
511 stringstoadd = [pathname]
Jack Jansenf86eda52000-09-19 22:42:38 +0000512 elif n == ARGV_ADD_FOLDER:
Jack Jansen08a7a0d2003-01-21 13:56:34 +0000513 pathname = AskFolder()
514 if pathname:
515 stringstoadd = [pathname]
Jack Jansenf86eda52000-09-19 22:42:38 +0000516 elif n == ARGV_CMDLINE_DATA:
517 pass # Nothing to do
518 else:
519 raise RuntimeError, "Unknown dialog item %d"%n
520
521 for stringtoadd in stringstoadd:
522 if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
523 stringtoadd = `stringtoadd`
524 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
525 oldstr = GetDialogItemText(h)
526 if oldstr and oldstr[-1] != ' ':
527 oldstr = oldstr + ' '
528 oldstr = oldstr + stringtoadd
529 if oldstr[-1] != ' ':
530 oldstr = oldstr + ' '
531 SetDialogItemText(h, oldstr)
532 d.SelectDialogItemText(ARGV_CMDLINE_DATA, 0x7fff, 0x7fff)
533 h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
534 oldstr = GetDialogItemText(h)
535 tmplist = string.split(oldstr)
536 newlist = []
537 while tmplist:
538 item = tmplist[0]
539 del tmplist[0]
540 if item[0] == '"':
541 while item[-1] != '"':
542 if not tmplist:
543 raise RuntimeError, "Unterminated quoted argument"
544 item = item + ' ' + tmplist[0]
545 del tmplist[0]
546 item = item[1:-1]
547 if item[0] == "'":
548 while item[-1] != "'":
549 if not tmplist:
550 raise RuntimeError, "Unterminated quoted argument"
551 item = item + ' ' + tmplist[0]
552 del tmplist[0]
553 item = item[1:-1]
554 newlist.append(item)
555 return newlist
556 finally:
Jack Janseneb308432001-09-09 00:36:01 +0000557 if hasattr(MacOS, 'SchedParams'):
558 apply(MacOS.SchedParams, appsw)
Jack Jansen0bb0a902000-09-21 22:01:08 +0000559 del d
Jack Jansenf0d12da2003-01-17 16:04:39 +0000560
Jack Jansen3032fe62003-01-21 14:38:32 +0000561def _process_Nav_args(dftflags, **args):
Jack Jansenf0d12da2003-01-17 16:04:39 +0000562 import aepack
563 import Carbon.AE
564 import Carbon.File
Jack Jansenf0d12da2003-01-17 16:04:39 +0000565 for k in args.keys():
Jack Jansen3032fe62003-01-21 14:38:32 +0000566 if args[k] is None:
567 del args[k]
Jack Jansenf0d12da2003-01-17 16:04:39 +0000568 # Set some defaults, and modify some arguments
569 if not args.has_key('dialogOptionFlags'):
570 args['dialogOptionFlags'] = dftflags
571 if args.has_key('defaultLocation') and \
572 not isinstance(args['defaultLocation'], Carbon.AE.AEDesc):
573 defaultLocation = args['defaultLocation']
574 if isinstance(defaultLocation, (Carbon.File.FSSpec, Carbon.File.FSRef)):
575 args['defaultLocation'] = aepack.pack(defaultLocation)
576 else:
577 defaultLocation = Carbon.File.FSRef(defaultLocation)
578 args['defaultLocation'] = aepack.pack(defaultLocation)
579 if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType):
Jack Jansene1c4f0b2003-01-21 22:57:53 +0000580 typeList = args['typeList'][:]
Jack Jansenf0d12da2003-01-17 16:04:39 +0000581 # Workaround for OSX typeless files:
582 if 'TEXT' in typeList and not '\0\0\0\0' in typeList:
583 typeList = typeList + ('\0\0\0\0',)
584 data = 'Pyth' + struct.pack("hh", 0, len(typeList))
585 for type in typeList:
586 data = data+type
587 args['typeList'] = Carbon.Res.Handle(data)
588 tpwanted = str
589 if args.has_key('wanted'):
590 tpwanted = args['wanted']
591 del args['wanted']
592 return args, tpwanted
593
Jack Jansen3032fe62003-01-21 14:38:32 +0000594def AskFileForOpen(
595 version=None,
596 defaultLocation=None,
597 dialogOptionFlags=None,
598 location=None,
599 clientName=None,
600 windowTitle=None,
601 actionButtonLabel=None,
602 cancelButtonLabel=None,
603 message=None,
604 preferenceKey=None,
605 popupExtension=None,
606 eventProc=None,
607 previewProc=None,
608 filterProc=None,
609 typeList=None,
610 wanted=None,
611 multiple=None):
612 """Display a dialog asking the user for a file to open.
613
614 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
615 the other arguments can be looked up in Apple's Navigation Services documentation"""
616
Jack Jansenf0d12da2003-01-17 16:04:39 +0000617 default_flags = 0x56 # Or 0xe4?
Jack Jansen3032fe62003-01-21 14:38:32 +0000618 args, tpwanted = _process_Nav_args(default_flags, version=version,
619 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
620 location=location,clientName=clientName,windowTitle=windowTitle,
621 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
622 message=message,preferenceKey=preferenceKey,
623 popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc,
624 filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000625 try:
626 rr = Nav.NavChooseFile(args)
627 good = 1
628 except Nav.error, arg:
629 if arg[0] != -128: # userCancelledErr
630 raise Nav.error, arg
631 return None
632 if not rr.validRecord or not rr.selection:
633 return None
634 if issubclass(tpwanted, Carbon.File.FSRef):
635 return tpwanted(rr.selection_fsr[0])
636 if issubclass(tpwanted, Carbon.File.FSSpec):
637 return tpwanted(rr.selection[0])
638 if issubclass(tpwanted, str):
Jack Jansen2b3ce3b2003-01-26 20:22:41 +0000639 return tpwanted(rr.selection_fsr[0].as_pathname())
Jack Jansenf0d12da2003-01-17 16:04:39 +0000640 if issubclass(tpwanted, unicode):
Jack Jansen2b3ce3b2003-01-26 20:22:41 +0000641 return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
Jack Jansenf0d12da2003-01-17 16:04:39 +0000642 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
643
Jack Jansen3032fe62003-01-21 14:38:32 +0000644def AskFileForSave(
645 version=None,
646 defaultLocation=None,
647 dialogOptionFlags=None,
648 location=None,
649 clientName=None,
650 windowTitle=None,
651 actionButtonLabel=None,
652 cancelButtonLabel=None,
653 savedFileName=None,
654 message=None,
655 preferenceKey=None,
656 popupExtension=None,
657 eventProc=None,
658 fileType=None,
659 fileCreator=None,
660 wanted=None,
661 multiple=None):
662 """Display a dialog asking the user for a filename to save to.
663
664 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
665 the other arguments can be looked up in Apple's Navigation Services documentation"""
666
667
Jack Jansenf0d12da2003-01-17 16:04:39 +0000668 default_flags = 0x07
Jack Jansen3032fe62003-01-21 14:38:32 +0000669 args, tpwanted = _process_Nav_args(default_flags, version=version,
670 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
671 location=location,clientName=clientName,windowTitle=windowTitle,
672 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
673 savedFileName=savedFileName,message=message,preferenceKey=preferenceKey,
674 popupExtension=popupExtension,fileType=fileType,fileCreator=fileCreator,
675 wanted=wanted,multiple=multiple)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000676 try:
677 rr = Nav.NavPutFile(args)
678 good = 1
679 except Nav.error, arg:
680 if arg[0] != -128: # userCancelledErr
681 raise Nav.error, arg
682 return None
683 if not rr.validRecord or not rr.selection:
684 return None
685 if issubclass(tpwanted, Carbon.File.FSRef):
686 raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave"
687 if issubclass(tpwanted, Carbon.File.FSSpec):
688 return tpwanted(rr.selection[0])
689 if issubclass(tpwanted, (str, unicode)):
Jack Jansen2b3ce3b2003-01-26 20:22:41 +0000690 if sys.platform == 'mac':
691 fullpath = rr.selection[0].as_pathname()
692 else:
693 # This is gross, and probably incorrect too
694 vrefnum, dirid, name = rr.selection[0].as_tuple()
695 pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, ''))
696 pardir_fsr = Carbon.File.FSRef(pardir_fss)
697 pardir_path = pardir_fsr.FSRefMakePath() # This is utf-8
698 name_utf8 = unicode(name, 'macroman').encode('utf8')
699 fullpath = os.path.join(pardir_path, name_utf8)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000700 if issubclass(tpwanted, unicode):
701 return unicode(fullpath, 'utf8')
702 return tpwanted(fullpath)
703 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
704
Jack Jansen3032fe62003-01-21 14:38:32 +0000705def AskFolder(
706 version=None,
707 defaultLocation=None,
708 dialogOptionFlags=None,
709 location=None,
710 clientName=None,
711 windowTitle=None,
712 actionButtonLabel=None,
713 cancelButtonLabel=None,
714 message=None,
715 preferenceKey=None,
716 popupExtension=None,
717 eventProc=None,
718 filterProc=None,
719 wanted=None,
720 multiple=None):
721 """Display a dialog asking the user for select a folder.
722
723 wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
724 the other arguments can be looked up in Apple's Navigation Services documentation"""
725
Jack Jansenf0d12da2003-01-17 16:04:39 +0000726 default_flags = 0x17
Jack Jansen3032fe62003-01-21 14:38:32 +0000727 args, tpwanted = _process_Nav_args(default_flags, version=version,
728 defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
729 location=location,clientName=clientName,windowTitle=windowTitle,
730 actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
731 message=message,preferenceKey=preferenceKey,
732 popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc,
733 wanted=wanted,multiple=multiple)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000734 try:
735 rr = Nav.NavChooseFolder(args)
736 good = 1
737 except Nav.error, arg:
738 if arg[0] != -128: # userCancelledErr
739 raise Nav.error, arg
740 return None
741 if not rr.validRecord or not rr.selection:
742 return None
743 if issubclass(tpwanted, Carbon.File.FSRef):
744 return tpwanted(rr.selection_fsr[0])
745 if issubclass(tpwanted, Carbon.File.FSSpec):
746 return tpwanted(rr.selection[0])
747 if issubclass(tpwanted, str):
Jack Jansen2b3ce3b2003-01-26 20:22:41 +0000748 return tpwanted(rr.selection_fsr[0].as_pathname())
Jack Jansenf0d12da2003-01-17 16:04:39 +0000749 if issubclass(tpwanted, unicode):
Jack Jansen2b3ce3b2003-01-26 20:22:41 +0000750 return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
Jack Jansenf0d12da2003-01-17 16:04:39 +0000751 raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
752
753
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000754def test():
Jack Jansen2b3ce3b2003-01-26 20:22:41 +0000755 import time, macfs
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000756
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000757 Message("Testing EasyDialogs.")
Jack Jansenf86eda52000-09-19 22:42:38 +0000758 optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
759 ('flags=', 'Valued option'), ('f:', 'Short valued option'))
760 commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
761 argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
Jack Jansenf0d12da2003-01-17 16:04:39 +0000762 Message("Command line: %s"%' '.join(argv))
Jack Jansenf86eda52000-09-19 22:42:38 +0000763 for i in range(len(argv)):
764 print 'arg[%d] = %s'%(i, `argv[i]`)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000765 ok = AskYesNoCancel("Do you want to proceed?")
Jack Jansen60429e01999-12-13 16:07:01 +0000766 ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000767 if ok > 0:
Jack Jansend61f92b1999-01-22 13:14:06 +0000768 s = AskString("Enter your first name", "Joe")
Jack Jansen60429e01999-12-13 16:07:01 +0000769 s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
770 if not s2:
771 Message("%s has no secret nickname"%s)
772 else:
773 Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
Jack Jansenf0d12da2003-01-17 16:04:39 +0000774 else:
775 s = 'Anonymous'
776 rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=macfs.FSSpec)
777 Message("rv: %s"%rv)
778 rv = AskFileForSave(wanted=macfs.FSSpec, savedFileName="%s.txt"%s)
779 Message("rv.as_pathname: %s"%rv.as_pathname())
780 rv = AskFolder()
781 Message("Folder name: %s"%rv)
Jack Jansen911e87d2001-08-27 15:24:07 +0000782 text = ( "Working Hard...", "Hardly Working..." ,
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000783 "So far, so good!", "Keep on truckin'" )
Jack Jansen911e87d2001-08-27 15:24:07 +0000784 bar = ProgressBar("Progress, progress...", 0, label="Ramping up...")
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000785 try:
Jack Janseneb308432001-09-09 00:36:01 +0000786 if hasattr(MacOS, 'SchedParams'):
787 appsw = MacOS.SchedParams(1, 0)
Jack Jansen911e87d2001-08-27 15:24:07 +0000788 for i in xrange(20):
789 bar.inc()
790 time.sleep(0.05)
791 bar.set(0,100)
792 for i in xrange(100):
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000793 bar.set(i)
Jack Jansen911e87d2001-08-27 15:24:07 +0000794 time.sleep(0.05)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000795 if i % 10 == 0:
796 bar.label(text[(i/10) % 4])
797 bar.label("Done.")
Jack Jansen911e87d2001-08-27 15:24:07 +0000798 time.sleep(1.0) # give'em a chance to see "Done."
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000799 finally:
800 del bar
Jack Janseneb308432001-09-09 00:36:01 +0000801 if hasattr(MacOS, 'SchedParams'):
802 apply(MacOS.SchedParams, appsw)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000803
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000804if __name__ == '__main__':
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000805 try:
806 test()
807 except KeyboardInterrupt:
808 Message("Operation Canceled.")
809