findertools.py 29.5 KB
Newer Older
1 2
"""Utility routines depending on the finder,
a combination of code by Jack Jansen and erik@letterror.com.
3

4 5 6 7 8 9 10 11 12 13 14 15 16
Most events have been captured from
Lasso Capture AE and than translated to python code.

IMPORTANT
Note that the processes() function returns different values
depending on the OS version it is running on. On MacOS 9
the Finder returns the process *names* which can then be
used to find out more about them. On MacOS 8.6 and earlier
the Finder returns a code which does not seem to work.
So bottom line: the processes() stuff does not work on < MacOS9

Mostly written by erik@letterror.com
"""
17
import Finder
18
from Carbon import AppleEvents
19 20 21
import aetools
import MacOS
import sys
Jack Jansen's avatar
Jack Jansen committed
22 23
import Carbon.File
import Carbon.Folder
24 25 26 27
import aetypes

__version__ = '1.1'
Error = 'findertools.Error'
28 29 30 31

_finder_talker = None

def _getfinder():
Jack Jansen's avatar
Jack Jansen committed
32 33 34 35
    """returns basic (recyclable) Finder AE interface object"""
    global _finder_talker
    if not _finder_talker:
        _finder_talker = Finder.Finder()
36
    _finder_talker.send_flags = ( _finder_talker.send_flags |
Jack Jansen's avatar
Jack Jansen committed
37 38
        AppleEvents.kAECanInteract | AppleEvents.kAECanSwitchLayer)
    return _finder_talker
39

40
def launch(file):
Jack Jansen's avatar
Jack Jansen committed
41 42 43 44
    """Open a file thru the finder. Specify file by name or fsspec"""
    finder = _getfinder()
    fss = Carbon.File.FSSpec(file)
    return finder.open(fss)
45

46
def Print(file):
Jack Jansen's avatar
Jack Jansen committed
47 48 49 50
    """Print a file thru the finder. Specify file by name or fsspec"""
    finder = _getfinder()
    fss = Carbon.File.FSSpec(file)
    return finder._print(fss)
51

52
def copy(src, dstdir):
Jack Jansen's avatar
Jack Jansen committed
53 54 55 56 57 58 59 60 61 62
    """Copy a file to a folder"""
    finder = _getfinder()
    if type(src) == type([]):
        src_fss = []
        for s in src:
            src_fss.append(Carbon.File.FSSpec(s))
    else:
        src_fss = Carbon.File.FSSpec(src)
    dst_fss = Carbon.File.FSSpec(dstdir)
    return finder.duplicate(src_fss, to=dst_fss)
63 64

def move(src, dstdir):
Jack Jansen's avatar
Jack Jansen committed
65 66 67 68 69 70 71 72 73 74
    """Move a file to a folder"""
    finder = _getfinder()
    if type(src) == type([]):
        src_fss = []
        for s in src:
            src_fss.append(Carbon.File.FSSpec(s))
    else:
        src_fss = Carbon.File.FSSpec(src)
    dst_fss = Carbon.File.FSSpec(dstdir)
    return finder.move(src_fss, to=dst_fss)
75

76
def sleep():
Jack Jansen's avatar
Jack Jansen committed
77 78 79
    """Put the mac to sleep"""
    finder = _getfinder()
    finder.sleep()
80

81
def shutdown():
Jack Jansen's avatar
Jack Jansen committed
82 83 84
    """Shut the mac down"""
    finder = _getfinder()
    finder.shut_down()
85

86
def restart():
Jack Jansen's avatar
Jack Jansen committed
87 88 89
    """Restart the mac"""
    finder = _getfinder()
    finder.restart()
90 91 92


#---------------------------------------------------
Jack Jansen's avatar
Jack Jansen committed
93
#   Additional findertools
94 95 96
#

def reveal(file):
Jack Jansen's avatar
Jack Jansen committed
97 98 99 100 101
    """Reveal a file in the finder. Specify file by name, fsref or fsspec."""
    finder = _getfinder()
    fsr = Carbon.File.FSRef(file)
    file_alias = fsr.FSNewAliasMinimal()
    return finder.reveal(file_alias)
102

103
def select(file):
Jack Jansen's avatar
Jack Jansen committed
104 105 106 107 108
    """select a file in the finder. Specify file by name, fsref or fsspec."""
    finder = _getfinder()
    fsr = Carbon.File.FSRef(file)
    file_alias = fsr.FSNewAliasMinimal()
    return finder.select(file_alias)
109

110
def update(file):
111
    """Update the display of the specified object(s) to match
Jack Jansen's avatar
Jack Jansen committed
112 113 114 115 116
    their on-disk representation. Specify file by name, fsref or fsspec."""
    finder = _getfinder()
    fsr = Carbon.File.FSRef(file)
    file_alias = fsr.FSNewAliasMinimal()
    return finder.update(file_alias)
