Checking in code contributed by Jason Bagley (jbagley@artlogic.com) to implement window iteration and getting the URL for the front window from Apple Events, and handling of the 'inside' parameter for GetURL Apple Event. This also fixes a problem with AETokenDesc that it was not saving changes made on it back into the AEDesc*. r=me, sr=pinkerton

This commit is contained in:
sfraser%netscape.com 2001-01-20 02:50:37 +00:00
Родитель 7a48de7730
Коммит 706c5ee09a
16 изменённых файлов: 613 добавлений и 85 удалений

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

@ -492,7 +492,7 @@ void AEApplicationClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredT
Str255 applicationName = "\p";
Str255 versionString;
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
ProcessSerialNumber applicationProcessNumber;
ProcessInfoRec applicationInfo;
@ -655,7 +655,7 @@ void AEApplicationClass::SetDataForObject(const AEDesc *token, AEDesc *data)
long index;
AEKeyword theAEKeyword;
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
Boolean usePropertyCode = tokenDesc.UsePropertyCode();
DescType propertyCode;

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

@ -95,8 +95,8 @@ void AEClassIterator::GetItemFromContainer( DescType desiredClass,
{
ProcessFormRange((AEDesc *)keyData, &startObject, &stopObject);
AETokenDesc startToken(&startObject);
AETokenDesc stopToken(&stopObject);
ConstAETokenDesc startToken(&startObject);
ConstAETokenDesc stopToken(&stopObject);
DescType startType = startToken.GetDispatchClass();
DescType stopType = stopToken.GetDispatchClass();
@ -150,8 +150,8 @@ void AEClassIterator::GetItemFromContainer( DescType desiredClass,
}
else if (keyForm == formRange)
{
AETokenDesc startToken(&startObject);
AETokenDesc stopToken(&stopObject);
ConstAETokenDesc startToken(&startObject);
ConstAETokenDesc stopToken(&stopObject);
ItemID beginItemID = GetItemIDFromToken(&startObject);
ItemID endItemID = GetItemIDFromToken(&stopObject);

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

@ -182,8 +182,8 @@ public:
protected:
virtual ItemRef GetNamedItemReference(const AEDesc* containerToken, const char *itemName) { ThrowOSErr(errAEEventNotHandled); }
virtual ItemID GetNamedItemID(const AEDesc* containerToken, const char *itemName) { ThrowOSErr(errAEEventNotHandled); }
virtual ItemRef GetNamedItemReference(const AEDesc* containerToken, const char *itemName) { ThrowOSErr(errAEEventNotHandled); return 0; }
virtual ItemID GetNamedItemID(const AEDesc* containerToken, const char *itemName) { ThrowOSErr(errAEEventNotHandled); return 0; }
virtual void GetIndexedItemName(const AEDesc* containerToken, TAEListIndex itemIndex, char *outName, long maxLen) { ThrowOSErr(errAEEventNotHandled); }
};

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

@ -309,7 +309,7 @@ void AECoreClass::HandleCoreSuiteEvent(const AppleEvent *appleEvent, AppleEvent
err = AEListUtils::GetFirstNonListToken((AEDesc *)&token, &tempToken);
if (err == noErr && tempToken.descriptorType != typeNull)
{
AETokenDesc tokenDesc(&tempToken);
ConstAETokenDesc tokenDesc(&tempToken);
dispatchClass = tokenDesc.GetDispatchClass();
}
else
@ -325,7 +325,7 @@ void AECoreClass::HandleCoreSuiteEvent(const AppleEvent *appleEvent, AppleEvent
}
else
{
AETokenDesc tokenDesc(&token);
ConstAETokenDesc tokenDesc(&token);
dispatchClass = tokenDesc.GetDispatchClass();
}
@ -421,7 +421,7 @@ void AECoreClass::PropertyTokenFromList( DescType desiredClass,
AEDesc* resultToken)
{
DescType handlerClass;
AETokenDesc containerDesc(containerToken);
ConstAETokenDesc containerDesc(containerToken);
switch (containerClass)
{
@ -958,7 +958,7 @@ void AECoreClass::ExtractData(const AEDesc *source, AEDesc *data)
if (temp.descriptorType == typeProperty)
{
AETokenDesc tokenDesc(&temp);
ConstAETokenDesc tokenDesc(&temp);
dispatchClass = tokenDesc.GetDispatchClass();
}
else

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

@ -34,8 +34,22 @@ typedef long TAEListIndex; // a 1-based list index
typedef short TWindowKind;
/*
We don't (yet) actually set these window kinds on the Mac windows
that Mozilla creates. These values are derived from the windowtype
strings that XUL windows have. See functions in nsWindowUtils.cpp.
*/
enum {
kAnyWindowKind = 99
kAnyWindowKind = 99,
// custom window kinds should start at 9 or above
kBrowserWindowKind = 100,
kMailWindowKind,
kMailComposeWindowKind,
kComposerWindowKind,
kAddressBookWindowKind,
kOtherWindowKind
};

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

@ -159,8 +159,8 @@ void AEDocumentClass::GetDocumentFromApp( DescType desiredClass, // cDocumen
err = ProcessFormRange((AEDesc *)keyData, &startObject, &stopObject);
if (err == noErr)
{
AETokenDesc startTokenDesc(&startObject);
AETokenDesc stopTokenDesc(&startObject);
ConstAETokenDesc startTokenDesc(&startObject);
ConstAETokenDesc stopTokenDesc(&startObject);
DescType startType = startTokenDesc.GetDispatchClass();
DescType stopType = stopTokenDesc.GetDispatchClass();
@ -309,7 +309,7 @@ pascal OSErr AEDocumentClass::DocumentAccessor( DescType desiredClass, // cD
----------------------------------------------------------------------------*/
void AEDocumentClass::ProcessFormRelativePostition(const AEDesc* anchorToken, const AEDesc *keyData, DocumentReference *document)
{
AETokenDesc tokenDesc(anchorToken);
ConstAETokenDesc tokenDesc(anchorToken);
OSErr err = noErr;
DescType positionEnum;
DocumentReference anchorDocument;
@ -445,7 +445,7 @@ void AEDocumentClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredType
OSErr err = noErr;
Boolean usePropertyCode = false;
DocumentReference document = nil;
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
DescType aType = cDocument;
Str63 documentName;
Boolean isModified;
@ -507,7 +507,7 @@ void AEDocumentClass::SetDataForObject(const AEDesc *token, AEDesc *data)
Boolean usePropertyCode;
DescType propertyCode;
DocumentReference document = nil;
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
StAEDesc propertyRecord;
usePropertyCode = tokenDesc.UsePropertyCode();
@ -614,7 +614,7 @@ DocumentReference AEDocumentClass::GetPreviousDocument(DocumentReference docRef)
----------------------------------------------------------------------------*/
DocumentReference AEDocumentClass::GetDocumentReferenceFromToken(const AEDesc *token)
{
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
long docID = tokenDesc.GetDocumentID();
return GetDocumentByID(docID);

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

@ -258,7 +258,7 @@ void AEGenericClass::HandleClose(AEDesc *token, const AppleEvent *appleEvent, Ap
----------------------------------------------------------------------------*/
void AEGenericClass::HandleCount(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
long numberOfObjects = 0;
DescType objectClass;
OSErr err = noErr;
@ -634,7 +634,7 @@ void AEGenericClass::SetDataForListOrObject(const AEDesc *tokenOrTokenList, cons
case cProperty:
{
AETokenDesc tokenDesc(tokenOrTokenList);
ConstAETokenDesc tokenDesc(tokenOrTokenList);
DescType propertyCode = tokenDesc.GetPropertyCode();
//DescType objectClass = tokenDesc.GetObjectClass();
@ -699,7 +699,7 @@ void AEGenericClass::GetDataFromList(const AEDesc *srcList, AEDesc *desiredTypes
----------------------------------------------------------------------------*/
void AEGenericClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data)
{
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
DescType propertyCode = tokenDesc.GetPropertyCode();
OSErr err = noErr;

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

@ -24,6 +24,9 @@
#include "nsMemory.h"
#include "nsWindowUtils.h"
#include "nsAETokens.h"
#include "nsAEGetURLSuiteHandler.h"
#include "nsCommandLineServiceMac.h"
@ -99,6 +102,7 @@ void AEGetURLSuiteHandler::HandleGetURLSuiteEvent(const AppleEvent *appleEvent,
void AEGetURLSuiteHandler::HandleGetURLEvent(const AppleEvent *appleEvent, AppleEvent *reply)
{
StAEDesc directParameter;
WindowPtr targetWindow = NULL;
OSErr err;
// extract the direct parameter (an object specifier)
@ -106,15 +110,34 @@ void AEGetURLSuiteHandler::HandleGetURLEvent(const AppleEvent *appleEvent, Apple
ThrowIfOSErr(err);
// we need to look for other parameters, to do with destination etc.
long dataSize = directParameter.GetDataSize();
char* urlString = (char *)nsMemory::Alloc(dataSize + 1);
ThrowIfNil(urlString);
directParameter.GetCString(urlString, dataSize + 1);
// get the destination window, if applicable
StAEDesc openInWindowDesc;
err = ::AEGetKeyDesc(appleEvent, kInsideWindowParameter, typeObjectSpecifier, &openInWindowDesc);
if (err != errAEDescNotFound)
{
// resolve the object specifier into a token record
StAEDesc tokenDesc;
err = ::AEResolve(&openInWindowDesc, kAEIDoMinimum, &tokenDesc);
ThrowIfOSErr(err);
ConstAETokenDesc tokenContainer(&tokenDesc);
targetWindow = tokenContainer.GetWindowPtr();
}
if (targetWindow)
{
LoadURLInWindow(targetWindow, urlString);
}
else
{
nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
cmdLine.DispatchURLToNewBrowser(urlString);
}
nsMemory::Free(urlString);
}

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

@ -34,7 +34,10 @@ class AEGetURLSuiteHandler
public:
enum {
kSuiteSignature = 'GURL',
kGetURLEvent = 'GURL'
kGetURLEvent = 'GURL',
kInsideWindowParameter = 'HWIN',
kReferrerParameter = 'refe'
};
AEGetURLSuiteHandler();

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

@ -25,28 +25,35 @@
#include "nsAETokens.h"
AETokenDesc::AETokenDesc(const AEDesc* token)
: mTokenValid(false)
// ---------------------------------------------------------------------------
ConstAETokenDesc::ConstAETokenDesc(const AEDesc* token)
{
mTokenValid = (AEGetDescDataSize(token) == sizeof(CoreTokenRecord));
if (mTokenValid)
AEGetDescData(token, &mTokenData, sizeof(CoreTokenRecord));
mTokenWasNull = (token->descriptorType == typeNull);
if (!mTokenWasNull)
{
if (::AEGetDescDataSize(token) != sizeof(CoreTokenRecord))
ThrowOSErr(paramErr); // invalid token
ThrowIfOSErr(::AEGetDescData(token, &mTokenRecord, sizeof(CoreTokenRecord)));
}
}
AETokenDesc::~AETokenDesc() {}
// ---------------------------------------------------------------------------
DescType AETokenDesc::GetDispatchClass() const
DescType ConstAETokenDesc::GetDispatchClass() const
{
return (mTokenValid ? mTokenData.dispatchClass : typeNull);
ThrowErrIfTrue(mTokenWasNull, paramErr);
return mTokenRecord.dispatchClass;
}
// ---------------------------------------------------------------------------
DescType AETokenDesc::GetObjectClass() const
DescType ConstAETokenDesc::GetObjectClass() const
{
return (mTokenValid ? mTokenData.objectClass : typeNull);
ThrowErrIfTrue(mTokenWasNull, paramErr);
return mTokenRecord.objectClass;
}
// ---------------------------------------------------------------------------
@ -54,72 +61,99 @@ DescType AETokenDesc::GetObjectClass() const
// 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
Boolean ConstAETokenDesc::UsePropertyCode() const
{
return (mTokenValid ? mTokenData.propertyCode != typeNull : false);
ThrowErrIfTrue(mTokenWasNull, paramErr);
return (mTokenRecord.propertyCode != typeNull);
}
// ---------------------------------------------------------------------------
DescType AETokenDesc::GetPropertyCode() const
DescType ConstAETokenDesc::GetPropertyCode() const
{
return (mTokenValid ? mTokenData.propertyCode : typeNull);
ThrowErrIfTrue(mTokenWasNull, paramErr);
return mTokenRecord.propertyCode;
}
// ---------------------------------------------------------------------------
long AETokenDesc::GetDocumentID() const
long ConstAETokenDesc::GetDocumentID() const
{
return (mTokenValid ? mTokenData.documentID : typeNull);
ThrowErrIfTrue(mTokenWasNull, paramErr);
return mTokenRecord.documentID;
}
// ---------------------------------------------------------------------------
WindowPtr AETokenDesc::GetWindowPtr() const
WindowPtr ConstAETokenDesc::GetWindowPtr() const
{
return (mTokenValid ? mTokenData.window : nil);
ThrowErrIfTrue(mTokenWasNull, paramErr);
return mTokenRecord.window;
}
// ---------------------------------------------------------------------------
TAEListIndex AETokenDesc::GetElementNumber() const
TAEListIndex ConstAETokenDesc::GetElementNumber() const
{
return (mTokenValid ? mTokenData.elementNumber : 0);
ThrowErrIfTrue(mTokenWasNull, paramErr);
return mTokenRecord.elementNumber;
}
#pragma mark -
// ---------------------------------------------------------------------------
AETokenDesc::AETokenDesc(AEDesc* token)
: ConstAETokenDesc(token)
, mTokenDesc(token)
{
if (mTokenWasNull) // we cannot wrap a null token
ThrowOSErr(paramErr);
}
// ---------------------------------------------------------------------------
AETokenDesc::~AETokenDesc()
{
UpdateDesc(); // update the AEDesc that we wrap
}
// ---------------------------------------------------------------------------
void AETokenDesc::SetPropertyCode(DescType propertyCode)
{
mTokenData.propertyCode = propertyCode;
mTokenRecord.propertyCode = propertyCode;
}
// ---------------------------------------------------------------------------
void AETokenDesc::SetDispatchClass(DescType dispatchClass)
{
mTokenData.dispatchClass = dispatchClass;
mTokenRecord.dispatchClass = dispatchClass;
}
// ---------------------------------------------------------------------------
void AETokenDesc::SetObjectClass(DescType objectClass)
{
mTokenData.objectClass = objectClass;
mTokenRecord.objectClass = objectClass;
}
// ---------------------------------------------------------------------------
void AETokenDesc::SetElementNumber(TAEListIndex number)
{
mTokenData.elementNumber = number;
mTokenRecord.elementNumber = number;
}
// ---------------------------------------------------------------------------
void AETokenDesc::SetWindow(WindowPtr wind)
{
mTokenData.window = wind;
mTokenRecord.window = wind;
}
// ---------------------------------------------------------------------------
void AETokenDesc::UpdateDesc()
{
OSErr err = ::AEReplaceDescData(mTokenDesc->descriptorType, &mTokenRecord, sizeof(CoreTokenRecord), mTokenDesc);
ThrowIfOSErr(err);
}

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- 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
@ -57,14 +57,16 @@ struct CoreTokenRecord
typedef struct CoreTokenRecord CoreTokenRecord, *CoreTokenPtr, **CoreTokenHandle;
// AETokenDesc
// A utility class designed to give easy access to the contents of the token
class AETokenDesc
// ConstAETokenDesc
// This is a read-only wrapper for an AEDesc* that can be used
// to read the contents of the token record.
class ConstAETokenDesc
{
public:
AETokenDesc(const AEDesc* token);
~AETokenDesc();
ConstAETokenDesc(const AEDesc* token);
DescType GetDispatchClass() const;
DescType GetObjectClass() const;
@ -75,15 +77,38 @@ public:
WindowPtr GetWindowPtr() const;
TAEListIndex GetElementNumber() const;
protected:
CoreTokenRecord mTokenRecord;
Boolean mTokenWasNull; // true if we were passed an empty AEDesc
};
// AETokenDesc
// A read-write wrapper for an AEDesc*. Use this if you want to
// update the contents of the AEDesc's data handle
class AETokenDesc : public ConstAETokenDesc
{
public:
AETokenDesc(AEDesc* token);
~AETokenDesc();
void SetDispatchClass(DescType dispatchClass);
void SetObjectClass(DescType objectClass);
void SetPropertyCode(DescType propertyCode);
void SetElementNumber(TAEListIndex number);
void SetWindow(WindowPtr wind);
void UpdateDesc(); // update the AEDesc wrapped by this class
CoreTokenRecord& GetTokenRecord() { return mTokenRecord; }
protected:
CoreTokenRecord mTokenData;
Boolean mTokenValid;
AEDesc* mTokenDesc;
};
#endif /* __AETOKENS__ */

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

@ -119,6 +119,16 @@ Size AEGetDescDataSize(const AEDesc *theAEDesc)
return dataSize;
}
/*----------------------------------------------------------------------------
AEReplaceDescData
Replace the data in the descriptor
----------------------------------------------------------------------------*/
OSErr AEReplaceDescData(DescType typeCode, const void *dataPtr, Size dataSize, AEDesc* theAEDesc)
{
AEDisposeDesc(theAEDesc);
return AECreateDesc(typeCode, dataPtr, dataSize, theAEDesc);
}
#endif //TARGET_CARBON

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

@ -42,11 +42,12 @@
#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 ThrowIfNil(a) do { if (a == nil) { throw((OSErr)memFullErr); } } while (0)
#define ThrowErrIfNil(a, err) do { if (a == nil) { OSErr theErr = (err); throw((OSErr)theErr); } } while (0)
#define ThrowErrIfTrue(a, err) do { if (a) { OSErr theErr = (err); throw((OSErr)theErr); } } while (0)
#define ThrowIfOSErr(err) do { OSErr theErr = (err); if (theErr != noErr) { throw((OSErr)theErr); } } while (0)
#define ThrowOSErr(err) do { throw((OSErr)err); } while (0)
#define ThrowNoErr() do { throw((OSErr)noErr); } while (0)
#define pObjectType 'pObT'
@ -97,6 +98,7 @@ OSErr ResumeThreadAE(TThreadAEInfo *threadAEInfo, OSErr threadError);
OSErr AEGetDescData(const AEDesc *theAEDesc, void * dataPtr, Size maximumSize);
Size AEGetDescDataSize(const AEDesc *theAEDesc);
OSErr AEReplaceDescData(DescType typeCode, const void *dataPtr, Size dataSize, AEDesc* theAEDesc);
#endif /* TARGET_CARBON */

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

@ -25,8 +25,11 @@
#include <string.h>
#include <AEPackObject.h>
#include "nsMemory.h"
#include "nsWindowUtils.h"
#include "nsAppleEvents.h"
#include "nsAEUtils.h"
#include "nsAETokens.h"
#include "nsAECoreClass.h"
@ -130,7 +133,7 @@ AEClassIterator::ItemRef AEWindowIterator::GetReferenceFromID(const AEDesc* cont
----------------------------------------------------------------------------*/
AEClassIterator::ItemID AEWindowIterator::GetItemIDFromToken(const AEDesc* token)
{
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
return (ItemID)tokenDesc.GetWindowPtr();
}
@ -392,7 +395,7 @@ void AEWindowClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes,
{
OSErr err = noErr;
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
DescType aType = mClass;
Rect aRect;
@ -400,6 +403,7 @@ void AEWindowClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes,
Boolean aBoolean;
long index;
CStr255 windowTitle;
char* urlString = NULL;
DescType propertyCode = tokenDesc.GetPropertyCode();
Boolean usePropertyCode = tokenDesc.UsePropertyCode();
@ -416,6 +420,13 @@ void AEWindowClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes,
GetCleanedWindowName(window, windowTitle, 255);
err = AEPutKeyPtr(data, pTitle, typeChar, windowTitle, strlen(windowTitle));
GetWindowUrlString(window, &urlString);
if (urlString)
{
err = AEPutKeyPtr(data, AE_www_typeWindowURL, typeChar, urlString, strlen(urlString));
nsMemory::Free(urlString); urlString = NULL;
}
index = GetWindowIndex(GetThisWindowKind(), window);
err = AEPutKeyPtr(data, pIndex, typeLongInteger, &index, sizeof(long));
@ -536,6 +547,15 @@ void AEWindowClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes,
err = AECreateDesc(typeChar, windowTitle, strlen(windowTitle), data);
break;
case AE_www_typeWindowURL:
GetWindowUrlString(window, &urlString);
if (urlString)
{
err = AECreateDesc(typeChar, urlString, strlen(urlString), data);
nsMemory::Free(urlString); urlString = NULL;
}
break;
default:
Inherited::GetDataFromObject(token, desiredTypes, data);
break;
@ -553,7 +573,7 @@ void AEWindowClass::SetDataForObject(const AEDesc *token, AEDesc *data)
{
OSErr err;
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
Boolean usePropertyCode = tokenDesc.UsePropertyCode();
WindowPtr window = tokenDesc.GetWindowPtr();
@ -620,7 +640,9 @@ Boolean AEWindowClass::CanSetProperty(DescType propertyCode)
break;
// Properties we should be able to set, but not implemented yet:
case AE_www_typeWindowURL:
result = false;
break;
// Properties we can't set:
@ -677,6 +699,8 @@ Boolean AEWindowClass::CanGetProperty(DescType propertyCode)
case pTitle:
case pName: // Synonym for pTitle
case AE_www_typeWindowURL:
case pIsModeless:
case pIsMovableModal:
case pIsSuspended:
@ -876,7 +900,7 @@ void AEWindowClass::MakeWindowObjectSpecifier(WindowPtr wind, AEDesc *outSpecifi
----------------------------------------------------------------------------*/
void AEWindowClass::CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier)
{
AETokenDesc tokenDesc(token);
ConstAETokenDesc tokenDesc(token);
WindowPtr window = tokenDesc.GetWindowPtr();
long position = GetWindowIndex(mWindowKind, window);
AEDesc selfDesc = { typeNull, nil };

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

@ -21,43 +21,400 @@
* Simon Fraser <sfraser@netscape.com>
*/
#include <MacWindows.h>
#include "nsCommandLineServiceMac.h"
#include "nsComPtr.h"
#include "nsIBaseWindow.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMElement.h"
#include "nsIDOMNode.h"
#include "nsIHTMLContent.h"
#include "nsIPrincipal.h"
#include "nsICodebasePrincipal.h"
#include "nsIServiceManager.h"
#include "nsIWebNavigation.h"
#include "nsIWebShellWindow.h"
#include "nsIWidget.h"
#include "nsIWindowMediator.h"
#include "nsIURI.h"
#include "nsIXULWindow.h"
#include "nsString2.h"
#include "nsWindowUtils.h"
#include "nsMacUtils.h"
#include "nsXPIDLString.h"
#include "nsXULWindow.h"
#include "nsAEUtils.h"
// CIDs
static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID);
/*----------------------------------------------------------------------------
GetXULWindowFromWindowPtr
Get an nsIXULWindow from a WindowPtr. Returns an ADDREFFED xulWindow,
which you must release (hint: use an nsCOMPtr).
Throws on error.
----------------------------------------------------------------------------*/
static void GetXULWindowFromWindowPtr(WindowPtr inWindowPtr, nsIXULWindow **outXULWindow)
{
*outXULWindow = NULL;
if (!inWindowPtr)
ThrowOSErr(paramErr);
nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
ThrowErrIfNil(windowMediator, paramErr);
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
if (NS_FAILED(windowMediator->GetXULWindowEnumerator(nsnull, getter_AddRefs(windowEnumerator))))
ThrowOSErr(paramErr); // need a better error
// Find the window
while (true)
{
PRBool more = false;
windowEnumerator->HasMoreElements(&more);
if (!more)
break;
nsCOMPtr<nsISupports> nextWindow = nsnull;
windowEnumerator->GetNext(getter_AddRefs(nextWindow));
nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(nextWindow));
if (NULL == baseWindow)
continue;
nsCOMPtr<nsIWidget> widget = nsnull;
baseWindow->GetMainWidget(getter_AddRefs(widget));
if (NULL == widget)
continue;
WindowRef windowRef = (WindowRef)widget->GetNativeData(NS_NATIVE_DISPLAY);
if ((WindowPtr)windowRef == inWindowPtr)
{
// !!! There really must be an easier way to do this. JavaScript?
nsCOMPtr<nsIXULWindow> xulWindow(do_QueryInterface(nextWindow));
if (!xulWindow)
break;
NS_ADDREF(*outXULWindow = xulWindow);
return;
}
}
// if we got here, we didn't find the window
ThrowOSErr(paramErr);
}
/*----------------------------------------------------------------------------
GetXULWindowTypeString
Get the type string for a XUL window
----------------------------------------------------------------------------*/
static void GetXULWindowTypeString(nsIXULWindow *inXULWindow, nsString& outWindowType)
{
outWindowType.Truncate();
if (inXULWindow)
{
nsCOMPtr<nsIDocShellTreeItem> contentShell;
inXULWindow->GetPrimaryContentShell(getter_AddRefs(contentShell));
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(contentShell));
ThrowErrIfNil(webNav, paramErr);
nsCOMPtr<nsIDOMDocument> domDoc;
webNav->GetDocument(getter_AddRefs(domDoc));
if (domDoc)
{
nsCOMPtr<nsIDOMElement> element;
domDoc->GetDocumentElement(getter_AddRefs(element));
if (element)
element->GetAttribute(NS_LITERAL_STRING("windowtype"), outWindowType);
}
}
}
/*----------------------------------------------------------------------------
WindowKindFromTypeString
----------------------------------------------------------------------------*/
static TWindowKind WindowKindFromTypeString(const nsString& inWindowType)
{
if (inWindowType.IsEmpty())
return kAnyWindowKind;
if (inWindowType.Equals(NS_LITERAL_STRING("navigator:browser")))
return kBrowserWindowKind;
if (inWindowType.Equals(NS_LITERAL_STRING("mail:3pane")))
return kMailWindowKind;
if (inWindowType.Equals(NS_LITERAL_STRING("msgcompose")))
return kMailComposeWindowKind;
if (inWindowType.Equals(NS_LITERAL_STRING("mail:addressbook")))
return kAddressBookWindowKind;
if (inWindowType.Equals(NS_LITERAL_STRING("composer:html")))
return kComposerWindowKind;
if (inWindowType.Equals(NS_LITERAL_STRING("composer:text")))
return kComposerWindowKind;
return kOtherWindowKind;
}
/*----------------------------------------------------------------------------
GetXULWindowKind
----------------------------------------------------------------------------*/
static TWindowKind GetXULWindowKind(nsIXULWindow *inXULWindow)
{
nsAutoString windowType;
GetXULWindowTypeString(inXULWindow, windowType);
return WindowKindFromTypeString(windowType);
}
/*----------------------------------------------------------------------------
CountWindowsOfKind
----------------------------------------------------------------------------*/
long CountWindowsOfKind(TWindowKind windowKind)
{
// ¥¥¥ write me
return 0;
nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
ThrowErrIfNil(windowMediator, paramErr);
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
if (NS_FAILED(windowMediator->GetXULWindowEnumerator(nsnull, getter_AddRefs(windowEnumerator))))
ThrowOSErr(paramErr); // need a better error
long windowCount = 0L;
PRBool more;
windowEnumerator->HasMoreElements(&more);
while (more)
{
nsCOMPtr<nsISupports> nextWindow = nsnull;
windowEnumerator->GetNext(getter_AddRefs(nextWindow));
nsCOMPtr<nsIXULWindow> xulWindow(do_QueryInterface(nextWindow));
if (!xulWindow) break;
if (kAnyWindowKind == windowKind)
++windowCount;
else
{
// Test window kind.
TWindowKind thisWindowKind = GetXULWindowKind(xulWindow);
if (thisWindowKind == windowKind)
++windowCount;
}
windowEnumerator->HasMoreElements(&more);
}
return windowCount;
}
WindowPtr GetNamedOrFrontmostWindow(TWindowKind windowKind, const char* windowName)
{
// ¥¥¥ write me
return NULL;
// Search for window with the desired kind and name.
nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
ThrowErrIfNil(windowMediator, paramErr);
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
if (NS_FAILED(windowMediator->GetXULWindowEnumerator(nsnull, getter_AddRefs(windowEnumerator))))
ThrowOSErr(paramErr); // need a better error
WindowPtr windowPtr = NULL;
PRBool more;
nsCString windowNameString(windowName);
windowEnumerator->HasMoreElements(&more);
while (more)
{
nsCOMPtr<nsISupports> nextWindow = nsnull;
windowEnumerator->GetNext(getter_AddRefs(nextWindow));
nsCOMPtr<nsIXULWindow> xulWindow(do_QueryInterface(nextWindow));
if (!xulWindow) break;
nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(xulWindow));
ThrowErrIfNil(baseWindow, paramErr);
nsCOMPtr<nsIWidget> widget = nsnull;
baseWindow->GetMainWidget(getter_AddRefs(widget));
ThrowErrIfNil(widget, paramErr);
WindowRef windowRef = (WindowRef)widget->GetNativeData(NS_NATIVE_DISPLAY);
TWindowKind thisWindowKind = GetXULWindowKind(xulWindow);
// If this is the kind of window we are looking for...
if (kAnyWindowKind == windowKind || (thisWindowKind == windowKind))
{
if (NULL == windowName)
{
// ...see if its the frontmost of this kind.
PRInt32 zIndex;
widget->GetZIndex(&zIndex);
if (0L == zIndex)
{
windowPtr = (WindowPtr)windowRef;
break;
}
}
else
{
// ...see if its name is the desired one.
Str255 pascalTitle;
GetWTitle(windowRef, pascalTitle);
if (windowNameString.EqualsWithConversion((const char*)&pascalTitle[1], PR_FALSE, pascalTitle[0]))
{
windowPtr = (WindowPtr)windowRef; // WindowRef is the WindowPtr.
break;
}
}
}
windowEnumerator->HasMoreElements(&more);
}
return windowPtr;
}
WindowPtr GetIndexedWindowOfKind(TWindowKind windowKind, TAEListIndex index)
{
// ¥¥¥ write me
return NULL;
nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
ThrowErrIfNil(windowMediator, paramErr);
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
if (NS_FAILED(windowMediator->GetXULWindowEnumerator(nsnull, getter_AddRefs(windowEnumerator))))
ThrowOSErr(paramErr); // need a better error
WindowPtr windowPtr = NULL;
PRBool more;
windowEnumerator->HasMoreElements(&more);
while (more)
{
nsCOMPtr<nsISupports> nextWindow = nsnull;
windowEnumerator->GetNext(getter_AddRefs(nextWindow));
nsCOMPtr<nsIXULWindow> xulWindow(do_QueryInterface(nextWindow));
if (!xulWindow) break;
nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(xulWindow));
ThrowErrIfNil(baseWindow, paramErr);
nsCOMPtr<nsIWidget> widget = nsnull;
baseWindow->GetMainWidget(getter_AddRefs(widget));
ThrowErrIfNil(widget, paramErr);
WindowRef windowRef = (WindowRef)widget->GetNativeData(NS_NATIVE_DISPLAY);
TWindowKind thisWindowKind = GetXULWindowKind(xulWindow);
// If this is the kind of window we are looking for...
if (kAnyWindowKind == windowKind || (thisWindowKind == windowKind))
{
// ...decrement index and test if this is the window at that index.
if (0L == --index)
{
windowPtr = (WindowPtr)windowRef; // WindowRef is the WindowPtr.
break;
}
}
windowEnumerator->HasMoreElements(&more);
}
return windowPtr;
}
TAEListIndex GetWindowIndex(TWindowKind windowKind, WindowPtr theWindow)
{
// ¥¥¥ write me
return 0;
nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
ThrowErrIfNil(windowMediator, paramErr);
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
if (NS_FAILED(windowMediator->GetXULWindowEnumerator(nsnull, getter_AddRefs(windowEnumerator))))
ThrowOSErr(paramErr); // need a better error
TAEListIndex index = 0L;
PRBool more;
windowEnumerator->HasMoreElements(&more);
while (more)
{
nsCOMPtr<nsISupports> nextWindow = nsnull;
windowEnumerator->GetNext(getter_AddRefs(nextWindow));
nsCOMPtr<nsIXULWindow> xulWindow(do_QueryInterface(nextWindow));
if (!xulWindow) break;
nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(xulWindow));
ThrowErrIfNil(baseWindow, paramErr);
nsCOMPtr<nsIWidget> widget = nsnull;
baseWindow->GetMainWidget(getter_AddRefs(widget));
ThrowErrIfNil(widget, paramErr);
WindowRef windowRef = (WindowRef)widget->GetNativeData(NS_NATIVE_DISPLAY);
TWindowKind thisWindowKind = GetXULWindowKind(xulWindow);
if (kAnyWindowKind == windowKind || (thisWindowKind == windowKind))
{
++index;
if ((WindowPtr)windowRef == theWindow)
return index;
}
windowEnumerator->HasMoreElements(&more);
}
return 0L; // error: theWindow wasn't found. Return an invalid index.
}
//---------------------------------------------------------
void GetCleanedWindowName(WindowPtr wind, char* outName, long maxLen)
{
// ¥¥¥ write me
*outName = '\0';
Str255 uncleanName;
GetWTitle(wind, uncleanName);
CopyPascalToCString(uncleanName, outName, maxLen);
}
//---------------------------------------------------------
void GetWindowUrlString(WindowPtr wind, char** outUrlStringPtr)
{
*outUrlStringPtr = NULL;
nsCOMPtr<nsIXULWindow> xulWindow;
GetXULWindowFromWindowPtr(wind, getter_AddRefs(xulWindow));
ThrowErrIfNil(xulWindow, paramErr);
nsCOMPtr<nsIDocShellTreeItem> contentShell;
xulWindow->GetPrimaryContentShell(getter_AddRefs(contentShell));
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(contentShell));
ThrowErrIfNil(webNav, paramErr);
nsCOMPtr<nsIURI> sourceURL;
webNav->GetCurrentURI(getter_AddRefs(sourceURL));
ThrowErrIfNil(sourceURL, paramErr);
// Now get the string;
sourceURL->GetSpec(outUrlStringPtr);
}
@ -96,6 +453,39 @@ void GetWindowGlobalBounds(WindowPtr wind, Rect* outBounds)
}
/*----------------------------------------------------------------------------
LoadURLInWindow
----------------------------------------------------------------------------*/
void LoadURLInWindow(WindowPtr wind, const char* urlString)
{
OSErr err = noErr;
if (wind == nil)
{
// this makes a new window
nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
err = cmdLine.DispatchURLToNewBrowser(urlString);
ThrowIfOSErr(err);
}
// existing window. Go through hoops to load a URL in it
nsCOMPtr<nsIXULWindow> xulWindow;
GetXULWindowFromWindowPtr(wind, getter_AddRefs(xulWindow));
ThrowErrIfNil(xulWindow, paramErr);
nsCOMPtr<nsIDocShellTreeItem> contentShell;
xulWindow->GetPrimaryContentShell(getter_AddRefs(contentShell));
ThrowErrIfNil(contentShell, paramErr);
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(contentShell));
ThrowErrIfNil(webNav, paramErr);
nsAutoString urlWString; urlWString.AssignWithConversion(urlString);
webNav->LoadURI(urlWString.GetUnicode(), nsIWebNavigation::LOAD_FLAGS_NONE);
}
#pragma mark -
/*----------------------------------------------------------------------------

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

@ -42,8 +42,11 @@ WindowPtr GetIndexedWindowOfKind(TWindowKind windowKind, TAEListIndex index);
TAEListIndex GetWindowIndex(TWindowKind windowKind, WindowPtr theWindow);
void GetCleanedWindowName(WindowPtr wind, char* outName, long maxLen);
void GetWindowUrlString(WindowPtr wind, char** outUrlStringPtr);
void GetWindowGlobalBounds(WindowPtr wind, Rect* outRect);
void LoadURLInWindow(WindowPtr wind, const char* urlString);
Boolean WindowIsResizeable(WindowPtr wind);
Boolean WindowIsZoomable(WindowPtr wind);
Boolean WindowIsZoomed(WindowPtr wind);