~pythonregexp2.7/python/issue2636-11

25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
1
"""Easy to use dialogs.
2
3
Message(msg) -- display a message and an OK button.
4
AskString(prompt, default) -- ask for a string, display OK and Cancel buttons.
5
AskPassword(prompt, default) -- like AskString(), but shows text as bullets.
6
AskYesNoCancel(question, default) -- display a question and Yes, No and Cancel buttons.
25689 by jackjansen
Spell out the arguments to AskFileForOpen and friends, so help() gives useful
7
GetArgv(optionlist, commandlist) -- fill a sys.argv-like list using a dialog
26791 by rhettinger
SF patch #701494: more apply removals
8
AskFileForOpen(...) -- Ask the user for an existing file
25689 by jackjansen
Spell out the arguments to AskFileForOpen and friends, so help() gives useful
9
AskFileForSave(...) -- Ask the user for an output file
10
AskFolder(...) -- Ask the user to select a folder
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
11
bar = Progress(label, maxvalue) -- Display a progress bar
12
bar.set(value) -- Set value
13
bar.inc( *amount ) -- increment value by amount (default=1)
26791 by rhettinger
SF patch #701494: more apply removals
14
bar.label( *newlabel ) -- get or set text label.
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
15
16
More documentation in each function.
17
This module uses DLOG resources 260 and on.
18
Based upon STDWIN dialogs with the same names and functions.
19
"""
20
39021.1.237 by benjamin.peterson
Add warnings to and deprecated all those Mac modules
21
from warnings import warnpy3k
39021.2.472 by benjamin.peterson
fix test_py3kwarns
22
warnpy3k("In 3.x, the EasyDialogs module is removed.", stacklevel=2)
39021.1.237 by benjamin.peterson
Add warnings to and deprecated all those Mac modules
23
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
24
from Carbon.Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText, ModalDialog
25
from Carbon import Qd
26
from Carbon import QuickDraw
27
from Carbon import Dialogs
28
from Carbon import Windows
29
from Carbon import Dlg,Win,Evt,Events # sdm7g
30
from Carbon import Ctl
31
from Carbon import Controls
32
from Carbon import Menu
26457 by jackjansen
Call AEInteractWithUser() before bringing up any of the dialogs (with the
33
from Carbon import AE
25643 by jackjansen
Added methods AskFileForOpen(), AskFileForSave() and AskFolder(). These
34
import Nav
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
35
import MacOS
36
import string
26791 by rhettinger
SF patch #701494: more apply removals
37
from Carbon.ControlAccessor import *    # Also import Controls constants
25643 by jackjansen
Added methods AskFileForOpen(), AskFileForSave() and AskFolder(). These
38
import Carbon.File
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
39
import macresource
25654 by jackjansen
Fixed the first two bugs in the new file dialogs (found by Just):
40
import os
25764 by jackjansen
FSRef and EasyDialogs pathname support was pretty much broken in MacPython-OS9. Fixed.
41
import sys
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
42
25689 by jackjansen
Spell out the arguments to AskFileForOpen and friends, so help() gives useful
43
__all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel',
27726 by jvr
changed 8-space indentation to 4
44
    'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder',
45
    'ProgressBar']
26791 by rhettinger
SF patch #701494: more apply removals
46
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
47
_initialized = 0
48
49
def _initialize():
27726 by jvr
changed 8-space indentation to 4
50
    global _initialized
51
    if _initialized: return
52
    macresource.need("DLOG", 260, "dialogs.rsrc", __name__)