117 118 119


#---------------------------------------------------
Jack Jansen's avatar
Jack Jansen committed
120
#   More findertools
121 122 123
#

def comment(object, comment=None):
Jack Jansen's avatar
Jack Jansen committed
124 125 126
    """comment: get or set the Finder-comment of the item, displayed in the 'Get Info' window."""
    object = Carbon.File.FSRef(object)
    object_alias = object.FSNewAliasMonimal()
127
    if comment is None:
Jack Jansen's avatar
Jack Jansen committed
128 129 130
        return _getcomment(object_alias)
    else:
        return _setcomment(object_alias, comment)
131

132
def _setcomment(object_alias, comment):
Jack Jansen's avatar
Jack Jansen committed
133 134 135 136 137 138 139 140
    finder = _getfinder()
    args = {}
    attrs = {}
    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cobj'), form="alis", seld=object_alias, fr=None)
    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('comt'), fr=aeobj_00)
    args['----'] = aeobj_01
    args["data"] = comment
    _reply, args, attrs = finder.send("core", "setd", args, attrs)
141
    if 'errn' in args:
142
        raise Error(aetools.decodeerror(args))
143
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
144
        return args['----']
145 146

def _getcomment(object_alias):
Jack Jansen's avatar
Jack Jansen committed
147 148 149 150 151 152 153
    finder = _getfinder()
    args = {}
    attrs = {}
    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cobj'), form="alis", seld=object_alias, fr=None)
    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('comt'), fr=aeobj_00)
    args['----'] = aeobj_01
    _reply, args, attrs = finder.send("core", "getd", args, attrs)
154
    if 'errn' in args:
155
        raise Error(aetools.decodeerror(args))
156
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
157
        return args['----']
158 159 160


#---------------------------------------------------
Jack Jansen's avatar
Jack Jansen committed
161
#   Get information about current processes in the Finder.
162 163

def processes():
Jack Jansen's avatar
Jack Jansen committed
164 165 166 167 168 169 170 171 172 173 174 175
    """processes returns a list of all active processes running on this computer and their creators."""
    finder = _getfinder()
    args = {}
    attrs = {}
    processnames = []
    processnumbers = []
    creators = []
    partitions = []
    used = []
    ## get the processnames or else the processnumbers
    args['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('prcs'), form="indx", seld=aetypes.Unknown('abso', "all "), fr=None)
    _reply, args, attrs = finder.send('core', 'getd', args, attrs)
176
    if 'errn' in args:
177
        raise Error(aetools.decodeerror(args))
Jack Jansen's avatar
Jack Jansen committed
178
    p = []
179
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
        p =  args['----']
        for proc in p:
            if hasattr(proc, 'seld'):
                # it has a real name
                processnames.append(proc.seld)
            elif hasattr(proc, 'type'):
                if proc.type == "psn ":
                    # it has a process number
                    processnumbers.append(proc.data)
    ## get the creators
    args = {}
    attrs = {}
    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('prcs'), form="indx", seld=aetypes.Unknown('abso', "all "), fr=None)
    args['----'] =  aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('fcrt'), fr=aeobj_0)
    _reply, args, attrs = finder.send('core', 'getd', args, attrs)
195
    if 'errn' in args:
196
        raise Error(aetools.decodeerror(_arg))
197
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
198 199 200 201 202 203 204 205 206 207 208
        p =  args['----']
        creators = p[:]
    ## concatenate in one dict
    result = []
    if len(processnames) > len(processnumbers):
        data = processnames
    else:
        data = processnumbers
    for i in range(len(creators)):
        result.append((data[i], creators[i]))
    return result
209 210

class _process:
Jack Jansen's avatar
Jack Jansen committed
211
    pass
212 213

def isactiveprocess(processname):
Jack Jansen's avatar
Jack Jansen committed
214 215 216 217 218 219 220
    """Check of processname is active. MacOS9"""
    all = processes()
    ok = 0
    for n, c in all:
        if n == processname:
            return 1
    return 0
221

222
def processinfo(processname):
Jack Jansen's avatar
Jack Jansen committed
223 224
    """Return an object with all process properties as attributes for processname. MacOS9"""
    p = _process()
225

