home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-04-08 | 58.3 KB | 1,916 lines |
- /* -*- 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.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- // CAppleEventHandler.cp
-
- // ---- Apple Events
- #include "CAppleEventHandler.h"
-
-
- /*-------------------------------------------------------------*/
- // Includes
- /*-------------------------------------------------------------*/
-
- // --- just in case
- #include "uapp.h"
-
- // --- Netscape macfe
- #include "Netscape_Constants.h"
- #include "earlmgr.h"
- #include "findw.h"
- #include "macgui.h"
- #include "macutil.h"
- #include "CBookmarksAttachment.h"
- #include "BookmarksFile.h"
- #include "mimages.h"
- #include "mplugin.h"
-
- #if defined (JAVA)
- #include "mjava.h"
- #endif /* defined (JAVA) */
-
- #include "mregistr.h"
- #include "prefw.h"
- #include "resae.h"
- #include "resgui.h"
- #include "uerrmgr.h"
- #include "ufilemgr.h"
-
- // -- For getting Profile information
- #include "prefapi.h"
-
- // --- Netscape Misc
- #include "CEditorWindow.h"
- #include "CBrowserWindow.h"
-
- // --- Just plain Misc
- #include "mkutils.h" // only for FREEIF() macro. JRM 96/10/17
-
- // --- Natscape NS
- #include "CNSContextCallbacks.h"
-
- // --- Natscape Browser
- #include "CBrowserContext.h"
- #include "CBrowserWindow.h"
-
- // --- Natscape MailNews
- #ifdef MOZ_MAIL_NEWS
- #include "MailNewsSearch.h"
- #include "MailNewsFilters.h"
- #include "MailNewsAddressBook.h"
- #include "MailNewsClasses.h"
- #include "MailNewsgroupWindow_Defines.h"
- #endif // MOZ_MAIL_NEWS
- #include "BrowserClasses.h"
-
- // --- Mac Toolbox
- #include <Displays.h> // For the display notice event
- #include <Balloons.h>
- #include <Errors.h>
- #include <EPPC.h>
-
-
-
- #include "CURLDispatcher.h"
- #include "xp.h"
-
- /*--------------------------------------------------------------*/
- // Constructor, Destructor and Dispach
- /*--------------------------------------------------------------*/
-
- /*----------------------------------------------------------------
- CAppleEventHandler::CAppleEventHandler
- Constructor
- ----------------------------------------------------------------*/
- CAppleEventHandler::CAppleEventHandler()
- {
- // Remember our one instance
- sAppleEventHandler = this;
-
- // We assume not operating in kiosk mode unless told otherwise
- fKioskMode = KioskOff;
-
- }
- /*----------------------------------------------------------------
- CAppleEventHandler::~CAppleEventHandler
- Destructor
- ----------------------------------------------------------------*/
- CAppleEventHandler::~CAppleEventHandler()
- {
- // Reste to NULL, we're gone
- sAppleEventHandler = NULL;
- }
-
- /*----------------------------------------------------------------
- CAppleEventHandler::HandleAppleEvent
- AppleEvent Dispach Here
- In: & AppleEvent Incoming apple event
- & ReplyEvent Reply event we can attach result info to
- & Descriptor OUtgoing descriptor
- AppleEvent ID The Apple Event ID we were called with.
- Out: Event Handled by CAppleEvent
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleAppleEvent(
- const AppleEvent &inAppleEvent,
- AppleEvent &outAEReply,
- AEDesc &outResult,
- long inAENumber)
- {
- switch (inAENumber)
- {
- case AE_GetURL:
- case AE_OpenURL:
- case AE_OpenProfileManager:
- // Required Suite
- case ae_OpenApp:
- case ae_OpenDoc:
- case ae_PrintDoc:
- case ae_Quit:
- break;
-
- default:
- if (!(CFrontApp::GetApplication() && CFrontApp::GetApplication()->HasProperlyStartedUp()))
- {
- // Ignore all apple events handled by this handler except get url, open
- // url and the required suite until we have properly started up.
- return;
- }
- break;
- }
-
- switch (inAENumber) {
-
- // ### Mac URL standard Suite
- // -----------------------------------------------------------
- case AE_GetURL: // Direct object - url, cwin - HyperWindow
- HandleGetURLEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- // ### Spyglass Suite
- // -----------------------------------------------------------
- case AE_OpenURL:
- HandleOpenURLEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- case AE_CancelProgress:
- HandleCancelProgress( inAppleEvent, outAEReply, outResult, inAENumber);
- break;
-
- case AE_FindURL: // located elsewhere
- CFileMgr::sFileManager.HandleFindURLEvent(inAppleEvent, outAEReply, outResult, inAENumber);
- break;
-
- case AE_ShowFile:
- HandleShowFile(inAppleEvent, outAEReply, outResult, inAENumber);
- break;
-
- case AE_ParseAnchor:
- HandleParseAnchor(inAppleEvent, outAEReply, outResult, inAENumber);
- break;
-
- case AE_SpyActivate:
- HandleSpyActivate(inAppleEvent, outAEReply, outResult, inAENumber);
- break;
-
- case AE_SpyListWindows:
- HandleSpyListWindows(inAppleEvent, outAEReply, outResult, inAENumber);
- break;
-
- case AE_GetWindowInfo:
- HandleSpyGetWindowInfo(inAppleEvent, outAEReply, outResult, inAENumber);
- break;
-
- case AE_RegisterWinClose:
- case AE_UnregisterWinClose:
- HandleWindowRegistration(inAppleEvent, outAEReply, outResult, inAENumber);
- break;
-
- // --- These Spyglass events are handled elswhere
- case AE_RegisterViewer:
- CPrefs::sMimeTypes.HandleRegisterViewerEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- case AE_UnregisterViewer:
- CPrefs::sMimeTypes.HandleUnregisterViewerEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- case AE_RegisterProtocol:
- case AE_UnregisterProtocol:
- case AE_RegisterURLEcho:
- case AE_UnregisterURLEcho:
- CNotifierRegistry::HandleAppleEvent(inAppleEvent, outAEReply, outResult, inAENumber);
- break;
-
-
- // ### Netscape Experimental Suite
- // -----------------------------------------------------------
- case AE_OpenBookmark:
- HandleOpenBookmarksEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- case AE_ReadHelpFile:
- HandleReadHelpFileEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- case AE_Go:
- HandleGoEvent (inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- case AE_GetWD: // Return Working Directory
- HandleGetWDEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- case AE_OpenProfileManager:
- CFrontApp::sApplication->ProperStartup( NULL, FILE_TYPE_PROFILES );
- break;
-
- case AE_OpenAddressBook:
- HandleOpenAddressBookEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- case AE_OpenComponent:
- HandleOpenComponentEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- case AE_HandleCommand:
- HandleCommandEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- case AE_GetActiveProfile:
- HandleGetActiveProfileEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
-
- // ### ???? 2014 looks like it's a core suite thing, but not defined in the aedt
- // -----------------------------------------------------------
- /* case 2014: // Display has changed. Maybe in 2.0, should change the pictures
- {
- StAEDescriptor displayDesc;
- OSErr err = AEGetParamDesc(&inAppleEvent,kAEDisplayNotice,typeWildCard,&displayDesc.mDesc);
- if (err == noErr)
- SysBeep(1);
- }
- break;
- */
-
- // ### If all else fails behave like a word processor
- // -----------------------------------------------------------
- default:
- CFrontApp::sApplication->LDocApplication::HandleAppleEvent( inAppleEvent, outAEReply, outResult, inAENumber );
- break;
- }
- }
-
- /*--------------------------------------------------------------------------*/
- /* ---- Mac URL standard, supported by many apps ---- */
- /*--------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------
- CAppleEventHandler::HandleGetURLEvent Suite:URL
- Dispach the URL event to the correct window and let the
- window handle the event.
-
- GetURL: Loads the URL (optionaly to disk)
-
- GetURL string -- The url
- [to file specification] -- file the URL should be loaded into
- [inside reference] -- Window the URL should be loaded to
- [from string] -- Refererer, to be sent with the HTTP request
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleGetURLEvent(
- const AppleEvent &inAppleEvent,
- AppleEvent &outAEReply,
- AEDesc &outResult,
- long /*inAENumber*/)
- {
- // We need to make sure
-
- CFrontApp::sApplication->ProperStartup( NULL, FILE_TYPE_GETURL );
-
- // Get the window, and let it handle the event
- StAEDescriptor keyData;
- OSErr err = ::AEGetKeyDesc(&inAppleEvent, AE_www_typeWindow, typeWildCard,&keyData.mDesc);
-
- // TODO: handle dispatching to storage
-
- if (CFrontApp::GetApplication()->HasProperlyStartedUp())
- {
- // A window was specified, open the url in that window
- if ((err == noErr) && (keyData.mDesc.descriptorType == typeObjectSpecifier))
- {
- StAEDescriptor theToken;
- err = ::AEResolve(&keyData.mDesc, kAEIDoMinimum, &theToken.mDesc);
- ThrowIfOSErr_(err);
- LModelObject * model = CFrontApp::sApplication->GetModelFromToken(theToken.mDesc);
- ThrowIfNil_(model);
-
- CBrowserWindow* win = dynamic_cast<CBrowserWindow*>(model);
- ThrowIfNil_(win);
-
- CBrowserWindow::HandleGetURLEvent(inAppleEvent, outAEReply, outResult, win);
- }
- // No window or file specified, we will open the url in the frontmost
- // browser window or a new browser window if there are no open browser
- // windows.
- // Or no browser window if one is not appropriate. Good grief! jrm.
- else
- {
- try
- {
- MoreExtractFromAEDesc::DispatchURLDirectly(inAppleEvent);
- }
- catch (...)
- {
- // Get a window
-
- CBrowserWindow* win = CBrowserWindow::FindAndShow(true);
- ThrowIfNil_(win);
-
- // Let the window handle the event
-
- CBrowserWindow::HandleGetURLEvent(inAppleEvent, outAEReply, outResult, win);
- }
- }
- }
- else
- {
- CBrowserWindow::HandleGetURLEvent(inAppleEvent, outAEReply, outResult);
- }
- } // CAppleEventHandler::HandleGetURLEvent
-
- /*--------------------------------------------------------------------------*/
- /* ---- The Spygless Suite ---- */
- /*--------------------------------------------------------------------------*/
-
- #define errMakeNewWindow 100
-
- /*----------------------------------------------------------------
- CAppleEventHandler::HandleOpenURLEvent Suite:Spyglass
- Open to a URL
- In: Incoming apple event, reply event, outtgoing descriptor, eventID
-
- Flavors of OpenURL
- #define AE_spy_openURL 'OURL' // typeChar OpenURL
- AE_spy_openURL_into // typeFSS into
- AE_spy_openURL_wind // typeLongInteger windowID
- AE_spy_openURL_flag // typeLongInteger flags
- 4 bits used.
- 1 =
- 2 =
- 4 =
- 8 = Open into editor window
- AE_spy_openURL_post // typeWildCard post data
- AE_spy_openURL_mime // typeChar MIME type
- AE_spy_openURL_prog // typePSN Progress app
-
- Just like with GetURL, figure out the window, and let it handle the load
- Arguments we care about: AE_spy_openURL_wind
-
- Out: OpenURLEvent handled
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleOpenURLEvent(
- const AppleEvent &inAppleEvent,
- AppleEvent &outAEReply,
- AEDesc &outResult,
- long /*inAENumber*/)
- {
- // We need to make sure
- CFrontApp::sApplication->ProperStartup( NULL, FILE_TYPE_GETURL );
-
- // Get the Flags to see if we want an editor
- try
- {
- long flags;
- DescType realType;
- Size actualSize;
- OSErr err = ::AEGetParamPtr(&inAppleEvent, AE_spy_openURL_flag, typeLongInteger,
- &realType, &flags, sizeof(flags), &actualSize);
- ThrowIfOSErr_(err);
- #ifdef EDITOR
- if (flags & 0x8)
- {
- // Get the url (in case we want an editor)
- char* url = NULL;
- MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, url);
- ThrowIfNil_(url);
- // MAJOR CRASHING BUG!!! if building Akbar 3.0 we should NOT CALL MakeEditWindow!!!
- URL_Struct * request = NET_CreateURLStruct (url, NET_DONT_RELOAD);
- XP_FREE (url);
- ThrowIfNil_(request);
- CEditorWindow::MakeEditWindow( NULL, request);
- return;
- }
- #endif // EDITOR
- }
- catch(...)
- {
- }
-
- if (CFrontApp::GetApplication()->HasProperlyStartedUp())
- {
- // Get the window, and let it handle the event
- try
- {
- Int32 windowID;
- Size realSize;
- OSType realType;
-
- OSErr err = ::AEGetParamPtr(&inAppleEvent, AE_spy_openURL_wind, typeLongInteger,
- &realType, &windowID, sizeof(windowID), &realSize);
- ThrowIfOSErr_(err);
-
- // If 0 then create a new window,
- // If FFFF set to front most window
- CBrowserWindow* win = NULL;
- if (windowID == 0)
- {
- win = CURLDispatcher::CreateNewBrowserWindow();
- }
- else if (windowID == 0xFFFFFFFF) // Frontmost window
- win = CBrowserWindow::FindAndShow();
- else
- win = CBrowserWindow::GetWindowByID(windowID);
-
- ThrowIfNil_(win);
- CBrowserWindow::HandleOpenURLEvent(inAppleEvent, outAEReply, outResult, win);
- }
- catch(...)
- {
- MoreExtractFromAEDesc::DispatchURLDirectly(inAppleEvent);
- return;
- }
- }
- else
- {
- CBrowserWindow::HandleOpenURLEvent(inAppleEvent, outAEReply, outResult);
- }
- } // CAppleEventHandler::HandleOpenURLEvent
-
-
- /*----------------------------------------------------------------
- ShowFile
- Similar to odoc, except that it takes a few extra arguments
- keyDirectObject file spec
- AE_spy_showFile_mime MIME type (optional)
- AE_spy_showFile_win window ID (optional)
- AE_spy_showFile_url url (optional)
-
- ShowFile: Similar to OpenDocuments, except that it specifies the parent
- URL, and MIME type of the file
-
- ShowFile
- alias -- File to open
- [MIME type string] -- MIME type
- [Window ID integer] -- Window to open the file in
- [URL string] -- Use this as a base URL
-
- Result:
- integer -- Window ID of the loaded window.
- 0 means ShowFile failed,
- FFFFFFF means that data was not appropriate type to display in the browser.
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleShowFile(const AppleEvent &inAppleEvent,
- AppleEvent& /*outAEReply*/, AEDesc& /*outResult*/, long /*inAENumber*/)
- {
- Assert_(false);
- char * url = NULL;
- char * mimeType = NULL;
- CBrowserWindow * win = NULL;
- FSSpec fileSpec;
- Boolean hasFileSpec = FALSE;
- OSErr err;
- Size realSize;
- OSType realType;
-
- // Get the file specs
- err = ::AEGetKeyPtr(&inAppleEvent, keyDirectObject, typeFSS,
- &realType, &fileSpec, sizeof(fileSpec), &realSize);
- ThrowIfOSErr_(err);
-
- // Get the window
- try
- {
- Int32 windowID;
- err = ::AEGetParamPtr(&inAppleEvent, AE_spy_openURL_wind, typeLongInteger,
- &realType, &windowID, sizeof(windowID), &realSize);
- ThrowIfOSErr_(err);
- win = CBrowserWindow::GetWindowByID(windowID);
- ThrowIfNil_(win);
- }
- catch (...)
- {
- win = CBrowserWindow::FindAndShow();
- ThrowIfNil_(win);
- }
-
- // Get the url
- try
- {
- MoreExtractFromAEDesc::GetCString(inAppleEvent, AE_spy_showFile_url, url);
- }
- catch(...)
- {
- }
-
- // Get the mime type
- try
- {
- MoreExtractFromAEDesc::GetCString(inAppleEvent, AE_spy_showFile_mime, mimeType);
- }
- catch(...)
- {
- }
-
- CFrontApp::sApplication->OpenLocalURL(&fileSpec, win, mimeType);
- }
-
- /*----------------------------------------------------------------
- ParseAnchor AppleEvent
- Gets the URL, the relative url, and returns the full url of the relative
-
- arse anchor: Resolves the relative URL
- parse anchor
- string -- Main URL
- relative to string -- Relative URL
- Result:
- string -- Parsed URL
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleParseAnchor(const AppleEvent
- &inAppleEvent, AppleEvent &outAEReply, AEDesc& /*outResult*/, long /*inAENumber*/)
- {
- char * url = nil;
- char * relative = nil;
- char * parsed = nil;
- MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, url);
- MoreExtractFromAEDesc::GetCString(inAppleEvent, AE_spy_parse_rel, relative);
- parsed = NET_MakeAbsoluteURL(url, relative);
- ThrowIfNil_(parsed);
-
- OSErr err = ::AEPutParamPtr(&outAEReply, keyAEResult, typeChar, parsed, strlen(parsed));
- if (parsed)
- XP_FREE(parsed);
- }
-
- /*----------------------------------------------------------------
- HandleCancelProgress
- Find the context with this transaction ID, and cancel it
- In: Incoming apple event, reply event, outtgoing descriptor, eventID
- Out: OpenURLEvent handled
-
- cancel progress:
- Interrupts the download of the document in the given window
-
- cancel progress
- integer -- progress ID, obtained from the progress app
- [in window integer] -- window ID of the progress to cancel
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleCancelProgress(const AppleEvent &inAppleEvent,
- AppleEvent & /* outAEReply */,
- AEDesc & /* outResult */,
- long /* inAENumber */)
- {
- // Find the window with this transaction, and let it handle the event
-
- try
- {
- Int32 transactionID;
- StAEDescriptor transDesc;
- Boolean hasTransactionID = FALSE;
- Boolean hasWindowID = FALSE;
- try
- {
- OSErr err = ::AEGetKeyDesc(&inAppleEvent, keyDirectObject, typeWildCard, &transDesc.mDesc);
- ThrowIfOSErr_(err);
- UExtractFromAEDesc::TheInt32(transDesc.mDesc, transactionID);
- hasTransactionID = TRUE;
- }
- catch(...)
- {
- }
- try
- {
- OSErr err = ::AEGetKeyDesc(&inAppleEvent, AE_spy_CancelProgress_win, typeWildCard, &transDesc.mDesc);
- ThrowIfOSErr_(err);
- UExtractFromAEDesc::TheInt32(transDesc.mDesc, transactionID);
- hasWindowID = TRUE;
- }
- catch(...)
- {
- }
-
- CBrowserWindow* window;
- if (!hasTransactionID && !hasWindowID) // No arguments, interrupt frontmost by default
- {
- window = CBrowserWindow::FindAndShow();
- if (window && window->GetWindowContext())
- NET_InterruptWindow(*(window->GetWindowContext()));
- }
- else
- {
- CMediatedWindow* theWindow;
- CWindowIterator iter(WindowType_Browser);
- while (iter.Next(theWindow))
- {
- CBrowserWindow* theBrowserWindow = dynamic_cast<CBrowserWindow*>(theWindow);
- CNSContext* nsContext = theBrowserWindow->GetWindowContext();
- if (((nsContext->GetTransactionID() == transactionID) && hasTransactionID)
- || ((nsContext->GetContextUniqueID() == transactionID) && hasWindowID))
- NET_InterruptWindow(*nsContext);
- }
- }
- }
- catch(...)
- {
- }
- }
-
-
- /*----------------------------------------------------------------
- webActivate: Makes Netscape the frontmost application, and selects a given
- window. This event is here for suite completeness/ cross-platform
- compatibility only, you should use standard AppleEvents instead.
-
- webActivate
- integer -- window to bring to front
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleSpyActivate(const AppleEvent &inAppleEvent, AppleEvent& /*outAEReply*/,
- AEDesc& /*outResult*/, long /*inAENumber*/)
- {
- Size realSize;
- OSType realType;
- CBrowserWindow * win = NULL;
- OSErr err;
-
- MakeFrontApplication();
- // Get the window, and select it
- try
- {
- Int32 windowID;
-
- err = ::AEGetParamPtr(&inAppleEvent, AE_spy_openURL_wind, typeLongInteger,
- &realType, &windowID, sizeof(windowID), &realSize);
- ThrowIfOSErr_(err);
-
- win = CBrowserWindow::GetWindowByID(windowID);
- if (win == nil)
- Throw_(errAENoSuchObject);
- UDesktop::SelectDeskWindow(win);
- }
- catch(...){}
- }
-
- /*----------------------------------------------------------------
- list windows: Lists the IDs of all the hypertext windows
-
- list windows
- Result:
- list -- List of unique IDs of all the hypertext windows
- ----------------------------------------------------------------*/
- void
- CAppleEventHandler::HandleSpyListWindows(
- const AppleEvent& inAppleEvent,
- AppleEvent& outAEReply,
- AEDesc& outResult,
- long inAENumber)
- {
- #pragma unused(inAppleEvent, outResult, inAENumber)
-
- AEDescList windowList;
- windowList.descriptorType = typeNull;
- OSErr err;
-
- try
- {
- // Create a descriptor list, and add a windowID for each browser window to the list
-
- CMediatedWindow* theWindow = NULL;
- DataIDT windowType = WindowType_Browser;
- CWindowIterator iter(windowType);
-
- err = ::AECreateList(nil, 0, FALSE, &windowList);
- ThrowIfOSErr_(err);
-
- while (iter.Next(theWindow))
- {
- CBrowserWindow* theBrowserWindow = dynamic_cast<CBrowserWindow*>(theWindow);
- ThrowIfNil_(theBrowserWindow);
-
- CBrowserContext* theBrowserContext = (CBrowserContext*)theBrowserWindow->GetWindowContext();
- ThrowIfNil_(theBrowserContext);
-
- StAEDescriptor theIDDesc(theBrowserContext->GetContextUniqueID());
- err = ::AEPutDesc(&windowList, 0, &theIDDesc.mDesc);
- ThrowIfOSErr_(err);
- }
- }
- catch (...)
- {
- if (windowList.descriptorType != typeNull)
- ::AEDisposeDesc(&windowList);
- throw;
- }
-
- err = ::AEPutParamDesc(&outAEReply, keyAEResult, &windowList);
- ThrowIfOSErr_(err);
- ::AEDisposeDesc(&windowList);
- }
-
-
- /*----------------------------------------------------------------
- Gets the window information, a list containing URL and title
- ## Another redundant event that has an equivalent event already
- specified by Apple
-
- get window info:
- Returns the information about the window as a list.
- Currently the list contains the window title and the URL.
- ## You can get the same information using standard Apple Event GetProperty.
-
- get window info
- integer -- window ID
- Result:
- list -- contains URL and title strings
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleSpyGetWindowInfo(const AppleEvent &inAppleEvent, AppleEvent &outAEReply,
- AEDesc& /*outResult*/, long /*inAENumber*/)
- {
- Size realSize;
- OSType realType;
- CBrowserWindow * win = NULL; // Window
- OSErr err;
- AEDescList volatile propertyList;
- propertyList.descriptorType = typeNull;
-
- try
- {
- // Get the window, and list its properties
- Int32 windowID;
-
- err = ::AEGetParamPtr(&inAppleEvent, keyDirectObject, typeLongInteger,
- &realType, &windowID, sizeof(windowID), &realSize);
- ThrowIfOSErr_(err);
- win = CBrowserWindow::GetWindowByID(windowID);
- if (win == nil)
- Throw_(errAENoSuchObject);
-
- // Create the list
- err = ::AECreateList(nil, 0, FALSE, &propertyList);
- ThrowIfOSErr_(err);
-
- // Put the URL as the first item in the list
- cstring url = win->GetWindowContext()->GetCurrentURL();
- err = ::AEPutPtr(&propertyList, 1, typeChar, (char*)url, url.length());
- ThrowIfOSErr_(err);
-
- // Put the title as the second item in the list
- CStr255 ptitle;
- GetWTitle(win->GetMacPort(), ptitle);
- cstring ctitle((char*)ptitle);
- err = ::AEPutPtr(&propertyList, 2, typeChar, (char*)ctitle, ctitle.length());
- ThrowIfOSErr_(err);
-
- // Put the list as the reply
- err = ::AEPutParamDesc(&outAEReply, keyAEResult, &propertyList);
- ::AEDisposeDesc(&propertyList);
- }
- catch(...)
- {
- if (propertyList.descriptorType != typeNull)
- ::AEDisposeDesc(&propertyList);
- throw;
- }
- }
-
- /*----------------------------------------------------------------
- register window close:
- Netscape will notify registered application when this window closes
-
- register window close
- 'sign' -- Application signature for window
- integer -- window ID
-
- [Result: boolean] -- true if successful
-
- unregister window close:
- Undo for register window close unregister window close
-
- 'sign' -- Application signature for window
- integer -- window ID
-
- [Result: boolean] -- true if successful
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleWindowRegistration(const AppleEvent &inAppleEvent, AppleEvent &outAEReply,
- AEDesc &outResult, long inAENumber)
- {
- Size realSize;
- OSType realType;
- CBrowserWindow * win = NULL;
- OSErr err;
-
- // Get the window, and select it
- Int32 windowID;
-
- err = ::AEGetParamPtr(&inAppleEvent, AE_spy_registerWinClose_win, typeLongInteger,
- &realType, &windowID, sizeof(windowID), &realSize);
- ThrowIfOSErr_(err);
-
- win = CBrowserWindow::GetWindowByID(windowID);
- if (win == nil)
- Throw_(errAENoSuchObject);
- win->HandleAppleEvent(inAppleEvent, outAEReply, outResult, inAENumber);
- }
-
-
-
- /*--------------------------------------------------------------------------*/
- /* ---- Experimental Netscape Suite ---- */
- /*--------------------------------------------------------------------------*/
-
- /*----------------------------------------------------------------
- Open bookmark: Reads in a bookmark file
-
- Open bookmark
- alias -- If not available, reloads the current bookmark file
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleOpenBookmarksEvent( const AppleEvent &inAppleEvent,
- AppleEvent & /*outAEReply*/,
- AEDesc & /*outResult*/,
- long /*inAENumber*/)
- {
- FSSpec fileSpec;
- Boolean hasFileSpec = FALSE;
- OSErr err;
- Size realSize;
- OSType realType;
-
- char * path = NULL;
-
- // Get the file specs
- err = ::AEGetKeyPtr(&inAppleEvent, keyDirectObject, typeFSS,
- &realType, &fileSpec, sizeof(fileSpec), &realSize);
-
- // If none, use the default file
- // I hate this glue to uapp. Will change as soon as all AE stuff
- // is working.
- if (err != noErr)
- path = GetBookmarksPath( fileSpec, TRUE );
- else
- path = GetBookmarksPath( fileSpec, FALSE );
-
- ThrowIfNil_(path);
-
- DebugStr("\pNot implemented");
- //ÑÑÑ CBookmarksContext::Initialize();
- //ÑÑÑ BM_ReadBookmarksFromDisk( *CBookmarksContext::GetInstance(), path, NULL );
- }
-
- /*----------------------------------------------------------------
- Open AddressBook: Opens the address book
-
- Open AddressBook
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleOpenAddressBookEvent(
- const AppleEvent &/*inAppleEvent*/,
- AppleEvent & /*outAEReply*/,
- AEDesc & /*outResult*/,
- long /*inAENumber*/)
- {
- #ifdef MOZ_MAIL_NEWS
- CAddressBookManager::ShowAddressBookWindow();
- #endif // MOZ_MAIL_NEWS
- }
-
-
- /*----------------------------------------------------------------
- Open Component: Opens the component specified in the parameter
- to the Apple Event.
-
- HandleOpenComponentEvent
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleOpenComponentEvent(
- const AppleEvent &inAppleEvent,
- AppleEvent & /*outAEReply*/,
- AEDesc & /*outResult*/,
- long /*inAENumber*/)
- {
- OSType componentType;
- DescType returnedType;
- Size gotSize = 0;
-
- OSErr err = ::AEGetKeyPtr(&inAppleEvent, keyDirectObject, typeEnumerated, &returnedType, &componentType,
- sizeof(OSType), &gotSize);
-
- if (err == noErr && gotSize == sizeof(OSType))
- {
- switch (componentType)
- {
- case AE_www_comp_navigator:
- CFrontApp::sApplication->ObeyCommand(cmd_BrowserWindow);
- break;
-
- #ifdef MOZ_MAIL_NEWS
- case AE_www_comp_inbox:
- CFrontApp::sApplication->ObeyCommand(cmd_Inbox);
- break;
-
- case AE_www_comp_collabra:
- CFrontApp::sApplication->ObeyCommand(cmd_MailNewsFolderWindow);
- break;
- #endif // MOZ_MAIL_NEWS
- #ifdef EDITOR
- case AE_www_comp_composer:
- CFrontApp::sApplication->ObeyCommand(cmd_NewWindowEditor);
- break;
- #endif // EDITOR
- #if !defined(MOZ_LITE) && !defined(MOZ_MEDIUM)
- case AE_www_comp_conference:
- CFrontApp::sApplication->ObeyCommand(cmd_LaunchConference);
- break;
-
- case AE_www_comp_calendar:
- CFrontApp::sApplication->ObeyCommand(cmd_LaunchCalendar);
- break;
-
- case AE_www_comp_ibmHostOnDemand:
- CFrontApp::sApplication->ObeyCommand(cmd_Launch3270);
- break;
- #endif
- #ifdef MOZ_NETCAST
- case AE_www_comp_netcaster:
- CFrontApp::sApplication->ObeyCommand(cmd_LaunchNetcaster);
- break;
- #endif // MOZ_NETCAST
- default:
- ; //do nothing
- }
- }
- }
-
-
- /*----------------------------------------------------------------
- HandleCommandEvent
-
- Get new mail
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleCommandEvent(
- const AppleEvent & inAppleEvent,
- AppleEvent & /*outAEReply*/,
- AEDesc & /*outResult*/,
- long /*inAENumber*/)
- {
-
- long commandID;
- DescType returnedType;
- Size gotSize = 0;
-
- OSErr err = ::AEGetKeyPtr(&inAppleEvent, keyDirectObject, typeEnumerated, &returnedType,
- &commandID, sizeof(long), &gotSize);
-
- if (err == noErr && gotSize == sizeof(long))
- {
- // Is this really only for mail????
- #ifdef MOZ_MAIL_NEWS
- CFrontApp::sApplication->ObeyCommand(commandID);
- #endif // MOZ_MAIL_NEWS
-
-
- }
- }
-
-
- /*----------------------------------------------------------------
- Read help file:
- Reads in the help file (file should be in the help file format)
- ## Questions about the new help file system, ask montulli
-
- Read help file
- alias
- [with index string] -- Index to the help file. Defaults to ╘DEFAULT╒)
- [search text string] -- Optional text to search for
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleReadHelpFileEvent(const AppleEvent &inAppleEvent,
- AppleEvent & /*outAEReply*/,
- AEDesc & /*outResult*/,
- long /*inAENumber*/)
- {
- FSSpec fileSpec;
- char * map_file_url = NULL;
- char * help_id = NULL;
- char * search_text = NULL;
- OSErr err;
- Size realSize;
- OSType realType;
-
- CFrontApp::sApplication->ProperStartup(NULL, FILE_TYPE_NONE);
-
- try
- {
- // Get the file specs
- err = ::AEGetKeyPtr(&inAppleEvent, keyDirectObject, typeFSS,
- &realType, &fileSpec, sizeof(fileSpec), &realSize);
- ThrowIfOSErr_(err);
-
- map_file_url = CFileMgr::GetURLFromFileSpec( fileSpec );
- ThrowIfNil_(map_file_url);
-
- // Get the help text
-
- try
- {
- MoreExtractFromAEDesc::GetCString(inAppleEvent, AE_www_ReadHelpFileID, help_id);
- }
- catch(...)
- {
- }
-
- // Get the search text (optional)
- try
- {
- MoreExtractFromAEDesc::GetCString(inAppleEvent, AE_www_ReadHelpFileSearchText, search_text);
- }
- catch(...)
- {}
- }
- catch(...)
- {
- throw;
- }
-
- // Will using the bookmark context as a dummy work?
- DebugStr("\pNot implemented");
- //ÑÑÑ CBookmarksContext::Initialize();
- //ÑÑÑ NET_GetHTMLHelpFileFromMapFile(*CBookmarksContext::GetInstance(),
- // map_file_url, help_id, search_text);
-
- FREEIF(map_file_url);
- FREEIF(help_id);
- FREEIF(search_text);
- }
-
- /*----------------------------------------------------------------
- Go: navigate a window: back, forward, again(reload), home)
- Go
- reference -- window
- direction again/home/backward/forward
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleGoEvent(
- const AppleEvent &inAppleEvent,
- AppleEvent &outAEReply,
- AEDesc &outResult,
- long inAENumber)
- {
- // We need to make sure
-
- CFrontApp::sApplication->ProperStartup( NULL, FILE_TYPE_GETURL );
- CBrowserWindow * win = NULL;
-
- // Get the window. If it is a Browser window then
- // decode the AE and send a message.
-
- // The keyData.mDesc should be a ref to a browser window
- // If we get it successfulle (ie the user included the "in window 1"
- // then we can get a hold of the actual BrowserWindow object by using
- // AEResolve and GetModelFromToken somehow
- StAEDescriptor keyData;
- OSErr err = ::AEGetKeyDesc(&inAppleEvent, AE_www_typeWindow, typeWildCard, &keyData.mDesc);
- if ((err == noErr) && (keyData.mDesc.descriptorType == typeObjectSpecifier))
- {
- StAEDescriptor theToken;
- err = ::AEResolve(&keyData.mDesc, kAEIDoMinimum, &theToken.mDesc);
- ThrowIfOSErr_(err);
- LModelObject * model = CFrontApp::sApplication->GetModelFromToken(theToken.mDesc);
- ThrowIfNil_(model);
- model->HandleAppleEvent(inAppleEvent, outAEReply, outResult, inAENumber);
-
- // else the user did not provide an inside reference "inside window 1"
- // so send back an error
- }else{
-
- }
- }
-
- /*----------------------------------------------------------------
- Get workingURL:
- Get the path to the running application in URL format.
- This will allow a script to construct a relative URL
-
- Get workingURL
- Result:
- 'tTXT' -- Will return text of the from ╥FILE://foo/applicationname╙
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleGetWDEvent(
- const AppleEvent & /*inAppleEvent */,
- AppleEvent & outAEReply,
- AEDesc & /*outResult */,
- long /*inAENumber */)
- {
- char *pathBlock = NULL;
- Size pathLength;
- OSErr err;
-
- // Grab the URL of the running application
- pathBlock = PathURLFromProcessSignature (emSignature, 'APPL');
-
- if (outAEReply.dataHandle != NULL && pathBlock != NULL)
- {
- pathLength = XP_STRLEN(pathBlock);
-
- err = AEPutParamPtr( &outAEReply,
- keyDirectObject,
- typeChar,
- pathBlock, pathLength);
- }
-
- if (pathBlock)
- XP_FREE(pathBlock);
-
- }
-
-
- /*----------------------------------------------------------------
- HandleGetActiveProfileEvent:
- Get the name of the active profile from the prefs.
-
- Result:
- 'tTXT' -- Will return text of the profile name
- ----------------------------------------------------------------*/
- void CAppleEventHandler::HandleGetActiveProfileEvent(
- const AppleEvent & /*inAppleEvent */,
- AppleEvent &outAEReply,
- AEDesc & /*outResult */,
- long /*inAENumber */)
- {
- char profileName[255];
- int len = 255;
- OSErr err = noErr;
-
- err = PREF_GetCharPref("profile.name", profileName, &len);
-
- if (err == PREF_NOERROR && outAEReply.dataHandle != nil) {
-
- err = AEPutParamPtr( &outAEReply,
- keyDirectObject,
- typeChar,
- profileName, strlen(profileName));
- }
- }
-
-
- /*--------------------------------------------------------------------------*/
- /* ---- Apple Event Object Model support ---- */
- /*--------------------------------------------------------------------------*/
-
- void CAppleEventHandler::GetSubModelByUniqueID(DescType inModelID, const AEDesc &inKeyData, AEDesc &outToken) const
- {
- switch (inModelID)
- {
- case cWindow: // The hyperwindows have unique IDs that can be resolved
- // FFFFFFFFF is the front window, 0 is a new window
- Int32 windowID;
- UExtractFromAEDesc::TheInt32(inKeyData, windowID);
- LWindow* foundWindow = NULL;
-
- foundWindow = CBrowserWindow::GetWindowByID(windowID);
- if (foundWindow == NULL)
- ThrowOSErr_(errAENoSuchObject);
- else
- CFrontApp::sApplication->PutInToken(foundWindow, outToken);
- break;
- default:
- CFrontApp::sApplication->LDocApplication::GetSubModelByUniqueID(inModelID, inKeyData, outToken);
- break;
- }
- }
-
- void CAppleEventHandler::GetAEProperty(DescType inProperty,
- const AEDesc &inRequestedType,
- AEDesc &outPropertyDesc) const
- {
- OSErr err;
-
- switch (inProperty)
- {
- case AE_www_typeApplicationAlert: // application that handles alerts
- err = ::AECreateDesc(typeType, &ErrorManager::sAlertApp,
- sizeof(ErrorManager::sAlertApp), &outPropertyDesc);
- ThrowIfOSErr_(err);
- break;
-
- case AE_www_typeKioskMode:
- err = ::AECreateDesc(typeLongInteger, (const void *)fKioskMode,
- sizeof(fKioskMode), &outPropertyDesc);
- break;
-
- default:
- CFrontApp::sApplication->LApplication::GetAEProperty(inProperty, inRequestedType, outPropertyDesc);
- break;
- }
- }
-
- void CAppleEventHandler::SetAEProperty(DescType inProperty,
- const AEDesc &inValue,
- AEDesc &outPropertyDesc)
- {
-
- switch (inProperty) {
- case AE_www_typeApplicationAlert: // application that handles alerts
- try
- {
- OSType newSig;
- UExtractFromAEDesc::TheType(inValue, newSig);
- ErrorManager::sAlertApp = newSig;
- }
- catch(...) // In case of error, revert to self
- {
- ErrorManager::sAlertApp = emSignature;
- }
- break;
- case AE_www_typeKioskMode:
- try
- {
- Boolean menuBarModeChangeBroadcasted = false;
- Int32 kMode;
- UExtractFromAEDesc::TheInt32(inValue, kMode);
-
- if ((kMode == KioskOn) && (fKioskMode != KioskOn))
- {
- fKioskMode = KioskOn;
- // SetMenubar(KIOSK_MENUBAR); ÑÑÑ this is currently handled by the chrome structure, below
- // BUT, they want three states for menu bars, and the field is only a boolean
-
- CMediatedWindow* theIterWindow = NULL;
- DataIDT windowType = WindowType_Browser;
- CWindowIterator theWindowIterator(windowType);
-
- while (theWindowIterator.Next(theIterWindow))
- {
- CBrowserWindow* theBrowserWindow = dynamic_cast<CBrowserWindow*>(theIterWindow);
- if (theBrowserWindow != nil)
- {
- Chrome aChrome;
- theBrowserWindow->GetChromeInfo(&aChrome);
- aChrome.show_button_bar = 0;
- aChrome.show_url_bar = 0;
- aChrome.show_directory_buttons = 0;
- aChrome.show_security_bar = 0;
- aChrome.show_menu = 0; // ÑÑÑ this isn't designed correctly! deeje 97-03-13
-
- // Make sure we only broadcast the menubar mode change once!
- theBrowserWindow->SetChromeInfo(&aChrome, !menuBarModeChangeBroadcasted);
- if (!menuBarModeChangeBroadcasted)
- {
- menuBarModeChangeBroadcasted = true;
- }
- }
- }
- }
- else if ((kMode == KioskOff) && (fKioskMode != KioskOff))
- {
- fKioskMode = KioskOff;
- // SetMenubar(MAIN_MENUBAR); ÑÑÑ this is currently handled by the chrome structure, below
- // BUT, they want three states for menu bars, and the field is only a boolean
-
- CMediatedWindow* theIterWindow = NULL;
- DataIDT windowType = WindowType_Browser;
- CWindowIterator theWindowIterator(windowType);
-
- while (theWindowIterator.Next(theIterWindow))
- {
- CBrowserWindow* theBrowserWindow = dynamic_cast<CBrowserWindow*>(theIterWindow);
- if (theBrowserWindow != nil)
- {
- Chrome aChrome;
- theBrowserWindow->GetChromeInfo(&aChrome);
- aChrome.show_button_bar = CPrefs::GetBoolean(CPrefs::ShowToolbar);
- aChrome.show_url_bar = CPrefs::GetBoolean(CPrefs::ShowURL);
- aChrome.show_directory_buttons = CPrefs::GetBoolean(CPrefs::ShowDirectory);
- aChrome.show_security_bar = CPrefs::GetBoolean(CPrefs::ShowToolbar) || CPrefs::GetBoolean(CPrefs::ShowURL);
- aChrome.show_menu = 1; // ÑÑÑ this isn't designed correctly! deeje 97-03-13
-
- // Make sure we only broadcast the menubar mode change once!
- theBrowserWindow->SetChromeInfo(&aChrome, !menuBarModeChangeBroadcasted);
- if (!menuBarModeChangeBroadcasted)
- {
- menuBarModeChangeBroadcasted = true;
- }
- }
- }
- }
-
- }
- catch(...)
- {}
- break;
- default:
- CFrontApp::sApplication->LApplication::SetAEProperty(inProperty, inValue, outPropertyDesc);
- break;
- }
-
-
- }
-
- /*--------------------------------------------------------------------------*/
- /* ---- Eudora (send) Mail Suite ---- */
- /*--------------------------------------------------------------------------*/
-
-
- /*-------------------------------------------------------------*/
- // class EudoraSuite This supports sending to Eudora
- // Tools used to communicate with Eudora
- // The only real use these have is if we are operating in
- // Browser-only mode and the user wishes to use Eudora to
- // handle mail functions.
- //
- /*-------------------------------------------------------------*/
-
-
- // --------------------------------------------------------------
- /* This makes a Null AppleEvent descriptor.
- */
- // --------------------------------------------------------------
- void EudoraSuite::MakeNullDesc (AEDesc *theDesc)
- {
- theDesc->descriptorType = typeNull;
- theDesc->dataHandle = nil;
- }
-
- // --------------------------------------------------------------
- /* This makes a string AppleEvent descriptor.
- In: A pascal string
- Pointer to an AEDesc.
-
- Out: AEDesc of type TEXT created and returned. */
- // --------------------------------------------------------------
- OSErr EudoraSuite::MakeStringDesc (Str255 theStr,AEDesc *theDesc)
- {
- return AECreateDesc(kAETextSuite, &theStr[1], StrLength(theStr), theDesc);
- }
-
- // --------------------------------------------------------------
- /* This stuffs the required parameters into the AppleEvent.
- */
- // --------------------------------------------------------------
-
-
- OSErr EudoraSuite::CreateObjSpecifier (AEKeyword theClass,AEDesc theContainer,
- AEKeyword theForm,AEDesc theData, Boolean /*disposeInputs*/,AEDesc *theSpec)
- {
- AEDesc theRec;
- OSErr err;
-
- err = AECreateList(nil,0,true,&theRec);
- if (!err)
- err = AEPutKeyPtr(&theRec,keyAEKeyForm,typeEnumeration,&theForm,sizeof(theForm));
- if (!err)
- err = AEPutKeyPtr(&theRec,keyAEDesiredClass,cType,&theClass,sizeof(theClass));
- if (!err)
- err = AEPutKeyDesc(&theRec,keyAEKeyData,&theData);
- if (!err)
- err = AEPutKeyDesc(&theRec,keyAEContainer,&theContainer);
- if (!err)
- err = AECoerceDesc(&theRec,cObjectSpecifier,theSpec);
- AEDisposeDesc(&theRec);
- return err;
- }
-
- // --------------------------------------------------------------
- /* This creates an AEDesc for the current message.
- (The current message index = 1)
-
- In: Pointer to AEDesc to return
- Out: AEDesc constructed. */
- // --------------------------------------------------------------
-
- OSErr EudoraSuite::MakeCurrentMsgSpec (AEDesc *theSpec)
- {
- AEDesc theContainer,theIndex;
- OSErr err;
- long msgIndex = 1;
-
- EudoraSuite::MakeNullDesc (&theContainer);
- err = AECreateDesc(cLongInteger, &msgIndex, sizeof(msgIndex), &theIndex);
- if (!err)
- err = EudoraSuite::CreateObjSpecifier(cEuMessage, theContainer,
- formAbsolutePosition, theIndex, true, theSpec);
-
- AEDisposeDesc(&theContainer);
- AEDisposeDesc(&theIndex);
-
- return err;
- }
-
-
- // --------------------------------------------------------------
- /* Send a given Apple Event. Special case for Eudora, should
- be rewritten, but it works for the moment.
- In: AppleEvent
- Out: Event sent */
- // --------------------------------------------------------------
- OSErr EudoraSuite::SendEvent (AppleEvent *theEvent)
- {
- AppleEvent theReply;
- OSErr err;
-
- EudoraSuite::MakeNullDesc(&theReply);
- err = AESend(theEvent,&theReply,kAENoReply + kAENeverInteract
- + kAECanSwitchLayer+kAEDontRecord,kAENormalPriority,-1,nil,nil);
-
- AEDisposeDesc(&theReply);
- AEDisposeDesc(theEvent);
-
- return err;
- }
-
- // --------------------------------------------------------------
- /* Create an Apple Event to be sent to Eudora
- In: Event Class
- Event ID
- Ptr to Apple Event
- Out: Event constructed and returned. */
- // --------------------------------------------------------------
- OSErr EudoraSuite::MakeEvent (AEEventClass eventClass,AEEventID eventID,AppleEvent *theEvent)
- {
- AEAddressDesc theTarget;
- OSType theSignature;
- OSErr err;
-
- theSignature = kEudoraSuite;
- err = AECreateDesc(typeApplSignature,&theSignature,sizeof(theSignature),&theTarget);
- if (!err)
- err = AECreateAppleEvent(eventClass,eventID,&theTarget,0,0,theEvent);
- AEDisposeDesc(&theTarget);
- return err;
- }
-
- // --------------------------------------------------------------
- /* This sets the data in a specified field. It operates on the frontmost message
- in Eudora. It is the equivalent of sending the following AppleScript:
- set field "fieldname" of message 0 to "data"
-
- Examples for setting up a complete mail message:
- EudoraSuite::SendSetData("\pto",toRecipientPtr);
- EudoraSuite::SendSetData("\pcc",ccRecipientPtr);
- EudoraSuite::SendSetData("\pbcc",bccRecipientPtr);
- EudoraSuite::SendSetData("\psubject",subjectPtr);
- EudoraSuite::SendSetData("\p",bodyPtr);
-
- In: Field to set the data in (Subject, Address, Content, etc)
- Pointer to text data.
- Size of pointer (allows us to work with XP_Ptrs).
- Out: Apple Event sent to Eudora, setting a given field. */
- // --------------------------------------------------------------
- OSErr EudoraSuite::SendSetData(Str31 theFieldName, Ptr thePtr, long thePtrSize)
- {
- AEDesc theMsg,theName,theFieldSpec,theText;
- AppleEvent theEvent;
- OSErr err;
- Handle theData;
-
- theData = NewHandle(thePtrSize);
- BlockMove((Ptr)thePtr,*theData,thePtrSize);
-
- if (theData != nil)
- {
-
- err = EudoraSuite::MakeCurrentMsgSpec(&theMsg);
- if (!err)
- err = EudoraSuite::MakeStringDesc(theFieldName,&theName);
- if (!err)
- err = EudoraSuite::CreateObjSpecifier(cEuField,theMsg,formName,theName,true,&theFieldSpec);
- if (!err)
- err = EudoraSuite::MakeEvent(kAECoreSuite,kAESetData,&theEvent);
- if (!err)
- err = AEPutParamDesc(&theEvent,keyAEResult,&theFieldSpec);
- AEDisposeDesc(&theFieldSpec);
-
- theText.descriptorType = typeChar;
- theText.dataHandle = theData;
- if (!err)
- err = AEPutParamDesc(&theEvent,keyAEData,&theText);
- if (!err)
- err = EudoraSuite::SendEvent(&theEvent);
-
- DisposeHandle(theText.dataHandle);
- AEDisposeDesc(&theText);
- AEDisposeDesc(&theMsg);
- AEDisposeDesc(&theName);
- }
- DisposeHandle(theData);
- return err;
-
- }
- // --------------------------------------------------------------
- /* Everything you need to tell Eudora to construct a new message
- and send it.
- In: Pointer to the list of e mail addresses to send TO
- Pointer to the list of e mail addresses to send CC
- Pointer to the list of e mail addresses to send BCC
- Pointer to the Subject text
- Priority level of message.
- Pointer to the contents of the mail
- Pointer to an FSSpec (or null if none) for an enclosure.
- Out: Apple Events sent to Eudora telling it to construct the
- message and send it. */
- // --------------------------------------------------------------
-
- OSErr EudoraSuite::SendMessage(
- Ptr toRecipientPtr,
- Ptr ccRecipientPtr,
- Ptr bccRecipientPtr,
- Ptr subjectPtr,
- XP_HUGE_CHAR_PTR bodyPtr,
- long thePriority,
- FSSpec *theEnclosurePtr)
- {
- AEDesc nullSpec,theName,theFolder,theMailbox,theInsertRec,theInsl,msgSpec,theEnclList;
- OSType thePos,theClass;
- AppleEvent theEvent;
- OSErr err;
-
-
- /* This section creates a new message and places it at the end of the out mailbox.
- It is equivalent to the following AppleScript:
- make message at end of mailbox "out" of mail folder ""
- */
-
-
- MakeNullDesc(&nullSpec);
- err = MakeStringDesc("\p",&theName);
- if (!err)
- err = EudoraSuite::CreateObjSpecifier(cEuMailfolder,nullSpec,formName,theName,true,&theFolder);
-
-
- if (!err)
- err = MakeStringDesc("\pout",&theName);
- if (!err)
- err = EudoraSuite::CreateObjSpecifier(cEuMailbox,theFolder,formName,theName,true,&theMailbox);
- if (!err)
- err = AECreateList(nil,0,true,&theInsertRec);
- if (!err)
- err = AEPutKeyDesc(&theInsertRec,keyAEObject,&theMailbox);
-
-
- thePos=kAEEnd;
- if (!err)
- err = AEPutKeyPtr(&theInsertRec,keyAEPosition,typeEnumeration,&thePos,sizeof(thePos));
-
- if (!err)
- err = AECoerceDesc(&theInsertRec,typeInsertionLoc,&theInsl);
-
- if (!err)
- err = EudoraSuite::MakeEvent(kAECoreSuite,kAECreateElement,&theEvent);
- if (!err)
- err = AEPutParamDesc(&theEvent,keyAEInsertHere,&theInsl);
-
- AEDisposeDesc(&nullSpec);
- AEDisposeDesc(&theName);
- AEDisposeDesc(&theFolder);
- AEDisposeDesc(&theMailbox);
- AEDisposeDesc(&theInsertRec);
- AEDisposeDesc(&theInsl);
-
- theClass=cEuMessage;
- if (!err)
- err = AEPutParamPtr(&theEvent,keyAEObjectClass,cType,&theClass,sizeof(theClass));
- if (!err)
- err = EudoraSuite::SendEvent(&theEvent);
-
-
- /* This section fills in various fields.
- It is equivalent to the following AppleScript:
- set field "to" of message 0 to "data"
- */
-
- if (!err) {
- if ( toRecipientPtr )
- err = SendSetData("\pto",toRecipientPtr, GetPtrSize(toRecipientPtr));
- }
-
- if (!err) {
- if ( ccRecipientPtr )
- err = SendSetData("\pcc",ccRecipientPtr, GetPtrSize(ccRecipientPtr));
- }
- if (!err) {
- if ( bccRecipientPtr )
- err = SendSetData("\pbcc",bccRecipientPtr, GetPtrSize(bccRecipientPtr));
- }
-
- if (!err)
- err = SendSetData("\psubject",subjectPtr, GetPtrSize(subjectPtr));
- if (!err)
- err = SendSetData("\p",bodyPtr, XP_STRLEN(bodyPtr) );
-
- /* This sets the priority of the message. See the constants defined above for the legal
- values.
- */
-
- err = Set_Eudora_Priority(thePriority);
-
-
- /* This attaches a file to the Eudora message provided it is a proper FSSpec. */
- if (StrLength(theEnclosurePtr->name)>0)
- {
- if (!err)
- err = MakeCurrentMsgSpec(&msgSpec);
- if (!err)
- err = EudoraSuite::MakeEvent(kEudoraSuite,kEuAttach,&theEvent);
- if (!err)
- err = AEPutParamDesc(&theEvent,keyAEResult,&msgSpec);
- if (!err)
- err = AECreateList(nil,0,false,&theEnclList);
- if (!err)
- err = AEPutPtr(&theEnclList,0,typeFSS,&theEnclosurePtr->name,
- sizeof(theEnclosurePtr->name) );
- if (!err)
- err = AEPutParamDesc(&theEvent,keyEuDocumentList,&theEnclList);
- if (!err)
- err = EudoraSuite::SendEvent(&theEvent);
- AEDisposeDesc(&msgSpec);
- AEDisposeDesc(&theEnclList);
- }
-
-
- /* This tells Eudora to queue the current message. */
- if (!err)
- err = EudoraSuite::MakeCurrentMsgSpec(&msgSpec);
- if (!err)
- err = EudoraSuite::MakeEvent(kEudoraSuite,kEuQueue,&theEvent);
- if (!err)
- err = AEPutParamDesc(&theEvent,keyAEResult,&msgSpec);
- AEDisposeDesc(&msgSpec);
- if (!err)
- err = EudoraSuite::SendEvent(&theEvent);
-
- return err;
-
- }
-
- // --------------------------------------------------------------
- /* Given the priority of a message, this sets the priority in the message.
- This same type of procedure can be used for many of the AppleScript commands in
- the form of: set <item> of message 0 to <data>
-
- */
- // --------------------------------------------------------------
-
- OSErr EudoraSuite::Set_Eudora_Priority(long thePriority)
- {
- AEDesc theMsg,theData,thePropSpec,thePriorityDesc;
- AppleEvent theEvent;
- OSErr theErr;
- AEKeyword theProperty;
- Handle h;
-
- theErr = MakeCurrentMsgSpec(&theMsg);
-
- theProperty = pEuPriority;
- AECreateDesc(typeType,&theProperty,sizeof (theProperty),&thePriorityDesc);
-
- if (!theErr)
- theErr = CreateObjSpecifier(typeProperty,theMsg,typeProperty,thePriorityDesc,true,&thePropSpec);
- if (!theErr)
- theErr = MakeEvent(kAECoreSuite,kAESetData,&theEvent);
-
- if (!theErr)
- theErr = AEPutKeyDesc(&theEvent, keyDirectObject, &thePropSpec);
- if (!theErr)
- theErr = AEDisposeDesc(&thePropSpec);
-
- h = NewHandle (sizeof(thePriority));
- BlockMove ((Ptr)&thePriority,*h,sizeof(thePriority));
- theData.descriptorType = typeInteger;
- theData.dataHandle = h;
- if (!theErr)
- theErr=AEPutParamDesc(&theEvent,keyAEData,&theData);
- if (!theErr)
- theErr = SendEvent(&theEvent);
- DisposeHandle(h);
- AEDisposeDesc(&theMsg);
- AEDisposeDesc(&theData);
- AEDisposeDesc(&thePriorityDesc);
-
- return theErr;
-
- }
-
-
-
- /*-------------------------------------------------------------*/
- // class MoreExtractFromAEDesc
- // Apple event helpers -- extension of UExtractFromAEDesc.h
- // All the miscelaneous AppleEvent helper routines.
- /*-------------------------------------------------------------*/
-
-
- // --------------------------------------------------------------
- /* Given an AppleEvent, locate a string given a keyword and
- return the string
- In: Event to search
- AEKeyword assocaated with the string
- C string ptr
- Out: Pointer to a newly created C string returned */
- // --------------------------------------------------------------
- void MoreExtractFromAEDesc::GetCString(const AppleEvent &inAppleEvent,
- AEKeyword keyword, char * & s)
- {
- StAEDescriptor desc;
- OSErr err = ::AEGetParamDesc(&inAppleEvent,keyword,typeWildCard,&desc.mDesc);
-
- ThrowIfOSErr_(err);
- TheCString(desc, s);
- }
-
- // --------------------------------------------------------------
- /* Given an AEDesc of type typeChar, return its string.
- In: AEDesc containing a string
- C string ptr
- Out: Pointer to a newly created C string returned */
- // --------------------------------------------------------------
- void MoreExtractFromAEDesc::TheCString(const AEDesc &inDesc, char * & outPtr)
- {
- outPtr = nil;
- Handle dataH;
- AEDesc coerceDesc = {typeNull, nil};
- if (inDesc.descriptorType == typeChar) {
- dataH = inDesc.dataHandle; // Descriptor is the type we want
-
- } else { // Try to coerce to the desired type
- if (AECoerceDesc(&inDesc, typeChar, &coerceDesc) == noErr) {
- // Coercion succeeded
- dataH = coerceDesc.dataHandle;
-
- } else { // Coercion failed
- ThrowOSErr_(errAETypeError);
- }
- }
-
- Int32 strLength = GetHandleSize(dataH);
- outPtr = (char *)XP_ALLOC(strLength+1); // +1 for NULL ending
- ThrowIfNil_( outPtr );
- // Terminate the string
- BlockMoveData(*dataH, outPtr, strLength);
- outPtr[strLength] = 0;
-
- if (coerceDesc.dataHandle != nil) {
- AEDisposeDesc(&coerceDesc);
- }
- }
-
- // --------------------------------------------------------------
- /* Add an error string and error code to an AppleEvent.
- Typically used when constructing the return event when an
- error occured
- In: Apple Event to append to
- Error string
- Error code
- Out: keyErrorNum and keyErrorSting AEDescs are added to the Event. */
- // --------------------------------------------------------------
- void MoreExtractFromAEDesc::MakeErrorReturn(AppleEvent &event,const
- CStr255& errorString, OSErr errorCode)
- {
- StAEDescriptor errorNum(errorCode);
- StAEDescriptor errorText((ConstStringPtr)errorString);
- // We can ignore the errors. If error occurs, it only means that the reply is not handled
- OSErr err = ::AEPutParamDesc(&event, keyErrorNumber, &errorNum.mDesc);
- err = ::AEPutParamDesc(&event, keyErrorString, &errorText.mDesc);
- }
-
- // --------------------------------------------------------------
- /* Display an error dialog if the given AppleEvent contains
- a keyErrorNumber. a keyErrorString is optional and will be
- displayed if present
- In: Apple Event
- Out: Error dialog displayed if error data present. */
- // --------------------------------------------------------------
- Boolean MoreExtractFromAEDesc::DisplayErrorReply(AppleEvent &reply)
- {
- DescType realType;
- Size actualSize;
- OSErr errNumber;
- Str255 errorString;
- // First check for errors
- errNumber = AEUtilities::EventHasErrorReply(reply);
- if (errNumber == noErr)
- return false;
-
- // server returned an error, so get error string
- OSErr err = ::AEGetParamPtr(&reply, keyErrorString, typeChar,
- &realType, &errorString[1], sizeof(errorString)-1,
- &actualSize);
- if (err == noErr)
- {
- errorString[0] = actualSize > 255 ? 255 : actualSize;
- ErrorManager::ErrorNotify(errNumber, errorString);
- }
- else
- ErrorManager::ErrorNotify(errNumber, (unsigned char *)*GetString(AE_ERR_RESID));
- return TRUE;
- }
-
- // --------------------------------------------------------------
- /* Return the process serial number of the sending process.
- In: Apple Event send by some app.
- Out: ProcessSerialNumber of the sending app. */
- // --------------------------------------------------------------
- ProcessSerialNumber MoreExtractFromAEDesc::ExtractAESender(const AppleEvent &inAppleEvent)
- {
- Size realSize;
- DescType realType;
- TargetID target;
- ProcessSerialNumber psn;
-
- OSErr err = AEGetAttributePtr(&inAppleEvent, keyAddressAttr, typeTargetID, &realType,
- &target, sizeof(target), &realSize);
- ThrowIfOSErr_(err);
- err = ::GetProcessSerialNumberFromPortName(&target.name,&psn);
- ThrowIfOSErr_(err);
- return psn;
- }
-
- //-----------------------------------
- void MoreExtractFromAEDesc::DispatchURLDirectly(const AppleEvent &inAppleEvent)
- //-----------------------------------
- {
- char *url = NULL;
- MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, url);
- ThrowIfNil_(url);
- URL_Struct * request = NET_CreateURLStruct (url, NET_DONT_RELOAD);
- XP_FREE (url);
- ThrowIfNil_(request);
- request->internal_url = TRUE; // for attachments in mailto: urls.
- CURLDispatcher::DispatchURL(request, NULL);
- }
-
-
- /*-------------------------------------------------------------*/
- // class AEUtilities
- // Some more simple Apple Event utility routines.
- /*-------------------------------------------------------------*/
-
- // --------------------------------------------------------------
- /* CreateAppleEvent
- Create a new Apple Event from scratch.
- In: Apple Event suite
- Apple Event ID
- Ptr to return Apple Event
- ProcessSerialNumber of the target app to send event to.
- Out:A new Apple Event is created. More data may be added to
- the event simply by calling AEPutParamDesc or AEPutParamPtr */
- // --------------------------------------------------------------
-
- OSErr AEUtilities::CreateAppleEvent(OSType suite, OSType id,
- AppleEvent &event, ProcessSerialNumber targetPSN)
- {
- AEAddressDesc progressApp;
- OSErr err = ::AECreateDesc(typeProcessSerialNumber, &targetPSN,
- sizeof(targetPSN), &progressApp);
- if (err)
- return err;
- err = ::AECreateAppleEvent(suite, id,
- &progressApp,
- kAutoGenerateReturnID,
- kAnyTransactionID,
- &event);
- AEDisposeDesc(&progressApp);
- return err;
- }
-
- // --------------------------------------------------------------
- /* Check to see if there is an error in the given AEvent.
- We simply return an OSError equiv to the error value
- in the event. If none exists (or an error took place
- during access) we return 0.
- In: Apple Event to test
- Out:Error value returned */
- // --------------------------------------------------------------
- OSErr AEUtilities::EventHasErrorReply(AppleEvent & reply)
- {
- if (reply.descriptorType == typeNull)
- return noErr;
-
- long errNumber;
- Size realSize;
- DescType realType;
- OSErr err = ::AEGetParamPtr(&reply, keyErrorNumber, typeLongInteger,
- &realType, &errNumber, sizeof(errNumber),
- &realSize);
- if (err == noErr)
- return errNumber;
- else
- return noErr;
- }
-