mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 09:05:45 +00:00
956 lines
26 KiB
C++
956 lines
26 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is Mozilla Communicator client code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Simon Fraser <sfraser@netscape.com>
|
|
*/
|
|
|
|
|
|
#include "nsAEUtils.h"
|
|
#include "nsAETokens.h"
|
|
#include "nsAECoreClass.h"
|
|
|
|
#include "nsAEGenericClass.h"
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
AEGenericClass
|
|
|
|
----------------------------------------------------------------------------*/
|
|
AEGenericClass::AEGenericClass(DescType classType, DescType containerClass)
|
|
: mClass(classType)
|
|
, mContainerClass(containerClass)
|
|
, mItemFromContainerAccessor(nil)
|
|
{
|
|
|
|
// Window from null accessor used by the entire window hierarchy
|
|
mItemFromContainerAccessor = NewOSLAccessorProc(AEGenericClass::ItemFromContainerAccessor);
|
|
ThrowIfNil(mItemFromContainerAccessor);
|
|
|
|
OSErr err;
|
|
err = AEInstallObjectAccessor(mClass, containerClass,
|
|
mItemFromContainerAccessor,
|
|
(long)this,
|
|
false);
|
|
|
|
// although items of a given class can't contain other items of the same class,
|
|
// we need this accessor to support formRelativePostion,
|
|
// which sends us one item as a "container" and asks us to find
|
|
// either the item before or after that item
|
|
err = AEInstallObjectAccessor(mClass, mClass,
|
|
mItemFromContainerAccessor,
|
|
(long)this,
|
|
false);
|
|
ThrowIfOSErr(err);
|
|
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
~AEGenericClass
|
|
|
|
----------------------------------------------------------------------------*/
|
|
AEGenericClass::~AEGenericClass()
|
|
{
|
|
if (mItemFromContainerAccessor)
|
|
DisposeOSLAccessorUPP(mItemFromContainerAccessor);
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
DispatchEvent
|
|
|
|
Handles all OSL messages that this object should handle
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::DispatchEvent(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
OSErr err = noErr;
|
|
|
|
AEEventID eventID;
|
|
OSType typeCode;
|
|
Size actualSize = 0L;
|
|
|
|
// Get the event ID
|
|
err = AEGetAttributePtr(appleEvent, keyEventIDAttr,
|
|
typeType,
|
|
&typeCode,
|
|
(Ptr)&eventID,
|
|
sizeof(eventID),
|
|
&actualSize);
|
|
ThrowIfOSErr(err);
|
|
|
|
try
|
|
{
|
|
switch (eventID)
|
|
{
|
|
case kAEClone:
|
|
HandleDuplicate(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAEClose:
|
|
HandleClose(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAECountElements:
|
|
HandleCount(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAECreateElement:
|
|
HandleMake(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAEDelete:
|
|
HandleDelete(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAEDoObjectsExist:
|
|
HandleExists(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAEGetData:
|
|
HandleGetData(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAEGetDataSize:
|
|
HandleDataSize(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAEMove:
|
|
HandleMove(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAEOpen: // == kAEOpenDocuments
|
|
HandleOpen(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAEPrint:
|
|
HandlePrint(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAEOpenApplication:
|
|
HandleRun(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAEQuitApplication:
|
|
HandleQuit(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAESave:
|
|
HandleSave(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAESetData:
|
|
HandleSetData(token, appleEvent, reply);
|
|
break;
|
|
|
|
// MT-NW suite
|
|
case kAEExtract:
|
|
HandleExtract(token, appleEvent, reply);
|
|
break;
|
|
|
|
case kAESendMessage:
|
|
HandleSendMessage(token, appleEvent, reply);
|
|
break;
|
|
|
|
default:
|
|
err = errAEEventNotHandled;
|
|
break;
|
|
}
|
|
}
|
|
catch (OSErr catchErr)
|
|
{
|
|
PutReplyErrorNumber(reply, catchErr);
|
|
throw;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
PutReplyErrorNumber(reply, paramErr);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
GetProperty
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::GetProperty( DescType desiredClass,
|
|
const AEDesc* containerToken,
|
|
DescType containerClass,
|
|
DescType keyForm,
|
|
const AEDesc* keyData,
|
|
AEDesc* resultToken)
|
|
{
|
|
|
|
// call the base class utility method, which calls back up to the object
|
|
GetPropertyFromListOrObject(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
/*----------------------------------------------------------------------------
|
|
ItemFromContainerAccessor
|
|
|
|
Callback for getting an item from its container
|
|
----------------------------------------------------------------------------*/
|
|
pascal OSErr AEGenericClass::ItemFromContainerAccessor( DescType desiredClass, // cWindow
|
|
const AEDesc* containerToken, // null container
|
|
DescType containerClass, // cApplication
|
|
DescType keyForm,
|
|
const AEDesc* keyData,
|
|
AEDesc* resultToken, // specified window is returned in result
|
|
long refCon)
|
|
{
|
|
AEGenericClass* itemClass = reinterpret_cast<AEGenericClass *>(refCon);
|
|
if (!itemClass) return paramErr;
|
|
|
|
OSErr err = noErr;
|
|
|
|
try
|
|
{
|
|
itemClass->GetItemFromContainer(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
|
|
}
|
|
catch(OSErr catchErr)
|
|
{
|
|
err = catchErr;
|
|
}
|
|
catch(...)
|
|
{
|
|
err = paramErr;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleClose
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleClose(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowIfOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleCount
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleCount(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
AETokenDesc tokenDesc(token);
|
|
long numberOfObjects = 0;
|
|
DescType objectClass;
|
|
OSErr err = noErr;
|
|
|
|
if (!reply->dataHandle)
|
|
return;
|
|
|
|
// Get the class of object that we will count
|
|
err = GetObjectClassFromAppleEvent(appleEvent, &objectClass);
|
|
ThrowIfOSErr(err);
|
|
|
|
err = CheckForUnusedParameters(appleEvent);
|
|
ThrowIfOSErr(err);
|
|
|
|
if (AEListUtils::TokenContainsTokenList(token))
|
|
{
|
|
err = AECountItems(token, &numberOfObjects);
|
|
ThrowIfOSErr(err);
|
|
|
|
}
|
|
else
|
|
{
|
|
CountObjects(objectClass, tokenDesc.GetDispatchClass(), token, &numberOfObjects);
|
|
}
|
|
|
|
err = AEPutParamPtr(reply, keyAEResult,
|
|
typeLongInteger,
|
|
(Ptr)&numberOfObjects,
|
|
sizeof(long));
|
|
ThrowIfOSErr(err);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleGetData
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleGetData(AEDesc *tokenOrTokenList, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
OSErr err = noErr;
|
|
StAEDesc data;
|
|
StAEDesc desiredTypes;
|
|
|
|
(void)AEGetParamDesc(appleEvent, keyAERequestedType, typeAEList, &desiredTypes);
|
|
|
|
GetDataFromListOrObject(tokenOrTokenList, &desiredTypes, &data);
|
|
|
|
if (reply->descriptorType != typeNull)
|
|
{
|
|
err = AEPutKeyDesc(reply, keyDirectObject, &data);
|
|
ThrowIfOSErr(err);
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleSetData
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleSetData(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
SetDataForListOrObject(token, appleEvent, reply);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleDataSize
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleDataSize(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowIfOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleDelete
|
|
|
|
All attempts to delete an empty list are handled here
|
|
Application contains documents and windows, and they can't be deleted
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleDelete(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowIfOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleDuplicate
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleDuplicate(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowIfOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleExists
|
|
|
|
If <anObject> exists...
|
|
The AEResolve() function in AERCoreSuite.c will already have filtered
|
|
out all cases where the object did not exist, so this function should
|
|
always return TRUE.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleExists(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
OSErr err;
|
|
Boolean foundIt = true;
|
|
|
|
err = AEPutParamPtr(reply,
|
|
keyAEResult,
|
|
typeBoolean,
|
|
(Ptr)&foundIt,
|
|
sizeof(Boolean));
|
|
|
|
ThrowIfOSErr(err);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleMake
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleMake(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
DescType insertionPos = typeNull;
|
|
OSErr err = noErr;
|
|
|
|
StAEDesc insertionLoc;
|
|
StAEDesc objectSpec;
|
|
|
|
// For Create Element, the object specifier is contained in
|
|
// a typeInsertionLoc record instead of in a direct parameter.
|
|
// We coerce the insertionLoc record into an AERecord so we can extract the fields.
|
|
// Notice that this is a REQUIRED parameter, but we give it a default behavior
|
|
// by creating a new element at beginning of the first document
|
|
|
|
err = ::AEGetParamDesc(appleEvent, // Extract as a AERecord
|
|
keyAEInsertHere,
|
|
typeAERecord,
|
|
&insertionLoc);
|
|
if (err == errAEDescNotFound)
|
|
{
|
|
insertionPos = kAEBeginning;
|
|
err = noErr;
|
|
}
|
|
else if (err == noErr)
|
|
{
|
|
// Get the enumerated insertion location (at end, in front, before, after, replace.)
|
|
|
|
OSType typeCode;
|
|
Size actualSize;
|
|
err = ::AEGetKeyPtr(&insertionLoc,
|
|
keyAEPosition, // insertion location
|
|
typeEnumeration,
|
|
&typeCode,
|
|
(Ptr)&insertionPos,
|
|
sizeof(insertionPos),
|
|
&actualSize);
|
|
|
|
// Extract and resolve the object specifier from the insertion location record.
|
|
// In a case like "make new rectangle before rectangle 1 of document 1",
|
|
// the ospec will resolve to "rectangle 1 of document 1"
|
|
|
|
err = ::AEGetKeyDesc(&insertionLoc,
|
|
keyAEObject,
|
|
typeWildCard,
|
|
&objectSpec);
|
|
}
|
|
|
|
// if there was a object specifier in the insertion location (eg, "before rectangle 1 of document 1"),
|
|
// then we call AEResolve() to get a token for it,
|
|
// Otherwise, is was something like "at end" or "at beginning", which is also OK,
|
|
// then deal with it correctly later.
|
|
if (objectSpec.descriptorType == typeNull)
|
|
{
|
|
::AEDisposeDesc(token); // destroy it's old representation, token will now be null descriptor
|
|
}
|
|
else
|
|
{
|
|
err = ::AEResolve(&objectSpec,
|
|
kAEIDoMinimum,
|
|
token); // token will contain info about the object to insert before, after, etc.
|
|
ThrowIfOSErr(err);
|
|
}
|
|
|
|
// Extract the optional parameters from the AppleEvent
|
|
|
|
// ----- [with data ....] -----
|
|
|
|
StAEDesc withData;
|
|
const AEDesc* withDataPtr = nil;
|
|
|
|
err = ::AEGetParamDesc(appleEvent,
|
|
keyAEData,
|
|
typeWildCard,
|
|
&withData);
|
|
if (err == errAEDescNotFound)
|
|
err = noErr;
|
|
else
|
|
{
|
|
ThrowIfOSErr(err);
|
|
withDataPtr = &withData;
|
|
}
|
|
|
|
// ----- [with properties {property: value, ...}] -----
|
|
StAEDesc withProperties;
|
|
const AEDesc* withPropertiesPtr = nil;
|
|
err = AEGetParamDesc(appleEvent,
|
|
keyAEPropData,
|
|
typeWildCard,
|
|
&withProperties);
|
|
|
|
if (err == errAEDescNotFound)
|
|
err = noErr;
|
|
else
|
|
{
|
|
ThrowIfOSErr(err);
|
|
withPropertiesPtr = &withProperties;
|
|
}
|
|
|
|
// Finally, use the token and other parameters to create & initialize the object
|
|
MakeNewObject(insertionPos, token, withDataPtr, withPropertiesPtr, reply);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleMove
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleMove(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowIfOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleOpen
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowIfOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleRun
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleRun(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowIfOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandlePrint
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandlePrint(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowIfOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleQuit
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleQuit(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowIfOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleSave
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleSave(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleExtract
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleExtract(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandleSendMessage
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::HandleSendMessage(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
ThrowOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
|
|
/*----------------------------------------------------------------------------
|
|
CompareObjects
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::CompareObjects( DescType comparisonOperator,
|
|
const AEDesc * object,
|
|
const AEDesc * descriptorOrObject,
|
|
Boolean * result)
|
|
{
|
|
ThrowOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
CountObjects
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::CountObjects( DescType desiredType,
|
|
DescType containerClass,
|
|
const AEDesc * container,
|
|
long * result)
|
|
{
|
|
ThrowOSErr(errAEEventNotHandled);
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
/*----------------------------------------------------------------------------
|
|
GetDataFromListOrObject
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
|
|
void AEGenericClass::GetDataFromListOrObject(const AEDesc *tokenOrTokenList, AEDesc *desiredTypes, AEDesc *data)
|
|
{
|
|
if (AEListUtils::TokenContainsTokenList(tokenOrTokenList) == false)
|
|
{
|
|
GetDataFromObject(tokenOrTokenList, desiredTypes, data);
|
|
}
|
|
else
|
|
{
|
|
ThrowIfOSErr(AECreateList(nil, 0, false, data));
|
|
GetDataFromList(tokenOrTokenList, desiredTypes, data);
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
GetDataFromListOrObject
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
|
|
void AEGenericClass::SetDataForListOrObject(const AEDesc *tokenOrTokenList, const AppleEvent *appleEvent, AppleEvent *reply)
|
|
{
|
|
StAEDesc data;
|
|
|
|
switch (tokenOrTokenList->descriptorType)
|
|
{
|
|
case typeAEList:
|
|
{
|
|
AECoreClass::GetAECoreHandler()->GetEventKeyDataParameter(appleEvent, typeWildCard, &data);
|
|
SetDataForList(tokenOrTokenList, &data);
|
|
}
|
|
break;
|
|
|
|
case cProperty:
|
|
{
|
|
AETokenDesc tokenDesc(tokenOrTokenList);
|
|
DescType propertyCode = tokenDesc.GetPropertyCode();
|
|
//DescType objectClass = tokenDesc.GetObjectClass();
|
|
|
|
if (CanSetProperty(propertyCode))
|
|
{
|
|
AECoreClass::GetAECoreHandler()->GetEventKeyDataParameter(appleEvent, GetKeyEventDataAs(propertyCode), &data);
|
|
SetDataForObject(tokenOrTokenList, &data);
|
|
}
|
|
else
|
|
{
|
|
ThrowIfOSErr(errAENotModifiable);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ThrowIfOSErr(errAENotModifiable);
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
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);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
GetDataFromObject
|
|
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data)
|
|
{
|
|
AETokenDesc tokenDesc(token);
|
|
DescType propertyCode = tokenDesc.GetPropertyCode();
|
|
OSErr err = noErr;
|
|
|
|
switch (propertyCode)
|
|
{
|
|
case pContents:
|
|
case typeNull:
|
|
// must mean contents. Make a self specifier.
|
|
CreateSpecifier(token, data);
|
|
break;
|
|
|
|
default:
|
|
err = errAECantSupplyType;
|
|
break;
|
|
}
|
|
|
|
ThrowIfOSErr(err);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
CanGetProperty
|
|
|
|
----------------------------------------------------------------------------*/
|
|
DescType AEGenericClass::GetKeyEventDataAs(DescType propertyCode)
|
|
{
|
|
return typeWildCard;
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
/*----------------------------------------------------------------------------
|
|
CanGetProperty
|
|
|
|
----------------------------------------------------------------------------*/
|
|
Boolean AEGenericClass::CanGetProperty(DescType propertyCode)
|
|
{
|
|
Boolean canGet = false;
|
|
|
|
switch (propertyCode)
|
|
{
|
|
case pContents:
|
|
canGet = true;
|
|
break;
|
|
}
|
|
return canGet;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
CanSetProperty
|
|
|
|
----------------------------------------------------------------------------*/
|
|
Boolean AEGenericClass::CanSetProperty(DescType propertyCode)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
|
|
/*----------------------------------------------------------------------------
|
|
CreateSpecifier
|
|
|
|
Subclasses should not need to override this. It
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::CreateSpecifier(const AEDesc *token, AEDesc *outSpecifier)
|
|
{
|
|
CreateSelfSpecifier(token, outSpecifier);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
GetContainerSpecifier
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::GetContainerSpecifier(const AEDesc *token, AEDesc *outContainerSpecifier)
|
|
{
|
|
outContainerSpecifier->descriptorType = typeNull;
|
|
outContainerSpecifier->dataHandle = nil;
|
|
|
|
AEDispatchHandler* handler = AECoreClass::GetDispatchHandlerForClass(mContainerClass);
|
|
if (handler)
|
|
{
|
|
handler->CreateSelfSpecifier(token, outContainerSpecifier);
|
|
}
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
/*----------------------------------------------------------------------------
|
|
GetPropertyFromListOrObject
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::GetPropertyFromListOrObject( DescType desiredClass,
|
|
const AEDesc* containerToken,
|
|
DescType containerClass,
|
|
DescType keyForm,
|
|
const AEDesc* keyData,
|
|
AEDesc* resultToken)
|
|
{
|
|
if (AEListUtils::TokenContainsTokenList((AEDescList*)containerToken) == false)
|
|
{
|
|
GetPropertyFromObject(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
|
|
}
|
|
else
|
|
{
|
|
OSErr err = AECreateList(nil, 0, false, resultToken);
|
|
ThrowIfOSErr(err);
|
|
|
|
GetPropertyFromList(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
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);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
GetPropertyFromObject
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::GetPropertyFromObject( DescType desiredType,
|
|
const AEDesc* containerToken,
|
|
DescType containerClass,
|
|
DescType keyForm,
|
|
const AEDesc* keyData,
|
|
AEDesc* resultToken)
|
|
{
|
|
OSErr err;
|
|
DescType requestedProperty;
|
|
|
|
err = AEDuplicateDesc(containerToken, resultToken);
|
|
ThrowIfOSErr(err);
|
|
|
|
requestedProperty = **(DescType**)(keyData->dataHandle);
|
|
|
|
if (requestedProperty == kAEAll || requestedProperty == keyAEProperties)
|
|
requestedProperty = pProperties;
|
|
|
|
if (CanGetProperty(requestedProperty) || CanSetProperty(requestedProperty))
|
|
{
|
|
AETokenDesc resultTokenDesc(resultToken);
|
|
resultToken->descriptorType = desiredType;
|
|
resultTokenDesc.SetPropertyCode(requestedProperty);
|
|
}
|
|
else
|
|
{
|
|
ThrowIfOSErr(errAEEventNotHandled);
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
MakeNewObject
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void AEGenericClass::MakeNewObject( const DescType insertionPosition,
|
|
const AEDesc* token,
|
|
const AEDesc* ptrToWithData,
|
|
const AEDesc* ptrToWithProperties,
|
|
AppleEvent* reply)
|
|
{
|
|
ThrowOSErr(errAEEventNotHandled);
|
|
}
|
|
|