Example #1
0
/*----------------------------------------------------------------------------
	GetDataFromList 

	
----------------------------------------------------------------------------*/
void AEGenericClass::GetDataFromList(const AEDesc *srcList, AEDesc *desiredTypes, AEDesc *dstList)
{
	OSErr		err;
	long			itemNum;
	long			numItems;
	DescType		keyword;
	StAEDesc		srcItem;
	StAEDesc		dstItem;
		
	err = AECountItems((AEDescList*)srcList, &numItems);
	ThrowIfOSErr(err);
		
	for (itemNum = 1; itemNum <= numItems; itemNum++)
	{
		err = AEGetNthDesc(srcList, itemNum, typeWildCard, &keyword, &srcItem);
		ThrowIfOSErr(err);
		
		if (AEListUtils::TokenContainsTokenList(&srcItem) == false)
		{
			GetDataFromObject(&srcItem, desiredTypes, &dstItem);  // Get data from single item
		}
		else
		{
			ThrowIfOSErr(AECreateList(nil, 0, false, &dstItem));
			GetDataFromList(&srcItem, desiredTypes, &dstItem);
		}
		err = AEPutDesc(dstList, itemNum, &dstItem);
		ThrowIfOSErr(err);
	}
}
Example #2
0
static PyObject *AEDesc_AEGetNthDesc(AEDescObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	long index;
	DescType desiredType;
	AEKeyword theAEKeyword;
	AEDesc result;
#ifndef AEGetNthDesc
	PyMac_PRECHECK(AEGetNthDesc);
#endif
	if (!PyArg_ParseTuple(_args, "lO&",
	                      &index,
	                      PyMac_GetOSType, &desiredType))
		return NULL;
	_err = AEGetNthDesc(&_self->ob_itself,
	                    index,
	                    desiredType,
	                    &theAEKeyword,
	                    &result);
	if (_err != noErr) return PyMac_Error(_err);
	_res = Py_BuildValue("O&O&",
	                     PyMac_BuildOSType, theAEKeyword,
	                     AEDesc_New, &result);
	return _res;
}
Example #3
0
/*----------------------------------------------------------------------------
	SetDataForList 

	Given a token that contains a list of cWindow tokens,
	walk the list recursively to set the data for each token in the list
	
----------------------------------------------------------------------------*/
void AEGenericClass::SetDataForList(const AEDesc *token, AEDesc *data)
{
	OSErr 			err;
		
	if (AEListUtils::TokenContainsTokenList(token) == false)
	{
		SetDataForObject(token, data);
	}
	else
	{
		long			numItems;
		long			itemNum;
		err = AECountItems((AEDescList*)token, &numItems);
		ThrowIfOSErr(err);
		
		for (itemNum = 1; itemNum <= numItems; itemNum++)
		{
			StAEDesc	  	tempToken;
			AEKeyword	keyword;
			
		 	err = AEGetNthDesc((AEDescList*)token, itemNum, typeWildCard, &keyword, &tempToken);
			ThrowIfOSErr(err);
			
			if (AEListUtils::TokenContainsTokenList(&tempToken) == false)
			{
				SetDataForObject(&tempToken, data);  		// Set data from single item
			}
			else
			{
				SetDataForList(&tempToken, data); 	// Recurse sublist
			}
		}
	}
}
Example #4
0
static int manually_locate_product(const char *name, char *buf, size_t bufsize, const char *title)
{
    NavDialogCreationOptions dlgopt;
    NavDialogRef dlg;
    NavReplyRecord reply;
    NavUserAction action;
    AEKeyword keyword;
    AEDesc desc;
    FSRef fsref;
    OSStatus rc;
    int retval = 0;
    const char *promptfmt = _("We can't find your \"%s\" installation."
                            " Would you like to show us where it is?");
    char *promptstr = alloca(strlen(name) + strlen(promptfmt) + 1);

    if (promptstr == NULL)
    {
        log_fatal(_("Out of memory."));
        return(0);
    } /* if */
    sprintf(promptstr, promptfmt, name);

    if (!ui_prompt_yn(promptstr, title))
        return(0);

    NavGetDefaultDialogCreationOptions(&dlgopt);
    dlgopt.optionFlags |= kNavSupportPackages;
    dlgopt.optionFlags |= kNavAllowOpenPackages;
    dlgopt.optionFlags &= ~kNavAllowMultipleFiles;
    dlgopt.windowTitle = CFSTR("Please select the product's icon and click 'OK'.");  /* !!! FIXME! */
    dlgopt.actionButtonLabel = CFSTR("OK");
    NavCreateChooseFolderDialog(&dlgopt, NULL, NULL, NULL, &dlg);
    NavDialogRun(dlg);
    action = NavDialogGetUserAction(dlg);
    if (action != kNavUserActionCancel)
    {
        NavDialogGetReply(dlg, &reply);
        rc = AEGetNthDesc(&reply.selection, 1, typeFSRef, &keyword, &desc);
        if (rc != noErr)
            log_fatal("Unexpected error in AEGetNthDesc: %d", (int) rc);
        else
        {
            /* !!! FIXME: Check return values here! */
            BlockMoveData(*desc.dataHandle, &fsref, sizeof (fsref));
            FSRefMakePath(&fsref, BAD_CAST buf, bufsize - 1);
            buf[bufsize - 1] = '\0';
            AEDisposeDesc(&desc);
            retval = 1;
        } /* if */

        NavDisposeReply(&reply);
    } /* else */

    NavDialogDispose(dlg);

    return(retval);
} /* manually_locate_product */
Example #5
0
static PyObject *BuildTerminologyList(AEDesc *theDesc, DescType requiredType) {
	AEDesc item;
	long size, i;
	AEKeyword key;
	PyObject *itemObj, *result;
	OSErr err;
	
	result = PyList_New(0);
	if (!result) return NULL;
	if (theDesc->descriptorType == typeAEList) {
		err = AECountItems(theDesc, &size);
		if (err) {
			Py_DECREF(result);
			return AE_MacOSError(err);
		}
		for (i = 1; i <= size; i++) {			
			err = AEGetNthDesc(theDesc, i, requiredType, &key, &item);
			if (!err) {
				itemObj = AE_AEDesc_New(&item);
				if (!itemObj) {
					AEDisposeDesc(&item);
					Py_DECREF(result);
					return NULL;
				}
				err = PyList_Append(result, itemObj);
				if (err) {
					Py_DECREF(itemObj);
					Py_DECREF(result);
					return NULL;
				}
			} else if (err != errAECoercionFail) {
				Py_DECREF(result);
				return AE_MacOSError(err);
			}
		}
	} else {
		itemObj = AE_AEDesc_New(theDesc);
		if (!itemObj) {
			AEDisposeDesc(theDesc);
			Py_DECREF(result);
			return NULL;
		}
		err = PyList_Append(result, itemObj);
		if (err) {
			Py_DECREF(itemObj);
			Py_DECREF(result);
			return NULL;
		}
	}
	return result;
}
Example #6
0
void ObjectTraverse(const AEDescList *object)
{
	static int recurse=0;
	long count;
	AEKeyword keyword;
	DescType data_desc;
	MacSize data_size;
	char buffer[1024];
	OSStatus err;
	if (noErr == AECountItems(object, &count))
	{
		for (int i = 1; i <= count; i++)	// AERecord starts at index 1
		{
			err = AESizeOfNthItem(object, i, &data_desc, &data_size);
			if (noErr == err)
			{
				err = AEGetNthPtr(object, i, data_desc, &keyword, &data_desc, buffer, 1024, &data_size);
				if (logfile)
				{
					long r;
					for (r = 0; r < recurse; r++)
						fprintf(logfile,"  ");

					fprintf(logfile,"key:'%c%c%c%c' desc:'%c%c%c%c' size: %ld", FCC_TO_CHARS(keyword), FCC_TO_CHARS(data_desc), data_size);
					if (err == noErr) {
						if (data_size == 4) {
							int val = *((int*) buffer);
							if ((data_desc == typeSInt32) || (data_desc == typeUInt32))
								fprintf(logfile," value: %d", val);
							if ((data_desc == typeSInt32) || (data_desc == typeUInt32))
								fprintf(logfile," value:'%c%c%c%c'", FCC_TO_CHARS(val));
						}
					}
					fprintf(logfile,"\r");
				}
				if ((err == noErr) && ((data_desc == cObjectSpecifier) || (data_desc == cAEList) || (data_desc == typeAERecord))) {
					AEDesc obj2;
					err = AEGetNthDesc(object, i, data_desc, &keyword, &obj2);
					if (err == noErr) {
						recurse++;
						ObjectTraverse(&obj2);
						recurse--;
					}
				}
			}
		}
	}
}
Example #7
0
static VALUE
__rbosa_elementlist_get (VALUE self, long index, AEKeyword *keyword)
{
    OSErr       error;
    AEDesc      desc;

    error = AEGetNthDesc ((AEDescList *)rbosa_element_aedesc (self),
                          index + 1,
                          typeWildCard,
                          keyword,
                          &desc);
    
    if (error != noErr)
        rb_raise (rb_eRuntimeError, "Cannot get desc at index %d : %s (%d)", 
                  index, error_code_to_string (error), error);

    return rbosa_element_make (cOSAElement, &desc, rb_ivar_get (self, sApp));
}
Example #8
0
/*----------------------------------------------------------------------------
	GetPropertyFromList 

----------------------------------------------------------------------------*/
void AEGenericClass::GetPropertyFromList(				DescType			desiredClass,
												const AEDesc*		containerToken,
												DescType			containerClass,
												DescType			keyForm,
												const AEDesc*		keyData,
												AEDesc*			resultToken)
{
	OSErr		err		= noErr;
	long			itemNum;
	long			numItems;
	DescType		keyword;
	
	err = AECountItems((AEDescList*)containerToken, &numItems);
	ThrowIfOSErr(err);
		
	for (itemNum = 1; itemNum <= numItems; itemNum++)
	{
		StAEDesc		srcItem;
		StAEDesc		dstItem;
		
		err = AEGetNthDesc(containerToken, itemNum, typeWildCard, &keyword, &srcItem);
		ThrowIfOSErr(err);
		
		if (AEListUtils::TokenContainsTokenList(&srcItem) == false)
		{
			GetPropertyFromObject(desiredClass, &srcItem, containerClass, keyForm, keyData, &dstItem);
		}
		else
		{
			err = AECreateList(nil, 0, false, &dstItem);
			ThrowIfOSErr(err);
			
			GetPropertyFromList(desiredClass, &srcItem, containerClass, keyForm, keyData, &dstItem);
		}

		err = AEPutDesc(resultToken, itemNum, &dstItem);
		ThrowIfOSErr(err);
	}
	
}
static OSStatus CreateCFArrayFromAEDescList(
	const AEDescList *	descList, 
	CFArrayRef *		itemsPtr
)
	// This routine's input is an AEDescList that contains replies 
	// from the "properties of every login item" event.  Each element 
	// of the list is an AERecord with two important properties, 
	// "path" and "hidden".  This routine creates a CFArray that 
	// corresponds to this list.  Each element of the CFArray 
	// contains two properties, kLIAEURL and 
	// kLIAEHidden, that are derived from the corresponding 
	// AERecord properties.
	//
	// On entry, descList must not be NULL
	// On entry,  itemsPtr must not be NULL
	// On entry, *itemsPtr must be NULL
	// On success, *itemsPtr will be a valid CFArray
	// On error, *itemsPtr will be NULL
{
	OSStatus			err;
	CFMutableArrayRef	result;
	long				itemCount;
	long				itemIndex;
	AEKeyword			junkKeyword;
	DescType			junkType;
	Size				junkSize;
	
	assert( itemsPtr != NULL);
	assert(*itemsPtr == NULL);

	result = NULL;
	
	// Create a place for the result.
	
    err = noErr;
    result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    if (result == NULL) {
        err = coreFoundationUnknownErr;
    }
	
	// For each element in the descriptor list...
	
	if (err == noErr) {
		err = AECountItems(descList, &itemCount);
	}
	if (err == noErr) {
		for (itemIndex = 1; itemIndex <= itemCount; itemIndex++) {
		  if (itemIndex == 4) {
			  int notused = 0;
				notused++;
			}
			AERecord 			thisItem;
			UInt8 				thisPath[1024];
			Size				thisPathSize;
			FSRef				thisItemRef;
			CFURLRef			thisItemURL;
			Boolean				thisItemHidden;
			CFDictionaryRef		thisItemDict;
			
			thisItem = kAENull;
			thisItemURL = NULL;
			thisItemDict = NULL;
			
			// Get this element's AERecord.
			
			err = AEGetNthDesc(descList, itemIndex, typeAERecord, &junkKeyword, &thisItem);

			if (err != noErr) {
			  err = noErr;
				continue;
			}

			// Extract the path and create a CFURL.

			if (err == noErr) {
				err = AEGetKeyPtr(
					&thisItem, 
					propPath, 
					typeUTF8Text, 
					&junkType, 
					thisPath, 
					sizeof(thisPath) - 1, 		// to ensure that we can always add null terminator
					&thisPathSize
				);
			}
			
			if (err == noErr) {
				thisPath[thisPathSize] = 0;
				
				err = FSPathMakeRef(thisPath, &thisItemRef, NULL);
				
				if (err == noErr) {
					thisItemURL = CFURLCreateFromFSRef(NULL, &thisItemRef);
				} else {
					err = noErr;			// swallow error and create an imprecise URL
					
					thisItemURL = CFURLCreateFromFileSystemRepresentation(
						NULL,
						thisPath,
						thisPathSize,
						false
					);
				}
				if (thisItemURL == NULL) {
					err = coreFoundationUnknownErr;
				}
			}
			
			// Extract the hidden flag.
			
			if (err == noErr) {
				err = AEGetKeyPtr(
					&thisItem, 
					propHidden, 
					typeBoolean, 
					&junkType, 
					&thisItemHidden, 
					sizeof(thisItemHidden),
					&junkSize
				);
                
                // Work around <rdar://problem/4052117> by assuming that hidden 
                // is false if we can't get its value.
                
                if (err != noErr) {
                    thisItemHidden = false;
                    err = noErr;
                }
			}

			// Create the CFDictionary for this item.
			
			if (err == noErr) {
				CFStringRef keys[2];
				CFTypeRef	values[2];
				
				keys[0] = kLIAEURL;
				keys[1] = kLIAEHidden;
				
				values[0] = thisItemURL;
				values[1] = (thisItemHidden ? kCFBooleanTrue : kCFBooleanFalse);

				thisItemDict = CFDictionaryCreate(
					NULL,
					(const void **) keys,
					values,
					2,
					&kCFTypeDictionaryKeyCallBacks,
					&kCFTypeDictionaryValueCallBacks
				);
				if (thisItemDict == NULL) {
					err = coreFoundationUnknownErr;
				}
			}
			
			// Add it to the results array.
			
			if (err == noErr) {
				CFArrayAppendValue(result, thisItemDict);
			}
						
			AEDisposeDescQ(&thisItem);
			CFQRelease(thisItemURL);
			CFQRelease(thisItemDict);
						
			if (err != noErr) {
				break;
			}
		}
	}

	// Clean up.
	
	if (err != noErr) {
		CFQRelease(result);
		result = NULL;
	}
	*itemsPtr = result;
	assert( (err == noErr) == (*itemsPtr != NULL) );

	return err;
}
Example #10
0
void userActionCallback ( NavCBRecPtr callBackParms ) { 


    OSStatus err;
    long int n;
    NavReplyRecord * nReply = new NavReplyRecord;
    err = NavDialogGetReply ( callBackParms->context, nReply );
    if ( err != noErr ) {
        NavDisposeReply( nReply );
        return;
    } 

    NavUserAction userAction; 
    userAction = NavDialogGetUserAction( callBackParms->context );

    switch ( userAction ) { 
    case kNavUserActionOpen:

        AECountItems( &(nReply->selection), &n ) ;

        if ( n != 0 ) { 
            AEKeyword aeKey;
            AEDesc record;
            FSRef fref;
            char newfilename[512];
            openfD = new fileData();
            fileData * newfD = openfD;
            for ( int i = 0; i < n ; i++ ) { 
                if ( i != 0 ) { 
                                    newfD->next = new fileData();
                                    newfD = newfD->next;
                }                

                AEGetNthDesc (&(nReply->selection), i+1, typeFSRef, &aeKey, &record );
                err = AEGetDescData( &record, ( void * )( &fref ), sizeof( FSRef ) );      
                FSRefMakePath( &fref, (UInt8*)newfilename, 512);
                fprintf(stderr, "open: %s\n", newfilename );
                newfD->fileName = newfilename;
                newfD->isDir = false;
            }
        }

        break;
    case kNavUserActionSaveAs:

        AECountItems( &(nReply->selection), &n ) ;

        if ( n != 0 ) { 
            AEKeyword aeKey;
            AEDesc record;
            FSRef fref;
            char newfilename[512];
            char fileSaveName[512];
            savefD = new fileData();
            for ( int i = 0; i < n ; i++ ) { 
                AEGetNthDesc (&(nReply->selection), i+1, typeFSRef, &aeKey, &record );
                err = AEGetDescData( &record, ( void * )( &fref ), sizeof( FSRef ) );      
                FSRefMakePath( &fref, (UInt8*)newfilename, 512);
                fprintf(stderr, "save: %s\n", newfilename );
                savefD->fileName = newfilename;
                savefD->isDir = false;

                const char * fname  = CFStringGetCStringPtr( nReply->saveFileName, kCFStringEncodingASCII );
                if ( fname ) {
                    fprintf(stderr, "file is %s\n", fname);
                    savefD->fileName += "/";
                    savefD->fileName += fname;
                }
                else { 
                    CFStringGetCString ( nReply->saveFileName, (char*)fileSaveName, 512, kCFStringEncodingASCII );
                    savefD->fileName += "/";
                    savefD->fileName += fileSaveName;
                    fprintf(stderr, "no filename given\n");
                }

            }
        }

        break;

    }
    NavDisposeReply( nReply );
    
}
Example #11
0
// This routine's input is an AEDescList that contains replies
// from the "properties of every login item" event.  Each element
// of the list is an AERecord with two important properties,
// "path" and "hidden".  This routine creates a CFArray that
// corresponds to this list.  Each element of the CFArray
// contains two properties, kLIAEURL and
// kLIAEHidden, that are derived from the corresponding
// AERecord properties.
//
// On entry, descList must not be NULL
// On entry,  itemsPtr must not be NULL
// On entry, *itemsPtr must be NULL
// On success, *itemsPtr will be a valid CFArray
// On error, *itemsPtr will be NULL
static OSStatus CreateCFArrayFromAEDescList(const AEDescList *descList, CFArrayRef *itemsPtr) {
  if (!descList || !itemsPtr) return paramErr;
  check(*itemsPtr == NULL);

  // Create a place for the result.
  OSStatus err = noErr;
  CFMutableArrayRef result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
  if (result == NULL)
    err = coreFoundationUnknownErr;

  // For each element in the descriptor list...
  long itemCount;
  if (err == noErr)
    err = AECountItems(descList, &itemCount);

  if (err == noErr) {
    for (long itemIndex = 1; itemIndex <= itemCount; itemIndex++) {
      UInt8 thisPath[1024];
      Size thisPathSize;
      FSRef thisItemRef;
      CFURLRef thisItemURL;
      Boolean thisItemHidden;
      CFDictionaryRef thisItemDict;
      AERecord thisItem = WBAEEmptyDesc();

      thisItemURL = NULL;
      thisItemDict = NULL;

      // Get this element's AERecord.
      AEKeyword junkKeyword;
      err = AEGetNthDesc(descList, itemIndex, typeAERecord, &junkKeyword, &thisItem);

      // Extract the path and create a CFURL.
      if (err == noErr) {
        err = AEGetKeyPtr(&thisItem,
                          propPath, typeUTF8Text,
                          NULL, thisPath,
                          sizeof(thisPath) - 1, 		// to ensure that we can always add null terminator
                          &thisPathSize);
      }
      if (err == noErr) {
        thisPath[thisPathSize] = 0;
        /* resolve symlink */
        err = FSPathMakeRef(thisPath, &thisItemRef, NULL);

        if (err == noErr) {
          thisItemURL = CFURLCreateFromFSRef(NULL, &thisItemRef);
        } else {
          err = noErr;			// swallow error and create an imprecise URL

          thisItemURL = CFURLCreateFromFileSystemRepresentation(NULL,
                                                                thisPath,
                                                                thisPathSize,
                                                                false);
        }
        if (thisItemURL == NULL) {
          err = coreFoundationUnknownErr;
        }
      }

      // Extract the hidden flag.
      if (err == noErr) {
        err = AEGetKeyPtr(&thisItem,
                          propHidden, typeBoolean,
                          NULL, &thisItemHidden,
                          sizeof(thisItemHidden), NULL);

        // Work around <rdar://problem/4052117> by assuming that hidden
        // is false if we can't get its value.
        if (err != noErr) {
          thisItemHidden = false;
          err = noErr;
        }
      }

      // Create the CFDictionary for this item.
      if (err == noErr) {
        CFStringRef keys[2];
        CFTypeRef values[2];

        keys[0] = kWBLoginItemURL;
        keys[1] = kWBLoginItemHidden;

        values[0] = thisItemURL;
        values[1] = (thisItemHidden ? kCFBooleanTrue : kCFBooleanFalse);

        thisItemDict = CFDictionaryCreate(kCFAllocatorDefault,
                                          (const void **) keys, values, 2,
                                          &kCFTypeDictionaryKeyCallBacks,
                                          &kCFTypeDictionaryValueCallBacks);
        if (thisItemDict == NULL) {
          err = coreFoundationUnknownErr;
        }
      }

      // Add it to the results array.
      if (err == noErr) {
        CFArrayAppendValue(result, thisItemDict);
      }

      WBAEDisposeDesc(&thisItem);
      if (thisItemURL) CFRelease(thisItemURL);
      if (thisItemDict) CFRelease(thisItemDict);

      if (err != noErr) {
        break;
      }
    }
  }

  // Clean up.
  if (err != noErr) {
    if (result) CFRelease(result);
    result = NULL;
  }
  *itemsPtr = result;
  check( (err == noErr) == (*itemsPtr != NULL) );

  return err;
}
static pascal void NavEventProc( NavEventCallbackMessage callBackSelector, 
                                NavCBRecPtr callBackParms, void* callBackUD )
{
    OurDialogData *dialogDataP = (OurDialogData*)callBackUD;
    OSStatus 	err = noErr;		        
	
    switch( callBackSelector )
	{
		case kNavCBUserAction:
		{
			NavReplyRecord 	reply;
			NavUserAction 	userAction = 0;
			
			if ((err = NavDialogGetReply( callBackParms->context, &reply )) == noErr )
			{
			OSStatus tempErr;
			userAction = NavDialogGetUserAction( callBackParms->context );
					
			switch( userAction )
			{
				case kNavUserActionOpen:
				{	
					long count = 0;
					short index;
					err = AECountItems( &reply.selection, &count );
					for ( index = 1; index <= count; index++ )
					{
						AEKeyword 	keyWord;
						AEDesc		theDesc;
						if (( err = AEGetNthDesc( &reply.selection, index, typeWildCard, &keyWord, &theDesc )) == noErr )
						{
							FSRef 	fileRef;
							GetFSRefFromAEDesc(&theDesc, &fileRef);
							(void)doTheFile( fileRef );
							AEDisposeDesc( &theDesc );
						}
					}
					EnableMenuCommand(NULL, kHICommandOpen);
				}
				break;
											
				case kNavUserActionCancel:
					//..
					break;
							
				case kNavUserActionNewFolder:
					//..
					break;
			}
				  
			tempErr = NavDisposeReply( &reply );
			if(!err)
				err = tempErr;
				}
				break;
		}
				
		case kNavCBTerminate:
			if( dialogDataP != NULL )
			{
				if(dialogDataP->dialogRef)
					NavDialogDispose(dialogDataP->dialogRef );
				
				dialogDataP->dialogRef = NULL;
				free(dialogDataP);
			}
			
		break;
	}
}
Example #13
0
static OSErr aplEventHdlr(const AppleEvent *thisEvt, AppleEvent *thisReply, SInt32 iRefCon)
{
    AEKeyword aeListKeyword;
    AEDesc aeContents, aeSubDesc;
    SInt32 iAEListLen, i;
    FSSpec fileSpec;
    FSRef fileRef;
    OSErr iErr;
    bool bOK;
    
    switch (iRefCon)
    {
        case FOUR_CHAR_CODE('PREF'):
            if (!isPrefsWinVisible())  {  showPrefsWin();  }
            return noErr;
            
        case FOUR_CHAR_CODE('QUIT'):
            return errAEEventNotHandled;
            
        case FOUR_CHAR_CODE('OPEN'):

            if (noErr == (iErr = AEGetParamDesc(thisEvt, keyDirectObject, typeFSRef, &aeContents)))
            {
                /* Direct FSR case (usual for OS X) */

                if (noErr != (iErr = AEGetDescData(&aeContents, &fileRef, sizeof(FSRef))))
                {
                    AEDisposeDesc(&aeContents);
                    fprintf(stderr, "aplEventHdlr() - AEGetDescData() failed (FSRef case), returning %lu!\n", (unsigned long) iErr);
                    return noErr;
                }

                attemptOpen(&fileRef);	/* See FroggCtrl.cpp */

                AEDisposeDesc(&aeContents);
                return noErr;
            }

            if (iErr != errAECoercionFail)
            {
                fprintf(stderr, "aplEventHdlr() - AEGetParamDesc(typeFSRef) returned %lu, instead of noErr or errAECoercionFail!\n", (unsigned long) iErr);
                return noErr;
            }
            else if (noErr == (iErr = AEGetParamDesc(thisEvt, keyDirectObject, typeFSS, &aeContents)))
            {
                /* Two-step FSS case (OS9 and Folders) */

                if (noErr != (iErr = AEGetDescData(&aeContents, &fileSpec, sizeof(FSSpec))))
                {
                    AEDisposeDesc(&aeContents);
                    fprintf(stderr, "aplEventHdlr() - AEGetDescData() failed (FSSpec case), returning %lu!\n", (unsigned long) iErr);
                    return noErr;
                }

                if (noErr != (iErr = FSpMakeFSRef(&fileSpec, &fileRef)))
                {
                    AEDisposeDesc(&aeContents);
                    fprintf(stderr, "aplEventHdlr() - FSpMakeFSRef() failed (FSSpec case), returning %lu!\n", (unsigned long) iErr);
                    return noErr;
                }
                
                attemptOpen(&fileRef);	/* See FroggCtrl.cpp */

                AEDisposeDesc(&aeContents);
                return noErr;
            }

            if (iErr != errAECoercionFail)
            {
                fprintf(stderr, "aplEventHdlr() - AEGetParamDesc(typeFSS) returned %lu, instead of noErr or errAECoercionFail!\n", (unsigned long) iErr);
                return noErr;
            }            
            else if (noErr == (iErr = AEGetParamDesc(thisEvt, keyDirectObject, typeAEList, &aeContents)))
            {
                /* Last resort: we might have gotten a whole list of files. */
                /* Find the first FSRef or FSSpec descriptor in the list if */
                /* any, and open that as a single file.                     */

                if (noErr != (iErr = AECountItems(&aeContents, &iAEListLen)))
                {
                    AEDisposeDesc(&aeContents);
                    fprintf(stderr, "aplEventHdlr() - AECountItems() failed (AEList case), returning %lu!\n", (unsigned long) iErr);
                    return noErr;
                }

                bOK = false;
                
                for (i = 0; i < iAEListLen; i++)
                {
                    if (noErr == (iErr = AEGetNthDesc(&aeContents, i, typeFSRef, &aeListKeyword, &aeSubDesc)))
                    {
                        /* Found an FSRef object inside the list. */

                        if (noErr != (iErr = AEGetDescData(&aeSubDesc, &fileRef, sizeof(FSRef))))
                        {
                            AEDisposeDesc(&aeSubDesc);
                            fprintf(stderr, "aplEventHdlr() - AEGetDescData() failed (AEList->FSRef case), returning %lu!\n", (unsigned long) iErr);
                            break;
                        }

                        bOK = true;
                        attemptOpen(&fileRef);	/* See FroggCtrl.cpp */
                        AEDisposeDesc(&aeSubDesc);
                        break;
                    }
                    else if (noErr == (iErr = AEGetNthDesc(&aeContents, i, typeFSS, &aeListKeyword, &aeSubDesc)))
                    {
                        /* Found an FSSpec object inside the list. */

                        if (noErr != (iErr = AEGetDescData(&aeSubDesc, &fileSpec, sizeof(FSSpec))))
                        {
                            AEDisposeDesc(&aeSubDesc);
                            fprintf(stderr, "aplEventHdlr() - AEGetDescData() failed (AEList->FSSpec case), returning %lu!\n", (unsigned long) iErr);
                            break;
                        }

                        if (noErr != (iErr = FSpMakeFSRef(&fileSpec, &fileRef)))
                        {
                            AEDisposeDesc(&aeSubDesc);
                            fprintf(stderr, "aplEventHdlr() - FSpMakeFSRef() failed (AEList->FSSpec case), returning %lu!\n", (unsigned long) iErr);
                            break;
                        }

                        bOK = true;
                        attemptOpen(&fileRef);	/* See FroggCtrl.cpp */
                        AEDisposeDesc(&aeSubDesc);
                        break;
                    }
                }
                
                AEDisposeDesc(&aeContents);
                return (bOK ? ((OSErr) noErr) : ((OSErr) errAEEventNotHandled));
            }

            if (iErr != errAECoercionFail)
            {
                fprintf(stderr, "aplEventHdlr() - AEGetParamDesc(typeAEList) returned %lu, instead of noErr or errAECoercionFail!\n", (unsigned long) iErr);
                return noErr;
            }            
            else
            {
                /* Umm... what the hell were we sent? */
                return errAEEventNotHandled;
            }
            
        default:
            return errAEEventNotHandled; 
    }
}
OSStatus BeginSave( NavDialogRef inDialog, NavReplyRecord* outReply, FSRef* outFileRef )
{
    OSStatus status = paramErr;
    AEDesc		dirDesc;
    AEKeyword	keyword;
    CFIndex		len;

    require( outReply, Return );
    require( outFileRef, Return );

    status = NavDialogGetReply( inDialog, outReply );
    nrequire( status, Return );

    status = AEGetNthDesc( &outReply->selection, 1, typeWildCard, &keyword, &dirDesc );
    nrequire( status, DisposeReply );

    len = CFStringGetLength( outReply->saveFileName );

    if ( dirDesc.descriptorType == typeFSRef )
    {
        const UInt32	kMaxNameLen = 255;
        FSRef		dirRef;
        UniChar		name[ kMaxNameLen ];

        if ( len > kMaxNameLen )
        {
            len = kMaxNameLen;
        }

        status = AEGetDescData( &dirDesc, &dirRef, sizeof( dirRef ));
        nrequire( status, DisposeDesc );

        CFStringGetCharacters( outReply->saveFileName, CFRangeMake( 0, len ), &name[0] );

        status = FSMakeFSRefUnicode( &dirRef, len, &name[0], GetApplicationTextEncoding(), outFileRef );
        if (status == fnfErr )
        {
            // file is not there yet - create it and return FSRef
            status = FSCreateFileUnicode( &dirRef, len, &name[0], 0, NULL, outFileRef, NULL );
        }
        else
        {
            // looks like file is there. Just make sure there is no error
            nrequire( status, DisposeDesc );
        }
    }
    else if ( dirDesc.descriptorType == typeFSS )
    {
        FSSpec	theSpec;
        status = AEGetDescData( &dirDesc, &theSpec, sizeof( FSSpec ));
        nrequire( status, DisposeDesc );

        if ( CFStringGetPascalString( outReply->saveFileName, &(theSpec.name[0]),
                                      sizeof( StrFileName ), GetApplicationTextEncoding()))
        {
            status = FSpMakeFSRef(&theSpec, outFileRef);
            nrequire( status, DisposeDesc );
            status = FSpCreate( &theSpec, 0, 0, smSystemScript );
            nrequire( status, DisposeDesc );
        }
        else
        {
            status = bdNamErr;
            nrequire( status, DisposeDesc );
        }
    }

DisposeDesc:
    AEDisposeDesc( &dirDesc );

DisposeReply:
    if ( status != noErr )
    {
        NavDisposeReply( outReply );
    }

Return:
    return status;
}