зеркало из https://github.com/mozilla/pjs.git
4462 строки
121 KiB
C++
4462 строки
121 KiB
C++
/* -*- 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.
|
|
*/
|
|
|
|
/* Portions copyright Metrowerks Corporation. */
|
|
|
|
|
|
// A a temporary solution, some lines have been out-commented
|
|
// with the tag //¥¥¥ REVISIT NOVA MERGE ¥¥¥
|
|
//
|
|
|
|
// ===========================================================================
|
|
// UApp.cp
|
|
// main and CFrontApp's methods
|
|
// Created by atotic, June 6th, 1994
|
|
// ===========================================================================
|
|
|
|
//#define DONT_DO_MOZILLA_PROFILE
|
|
//#define PROFILE_UPDATE_MENUS
|
|
|
|
#include "fullsoft.h"
|
|
|
|
#include "uapp.h"
|
|
|
|
#include "CAppleEventHandler.h"
|
|
//#include "shist.h"
|
|
|
|
#include <LGARadioButton.h>
|
|
#include <LGACheckbox.h>
|
|
|
|
// macfe
|
|
//#include "NavigationServicesSupport.h"
|
|
#include "earlmgr.h"
|
|
#include "macutil.h"
|
|
#include "macgui.h" // HyperStyle
|
|
#include "CBookmarksAttachment.h"
|
|
#include "CToolsAttachment.h"
|
|
#include "CFontMenuAttachment.h"
|
|
#include "CRecentEditMenuAttachment.h"
|
|
#include "BookmarksFile.h"
|
|
#include "mprint.h"
|
|
#include "mimages.h"
|
|
#include "mplugin.h"
|
|
#include "prpriv.h"
|
|
|
|
#if defined (JAVA)
|
|
#include "mjava.h"
|
|
#endif
|
|
|
|
#include "mregistr.h"
|
|
#include "resae.h"
|
|
#include "resgui.h"
|
|
#include "uerrmgr.h"
|
|
#include "ufilemgr.h"
|
|
#include "msv2dsk.h"
|
|
#include "mversion.h"
|
|
#include "xp_sec.h"
|
|
#include "xp_trace.h"
|
|
#include "CTargetedUpdateMenuRegistry.h"
|
|
#include "UDesktop.h"
|
|
#include "CNavCenterWindow.h"
|
|
#include "UDeferredTask.h"
|
|
#include "URobustCreateWindow.h"
|
|
#include "URDFUtilities.h"
|
|
#ifdef MOZ_MAIL_NEWS
|
|
#include "CMessageFolder.h"
|
|
#include "UNewFolderDialog.h"
|
|
#endif
|
|
|
|
#include "LMenuSharing.h"
|
|
#define MENU_SHARING_FIRST 40
|
|
|
|
#ifndef NSPR20
|
|
#include "CNetwork.h"
|
|
#endif
|
|
#include "CEnvironment.h"
|
|
|
|
#include "CWindowMenu.h"
|
|
#include "CHistoryMenu.h"
|
|
#include "CNSMenuBarManager.h"
|
|
#ifdef MOZ_MAIL_NEWS
|
|
#include "CThreadWindow.h"
|
|
#include "CMailProgressWindow.h"
|
|
#include "UMailFolderMenus.h"
|
|
#endif
|
|
|
|
#include "UTearOffPalette.h"
|
|
#include "CPaneEnabler.h"
|
|
#include "CApplicationEventAttachment.h"
|
|
#include "CCloseAllAttachment.h"
|
|
|
|
#include "CNSContextCallbacks.h"
|
|
#include "CBrowserContext.h"
|
|
|
|
#include "prgc.h"
|
|
#include "java.h"
|
|
|
|
#include "secrng.h"
|
|
#include "secnav.h"
|
|
#include "mkutils.h" // only for FREEIF() macro. JRM 96/10/17
|
|
|
|
#include "CEditorWindow.h"
|
|
#include "CEditView.h"
|
|
#include "meditdlg.h"
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
#include "MailNewsSearch.h"
|
|
#include "MailNewsFilters.h"
|
|
#include "MailNewsAddressBook.h"
|
|
|
|
#include "CCheckMailContext.h"
|
|
#endif // MOZ_MAIL_NEWS
|
|
|
|
#include "StBlockingDialogHandler.h"
|
|
#include "CSecureAttachment.h"
|
|
//#include "VTSMProxy.h"
|
|
|
|
#include "LTSMSupport.h"
|
|
|
|
#include "CMouseDispatcher.h"
|
|
#include "CSuspenderResumer.h"
|
|
|
|
#if defined(MOZ_MAIL_COMPOSE) || defined(MOZ_MAIL_NEWS)
|
|
#include "MailNewsClasses.h"
|
|
#include "msgcom.h"
|
|
#include "MailNewsgroupWindow_Defines.h"
|
|
#endif
|
|
|
|
#include "BrowserClasses.h"
|
|
|
|
//#include "CBrowserView.h" // need for CFrontApp::EventKeyUp() 1997-02-24 mjc
|
|
#include "CKeyUpReceiver.h" // need in CFrontApp::EventKeyUp()
|
|
|
|
#include "CToolbarModeManager.h"
|
|
#include "CMozillaToolbarPrefsProxy.h"
|
|
#include "CSharedPatternWorld.h"
|
|
|
|
#include "InternetConfig.h"
|
|
#include "il_strm.h" /* Image Library stream converters. */
|
|
#ifdef MOCHA
|
|
//#include "libmocha.h"
|
|
#include "CMochaHacks.h"
|
|
#endif
|
|
|
|
PRThread* mozilla_thread;
|
|
|
|
PREventQueue *mozilla_event_queue = NULL;
|
|
|
|
#if defined (JAVA)
|
|
#include "MFramePeer.h"
|
|
#endif
|
|
|
|
#include "CLibMsgPeriodical.h"
|
|
|
|
// Netscape
|
|
#ifndef GLHIST_H
|
|
#include "glhist.h"
|
|
#endif
|
|
|
|
#include "edtplug.h"
|
|
|
|
#include "m_cvstrm.h"
|
|
#include "prefapi.h"
|
|
#include "NSReg.h"
|
|
#ifdef MOZ_SMARTUPDATE
|
|
#include "softupdt.h"
|
|
#endif
|
|
#include <Balloons.h>
|
|
|
|
// HERE ONLY UNTIL NAV SERVICES CODE MERGED INTO TIP
|
|
Boolean SimpleOpenDlog ( short numTypes, const OSType typeList[], FSSpec* outFSSpec ) ;
|
|
|
|
|
|
CAutoPtr<CNSContext> CFrontApp::sRDFContext;
|
|
|
|
|
|
|
|
// Now we modify the frequency with which we call WaitNextEvent to try
|
|
// to minimize the time we spend in this expensive function. The strategy
|
|
// is two-fold:
|
|
// 1. If we are in the foreground, and there are no pending user
|
|
// events (determined with OSEventAvail), then only call WNE every
|
|
// kWNETicksInterval (4) ticks.
|
|
// Note that OSEvent avail only knows about the Operating System
|
|
// event queue, which contains these events:
|
|
// mouseDown, mouseUp, keyDown, keyUp, autoKey, diskEvent
|
|
//
|
|
// If we are in the background, we are nice to front apps and
|
|
// call WNE every time.
|
|
//
|
|
// 2. We also adjust the sleep time (the value passed to WNE to determine
|
|
// how long it is before the Event Manager returns control to us).
|
|
// This is done on EventSuspend and EventResume. We set the sleep time
|
|
// to 0 in the foreground, and 4 in the background.
|
|
|
|
#define DAVIDM_SPEED2 // Comment out to remove this WNE wrapper code
|
|
//======================================================================================
|
|
// PROFILE
|
|
//======================================================================================
|
|
|
|
//#define PROFILE_LOCALLY 1
|
|
#if defined(PROFILE) || defined (PROFILE_LOCALLY)
|
|
#include <profiler.h>
|
|
|
|
// Define this if you want to start profiling when the Caps Lock
|
|
// key is pressed. Usually that's what you want: press Caps Lock,
|
|
// start the command you want to profile, release Caps Lock when
|
|
// the command is done. It works for all the major commands:
|
|
// display a page, send a mail, save an attachment, etc...
|
|
#define PROFILE_ON_CAPSLOCK
|
|
|
|
// Define this if you want to let the profiler run while you're
|
|
// spending time in other apps. Usually you don't.
|
|
//#define PROFILE_WAITNEXTEVENT
|
|
|
|
|
|
// Legacy stuff: profiles CFrontApp::UpdateMenus().
|
|
// Don't use other profile methods at the same time.
|
|
//#define PROFILE_UPDATE_MENUS
|
|
|
|
|
|
//---------------------------------------------
|
|
// Paste these in the file you want to profile
|
|
// The code to be profiled must be in a project
|
|
// with "Emit profiler calls" turned on.
|
|
//
|
|
// Example:
|
|
// ProfileStart()
|
|
// ...
|
|
// ProfileSuspend()
|
|
// ...
|
|
// ProfileResume()
|
|
// ...
|
|
// ProfileStop()
|
|
//
|
|
// If you want to start the profile when Caps Lock
|
|
// is pressed, you can use:
|
|
//
|
|
// if (IsThisKeyDown(0x39)) // caps lock
|
|
// ProfileStart()
|
|
//
|
|
//---------------------------------------------
|
|
extern void ProfileStart();
|
|
extern void ProfileStop();
|
|
extern void ProfileSuspend();
|
|
extern void ProfileResume();
|
|
extern Boolean ProfileInProgress();
|
|
//---------------------------------------------
|
|
|
|
static Boolean sProfileInProgress = false;
|
|
void ProfileStart()
|
|
{
|
|
if (! sProfileInProgress)
|
|
{
|
|
sProfileInProgress = true;
|
|
if (ProfilerInit(collectDetailed, microsecondsTimeBase, 2000, 100))
|
|
return;
|
|
ProfilerSetStatus(true);
|
|
}
|
|
}
|
|
|
|
void ProfileStop()
|
|
{
|
|
if (sProfileInProgress)
|
|
{
|
|
ProfilerDump("\pMozilla Profile");
|
|
ProfilerTerm();
|
|
sProfileInProgress = false;
|
|
}
|
|
}
|
|
|
|
void ProfileSuspend()
|
|
{
|
|
if (sProfileInProgress)
|
|
ProfilerSetStatus(false);
|
|
}
|
|
|
|
void ProfileResume()
|
|
{
|
|
if (sProfileInProgress)
|
|
ProfilerSetStatus(true);
|
|
}
|
|
|
|
Boolean ProfileInProgress()
|
|
{
|
|
return sProfileInProgress;
|
|
}
|
|
|
|
#endif // PROFILE
|
|
//======================================================================================
|
|
|
|
#ifdef FORTEZZA
|
|
#include "ssl.h"
|
|
#endif
|
|
|
|
#include <LArray.h>
|
|
|
|
#include "CPrefsDialog.h"
|
|
#include "UProcessUtils.h" // for LaunchApplication
|
|
|
|
#ifdef MOZ_OFFLINE
|
|
#include "UOffline.h"
|
|
#endif
|
|
|
|
#define LICENSE_REVISION 7
|
|
|
|
extern NET_StreamClass *IL_NewStream(int, void *, URL_Struct *, MWContext *);
|
|
extern void TrySetCursor( int whichCursor );
|
|
|
|
list<CommandT> CFrontApp::sCommandsToUpdateBeforeSelectingMenu;
|
|
|
|
CFrontApp* CFrontApp::sApplication = NULL;
|
|
CAppleEventHandler* CAppleEventHandler::sAppleEventHandler = NULL;
|
|
short CFrontApp::sHelpMenuOrigLength = 4;
|
|
short CFrontApp::sHelpMenuItemCount = 0;
|
|
double CFrontApp::sHRes = 1.0;
|
|
double CFrontApp::sVRes = 1.0;
|
|
static PA_InitData parser_initdata;
|
|
|
|
static void InitDebugging();
|
|
static void ConfirmWeWillRun();
|
|
static Boolean NetscapeIsRunning(ProcessSerialNumber& psn);
|
|
static Boolean LicenseHasExpired();
|
|
static void CheckForOtherNetscapes();
|
|
static void Assert68020();
|
|
static void AssertSystem7();
|
|
|
|
static const OSType kConferenceAppSig = 'Ncq¹';
|
|
static const OSType kCalendarAppSig = 'NScl';
|
|
static const OSType kImportAppSig = 'NSi2';
|
|
static const OSType kAOLInstantMessengerSig = 'Oscr';
|
|
|
|
#ifdef EDITOR
|
|
static void OpenEditURL(const char* url){
|
|
if ( url != NULL ) {
|
|
URL_Struct * request = NET_CreateURLStruct ( url, NET_NORMAL_RELOAD );
|
|
if ( request )
|
|
CEditorWindow::MakeEditWindow( NULL, request );
|
|
}
|
|
}
|
|
#endif // EDITOR
|
|
|
|
//======================================
|
|
class LTimerCallback: public LPeriodical
|
|
// class that keeps track of xp timeout callbacks
|
|
//======================================
|
|
{
|
|
public:
|
|
LTimerCallback( TimeoutCallbackFunction func, void* closure, uint32 msecs );
|
|
void SpendTime( const EventRecord& inMacEvent );
|
|
|
|
static LArray* sTimerList;
|
|
|
|
protected:
|
|
UInt32 fFireTime;
|
|
TimeoutCallbackFunction fFireFunc;
|
|
void* fClosure;
|
|
};
|
|
|
|
LArray* LTimerCallback::sTimerList = NULL;
|
|
|
|
//-----------------------------------
|
|
LTimerCallback::LTimerCallback( TimeoutCallbackFunction func, void* closure, uint32 msecs )
|
|
: LPeriodical()
|
|
//-----------------------------------
|
|
{
|
|
UInt32 ticks = ::TickCount();
|
|
|
|
// ¥Êcalculate the fire time in ticks from now
|
|
fFireTime = ticks + ceil(((double)msecs / 100.0) * 6.0);
|
|
fFireFunc = func;
|
|
fClosure = closure;
|
|
this->StartIdling();
|
|
}
|
|
|
|
//-----------------------------------
|
|
void LTimerCallback::SpendTime( const EventRecord& inMacEvent )
|
|
//-----------------------------------
|
|
{
|
|
UInt32 ticks = inMacEvent.when;
|
|
|
|
if ( ticks >= fFireTime )
|
|
{
|
|
// 97-06-18 pkc -- Remove this from sTimerList first because when we call
|
|
// fFireFunc could possibly cause a call to FE_ClearTimeout on this
|
|
// remove from timer list before deleting
|
|
LTimerCallback::sTimerList->Remove(&this);
|
|
|
|
// let's just say that the fFireFunc gives time to repeaters...
|
|
// We don't want this one going off again before it is deleted!
|
|
fFireTime = LONG_MAX;
|
|
|
|
if ( fFireFunc )
|
|
(*fFireFunc)( fClosure );
|
|
delete this;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------
|
|
void* FE_SetTimeout( TimeoutCallbackFunction func, void* closure, uint32 msecs )
|
|
// this function should register a function that will
|
|
// be called after the specified interval of time has
|
|
// elapsed. This function should return an id
|
|
// that can be passed to FE_ClearTimer to cancel
|
|
// the timer request.
|
|
//
|
|
// func: The function to be invoked upon expiration of
|
|
// the timer interval
|
|
// closure: Data to be passed as the only argument to "func"
|
|
// msecs: The number of milli-seconds in the interval
|
|
//-----------------------------------
|
|
{
|
|
Try_
|
|
{
|
|
LTimerCallback* t = new LTimerCallback( func, closure, msecs );
|
|
// insert timer callback into list
|
|
try {
|
|
if (!LTimerCallback::sTimerList)
|
|
LTimerCallback::sTimerList = new LArray(sizeof(LTimerCallback*));
|
|
LTimerCallback::sTimerList->InsertItemsAt(1, LArray::index_Last, &t);
|
|
} catch (...) {
|
|
}
|
|
return t;
|
|
}
|
|
Catch_( inErr )
|
|
{
|
|
return NULL;
|
|
}
|
|
EndCatch_
|
|
}
|
|
|
|
//-----------------------------------
|
|
void FE_ClearTimeout( void* timer_id )
|
|
// This function cancels a timer that has previously been set.
|
|
// Callers should not pass in NULL or a timer_id that has already expired.
|
|
//-----------------------------------
|
|
{
|
|
XP_ASSERT( timer_id );
|
|
|
|
LTimerCallback* timer = (LTimerCallback*)timer_id;
|
|
if (LTimerCallback::sTimerList)
|
|
{
|
|
if (LTimerCallback::sTimerList->FetchIndexOf(&timer) > LArray::index_Bad)
|
|
{
|
|
// this LTimerCallback is in timer list
|
|
// remove from timer list before deleting
|
|
LTimerCallback::sTimerList->Remove(&timer);
|
|
delete timer;
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
void Assert68020()
|
|
{
|
|
long response = 0;
|
|
OSErr err = ::Gestalt (gestaltQuickdrawVersion, &response);
|
|
if (err || response == gestaltOriginalQD) {
|
|
::Alert (14000, NULL);
|
|
::ExitToShell ();
|
|
}
|
|
}
|
|
|
|
void AssertSystem7()
|
|
{
|
|
long response = 0;
|
|
OSErr err = ::Gestalt (gestaltSystemVersion, &response);
|
|
if (err || response < 0x700) {
|
|
::Alert (14001, NULL);
|
|
::ExitToShell ();
|
|
}
|
|
}
|
|
|
|
static void RequiredGutsNotFoundAlert()
|
|
{
|
|
Str255 gutsFolderName;
|
|
|
|
GetIndString(gutsFolderName, 14000, 1);
|
|
ParamText(gutsFolderName, NULL, NULL, NULL);
|
|
Alert (14002, NULL);
|
|
ExitToShell();
|
|
}
|
|
|
|
static void AssertRequiredGuts()
|
|
{
|
|
// Initialize the "CPrefs::NetscapeFolder" and "CPrefs::RequiredGutsFolder"
|
|
// static variables early for use by the XP strings code in "errmgr.cp."
|
|
|
|
short vRefNum;
|
|
long dirID;
|
|
|
|
if (HGetVol(NULL, &vRefNum, &dirID) != noErr)
|
|
ExitToShell();
|
|
|
|
FSSpec netscapeFolderSpec;
|
|
|
|
if (CFileMgr::FolderSpecFromFolderID(vRefNum, dirID, netscapeFolderSpec) != noErr)
|
|
RequiredGutsNotFoundAlert();
|
|
|
|
try
|
|
{
|
|
CPrefs::Initialize();
|
|
}
|
|
catch (...)
|
|
{
|
|
RequiredGutsNotFoundAlert();
|
|
}
|
|
CPrefs::SetFolderSpec(netscapeFolderSpec, CPrefs::NetscapeFolder);
|
|
|
|
FSSpec gutsFolderSpec;
|
|
|
|
// Build a partial path to the guts folder starting from a folder we know (the Netscape folder)
|
|
Str255 partialPath;
|
|
|
|
{
|
|
// Get the name of the guts folder
|
|
Str255 gutsFolderName;
|
|
GetIndString(gutsFolderName, 14000, 1);
|
|
|
|
// partialPath = ":" + netscapeFolderSpec.name + ":" + gutsFolderName;
|
|
// ( this may _look_ cumbersome, but it's really the most space and time efficient way to catentate 4 pstrings )
|
|
int dest=0;
|
|
partialPath[++dest] = ':';
|
|
for ( int src=0; src<netscapeFolderSpec.name[0]; )
|
|
partialPath[++dest] = netscapeFolderSpec.name[++src];
|
|
partialPath[++dest] = ':';
|
|
for ( int src=0; src<gutsFolderName[0]; )
|
|
partialPath[++dest] = gutsFolderName[++src];
|
|
partialPath[0] = dest;
|
|
}
|
|
|
|
// Use the partial path to construct an FSSpec identifying the required guts folder
|
|
FSMakeFSSpec(netscapeFolderSpec.vRefNum, netscapeFolderSpec.parID, partialPath, &gutsFolderSpec);
|
|
|
|
{ // Ensure that the folder exists (even if pointed to by an alias) and actually _is_ a folder
|
|
Boolean targetIsFolder, targetWasAliased;
|
|
if ( (ResolveAliasFile(&gutsFolderSpec, true, &targetIsFolder, &targetWasAliased) != noErr)
|
|
|| !targetIsFolder )
|
|
RequiredGutsNotFoundAlert();
|
|
}
|
|
|
|
// ...and finally, publish the found spec where other routines in the app can find it
|
|
CPrefs::SetFolderSpec(gutsFolderSpec, CPrefs::RequiredGutsFolder);
|
|
}
|
|
|
|
static void DisableJavaIfNotAvailable ()
|
|
{
|
|
short vRefNum;
|
|
long dirID;
|
|
|
|
if (HGetVol(NULL, &vRefNum, &dirID) != noErr)
|
|
ExitToShell();
|
|
|
|
FSSpec netscapeFolderSpec;
|
|
|
|
// This can't fail because we already called AssertRequiredGuts
|
|
CFileMgr::FolderSpecFromFolderID(vRefNum, dirID, netscapeFolderSpec);
|
|
|
|
FSSpec javaFolderSpec;
|
|
|
|
// Build a partial path to the guts folder starting from a folder we know (the Netscape folder)
|
|
Str255 partialPath;
|
|
|
|
{
|
|
// Get the name of the guts folder
|
|
Str255 gutsFolderName;
|
|
GetIndString(gutsFolderName, 14000, 1);
|
|
|
|
// jj confirmed it's OK to hard code the name of this folder
|
|
static unsigned char *javaFolderName = "\pJava";
|
|
|
|
// partialPath = ":" + netscapeFolderSpec.name + ":" + gutsFolderName + ":" + javaFolderName
|
|
// ( this may _look_ cumbersome, but it's really the most space and time efficient way to catentate 4 pstrings )
|
|
int dest=0;
|
|
partialPath[++dest] = ':';
|
|
for ( int src=0; src<netscapeFolderSpec.name[0]; )
|
|
partialPath[++dest] = netscapeFolderSpec.name[++src];
|
|
partialPath[++dest] = ':';
|
|
for ( int src=0; src<gutsFolderName[0]; )
|
|
partialPath[++dest] = gutsFolderName[++src];
|
|
partialPath[++dest] = ':';
|
|
for ( int src=0; src<javaFolderName[0]; )
|
|
partialPath[++dest] = javaFolderName[++src];
|
|
partialPath[0] = dest;
|
|
}
|
|
|
|
// Use the partial path to construct an FSSpec identifying the required guts folder
|
|
OSErr err = FSMakeFSSpec(netscapeFolderSpec.vRefNum, netscapeFolderSpec.parID, partialPath, &javaFolderSpec);
|
|
if (
|
|
(FSMakeFSSpec(netscapeFolderSpec.vRefNum, netscapeFolderSpec.parID, partialPath, &javaFolderSpec) != noErr)
|
|
||
|
|
!CFileMgr::IsFolder(javaFolderSpec)
|
|
)
|
|
{
|
|
static const char* inline_javascript_text ="lockPref(\"security.enable_java\", false)";
|
|
PREF_EvaluateJSBuffer(inline_javascript_text, strlen(inline_javascript_text));
|
|
}
|
|
|
|
}
|
|
|
|
static void DisplayErrorDialog ( OSErr err )
|
|
{
|
|
if (::GetResource('ALRT', ALRT_ErrorOccurred) && ::GetResource('STR#', 7098))
|
|
{
|
|
short stringIndex;
|
|
switch (err)
|
|
{
|
|
case userCanceledErr:
|
|
return; // no alert
|
|
case memFullErr:
|
|
stringIndex = 1; //"there was not enough memory."
|
|
break;
|
|
case dskFulErr:
|
|
stringIndex = 3;
|
|
break;
|
|
case fnfErr:
|
|
stringIndex = 4;
|
|
break;
|
|
case dirNFErr:
|
|
stringIndex = 5;
|
|
break;
|
|
case nsvErr:
|
|
stringIndex = 6;
|
|
break;
|
|
case bdNamErr:
|
|
stringIndex = 7;
|
|
break;
|
|
case vLckdErr:
|
|
stringIndex = 8;
|
|
break;
|
|
case fBsyErr:
|
|
stringIndex = 9;
|
|
break;
|
|
case dupFNErr:
|
|
stringIndex = 10;
|
|
break;
|
|
case opWrErr:
|
|
stringIndex = 11;
|
|
break;
|
|
case permErr:
|
|
stringIndex = 12;
|
|
break;
|
|
// ADD OTHER CASES HERE
|
|
default:
|
|
stringIndex = 2; //"of an unknown error."
|
|
break;
|
|
}
|
|
CStr255 p0, p1;
|
|
::GetIndString(p0, 7098, stringIndex);
|
|
::NumToString(err, p1);
|
|
::ParamText(p0, p1, nil, nil);
|
|
::CautionAlert(ALRT_ErrorOccurred, nil);
|
|
}
|
|
else
|
|
throw;
|
|
}
|
|
|
|
static void DisplayExceptionCodeDialog ( ExceptionCode err )
|
|
{
|
|
if (err == userCanceledErr) return;
|
|
|
|
if (::GetResource('ALRT', ALRT_ErrorOccurred) && ::GetResource('STR#', 7098))
|
|
{
|
|
short stringIndex;
|
|
switch (err)
|
|
{
|
|
case memFullErr:
|
|
err = err_NilPointer; // & fall through...
|
|
case err_NilPointer:
|
|
stringIndex = 1; //"there was not enough memory."
|
|
break;
|
|
default:
|
|
stringIndex = 2; //"of an unknown error."
|
|
break;
|
|
}
|
|
CStr255 p0, p1;
|
|
|
|
::NumToString(err, p1); // The error is supposed to be numeric, not an OSType
|
|
// Initializing it in the CStr255 constructor doesn't handle this properly
|
|
|
|
::GetIndString(p0, 7098, stringIndex);
|
|
::ParamText(p0, p1, nil, nil);
|
|
::CautionAlert(ALRT_ErrorOccurred, nil);
|
|
}
|
|
else
|
|
throw;
|
|
}
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
// TRUE if url *must* be loaded in this context type
|
|
Boolean URLRequiresContextType( const URL_Struct* url, MWContextType & type)
|
|
{
|
|
if ( url )
|
|
{
|
|
if ( MSG_RequiresMailWindow( url->address ) )
|
|
type = MWContextMail;
|
|
else if ( MSG_RequiresNewsWindow( url->address ) )
|
|
type = MWContextNews;
|
|
else if (MSG_RequiresBrowserWindow(url->address))
|
|
type = MWContextBrowser;
|
|
else
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
#endif // MOZ_MAIL_NEWS
|
|
|
|
extern "C" {
|
|
void InitializeASLM();
|
|
void CleanupASLM();
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
//======================================
|
|
class CResumeEventAttachment : public LAttachment
|
|
// This silly class fixes a weird bug where the app doesnÕt
|
|
// get resume events after being sent a getURL AppleEvent.
|
|
// This attachment will run whenever we get an event, so
|
|
// we can check to see if the event is not a resume event,
|
|
// target is nil (meaning we havenÕt received a resume
|
|
// event yet), and weÕre in the foreground (meaning we got
|
|
// switched in without getting the event). If all those
|
|
// are true, we can resume ourselves so we wonÕt crash
|
|
// because target is nil.
|
|
//======================================
|
|
{
|
|
public:
|
|
CResumeEventAttachment(CFrontApp* app) : LAttachment(msg_Event), fApp(app) {}
|
|
protected:
|
|
virtual void ExecuteSelf(MessageT inMessage, void* ioParam);
|
|
private:
|
|
CFrontApp* fApp;
|
|
};
|
|
|
|
//-----------------------------------
|
|
void CResumeEventAttachment::ExecuteSelf(MessageT inMessage, void* ioParam)
|
|
//-----------------------------------
|
|
{
|
|
EventRecord* event = (EventRecord*) ioParam;
|
|
|
|
//
|
|
// Do quick tests first to see if we should
|
|
// go ahead and check if weÕre in the foreground.
|
|
//
|
|
if (inMessage == msg_Event && event->what != osEvt && LCommander::GetTarget() == nil)
|
|
{
|
|
ProcessSerialNumber frontProcess;
|
|
ProcessSerialNumber currentProcess;
|
|
GetFrontProcess(&frontProcess);
|
|
GetCurrentProcess(¤tProcess);
|
|
Boolean result = false;
|
|
SameProcess(&frontProcess, ¤tProcess, &result);
|
|
if (result)
|
|
{
|
|
//
|
|
// WeÕre in the foreground, so synthesize
|
|
// a resume event and process it.
|
|
//
|
|
EventRecord resumeEvent;
|
|
memset(&resumeEvent, 0, sizeof(EventRecord));
|
|
resumeEvent.what = osEvt;
|
|
resumeEvent.message = suspendResumeMessage << 24;
|
|
resumeEvent.message |= resumeFlag;
|
|
fApp->DispatchEvent(resumeEvent);
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
//======================================
|
|
class CSplashScreen : public LWindow
|
|
//======================================
|
|
{
|
|
public:
|
|
enum { class_ID = 'Spls' };
|
|
|
|
CSplashScreen(LStream* inStream);
|
|
virtual ~CSplashScreen();
|
|
|
|
virtual void SetDescriptor(ConstStringPtr inDescriptor);
|
|
|
|
protected:
|
|
|
|
virtual void FinishCreateSelf(void);
|
|
|
|
LCaption* mStatusCaption;
|
|
CResPicture* mBackPicture;
|
|
LFile* mPictureResourceFile;
|
|
};
|
|
|
|
#pragma mark -
|
|
|
|
//======================================
|
|
// CLASS CFrontApp
|
|
//======================================
|
|
|
|
//-----------------------------------
|
|
CFrontApp::CFrontApp()
|
|
//-----------------------------------
|
|
: fCurrentMbar(cBrowserMenubar)
|
|
, fWantedMbar(fCurrentMbar)
|
|
, fStartupAborted(false)
|
|
, fProperStartup(false)
|
|
, mSplashScreen(NULL)
|
|
#ifdef MOZ_MAIL_NEWS
|
|
, mLibMsgPeriodical(NULL)
|
|
#endif // MOZ_MAIL_NEWS
|
|
, mConferenceApplicationExists(false)
|
|
, mJavaEnabled(false)
|
|
, mHasBookmarksMenu(false)
|
|
, mHasFrontierMenuSharing(false)
|
|
, mMouseRgnH( NewRgn() )
|
|
// Performance
|
|
// We really should be adjusting this dynamically
|
|
{
|
|
// Set environment features
|
|
|
|
CEnvironment::SetAllFeatures();
|
|
|
|
// Static data members
|
|
|
|
sApplication = this;
|
|
|
|
// Add CApplicationEventAttachment
|
|
|
|
AddAttachment(new CApplicationEventAttachment);
|
|
|
|
// Add CCloseAllAttachment
|
|
|
|
AddAttachment(new CCloseAllAttachment(CLOSE_WINDOW, CLOSE_ALL_WINDOWS));
|
|
|
|
// Inherited data members
|
|
mSleepTime = 1;
|
|
|
|
// Indicate we don't want to be able to quit yet
|
|
fSafeToQuit = false;
|
|
fUserWantsToQuit = false;
|
|
|
|
// Toolbox
|
|
qd.randSeed = TickCount(); // Toolbox
|
|
|
|
AddAttachment(new LClipboard());
|
|
AddAttachment(new CSecureAttachment);
|
|
AddAttachment(new CResumeEventAttachment(this));
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
// create CLibMsgPeriodical
|
|
mLibMsgPeriodical = new CLibMsgPeriodical;
|
|
mLibMsgPeriodical->StartIdling();
|
|
#endif // MOZ_MAIL_NEWS
|
|
|
|
//
|
|
// Initial inline support (TSM)
|
|
//
|
|
LTSMSupport::Initialize();
|
|
|
|
UHTMLPrinting::InitCustomPageSetup();
|
|
|
|
#ifdef MOZ_SMARTUPDATE
|
|
SU_Startup();
|
|
#endif
|
|
NR_StartupRegistry();
|
|
|
|
// ¥ PowerPlant initialization
|
|
UScreenPort::Initialize();
|
|
|
|
#if defined(MOZ_MAIL_NEWS) || defined(MOZ_MAIL_COMPOSE)
|
|
RegisterAllMailNewsClasses();
|
|
#endif // MOZ_MAIL_NEWS
|
|
RegisterAllBrowserClasses();
|
|
|
|
ShowSplashScreen();
|
|
|
|
InitUTearOffPalette(this);
|
|
CTearOffManager::GetDefaultManager()->AddListener(this);
|
|
|
|
// ¥Ênetwork
|
|
#ifndef NSPR20
|
|
CNetworkDriver::CreateNetworkDriver();
|
|
#endif
|
|
|
|
TheEarlManager.StartRepeating();
|
|
|
|
// WTSMManager::Initialize();
|
|
// AddAttachment(new VTSMDoEvent(msg_Event));
|
|
|
|
HyperStyle::InitHyperStyle();
|
|
|
|
// ¥ parser
|
|
parser_initdata.output_func = LO_ProcessTag;
|
|
|
|
// ¥Êparsers
|
|
// mime parsers
|
|
NET_RegisterMIMEDecoders();
|
|
|
|
// external objects go to disk
|
|
NET_RegisterContentTypeConverter ("*", FO_PRESENT, nil, NewFilePipe);
|
|
NET_RegisterContentTypeConverter ("*", FO_SAVE_AS, nil, NewFilePipe);
|
|
|
|
FSSpec spec;
|
|
mImportModuleExists = CFileMgr::FindApplication(kImportAppSig, spec) == noErr;
|
|
mAOLMessengerExists = CFileMgr::FindApplication(kAOLInstantMessengerSig, spec) == noErr;
|
|
// Record whether the conference application exists. We do this once here
|
|
// instead of lots 'o times in FindCommandStatus so searching for an app
|
|
// doesn't slow us to a crawl (especially when searchin on network volumes).
|
|
// One drawback of course, is that when the app is installed or removed,
|
|
// the menu won't be enabled or disabled until the user quits and restarts
|
|
// the app. This behavior is different than the pref panel for controlling
|
|
// whether conference launches on startup or not (but that occurence of
|
|
// FindApplication isn't called many times/sec either).
|
|
mConferenceApplicationExists = (CFileMgr::FindApplication(kConferenceAppSig, spec) == noErr);
|
|
mNetcasterContext = NULL;
|
|
}
|
|
|
|
//-----------------------------------
|
|
CFrontApp::~CFrontApp()
|
|
//-----------------------------------
|
|
{
|
|
// Save the current visibility information
|
|
if ( CPrefs::GetLong( CPrefs::StartupAsWhat ) == STARTUP_VISIBLE)
|
|
{
|
|
long winRecord = 0;
|
|
|
|
CMediatedWindow* theWindow;
|
|
CWindowIterator iter(WindowType_Any);
|
|
while (iter.Next(theWindow))
|
|
{
|
|
switch(theWindow->GetWindowType())
|
|
{
|
|
case WindowType_MailNews:
|
|
winRecord |= (MAIL_STARTUP_ID | NEWS_STARTUP_ID);
|
|
break;
|
|
case WindowType_Browser:
|
|
winRecord |= BROWSER_STARTUP_ID;
|
|
break;
|
|
case WindowType_NavCenter:
|
|
winRecord |= NAVCENTER_STARTUP_ID;
|
|
break;
|
|
case WindowType_Address:
|
|
winRecord |= ADDRESS_STARTUP_ID;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (winRecord != 0)
|
|
CPrefs::SetLong(winRecord, CPrefs::StartupBitfield);
|
|
}
|
|
|
|
|
|
{
|
|
// This really comes from ~LCommander. This gets
|
|
// executed after our destructor, and deletes all the windows
|
|
// We need windows to be deleted before we are done,
|
|
// because window destruction callbacks reference the app!
|
|
// DO NOT DO THIS (IT CAUSES UNNECESSARY DEBUG BREAKS): SetTarget(this);
|
|
|
|
// tj, 5/1/96
|
|
//
|
|
// We must close the windows explicitly, so that each window
|
|
// can interrupt its context (XP_InterruptContext) while the
|
|
// window is still completely alive
|
|
//
|
|
|
|
// Hmmmmm ... better be a hair more careful about traversing that window list.
|
|
// DDM 21-JUN-96
|
|
|
|
WindowRef macWindow = LMGetWindowList();
|
|
|
|
while (macWindow)
|
|
{
|
|
LWindow *ppWindow = LWindow::FetchWindowObject(macWindow);
|
|
|
|
if (ppWindow)
|
|
{
|
|
ppWindow->DoClose();
|
|
|
|
// Start over at the beginning of the list.
|
|
// This is possibly slow but definitely safe, i.e. we're not using
|
|
// a block of memory that's been deleted.
|
|
macWindow = LMGetWindowList();
|
|
}
|
|
else
|
|
// Skip to the next window in the list.
|
|
macWindow = GetNextWindow(macWindow);
|
|
}
|
|
|
|
// Delete all SubCommanders
|
|
LArrayIterator iterator(mSubCommanders);
|
|
LCommander *theSub;
|
|
while (iterator.Next(&theSub))
|
|
delete theSub;
|
|
}
|
|
|
|
HyperStyle::FinishHyperStyle();
|
|
|
|
LTSMSupport::DoQuit( 0 );
|
|
|
|
// WTSMManager::Quit();
|
|
|
|
// UpdateMenus();
|
|
TrySetCursor( watchCursor );
|
|
// XP_Saves
|
|
GH_SaveGlobalHistory();
|
|
GH_FreeGlobalHistory();
|
|
#ifdef MOZ_MAIL_NEWS
|
|
NET_SaveNewsrcFileMappings();
|
|
CAddressBookManager::CloseAddressBookManager();
|
|
CCheckMailContext::Release(this);
|
|
#endif // MOZ_MAIL_NEWS
|
|
|
|
//-----
|
|
// We just closed all the windows but we now have to wait for the callbacks
|
|
// in order to really delete the different contexts. That's because
|
|
// CNSContext::NoMoreUsers() calls ET_RemoveWindowContext() which posts
|
|
// an event which calls MochaDone() asynchronously and deletes the context..
|
|
//
|
|
// NOTE: CCheckMailContext::Release() also posts an event in order to delete
|
|
// its context. So make sure that PR_ProcessPendingEvents() is always
|
|
// executed after window->DoClose(), CCheckMailContext::Release() or any
|
|
// other destructor function which deletes a context. A symptom of not
|
|
// deleting the context is that newsgroups which have been unsubscribed
|
|
// in the Message Center reappear when launching the application again.
|
|
PR_ProcessPendingEvents(mozilla_event_queue);
|
|
//-----
|
|
|
|
#ifndef NSPR20
|
|
if (gNetDriver && !fStartupAborted)
|
|
{
|
|
extern const char* CacheFilePrefix;
|
|
NET_CleanupCacheDirectory( "", CacheFilePrefix );
|
|
NET_ShutdownNetLib();
|
|
delete gNetDriver;
|
|
gNetDriver = NULL;
|
|
}
|
|
#else
|
|
if (!fStartupAborted)
|
|
{
|
|
extern const char* CacheFilePrefix;
|
|
NET_CleanupCacheDirectory( "", CacheFilePrefix );
|
|
NET_ShutdownNetLib();
|
|
}
|
|
#endif
|
|
|
|
if (!fStartupAborted)
|
|
CPrefs::DoWrite();
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
delete mLibMsgPeriodical;
|
|
#endif // MOZ_MAIL_NEWS
|
|
|
|
SetCursor( &qd.arrow );
|
|
|
|
// remove anything we left in the Temporary Items:nscomm40 folder
|
|
CFileMgr::DeleteCommTemporaryItems();
|
|
|
|
NR_ShutdownRegistry();
|
|
#ifdef MOZ_SMARTUPDATE
|
|
SU_Shutdown();
|
|
#endif // MOZ_SMARTUPDATE
|
|
|
|
ET_FinishMocha();
|
|
|
|
LJ_ShutdownJava();
|
|
|
|
DisposeRgn(mMouseRgnH);
|
|
|
|
// Un-init RDF
|
|
URDFUtilities::ShutdownRDF();
|
|
|
|
sApplication = NULL;
|
|
} // CFrontApp::~CFrontApp()
|
|
|
|
//-----------------------------------
|
|
void CFrontApp::Initialize()
|
|
//-----------------------------------
|
|
{
|
|
// Insert commands to update before seleting menu into list
|
|
|
|
sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Redo);
|
|
sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Close);
|
|
sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Undo);
|
|
sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Cut);
|
|
sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Copy);
|
|
sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Paste);
|
|
sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Clear);
|
|
sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_SelectAll);
|
|
|
|
new CNSContextCallbacks;
|
|
LDocApplication::Initialize();
|
|
|
|
#ifdef FCAPI
|
|
// initialization for spiral stuff.....
|
|
FCInitialize();
|
|
#endif
|
|
|
|
CMouseDispatcher* md = new CMouseDispatcher;
|
|
AddAttachment(md);
|
|
|
|
// 97-09-11 pchen -- setup prefs proxy for CToolbarModeManager so that knows
|
|
// how to get Communicator toolbar style pref
|
|
CMozillaToolbarPrefsProxy* prefsProxy = new CMozillaToolbarPrefsProxy();
|
|
CToolbarModeManager::SetPrefsProxy(prefsProxy);
|
|
|
|
// Register callback function when browser.chrome.toolbar_style
|
|
// pref changes
|
|
PREF_RegisterCallback("browser.chrome.toolbar_style",
|
|
CToolbarModeManager::BroadcastToolbarModeChange,
|
|
(void*)NULL);
|
|
// 97-05-12 pkc -- setup sHRes and sVRes data members
|
|
CGrafPtr wMgrPort;
|
|
GetCWMgrPort(&wMgrPort);
|
|
sHRes = (**wMgrPort->portPixMap).hRes / 0x00010000; // convert from Fixed to floating point
|
|
sVRes = (**wMgrPort->portPixMap).vRes / 0x00010000; // convert from Fixed to floating point
|
|
|
|
// 97-08-23 pchen -- register us as listener to LGrowZone
|
|
LGrowZone::GetGrowZone()->AddListener(this);
|
|
|
|
} // CFrontApp::Initialize()
|
|
|
|
void CFrontApp::RegisterMimeType(CMimeMapper * mapper)
|
|
{
|
|
CMimeMapper::LoadAction loadAction = mapper->GetLoadAction();
|
|
CStr255 mimeName = mapper->GetMimeName();
|
|
CStr255 pluginName = mapper->GetPluginName();
|
|
void* pdesc = nil;
|
|
if (pluginName.Length() > 0)
|
|
pdesc = GetPluginDesc(pluginName);
|
|
|
|
switch (loadAction)
|
|
{
|
|
case CMimeMapper::Internal:
|
|
// Disable the previous plug-in, if any
|
|
if (pdesc)
|
|
NPL_EnablePluginType(mimeName, pdesc, false);
|
|
#ifdef OLD_IMAGE_LIB
|
|
if (mimeName == IMAGE_GIF || mimeName == IMAGE_JPG || mimeName == IMAGE_XBM || mimeName == IMAGE_PNG)
|
|
NET_RegisterContentTypeConverter(mimeName, FO_PRESENT, nil, IL_ViewStream);
|
|
#endif
|
|
#ifdef MOZ_MAIL_NEWS // BinHex decoder is in mail/news code, right?
|
|
else if (mimeName == APPLICATION_BINHEX)
|
|
NET_RegisterContentTypeConverter(APPLICATION_BINHEX, FO_PRESENT, nil, fe_MakeBinHexDecodeStream);
|
|
#endif // MOZ_MAIL_NEWS
|
|
break;
|
|
|
|
case CMimeMapper::Plugin:
|
|
//
|
|
// pdesc can be nil when reading prefs on startup -- that's OK,
|
|
// the plug-in code in mplugin.cp will take care of registration.
|
|
// bing: Alternatively, we could call NPL_EnablePluginType(true)
|
|
// here and set up the new description and extensions below.
|
|
//
|
|
if (pdesc)
|
|
NPL_RegisterPluginType(mimeName, mapper->GetExtensions(), mapper->GetDescription(), nil, pdesc, true);
|
|
return; // XP code will take care of the cdata
|
|
|
|
default:
|
|
// Disable the previous plug-in, if any
|
|
if (pdesc)
|
|
NPL_EnablePluginType(mimeName, pdesc, false);
|
|
//
|
|
// NewFilePipe will look at the mapper list and
|
|
// decide whether it should launch an app or save.
|
|
//
|
|
NET_RegisterContentTypeConverter(mimeName, FO_PRESENT, nil, NewFilePipe);
|
|
break;
|
|
}
|
|
|
|
CStr255 extensions = mapper->GetExtensions();
|
|
CStr255 mimetype = mapper->GetMimeName();
|
|
NET_cdataCommit(mimetype, extensions);
|
|
|
|
// Special case for View Source
|
|
// montulli knows why is this
|
|
if (mimetype == HTML_VIEWER_APPLICATION_MIME_TYPE) {
|
|
if (loadAction == CMimeMapper::Internal) {
|
|
NET_RegisterContentTypeConverter (TEXT_HTML, FO_VIEW_SOURCE, NULL, INTL_ConvCharCode);
|
|
NET_RegisterContentTypeConverter (INTERNAL_PARSER, FO_VIEW_SOURCE,TEXT_HTML, net_ColorHTMLStream);
|
|
NET_RegisterContentTypeConverter ("*", FO_VIEW_SOURCE, TEXT_PLAIN, net_ColorHTMLStream);
|
|
NET_RegisterContentTypeConverter (MESSAGE_RFC822, FO_VIEW_SOURCE, NULL, INTL_ConvCharCode); // added by ftang. copy from libnet #ifdef UNIX
|
|
NET_RegisterContentTypeConverter (MESSAGE_NEWS, FO_VIEW_SOURCE, NULL, INTL_ConvCharCode); // added by ftang. copy from libnet #ifdef UNIX
|
|
}
|
|
else // Pipe to disk for launching
|
|
{
|
|
NET_RegisterContentTypeConverter (INTERNAL_PARSER, FO_VIEW_SOURCE, nil, NewFilePipe);
|
|
NET_RegisterContentTypeConverter (TEXT_HTML, FO_VIEW_SOURCE, nil, NewFilePipe);
|
|
NET_RegisterContentTypeConverter ("*", FO_VIEW_SOURCE, nil, NewFilePipe);
|
|
}
|
|
}
|
|
|
|
// We need to add the description, too, which unfortunately requires
|
|
// looking the cinfo up AGAIN and setting the desc field...
|
|
char* description = (char*) mapper->GetDescription();
|
|
XP_ASSERT(description);
|
|
if (description)
|
|
{
|
|
NET_cdataStruct temp;
|
|
NET_cdataStruct* cdata;
|
|
char* mimetype = (char*) mimeName;
|
|
|
|
XP_BZERO(&temp, sizeof(temp));
|
|
temp.ci.type = mimetype;
|
|
cdata = NET_cdataExist(&temp);
|
|
XP_ASSERT(cdata);
|
|
if (cdata)
|
|
StrAllocCopy(cdata->ci.desc, description);
|
|
}
|
|
}
|
|
|
|
|
|
// NetLib Internals!
|
|
extern char * XP_AppName;
|
|
extern char * XP_AppVersion;
|
|
extern char * XP_AppCodeName;
|
|
extern char * XP_AppLanguage;
|
|
extern char * XP_AppPlatform;
|
|
|
|
// Creates a path suitable for use by XP_FILE_OPEN, and xpHotlist file spec
|
|
|
|
char* GetBookmarksPath( FSSpec& spec, Boolean useDefault )
|
|
{
|
|
if ( useDefault )
|
|
{
|
|
spec = CPrefs::GetFilePrototype( CPrefs::MainFolder );
|
|
::GetIndString( spec.name, 300, bookmarkFile );
|
|
}
|
|
char* newPath = CFileMgr::GetURLFromFileSpec( spec );
|
|
if ( newPath )
|
|
::BlockMoveData( newPath + 7, newPath, strlen( newPath )-6 );
|
|
// Hack, gets rid of the file:///
|
|
return newPath;
|
|
}
|
|
|
|
void CFrontApp::InitBookmarks()
|
|
{
|
|
CBookmarksAttachment *attachment = new CBookmarksAttachment;
|
|
AddAttachment( attachment ); // Bookmark commands
|
|
|
|
UpdateMenus();
|
|
}
|
|
|
|
|
|
// static
|
|
int CFrontApp::SetBooleanWithPref(const char *prefName, void *boolPtr)
|
|
{
|
|
XP_Bool currentValue = *(Boolean *)boolPtr;
|
|
PREF_GetBoolPref(prefName, ¤tValue);
|
|
*(Boolean *)boolPtr = currentValue;
|
|
return 0;
|
|
}
|
|
|
|
// This is called right after startup for us to do our initialization. If
|
|
// the user wants to open/print a document then this will be the file
|
|
// spec. Otherwise it's nil (normal startup)
|
|
void CFrontApp::ProperStartup( FSSpec* file, short fileType )
|
|
{
|
|
LFile* prefsFile = NULL;
|
|
Boolean gotPrefsFile = false;
|
|
static Boolean properStartup = FALSE;
|
|
|
|
if ( fStartupAborted )
|
|
return;
|
|
|
|
if ( properStartup )
|
|
{
|
|
if ( fileType == FILE_TYPE_ODOC
|
|
|| fileType == FILE_TYPE_GETURL
|
|
|| fileType == FILE_TYPE_LDIF)
|
|
DoOpenDoc( file, fileType );
|
|
|
|
// Cannot open the Profile Manager while app is running
|
|
if ( (fileType == FILE_TYPE_PROFILES )
|
|
|| (fileType == STARTUP_TYPE_NETPROFILE) )
|
|
ErrorManager::PlainAlert(ERROR_OPEN_PROFILE_MANAGER);
|
|
|
|
return;
|
|
}
|
|
|
|
properStartup = TRUE;
|
|
|
|
// Initialize all the modules,
|
|
// Read generic prefs (which will LoadState all the modules)
|
|
// Then start the modules and managers
|
|
|
|
NET_InitFileFormatTypes(NULL, NULL); // Needs to be initialized before prefs are read in.
|
|
SECNAV_InitConfigObject(); // ditto
|
|
|
|
CPrefs::PrefErr abortStartup = CPrefs::eOK;
|
|
SplashProgress( GetPString(MAC_PROGRESS_PREFS));
|
|
|
|
if ((fileType == FILE_TYPE_PREFS) && file) {
|
|
gotPrefsFile = true;
|
|
prefsFile = new LFile(*file);
|
|
}
|
|
|
|
// Once we get to this point it's safe to quit
|
|
fSafeToQuit = true;
|
|
|
|
#ifdef DEBUG
|
|
// hack to show the profile manager stuff when a modifier key is down
|
|
KeyMap theKeys;
|
|
GetKeys(theKeys);
|
|
|
|
if (theKeys[1] & 0x00008000) // is the command key down
|
|
{
|
|
prefsFile = NULL;
|
|
fileType = FILE_TYPE_PROFILES;
|
|
}
|
|
#endif
|
|
|
|
abortStartup = CPrefs::DoRead( prefsFile, fileType );
|
|
|
|
if (( abortStartup == CPrefs::eAbort ) || fUserWantsToQuit)
|
|
{
|
|
fStartupAborted = true;
|
|
DoQuit();
|
|
return;
|
|
}
|
|
|
|
if ( fileType == FILE_TYPE_ASW && file )
|
|
abortStartup = CPrefs::eRunAccountSetup;
|
|
|
|
XP_Bool startupFlag;
|
|
mHasFrontierMenuSharing = (!(PREF_GetBoolPref("browser.mac.no_menu_sharing", &startupFlag) == PREF_NOERROR && startupFlag));
|
|
mHasBookmarksMenu = (!(PREF_GetBoolPref("browser.mac.no_bookmarks_menu", &startupFlag) == PREF_NOERROR && startupFlag));
|
|
|
|
#ifndef MOZ_MAIL_NEWS
|
|
#ifdef SERVER_ON_RESTART_HACK // not needed in Nova.
|
|
// Do this after we read prefs:
|
|
{
|
|
// Check to see what mail.server_type is and what mail.server_type_on_restart is.
|
|
// Must be careful because our auto admin tool may have created a "Big Brother"
|
|
// preference file that locks mail.server_type. If this is the case we must
|
|
// discard whatever mail.server_type_on_restart is. If the admin hasn't
|
|
// locked this preference then we use mail.server_type_on_restart (this is what
|
|
// gets set in the preference dialog).
|
|
int32 mailServerType, mailServerTypeOnRestart;
|
|
PREF_GetIntPref("mail.server_type" , &mailServerType);
|
|
PREF_GetIntPref("mail.server_type_on_restart" , &mailServerTypeOnRestart);
|
|
|
|
// The default value of the latter is -1, of the former, 0 (POP3).
|
|
// Neither of these should NEVER be set to -1 after we run the first time.
|
|
if (-1 == mailServerTypeOnRestart)
|
|
mailServerTypeOnRestart = mailServerType;
|
|
else
|
|
mailServerType = mailServerTypeOnRestart;
|
|
// Write the adjusted values back to the prefs database.
|
|
if (!PREF_PrefIsLocked("mail.server_type"))
|
|
PREF_SetIntPref("mail.server_type" , mailServerType);
|
|
PREF_SetIntPref("mail.server_type_on_restart" , mailServerTypeOnRestart);
|
|
}
|
|
#endif
|
|
#endif // MOZ_MAIL_NEWS
|
|
|
|
// Set the state of network.online to match offline.startup_mode
|
|
Int32 startupNetworkState;
|
|
enum {kOnlineState, kOfflineState, kAskUserForState};
|
|
PREF_GetIntPref("offline.startup_mode" , &startupNetworkState);
|
|
switch (startupNetworkState)
|
|
{
|
|
case kOnlineState:
|
|
PREF_SetBoolPref("network.online" , true);
|
|
break;
|
|
|
|
case kOfflineState:
|
|
PREF_SetBoolPref("network.online" , false);
|
|
break;
|
|
|
|
case kAskUserForState:
|
|
{
|
|
XP_Bool onlineLastTime;
|
|
PREF_GetBoolPref("network.online" , &onlineLastTime);
|
|
XP_Bool locked = PREF_PrefIsLocked("offline.startup_mode");
|
|
|
|
enum
|
|
{
|
|
eAskMeDialog = 12009,
|
|
eWorkOnline,
|
|
eWorkOffline,
|
|
eSetPref
|
|
};
|
|
|
|
StDialogHandler handler(eAskMeDialog, nil);
|
|
LWindow *dialog = handler.GetDialog();
|
|
LGARadioButton *onRButton =
|
|
(LGARadioButton *)dialog->FindPaneByID(eWorkOnline);
|
|
XP_ASSERT(onRButton);
|
|
LGARadioButton *offRButton =
|
|
(LGARadioButton *)dialog->FindPaneByID(eWorkOffline);
|
|
XP_ASSERT(offRButton);
|
|
if (onlineLastTime)
|
|
{
|
|
onRButton->SetValue(true);
|
|
}
|
|
else
|
|
{
|
|
offRButton->SetValue(true);
|
|
}
|
|
LGACheckbox *setPrefBox =
|
|
(LGACheckbox *)dialog->FindPaneByID(eSetPref);
|
|
XP_ASSERT(setPrefBox);
|
|
if (locked)
|
|
{
|
|
setPrefBox->Disable();
|
|
}
|
|
// Run the dialog
|
|
MessageT message = msg_Nothing;
|
|
do
|
|
{
|
|
message = handler.DoDialog();
|
|
} while (msg_OK != message);
|
|
XP_Bool goOnline = onRButton->GetValue();
|
|
if (setPrefBox->GetValue())
|
|
{
|
|
int32 newPrefValue = goOnline ?
|
|
kOnlineState:
|
|
kOfflineState;
|
|
PREF_SetIntPref("offline.startup_mode", newPrefValue);
|
|
}
|
|
if (goOnline)
|
|
{
|
|
PREF_SetBoolPref("network.online" , true);
|
|
}
|
|
else
|
|
{
|
|
PREF_SetBoolPref("network.online" , false);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
SetBooleanWithPref("security.enable_java", &mJavaEnabled);
|
|
PREF_RegisterCallback("security.enable_java",
|
|
SetBooleanWithPref,
|
|
(void*)&mJavaEnabled);
|
|
|
|
// Set CSharedPatternWorld::sUseUtilityPattern from pref
|
|
XP_Bool useUtilityPattern;
|
|
int prefResult = PREF_GetBoolPref("browser.mac.use_utility_pattern", &useUtilityPattern);
|
|
if (prefResult == PREF_NOERROR && useUtilityPattern)
|
|
{
|
|
// Just for grins, check to see if utility pattern exists
|
|
PixPatHandle thePattern = NULL;
|
|
thePattern = ::GetPixPat(cUtilityPatternResID);
|
|
if (thePattern)
|
|
{
|
|
CSharedPatternWorld::sUseUtilityPattern = true;
|
|
::DisposePixPat(thePattern);
|
|
}
|
|
}
|
|
|
|
|
|
// NETLIB wait until we've read prefs to determine what to set up
|
|
CStr255 tmp;
|
|
|
|
// It is a good idea to allocate enough space for strings.
|
|
// Before today, we were not doing so. This was evil...
|
|
// So, XP_ALLOC now takes tmp.Length() + 1 as an argument
|
|
// instead of XP_ALLOC.
|
|
// dkc 1/25/96
|
|
|
|
::GetIndString( tmp, ID_STRINGS, APPNAME_STRING_INDEX );
|
|
XP_AppName = (char*)XP_ALLOC( tmp.Length() + 1);
|
|
sprintf( XP_AppName, tmp );
|
|
|
|
::GetIndString( tmp, ID_STRINGS, APPLANGUAGE_STRING_INDEX );
|
|
XP_AppLanguage = (char*)XP_ALLOC( tmp.Length() + 1);
|
|
sprintf( XP_AppLanguage, tmp );
|
|
|
|
::GetIndString( tmp, ID_STRINGS, APPVERSION_STRING_INDEX );
|
|
// Admin Kit: support optional user-agent suffix
|
|
{
|
|
char* suffix;
|
|
if ( PREF_CopyConfigString("user_agent", &suffix) == PREF_NOERROR )
|
|
{
|
|
tmp = tmp + "C-" + suffix;
|
|
XP_FREE(suffix);
|
|
}
|
|
}
|
|
|
|
CStr255 tmp2;
|
|
#ifdef powerc
|
|
::GetIndString( tmp2, ID_STRINGS, USERAGENT_PPC_STRING_INDEX );
|
|
#else
|
|
::GetIndString( tmp2, ID_STRINGS, USERAGENT_68K_STRING_INDEX );
|
|
#endif
|
|
tmp = tmp + " ";
|
|
tmp = tmp + tmp2;
|
|
|
|
char* securityText = "X";
|
|
|
|
XP_AppVersion = (char*)XP_ALLOC( tmp.Length() + strlen( securityText ) + 1);
|
|
sprintf( XP_AppVersion, tmp, securityText );
|
|
|
|
::GetIndString( tmp2, ID_STRINGS, APPCODENAME_STRING_INDEX );
|
|
XP_AppCodeName = (char*)XP_ALLOC( tmp2.Length() + 1);
|
|
sprintf( XP_AppCodeName, tmp2 );
|
|
|
|
#ifdef powerc
|
|
XP_AppPlatform = "MacPPC";
|
|
#else
|
|
XP_AppPlatform = "Mac68k";
|
|
#endif
|
|
|
|
SplashProgress( GetPString(MAC_PROGRESS_NET) );
|
|
|
|
NET_InitNetLib (CPrefs::GetLong( CPrefs::BufferSize ), CPrefs::GetLong( CPrefs::Connections ) );
|
|
|
|
SECNAV_EarlyInit();
|
|
NET_ChangeMaxNumberOfConnections(50);
|
|
RNG_SystemInfoForRNG();
|
|
|
|
// 1998.01.12 pchen and 1998.02.23 rjc
|
|
// RDF now uses NetLib. Netlib initializes history. RDF reimplements
|
|
// history. Looks like History initialization has been changed to work
|
|
// correctly. Also, GH_InitGlobalHistory() can be safely called twice.
|
|
URDFUtilities::StartupRDF();
|
|
|
|
// Load the .jsc startup file, if necessary (autoadmin added 2/11/98 arshad)
|
|
//¥¥¥ REVISIT NOVA MERGE ¥¥¥ NET_DownloadAutoAdminCfgFile();
|
|
|
|
// Install Help and Directory menus
|
|
InstallMenus(); // arshad - taken from line 1317, moved here for autoadmin to update menus (re: bug 88421)
|
|
|
|
// 1998-03-17 pchen -- Moved this code here to fix Communicator menu
|
|
// Polaris: remove Calendar/3270 items if they're not installed
|
|
// (?? maybe these are always available for Polaris (autoadmin lib)
|
|
// so users get helpful error messages if they try them..?)
|
|
if (CWindowMenu::sWindowMenu)
|
|
{
|
|
FSSpec fspec;
|
|
|
|
if ( CFileMgr::FindApplication(kCalendarAppSig, fspec) != noErr )
|
|
(CWindowMenu::sWindowMenu)->RemoveCommand(cmd_LaunchCalendar);
|
|
|
|
if ( CFileMgr::FindApplication(kAOLInstantMessengerSig, fspec) != noErr )
|
|
(CWindowMenu::sWindowMenu)->RemoveCommand(cmd_LaunchAOLInstantMessenger);
|
|
|
|
if ( ! Find3270Applet(fspec) )
|
|
(CWindowMenu::sWindowMenu)->RemoveCommand(cmd_Launch3270);
|
|
|
|
if ( ! FE_IsNetcasterInstalled() )
|
|
(CWindowMenu::sWindowMenu)->RemoveCommand(cmd_LaunchNetcaster);
|
|
}
|
|
|
|
SECNAV_Init();
|
|
SECNAV_RunInitialSecConfig(); // call after SECNAV_Init()
|
|
|
|
// Must not call SECNAV_SecurityVersion before SECNAV_Init().
|
|
securityText = SECNAV_SecurityVersion( PR_FALSE );
|
|
XP_FREE(XP_AppVersion);
|
|
XP_AppVersion = (char*)XP_ALLOC( tmp.Length() + strlen( securityText ) + 1);
|
|
sprintf( XP_AppVersion, tmp, securityText );
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
NET_ReadNewsrcFileMappings();
|
|
#endif
|
|
|
|
SplashProgress( GetPString(MAC_PROGRESS_BOOKMARK));
|
|
InitBookmarks();
|
|
|
|
// Create the NSPR event queue
|
|
|
|
mozilla_event_queue = PR_CreateEventQueue("Mozilla Event Queue", mozilla_thread);
|
|
|
|
LM_InitMocha(); // mocha, mocha, mocha
|
|
NPL_Init(); // plugins
|
|
|
|
// The tools menus must be created after the plugins are read in.
|
|
|
|
#ifdef EDITOR
|
|
CToolsAttachment *attachment = new CToolsAttachment;
|
|
if ( attachment )
|
|
AddAttachment( attachment ); // Tools menu
|
|
CFontMenuAttachment *fontattachment = new CFontMenuAttachment;
|
|
if ( fontattachment )
|
|
AddAttachment( fontattachment ); // Font menu
|
|
CRecentEditMenuAttachment *recentattachment = new CRecentEditMenuAttachment;
|
|
if ( recentattachment )
|
|
AddAttachment( recentattachment );
|
|
#endif // EDITOR
|
|
UpdateMenus();
|
|
|
|
#if defined (JAVA)
|
|
// Initialize the java runtime, start the MToolkit thread running
|
|
// to keep the network alive. For now, we have to temporarily
|
|
// enable java to make sure that the runtime bootstraps itself
|
|
// minimally.
|
|
// dkc 3-18-96
|
|
|
|
this->SplashProgress( GetPString(MAC_PROGRESS_JAVAINIT));
|
|
|
|
LJ_SetJavaEnabled((PRBool)CPrefs::GetBoolean(CPrefs::EnableJava));
|
|
#endif /* defined (JAVA) */
|
|
|
|
#if defined(EDITOR) && defined(MOZ_JAVA)
|
|
EDTPLUG_RegisterEditURLCallback(&OpenEditURL);
|
|
#endif // EDITOR && MOZ_JAVA
|
|
|
|
/* Okay, this is hacky, but necessary. It is extremely
|
|
important that the Macintosh reclaims memory. So,
|
|
we want the finalizer to be at as high a priority as
|
|
possible. */
|
|
|
|
if ((PR_GetGCInfo() != NULL) && (PR_GetGCInfo()->finalizer != NULL))
|
|
#ifndef NSPR20
|
|
PR_SetThreadPriority(PR_GetGCInfo()->finalizer, 31);
|
|
#else
|
|
PR_SetThreadPriority(PR_GetGCInfo()->finalizer, PR_PRIORITY_URGENT);
|
|
#endif
|
|
|
|
DestroySplashScreen();
|
|
if ( abortStartup == CPrefs::eRunAccountSetup )
|
|
file = NULL;
|
|
|
|
Boolean agreedToLicense = AgreedToLicense( file, fileType );
|
|
|
|
if ( abortStartup == CPrefs::eRunAccountSetup )
|
|
LaunchAccountSetup();
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
// This is for Biff notification.
|
|
// It should come after menus and after prefs are read in and probably
|
|
// after the online/offline determination is made.
|
|
CCheckMailContext::Initialize(this); // we are the owner/user
|
|
#endif // MOZ_MAIL_NEWS
|
|
#ifdef MOZ_LOC_INDEP
|
|
InitializeLocationIndependence();
|
|
#endif
|
|
#ifdef MOZ_MAIL_NEWS
|
|
SplashProgress( GetPString(MAC_PROGRESS_ADDRESS) );
|
|
CAddressBookManager::OpenAddressBookManager();
|
|
#endif // MOZ_MAIL_NEWS
|
|
// NET_FinishInitNetLib();
|
|
if (agreedToLicense)
|
|
CreateStartupEnvironment(! gotPrefsFile);
|
|
|
|
fProperStartup = true;
|
|
} // CFrontApp::ProperStartup
|
|
|
|
|
|
Boolean CFrontApp::AgreedToLicense( FSSpec* fileSpec, short fileType )
|
|
{
|
|
// ML License clicker moved to installer so just open
|
|
DoOpenDoc( fileSpec, fileType );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
// Called when application starts up without any documents
|
|
// Reads in the default preferences doc, and then creates a default browser window
|
|
void CFrontApp::StartUp()
|
|
{
|
|
ProperStartup( NULL, FILE_TYPE_PREFS );
|
|
// CMailNewsFolderWindow::FindAndShow(true);
|
|
}
|
|
|
|
|
|
pascal void colorPopupMDEFProc(short message, MenuHandle theMenu,
|
|
Rect *menuRect, Point hitPt, short *whichItem);
|
|
|
|
// openStartupWindows is only false if we started comm from a desktop icon
|
|
// and don't want the prefs-specified components to open up
|
|
void CFrontApp::CreateStartupEnvironment(Boolean openStartupWindows)
|
|
{
|
|
#ifdef EDITOR
|
|
// Composer's color picker MDEF
|
|
Handle stubMDEFH;
|
|
MenuDefUPP colorMdefUPP;
|
|
|
|
// load/lock (but DON'T detach) MDEF stub and set it to call appropriate routine
|
|
if ( (stubMDEFH = Get1Resource( 'MDEF', 20000 )) != NULL)
|
|
{
|
|
HNoPurge((Handle)stubMDEFH);
|
|
HUnlock((Handle)stubMDEFH);
|
|
MoveHHi((Handle)stubMDEFH);
|
|
HLock((Handle)stubMDEFH);
|
|
if ( (colorMdefUPP = NewMenuDefProc(colorPopupMDEFProc)) != NULL)
|
|
{
|
|
*(ProcPtr *)(*stubMDEFH + 6L) = (ProcPtr)colorMdefUPP;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
XP_Bool startupFlag;
|
|
|
|
// handle new startup preferences
|
|
CommandT command = cmd_Nothing;
|
|
// check to see if we need to bring up a new browser window at startup
|
|
if (PREF_GetBoolPref("general.startup.browser", &startupFlag) == PREF_NOERROR)
|
|
{
|
|
if (startupFlag)
|
|
{
|
|
// Only create a new browser window if the startupFlag indicates
|
|
// that we should and there are no delayed URLs (which could happen
|
|
// if a 'GURL' or 'OURL' event is handled while the profile dialog
|
|
// or license dialog is waiting to be dismissed) and there are no
|
|
// open browser windows (which could happen if an 'odoc' event
|
|
// was processed prior to CreateStartupEnvironment being called).
|
|
// These guards will ensure that we don't open any unnecessary blank
|
|
// browser windows at startup.
|
|
|
|
CMediatedWindow* window = CWindowMediator::GetWindowMediator()->FetchTopWindow(
|
|
WindowType_Browser,
|
|
regularLayerType,
|
|
true);
|
|
UInt32 howMany = CURLDispatcher::CountDelayedURLs();
|
|
if (openStartupWindows && !window && !CURLDispatcher::CountDelayedURLs())
|
|
MakeNewDocument();
|
|
}
|
|
}
|
|
if (PREF_GetBoolPref("general.startup.netcaster", &startupFlag) == PREF_NOERROR)
|
|
{
|
|
if (openStartupWindows && startupFlag)
|
|
ObeyCommand(cmd_LaunchNetcaster, NULL);
|
|
}
|
|
|
|
startupFlag = false;
|
|
if (HasFrontierMenuSharing())
|
|
{
|
|
AddAttachment(new LMenuSharingAttachment( msg_AnyMessage, TRUE, MENU_SHARING_FIRST ) ); // Menu Sharing
|
|
}
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
// check to see if we need to bring up mail window at startup
|
|
if (PREF_GetBoolPref("general.startup.mail", &startupFlag) == PREF_NOERROR)
|
|
{
|
|
if (openStartupWindows && startupFlag)
|
|
ObeyCommand(cmd_Inbox, NULL);
|
|
}
|
|
// check to see if we need to bring up news window at startup
|
|
if (PREF_GetBoolPref("general.startup.news", &startupFlag) == PREF_NOERROR)
|
|
{
|
|
if (openStartupWindows && startupFlag)
|
|
ObeyCommand(cmd_NewsGroups, NULL);
|
|
}
|
|
#endif // MOZ_MAIL_NEWS
|
|
#ifdef EDITOR
|
|
// check to see if we need to bring up an editor window at startup
|
|
if (PREF_GetBoolPref("general.startup.editor", &startupFlag) == PREF_NOERROR)
|
|
{
|
|
if (openStartupWindows && startupFlag)
|
|
ObeyCommand(cmd_NewWindowEditor, NULL);
|
|
}
|
|
#endif
|
|
#if !defined(MOZ_LITE) && !defined(MOZ_MEDIUM)
|
|
// check to see if we need to launch conference at startup
|
|
if (PREF_GetBoolPref("general.startup.conference", &startupFlag) == PREF_NOERROR)
|
|
{
|
|
if (openStartupWindows && startupFlag)
|
|
ObeyCommand(cmd_LaunchConference, NULL);
|
|
}
|
|
// check to see if we need to launch calendar at startup
|
|
if (PREF_GetBoolPref("general.startup.calendar", &startupFlag) == PREF_NOERROR)
|
|
{
|
|
if (openStartupWindows && startupFlag)
|
|
ObeyCommand(cmd_LaunchCalendar, NULL);
|
|
}
|
|
|
|
// check to see if we need to launch AOL Instant Messenger at startup
|
|
if (PREF_GetBoolPref("general.startup.AIM", &startupFlag) == PREF_NOERROR)
|
|
{
|
|
if (openStartupWindows && startupFlag)
|
|
ObeyCommand(cmd_LaunchAOLInstantMessenger, NULL);
|
|
}
|
|
#endif // !MOZ_LITE && !MOZ_MEDIUM
|
|
#ifdef MOZ_TASKBAR
|
|
if (PREF_GetBoolPref("taskbar.mac.is_open", &startupFlag) == PREF_NOERROR)
|
|
{
|
|
if (openStartupWindows && startupFlag)
|
|
ObeyCommand(cmd_ToggleTaskBar, NULL);
|
|
}
|
|
#endif // MOZ_TASKBAR
|
|
}
|
|
|
|
// OpenDocument asserts that there is a preference document read in,
|
|
// because we cannot do any document operations before preferences are
|
|
// initialized. Pref documents are read automatically in assertion
|
|
// Hyper document is read in here
|
|
void CFrontApp::OpenDocument( FSSpec* inFileSpec )
|
|
{
|
|
FInfo fndrInfo;
|
|
short fileType;
|
|
|
|
OSErr err = ::FSpGetFInfo( inFileSpec, &fndrInfo );
|
|
//what to do on error?
|
|
|
|
// ¥Êhow silly is this?
|
|
if ( emPrefsType == fndrInfo.fdType )
|
|
fileType = FILE_TYPE_PREFS;
|
|
else if ( emProfileType == fndrInfo.fdType )
|
|
fileType = FILE_TYPE_PROFILES;
|
|
else if ( 'ASWl' == fndrInfo.fdType )
|
|
fileType = FILE_TYPE_ASW;
|
|
else if ( emLDIFType == fndrInfo.fdType)
|
|
fileType = FILE_TYPE_LDIF;
|
|
else if (emNetprofileType == fndrInfo.fdType)
|
|
fileType = STARTUP_TYPE_NETPROFILE;
|
|
else
|
|
fileType = FILE_TYPE_ODOC;
|
|
|
|
ProperStartup( inFileSpec, fileType );
|
|
}
|
|
|
|
void CFrontApp::DoOpenDoc( FSSpec* inFileSpec, short fileType )
|
|
{
|
|
switch ( fileType )
|
|
{
|
|
case FILE_TYPE_ODOC:
|
|
if ( inFileSpec )
|
|
OpenLocalURL(inFileSpec );
|
|
break;
|
|
case FILE_TYPE_LDIF:
|
|
#ifdef MOZ_MAIL_NEWS
|
|
if (inFileSpec)
|
|
CAddressBookManager::ImportLDIF(*inFileSpec);
|
|
break;
|
|
#endif // MOZ_MAIL_NEWS
|
|
case FILE_TYPE_PREFS:
|
|
case FILE_TYPE_PROFILES:
|
|
break;
|
|
case FILE_TYPE_GETURL:
|
|
case FILE_TYPE_NONE:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Opens up a bookmark file
|
|
void CFrontApp::OpenBookmarksFile( FSSpec* inFileSpec, CBrowserWindow * /*win*/, Boolean /*delayed*/)
|
|
{
|
|
Try_
|
|
{
|
|
vector<char> url(500);
|
|
OSErr err = ReadBookmarksFile(url, *inFileSpec);
|
|
ThrowIfOSErr_(err);
|
|
|
|
URL_Struct * request = NET_CreateURLStruct( url.begin(), NET_DONT_RELOAD );
|
|
CURLDispatcher::DispatchURL(request, NULL);
|
|
}
|
|
Catch_(inErr)
|
|
{}
|
|
EndCatch_
|
|
}
|
|
|
|
|
|
// Opens a local file. If it is a bookmark, load the URL stored in it
|
|
void CFrontApp::OpenLocalURL( FSSpec* inFileSpec ,
|
|
CBrowserWindow * win,
|
|
char * mime_type,
|
|
Boolean delayed)
|
|
{
|
|
if (inFileSpec == NULL)
|
|
return;
|
|
Boolean dummy, dummy2;
|
|
|
|
// Resolve the aliases
|
|
OSErr err = ::ResolveAliasFile(inFileSpec,TRUE,&dummy,&dummy2);
|
|
|
|
// If we are a bookmark file, open a bookmark
|
|
FInfo info;
|
|
err = ::FSpGetFInfo (inFileSpec, &info);
|
|
if ((info.fdType == emBookmarkFile) && (mime_type == NULL))
|
|
{
|
|
OpenBookmarksFile( inFileSpec, win, delayed);
|
|
return;
|
|
}
|
|
|
|
// If we are a help file, open a help document
|
|
if ((info.fdType == emHelpType) && (mime_type == NULL))
|
|
{
|
|
char * help_id = NULL;
|
|
char * map_file_url = CFileMgr::GetURLFromFileSpec(*inFileSpec);
|
|
|
|
DebugStr("\pNot implemented");
|
|
//¥¥¥ NET_GetHTMLHelpFileFromMapFile(*CBookmarksContext::GetInstance(), // Will this work?
|
|
//¥¥¥ map_file_url, help_id, NULL);
|
|
FREEIF( help_id );
|
|
FREEIF( map_file_url );
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
// If we are mailbox file at the root of the local mail hierarchy, we can assume that it's an
|
|
// imported mailbox created by the import module. Then just update the folder tree (the new mailbox
|
|
// will appear in the folder hierarchy).
|
|
FSSpec mailFolderSpec = CPrefs::GetFilePrototype(CPrefs::MailFolder);
|
|
if (mailFolderSpec.vRefNum == inFileSpec->vRefNum
|
|
&& mailFolderSpec.parID == inFileSpec->parID)
|
|
{
|
|
Assert_(false);
|
|
//MSG_UpdateFolderTree(); not checked in yet by phil.
|
|
return;
|
|
}
|
|
#endif //MOZ_MAIL_NEWS
|
|
|
|
// Open it by loading the URL into specified window
|
|
|
|
char* localURL;
|
|
if (win == NULL)
|
|
win = CBrowserWindow::FindAndPrepareEmpty(true);
|
|
if (win != NULL)
|
|
{
|
|
localURL = CFileMgr::GetURLFromFileSpec(*inFileSpec);
|
|
URL_Struct * request = NET_CreateURLStruct (localURL, NET_DONT_RELOAD);
|
|
if (localURL)
|
|
XP_FREE(localURL);
|
|
ThrowIfNil_(request);
|
|
request->content_type = mime_type;
|
|
// if (delayed)
|
|
// win->StartLatentLoading(request);
|
|
// else
|
|
// win->StartLoadingURL (request, FO_CACHE_AND_PRESENT);
|
|
// FIX ME!!! Hook up latent loading!!!
|
|
CBrowserContext* theContext = (CBrowserContext*)win->GetWindowContext();
|
|
theContext->SwitchLoadURL(request, FO_CACHE_AND_PRESENT);
|
|
}
|
|
}
|
|
|
|
void CFrontApp::PrintDocument(FSSpec* inFileSpec)
|
|
{
|
|
ProperStartup( inFileSpec, FILE_TYPE_ODOC );
|
|
PrintDocument( inFileSpec );
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ¥ ClickMenuBar
|
|
// ---------------------------------------------------------------------------
|
|
// Respond to a mouse click in the menu bar.
|
|
//
|
|
// Also, we do a targeted update of menus before calling MenuSelect
|
|
|
|
void
|
|
CFrontApp::ClickMenuBar(
|
|
const EventRecord& inMacEvent)
|
|
{
|
|
StUnhiliteMenu unhiliter; // Destructor unhilites menu title
|
|
Int32 menuChoice;
|
|
|
|
CTargetedUpdateMenuRegistry::SetCommands(sCommandsToUpdateBeforeSelectingMenu);
|
|
CTargetedUpdateMenuRegistry::UpdateMenus();
|
|
|
|
CommandT menuCmd = LMenuBar::GetCurrentMenuBar()->
|
|
MenuCommandSelection(inMacEvent, menuChoice);
|
|
|
|
if (menuCmd != cmd_Nothing) {
|
|
SignalIf_(LCommander::GetTarget() == nil);
|
|
LCommander::SetUpdateCommandStatus(true);
|
|
LCommander::GetTarget()->ProcessCommand(menuCmd, &menuChoice);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ¥ UpdateMenus
|
|
// ---------------------------------------------------------------------------
|
|
// Update the status of all menu items
|
|
//
|
|
// General Strategy:
|
|
// (1) Designate every Menu as "unused".
|
|
// (2) Iterate through all menu commands, asking the Target chain for
|
|
// the status of each one. Enable/Disable, mark, and adjust the
|
|
// name of each menu accordingly. Enabling any item in a Menu
|
|
// designates that Menu as "used".
|
|
// (3) Iterate through each menu, asking for the status of a special
|
|
// synthetic command that indicates the entire menu. At this time,
|
|
// Commanders can perform operations that affect the menu as a whole.
|
|
// Menus that are desinated "used" are enabled; "unused" ones
|
|
// are disabled.
|
|
//
|
|
// Changes from LEventDispatcher::UpdateMenus():
|
|
//
|
|
// - We maintain a list of commands to update and a bool to indicate
|
|
// whether to update just those commands or all commands. This is
|
|
// useful for targeting specific commands to update without having
|
|
// to pay the price for updating hundreds of commands. The registry
|
|
// of commands is maintained separately from CFrontApp. The general
|
|
// pattern is that the client which calls UpdateMenus will stuff
|
|
// it's commands in the registry and then call UpdateMenus.
|
|
//
|
|
// One limitation of this targeted updating is that it is possible
|
|
// that a menu which should be disabled because there are no enabled
|
|
// items might still be enabled. However, given that the typical
|
|
//
|
|
// - We call UpdateMenusSelf() to get some more work done.
|
|
//
|
|
// - We cache some stuff during UpdateMenus
|
|
|
|
void
|
|
CFrontApp::UpdateMenus()
|
|
{
|
|
#ifdef PROFILE_UPDATE_MENUS
|
|
StProfileSection profileThis("\pprofile", 1000, 100);
|
|
#endif
|
|
|
|
// UDesktop::StUseFrontWindowIsModalCache theFrontWindowIsModalCache;
|
|
|
|
#ifdef EDITOR
|
|
CAutoPtr<CEditView::StUseCharFormattingCache> stCharCache;
|
|
|
|
CEditView *editViewCommander = dynamic_cast<CEditView *>(LCommander::GetTarget());
|
|
if ( editViewCommander )
|
|
stCharCache.reset(new CEditView::StUseCharFormattingCache(*editViewCommander));
|
|
#endif
|
|
|
|
LMenuBar *theMenuBar = LMenuBar::GetCurrentMenuBar();
|
|
Int16 menuItem;
|
|
MenuHandle macMenuH = nil;
|
|
LMenu *theMenu;
|
|
CommandT theCommand;
|
|
Boolean isEnabled;
|
|
Boolean usesMark;
|
|
Char16 mark;
|
|
Str255 itemName;
|
|
LCommander *theTarget = LCommander::GetTarget();
|
|
|
|
theMenu = nil; // Designate each menu as "unused"
|
|
while (theMenuBar->FindNextMenu(theMenu)) {
|
|
theMenu->SetUsed(false);
|
|
}
|
|
|
|
// Loop thru each menu item that has an
|
|
// associated command
|
|
while (theMenuBar->FindNextCommand(menuItem, macMenuH,
|
|
theMenu, theCommand)) {
|
|
|
|
// Don't change menu item state for
|
|
// special commands (all negative
|
|
// values except cmd_UseMenuItem)
|
|
// or for commands which are not
|
|
// in the registry when we are
|
|
// supposed to only update commands
|
|
// which are in the registry.
|
|
if ((theCommand > 0 || theCommand == cmd_UseMenuItem) &&
|
|
(!CTargetedUpdateMenuRegistry::UseRegistryToUpdateMenus() ||
|
|
CTargetedUpdateMenuRegistry::CommandInRegistry(theCommand)))
|
|
{
|
|
|
|
// For commands that depend on the menu
|
|
// item, get synthetic command number
|
|
if (theCommand == cmd_UseMenuItem) {
|
|
theCommand = theMenu->SyntheticCommandFromIndex(menuItem);
|
|
}
|
|
|
|
// Ask Target if command is enabled,
|
|
// if the menu item should be marked,
|
|
// and if the name should be changed
|
|
isEnabled = false;
|
|
usesMark = false;
|
|
itemName[0] = 0;
|
|
|
|
if (theTarget != nil) {
|
|
theTarget->ProcessCommandStatus(theCommand, isEnabled,
|
|
usesMark, mark, itemName);
|
|
}
|
|
|
|
// Adjust the state of each menu item as needed.
|
|
// Also designate as "used" the Menu containing an
|
|
// enabled item.
|
|
|
|
if (isEnabled) {
|
|
::EnableItem(macMenuH, menuItem);
|
|
theMenu->SetUsed(true);
|
|
} else {
|
|
::DisableItem(macMenuH, menuItem);
|
|
}
|
|
|
|
if (usesMark) {
|
|
::SetItemMark(macMenuH, menuItem, mark);
|
|
}
|
|
|
|
if (itemName[0] > 0) {
|
|
::SetMenuItemText(macMenuH, menuItem, itemName);
|
|
}
|
|
|
|
} else if (theCommand < 0 || CTargetedUpdateMenuRegistry::UseRegistryToUpdateMenus()) {
|
|
// Don't change state of items with
|
|
// negative command numbers or
|
|
// when the registry is in use.
|
|
if (theMenu->ItemIsEnabled(menuItem)) {
|
|
theMenu->SetUsed(true);
|
|
}
|
|
|
|
} else { // Item has command number 0
|
|
::DisableItem(macMenuH, menuItem);
|
|
}
|
|
|
|
}
|
|
|
|
if (theTarget != nil) {
|
|
// Loop thru each menu
|
|
theMenu = nil;
|
|
while (theMenuBar->FindNextMenu(theMenu)) {
|
|
|
|
// The "command" for an entire Menu is the synthetic command
|
|
// number for item zero (negative number that has the Menu ID
|
|
// in the high word and 0 in the low word.
|
|
|
|
theCommand = theMenu->SyntheticCommandFromIndex(0);
|
|
|
|
// The Target chain now has the opportunity to do something
|
|
// to the Menu as a whole, as a call for this special
|
|
// synthetic command is made only once for each menu.
|
|
// For example, a text handling Commander could put a check
|
|
// mark next to the current font in a Fonts menu.
|
|
//
|
|
// The isEnabled parameter [outEnabled as an argument to
|
|
// FindCommandStatus()] should be set to true to enable
|
|
// a menu that does not contain commands that have
|
|
// already been explicitly enabled. For example, a Fonts
|
|
// menu typically has no associated commands (the menu
|
|
// items all use synthetic commands), so a Commander
|
|
// must set outEnabled to true when asked the status
|
|
// of the synthetic command corresponding the Fonts menu.
|
|
//
|
|
// The mark information is ignored, as is the itemName.
|
|
// It would be possible to use the itemName to facilitate
|
|
// dynamic changing of menu titles. However, this is bad
|
|
// interface design which we don't want to encourage.
|
|
|
|
isEnabled = false;
|
|
|
|
theTarget->ProcessCommandStatus(theCommand, isEnabled,
|
|
usesMark, mark, itemName);
|
|
|
|
// Menu is "used" if it contains commands that were
|
|
// explicity enabled in the loop above, or if this
|
|
// last call passes back "true" for isEnabled.
|
|
|
|
if (isEnabled) {
|
|
theMenu->SetUsed(true);
|
|
}
|
|
|
|
// Enable all "used" Menus and disable "unused" ones
|
|
// To avoid unnecessary redraws, we invalidate the menu
|
|
// bar only if a Menu's enableFlags changes (which means
|
|
// that its state has changed).
|
|
|
|
macMenuH = theMenu->GetMacMenuH();
|
|
Uint32 originalFlags = (**macMenuH).enableFlags;
|
|
|
|
if (theMenu->IsUsed()) {
|
|
::EnableItem(macMenuH, 0);
|
|
} else {
|
|
if (!CTargetedUpdateMenuRegistry::UseRegistryToUpdateMenus())
|
|
{
|
|
// When we are using the registry, it is OK to enable
|
|
// menus that are now used, but it is inappropriate
|
|
// to disable menus, since we did not update the command
|
|
// status of all menu items and therefore we do not have
|
|
// enough information to disable the whole menu,
|
|
|
|
::DisableItem(macMenuH, 0);
|
|
}
|
|
}
|
|
|
|
if (originalFlags != (**macMenuH).enableFlags) {
|
|
::InvalMenuBar();
|
|
}
|
|
}
|
|
}
|
|
|
|
UpdateMenusSelf();
|
|
}
|
|
|
|
void CFrontApp::UpdateMenusSelf()
|
|
{
|
|
if (CWindowMenu::sWindowMenu)
|
|
(CWindowMenu::sWindowMenu)->Update();
|
|
if (CHistoryMenu::sHistoryMenu)
|
|
(CHistoryMenu::sHistoryMenu)->Update();
|
|
|
|
CBookmarksAttachment::UpdateMenu();
|
|
|
|
#ifdef EDITOR
|
|
CToolsAttachment::UpdateMenu();
|
|
CRecentEditMenuAttachment::UpdateMenu();
|
|
#endif // EDITOR
|
|
|
|
UpdateHierarchicalMenus();
|
|
|
|
CPaneEnabler::UpdatePanes();
|
|
#ifdef MOZ_MAIL_NEWS
|
|
CMailFolderMixin::UpdateMailFolderMixinsNow();
|
|
#endif // MOZ_MAIL_NEWS
|
|
|
|
}
|
|
|
|
void CFrontApp::UpdateHierarchicalMenus()
|
|
// This is called after LEventDispatcher::UpdateMenus(), and enables parent
|
|
// items of any used submenu.
|
|
{
|
|
if (!LCommander::GetTarget())
|
|
return;
|
|
Int16 menuItem;
|
|
MenuHandle macMenuH = nil;
|
|
LMenu *theMenu;
|
|
CommandT theCommand;
|
|
LMenuBar *theMenuBar = LMenuBar::GetCurrentMenuBar();
|
|
while (theMenuBar->FindNextCommand(menuItem, macMenuH,
|
|
theMenu, theCommand))
|
|
{
|
|
short menuChar;
|
|
::GetItemCmd(macMenuH, menuItem, &menuChar);
|
|
if (menuChar != hMenuCmd)
|
|
continue;
|
|
// We have an item item with the "hierarchical" flag.
|
|
|
|
// If we have a hierarchal menu that HAS a command number (ie CommandFromIndex
|
|
// returns something greater than zero) then we're going to trust that it
|
|
// has been properly enabled already. If we don't give the root menu item the
|
|
// benefit of the doubt then we could end up accidentally enabling it if it has
|
|
// more than 31 items in its sub menu
|
|
if (theMenu->CommandFromIndex(menuItem) < 0) {
|
|
|
|
// Find the child menu, see if LEventDispatcher::UpdateMenus() has
|
|
// marked it as "used", and if so, make sure we enable this item
|
|
short childMenuID;
|
|
::GetItemMark(macMenuH, menuItem, &childMenuID);
|
|
LMenu* childMenu = theMenuBar->FetchMenu(childMenuID);
|
|
if (childMenu && childMenu->IsUsed())
|
|
{
|
|
::EnableItem(macMenuH, menuItem);
|
|
theMenu->SetUsed(true);
|
|
}
|
|
}
|
|
}
|
|
// Now make sure entire menus get enabled.
|
|
while (theMenuBar->FindNextMenu(theMenu))
|
|
{
|
|
macMenuH = theMenu->GetMacMenuH();
|
|
Uint32 originalFlags = (**macMenuH).enableFlags;
|
|
if (theMenu->IsUsed())
|
|
::EnableItem(macMenuH, 0);
|
|
else
|
|
::DisableItem(macMenuH, 0);
|
|
if (originalFlags != (**macMenuH).enableFlags)
|
|
::InvalMenuBar();
|
|
}
|
|
} // CFrontApp::UpdateHierarchicalMenus
|
|
|
|
|
|
/*
|
|
App::::MakeNewDocument
|
|
Called by PowerPlant when a user chooses "New"
|
|
Returns a window (which is also a model object) in this case. Will change.
|
|
Is recordable.
|
|
*/
|
|
LModelObject* CFrontApp::MakeNewDocument()
|
|
{
|
|
|
|
try
|
|
{
|
|
enum
|
|
{
|
|
kBlankPage,
|
|
kHomePage,
|
|
kLastPage
|
|
};
|
|
int32 prefValue = kHomePage;
|
|
int prefResult = PREF_GetIntPref("browser.startup.page", &prefValue);
|
|
if (prefResult != PREF_NOERROR)
|
|
{
|
|
prefValue = kHomePage;
|
|
}
|
|
URL_Struct* theURL;
|
|
|
|
switch (prefValue)
|
|
{
|
|
case kBlankPage:
|
|
theURL = nil;
|
|
break;
|
|
case kLastPage:
|
|
char urlBuffer[1024];
|
|
if (GH_GetMRUPage(urlBuffer, 1024))
|
|
{
|
|
theURL = NET_CreateURLStruct(urlBuffer, NET_DONT_RELOAD);
|
|
}
|
|
else
|
|
{
|
|
theURL = nil;
|
|
//theURL = NET_CreateURLStruct(urlBuffer, NET_DONT_RELOAD);
|
|
}
|
|
break;
|
|
case kHomePage:
|
|
default:
|
|
{
|
|
CStr255 url = CPrefs::GetString(CPrefs::HomePage);
|
|
if (url.Length() > 0)
|
|
theURL = NET_CreateURLStruct(url, NET_DONT_RELOAD);
|
|
else
|
|
theURL = nil;
|
|
}
|
|
break;
|
|
}
|
|
|
|
CURLDispatcher::DispatchURL(theURL, NULL, false, true);
|
|
}
|
|
catch (...)
|
|
{
|
|
|
|
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//
|
|
// ChooseDocument
|
|
//
|
|
// Picks a document, and opens it in a window (uses existing window if one is open). This
|
|
// takes advantage of the new NavigationServices stuff if it is available.
|
|
//
|
|
void CFrontApp::ChooseDocument()
|
|
{
|
|
static const OSType myTypes[] = { 'TEXT', 'JPEG', 'GIFf'};
|
|
|
|
UDesktop::Deactivate(); // Always bracket this
|
|
|
|
FSSpec fileSpec;
|
|
Boolean fileSelected = SimpleOpenDlog ( 3, myTypes, &fileSpec );
|
|
|
|
if ( fileSelected )
|
|
OpenDocument(&fileSpec);
|
|
|
|
UDesktop::Activate();
|
|
|
|
} // ChooseDocument
|
|
|
|
|
|
CFrontApp* CFrontApp::GetApplication()
|
|
{
|
|
return sApplication;
|
|
}
|
|
|
|
// ¥¥ commands
|
|
|
|
void CFrontApp::ProcessCommandStatus(CommandT inCommand,Boolean &outEnabled, Boolean &outUsesMark,
|
|
Char16 &outMark, Str255 outName)
|
|
{
|
|
if (GetState() == programState_Quitting)
|
|
// If we are quitting, all commands are disabled
|
|
{
|
|
outEnabled = FALSE;
|
|
return;
|
|
}
|
|
else
|
|
LApplication::ProcessCommandStatus(inCommand,outEnabled, outUsesMark,outMark, outName);
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CFrontApp::FindCommandStatus( CommandT command, Boolean& enabled,
|
|
Boolean& usesMark, Char16& mark, Str255 outName )
|
|
//-----------------------------------
|
|
{
|
|
// Allow only close and quit if memory is low.
|
|
if (Memory_MemoryIsLow())
|
|
{
|
|
if (command != cmd_Quit) // cmd_Close and cmd_CloseAll will also be avail., from elsewhere.
|
|
enabled = FALSE;
|
|
else
|
|
LDocApplication::FindCommandStatus (command, enabled, usesMark, mark, outName);
|
|
return;
|
|
}
|
|
// Do not enable menus behind modal dialogs
|
|
if (IsFrontWindowModal()) // Only enable quit when front window is modal
|
|
{
|
|
if (command != cmd_Quit)
|
|
enabled = FALSE;
|
|
else
|
|
LDocApplication::FindCommandStatus (command, enabled, usesMark, mark, outName);
|
|
return;
|
|
}
|
|
usesMark = FALSE;
|
|
switch ( command )
|
|
{
|
|
case cmd_GoForward:
|
|
if (CApplicationEventAttachment::CurrentEventHasModifiers(optionKey))
|
|
{
|
|
LString::CopyPStr(::GetPString(MENU_FORWARD_ONE_HOST), outName);
|
|
}
|
|
else
|
|
{
|
|
LString::CopyPStr(::GetPString(MENU_FORWARD), outName);
|
|
}
|
|
break;
|
|
case cmd_GoBack:
|
|
if (CApplicationEventAttachment::CurrentEventHasModifiers(optionKey))
|
|
{
|
|
LString::CopyPStr(::GetPString(MENU_BACK_ONE_HOST), outName);
|
|
}
|
|
else
|
|
{
|
|
LString::CopyPStr(::GetPString(MENU_BACK), outName);
|
|
}
|
|
break;
|
|
|
|
case cmd_ShowJavaConsole:
|
|
#if defined (JAVA)
|
|
usesMark = true;
|
|
mark = LJ_IsConsoleShowing() ? 0x12 : 0;
|
|
enabled = mJavaEnabled;
|
|
#endif /* defined (JAVA) */
|
|
break;
|
|
|
|
#ifdef EDITOR
|
|
// case cmd_New_Document_Heirarchical_Menu:
|
|
case cmd_NewWindowEditor:
|
|
case cmd_NewWindowEditorIFF:
|
|
case cmd_New_Document_Template:
|
|
case cmd_New_Document_Wizard:
|
|
case cmd_OpenFileEditor:
|
|
case cmd_EditEditor:
|
|
#endif // EDITOR
|
|
#ifdef MOZ_MAIL_NEWS
|
|
case cmd_MailNewsFolderWindow:
|
|
case cmd_NewsGroups:
|
|
// case cmd_GetNewMail:
|
|
case cmd_Inbox:
|
|
case cmd_MailNewsSearch:
|
|
case cmd_MailFilters:
|
|
case cmd_SearchAddresses:
|
|
case cmd_AddressBookWindow:
|
|
case cmd_NewFolder:
|
|
#endif // MOZ_MAIL_NEWS
|
|
#if defined(MOZ_MAIL_COMPOSE) || defined(MOZ_MAIL_NEWS)
|
|
case cmd_NewMailMessage:
|
|
#endif // MOZ_MAIL_COMPOSE
|
|
#ifdef EDITOR
|
|
case cmd_OpenURLEditor:
|
|
#endif // EDITOR
|
|
case cmd_BrowserWindow:
|
|
case cmd_Preferences:
|
|
case 19896: /*cmd_NetToggle*/
|
|
case cmd_OpenURL:
|
|
// case cmd_EditGeneral:
|
|
case cmd_EditNetwork:
|
|
case cmd_EditSecurity:
|
|
// old mail/news stuff
|
|
// case cmd_MailWindow:
|
|
// case cmd_NewsWindow:
|
|
// case cmd_MailTo:
|
|
case cmd_CoBrandLogo:
|
|
case cmd_AboutPlugins:
|
|
case cmd_LaunchCalendar:
|
|
case cmd_Launch3270:
|
|
case cmd_LaunchNetcaster:
|
|
#ifdef FORTEZZA
|
|
case cmd_FortezzaCard:
|
|
case cmd_FortezzaChange:
|
|
case cmd_FortezzaView:
|
|
case cmd_FortezzaInfo:
|
|
case cmd_FortezzaLogout:
|
|
#endif // FORTEZZA
|
|
enabled = TRUE;
|
|
break;
|
|
|
|
case cmd_LaunchConference:
|
|
enabled = mConferenceApplicationExists;
|
|
break;
|
|
|
|
case cmd_BookmarksWindow:
|
|
case cmd_HistoryWindow:
|
|
case cmd_NCNewWindow:
|
|
enabled = !Memory_MemoryIsLow();
|
|
break;
|
|
|
|
case cmd_LaunchImportModule:
|
|
enabled = mImportModuleExists;
|
|
break;
|
|
|
|
case cmd_New:
|
|
case cmd_Open:
|
|
enabled = !Memory_MemoryIsLow();
|
|
break;
|
|
#ifdef MOZ_TASKBAR
|
|
case cmd_ToggleTaskBar:
|
|
enabled = TRUE;
|
|
CTaskBarListener::GetToggleTaskBarWindowMenuItemName(outName);
|
|
break;
|
|
#endif // MOZ_TASKBAR
|
|
#ifdef MOZ_OFFLINE
|
|
// Online/Offline mode
|
|
case cmd_ToggleOffline:
|
|
case cmd_SynchronizeForOffline:
|
|
enabled = TRUE;
|
|
UOffline::FindOfflineCommandStatus(command, enabled, outName);
|
|
break;
|
|
#endif // MOZ_OFFLINE
|
|
default:
|
|
ResIDT menuID;
|
|
Int16 menuItem;
|
|
if ( command >= DIR_BUTTON_BASE && command <= DIR_BUTTON_LAST )
|
|
enabled = TRUE;
|
|
else if (IsSyntheticCommand(command, menuID, menuItem) && menuID == cWindowMenuID)
|
|
// --ML 4.0b2 Disable all Window menu items without a command number
|
|
// (i.e. Conference, Calendar, IBM, History)
|
|
enabled = FALSE;
|
|
// the code below was used ifndef MAILNEWS
|
|
// else if ((command > cmd_WINDOW_MENU_BASE) && (command < cmd_WINDOW_MENU_BASE_LAST))
|
|
// enabled = TRUE;
|
|
else
|
|
LDocApplication::FindCommandStatus (command, enabled, usesMark, mark, outName);
|
|
}
|
|
} // CFrontApp::FindCommandStatus
|
|
|
|
extern void NET_ToggleTrace();
|
|
|
|
//-----------------------------------
|
|
Boolean CFrontApp::ObeyCommand(CommandT inCommand, void* ioParam)
|
|
//-----------------------------------
|
|
{
|
|
Boolean bCommandHandled = true;
|
|
|
|
switch ( inCommand )
|
|
{
|
|
case cmd_BrowserWindow:
|
|
/*
|
|
URL_Struct* theURL = NULL;
|
|
CURLDispatcher* theDispatcher = CURLDispatcher::GetURLDispatcher();
|
|
Assert_(theDispatcher != NULL);
|
|
theDispatcher->DispatchToView(NULL, theURL, FO_CACHE_AND_PRESENT);
|
|
*/
|
|
// this code is stolen from the editor button, below! Thanks Kathy!
|
|
// get the front window so we know if an browser window is already in the front
|
|
CMediatedWindow *wp, *browserwin;
|
|
CWindowIterator iterAny(WindowType_Any);
|
|
iterAny.Next(wp);
|
|
CWindowIterator iter(WindowType_Browser);
|
|
iter.Next(browserwin);
|
|
if (browserwin && (wp == browserwin))
|
|
{
|
|
// count the number of windows; stuff current browser window into browserwin
|
|
// put the window we want to be frontmost into wp (reuse)
|
|
// spec says to cycle through all windows of our type so we bring the
|
|
// backmost-window to the front and push the others down in the stack
|
|
int numWindows = 1;
|
|
while (iter.Next(wp))
|
|
{
|
|
numWindows++;
|
|
browserwin = wp;
|
|
}
|
|
|
|
if (numWindows == 1)
|
|
browserwin = NULL; // set to NULL so we create new window below
|
|
}
|
|
|
|
// if no browser in front window bring the frontmost browser window to front
|
|
// if browser is in front select the window determined above and we're done!
|
|
if (browserwin)
|
|
{
|
|
browserwin->Show();
|
|
browserwin->Select();
|
|
break;
|
|
}
|
|
else // let's make a new one
|
|
{
|
|
MakeNewDocument();
|
|
}
|
|
break;
|
|
case 19896: /*cmd_NetToggle*/
|
|
NET_ToggleTrace();
|
|
break;
|
|
case cmd_ShowJavaConsole:
|
|
#if defined (JAVA)
|
|
{
|
|
if (LJ_IsConsoleShowing())
|
|
LJ_HideConsole();
|
|
else
|
|
LJ_ShowConsole();
|
|
}
|
|
#endif /* defined (JAVA) */
|
|
break;
|
|
|
|
case cmd_HistoryWindow:
|
|
{
|
|
|
|
CNavCenterWindow* navCenter = dynamic_cast<CNavCenterWindow*>(URobustCreateWindow::CreateWindow(CNavCenterWindow::res_ID, this));
|
|
navCenter->BringPaneToFront ( HT_VIEW_HISTORY );
|
|
}
|
|
break;
|
|
|
|
case cmd_BookmarksWindow:
|
|
case cmd_NCNewWindow:
|
|
{
|
|
CNavCenterWindow* navCenter = dynamic_cast<CNavCenterWindow*>(URobustCreateWindow::CreateWindow(CNavCenterWindow::res_ID, this));
|
|
navCenter->BringPaneToFront ( HT_VIEW_BOOKMARK );
|
|
}
|
|
break;
|
|
|
|
#if defined(MOZ_MAIL_COMPOSE) || defined(MOZ_MAIL_NEWS)
|
|
case cmd_NewMailMessage:
|
|
MSG_MailDocument(NULL);
|
|
break;
|
|
#endif // MOZ_MAIL_COMPOSE || MOZ_MAIL_NEWS
|
|
|
|
case cmd_OpenURL:
|
|
DoOpenURLDialog();
|
|
break;
|
|
|
|
#ifdef EDITOR
|
|
|
|
case cmd_OpenURLEditor:
|
|
DoOpenURLDialogInEditor();
|
|
break;
|
|
|
|
case cmd_New_Document_Template:
|
|
{
|
|
CStr255 urlString = CPrefs::GetString(CPrefs::EditorNewDocTemplateLocation);
|
|
if ( urlString != CStr255::sEmptyString )
|
|
{
|
|
URL_Struct* theURL = NET_CreateURLStruct(urlString, NET_DONT_RELOAD);
|
|
if (theURL)
|
|
CURLDispatcher::DispatchURL(theURL, NULL, false, true);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case cmd_New_Document_Wizard:
|
|
char* url;
|
|
if (PREF_CopyConfigString("internal_url.page_from_wizard.url", &url) == PREF_NOERROR)
|
|
{
|
|
URL_Struct* theURL = NET_CreateURLStruct(url, NET_DONT_RELOAD);
|
|
if (theURL)
|
|
CURLDispatcher::DispatchURL(theURL, NULL, false, true);
|
|
}
|
|
break;
|
|
|
|
case cmd_NewWindowEditorIFF:
|
|
{
|
|
// get the front window so we know if an editor window is already in the front
|
|
CMediatedWindow *wp, *editwin;
|
|
CWindowIterator iterAny(WindowType_Any);
|
|
iterAny.Next(wp);
|
|
|
|
CWindowIterator iter(WindowType_Editor);
|
|
iter.Next(editwin);
|
|
|
|
if ( editwin && ( wp == editwin ) )
|
|
{
|
|
// count the number of windows; stuff current editor window into editwin
|
|
// put the window we want to be frontmost into wp (reuse)
|
|
// spec says to cycle through all windows of our type so we bring the
|
|
// backmost-window to the front and push the others down in the stack
|
|
int numWindows = 1;
|
|
while ( iter.Next(wp) )
|
|
{
|
|
numWindows++;
|
|
editwin = wp;
|
|
}
|
|
|
|
if ( numWindows == 1 )
|
|
editwin = NULL; // set to NULL so we create new window below
|
|
}
|
|
|
|
// if no editor in front window bring the frontmost editor window to front
|
|
// if editor is in front select the window determined above and we're done!
|
|
if ( editwin )
|
|
{
|
|
editwin->Show();
|
|
editwin->Select();
|
|
break;
|
|
}
|
|
// else continue below
|
|
}
|
|
case cmd_NewWindowEditor:
|
|
CEditorWindow::MakeEditWindow( NULL, NULL );
|
|
break;
|
|
|
|
case cmd_OpenFileEditor:
|
|
{
|
|
|
|
// StandardFileReply myReply;
|
|
|
|
static const OSType myTypes[] = { 'TEXT'};
|
|
|
|
UDesktop::Deactivate(); // Always bracket this
|
|
|
|
FSSpec fileSpec;
|
|
Boolean fileSelected = SimpleOpenDlog ( 1, myTypes, &fileSpec );
|
|
|
|
UDesktop::Activate();
|
|
|
|
if (!fileSelected) return TRUE; // we handled it... we just didn't do anything!
|
|
|
|
char* localURL = CFileMgr::GetURLFromFileSpec(fileSpec);
|
|
if (localURL == NULL) return TRUE;
|
|
|
|
NET_cinfo *cinfo = NET_cinfo_find_type (localURL);
|
|
if (cinfo && cinfo->type && (!strcasecomp (cinfo->type, TEXT_HTML)
|
|
|| !strcasecomp (cinfo->type, UNKNOWN_CONTENT_TYPE)
|
|
|| !strcasecomp (cinfo->type, TEXT_PLAIN)))
|
|
{
|
|
URL_Struct * request = NET_CreateURLStruct ( localURL, NET_NORMAL_RELOAD );
|
|
if ( request )
|
|
CEditorWindow::MakeEditWindow( NULL, request );
|
|
}
|
|
else
|
|
{
|
|
ErrorManager::PlainAlert( NOT_HTML );
|
|
}
|
|
|
|
XP_FREE(localURL);
|
|
}
|
|
break;
|
|
|
|
case cmd_EditEditor:
|
|
CPrefsDialog::EditPrefs( CPrefsDialog::eExpandEditor,
|
|
PrefPaneID::eEditor_Main, CPrefsDialog::eIgnore);
|
|
break;
|
|
|
|
#endif
|
|
|
|
case cmd_Preferences:
|
|
CPrefsDialog::EditPrefs();
|
|
break;
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
case cmd_NewsGroups:
|
|
case cmd_MailNewsFolderWindow:
|
|
{
|
|
CMailNewsFolderWindow::FindAndShow(true, inCommand);
|
|
break;
|
|
}
|
|
case cmd_GetNewMail:
|
|
// If it came here, we must assume there are no mail/news windows.
|
|
// So open the inbox First.
|
|
CThreadWindow* tw = CThreadWindow::ShowInbox(cmd_GetNewMail);
|
|
break;
|
|
case cmd_Inbox:
|
|
CThreadWindow::ShowInbox(cmd_Nothing);
|
|
break;
|
|
case cmd_MailTo:
|
|
{
|
|
MSG_Mail(NULL); // Crashes now, libmsg error
|
|
}
|
|
break;
|
|
#endif // MOZ_MAIL_NEWS
|
|
|
|
case cmd_AboutPlugins:
|
|
DoGetURL( "about:plugins" );
|
|
break;
|
|
|
|
case cmd_LaunchConference:
|
|
LaunchExternalApp(kConferenceAppSig, CONFERENCE_APP_NAME);
|
|
break;
|
|
|
|
case cmd_LaunchImportModule:
|
|
LaunchExternalApp(kImportAppSig, IMPORT_APP_NAME);
|
|
break;
|
|
|
|
// --ML Polaris
|
|
case cmd_LaunchCalendar:
|
|
LaunchExternalApp(kCalendarAppSig, CALENDAR_APP_NAME);
|
|
break;
|
|
|
|
case cmd_LaunchAOLInstantMessenger:
|
|
LaunchExternalApp(kAOLInstantMessengerSig, AIM_APP_NAME);
|
|
break;
|
|
|
|
case cmd_Launch3270:
|
|
Launch3270Applet();
|
|
break;
|
|
|
|
case cmd_LaunchNetcaster:
|
|
LaunchNetcaster();
|
|
break;
|
|
|
|
|
|
#ifdef FORTEZZA
|
|
case cmd_FortezzaCard:
|
|
SSL_FortezzaMenu(NULL,SSL_FORTEZZA_CARD_SELECT);
|
|
break;
|
|
case cmd_FortezzaChange:
|
|
// er, excuse me, mr fortezza, but CHyperWin::Show() might return NULL....
|
|
CHyperWin* win = GetFrontHyperWin();
|
|
if (win)
|
|
SSL_FortezzaMenu(win->fHyperView->GetContext(),SSL_FORTEZZA_CHANGE_PERSONALITY);
|
|
break;
|
|
case cmd_FortezzaView:
|
|
CHyperWin* win = GetFrontHyperWin();
|
|
if (win)
|
|
SSL_FortezzaMenu(win->fHyperView->GetContext(),SSL_FORTEZZA_VIEW_PERSONALITY);
|
|
break;
|
|
case cmd_FortezzaInfo:
|
|
SSL_FortezzaMenu(NULL,SSL_FORTEZZA_CARD_INFO);
|
|
break;
|
|
case cmd_FortezzaLogout:
|
|
/* sBookMarkContext */
|
|
SSL_FortezzaMenu(NULL,SSL_FORTEZZA_LOGOUT);
|
|
break;
|
|
#endif
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
// This really shouldn't be here, but since the mail/news windows are not up yet,
|
|
// it's here for testing
|
|
case cmd_MailNewsSearch:
|
|
CSearchWindowManager::ShowSearchWindow();
|
|
break;
|
|
case cmd_MailFilters:
|
|
CFiltersWindowManager::ShowFiltersWindow();
|
|
break;
|
|
case cmd_AddressBookWindow:
|
|
CAddressBookManager::ShowAddressBookWindow();
|
|
break;
|
|
case cmd_NewFolder:
|
|
{
|
|
CMessageFolder folder(nil);
|
|
UFolderDialogs::ConductNewFolderDialog(folder);
|
|
break;
|
|
}
|
|
// case cmd_SearchAddresses:
|
|
// CSearchWindowManager::ShowSearchAddressesWindow();
|
|
// break;
|
|
#endif // MOZ_MAIL_NEWS
|
|
#ifdef MOZ_TASKBAR
|
|
case cmd_ToggleTaskBar:
|
|
CTaskBarListener::ToggleTaskBarWindow();
|
|
break;
|
|
#endif // MOZ_TASKBAR
|
|
#ifdef MOZ_OFFLINE
|
|
// Online/Offline mode
|
|
case cmd_ToggleOffline:
|
|
UOffline::ObeyToggleOfflineCommand();
|
|
break;
|
|
|
|
case cmd_SynchronizeForOffline:
|
|
UOffline::ObeySynchronizeCommand();
|
|
break;
|
|
#endif // MOZ_OFFLINE
|
|
default:
|
|
{
|
|
// Directory urls
|
|
if ( inCommand >= DIR_BUTTON_BASE && inCommand <= DIR_BUTTON_LAST )
|
|
DoOpenDirectoryURL( inCommand );
|
|
|
|
// Spinning icon
|
|
else if ( inCommand == LOGO_BUTTON || inCommand == cmd_CoBrandLogo )
|
|
DoOpenLogoURL( inCommand );
|
|
|
|
else if (!CWindowMenu::ObeyWindowCommand(inCommand))
|
|
{
|
|
ResIDT menuID = ( HiWord( -inCommand ) );
|
|
Int16 itemNum = ( LoWord( -inCommand ) );
|
|
if ( menuID == kHMHelpMenuID )
|
|
{
|
|
itemNum -= sHelpMenuOrigLength;
|
|
DoHelpMenuItem( itemNum );
|
|
}
|
|
else
|
|
bCommandHandled = LDocApplication::ObeyCommand(inCommand, ioParam);
|
|
}
|
|
break;
|
|
}
|
|
} // switch
|
|
return bCommandHandled;
|
|
} // CFrontApp::ObeyCommand
|
|
|
|
|
|
//-----------------------------------
|
|
void CFrontApp::DoOpenDirectoryURL( CommandT menuCommand )
|
|
//-----------------------------------
|
|
{
|
|
CStr255 urlString;
|
|
Boolean isMenuCommand = (menuCommand >= DIR_MENU_BASE);
|
|
short stringID = isMenuCommand ? DIR_MENU_BASE : DIR_BUTTON_BASE;
|
|
|
|
char* url;
|
|
if ( PREF_CopyIndexConfigString(
|
|
isMenuCommand ? "menu.places.item" : "toolbar.places.item",
|
|
menuCommand - stringID, "url", &url) == PREF_NOERROR )
|
|
{
|
|
DoGetURL(url);
|
|
XP_FREE(url);
|
|
}
|
|
}
|
|
|
|
void CFrontApp::DoOpenLogoURL( CommandT menuCommand )
|
|
{
|
|
// Admin Kit: Handle co-brand button
|
|
char* url;
|
|
if ( menuCommand == LOGO_BUTTON &&
|
|
PREF_CopyConfigString("toolbar.logo.url", &url) == PREF_NOERROR )
|
|
{
|
|
DoGetURL(url);
|
|
XP_FREE(url);
|
|
}
|
|
else
|
|
{
|
|
StringHandle handle = GetString( LOGO_BUTTON_URL_RESID );
|
|
CStr255 urlString = *((unsigned char**)handle);
|
|
if ( urlString != CStr255::sEmptyString )
|
|
DoGetURL( (unsigned char*)urlString );
|
|
}
|
|
}
|
|
|
|
void CFrontApp::DoWindowsMenu(CommandT inCommand)
|
|
{
|
|
Int32 index = inCommand - cmd_WINDOW_MENU_BASE;
|
|
LWindow * win;
|
|
if (fWindowsMenu.FetchItemAt(index, &win))
|
|
win->Select();
|
|
}
|
|
|
|
// DoGetURL loads the given url into the frontmost window, or new one if there is no frontmost
|
|
// Provides a bottleneck for UI generated requests to load a URL
|
|
void CFrontApp::DoGetURL( const cstring& url )
|
|
{
|
|
// Check for kiosk mode and bail if it's set so that the user can't manually
|
|
// go to a different URL. Note that this does NOT prevent dispatching to a different
|
|
// URL from the content.
|
|
if (CAppleEventHandler::GetKioskMode() == KioskOn)
|
|
return;
|
|
|
|
// Is this REALLY necessary?
|
|
(CFrontApp::GetApplication())->ProperStartup( NULL, FILE_TYPE_NONE ); // Making sure that we have the prefs loaded
|
|
|
|
URL_Struct* theURL = NET_CreateURLStruct(url, NET_DONT_RELOAD);
|
|
if (theURL)
|
|
CURLDispatcher::DispatchURL(theURL, NULL);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Chenge of address
|
|
// AppleEvents has moved to CAppleEventHandler.cp
|
|
// C Hull
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/*------------------------------------------------
|
|
AppleEvent Dispach Here
|
|
In: & AppleEvent/ Evenc coming in
|
|
& ReplyEvent/ Reply event back to sender
|
|
& Descriptor/ Not sure why this was extracted, but OK.
|
|
AppleEvent/ ID The event
|
|
Out: Event Handled by the sAppleEvents entity
|
|
------------------------------------------------*/
|
|
void CFrontApp::HandleAppleEvent(
|
|
const AppleEvent& inAppleEvent,
|
|
AppleEvent& outAEReply,
|
|
AEDesc& outResult,
|
|
long inAENumber)
|
|
{
|
|
XP_TRACE(("Handling event %d", inAENumber));
|
|
Try_
|
|
{
|
|
if ( CAppleEventHandler::sAppleEventHandler == NULL )
|
|
new CAppleEventHandler;
|
|
|
|
ThrowIfNil_(CAppleEventHandler::sAppleEventHandler);
|
|
|
|
CAppleEventHandler::sAppleEventHandler->HandleAppleEvent(inAppleEvent,
|
|
outAEReply,
|
|
outResult,
|
|
inAENumber);
|
|
|
|
}
|
|
Catch_( inErr )
|
|
{}
|
|
EndCatch_
|
|
}
|
|
|
|
|
|
|
|
|
|
void CFrontApp::GetAEProperty(DescType inProperty,
|
|
const AEDesc &inRequestedType,
|
|
AEDesc &outPropertyDesc) const
|
|
{
|
|
try
|
|
{
|
|
if (CAppleEventHandler::sAppleEventHandler == NULL)
|
|
new CAppleEventHandler;
|
|
ThrowIfNil_(CAppleEventHandler::sAppleEventHandler);
|
|
|
|
CAppleEventHandler::sAppleEventHandler->GetAEProperty(inProperty,
|
|
inRequestedType,
|
|
outPropertyDesc);
|
|
}
|
|
catch(...)
|
|
{}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CFrontApp::SetAEProperty(DescType inProperty,
|
|
const AEDesc &inRequestedType,
|
|
AEDesc &outPropertyDesc)
|
|
{
|
|
try
|
|
{
|
|
if (CAppleEventHandler::sAppleEventHandler == NULL)
|
|
new CAppleEventHandler;
|
|
ThrowIfNil_(CAppleEventHandler::sAppleEventHandler);
|
|
|
|
CAppleEventHandler::sAppleEventHandler->SetAEProperty(inProperty,
|
|
inRequestedType,
|
|
outPropertyDesc);
|
|
}
|
|
catch(...)
|
|
{}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Printing
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------
|
|
void CFrontApp::SetupPage()
|
|
//-----------------------------------
|
|
{
|
|
THPrint hPrintRec;
|
|
Boolean havePrinter;
|
|
|
|
hPrintRec = CPrefs::GetPrintRecord();
|
|
|
|
havePrinter = hPrintRec != 0;
|
|
|
|
if (havePrinter)
|
|
{
|
|
UPrintingMgr::ValidatePrintRecord( hPrintRec );
|
|
if ( UPrintingMgr::OpenPrinter() )
|
|
{
|
|
UDesktop::Deactivate();
|
|
UHTMLPrinting::OpenPageSetup( hPrintRec );
|
|
UDesktop::Activate();
|
|
|
|
UPrintingMgr::ClosePrinter();
|
|
} else
|
|
havePrinter = false;
|
|
}
|
|
if ( !havePrinter )
|
|
FE_Alert( NULL, GetPString ( NO_PRINTER_RESID ) );
|
|
} // CFrontApp::SetupPage
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Menubar management
|
|
//-----------------------------------------------------------------------------
|
|
void CFrontApp::SetMenubar( ResIDT mbar, Boolean inUpdateNow )
|
|
{
|
|
fWantedMbar = mbar;
|
|
|
|
if (inUpdateNow) {
|
|
UpdateMenus();
|
|
}
|
|
}
|
|
|
|
void CFrontApp::InstallMenus()
|
|
{
|
|
// Menu creation must go here, because until now, the menu bar has not
|
|
// been created. (see LApplication::Run())
|
|
CHistoryMenu* historyMenu = new CHistoryMenu(cHistoryMenuID);
|
|
CWindowMenu* windowMenu = new CWindowMenu(cWindowMenuID);
|
|
// create CNSMenuBarManager
|
|
new CNSMenuBarManager(CWindowMediator::GetWindowMediator());
|
|
LMenuBar::GetCurrentMenuBar()->InstallMenu(historyMenu, InstallMenu_AtEnd);
|
|
CBookmarksAttachment::InstallMenus();
|
|
LMenuBar::GetCurrentMenuBar()->InstallMenu(windowMenu, InstallMenu_AtEnd);
|
|
CWindowMediator::GetWindowMediator()->AddListener(windowMenu);
|
|
|
|
// Admin Kit friendly Help and Places menus: labels and URLs are
|
|
// initialized in config.js and may be overridden by config file.
|
|
MenuHandle balloonMenuH;
|
|
HMGetHelpMenuHandle( &balloonMenuH );
|
|
if ( balloonMenuH )
|
|
{
|
|
sHelpMenuOrigLength = CountMItems(balloonMenuH);
|
|
|
|
sHelpMenuItemCount = BuildConfigurableMenu( balloonMenuH,
|
|
"menu.help.item", HELP_URLS_MENU_STRINGS );
|
|
}
|
|
|
|
/* NOTE: Places menu is installed in CBookmarksAttachment::InstallMenus(),
|
|
which calls back to BuildConfigurableMenu. */
|
|
}
|
|
|
|
int CFrontApp::BuildConfigurableMenu(MenuHandle menu, const char* xp_name, short stringsID)
|
|
{
|
|
CStr255 entry;
|
|
short i;
|
|
|
|
// Append configurable items first
|
|
for (i = 1; i <= 25; i++) {
|
|
char* label;
|
|
if ( PREF_CopyIndexConfigString(xp_name, i - 1, "label", &label) == PREF_NOERROR )
|
|
{
|
|
entry = label;
|
|
XP_FREE(label);
|
|
|
|
if (entry.IsEmpty()) // blank entry marks end of menu
|
|
break;
|
|
|
|
StripChar(entry, '&'); // strip ampersands from label
|
|
|
|
AppendMenu(menu, entry);
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
// Then append fixed items, if any (i.e. About Netscape)
|
|
if (stringsID > 0) {
|
|
CStringListRsrc menuStrings( stringsID );
|
|
for (short j = 1; j < menuStrings.CountStrings() + 1; j++) {
|
|
menuStrings.GetString( j, entry );
|
|
AppendMenu(menu, entry);
|
|
}
|
|
}
|
|
|
|
return i - 1;
|
|
}
|
|
|
|
void CFrontApp::DoHelpMenuItem( short itemNum )
|
|
{
|
|
// use configurable URL if defined, else use built-in URL
|
|
char* url;
|
|
if ( itemNum <= sHelpMenuItemCount && PREF_CopyIndexConfigString("menu.help.item",
|
|
itemNum - 1, "url", &url) == PREF_NOERROR )
|
|
{
|
|
DoGetURL( url );
|
|
XP_FREE(url);
|
|
}
|
|
else {
|
|
CStr255 urlString;
|
|
|
|
GetIndString( urlString, HELP_URLS_RESID, itemNum - sHelpMenuItemCount );
|
|
|
|
if ( urlString != CStr255::sEmptyString )
|
|
DoGetURL( (unsigned char*)urlString );
|
|
}
|
|
}
|
|
|
|
extern pascal long MDEF_MenuKey( long theMessage, short theModifiers, MenuHandle hMenu );
|
|
|
|
//-----------------------------------
|
|
void CFrontApp::EventKeyDown( const EventRecord& inMacEvent )
|
|
// ¥ we override this to patch Mercutio in
|
|
//-----------------------------------
|
|
{
|
|
CommandT keyCommand = cmd_Nothing;
|
|
Int32 menuChoice = 0;
|
|
// Remap function keys. Is there a better way? jrm 97/04/03
|
|
switch ((inMacEvent.message & keyCodeMask) >> 8)
|
|
{
|
|
case vkey_F1:
|
|
keyCommand = cmd_Undo;
|
|
break;
|
|
case vkey_F2:
|
|
keyCommand = cmd_Cut;
|
|
break;
|
|
case vkey_F3:
|
|
keyCommand = cmd_Copy;
|
|
break;
|
|
case vkey_F4:
|
|
keyCommand = cmd_Paste;
|
|
break;
|
|
default:
|
|
// Modal dialogs might have OK/cancel buttons, and handle their own keys.
|
|
// So only convert to command when front window is not modal
|
|
if ((inMacEvent.modifiers & cmdKey) && (inMacEvent.message & charCodeMask) == '.')
|
|
{
|
|
if (!IsFrontWindowModal())
|
|
keyCommand = cmd_Stop;
|
|
}
|
|
// Check if the keystroke is a Menu Equivalent
|
|
else if (LMenuBar::GetCurrentMenuBar()->CouldBeKeyCommand(inMacEvent))
|
|
{
|
|
CTargetedUpdateMenuRegistry::SetCommands(CFrontApp::GetCommandsToUpdateBeforeSelectingMenu());
|
|
CTargetedUpdateMenuRegistry::UpdateMenus();
|
|
|
|
menuChoice = MDEF_MenuKey(
|
|
inMacEvent.message,
|
|
inMacEvent.modifiers, ::GetMenu( 666 ) );
|
|
|
|
// If menuChoice is 0, then a modifer key may have been held down that
|
|
// didn't map to a known command-key equivalent (e.g. cmd-opt-n).
|
|
// In this case, we will try again with just the cmdKey. Recall that
|
|
// this is what the Finder does (with cmd-n for New Folder, for instance).
|
|
// It makes especially good sense when you think about the fact that since
|
|
// the command and option keys are close, users sometimes accidently hit both.
|
|
// Without this "fix", cmd_Nothing would be returned.
|
|
if (menuChoice == 0)
|
|
{
|
|
EventModifiers modifiers = cmdKey;
|
|
|
|
menuChoice = MDEF_MenuKey(inMacEvent.message, modifiers, ::GetMenu( 666 ));
|
|
}
|
|
|
|
if ( HiWord( menuChoice ) != 0 )
|
|
keyCommand = LMenuBar::GetCurrentMenuBar()->FindCommand(
|
|
HiWord(menuChoice),
|
|
LoWord(menuChoice));
|
|
}
|
|
}
|
|
SignalIf_(LCommander::GetTarget() == nil);
|
|
|
|
// Don't allow quit events if it isn't safe to quit but remember the request
|
|
if ((keyCommand == cmd_Quit) && !fSafeToQuit)
|
|
{
|
|
keyCommand = cmd_Nothing;
|
|
fUserWantsToQuit = true;
|
|
}
|
|
if (keyCommand != cmd_Nothing)
|
|
{
|
|
LCommander::SetUpdateCommandStatus( true );
|
|
LCommander::GetTarget()->ProcessCommand(keyCommand, &menuChoice);
|
|
::HiliteMenu( 0 );
|
|
}
|
|
else
|
|
LCommander::GetTarget()->ProcessKeyPress(inMacEvent);
|
|
} // CFrontApp::EventKeyDown
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// About Box & Splash Screen
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
void CFrontApp::ShowAboutBox()
|
|
{
|
|
DoGetURL( "about:" );
|
|
}
|
|
|
|
void* FE_AboutData( const char* which, char** data_ret, int32* length_ret,
|
|
char** content_type_ret )
|
|
{
|
|
char* ss = NULL; // security string, of course
|
|
Handle data = NULL;
|
|
|
|
try {
|
|
// Nuke the ismap portion so we can hide the url
|
|
const char* ismap = strrchr( (char*)which, '?' );
|
|
CStr255 dataName = which ? which : "";
|
|
if ( ismap )
|
|
{
|
|
ismap++;
|
|
for ( int i = 1; i <= dataName.Length(); i++ )
|
|
if (dataName[i] == '?')
|
|
{
|
|
dataName[0] = i - 1;
|
|
break;
|
|
}
|
|
}
|
|
Boolean doSprintf = FALSE;
|
|
|
|
/*
|
|
about: 128 text of about box, includes logo
|
|
about:logo 129 picture for about box
|
|
about:plugins 130 list of installed plug-ins
|
|
about:authors 131 text for authors box
|
|
about:authors? 132 text for team box
|
|
about:teamlogo 133 picture for team box
|
|
about:mailintro 134
|
|
about:rsalogo 135 picture for rsa logo
|
|
about:mozilla 136 mozilla easter egg
|
|
about:hype 137 hype sound
|
|
about:license 2890 license text
|
|
*/
|
|
if ( dataName == "" )
|
|
{
|
|
data = ::GetResource( 'TEXT', ABOUT_ABOUTPAGE_TEXT );
|
|
*content_type_ret = TEXT_MDL;
|
|
doSprintf = true;
|
|
}
|
|
else if ( dataName == "logo" )
|
|
{
|
|
data = ::GetResource ( 'Tang', ABOUT_BIGLOGO_TANG );
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
else if ( dataName == "plugins" )
|
|
{
|
|
data = ::GetResource ( 'TEXT', ABOUT_PLUGINS_TEXT );
|
|
*content_type_ret = TEXT_MDL;
|
|
}
|
|
else if ( dataName == "authors" )
|
|
{
|
|
data = ::GetResource ( 'TEXT', ABOUT_AUTHORS_TEXT );
|
|
*content_type_ret = TEXT_MDL;
|
|
}
|
|
else if ( dataName == "mailintro" )
|
|
{
|
|
data = ::GetResource( 'TEXT', ABOUT_MAIL_TEXT );
|
|
*content_type_ret = TEXT_MDL;
|
|
}
|
|
else if ( dataName == "rsalogo" )
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_RSALOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
else if ( dataName == "javalogo" )
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_JAVALOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
else if (dataName == "qtlogo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_QTLOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
|
|
else if (dataName == "insologo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_INSOLOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
else if (dataName == "litronic")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_LITRONIC_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
|
|
else if (dataName == "mclogo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_MCLOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
|
|
else if (dataName == "mmlogo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_MMLOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
|
|
else if (dataName == "ncclogo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_NCCLOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
|
|
else if (dataName == "odilogo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_ODILOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
|
|
else if (dataName == "symlogo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_SYMLOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
|
|
else if (dataName == "tdlogo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_TDLOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
|
|
else if (dataName == "visilogo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_VISILOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
|
|
else if (dataName == "visilogo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_VISILOGO_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
|
|
else if (dataName == "coslogo")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_COSLOGO_TANG);
|
|
*content_type_ret = IMAGE_JPG;
|
|
}
|
|
|
|
|
|
|
|
#ifdef FORTEZZA
|
|
else if (dataName == "litronic")
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_LITRONIC_TANG);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
#endif
|
|
else if (dataName == "mozilla")
|
|
{
|
|
data = ::GetResource ( 'TEXT', ABOUT_MOZILLA_TEXT );
|
|
*content_type_ret = TEXT_MDL;
|
|
}
|
|
else if (dataName == "hype")
|
|
{
|
|
data = ::GetResource ( 'Tang', ABOUT_HYPE_TANG );
|
|
*content_type_ret = AUDIO_BASIC;
|
|
}
|
|
else if ( dataName == "license" )
|
|
{
|
|
data = ::GetResource ('TEXT', ABOUT_LICENSE);
|
|
*content_type_ret = TEXT_PLAIN;
|
|
}
|
|
else if ( dataName == "custom" ) // optional resource added by EKit
|
|
{
|
|
data = ::GetResource ( 'TEXT', ABOUT_CUSTOM_TEXT );
|
|
*content_type_ret = TEXT_PLAIN;
|
|
}
|
|
#ifdef EDITOR
|
|
else if ( dataName == "editfilenew" )
|
|
{
|
|
data = ::GetResource ( 'TEXT', ABOUT_NEW_DOCUMENT );
|
|
*content_type_ret = TEXT_HTML;
|
|
}
|
|
#endif
|
|
else if ( dataName == "flamer" )
|
|
{
|
|
data = ::GetResource ('Tang', ABOUT_MOZILLA_FLAME);
|
|
*content_type_ret = IMAGE_GIF;
|
|
}
|
|
else
|
|
{
|
|
data = ::GetResource ('TEXT', ABOUT_BLANK_TEXT);
|
|
*content_type_ret = TEXT_MDL;
|
|
}
|
|
|
|
// prepare the arguments and return
|
|
if ( data )
|
|
{
|
|
UInt32 dataSize;
|
|
|
|
::DetachResource( data );
|
|
::HNoPurge( data );
|
|
::MoveHHi( data );
|
|
|
|
dataSize = GetHandleSize(data);
|
|
|
|
if ( doSprintf )
|
|
{
|
|
// Security stuff ( 3 strings -> 1 )
|
|
char* s0 = (char *)GetCString(SECURITY_LEVEL_RESID );
|
|
char* s1 = SECNAV_SecurityVersion( PR_TRUE );
|
|
char* s2 = SECNAV_SSLCapabilities();
|
|
ThrowIfNil_(s0);
|
|
ThrowIfNil_(s1);
|
|
ThrowIfNil_(s2);
|
|
char * secStr = PR_smprintf( s0, s1, s2 );
|
|
ThrowIfNil_(secStr);
|
|
|
|
// Version
|
|
CStr255 vers;
|
|
::GetIndString( vers, ID_STRINGS, APPVERSION_STRING_INDEX );
|
|
|
|
|
|
// Assure that data terminates with nul by appending the NULL string
|
|
{
|
|
dataSize += 1;
|
|
SetHandleSize( data, dataSize);
|
|
OSErr err = MemError();
|
|
ThrowIfOSErr_(err);
|
|
(*data)[dataSize-1] = '\0';
|
|
}
|
|
|
|
// Create the final string
|
|
::HLock(data);
|
|
char * finalStr = PR_smprintf((char*)*data, (char*)vers, (char*)vers, (char*)secStr);
|
|
::HUnlock(data);
|
|
|
|
XP_FREE( secStr );
|
|
ThrowIfNil_(finalStr);
|
|
|
|
// Make handle out of final string
|
|
|
|
dataSize = strlen(finalStr) + 1;
|
|
Handle finalHandle = ::NewHandle( dataSize );
|
|
ThrowIfNil_(finalHandle);
|
|
::BlockMoveData( finalStr, *finalHandle, dataSize );
|
|
XP_FREE( finalStr );
|
|
// Exchange
|
|
::DisposeHandle(data);
|
|
data = finalHandle;
|
|
}
|
|
|
|
*data_ret = *data;
|
|
*length_ret = dataSize;
|
|
}
|
|
else
|
|
{
|
|
XP_ASSERT(0);
|
|
*data_ret = NULL;
|
|
*length_ret = 0;
|
|
*content_type_ret = NULL;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
Assert_(false);
|
|
if (data != NULL)
|
|
{
|
|
::DisposeHandle(data);
|
|
data = NULL;
|
|
}
|
|
|
|
if (ss != NULL)
|
|
XP_FREE(ss);
|
|
|
|
*data_ret = NULL;
|
|
*length_ret = 0;
|
|
*content_type_ret = NULL;
|
|
}
|
|
|
|
if (data)
|
|
::HLock(data);
|
|
|
|
return data;
|
|
}
|
|
|
|
void FE_FreeAboutData( void* data, const char* /*which*/ )
|
|
{
|
|
if ( !data )
|
|
return;
|
|
Handle h = (Handle)data;
|
|
DisposeHandle( h );
|
|
}
|
|
|
|
|
|
// ===========================================================================
|
|
// ¥ Main Program
|
|
// ===========================================================================
|
|
|
|
XP_BEGIN_PROTOS
|
|
OSErr InitLibraryManager(size_t poolsize, int zoneType, int memType);
|
|
void CleanupLibraryManager(void);
|
|
XP_END_PROTOS
|
|
|
|
extern void Memory_DoneWithMemory();
|
|
extern UInt8 MemoryCacheFlusher(size_t size);
|
|
extern void PreAllocationHook(void);
|
|
|
|
const Size cSystemHeapFudgeFactor = 96 * 1024;
|
|
|
|
void main( void )
|
|
{
|
|
SetDebugThrow_(debugAction_Nothing);
|
|
#ifdef DEBUG
|
|
//SetDebugSignal_(debugAction_SourceDebugger); // SysBreak broken in MetroNub 1.3.2
|
|
SetDebugSignal_(debugAction_LowLevelDebugger);
|
|
#else
|
|
SetDebugSignal_(debugAction_Nothing);
|
|
#endif
|
|
CFrontApp* app = NULL;
|
|
|
|
// System Heap check hack
|
|
Handle sysHandle = ::NewHandleSys(cSystemHeapFudgeFactor);
|
|
if (sysHandle)
|
|
::DisposeHandle(sysHandle);
|
|
Size maxBlockSize = ::FreeMemSys();
|
|
if (maxBlockSize < cSystemHeapFudgeFactor)
|
|
::ExitToShell();
|
|
|
|
// Initialize the tracing package if we're debugging
|
|
#ifdef DEBUG
|
|
XP_TraceInit();
|
|
#endif
|
|
|
|
// pkc -- instantiate main thread object. As side effect, NSPR will create new
|
|
// subheap if this is the first allocation call, ie, if no static initializers
|
|
// did an allocation.
|
|
|
|
//-----------------------------------
|
|
// NOTE: SetApplLimit and MaxApplZone are called from NSPR!
|
|
// in MacintoshInitializeMemory()
|
|
//-----------------------------------
|
|
|
|
// ¥Êinitialize QuickDraw
|
|
UQDGlobals::InitializeToolbox( &qd );
|
|
|
|
// Preference library needs to be initialized at this point because
|
|
// the msglib thread constructor is making a prefapi call
|
|
PREF_Init(NULL);
|
|
|
|
#if __MC68K__
|
|
{
|
|
// Bug #58086: this hack locks the "Enable Java" preference `off' and
|
|
// must be removed when Java works for 68K.
|
|
static const char* inline_javascript_text ="lockPref(\"security.enable_java\", false)";
|
|
PREF_EvaluateJSBuffer(inline_javascript_text, strlen(inline_javascript_text));
|
|
}
|
|
#else
|
|
|
|
// ¥ double check to make sure we have Java installed
|
|
DisableJavaIfNotAvailable();
|
|
|
|
#endif
|
|
|
|
// NSPR/MOCHA Initialization
|
|
#ifndef NSPR20
|
|
PR_Init("Navigator", 0,0,0);
|
|
#endif
|
|
mozilla_thread = PR_CurrentThread();
|
|
#ifdef NSPR20
|
|
PR_SetThreadGCAble();
|
|
#endif
|
|
|
|
// ¥ initialize the memory manager
|
|
// it's important that this is done VERY early
|
|
Memory_InitializeMemory();
|
|
|
|
// ¥Êif we're not on a PowerPC, check that we're on an '020 or later
|
|
// and have System 7 installed
|
|
ConfirmWeWillRun();
|
|
RNG_RNGInit(); // This needs to be called before the main loop
|
|
ProcessSerialNumber psn;
|
|
if (NetscapeIsRunning(psn))
|
|
{
|
|
ErrorManager::PlainAlert(NO_TWO_NETSCAPES_RESID);
|
|
SetFrontProcess(&psn);
|
|
}
|
|
else
|
|
{
|
|
#if defined(PROFILE) || defined (PROFILE_LOCALLY)
|
|
#ifndef DONT_DO_MOZILLA_PROFILE
|
|
StartProfiling();
|
|
#endif
|
|
#endif
|
|
|
|
// NET_ToggleTrace();
|
|
|
|
app = new CFrontApp;
|
|
#if defined(QAP_BUILD)
|
|
QAP_AssistHook (kQAPAppToForeground, 0, NULL, 0, 0);
|
|
#endif
|
|
app->Run();
|
|
|
|
#if defined(QAP_BUILD)
|
|
QAP_AssistHook (kQAPAppToBackground, 0, NULL, 0, 0);
|
|
#endif
|
|
|
|
delete app;
|
|
#if defined(PROFILE) || defined (PROFILE_LOCALLY)
|
|
#ifndef DONT_DO_MOZILLA_PROFILE
|
|
StopProfiling();
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
Memory_DoneWithMemory();
|
|
|
|
// do this at the very end, god knows who's fetching prefs during cleanup
|
|
PREF_Cleanup();
|
|
}
|
|
|
|
static void InitDebugging()
|
|
{
|
|
// ¥Êdebugging Setup
|
|
}
|
|
|
|
static void ConfirmWeWillRun()
|
|
{
|
|
#ifndef powerc
|
|
Assert68020();
|
|
AssertSystem7();
|
|
#endif
|
|
AssertRequiredGuts();
|
|
}
|
|
|
|
//-----------------------------------
|
|
static Boolean NetscapeIsRunning(ProcessSerialNumber& psn)
|
|
// True if other versions of Netscape are running
|
|
//-----------------------------------
|
|
{
|
|
OSErr err;
|
|
ProcessInfoRec info;
|
|
ProcessSerialNumber myPsn;
|
|
::GetCurrentProcess(&myPsn);
|
|
|
|
psn.highLongOfPSN = 0;
|
|
psn.lowLongOfPSN = kNoProcess;
|
|
do
|
|
{
|
|
err = GetNextProcess(&psn);
|
|
if( err == noErr )
|
|
{
|
|
|
|
info.processInfoLength = sizeof(ProcessInfoRec);
|
|
info.processName = NULL;
|
|
info.processAppSpec = NULL;
|
|
|
|
err= GetProcessInformation(&psn, &info);
|
|
}
|
|
if ((err == noErr) &&
|
|
((psn.highLongOfPSN != myPsn.highLongOfPSN) || (psn.lowLongOfPSN != myPsn.lowLongOfPSN)) &&
|
|
(info.processSignature == emSignature || info.processSignature == 'MOSM'))
|
|
return TRUE;
|
|
} while (err == noErr);
|
|
return FALSE;
|
|
}
|
|
|
|
//-----------------------------------
|
|
Boolean CFrontApp::AttemptQuitSelf(long /*inSaveOption*/)
|
|
//-----------------------------------
|
|
{
|
|
#ifdef MOZ_OFFLINE
|
|
XP_Bool value;
|
|
PREF_GetBoolPref("offline.prompt_synch_on_exit", &value);
|
|
if (value)
|
|
{
|
|
// Put up dialog
|
|
StDialogHandler aHandler(20004, NULL);
|
|
LWindow* dialog = aHandler.GetDialog();
|
|
|
|
// Get the window title to use later in the progress dialog.
|
|
Str255 windowTitle;
|
|
dialog->GetDescriptor(windowTitle);
|
|
|
|
// Run the dialog
|
|
MessageT message;
|
|
do
|
|
{
|
|
message = aHandler.DoDialog();
|
|
|
|
} while ((message != 'Yes ') && (message != 'No ') && (message != msg_Cancel));
|
|
|
|
// Use the result
|
|
if (message == 'Yes ')
|
|
UOffline::ObeySynchronizeCommand(UOffline::syncModal);
|
|
|
|
if (message == msg_Cancel)
|
|
return false;
|
|
}
|
|
#endif // MOZ_OFFLINE
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CFrontApp::DoQuit(
|
|
Int32 inSaveOption)
|
|
//-----------------------------------
|
|
{
|
|
LDocApplication::DoQuit(inSaveOption);
|
|
|
|
if (mState == programState_Quitting)
|
|
CDeferredTaskManager::DoQuit(inSaveOption);
|
|
// if (mState == programState_Quitting)
|
|
// LTSMSupport::DoQuit(inSaveOption);
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CFrontApp::DispatchEvent(
|
|
const EventRecord& inMacEvent)
|
|
// From IM-Text 7-22
|
|
//-----------------------------------
|
|
{
|
|
|
|
try
|
|
{
|
|
try
|
|
{
|
|
if(! LTSMSupport::TSMEvent(inMacEvent))
|
|
LDocApplication::DispatchEvent(inMacEvent);
|
|
}
|
|
catch (int err) // some people do throw-em! Also "throw memFullErr" will come here.
|
|
{
|
|
throw (OSErr)err;
|
|
}
|
|
}
|
|
// Here we catch anything thrown from anywhere. (OSErr and ExceptionCode).
|
|
// STR# 7098 is reserved for just this purpose. See ns/cmd/macfe/restext/macfe.r
|
|
// These alerts all use ALRT_ErrorOccurred. See ns/cmd/macfe/rsrc/MacDialogs.rsrc.
|
|
// The value of ALRT_ErrorOccurred is in reserr.h
|
|
// The alert says
|
|
// "Your last command could not be completed because <reason>"
|
|
// "(Error code <nnn>)"
|
|
catch (OSErr err)
|
|
{
|
|
DisplayErrorDialog ( err );
|
|
}
|
|
catch (ExceptionCode err)
|
|
{
|
|
DisplayExceptionCodeDialog ( err );
|
|
}
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
// ¥ AdjustCursor
|
|
// From IM-Text 7-22
|
|
// ---------------------------------------------------------------------------
|
|
void CFrontApp::AdjustCursor( const EventRecord& inMacEvent )
|
|
{
|
|
#if defined (JAVA)
|
|
if ( UsingCustomAWTFrameCursor() )
|
|
return;
|
|
#endif /* defined (JAVA) */
|
|
// Find out where the mouse is
|
|
WindowPtr macWindowP;
|
|
Point globalMouse = inMacEvent.where;
|
|
Int16 thePart = ::FindWindow( globalMouse, &macWindowP );
|
|
|
|
Boolean useArrow = TRUE; // Assume cursor will be the Arrow
|
|
LWindow* theWindow = NULL;
|
|
|
|
if ( macWindowP )
|
|
{ // Mouse is inside a Window
|
|
theWindow = LWindow::FetchWindowObject( macWindowP );
|
|
}
|
|
if (( theWindow ) &&
|
|
(theWindow->IsActive() || theWindow->HasAttribute(windAttr_GetSelectClick)) && // adjust inactive window if one click away - mjc
|
|
theWindow->IsEnabled() )
|
|
{
|
|
// Mouse is inside an active and enabled
|
|
// PowerPlant Window. Let the Window
|
|
// adjust the cursor shape.
|
|
|
|
// Get mouse location in Port coords
|
|
Point portMouse = globalMouse;
|
|
theWindow->GlobalToPortPoint( portMouse );
|
|
|
|
theWindow->AdjustCursor( portMouse, inMacEvent );
|
|
useArrow = FALSE;
|
|
}
|
|
if ( useArrow )
|
|
{
|
|
// Window didn't set the cursor
|
|
// Default cursor is the arrow
|
|
::SetCursor( &UQDGlobals::GetQDGlobals()->arrow );
|
|
}
|
|
|
|
//
|
|
// Rather than trying to calculate an accurate mouse region,
|
|
// we define a region that contains just the one pixel where
|
|
// the mouse is located. This is quick, and handles the common
|
|
// case where this application is in the foreground but the user
|
|
// isn't doing anything. However, any mouse movement will generate
|
|
// a mouse-moved event.
|
|
//
|
|
::SetRectRgn( mMouseRgnH, globalMouse.h, globalMouse.v,
|
|
globalMouse.h + 1, globalMouse.v + 1 );
|
|
}
|
|
|
|
|
|
|
|
void
|
|
CFrontApp::EventSuspend (const EventRecord &inMacEvent)
|
|
{
|
|
CSuspenderResumer::Suspend();
|
|
#ifdef MOZ_MAIL_NEWS
|
|
CCheckMailContext::SuspendResume(); // Stop all current notification of mail
|
|
#endif // MOZ_MAIL_NEWS
|
|
CPluginView::BroadcastPluginEvent(inMacEvent); // Tell plug-ins about the suspend
|
|
LDocApplication::EventSuspend(inMacEvent); // Do the suspend
|
|
|
|
#if defined(QAP_BUILD)
|
|
QAP_AssistHook (kQAPAppToBackground, 0, NULL, 0, 0);
|
|
#endif
|
|
|
|
#ifdef DAVIDM_SPEED2
|
|
SetSleepTime(4); // be more friendly in the background
|
|
#endif
|
|
|
|
}
|
|
|
|
void
|
|
CFrontApp::EventResume(const EventRecord &inMacEvent)
|
|
{
|
|
CSuspenderResumer::Resume();
|
|
LDocApplication::EventResume(inMacEvent); // Do the resume
|
|
CPluginView::BroadcastPluginEvent(inMacEvent); // Tell plug-ins about the resume
|
|
#ifdef MOZ_MAIL_NEWS
|
|
CCheckMailContext::SuspendResume(); // Reset mail notification
|
|
#endif // MOZ_MAIL_NEWS
|
|
CInternetConfigInterface::ResumeEvent(); // check is InternetConfig changed
|
|
|
|
#if defined(QAP_BUILD)
|
|
QAP_AssistHook (kQAPAppToForeground, 0, NULL, 0, 0);
|
|
#endif
|
|
|
|
#ifdef DAVIDM_SPEED2
|
|
SetSleepTime(1); // let's go faster
|
|
#endif
|
|
}
|
|
|
|
|
|
void
|
|
CFrontApp::EventKeyUp(const EventRecord &inMacEvent)
|
|
{
|
|
//
|
|
// Pass key ups down to the target if itÕs a plug-in. The static variable
|
|
// sPluginTarget is maintained by CPluginViews when they become or are no
|
|
// longer the target. (We know calling ProcessKeyPress for a key up is OK
|
|
// because CPluginView overrides it.)
|
|
//
|
|
CPluginView* pluginTarget = CPluginView::sPluginTarget;
|
|
if (pluginTarget != NULL && pluginTarget == sTarget)
|
|
pluginTarget->ProcessKeyPress(inMacEvent);
|
|
else
|
|
{
|
|
/* if it's a CKeyUpReceiver, send the key up. We used to send keyups to
|
|
* targets if a browser view was on duty, which had two disadvantages: it required
|
|
* any potential targets in a browser view to handle a key up, and sometimes
|
|
* the commander chain would be incorrect so key ups were sent to a target in a
|
|
* view that was not on duty.
|
|
*/
|
|
if (dynamic_cast<CKeyUpReceiver *>(sTarget))
|
|
sTarget->ProcessKeyPress(inMacEvent);
|
|
/*
|
|
// Pass key ups down to the target if it has a super commander which is
|
|
// a browser view. Key up events must be sent to mocha. 1997-02-24 mjc
|
|
if (CBrowserView::sOnDutyBrowserView != NULL)
|
|
sTarget->ProcessKeyPress(inMacEvent);
|
|
*/
|
|
}
|
|
}
|
|
|
|
|
|
// A C interface to ProcessNextEvent, which needs to be called when waiting for
|
|
// the .jsc file to load at startup
|
|
extern "C" {
|
|
void FEU_StayingAlive();
|
|
}
|
|
|
|
|
|
void FEU_StayingAlive()
|
|
{
|
|
CFrontApp::GetApplication()->ProcessNextEvent();
|
|
}
|
|
|
|
void
|
|
CFrontApp::ProcessNextEvent()
|
|
{
|
|
#ifdef PROFILE
|
|
#ifdef PROFILE_ON_CAPSLOCK
|
|
if (IsThisKeyDown(0x39)) // caps lock
|
|
ProfileStart();
|
|
else
|
|
ProfileStop();
|
|
#endif // PROFILE_ON_CAPSLOCK
|
|
#endif // PROFILE
|
|
|
|
#ifdef DAVIDM_SPEED2
|
|
static UInt32 sNextWNETicks = 0;
|
|
const UInt32 kWNETicksInterval = 4;
|
|
#endif
|
|
|
|
try
|
|
{
|
|
// Handle all pending NSPR events
|
|
PR_ProcessPendingEvents(mozilla_event_queue);
|
|
}
|
|
catch (OSErr err)
|
|
{
|
|
DisplayErrorDialog ( err );
|
|
}
|
|
catch (ExceptionCode err)
|
|
{
|
|
DisplayExceptionCodeDialog ( err );
|
|
}
|
|
|
|
// The block surrounded by *** ... from LApplication::ProcessNextEvent() ***
|
|
// is identical to LApplication::ProcessNextEvent with one exception:
|
|
// the EventRecord is declared static in order to persist across calls
|
|
// to ProcessNextEvent to prevent dangling references to the event
|
|
// recorded by CApplicationEventAttachment (read the usage notes for
|
|
// CApplicationEventAttachment).
|
|
|
|
// *** Begin block from LApplication::ProcessNextEvent() ***
|
|
|
|
static EventRecord macEvent;
|
|
Boolean haveUserEvent = true; // so we call WNE every time in the background
|
|
|
|
// When on duty (application is in the foreground), adjust the
|
|
// cursor shape before waiting for the next event. Except for the
|
|
// very first time, this is the same as adjusting the cursor
|
|
// after every event.
|
|
|
|
if (IsOnDuty()) {
|
|
|
|
// Plug-ins and Java need key up events, which are masked by default
|
|
// (the event mask lomem is set to everyEvent - keyUp). To ensure
|
|
// that itÕs always set to mask out nothing, reset it here every time
|
|
// before we call WaitNextEvent.
|
|
//
|
|
|
|
SetEventMask(everyEvent);
|
|
|
|
// Calling OSEventAvail with a zero event mask will always
|
|
// pass back a null event. However, it fills the EventRecord
|
|
// with the information we need to set the cursor shape--
|
|
// the mouse location in global coordinates and the state
|
|
// of the modifier keys.
|
|
|
|
haveUserEvent = ::OSEventAvail(everyEvent, &macEvent);
|
|
AdjustCursor(macEvent);
|
|
}
|
|
|
|
#ifdef DAVIDM_SPEED2
|
|
#ifndef NSPR20
|
|
CSelectObject socketToCallWith;
|
|
Boolean doWNE = haveUserEvent || ::LMGetTicks() > sNextWNETicks || ( gNetDriver && !gNetDriver->CanCallNetlib(socketToCallWith) );
|
|
#else
|
|
Boolean doWNE = haveUserEvent || ::LMGetTicks() > sNextWNETicks || NET_PollSockets();
|
|
#endif // NSPR_20
|
|
SetUpdateCommandStatus(false);
|
|
|
|
if ( doWNE )
|
|
{
|
|
#endif // DAVIDM_SPEED2
|
|
|
|
// Retrieve the next event. Context switch could happen here.
|
|
|
|
#ifdef PROFILE
|
|
#ifndef PROFILE_WAITNEXTEVENT
|
|
ProfileSuspend();
|
|
#endif // PROFILE_WAITNEXTEVENT
|
|
#endif // PROFILE
|
|
|
|
Boolean gotEvent = ::WaitNextEvent(everyEvent, &macEvent, mSleepTime, mMouseRgnH);
|
|
|
|
#ifdef PROFILE
|
|
#ifndef PROFILE_WAITNEXTEVENT
|
|
ProfileResume();
|
|
#endif // PROFILE_WAITNEXTEVENT
|
|
#endif // PROFILE
|
|
|
|
// Let Attachments process the event. Continue with normal
|
|
// event dispatching unless suppressed by an Attachment.
|
|
|
|
if (LAttachable::ExecuteAttachments(msg_Event, &macEvent)) {
|
|
if (gotEvent) {
|
|
DispatchEvent(macEvent);
|
|
} else {
|
|
UseIdleTime(macEvent);
|
|
}
|
|
}
|
|
|
|
#ifdef DAVIDM_SPEED2
|
|
sNextWNETicks = ::LMGetTicks() + kWNETicksInterval;
|
|
}
|
|
#endif // DAVIDM_SPEED2
|
|
|
|
LPeriodical::DevoteTimeToRepeaters(macEvent);
|
|
|
|
// Update status of menu items
|
|
if (IsOnDuty() && GetUpdateCommandStatus()) {
|
|
UpdateMenus();
|
|
}
|
|
|
|
// *** End block from LApplication::ProcessNextEvent() ***
|
|
}
|
|
|
|
|
|
void CFrontApp::DoOpenURLDialog(void)
|
|
{
|
|
StBlockingDialogHandler theHandler(liLoadItemWind, this);
|
|
LWindow* theDialog = theHandler.GetDialog();
|
|
LEditField* theEdit = (LEditField*)theDialog->FindPaneByID('edit');
|
|
Assert_(theEdit != NULL);
|
|
theDialog->SetLatentSub(theEdit);
|
|
theDialog->Show();
|
|
|
|
MessageT theMessage = msg_Nothing;
|
|
while ((theMessage != msg_Cancel) && (theMessage != msg_OK))
|
|
theMessage = theHandler.DoDialog();
|
|
|
|
if (theMessage == msg_OK)
|
|
{
|
|
cstring curl;
|
|
CStr255 purl;
|
|
theEdit->GetDescriptor(purl);
|
|
CleanUpLocationString (purl);
|
|
curl = (unsigned char*)purl;
|
|
DoGetURL(curl);
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef EDITOR
|
|
void CFrontApp::DoOpenURLDialogInEditor(void)
|
|
{
|
|
StBlockingDialogHandler theHandler(liLoadItemWind, this);
|
|
LWindow* theDialog = theHandler.GetDialog();
|
|
LEditField* theEdit = (LEditField*)theDialog->FindPaneByID('edit');
|
|
Assert_(theEdit != NULL);
|
|
theDialog->SetLatentSub(theEdit);
|
|
theDialog->Show();
|
|
|
|
MessageT theMessage = msg_Nothing;
|
|
while ((theMessage != msg_Cancel) && (theMessage != msg_OK))
|
|
theMessage = theHandler.DoDialog();
|
|
|
|
if (theMessage == msg_OK)
|
|
{
|
|
cstring curl;
|
|
CStr255 purl;
|
|
// we really should try to do better parsing here
|
|
theEdit->GetDescriptor( purl );
|
|
CleanUpLocationString( purl );
|
|
curl = (unsigned char*)purl;
|
|
|
|
URL_Struct* theURL = NET_CreateURLStruct( curl, NET_DONT_RELOAD );
|
|
if ( theURL )
|
|
CEditorWindow::MakeEditWindow( NULL, theURL );
|
|
}
|
|
}
|
|
#endif // EDITOR
|
|
|
|
|
|
void CFrontApp::ShowSplashScreen()
|
|
{
|
|
// Register the splash screen first so that we can show it.
|
|
RegisterClass_(CSplashScreen);
|
|
RegisterClass_(CResPicture);
|
|
|
|
mSplashScreen = (CSplashScreen*)LWindow::CreateWindow(2891, this);
|
|
mSplashScreen->Show();
|
|
mSplashScreen->UpdatePort();
|
|
}
|
|
|
|
void CFrontApp::DestroySplashScreen()
|
|
{
|
|
delete mSplashScreen;
|
|
mSplashScreen = NULL;
|
|
}
|
|
|
|
void CFrontApp::SplashProgress(CStr255 inMessage)
|
|
{
|
|
if (sApplication->mSplashScreen != NULL)
|
|
sApplication->mSplashScreen->SetDescriptor(inMessage);
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CFrontApp::ListenToMessage(MessageT inMessage, void * ioParam)
|
|
//-----------------------------------
|
|
{
|
|
switch (inMessage)
|
|
{
|
|
#ifdef MOZ_MAIL_NEWS
|
|
case cmd_GetNewMail:
|
|
case cmd_NewsGroups:
|
|
case cmd_MailNewsFolderWindow:
|
|
#endif // MOZ_MAIL_NEWS
|
|
#ifdef EDITOR
|
|
case cmd_NewWindowEditorIFF:
|
|
// case cmd_NewMailMessage:
|
|
#endif // EDITOR
|
|
#ifdef MOZ_MAIL_NEWS
|
|
case cmd_ToggleOffline:
|
|
#endif // MOZ_MAIL_NEWS
|
|
case cmd_BrowserWindow:
|
|
ObeyCommand(inMessage);
|
|
break;
|
|
case msg_GrowZone:
|
|
MemoryIsLow();
|
|
// 1998.01.12 pchen -- replicate fix for bug #85275
|
|
// We don't know how much memory was freed, so just set bytes freed to 0
|
|
*((Int32 *)ioParam) = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CFrontApp::LaunchExternalApp(OSType inAppSig, ResIDT inAppNameStringResourceID)
|
|
{
|
|
Assert_(inAppNameStringResourceID);
|
|
|
|
FSSpec appSpec;
|
|
OSErr err = CFileMgr::FindApplication(inAppSig, appSpec);
|
|
CStr255 theAppName(::GetCString(inAppNameStringResourceID));
|
|
CStr255 theMessage;
|
|
|
|
if (err == noErr)
|
|
{
|
|
ProcessSerialNumber psn;
|
|
err = UProcessUtils::LaunchApplication(
|
|
appSpec, launchContinue + launchNoFileFlags, psn);
|
|
}
|
|
|
|
switch (err)
|
|
{
|
|
case noErr:
|
|
break;
|
|
|
|
case memFullErr:
|
|
case memFragErr:
|
|
theMessage = ::GetCString(MEMORY_ERROR_LAUNCH);
|
|
::StringParamText(theMessage, theAppName);
|
|
ErrorManager::PlainAlert(theMessage);
|
|
break;
|
|
|
|
case fnfErr:
|
|
theMessage = ::GetCString(FNF_ERROR_LAUNCH);
|
|
::StringParamText(theMessage, theAppName);
|
|
ErrorManager::PlainAlert(theMessage);
|
|
break;
|
|
|
|
default:
|
|
theMessage = ::GetCString(MISC_ERROR_LAUNCH);
|
|
::StringParamText(theMessage, theAppName);
|
|
ErrorManager::PlainAlert(theMessage);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Tries to find local file 3270/HE3270EN.HTM
|
|
Boolean CFrontApp::Find3270Applet(FSSpec& tn3270File)
|
|
{
|
|
Boolean found = false;
|
|
FSSpec appFolder = CPrefs::GetFilePrototype( CPrefs::NetscapeFolder );
|
|
|
|
CStr255 folderName;
|
|
::GetIndString( folderName, 300, ibm3270Folder );
|
|
|
|
if ( CFileMgr::FindWFolderInFolder(appFolder.vRefNum, appFolder.parID,
|
|
folderName, &tn3270File.vRefNum, &tn3270File.parID) == noErr )
|
|
{
|
|
::GetIndString( tn3270File.name, 300, ibm3270File );
|
|
|
|
found = CFileMgr::FileExists(tn3270File);
|
|
}
|
|
return found;
|
|
}
|
|
|
|
void CFrontApp::Launch3270Applet()
|
|
{
|
|
Boolean ok = false;
|
|
FSSpec tn3270File;
|
|
if ( Find3270Applet(tn3270File) )
|
|
{
|
|
char* url = CFileMgr::GetURLFromFileSpec(tn3270File);
|
|
if (url) {
|
|
// Opens the URL in a new window (copied from DoGetURL)
|
|
// !! winfe opens a window with no toolbars, if we care.
|
|
URL_Struct* theURL = NET_CreateURLStruct(url, NET_DONT_RELOAD);
|
|
if (FE_MakeNewWindow(NULL, theURL, NULL, NULL) != NULL)
|
|
ok = true;
|
|
free(url);
|
|
}
|
|
}
|
|
if (!ok) {
|
|
ErrorManager::PlainAlert(ERROR_LAUNCH_IBM3270);
|
|
}
|
|
}
|
|
|
|
FSSpec CFrontApp::CreateAccountSetupSpec()
|
|
{
|
|
FSSpec asw;
|
|
|
|
asw = CPrefs::GetFilePrototype( CPrefs::NetscapeFolder );
|
|
::GetIndString( asw.name, 300, aswName );
|
|
return asw;
|
|
}
|
|
|
|
Boolean CFrontApp::LaunchAccountSetup()
|
|
{
|
|
FSSpec tmp = CreateAccountSetupSpec();
|
|
|
|
LFile aswFile( tmp );
|
|
Handle alias;
|
|
OSErr err;
|
|
FSSpec startAswFile;
|
|
Boolean wasChanged;
|
|
|
|
#ifdef DEBUG
|
|
try
|
|
{
|
|
#endif
|
|
|
|
aswFile.OpenResourceFork( fsRdPerm );
|
|
|
|
#ifdef DEBUG
|
|
}
|
|
catch ( ... )
|
|
{
|
|
StandardFileReply reply;
|
|
AliasHandle alias;
|
|
SFTypeList types;
|
|
|
|
UDesktop::Deactivate();
|
|
::StandardGetFile( NULL, -1, types, &reply );
|
|
UDesktop::Activate();
|
|
|
|
if ( reply.sfGood )
|
|
{
|
|
LFile startFile( reply.sfFile );
|
|
|
|
aswFile.CreateNewFile( emSignature, 'ASWl', smSystemScript );
|
|
aswFile.OpenResourceFork( fsWrPerm );
|
|
alias = startFile.MakeAlias();
|
|
if ( alias )
|
|
AddResource( (Handle)alias, 'alis', 1, reply.sfFile.name );
|
|
aswFile.CloseResourceFork();
|
|
aswFile.OpenResourceFork( fsRdPerm );
|
|
}
|
|
}
|
|
|
|
#endif DEBUG
|
|
|
|
alias = ::Get1Resource( 'alis', 1 );
|
|
if ( !alias )
|
|
return FALSE;
|
|
|
|
err = ::ResolveAlias( NULL, (AliasHandle)alias, &startAswFile, &wasChanged );
|
|
if ( err == noErr )
|
|
{
|
|
CFrontApp::GetApplication()->SendAEOpenDoc( startAswFile );
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void launchNetcasterCallback(void* closure);
|
|
|
|
static void launchNetcasterCallback(void* /*closure*/)
|
|
{
|
|
FE_RunNetcaster(NULL);
|
|
}
|
|
|
|
// Launch Netcaster on a timeout to avoid interfering with other components because
|
|
// it is slow to start up.
|
|
void CFrontApp::LaunchNetcaster()
|
|
{
|
|
FE_SetTimeout(launchNetcasterCallback, NULL, 0);
|
|
}
|
|
|
|
// We keep track of the Netcaster context in the app so we can assure ourselves
|
|
// that only one Netcaster context will be open at any given time. These calls
|
|
// are used by FE_RunNetcaster to either launch Netcaster (if the netcaster context
|
|
// is NULL) or to activate its window (if not). The alternative would have been
|
|
// to use named contexts; the disadvantage is that the Netcaster window could be
|
|
// spoofed, and that we would have a performance hit whenever the Netcaster object
|
|
// were referenced (such as from JS). - EA
|
|
|
|
//-----------------------------------
|
|
MWContext *CFrontApp::GetNetcasterContext()
|
|
//-----------------------------------
|
|
{
|
|
return mNetcasterContext;
|
|
}
|
|
|
|
//-----------------------------------
|
|
void CFrontApp::SetNetcasterContext(MWContext *context)
|
|
//-----------------------------------
|
|
{
|
|
mNetcasterContext = context;
|
|
}
|
|
|
|
// 97-08-23 pchen -- This method should be called when we're "low on memory."
|
|
// For now, we just call LJ_ShutdownJava().
|
|
//-----------------------------------
|
|
void CFrontApp::MemoryIsLow()
|
|
//-----------------------------------
|
|
{
|
|
#if defined (JAVA)
|
|
// Call LJ_ShutdownJava() if Java is running
|
|
if (LJ_GetJavaStatus() == LJJavaStatus_Running)
|
|
LJ_ShutdownJava();
|
|
#endif /* defined (JAVA) */
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
//======================================
|
|
// class CSplashScreen
|
|
//======================================
|
|
|
|
extern Boolean pref_FindAutoAdminLib(FSSpec& spec);
|
|
|
|
CSplashScreen::CSplashScreen(LStream* inStream)
|
|
: LWindow(inStream)
|
|
{
|
|
mStatusCaption = NULL;
|
|
mPictureResourceFile = NULL;
|
|
}
|
|
|
|
CSplashScreen::~CSplashScreen()
|
|
{
|
|
ResIDT thePicID = mBackPicture->GetPictureID();
|
|
|
|
// this returns the picture that has already been loaded by the picture pane
|
|
PicHandle thePicHandle = ::GetPicture(thePicID);
|
|
if (thePicHandle != NULL)
|
|
::ReleaseResource((Handle)thePicHandle);
|
|
|
|
if (mPictureResourceFile) {
|
|
mPictureResourceFile->CloseResourceFork();
|
|
delete mPictureResourceFile;
|
|
}
|
|
}
|
|
|
|
void CSplashScreen::SetDescriptor(ConstStringPtr inDescriptor)
|
|
{
|
|
mStatusCaption->SetDescriptor(inDescriptor);
|
|
// we're relying on the fact that the splash window has erase on
|
|
// update set so that the old caption gets erased in the window's
|
|
// background color (which we're assuming to be black)
|
|
mStatusCaption->UpdatePort();
|
|
}
|
|
|
|
void CSplashScreen::FinishCreateSelf(void)
|
|
{
|
|
LWindow::FinishCreateSelf();
|
|
|
|
mStatusCaption = (LCaption*)FindPaneByID(1);
|
|
Assert_(mStatusCaption != NULL);
|
|
|
|
mBackPicture = (CResPicture*)FindPaneByID(2);
|
|
Assert_(mBackPicture != NULL);
|
|
|
|
// choose the b/w or color splash screen
|
|
ResIDT thePicID = (GetDepth(GetDeepestDevice()) == 1) ? 129 : 128;
|
|
|
|
// If AutoAdminLib is installed, then load the Communicator Pro
|
|
// splash screen from the library's resource fork.
|
|
// Otherwise, picture comes from app resource.
|
|
try {
|
|
FSSpec autoAdminLib;
|
|
if ( pref_FindAutoAdminLib(autoAdminLib) ) {
|
|
mPictureResourceFile = new LFile(autoAdminLib);
|
|
mPictureResourceFile->OpenResourceFork(fsRdPerm);
|
|
|
|
mBackPicture->SetResFileID( mPictureResourceFile->GetResourceForkRefNum() );
|
|
}
|
|
}
|
|
catch (...) {
|
|
}
|
|
|
|
mBackPicture->SetPictureID(thePicID);
|
|
}
|
|
|
|
|
|
//
|
|
// THIS IS HERE ONLY AS A PLACEHOLDER UNTIL I PUT THE NAV-SERVICES CODE INTO THE SOURCE TREE....
|
|
// DO NOT RELY ON THIS IMPLEMENTATION OR EVEN THAT THIS ROUTINE USES THE SF PACKAGE
|
|
//
|
|
Boolean SimpleOpenDlog ( short numTypes, const OSType typeList[], FSSpec* outFSSpec )
|
|
{
|
|
Boolean fileSelected = false;
|
|
StandardFileReply myReply;
|
|
if (CApplicationEventAttachment::CurrentEventHasModifiers(optionKey))
|
|
::StandardGetFile(NULL, numTypes, typeList, &myReply);
|
|
else
|
|
::StandardGetFile(NULL, -1, NULL, &myReply);
|
|
fileSelected = myReply.sfGood;
|
|
*outFSSpec = myReply.sfFile;
|
|
|
|
return fileSelected;
|
|
|
|
} // SimpleOpenDialog
|