Jack Jansen's avatar
Jack Jansen committed
226 227 228 229 230 231 232 233 234 235 236 237 238 239
    if processname == "Finder":
        p.partition = None
        p.used = None
    else:
        p.partition = _processproperty(processname, 'appt')
        p.used = _processproperty(processname, 'pusd')
    p.visible = _processproperty(processname, 'pvis')       #Is the process' layer visible?
    p.frontmost = _processproperty(processname, 'pisf') #Is the process the frontmost process?
    p.file = _processproperty(processname, 'file')          #the file from which the process was launched
    p.filetype  = _processproperty(processname, 'asty')     #the OSType of the file type of the process
    p.creatortype = _processproperty(processname, 'fcrt')   #the OSType of the creator of the process (the signature)
    p.accepthighlevel = _processproperty(processname, 'revt')   #Is the process high-level event aware (accepts open application, open document, print document, and quit)?
    p.hasscripting = _processproperty(processname, 'hscr')      #Does the process have a scripting terminology, i.e., can it be scripted?
    return p
240

241
def _processproperty(processname, property):
Jack Jansen's avatar
Jack Jansen committed
242 243 244 245 246 247 248 249
    """return the partition size and memory used for processname"""
    finder = _getfinder()
    args = {}
    attrs = {}
    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('prcs'), form="name", seld=processname, fr=None)
    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type(property), fr=aeobj_00)
    args['----'] = aeobj_01
    _reply, args, attrs = finder.send("core", "getd", args, attrs)
250
    if 'errn' in args:
251
        raise Error(aetools.decodeerror(args))
252
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
253
        return args['----']
254 255 256


#---------------------------------------------------
Jack Jansen's avatar
Jack Jansen committed
257
#   Mess around with Finder windows.
258

259
def openwindow(object):
Jack Jansen's avatar
Jack Jansen committed
260 261 262 263 264 265 266 267 268 269 270
    """Open a Finder window for object, Specify object by name or fsspec."""
    finder = _getfinder()
    object = Carbon.File.FSRef(object)
    object_alias = object.FSNewAliasMinimal()
    args = {}
    attrs = {}
    _code = 'aevt'
    _subcode = 'odoc'
    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'), form="alis", seld=object_alias, fr=None)
    args['----'] = aeobj_0
    _reply, args, attrs = finder.send(_code, _subcode, args, attrs)
271
    if 'errn' in args:
272
        raise Error(aetools.decodeerror(args))
273

274
def closewindow(object):
Jack Jansen's avatar
Jack Jansen committed
275 276 277 278 279 280 281 282 283 284 285
    """Close a Finder window for folder, Specify by path."""
    finder = _getfinder()
    object = Carbon.File.FSRef(object)
    object_alias = object.FSNewAliasMinimal()
    args = {}
    attrs = {}
    _code = 'core'
    _subcode = 'clos'
    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'), form="alis", seld=object_alias, fr=None)
    args['----'] = aeobj_0
    _reply, args, attrs = finder.send(_code, _subcode, args, attrs)
286
    if 'errn' in args:
287
        raise Error(aetools.decodeerror(args))
288 289

def location(object, pos=None):
Jack Jansen's avatar
Jack Jansen committed
290 291 292 293 294 295 296
    """Set the position of a Finder window for folder to pos=(w, h). Specify file by name or fsspec.
    If pos=None, location will return the current position of the object."""
    object = Carbon.File.FSRef(object)
    object_alias = object.FSNewAliasMinimal()
    if not pos:
        return _getlocation(object_alias)
    return _setlocation(object_alias, pos)
297

298
def _setlocation(object_alias, location):
Jack Jansen's avatar
Jack Jansen committed
299
    """_setlocation: Set the location of the icon for the object."""
300
    x, y = location
Jack Jansen's avatar
Jack Jansen committed
301 302 303 304 305 306 307 308
    finder = _getfinder()
    args = {}
    attrs = {}
    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'), form="alis", seld=object_alias, fr=None)
    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('posn'), fr=aeobj_00)
    args['----'] = aeobj_01
    args["data"] = [x, y]
    _reply, args, attrs = finder.send("core", "setd", args, attrs)
309
    if 'errn' in args:
310
        raise Error(aetools.decodeerror(args))
Jack Jansen's avatar
Jack Jansen committed
311
    return (x,y)
312

313
def _getlocation(object_alias):
Jack Jansen's avatar
Jack Jansen committed
314 315 316 317 318 319 320 321
    """_getlocation: get the location of the icon for the object."""
    finder = _getfinder()
    args = {}
    attrs = {}
    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'), form="alis", seld=object_alias, fr=None)
    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('posn'), fr=aeobj_00)
    args['----'] = aeobj_01
    _reply, args, attrs = finder.send("core", "getd", args, attrs)
322
    if 'errn' in args:
323
        raise Error(aetools.decodeerror(args))
324
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
325 326
        pos = args['----']
        return pos.h, pos.v
327 328

