blob: 24f65157b92972b23dd019ca317ef11ea859be49 [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
75 id = 257
76 d = GetNewDialog(id, -1)
77 if not d:
78 print "Can't get DLOG resource with id =", id
79 return
Jack Jansene4b40381995-07-17 13:25:15 +000080 tp, h, rect = d.GetDialogItem(3)
Jack Jansena5a49811998-07-01 15:47:44 +000081 SetDialogItemText(h, lf2cr(prompt))
Jack Jansene4b40381995-07-17 13:25:15 +000082 tp, h, rect = d.GetDialogItem(4)
Jack Jansena5a49811998-07-01 15:47:44 +000083 SetDialogItemText(h, lf2cr(default))
Jack Jansend61f92b1999-01-22 13:14:06 +000084 d.SelectDialogItemText(4, 0, 999)
Jack Jansene4b40381995-07-17 13:25:15 +000085# d.SetDialogItem(4, 0, 255)
Jack Jansen208c15a1999-02-16 16:06:39 +000086 if ok != None:
87 tp, h, rect = d.GetDialogItem(1)
88 h.as_Control().SetControlTitle(ok)
89 if cancel != None:
90 tp, h, rect = d.GetDialogItem(2)
91 h.as_Control().SetControlTitle(cancel)
Jack Jansen3a87f5b1995-11-14 10:13:49 +000092 d.SetDialogDefaultItem(1)
93 d.SetDialogCancelItem(2)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000094 while 1:
95 n = ModalDialog(None)
96 if n == 1:
Jack Jansene4b40381995-07-17 13:25:15 +000097 tp, h, rect = d.GetDialogItem(4)
Jack Jansena5a49811998-07-01 15:47:44 +000098 return cr2lf(GetDialogItemText(h))
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +000099 if n == 2: return None
100
Jack Jansenb92268a1999-02-10 22:38:44 +0000101def AskPassword(prompt, default='', id=257):
102 """Display a PROMPT string and a text entry field with a DEFAULT string.
103 The string is displayed as bullets only.
104
105 Return the contents of the text entry field when the user clicks the
106 OK button or presses Return.
107 Return None when the user clicks the Cancel button.
108
109 If omitted, DEFAULT is empty.
110
111 The PROMPT and DEFAULT strings, as well as the return value,
112 can be at most 255 characters long.
113 """
114 d = GetNewDialog(id, -1)
115 if not d:
116 print "Can't get DLOG resource with id =", id
117 return
118 tp, h, rect = d.GetDialogItem(3) # STATIC TEXT ITEM <= prompt
119 SetDialogItemText(h, lf2cr(prompt))
120 tp, h, rect = d.GetDialogItem(4) # EDIT TEXT ITEM
121 bullets = '\245'*len(default)
122 SetDialogItemText(h, bullets )
123 d.SelectDialogItemText(4, 999, 999)
124 d.SetDialogDefaultItem(Dialogs.ok)
125 d.SetDialogCancelItem(Dialogs.cancel)
126 string = default
127 oldschedparams = MacOS.SchedParams(0,0)
128 while 1:
Just van Rossumcdcc0f01999-02-15 00:04:05 +0000129 ready,ev = Evt.WaitNextEvent(Events.everyEvent, 6)
Jack Jansenb92268a1999-02-10 22:38:44 +0000130 if not ready: continue
131 what,msg,when,where,mod = ev
132 if what == 0 : Dlg.DialogSelect(ev) # for blinking caret
133 elif Dlg.IsDialogEvent(ev):
Just van Rossumcdcc0f01999-02-15 00:04:05 +0000134 if what in (Events.keyDown, Events.autoKey):
Jack Jansenb92268a1999-02-10 22:38:44 +0000135 charcode = msg & Events.charCodeMask
136 if ( mod & Events.cmdKey ):
137 MacOS.SysBeep()
138 continue # don't do cut & paste commands
139 else:
140 if charcode == Events.kReturnCharCode:
141 break
142 elif charcode == Events.kEscapeCharCode:
143 string = None
144 break
145 elif charcode in (Events.kLeftArrowCharCode,
146 Events.kBackspaceCharCode):
147 string = string[:-1]
148 else:
149 string = string + chr(charcode)
150 msg = 0245 # Octal code for bullet
151 ev = (what,msg,when,where,mod)
152 rs, win, item = Dlg.DialogSelect(ev)
153 if item == Dialogs.ok :
154 break
155 elif item == Dialogs.cancel :
156 string = None
157 break
158 elif what == Events.mouseDown:
159 part, win = Win.FindWindow(where)
160 if part == Windows.inDrag and win:
161 win.DragWindow(where, screenbounds)
162 elif part == Windows.inMenuBar:
163 MacOS.HandleEvent(ev)
164 else:
165 MacOS.SysBeep() # Cannot handle selections, unfortunately
166
167 elif what == Events.updateEvt: MacOS.HandleEvent(ev)
168 apply(MacOS.SchedParams, oldschedparams)
169 return string
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000170
Jack Jansen3f5aef71997-06-20 16:23:37 +0000171def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=258):
Jack Jansencf2efc61999-02-25 22:05:45 +0000172 """Display a QUESTION string which can be answered with Yes or No.
173
174 Return 1 when the user clicks the Yes button.
175 Return 0 when the user clicks the No button.
176 Return -1 when the user clicks the Cancel button.
177
178 When the user presses Return, the DEFAULT value is returned.
179 If omitted, this is 0 (No).
180
181 The QUESTION strign ca be at most 255 characters.
182 """
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000183
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000184 d = GetNewDialog(id, -1)
185 if not d:
186 print "Can't get DLOG resource with id =", id
187 return
188 # Button assignments:
189 # 1 = default (invisible)
190 # 2 = Yes
191 # 3 = No
192 # 4 = Cancel
193 # The question string is item 5
Jack Jansene4b40381995-07-17 13:25:15 +0000194 tp, h, rect = d.GetDialogItem(5)
Jack Jansena5a49811998-07-01 15:47:44 +0000195 SetDialogItemText(h, lf2cr(question))
Jack Jansen3f5aef71997-06-20 16:23:37 +0000196 if yes != None:
197 tp, h, rect = d.GetDialogItem(2)
198 h.as_Control().SetControlTitle(yes)
199 if no != None:
200 tp, h, rect = d.GetDialogItem(3)
201 h.as_Control().SetControlTitle(no)
202 if cancel != None:
Jack Jansen208c15a1999-02-16 16:06:39 +0000203 if cancel == '':
204 d.HideDialogItem(4)
205 else:
206 tp, h, rect = d.GetDialogItem(4)
207 h.as_Control().SetControlTitle(cancel)
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000208 d.SetDialogCancelItem(4)
Jack Jansen0b690db1996-04-10 14:49:41 +0000209 if default == 1:
210 d.SetDialogDefaultItem(2)
211 elif default == 0:
212 d.SetDialogDefaultItem(3)
213 elif default == -1:
214 d.SetDialogDefaultItem(4)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000215 while 1:
216 n = ModalDialog(None)
217 if n == 1: return default
218 if n == 2: return 1
219 if n == 3: return 0
220 if n == 4: return -1
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000221
222
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000223
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000224
225screenbounds = Qd.qd.screenBits.bounds
226screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
227 screenbounds[2]-4, screenbounds[3]-4
228
229
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000230class ProgressBar:
Jack Jansen3f5aef71997-06-20 16:23:37 +0000231 def __init__(self, title="Working...", maxval=100, label="", id=259):
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000232 self.maxval = maxval
233 self.curval = -1
Jack Jansen3f5aef71997-06-20 16:23:37 +0000234 self.d = GetNewDialog(id, -1)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000235 self.title(title)
236 self.label(label)
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000237 self._update(0)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000238
239 def __del__( self ):
Jack Jansen48c55271997-05-13 15:41:07 +0000240 self.d.BringToFront()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000241 self.d.HideWindow()
242 del self.d
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000243
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000244 def title(self, newstr=""):
245 """title(text) - Set title of progress window"""
Jack Jansen48c55271997-05-13 15:41:07 +0000246 self.d.BringToFront()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000247 w = self.d.GetDialogWindow()
248 w.SetWTitle(newstr)
249
250 def label( self, *newstr ):
251 """label(text) - Set text in progress box"""
Jack Jansen48c55271997-05-13 15:41:07 +0000252 self.d.BringToFront()
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000253 if newstr:
Jack Jansena5a49811998-07-01 15:47:44 +0000254 self._label = lf2cr(newstr[0])
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000255 tp, text_h, rect = self.d.GetDialogItem(2)
256 SetDialogItemText(text_h, self._label)
257
258
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000259 def _update(self, value):
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000260 self.d.BringToFront()
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000261 tp, h, bar_rect = self.d.GetDialogItem(3)
262 Qd.SetPort(self.d)
263
264 Qd.FrameRect(bar_rect) # Draw outline
265
266 inner_rect = Qd.InsetRect(bar_rect, 1, 1)
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000267 l, t, r, b = inner_rect
Jack Jansen3a4b3b01996-10-15 16:11:50 +0000268
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000269 Qd.ForeColor(QuickDraw.blackColor)
270 Qd.BackColor(QuickDraw.blackColor)
Jack Jansen3a4b3b01996-10-15 16:11:50 +0000271 Qd.PaintRect((l, t, int(l + (r-l)*value/self.maxval), b)) # Draw bar
272
273 Qd.ForeColor(QuickDraw.whiteColor)
274 Qd.BackColor(QuickDraw.whiteColor)
275 Qd.PaintRect((int(l + (r-l)*value/self.maxval), t, r, b)) # Clear rest
276
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000277 # Restore settings
278 Qd.ForeColor(QuickDraw.blackColor)
279 Qd.BackColor(QuickDraw.whiteColor)
280
281 # Test for cancel button
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000282
283 ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1 )
284 if ready :
285 what,msg,when,where,mod = ev
286 part = Win.FindWindow(where)[0]
287 if Dlg.IsDialogEvent(ev):
288 ds = Dlg.DialogSelect(ev)
289 if ds[0] and ds[1] == self.d and ds[-1] == 1:
290 raise KeyboardInterrupt, ev
291 else:
292 if part == 4: # inDrag
293 self.d.DragWindow(where, screenbounds)
294 else:
295 MacOS.HandleEvent(ev)
296
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000297
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000298 def set(self, value):
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000299 """set(value) - Set progress bar position"""
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000300 if value < 0: value = 0
301 if value > self.maxval: value = self.maxval
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000302 self.curval = value
Jack Jansen3a87f5b1995-11-14 10:13:49 +0000303 self._update(value)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000304
305 def inc(self, n=1):
306 """inc(amt) - Increment progress bar position"""
307 self.set(self.curval + n)
308
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000309def test():
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000310 import time
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000311
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000312 Message("Testing EasyDialogs.")
313 ok = AskYesNoCancel("Do you want to proceed?")
Jack Jansen3f5aef71997-06-20 16:23:37 +0000314 ok = AskYesNoCancel("Do you want to identify?", yes="Indentify", no="Don't identify")
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000315 if ok > 0:
Jack Jansend61f92b1999-01-22 13:14:06 +0000316 s = AskString("Enter your first name", "Joe")
Jack Jansena5a49811998-07-01 15:47:44 +0000317 Message("Thank you,\n%s" % `s`)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000318 text = ( "Working Hard...", "Hardly Working..." ,
319 "So far, so good!", "Keep on truckin'" )
320 bar = ProgressBar("Progress, progress...", 100)
321 try:
Jack Jansen3368cb71997-06-12 10:51:18 +0000322 appsw = MacOS.SchedParams(1, 0)
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000323 for i in range(100):
324 bar.set(i)
325 time.sleep(0.1)
326 if i % 10 == 0:
327 bar.label(text[(i/10) % 4])
328 bar.label("Done.")
329 time.sleep(0.3) # give'em a chance to see the done.
330 finally:
331 del bar
Jack Jansen3368cb71997-06-12 10:51:18 +0000332 apply(MacOS.SchedParams, appsw)
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000333
334
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000335
336
Guido van Rossum8f4b6ad1995-04-05 09:18:35 +0000337if __name__ == '__main__':
Jack Jansen1d63d8c1997-05-12 15:44:14 +0000338 try:
339 test()
340 except KeyboardInterrupt:
341 Message("Operation Canceled.")
342