26791 by rhettinger
SF patch #701494: more apply removals
53
26457 by jackjansen
Call AEInteractWithUser() before bringing up any of the dialogs (with the
54
def _interact():
27726 by jvr
changed 8-space indentation to 4
55
    """Make sure the application is in the foreground"""
56
    AE.AEInteractWithUser(50000000)
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
57
58
def cr2lf(text):
27726 by jvr
changed 8-space indentation to 4
59
    if '\r' in text:
60
        text = string.join(string.split(text, '\r'), '\n')
61
    return text
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
62
63
def lf2cr(text):
27726 by jvr
changed 8-space indentation to 4
64
    if '\n' in text:
65
        text = string.join(string.split(text, '\n'), '\r')
66
    if len(text) > 253:
67
        text = text[:253] + '\311'
68
    return text
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
69
70
def Message(msg, id=260, ok=None):
27726 by jvr
changed 8-space indentation to 4
71
    """Display a MESSAGE string.
72
73
    Return when the user clicks the OK button or presses Return.
74
75
    The MESSAGE string can be at most 255 characters long.
76
    """
77
    _initialize()
78
    _interact()
79
    d = GetNewDialog(id, -1)
80
    if not d:
81
        print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
82
        return
83
    h = d.GetDialogItemAsControl(2)
84
    SetDialogItemText(h, lf2cr(msg))
38800 by benjamin.peterson
#2503 make singletons compared with "is" not == or !=
85
    if ok is not None:
27726 by jvr
changed 8-space indentation to 4
86
        h = d.GetDialogItemAsControl(1)
87
        h.SetControlTitle(ok)
88
    d.SetDialogDefaultItem(1)
89
    d.AutoSizeDialog()
90
    d.GetDialogWindow().ShowWindow()
91
    while 1:
92
        n = ModalDialog(None)
93
        if n == 1:
94
            return
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
95
96
97
def AskString(prompt, default = "", id=261, ok=None, cancel=None):
27726 by jvr
changed 8-space indentation to 4
98
    """Display a PROMPT string and a text entry field with a DEFAULT string.
99
100
    Return the contents of the text entry field when the user clicks the
101
    OK button or presses Return.
102
    Return None when the user clicks the Cancel button.
103
104
    If omitted, DEFAULT is empty.
105
106
    The PROMPT and DEFAULT strings, as well as the return value,
107
    can be at most 255 characters long.
108
    """
109
110
    _initialize()
111
    _interact()
112
    d = GetNewDialog(id, -1)
113
    if not d:
114
        print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
115
        return
116
    h = d.GetDialogItemAsControl(3)
117
    SetDialogItemText(h, lf2cr(prompt))
118
    h = d.GetDialogItemAsControl(4)
119
    SetDialogItemText(h, lf2cr(default))
120
    d.SelectDialogItemText(4, 0, 999)
26791 by rhettinger
SF patch #701494: more apply removals
121
#       d.SetDialogItem(4, 0, 255)
38800 by benjamin.peterson
#2503 make singletons compared with "is" not == or !=
122
    if ok is not None:
27726 by jvr
changed 8-space indentation to 4
123
        h = d.GetDialogItemAsControl(1)
124
        h.SetControlTitle(ok)
38800 by benjamin.peterson
#2503 make singletons compared with "is" not == or !=
125
    if cancel is not None:
27726 by jvr
changed 8-space indentation to 4
126
        h = d.GetDialogItemAsControl(2)
127
        h.SetControlTitle(cancel)
128
    d.SetDialogDefaultItem(1)
129
    d.SetDialogCancelItem(2)
130
    d.AutoSizeDialog()
131
    d.GetDialogWindow().ShowWindow()
132
    while 1:
133
        n = ModalDialog(None)
134
        if n == 1:
135
            h = d.GetDialogItemAsControl(4)
136
            return cr2lf(GetDialogItemText(h))
137
        if n == 2: return None
26791 by rhettinger
SF patch #701494: more apply removals
138
139
def AskPassword(prompt,  default='', id=264, ok=None, cancel=None):
27726 by jvr
changed 8-space indentation to 4
140
    """Display a PROMPT string and a text entry field with a DEFAULT string.
141
    The string is displayed as bullets only.
142
143
    Return the contents of the text entry field when the user clicks the
144
    OK button or presses Return.
145
    Return None when the user clicks the Cancel button.
146
147
    If omitted, DEFAULT is empty.
148
149
    The PROMPT and DEFAULT strings, as well as the return value,
150
    can be at most 255 characters long.
151
    """
152
    _initialize()
153
    _interact()
154
    d = GetNewDialog(id, -1)
155
    if not d:
156
        print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
157
        return
158
    h = d.GetDialogItemAsControl(3)
159
    SetDialogItemText(h, lf2cr(prompt))
160
    pwd = d.GetDialogItemAsControl(4)
161
    bullets = '\245'*len(default)
26791 by rhettinger
SF patch #701494: more apply removals
162
##      SetControlData(pwd, kControlEditTextPart, kControlEditTextTextTag, bullets)
27726 by jvr
changed 8-space indentation to 4
163
    SetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag, default)
164
    d.SelectDialogItemText(4, 0, 999)
165
    Ctl.SetKeyboardFocus(d.GetDialogWindow(), pwd, kControlEditTextPart)
38800 by benjamin.peterson
#2503 make singletons compared with "is" not == or !=
166
    if ok is not None:
27726 by jvr
changed 8-space indentation to 4
167
        h = d.GetDialogItemAsControl(1)
168
        h.SetControlTitle(ok)
38800 by benjamin.peterson
#2503 make singletons compared with "is" not == or !=
169
    if cancel is not None:
27726 by jvr
changed 8-space indentation to 4
170
        h = d.GetDialogItemAsControl(2)
171
        h.SetControlTitle(cancel)
172
    d.SetDialogDefaultItem(Dialogs.ok)
173
    d.SetDialogCancelItem(Dialogs.cancel)
174
    d.AutoSizeDialog()
175
    d.GetDialogWindow().ShowWindow()
176
    while 1:
177
        n = ModalDialog(None)
178
        if n == 1:
179
            h = d.GetDialogItemAsControl(4)
180
            return cr2lf(GetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag))