def label(object, index=None):
Jack Jansen's avatar
Jack Jansen committed
329 330 331
    """label: set or get the label of the item. Specify file by name or fsspec."""
    object = Carbon.File.FSRef(object)
    object_alias = object.FSNewAliasMinimal()
332
    if index is None:
Jack Jansen's avatar
Jack Jansen committed
333 334 335 336
        return _getlabel(object_alias)
    if index < 0 or index > 7:
        index = 0
    return _setlabel(object_alias, index)
337

338
def _getlabel(object_alias):
Jack Jansen's avatar
Jack Jansen committed
339 340 341 342 343 344 345 346
    """label: Get the label for the object."""
    finder = _getfinder()
    args = {}
    attrs = {}
    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cobj'), form="alis", seld=object_alias, fr=None)
    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('labi'), fr=aeobj_00)
    args['----'] = aeobj_01
    _reply, args, attrs = finder.send("core", "getd", args, attrs)
347
    if 'errn' in args:
348
        raise Error(aetools.decodeerror(args))
349
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
350
        return args['----']
351 352

def _setlabel(object_alias, index):
Jack Jansen's avatar
Jack Jansen committed
353 354 355 356 357 358 359 360 361 362 363 364 365
    """label: Set the label for the object."""
    finder = _getfinder()
    args = {}
    attrs = {}
    _code = 'core'
    _subcode = 'setd'
    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
            form="alis", seld=object_alias, fr=None)
    aeobj_1 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
            form="prop", seld=aetypes.Type('labi'), fr=aeobj_0)
    args['----'] = aeobj_1
    args["data"] = index
    _reply, args, attrs = finder.send(_code, _subcode, args, attrs)
366
    if 'errn' in args:
367
        raise Error(aetools.decodeerror(args))
Jack Jansen's avatar
Jack Jansen committed
368
    return index
369 370

def windowview(folder, view=None):
Jack Jansen's avatar
Jack Jansen committed
371 372 373 374 375 376 377
    """windowview: Set the view of the window for the folder. Specify file by name or fsspec.
    0 = by icon (default)
    1 = by name
    2 = by button
    """
    fsr = Carbon.File.FSRef(folder)
    folder_alias = fsr.FSNewAliasMinimal()
378
    if view is None:
Jack Jansen's avatar
Jack Jansen committed
379 380
        return _getwindowview(folder_alias)
    return _setwindowview(folder_alias, view)
381

382
def _setwindowview(folder_alias, view=0):
Jack Jansen's avatar
Jack Jansen committed
383 384 385 386 387 388 389 390 391 392
    """set the windowview"""
    attrs = {}
    args = {}
    if view == 1:
        _v = aetypes.Type('pnam')
    elif view == 2:
        _v = aetypes.Type('lgbu')
    else:
        _v = aetypes.Type('iimg')
    finder = _getfinder()
393
    aeobj_0 = aetypes.ObjectSpecifier(want = aetypes.Type('cfol'),
Jack Jansen's avatar
Jack Jansen committed
394
            form = 'alis', seld = folder_alias, fr=None)
395
    aeobj_1 = aetypes.ObjectSpecifier(want = aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
396
            form = 'prop', seld = aetypes.Type('cwnd'), fr=aeobj_0)
397
    aeobj_2 = aetypes.ObjectSpecifier(want = aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
398
            form = 'prop', seld = aetypes.Type('pvew'), fr=aeobj_1)
399
    aeobj_3 = aetypes.ObjectSpecifier(want = aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
400 401 402 403 404 405
            form = 'prop', seld = _v, fr=None)
    _code = 'core'
    _subcode = 'setd'
    args['----'] = aeobj_2
    args['data'] = aeobj_3
    _reply, args, attrs = finder.send(_code, _subcode, args, attrs)
406
    if 'errn' in args:
407
        raise Error(aetools.decodeerror(args))
408
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
409
        return args['----']
410 411

def _getwindowview(folder_alias):
Jack Jansen's avatar
Jack Jansen committed
412 413 414 415 416 417 418 419 420 421 422
    """get the windowview"""
    attrs = {}
    args = {}
    finder = _getfinder()
    args = {}
    attrs = {}
    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'), form="alis", seld=folder_alias, fr=None)
    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('cwnd'), fr=aeobj_00)
    aeobj_02 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('pvew'), fr=aeobj_01)
    args['----'] = aeobj_02
    _reply, args, attrs = finder.send("core", "getd", args, attrs)
423
    if 'errn' in args:
424
        raise Error(aetools.decodeerror(args))
Jack Jansen's avatar
Jack Jansen committed
425
    views = {'iimg':0, 'pnam':1, 'lgbu':2}
426
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
427
        return views[args['----'].enum]
428 429

