blob: db855f58d6beab4236b9a0428d50bb5cd479f0e4 [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 Jansen3a87f5b1995-11-14 10:13:49 +00007bar = Progress(label, maxvalue) -- Display a progress bar
8bar.set(value) -- Set value
Jack Jansen1d63d8c1997-05-12 15:44:14 +00009bar.inc( *amount ) -- increment value by amount (default=1)
10bar.label( *newlabel ) -- get or set text label.
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000011
12More documentation in each function.
13This module uses DLOG resources 256, 257 and 258.
14Based upon STDWIN dialogs with the same names and functions.
15"""
16
Jack Jansene4b40381995-07-17 13:25:15 +000017from Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText, ModalDialog
Jack Jansen3a87f5b1995-11-14 10:13:49 +000018import Qd
Jack Jansen3a87f5b1995-11-14 10:13:49 +000019import QuickDraw
Jack Jansenb92268a1999-02-10 22:38:44 +000020import Dialogs
21import Windows
Jack Jansen1d63d8c1997-05-12 15:44:14 +000022import Dlg,Win,Evt,Events # sdm7g
Jack Jansena5a49811998-07-01 15:47:44 +000023import MacOS
24import string
25
26def cr2lf(text):
27 if '\r' in text:
28 text = string.join(string.split(text, '\r'), '\n')
29 return text
30
31def lf2cr(text):
32 if '\n' in text:
33 text = string.join(string.split(text, '\n'), '\r')
Jack Jansend5af7bd1998-09-28 10:37:08 +000034 if len(text) > 253:
35 text = text[:253] + '\311'
Jack Jansena5a49811998-07-01 15:47:44 +000036 return text
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000037
Jack Jansen208c15a1999-02-16 16:06:39 +000038def Message(msg, id=256, ok=None):
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000039 """Display a MESSAGE string.
40
41 Return when the user clicks the OK button or presses Return.
42
43 The MESSAGE string can be at most 255 characters long.
44 """
45
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000046 d = GetNewDialog(id, -1)
47 if not d:
48 print "Can't get DLOG resource with id =", id
49 return
Jack Jansene4b40381995-07-17 13:25:15 +000050 tp, h, rect = d.GetDialogItem(2)
Jack Jansena5a49811998-07-01 15:47:44 +000051 SetDialogItemText(h, lf2cr(msg))
Jack Jansen208c15a1999-02-16 16:06:39 +000052 if ok != None:
53 tp, h, rect = d.GetDialogItem(1)
54 h.as_Control().SetControlTitle(ok)
Jack Jansen3a87f5b1995-11-14 10:13:49 +000055 d.SetDialogDefaultItem(1)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000056 while 1:
57 n = ModalDialog(None)
58 if n == 1:
59 return
60
61
Jack Jansen208c15a1999-02-16 16:06:39 +000062def AskString(prompt, default = "", id=257, ok=None, cancel=None):
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000063 """Display a PROMPT string and a text entry field with a DEFAULT string.
64
65 Return the contents of the text entry field when the user clicks the
66 OK button or presses Return.
67 Return None when the user clicks the Cancel button.
68
69 If omitted, DEFAULT is empty.
70
71 The PROMPT and DEFAULT strings, as well as the return value,
72 can be at most 255 characters long.
73 """
74
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000075 d = GetNewDialog(id, -1)
76 if not d:
77 print "Can't get DLOG resource with id =", id
78 return
Jack Jansene4b40381995-07-17 13:25:15 +000079 tp, h, rect = d.GetDialogItem(3)
Jack Jansena5a49811998-07-01 15:47:44 +000080 SetDialogItemText(h, lf2cr(prompt))
Jack Jansene4b40381995-07-17 13:25:15 +000081 tp, h, rect = d.GetDialogItem(4)
Jack Jansena5a49811998-07-01 15:47:44 +000082 SetDialogItemText(h, lf2cr(default))
Jack Jansend61f92b1999-01-22 13:14:06 +000083 d.SelectDialogItemText(4, 0, 999)
Jack Jansene4b40381995-07-17 13:25:15 +000084# d.SetDialogItem(4, 0, 255)
Jack Jansen208c15a1999-02-16 16:06:39 +000085 if ok != None:
86 tp, h, rect = d.GetDialogItem(1)
87 h.as_Control().SetControlTitle(ok)
88 if cancel != None:
89 tp, h, rect = d.GetDialogItem(2)
90 h.as_Control().SetControlTitle(cancel)
Jack Jansen3a87f5b1995-11-14 10:13:49 +000091 d.SetDialogDefaultItem(1)
92 d.SetDialogCancelItem(2)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000093 while 1:
94 n = ModalDialog(None)
95 if n == 1:
Jack Jansene4b40381995-07-17 13:25:15 +000096 tp, h, rect = d.GetDialogItem(4)
Jack Jansena5a49811998-07-01 15:47:44 +000097 return cr2lf(GetDialogItemText(h))
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000098 if n == 2: return None
99
Jack Jansenb92268a1999-02-10 22:38:44 +0000100def AskPassword(prompt, default='', id=257):
101 """Display a PROMPT string and a text entry field with a DEFAULT string.
102 The string is displayed as bullets only.
103
104 Return the contents of the text entry field when the user clicks the
105 OK button or presses Return.
106 Return None when the user clicks the Cancel button.
107
108 If omitted, DEFAULT is empty.
109
110 The PROMPT and DEFAULT strings, as well as the return value,
111 can be at most 255 characters long.
112 """
113 d = GetNewDialog(id, -1)
114 if not d:
115 print "Can't get DLOG resource with id =", id
116 return
117 tp, h, rect = d.GetDialogItem(3) # STATIC TEXT ITEM <= prompt
118 SetDialogItemText(h, lf2cr(prompt))
119 tp, h, rect = d.GetDialogItem(4) # EDIT TEXT ITEM
120 bullets = '\245'*len(default)
121 SetDialogItemText(h, bullets )
122 d.SelectDialogItemText(4, 999, 999)
123 d.SetDialogDefaultItem(Dialogs.ok)
124 d.SetDialogCancelItem(Dialogs.cancel)
125 string = default
126 oldschedparams = MacOS.SchedParams(0,0)
127 while 1:
Just van Rossumcdcc0f01999-02-15 00:04:05 +0000128 ready,ev = Evt.WaitNextEvent(Events.everyEvent, 6)
Jack Jansenb92268a1999-02-10 22:38:44 +0000129 if not ready: continue
130 what,msg,when,where,mod = ev
131 if what == 0 : Dlg.DialogSelect(ev) # for blinking caret
132 elif Dlg.IsDialogEvent(ev):
Just van Rossumcdcc0f01999-02-15 00:04:05 +0000133 if what in (Events.keyDown, Events.autoKey):
Jack Jansenb92268a1999-02-10 22:38:44 +0000134 charcode = msg & Events.charCodeMask
135 if ( mod & Events.cmdKey ):
136 MacOS.SysBeep()
137 continue # don't do cut & paste commands
138 else:
139 if charcode == Events.kReturnCharCode:
140 break
141 elif charcode == Events.kEscapeCharCode:
142 string = None
143 break
144 elif charcode in (Events.kLeftArrowCharCode,
145 Events.kBackspaceCharCode):
146 string = string[:-1]
147 else:
148 string = string + chr(charcode)
149 msg = 0245 # Octal code for bullet
150 ev = (what,msg,when,where,mod)
151 rs, win, item = Dlg.DialogSelect(ev)
152 if item == Dialogs.ok :
153 break
154 elif item == Dialogs.cancel :
155 string = None
156 break
157 elif what == Events.mouseDown:
158 part, win = Win.FindWindow(where)
159 if part == Windows.inDrag and win:
160 win.DragWindow(where, screenbounds)
161 elif part == Windows.inMenuBar:
162 MacOS.HandleEvent(ev)
163 else:
164 MacOS.SysBeep() # Cannot handle selections, unfortunately
165
166 elif what == Events.updateEvt: MacOS.HandleEvent(ev)
167 apply(MacOS.SchedParams, oldschedparams)
168 return string
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000169
Jack Jansen3f5aef71997-06-20 16:23:37 +0000170def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=258):
Jack Jansencf2efc61999-02-25 22:05:45 +0000171 """Display a QUESTION string which can be answered with Yes or No.
172
173 Return 1 when the user clicks the Yes button.
174 Return 0 when the user clicks the No button.
175 Return -1 when the user clicks the Cancel button.
176
177 When the user presses Return, the DEFAULT value is returned.
178 If omitted, this is 0 (No).
179
180 The QUESTION strign ca be at most 255 characters.
181 """
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000182
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000183 d = GetNewDialog(id, -1)
184 if not d:
185 print "Can't get DLOG resource with id =", id
186 return
187 # Button assignments:
188 # 1 = default (invisible)
189 # 2 = Yes
190 # 3 = No
191 # 4 = Cancel
192 # The question string is item 5
Jack Jansene4b40381995-07-17 13:25:15 +0000193 tp, h, rect = d.GetDialogItem(5)
Jack Jansena5a49811998-07-01 15:47:44 +0000194 SetDialogItemText(h, lf2cr(question))
Jack Jansen3f5aef71997-06-20 16:23:37 +0000195 if yes != None:
196 tp, h, rect = d.GetDialogItem(2)
197 h.as_Control().SetControlTitle(yes)
198 if no != None:
199 tp, h, rect = d.GetDialogItem(3)
200 h.as_Control().SetControlTitle(no)
201 if cancel != None:
Jack Jansen208c15a1999-02-16 16:06:39 +0000202 if cancel == '':
203 d.HideDialogItem(4)
204 else:
205 tp, h, rect = d.GetDialogItem(4)
206 h.as_Control().SetControlTitle(cancel)
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000207 d.SetDialogCancelItem(4)
Jack Jansen0b690db1996-04-10 14:49:41 +0000208 if default == 1:
209 d.SetDialogDefaultItem(2)
210 elif default == 0:
211 d.SetDialogDefaultItem(3)
212 elif default == -1:
213 d.SetDialogDefaultItem(4)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000214 while 1:
215 n = ModalDialog(None)
216 if n == 1: return default
217 if n == 2: return 1
218 if n == 3: return 0
219 if n == 4: return -1
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000220
221
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000222
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000223
224screenbounds = Qd.qd.screenBits.bounds
225screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
226 screenbounds[2]-4, screenbounds[3]-4
227
228
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000229class ProgressBar:
Jack Jansen3f5aef71997-06-20 16:23:37 +0000230 def __init__(self, title="Working...", maxval=100, label="", id=259):
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000231 self.maxval = maxval
232 self.curval = -1
Jack Jansen3f5aef71997-06-20 16:23:37 +0000233 self.d = GetNewDialog(id, -1)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000234 self.title(title)
235 self.label(label)
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000236 self._update(0)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000237
238 def __del__( self ):
Jack Jansen48c55271997-05-13 15:41:07 +0000239 self.d.BringToFront()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000240 self.d.HideWindow()
241 del self.d
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000242
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000243 def title(self, newstr=""):
244 """title(text) - Set title of progress window"""
Jack Jansen48c55271997-05-13 15:41:07 +0000245 self.d.BringToFront()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000246 w = self.d.GetDialogWindow()
247 w.SetWTitle(newstr)
248
249 def label( self, *newstr ):
250 """label(text) - Set text in progress box"""
Jack Jansen48c55271997-05-13 15:41:07 +0000251 self.d.BringToFront()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000252 if newstr:
Jack Jansena5a49811998-07-01 15:47:44 +0000253 self._label = lf2cr(newstr[0])
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000254 tp, text_h, rect = self.d.GetDialogItem(2)
255 SetDialogItemText(text_h, self._label)
256
257
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000258 def _update(self, value):
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000259 self.d.BringToFront()
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000260 tp, h, bar_rect = self.d.GetDialogItem(3)
261 Qd.SetPort(self.d)
262
263 Qd.FrameRect(bar_rect) # Draw outline
264
265 inner_rect = Qd.InsetRect(bar_rect, 1, 1)
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000266 l, t, r, b = inner_rect
Jack Jansen3a4b3b01996-10-15 16:11:50 +0000267
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000268 Qd.ForeColor(QuickDraw.blackColor)
269 Qd.BackColor(QuickDraw.blackColor)
Jack Jansen3a4b3b01996-10-15 16:11:50 +0000270 Qd.PaintRect((l, t, int(l + (r-l)*value/self.maxval), b)) # Draw bar
271
272 Qd.ForeColor(QuickDraw.whiteColor)
273 Qd.BackColor(QuickDraw.whiteColor)
274 Qd.PaintRect((int(l + (r-l)*value/self.maxval), t, r, b)) # Clear rest
275
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000276 # Restore settings
277 Qd.ForeColor(QuickDraw.blackColor)
278 Qd.BackColor(QuickDraw.whiteColor)
279
280 # Test for cancel button
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000281
282 ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1 )
283 if ready :
284 what,msg,when,where,mod = ev
285 part = Win.FindWindow(where)[0]
286 if Dlg.IsDialogEvent(ev):
287 ds = Dlg.DialogSelect(ev)
288 if ds[0] and ds[1] == self.d and ds[-1] == 1:
289 raise KeyboardInterrupt, ev
290 else:
291 if part == 4: # inDrag
292 self.d.DragWindow(where, screenbounds)
293 else:
294 MacOS.HandleEvent(ev)
295
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000296
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000297 def set(self, value):
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000298 """set(value) - Set progress bar position"""
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000299 if value < 0: value = 0
300 if value > self.maxval: value = self.maxval
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000301 self.curval = value
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000302 self._update(value)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000303
304 def inc(self, n=1):
305 """inc(amt) - Increment progress bar position"""
306 self.set(self.curval + n)
307
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000308def test():
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000309 import time
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000310
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000311 Message("Testing EasyDialogs.")
312 ok = AskYesNoCancel("Do you want to proceed?")
Jack Jansen3f5aef71997-06-20 16:23:37 +0000313 ok = AskYesNoCancel("Do you want to identify?", yes="Indentify", no="Don't identify")
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000314 if ok > 0:
Jack Jansend61f92b1999-01-22 13:14:06 +0000315 s = AskString("Enter your first name", "Joe")
Jack Jansena5a49811998-07-01 15:47:44 +0000316 Message("Thank you,\n%s" % `s`)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000317 text = ( "Working Hard...", "Hardly Working..." ,
318 "So far, so good!", "Keep on truckin'" )
319 bar = ProgressBar("Progress, progress...", 100)
320 try:
Jack Jansen3368cb71997-06-12 10:51:18 +0000321 appsw = MacOS.SchedParams(1, 0)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000322 for i in range(100):
323 bar.set(i)
324 time.sleep(0.1)
325 if i % 10 == 0:
326 bar.label(text[(i/10) % 4])
327 bar.label("Done.")
328 time.sleep(0.3) # give'em a chance to see the done.
329 finally:
330 del bar
Jack Jansen3368cb71997-06-12 10:51:18 +0000331 apply(MacOS.SchedParams, appsw)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000332
333
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000334
335
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000336if __name__ == '__main__':
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000337 try:
338 test()
339 except KeyboardInterrupt:
340 Message("Operation Canceled.")
341