181
        if n == 2: return None
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
182
183
def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=262):
27726 by jvr
changed 8-space indentation to 4
184
    """Display a QUESTION string which can be answered with Yes or No.
185
186
    Return 1 when the user clicks the Yes button.
187
    Return 0 when the user clicks the No button.
188
    Return -1 when the user clicks the Cancel button.
189
190
    When the user presses Return, the DEFAULT value is returned.
191
    If omitted, this is 0 (No).
192
193
    The QUESTION string can be at most 255 characters.
194
    """
195
196
    _initialize()
197
    _interact()
198
    d = GetNewDialog(id, -1)
199
    if not d:
200
        print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
201
        return
202
    # Button assignments:
203
    # 1 = default (invisible)
204
    # 2 = Yes
205
    # 3 = No
206
    # 4 = Cancel
207
    # The question string is item 5
208
    h = d.GetDialogItemAsControl(5)
209
    SetDialogItemText(h, lf2cr(question))
38800 by benjamin.peterson
#2503 make singletons compared with "is" not == or !=
210
    if yes is not None:
27726 by jvr
changed 8-space indentation to 4
211
        if yes == '':
212
            d.HideDialogItem(2)
213
        else:
214
            h = d.GetDialogItemAsControl(2)
215
            h.SetControlTitle(yes)
38800 by benjamin.peterson
#2503 make singletons compared with "is" not == or !=
216
    if no is not None:
27726 by jvr
changed 8-space indentation to 4
217
        if no == '':
218
            d.HideDialogItem(3)
219
        else:
220
            h = d.GetDialogItemAsControl(3)
221
            h.SetControlTitle(no)
38800 by benjamin.peterson
#2503 make singletons compared with "is" not == or !=
222
    if cancel is not None:
27726 by jvr
changed 8-space indentation to 4
223
        if cancel == '':
224
            d.HideDialogItem(4)
225
        else:
226
            h = d.GetDialogItemAsControl(4)
227
            h.SetControlTitle(cancel)
228
    d.SetDialogCancelItem(4)
229
    if default == 1:
230
        d.SetDialogDefaultItem(2)
231
    elif default == 0:
232
        d.SetDialogDefaultItem(3)
233
    elif default == -1:
234
        d.SetDialogDefaultItem(4)
235
    d.AutoSizeDialog()
236
    d.GetDialogWindow().ShowWindow()
237
    while 1:
238
        n = ModalDialog(None)
239
        if n == 1: return default
240
        if n == 2: return 1
241
        if n == 3: return 0
242
        if n == 4: return -1
26791 by rhettinger
SF patch #701494: more apply removals
243
244
245
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
246
247
screenbounds = Qd.GetQDGlobalsScreenBits().bounds
248
screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
27726 by jvr
changed 8-space indentation to 4
249
    screenbounds[2]-4, screenbounds[3]-4
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
250
26791 by rhettinger
SF patch #701494: more apply removals
251
kControlProgressBarIndeterminateTag = 'inde'    # from Controls.py
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
252
253
254
class ProgressBar:
27726 by jvr
changed 8-space indentation to 4
255
    def __init__(self, title="Working...", maxval=0, label="", id=263):
256
        self.w = None
257
        self.d = None
258
        _initialize()
259
        self.d = GetNewDialog(id, -1)
260
        self.w = self.d.GetDialogWindow()
261
        self.label(label)
262
        self.title(title)
263
        self.set(0, maxval)
264
        self.d.AutoSizeDialog()
265
        self.w.ShowWindow()
266
        self.d.DrawDialog()
267
34794 by martin.blais
Normalized a few cases of whitespace in function declarations.
268
    def __del__(self):
27726 by jvr
changed 8-space indentation to 4
269
        if self.w:
270
            self.w.BringToFront()
271
            self.w.HideWindow()
272
        del self.w
273
        del self.d
274
275
    def title(self, newstr=""):
276
        """title(text) - Set title of progress window"""
277
        self.w.BringToFront()
278
        self.w.SetWTitle(newstr)
279
34794 by martin.blais
Normalized a few cases of whitespace in function declarations.
280
    def label(self, *newstr):
27726 by jvr
changed 8-space indentation to 4
281
        """label(text) - Set text in progress box"""
282
        self.w.BringToFront()
283
        if newstr:
284
            self._label = lf2cr(newstr[0])
285
        text_h = self.d.GetDialogItemAsControl(2)
286
        SetDialogItemText(text_h, self._label)
287
288
    def _update(self, value):
289
        maxval = self.maxval
290
        if maxval == 0:     # an indeterminate bar
291
            Ctl.IdleControls(self.w)    # spin the barber pole
292
        else:               # a determinate bar
293
            if maxval > 32767:
294
                value = int(value/(maxval/32767.0))
295
                maxval = 32767
296
            maxval = int(maxval)
297
            value = int(value)
298
            progbar = self.d.GetDialogItemAsControl(3)
299
            progbar.SetControlMaximum(maxval)