def windowsize(folder, size=None):
Jack Jansen's avatar
Jack Jansen committed
430 431 432 433 434 435 436 437 438 439
    """Set the size of a Finder window for folder to size=(w, h), Specify by path.
    If size=None, windowsize will return the current size of the window.
    Specify file by name or fsspec.
    """
    fsr = Carbon.File.FSRef(folder)
    folder_alias = fsr.FSNewAliasMinimal()
    openwindow(fsr)
    if not size:
        return _getwindowsize(folder_alias)
    return _setwindowsize(folder_alias, size)
440

441
def _setwindowsize(folder_alias, size):
Jack Jansen's avatar
Jack Jansen committed
442
    """Set the size of a Finder window for folder to (w, h)"""
443
    w, h = size
Jack Jansen's avatar
Jack Jansen committed
444 445 446 447 448 449 450 451
    finder = _getfinder()
    args = {}
    attrs = {}
    _code = 'core'
    _subcode = 'setd'
    aevar00 = [w, h]
    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'),
            form="alis", seld=folder_alias, fr=None)
452
    aeobj_1 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
453
            form="prop", seld=aetypes.Type('cwnd'), fr=aeobj_0)
454
    aeobj_2 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
455 456 457 458
            form="prop", seld=aetypes.Type('ptsz'), fr=aeobj_1)
    args['----'] = aeobj_2
    args["data"] = aevar00
    _reply, args, attrs = finder.send(_code, _subcode, args, attrs)
459
    if 'errn' in args:
460
        raise Error(aetools.decodeerror(args))
Jack Jansen's avatar
Jack Jansen committed
461
    return (w, h)
462

463
def _getwindowsize(folder_alias):
Jack Jansen's avatar
Jack Jansen committed
464 465 466 467
    """Set the size of a Finder window for folder to (w, h)"""
    finder = _getfinder()
    args = {}
    attrs = {}
468
    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'),
Jack Jansen's avatar
Jack Jansen committed
469
            form="alis", seld=folder_alias, fr=None)
470
    aeobj_1 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
471
            form="prop", seld=aetypes.Type('cwnd'), fr=aeobj_0)
472
    aeobj_2 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
473 474 475
            form="prop", seld=aetypes.Type('posn'), fr=aeobj_1)
    args['----'] = aeobj_2
    _reply, args, attrs = finder.send('core', 'getd', args, attrs)
476
    if 'errn' in args:
477
        raise Error(aetools.decodeerror(args))
478
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
479
        return args['----']
480 481

def windowposition(folder, pos=None):
Jack Jansen's avatar
Jack Jansen committed
482 483 484 485 486 487
    """Set the position of a Finder window for folder to pos=(w, h)."""
    fsr = Carbon.File.FSRef(folder)
    folder_alias = fsr.FSNewAliasMinimal()
    openwindow(fsr)
    if not pos:
        return _getwindowposition(folder_alias)
488 489
    if aetypes.IsQDPoint(pos):
        # QDPoint object as returned by _getwindowposition
Jack Jansen's avatar
Jack Jansen committed
490 491
        pos = (pos.h, pos.v)
    return _setwindowposition(folder_alias, pos)
492

493
def _setwindowposition(folder_alias, position):
Jack Jansen's avatar
Jack Jansen committed
494
    """Set the size of a Finder window for folder to (w, h)."""
495
    x, y = position
Jack Jansen's avatar
Jack Jansen committed
496 497 498
    finder = _getfinder()
    args = {}
    attrs = {}
499
    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'),
Jack Jansen's avatar
Jack Jansen committed
500
            form="alis", seld=folder_alias, fr=None)
501
    aeobj_1 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
502
            form="prop", seld=aetypes.Type('cwnd'), fr=aeobj_0)
503
    aeobj_2 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
504 505 506 507
            form="prop", seld=aetypes.Type('posn'), fr=aeobj_1)
    args['----'] = aeobj_2
    args["data"] = [x, y]
    _reply, args, attrs = finder.send('core', 'setd', args, attrs)
508
    if 'errn' in args:
509
        raise Error(aetools.decodeerror(args))
510
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
511
        return args['----']
512 513

def _getwindowposition(folder_alias):
Jack Jansen's avatar
Jack Jansen committed
514 515 516 517
    """Get the size of a Finder window for folder, Specify by path."""
    finder = _getfinder()
    args = {}
    attrs = {}
518
    aeobj_0 = aetypes.ObjectSpecifier(want=aetypes.Type('cfol'),
Jack Jansen's avatar
Jack Jansen committed
519
            form="alis", seld=folder_alias, fr=None)
520
    aeobj_1 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
521
            form="prop", seld=aetypes.Type('cwnd'), fr=aeobj_0)
522
    aeobj_2 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
