Boolean AEComparisons::CompareEnumeration(DescType oper, const AEDesc *desc1, const AEDesc *desc2) { OSErr err = noErr; Boolean result = false; long lhs; long rhs; StAEDesc charDesc; // Make each number is a long integer (in case it's a short integer or other integer type) // before extracting the data */ err = AECoerceDesc(desc1, typeChar, &charDesc); ThrowIfOSErr(err); lhs = **(long **)(charDesc.dataHandle); AEDisposeDesc(&charDesc); err = AECoerceDesc(desc2, typeChar, &charDesc); ThrowIfOSErr(err); rhs = **(long **)charDesc.dataHandle; AEDisposeDesc(&charDesc); switch (oper) { case kAEEquals: result = (lhs == rhs); // equality is the only test that makes sense for enumerators break; default: ThrowOSErr(errAEBadTestKey); } return result; }
Boolean AEComparisons::CompareInteger(DescType oper, const AEDesc *desc1, const AEDesc *desc2) { OSErr err = noErr; Boolean result = false; long lhs; long rhs; StAEDesc longDesc; // Make each number is a long integer (in case it's a short integer or other integer type) // before extracting the data */ err = AECoerceDesc(desc1, typeLongInteger, &longDesc); ThrowIfOSErr(err); lhs = **(long **)(longDesc.dataHandle); AEDisposeDesc(&longDesc); err = AECoerceDesc(desc2, typeLongInteger, &longDesc); ThrowIfOSErr(err); rhs = **(long **)longDesc.dataHandle; AEDisposeDesc(&longDesc); switch (oper) { case kAEEquals: result = (lhs == rhs); break; case kAELessThan: result = (lhs < rhs); break; case kAELessThanEquals: result = (lhs <= rhs); break; case kAEGreaterThan: result = (lhs > rhs); break; case kAEGreaterThanEquals: result = (lhs >= rhs); break; default: ThrowOSErr(errAEBadTestKey); } return result; }
Boolean nav_file_filter(AEDesc *theItem,void *info,void *callBackUD,NavFilterModes filterMode) { char *c,filename[256]; NavFileOrFolderInfo *filefolder; AEDesc desc; HFSUniStr255 uniname; CFStringRef cfstr; FSRef fref; if ((theItem->descriptorType!=typeFSS) && (theItem->descriptorType!=typeFSRef)) return(FALSE); filefolder=(NavFileOrFolderInfo*)info; if (filefolder->isFolder) return(TRUE); AECoerceDesc(theItem,typeFSRef,&desc); AEGetDescData(&desc,(void*)&fref,sizeof(FSRef)); AEDisposeDesc(&desc); FSGetCatalogInfo(&fref,kFSCatInfoNone,NULL,&uniname,NULL,NULL); cfstr=CFStringCreateWithCharacters(kCFAllocatorDefault,uniname.unicode,uniname.length); CFStringGetCString(cfstr,filename,256,kCFStringEncodingMacRoman); CFRelease(cfstr); c=strchr(filename,'.'); if (c==NULL) return(FALSE); return(strcasecmp((c+1),nav_filetype)==0); }
pascal OSErr MoreAEGetCFStringFromDescriptor(const AEDesc* pAEDesc, CFStringRef* pCFStringRef) { AEDesc uniAEDesc = {typeNull, NULL}; OSErr anErr; if (NULL == pCFStringRef) return paramErr; anErr = AECoerceDesc(pAEDesc, typeUnicodeText, &uniAEDesc); if (noErr == anErr) { if (typeUnicodeText == uniAEDesc.descriptorType) { Size bufSize = AEGetDescDataSize(&uniAEDesc); Ptr buf = NewPtr(bufSize); if ((noErr == (anErr = MemError())) && (NULL != buf)) { anErr = AEGetDescData(&uniAEDesc, buf, bufSize); if (noErr == anErr) *pCFStringRef = CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*) buf, bufSize / (Size) sizeof(UniChar)); DisposePtr(buf); } } MoreAEDisposeDesc(&uniAEDesc); } return (anErr); }//end MoreAEGetCFStringFromDescriptor
static VALUE rbosa_element_data (int argc, VALUE *argv, VALUE self) { VALUE coerce_type; AEDesc coerced_desc; AEDesc * desc; OSErr error; void * data; Size datasize; VALUE retval; bool to_4cc; rb_scan_args (argc, argv, "01", &coerce_type); to_4cc = false; desc = rbosa_element_aedesc (self); if (!NIL_P (coerce_type)) { FourCharCode code; code = RVAL2FOURCHAR (coerce_type); error = AECoerceDesc (desc, code, &coerced_desc); if (error != noErr) rb_raise (rb_eRuntimeError, "Cannot coerce desc to type %s : %s (%d)", RVAL2CSTR (coerce_type), error_code_to_string (error), error); desc = &coerced_desc; to_4cc = code == 'type'; } datasize = AEGetDescDataSize (desc); data = (void *)malloc (datasize); if (data == NULL) rb_fatal ("cannot allocate memory"); error = AEGetDescData (desc, data, datasize); if (error == noErr) { if (to_4cc) *(DescType*)data = CFSwapInt32HostToBig (*(DescType*)data); retval = rb_str_new (data, datasize); } else { retval = Qnil; } if (!NIL_P (coerce_type)) AEDisposeDesc (&coerced_desc); free (data); if (error != noErr) rb_raise (rb_eRuntimeError, "Cannot get desc data : %s (%d)", error_code_to_string (error), error); return retval; }
/*---------------------------------------------------------------------------- CompareObjectsCallback ----------------------------------------------------------------------------*/ pascal OSErr AECoreClass::CompareObjectsCallback( DescType comparisonOperator, // operator to use const AEDesc * object, // left-hand side const AEDesc * descriptorOrObject, // right-hand side Boolean * result) { OSErr err = noErr; try { OSErr err = noErr; StAEDesc desc1; StAEDesc desc2; // This first AEDesc is a token to a specific object, so we resolve it. AECoreClass::GetAECoreHandler()->ExtractData(object, &desc1); // A second AEDesc is either a token to another object or an AEDesc containing literal data. AECoreClass::GetAECoreHandler()->ExtractData(descriptorOrObject, &desc2); // Make sure the data type extracted from the second AEDesc is the same as the // data specified by the first AEDesc. if (desc1.descriptorType != desc2.descriptorType) { StAEDesc temp; // Create a temporary duplicate of desc2 and coerce it to the // requested type. This could call a coercion handler you have // installed. If there are no errors, stuff the coerced value back into desc2 err = AEDuplicateDesc(&desc2, &temp); ThrowIfOSErr(err); desc2.Clear(); err = AECoerceDesc(&temp, desc1.descriptorType, &desc2); ThrowIfOSErr(err); } AEDispatchHandler* handler = AECoreClass::GetDispatchHandlerForClass(desc1.descriptorType); if (handler) handler->CompareObjects(comparisonOperator, &desc1, &desc2, result); else *result = AEComparisons::TryPrimitiveComparison(comparisonOperator, &desc1, &desc2); } catch (OSErr catchErr) { err = catchErr; } catch (...) { err = paramErr; } return err; }
static OSStatus GetFSRefFromAEDesc( AEDesc* fileObject, FSRef* returnRef ) { OSStatus theErr = noErr; AEDesc theDesc; if ((theErr = AECoerceDesc( fileObject, typeFSRef, &theDesc )) == noErr) { theErr = AEGetDescData( &theDesc, returnRef, sizeof ( FSRef ) ); AEDisposeDesc( &theDesc ); } return theErr; }
// does an in-place coercion! void ThrowIfCantCoerce( AEDesc* data, DescType desiredType ) { #if !defined(_PLATFORM_WIN32_) || !defined(PORTING_HACK) if ( data->descriptorType == desiredType ) return ; AEDesc newDesc ; THROW_IF_ERROR( AECoerceDesc( data, desiredType, &newDesc ) ) ; AEDisposeDesc( data ) ; *data = newDesc ; #endif // !defined(_PLATFORM_WIN32_) || !defined(PORTING_HACK) }
pascal Boolean CrossPlatformFilterCallback( AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode ) { OpenUserDataRecPtr data = (OpenUserDataRecPtr) callBackUD ; if (filterMode == kNavFilteringBrowserList) { // We allow navigation to all folders. For files, we check against the current // filter string. // However, packages should be dealt with like files and not like folders. So // check if a folder is a package before deciding what to do. NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*) info ; FSRef fsref; if ( theInfo->isFolder ) { // check bundle bit (using Finder Services - used by OS9 on some bundles) FSCatalogInfo catalogInfo; if (FSGetCatalogInfo (&fsref, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL) != noErr) return true; // Check bundle item (using Launch Services - used by OS-X through info.plist or APP) LSItemInfoRecord lsInfo; if (LSCopyItemInfoForRef(&fsref, kLSRequestBasicFlagsOnly, &lsInfo ) != noErr) return true; // If it's not a bundle, then it's a normal folder and it passes our filter FileInfo *fileInfo = (FileInfo *) catalogInfo.finderInfo; if ( !(fileInfo->finderFlags & kHasBundle) && !(lsInfo.flags & (kLSItemInfoIsApplication | kLSItemInfoIsPackage)) ) return true; } else { AECoerceDesc (theItem, typeFSRef, theItem); if ( AEGetDescData (theItem, &fsref, sizeof (FSRef)) == noErr) { wxString file = wxMacFSRefToPath( &fsref ) ; return CheckFile( file , theInfo->fileAndFolder.fileInfo.finderInfo.fdType , data ) ; } } } return true; }
static PyObject *AEDesc_AECoerceDesc(AEDescObject *_self, PyObject *_args) { PyObject *_res = NULL; OSErr _err; DescType toType; AEDesc result; if (!PyArg_ParseTuple(_args, "O&", AE_GetOSType, &toType)) return NULL; _err = AECoerceDesc(&_self->ob_itself, toType, &result); if (_err != noErr) return AE_MacOSError(_err); _res = Py_BuildValue("O&", AE_AEDesc_New, &result); return _res; }
static VALUE __rbosa_insertion_loc_new (VALUE rcv, FourCharCode code) { AEDesc * self_desc; AEDesc rec; AEDesc pos_desc; AEDesc new_desc; self_desc = rbosa_element_aedesc (rcv); AECreateList (NULL, 0, true, &rec); AEPutParamDesc (&rec, keyAEObject, self_desc); AECreateDesc (code, NULL, 0, &pos_desc); AEPutParamPtr (&rec, keyAEPosition, typeEnumerated, &pos_desc, 4); AECoerceDesc (&rec, typeInsertionLoc, &new_desc); AEDisposeDesc (&rec); return rbosa_element_make (cOSAElement, &new_desc, Qnil); }
// A proper object descriptor has 4 parts: // - What class it is // - How it is being identified (in our case an ID number, specified by formUniqueID) // - The identification itself // - The parent of the object OSErr CreateAEDescFromID(unsigned int id_num, DescType object_type, AEDesc* item_desc) { AEDesc item_record; unsigned int form = formUniqueID; OSStatus err; err = AECreateList(NULL, 0, true, &item_record); if (err == noErr) { AERecord * record = &item_record; err = AEPutKeyPtr(record, keyAEDesiredClass, cType, &object_type, sizeof(object_type)); err |= AEPutKeyPtr(record, keyAEContainer, typeNull, NULL, 0); // No parent err |= AEPutKeyPtr(record, keyAEKeyForm, cEnumeration, &form, sizeof(form)); err |= AEPutKeyPtr(record, keyAEKeyData, typeUInt32, &id_num, sizeof(id_num)); if (err == noErr) { err = AECoerceDesc(record, typeObjectSpecifier, item_desc); } AEDisposeDesc(&item_record); } return err; }
static PyObject *AEDesc_AECoerceDesc(AEDescObject *_self, PyObject *_args) { PyObject *_res = NULL; OSErr _err; DescType toType; AEDesc result; #ifndef AECoerceDesc PyMac_PRECHECK(AECoerceDesc); #endif if (!PyArg_ParseTuple(_args, "O&", PyMac_GetOSType, &toType)) return NULL; _err = AECoerceDesc(&_self->ob_itself, toType, &result); if (_err != noErr) return PyMac_Error(_err); _res = Py_BuildValue("O&", AEDescX_New, &result); return _res; }
pascal Boolean CrossPlatformFilterCallback( AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode ) { bool display = true; OpenUserDataRecPtr data = (OpenUserDataRecPtr) callBackUD ; if (filterMode == kNavFilteringBrowserList) { NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*) info ; if ( !theInfo->isFolder ) { AECoerceDesc (theItem, typeFSRef, theItem); FSRef fsref ; if ( AEGetDescData (theItem, &fsref, sizeof (FSRef)) == noErr ) { #if 1 memcpy( &fsref , *theItem->dataHandle , sizeof(FSRef) ) ; wxString file = wxMacFSRefToPath( &fsref ) ; display = CheckFile( file , theInfo->fileAndFolder.fileInfo.finderInfo.fdType , data ) ; #else CFStringRef itemUTI = NULL; OSStatus status = LSCopyItemAttribute (&fsref, kLSRolesAll, kLSItemContentType, (CFTypeRef*)&itemUTI); if (status == noErr) { display = UTTypeConformsTo (itemUTI, CFSTR("public.text") ); CFRelease (itemUTI); } #endif } } } return display; }
Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) { Boolean result = true; ELoadFilter filter = *((ELoadFilter*) callBackUD); OSStatus error = noErr; if (filterMode == kNavFilteringBrowserList && filter != FFLOAD_ALL && (theItem->descriptorType == typeFSRef || theItem->descriptorType == typeFSS)) { // navInfo is only valid for typeFSRef and typeFSS NavFileOrFolderInfo *navInfo = (NavFileOrFolderInfo*) info; if (!navInfo->isFolder) { AEDesc desc; error = AECoerceDesc(theItem, typeFSRef, &desc); if (error == noErr) { FSRef fileRef; error = AEGetDescData(&desc, &fileRef, sizeof(fileRef)); if (error == noErr) { LSItemInfoRecord fileInfo; error = LSCopyItemInfoForRef(&fileRef, kLSRequestExtension | kLSRequestTypeCreator, &fileInfo); if (error == noErr) { if (filter == FFLOAD_IMAGE) { if (fileInfo.filetype != 'JPEG' && fileInfo.filetype != 'JPG ' && fileInfo.filetype != 'BMP ' && fileInfo.filetype != 'TGA ' && fileInfo.filetype != 'BMPf' && fileInfo.filetype != 'TPIC' && fileInfo.filetype != 'PNG ' && (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("jpeg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && CFStringCompare(fileInfo.extension, CFSTR("jpg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && CFStringCompare(fileInfo.extension, CFSTR("bmp"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && CFStringCompare(fileInfo.extension, CFSTR("tga"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && CFStringCompare(fileInfo.extension, CFSTR("png"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) ) { result = false; } } else if (filter == FFLOAD_WAV) { if (fileInfo.filetype != 'WAVE' && fileInfo.filetype != 'WAV ' && (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("wave"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && CFStringCompare(fileInfo.extension, CFSTR("wav"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) ) { result = false; } } else if (filter == FFLOAD_ANIM) { if (fileInfo.filetype != 'BVH ' && (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("bvh"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) ) { result = false; } } #ifdef _CORY_TESTING else if (filter == FFLOAD_GEOMETRY) { if (fileInfo.filetype != 'SLG ' && (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("slg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) ) { result = false; } } #endif else if (filter == FFLOAD_SLOBJECT) { llwarns << "*** navOpenFilterProc: FFLOAD_SLOBJECT NOT IMPLEMENTED ***" << llendl; } else if (filter == FFLOAD_RAW) { if (fileInfo.filetype != '\?\?\?\?' && (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("raw"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) ) { result = false; } } if (fileInfo.extension) { CFRelease(fileInfo.extension); } } } AEDisposeDesc(&desc); } } } return result; }
// ----------------------------------------------------------------------------- // AddCommandToAEDescList // ----------------------------------------------------------------------------- static OSStatus AddCommandToAEDescList( ConstStr255Param inCommandString, TextEncoding inEncoding, DescType inDescType, SInt32 inCommandID, MenuItemAttributes inAttributes, UInt32 inModifiers, AEDescList* ioCommandList) { OSStatus theError = noErr; AERecord theCommandRecord = { typeNull, NULL }; printf( "AddCommandToAEDescList: Trying to add an item.\n" ); // create an apple event record for our command theError = AECreateList( NULL, kAEDescListFactorNone, true, &theCommandRecord ); require_noerr( theError, AddCommandToAEDescList_fail ); // stick the command text into the AERecord if ( inCommandString != NULL ) { if ( inDescType == typeChar ) { theError = AEPutKeyPtr( &theCommandRecord, keyAEName, typeChar, &inCommandString[1], StrLength( inCommandString ) ); require_noerr( theError, AddCommandToAEDescList_fail ); } else if ( inDescType == typeStyledText ) { AERecord textRecord; WritingCode writingCode; AEDesc textDesc; theError = AECreateList( NULL, kAEDescListFactorNone, true, &textRecord ); require_noerr( theError, AddCommandToAEDescList_fail ); theError = AEPutKeyPtr( &textRecord, keyAEText, typeChar, &inCommandString[1], StrLength( inCommandString ) ); require_noerr( theError, AddCommandToAEDescList_fail ); RevertTextEncodingToScriptInfo( inEncoding, &writingCode.theScriptCode, &writingCode.theLangCode, NULL ); theError = AEPutKeyPtr( &textRecord, keyAEScriptTag, typeIntlWritingCode, &writingCode, sizeof( writingCode ) ); require_noerr( theError, AddCommandToAEDescList_fail ); theError = AECoerceDesc( &textRecord, typeStyledText, &textDesc ); require_noerr( theError, AddCommandToAEDescList_fail ); theError = AEPutKeyDesc( &theCommandRecord, keyAEName, &textDesc ); require_noerr( theError, AddCommandToAEDescList_fail ); AEDisposeDesc( &textRecord ); } else if ( inDescType == typeIntlText ) { IntlText* intlText; ByteCount size = sizeof( IntlText ) + StrLength( inCommandString ) - 1; // create an IntlText structure with the text and script intlText = (IntlText*) malloc( size ); RevertTextEncodingToScriptInfo( inEncoding, &intlText->theScriptCode, &intlText->theLangCode, NULL ); BlockMoveData( &inCommandString[1], &intlText->theText, StrLength( inCommandString ) ); theError = AEPutKeyPtr( &theCommandRecord, keyAEName, typeIntlText, intlText, size ); free( (char*) intlText ); require_noerr( theError, AddCommandToAEDescList_fail ); } else if ( inDescType == typeUnicodeText ) { CFStringRef str = CFStringCreateWithPascalString( NULL, inCommandString, inEncoding ); if ( str != NULL ) { Boolean doFree = false; CFIndex sizeInChars = CFStringGetLength( str ); CFIndex sizeInBytes = sizeInChars * sizeof( UniChar ); const UniChar* unicode = CFStringGetCharactersPtr( str ); if ( unicode == NULL ) { doFree = true; unicode = (UniChar*) malloc( sizeInBytes ); CFStringGetCharacters( str, CFRangeMake( 0, sizeInChars ), (UniChar*) unicode ); } theError = AEPutKeyPtr( &theCommandRecord, keyAEName, typeUnicodeText, unicode, sizeInBytes ); CFRelease( str ); if ( doFree ) free( (char*) unicode ); require_noerr( theError, AddCommandToAEDescList_fail ); } } else if ( inDescType == typeCFStringRef ) { CFStringRef str = CFStringCreateWithPascalString( NULL, inCommandString, inEncoding ); if ( str != NULL ) { theError = AEPutKeyPtr( &theCommandRecord, keyAEName, typeCFStringRef, &str, sizeof( str ) ); require_noerr( theError, AddCommandToAEDescList_fail ); // do not release the string; the Contextual Menu Manager will release it for us } } } // stick the command ID into the AERecord if ( inCommandID != 0 ) { theError = AEPutKeyPtr( &theCommandRecord, keyContextualMenuCommandID, typeLongInteger, &inCommandID, sizeof( inCommandID ) ); require_noerr( theError, AddCommandToAEDescList_fail ); } // stick the attributes into the AERecord if ( inAttributes != 0 ) { theError = AEPutKeyPtr( &theCommandRecord, keyContextualMenuAttributes, typeLongInteger, &inAttributes, sizeof( inAttributes ) ); require_noerr( theError, AddCommandToAEDescList_fail ); } // stick the modifiers into the AERecord if ( inModifiers != 0 ) { theError = AEPutKeyPtr( &theCommandRecord, keyContextualMenuModifiers, typeLongInteger, &inModifiers, sizeof( inModifiers ) ); require_noerr( theError, AddCommandToAEDescList_fail ); } // stick this record into the list of commands that we are // passing back to the CMM theError = AEPutDesc( ioCommandList, // the list we're putting our command into 0, // stick this command onto the end of our list &theCommandRecord ); // the command I'm putting into the list AddCommandToAEDescList_fail: // clean up after ourself; dispose of the AERecord AEDisposeDesc( &theCommandRecord ); return theError; } // AddCommandToAEDescList
// ----------------------------------------------------------------------------- // SampleCMPluginExamineContext // ----------------------------------------------------------------------------- // The implementation of the ExamineContext test interface function. // static OSStatus SampleCMPluginExamineContext( void* thisInstance, const AEDesc* inContext, AEDescList* outCommandPairs ) { // Sequence the command ids SInt32 theCommandID = 1; SInt32 result; printf( "SampleCMPlugin->SampleCMPluginExamineContext(): instance 0x%x, inContext 0x%x, outCommandPairs 0x%x\n", ( unsigned ) thisInstance, ( const unsigned ) inContext, ( unsigned ) outCommandPairs ); // Verify that we've got an up-to-date CMM verify_noerr( Gestalt( gestaltContextualMenuAttr, &result ) ); if ( ( result & ( 1 << gestaltContextualMenuHasAttributeAndModifierKeys ) ) != 0 ) printf( "SampleCMPlugin: CMM supports Attributes and Modifiers keys\n" ); else printf( "SampleCMPlugin: CMM DOES NOT support Attributes and Modifiers keys\n" ); if ( ( result & ( 1 << gestaltContextualMenuHasUnicodeSupport ) ) != 0 ) printf( "SampleCMPlugin: CMM supports typeUnicodeText and typeCFStringRef\n" ); else printf( "SampleCMPlugin: CMM DOES NOT support typeUnicodeText and typeCFStringRef\n" ); // this is a quick sample that looks for text in the context descriptor // make sure the descriptor isn't null if ( inContext != NULL ) { AEDesc theTextDesc = { typeNull, NULL }; Str15 theDescriptorType; AddCommandToAEDescList( "\pInside SampleCMPlugin!", kTextEncodingMacRoman, typeChar, theCommandID++, 0, 0, outCommandPairs ); AddCommandToAEDescList( "\pキャンセル", kTextEncodingMacJapanese, typeIntlText, theCommandID++, 0, 0, outCommandPairs ); AddCommandToAEDescList( "\p-A separator item", kTextEncodingMacRoman, typeChar, 0, 0, 0, outCommandPairs ); AddCommandToAEDescList( "\p-A non-separator item", kTextEncodingMacRoman, typeChar, theCommandID++, kMenuItemAttrIgnoreMeta, 0, outCommandPairs ); AddCommandToAEDescList( NULL, 0, typeNull, 0, kMenuItemAttrSeparator, 0, outCommandPairs ); AddCommandToAEDescList( NULL, 0, typeNull, 0, 0, 0, outCommandPairs ); AddCommandToAEDescList( "\pキャンセル", kTextEncodingMacJapanese, typeUnicodeText, theCommandID++, 0, 0, outCommandPairs ); // tell the raw type of the descriptor theDescriptorType[0] = 4; *( DescType* )( &theDescriptorType[1] ) = inContext->descriptorType; AddCommandToAEDescList( theDescriptorType, kTextEncodingMacRoman, typeChar, theCommandID++, 0, 0, outCommandPairs ); // try to get text out of the context descriptor; make sure to // coerce it, cuz the app may have passed an object specifier or // styled text, etc. if ( AECoerceDesc( inContext, typeChar, &theTextDesc ) == noErr ) { printf( "SampleCMPluginExamineContext: Able to coerce to text object.\n" ); // add a text only command to our command list AddCommandToAEDescList( "\pWe got text!", kTextEncodingMacRoman, typeChar, theCommandID++, 0, 0, outCommandPairs ); } else { printf( "SampleCMPluginExamineContext: Unable to coerce to text object.\n" ); // add a text only command to our command list AddCommandToAEDescList( "\pCan't Coerce. 8(", kTextEncodingMacRoman, typeChar, theCommandID++, 0, 0, outCommandPairs ); } AEDisposeDesc( &theTextDesc ); // Just for kicks, let's create a submenu for our plugin CreateSampleSubmenu( outCommandPairs ); // Let's also demonstrate dynamic items in a contextual menu CreateSampleDynamicItems( outCommandPairs ); } else { printf( "SampleCMPluginExamineContext: Hey! What's up with the NULL descriptor?\n" ); // we have a null descriptor AddCommandToAEDescList( "\pNULL Descriptor", kTextEncodingMacRoman, typeChar, theCommandID++, 0, 0, outCommandPairs ); } return noErr; }
PPOpenPanel::ReturnCodes PPOpenPanel::runModal() { ReturnCodes result = ReturnCodeCANCEL; OSStatus err = noErr; NavDialogRef theOpenDialog; NavDialogCreationOptions dialogOptions; if ((err = NavGetDefaultDialogCreationOptions(&dialogOptions)) == noErr) { dialogOptions.modality = kWindowModalityAppModal; dialogOptions.windowTitle = CFStringCreateWithCString(NULL, caption, kCFStringEncodingASCII); err = NavCreateChooseFileDialog(&dialogOptions, NULL, NULL, NULL, NULL, NULL, &theOpenDialog); if (theOpenDialog) { err = NavDialogRun(theOpenDialog); NavReplyRecord reply; err = NavDialogGetReply (theOpenDialog, &reply); if (err == noErr) { // retrieve filename AEDesc actualDesc; FSRef fileToOpen; //HFSUniStr255 theFileName; //CFStringRef fileNameCFString; err = AECoerceDesc(&reply.selection, typeFSRef, &actualDesc); err = AEGetDescData(&actualDesc, reinterpret_cast<void*>(&fileToOpen), sizeof(FSRef)); // gib ihm int len = PATH_MAX; char* buffer = new char[PATH_MAX+1]; FSRefMakePath (&fileToOpen, (UInt8*)buffer, len); fileName = buffer; delete[] buffer; result = ReturnCodeOK; NavDisposeReply(&reply); } NavDialogDispose(theOpenDialog); } if (dialogOptions.windowTitle) CFRelease(dialogOptions.windowTitle); } return result; }
boolean coercetolist (tyvaluerecord *val, tyvaluetype type) { /* 4/14/93 dmb: support list <-> record coercion when empty, but don't allow it otherwise 2.1b8 dmb: coercing a list to a record creates a true record 4.1b2 dmb: use stringtolist for string values */ register tyvaluerecord *v = val; register tyvaluetype vtype = (*v).valuetype; hdllistrecord hlist = nil; long size; if (vtype == type) return (true); switch (vtype) { case novaluetype: if (flinhibitnilcoercion) return (false); if (type == listvaluetype) return (makelistvalue (nil, v)); else return (makerecordvalue (nil, false, v)); case externalvaluetype: langbadexternaloperror (badexternaloperationerror, *v); return (false); case listvaluetype: case recordvaluetype: if (!langgetlistsize (v, &size)) return (false); if (size > 0) { langcoerceerror (v, type); return (false); } if (!opnewlist (&hlist, type == recordvaluetype)) return (false); break; case pointvaluetype: { Point pt = swappoint ((*v).data.pointvalue); if (!makeintegerlist (v, type, &pt, 2, &hlist)) return (false); break; } case rgbvaluetype: { RGBColor rgb = **(*v).data.rgbvalue; if (!makeintegerlist (v, type, &rgb, 3, &hlist)) return (false); break; } case rectvaluetype: { Rect r = **(*v).data.rectvalue; if (!makeintegerlist (v, type, &r, 4, &hlist)) return (false); break; } #ifdef MACVERSION case objspecvaluetype: case binaryvaluetype: { AEDesc vdesc, listdesc; OSErr err; boolean fl; if (!coercetobinary (v)) return (false); binarytodesc ((*v).data.binaryvalue, &vdesc); // still in temp stack err = AECoerceDesc (&vdesc, langgettypeid (type), &listdesc); if (err != noErr) { if (err == errAECoercionFail) { coercevalue (v, vtype); /*back to it's original type for the error message*/ langcoerceerror (v, type); } else oserror (err); return (false); } fl = langipcconvertaelist (&listdesc, v); AEDisposeDesc (&listdesc); return (fl); } #endif case stringvaluetype: if (stringtolist (v, type)) return (true); /*else fall through...*/ default: /* create a list containing the item. note that this does not emulate version 4.x's AE functionality, where the value might be coerceable to a list directly. */ if (!opnewlist (&hlist, type == recordvaluetype)) return (false); if (!langpushlistval (hlist, nil, v)) { opdisposelist (hlist); langcoerceerror (v, type); return (false); } break; } disposevaluerecord (*v, true); return (setheapvalue ((Handle) hlist, type, v)); } /*coercetolist*/
pascal void NavEventProc( NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void* callBackUD ) { OurSaveDialogData *dialogDataP = (OurSaveDialogData*)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 kNavUserActionSaveAs: { if ( dialogDataP != NULL ){ AEDesc actualDesc; if ( (err = AECoerceDesc( &reply.selection, typeFSRef, &actualDesc )) == noErr ) { // the coercion succeeded as an FSRef, // so use HFS+ APIs to save the file: err = DoFSRefSave( dialogDataP, &reply, &actualDesc); AEDisposeDesc( &actualDesc ); }else{ // the coercion failed as an FSRef, so get the FSSpec and // save the file /* FSRef's don't exist on systems prior to MacOS 9 so there it is necessary to have a different approach as shown in the Nav Services sample in the CarbonSDK. Since this code is used on MacOS X only, this is not an issue. */ // assert(...) } } 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; } }
OSErr MyAECoerceDescPtr(AEDesc theAEDesc, DescType toType, Ptr dataPtr, Size maximumSize, Size* actualSize) /* this routine plugs a hole that's been nagging at me in the AppleEvents interface. It takes a descriptor and coerces it to a desired type; but instead of returning a descriptor, it returns data in a buffer specified by the caller. INPUTS: theAEDesc descriptor to be coerced toType type to coerce it to dataPtr ptr to data buffer maximumSize maximum length in bytes of data to be returned actualSize actual length in bytes of data for the descriptor OUTPUTS: error code (noErr if none) ERRORS: SIDE EFFECTS: NOTES: 12/16/91 BHM (1) Changed to avoid unecessary duplication when the type doesn't really change (this should also enable it to handle typeWildCard better) (2) We don't need to dispose of newDesc because it is a direct copy (not a duplicate) of either theAEDesc or resultDesc - that is, it contains the same handle 03/12/92 BHM Added special case to deal with NIL data handles (which should only occur for typeNull, I believe) */ { short myErr; AEDesc newDesc; AEDesc resultDesc = NULL_DESCRIPTOR_DEFINITION; Size transferSize; myErr = errAECoercionFail; /* to avoid unnecessary duplication, check old type vs. new type */ if ((theAEDesc.descriptorType == toType) || (toType == typeWildCard)) newDesc = theAEDesc; else { /* must coerce to new type */ myErr = AECoerceDesc(&theAEDesc, toType, &resultDesc); if (myErr) goto exit; newDesc = resultDesc; } // WITH newDesc DO { /* special-case for NIL handle */ /* should I **CHECK to make sure it's typeNull here? */ if (newDesc.dataHandle == kODNULL) { actualSize = 0; myErr = noErr; goto exit; } /* not NIL handle - get the size */ *actualSize = ODGetHandleSize((ODHandle)newDesc.dataHandle); myErr = MemError(); if (myErr) goto exit; /* calculate number of bytes to move */ transferSize = *actualSize; if (maximumSize < transferSize) transferSize = maximumSize; /* move the data */ // HLock(newDesc.dataHandle); ODBlockMove(*(newDesc.dataHandle), dataPtr, transferSize); // HUnlock(newDesc.dataHandle); } /* of WITH newDesc */ /* everything fine */ myErr = noErr; exit: /* finish up */ AEDisposeDesc(&resultDesc); return myErr; } /* MyAECoerceDescPtr */