300
            progbar.SetControlValue(value)  # set the bar length
301
302
        # Test for cancel button
303
        ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1  )
304
        if ready :
305
            what,msg,when,where,mod = ev
306
            part = Win.FindWindow(where)[0]
307
            if Dlg.IsDialogEvent(ev):
308
                ds = Dlg.DialogSelect(ev)
309
                if ds[0] and ds[1] == self.d and ds[-1] == 1:
310
                    self.w.HideWindow()
311
                    self.w = None
312
                    self.d = None
313
                    raise KeyboardInterrupt, ev
314
            else:
315
                if part == 4:   # inDrag
316
                    self.w.DragWindow(where, screenbounds)
317
                else:
318
                    MacOS.HandleEvent(ev)
319
320
321
    def set(self, value, max=None):
322
        """set(value) - Set progress bar position"""
38800 by benjamin.peterson
#2503 make singletons compared with "is" not == or !=
323
        if max is not None:
27726 by jvr
changed 8-space indentation to 4
324
            self.maxval = max
325
            bar = self.d.GetDialogItemAsControl(3)
326
            if max <= 0:    # indeterminate bar
327
                bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x01')
328
            else:           # determinate bar
329
                bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x00')
330
        if value < 0:
331
            value = 0
332
        elif value > self.maxval:
333
            value = self.maxval
334
        self.curval = value
335
        self._update(value)
336
337
    def inc(self, n=1):
338
        """inc(amt) - Increment progress bar position"""
339
        self.set(self.curval + n)
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
340
341
ARGV_ID=265
342
ARGV_ITEM_OK=1
343
ARGV_ITEM_CANCEL=2
344
ARGV_OPTION_GROUP=3
345
ARGV_OPTION_EXPLAIN=4
346
ARGV_OPTION_VALUE=5
347
ARGV_OPTION_ADD=6
348
ARGV_COMMAND_GROUP=7
349
ARGV_COMMAND_EXPLAIN=8
350
ARGV_COMMAND_ADD=9
351
ARGV_ADD_OLDFILE=10
352
ARGV_ADD_NEWFILE=11
353
ARGV_ADD_FOLDER=12
354
ARGV_CMDLINE_GROUP=13
355
ARGV_CMDLINE_DATA=14
356
357
##def _myModalDialog(d):
26791 by rhettinger
SF patch #701494: more apply removals
358
##      while 1:
27726 by jvr
changed 8-space indentation to 4
359
##          ready, ev = Evt.WaitNextEvent(0xffff, -1)
360
##          print 'DBG: WNE', ready, ev
361
##          if ready :
362
##              what,msg,when,where,mod = ev
363
##              part, window = Win.FindWindow(where)
364
##              if Dlg.IsDialogEvent(ev):
365
##                  didit, dlgdone, itemdone = Dlg.DialogSelect(ev)
366
##                  print 'DBG: DialogSelect', didit, dlgdone, itemdone, d
367
##                  if didit and dlgdone == d:
368
##                      return itemdone
369
##              elif window == d.GetDialogWindow():
370
##                  d.GetDialogWindow().SelectWindow()
371
##                  if part == 4:   # inDrag
372
##                          d.DragWindow(where, screenbounds)
373
##                  else:
374
##                      MacOS.HandleEvent(ev)
375
##              else:
376
##                  MacOS.HandleEvent(ev)
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
377
##
378
def _setmenu(control, items):
30127 by tim_one
Whitespace normalization, via reindent.py.
379
    mhandle = control.GetControlData_Handle(Controls.kControlMenuPart,
380
            Controls.kControlPopupButtonMenuHandleTag)
381
    menu = Menu.as_Menu(mhandle)
382
    for item in items:
383
        if type(item) == type(()):
384
            label = item[0]
385
        else:
386
            label = item
387
        if label[-1] == '=' or label[-1] == ':':
388
            label = label[:-1]
389
        menu.AppendMenu(label)
27726 by jvr
changed 8-space indentation to 4
390
##          mhandle, mid = menu.getpopupinfo()
391
##          control.SetControlData_Handle(Controls.kControlMenuPart,
392
##                  Controls.kControlPopupButtonMenuHandleTag, mhandle)
30127 by tim_one
Whitespace normalization, via reindent.py.
393
    control.SetControlMinimum(1)
394
    control.SetControlMaximum(len(items)+1)
26791 by rhettinger
SF patch #701494: more apply removals
395
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
396
def _selectoption(d, optionlist, idx):
27726 by jvr
changed 8-space indentation to 4
397
    if idx < 0 or idx >= len(optionlist):
398
        MacOS.SysBeep()
399
        return
400
    option = optionlist[idx]
401
    if type(option) == type(()):
402
        if len(option) == 4:
403
            help = option[2]
404
        elif len(option) > 1:
405
            help = option[-1]
406
        else:
407
            help = ''
408
    else:
409
        help = ''
