This commit is contained in:
sfraser%netscape.com 2000-02-11 22:06:28 +00:00
Родитель 16ae3bc9ca
Коммит 69b3433226
46 изменённых файлов: 11938 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,158 @@
/* -*- 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 "AEUtils.h"
#include "PatriciaTree.h"
/*----------------------------------------------------------------------------
CPatriciaTree
----------------------------------------------------------------------------*/
CPatriciaTree::CPatriciaTree(long keyBitsLen)
: mTree(nil)
, mKeyBits(keyBitsLen)
{
mTree = PatriciaInitTree(mKeyBits);
ThrowErrIfNil(mTree, paramErr);
}
/*----------------------------------------------------------------------------
~CPatriciaTree
----------------------------------------------------------------------------*/
CPatriciaTree::~CPatriciaTree()
{
if (mTree)
{
PatriciaFreeTree(mTree, NodeFreeCallback, (void *)this);
}
}
#pragma mark -
/*----------------------------------------------------------------------------
InsertNode
Insert a node. Call the class's replace function by default.
Returns true if replaced
----------------------------------------------------------------------------*/
Boolean CPatriciaTree::InsertNode(TPatriciaKey key, CPatriciaNode* nodeData)
{
int result = PatriciaInsert(mTree, NodeReplaceCallback, key, (void *)nodeData, (void *)this);
return (result == 1);
}
/*----------------------------------------------------------------------------
SeekNode
Look for the node with the given key. Returns true if found
----------------------------------------------------------------------------*/
Boolean CPatriciaTree::SeekNode(TPatriciaKey key, CPatriciaNode**outNodeData)
{
int result = PatriciaSearch(mTree, key, (void **)outNodeData);
return (result == 1);
}
/*----------------------------------------------------------------------------
Traverse
Traverse over every node in the tree. Returns true if traversed the entire
tree without halting.
----------------------------------------------------------------------------*/
Boolean CPatriciaTree::Traverse(NodeTraverseFunction traverseFcn, void *arg, void *refCon)
{
int result = PatriciaTraverse(mTree, traverseFcn, arg, refCon);
return (result == 0);
}
/*----------------------------------------------------------------------------
GetNumNodes
Get the number of entries in the tree
----------------------------------------------------------------------------*/
long CPatriciaTree::GetNumNodes()
{
return (mTree) ? PatriciaGetNumNodes(mTree) : 0;
}
#pragma mark -
/*----------------------------------------------------------------------------
ReplaceNode
Detault replace node implementation. Does nothing.
----------------------------------------------------------------------------*/
int CPatriciaTree::ReplaceNode(CPatriciaNode**nodeDataPtr, TPatriciaKey key, CPatriciaNode *replaceData)
{
return 0;
}
/*----------------------------------------------------------------------------
FreeNode
Detault free node implementation. Does nothing.
----------------------------------------------------------------------------*/
int CPatriciaTree::FreeNode(CPatriciaNode *nodeData, TPatriciaKey key)
{
return 0;
}
#pragma mark -
/*----------------------------------------------------------------------------
NodeReplaceCallback
[static]
----------------------------------------------------------------------------*/
int CPatriciaTree::NodeReplaceCallback(void**nodeDataPtr, unsigned char *key, void *replaceData, void *refCon)
{
CPatriciaTree* theTree = reinterpret_cast<CPatriciaTree *>(refCon);
Assert(theTree);
return theTree->ReplaceNode((CPatriciaNode**)nodeDataPtr, key, static_cast<CPatriciaNode *>(replaceData));
}
/*----------------------------------------------------------------------------
NodeTraverseCallback
[static]
----------------------------------------------------------------------------*/
int CPatriciaTree::NodeFreeCallback(void *nodeData, unsigned char *key, void *refCon)
{
CPatriciaTree* theTree = reinterpret_cast<CPatriciaTree *>(refCon);
Assert(theTree);
return theTree->FreeNode(static_cast<CPatriciaNode *>(nodeData), key);
}

Просмотреть файл

@ -0,0 +1,86 @@
/* -*- 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>
*/
#ifndef PatricaTree_h_
#define PatricaTree_h_
#include "patricia.h"
// node base class. Subclass for your nodes.
class CPatriciaNode
{
public:
CPatriciaNode() {}
virtual ~CPatriciaNode() {}
};
// tree base class. Subclass for your tree.
class CPatriciaTree
{
public:
typedef const unsigned char* TPatriciaKey;
CPatriciaTree(long keyBitsLen);
virtual ~CPatriciaTree();
// override if you want variable replace functionality
// returns true if replaced
virtual Boolean InsertNode(TPatriciaKey key, CPatriciaNode* nodeData);
// returns true if found
Boolean SeekNode(TPatriciaKey key, CPatriciaNode**outNodeData);
// returns true if entire tree traversed
Boolean Traverse(NodeTraverseFunction traverseFcn, void *arg, void *refCon);
long GetNumNodes();
protected:
// your implementation should override these.
virtual int ReplaceNode(CPatriciaNode**nodeDataPtr, TPatriciaKey key, CPatriciaNode *replaceData);
virtual int FreeNode(CPatriciaNode *nodeData, TPatriciaKey key);
private:
// static callbacks.
static int NodeReplaceCallback(void**nodeDataPtr, unsigned char *key, void *replaceData, void *refCon);
static int NodeFreeCallback(void *nodeData, unsigned char *key, void *refCon);
protected:
PatriciaTreeRef mTree;
long mKeyBits;
};
#endif // PatricaTree_h_

Просмотреть файл

@ -0,0 +1,880 @@
/* -*- 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 <Sound.h>
#include <Scrap.h>
#include "nsAEUtils.h"
#include "nsAETokens.h"
#include "nsAECoreClass.h"
#include "nsAEDocumentClass.h"
#include "nsAEWindowClass.h"
#include "nsAEApplicationClass.h"
#include "nsCommandLineServiceMac.h"
/*----------------------------------------------------------------------------
AEApplicationClass
----------------------------------------------------------------------------*/
AEApplicationClass::AEApplicationClass()
: AEGenericClass(cApplication, typeNull)
{
}
/*----------------------------------------------------------------------------
~AEApplicationClass
----------------------------------------------------------------------------*/
AEApplicationClass::~AEApplicationClass()
{
}
#pragma mark -
/*----------------------------------------------------------------------------
GetPropertyFromApp
Override default to customize behaviour.
----------------------------------------------------------------------------*/
void AEApplicationClass::GetProperty( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken)
{
OSErr err;
CoreTokenRecord token;
DescType requestedProperty = **(DescType**)keyData->dataHandle;
token.dispatchClass = GetClass();
token.objectClass = GetClass();
token.propertyCode = requestedProperty;
if (CanGetProperty(requestedProperty) || CanSetProperty(requestedProperty))
{
err = AECreateDesc(cProperty, (Ptr)&token, sizeof(CoreTokenRecord), resultToken);
ThrowIfOSErr(err);
}
else
{
ThrowIfOSErr(errAEEventNotHandled);
}
}
/*----------------------------------------------------------------------------
GetItemFromContainer
Not appropriate for the application
----------------------------------------------------------------------------*/
void AEApplicationClass::GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken)
{
ThrowIfOSErr(errAEEventNotHandled);
}
#pragma mark -
/*----------------------------------------------------------------------------
HandleClose
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleClose(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
OSErr err = noErr;
StAEDesc saving;
StAEDesc savingIn;
// Extract the [saving yes/no/ask] optional parameter, if present
err = AEGetParamDesc(appleEvent,
keyAESaveOptions,
typeWildCard,
&saving);
if (err != errAEDescNotFound)
ThrowIfOSErr(err);
// Extract the [saving in <alias>] optional parameter, if present
err = AEGetParamDesc(appleEvent,
keyAEFile,
typeWildCard,
&savingIn);
if (err != errAEDescNotFound)
ThrowIfOSErr(err);
// Check for any required parameters we may have missed
err = CheckForUnusedParameters(appleEvent);
ThrowIfOSErr(err);
// Now, do the application-related work
SysBeep(2);
}
/*----------------------------------------------------------------------------
HandleCount
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleCount(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
OSErr err = noErr;
long numberOfObjects = 0L;
DescType objectClass;
if (!reply->dataHandle)
return;
// Get the class of object that we will count
err = GetObjectClassFromAppleEvent(appleEvent, &objectClass);
ThrowIfOSErr(err);
// Make sure we got & handled all of the required paramters
err = CheckForUnusedParameters(appleEvent);
ThrowIfOSErr(err);
// Send back the results
numberOfObjects = CountApplicationObjects(token, objectClass);
err = AEPutParamPtr(reply, keyAEResult, typeLongInteger, (Ptr)&numberOfObjects, sizeof(long));
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
HandleDataSize
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleDataSize(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
OSErr err = noErr;
StAEDesc data;
long size = 0L;
// First, get the data
HandleGetData(token, appleEvent, reply);
// now, extract it from the reply
err = AEGetKeyDesc(reply, keyDirectObject, typeWildCard, &data);
ThrowIfOSErr(err);
size = data.GetDataSize();
// do we leak all the data here?
err = AEPutParamPtr(reply,
keyAEResult,
typeLongInteger,
(Ptr)&size,
sizeof(long));
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
HandleDelete
All attempts to delete an empty list are handled here
Application contains documents and windows, and they can't be deleted
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleDelete(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
OSErr err = noErr;
if (AEListUtils::TokenContainsTokenList(token))
{
long numItems;
AECountItems(token, &numItems);
if (numItems > 0)
err = errAEEventNotHandled;
}
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
HandleDuplicate
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleDuplicate(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandleExists
If <referenceToObject> 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 AEApplicationClass::HandleExists(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
OSErr err = noErr;
Boolean foundIt = true;
err = AEPutParamPtr(reply,
keyAEResult,
typeBoolean,
(Ptr)&foundIt,
sizeof(Boolean));
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
HandleMake
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleMake(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandleMove
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleMove(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandleRun
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleRun(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
OSErr err = noErr;
// do stuff on startup that we want to do
err = CheckForUnusedParameters(appleEvent);
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
HandleOpen
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
OSErr err;
err = CheckForUnusedParameters(appleEvent);
ThrowIfOSErr(err);
long numItems, i;
Boolean openedGroups = false;
err = ::AECountItems(token, &numItems);
ThrowIfOSErr(err);
for (i = 1; i <= numItems; i++)
{
FSSpec fSpec;
FInfo fndrInfo;
AEKeyword keywd;
DescType returnedType;
Size actualSize;
err = ::AEGetNthPtr(token, i, typeFSS, &keywd, &returnedType, (Ptr)&fSpec, sizeof(fSpec), &actualSize);
ThrowIfOSErr(err);
err = ::FSpGetFInfo(&fSpec, &fndrInfo);
ThrowIfOSErr(err);
nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
cmdLine.HandleOpenOneDoc(fSpec, fndrInfo.fdType);
}
}
/*----------------------------------------------------------------------------
HandlePrint
----------------------------------------------------------------------------*/
void AEApplicationClass::HandlePrint(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
OSErr err;
err = CheckForUnusedParameters(appleEvent);
ThrowIfOSErr(err);
long numItems, i;
Boolean openedGroups = false;
err = ::AECountItems(token, &numItems);
ThrowIfOSErr(err);
for (i = 1; i <= numItems; i++)
{
FSSpec fSpec;
FInfo fndrInfo;
AEKeyword keywd;
DescType returnedType;
Size actualSize;
err = ::AEGetNthPtr(token, i, typeFSS, &keywd, &returnedType, (Ptr)&fSpec, sizeof(fSpec), &actualSize);
ThrowIfOSErr(err);
err = ::FSpGetFInfo(&fSpec, &fndrInfo);
ThrowIfOSErr(err);
nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
cmdLine.HandlePrintOneDoc(fSpec, fndrInfo.fdType);
}
}
/*----------------------------------------------------------------------------
HandleQuit
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleQuit(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
// get optional saving param
StAEDesc savingParam;
TAskSave askSave = eSaveUnspecified;
OSErr err = ::AEGetKeyDesc(appleEvent, keyAESaveOptions, typeEnumeration, &savingParam);
if (err != errAEDescNotFound)
{
DescType enumValue = savingParam.GetEnumType();
switch (enumValue)
{
case 'yes ': askSave = eSaveYes; break;
case 'no ': askSave = eSaveNo; break;
case 'ask ': askSave = eSaveAsk; break;
}
}
err = CheckForUnusedParameters(appleEvent);
ThrowIfOSErr(err);
nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
err = cmdLine.Quit(askSave);
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
HandleSave
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleSave(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
#if 0
/*----------------------------------------------------------------------------
HandleSetData
----------------------------------------------------------------------------*/
void AEApplicationClass::HandleSetData(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
OSErr err = noErr;
StAEDesc tokenData;
AETokenDesc tokenDesc(token);
DescType propertyCode;
if (token->descriptorType == cProperty)
{
propertyCode = tokenDesc.GetPropertyCode();
if (CanSetProperty(propertyCode))
{
// only the clipboard property is writeable
// the clipboard data should be in a list, so we extract that list
switch (propertyCode)
{
case pClipboard:
err = AEGetKeyDesc(appleEvent, keyAEData, typeAEList, &tokenData);
ThrowIfOSErr(err);
SetDataForObject(token, &tokenData); // may throw
err = AEPutKeyDesc(reply, keyDirectObject, &tokenData); // return the requested data
ThrowIfOSErr(err);
break;
default:
ThrowIfOSErr(errAENotModifiable); // "Can't set xxx to nnn"
break;
}
}
else
{
ThrowIfOSErr(errAENotModifiable);
}
}
else
{
ThrowIfOSErr(errAEEventNotHandled);
}
}
#endif
#pragma mark -
/*----------------------------------------------------------------------------
CountObjects
----------------------------------------------------------------------------*/
void AEApplicationClass::CountObjects( DescType desiredType,
DescType containerClass,
const AEDesc * container,
long * result)
{
long numberOfObjects = CountApplicationObjects(container, desiredType);
*result = numberOfObjects;
}
#pragma mark -
/*----------------------------------------------------------------------------
GetDataFromObject
----------------------------------------------------------------------------*/
void AEApplicationClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data)
{
OSErr err = noErr;
Str255 applicationName = "\p";
Str255 versionString;
AETokenDesc tokenDesc(token);
ProcessSerialNumber applicationProcessNumber;
ProcessInfoRec applicationInfo;
FSSpec appFSSpec;
Boolean isFrontProcess = true; // ¥¥¥ !gInBackground;
DescType aDescType = cApplication;
long documentNumber = 0L;
unsigned long elementNumber = 0L;
Boolean usePropertyCode = tokenDesc.UsePropertyCode();
DescType propertyCode;
long free;
long contiguous;
unsigned long ticks;
err = GetCurrentProcess(&applicationProcessNumber);
if (err == noErr)
{
applicationInfo.processInfoLength = sizeof(ProcessInfoRec);
applicationInfo.processName = applicationName;
applicationInfo.processAppSpec = &appFSSpec;
err = GetProcessInformation(&applicationProcessNumber, &applicationInfo);
}
GetShortVersionString(2, versionString);
PurgeSpace(&free, &contiguous);
ticks = TickCount();
propertyCode = tokenDesc.GetPropertyCode();
switch (propertyCode)
{
case pProperties:
err = AECreateList(nil, 0, true, data);
ThrowIfOSErr(err);
err = AEPutKeyPtr(data, pObjectType, typeType, &aDescType, sizeof(DescType));
err = AEPutKeyPtr(data, pName, typeChar, &applicationName[1], applicationName[0]);
err = AEPutKeyPtr(data, pVersion, typeChar, &versionString[1], versionString[0]);
err = AEPutKeyPtr(data, pIsFrontProcess, typeBoolean, &isFrontProcess, sizeof(Boolean));
err = AEPutKeyPtr(data, pFreeMemory, typeLongInteger, &free, sizeof(long));
err = AEPutKeyPtr(data, pLargestFreeBlock, typeLongInteger, &contiguous, sizeof(long));
err = AEPutKeyPtr(data, pTicks, typeLongInteger, &ticks, sizeof(long));
break;
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
err = AECreateDesc(typeType, &aDescType, sizeof(DescType), data);
break;
case pName:
err = AECreateDesc(typeChar, &applicationName[1], applicationName[0], data);
break;
case pVersion:
err = AECreateDesc(typeChar, &versionString[1], versionString[0], data);
break;
case pIsFrontProcess:
err = AECreateDesc(typeBoolean, &isFrontProcess, sizeof(Boolean), data);
break;
case pFreeMemory:
err = AECreateDesc(typeLongInteger, &free, sizeof(long), data);
break;
case pLargestFreeBlock:
err = AECreateDesc(typeLongInteger, &contiguous, sizeof(long), data);
break;
case pTicks:
err = AECreateDesc(typeLongInteger, &ticks, sizeof(long), data);
break;
case pClipboard:
{
// Return all of the items currently on the clipboard.
// The returned information is an AEList, and each data type
// on the scrap gets its own entry in the list
// Since the OS doesn't supply the tools for getting all
// of the types in the scrap, we have to scan the scrap ourselves
char *scrapPtr;
char *scrapEnd;
PScrapStuff scrapInfo;
OSType itemType;
long itemLength;
long index;
err = AECreateList(NULL, 0, false, data);
ThrowIfOSErr(err);
err = LoadScrap(); // Make sure the scrap is in memory, not on disk.
ThrowIfOSErr(err);
scrapInfo = InfoScrap(); // Get the base address of the scrap in RAM
MoveHHi(scrapInfo->scrapHandle);
HLock (scrapInfo->scrapHandle); // ...and lock it
scrapPtr = (char *)*scrapInfo->scrapHandle;
scrapEnd = scrapPtr + scrapInfo->scrapSize;
// scan the scrap in memory and extract each scrap type
index = 1;
while (scrapPtr < scrapEnd)
{
itemType = *(OSType *)scrapPtr;
scrapPtr += sizeof(itemType);
itemLength = *(long *)scrapPtr;
scrapPtr += sizeof(itemLength);
// Move this information into the next entry on the list
err = AEPutPtr(data, index, itemType, scrapPtr, itemLength);
ThrowIfOSErr(err);
index++;
// Adjust the pointer to the start of the next item
if (itemLength & 1)
itemLength++; // If it's odd, make it even
scrapPtr += itemLength;
}
HUnlock (scrapInfo->scrapHandle);
}
break;
default:
Inherited::GetDataFromObject(token, desiredTypes, data);
break;
}
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
SetDataForObject
Assumption: HandleSetData() has already filtered out all attempts
to write to a read-only property.
----------------------------------------------------------------------------*/
void AEApplicationClass::SetDataForObject(const AEDesc *token, AEDesc *data)
{
OSErr err = noErr;
long numItems;
long index;
AEKeyword theAEKeyword;
AETokenDesc tokenDesc(token);
Boolean usePropertyCode = tokenDesc.UsePropertyCode();
DescType propertyCode;
if (usePropertyCode)
{
propertyCode = tokenDesc.GetPropertyCode();
switch (propertyCode)
{
// the clipboard is the only writeable property for the application object
case pClipboard:
// The data should be an AE list containing a series of things to be placed on the
// clipboard. The data type of each item is also the clipboard type for that data
err = ZeroScrap();
ThrowIfOSErr(err);
AECountItems(data, &numItems);
// Copy each item onto the clipboard
for (index = 1; index <= numItems; index++)
{
StAEDesc currentItemDesc;
err = AEGetNthDesc(data, index, typeWildCard, &theAEKeyword, &currentItemDesc);
ThrowIfOSErr(err);
HLock(currentItemDesc.dataHandle);
err = PutScrap(GetHandleSize(currentItemDesc.dataHandle),
currentItemDesc.descriptorType,
*currentItemDesc.dataHandle);
ThrowIfOSErr(err);
}
break;
default:
ThrowIfOSErr(errAENotModifiable);
}
}
}
/*----------------------------------------------------------------------------
GetKeyEventDataAs
----------------------------------------------------------------------------*/
DescType AEApplicationClass::GetKeyEventDataAs(DescType propertyCode)
{
DescType returnType;
switch (propertyCode)
{
case pClipboard:
returnType = typeAEList;
break;
default:
returnType = typeWildCard;
}
return returnType;
}
#pragma mark -
/*----------------------------------------------------------------------------
CanSetProperty
----------------------------------------------------------------------------*/
Boolean AEApplicationClass::CanSetProperty(DescType propertyCode)
{
Boolean result = false;
switch (propertyCode)
{
// Properties we can set:
case pClipboard:
result = true;
break;
// Properties we should be able to set, but they're not implemented yet:
// Properties that are read-only
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
case pProperties:
case pFreeMemory:
case pLargestFreeBlock:
case pTicks:
case pIsFrontProcess:
case pName:
case pVersion:
case pInsertionLoc:
case pSelection:
case pUserSelection:
result = false;
break;
default:
result = Inherited::CanSetProperty(propertyCode);
break;
}
return result;
}
/*----------------------------------------------------------------------------
CanGetProperty
----------------------------------------------------------------------------*/
Boolean AEApplicationClass::CanGetProperty(DescType propertyCode)
{
Boolean result = false;
switch (propertyCode)
{
// Properties we can get:
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
case pProperties:
case pFreeMemory:
case pLargestFreeBlock:
case pTicks:
case pIsFrontProcess:
case pName:
case pVersion:
case pInsertionLoc:
case pSelection:
case pUserSelection:
result = true;
break;
// Properties we should be able to get, but they're not implemented yet:
// Properties we should not be able to get:
default:
result = Inherited::CanGetProperty(propertyCode);
break;
}
return result;
}
#pragma mark -
/*----------------------------------------------------------------------------
CreateSelfSpecifier
----------------------------------------------------------------------------*/
void AEApplicationClass::CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier)
{
OSErr err = ::AECreateDesc(typeNull, nil, 0, outSpecifier);
ThrowIfOSErr(err);
}
#pragma mark -
/*----------------------------------------------------------------------------
CountApplicationObjects
----------------------------------------------------------------------------*/
long AEApplicationClass::CountApplicationObjects(const AEDesc *token, DescType desiredType)
{
long numberOfObjects = 0;
OSErr err = noErr;
if (AEListUtils::TokenContainsTokenList(token))
{
err = AECountItems(token, &numberOfObjects);
}
else
{
AEDispatchHandler* countHandler = AECoreClass::sAECoreHandler->GetDispatchHandler(desiredType);
if (countHandler == nil)
ThrowOSErr(errAEEventNotHandled);
countHandler->CountObjects(desiredType, typeNull, token, &numberOfObjects);
/*
switch (desiredType)
{
case cDocument:
numberOfObjects = AEDocumentClass::CountDocuments();
break;
case cWindow:
numberOfObjects = AEWindowClass::CountWindows(kAnyWindowKind);
break;
// application specific classes
case cGroupWindow:
numberOfObjects = AEWindowClass::CountWindows(kUserGroupWindowKind);
break;
default:
err = errAEEventNotHandled;
break;
}
*/
}
ThrowIfOSErr(err);
return numberOfObjects;
}