523 524 525
            form="prop", seld=aetypes.Type('ptsz'), fr=aeobj_1)
    args['----'] = aeobj_2
    _reply, args, attrs = finder.send('core', 'getd', args, attrs)
526
    if 'errn' in args:
527
        raise Error(aetools.decodeerror(args))
528
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
529
        return args['----']
530 531

def icon(object, icondata=None):
Jack Jansen's avatar
Jack Jansen committed
532 533 534 535 536 537
    """icon sets the icon of object, if no icondata is given,
    icon will return an AE object with binary data for the current icon.
    If left untouched, this data can be used to paste the icon on another file.
    Development opportunity: get and set the data as PICT."""
    fsr = Carbon.File.FSRef(object)
    object_alias = fsr.FSNewAliasMinimal()
538
    if icondata is None:
Jack Jansen's avatar
Jack Jansen committed
539 540
        return _geticon(object_alias)
    return _seticon(object_alias, icondata)
541

542
def _geticon(object_alias):
Jack Jansen's avatar
Jack Jansen committed
543 544 545 546
    """get the icondata for object. Binary data of some sort."""
    finder = _getfinder()
    args = {}
    attrs = {}
547
    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cobj'),
Jack Jansen's avatar
Jack Jansen committed
548
            form="alis", seld=object_alias, fr=None)
549
    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
550 551 552
            form="prop", seld=aetypes.Type('iimg'), fr=aeobj_00)
    args['----'] = aeobj_01
    _reply, args, attrs = finder.send("core", "getd", args, attrs)
553
    if 'errn' in args:
554
        raise Error(aetools.decodeerror(args))
555
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
556
        return args['----']
557 558

def _seticon(object_alias, icondata):
Jack Jansen's avatar
Jack Jansen committed
559 560 561 562
    """set the icondata for object, formatted as produced by _geticon()"""
    finder = _getfinder()
    args = {}
    attrs = {}
563
    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('cobj'),
Jack Jansen's avatar
Jack Jansen committed
564
            form="alis", seld=object_alias, fr=None)
565
    aeobj_01 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'),
Jack Jansen's avatar
Jack Jansen committed
566 567 568 569
            form="prop", seld=aetypes.Type('iimg'), fr=aeobj_00)
    args['----'] = aeobj_01
    args["data"] = icondata
    _reply, args, attrs = finder.send("core", "setd", args, attrs)
570
    if 'errn' in args:
571
        raise Error(aetools.decodeerror(args))
572
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
573
        return args['----'].data
574 575 576


#---------------------------------------------------
Jack Jansen's avatar
Jack Jansen committed
577
#   Volumes and servers.
578

579
def mountvolume(volume, server=None, username=None, password=None):
Jack Jansen's avatar
Jack Jansen committed
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
    """mount a volume, local or on a server on AppleTalk.
    Note: mounting a ASIP server requires a different operation.
    server is the name of the server where the volume belongs
    username, password belong to a registered user of the volume."""
    finder = _getfinder()
    args = {}
    attrs = {}
    if password:
        args["PASS"] = password
    if username:
        args["USER"] = username
    if server:
        args["SRVR"] = server
    args['----'] = volume
    _reply, args, attrs = finder.send("aevt", "mvol", args, attrs)
595
    if 'errn' in args:
596
        raise Error(aetools.decodeerror(args))
597
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
598
        return args['----']
599 600

def unmountvolume(volume):
Jack Jansen's avatar
Jack Jansen committed
601 602
    """unmount a volume that's on the desktop"""
    putaway(volume)
603

604
def putaway(object):
Jack Jansen's avatar
Jack Jansen committed
605 606 607 608 609 610
    """puth the object away, whereever it came from."""
    finder = _getfinder()
    args = {}
    attrs = {}
    args['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('cdis'), form="name", seld=object, fr=None)
    _reply, args, attrs = talker.send("fndr", "ptwy", args, attrs)
611
    if 'errn' in args:
612
        raise Error(aetools.decodeerror(args))
613
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
614
        return args['----']
615

616

617
#---------------------------------------------------
Jack Jansen's avatar
Jack Jansen committed
618
#   Miscellaneous functions
619 620 621
#

def volumelevel(level):
Jack Jansen's avatar
Jack Jansen committed
622 623 624 625 626 627 628 629 630 631
    """set the audio output level, parameter between 0 (silent) and 7 (full blast)"""
    finder = _getfinder()
    args = {}
    attrs = {}
    if level < 0:
        level = 0
    elif level > 7:
        level = 7
    args['----'] = level
    _reply, args, attrs = finder.send("aevt", "stvl", args, attrs)
632
    if 'errn' in args:
633
        raise Error(aetools.decodeerror(args))
634
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
635
        return args['----']
636 637

def OSversion():
Jack Jansen's avatar
Jack Jansen committed
638 639 640 641 642 643 644
    """return the version of the system software"""
    finder = _getfinder()
    args = {}
    attrs = {}
    aeobj_00 = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('ver2'), fr=None)
    args['----'] = aeobj_00
    _reply, args, attrs = finder.send("core", "getd", args, attrs)