410
    h = d.GetDialogItemAsControl(ARGV_OPTION_EXPLAIN)
411
    if help and len(help) > 250:
412
        help = help[:250] + '...'
413
    Dlg.SetDialogItemText(h, help)
414
    hasvalue = 0
415
    if type(option) == type(()):
416
        label = option[0]
417
    else:
418
        label = option
419
    if label[-1] == '=' or label[-1] == ':':
420
        hasvalue = 1
421
    h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
422
    Dlg.SetDialogItemText(h, '')
423
    if hasvalue:
424
        d.ShowDialogItem(ARGV_OPTION_VALUE)
425
        d.SelectDialogItemText(ARGV_OPTION_VALUE, 0, 0)
426
    else:
427
        d.HideDialogItem(ARGV_OPTION_VALUE)
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
428
429
430
def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID):
27726 by jvr
changed 8-space indentation to 4
431
    _initialize()
432
    _interact()
433
    d = GetNewDialog(id, -1)
434
    if not d:
435
        print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
436
        return
26791 by rhettinger
SF patch #701494: more apply removals
437
#       h = d.GetDialogItemAsControl(3)
438
#       SetDialogItemText(h, lf2cr(prompt))
439
#       h = d.GetDialogItemAsControl(4)
440
#       SetDialogItemText(h, lf2cr(default))
441
#       d.SelectDialogItemText(4, 0, 999)
442
#       d.SetDialogItem(4, 0, 255)
27726 by jvr
changed 8-space indentation to 4
443
    if optionlist:
444
        _setmenu(d.GetDialogItemAsControl(ARGV_OPTION_GROUP), optionlist)
445
        _selectoption(d, optionlist, 0)
446
    else:
447
        d.GetDialogItemAsControl(ARGV_OPTION_GROUP).DeactivateControl()
448
    if commandlist:
449
        _setmenu(d.GetDialogItemAsControl(ARGV_COMMAND_GROUP), commandlist)
450
        if type(commandlist[0]) == type(()) and len(commandlist[0]) > 1:
451
            help = commandlist[0][-1]
452
            h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
453
            Dlg.SetDialogItemText(h, help)
454
    else:
455
        d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).DeactivateControl()
456
    if not addoldfile:
457
        d.GetDialogItemAsControl(ARGV_ADD_OLDFILE).DeactivateControl()
458
    if not addnewfile:
459
        d.GetDialogItemAsControl(ARGV_ADD_NEWFILE).DeactivateControl()
460
    if not addfolder:
461
        d.GetDialogItemAsControl(ARGV_ADD_FOLDER).DeactivateControl()
462
    d.SetDialogDefaultItem(ARGV_ITEM_OK)
463
    d.SetDialogCancelItem(ARGV_ITEM_CANCEL)
464
    d.GetDialogWindow().ShowWindow()
465
    d.DrawDialog()
466
    if hasattr(MacOS, 'SchedParams'):
467
        appsw = MacOS.SchedParams(1, 0)
468
    try:
469
        while 1:
470
            stringstoadd = []
471
            n = ModalDialog(None)
472
            if n == ARGV_ITEM_OK:
473
                break
474
            elif n == ARGV_ITEM_CANCEL:
475
                raise SystemExit
476
            elif n == ARGV_OPTION_GROUP:
477
                idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
478
                _selectoption(d, optionlist, idx)
479
            elif n == ARGV_OPTION_VALUE:
480
                pass
481
            elif n == ARGV_OPTION_ADD:
482
                idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
483
                if 0 <= idx < len(optionlist):
484
                    option = optionlist[idx]
485
                    if type(option) == type(()):
486
                        option = option[0]
487
                    if option[-1] == '=' or option[-1] == ':':
488
                        option = option[:-1]
489
                        h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
490
                        value = Dlg.GetDialogItemText(h)
491
                    else:
492
                        value = ''
493
                    if len(option) == 1:
494
                        stringtoadd = '-' + option
495
                    else:
496
                        stringtoadd = '--' + option
497
                    stringstoadd = [stringtoadd]
498
                    if value:
499
                        stringstoadd.append(value)
500
                else:
501
                    MacOS.SysBeep()
502
            elif n == ARGV_COMMAND_GROUP:
503
                idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
504
                if 0 <= idx < len(commandlist) and type(commandlist[idx]) == type(()) and \
505
                        len(commandlist[idx]) > 1:
506
                    help = commandlist[idx][-1]
507
                    h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
508
                    Dlg.SetDialogItemText(h, help)
509
            elif n == ARGV_COMMAND_ADD:
510
                idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
511
                if 0 <= idx < len(commandlist):
512
                    command = commandlist[idx]
513
                    if type(command) == type(()):
514
                        command = command[0]
515
                    stringstoadd = [command]
516
                else:
517
                    MacOS.SysBeep()
518
            elif n == ARGV_ADD_OLDFILE:
519
                pathname = AskFileForOpen()