Просмотреть файл

@ -0,0 +1,103 @@
/* -*- 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>
*/
#ifndef __AEAPPLICATIONCLASS__
#define __AEAPPLICATIONCLASS__
#include "nsAEGenericClass.h"
#include "nsAEDocumentClass.h" // for document typedef
class AEApplicationClass : public AEGenericClass
{
friend class AECoreClass;
friend class AEDocumentClass;
private:
typedef AEGenericClass Inherited;
protected:
// only the AECoreClass can instantiate us
AEApplicationClass();
~AEApplicationClass();
protected:
// Accessors
virtual void GetProperty( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
virtual void GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
void CountObjects( DescType desiredType,
DescType containerClass,
const AEDesc * container,
long * result);
protected:
// ----------------------------------------------------------------------------
// Core Suite Object Event handlers
// ----------------------------------------------------------------------------
virtual void HandleClose(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleCount(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
//virtual void HandleSetData(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleDataSize(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleDelete(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleDuplicate(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleExists(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleMake(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleMove(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleRun(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandlePrint(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleQuit(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleSave(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier);
virtual void GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data);
virtual void SetDataForObject(const AEDesc *token, AEDesc *data);
virtual Boolean CanSetProperty(DescType propertyCode);
virtual Boolean CanGetProperty(DescType propertyCode);
virtual DescType GetKeyEventDataAs(DescType propertyCode);
protected:
long CountApplicationObjects(const AEDesc *token, DescType desiredType);
};
#endif /* __AEAPPLICATIONCLASS__ */

Просмотреть файл

@ -0,0 +1,248 @@
/* -*- 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 "nsAEGenericClass.h"
#include "nsAEClassDispatcher.h"
/*----------------------------------------------------------------------------
AEDispatchHandler
Ownership of the hanlder passes to this object
----------------------------------------------------------------------------*/
AEDispatchHandler::AEDispatchHandler(DescType handlerClass, AEGenericClass* handler, Boolean deleteOnRemove /* = true*/ )
: mDeleteHandler(deleteOnRemove)
, mHandlerClass(handlerClass)
, mHandler(handler)
{
ASSERT(mHandler, "No handler");
}
/*----------------------------------------------------------------------------
AEDispatchHandler
----------------------------------------------------------------------------*/
AEDispatchHandler::~AEDispatchHandler()
{
if (mDeleteHandler)
delete mHandler;
}
/*----------------------------------------------------------------------------
DispatchEvent
----------------------------------------------------------------------------*/
void AEDispatchHandler::DispatchEvent( AEDesc * token,
const AppleEvent * appleEvent,
AppleEvent * reply)
{
ASSERT(mHandler, "No handler");
mHandler->DispatchEvent(token, appleEvent, reply);
}
/*----------------------------------------------------------------------------
GetProperty
----------------------------------------------------------------------------*/
void AEDispatchHandler::GetProperty( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken)
{
ASSERT(mHandler, "No handler");
mHandler->GetProperty(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
}
/*----------------------------------------------------------------------------
GetDataFromListOrObject
----------------------------------------------------------------------------*/
void AEDispatchHandler::GetDataFromListOrObject( const AEDesc * tokenOrTokenList,
AEDesc * desiredTypes,
AEDesc * data)
{
ASSERT(mHandler, "No handler");
mHandler->GetDataFromListOrObject(tokenOrTokenList, desiredTypes, data);
}
/*----------------------------------------------------------------------------
GetItemFromContainer
----------------------------------------------------------------------------*/
void AEDispatchHandler::GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken)
{
ASSERT(mHandler, "No handler");
mHandler->GetItemFromContainer(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
}
/*----------------------------------------------------------------------------
CompareObjects
----------------------------------------------------------------------------*/
void AEDispatchHandler::CompareObjects( DescType comparisonOperator,
const AEDesc * object,
const AEDesc * descriptorOrObject,
Boolean * result)
{
ASSERT(mHandler, "No handler");
mHandler->CompareObjects(comparisonOperator, object, descriptorOrObject, result);
}
/*----------------------------------------------------------------------------
CountObjects
----------------------------------------------------------------------------*/
void AEDispatchHandler::CountObjects( DescType desiredType,
DescType containerClass,
const AEDesc * container,
long * result)
{
ASSERT(mHandler, "No handler");
mHandler->CountObjects(desiredType, containerClass, container, result);
}
/*----------------------------------------------------------------------------
CreateSelfSpecifier
----------------------------------------------------------------------------*/
void AEDispatchHandler::CreateSelfSpecifier( const AEDesc * token,
AEDesc * outSpecifier)
{
ASSERT(mHandler, "No handler");
mHandler->CreateSelfSpecifier(token, outSpecifier);
}
#pragma mark -
/*----------------------------------------------------------------------------
AEDispatchTree
----------------------------------------------------------------------------*/
AEDispatchTree::AEDispatchTree()
: mTree(nil)
{
mTree = PatriciaInitTree(8 * sizeof(DescType));
ThrowIfNil(mTree);
}
/*----------------------------------------------------------------------------
~AEDispatchTree
----------------------------------------------------------------------------*/
AEDispatchTree::~AEDispatchTree()
{
if (mTree)
PatriciaFreeTree(mTree, FreeDispatchTreeNodeData, this);
}
/*----------------------------------------------------------------------------
InsertHandler
----------------------------------------------------------------------------*/
void AEDispatchTree::InsertHandler(DescType handlerClass, AEGenericClass *handler, Boolean isDuplicate /* = false */)
{
AEDispatchHandler *newHandler = new AEDispatchHandler(handlerClass, handler, !isDuplicate);
unsigned char key[5] = {0};
int result;
*(DescType *)key = handlerClass;
result = PatriciaInsert(mTree, nil, key, newHandler, nil);
if (result == kDuplicateKeyError || result == 1)
{
ThrowIfOSErr(kDuplicateKeyError);
}
else if (result != 0)
{
ThrowIfOSErr(result);
}
}
/*----------------------------------------------------------------------------
FindHandler
----------------------------------------------------------------------------*/
AEDispatchHandler* AEDispatchTree::FindHandler(DescType handlerClass)
{
AEDispatchHandler* foundClass = nil;
unsigned char key[5] = {0};
*(DescType *)key = handlerClass;
(void)PatriciaSearch(mTree, key, &foundClass);
return foundClass;
}
/*----------------------------------------------------------------------------
ReplaceDispatchTreeNode
static
if this ever gets called, it means we tried to insert a node for a duplicate class,
which is an error. So return an error. We don't want to throw because the
patricia code may not be exception-safe.
----------------------------------------------------------------------------*/
int AEDispatchTree::ReplaceDispatchTreeNode(void *nodeData, unsigned char *key, void *replaceData)
{
return kDuplicateKeyError;
}
/*----------------------------------------------------------------------------
FreeDispatchTreeNodeData
static
----------------------------------------------------------------------------*/
int AEDispatchTree::FreeDispatchTreeNodeData(void *nodeData, unsigned char *key, void *refCon)
{
AEDispatchTree* dispatchTree = reinterpret_cast<AEDispatchTree *>(refCon);
AEDispatchHandler* handler = reinterpret_cast<AEDispatchHandler *>(nodeData);
delete handler;
return 0;
}

Просмотреть файл

@ -0,0 +1,115 @@
/* -*- 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>
*/
#ifndef __AECLASSDISPATCHER__
#define __AECLASSDISPATCHER__
#include "patricia.h"
// this class is used to dispatch calls to handlers on the basis of their class. It avoids
// us having to switch on the class in the code.
class AEGenericClass;
class AEDispatchHandler
{
public:
AEDispatchHandler(DescType handlerClass, AEGenericClass* handler, Boolean deleteOnRemove = true);
~AEDispatchHandler();
void DispatchEvent( AEDesc * token,
const AppleEvent * appleEvent,
AppleEvent * reply);
void GetProperty( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
void GetDataFromListOrObject( const AEDesc * tokenOrTokenList,
AEDesc * desiredTypes,
AEDesc * data);
void GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
void CompareObjects( DescType comparisonOperator,
const AEDesc * object,
const AEDesc * descriptorOrObject,
Boolean * result);
void CountObjects( DescType desiredType,
DescType containerClass,
const AEDesc * container,
long * result);
void CreateSelfSpecifier( const AEDesc * token,
AEDesc * outSpecifier);
protected:
Boolean mDeleteHandler;
DescType mHandlerClass;
AEGenericClass* mHandler;
};
class AEDispatchTree
{
public:
AEDispatchTree();
~AEDispatchTree();
void InsertHandler(DescType handlerClass, AEGenericClass *handler, Boolean isDuplicate = false);
AEDispatchHandler* FindHandler(DescType handlerClass);
protected:
enum {
kDuplicateKeyError = 750
};
static int FreeDispatchTreeNodeData(void *nodeData, unsigned char *key, void *refCon);
static int ReplaceDispatchTreeNode(void *nodeData, unsigned char *key, void *replaceData);
protected:
PatriciaTreeRef mTree;
};
#endif /* __AECLASSDISPATCHER__ */

Просмотреть файл

@ -0,0 +1,457 @@
/* -*- 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 "nsAEClassIterator.h"
const AEClassIterator::ItemRef AEClassIterator::kNoItemRef = -1;
const AEClassIterator::ItemID AEClassIterator::kNoItemID = -1;
/*----------------------------------------------------------------------------
GetItemFromContainer
----------------------------------------------------------------------------*/
void AEClassIterator::GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken)
{
OSErr err = noErr;
CStr255 itemName;
ItemRef itemRef = kNoItemRef;
ItemID itemID = kNoItemID;
DescType keyDataType = keyData->descriptorType;
Boolean wantsAllItems = false;
StAEDesc startObject; // These are used to resolve formRange
StAEDesc stopObject;
CoreTokenRecord token;
long numItems = GetNumItems(containerToken);
TAEListIndex itemIndex;
CheckKeyFormSupport(keyForm); // throws on error
switch (keyForm)
{
case formName: // item by name
if (DescToCString(keyData, itemName, 255) != noErr)
ThrowIfOSErr(errAECoercionFail);
itemRef = GetNamedItemReference(containerToken, itemName);
if (itemRef == kNoItemRef)
ThrowIfOSErr(errAENoSuchObject);
break;
case formAbsolutePosition: // item by number
itemIndex = NormalizeAbsoluteIndex(keyData, numItems, &wantsAllItems);
if (wantsAllItems == false)
{
if (itemIndex == 0 || itemIndex > numItems)
ThrowOSErr(errAEIllegalIndex);
}
itemRef = GetIndexedItemReference(containerToken, itemIndex);
if (itemRef == kNoItemRef)
ThrowOSErr(errAENoSuchObject);
break;
case formRelativePosition:
itemRef = ProcessFormRelativePostition(containerToken, keyData);
break;
case formRange:
switch (keyDataType)
{
case typeRangeDescriptor:
{
ProcessFormRange((AEDesc *)keyData, &startObject, &stopObject);
AETokenDesc startToken(&startObject);
AETokenDesc stopToken(&stopObject);
DescType startType = startToken.GetDispatchClass();
DescType stopType = stopToken.GetDispatchClass();
if (startType != mClass || stopType != mClass)
ThrowOSErr(errAEWrongDataType);
}
break;
default:
ThrowOSErr(errAEWrongDataType);
break;
}
break;
default:
ThrowIfOSErr(errAEEventNotHandled);
}
// if user asked for all items, and there aren't any,
// we'll be kind and return an empty list.
if (wantsAllItems && (err == errAENoSuchObject || err == errAEIllegalIndex))
{
err = AECreateList(nil, 0, false, (AEDescList*)resultToken);
ThrowIfOSErr(err);
return;
}
ThrowIfOSErr(err);
// fill in the result token
token.dispatchClass = GetClass();
token.objectClass = GetClass();
token.propertyCode = typeNull;
if (wantsAllItems)
{
err = AECreateList(NULL, 0, false, (AEDescList*)resultToken);
ThrowIfOSErr(err);
for (TAEListIndex index = 1; index <= numItems; index++)
{
ItemID itemID = GetIndexedItemID(containerToken, index);
if (itemID != kNoItemID)
{
SetItemIDInCoreToken(containerToken, &token, itemID);
err = AEPutPtr(resultToken, 0, desiredClass, &token, sizeof(token));
ThrowIfOSErr(err);
}
}
}
else if (keyForm == formRange)
{
AETokenDesc startToken(&startObject);
AETokenDesc stopToken(&stopObject);
ItemID beginItemID = GetItemIDFromToken(&startObject);
ItemID endItemID = GetItemIDFromToken(&stopObject);
TAEListIndex beginIndex = GetIndexFromItemID(containerToken, beginItemID);
TAEListIndex endIndex = GetIndexFromItemID(containerToken, endItemID);
err = AECreateList(nil, 0, false, (AEDescList*)resultToken);
ThrowIfOSErr(err);
if (beginIndex > endIndex) // swap elements
{
TAEListIndex temp = beginIndex;
beginIndex = endIndex;
endIndex = temp;
}
for (TAEListIndex i = beginIndex; i <= endIndex; i ++)
{
ItemID itemID = GetIndexedItemID(containerToken, i);
if (itemID != kNoItemID)
{
SetItemIDInCoreToken(containerToken, &token, itemID);
err = AEPutPtr(resultToken, 0, desiredClass, &token, sizeof(token));
ThrowIfOSErr(err);
}
}
}
else
{
SetItemIDInCoreToken(containerToken, &token, GetIDFromReference(containerToken, itemRef));
err = AECreateDesc(desiredClass, &token, sizeof(token), resultToken);
ThrowIfOSErr(err);
}
}
/*----------------------------------------------------------------------------
ProcessFormRelativePostition
----------------------------------------------------------------------------*/
AEClassIterator::ItemRef AEClassIterator::ProcessFormRelativePostition(const AEDesc* anchorToken, const AEDesc *keyData)
{
OSErr err = noErr;
ItemID anchorItemID = GetItemIDFromToken(anchorToken);
TAEListIndex anchorListIndex = GetIndexFromItemID(anchorToken, anchorItemID);
TAEListIndex wantedListIndex = 0;
long numItems = GetNumItems(anchorToken);
ItemRef returnRef = kNoItemRef;
if (anchorListIndex != 0)
{
switch (keyData->descriptorType)
{
case typeEnumerated:
DescType positionEnum;
if (DescToDescType((AEDesc*)keyData, &positionEnum) != noErr)
ThrowIfOSErr(errAECoercionFail);
switch (positionEnum)
{
case kAENext: // get the window behind the anchor
wantedListIndex = anchorListIndex + 1;
if (wantedListIndex > numItems)
err = errAENoSuchObject;
break;
case kAEPrevious: // get the document in front of the anchor
wantedListIndex = anchorListIndex - 1;
if (wantedListIndex < 1)
err = errAENoSuchObject;
break;
default:
err = errAEEventNotHandled;
break;
}
ThrowIfOSErr(err);
break;
default:
err = errAECoercionFail;
break;
}
}
ThrowIfOSErr(err);
return GetIndexedItemReference(anchorToken, wantedListIndex);
}
/*----------------------------------------------------------------------------
NormalizeAbsoluteIndex
Handles formAbsolutePosition resolution
---------------------------------------------------------------------------*/
TAEListIndex AEClassIterator::NormalizeAbsoluteIndex(const AEDesc *keyData, TAEListIndex maxIndex, Boolean *isAllItems)
{
TAEListIndex index;
*isAllItems = false; // set to true if we receive kAEAll constant
// Extract the formAbsolutePosition data, either a integer or a literal constant
switch (keyData->descriptorType)
{
case typeLongInteger: // positve or negative index
if (DescToLong(keyData, &index) != noErr)
ThrowOSErr(errAECoercionFail);
if (index < 0) // convert a negative index from end of list to a positive index from beginning of list
index = maxIndex + index + 1;
break;
case typeAbsoluteOrdinal: // 'abso'
DescType ordinalDesc;
if (DescToDescType((AEDesc*)keyData, &ordinalDesc) != noErr)
ThrowOSErr(errAECoercionFail);
switch (ordinalDesc)
{
case kAEFirst:
index = 1;
break;
case kAEMiddle:
index = (maxIndex >> 1) + (maxIndex % 2);
break;
case kAELast:
index = maxIndex;
break;
case kAEAny:
index = (TickCount() % maxIndex) + 1; // poor man's random
break;
case kAEAll:
index = 1;
*isAllItems = true;
break;
}
break;
default:
ThrowOSErr(errAEWrongDataType);
}
// range-check the new index number
if ((index < 1) || (index > maxIndex))
ThrowOSErr(errAEIllegalIndex);
return index;
}
/*----------------------------------------------------------------------------
ProcessFormRange
Handles formRange resolution of boundary objects
----------------------------------------------------------------------------*/
void AEClassIterator::ProcessFormRange(AEDesc *keyData, AEDesc *start, AEDesc *stop)
{
OSErr err = noErr;
StAEDesc rangeRecord;
StAEDesc ospec;
// coerce the range record data into an AERecord
err = AECoerceDesc(keyData, typeAERecord, &rangeRecord);
ThrowIfOSErr(err);
// object specifier for first object in the range
err = AEGetKeyDesc(&rangeRecord, keyAERangeStart, typeWildCard, &ospec);
if (err == noErr && ospec.descriptorType == typeObjectSpecifier)
err = AEResolve(&ospec, kAEIDoMinimum, start);
ThrowIfOSErr(err);
ospec.Clear();
// object specifier for last object in the range
err = AEGetKeyDesc(&rangeRecord, keyAERangeStop, typeWildCard, &ospec);
if (err == noErr && ospec.descriptorType == typeObjectSpecifier)
err = AEResolve(&ospec, kAEIDoMinimum, stop);
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
CheckKeyFormSupport
throws if unsupported key form
----------------------------------------------------------------------------*/
void AEClassIterator::CheckKeyFormSupport(DescType keyForm)
{
UInt16 testMask;
switch (keyForm)
{
case formAbsolutePosition: testMask = eHasFormAbsolutePosition; break;
case formRelativePosition: testMask = eHasFormRelativePosition; break;
case formTest: testMask = eHasFormTest; break;
case formRange: testMask = eHasFormRange; break;
case formPropertyID: testMask = eHasFormPropertyID; break;
case formName: testMask = eHasFormName; break;
default:
ASSERT(false, "Unknown key form");
}
if ((mKeyFormSupport & testMask) == 0)
ThrowOSErr(errAEBadKeyForm);
}
#pragma mark -
/*----------------------------------------------------------------------------
GetItemFromContainer
----------------------------------------------------------------------------*/
void AENamedClassIterator::GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken)
{
OSErr err = noErr;
CStr255 itemName;
DescType keyDataType = keyData->descriptorType;
Boolean wantsAllItems = false;
StAEDesc startObject; // These are used to resolve formRange
StAEDesc stopObject;
CoreTokenRecord token;
long numItems = GetNumItems(containerToken);
CheckKeyFormSupport(keyForm); // throws on error
switch (keyForm)
{
case formName: // item by name
if (DescToCString(keyData, itemName, 255) != noErr)
ThrowIfOSErr(errAECoercionFail);
if (!NamedItemExists(containerToken, itemName))
ThrowIfOSErr(errAENoSuchObject);
break;
/*
case formAbsolutePosition: // item by number
DescType ordinalDesc;
if (DescToDescType((AEDesc*)keyData, &ordinalDesc) != noErr)
ThrowOSErr(errAECoercionFail);
if (ordinalDesc != kAEAll)
ThrowOSErr(errAEWrongDataType);
wantsAllItems = true;
break;
*/
default:
ThrowIfOSErr(errAEEventNotHandled);
}
ThrowIfOSErr(err);
// fill in the result token
token.dispatchClass = GetClass();
token.objectClass = GetClass();
token.propertyCode = typeNull;
if (wantsAllItems)
{
err = AECreateList(NULL, 0, false, (AEDescList*)resultToken);
ThrowIfOSErr(err);
for (TAEListIndex index = 1; index <= numItems; index++)
{
ItemID itemID = GetIndexedItemID(containerToken, index);
if (itemID != kNoItemID)
{
SetItemIDInCoreToken(containerToken, &token, itemID);
err = AEPutPtr(resultToken, 0, desiredClass, &token, sizeof(token));
ThrowIfOSErr(err);
}
}
}
else
{
SetNamedItemIDInCoreToken(containerToken, &token, itemName);
err = AECreateDesc(desiredClass, &token, sizeof(token), resultToken);
ThrowIfOSErr(err);
}
}

Просмотреть файл

@ -0,0 +1,192 @@
/* -*- 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>
*/
#ifndef __AECLASSITERATOR__
#define __AECLASSITERATOR__
#include "nsAETokens.h"
class AEClassIterator
{
protected:
enum
{
eFormAbsolutePositionBit = 0,
eFormRelativePositionBit,
eFormTestBit,
eFormRangeBit,
eFormPropertyIDBit,
eFormNameBit
};
public:
enum
{
eHasFormAbsolutePosition = (1 << eFormAbsolutePositionBit),
eHasFormRelativePosition = (1 << eFormRelativePositionBit),
eHasFormTest = (1 << eFormTestBit),
eHasFormRange = (1 << eFormPropertyIDBit),
eHasFormPropertyID = (1 << eFormRangeBit),
eHasFormName = (1 << eFormNameBit),
eStandardKeyFormSupport = (eHasFormAbsolutePosition | eHasFormRelativePosition | eHasFormRange | eHasFormName)
};
AEClassIterator(DescType classType, UInt16 keyFormSupport = eStandardKeyFormSupport)
: mClass(classType)
, mKeyFormSupport(keyFormSupport)
{}
virtual ~AEClassIterator() {}
virtual void GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
virtual UInt32 GetNumItems(const AEDesc* containerToken) = 0; // get the number of items
typedef UInt32 ItemRef; // runtime, optimized reference to an object
typedef UInt32 ItemID; // persistent reference, used for storage
protected:
static const ItemRef kNoItemRef; // value for a nonexistent item reference (usu. -1)
static const ItemID kNoItemID; // value for a nonexistent item ID (usu -1)
virtual ItemRef GetNamedItemReference(const AEDesc* containerToken, const char *itemName) = 0;
virtual ItemRef GetIndexedItemReference(const AEDesc* containerToken, TAEListIndex itemIndex) = 0;
virtual TAEListIndex GetIndexFromItemID(const AEDesc* containerToken, ItemID itemID) = 0;
virtual ItemID GetNamedItemID(const AEDesc* containerToken, const char *itemName) = 0;
virtual ItemID GetIndexedItemID(const AEDesc* containerToken, TAEListIndex itemIndex) = 0;
// index to name
virtual void GetIndexedItemName(const AEDesc* containerToken, TAEListIndex itemIndex, char *outName, long maxLen) = 0;
// conversion routines.
virtual ItemID GetIDFromReference(const AEDesc* containerToken, ItemRef itemRef) = 0;
virtual ItemRef GetReferenceFromID(const AEDesc* containerToken, ItemID itemID) = 0;
virtual ItemID GetItemIDFromToken(const AEDesc* token) = 0;
virtual void SetItemIDInCoreToken(const AEDesc* containerToken, CoreTokenRecord* tokenRecord, ItemID itemID) = 0;
// Range and index processing routines.
virtual ItemRef ProcessFormRelativePostition(const AEDesc* anchorToken, const AEDesc *keyData);
TAEListIndex NormalizeAbsoluteIndex(const AEDesc *keyData, TAEListIndex maxIndex, Boolean *isAllItems);
void ProcessFormRange(AEDesc *keyData, AEDesc *start, AEDesc *stop);
void CheckKeyFormSupport(DescType keyForm); // throws if unsupported key form
DescType GetClass() { return mClass; }
DescType mClass;
UInt16 mKeyFormSupport;
};
class AENamedClassIterator : public AEClassIterator
{
public:
AENamedClassIterator(DescType classType)
: AEClassIterator(classType, eHasFormName)
{}
~AENamedClassIterator() {}
virtual void GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
protected:
// stubs for those pure virtual functions that we can't use with named items
virtual UInt32 GetNumItems(const AEDesc* containerToken) { return 0; }
virtual ItemRef GetNamedItemReference(const AEDesc* containerToken, const char *itemName) { return kNoItemRef; }
virtual ItemRef GetIndexedItemReference(const AEDesc* containerToken, TAEListIndex itemIndex) { return kNoItemRef; }
virtual TAEListIndex GetIndexFromItemID(const AEDesc* containerToken, ItemID itemID) { return 0; }
virtual Boolean NamedItemExists(const AEDesc* containerToken, const char *itemName) = 0;
virtual ItemID GetNamedItemID(const AEDesc* containerToken, const char *itemName) { return kNoItemID; }
virtual ItemID GetIndexedItemID(const AEDesc* containerToken, TAEListIndex itemIndex) { return kNoItemID; }
// index to name
virtual void GetIndexedItemName(const AEDesc* containerToken, TAEListIndex itemIndex, char *outName, long maxLen) {}
// conversion routines.
virtual ItemID GetIDFromReference(const AEDesc* containerToken, ItemRef itemRef) { return kNoItemID; }
virtual ItemRef GetReferenceFromID(const AEDesc* containerToken, ItemID itemID) { return kNoItemRef; }
virtual ItemID GetItemIDFromToken(const AEDesc* token) { return kNoItemID; }
virtual void SetItemIDInCoreToken(const AEDesc* containerToken, CoreTokenRecord* tokenRecord, ItemID itemID) {}
virtual void SetNamedItemIDInCoreToken(const AEDesc* containerToken, CoreTokenRecord* token, const char *itemName) = 0;
};
// base class for items that cannot be referred to by name
class AEUnnamedClassIterator : public AEClassIterator
{
public:
enum
{
eNoNameKeyFormSupport = (eHasFormAbsolutePosition | eHasFormRelativePosition | eHasFormRange)
};
AEUnnamedClassIterator(DescType classType)
: AEClassIterator(classType, eNoNameKeyFormSupport)
{}
~AEUnnamedClassIterator() {}
protected:
virtual ItemRef GetNamedItemReference(const AEDesc* containerToken, const char *itemName) { ThrowOSErr(errAEEventNotHandled); }
virtual ItemID GetNamedItemID(const AEDesc* containerToken, const char *itemName) { ThrowOSErr(errAEEventNotHandled); }
virtual void GetIndexedItemName(const AEDesc* containerToken, TAEListIndex itemIndex, char *outName, long maxLen) { ThrowOSErr(errAEEventNotHandled); }
};
#endif /* __AECLASSITERATOR__ */

Просмотреть файл

@ -0,0 +1,69 @@
/* -*- 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>
*/
#ifndef __AECLASSTYPES__
#define __AECLASSTYPES__
/* Verbs */
enum {
kAEUnselect = 'uslt'
};
/* Classes */
enum {
kPrefsClassID = 'PREF'
};
/* Prefs class properties */
enum {
pPrefsUserName = 'UNAM',
pPrefsEmail = 'EMIL',
pWindowName = 'NAME' // not sure why this isn't in the headers
};
/* Classes */
enum {
cMailServer = 'SMTP',
cMessageWindow = 'MWIN',
cNewGroupsWindow = 'NWIN',
cFullGroupsWindow = 'FWIN'
};
/* Classes for coercion */
enum {
cWrappedText = 'cWtx'
};
#endif /* __AECLASSTYPES__ */

Просмотреть файл

@ -0,0 +1,212 @@
/* -*- 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 "nsAECoercionHandlers.h"
AECoercionHandlers* AECoercionHandlers::sAECoercionHandlers = nil;
/*----------------------------------------------------------------------------
AECoercionHandlers
----------------------------------------------------------------------------*/
AECoercionHandlers::AECoercionHandlers()
: mTextDescToPascalString(nil)
, mPascalStringDescToText(nil)
{
OSErr err;
mTextDescToPascalString = NewAECoerceDescProc(TextToPascalStringCoercion);
ThrowIfNil(mTextDescToPascalString);
err = ::AEInstallCoercionHandler(typeChar, typePascalString,
mTextDescToPascalString,
(long)this,
true, /* Pass a pointer not a descriptor */
false ); /* Application table, not System */
ThrowIfOSErr(err);
mPascalStringDescToText = NewAECoerceDescProc(PascalStringToTextCoercion);
ThrowIfNil(mPascalStringDescToText);
err = ::AEInstallCoercionHandler(typePascalString, typeChar,
mPascalStringDescToText,
(long)this,
true, /* Pass a pointer not a descriptor */
false ); /* Application table, not System */
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
~AECoercionHandlers
----------------------------------------------------------------------------*/
AECoercionHandlers::~AECoercionHandlers()
{
if (mTextDescToPascalString)
{
AERemoveCoercionHandler(typeChar, typePascalString, mTextDescToPascalString, false);
DisposeRoutineDescriptor(mTextDescToPascalString);
}
if (mPascalStringDescToText)
{
AERemoveCoercionHandler(typePascalString, typeChar, mPascalStringDescToText, false);
DisposeRoutineDescriptor(mPascalStringDescToText);
}
}
#pragma mark -
/*----------------------------------------------------------------------------
TextToPascalStringCoercion
----------------------------------------------------------------------------*/
OSErr AECoercionHandlers::TextToPascalStringCoercion(const AEDesc *fromDesc, DescType toType, long handlerRefcon, AEDesc *toDesc)
{
OSErr err = noErr;
if (toType != typePascalString)
return errAECoercionFail;
switch (fromDesc->descriptorType)
{
case typeChar:
Str255 pString;
DescToPString(fromDesc, pString, 255);
err = AECreateDesc(typePascalString, pString, pString[0] + 1, toDesc);
break;
default:
err = errAECoercionFail;
break;
}
return err;
}
/*----------------------------------------------------------------------------
PascalStringToTextCoercion
----------------------------------------------------------------------------*/
OSErr AECoercionHandlers::PascalStringToTextCoercion(const AEDesc *fromDesc, DescType toType, long handlerRefcon, AEDesc *toDesc)
{
OSErr err = noErr;
if (toType != typeChar)
return errAECoercionFail;
switch (fromDesc->descriptorType)
{
case typePascalString:
{
Handle dataHandle = fromDesc->dataHandle;
long stringLen = *(unsigned char *)(*dataHandle);
if (stringLen > 255)
{
err = errAECoercionFail;
break;
}
StHandleLocker locker(dataHandle);
err = AECreateDesc(typeChar, *dataHandle + 1, stringLen, toDesc);
}
break;
default:
err = errAECoercionFail;
break;
}
return err;
}
#pragma mark -
/*----------------------------------------------------------------------------
CreateCoercionHandlers
----------------------------------------------------------------------------*/
OSErr CreateCoercionHandlers()
{
OSErr err = noErr;
if (AECoercionHandlers::sAECoercionHandlers)
return noErr;
try
{
AECoercionHandlers::sAECoercionHandlers = new AECoercionHandlers;
}
catch(OSErr catchErr)
{
err = catchErr;
}
catch( ... )
{
err = paramErr;
}
return err;
}
/*----------------------------------------------------------------------------
ShutdownCoercionHandlers
----------------------------------------------------------------------------*/
OSErr ShutdownCoercionHandlers()
{
if (!AECoercionHandlers::sAECoercionHandlers)
return noErr;
try
{
delete AECoercionHandlers::sAECoercionHandlers;
}
catch(...)
{
}
AECoercionHandlers::sAECoercionHandlers = nil;
return noErr;
}

Просмотреть файл

@ -0,0 +1,74 @@
/* -*- 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>
*/
#ifndef AECoercionHandlers_h_
#define AECoercionHandlers_h_
#ifdef __cplusplus
class AECoercionHandlers
{
public:
AECoercionHandlers();
~AECoercionHandlers();
enum {
typePascalString = 'PStr' /* Descriptor type for a pascal string */
};
protected:
static OSErr TextToPascalStringCoercion(const AEDesc *fromDesc, DescType toType, long handlerRefcon, AEDesc *toDesc);
static OSErr PascalStringToTextCoercion(const AEDesc *fromDesc, DescType toType, long handlerRefcon, AEDesc *toDesc);
protected:
AECoerceDescUPP mTextDescToPascalString;
AECoerceDescUPP mPascalStringDescToText;
public:
static AECoercionHandlers* GetAECoercionHandlers() { return sAECoercionHandlers; }
static AECoercionHandlers* sAECoercionHandlers;
};
#endif //__cplusplus
#ifdef __cplusplus
extern "C" {
#endif
OSErr CreateCoercionHandlers();
OSErr ShutdownCoercionHandlers();
#ifdef __cplusplus
}
#endif
#endif // AECoercionHandlers_h_

Просмотреть файл

@ -0,0 +1,515 @@
/* -*- 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 <StringCompare.h>
#include "nsAEUtils.h"
#include "nsAECompare.h"
// ----------------------------------------------------------------------------------------
Boolean AEComparisons::CompareTexts(DescType oper, const AEDesc *desc1, const AEDesc *desc2)
{
Boolean result = false;
short compareResult;
char *lhs;
char *rhs;
long lhsSize;
long rhsSize;
char h1State, h2State;
lhsSize = GetHandleSize(desc1->dataHandle);
h1State = HGetState(desc1->dataHandle);
HLock(desc1->dataHandle);
lhs = *(desc1->dataHandle);
rhsSize = GetHandleSize(desc2->dataHandle);
h2State = HGetState(desc2->dataHandle);
HLock(desc2->dataHandle);
rhs = *(desc2->dataHandle);
compareResult = ::CompareText(lhs, rhs, lhsSize, rhsSize, nil);
switch (oper)
{
case kAEEquals:
result = (compareResult == 0);
break;
case kAELessThan:
result = (compareResult < 0);
break;
case kAELessThanEquals:
result = (compareResult <= 0);
break;
case kAEGreaterThan:
result = (compareResult > 0);
break;
case kAEGreaterThanEquals:
result = (compareResult >= 0);
break;
case kAEBeginsWith:
if (rhsSize > lhsSize)
{
result = false;
}
else
{
// compare only the number of characters in rhs
// begin comparing at the beginning of lhs
compareResult = CompareText(lhs, rhs, rhsSize, rhsSize, nil);
result = (compareResult == 0);
}
break;
case kAEEndsWith:
if (rhsSize > lhsSize)
{
result = false;
}
else
{
// compare only the number of characters in rhs
// begin comparing rhsSize characters from the end of lhs
// start
lhs += (lhsSize - rhsSize);
compareResult = CompareText(lhs, rhs, rhsSize, rhsSize, nil);
result = (compareResult == 0);
}
break;
case kAEContains:
// Here I use an inefficient search strategy, but we're dealing with small amounts
// of text and by using CompareText(), we're doing the same style of comparison
// as in the other cases above.
result = false;
while (lhsSize >= rhsSize)
{
compareResult = CompareText(lhs, rhs, rhsSize, rhsSize, nil);
if (compareResult == 0)
{
result = true;
break;
}
lhs++;
lhsSize--;
}
break;
default:
ThrowOSErr(errAEBadTestKey);
}
HSetState(desc1->dataHandle, h1State);
HSetState(desc2->dataHandle, h2State);
return result;
}
// ----------------------------------------------------------------------------------------
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 AEComparisons::CompareFixed(DescType oper, const AEDesc *desc1, const AEDesc *desc2)
{
OSErr err = noErr;
Boolean result = false;
Fixed lhs;
Fixed rhs;
err = DescToFixed(desc1, &lhs);
ThrowIfOSErr(err);
err = DescToFixed(desc2, &rhs);
ThrowIfOSErr(err);
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 AEComparisons::CompareFloat(DescType oper, const AEDesc *desc1, const AEDesc *desc2)
{
OSErr err = noErr;
Boolean result = false;
float lhs;
float rhs;
err = DescToFloat(desc1, &lhs);
ThrowIfOSErr(err);
err = DescToFloat(desc2, &rhs);
ThrowIfOSErr(err);
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;
}
// ----------------------------------------------------------------------------------------
// Apple events defines a boolean as a 1-byte value containing 1 for TRUE and 0 for FALSE
Boolean AEComparisons::CompareBoolean(DescType oper, const AEDesc *desc1, const AEDesc *desc2)
{
OSErr err = noErr;
Boolean result = false;
Boolean bool1 = ((**(char **)desc1->dataHandle) != 0);
Boolean bool2 = ((**(char **)desc2->dataHandle) != 0);
if (oper == kAEEquals)
result = (bool1 == bool2);
else
ThrowOSErr(errAEBadTestKey); // No other tests make sense
return result;
}
// ----------------------------------------------------------------------------------------
Boolean AEComparisons::CompareRGBColor(DescType oper, const AEDesc *desc1, const AEDesc *desc2)
{
OSErr err = noErr;
Boolean result = false;
RGBColor lhs;
RGBColor rhs;
err = DescToRGBColor(desc1, &lhs);
ThrowIfOSErr(err);
err = DescToRGBColor(desc2, &rhs);
ThrowIfOSErr(err);
if (oper == kAEEquals)
result = EqualRGB(lhs, rhs);
else
ThrowOSErr(errAEBadTestKey); // No other tests make sense
return result;
}
// ----------------------------------------------------------------------------------------
Boolean AEComparisons::ComparePoint(DescType oper, const AEDesc *desc1, const AEDesc *desc2)
{
OSErr err = noErr;
Boolean result = false;
Point lhs;
Point rhs;
err = DescToPoint(desc1, &lhs);
ThrowIfOSErr(err);
err = DescToPoint(desc2, &rhs);
ThrowIfOSErr(err);
switch (oper)
{
case kAEEquals:
result = (lhs.h = rhs.h && lhs.v == rhs.v);
break;
case kAELessThan:
result = (lhs.h < rhs.h && lhs.v < rhs.v);
break;
case kAELessThanEquals:
result = (lhs.h <= rhs.h && lhs.v <= rhs.v);
break;
case kAEGreaterThan:
result = (lhs.h > rhs.h && lhs.v > rhs.v);
break;
case kAEGreaterThanEquals:
result = (lhs.h >= rhs.h && lhs.v >= rhs.v);
break;
default:
ThrowOSErr(errAEBadTestKey); // No other tests make sense
}
return result;
}
// ----------------------------------------------------------------------------------------
Boolean AEComparisons::CompareRect(DescType oper, const AEDesc *desc1, const AEDesc *desc2)
{
OSErr err = noErr;
Boolean result = false;
Rect lhs;
Rect rhs;
err = DescToRect(desc1, &lhs);
ThrowIfOSErr(err);
err = DescToRect(desc2, &rhs);
ThrowIfOSErr(err);
switch (oper)
{
// compare size AND location
case kAEEquals:
result = ((lhs.top == rhs.top) && (lhs.left == rhs.left) && (lhs.bottom == rhs.bottom) && (lhs.right == rhs.right));
break;
// compare size only on the rest of the tests
case kAELessThan:
result = (((lhs.bottom - lhs.top) < (rhs.bottom - rhs.top)) && ((lhs.right - lhs.left) < (lhs.right - rhs.left)));
break;
case kAELessThanEquals:
result = (((lhs.bottom - lhs.top) < (rhs.bottom - rhs.top)) && ((lhs.right - lhs.left) < (lhs.right - rhs.left)));
break;
case kAEGreaterThan:
result = (((lhs.bottom - lhs.top) < (rhs.bottom - rhs.top)) && ((lhs.right - lhs.left) < (lhs.right - rhs.left)));
break;
case kAEGreaterThanEquals:
result = (((lhs.bottom - lhs.top) < (rhs.bottom - rhs.top)) && ((lhs.right - lhs.left) < (lhs.right - rhs.left)));
break;
case kAEContains:
// Note: two identical Rects contain each other, according to this test:
result = ((lhs.top <= rhs.top) && (lhs.left <= rhs.left) && (lhs.bottom >= rhs.bottom) && (lhs.right >= rhs.right));
break;
default:
ThrowOSErr(errAEBadTestKey); // No other tests make sense
}
return result;
}
#pragma mark -
/*----------------------------------------------------------------------------
TryPrimitiveComparison
----------------------------------------------------------------------------*/
Boolean AEComparisons::TryPrimitiveComparison(DescType comparisonOperator, const AEDesc *desc1, const AEDesc *desc2)
{
Boolean result = false;
// This has to handle all the data types used in the application's
// object model implementation.
switch (desc1->descriptorType)
{
case typeChar:
result = CompareTexts(comparisonOperator, desc1, desc2);
break;
case typeShortInteger: // also covers typeSMInt 'shor'
case typeLongInteger: // also covers typeInteger 'long'
case typeMagnitude: // 'magn'
result = CompareInteger(comparisonOperator, desc1, desc2);
break;
case typeEnumerated:
result = CompareEnumeration(comparisonOperator, desc1, desc2);
break;
case typeFixed:
result = CompareFixed(comparisonOperator, desc1, desc2);
break;
case typeFloat:
result = CompareFloat(comparisonOperator, desc1, desc2);
break;
case typeBoolean:
result = CompareBoolean(comparisonOperator, desc1, desc2);
break;
case typeRGBColor:
result = CompareRGBColor(comparisonOperator, desc1, desc2);
break;
case typeQDRectangle:
result = CompareRect(comparisonOperator, desc1, desc2);
break;
case typeQDPoint:
result = ComparePoint(comparisonOperator, desc1, desc2);
break;
default:
ThrowOSErr(errAEWrongDataType);
}
return result;
}

Просмотреть файл

@ -0,0 +1,48 @@
/* -*- 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>
*/
class AEComparisons
{
public:
static Boolean CompareTexts(DescType oper, const AEDesc *desc1, const AEDesc *desc2);
static Boolean CompareEnumeration(DescType oper, const AEDesc *desc1, const AEDesc *desc2);
static Boolean CompareInteger(DescType oper, const AEDesc *desc1, const AEDesc *desc2);
static Boolean CompareFixed(DescType oper, const AEDesc *desc1, const AEDesc *desc2);
static Boolean CompareFloat(DescType oper, const AEDesc *desc1, const AEDesc *desc2);
static Boolean CompareBoolean(DescType oper, const AEDesc *desc1, const AEDesc *desc2);
static Boolean CompareRGBColor(DescType oper, const AEDesc *desc1, const AEDesc *desc2);
static Boolean ComparePoint(DescType oper, const AEDesc *desc1, const AEDesc *desc2);
static Boolean CompareRect(DescType oper, const AEDesc *desc1, const AEDesc *desc2);
static Boolean TryPrimitiveComparison(DescType comparisonOperator, const AEDesc *desc1, const AEDesc *desc2);
protected:
static Boolean EqualRGB(RGBColor colorA, RGBColor colorB)
{
return((colorA.red == colorB.red) && (colorA.green == colorB.green) && (colorA.blue == colorB.blue));
}
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,191 @@
/* -*- 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>
*/
#ifndef __AECORECLASS__
#define __AECORECLASS__
#ifdef __cplusplus
#include <AEDataModel.h>
#include <AppleEvents.h>
#include <AEObjects.h>
#include "nsAEClassDispatcher.h"
class AEApplicationClass;
class AEDocumentClass;
class AEWindowClass;
class AECoreClass
{
public:
enum {
kAEMozillaSuite = 'MOZZ',
kAEUrlSuite = 'GURL',
kAESpyglassSuite = 'WWW!'
};
AECoreClass(Boolean suspendEvents = false); // throws OSErrs
~AECoreClass();
void HandleCoreSuiteEvent(AppleEvent *appleEvent, AppleEvent *reply); // throws OSErrs
void HandleRequiredSuiteEvent(AppleEvent *appleEvent, AppleEvent *reply); // throws OSErrs
void HandleMozillaSuiteEvent(AppleEvent *appleEvent, AppleEvent *reply); // throws OSErrs
void HandleGetURLSuiteEvent(AppleEvent *appleEvent, AppleEvent *reply); // throws OSErrs
void HandleSpyglassSuiteEvent(AppleEvent *appleEvent, AppleEvent *reply); // throws OSErrs
void HandleCreateElementEvent(AppleEvent *appleEvent, AppleEvent *reply); // throws OSErrs
void HandleEventSuspend(AppleEvent *appleEvent, AppleEvent *reply);
void ResumeEventHandling(AppleEvent *appleEvent, AppleEvent *reply, Boolean dispatchEvent);
// AE Handlers
static pascal OSErr SuspendEventHandler(AppleEvent *appleEvent, AppleEvent *reply, long refCon);
static pascal OSErr RequiredSuiteHandler(AppleEvent *appleEvent, AppleEvent *reply, long refCon);
static pascal OSErr CoreSuiteHandler(AppleEvent *appleEvent, AppleEvent *reply, long refCon);
static pascal OSErr CreateElementHandler(AppleEvent *appleEvent, AppleEvent *reply, long refCon);
// Handler for Mozilla Suite events
static pascal OSErr MozillaSuiteHandler(AppleEvent *appleEvent, AppleEvent *reply, long refCon);
// Handler for GetURL events
static pascal OSErr GetURLSuiteHandler(AppleEvent *appleEvent, AppleEvent *reply, long refCon);
// Handler for GetURL events
static pascal OSErr SpyglassSuiteHandler(AppleEvent *appleEvent, AppleEvent *reply, long refCon);
AEDispatchHandler* GetDispatchHandler(DescType dispatchClass);
void GetSuspendedEvent(AppleEvent *appleEvent, AppleEvent *reply)
{
*appleEvent = mSuspendedEvent;
*reply = mReplyToSuspendedEvent;
}
protected:
// Property token from list of tokens accessor
void PropertyTokenFromList( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
void GetAnythingFromApp( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
void RegisterClassHandler( DescType handlerClass,
AEGenericClass* classHandler,
Boolean isDuplicate = false);
void InstallSuiteHandlers( Boolean suspendEvents);
public:
void GetEventKeyDataParameter( const AppleEvent* appleEvent,
DescType requestedType,
AEDesc* data);
static pascal OSErr PropertyTokenFromAnything( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken,
long refCon);
static pascal OSErr AnythingFromAppAccessor( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken,
long refCon);
static pascal OSErr CompareObjectsCallback( DescType comparisonOperator, // operator to use
const AEDesc * object, // left-hand side
const AEDesc * descriptorOrObject, // right-hand side
Boolean * result);
static pascal OSErr CountObjectsCallback( DescType desiredType,
DescType containerClass,
const AEDesc * container,
long * result);
void ExtractData( const AEDesc* source,
AEDesc* data);
static AEDispatchHandler* GetDispatchHandlerForClass( DescType dispatchClass);
protected:
AEDispatchTree mDispatchTree; // tree of handler dispatchers
AEEventHandlerUPP mSuspendEventHandlerUPP;
AEEventHandlerUPP mStandardSuiteHandlerUPP;
AEEventHandlerUPP mRequiredSuiteHandlerUPP;
AEEventHandlerUPP mCreateElementHandlerUPP;
AEEventHandlerUPP mMozillaSuiteHandlerUPP;
AEEventHandlerUPP mGetURLSuiteHandlerUPP;
AEEventHandlerUPP mSpyGlassSuiteHandlerUPP;
OSLAccessorUPP mPropertyFromListAccessor;
OSLAccessorUPP mAnythingFromAppAccessor;
OSLCountUPP mCountItemsCallback;
OSLCompareUPP mCompareItemsCallback;
private:
AppleEvent mSuspendedEvent;
AppleEvent mReplyToSuspendedEvent;
public:
static AECoreClass* GetAECoreHandler() { return sAECoreHandler; }
static AECoreClass* sAECoreHandler;
};
#endif //__cplusplus
#endif /* __AECORECLASS__ */

Просмотреть файл

@ -0,0 +1,64 @@
/* -*- 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>
*/
#ifndef nsAEDefs_h_
#define nsAEDefs_h_
#include <MacTypes.h>
typedef char CStr255[256]; /* like Str255, except for C-format strings. */
typedef long TAEListIndex; // a 1-based list index
typedef short TWindowKind;
enum {
kAnyWindowKind = 99
};
typedef enum
{
eSaveUnspecified,
eSaveYes,
eSaveNo,
eSaveAsk
} TAskSave;
#if DEBUG
#define ASSERT(x,msg) { if (!(x)) { DebugStr("\p"msg); } }
#else
#define ASSERT(x) ((void) 0)
#endif
#endif // nsAEDefs_h_

Просмотреть файл

@ -0,0 +1,694 @@
/* -*- 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 "nsAEApplicationClass.h"
#include "nsAEDocumentClass.h"
/*----------------------------------------------------------------------------
AEDocumentClass
----------------------------------------------------------------------------*/
AEDocumentClass::AEDocumentClass()
: AEGenericClass(cDocument, typeNull)
{
}
/*----------------------------------------------------------------------------
~AEDocumentClass
----------------------------------------------------------------------------*/
AEDocumentClass::~AEDocumentClass()
{
}
#pragma mark -
/*----------------------------------------------------------------------------
PropertyFromApplicationAccessor
----------------------------------------------------------------------------*/
pascal OSErr AEDocumentClass::PropertyAccessor( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken,
long refCon)
{
AEDocumentClass* docClass = reinterpret_cast<AEDocumentClass *>(refCon);
if (!docClass) return paramErr;
OSErr err = noErr;
try
{
docClass->GetProperty(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
}
catch(OSErr catchErr)
{
err = catchErr;
}
catch(...)
{
err = paramErr;
}
return err;
}
/*----------------------------------------------------------------------------
GetItemFromContainer
Not appropriate for the application
----------------------------------------------------------------------------*/
void AEDocumentClass::GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
GetDocumentFromApp
----------------------------------------------------------------------------*/
void AEDocumentClass::GetDocumentFromApp( DescType desiredClass, // cDocument
const AEDesc* containerToken, // null container
DescType containerClass, // cApplication
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken) // specified Document is returned in result
{
OSErr err = noErr;
DescType keyDataType = keyData->descriptorType;
long index;
long numItems;
Boolean wantsAllItems = false;
StAEDesc startObject; // These are used to resolve formRange
StAEDesc stopObject;
DocumentReference document;
Str63 documentName;
CoreTokenRecord token;
numItems = CountDocuments();
switch (keyForm)
{
case formName: // Document by name
{
if (DescToPString(keyData, documentName, 63) != noErr)
{
err = errAECoercionFail;
}
else
{
document = GetDocumentByName(documentName);
if (document == nil)
err = errAENoSuchObject;
}
}
break;
case formAbsolutePosition: // Document by number
err = NormalizeAbsoluteIndex(keyData, &index, numItems, &wantsAllItems);
if ((err == noErr) && (wantsAllItems == false))
{
document = GetDocumentByIndex(index);
if (document == nil)
err = errAEIllegalIndex;
}
break;
case formRelativePosition:
ProcessFormRelativePostition(containerToken, keyData, &document);
break;
case formRange:
switch (keyDataType)
{
case typeRangeDescriptor:
err = ProcessFormRange((AEDesc *)keyData, &startObject, &stopObject);
if (err == noErr)
{
AETokenDesc startTokenDesc(&startObject);
AETokenDesc stopTokenDesc(&startObject);
DescType startType = startTokenDesc.GetDispatchClass();
DescType stopType = stopTokenDesc.GetDispatchClass();
if (startType != cDocument || stopType != cDocument)
err = errAEWrongDataType;
}
break;
default:
err = errAEWrongDataType;
break;
}
break;
default:
err = errAEEventNotHandled;
break;
}
// if user asked for all items, and there aren't any,
// we'll be kind and return an empty list.
if (wantsAllItems && (err == errAENoSuchObject || err == errAEIllegalIndex))
{
err = AECreateList(NULL, 0, false, (AEDescList*)resultToken);
ThrowIfOSErr(err);
return;
}
ThrowIfOSErr(err);
// fill in the result token
token.dispatchClass = GetClass();
token.objectClass = GetClass();
token.propertyCode = typeNull;
if (wantsAllItems)
{
err = AECreateList(NULL, 0, false, (AEDescList*)resultToken);
if (err == noErr)
{
for (index = 1; index <= numItems; index++)
{
document = GetDocumentByIndex(index);
ThrowIfOSErr(errAEEventNotHandled);
token.documentID = GetDocumentID(document);
err = AEPutPtr(resultToken, 0, desiredClass, &token, sizeof(token));
ThrowIfOSErr(err);
}
}
}
else if (keyForm == formRange)
{
DocumentReference beginDocument;
DocumentReference endDocument;
long beginIndex;
long endIndex;
beginDocument = GetDocumentReferenceFromToken(&startObject);
beginIndex = GetDocumentIndex(beginDocument);
endDocument = GetDocumentReferenceFromToken(&stopObject);
endIndex = GetDocumentIndex(endDocument);
err = AECreateList(NULL, 0, false, (AEDescList*)resultToken);
ThrowIfOSErr(err);
if (beginIndex > endIndex) // swap elements
{
DocumentReference temp;
temp = beginDocument;
beginDocument = endDocument;
endDocument = temp;
}
document = beginDocument;
while (document != nil)
{
token.documentID = GetDocumentID(document);
err = AEPutPtr(resultToken, 0, desiredClass, &token, sizeof(token));
ThrowIfOSErr(err);
if (document == endDocument)
break;
document = GetNextDocument(document);
}
}
else
{
token.documentID = GetDocumentID(document);
err = AECreateDesc(desiredClass, &token, sizeof(token), resultToken);
}
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
DocumentAccessor
Document from null accessor
----------------------------------------------------------------------------*/
pascal OSErr AEDocumentClass::DocumentAccessor( DescType desiredClass, // cDocument
const AEDesc* containerToken, // null container
DescType containerClass, // cApplication
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken, // specified Document is returned in result
long refCon)
{
AEDocumentClass* docClass = reinterpret_cast<AEDocumentClass *>(refCon);
if (!docClass) return paramErr;
OSErr err = noErr;
try
{
docClass->GetDocumentFromApp(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
}
catch(OSErr catchErr)
{
err = catchErr;
}
catch(...)
{
err = paramErr;
}
return err;
}
#pragma mark -
/*----------------------------------------------------------------------------
ProcessFormRelativePostition
----------------------------------------------------------------------------*/
void AEDocumentClass::ProcessFormRelativePostition(const AEDesc* anchorToken, const AEDesc *keyData, DocumentReference *document)
{
AETokenDesc tokenDesc(anchorToken);
OSErr err = noErr;
DescType positionEnum;
DocumentReference anchorDocument;
DocumentReference relativeDocument = nil;
*document = nil;
anchorDocument = GetDocumentReferenceFromToken(anchorToken);
if (err == noErr)
{
switch (keyData->descriptorType)
{
case typeEnumerated:
if (DescToDescType((AEDesc*)keyData, &positionEnum) != noErr)
{
err = errAECoercionFail;
}
else
{
switch (positionEnum)
{
case kAENext: // get the document behind the anchor
*document = GetPreviousDocument(anchorDocument);
if (*document == nil)
err = errAENoSuchObject;
break;
case kAEPrevious: // get the document in front of the anchor
*document = GetNextDocument(anchorDocument);
if (*document == nil)
err = errAENoSuchObject;
break;
default:
err = errAEEventNotHandled;
break;
}
}
break;
default:
err = errAECoercionFail;
break;
}
}
ThrowIfOSErr(err);
}
#pragma mark -
/*----------------------------------------------------------------------------
CanGetProperty
----------------------------------------------------------------------------*/
Boolean AEDocumentClass::CanGetProperty(DescType property)
{
Boolean result = false;
switch (property)
{
// Properties we can get:
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
case pName:
case pProperties:
case pIsModified:
result = true;
break;
// Properties we can't get:
default:
result = Inherited::CanGetProperty(property);
break;
}
return result;
}
/*----------------------------------------------------------------------------
CanSetProperty
----------------------------------------------------------------------------*/
Boolean AEDocumentClass::CanSetProperty(DescType property)
{
Boolean result = false;
switch (property)
{
// Properties we can set:
case pName:
result = true;
break;
// Properties we can't set:
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
case pProperties:
case pIsModified:
result = false;
break;
default:
result = Inherited::CanSetProperty(property);
break;
}
return result;
}
#pragma mark -
/*----------------------------------------------------------------------------
GetDataFromObject
----------------------------------------------------------------------------*/
void AEDocumentClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data)
{
OSErr err = noErr;
Boolean usePropertyCode = false;
DocumentReference document = nil;
AETokenDesc tokenDesc(token);
DescType aType = cDocument;
Str63 documentName;
Boolean isModified;
// ugh
document = GetDocumentReferenceFromToken(token);
ThrowIfOSErr(err);
if (document == nil)
ThrowIfOSErr(paramErr);
GetDocumentName(document, documentName);
isModified = DocumentIsModified(document);
usePropertyCode = tokenDesc.UsePropertyCode();
DescType propertyCode = tokenDesc.GetPropertyCode();
switch (propertyCode)
{
case pProperties:
err = AECreateList(NULL, 0L, true, data);
ThrowIfOSErr(err);
err = AEPutKeyPtr(data, pObjectType, typeType, &aType, sizeof(DescType));
err = AEPutKeyPtr(data, pName, typeChar, &documentName[1], documentName[0]);
err = AEPutKeyPtr(data, pIsModified, typeBoolean, &isModified, sizeof(Boolean));
break;
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
err = AECreateDesc(typeType, &aType, sizeof(DescType), data);
break;
case pName:
err = AECreateDesc(typeChar, &documentName[1], documentName[0], data);
break;
case pIsModified:
err = AECreateDesc(typeBoolean, &isModified, sizeof(Boolean), data);
break;
default:
Inherited::GetDataFromObject(token, desiredTypes, data);
break;
}
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
SetDataForObject
----------------------------------------------------------------------------*/
void AEDocumentClass::SetDataForObject(const AEDesc *token, AEDesc *data)
{
OSErr err = noErr;
Boolean usePropertyCode;
DescType propertyCode;
DocumentReference document = nil;
AETokenDesc tokenDesc(token);
StAEDesc propertyRecord;
usePropertyCode = tokenDesc.UsePropertyCode();
document = GetDocumentReferenceFromToken(token);
if (usePropertyCode == false)
{
err = errAEWriteDenied;
}
else
{
propertyCode = tokenDesc.GetPropertyCode();
if (data->descriptorType == typeAERecord)
{
SetDocumentProperties(document, data);
}
else // Build a record with one property
{
err = AECreateList(NULL, 0L, true, &propertyRecord);
ThrowIfOSErr(err);
err = AEPutKeyDesc(&propertyRecord, propertyCode, data);
ThrowIfOSErr(err);
SetDocumentProperties(document, &propertyRecord);
}
}
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
SetDocumentProperties
----------------------------------------------------------------------------*/
void AEDocumentClass::SetDocumentProperties(DocumentReference document, AEDesc *propertyRecord)
{
}
/*----------------------------------------------------------------------------
CountDocuments
----------------------------------------------------------------------------*/
long AEDocumentClass::CountDocuments()
{
return 0;
}
/*----------------------------------------------------------------------------
GetDocumentByName
----------------------------------------------------------------------------*/
DocumentReference AEDocumentClass::GetDocumentByName(ConstStr255Param docName)
{
return nil;
}
/*----------------------------------------------------------------------------
GetDocumentByIndex
----------------------------------------------------------------------------*/
DocumentReference AEDocumentClass::GetDocumentByIndex(long index)
{
return nil;
}
/*----------------------------------------------------------------------------
GetDocumentByID
----------------------------------------------------------------------------*/
DocumentReference AEDocumentClass::GetDocumentByID(long docID)
{
return nil;
}
/*----------------------------------------------------------------------------
GetNextDocument
----------------------------------------------------------------------------*/
DocumentReference AEDocumentClass::GetNextDocument(DocumentReference docRef)
{
return nil;
}
/*----------------------------------------------------------------------------
GetPreviousDocument
----------------------------------------------------------------------------*/
DocumentReference AEDocumentClass::GetPreviousDocument(DocumentReference docRef)
{
return nil;
}
/*----------------------------------------------------------------------------
GetDocumentReferenceFromToken
----------------------------------------------------------------------------*/
DocumentReference AEDocumentClass::GetDocumentReferenceFromToken(const AEDesc *token)
{
AETokenDesc tokenDesc(token);
long docID = tokenDesc.GetDocumentID();
return GetDocumentByID(docID);
}
/*----------------------------------------------------------------------------
CloseWindowSaving
----------------------------------------------------------------------------*/
void AEDocumentClass::CloseWindowSaving(AEDesc *token, const AEDesc *saving, AEDesc *savingIn)
{
OSErr err = noErr;
DocumentReference document;
document = GetDocumentReferenceFromToken(token);
if (document != nil)
{
// DestroyDocument(document);
}
else
err = errAEEventNotHandled;
ThrowIfOSErr(err);
}
#pragma mark -
/*----------------------------------------------------------------------------
CreateSelfSpecifier
----------------------------------------------------------------------------*/
void AEDocumentClass::CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier)
{
ThrowIfOSErr(errAENoSuchObject);
}
#pragma mark -
/*----------------------------------------------------------------------------
GetDocumentID
----------------------------------------------------------------------------*/
long GetDocumentID(DocumentReference docRef)
{
return 0;
}
/*----------------------------------------------------------------------------
GetDocumentIndex
----------------------------------------------------------------------------*/
long GetDocumentIndex(DocumentReference docRef)
{
return 0;
}
/*----------------------------------------------------------------------------
GetDocumentIndex
----------------------------------------------------------------------------*/
void GetDocumentName(DocumentReference docRef, Str63 docName)
{
docName[0] = 0;
}
/*----------------------------------------------------------------------------
GetDocumentIndex
----------------------------------------------------------------------------*/
Boolean DocumentIsModified(DocumentReference docRef)
{
return false;
}

Просмотреть файл

@ -0,0 +1,125 @@
/* -*- 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>
*/
#ifndef __AEDOCUMENTCLASS__
#define __AEDOCUMENTCLASS__
#include "nsAEGenericClass.h"
typedef WindowPtr DocumentReference; // for now, we'll refer to document by their window
class AEDocumentClass : public AEGenericClass
{
friend class AECoreClass;
private:
typedef AEGenericClass Inherited;
protected:
// only the AECoreClass can instantiate us
AEDocumentClass();
~AEDocumentClass();
void GetDocumentFromApp( DescType desiredClass, // cDocument
const AEDesc* containerToken, // null container
DescType containerClass, // cApplication
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken); // specified Document is returned in result
virtual void GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
public:
static pascal OSErr DocumentAccessor( DescType desiredClass, // cDocument
const AEDesc* containerToken, // null container
DescType containerClass, // cApplication
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken, // specified Document is returned in result
long refCon);
static pascal OSErr PropertyAccessor( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken,
long refCon);
void ProcessFormRelativePostition( const AEDesc* anchorToken,
const AEDesc* keyData,
DocumentReference* document);
void CloseWindowSaving( AEDesc* token,
const AEDesc* saving,
AEDesc* savingIn);
protected:
// ----------------------------------------------------------------------------
// Get and Set methods for objects and list. Note that the object methods are pure virtual
// ----------------------------------------------------------------------------
virtual void GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data);
void GetDataFromList(AEDesc *srcList, AEDesc *desiredTypes, AEDesc *dstList);
virtual void SetDataForObject(const AEDesc *token, AEDesc *data);
void SetDataForList(const AEDesc *token, AEDesc *data);
virtual void CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier);
virtual Boolean CanSetProperty(DescType propertyCode);
virtual Boolean CanGetProperty(DescType propertyCode);
void SetDocumentProperties(DocumentReference document, AEDesc *propertyRecord);
DocumentReference GetDocumentReferenceFromToken(const AEDesc *token); // these can all throw
DocumentReference GetDocumentByName(ConstStr255Param docName);
DocumentReference GetDocumentByIndex(long index);
DocumentReference GetDocumentByID(long docID);
DocumentReference GetNextDocument(DocumentReference docRef);
DocumentReference GetPreviousDocument(DocumentReference docRef);
public:
static long CountDocuments();
};
long GetDocumentID(DocumentReference docRef);
long GetDocumentIndex(DocumentReference docRef);
void GetDocumentName(DocumentReference docRef, Str63 docName);
Boolean DocumentIsModified(DocumentReference docRef);
#endif /* __AEDOCUMENTCLASS__ */

Просмотреть файл

@ -0,0 +1,144 @@
/* -*- 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 "nsAEEventHandling.h"
#include "nsAECoreClass.h"
/*----------------------------------------------------------------------------
CreateAEHandlerClasses
This call creates everything.
----------------------------------------------------------------------------*/
OSErr CreateAEHandlerClasses(Boolean suspendFirstEvent)
{
OSErr err = noErr;
// if we have one, assume we have all
if (AECoreClass::sAECoreHandler)
return noErr;
try
{
AECoreClass::sAECoreHandler = new AECoreClass(suspendFirstEvent);
}
catch(OSErr catchErr)
{
err = catchErr;
}
catch( ... )
{
err = paramErr;
}
return err;
}
/*----------------------------------------------------------------------------
CreateAEHandlerClasses
This call creates everything.
----------------------------------------------------------------------------*/
OSErr ResumeAEHandling(AppleEvent *appleEvent, AppleEvent *reply, Boolean dispatchEvent)
{
OSErr err = noErr;
if (!AECoreClass::sAECoreHandler)
return paramErr;
try
{
AECoreClass::sAECoreHandler->ResumeEventHandling(appleEvent, reply, dispatchEvent);
}
catch(OSErr catchErr)
{
err = catchErr;
}
catch( ... )
{
err = paramErr;
}
return err;
}
/*----------------------------------------------------------------------------
GetSuspendedEvent
Return the suspended event, if any
----------------------------------------------------------------------------*/
OSErr GetSuspendedEvent(AppleEvent *theEvent, AppleEvent *reply)
{
OSErr err = noErr;
theEvent->descriptorType = typeNull;
theEvent->dataHandle = nil;
reply->descriptorType = typeNull;
reply->dataHandle = nil;
if (!AECoreClass::sAECoreHandler)
return paramErr;
try
{
AECoreClass::sAECoreHandler->GetSuspendedEvent(theEvent, reply);
}
catch(OSErr catchErr)
{
err = catchErr;
}
catch( ... )
{
err = paramErr;
}
return err;
}
/*----------------------------------------------------------------------------
ShutdownAEHandlerClasses
and this destroys the whole lot.
----------------------------------------------------------------------------*/
OSErr ShutdownAEHandlerClasses(void)
{
if (!AECoreClass::sAECoreHandler)
return noErr;
try
{
delete AECoreClass::sAECoreHandler;
}
catch(...)
{
}
AECoreClass::sAECoreHandler = nil;
return noErr;
}

Просмотреть файл

@ -0,0 +1,40 @@
/* -*- 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"
#ifdef __cplusplus
extern "C" {
#endif
OSErr CreateAEHandlerClasses(Boolean suspendFirstEvent);
OSErr GetSuspendedEvent(AppleEvent *event, AppleEvent *reply);
OSErr ResumeAEHandling(AppleEvent *event, AppleEvent *reply, Boolean dispatchEvent);
OSErr ShutdownAEHandlerClasses(void);
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -0,0 +1,955 @@
/* -*- 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)
DisposeRoutineDescriptor(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);
}

Просмотреть файл

@ -0,0 +1,202 @@
/* -*- 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>
*/
#ifndef __AEGENERICCLASS__
#define __AEGENERICCLASS__
#include "nsAEClassIterator.h"
// pure virtual base class that provides stubs for much objecct functionality.
class AEGenericClass
{
friend class AEDispatchHandler;
public:
AEGenericClass(DescType classType, DescType containerClass); // throws OSErrs
virtual ~AEGenericClass();
// ----------------------------------------------------------------------------
// Dispatch routine
// ----------------------------------------------------------------------------
void DispatchEvent( AEDesc* token,
const AppleEvent* appleEvent,
AppleEvent* reply); // throws OSErrs
// ----------------------------------------------------------------------------
// Item from container accessor
// ----------------------------------------------------------------------------
static pascal OSErr ItemFromContainerAccessor( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken,
long refCon);
protected:
// MT-NW suite events
enum {
kAEExtract = 'Extr',
kExtractKeyDestFolder = 'Fold',
kAESendMessage = 'Post'
};
virtual void GetPropertyFromObject( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
virtual void GetProperty( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
// ----------------------------------------------------------------------------
// GetItemFromContainer
//
// Overridable method to get an item from its container.
//
// ----------------------------------------------------------------------------
virtual void GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken) = 0;
// ----------------------------------------------------------------------------
// OSL Callbacks (compare and count)
// ----------------------------------------------------------------------------
virtual void CompareObjects( DescType comparisonOperator,
const AEDesc * object,
const AEDesc * descriptorOrObject,
Boolean * result);
virtual void CountObjects( DescType desiredType,
DescType containerClass,
const AEDesc * container,
long * result);
// ----------------------------------------------------------------------------
// Core Suite Object Event handlers
// ----------------------------------------------------------------------------
virtual void HandleClose(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleCount(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleSetData(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleGetData(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleDataSize(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleDelete(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleDuplicate(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleExists(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleMake(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleMove(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleRun(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandlePrint(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleQuit(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleSave(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
// ----------------------------------------------------------------------------
// MT-NW suite event handlers
// ----------------------------------------------------------------------------
virtual void HandleExtract(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleSendMessage(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
// ----------------------------------------------------------------------------
// Get and Set methods for objects and list. Note that the object methods are pure virtual
// ----------------------------------------------------------------------------
virtual void GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data) = 0;
virtual void SetDataForObject(const AEDesc *token, AEDesc *data) = 0;
// ----------------------------------------------------------------------------
// Methods for creating self and container specifiers
// ----------------------------------------------------------------------------
void CreateSpecifier(const AEDesc *token, AEDesc *outSpecifier);
virtual void GetContainerSpecifier(const AEDesc *token, AEDesc *outContainerSpecifier);
virtual void CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier) = 0;
void GetDataFromListOrObject(const AEDesc *tokenOrTokenList, AEDesc *desiredTypes, AEDesc *data);
void SetDataForListOrObject(const AEDesc *tokenOrTokenList, const AppleEvent *appleEvent, AppleEvent *reply);
void GetDataFromList(const AEDesc *srcList, AEDesc *desiredTypes, AEDesc *dstList);
void SetDataForList(const AEDesc *token, AEDesc *data);
void GetPropertyFromListOrObject( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
void GetPropertyFromList( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
virtual DescType GetKeyEventDataAs(DescType propertyCode);
virtual Boolean CanSetProperty(DescType propertyCode) = 0;
virtual Boolean CanGetProperty(DescType propertyCode) = 0;
DescType GetClass() { return mClass; }
// ----------------------------------------------------------------------------
// Methods called from the main handlers
// ----------------------------------------------------------------------------
virtual void MakeNewObject( const DescType insertionPosition,
const AEDesc* token,
const AEDesc* ptrToWithData,
const AEDesc* ptrToWithProperties,
AppleEvent* reply);
protected:
DescType mClass;
DescType mContainerClass;
OSLAccessorUPP mItemFromContainerAccessor;
};
#endif /* __AEGENERICCLASS__ */

Просмотреть файл

@ -0,0 +1,121 @@
/* -*- 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 "nsIAllocator.h"
#include "nsAEGetURLSuiteHandler.h"
#include "nsCommandLineServiceMac.h"
/*----------------------------------------------------------------------------
AEGetURLSuiteHandler
----------------------------------------------------------------------------*/
AEGetURLSuiteHandler::AEGetURLSuiteHandler()
{
}
/*----------------------------------------------------------------------------
~AEGetURLSuiteHandler
----------------------------------------------------------------------------*/
AEGetURLSuiteHandler::~AEGetURLSuiteHandler()
{
}
/*----------------------------------------------------------------------------
HandleGetURLSuiteEvent
----------------------------------------------------------------------------*/
void AEGetURLSuiteHandler::HandleGetURLSuiteEvent(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 kGetURLEvent:
HandleGetURLEvent(appleEvent, reply);
break;
default:
ThrowOSErr(errAEEventNotHandled);
break;
}
}
catch (OSErr catchErr)
{
PutReplyErrorNumber(reply, catchErr);
throw;
}
catch ( ... )
{
PutReplyErrorNumber(reply, paramErr);
throw;
}
}
/*----------------------------------------------------------------------------
HandleGetURLEvent
----------------------------------------------------------------------------*/
void AEGetURLSuiteHandler::HandleGetURLEvent(AppleEvent *appleEvent, AppleEvent *reply)
{
StAEDesc directParameter;
OSErr err;
// extract the direct parameter (an object specifier)
err = ::AEGetKeyDesc(appleEvent, keyDirectObject, typeWildCard, &directParameter);
ThrowIfOSErr(err);
// we need to look for other parameters, to do with destination etc.
long dataSize = directParameter.GetDataSize();
char* urlString = (char *)nsAllocator::Alloc(dataSize + 1);
ThrowIfNil(urlString);
directParameter.GetCString(urlString, dataSize);
nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
cmdLine.DispatchURLToNewBrowser(urlString);
nsAllocator::Free(urlString);
}

Просмотреть файл

@ -0,0 +1,53 @@
/* -*- 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>
*/
#ifndef nsAEGetURLSuiteHandler_h_
#define nsAEGetURLSuiteHandler_h_
#include "nsAEUtils.h"
class AEGetURLSuiteHandler
{
public:
enum {
kGetURLEvent = 'GURL'
};
AEGetURLSuiteHandler();
~AEGetURLSuiteHandler();
void HandleGetURLSuiteEvent(AppleEvent *appleEvent, AppleEvent *reply); // throws OSErrs
protected:
void HandleGetURLEvent(AppleEvent *appleEvent, AppleEvent *reply);
};
#endif // nsAEGetURLSuiteHandler_h_

Просмотреть файл

@ -0,0 +1,92 @@
/* -*- 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 "nsAEMozillaSuiteHandler.h"
/*----------------------------------------------------------------------------
AEMozillaSuiteHandler
----------------------------------------------------------------------------*/
AEMozillaSuiteHandler::AEMozillaSuiteHandler()
{
}
/*----------------------------------------------------------------------------
~AEMozillaSuiteHandler
----------------------------------------------------------------------------*/
AEMozillaSuiteHandler::~AEMozillaSuiteHandler()
{
}
/*----------------------------------------------------------------------------
HandleMozillaSuiteEvent
----------------------------------------------------------------------------*/
void AEMozillaSuiteHandler::HandleMozillaSuiteEvent(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 kDoJavaScriptEvent:
// write me!
ThrowOSErr(errAEEventNotHandled);
break;
default:
ThrowOSErr(errAEEventNotHandled);
break;
}
}
catch (OSErr catchErr)
{
PutReplyErrorNumber(reply, catchErr);
throw;
}
catch ( ... )
{
PutReplyErrorNumber(reply, paramErr);
throw;
}
}

Просмотреть файл

@ -0,0 +1,51 @@
/* -*- 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>
*/
#ifndef nsAEMozillaSuiteHandler_h_
#define nsAEMozillaSuiteHandler_h_
#include "nsAEUtils.h"
class AEMozillaSuiteHandler
{
public:
enum {
kDoJavaScriptEvent = 'jscr'
};
AEMozillaSuiteHandler();
~AEMozillaSuiteHandler();
void HandleMozillaSuiteEvent(AppleEvent *appleEvent, AppleEvent *reply); // throws OSErrs
protected:
};
#endif // nsAEMozillaSuiteHandler_h_

Просмотреть файл

@ -0,0 +1,123 @@
/* -*- 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 "nsIAllocator.h"
#include "nsAESpyglassSuiteHandler.h"
#include "nsCommandLineServiceMac.h"
/*----------------------------------------------------------------------------
AESpyglassSuiteHandler
----------------------------------------------------------------------------*/
AESpyglassSuiteHandler::AESpyglassSuiteHandler()
{
}
/*----------------------------------------------------------------------------
~AESpyglassSuiteHandler
----------------------------------------------------------------------------*/
AESpyglassSuiteHandler::~AESpyglassSuiteHandler()
{
}
/*----------------------------------------------------------------------------
HandleSpyglassSuiteEvent
----------------------------------------------------------------------------*/
void AESpyglassSuiteHandler::HandleSpyglassSuiteEvent(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 kOpenURLEvent:
HandleOpenURLEvent(appleEvent, reply);
break;
default:
ThrowOSErr(errAEEventNotHandled);
break;
}
}
catch (OSErr catchErr)
{
PutReplyErrorNumber(reply, catchErr);
throw;
}
catch ( ... )
{
PutReplyErrorNumber(reply, paramErr);
throw;
}
}
/*----------------------------------------------------------------------------
HandleOpenURLEvent
----------------------------------------------------------------------------*/
void AESpyglassSuiteHandler::HandleOpenURLEvent(AppleEvent *appleEvent, AppleEvent *reply)
{
StAEDesc directParameter;
OSErr err;
// extract the direct parameter (an object specifier)
err = ::AEGetKeyDesc(appleEvent, keyDirectObject, typeWildCard, &directParameter);
ThrowIfOSErr(err);
// we need to look for other parameters, to do with destination etc.
long dataSize = directParameter.GetDataSize();
char* urlString = (char *)nsAllocator::Alloc(dataSize + 1);
ThrowIfNil(urlString);
directParameter.GetCString(urlString, dataSize);
nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
cmdLine.DispatchURLToNewBrowser(urlString);
nsAllocator::Free(urlString);
}

Просмотреть файл

@ -0,0 +1,53 @@
/* -*- 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>
*/
#ifndef nsAESpyglassSuiteHandler_h_
#define nsAESpyglassSuiteHandler_h_
#include "nsAEUtils.h"
class AESpyglassSuiteHandler
{
public:
enum {
kOpenURLEvent = 'OURL'
};
AESpyglassSuiteHandler();
~AESpyglassSuiteHandler();
void HandleSpyglassSuiteEvent(AppleEvent *appleEvent, AppleEvent *reply); // throws OSErrs
protected:
void HandleOpenURLEvent(AppleEvent *appleEvent, AppleEvent *reply);
};
#endif // nsAESpyglassSuiteHandler_h_

Просмотреть файл

@ -0,0 +1,134 @@
/* -*- 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 "nsAETokens.h"
// ---------------------------------------------------------------------------
DescType AETokenDesc::GetDispatchClass() const
{
CoreTokenHandle tokenData = GetTokenHandle();
return (tokenData) ? (**tokenData).dispatchClass : typeNull;
}
// ---------------------------------------------------------------------------
DescType AETokenDesc::GetObjectClass() const
{
CoreTokenHandle tokenData = GetTokenHandle();
return (tokenData) ? (**tokenData).objectClass : typeNull;
}
// ---------------------------------------------------------------------------
// The field usePropertyCode has been removed from the token record,
// so we emulate it here by seeing if the propertyCode field is typeNull,
// which is interpreted to mean that this is NOT a property token
Boolean AETokenDesc::UsePropertyCode() const
{
CoreTokenHandle tokenData = GetTokenHandle();
return (tokenData) ? ((**tokenData).propertyCode != typeNull) : false;
}
// ---------------------------------------------------------------------------
DescType AETokenDesc::GetPropertyCode() const
{
CoreTokenHandle tokenData = GetTokenHandle();
return (tokenData) ? (**tokenData).propertyCode : typeNull;
}
// ---------------------------------------------------------------------------
long AETokenDesc::GetDocumentID() const
{
CoreTokenHandle tokenData = GetTokenHandle();
return (tokenData) ? (**tokenData).documentID : 0;
}
// ---------------------------------------------------------------------------
WindowPtr AETokenDesc::GetWindowPtr() const
{
CoreTokenHandle tokenData = GetTokenHandle();
return (tokenData) ? (**tokenData).window : nil;
}
// ---------------------------------------------------------------------------
TAEListIndex AETokenDesc::GetElementNumber() const
{
CoreTokenHandle tokenData = GetTokenHandle();
return (tokenData) ? (**tokenData).elementNumber : 0;
}
#pragma mark -
// ---------------------------------------------------------------------------
void AETokenDesc::SetPropertyCode(DescType propertyCode)
{
CoreTokenHandle tokenData = GetTokenHandle();
ThrowIfNil(tokenData);
(**tokenData).propertyCode = propertyCode;
}
// ---------------------------------------------------------------------------
void AETokenDesc::SetDispatchClass(DescType dispatchClass)
{
CoreTokenHandle tokenData = GetTokenHandle();
ThrowIfNil(tokenData);
(**tokenData).dispatchClass = dispatchClass;
}
// ---------------------------------------------------------------------------
void AETokenDesc::SetObjectClass(DescType objectClass)
{
CoreTokenHandle tokenData = GetTokenHandle();
ThrowIfNil(tokenData);
(**tokenData).objectClass = objectClass;
}
// ---------------------------------------------------------------------------
void AETokenDesc::SetElementNumber(TAEListIndex number)
{
CoreTokenHandle tokenData = GetTokenHandle();
ThrowIfNil(tokenData);
(**tokenData).elementNumber = number;
}
// ---------------------------------------------------------------------------
void AETokenDesc::SetWindow(WindowPtr wind)
{
CoreTokenHandle tokenData = GetTokenHandle();
ThrowIfNil(tokenData);
(**tokenData).window = wind;
}

Просмотреть файл

@ -0,0 +1,99 @@
/* -*- 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>
*/
#ifndef __AETOKENS__
#define __AETOKENS__
#include "nsAEUtils.h"
// ----------------------------------------------------------------------------
// This is the token record used for all tokens in the CORE Suite
// This uses the "kitchen sink" token metaphor: a single token is used to represent
// all objects, and some fields are only appropriate for some objects.
struct CoreTokenRecord
{
DescType dispatchClass; // the class that will dispatch this class
DescType objectClass; // the actual class of the tokenized object
DescType propertyCode; // property code, or typeNull if not a property token
long documentID;
TAEListIndex elementNumber;
WindowPtr window; // only used for window objects
CoreTokenRecord()
: dispatchClass(typeNull)
, objectClass(typeNull)
, propertyCode(typeNull)
, documentID(0)
, elementNumber(0)
, window(nil)
{
}
};
typedef struct CoreTokenRecord CoreTokenRecord, *CoreTokenPtr, **CoreTokenHandle;
// AETokenDesc
// A utility class designed to give easy access to the contents of the token
class AETokenDesc
{
public:
AETokenDesc(const AEDesc* token) { mToken = token; }
~AETokenDesc() {}
DescType GetDispatchClass() const;
DescType GetObjectClass() const;
Boolean UsePropertyCode() const;
DescType GetPropertyCode() const;
long GetDocumentID() const;
WindowPtr GetWindowPtr() const;
TAEListIndex GetElementNumber() const;
void SetDispatchClass(DescType dispatchClass);
void SetObjectClass(DescType objectClass);
void SetPropertyCode(DescType propertyCode);
void SetElementNumber(TAEListIndex number);
void SetWindow(WindowPtr wind);
protected:
CoreTokenHandle GetTokenHandle() const
{
if (mToken->dataHandle && GetHandleSize(mToken->dataHandle) == sizeof(CoreTokenRecord))
return (CoreTokenHandle)mToken->dataHandle;
else
return nil;
}
const AEDesc* mToken;
};
#endif /* __AETOKENS__ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,334 @@
/* -*- 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>
*/
#ifndef __AEUTILS__
#define __AEUTILS__
#include <MacTypes.h>
#include <AppleEvents.h>
#include <AERegistry.h>
#include <ASRegistry.h>
#include <AEObjects.h>
#include <FinderRegistry.h>
#include <Files.h>
#include <Errors.h>
#include <Aliases.h>
#include "nsAEDefs.h"
#include "nsMacUtils.h"
#define ThrowIfNil(a) { if (a == nil) { throw((OSErr)memFullErr); } }
#define ThrowErrIfNil(a, err) { if (a == nil) { OSErr theErr = (err); throw((OSErr)theErr); } }
#define ThrowIfOSErr(err) { OSErr theErr = (err); if (theErr != noErr) { throw((OSErr)theErr); } }
#define ThrowOSErr(err) { throw((OSErr)err); }
#define ThrowNoErr() { throw((OSErr)noErr); }
#define pObjectType 'pObT'
// Windows
#define pTitle 'pTit'
#define pIsModeless 'pNMo'
#define pIsMovableModal 'pMMo'
#define pIsSuspended 'pSus'
#define pIsPalette 'pPal'
#define pIsDialog 'pDlg'
#define pLocation 'pLcn' // the upper left corner of the object's bounding box
// Application
#define pFreeMemory 'pMem'
#define pTicks 'pTic'
// data given to a spawned thread for suspending and resuming Apple Events.
// there should be one of these per event.
typedef struct TThreadAEInfo
{
AppleEvent mAppleEvent;
AppleEvent mReply;
SInt32 mSuspendCount; // how many suspend calls we have
Boolean mGotEventData;
} TThreadAEInfo, *TThreadAEInfoPtr;
#ifdef __cplusplus
extern "C" {
#endif
OSErr CreateAliasAEDesc(AliasHandle theAlias, AEDesc *ioDesc);
OSErr GetTextFromAEDesc(const AEDesc *inDesc, Handle *outTextHandle);
OSErr CreateThreadAEInfo(const AppleEvent *event, AppleEvent *reply, TThreadAEInfoPtr *outThreadAEInfo);
void DisposeThreadAEInfo(TThreadAEInfo *threadAEInfo);
OSErr SuspendThreadAE(TThreadAEInfo *threadAEInfo);
OSErr ResumeThreadAE(TThreadAEInfo *threadAEInfo, OSErr threadError);
#if !TARGET_CARBON
OSErr AEGetDescData(const AEDesc *theAEDesc, DescType typeCode, void * dataPtr, Size maximumSize);
Size AEGetDescDataSize(const AEDesc *theAEDesc);
#endif /* TARGET_CARBON */
#ifdef __cplusplus
}
#endif
// utility port setting class
class StPortSetter
{
public:
StPortSetter(WindowPtr destWindowPort)
{
::GetPort(&mOldPort);
#if TARGET_CARBON
::SetPortWindowPort(destWindowPort);
#else
::SetPort(destWindowPort);
#endif
}
~StPortSetter()
{
::SetPort(mOldPort);
}
protected:
GrafPtr mOldPort;
};
// a stack-based, exception safely class for an AEDesc
class StAEDesc: public AEDesc
{
public:
StAEDesc()
{
descriptorType = typeNull;
dataHandle = nil;
}
StAEDesc(const StAEDesc& rhs); // copy constructor
~StAEDesc()
{
::AEDisposeDesc(this);
}
void Clear()
{
::AEDisposeDesc(this);
descriptorType = typeNull;
dataHandle = nil;
}
void CheckDataType(DescType expectedType)
{
if (descriptorType != expectedType)
ThrowOSErr(errAEWrongDataType);
}
StAEDesc& operator= (const StAEDesc&rhs); // throws OSErrs
Size GetDataSize() { return (dataHandle) ? GetHandleSize(dataHandle) : 0; }
Boolean GetBoolean();
SInt16 GetShort();
SInt32 GetLong();
DescType GetEnumType();
void GetRect(Rect& outRect);
void GetRGBColor(RGBColor& outColor);
void GetLongDateTime(LongDateTime& outDateTime);
void GetFileSpec(FSSpec &outFileSpec);
void GetCString(char *outString, short maxLen);
void GetPString(Str255 outString);
Handle GetTextHandle();
};
class StEventSuspender
{
public:
// use deleteData = false when calling threads, which take ownership of the TThreadAEInfoPtr
StEventSuspender(const AppleEvent *appleEvent, AppleEvent *reply, Boolean deleteData = true);
~StEventSuspender();
void SetDeleteData(Boolean deleteData) { mDeleteData = deleteData; }
void SuspendEvent();
void ResumeEvent();
TThreadAEInfoPtr GetThreadAEInfo() { return mThreadAEInfo; }
protected:
TThreadAEInfoPtr mThreadAEInfo;
Boolean mDeleteData;
};
class StHandleHolder
{
public:
StHandleHolder(Handle inHandle = nil); // takes ownership of the handle
~StHandleHolder();
StHandleHolder& operator=(Handle rhs);
void Lock();
void Unlock();
Handle GetHandle() { return mHandle; }
Size GetHandleSize() { return (mHandle) ? ::GetHandleSize(mHandle) : 0; }
Ptr GetPtr() { return (mHandle) ? *mHandle : nil; }
class getter
{
public:
getter(StHandleHolder& handleHolder)
: mHandleHolder(handleHolder)
, mHandle(nil)
{
}
~getter()
{
mHandleHolder = mHandle;
}
operator Handle*()
{
return &mHandle;
}
private:
StHandleHolder& mHandleHolder;
Handle mHandle;
};
// it is risky to define operator&, but, hey, we know what we're doing.
getter operator &()
{
return getter(*this);
}
// Does the same as operator&, but more explicitly.
getter AssignHandle()
{
return getter(*this);
}
protected:
Handle mHandle;
SInt32 mLockCount;
UInt8 mOldHandleState;
};
class StHandleLocker
{
public:
StHandleLocker(Handle inHandle)
: mHandle(inHandle)
{
ASSERT(mHandle, "No handle");
mOldHandleState = HGetState(mHandle);
HLock(mHandle);
}
~StHandleLocker()
{
HSetState(mHandle, mOldHandleState);
}
protected:
Handle mHandle;
UInt8 mOldHandleState;
};
class AEListUtils
{
public:
static Boolean TokenContainsTokenList(const AEDesc *token) { return (token->descriptorType == typeAEList); }
static OSErr GetFirstNonListToken(const AEDesc *token, AEDesc *result);
static OSErr FlattenAEList(AEDescList *deepList, AEDescList *flatList);
};
// simple iterator for AEDescs which may be lists. Is NOT safe to the list changing under it.
// also, it does not handle nested lists.
class AEListIterator
{
public:
AEListIterator(AEDesc *token);
~AEListIterator() {}
Boolean Next(AEDesc* outItemData); // data should be deleted by the caller.
SInt32 GetNumItems() { return mNumItems; }
protected:
AEDesc mListToken; // we don't own this.
SInt32 mNumItems;
SInt32 mCurItem;
Boolean mIsListDesc;
};
OSErr DescToPString(const AEDesc* desc, Str255 aPString, short maxLength);
OSErr DescToCString(const AEDesc* desc, CStr255 aPString, short maxLength);
OSErr DescToDescType(const AEDesc *desc, DescType *descType);
OSErr DescToBoolean(const AEDesc* desc, Boolean* aBoolean);
OSErr DescToFixed(const AEDesc* desc, Fixed* aFixed);
OSErr DescToFloat(const AEDesc* desc, float* aFloat);
OSErr DescToLong(const AEDesc* desc, long* aLong);
OSErr DescToRGBColor(const AEDesc* desc, RGBColor* aRGBColor);
OSErr DescToShort(const AEDesc* desc, short* aShort);
OSErr DescToTextHandle(const AEDesc* desc, Handle *text);
OSErr DescToRect(const AEDesc* desc, Rect* aRect);
OSErr DescToPoint(const AEDesc* desc, Point* aPoint);
OSErr CheckForUnusedParameters(const AppleEvent* appleEvent);
OSErr PutReplyErrorNumber(AppleEvent* reply, long errorNumber);
OSErr PutReplyErrorMessage(AppleEvent* reply, char *message);
OSErr GetObjectClassFromAppleEvent(const AppleEvent *appleEvent, DescType *objectClass);
OSErr NormalizeAbsoluteIndex(const AEDesc *keyData, long *index, long maxIndex, Boolean *isAllItems);
OSErr ProcessFormRange(AEDesc *keyData, AEDesc *start, AEDesc *stop);
#endif /* __AEUTILS__ */

Просмотреть файл

@ -0,0 +1,949 @@
/* -*- 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 <string.h>
#include <AEPackObject.h>
#include "nsWindowUtils.h"
#include "nsAEUtils.h"
#include "nsAETokens.h"
#include "nsAECoreClass.h"
#include "nsAEApplicationClass.h"
#include "nsAEWindowClass.h"
/*----------------------------------------------------------------------------
GetNumItems
----------------------------------------------------------------------------*/
UInt32 AEWindowIterator::GetNumItems(const AEDesc* containerToken)
{
return CountWindowsOfKind(mWindowKind);
}
/*----------------------------------------------------------------------------
GetNamedItemReference
----------------------------------------------------------------------------*/
AEClassIterator::ItemRef AEWindowIterator::GetNamedItemReference(const AEDesc* containerToken, const char *itemName)
{
WindowPtr wind;
wind = ::GetNamedOrFrontmostWindow(mWindowKind, itemName);
return (wind) ? (ItemRef)wind : kNoItemRef;
}
/*----------------------------------------------------------------------------
GetIndexedItemReference
----------------------------------------------------------------------------*/
AEClassIterator::ItemRef AEWindowIterator::GetIndexedItemReference(const AEDesc* containerToken, TAEListIndex itemIndex)
{
WindowPtr wind = GetIndexedWindowOfKind(mWindowKind, itemIndex);
return (wind) ? (ItemRef)wind : kNoItemRef;
}
/*----------------------------------------------------------------------------
GetNamedItemID
Window refs and IDs are the same for windows
----------------------------------------------------------------------------*/
AEClassIterator::ItemID AEWindowIterator::GetNamedItemID(const AEDesc* containerToken, const char *itemName)
{
WindowPtr wind;
wind = ::GetNamedOrFrontmostWindow(mWindowKind, itemName);
return (wind) ? (ItemRef)wind : kNoItemID;
}
/*----------------------------------------------------------------------------
GetIndexFromItemID
----------------------------------------------------------------------------*/
TAEListIndex AEWindowIterator::GetIndexFromItemID(const AEDesc* containerToken, ItemID itemID)
{
return GetWindowIndex(mWindowKind, (WindowPtr)itemID);
}
/*----------------------------------------------------------------------------
GetIndexedItemID
----------------------------------------------------------------------------*/
AEClassIterator::ItemID AEWindowIterator::GetIndexedItemID(const AEDesc* containerToken, TAEListIndex itemIndex)
{
WindowPtr wind = GetIndexedWindowOfKind(mWindowKind, itemIndex);
return (wind) ? (ItemRef)wind : kNoItemID;
}
/*----------------------------------------------------------------------------
GetIndexedItemName
----------------------------------------------------------------------------*/
void AEWindowIterator::GetIndexedItemName(const AEDesc* containerToken, TAEListIndex itemIndex, char *outName, long maxLen)
{
WindowPtr wind = GetIndexedWindowOfKind(mWindowKind, itemIndex);
GetCleanedWindowName(wind, outName, maxLen);
}
/*----------------------------------------------------------------------------
GetIDFromReference
----------------------------------------------------------------------------*/
AEClassIterator::ItemID AEWindowIterator::GetIDFromReference(const AEDesc* containerToken, ItemRef itemRef)
{
return (ItemID)itemRef;
}
/*----------------------------------------------------------------------------
GetReferenceFromID
----------------------------------------------------------------------------*/
AEClassIterator::ItemRef AEWindowIterator::GetReferenceFromID(const AEDesc* containerToken, ItemID itemID)
{
return (ItemRef)itemID;
}
/*----------------------------------------------------------------------------
GetItemIDFromToken
----------------------------------------------------------------------------*/
AEClassIterator::ItemID AEWindowIterator::GetItemIDFromToken(const AEDesc* token)
{
AETokenDesc tokenDesc(token);
return (ItemID)tokenDesc.GetWindowPtr();
}
/*----------------------------------------------------------------------------
SetItemIDInCoreToken
----------------------------------------------------------------------------*/
void AEWindowIterator::SetItemIDInCoreToken(const AEDesc* containerToken, CoreTokenRecord* tokenRecord, ItemID itemID)
{
tokenRecord->window = (WindowPtr)itemID;
}
#pragma mark -
/*----------------------------------------------------------------------------
AEWindowClass
----------------------------------------------------------------------------*/
AEWindowClass::AEWindowClass(DescType classType, TWindowKind windowKind)
: AEGenericClass(classType, typeNull)
, mWindowKind(windowKind)
, mDocumentAccessor(nil)
{
}
/*----------------------------------------------------------------------------
~AEWindowClass
----------------------------------------------------------------------------*/
AEWindowClass::~AEWindowClass()
{
if (mDocumentAccessor)
DisposeRoutineDescriptor(mDocumentAccessor);
}
#pragma mark -
/*----------------------------------------------------------------------------
GetItemFromContainer
----------------------------------------------------------------------------*/
void AEWindowClass::GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken)
{
AEWindowIterator windowIterator(GetClass(), GetThisWindowKind());
windowIterator.GetItemFromContainer(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
}
/*----------------------------------------------------------------------------
CompareObjects
----------------------------------------------------------------------------*/
void AEWindowClass::CompareObjects( DescType comparisonOperator,
const AEDesc * object1,
const AEDesc * object2,
Boolean * result)
{
}
/*----------------------------------------------------------------------------
CountObjects
----------------------------------------------------------------------------*/
void AEWindowClass::CountObjects( DescType desiredType,
DescType containerClass,
const AEDesc * container,
long * result)
{
*result = CountWindows(mWindowKind);
}
#pragma mark -
/*----------------------------------------------------------------------------
HandleClose
----------------------------------------------------------------------------*/
void AEWindowClass::HandleClose(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
OSErr err = noErr;
DescType typeCode = 0L;
StAEDesc saving;
StAEDesc savingIn;
AEDesc *ptrToSaving = nil;
AEDesc *ptrToSavingIn = nil;
// Extract the [saving yes/no/ask] optional parameter, if present
err = AEGetParamDesc(appleEvent, keyAESaveOptions, typeWildCard, &saving);
if (err == noErr)
ptrToSaving = &saving;
else if (err == errAEDescNotFound)
err = noErr;
else
ThrowIfOSErr(err);
// Extract the [saving in <alias>] optional parameter, if present
err = AEGetParamDesc(appleEvent, keyAEFile, typeFSS, &savingIn);
if (err == noErr)
ptrToSavingIn = &savingIn;
else if (err == errAEDescNotFound)
err = noErr;
else
ThrowIfOSErr(err);
// Check for any required parameters we may have missed
err = CheckForUnusedParameters(appleEvent);
ThrowIfOSErr(err);
// Now, do the application-related work
if (AEListUtils::TokenContainsTokenList(token))
{
long numItems;
long itemNum;
AEKeyword keyword;
err = AECountItems(token, &numItems);
ThrowIfOSErr(err);
if (numItems > 0)
{
for (itemNum = 1; itemNum <= numItems; itemNum++)
{
StAEDesc windowToken;
err = AEGetNthDesc(token, itemNum, typeWildCard, &keyword, &windowToken);
if (err != noErr) break;
//AECoreClass::sAECoreHandler->GetDocumentClass()->CloseWindowSaving(&windowToken, ptrToSaving, ptrToSavingIn);
}
}
}
else
{
//AECoreClass::sAECoreHandler->GetDocumentClass()->CloseWindowSaving(token, ptrToSaving, ptrToSavingIn);
}
}
/*----------------------------------------------------------------------------
HandleDataSize
----------------------------------------------------------------------------*/
void AEWindowClass::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 AEWindowClass::HandleDelete(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandleDuplicate
----------------------------------------------------------------------------*/
void AEWindowClass::HandleDuplicate(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandleExists
----------------------------------------------------------------------------*/
void AEWindowClass::HandleExists(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandleMake
We can't make generic windows.
----------------------------------------------------------------------------*/
void AEWindowClass::HandleMake(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandleMove
----------------------------------------------------------------------------*/
void AEWindowClass::HandleMove(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandleOpen
----------------------------------------------------------------------------*/
void AEWindowClass::HandleOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandlePrint
----------------------------------------------------------------------------*/
void AEWindowClass::HandlePrint(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandleQuit
----------------------------------------------------------------------------*/
void AEWindowClass::HandleQuit(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
/*----------------------------------------------------------------------------
HandleSave
----------------------------------------------------------------------------*/
void AEWindowClass::HandleSave(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
ThrowIfOSErr(errAEEventNotHandled);
}
#pragma mark -
/*----------------------------------------------------------------------------
GetDataFromObject
----------------------------------------------------------------------------*/
void AEWindowClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data)
{
OSErr err = noErr;
AETokenDesc tokenDesc(token);
DescType aType = mClass;
Rect aRect;
Point aPoint;
Boolean aBoolean;
long index;
CStr255 windowTitle;
DescType propertyCode = tokenDesc.GetPropertyCode();
Boolean usePropertyCode = tokenDesc.UsePropertyCode();
WindowPtr window = tokenDesc.GetWindowPtr();
switch (propertyCode)
{
case pProperties:
err = AECreateList(NULL, 0L, true, data);
ThrowIfOSErr(err);
err = AEPutKeyPtr(data, pObjectType, typeType, &aType, sizeof(DescType));
GetCleanedWindowName(window, windowTitle, 255);
err = AEPutKeyPtr(data, pTitle, typeChar, windowTitle, strlen(windowTitle));
index = GetWindowIndex(GetThisWindowKind(), window);
err = AEPutKeyPtr(data, pIndex, typeLongInteger, &index, sizeof(long));
GetWindowGlobalBounds(window, &aRect);
err = AEPutKeyPtr(data, pBounds, typeQDRectangle, &aRect, sizeof(Rect));
aPoint.h = aRect.left;
aPoint.v = aRect.top;
err = AEPutKeyPtr(data, pLocation, typeQDPoint, &aPoint, sizeof(Point));
aBoolean = WindowIsCloseable(window);
err = AEPutKeyPtr(data, pHasCloseBox, typeBoolean, &aBoolean, sizeof(Boolean));
aBoolean = WindowHasTitleBar(window);
err = AEPutKeyPtr(data, pHasTitleBar, typeBoolean, &aBoolean, sizeof(Boolean));
aBoolean = WindowIsModal(window);
err = AEPutKeyPtr(data, pIsModal, typeBoolean, &aBoolean, sizeof(Boolean));
aBoolean = WindowIsResizeable(window);
err = AEPutKeyPtr(data, pIsResizable, typeBoolean, &aBoolean, sizeof(Boolean));
aBoolean = WindowIsZoomable(window);
err = AEPutKeyPtr(data, pIsZoomable, typeBoolean, &aBoolean, sizeof(Boolean));
aBoolean = WindowIsZoomed(window);
err = AEPutKeyPtr(data, pIsZoomed, typeBoolean, &aBoolean, sizeof(Boolean));
aBoolean = !WindowIsModal(window);
err = AEPutKeyPtr(data, pIsModeless, typeBoolean, &aBoolean, sizeof(Boolean));
aBoolean = WindowIsModal(window) && WindowHasTitleBar(window);
err = AEPutKeyPtr(data, pIsMovableModal, typeBoolean, &aBoolean, sizeof(Boolean));
aBoolean = WindowIsFloating(window);
err = AEPutKeyPtr(data, pIsFloating, typeBoolean, &aBoolean, sizeof(Boolean));
aBoolean = IsWindowVisible(window);
err = AEPutKeyPtr(data, pVisible, typeBoolean, &aBoolean, sizeof(Boolean));
break;
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
err = AECreateDesc(typeType, &aType, sizeof(DescType), data);
break;
case pBounds:
GetWindowGlobalBounds(window, &aRect);
err = AECreateDesc(typeQDRectangle, &aRect, sizeof(Rect), data);
break;
case pLocation:
GetWindowGlobalBounds(window, &aRect);
aPoint.h = aRect.left;
aPoint.v = aRect.top;
err = AECreateDesc(typeQDPoint, &aPoint, sizeof(Point), data);
break;
case pIsModeless:
aBoolean = !WindowIsModal(window);
err = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
break;
case pIsMovableModal:
aBoolean = WindowIsModal(window) && WindowHasTitleBar(window);
err = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
break;
case pHasCloseBox:
aBoolean = WindowIsCloseable(window);
err = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
break;
case pHasTitleBar:
aBoolean = WindowHasTitleBar(window);
err = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
break;
case pIndex:
index = GetWindowIndex(GetThisWindowKind(), window);
err = AECreateDesc(typeLongInteger, &index, sizeof(long), data);
break;
case pIsModal:
aBoolean = WindowIsModal(window);
err = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
break;
case pIsResizable:
aBoolean = WindowIsResizeable(window);
err = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
break;
case pIsZoomable:
aBoolean = WindowIsZoomable(window);
err = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
break;
case pIsZoomed:
aBoolean = WindowIsZoomed(window);
err = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
break;
case pVisible:
aBoolean = IsWindowVisible(window);
err = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
break;
case pIsFloating:
aBoolean = WindowIsFloating(window);
err = AECreateDesc(typeBoolean, &aBoolean, sizeof(Boolean), data);
break;
case pName: // Synonym for pTitle
case pTitle:
GetCleanedWindowName(window, windowTitle, 255);
err = AECreateDesc(typeChar, windowTitle, strlen(windowTitle), data);
break;
default:
Inherited::GetDataFromObject(token, desiredTypes, data);
break;
}
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
SetDataForObject
----------------------------------------------------------------------------*/
void AEWindowClass::SetDataForObject(const AEDesc *token, AEDesc *data)
{
OSErr err;
AETokenDesc tokenDesc(token);
Boolean usePropertyCode = tokenDesc.UsePropertyCode();
WindowPtr window = tokenDesc.GetWindowPtr();
if (usePropertyCode == false)
{
ThrowIfOSErr(errAEWriteDenied);
}
else
{
DescType propertyCode = tokenDesc.GetPropertyCode();
// Convert the single property to a record containing one property
if (data->descriptorType == typeAERecord)
{
SetWindowProperties(window, data);
}
else // Build a record with one property
{
StAEDesc propertyRecord;
err = AECreateList(nil, 0, true, &propertyRecord);
ThrowIfOSErr(err);
err = AEPutKeyDesc(&propertyRecord, propertyCode, data);
ThrowIfOSErr(err);
SetWindowProperties(window, &propertyRecord);
}
}
}
#pragma mark -
/*----------------------------------------------------------------------------
CanSetProperty
----------------------------------------------------------------------------*/
Boolean AEWindowClass::CanSetProperty(DescType propertyCode)
{
Boolean result = false;
switch (propertyCode)
{
// Properties we can set:
case pProperties:
result = true;
break;
// Properties that can be set only for certain types of windows:
case pTitle:
case pName: // Synonym for pTitle
case pBounds:
case pLocation:
case pIndex:
case pVisible:
case pIsZoomed:
result = true;
break;
// Properties we should be able to set, but not implemented yet:
// Properties we can't set:
default:
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
case pIsModeless:
case pIsMovableModal:
case pIsSuspended:
case pIsPalette:
case pIsDialog:
case pHasCloseBox:
case pHasTitleBar:
case pIsFloating:
case pIsModal:
case pIsResizable:
case pIsZoomable:
result = Inherited::CanSetProperty(propertyCode);
break;
}
return result;
}
/*----------------------------------------------------------------------------
CanGetProperty
----------------------------------------------------------------------------*/
Boolean AEWindowClass::CanGetProperty(DescType propertyCode)
{
Boolean result = false;
switch (propertyCode)
{
// Properties we can get:
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
case pContents:
case pProperties:
case keyAEProperties:
case pTitle:
case pName: // Synonym for pTitle
case pIsModeless:
case pIsMovableModal:
case pIsSuspended:
case pIsPalette:
case pIsDialog:
case pBounds:
case pLocation:
case pHasCloseBox:
case pHasTitleBar:
case pIndex:
case pIsFloating:
case pIsModal:
case pIsResizable:
case pIsZoomable:
case pIsZoomed:
case pVisible:
result = true;
break;
// Properties we can't get:
default:
result = Inherited::CanGetProperty(propertyCode);
break;
}
return result;
}
#pragma mark -
/*----------------------------------------------------------------------------
SetWindowProperties
----------------------------------------------------------------------------*/
void AEWindowClass::SetWindowProperties(WindowPtr window, const AEDesc *propertyRecord)
{
OSErr err = noErr;
OSErr ignoreError = noErr;
long numProperties = 0L;
StAEDesc data;
if (propertyRecord == nil || propertyRecord->descriptorType != typeAERecord)
{
ThrowIfOSErr(errAEWrongDataType);
}
err = AECountItems(propertyRecord, &numProperties);
ThrowIfOSErr(err);
if (numProperties <= 0)
ThrowIfOSErr(paramErr);
StPortSetter portSetter(window);
// pBounds
ignoreError = AEGetKeyDesc(propertyRecord, pBounds, typeQDRectangle, &data);
if (ignoreError != errAEDescNotFound)
{
Rect r;
err = DescToRect(&data, &r);
if (err == noErr)
{
short windowWidth = r.right - r.left;
short windowDepth = r.bottom - r.top;
MoveWindow(window, r.left, r.top, false);
// ¥¥¥ÊDoResize(window, windowWidth, windowDepth);
}
data.Clear();
}
// pLocation
ignoreError = AEGetKeyDesc(propertyRecord, pLocation, typeQDPoint, &data);
if (ignoreError != errAEDescNotFound)
{
Point p;
err = DescToPoint(&data, &p);
if (err == noErr)
MoveWindow(window, p.h, p.v, false); // don't let Window Manager bring it to front!
data.Clear();
}
// pIndex
ignoreError = AEGetKeyDesc(propertyRecord, pIndex, typeLongInteger, &data);
if (ignoreError != errAEDescNotFound)
{
long index;
long numWindows;
WindowPtr behindWindow;
err = DescToLong(&data, &index);
if (err == noErr)
{
numWindows = CountWindows(GetThisWindowKind());
if (index < 0)
index = numWindows + index + 1;
if (index == 1)
{
SelectWindow(window);
}
else
{
behindWindow = GetWindowByIndex(GetThisWindowKind(), index);
if (behindWindow != NULL)
{
SendBehind(window, behindWindow);
}
else
{
err = errAEEventNotHandled;
}
}
}
data.Clear();
}
// pIsZoomed
ignoreError = AEGetKeyDesc(propertyRecord, pIsZoomed, typeBoolean, &data);
if (ignoreError != errAEDescNotFound)
{
Boolean zoomIt;
err = DescToBoolean(&data, &zoomIt);
if (err == noErr)
{
if (zoomIt)
ZoomWindow(window, inZoomOut, false);
else
ZoomWindow(window, inZoomIn, false);
}
data.Clear();
}
// pVisible
ignoreError = AEGetKeyDesc(propertyRecord, pVisible, typeBoolean, &data);
if (ignoreError != errAEDescNotFound)
{
Boolean showIt;
err = DescToBoolean(&data, &showIt);
if (err == noErr)
{
if (showIt)
ShowWindow(window);
else
HideWindow(window);
}
data.Clear();
}
}
#pragma mark -
/*----------------------------------------------------------------------------
MakeWindowObjectSpecifier
----------------------------------------------------------------------------*/
void AEWindowClass::MakeWindowObjectSpecifier(WindowPtr wind, AEDesc *outSpecifier)
{
// fill in the reply with the newly created object
CoreTokenRecord coreToken;
StAEDesc windowToken;
coreToken.window = wind;
OSErr err = ::AECreateDesc(typeObjectSpecifier, &coreToken, sizeof(CoreTokenRecord), &windowToken);
ThrowIfOSErr(err);
CreateSelfSpecifier(&windowToken, outSpecifier);
}
/*----------------------------------------------------------------------------
CreateSelfSpecifier
----------------------------------------------------------------------------*/
void AEWindowClass::CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier)
{
AETokenDesc tokenDesc(token);
WindowPtr window = tokenDesc.GetWindowPtr();
long position = GetWindowIndex(mWindowKind, window);
AEDesc selfDesc = { typeNull, nil };
AEDesc containerSpecifier = { typeNull, nil };
DescType desiredClass = mClass;
DescType keyForm = formAbsolutePosition;
OSErr err = noErr;
GetContainerSpecifier(token, &containerSpecifier);
err = ::AECreateDesc(typeLongInteger, &position, sizeof(long), &selfDesc);
ThrowIfOSErr(err);
err = ::CreateObjSpecifier(desiredClass, &containerSpecifier, keyForm, &selfDesc, true, outSpecifier);
ThrowIfOSErr(err);
}
#pragma mark -
/*----------------------------------------------------------------------------
CountWindows
----------------------------------------------------------------------------*/
long AEWindowClass::CountWindows(TWindowKind windowKind)
{
return CountWindowsOfKind(windowKind);
}
/*----------------------------------------------------------------------------
GetWindowByIndex
----------------------------------------------------------------------------*/
WindowPtr AEWindowClass::GetWindowByIndex(TWindowKind windowKind, long index)
{
return ::GetIndexedWindowOfKind(windowKind, index);
}
/*----------------------------------------------------------------------------
GetWindowByTitle
----------------------------------------------------------------------------*/
WindowPtr AEWindowClass::GetWindowByTitle(TWindowKind windowKind, ConstStr63Param title)
{
CStr255 windowName;
CopyPascalToCString((const StringPtr)title, windowName, 255);
return ::GetNamedOrFrontmostWindow(windowKind, windowName);
}
/*----------------------------------------------------------------------------
GetWindowIndex
----------------------------------------------------------------------------*/
long AEWindowClass::GetWindowIndex(TWindowKind windowKind, WindowPtr window)
{
return ::GetWindowIndex(windowKind, window);
}
/*----------------------------------------------------------------------------
GetPreviousWindow
----------------------------------------------------------------------------*/
WindowPtr AEWindowClass::GetPreviousWindow(TWindowKind windowKind, WindowPtr wind)
{
short windowIndex = GetWindowIndex(windowKind, wind);
return GetIndexedWindowOfKind(windowKind, windowIndex - 1);
}

Просмотреть файл

@ -0,0 +1,179 @@
/* -*- 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>
*/
#ifndef __AEWINDOWCLASS__
#define __AEWINDOWCLASS__
#include "nsAEGenericClass.h"
class AEWindowIterator : public AEClassIterator
{
public:
AEWindowIterator(DescType classType, TWindowKind windowKind)
: AEClassIterator(classType)
, mWindowKind(windowKind)
{}
virtual UInt32 GetNumItems(const AEDesc* containerToken);
virtual ItemRef GetNamedItemReference(const AEDesc* containerToken, const char *itemName);
virtual ItemRef GetIndexedItemReference(const AEDesc* containerToken, TAEListIndex itemIndex);
virtual TAEListIndex GetIndexFromItemID(const AEDesc* containerToken, ItemID itemID);
virtual ItemID GetNamedItemID(const AEDesc* containerToken, const char *itemName);
virtual ItemID GetIndexedItemID(const AEDesc* containerToken, TAEListIndex itemIndex);
// index to name
virtual void GetIndexedItemName(const AEDesc* containerToken, TAEListIndex itemIndex, char *outName, long maxLen);
// conversion routines.
virtual ItemID GetIDFromReference(const AEDesc* containerToken, ItemRef itemRef);
virtual ItemRef GetReferenceFromID(const AEDesc* containerToken, ItemID itemID);
virtual ItemID GetItemIDFromToken(const AEDesc* token);
virtual void SetItemIDInCoreToken(const AEDesc* containerToken, CoreTokenRecord* tokenRecord, ItemID itemID);
TWindowKind GetThisWindowKind() { return mWindowKind; }
protected:
TWindowKind mWindowKind;
};
class AEWindowClass : public AEGenericClass
{
friend class AECoreClass;
private:
typedef AEGenericClass Inherited;
protected:
// only the AECoreClass can instantiate us
AEWindowClass(DescType classType, TWindowKind windowKind);
~AEWindowClass();
void GetDocumentFromWindow( DescType desiredClass, // cWindow
const AEDesc* containerToken, // null container
DescType containerClass, // cApplication
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken); // specified Window is returned in result
virtual void GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
virtual void CompareObjects( DescType comparisonOperator,
const AEDesc * object,
const AEDesc * descriptorOrObject,
Boolean * result);
virtual void CountObjects( DescType desiredType,
DescType containerClass,
const AEDesc * container,
long * result);
public:
// AE Handlers
static pascal OSErr DocumentAccessor( DescType desiredClass, // cDocument
const AEDesc* containerToken, // null container
DescType containerClass, // cApplication
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken, // specified Document is returned in result
long refCon);
protected:
// ----------------------------------------------------------------------------
// Core Suite Object Event handlers
// ----------------------------------------------------------------------------
virtual void HandleClose(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleDataSize(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleDelete(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleDuplicate(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleExists(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleMake(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleMove(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandlePrint(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleQuit(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
virtual void HandleSave(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply);
// ----------------------------------------------------------------------------
// Methods for creating self and container specifiers
// ----------------------------------------------------------------------------
virtual void CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier);
// ----------------------------------------------------------------------------
// Get and Set methods for objects and list
// ----------------------------------------------------------------------------
virtual void GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data);
virtual void SetDataForObject(const AEDesc *token, AEDesc *data);
virtual Boolean CanSetProperty(DescType propertyCode);
virtual Boolean CanGetProperty(DescType propertyCode);
void SetWindowProperties(WindowPtr wind, const AEDesc *propertyRecord);
void MakeWindowObjectSpecifier(WindowPtr wind, AEDesc *outSpecifier);
WindowPtr GetWindowByIndex(TWindowKind windowKind, long index);
WindowPtr GetWindowByTitle(TWindowKind windowKind, ConstStr63Param title);
long GetWindowIndex(TWindowKind windowKind, WindowPtr window);
WindowPtr GetPreviousWindow(TWindowKind windowKind, WindowPtr wind);
TWindowKind GetThisWindowKind() { return mWindowKind; }
public:
static long CountWindows(TWindowKind windowKind);
protected:
TWindowKind mWindowKind;
protected:
OSLAccessorUPP mDocumentAccessor;
};
#endif /* __AEWINDOWCLASS__ */

Просмотреть файл

@ -0,0 +1,353 @@
/* -*- 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 "def.h"
#include "wasteutil.h"
#include "AEUtils.h"
#include "AETextClass.h"
#include "AEWordClass.h"
/*----------------------------------------------------------------------------
GetNumItems
----------------------------------------------------------------------------*/
UInt32 AEWordIterator::GetNumItems(const AEDesc* containerToken)
{
AETokenDesc container(containerToken);
WEReference theWE = container.GetWEReference();
return theWE ? GetWENumWords(theWE) : 0;
}
/*----------------------------------------------------------------------------
GetIndexedItemReference
----------------------------------------------------------------------------*/
AEClassIterator::ItemRef AEWordIterator::GetIndexedItemReference(const AEDesc* containerToken, TAEListIndex itemIndex)
{
return (ItemRef)itemIndex;
}
/*----------------------------------------------------------------------------
GetIndexFromItemID
----------------------------------------------------------------------------*/
TAEListIndex AEWordIterator::GetIndexFromItemID(const AEDesc* containerToken, ItemID itemID)
{
return (TAEListIndex)itemID;
}
/*----------------------------------------------------------------------------
GetIndexedItemID
----------------------------------------------------------------------------*/
AEClassIterator::ItemID AEWordIterator::GetIndexedItemID(const AEDesc* containerToken, TAEListIndex itemIndex)
{
return (ItemID)GetIndexedItemReference(containerToken, itemIndex);
}
/*----------------------------------------------------------------------------
GetIDFromReference
----------------------------------------------------------------------------*/
AEClassIterator::ItemID AEWordIterator::GetIDFromReference(const AEDesc* containerToken, ItemRef itemRef)
{
return (ItemID)itemRef;
}
/*----------------------------------------------------------------------------
GetReferenceFromID
----------------------------------------------------------------------------*/
AEClassIterator::ItemRef AEWordIterator::GetReferenceFromID(const AEDesc* containerToken, ItemID itemID)
{
return (ItemRef)itemID;
}
/*----------------------------------------------------------------------------
GetItemIDFromToken
----------------------------------------------------------------------------*/
AEClassIterator::ItemID AEWordIterator::GetItemIDFromToken(const AEDesc* token)
{
AETokenDesc container(token);
return (ItemID)container.GetElementNumber();
}
/*----------------------------------------------------------------------------
SetItemIDInCoreToken
----------------------------------------------------------------------------*/
void AEWordIterator::SetItemIDInCoreToken(const AEDesc* containerToken, CoreTokenRecord* tokenRecord, ItemID itemID)
{
AETokenDesc tokenDesc(containerToken);
WindowPtr wind = tokenDesc.GetWindowPtr();
WEReference theWE = tokenDesc.GetWEReference();
tokenRecord->window = wind;
tokenRecord->theWE = theWE;
tokenRecord->elementNumber = (TAEListIndex)itemID;
}
#pragma mark -
/*----------------------------------------------------------------------------
AEWordClass
----------------------------------------------------------------------------*/
AEWordClass::AEWordClass()
: AEGenericClass(cWord, AETextClass::cTEText)
{
}
/*----------------------------------------------------------------------------
~AEWordClass
----------------------------------------------------------------------------*/
AEWordClass::~AEWordClass()
{
}
#pragma mark -
/*----------------------------------------------------------------------------
GetItemFromContainer
----------------------------------------------------------------------------*/
void AEWordClass::GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken)
{
AEWordIterator wordIterator;
wordIterator.GetItemFromContainer(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken);
}
/*----------------------------------------------------------------------------
CountObjects
----------------------------------------------------------------------------*/
void AEWordClass::CountObjects( DescType desiredType,
DescType containerClass,
const AEDesc * container,
long * result)
{
AEWordIterator wordIterator;
long numItems = wordIterator.GetNumItems(container);
*result = numItems;
}
#pragma mark -
/*----------------------------------------------------------------------------
GetDataFromObject
----------------------------------------------------------------------------*/
void AEWordClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data)
{
AETokenDesc tokenDesc(token);
DescType aDescType = cWord;
DescType propertyCode = tokenDesc.GetPropertyCode();
WindowPtr window = tokenDesc.GetWindowPtr();
WEReference theWE = tokenDesc.GetWEReference();
TAEListIndex wordIndex = tokenDesc.GetElementNumber();
OSErr err = noErr;
long wordStart, wordEnd;
ThrowErrIfNil(theWE, errAENoSuchObject);
switch (propertyCode)
{
case pProperties:
err = AECreateList(nil, 0, true, data);
ThrowIfOSErr(err);
err = AEPutKeyPtr(data, pObjectType, typeType, &aDescType, sizeof(DescType));
break;
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
err = AECreateDesc(typeType, &aDescType, sizeof(DescType), data);
ThrowIfOSErr(err);
break;
case pContents:
case typeNull:
{
err = GetWEIndexedWordOffsets(theWE, wordIndex, &wordStart, &wordEnd);
ThrowIfOSErr(err);
Handle weHand = WEGetText(theWE);
StHandleLocker lockHand(weHand);
err = AECreateDesc(typeChar, *weHand + wordStart, wordEnd - wordStart,data);
ThrowIfOSErr(err);
}
break;
default:
Inherited::GetDataFromObject(token, desiredTypes, data);
break;
}
ThrowIfOSErr(err);
}
/*----------------------------------------------------------------------------
GetDataFromObject
----------------------------------------------------------------------------*/
void AEWordClass::SetDataForObject(const AEDesc *token, AEDesc *data)
{
AETokenDesc tokenDesc(token);
DescType aDescType = cWord;
DescType propertyCode = tokenDesc.GetPropertyCode();
WindowPtr window = tokenDesc.GetWindowPtr();
WEReference theWE = tokenDesc.GetWEReference();
TAEListIndex wordIndex = tokenDesc.GetElementNumber();
OSErr err = noErr;
long wordStart, wordEnd;
ThrowErrIfNil(theWE, errAENoSuchObject);
switch (propertyCode)
{
case pContents:
case typeNull:
{
err = GetWEIndexedWordOffsets(theWE, wordIndex, &wordStart, &wordEnd);
ThrowIfOSErr(err);
}
break;
}
ThrowIfOSErr(err);
}
#pragma mark -
/*----------------------------------------------------------------------------
CanSetProperty
----------------------------------------------------------------------------*/
Boolean AEWordClass::CanSetProperty(DescType propertyCode)
{
Boolean result = false;
switch (propertyCode)
{
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
result = false;
break;
case typeNull:
result = true; // contents
break;
case pProperties:
default:
result = Inherited::CanSetProperty(propertyCode);
break;
}
return result;
}
/*----------------------------------------------------------------------------
CanGetProperty
----------------------------------------------------------------------------*/
Boolean AEWordClass::CanGetProperty(DescType propertyCode)
{
Boolean result = false;
switch (propertyCode)
{
// Properties we can get:
case pBestType:
case pClass:
case pDefaultType:
case pObjectType:
case pProperties:
result = true;
break;
default:
result = Inherited::CanGetProperty(propertyCode);
break;
}
return result;
}
#pragma mark -
/*----------------------------------------------------------------------------
CreateSelfSpecifier
----------------------------------------------------------------------------*/
void AEWordClass::CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier)
{
AETokenDesc tokenDesc(token);
WEReference theWE = tokenDesc.GetWEReference();
TAEListIndex wordIndex = tokenDesc.GetElementNumber();
AEDesc selfDesc = { typeNull, nil };
AEDesc containerSpecifier = { typeNull, nil };
OSErr err = noErr;
GetContainerSpecifier(token, &containerSpecifier);
err = ::AECreateDesc(typeLongInteger, &wordIndex, sizeof(TAEListIndex), &selfDesc);
ThrowIfOSErr(err);
err = ::CreateObjSpecifier(mClass, &containerSpecifier, formAbsolutePosition, &selfDesc, true, outSpecifier);
ThrowIfOSErr(err);
}

Просмотреть файл

@ -0,0 +1,94 @@
/* -*- 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>
*/
#ifndef __AEWORDCLASS__
#define __AEWORDCLASS__
#include "AEGenericClass.h"
class AEWordClass : public AEGenericClass
{
friend class AECoreClass;
private:
typedef AEGenericClass Inherited;
public:
AEWordClass();
~AEWordClass();
virtual void GetItemFromContainer( DescType desiredClass,
const AEDesc* containerToken,
DescType containerClass,
DescType keyForm,
const AEDesc* keyData,
AEDesc* resultToken);
virtual void CountObjects( DescType desiredType,
DescType containerClass,
const AEDesc * container,
long * result);
// ----------------------------------------------------------------------------
// Methods for creating self and container specifiers
// ----------------------------------------------------------------------------
virtual void CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier);
virtual void GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data);
virtual void SetDataForObject(const AEDesc *token, AEDesc *data);
virtual Boolean CanSetProperty(DescType propertyCode);
virtual Boolean CanGetProperty(DescType propertyCode);
};
class AEWordIterator : public AEUnnamedClassIterator
{
public: AEWordIterator()
: AEUnnamedClassIterator(cWord)
{
}
virtual UInt32 GetNumItems(const AEDesc* containerToken);
virtual ItemRef GetIndexedItemReference(const AEDesc* containerToken, TAEListIndex itemIndex);
virtual TAEListIndex GetIndexFromItemID(const AEDesc* containerToken, ItemID itemID);
virtual ItemID GetIndexedItemID(const AEDesc* containerToken, TAEListIndex itemIndex);
// conversion routines.
virtual ItemID GetIDFromReference(const AEDesc* containerToken, ItemRef itemRef);
virtual ItemRef GetReferenceFromID(const AEDesc* containerToken, ItemID itemID);
virtual ItemID GetItemIDFromToken(const AEDesc* token);
virtual void SetItemIDInCoreToken(const AEDesc* containerToken, CoreTokenRecord* tokenRecord, ItemID itemID);
};
#endif // __AEWORDCLASS__

Просмотреть файл

@ -0,0 +1,157 @@
/* -*- Mode: C; tab-width: 4; 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):
*/
/*----------------------------------------------------------------------------
The Apple Events Template resource 'aedt' (found in Types.r)
is used to associate an Event Class and Event ID with a
unique integer value. These integer values are private to the
application processing the events.
restriction: PowerPlant uses integer valuse below 4000
All data for aetds is now centrally located in resae.h
----------------------------------------------------------------------------*/
#include "types.r"
// #include "AEUserTermTypes.r"
#include "nsAppleEvents.h" // Provides AE Types, IDs, and AE_RefNums
// Found in mozilla/xpfe/appshell/public
/*--------------------------------------------------------------------------*/
/* ----- World Wide Web - Spyglass Suite ----- */
/*--------------------------------------------------------------------------*/
resource 'aedt' (kSpyGlass_aedtResID, "World-Wide-Web Suite (Spyglass spec)") {
{
AE_spy_receive_suite, AE_spy_openURL, AE_OpenURL, // WWW! OURL
#ifndef MOZILLA_FIVE
AE_spy_receive_suite, AE_spy_registerViewer, AE_RegisterViewer, // WWW! RGVW
AE_spy_receive_suite, AE_spy_unregisterViewer, AE_UnregisterViewer, // WWW! UNRV
AE_spy_receive_suite, AE_spy_showFile, AE_ShowFile, // WWW! SHWF
AE_spy_receive_suite, AE_spy_parse, AE_ParseAnchor, // WWW! PRSA
AE_spy_receive_suite, AE_spy_registerURLecho, AE_RegisterURLEcho, // WWW! RGUE
AE_spy_receive_suite, AE_spy_unregisterURLecho, AE_UnregisterURLEcho, // WWW! UNRU
AE_spy_receive_suite, AE_spy_activate, AE_SpyActivate, // WWW! ACTV
AE_spy_receive_suite, AE_spy_listwindows, AE_SpyListWindows, // WWW! LSTW
AE_spy_receive_suite, AE_spy_getwindowinfo, AE_GetWindowInfo, // WWW! WNFO
AE_spy_receive_suite, AE_spy_registerWinClose, AE_RegisterWinClose, // WWW! RGWC
AE_spy_receive_suite, AE_spy_unregisterWinClose, AE_UnregisterWinClose, // WWW! UNRC
AE_spy_receive_suite, AE_spy_register_protocol, AE_RegisterProtocol, // WWW! RGPR
AE_spy_receive_suite, AE_spy_unregister_protocol, AE_UnregisterProtocol, // WWW! UNRP
AE_spy_receive_suite, AE_spy_CancelProgress, AE_CancelProgress, // WWW! CNCL
AE_spy_receive_suite, AE_spy_findURL, AE_FindURL // WWW! FURL
#endif // MOZILLA_FIVE
}
};
/*--------------------------------------------------------------------------*/
/* ----- Netscape and Macintosh Std URL Suites ----- */
/*--------------------------------------------------------------------------*/
resource 'aedt' (kURLSuite_aedtResID, "Netscape & URL suite") {
{
#ifdef MOZILLA_FIVE
AE_url_suite, AE_url_getURL, AE_GetURL // GURL GURL
, AE_www_suite, AE_www_doJavaScript, AE_DoJavascript // MOSS jscr
#else
AE_www_suite, AE_www_workingURL, AE_GetWD // MOSS wurl
, AE_www_suite, AE_www_openBookmark, AE_OpenBookmark // MOSS book
, AE_www_suite, AE_www_ReadHelpFile, AE_ReadHelpFile // MOSS help
, AE_www_suite, AE_www_go, AE_Go // MOSS gogo
, AE_url_suite, AE_url_getURL, AE_GetURL // GURL GURL
, AE_www_suite, AE_www_ProfileManager, AE_OpenProfileManager // MOSS prfl
, AE_www_suite, AE_www_openAddressBook, AE_OpenAddressBook // MOSS addr
, AE_www_suite, AE_www_openComponent, AE_OpenComponent // MOSS cpnt
, AE_www_suite, AE_www_getActiveProfile, AE_GetActiveProfile // MOSS upro
, AE_www_suite, AE_www_handleCommand, AE_HandleCommand // MOSS hcmd
, AE_www_suite, AE_www_getImportData, AE_GetProfileImportData // MOSS Impt
, AE_www_suite, AE_www_GuestMode, AE_OpenGuestMode // MOSS gues
#endif // MOZILLA_FIVE
}
};
/*--------------------------------------------------------------------------*/
/* Required Suite, we will leave this hard wired for now */
/*--------------------------------------------------------------------------*/
resource 'aedt' (kRequired_aedtResID, "Required Suite") {
{
'aevt', 'oapp', 1001,
'aevt', 'odoc', 1002,
'aevt', 'pdoc', 1003,
'aevt', 'quit', 1004
}
};
/*--------------------------------------------------------------------------*/
/* Core Suite, we will leave this hard wired for now */
/*--------------------------------------------------------------------------*/
resource 'aedt' (kCore_aedtResID, "Core Suite") {
{
'core', 'clon', 2001,
'core', 'clos', 2002,
'core', 'cnte', 2003,
'core', 'crel', 2004,
'core', 'delo', 2005,
'core', 'doex', 2006,
'core', 'qobj', 2007,
'core', 'getd', 2008,
'core', 'dsiz', 2009,
'core', 'gtei', 2010,
'core', 'move', 2011,
'core', 'save', 2012,
'core', 'setd', 2013
}
};
/*--------------------------------------------------------------------------*/
/* Misc Standards, we will leave this hard wired for now */
/*--------------------------------------------------------------------------*/
resource 'aedt' (kMisc_aedtResID, "Misc Standards") {
{
'aevt', 'obit', 3001,
'misc', 'begi', 3002,
'misc', 'copy', 3003,
'misc', 'cpub', 3004,
'misc', 'cut ', 3005,
'misc', 'dosc', 3006,
'misc', 'edit', 3007,
'misc', 'endt', 3008,
'misc', 'imgr', 3009,
'misc', 'isun', 3010,
'misc', 'mvis', 3011,
'misc', 'past', 3012,
'misc', 'redo', 3013,
'misc', 'rvrt', 3014,
'misc', 'ttrm', 3015,
'misc', 'undo', 3016
}
};

Двоичные данные
xpfe/bootstrap/appleevents/nsAppleEvents.rsrc Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,53 @@
/* -*- 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 "nsAppleEventsService.h"
#include "nsAECoreClass.h"
nsAppleEventsService::nsAppleEventsService()
{
NS_INIT_REFCNT();
}
nsAppleEventsService::~nsAppleEventsService()
{
}
NS_IMPL_ISUPPORTS(nsAppleEventsService, NS_GET_IID(nsIAppleEventsService));
NS_IMETHODIMP nsAppleEventsService::Init(void)
{
OSErr err = CreateAEHandlerClasses(false);
return (err == noErr) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsAppleEventsService::Shutdown(void)
{
ShutdownAEHandlerClasses();
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,51 @@
/* -*- 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>
*/
#ifndef nsAppleEventService_h_
#define nsAppleEventService_h_
#include "nsIAppleEventsService.h"
// this is currently unused
class nsAppleEventsService : public nsIAppleEventsService
{
public:
nsAppleEventsService();
virtual ~nsAppleEventsService();
NS_DECL_ISUPPORTS
NS_DECL_NSIAPPLEEVENTSSERVICE
protected:
};
#endif // nsAppleEventService_h_

Просмотреть файл

@ -0,0 +1,174 @@
/* -*- 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 <stdlib.h>
#include "nsMacUtils.h"
OSErr MyNewHandle(long length, Handle *outHandle)
{
Handle tempHandle = NewHandle(length);
if (!tempHandle) return memFullErr;
*outHandle = tempHandle;
return noErr;
}
void MyDisposeHandle(Handle theHandle)
{
if (theHandle)
DisposeHandle(theHandle);
}
void MyHLock(Handle theHandle)
{
HLock(theHandle);
}
void MyHUnlock(Handle theHandle)
{
HUnlock(theHandle);
}
#pragma mark -
OSErr MyNewBlockClear(long length, void* *outBlock)
{
void* newData = calloc(length, 1);
if (!newData) return memFullErr;
*outBlock = newData;
return noErr;
}
void MyDisposeBlock(void *dataBlock)
{
if (dataBlock)
free(dataBlock);
}
#pragma mark -
/*----------------------------------------------------------------------------
StrCopySafe
strcpy which checks destination buffer length
----------------------------------------------------------------------------*/
void StrCopySafe(char *dst, const char *src, long destLen)
{
const unsigned char *p = (unsigned char *) src - 1;
unsigned char *q = (unsigned char *) dst - 1;
unsigned char *end = (unsigned char *)dst + destLen;
while ( q < end && (*++q = (*++p)) != '\0' ) {;}
if (q == end)
*q = '\0';
}
/*----------------------------------------------------------------------------
CopyPascalString
Copy a pascal format string.
Entry: to = pointer to destination string.
from = pointer to source string.
----------------------------------------------------------------------------*/
void CopyPascalString (StringPtr to, const StringPtr from)
{
BlockMoveData(from, to, *from+1);
}
/*----------------------------------------------------------------------------
CopyCToPascalString
Copy from a C string to a Pascal string, up to maxLen chars.
----------------------------------------------------------------------------*/
void CopyCToPascalString(const char *src, StringPtr dest, long maxLen)
{
char *s = (char *)src;
char *d = (char *)(&dest[1]);
long count = 0;
while (count < maxLen && *s) {
*d ++ = *s ++;
count ++;
}
dest[0] = (unsigned char)(count);
}
/*----------------------------------------------------------------------------
CopyPascalToCString
Copy from a C string to a Pascal string, up to maxLen chars.
----------------------------------------------------------------------------*/
void CopyPascalToCString(const StringPtr src, char *dest, long maxLen)
{
short len = Min(maxLen, src[0]);
BlockMoveData(&src[1], dest, len);
dest[len] = '\0';
}
/*----------------------------------------------------------------------------
GetShortVersionString
Extracts the version number string from the specified 'vers' resource and
concats it onto the end of the specified string (Pascal-style). The short
version number string is extracted.
Exit: function result = error code.
*versionNumber = version number.
----------------------------------------------------------------------------*/
OSErr GetShortVersionString(short rID, StringPtr version)
{
VersRecHndl versionH;
OSErr error = resNotFound;
versionH = (VersRecHndl)Get1Resource('vers', rID);
if (versionH)
{
CopyPascalString(version, (**versionH).shortVersion);
ReleaseResource((Handle) versionH);
error = noErr;
}
else
CopyPascalString("\p<unknown>", version);
return error;
}

Просмотреть файл

@ -0,0 +1,62 @@
/* -*- 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>
*/
#ifndef nsMacUtils_h_
#define nsMacUtils_h_
#include <MacTypes.h>
#include <Memory.h>
#include <Errors.h>
#include <Resources.h>
#define Min(a, b) ((a) < (b) ? (a) : (b))
#ifdef __cplusplus
extern "C" {
#endif
OSErr MyNewHandle(long length, Handle *outHandle);
void MyDisposeHandle(Handle theHandle);
void MyHLock(Handle theHandle);
void MyHUnlock(Handle theHandle);
OSErr MyNewBlockClear(long length, void* *outBlock);
void MyDisposeBlock(void *dataBlock);
void StrCopySafe(char *dst, const char *src, long destLen);
void CopyPascalString (StringPtr to, const StringPtr from);
void CopyCToPascalString(const char *src, StringPtr dest, long maxLen);
void CopyPascalToCString(const StringPtr src, char *dest, long maxLen);
OSErr GetShortVersionString(short rID, StringPtr version);
#ifdef __cplusplus
}
#endif
#endif /* nsMacUtils_h_ */

Просмотреть файл

@ -0,0 +1,203 @@
/* -*- 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 "nsWindowUtils.h"
long CountWindowsOfKind(TWindowKind windowKind)
{
// ¥¥¥ write me
return 0;
}
WindowPtr GetNamedOrFrontmostWindow(TWindowKind windowKind, const char* windowName)
{
// ¥¥¥ write me
return NULL;
}
WindowPtr GetIndexedWindowOfKind(TWindowKind windowKind, TAEListIndex index)
{
// ¥¥¥ write me
return NULL;
}
TAEListIndex GetWindowIndex(TWindowKind windowKind, WindowPtr theWindow)
{
// ¥¥¥ write me
return 0;
}
void GetCleanedWindowName(WindowPtr wind, char* outName, long maxLen)
{
// ¥¥¥ write me
*outName = '\0';
}
//---------------------------------------------------------
inline void GetWindowPortRect(WindowPtr wind, Rect *outRect)
{
*outRect = wind->portRect;
}
/*----------------------------------------------------------------------------
LocalToGlobalRect
Convert a rectangle from local to global coordinates.
Entry: r = pointer to rectangle.
----------------------------------------------------------------------------*/
static void LocalToGlobalRect (Rect *r)
{
LocalToGlobal((Point*)&r->top);
LocalToGlobal((Point*)&r->bottom);
}
void GetWindowGlobalBounds(WindowPtr wind, Rect* outBounds)
{
GrafPtr curPort;
GetWindowPortRect(wind, outBounds);
GetPort(&curPort);
SetPort(wind);
LocalToGlobalRect(outBounds);
SetPort(curPort);
}
#pragma mark -
/*----------------------------------------------------------------------------
WindowIsResizeable
----------------------------------------------------------------------------*/
Boolean WindowIsResizeable(WindowPtr wind)
{
OSStatus status;
UInt32 features;
status = GetWindowFeatures(wind, &features);
return ((status == noErr) && ((features & kWindowCanGrow) != 0));
}
/*----------------------------------------------------------------------------
WindowIsZoomable
----------------------------------------------------------------------------*/
Boolean WindowIsZoomable(WindowPtr wind)
{
OSStatus status;
UInt32 features;
status = GetWindowFeatures(wind, &features);
return ((status == noErr) && ((features & kWindowCanZoom) != 0));
}
/*----------------------------------------------------------------------------
WindowIsZoomed
----------------------------------------------------------------------------*/
Boolean WindowIsZoomed(WindowPtr wind)
{
Rect r, userRect;
GetWindowUserState(wind, &userRect);
GetWindowPortRect(wind, &r);
OffsetRect(&userRect, -userRect.left, -userRect.top);
return EqualRect(&userRect, &r);
}
/*----------------------------------------------------------------------------
WindowHasTitleBar
This stuff only works in 8.0 and later (Appearance Mgr)
----------------------------------------------------------------------------*/
Boolean WindowHasTitleBar(WindowPtr wind)
{
OSStatus status;
UInt32 features;
status = GetWindowFeatures(wind, &features);
return ((status == noErr) && ((features & kWindowHasTitleBar) != 0));
}
/*----------------------------------------------------------------------------
WindowIsCloseable
This stuff only works in 8.5 and later (Appearance Mgr)
----------------------------------------------------------------------------*/
Boolean WindowIsCloseable(WindowPtr wind)
{
if ((long)GetWindowAttributes != kUnresolvedCFragSymbolAddress)
{
OSStatus status;
UInt32 attributes;
status = GetWindowAttributes(wind, &attributes);
return ((status == noErr) && ((attributes & kWindowCloseBoxAttribute) != 0));
}
return true;
}
/*----------------------------------------------------------------------------
WindowIsModal
This stuff only works in 8.0 and later (Appearance Mgr)
----------------------------------------------------------------------------*/
Boolean WindowIsModal(WindowPtr wind)
{
OSStatus status;
UInt32 features;
status = GetWindowFeatures(wind, &features);
return ((status == noErr) && ((features & kWindowIsModal) != 0));
}
/*----------------------------------------------------------------------------
WindowIsFloating
----------------------------------------------------------------------------*/
Boolean WindowIsFloating(WindowPtr wind)
{
WindowClass windClass;
if (GetWindowClass(wind, &windClass) == noErr)
{
return (windClass == kFloatingWindowClass);
}
return false;
}
/*----------------------------------------------------------------------------
WindowIsModified
----------------------------------------------------------------------------*/
Boolean WindowIsModified(WindowPtr wind)
{
// ¥¥¥ write me
return false;
}

Просмотреть файл

@ -0,0 +1,62 @@
/* -*- 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>
*/
#ifndef nsWindowUtils_h_
#define nsWindowUtils_h_
#include <QuickDraw.h>
#include <MacWindows.h>
#include "nsAEDefs.h"
#ifdef __cplusplus
extern "C" {
#endif
long CountWindowsOfKind(TWindowKind windowKind);
WindowPtr GetNamedOrFrontmostWindow(TWindowKind windowKind, const char* windowName);
WindowPtr GetIndexedWindowOfKind(TWindowKind windowKind, TAEListIndex index);
TAEListIndex GetWindowIndex(TWindowKind windowKind, WindowPtr theWindow);
void GetCleanedWindowName(WindowPtr wind, char* outName, long maxLen);
void GetWindowGlobalBounds(WindowPtr wind, Rect* outRect);
Boolean WindowIsResizeable(WindowPtr wind);
Boolean WindowIsZoomable(WindowPtr wind);
Boolean WindowIsZoomed(WindowPtr wind);
Boolean WindowHasTitleBar(WindowPtr wind);
Boolean WindowIsModal(WindowPtr wind);
Boolean WindowIsCloseable(WindowPtr wind);
Boolean WindowIsFloating(WindowPtr wind);
Boolean WindowIsModified(WindowPtr wind);
#ifdef __cplusplus
}
#endif
#endif // nsWindowUtils_h_

Просмотреть файл

@ -0,0 +1,520 @@
/* -*- 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>
*/
/*---------------------------------------------------------------------
Patricia
D.R. Morrison's "Practical Algorithm To Retrieve Information
Coded in Alphanumeric"
This implementation geared towards the storage of data that
is indexed through arbitrary-length binary keys (e.g. sequence
data). It also only deals with the case where every key is unique;
duplicate keys are not entered into the tree, although you may
do some processing on duplicates in the ReplaceFunction passed
to PatriciaInsert.
There is no function to remove nodes from the tree at present.
The implementation is modular, in the sense that all tree data structures
are declared in this file, and are not intended to be accessed externally.
You should only use the functions prototyped in patricia.h, all of which
start with 'Patricia', and should consider the tree as an opaque data
structure.
Ref: Donald R. Morrison. PATRICIA -- practical algorithm to retrieve
information coded in alphanumeric. Journal of the ACM, 15(4):514-534,
October 1968
See Sedgewick, R. Algorithms, 2nd Ed. (1988) for implemenation details.
-----------------------------------------------------------------------*/
#include <string.h>
#include <stdlib.h>
//#include "utils.h"
#include "patricia.h"
#include "nsAEDefs.h" // for ASSERT
/* Uncomment to print verbose logging on tree activity */
//#define VERBOSE
/* Data structures */
typedef struct TNodeTag {
unsigned char *key; /* The node's key value in an array of chars */
short bit; /* The bit that is examined at this node */
long nodeID; /* Unique ID for each node, used for debugging */
struct TNodeTag *left; /* Pointer to left child node */
struct TNodeTag *right; /* Pointer to right child node */
void *data; /* Pointer to user-defined data structure */
} TNode;
typedef struct {
TNode* headNode; /* Pointer to dummy head node */
long numKeyBits; /* Size of keys, in bits */
long keySize; /* Size of keys, in chars (assumed to be 8 bits each) */
long numNodes; /* Number of nodes in tree */
} TPatriciaTree;
/* These macros assume that key is a *[unsigned] char, and that a char is 8 bits big */
#define TestKeyBit(key, bit) ( (key[bit >> 3] & (1 << (bit & 7))) != 0 )
#define CompareKeyBits(key1, key2, bit) ( (key1[bit >> 3] & (1 << (bit & 7))) == (key2[bit >> 3] & (1 << (bit & 7))) )
/*---------------------------------------------------------------------
MakeNewNode
Allocates a new node as an object on the heap, and initializes
the key and bit values to those supplied.
Entry: key binary key data
bit bit value
nodeData user data for this node, if any.
Exit: return value pointer to the new node, or NULL on error
-----------------------------------------------------------------------*/
static TNode *MakeNewNode(TPatriciaTree *tree, const unsigned char *key, short bit, void *nodeData)
{
static long nodeID = 0;
TNode *newNode;
newNode = (TNode *)calloc(1, sizeof(TNode));
if (newNode == NULL) return NULL;
newNode->key = (unsigned char *)calloc(tree->keySize + 1, 1); //last bit must be zero
if (newNode->key == NULL) {
free(newNode);
return NULL;
}
memcpy(newNode->key, key, tree->keySize);
newNode->bit = bit;
newNode->data = nodeData;
newNode->nodeID = nodeID;
nodeID ++;
return newNode;
}
/*---------------------------------------------------------------------
MakeHeadNode
Allocates the dummy head node of the tree, which is initialized to
key field = 000000...
bits = numKeyBits
left & right = point to self
data = NULL
Exit: return value pointer to the new node, or NULL on error
-----------------------------------------------------------------------*/
static TNode *MakeHeadNode(TPatriciaTree *tree)
{
TNode *newNode;
newNode = (TNode *)calloc(1, sizeof(TNode));
if (newNode == NULL) return NULL;
newNode->key = (unsigned char *)calloc(tree->keySize + 1, 1); //last bit must be zero
if (newNode->key == NULL) {
free(newNode);
return NULL;
}
memset(newNode->key, 0, tree->keySize);
newNode->bit = tree->numKeyBits;
newNode->data = NULL;
newNode->nodeID = -1;
/* Both self-pointers for the head node */
newNode->left = newNode;
newNode->right = newNode;
return newNode;
}
/*---------------------------------------------------------------------
InternalSearch
Search the tree for a node with the given key, starting at
startNode.
Entry: tree pointer to a tree
key binary key data
startNode node to start the search (must NOT be NULL)
Exit: return value: pointer to found node, or node with upward
link. The caller must verify whether this
is the node wanted by comparing keys.
-----------------------------------------------------------------------*/
static TNode *InternalSearch(TPatriciaTree *tree, TNode *x, const unsigned char *key)
{
TNode *p;
ASSERT(x, "No node");
do {
p = x;
if (TestKeyBit(key, x->bit))
x = x->right;
else
x = x->left;
} while (p->bit > x->bit);
return x;
}
/*---------------------------------------------------------------------
InternalTraverse
A traverse routine used internally.
Entry: tree pointer to a tree
key binary key data
x node to start the search (must NOT be NULL)
traverseFunc function called on each node, like this:
(*traverseFunc)(x->data, x->key, arg1, arg2);
Exit: return value: 0 if everything OK
Non-zero value on error
-----------------------------------------------------------------------*/
static int InternalTraverse(TPatriciaTree *tree, TNode *x, NodeTraverseFunction traverseFunc, void *arg1, void *arg2)
{
TNode *p;
int err = 0;
ASSERT(x, "No node");
ASSERT(x->left && x->right, "Left or right child missing");
#ifdef VERBOSE
printf("Visiting node %ld with left %ld and right %ld\n", x->nodeID, x->left->nodeID, x->right->nodeID);
#endif
if (x != tree->headNode) {
err = (*traverseFunc)(x->data, x->key, arg1, arg2);
if (err != 0) return err;
}
p = x->left;
if (p->bit < x->bit)
err = InternalTraverse(tree, p, traverseFunc, arg1, arg2);
if (err != 0) return err;
p = x->right;
if (p->bit < x->bit)
err = InternalTraverse(tree, p, traverseFunc, arg1, arg2);
return err;
}
/*---------------------------------------------------------------------
TraverseAndFree
A traverse routine used internall.
Entry: tree pointer to a tree
key binary key data
x node to start the search (must NOT be NULL)
traverseFunc function called on each node, like this:
(*traverseFunc)(x->data, x->key, arg1, arg2);
Exit: return value: 0 if everything OK
Non-zero value on error
-----------------------------------------------------------------------*/
static int TraverseAndFree(TPatriciaTree *tree, TNode *x, NodeFreeFunction freeFunc, void *refCon)
{
TNode *p;
int err = 0;
ASSERT(x, "No node");
ASSERT(x->left && x->right, "Left or right child missing");
p = x->left;
if (p->bit < x->bit) {
err = TraverseAndFree(tree, p, freeFunc, refCon);
if (err != 0) return err;
}
p = x->right;
if (p->bit < x->bit) {
err = TraverseAndFree(tree, p, freeFunc, refCon);
if (err != 0) return err;
}
err = (*freeFunc)(x->data, x->key, refCon);
#ifdef VERBOSE
printf("Freeing node %ld\n", x->nodeID);
#endif
free(x->key);
free(x);
return err;
}
#pragma mark -
/*---------------------------------------------------------------------
InitPatriciaTree
Allocate and initialize a new, empty PatriciaTree.
Entry: keySize length of the keys, in bits
Exit: return value A reference to the created PatriciaTree,
or NULL on error.
-----------------------------------------------------------------------*/
PatriciaTreeRef PatriciaInitTree(long numKeyBits)
{
TPatriciaTree *tree = NULL;
tree = (TPatriciaTree *)calloc(1, sizeof(TPatriciaTree));
if (tree == NULL) return NULL;
tree->numKeyBits = numKeyBits;
tree->keySize = (numKeyBits >> 3) + ((numKeyBits & 7) != 0);
tree->numNodes = 0;
tree->headNode = MakeHeadNode(tree);
if (tree->headNode == NULL) {
free(tree);
return NULL;
}
return (PatriciaTreeRef)tree;
}
/*---------------------------------------------------------------------
PatriciaFreeTree
Free a Patricia tree and all associate data structures. freeFunc is
called on each node's node->data. If no freeFunc is supplied, then
the node->data will NOT be freed.
Entry: treeRef reference to a previously allocated PatriciaTree
freeFunc a function that is called on each node->data
arg pointer to data that is also passed to the free function.
The free function is called like this: (*freeFunc)(node->data, node->key, arg)
-----------------------------------------------------------------------*/
void PatriciaFreeTree(PatriciaTreeRef treeRef, NodeFreeFunction freeFunc, void *refCon)
{
TPatriciaTree *tree = (TPatriciaTree *)treeRef;
if (tree == NULL) return;
/* Traverse the tree and free the data */
TraverseAndFree(tree, tree->headNode, freeFunc, refCon);
free(tree);
}
/*---------------------------------------------------------------------
PatriciaSearch
Search the tree for the node with the given key.
Entry: key pointer to binary key data
data pointer to placeholder for returned data
If you pass NULL in this argument, no value
will be returned (i.e. I don't deference 0).
Exit: return value 1 if key found (data returned in *data)
0 if key not found (NULL returned in *data)
-----------------------------------------------------------------------*/
int PatriciaSearch(PatriciaTreeRef treeRef, const unsigned char *key, void **data)
{
TPatriciaTree *tree = (TPatriciaTree *)treeRef;
TNode *foundNode;
ASSERT(tree, "Where is my tree?");
foundNode = InternalSearch(tree, tree->headNode, key);
ASSERT(foundNode, "Should have found node");
if (memcmp(foundNode->key, key, tree->keySize) == 0) {
if (data != NULL)
*data = foundNode->data;
return 1;
} else
return 0;
}
/*---------------------------------------------------------------------
PatriciaInsert
Insert a node into the tree with the given key and data.
Entry: key pointer to binary key data
replaceFunc function executed when a node with the key we
are inserting is found in the tree.
data pointer to node data structure
Exit: return value 0 if insertion successful
1 if key already exists
-1 if some other error
-----------------------------------------------------------------------*/
int PatriciaInsert(PatriciaTreeRef treeRef, NodeReplaceFunction replaceFunc, const unsigned char *key, void *data, void *refCon)
{
TPatriciaTree *tree = (TPatriciaTree *)treeRef;
TNode *x, *t, *p;
short i;
x = tree->headNode;
t = InternalSearch(tree, x, key);
ASSERT(t, "Should have found node");
if (memcmp(t->key, key, tree->keySize) == 0) {
if (replaceFunc) (*replaceFunc)(&t->data, t->key, data, refCon);
return 1; /* It's already there */
}
i = tree->numKeyBits - 1;
while (CompareKeyBits(key, t->key, i))
i --;
do {
p = x;
x = (TestKeyBit(key, x->bit)) ? x->right : x->left;
} while (x->bit > i && p->bit > x->bit);
t = MakeNewNode(tree, key, i, data);
if (t == NULL) return -1;
if (TestKeyBit(key, t->bit)) {
t->right = t;
t->left = x;
} else {
t->right = x;
t->left = t;
}
if (TestKeyBit(key, p->bit))
p->right = t;
else
p->left = t;
#ifdef VERBOSE
printf("Inserted node %ld with left %ld and right %ld\n", t->nodeID, t->left->nodeID, t->right->nodeID);
#endif
tree->numNodes ++;
return 0;
}
/*---------------------------------------------------------------------
PatriciaTraverse
Traverse the tree, executing traverseFunc for each node. It's called like
this:
(*traverseFunc)(node->data, node->key, arg1, arg2);
traverseFunc should return 0 if it completes successfully, or any other
value if there is an error. In this case, the traverse is abruptly terminated.
Entry: treeRef reference to a Patricia tree
traverseFunc function to be called on each node
arg1, arg2 arguments passed to traverseFunc
Exit: return value 0 if traverse competed successfully
-1 if something caused the traverse to
terminate.
-----------------------------------------------------------------------*/
int PatriciaTraverse(PatriciaTreeRef treeRef, NodeTraverseFunction traverseFunc, void *arg, void *refCon)
{
TPatriciaTree *tree = (TPatriciaTree *)treeRef;
return InternalTraverse(tree, tree->headNode, traverseFunc, arg, refCon);
}
/*---------------------------------------------------------------------
PatriciaGetNumNodes
Return the number of nodes in the tree
-----------------------------------------------------------------------*/
long PatriciaGetNumNodes(PatriciaTreeRef treeRef)
{
return ((TPatriciaTree *)treeRef)->numNodes;
}

Просмотреть файл

@ -0,0 +1,93 @@
/* -*- 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>
*/
#ifndef __PATRICIA__
#define __PATRICIA__
/*---------------------------------------------------------------------
Patricia
D.R. Morrison's "Practical Algorithm To Retrieve Information
Coded in Alphanumeric"
See patricia.c for more information.
Ref: Donald R. Morrison. PATRICIA -- practical algorithm to retrieve
information coded in alphanumeric. Journal of the ACM, 15(4):514-534,
October 1968
See SedgeWick, R. Algorithms, 2nd Ed. (1988) for implemenation details.
-----------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
/* A type which you should use externally to refer to a Patricia tree. You
application should treat the tree as an opaque data structure, accessed
only through those routines whose prototypes are declared below.
All externally-visible routines start with 'Patricia'. Internal routines
are declared static in the .c file, and should not be used elsewhere.
*/
typedef void *PatriciaTreeRef;
/* Declarations for user-supplied functions, which are called on replacing
nodes (i.e. when inserting a node with a duplicate key, on traversing
the tree, and on freeing nodes. A non-zero return value indicates failure.
*/
typedef int (*NodeReplaceFunction) (void* *nodeDataPtr, unsigned char *key, void *replaceData, void *refCon);
typedef int (*NodeTraverseFunction) (void *nodeData, unsigned char *key, void *arg, void *refCon);
typedef int (*NodeFreeFunction) (void *nodeData, unsigned char *key, void *refCon);
/* The creation and destruction functions for allocating and freeing a tree.
PatriciaInitTree() allocates space for a tree and initializes it.
PatriciaFreeTree() frees the tree nodes and the tree itself. It does *NOT* free
the data associated with each node, unless you pass a NodeFreeFunction that
does this.
*/
PatriciaTreeRef PatriciaInitTree(long numKeyBits);
void PatriciaFreeTree(PatriciaTreeRef treeRef, NodeFreeFunction freeFunc, void *refCon);
/* Functions for inserting nodes, searching for a node with a given key,
and traversing the tree. Traversal involves visiting every node in the tree,
but does not guarantee that the nodes are visited in a particular order.
*/
int PatriciaInsert(PatriciaTreeRef treeRef, NodeReplaceFunction replaceFunc, const unsigned char *key, void *data, void *refCon);
int PatriciaSearch(PatriciaTreeRef treeRef, const unsigned char *key, void **data);
int PatriciaTraverse(PatriciaTreeRef treeRef, NodeTraverseFunction traverseFunc, void *arg, void *refCon);
/* An accessor function that returns the total number of nodes in the tree
*/
long PatriciaGetNumNodes(PatriciaTreeRef treeRef);
#ifdef __cplusplus
}
#endif
#endif /* __PATRICIA__ */