eudora-mac/functions.c

1 line
53 KiB
C
Executable File

/* Copyright (c) 2017, Computer History Museum
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted (subject to
the limitations in the disclaimer below) provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Computer History Museum nor the names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. */
#include "functions.h"
#include "regcode_v2.h"
#define FILE_NUM 15
/* Copyright (c) 1990-1992 by the University of Illinois Board of Trustees */
#pragma segment Misc
Boolean CloseRemaining(WindowPtr theWindow);
short ReallyChangePassword(TransStream stream,UPtr user,UPtr host,UPtr old,UPtr new);
short SendPwCommand(TransStream stream,short cmd,UPtr arg);
short CheckResult(TransStream stream,UPtr buffer);
void PICTUpdate(MyWindowPtr win);
void PICTDidResize(MyWindowPtr win,Rect *oldContR);
void PICTRect(short id, Rect *r);
OSErr AddWSService(FSSpecPtr spec, PStr menuItem);
OSErr GetWSMenuItem(AEAddressDescPtr aead, PStr itemText);
OSErr GetAppProperty(AEAddressDescPtr aead, DescType prop, DescType wantType, AEDescPtr ad);
OSErr VerifySpeller(short item);
OSErr StartSpeller(short item,Boolean runningOnly);
OSErr Spell(short item,AEDescPtr objAD);
void JustArrow(Point mouse);
OSErr GetProperty(AEAddressDescPtr aead, AEDescPtr objAD, DescType propType, DescType wantType, AEDescPtr ad);
Boolean IsSigWindow(WindowPtr theWindow);
/**********************************************************************
* DoQuit - let's get outta here
**********************************************************************/
void DoQuit(Boolean changeUserState)
{
uLong never = 3600*GetRLong(NEVER_WARN);
Str31 hours;
uLong now = GMTDateTime();
Boolean remember = !EjectBuckaroo;
Done = EjectBuckaroo = False;
AmQuitting = True;
#ifdef THREADING_ON
// may want to have a warning preference?
if (GetNumBackgroundThreads())
switch (AlertStr(QUIT_THREAD_RUN_ALRT,Caution,nil))
{
case QTR_WAIT:
// JDB 12/8/98. Do some processing while waiting to quit. This allows
// OT/PPP to finish connecting, if the user picked a bad time to leave.
// JDB 17/8/04. Wait for all open IMAP mailboxes to finish up as well.
while (!IMAPDoQuit() || GetNumBackgroundThreads())
{
SetMyCursor(watchCursor);
MiniEvents();
if (CommandPeriod)
{
AmQuitting = False;
return;
}
}
break;
case QTR_DONT:
KillThreads ();
break;
case QTR_CANCEL:
AmQuitting = False;
return;
}
#endif
if (!PrefIsSet(PREF_EASY_QUIT) && !Offline && ForceSend > now && ForceSend - now < never && !changeUserState)
{
GetRString(hours,NEVER_WARN);
switch (AlertStr(QUIT_MQ_ALRT,Caution,hours))
{
case QMQ_SEND_ALL:
WarpQueue(0);
XferMail(False,True,False,False,False,0);
break;
case QMQ_SEND:
WarpQueue(never);
XferMail(False,True,False,False,False,0);
break;
case QMQ_DONT:
break;
default:
AmQuitting = False;
return;
}
}
if (!PrefIsSet(PREF_EASY_QUIT) && !Offline && !changeUserState)
{
SetSendQueue();
if (SendQueue)
{
switch (ReallyDoAnAlert(QUIT_QUEUE_ALRT,Caution))
{
case QQL_SEND:
XferMail(False,True,False,False,False,0);
break;
case QQL_QUIT:
break;
default:
AmQuitting = False;
return;
}
}
}
NoMenus = True;
EnableMenus(nil,false);
if (remember) RememberOpenWindows();
// execute all pending IMAP commands
ExecuteAllPendingIMAPCommands();
// empty the IMAP trash now if we're asked to, before our windows get closed and our network is killed.
if (PrefIsSet(PREF_AUTO_EMPTY) && IMAPExists() && AutoCheckOK()) EmptyImapTrashes(kEmptyAutoCheckTrashes);
if (!CloseAll(True)) {AmQuitting=False; return;}
// Kill Kerberos if the preference is set no matter if the dominant personailty is using Kerberos or not.
if (KerberosWasUsed() && PrefIsSet(PREF_DIE_DOG)) KerbDestroy();
if (KerberosWasUsed() && PrefIsSet(PREF_DIE_DOG_USER)) KerbDestroyUser();
#ifdef TWO
CleanTempFolder();
#endif
#ifdef WINTERTREE
if (HasFeature (featureSpellChecking) && SpellSession) SpellClose(true);
#endif
/*
* account for face time in audit log
*/
if (FMBMain)
{
uLong face=0, rear=0, connect=0, total=0;
FaceMeasureReport(FMBMain,&face,&rear,&connect,&total);
AuditShutdown(face,rear,connect,total);
ZapFaceMeasure(FMBMain);
}
AdShutdown();
ShutdownStats();
OutgoingMIDListSave();
Done = True;
}
/************************************************************************
* CloseAll - close all windows
************************************************************************/
Boolean CloseAll(Boolean toolbarToo)
{
if (!CloseAllMessages()) return(False);
if (!CloseAllBoxes()) return(False);
#ifdef FLOAT_WIN
if (!CloseRemaining(FrontWindow())) return(False);
#else //FLOAT_WIN
if (!CloseRemaining(FrontWindow_())) return(False);
#endif //FLOAT_WIN
if (toolbarToo)
{
if (ToolbarShowing()) OpenToolbar();
CloseAdWindow();
}
return(True);
}
/************************************************************************
* CloseRemaining - get rid of any other windows there might be
************************************************************************/
Boolean CloseRemaining(WindowPtr theWindow)
{
if (!theWindow) return(True);
if (!CloseRemaining(GetNextWindow(theWindow))) return(False);
if (IsKnownWindowMyWindow(theWindow))
{
if ((GetWindowKind(theWindow)==TBAR_WIN) || (GetWindowKind(theWindow)==PROG_WIN) || (GetWindowKind(theWindow)==AD_WIN)) return(True);
else return(CloseMyWindow(theWindow));
}
else if (GetWindowKind(theWindow)==dialogKind)
{
DisposDialog_(GetDialogFromWindow(theWindow));
}
else if (IsPlugwindow(theWindow))
return(PlugwindowClose(theWindow));
return(True);
}
void ChangeTEFont(TEHandle teh,short font,short size);
#define aboutCreditsBtn 9
#define aboutWebBtn 6
/**********************************************************************
* DoAboutUIUCmail - put up the about box
**********************************************************************/
void DoAboutUIUCmail()
{
Str63 versionString;
Str255 partition, regInfo;
MyWindowPtr dlogWin;
DialogPtr dlog;
extern ModalFilterUPP DlgFilterUPP;
short item;
short hideItem;
OSType t;
Handle h;
Rect r, portR;
ControlRef webButton;
VersString(versionString);
if (HaveOSX())
// Memory size is meaningless under OS X
*partition = 0;
else
ComposeRString(partition,MEM_PARTITION,CurrentSize()/(1 K),
EstimatePartitionSize(true)/(1 K));
AboutRegisterString(regInfo);
MyParamText(versionString,regInfo,"","");
SetDialogFont(SmallSysFontID());
dlogWin = GetNewMyDialog(ABOUT_ALRT,nil,nil,InFront);
ConfigFontSetup(dlogWin);
SetDialogFont(0);
if (!dlogWin) return;
dlog = GetMyWindowDialogPtr (dlogWin);
/*
* put up the dialog
*/
StartMovableModal(dlog);
hideItem = CountDITL(dlog);
for (item=aboutCreditsBtn+2;item<hideItem;item++) HideDialogItem(dlog,item);
HideDialogItem(dlog,aboutCreditsBtn+1);
// size to fit
GetDialogItem(dlog,aboutCreditsBtn,&t,&h,&r);
GetPortBounds(GetDialogPort(dlog),&portR);
SizeWindow(GetDialogWindow(dlog),portR.right-portR.left,r.bottom+(3*INSET)/2,False);
// Get the ControlRef of the web button
GetDialogItem(dlog,aboutWebBtn,&t,&h,&r);
webButton = (ControlRef) h;
ShowWindow(GetDialogWindow (dlog));
do
{
#if 0
Boolean buttonSaysWeb = true;
Boolean optionKeySaysWeb;
optionKeySaysWeb = ( optionKey & CurrentModifiers ()) == 0;
if ( optionKeySaysWeb != buttonSaysWeb )
{
buttonSaysWeb = optionKeySaysWeb;
SetControlTitle ( webButton, buttonSaysWeb ? "\pWeb" : "\pFolder" );
}
#endif
MovableModalDialog(dlog,DlgFilterUPP,&item);
switch (item)
{
case aboutWebBtn:
if ( ( optionKey & CurrentModifiers ()) == 0 /* buttonSaysWeb */ )
{ // Open the web page and close the dialog
OpenAdwareURL(GetNagState(), UPDATE_SITE, actionSite, siteQuery, nil);
item = 1;
}
else
{ // Open the data folder and close the dialog
FSSpec aSpec;
aSpec.vRefNum = Root.vRef;
aSpec.parID = Root.dirId;
aSpec.name [ 0 ] = 0;
(void) FinderOpen(&aSpec,False,False);
item = 1;
}
break;
case aboutCreditsBtn: // Credits
HideDialogItem(dlog,aboutCreditsBtn); // hide this button to show next
ShowDialogItem(dlog,aboutCreditsBtn+1);
case aboutCreditsBtn+1: // More Credits;
ShowDialogItem(dlog,hideItem-1);
HideDialogItem(dlog,hideItem--);
if (hideItem==aboutCreditsBtn+2) HideDialogItem(dlog,aboutCreditsBtn+1);
break;
default:
break;
}
}
while (item!=1);
/*
* close
*/
EndMovableModal(dlog);
DisposeDialog_(dlog);
}
/**********************************************************************
* NotImplemented - tell the user a feature is not implemented
**********************************************************************/
void NotImplemented(void)
{
DoAnAlert(Stop,"\pSorry, I'm (still) too stupid to do that.");
}
#ifdef TWO
/************************************************************************
* DoCompWStationery - compose a message, using stationery
************************************************************************/
OSErr DoCompWStationery(FSSpecPtr spec)
{
MyWindowPtr win;
if (win=DoComposeNew(0))
{
WindowPtr winWP = GetMyWindowWindowPtr (win);
MessHandle messH =(MessHandle)GetWindowPrivateData(winWP);
ApplyStationery(win,spec,True,True);
UpdateSum(messH,SumOf(messH)->offset,SumOf(messH)->length);
ShowMyWindow(winWP);
return(0);
}
return(1);
}
/************************************************************************
* ApplyDefaultStationery - apply custom stationery to a message
************************************************************************/
void ApplyDefaultStationery(MyWindowPtr win,Boolean bodyToo,Boolean personality)
{
FSSpec spec;
Str31 name;
//Stationery - no support for default stationery in Light
if (HasFeature (featureStationery))
if (!FSMakeFSSpec(StationVRef,StationDirId,GetRString(name,STATIONERY),&spec))
ApplyStationery(win,&spec,bodyToo,personality);
else if (UseInlineSig)
AddInlineSig(Win2MessH(win));
}
/************************************************************************
* ApplyIndexStationery - apply custom stationery to a message
************************************************************************/
void ApplyIndexStationery(MyWindowPtr win,short which,Boolean bodyToo,Boolean personality)
{
FSSpec spec;
Str31 name;
OSErr err;
//Stationery - no support for this in Light
if (!HasFeature (featureStationery))
return;
MyGetItem(GetMHandle(REPLY_WITH_HIER_MENU),which,name);
if (err=FSMakeFSSpec(StationVRef,StationDirId,name,&spec))
FileSystemError(READ_STATION,name,err);
else
ApplyStationery(win,&spec,bodyToo,personality);
}
#endif
/************************************************************************
* DoComposeNew - start a new outgoing message
************************************************************************/
MyWindowPtr DoComposeNew(TextAddrHandle toWhom)
{
TOCHandle tocH;
MSumType sum;
MyWindowPtr newWin;
Boolean oldReallyDirty;
#ifdef THREADING_ON
// fix filter reply bug-- we should always be creating new mesgs in the real out toc
if (!(tocH=GetRealOutTOC())) return(nil);
#else
if (!(tocH=GetOutTOC())) return(nil);
#endif
Zero(sum);
sum.state = UNSENDABLE;
sum.flags = DefaultOutFlags();
sum.tableId = DEFAULT_TABLE;
sum.origZone = ZoneSecs()/60;
sum.seconds = GMTDateTime();
sum.persId = (*CurPers)->persId;
sum.sigId = SigValidate(GetPrefLong(PREF_SIGFILE));
oldReallyDirty = (*tocH)->reallyDirty;
if (!SaveMessageSum(&sum,&tocH))
{
WarnUser(MEM_ERR,MemError());
return(nil);
}
(*tocH)->reallyDirty = oldReallyDirty; // no need to get terribly excited about a new
// message that doesn't even exist on disk yet
newWin = OpenComp(tocH,(*tocH)->count-1,nil,nil,False,True);
if (newWin && toWhom)
{
MessHandle newMessH = (MessHandle)GetMyWindowPrivateData(newWin);
SetMessText(newMessH,TO_HEAD,LDRef(toWhom),GetHandleSize(toWhom));
UL(toWhom);
NickExpandAndCacheHead(newMessH,TO_HEAD,false);
}
if (newWin)
{
newWin->isDirty = False;
PeteResetCurStyle(newWin->pte);
PeteCleanList(newWin->pte);
}
return(newWin);
}
/**********************************************************************
* OpenAttachedApp - ask the user for confirmation, then unbundle and launch an application
**********************************************************************/
OSErr OpenAttachedApp(FSSpecPtr spec)
{
Str63 appName;
OSType creator;
short id;
short result;
OSErr err=noErr;
OSType type;
OSType **creatorList;
if (ExtractCreatorFromBndl(spec,&creator)) creator = '????';
id = (TypeIsOnList(creator,SEA_LIST_TYPE) || CreatorToName(creator,appName)) ? ATTACH_APP2_ALRT : ATTACH_APP_ALRT;
MyParamText(appName,spec->name,"","");
result = ReallyDoAnAlert(id,Caution);
if (result!=kAlertStdAlertCancelButton)
{
type = FileTypeOf(spec);
if (type==kFakeAppType) type = 'APPL';
else
{
id = (type&0xff)-'0';
if (creatorList=GetIndResource(EXECUTABLE_TYPE_LIST,1))
type = (*creatorList)[id];
else
type = 'APPL';
}
err = TweakFileType(spec,type,creator);
if (!err && result==1) err = OpenOtherDoc(spec,False,false,nil);
}
else err = userCancelled;
return(err);
}
/**********************************************************************
* CreatorToName - turn a creator into the name of its app
**********************************************************************/
OSErr CreatorToName(OSType creator,PStr appName)
{
short volIndex, vRef, dtRef;
OSErr err;
FSSpec appSpec;
for (volIndex=1;!(err=IndexVRef(volIndex,&vRef));volIndex++)
{
if (!(err = DTRef(vRef,&dtRef)))
{
if (!(err = DTGetAppl(vRef,dtRef,creator,&appSpec)))
{
if (FileCreatorOf(&appSpec)==creator)
{
PCopy(appName,appSpec.name);
return(noErr);
}
}
}
}
if (!err) err = fnfErr;
return(err);
}
/************************************************************************
* DefaultOutFlags - get the default flags for an outgoing message
************************************************************************/
uLong DefaultOutFlags(void)
{
uLong flags=0;
short aType=0;
flags |= FLAG_OUT;
if (!PrefIsSet(PREF_NO_QP)) flags |= FLAG_CAN_ENC;
if (PrefIsSet(PREF_DOUBLE)) aType = atmDouble;
else if (PrefIsSet(PREF_SINGLE)) aType = atmSingle;
else if (PrefIsSet(PREF_UUENCODE)) aType = atmUU;
else if (PrefIsSet(PREF_BINHEX)) aType = atmHQX;
if (!aType) aType = atmDouble;
SetAOptNumber(flags,aType-1);
if (PrefIsSet(PREF_WRAP_OUT)) flags |= FLAG_WRAP_OUT;
if (PrefIsSet(PREF_BX_TEXT)) flags |= FLAG_BX_TEXT;
if (PrefIsSet(PREF_KEEP_OUTGOING)) flags |= FLAG_KEEP_COPY;
if (PrefIsSet(PREF_TAB_IN_TEXT)) flags |= FLAG_TABS;
if (PrefIsSet(PREF_SEND_ENRICHED_NEW)) flags |= FLAG_RICH;
return(flags);
}
/**********************************************************************
* RemSpoolFolder - remove a message's spool folder
**********************************************************************/
OSErr RemSpoolFolder(long uidHash)
{
OSErr err = noErr;
Str255 scratch;
FSSpec spec;
NumToString(uidHash,scratch);
if (noErr == ( err = SubFolderSpec(SPOOL_FOLDER,&spec)))
if ( noErr == ( err = FSMakeFSSpec(spec.vRefNum,spec.parID,scratch,&spec)))
err = RemoveDir(&spec);
return err;
}
/************************************************************************
* CloseAllBoxes
************************************************************************/
Boolean CloseAllBoxes(void)
{
TOCHandle thisTOC,nextTOC;
for (thisTOC=TOCList; thisTOC; thisTOC=nextTOC)
{
nextTOC = (*thisTOC)->next;
// don't close temp mailbox if thread is using it!!!
#ifdef THREADING_ON
if (GetNumBackgroundThreads() && ((thisTOC == GetTempOutTOC()) || (thisTOC == GetTempInTOC())))
continue;
#endif
if (!CloseMyWindow(GetMyWindowWindowPtr((*thisTOC)->win))) return(False);
}
return(True);
}
/************************************************************************
*
************************************************************************/
Boolean CloseAllMessages(void)
{
MessHandle thisMess, nextMess;
for (thisMess=MessList; thisMess; thisMess=nextMess)
{
nextMess = (*thisMess)->next;
// don't close message if thread is using it!!!
#ifdef THREADING_ON
if (GetNumBackgroundThreads() && (((*thisMess)->tocH == GetTempOutTOC()) || ((*thisMess)->tocH == GetTempInTOC())))
continue;
#endif
if (!CloseMyWindow(GetMyWindowWindowPtr((*thisMess)->win))) return(False);
}
return(True);
}
/************************************************************************
* Type2Select - handle events for type-2-select
************************************************************************/
void Type2Select(EventRecord *event)
{
static uLong delay;
short key;
/*
* load up the delay
*/
if (!delay) delay = GetRLong(PARTIAL_TICKS);
/*
* if it's been a long time, toss the string
*/
if (event->when-Type2SelTicks > delay) *Type2SelString = 0;
/*
* now, the event
*/
switch (event->what)
{
case mouseDown:
case app1Evt:
case activateEvt:
*Type2SelString = 0;
break;
case keyDown:
if (event->modifiers & cmdKey)
*Type2SelString = 0;
else
{
key = event->message & charCodeMask;
if (key==backSpace || key==tabChar || key==returnChar || key==delChar || key==escChar || !DirtyKey(key))
*Type2SelString = 0;
else if (*Type2SelString<sizeof(Type2SelString)-1)
{
Type2SelTicks = event->when;
PCatC(Type2SelString,key);
}
}
break;
}
}
#pragma segment Balloon
void HelpRect(Rect *tipRect,Point tip,short method,short resSelect);
void HelpPict(Rect *tipRect,Point tip,short method,short resId);
void HelpRectString(Rect *tipRect,Point tip,short method,UPtr string);
/**********************************************************************
*
**********************************************************************/
void MyBalloon(Rect *tipRect,short percentRight,short method,short resSelect,short pict,PStr message)
{
static Rect oldTipRect;
static oldPercentRight;
static oldResSelect;
static oldPict;
static oldMethod;
static Str255 oldMessage;
Rect r;
Point tip;
if (!HMIsBalloon() ||
!AboutSameRect(tipRect,&oldTipRect) ||
percentRight!=oldPercentRight ||
resSelect!=oldResSelect ||
pict != oldPict ||
method != oldMethod ||
(message ? !StringSame(message,oldMessage) : *oldMessage))
{
oldTipRect = *tipRect;
oldPercentRight = percentRight;
oldResSelect = resSelect;
oldPict = pict;
oldMethod = method;
if (message) PCopy(oldMessage,message);
else *oldMessage = 0;
r = *tipRect;
LocalToGlobal((Point*)&r);
LocalToGlobal((Point*)&r + 1);
tip.h = r.left + (percentRight*RectWi(r))/100;
tip.v = r.top + RectHi(r)/2;
if (resSelect) HelpRect(&r,tip,method,resSelect);
else if (pict) HelpPict(&r,tip,method,pict);
else if (message) HelpRectString(&r,tip,method,message);
}
}
/************************************************************************
* HelpRect - show a standard help balloon
************************************************************************/
void HelpRect(Rect *tipRect,Point tip,short method,short resSelect)
{
#if TARGET_RT_MAC_CFM
HMMessageRecord hmmr;
Zero(hmmr);
hmmr.u.hmmStringRes.hmmResID = (resSelect/100)*100;
hmmr.u.hmmStringRes.hmmIndex = resSelect%100;
hmmr.hmmHelpType = khmmStringRes;
HMShowBalloon(&hmmr,tip,tipRect,nil,0,0,method);
#else
#warning "Need to use stuff in HIToolbox/MacHelp.h"
#endif
}
Boolean ManualTag; // have we just put up a manual help tag?
/************************************************************************
* MyHMHideTag - hide a tag, if it was put up by our routines
************************************************************************/
Boolean MyHMHideTag(void)
{
if (ManualTag)
{
ManualTag = false;
HMHideTag();
return true;
}
return false;
}
/************************************************************************
* MyHMDisplayTag - display a tag manually, and have it manually removed
************************************************************************/
OSErr MyHMDisplayTag(HMHelpContentPtr hmp)
{
ManualTag = true;
return HMDisplayTag(hmp);
}
/************************************************************************
* HelpPict - show a help balloon with a pict in it
************************************************************************/
void HelpPict(Rect *tipRect,Point tip,short method,short resId)
{
#if TARGET_RT_MAC_CFM
HMMessageRecord hmmr;
Zero(hmmr);
hmmr.u.hmmPict = resId;
hmmr.hmmHelpType = khmmPict;
HMShowBalloon(&hmmr,tip,tipRect,nil,0,0,method);
#else
#warning "Need to use stuff in HIToolbox/MacHelp.h"
#endif
}
/************************************************************************
* HelpRectString - show a standard help balloon
************************************************************************/
void HelpRectString(Rect *tipRect,Point tip,short method,UPtr string)
{
#if TARGET_RT_MAC_CFM
HMMessageRecord hmmr;
Zero(hmmr);
PCopy(hmmr.u.hmmString,string);
hmmr.hmmHelpType = khmmString;
HMShowBalloon(&hmmr,tip,tipRect,nil,0,0,method);
#else
#warning "Need to use stuff in HIToolbox/MacHelp.h"
#endif
}
/************************************************************************
* DoHelp - do help for a window
************************************************************************/
void DoHelp(WindowPtr winWP)
{
MyWindowPtr win;
Point mouse;
GrafPtr oldPort;
Str255 sHelp,sTitle;
Rect rPort;
if (!winWP || !IsMyWindow(winWP)) return;
win = GetWindowMyWindowPtr (winWP);
GetPort(&oldPort);
SetPort_(GetWindowPort(winWP));
GetMouse(&mouse);
if (win->sponsorAdExists && PtInRect(mouse,&win->sponsorAdRect))
{
// do sponsor ad help
GetSponsorAdTitle(sTitle);
ComposeRString(sHelp,SPONSOR_AD_HELP,sTitle);
MyBalloon(&win->sponsorAdRect,100,0,0,0,sHelp);
}
else if (PtInRect(mouse,GetPortBounds(GetWindowPort(winWP),&rPort)) && !WazooHelp(win,mouse) && win->help)
(*win->help)(win,mouse);
SetPort_(oldPort);
}
#pragma segment Misc
/************************************************************************
* HandleWindowChoice - handle the user choosing a window menu item
************************************************************************/
void HandleWindowChoice(short item)
{
WindowPtr theWindow=FrontWindow_();
switch(item)
{
case WIN_BEHIND_ITEM:
SendBack(theWindow);
break;
case WIN_MINIMIZE_ITEM:
CollapseWindow(theWindow, true);
break;
case WIN_BRINGALLTOFRONT_ITEM:
{
ProcessSerialNumber psn;
if (GetCurrentProcess(&psn)==noErr)
SetFrontProcess(&psn);
break;
}
default:
item -= WIN_BAR_ITEM;
// we use a slightly different defn of FrontWindow here
for (theWindow=FrontWindow();theWindow;theWindow=GetNextWindow(theWindow))
{
if (WinWPWindowsMenuEligible(theWindow) && !--item)
{
ShowMyWindow(theWindow);
UserSelectWindow(theWindow);
break;
}
}
break;
}
}
/**********************************************************************
* SendBack - send a window to the back
**********************************************************************/
void SendBack(WindowPtr theWindow)
{
WindowPtr behind;
if (theWindow)
{
for (behind = theWindow; GetNextWindow (behind); behind = GetNextWindow (behind))
if (GetWindowKind(GetNextWindow(behind))==TBAR_WIN) break;
if (behind!=theWindow) SendBehind(theWindow,behind);
}
}
/**********************************************************************
* IsSigWindow - is a window a signature window?
**********************************************************************/
Boolean IsSigWindow(WindowPtr theWindow)
{
FSSpec spec;
FSSpec winSpec = (*(TextDHandle) GetWindowPrivateData(theWindow))->spec;
SigSpec(&spec,0);
if (SameSpec(&spec,&winSpec)) return(True);
#ifdef TWO
SigSpec(&spec,1);
if (SameSpec(&spec,&winSpec)) return(True);
#endif
return False;
}
/**********************************************************************
* DoSFOpen - let the user choose a doc to open
**********************************************************************/
void DoSFOpen(short modifiers)
{
DoSFOpenNav (modifiers);
}
/**********************************************************************
* InsertTextFile - insert a file into an open window
**********************************************************************/
OSErr InsertTextFile(MyWindowPtr win, FSSpecPtr spec, Boolean rich, Boolean delSP)
{
WindowPtr winWP = GetMyWindowWindowPtr(win);
OSErr err = noErr;
Handle text;
OSType type = FileTypeOf(spec);
long pStart;
if (type!='TEXT' && type!='ttro') return(WarnUser(TEXT_ONLY,1));
if (err=MemoryPreflight(FSpDFSize(spec))) return(err);
// (jp) Be a little more paranoid of the window we're passed, just in case this is _ever_
// called for windows other than composition windows
if (IsMyWindow (winWP)) {
if (!(err=Snarf(spec,&text,0)))
{
if (win->pte)
{
CompReallyPreferBody(win);
PetePrepareUndo(win->pte,peUndoPaste,-1,-1,&pStart,nil);
//PeteCalcOn(win->pte);
if(rich)
{
StackHandle stack;
StackInit(sizeof(PartDesc),&stack);
err = InsertRich(text,0,-1,-1,true,win->pte,stack,delSP);
(*PeteExtra(win->pte))->partStack = stack;
}
else
err = PETEInsertText(PETE,win->pte,-1,text,nil);
if (!err)
{
text = nil;
if(!rich)
PeteSmallParas(win->pte);
PeteCalcOn(win->pte);
if (PrefIsSet(PREF_ZOOM_OPEN)) ReZoomMyWindow(winWP);
PeteFinishUndo(win->pte,peUndoPaste,pStart,-1);
}
else PeteKillUndo(win->pte);
}
ZapHandle(text);
}
}
return(err);
}
/************************************************************************
* ChangePassword - change the user's password
************************************************************************/
short ChangePassword(void)
{
Str31 user, old, new, candidate;
Str127 uName, hName, persName;
short err;
TransStream passStream = 0;
if (Offline && GoOnline()) return(OFFLINE);
if ((err=NewTransStream(&passStream)) == noErr)
{
*(*CurPersSafe)->password = 0; /* make the user reenter it */
(*CurPersSafe)->popSecure = 0;
GetPassStuff(persName,uName,hName);
if (!(err=GetPassword(persName,uName,hName,old,sizeof(old),ENTER)))
{
if (!(err=GetPassword(persName,uName,hName,candidate,sizeof(candidate),NEW)) &&
!(err=GetPassword(persName,uName,hName,new,sizeof(new),VERIFY_NEW)))
{
if (!EqualString(candidate,new,True,True))
{
WarnUser(PW_MISMATCH,0);
err = 1;
}
else
{
GetRString(hName,PW_CHANGE_SERVER);
if (err=GetPOPInfo(user,*hName ? nil:hName)) return(err);
PCopy((*CurPersSafe)->password,old);
err = ReallyChangePassword(passStream,user,hName,old,new);
}
}
}
if (err) InvalidatePasswords(True,False,False);
ZapTransStream(&passStream);
}
return(err);
}
/************************************************************************
* ReallyChangePassword - change the user's password, really
************************************************************************/
short ReallyChangePassword(TransStream stream,UPtr user,UPtr host,UPtr old,UPtr new)
{
enum {PW_USER=801,PW_PASS,PW_NEWPASS,PW_QUIT};
short err=1;
long port = GetRLong(PW_PORT);
Str255 buffer,junk;
OpenProgress();
ProgressMessageR(kpTitle,CHANGING_PW);
#ifdef CTB
if (!UseCTB || !DialThePhone(stream))
#endif
if (!ConnectTrans(stream,host,port,False,GetRLong(OPEN_TIMEOUT)))
{
if (!CheckResult(stream,buffer) &&
!SendPwCommand(stream,PW_USER,user) && !CheckResult(stream,buffer) &&
!SendPwCommand(stream,PW_PASS,old) && !CheckResult(stream,buffer) &&
!SendPwCommand(stream,PW_NEWPASS,new) && !CheckResult(stream,buffer))
{
err = 0;
SilenceTrans(stream,True);
if (!SendPwCommand(stream,PW_QUIT,"")) CheckResult(stream,junk);
PCopy((*CurPersSafe)->password,new);
(*CurPersSafe)->popSecure = True;
if (PrefIsSet(PREF_SAVE_PASSWORD)) PersSavePw(CurPersSafe);
}
}
#ifdef CTB
if (UseCTB) HangUpThePhone();
#endif
DestroyTrans(stream);
CloseProgress();
if (!err) {SetAlertBeep(False);AlertStr(OK_ALRT,Normal,buffer);SetAlertBeep(True);}
return(err);
}
/************************************************************************
* SendPwCommand - send a password command
************************************************************************/
short SendPwCommand(TransStream stream,short cmd,UPtr arg)
{
Str255 buffer;
ComposeRString(buffer,cmd,arg,NewLine);
return (SendTrans(stream,buffer+1,*buffer,nil));
}
/************************************************************************
* CheckResult - did the command succeed?
************************************************************************/
short CheckResult(TransStream stream,UPtr buffer)
{
short err;
do
{
err = GetReply(stream,buffer+1,253,False,False);
*buffer = strlen(buffer+1);
TransLitString(buffer);
if (err>=400 && err<600)
{
Str255 pwErr;
GetRString(pwErr,PW_ERROR);
MyParamText(pwErr,buffer,"","");
ReallyDoAnAlert(OK_ALRT,Stop);
}
else ProgressMessage(kpMessage,buffer);
}
while (err<200);
return(err>399);
}
/************************************************************************
* FindPSNByCreator - find a process by creator code
************************************************************************/
OSErr FindPSNByCreator(ProcessSerialNumberPtr psnPtr,OSType creator)
{
ProcessSerialNumber psn;
ProcessInfoRec pi;
short err;
Zero(psn);
for (err=GetNextProcess(&psn);!err;err=GetNextProcess(&psn))
{
pi.processInfoLength = sizeof(pi);
pi.processName = nil;
pi.processAppSpec = nil;
if (err=GetProcessInformation(&psn,&pi)) return(err);
if (pi.processSignature == creator)
{
if (psnPtr) *psnPtr = psn;
return(noErr);
}
}
return(procNotFound);
}
/************************************************************************
* FindPSNByAlias - find a process by creator code
************************************************************************/
OSErr FindPSNByAlias(ProcessSerialNumberPtr psnPtr,AliasHandle alias)
{
short err;
FSSpec spec;
Boolean wasChanged;
if (err=ResolveAlias(nil,alias,&spec,&wasChanged)) return(err);
return(FindPSNBySpec(psnPtr,&spec));
}
/**********************************************************************
* FindPSNBySpec - find a process by the file it belongs to
**********************************************************************/
OSErr FindPSNBySpec(ProcessSerialNumberPtr psnPtr,FSSpecPtr spec)
{
OSErr err;
ProcessSerialNumber psn;
FSRef appRef,processRef;
ProcessInfoRec pi;
FSSpec processSpec;
FSpMakeFSRef(spec,&appRef); // Need an FSRef for comparing with process bundle
Zero(psn);
for (err=GetNextProcess(&psn);!err;err=GetNextProcess(&psn))
{
Boolean found=false;
// Search first for application bundle
if (HaveOSX()) // Check for OS X, so we don't go boom! SD 4/8/02
{
GetProcessBundleLocation(&psn,&processRef);
found = !FSCompareFSRefs(&appRef,&processRef);
}
// Not OS X or Not Bundle
if (!found)
{
// Try reference to application itself
pi.processInfoLength = sizeof(pi);
pi.processName = nil;
pi.processAppSpec = &processSpec;
if (err=GetProcessInformation(&psn,&pi)) return(err);
found = SameSpec(pi.processAppSpec,spec);
}
if (found)
{
// Found it
if (psnPtr) *psnPtr = psn;
return(noErr);
}
}
return(procNotFound);
}
/**********************************************************************
* LocateApp - locate an application alias
**********************************************************************/
OSErr LocateApp(AliasHandle alias)
{
FSSpec spec;
OSErr err;
Boolean wasChanged;
if (!(err=ResolveAlias(nil,alias,&spec,&wasChanged)))
if (wasChanged)
{
HNoPurge((Handle)alias);
ChangedResource((Handle)alias); /* fix up the alias */
}
return(err);
}
/************************************************************************
* LaunchByAlias - launch an app from an alias
************************************************************************/
OSErr LaunchByAlias(AliasHandle alias)
{
FSSpec spec;
Boolean wasAlias;
short err;
err = ResolveAlias(nil,alias,&spec,&wasAlias);
if (!err) err = LaunchAppWith(&spec,nil,false);
if (err && err!=userCanceledErr) return(WarnUser(COULDNT_LAUNCH,err));
return err;
}
#pragma segment Balloon
void HelpTextWin(short itm)
{
Str255 name, existName;
MenuHandle hm;
WindowPtr theWindow;
Boolean same;
if (!HMGetHelpMenuHandle(&hm))
{
MyGetItem(hm,itm,name);
/*
* is window already open?
*/
for (theWindow = FrontWindow_(); theWindow; theWindow = GetNextWindow (theWindow))
{
if (GetWindowKind(theWindow)==HELP_WIN)
{
same = StringSame(name,MyGetWTitle(theWindow,existName));
if (same)
{
UserSelectWindow(theWindow);
if (ModalWindow) SelectWindow_(ModalWindow);
return;
}
}
}
/*
* nope. open it
*/
TextResWin(name);
}
}
void TextResWin(PStr name)
{
Handle picH = nil;
StringHandle textH;
short resID;
ResType resType;
PETEDocInitInfo pi;
OSErr err;
MyWindowPtr win;
Boolean dispose = false;
Str255 html;
if(((textH = (StringHandle)GetNamedResource('TEXT', name)) == nil) && ((picH = GetNamedResource('PICT', name)) == nil))
return;
if(textH == nil)
{
dispose = true;
GetResInfo(picH, &resID, &resType, name);
ComposeRString(html, PICT_HELP_HTML, resID);
if((textH = (StringHandle)NuHTempBetter(html[0])) == nil)
{
WarnUser(MEM_ERR,MemError());
return;
}
BMD(&html[1],*textH,html[0]);
}
else
{
ComposeRString(html, MIME_RICH_OFF, EnrichedStrn+enHTML);
if(Munger(textH, 0, &html[1], html[0], nil, 0) < 0)
{
StringHandle support;
dispose = true;
DetachResource(textH);
support = (StringHandle)GetResource('TEXT', IsFreeMode () ? 3001 : 3000);
HandAndHand(support, textH);
}
}
win = GetNewMyWindow(MESSAGE_WIND, nil, nil, nil, False, False, HELP_WIN);
if(win)
{
WindowPtr winWP = GetMyWindowWindowPtr (win);
DefaultPII(win,True,peVScroll|peGrowBox,&pi);
pi.inParaInfo.startMargin = 0;
pi.inParaInfo.endMargin = WindowWi(winWP)+1;
if (!(err=PeteCreate(win,&win->pte,0,&pi)))
{
long hOff = 0L, iOff = 0L;
PeteCalcOff(win->pte);
err = InsertHTML (textH, &hOff, GetHandleSize (textH), &iOff, win->pte, kDontEnsureCR);
PeteCalcOn(win->pte);
if(!err)
{
SetWTitle_(winWP,name);
win->position = PositionPrefsTitle;
win->didResize = TextDidResize;
win->zoomSize = CompZoomSize;
win->dontControl = True;
win->find = TextFind;
PETEMarkDocDirty(PETE,win->pte,False);
win->isDirty = False;
PeteSelect(win,win->pte,0,0);
PeteLock(win->pte, 0, LONG_MAX, peModLock);
PeteLock(win->pte, kPETECurrentStyle, kPETECurrentStyle, peModLock);
ShowMyWindow(winWP);
UpdateMyWindow(winWP);
}
}
if (err)
CloseMyWindow(winWP);
}
else
{
err = MemError();
}
if(dispose) ZapHandle(textH);
if(err) WarnUser(PETE_ERR,err);
}
/************************************************************************
* HelpPict - display a help picture
************************************************************************/
void HelpPICTWin(short itm)
{
Str255 name, existName;
MenuHandle hm;
WindowPtr theWindow;
Boolean same;
if (!HMGetHelpMenuHandle(&hm))
{
MyGetItem(hm,itm,name);
/*
* is window already open?
*/
for (theWindow = FrontWindow_(); theWindow; theWindow = GetNextWindow (theWindow))
{
if (GetWindowKind(theWindow)==PICT_WIN)
{
same = StringSame(name,MyGetWTitle(theWindow,existName));
if (same)
{
UserSelectWindow(theWindow);
if (ModalWindow) SelectWindow_(ModalWindow);
return;
}
}
}
/*
* nope. open it
*/
PICTResWin(name);
}
}
/************************************************************************
* PICTResWindow - display a pict window from a named resource
************************************************************************/
void PICTResWin(PStr name)
{
PicHandle resH;
Rect r;
short id;
OSType type;
MyWindowPtr win;
short h,v;
RGBColor color;
HSVColor hsv;
if (resH = (PicHandle)GetNamedResource('PICT',name))
{
r = (*resH)->picFrame;
win = GetNewMyWindow(HELP_WIND,nil,nil,BehindModal,True,True,PICT_WIN);
if (win)
{
WindowPtr winWP = GetMyWindowWindowPtr (win);
h = RoundDiv(r.right-r.left,win->hPitch);
v = RoundDiv(r.bottom-r.top,win->vPitch);
SetWTitle_(winWP,name);
#ifdef NEVER
SizeWindow(winWP,h*win->hPitch+GROW_SIZE+1,v*win->vPitch+GROW_SIZE+1,False);
#endif
MyWindowMaxes(win,h,v);
if (ThereIsColor)
{
GetBackColor(&color);
RGB2HSV(&color,&hsv);
hsv.value = MAX(40000,hsv.value);
HSV2RGB(&hsv,&color);
RGBBackColor(&color);
}
GetResInfo((Handle)resH,&id,&type,name);
SetWindowPrivateData (winWP, id);
win->position = PositionPrefsTitle;
win->update = PICTUpdate;
win->zoomSize = MaxSizeZoom;
win->cursor = JustArrow;
//win->dontControl = True;
ShowMyWindow(winWP);
if (ModalWindow) SelectWindow_(ModalWindow);
return;
}
}
}
#pragma segment Help
/************************************************************************
* JustArrow - make the cursor an arrow
************************************************************************/
void JustArrow(Point mouse)
{
#pragma unused(mouse)
SetMyCursor(arrowCursor);
}
/************************************************************************
* PICTUpdate - update a PICT window
************************************************************************/
void PICTUpdate(MyWindowPtr win)
{
PicHandle pic = GetResource_('PICT',GetMyWindowPrivateData(win));
Rect r;
if (pic)
{
HNoPurge_(pic);
r = (*pic)->picFrame;
OffsetRect(&r,-r.left-GetControlValue(win->hBar)*win->hPitch,-r.top-GetControlValue(win->vBar)*win->vPitch);
ClipRect(&win->contR);
DrawPicture(pic,&r);
InfiniteClip(GetMyWindowCGrafPtr(win));
HPurge((Handle)pic);
}
}
/************************************************************************
* PICTRect - find a pict's rect
************************************************************************/
void PICTRect(short id, Rect *r)
{
PicHandle pic = GetResource_('PICT',id);
if (pic)
*r = (*pic)->picFrame;
else
SetRect(r,0,0,0,0);
}
/**********************************************************************
* PurchaseEudora - buy Eudora
**********************************************************************/
void PurchaseEudora(void)
{
Str255 url, s;
ComposeRString(url,PURCH_URL,URLEscape(VersString(s)));
ParseURL(url,s,nil,nil);
if (EqualStrRes(s,ProtocolStrn+proMail)) OpenLocalURL(url,nil);
else OpenOtherURLPtr(s,url+1,*url);
}
#ifdef TWO
#pragma segment Spell
/************************************************************************
* FindSpeller - use the PPC browser to find a spell-checker
************************************************************************/
OSErr FindSpeller(void)
{
SFTypeList types;
FSSpec spec;
Str255 prompt;
OSErr theError;
Boolean good;
types[0] = 'APPL';
types[1] = 'adrp';
types[2] = 'appe';
types[3] = 0;
GetRString (prompt, SPELL_PROMPT);
theError = GetFileNav (types, CHOOSE_WORD_SERVICE_NAV_TITLE, prompt, 0, false, &spec, &good, nil);
if (!good) return(userCanceledErr);
if (FileCreatorOf(&spec)==CREATOR)
{
WarnUser(NOT_SPELLER,0);
return (fnfErr);
}
UpdateAllWindows();
InstallSpeller(&spec);
return(noErr);
}
/**********************************************************************
* InstallSpeller - Install a spelling app from an FSSpec
**********************************************************************/
OSErr InstallSpeller(FSSpecPtr spec)
{
Str255 menuItem;
OSErr err;
AEAddressDesc spellerAD;
short item;
ProcessSerialNumber psn;
/*
* launch it
*/
LaunchAppWith(spec,nil,false);
/*
* look for it
*/
if (!(err=FindPSNByCreator(&psn,FileCreatorOf(spec))))
{
if (!(err=AECreateDesc(typeProcessSerialNumber,&psn,sizeof(psn),&spellerAD)))
{
/*
* ask server for menu name
*/
if (!(err = GetWSMenuItem(&spellerAD,menuItem)))
{
if (item = FindItemByName(GetMHandle(EDIT_MENU),menuItem))
DelWSService(item,false);
AddWSService(spec,menuItem);
QuitApp(&spellerAD);
}
else if (!CommandPeriod) WarnUser(NOT_SPELLER,err);
AEDisposeDesc(&spellerAD);
}
}
return(err);
}
/************************************************************************
* DelWSService - get rid of a word service
************************************************************************/
void DelWSService(short item,Boolean toolbarToo)
{
short n;
Handle res;
Str255 name;
/*
* remove psn
*/
if (WordServices)
{
n = GetHandleSize_(WordServices)/sizeof(**WordServices);
if (item<n-1) BMD((*WordServices)+item,(*WordServices)+item-1,
(n-item-1)*sizeof(**WordServices));
SetHandleBig_(WordServices,(n-1)*sizeof(**WordServices));
}
/*
* remove alias from settings file
*/
MyGetItem(GetMHandle(EDIT_MENU),item,name);
if (res = GetNamedResource(WS_ALIAS_TYPE,name)) {RemoveResource(res); ZapHandle(res);}
/*
* and menu item
*/
DeleteMenuItem(GetMHandle(EDIT_MENU),item);
/*
* and toolbar button, if any
*/
if (toolbarToo && ToolbarShowing()) TBRemoveDefunctMenuButton(EDIT_MENU,item);
}
/************************************************************************
* AddWSService - add a new service to the edit menu
************************************************************************/
OSErr AddWSService(FSSpecPtr spec, PStr menuItem)
{
AliasHandle alias;
Handle old;
short err;
OSType creator;
ProcessSerialNumber psn;
/*
* ask the server for its location
*/
if (err=NewAlias(nil,spec,&alias)) return(err);
(*alias)->userType = creator = FileCreatorOf(spec);
/*
* do we have one already?
*/
if (old = GetNamedResource(WS_ALIAS_TYPE,menuItem)) {RemoveResource(old); ZapHandle(old);}
/*
* add the new one
*/
AddMyResource_(alias,WS_ALIAS_TYPE,MyUniqueID(WS_ALIAS_TYPE),menuItem);
err = ResError();
if (err) ZapHandle(alias);
else
{
FindPSNByCreator(&psn,creator);
if (!WordServices) WordServices = NuHandle(0);
err = PtrPlusHand_(&psn,WordServices,sizeof(**WordServices));
if (!err) MyAppendMenu(GetMHandle(EDIT_MENU),menuItem);
}
/*
* frontify ourselves
*/
SetFrontProcess(CurrentPSN(&psn));
return(err);
}
/************************************************************************
* GetWSMenuItem - get the menu item from a word services app
************************************************************************/
OSErr GetWSMenuItem(AEAddressDescPtr aead, PStr itemText)
{
short err;
AEDesc ad;
if (err = GetAppProperty(aead,pBatchMenuString,typeChar,&ad)) return(err);
*itemText = MIN(61,AEGetDescDataSize(&ad));
AEGetDescData(&ad,itemText+1,*itemText);
itemText[*itemText+1] = 0;
AEDisposeDesc(&ad);
return(noErr);
}
/************************************************************************
* ServeThemWords -
************************************************************************/
OSErr ServeThemWords(short item,AEDescPtr objAD)
{
OSErr err;
err = VerifySpeller(item);
if (err==2) item = CountMenuItems(GetMHandle(EDIT_MENU));
if (!err) err = Spell(item,objAD);
return(err);
}
/************************************************************************
* VerifySpeller - is the speller running?
************************************************************************/
OSErr VerifySpeller(short item)
{
return(StartSpeller(item,False));
}
/************************************************************************
* StartSpeller - start the speller running
************************************************************************/
OSErr StartSpeller(short item,Boolean runningOnly)
{
Str255 name;
AliasHandle alias;
OSErr err;
ProcessSerialNumber psn;
MyGetItem(GetMHandle(EDIT_MENU),item,name);
if (!(alias=(AliasHandle)GetNamedResource(WS_ALIAS_TYPE,name)))
{
WarnUser(SPELL_ALIAS_GONE,0);
DelWSService(item,false);
return(1);
}
if (err = FindPSNByCreator(&psn,(*alias)->userType))
{
if (!runningOnly && !(err = LaunchByAlias(alias)))
{
MiniEvents();
return(StartSpeller(item,True));
}
}
else (*WordServices)[item-EDIT_SPELL_ITEM-1] = psn;
ReleaseResource_(alias);
if ((err==fnfErr||err==nsvErr||err==dirNFErr||err==userCanceledErr))
switch (AlertStr(REMOVE_SPELL_ALRT,Note,name))
{
case kAlertStdAlertOKButton: // locate application
FindSpeller();
TBarHasChanged = true;
err = 2; // signal caller to retry
break;
case kAlertStdAlertCancelButton: // cancel
break;
case kAlertStdAlertOtherButton: // remove application
DelWSService(item,true);
break;
}
return(err);
}
/************************************************************************
* Spell - tell the speller to go for it
************************************************************************/
OSErr Spell(short item,AEDescPtr objAD)
{
ProcessSerialNumber psn = (*WordServices)[item-EDIT_SPELL_ITEM-1];
AppleEvent ae;
AEDesc spellerAD;
OSErr err;
NullADList(&ae,&spellerAD,nil);
if (err = AECreateDesc(typeProcessSerialNumber,&psn,sizeof(psn),&spellerAD))
goto done;
if (err = AECreateAppleEvent(kWordServicesClass,kWSBatchCheckMe,&spellerAD,kAutoGenerateReturnID,kAnyTransactionID,&ae))
goto done;
#ifdef DEBUG
if (RunType==Debugging) {AEGetDescDataSize(objAD); if (MemError()) Debugger();}
#endif
if (err = AEPutParamDesc(&ae,keyDirectObject,objAD)) goto done;
err = MyAESend(&ae,nil,kAEQueueReply|kAECanInteract,kAENormalPriority,0);
done:
if (err) WarnUser(AE_TROUBLE,err);
DisposeADList(&ae,&spellerAD,nil);
return(noErr);
}
/************************************************************************
* GetProperty - get a property
************************************************************************/
OSErr GetProperty(AEAddressDescPtr aead, AEDescPtr objAD, DescType propType, DescType wantType, AEDescPtr ad)
{
AppleEvent ae, reply;
AEDesc propAD, propObj;
short err;
NullADList(&ae,&reply,&propObj,&propAD,nil);
/*
* create the event
*/
if (err = AECreateAppleEvent(kAECoreSuite,kAEGetData,aead,kAutoGenerateReturnID,kAnyTransactionID,&ae))
goto done;
/*
* create the property descriptor
*/
if (err = AECreateDesc(typeType,&propType,sizeof(propType),&propAD)) goto done;
/*
* create the property specifier
* Boy, this all sure is fun.
*/
if (err = CreateObjSpecifier(typeProperty,objAD,formPropertyID,&propAD,False,&propObj))
goto done;
/*
* add object to param list
*/
if (err = AEPutParamDesc(&ae,keyDirectObject,&propObj)) goto done;
/*
* now, send the event
*/
if (err = MyAESend(&ae,&reply,kAEWaitReply|kAECanInteract,kAENormalPriority,GetRLong(AE_SHORT_TIMEOUT_TICKS)))
goto done;
/*
* was there an error?
*/
if (err = GetAEError(&reply)) goto done;
/*
* finally; get the value
*/
err = AEGetParamDesc(&reply,keyDirectObject,wantType,ad);
done:
DisposeADList(&ae,&reply,&propObj,&propAD,nil);
return(err);
}
/************************************************************************
* GetAppProperty - get a property from an app
************************************************************************/
OSErr GetAppProperty(AEAddressDescPtr aead, DescType propType, DescType wantType, AEDescPtr ad)
{
AEDesc appAD;
short err;
NullADList(&appAD,nil);
err = GetProperty(aead,&appAD, propType, wantType, ad);
return(err);
}
#endif
/************************************************************************
* EmptyTrash - empty the trash mailbox
************************************************************************/
void EmptyTrash(Boolean localOnly, Boolean currentOnly, Boolean all)
{
Str15 suffix;
TOCHandle tocH;
short refN;
FSSpec spec;
short sum;
short imapTrash = IMAPCountTrashMessages(localOnly, currentOnly, all);
spec.vRefNum = MailRoot.vRef;
spec.parID = MailRoot.dirId;
GetRString(spec.name,TRASH);
/*
* check with Mom first
*/
if (!PrefIsSet(PREF_NO_TRASH_WARN))
{
if ((tocH=GetTrashTOC()) && ((*tocH)->count || imapTrash))
{
short totalMessages = 0;
if (localOnly) totalMessages = (*tocH)->count;
else if (currentOnly) totalMessages = imapTrash ? imapTrash : (*tocH)->count;
else totalMessages = (*tocH)->count + imapTrash;
if (!Mom(EMPTY_BUTTON,0,PREF_NO_TRASH_WARN,EMPTY_TRASH_FMT,totalMessages,totalMessages))
return;
}
else return;
}
#ifdef TWO
if (tocH = GetTrashTOC())
{
if (PrefIsSet(PREF_SERVER_DEL))
{
for (sum=0;sum<(*tocH)->count;sum++)
{
CycleBalls();
if (IdIsOnPOPD(PERS_POPD_TYPE(TS_TO_PPERS(tocH,sum)),POPD_ID,(*tocH)->sums[sum].uidHash))
AddIdToPOPD(PERS_POPD_TYPE(TS_TO_PPERS(tocH,sum)),DELETE_ID,(*tocH)->sums[sum].uidHash,False);
}
}
for (sum=0;sum<(*tocH)->count;sum++)
{
CycleBalls();
if ((*tocH)->sums[sum].opts & OPT_HAS_SPOOL) RemSpoolFolder((*tocH)->sums[sum].uidHash);
}
}
#endif
// empty all the IMAP trash mailboxes, return if there's nothing left to do
if (!IMAPEmptyTrash(localOnly, currentOnly, all)) return;
NukeXfUndo();
/*
* close messages
*/
// tocH = FindTOC(&spec);
// if (tocH)
if (tocH = GetTrashTOC())
for (sum=0;sum<(*tocH)->count;sum++)
{
if ((*tocH)->sums[sum].messH) CloseMyWindow(GetMyWindowWindowPtr((*(*tocH)->sums[sum].messH)->win));
DeleteMesgError(tocH,sum);
}
/*
* open and truncate the mailbox
*/
if (!AFSpOpenDF(&spec,&spec,fsRdWrPerm,&refN))
{
SetEOF(refN,0);
MyFSClose(refN);
FixSpecUnread(&spec,False);
FixMenuUnread(GetMHandle(MAILBOX_MENU),MAILBOX_TRASH_ITEM,False);
}
/*
* fix visible window
*/
if (tocH && (*tocH)->win)
{
(*tocH)->count = 0;
TOCSetDirty(tocH,true);
SetHandleSize((Handle)tocH,sizeof(TOCType));
MyWindowMaxes((*tocH)->win,0,0);
MyWindowDidResize((*tocH)->win,nil);
InvalContent((*tocH)->win);
}
else
{
/*
* delete the toc
*/
FSpKillRFork(&spec);
PCat(spec.name,GetRString(suffix,TOC_SUFFIX));
FSpDelete(&spec);
}
// Notify any search windows that we nuked the trash
SearchUpdateSum(nil,0,nil,0,false,true);
}
PStr AboutRegisterString(PStr s)
{
Str255 regCode, regName;
Str63 oldRegCode;
UserStateType state;
int policyCode,
regMonth;
short id;
state = GetNagState ();
GetRegFirst (state, regName);
if (regName[0])
PCatC (regName, ' ');
PCat (regName, GetRegLast (state, s));
GetRegCode (state, regCode);
*regCode = MIN(*regCode,254);
*regName = MIN(*regName,254);
if (!regName[0] || !regCode[0] || (regName[++regName[0]] = 0, regCode[++regCode[0]] = 0, !RegCodeVerifies(&regCode[1], &regName[1], nil, nil)))
{
regCode[0] = regName[0] = 0;
}
if(!regName[0])
GetRString (regName, NO_REG_NAME_TEXT);
if (!regCode[0])
GetRString (regCode, NO_REG_CODE_TEXT);
if(PayMode(state)) id = paidModeName;
else if(AdwareMode(state)) id = adModeName;
else if(FreeMode(state)) id = freeModeName;
else id = unknownModeName;
// Look for a Paid reg code and append the regMonth to the about string
if (ValidRegCode (paidUser, &policyCode, &regMonth))
ComposeRString(s,ABOUT_REG_WITH_MONTH,regName,regCode,ModeNamesStrn+id,regMonth);
else
ComposeRString(s,*GetPref(oldRegCode,PREF_SITE)?ABOUT_REG_W_OLD:ABOUT_REG,regName,regCode,ModeNamesStrn+id,oldRegCode);
return s;
}
/************************************************************************
* ReportABug - help the user submit a bug report
************************************************************************/
void ReportABug(void)
{
MyWindowPtr win;
Handle textH = GetResource('TEXT',BUG_TEXT);
if (textH)
{
HNoPurge(textH);
if (win=DoComposeNew(0))
{
WindowPtr winWP = GetMyWindowWindowPtr (win);
MessHandle messH =(MessHandle)GetWindowPrivateData(winWP);
ApplyStationeryHandle(win,textH,true,false,false);
InsertSystemConfig((*messH)->bodyPTE);
PersonalizeSubject(messH);
SerializeSubject(messH);
CompSelectSecondUnquoted(messH);
UpdateSum(messH,SumOf(messH)->offset,SumOf(messH)->length);
ShowMyWindow(winWP);
}
HPurge(textH);
}
}
/************************************************************************
* MakeASuggestion - help the user submit a suggestion
************************************************************************/
void MakeASuggestion(void)
{
MyWindowPtr win;
Handle textH = GetResource('TEXT',SUGGEST_TEXT);
if (textH)
{
HNoPurge(textH);
if (win=DoComposeNew(0))
{
WindowPtr winWP = GetMyWindowWindowPtr (win);
MessHandle messH =(MessHandle)GetWindowPrivateData(winWP);
ApplyStationeryHandle(win,textH,true,false,false);
PersonalizeSubject(messH);
SerializeSubject(messH);
UpdateSum(messH,SumOf(messH)->offset,SumOf(messH)->length);
ShowMyWindow(winWP);
}
HPurge(textH);
}
}