520
                if pathname:
521
                    stringstoadd = [pathname]
522
            elif n == ARGV_ADD_NEWFILE:
523
                pathname = AskFileForSave()
524
                if pathname:
525
                    stringstoadd = [pathname]
526
            elif n == ARGV_ADD_FOLDER:
527
                pathname = AskFolder()
528
                if pathname:
529
                    stringstoadd = [pathname]
530
            elif n == ARGV_CMDLINE_DATA:
531
                pass # Nothing to do
532
            else:
533
                raise RuntimeError, "Unknown dialog item %d"%n
26791 by rhettinger
SF patch #701494: more apply removals
534
27726 by jvr
changed 8-space indentation to 4
535
            for stringtoadd in stringstoadd:
536
                if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
29133 by doerwalter
Replace backticks with repr() or "%r"
537
                    stringtoadd = repr(stringtoadd)
26791 by rhettinger
SF patch #701494: more apply removals
538
                h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
539
                oldstr = GetDialogItemText(h)
27726 by jvr
changed 8-space indentation to 4
540
                if oldstr and oldstr[-1] != ' ':
541
                    oldstr = oldstr + ' '
542
                oldstr = oldstr + stringtoadd
543
                if oldstr[-1] != ' ':
544
                    oldstr = oldstr + ' '
545
                SetDialogItemText(h, oldstr)
546
                d.SelectDialogItemText(ARGV_CMDLINE_DATA, 0x7fff, 0x7fff)
547
        h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
548
        oldstr = GetDialogItemText(h)
549
        tmplist = string.split(oldstr)
550
        newlist = []
551
        while tmplist:
552
            item = tmplist[0]
553
            del tmplist[0]
554
            if item[0] == '"':
555
                while item[-1] != '"':
556
                    if not tmplist:
557
                        raise RuntimeError, "Unterminated quoted argument"
558
                    item = item + ' ' + tmplist[0]
559
                    del tmplist[0]
560
                item = item[1:-1]
561
            if item[0] == "'":
562
                while item[-1] != "'":
563
                    if not tmplist:
564
                        raise RuntimeError, "Unterminated quoted argument"
565
                    item = item + ' ' + tmplist[0]
566
                    del tmplist[0]
567
                item = item[1:-1]
568
            newlist.append(item)
569
        return newlist
570
    finally:
571
        if hasattr(MacOS, 'SchedParams'):
572
            MacOS.SchedParams(*appsw)
573
        del d
25643 by jackjansen
Added methods AskFileForOpen(), AskFileForSave() and AskFolder(). These
574
25689 by jackjansen
Spell out the arguments to AskFileForOpen and friends, so help() gives useful
575
def _process_Nav_args(dftflags, **args):
27726 by jvr
changed 8-space indentation to 4
576
    import aepack
577
    import Carbon.AE
578
    import Carbon.File
579
    for k in args.keys():
580
        if args[k] is None:
581
            del args[k]
582
    # Set some defaults, and modify some arguments
583
    if not args.has_key('dialogOptionFlags'):
584
        args['dialogOptionFlags'] = dftflags
585
    if args.has_key('defaultLocation') and \
586
            not isinstance(args['defaultLocation'], Carbon.AE.AEDesc):
587
        defaultLocation = args['defaultLocation']
588
        if isinstance(defaultLocation, (Carbon.File.FSSpec, Carbon.File.FSRef)):
589
            args['defaultLocation'] = aepack.pack(defaultLocation)
590
        else:
591
            defaultLocation = Carbon.File.FSRef(defaultLocation)
592
            args['defaultLocation'] = aepack.pack(defaultLocation)
593
    if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType):
594
        typeList = args['typeList'][:]
595
        # Workaround for OSX typeless files:
596
        if 'TEXT' in typeList and not '\0\0\0\0' in typeList:
597
            typeList = typeList + ('\0\0\0\0',)
598
        data = 'Pyth' + struct.pack("hh", 0, len(typeList))
599
        for type in typeList:
600
            data = data+type
601
        args['typeList'] = Carbon.Res.Handle(data)
602
    tpwanted = str
603
    if args.has_key('wanted'):
604
        tpwanted = args['wanted']
605
        del args['wanted']
606
    return args, tpwanted
26791 by rhettinger
SF patch #701494: more apply removals
607
26097 by jackjansen
Made AskFile* dialogs movable-modal by default, by providing a dummy
608
def _dummy_Nav_eventproc(msg, data):
27726 by jvr
changed 8-space indentation to 4
609
    pass
26791 by rhettinger
SF patch #701494: more apply removals
610
26097 by jackjansen
Made AskFile* dialogs movable-modal by default, by providing a dummy
611
_default_Nav_eventproc = _dummy_Nav_eventproc
612
613
def SetDefaultEventProc(proc):
27726 by jvr
changed 8-space indentation to 4
614
    global _default_Nav_eventproc
615
    rv = _default_Nav_eventproc
