Home | History | Annotate | Download | only in Modules
      1 /***********************************************************
      2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
      3 The Netherlands.
      4 
      5                         All Rights Reserved
      6 
      7 Permission to use, copy, modify, and distribute this software and its
      8 documentation for any purpose and without fee is hereby granted,
      9 provided that the above copyright notice appear in all copies and that
     10 both that copyright notice and this permission notice appear in
     11 supporting documentation, and that the names of Stichting Mathematisch
     12 Centrum or CWI or Corporation for National Research Initiatives or
     13 CNRI not be used in advertising or publicity pertaining to
     14 distribution of the software without specific, written prior
     15 permission.
     16 
     17 While CWI is the initial source for this software, a modified version
     18 is made available by the Corporation for National Research Initiatives
     19 (CNRI) at the Internet address ftp://ftp.python.org.
     20 
     21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
     22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
     23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
     24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
     25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
     26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     28 PERFORMANCE OF THIS SOFTWARE.
     29 
     30 ******************************************************************/
     31 
     32 #include "Python.h"
     33 #include "pymactoolbox.h"
     34 #include <Carbon/Carbon.h>
     35 
     36 #ifndef __LP64__
     37 
     38 static PyObject *ErrorObject;
     39 
     40 static NavEventUPP my_eventProcUPP;
     41 static NavPreviewUPP my_previewProcUPP;
     42 static NavObjectFilterUPP my_filterProcUPP;
     43 
     44 /* Callback functions */
     45 static pascal void
     46 my_eventProc(NavEventCallbackMessage callBackSelector,
     47                          NavCBRecPtr callBackParms,
     48                          NavCallBackUserData callbackUD)
     49 {
     50     PyObject *dict = (PyObject *)callbackUD;
     51     PyObject *pyfunc;
     52     PyObject *rv;
     53 
     54     if (!dict) return;
     55     if ( (pyfunc = PyDict_GetItemString(dict, "eventProc")) == NULL ) {
     56         PyErr_Print();
     57         return;
     58     }
     59     if ( pyfunc == Py_None ) {
     60         return;
     61     }
     62     rv = PyObject_CallFunction(pyfunc, "ls#", (long)callBackSelector,
     63                     (void *)callBackParms, sizeof(NavCBRec));
     64     if ( rv )
     65         Py_DECREF(rv);
     66     else {
     67         PySys_WriteStderr("Nav: exception in eventProc callback\n");
     68         PyErr_Print();
     69     }
     70 }
     71 
     72 static pascal Boolean
     73 my_previewProc(NavCBRecPtr callBackParms,
     74                            NavCallBackUserData callbackUD)
     75 {
     76     PyObject *dict = (PyObject *)callbackUD;
     77     PyObject *pyfunc;
     78     PyObject *rv;
     79     Boolean c_rv = false;
     80 
     81     if (!dict) return false;
     82     if ( (pyfunc = PyDict_GetItemString(dict, "previewProc")) == NULL ) {
     83         PyErr_Print();
     84         return false;
     85     }
     86     rv = PyObject_CallFunction(pyfunc, "s#", (void *)callBackParms, sizeof(NavCBRec));
     87     if ( rv ) {
     88         c_rv = PyObject_IsTrue(rv);
     89         Py_DECREF(rv);
     90     } else {
     91         PySys_WriteStderr("Nav: exception in previewProc callback\n");
     92         PyErr_Print();
     93     }
     94     return c_rv;
     95 }
     96 
     97 static pascal Boolean
     98 my_filterProc(AEDesc *theItem, void *info,
     99                           NavCallBackUserData callbackUD,
    100                           NavFilterModes filterMode)
    101 {
    102     PyObject *dict = (PyObject *)callbackUD;
    103     PyObject *pyfunc;
    104     PyObject *rv;
    105     Boolean c_rv = false;
    106 
    107     if (!dict) return false;
    108     if ( (pyfunc = PyDict_GetItemString(dict, "filterProc")) == NULL ) {
    109         PyErr_Print();
    110         return false;
    111     }
    112     rv = PyObject_CallFunction(pyfunc, "O&s#h",
    113         AEDesc_NewBorrowed, theItem, info, sizeof(NavFileOrFolderInfo), (short)filterMode);
    114     if ( rv ) {
    115         c_rv = PyObject_IsTrue(rv);
    116         Py_DECREF(rv);
    117     } else {
    118         PySys_WriteStderr("Nav: exception in filterProc callback\n");
    119         PyErr_Print();
    120     }
    121     return c_rv;
    122 }
    123 
    124 /* ----------------------------------------------------- */
    125 static int
    126 filldialogoptions(PyObject *d,
    127                 AEDesc **defaultLocationP,
    128                 NavDialogOptions *opt,
    129                 NavEventUPP *eventProcP,
    130                 NavPreviewUPP *previewProcP,
    131                 NavObjectFilterUPP *filterProcP,
    132                 NavTypeListHandle *typeListP,
    133                 OSType *fileTypeP,
    134                 OSType *fileCreatorP)
    135 {
    136     Py_ssize_t pos = 0;
    137     PyObject *key, *value;
    138     char *keystr;
    139     AEDesc *defaultLocation_storage;
    140 
    141     NavGetDefaultDialogOptions(opt);
    142 
    143     while ( PyDict_Next(d, &pos, &key, &value) ) {
    144         if ( !key || !value || !PyString_Check(key) ) {
    145             PyErr_SetString(ErrorObject, "DialogOption has non-string key");
    146             return 0;
    147         }
    148         keystr = PyString_AsString(key);
    149         if( strcmp(keystr, "defaultLocation") == 0 ) {
    150             if ( (defaultLocation_storage = PyMem_NEW(AEDesc, 1)) == NULL ) {
    151                 PyErr_NoMemory();
    152                 return 0;
    153             }
    154             if ( !PyArg_Parse(value, "O&", AEDesc_Convert, defaultLocation_storage) ) {
    155                 PyMem_DEL(defaultLocation_storage);
    156                 return 0;
    157             }
    158             *defaultLocationP = defaultLocation_storage;
    159         } else if( strcmp(keystr, "version") == 0 ) {
    160             if ( !PyArg_Parse(value, "H", &opt->version) )
    161                 return 0;
    162         } else if( strcmp(keystr, "dialogOptionFlags") == 0 ) {
    163             if ( !PyArg_Parse(value, "k", &opt->dialogOptionFlags) )
    164                 return 0;
    165         } else if( strcmp(keystr, "location") == 0 ) {
    166             if ( !PyArg_Parse(value, "O&", PyMac_GetPoint, &opt->location) )
    167                 return 0;
    168         } else if( strcmp(keystr, "clientName") == 0 ) {
    169             if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->clientName) )
    170                 return 0;
    171         } else if( strcmp(keystr, "windowTitle") == 0 ) {
    172             if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->windowTitle) )
    173                 return 0;
    174         } else if( strcmp(keystr, "actionButtonLabel") == 0 ) {
    175             if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->actionButtonLabel) )
    176                 return 0;
    177         } else if( strcmp(keystr, "cancelButtonLabel") == 0 ) {
    178             if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->cancelButtonLabel) )
    179                 return 0;
    180         } else if( strcmp(keystr, "savedFileName") == 0 ) {
    181             if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->savedFileName) )
    182                 return 0;
    183         } else if( strcmp(keystr, "message") == 0 ) {
    184             if ( !PyArg_Parse(value, "O&", PyMac_GetStr255, &opt->message) )
    185                 return 0;
    186         } else if( strcmp(keystr, "preferenceKey") == 0 ) {
    187             if ( !PyArg_Parse(value, "O&", PyMac_GetOSType, &opt->preferenceKey) )
    188                 return 0;
    189         } else if( strcmp(keystr, "popupExtension") == 0 ) {
    190             if ( !PyArg_Parse(value, "O&", ResObj_Convert, &opt->popupExtension) )
    191                 return 0;
    192         } else if( eventProcP && strcmp(keystr, "eventProc") == 0 ) {
    193             *eventProcP = my_eventProcUPP;
    194         } else if( previewProcP && strcmp(keystr, "previewProc") == 0 ) {
    195             *previewProcP = my_previewProcUPP;
    196         } else if( filterProcP && strcmp(keystr, "filterProc") == 0 ) {
    197             *filterProcP = my_filterProcUPP;
    198         } else if( typeListP && strcmp(keystr, "typeList") == 0 ) {
    199             if ( !PyArg_Parse(value, "O&", ResObj_Convert, typeListP) )
    200                 return 0;
    201         } else if( fileTypeP && strcmp(keystr, "fileType") == 0 ) {
    202             if ( !PyArg_Parse(value, "O&", PyMac_GetOSType, fileTypeP) )
    203                 return 0;
    204         } else if( fileCreatorP && strcmp(keystr, "fileCreator") == 0 ) {
    205             if ( !PyArg_Parse(value, "O&", PyMac_GetOSType, fileCreatorP) )
    206                 return 0;
    207         } else {
    208             PyErr_Format(ErrorObject, "Unknown DialogOption key: %s", keystr);
    209             return 0;
    210         }
    211     }
    212     return 1;
    213 }
    214 
    215 /* ----------------------------------------------------- */
    216 
    217 /* Declarations for objects of type NavReplyRecord */
    218 
    219 typedef struct {
    220     PyObject_HEAD
    221     NavReplyRecord itself;
    222 } navrrobject;
    223 
    224 static PyTypeObject Navrrtype;
    225 
    226 
    227 
    228 /* ---------------------------------------------------------------- */
    229 
    230 static char nav_NavTranslateFile__doc__[] =
    231 "(NavTranslationOptions)->None"
    232 ;
    233 
    234 static PyObject *
    235 nav_NavTranslateFile(navrrobject *self, PyObject *args)
    236 {
    237     NavTranslationOptions howToTranslate;
    238     OSErr err;
    239 
    240     if (!PyArg_ParseTuple(args, "k", &howToTranslate))
    241         return NULL;
    242     err = NavTranslateFile(&self->itself, howToTranslate);
    243     if ( err ) {
    244         PyErr_Mac(ErrorObject, err);
    245         return NULL;
    246     }
    247     Py_INCREF(Py_None);
    248     return Py_None;
    249 }
    250 
    251 static char nav_NavCompleteSave__doc__[] =
    252 "(NavTranslationOptions)->None"
    253 ;
    254 
    255 static PyObject *
    256 nav_NavCompleteSave(navrrobject *self, PyObject *args)
    257 {
    258     NavTranslationOptions howToTranslate;
    259     OSErr err;
    260 
    261     if (!PyArg_ParseTuple(args, "k", &howToTranslate))
    262         return NULL;
    263     err = NavCompleteSave(&self->itself, howToTranslate);
    264     if ( err ) {
    265         PyErr_Mac(ErrorObject, err);
    266         return NULL;
    267     }
    268     Py_INCREF(Py_None);
    269     return Py_None;
    270 }
    271 
    272 
    273 static struct PyMethodDef navrr_methods[] = {
    274  {"NavTranslateFile",   (PyCFunction)nav_NavTranslateFile,      METH_VARARGS,   nav_NavTranslateFile__doc__},
    275  {"NavCompleteSave",    (PyCFunction)nav_NavCompleteSave,       METH_VARARGS,   nav_NavCompleteSave__doc__},
    276 
    277     {NULL,              NULL}           /* sentinel */
    278 };
    279 
    280 /* ---------- */
    281 
    282 
    283 static navrrobject *
    284 newnavrrobject(NavReplyRecord *itself)
    285 {
    286     navrrobject *self;
    287 
    288     self = PyObject_NEW(navrrobject, &Navrrtype);
    289     if (self == NULL)
    290         return NULL;
    291     self->itself = *itself;
    292     return self;
    293 }
    294 
    295 
    296 static void
    297 navrr_dealloc(navrrobject *self)
    298 {
    299     NavDisposeReply(&self->itself);
    300     PyObject_DEL(self);
    301 }
    302 
    303 static PyObject *
    304 navrr_getattr(navrrobject *self, char *name)
    305 {
    306     FSRef fsr;
    307     FSSpec fss;
    308 
    309     if( strcmp(name, "__members__") == 0 )
    310         return Py_BuildValue(
    311                         "ssssssssss",
    312                         "version", "validRecord", "replacing",
    313             "isStationery", "translationNeeded",
    314             "selection",
    315             "selection_fsr",
    316             "fileTranslation", "keyScript", "saveFileName");
    317 
    318     if( strcmp(name, "version") == 0 )
    319         return Py_BuildValue("h", self->itself.version);
    320     if( strcmp(name, "validRecord") == 0 )
    321         return Py_BuildValue("l", (long)self->itself.validRecord);
    322     if( strcmp(name, "replacing") == 0 )
    323         return Py_BuildValue("l", (long)self->itself.replacing);
    324     if( strcmp(name, "isStationery") == 0 )
    325         return Py_BuildValue("l", (long)self->itself.isStationery);
    326     if( strcmp(name, "translationNeeded") == 0 )
    327         return Py_BuildValue("l", (long)self->itself.translationNeeded);
    328     if( strcmp(name, "selection") == 0 ) {
    329         SInt32 i;
    330         long count;
    331         OSErr err;
    332         PyObject *rv, *rvitem;
    333         AEDesc desc;
    334 
    335         if ((err=AECountItems(&self->itself.selection, &count))) {
    336             PyErr_Mac(ErrorObject, err);
    337             return NULL;
    338         }
    339         if ( (rv=PyList_New(count)) == NULL )
    340             return NULL;
    341         for(i=0; i<count; i++) {
    342             desc.dataHandle = NULL;
    343             if ((err=AEGetNthDesc(&self->itself.selection, i+1, typeFSS, NULL, &desc))) {
    344                 Py_DECREF(rv);
    345                 PyErr_Mac(ErrorObject, err);
    346                 return NULL;
    347             }
    348             if ((err=AEGetDescData(&desc, &fss, sizeof(FSSpec)))) {
    349                 Py_DECREF(rv);
    350                 PyErr_Mac(ErrorObject, err);
    351                 return NULL;
    352             }
    353             rvitem = PyMac_BuildFSSpec(&fss);
    354             PyList_SetItem(rv, i, rvitem);
    355             AEDisposeDesc(&desc);
    356         }
    357         return rv;
    358     }
    359     if( strcmp(name, "selection_fsr") == 0 ) {
    360         SInt32 i;
    361         long count;
    362         OSErr err;
    363         PyObject *rv, *rvitem;
    364         AEDesc desc;
    365 
    366         if ((err=AECountItems(&self->itself.selection, &count))) {
    367             PyErr_Mac(ErrorObject, err);
    368             return NULL;
    369         }
    370         if ( (rv=PyList_New(count)) == NULL )
    371             return NULL;
    372         for(i=0; i<count; i++) {
    373             desc.dataHandle = NULL;
    374             if ((err=AEGetNthDesc(&self->itself.selection, i+1, typeFSRef, NULL, &desc))) {
    375                 Py_DECREF(rv);
    376                 PyErr_Mac(ErrorObject, err);
    377                 return NULL;
    378             }
    379             if ((err=AEGetDescData(&desc, &fsr, sizeof(FSRef)))) {
    380                 Py_DECREF(rv);
    381                 PyErr_Mac(ErrorObject, err);
    382                 return NULL;
    383             }
    384             rvitem = PyMac_BuildFSRef(&fsr);
    385             PyList_SetItem(rv, i, rvitem);
    386             AEDisposeDesc(&desc);
    387         }
    388         return rv;
    389     }
    390     if( strcmp(name, "fileTranslation") == 0 )
    391         return ResObj_New((Handle)self->itself.fileTranslation);
    392     if( strcmp(name, "keyScript") == 0 )
    393         return Py_BuildValue("h", (short)self->itself.keyScript);
    394     if( strcmp(name, "saveFileName") == 0 )
    395         return Py_BuildValue("O&", CFStringRefObj_New, self->itself.saveFileName);
    396 
    397 
    398     return Py_FindMethod(navrr_methods, (PyObject *)self, name);
    399 }
    400 
    401 static int
    402 navrr_setattr(navrrobject *self, char *name, PyObject *v)
    403 {
    404     /* Set attribute 'name' to value 'v'. v==NULL means delete */
    405 
    406     /* XXXX Add your own setattr code here */
    407     return -1;
    408 }
    409 
    410 static char Navrrtype__doc__[] =
    411 "Record containing result of a Nav file selection call. Use dir() for member names."
    412 ;
    413 
    414 static PyTypeObject Navrrtype = {
    415     PyObject_HEAD_INIT(&PyType_Type)
    416     0,                                  /*ob_size*/
    417     "Nav.NavReplyRecord",                       /*tp_name*/
    418     sizeof(navrrobject),                /*tp_basicsize*/
    419     0,                                  /*tp_itemsize*/
    420     /* methods */
    421     (destructor)navrr_dealloc,          /*tp_dealloc*/
    422     (printfunc)0,               /*tp_print*/
    423     (getattrfunc)navrr_getattr,         /*tp_getattr*/
    424     (setattrfunc)navrr_setattr,         /*tp_setattr*/
    425     (cmpfunc)0,                 /*tp_compare*/
    426     (reprfunc)0,                /*tp_repr*/
    427     0,                          /*tp_as_number*/
    428     0,                  /*tp_as_sequence*/
    429     0,                  /*tp_as_mapping*/
    430     (hashfunc)0,                /*tp_hash*/
    431     (ternaryfunc)0,             /*tp_call*/
    432     (reprfunc)0,                /*tp_str*/
    433 
    434     /* Space for future expansion */
    435     0L,0L,0L,0L,
    436     Navrrtype__doc__ /* Documentation string */
    437 };
    438 
    439 /* End of code for NavReplyRecord objects */
    440 
    441 /* ----------------------------------------------------- */
    442 
    443 static char nav_NavGetFile__doc__[] =
    444 "(DialogOptions dict or kwargs+defaultLocation,eventProc,previewProc,filterProc,typeList) -> NavReplyRecord"
    445 ;
    446 
    447 static PyObject *
    448 nav_NavGetFile(PyObject *self, PyObject *args, PyObject *kw)
    449 {
    450     PyObject *dict;
    451     AEDesc      *defaultLocation = NULL;
    452     NavReplyRecord reply;
    453     NavDialogOptions dialogOptions;
    454     NavEventUPP eventProc = NULL;
    455     NavPreviewUPP previewProc = NULL;
    456     NavObjectFilterUPP filterProc = NULL;
    457     NavTypeListHandle typeList = NULL;
    458     OSErr err;
    459 
    460     if ( kw && PyObject_IsTrue(kw) ) {
    461         if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
    462             return NULL;
    463         dict = kw;
    464     } else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
    465         return NULL;
    466     if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, &previewProc, &filterProc, &typeList, NULL, NULL))
    467         return NULL;
    468     err = NavGetFile(defaultLocation, &reply, &dialogOptions,
    469                     eventProc, previewProc, filterProc, typeList, (void *)dict);
    470     PyMem_DEL(defaultLocation);
    471     if ( err ) {
    472         PyErr_Mac(ErrorObject, err);
    473         return NULL;
    474     }
    475     return (PyObject *)newnavrrobject(&reply);
    476 }
    477 
    478 static char nav_NavPutFile__doc__[] =
    479 "(DialogOptions dict or kwargs+defaultLocation,eventProc,fileCreator,fileType) -> NavReplyRecord"
    480 ;
    481 
    482 static PyObject *
    483 nav_NavPutFile(PyObject *self, PyObject *args, PyObject *kw)
    484 {
    485     PyObject *dict;
    486     AEDesc      *defaultLocation = NULL;
    487     NavReplyRecord reply;
    488     NavDialogOptions dialogOptions;
    489     NavEventUPP eventProc = NULL;
    490     OSType fileType;
    491     OSType fileCreator;
    492     OSErr err;
    493 
    494     if ( kw && PyObject_IsTrue(kw) ) {
    495         if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
    496             return NULL;
    497         dict = kw;
    498     } else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
    499         return NULL;
    500     if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, NULL, NULL, NULL, &fileType, &fileCreator))
    501         return NULL;
    502     err = NavPutFile(defaultLocation, &reply, &dialogOptions,
    503                     eventProc, fileType, fileCreator, (void *)dict);
    504     PyMem_DEL(defaultLocation);
    505     if ( err ) {
    506         PyErr_Mac(ErrorObject, err);
    507         return NULL;
    508     }
    509     return (PyObject *)newnavrrobject(&reply);
    510 }
    511 
    512 static char nav_NavAskSaveChanges__doc__[] =
    513 "(NavAskSaveChangesAction, DialogOptions dict or kwargs+eventProc) -> NavAskSaveChangesResult"
    514 
    515 ;
    516 
    517 static PyObject *
    518 nav_NavAskSaveChanges(PyObject *self, PyObject *args, PyObject *kw)
    519 {
    520     PyObject *dict;
    521     NavDialogOptions dialogOptions;
    522     NavAskSaveChangesAction action;
    523     NavAskSaveChangesResult reply;
    524     NavEventUPP eventProc = NULL;
    525     OSErr err;
    526 
    527     if ( kw && PyObject_IsTrue(kw) ) {
    528         if (!PyArg_ParseTuple(args, "k", &action))
    529             return NULL;
    530         dict = kw;
    531     } else if (!PyArg_ParseTuple(args, "lO!", &action, &PyDict_Type, &dict))
    532         return NULL;
    533     if (!filldialogoptions(dict, NULL, &dialogOptions, &eventProc, NULL, NULL, NULL, NULL, NULL))
    534         return NULL;
    535     err = NavAskSaveChanges(&dialogOptions, action, &reply, eventProc, (void *)dict);
    536     if ( err ) {
    537         PyErr_Mac(ErrorObject, err);
    538         return NULL;
    539     }
    540     return Py_BuildValue("l", (long)reply);
    541 }
    542 
    543 static char nav_NavCustomAskSaveChanges__doc__[] =
    544 "(DialogOptions dict or kwargs+eventProc) -> NavAskSaveChangesResult"
    545 ;
    546 
    547 static PyObject *
    548 nav_NavCustomAskSaveChanges(PyObject *self, PyObject *args, PyObject *kw)
    549 {
    550     PyObject *dict;
    551     NavDialogOptions dialogOptions;
    552     NavAskSaveChangesResult reply;
    553     NavEventUPP eventProc = NULL;
    554     OSErr err;
    555 
    556     if ( kw && PyObject_IsTrue(kw) ) {
    557         if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
    558             return NULL;
    559         dict = kw;
    560     } else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
    561         return NULL;
    562     if (!filldialogoptions(dict, NULL, &dialogOptions, &eventProc, NULL, NULL, NULL, NULL, NULL))
    563         return NULL;
    564     err = NavCustomAskSaveChanges(&dialogOptions, &reply, eventProc, (void *)dict);
    565     if ( err ) {
    566         PyErr_Mac(ErrorObject, err);
    567         return NULL;
    568     }
    569     return Py_BuildValue("l", (long)reply);
    570 }
    571 
    572 static char nav_NavAskDiscardChanges__doc__[] =
    573 "(DialogOptions dict or kwargs+eventProc) -> NavAskSaveChangesResult"
    574 ;
    575 
    576 static PyObject *
    577 nav_NavAskDiscardChanges(PyObject *self, PyObject *args, PyObject *kw)
    578 {
    579     PyObject *dict;
    580     NavDialogOptions dialogOptions;
    581     NavAskSaveChangesResult reply;
    582     NavEventUPP eventProc = NULL;
    583     OSErr err;
    584 
    585     if ( kw && PyObject_IsTrue(kw) ) {
    586         if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
    587             return NULL;
    588         dict = kw;
    589     } else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
    590         return NULL;
    591     if (!filldialogoptions(dict, NULL, &dialogOptions, &eventProc, NULL, NULL, NULL, NULL, NULL))
    592         return NULL;
    593     err = NavAskDiscardChanges(&dialogOptions, &reply, eventProc, (void *)dict);
    594     if ( err ) {
    595         PyErr_Mac(ErrorObject, err);
    596         return NULL;
    597     }
    598     return Py_BuildValue("l", (long)reply);
    599 }
    600 
    601 static char nav_NavChooseFile__doc__[] =
    602 "(DialogOptions dict or kwargs+defaultLocation,eventProc,previewProc,filterProc,typeList) -> NavReplyRecord"
    603 ;
    604 
    605 static PyObject *
    606 nav_NavChooseFile(PyObject *self, PyObject *args, PyObject *kw)
    607 {
    608     PyObject *dict;
    609     AEDesc      *defaultLocation = NULL;
    610     NavReplyRecord reply;
    611     NavDialogOptions dialogOptions;
    612     NavEventUPP eventProc = NULL;
    613     NavPreviewUPP previewProc = NULL;
    614     NavObjectFilterUPP filterProc = NULL;
    615     NavTypeListHandle typeList = NULL;
    616     OSErr err;
    617 
    618     if ( kw && PyObject_IsTrue(kw) ) {
    619         if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
    620             return NULL;
    621         dict = kw;
    622     } else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
    623         return NULL;
    624     if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, &previewProc, &filterProc, &typeList, NULL, NULL))
    625         return NULL;
    626     err = NavChooseFile(defaultLocation, &reply, &dialogOptions,
    627                     eventProc, previewProc, filterProc, typeList, (void *)dict);
    628     PyMem_DEL(defaultLocation);
    629     if ( err ) {
    630         PyErr_Mac(ErrorObject, err);
    631         return NULL;
    632     }
    633     return (PyObject *)newnavrrobject(&reply);
    634 }
    635 
    636 static char nav_NavChooseFolder__doc__[] =
    637 "(DialogOptions dict or kwargs+defaultLocation,eventProc,filterProc) -> NavReplyRecord"
    638 ;
    639 
    640 static PyObject *
    641 nav_NavChooseFolder(PyObject *self, PyObject *args, PyObject *kw)
    642 {
    643     PyObject *dict;
    644     AEDesc      *defaultLocation = NULL;
    645     NavReplyRecord reply;
    646     NavDialogOptions dialogOptions;
    647     NavEventUPP eventProc = NULL;
    648     NavObjectFilterUPP filterProc = NULL;
    649     OSErr err;
    650 
    651     if ( kw && PyObject_IsTrue(kw) ) {
    652         if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
    653             return NULL;
    654         dict = kw;
    655     } else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
    656         return NULL;
    657     if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, NULL, &filterProc, NULL, NULL, NULL))
    658         return NULL;
    659     err = NavChooseFolder(defaultLocation, &reply, &dialogOptions,
    660                     eventProc, filterProc, (void *)dict);
    661     PyMem_DEL(defaultLocation);
    662     if ( err ) {
    663         PyErr_Mac(ErrorObject, err);
    664         return NULL;
    665     }
    666     return (PyObject *)newnavrrobject(&reply);
    667 }
    668 
    669 static char nav_NavChooseVolume__doc__[] =
    670 "(DialogOptions dict or kwargs+defaultLocation,eventProc,filterProc) -> NavReplyRecord"
    671 ;
    672 
    673 static PyObject *
    674 nav_NavChooseVolume(PyObject *self, PyObject *args, PyObject *kw)
    675 {
    676     PyObject *dict;
    677     AEDesc      *defaultLocation = NULL;
    678     NavReplyRecord reply;
    679     NavDialogOptions dialogOptions;
    680     NavEventUPP eventProc = NULL;
    681     NavObjectFilterUPP filterProc = NULL;
    682     OSErr err;
    683 
    684     if ( kw && PyObject_IsTrue(kw) ) {
    685         if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
    686             return NULL;
    687         dict = kw;
    688     } else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
    689         return NULL;
    690     if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, NULL, &filterProc, NULL, NULL, NULL))
    691         return NULL;
    692     err = NavChooseVolume(defaultLocation, &reply, &dialogOptions,
    693                     eventProc, filterProc, (void *)dict);
    694     PyMem_DEL(defaultLocation);
    695     if ( err ) {
    696         PyErr_Mac(ErrorObject, err);
    697         return NULL;
    698     }
    699     return (PyObject *)newnavrrobject(&reply);
    700 }
    701 
    702 static char nav_NavChooseObject__doc__[] =
    703 "(DialogOptions dict or kwargs+defaultLocation,eventProc,filterProc) -> NavReplyRecord"
    704 ;
    705 
    706 static PyObject *
    707 nav_NavChooseObject(PyObject *self, PyObject *args, PyObject *kw)
    708 {
    709     PyObject *dict;
    710     AEDesc      *defaultLocation = NULL;
    711     NavReplyRecord reply;
    712     NavDialogOptions dialogOptions;
    713     NavEventUPP eventProc = NULL;
    714     NavObjectFilterUPP filterProc = NULL;
    715     OSErr err;
    716 
    717     if ( kw && PyObject_IsTrue(kw) ) {
    718         if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
    719             return NULL;
    720         dict = kw;
    721     } else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
    722         return NULL;
    723     if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, NULL, &filterProc, NULL, NULL, NULL))
    724         return NULL;
    725     err = NavChooseObject(defaultLocation, &reply, &dialogOptions,
    726                     eventProc, filterProc, (void *)dict);
    727     PyMem_DEL(defaultLocation);
    728     if ( err ) {
    729         PyErr_Mac(ErrorObject, err);
    730         return NULL;
    731     }
    732     return (PyObject *)newnavrrobject(&reply);
    733 }
    734 
    735 static char nav_NavNewFolder__doc__[] =
    736 "(DialogOptions dict or kwargs+defaultLocation,eventProc) -> NavReplyRecord"
    737 ;
    738 
    739 static PyObject *
    740 nav_NavNewFolder(PyObject *self, PyObject *args, PyObject *kw)
    741 {
    742     PyObject *dict;
    743     AEDesc      *defaultLocation = NULL;
    744     NavReplyRecord reply;
    745     NavDialogOptions dialogOptions;
    746     NavEventUPP eventProc = NULL;
    747     OSErr err;
    748 
    749     if ( kw && PyObject_IsTrue(kw) ) {
    750         if (!PyArg_ParseTuple(args, ";either keyword arguments or dictionary expected"))
    751             return NULL;
    752         dict = kw;
    753     } else if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
    754         return NULL;
    755     if (!filldialogoptions(dict, &defaultLocation, &dialogOptions, &eventProc, NULL, NULL, NULL, NULL, NULL))
    756         return NULL;
    757     err = NavNewFolder(defaultLocation, &reply, &dialogOptions, eventProc, (void *)dict);
    758     PyMem_DEL(defaultLocation);
    759     if ( err ) {
    760         PyErr_Mac(ErrorObject, err);
    761         return NULL;
    762     }
    763     return (PyObject *)newnavrrobject(&reply);
    764 }
    765 
    766 #if 0
    767 /* XXXX I don't know what to do with the void * argument */
    768 static char nav_NavCustomControl__doc__[] =
    769 ""
    770 ;
    771 
    772 
    773 static PyObject *
    774 nav_NavCustomControl(PyObject *self, PyObject *args)
    775 {
    776 
    777     if (!PyArg_ParseTuple(args, ""))
    778         return NULL;
    779     Py_INCREF(Py_None);
    780     return Py_None;
    781 }
    782 #endif
    783 
    784 static char nav_NavServicesCanRun__doc__[] =
    785 "()->int"
    786 ;
    787 
    788 static PyObject *
    789 nav_NavServicesCanRun(PyObject *self, PyObject *args)
    790 {
    791     Boolean rv;
    792     if (!PyArg_ParseTuple(args, ""))
    793         return NULL;
    794     rv = NavServicesCanRun();
    795     return Py_BuildValue("l", (long)rv);
    796 }
    797 
    798 static char nav_NavServicesAvailable__doc__[] =
    799 "()->int"
    800 ;
    801 
    802 static PyObject *
    803 nav_NavServicesAvailable(PyObject *self, PyObject *args)
    804 {
    805     Boolean rv;
    806 
    807     if (!PyArg_ParseTuple(args, ""))
    808         return NULL;
    809     rv = NavServicesAvailable();
    810     return Py_BuildValue("l", (long)rv);
    811 }
    812 /* XX */
    813 static char nav_NavLoad__doc__[] =
    814 "()->None"
    815 ;
    816 
    817 static PyObject *
    818 nav_NavLoad(PyObject *self, PyObject *args)
    819 {
    820 
    821     if (!PyArg_ParseTuple(args, ""))
    822         return NULL;
    823     NavLoad();
    824     Py_INCREF(Py_None);
    825     return Py_None;
    826 }
    827 
    828 static char nav_NavUnload__doc__[] =
    829 "()->None"
    830 ;
    831 
    832 static PyObject *
    833 nav_NavUnload(PyObject *self, PyObject *args)
    834 {
    835 
    836     if (!PyArg_ParseTuple(args, ""))
    837         return NULL;
    838     NavUnload();
    839     Py_INCREF(Py_None);
    840     return Py_None;
    841 }
    842 
    843 static char nav_NavLibraryVersion__doc__[] =
    844 "()->int"
    845 ;
    846 
    847 static PyObject *
    848 nav_NavLibraryVersion(PyObject *self, PyObject *args)
    849 {
    850     UInt32 rv;
    851 
    852     if (!PyArg_ParseTuple(args, ""))
    853         return NULL;
    854     rv = NavLibraryVersion();
    855     return Py_BuildValue("l", (long)rv);
    856 }
    857 
    858 static char nav_NavGetDefaultDialogOptions__doc__[] =
    859 "()->dict\nPass dict or keyword args with same names to other calls."
    860 ;
    861 
    862 static PyObject *
    863 nav_NavGetDefaultDialogOptions(PyObject *self, PyObject *args)
    864 {
    865     NavDialogOptions dialogOptions;
    866     OSErr err;
    867 
    868     err = NavGetDefaultDialogOptions(&dialogOptions);
    869     if ( err ) {
    870         PyErr_Mac(ErrorObject, err);
    871         return NULL;
    872     }
    873     return Py_BuildValue(
    874                     "{s:h,s:l,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&,s:O&}",
    875         "version", dialogOptions.version,
    876         "dialogOptionFlags", dialogOptions.dialogOptionFlags,
    877         "location", PyMac_BuildPoint, dialogOptions.location,
    878         "clientName", PyMac_BuildStr255, &dialogOptions.clientName,
    879         "windowTitle", PyMac_BuildStr255, &dialogOptions.windowTitle,
    880         "actionButtonLabel", PyMac_BuildStr255, &dialogOptions.actionButtonLabel,
    881         "cancelButtonLabel", PyMac_BuildStr255, &dialogOptions.cancelButtonLabel,
    882         "savedFileName", PyMac_BuildStr255, &dialogOptions.savedFileName,
    883         "message", PyMac_BuildStr255, &dialogOptions.message,
    884         "preferenceKey", PyMac_BuildOSType, dialogOptions.preferenceKey
    885         ,"popupExtension", OptResObj_New, dialogOptions.popupExtension
    886         );
    887 }
    888 
    889 /* List of methods defined in the module */
    890 
    891 static struct PyMethodDef nav_methods[] = {
    892     {"NavGetFile",      (PyCFunction)nav_NavGetFile,    METH_VARARGS|METH_KEYWORDS,     nav_NavGetFile__doc__},
    893  {"NavPutFile", (PyCFunction)nav_NavPutFile,    METH_VARARGS|METH_KEYWORDS,     nav_NavPutFile__doc__},
    894  {"NavAskSaveChanges",  (PyCFunction)nav_NavAskSaveChanges,     METH_VARARGS|METH_KEYWORDS,     nav_NavAskSaveChanges__doc__},
    895  {"NavCustomAskSaveChanges",    (PyCFunction)nav_NavCustomAskSaveChanges,       METH_VARARGS|METH_KEYWORDS,     nav_NavCustomAskSaveChanges__doc__},
    896  {"NavAskDiscardChanges",       (PyCFunction)nav_NavAskDiscardChanges,  METH_VARARGS|METH_KEYWORDS,     nav_NavAskDiscardChanges__doc__},
    897  {"NavChooseFile",      (PyCFunction)nav_NavChooseFile, METH_VARARGS|METH_KEYWORDS,     nav_NavChooseFile__doc__},
    898  {"NavChooseFolder",    (PyCFunction)nav_NavChooseFolder,       METH_VARARGS|METH_KEYWORDS,     nav_NavChooseFolder__doc__},
    899  {"NavChooseVolume",    (PyCFunction)nav_NavChooseVolume,       METH_VARARGS|METH_KEYWORDS,     nav_NavChooseVolume__doc__},
    900  {"NavChooseObject",    (PyCFunction)nav_NavChooseObject,       METH_VARARGS|METH_KEYWORDS,     nav_NavChooseObject__doc__},
    901  {"NavNewFolder",       (PyCFunction)nav_NavNewFolder,  METH_VARARGS|METH_KEYWORDS,     nav_NavNewFolder__doc__},
    902 #if 0
    903  {"NavCustomControl",   (PyCFunction)nav_NavCustomControl,      METH_VARARGS,   nav_NavCustomControl__doc__},
    904 #endif
    905  {"NavServicesCanRun",  (PyCFunction)nav_NavServicesCanRun,     METH_VARARGS,   nav_NavServicesCanRun__doc__},
    906  {"NavServicesAvailable",       (PyCFunction)nav_NavServicesAvailable,  METH_VARARGS,   nav_NavServicesAvailable__doc__},
    907  {"NavLoad",    (PyCFunction)nav_NavLoad,       METH_VARARGS,   nav_NavLoad__doc__},
    908  {"NavUnload",  (PyCFunction)nav_NavUnload,     METH_VARARGS,   nav_NavUnload__doc__},
    909  {"NavLibraryVersion",  (PyCFunction)nav_NavLibraryVersion,     METH_VARARGS,   nav_NavLibraryVersion__doc__},
    910  {"NavGetDefaultDialogOptions", (PyCFunction)nav_NavGetDefaultDialogOptions,    METH_VARARGS,   nav_NavGetDefaultDialogOptions__doc__},
    911     {NULL,       (PyCFunction)NULL, 0, NULL}            /* sentinel */
    912 };
    913 
    914 
    915 /* Initialization function for the module (*must* be called initNav) */
    916 
    917 static char Nav_module_documentation[] =
    918 "Interface to Navigation Services\n"
    919 "Most calls accept a NavDialogOptions dictionary or keywords with the same names, pass {}\n"
    920 "if you want the default options.\n"
    921 "Use NavGetDefaultDialogOptions() to find out common option names.\n"
    922 "See individual docstrings for additional keyword args/dictentries supported by each call.\n"
    923 "Pass None as eventProc to get movable-modal dialogs that process updates through the standard Python mechanism."
    924 ;
    925 
    926 
    927 #endif /* !__LP64__ */
    928 
    929 
    930 void
    931 initNav(void)
    932 {
    933 #ifdef __LP64__
    934     PyErr_SetString(PyExc_ImportError, "Navigation Services not available in 64-bit mode");
    935     return;
    936 
    937 #else   /* !__LP64__ */
    938     PyObject *m, *d;
    939 
    940     if (PyErr_WarnPy3k("In 3.x, the Nav module is removed.", 1))
    941         return;
    942 
    943     /* Test that we have NavServices */
    944     if ( !NavServicesAvailable() ) {
    945         PyErr_SetString(PyExc_ImportError, "Navigation Services not available");
    946         return;
    947     }
    948     /* Create the module and add the functions */
    949     m = Py_InitModule4("Nav", nav_methods,
    950         Nav_module_documentation,
    951         (PyObject*)NULL,PYTHON_API_VERSION);
    952 
    953     /* Add some symbolic constants to the module */
    954     d = PyModule_GetDict(m);
    955     ErrorObject = PyString_FromString("Nav.error");
    956     PyDict_SetItemString(d, "error", ErrorObject);
    957 
    958     /* XXXX Add constants here */
    959 
    960     /* Set UPPs */
    961     my_eventProcUPP = NewNavEventUPP(my_eventProc);
    962     my_previewProcUPP = NewNavPreviewUPP(my_previewProc);
    963     my_filterProcUPP = NewNavObjectFilterUPP(my_filterProc);
    964 #endif /* !__LP64__ */
    965 
    966 }
    967 
    968