645
    if 'errn' in args:
646
        raise Error(aetools.decodeerror(args))
647
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
648
        return args['----']
649 650

def filesharing():
Jack Jansen's avatar
Jack Jansen committed
651 652 653 654 655 656 657 658 659 660 661
    """return the current status of filesharing and whether it is starting up or not:
        -1  file sharing is off and not starting up
        0   file sharing is off and starting up
        1   file sharing is on"""
    status = -1
    finder = _getfinder()
    # see if it is on
    args = {}
    attrs = {}
    args['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('fshr'), fr=None)
    _reply, args, attrs = finder.send("core", "getd", args, attrs)
662
    if 'errn' in args:
663
        raise Error(aetools.decodeerror(args))
664
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
665 666 667 668 669 670 671 672 673
        if args['----'] == 0:
            status = -1
        else:
            status = 1
    # is it starting up perchance?
    args = {}
    attrs = {}
    args['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('fsup'), fr=None)
    _reply, args, attrs = finder.send("core", "getd", args, attrs)
674
    if 'errn' in args:
675
        raise Error(aetools.decodeerror(args))
676
    if '----' in args:
Jack Jansen's avatar
Jack Jansen committed
677 678 679
        if args['----'] == 1:
            status = 0
    return status
680

681
def movetotrash(path):
Jack Jansen's avatar
Jack Jansen committed
682 683 684 685
    """move the object to the trash"""
    fss = Carbon.File.FSSpec(path)
    trashfolder = Carbon.Folder.FSFindFolder(fss.as_tuple()[0], 'trsh', 0)
    move(path, trashfolder)
686 687

def emptytrash():
Jack Jansen's avatar
Jack Jansen committed
688 689 690 691 692 693
    """empty the trash"""
    finder = _getfinder()
    args = {}
    attrs = {}
    args['----'] = aetypes.ObjectSpecifier(want=aetypes.Type('prop'), form="prop", seld=aetypes.Type('trsh'), fr=None)
    _reply, args, attrs = finder.send("fndr", "empt", args, attrs)
694
    if 'errn' in args:
695
        raise aetools.Error(aetools.decodeerror(args))
696 697 698


def _test():
Jack Jansen's avatar
Jack Jansen committed
699
    import EasyDialogs
700 701
    print('Original findertools functionality test...')
    print('Testing launch...')
Jack Jansen's avatar
Jack Jansen committed
702 703 704 705
    pathname = EasyDialogs.AskFileForOpen('File to launch:')
    if pathname:
        result = launch(pathname)
        if result:
706 707
            print('Result: ', result)
        print('Press return-', end=' ')
Jack Jansen's avatar
Jack Jansen committed
708
        sys.stdin.readline()
709
    print('Testing print...')
Jack Jansen's avatar
Jack Jansen committed
710 711 712 713
    pathname = EasyDialogs.AskFileForOpen('File to print:')
    if pathname:
        result = Print(pathname)
        if result:
714 715
            print('Result: ', result)
        print('Press return-', end=' ')
Jack Jansen's avatar
Jack Jansen committed
716
        sys.stdin.readline()
717
    print('Testing copy...')
Jack Jansen's avatar
Jack Jansen committed
718 719 720 721 722 723
    pathname = EasyDialogs.AskFileForOpen('File to copy:')
    if pathname:
        destdir = EasyDialogs.AskFolder('Destination:')
        if destdir:
            result = copy(pathname, destdir)
            if result:
724 725
                print('Result:', result)
            print('Press return-', end=' ')
Jack Jansen's avatar
Jack Jansen committed
726
            sys.stdin.readline()
727
    print('Testing move...')
Jack Jansen's avatar
Jack Jansen committed
728 729 730 731 732 733
    pathname = EasyDialogs.AskFileForOpen('File to move:')
    if pathname:
        destdir = EasyDialogs.AskFolder('Destination:')
        if destdir:
            result = move(pathname, destdir)
            if result:
734 735
                print('Result:', result)
            print('Press return-', end=' ')
Jack Jansen's avatar
Jack Jansen committed
736
            sys.stdin.readline()
737
    print('Testing sleep...')
Jack Jansen's avatar
Jack Jansen committed
738 739 740
    if EasyDialogs.AskYesNoCancel('Sleep?') > 0:
        result = sleep()
        if result:
741 742
            print('Result:', result)
        print('Press return-', end=' ')
Jack Jansen's avatar
Jack Jansen committed
743
        sys.stdin.readline()
744
    print('Testing shutdown...')
Jack Jansen's avatar
Jack Jansen committed
745 746 747
    if EasyDialogs.AskYesNoCancel('Shut down?') > 0:
        result = shutdown()
        if result:
748 749
            print('Result:', result)
        print('Press return-', end=' ')
Jack Jansen's avatar
Jack Jansen committed
750
        sys.stdin.readline()
751
    print('Testing restart...')
Jack Jansen's avatar
Jack Jansen committed
752 753 754
    if EasyDialogs.AskYesNoCancel('Restart?') > 0:
        result = restart()
        if result:
755 756
            print('Result:', result)
        print('Press return-', end=' ')
Jack Jansen's avatar
Jack Jansen committed
757
        sys.stdin.readline()
758 759

def _test2():
760
    print('\nmorefindertools version %s\nTests coming up...' %__version__)
Jack Jansen's avatar
Jack Jansen committed
761 762 763 764
    import os
    import random

    # miscellaneous
765 766
    print('\tfilesharing on?',  filesharing())       # is file sharing on, off, starting up?
    print('\tOS version',       OSversion())     # the version of the system software
Jack Jansen's avatar
Jack Jansen committed
767 768

    # set the soundvolume in a simple way
769
    print('\tSystem beep volume')
Jack Jansen's avatar
Jack Jansen committed
770
    for i in range(0, 7):
771
        volumelevel(i)
Jack Jansen's avatar
Jack Jansen committed
772 773 774 775 776 777 778 779 780 781 782 783 784 785
        MacOS.SysBeep()

    # Finder's windows, file location, file attributes
    open("@findertoolstest", "w")
    f = "@findertoolstest"
    reveal(f)               # reveal this file in a Finder window
    select(f)               # select this file

    base, file = os.path.split(f)
    closewindow(base)   # close the window this file is in  (opened by reveal)
    openwindow(base)        # open it again
    windowview(base, 1) # set the view by list

    label(f, 2)             # set the label of this file to something orange
786
    print('\tlabel', label(f))   # get the label of this file
Jack Jansen's avatar
Jack Jansen committed
787 788

    # the file location only works in a window with icon view!
789
    print('Random locations for an icon')
Jack Jansen's avatar
Jack Jansen committed
790 791 792 793 794 795 796 797 798
    windowview(base, 0)     # set the view by icon
    windowsize(base, (600, 600))
    for i in range(50):
        location(f, (random.randint(10, 590), random.randint(10, 590)))

    windowsize(base, (200, 400))
    windowview(base, 1)     # set the view by icon

    orgpos = windowposition(base)
799
    print('Animated window location')
Jack Jansen's avatar
Jack Jansen committed
800 801 802
    for i in range(10):
        pos = (100+i*10, 100+i*10)
        windowposition(base, pos)
803
        print('\twindow position', pos)
Jack Jansen's avatar
Jack Jansen committed
804 805
    windowposition(base, orgpos)    # park it where it was before

806 807
    print('Put a comment in file', f, ':')
    print('\t', comment(f))      # print the Finder comment this file has
Jack Jansen's avatar
Jack Jansen committed
808 809
    s = 'This is a comment no one reads!'
    comment(f, s)           # set the Finder comment
810

811
def _test3():
812
    print('MacOS9 or better specific functions')
Jack Jansen's avatar
Jack Jansen committed
813 814
    # processes
    pr = processes()        # return a list of tuples with (active_processname, creatorcode)
815
    print('Return a list of current active processes:')
Jack Jansen's avatar
Jack Jansen committed
816
    for p in pr:
817
        print('\t', p)
818

Jack Jansen's avatar
Jack Jansen committed
819
    # get attributes of the first process in the list
820
    print('Attributes of the first process in the list:')
Jack Jansen's avatar
Jack Jansen committed
821
    pinfo = processinfo(pr[0][0])
822 823 824 825 826 827 828
    print('\t', pr[0][0])
    print('\t\tmemory partition', pinfo.partition)       # the memory allocated to this process
    print('\t\tmemory used', pinfo.used)         # the memory actuall used by this process
    print('\t\tis visible', pinfo.visible)           # is the process visible to the user
    print('\t\tis frontmost', pinfo.frontmost)       # is the process the front most one?
    print('\t\thas scripting', pinfo.hasscripting)       # is the process scriptable?
    print('\t\taccepts high level events',  pinfo.accepthighlevel)   # does the process accept high level appleevents?
829

830
if __name__ == '__main__':
Jack Jansen's avatar
Jack Jansen committed
831 832 833
    _test()
    _test2()
    _test3()