616
    if proc is None:
617
        proc = _dummy_Nav_eventproc
618
    _default_Nav_eventproc = proc
619
    return rv
26791 by rhettinger
SF patch #701494: more apply removals
620
25689 by jackjansen
Spell out the arguments to AskFileForOpen and friends, so help() gives useful
621
def AskFileForOpen(
27726 by jvr
changed 8-space indentation to 4
622
        message=None,
623
        typeList=None,
624
        # From here on the order is not documented
625
        version=None,
626
        defaultLocation=None,
627
        dialogOptionFlags=None,
628
        location=None,
629
        clientName=None,
630
        windowTitle=None,
631
        actionButtonLabel=None,
632
        cancelButtonLabel=None,
633
        preferenceKey=None,
634
        popupExtension=None,
635
        eventProc=_dummy_Nav_eventproc,
636
        previewProc=None,
637
        filterProc=None,
638
        wanted=None,
639
        multiple=None):
640
    """Display a dialog asking the user for a file to open.
641
642
    wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
643
    the other arguments can be looked up in Apple's Navigation Services documentation"""
644
645
    default_flags = 0x56 # Or 0xe4?
646
    args, tpwanted = _process_Nav_args(default_flags, version=version,
647
        defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
648
        location=location,clientName=clientName,windowTitle=windowTitle,
649
        actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
650
        message=message,preferenceKey=preferenceKey,
651
        popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc,
652
        filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple)
653
    _interact()
654
    try:
655
        rr = Nav.NavChooseFile(args)
656
        good = 1
657
    except Nav.error, arg:
658
        if arg[0] != -128: # userCancelledErr
659
            raise Nav.error, arg
660
        return None
661
    if not rr.validRecord or not rr.selection:
662
        return None
663
    if issubclass(tpwanted, Carbon.File.FSRef):
664
        return tpwanted(rr.selection_fsr[0])
665
    if issubclass(tpwanted, Carbon.File.FSSpec):
666
        return tpwanted(rr.selection[0])
667
    if issubclass(tpwanted, str):
668
        return tpwanted(rr.selection_fsr[0].as_pathname())
669
    if issubclass(tpwanted, unicode):
670
        return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
671
    raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
25643 by jackjansen
Added methods AskFileForOpen(), AskFileForSave() and AskFolder(). These
672
25689 by jackjansen
Spell out the arguments to AskFileForOpen and friends, so help() gives useful
673
def AskFileForSave(
27726 by jvr
changed 8-space indentation to 4
674
        message=None,
675
        savedFileName=None,
676
        # From here on the order is not documented
677
        version=None,
678
        defaultLocation=None,
679
        dialogOptionFlags=None,
680
        location=None,
681
        clientName=None,
682
        windowTitle=None,
683
        actionButtonLabel=None,
684
        cancelButtonLabel=None,
685
        preferenceKey=None,
686
        popupExtension=None,
687
        eventProc=_dummy_Nav_eventproc,
688
        fileType=None,
689
        fileCreator=None,
690
        wanted=None,
691
        multiple=None):
692
    """Display a dialog asking the user for a filename to save to.
693
694
    wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
695
    the other arguments can be looked up in Apple's Navigation Services documentation"""
696
697
698
    default_flags = 0x07
699
    args, tpwanted = _process_Nav_args(default_flags, version=version,
700
        defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
701
        location=location,clientName=clientName,windowTitle=windowTitle,
702
        actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
703
        savedFileName=savedFileName,message=message,preferenceKey=preferenceKey,
704
        popupExtension=popupExtension,eventProc=eventProc,fileType=fileType,
705
        fileCreator=fileCreator,wanted=wanted,multiple=multiple)
706
    _interact()
707
    try:
708
        rr = Nav.NavPutFile(args)
709
        good = 1
710
    except Nav.error, arg:
711
        if arg[0] != -128: # userCancelledErr
712
            raise Nav.error, arg
713
        return None
714
    if not rr.validRecord or not rr.selection:
715
        return None
716
    if issubclass(tpwanted, Carbon.File.FSRef):
717
        raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave"
718
    if issubclass(tpwanted, Carbon.File.FSSpec):
719
        return tpwanted(rr.selection[0])
720
    if issubclass(tpwanted, (str, unicode)):
721
        if sys.platform == 'mac':
722
            fullpath = rr.selection[0].as_pathname()
723
        else:
724
            # This is gross, and probably incorrect too
725
            vrefnum, dirid, name = rr.selection[0].as_tuple()
726
            pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, ''))
727
            pardir_fsr = Carbon.File.FSRef(pardir_fss)
728
            pardir_path = pardir_fsr.FSRefMakePath()  # This is utf-8
729
            name_utf8 = unicode(name, 'macroman').encode('utf8')
730
            fullpath = os.path.join(pardir_path, name_utf8)
731
        if issubclass(tpwanted, unicode):
732
            return unicode(fullpath, 'utf8')
733
        return tpwanted(fullpath)
734
    raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
26791 by rhettinger
SF patch #701494: more apply removals
735
25689 by jackjansen
Spell out the arguments to AskFileForOpen and friends, so help() gives useful
736
def AskFolder(
27726 by jvr
changed 8-space indentation to 4
737
        message=None,
738
        # From here on the order is not documented
739
        version=None,
740
        defaultLocation=None,
741
        dialogOptionFlags=None,
742
        location=None,
743
        clientName=None,
744
        windowTitle=None,
745
        actionButtonLabel=None,
746
        cancelButtonLabel=None,
747
        preferenceKey=None,
748
        popupExtension=None,
749
        eventProc=_dummy_Nav_eventproc,
750
        filterProc=None,
751
        wanted=None,
752
        multiple=None):
753
    """Display a dialog asking the user for select a folder.
754
755
    wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
756
    the other arguments can be looked up in Apple's Navigation Services documentation"""
757
758
    default_flags = 0x17
759
    args, tpwanted = _process_Nav_args(default_flags, version=version,
760
        defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
761
        location=location,clientName=clientName,windowTitle=windowTitle,
762
        actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
763
        message=message,preferenceKey=preferenceKey,
764
        popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc,
765
        wanted=wanted,multiple=multiple)
766
    _interact()
767
    try:
768
        rr = Nav.NavChooseFolder(args)
769
        good = 1
770
    except Nav.error, arg:
771
        if arg[0] != -128: # userCancelledErr
772
            raise Nav.error, arg
773
        return None
774
    if not rr.validRecord or not rr.selection:
775
        return None
776
    if issubclass(tpwanted, Carbon.File.FSRef):
777
        return tpwanted(rr.selection_fsr[0])
778
    if issubclass(tpwanted, Carbon.File.FSSpec):
779
        return tpwanted(rr.selection[0])
780
    if issubclass(tpwanted, str):
781
        return tpwanted(rr.selection_fsr[0].as_pathname())
782
    if issubclass(tpwanted, unicode):
783
        return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
784
    raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
26791 by rhettinger
SF patch #701494: more apply removals
785
25643 by jackjansen
Added methods AskFileForOpen(), AskFileForSave() and AskFolder(). These
786
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
787
def test():
27726 by jvr
changed 8-space indentation to 4
788
    import time
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
789
27726 by jvr
changed 8-space indentation to 4
790
    Message("Testing EasyDialogs.")
791
    optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
792
                ('flags=', 'Valued option'), ('f:', 'Short valued option'))
793
    commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
794
    argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
795
    Message("Command line: %s"%' '.join(argv))
796
    for i in range(len(argv)):
29133 by doerwalter
Replace backticks with repr() or "%r"
797
        print 'arg[%d] = %r' % (i, argv[i])
27726 by jvr
changed 8-space indentation to 4
798
    ok = AskYesNoCancel("Do you want to proceed?")
799
    ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
800
    if ok > 0:
801
        s = AskString("Enter your first name", "Joe")
802
        s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
803
        if not s2:
804
            Message("%s has no secret nickname"%s)
26791 by rhettinger
SF patch #701494: more apply removals
805
        else:
27726 by jvr
changed 8-space indentation to 4
806
            Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
807
    else:
808
        s = 'Anonymous'
809
    rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=Carbon.File.FSSpec)
810
    Message("rv: %s"%rv)
811
    rv = AskFileForSave(wanted=Carbon.File.FSRef, savedFileName="%s.txt"%s)
812
    Message("rv.as_pathname: %s"%rv.as_pathname())
813
    rv = AskFolder()
814
    Message("Folder name: %s"%rv)
815
    text = ( "Working Hard...", "Hardly Working..." ,
816
            "So far, so good!", "Keep on truckin'" )
817
    bar = ProgressBar("Progress, progress...", 0, label="Ramping up...")
818
    try:
819
        if hasattr(MacOS, 'SchedParams'):
820
            appsw = MacOS.SchedParams(1, 0)
821
        for i in xrange(20):
822
            bar.inc()
823
            time.sleep(0.05)
824
        bar.set(0,100)
825
        for i in xrange(100):
826
            bar.set(i)
827
            time.sleep(0.05)
828
            if i % 10 == 0:
829
                bar.label(text[(i/10) % 4])
830
        bar.label("Done.")
831
        time.sleep(1.0)     # give'em a chance to see "Done."
832
    finally:
833
        del bar
834
        if hasattr(MacOS, 'SchedParams'):
835
            MacOS.SchedParams(*appsw)
25278 by jackjansen
Moved most of Mac/Lib hierarchy to Lib/plat-mac: it can be used both
836
837
if __name__ == '__main__':
27726 by jvr
changed 8-space indentation to 4
838
    try:
839
        test()
840
    except KeyboardInterrupt:
841
        Message("Operation Canceled.")