mirror of
https://github.com/evilneuro/eudora-mac.git
synced 2024-12-27 12:29:28 +00:00
1 line
111 KiB
C
Executable File
1 line
111 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 "ends.h"
|
||
#include "buildversion.h"
|
||
#define FILE_NUM 12
|
||
/* Copyright (c) 1990-1992 by the University of Illinois Board of Trustees */
|
||
/**********************************************************************
|
||
* initialization and cleanup
|
||
**********************************************************************/
|
||
|
||
#pragma segment Ends
|
||
typedef struct
|
||
{
|
||
Str31 *badNames;
|
||
short badCount;
|
||
Str31 newText;
|
||
#ifdef TWO
|
||
Str31 otherText;
|
||
#endif
|
||
#ifdef IMAP
|
||
Str31 thisBoxText;
|
||
#endif
|
||
short level;
|
||
CInfoPBRec hfi;
|
||
Str63 hfi_namePtr;
|
||
#ifdef IMAP
|
||
Str63 enclosingFolderName;
|
||
#endif
|
||
} BoxFolderDesc, *BoxFolderDescPtr;
|
||
#ifdef IMAP
|
||
typedef struct {FSSpec spec; Boolean isDir; Boolean hasUnread; Boolean skipIt; Boolean isIMAPpers; Boolean moveToTop; long imapAttributes;} NameType;
|
||
#else
|
||
typedef struct {FSSpec spec; Boolean isDir; Boolean hasUnread; Boolean skipIt;} NameType;
|
||
#endif
|
||
void ZapResMenu(short id);
|
||
Boolean HaveOptiMEM(void);
|
||
void doInitDEF(short resId,UniversalProcPtr upp,OSType type);
|
||
void SettingsInit(FSSpecPtr spec,Boolean system,Boolean changeUserState);
|
||
void OpenSettingsFile(FSSpecPtr spec);
|
||
void PutUpMenus(void);
|
||
void CreateBoxes(void);
|
||
void SetupInsurancePort(void);
|
||
void SetRunType(void);
|
||
Boolean ModernSystem(void);
|
||
void BoxFolder(short vRef,long dirId,MenuHandle *menus,BoxFolderDescPtr bfd,Boolean *anyUnread,Boolean appending,Boolean isIMAP);
|
||
void RemoveBoxMenus(void);
|
||
void BuildMarginMenu(void);
|
||
#ifdef NEVER
|
||
void MakeHmnusPurge(void);
|
||
void TrashHmnu(void);
|
||
#endif
|
||
void OpenPlugIns(void);
|
||
void MarkHavingUnread(MenuHandle mh, short item);
|
||
Boolean UsingNewTables(void);
|
||
void AwaitStartupAE(void);
|
||
void AddHelpMenuItems(void);
|
||
void AddWSMenuItems(void);
|
||
void Splash(void);
|
||
void MakeWordChars(void);
|
||
void ConvertSignature(void);
|
||
short PlugInDir(short vRef,long dirId);
|
||
void GenAliasList(void);
|
||
void BoxNamesSort(NameType **names);
|
||
int NameCompare(NameType *n1, NameType *n2);
|
||
void NameSwap(NameType *n1, NameType *n2);
|
||
void MakeUserFindSettings(FSSpecPtr spec);
|
||
Boolean MakeUserFindSettingsStd(FSSpecPtr spec);
|
||
void GetAndInsertHier(short menu);
|
||
#ifdef IMAP
|
||
Boolean InferUnread(CInfoPBRec *hfi, Boolean imap);
|
||
#else
|
||
Boolean InferUnread(CInfoPBRec *hfi);
|
||
#endif
|
||
void CheckAttachFolder(void);
|
||
void AddRes2HelpMenu(MenuHandle hm,Handle resH);
|
||
OSErr AddIconsToColorMenu(MenuHandle mh);
|
||
OSErr LogPlugins(void);
|
||
void SaneSettings(FSSpecPtr spec);
|
||
void HuntSpellswell(void);
|
||
Boolean HaveOT(void);
|
||
void CreateItemsFolder(void);
|
||
void CreateSpoolfolder(void);
|
||
void CreateMailFolder(void);
|
||
void CreatePartsfolder(void);
|
||
void CreateCachefolder(void);
|
||
#ifdef BATCH_DELIVERY_ON
|
||
void CreateDeliveryfolder(void);
|
||
#endif
|
||
OSErr LocalizeFiles(void);
|
||
void MoveMailboxesToMailFolder(void);
|
||
void ReloadStdSizes(void);
|
||
#ifdef LABEL_ICONS
|
||
OSErr RefreshLabelIcon(short item,RGBColor *color);
|
||
void UpdateLabelControls(void);
|
||
#endif
|
||
#ifdef USECMM
|
||
Boolean HaveCMM();
|
||
#endif
|
||
Boolean HaveVM(void);
|
||
Boolean FallbackSettings(FSSpecPtr spec);
|
||
OSErr LocalizeRename(FSSpecPtr spec,short id);
|
||
static void InitIntScript(void);
|
||
void ScanPrefs(void);
|
||
OSErr RegisterEudoraComponentFiles(void); // In peteglue.c
|
||
void AddCustomSortItems(void);
|
||
void InitCDEF(short resId,ControlDefProcPtr proc);
|
||
void InitLDEF(short resId,ListDefProcPtr proc);
|
||
pascal OSStatus ControlCNTLToCollection (Rect *bounds, SInt16 value, Boolean visible, SInt16 max, SInt16 min, SInt16 procID, SInt32 refCon, ConstStr255Param title, Collection collection);
|
||
|
||
#pragma segment Main
|
||
|
||
pascal void PeteCalled(Boolean entry);
|
||
pascal void PeteCalled(Boolean entry) {MemCanFail = entry;}
|
||
Boolean OkSettingsFileSpot(FSSpecPtr spec);
|
||
static void PrefillSettings(void);
|
||
static OSErr FindEudoraFolder(FSSpecPtr spec,StringPtr folder,short vRefNum,OSType folderType);
|
||
|
||
ModalFilterUPP DlgFilterUPP;
|
||
PETEGraphicHandlerProcPtr GraphicHandlers[] =
|
||
{
|
||
PersGraphic,
|
||
FileGraphic,
|
||
HorizRuleGraphic,
|
||
TableGraphic,
|
||
nil
|
||
};
|
||
|
||
#pragma segment Ends
|
||
/**********************************************************************
|
||
* Initialize - set up my stuff as well as the Mac managers
|
||
**********************************************************************/
|
||
void Initialize(void)
|
||
{
|
||
SInt32 gestaltResult;
|
||
|
||
#ifdef PEE
|
||
OSErr err;
|
||
short i;
|
||
#endif
|
||
|
||
VM = HaveVM();
|
||
MacInitialize(20,40 K); /* initialize mac managers */
|
||
SetQDGlobalsRandomSeed(LocalDateTime());
|
||
|
||
// Check for Appearance Extension
|
||
if (err = Gestalt(gestaltAppearanceAttr, &gestaltResult)) DieWithError(NO_APPEARANCE, err);
|
||
/* MJN *//* make sure the library is REALLY loaded and linked */
|
||
if ((long)RegisterAppearanceClient == kUnresolvedCFragSymbolAddress)
|
||
DieWithError(NO_APPEARANCE, cfragNoSymbolErr);
|
||
gAppearanceIsLoaded = true; // Okay, so we didn't die on loading AM
|
||
gGoodAppearance = !Gestalt(gestaltAppearanceVersion,&gestaltResult);
|
||
g16bitSubMenuIDs = gestaltResult >= 0x0110;
|
||
gBetterAppearance = gestaltResult >= 0x0110;
|
||
gBestAppearance = gestaltResult >= 0x0114;
|
||
gMaxBoxLevels = g16bitSubMenuIDs ? (BOX_MENU_LIMIT-BOX_MENU_START)/2 : OLD_MAX_BOX_LEVELS;
|
||
|
||
gHave85MenuMgr = !Gestalt(gestaltMenuMgrAttr,&gestaltResult)
|
||
&& gestaltResult&gestaltMenuMgrPresent
|
||
&& (long)EnableMenuItem != kUnresolvedCFragSymbolAddress;
|
||
|
||
SetRunType(); /* figure out what kind of run this is */
|
||
for (i=0;i<NSpare;i++) MakeGrow(SPARE_SIZE,i); /* reserve some memory for emergencies */
|
||
SetGrowZone(NewGrowZoneUPP(MyGrowZone)); /* let the mac know it's there */
|
||
DoMonitor = True;
|
||
ThereIsColor = utl_HaveColor();
|
||
if (!ModernSystem()) DieWithError(OLD_SYSTEM,0);
|
||
if (!(MousePen = NewRgn())) DieWithError(MEM_ERR,MemError());
|
||
if ((err = InitUnicode()) != noErr) DieWithError(MEM_ERR,err);
|
||
|
||
InitCarbonUtil(); // Set up Carbon utilities
|
||
|
||
RegisterProFeatures (); // (jp) Added to register each of the features supported in Pro
|
||
|
||
#ifdef USECMM
|
||
gHasCMM = HaveCMM();
|
||
if( gHasCMM && InitContextualMenus() )
|
||
gHasCMM = false;
|
||
#endif
|
||
|
||
InitIntScript();
|
||
OpenPlugIns();
|
||
|
||
#ifdef TWO
|
||
Splash();
|
||
#endif
|
||
InitLDEF(ICON_LDEF,SettingsListDef);
|
||
InitLDEF(TLATE_LDEF,TlateListDef);
|
||
#ifdef FANCY_FILT_LDEF
|
||
InitLDEF(FILT_LDEF,FiltListDef);
|
||
#endif
|
||
InitLDEF(FEATURE_LDEF,FeatureListDef);
|
||
InitCDEF(APP_CDEF,AppCdef);
|
||
InitCDEF(COL_CDEF,ColCdef);
|
||
InitCDEF(LIST_CDEF,ListCdef);
|
||
#ifdef DEBUG
|
||
InitCDEF(DEBUG_CDEF,DebugCdef);
|
||
#endif
|
||
InitLDEF(LISTVIEW_LDEF,ListViewListDef);
|
||
#ifdef TASK_PROGRESS_ON
|
||
InitLDEF(TASK_LDEF,ListItemDef);
|
||
#endif
|
||
|
||
INIT_UPP(DlgFilter,ModalFilter);
|
||
|
||
// Remember any plugins in the system (or extensions) folder.
|
||
// This must be called before PETEInit which installs all the
|
||
// components including the plug-ins. (ALB)
|
||
ETLGetSystemPlugins();
|
||
// Register for PETE and EMSAPI
|
||
RegisterEudoraComponentFiles();
|
||
#ifdef PEE
|
||
/*
|
||
* initialize editor
|
||
*/
|
||
if (err=PETEInit(&PETE,GraphicHandlers))
|
||
DieWithError(err==invalidComponentID ? NO_PETE:(err==afpBadVersNum?BAD_PETE:PETE_ERR),err);
|
||
PETESetMemFail(PETE,&MemCanFail);
|
||
#ifdef DEBUG
|
||
PETEDebugMode(PETE,RunType!=Production);
|
||
#endif
|
||
Pslh = NewZH(PETEStyleEntry);
|
||
PETESetCallback(PETE,nil,PeteCalled,peHasBeenCalled);
|
||
PETESetLabelCopyMask(PETE,LABEL_COPY_MASK);
|
||
#endif
|
||
|
||
ScanPrefs();
|
||
|
||
/* MJN *//* initialize LDAP and the LDAP utilities */
|
||
#ifdef LDAP_ENABLED
|
||
err = InitLDAP();
|
||
if (err)
|
||
DieWithError(LDAP_INIT_ERR, err);
|
||
#endif
|
||
|
||
/* MJN *//* initialize the nickname watcher */
|
||
err = InitNicknameWatcher();
|
||
if (err)
|
||
DieWithError(NICK_WATCHER_LOAD_ERR, err);
|
||
|
||
if (err=AEObjectInit()) DieWithError(INSTALL_AE,err);
|
||
InstallAE();
|
||
if (HasDragManager())
|
||
{
|
||
DECLARE_UPP(PantyTrack,DragTrackingHandler);
|
||
DECLARE_UPP(PantyReceive,DragReceiveHandler);
|
||
|
||
INIT_UPP(PantyTrack,DragTrackingHandler);
|
||
INIT_UPP(PantyReceive,DragReceiveHandler);
|
||
|
||
InstallTrackingHandler(PantyTrackUPP,nil,nil);
|
||
InstallReceiveHandler(PantyReceiveUPP,nil,nil);
|
||
}
|
||
MakeWordChars();
|
||
|
||
OTIs = HaveOT();
|
||
|
||
OptiMEMIs = HaveOptiMEM();
|
||
|
||
VicomIs = IsVICOM();
|
||
|
||
// The mailbox rename stack
|
||
if (!StackInit(sizeof(MBRenameProcPtr),&MBRenameStack))
|
||
{
|
||
MBRenameProcPtr proc;
|
||
|
||
proc = TellFiltMBRename; StackQueue(&proc,MBRenameStack);
|
||
proc = TellToolMBRename; StackQueue(&proc,MBRenameStack);
|
||
}
|
||
|
||
#ifdef DEMO
|
||
TimeBomb();
|
||
#endif
|
||
|
||
//LOGLINE;
|
||
AwaitStartupAE(); /* wait for the Finder to tell us what to do */
|
||
//LOGLINE;
|
||
|
||
UpdateFeatureUsage (gFeatureList);
|
||
|
||
#ifdef NAG
|
||
if (nagState)
|
||
CheckNagging ((*nagState)->state);
|
||
#endif
|
||
|
||
if (!JunkPrefDeadPluginsWarning() && ETLCountTranslatorsLo(EMSF_JUNK_MAIL,EMS_ModePaid)>ETLCountTranslators(EMSF_JUNK_MAIL))
|
||
JunkDownDialog();
|
||
}
|
||
|
||
/************************************************************************
|
||
* ScanPrefs - scan the prefs folder for "interesting" items
|
||
************************************************************************/
|
||
void ScanPrefs(void)
|
||
{
|
||
Str63 name;
|
||
CInfoPBRec hfi;
|
||
short vRef;
|
||
long dirId;
|
||
|
||
Zero(hfi);
|
||
hfi.hFileInfo.ioNamePtr = name;
|
||
hfi.hFileInfo.ioFDirIndex = 0;
|
||
if (!FindFolder(kOnSystemDisk,kPreferencesFolderType,False,&vRef,&dirId))
|
||
// keep going until we run out of files or find everything
|
||
#ifdef SPEECH_ENABLED
|
||
while((!AutoDoubler || !PrefsPlugIns || !*TCPprefFileSpec.name || !*PPPprefFileSpec.name || !*SpeechPrefFileSpec.name) &&
|
||
!DirIterate(vRef,dirId,&hfi))
|
||
#else
|
||
while((!AutoDoubler || !PrefsPlugIns || !*TCPprefFileSpec.name || !*PPPprefFileSpec.name) &&
|
||
!DirIterate(vRef,dirId,&hfi))
|
||
#endif
|
||
switch(hfi.hFileInfo.ioFlFndrInfo.fdCreator)
|
||
{
|
||
case TCP_PREF_FILE_CREATOR: // ot tcp prefs file
|
||
if (hfi.hFileInfo.ioFlFndrInfo.fdType == TCP_PREF_FILE_TYPE)
|
||
SimpleMakeFSSpec(vRef,dirId,name,&TCPprefFileSpec);
|
||
break;
|
||
case PPP_PREF_FILE_CREATOR:
|
||
if (hfi.hFileInfo.ioFlFndrInfo.fdType == PPP_PREF_FILE_TYPE)
|
||
SimpleMakeFSSpec(vRef,dirId,name,&PPPprefFileSpec);
|
||
break;
|
||
case CREATOR: // one of ours
|
||
PrefsPlugIns = True;
|
||
break;
|
||
case 'DDAP': // Autodoubler
|
||
if (hfi.hFileInfo.ioFlFndrInfo.fdType=='ADDA')
|
||
AutoDoubler = SyncRW = True;
|
||
break;
|
||
#ifdef SPEECH_ENABLED
|
||
case SPEECH_PREF_FILE_CREATOR: // Speech Preferences
|
||
if (hfi.hFileInfo.ioFlFndrInfo.fdType == SPEECH_PREF_FILE_TYPE)
|
||
SimpleMakeFSSpec (vRef, dirId, name, &SpeechPrefFileSpec);
|
||
break;
|
||
#endif
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
* ReloadStdSizes - reload standard font size array
|
||
************************************************************************/
|
||
void ReloadStdSizes(void)
|
||
{
|
||
short size;
|
||
short i;
|
||
short narml = FontSize;
|
||
short finnarml = FixedSize;
|
||
|
||
ZapHandle(StdSizes);
|
||
ZapHandle(FixedSizes);
|
||
StdSizes = NuHandle(0);
|
||
if (!StdSizes) DieWithError(MEM_ERR,MemError()); // yeah, right
|
||
FixedSizes = NuHandle(0);
|
||
if (!FixedSizes) DieWithError(MEM_ERR,MemError()); // yeah, right
|
||
for (i=1;;i++)
|
||
if (size=GetRLong(StdSizesStrn+i))
|
||
{
|
||
if (size==narml) narml = 0;
|
||
if (size==finnarml) finnarml = 0;
|
||
if (size>narml && narml)
|
||
{
|
||
PtrPlusHand(&narml,(Handle)StdSizes,sizeof(short));
|
||
narml = 0;
|
||
}
|
||
if (size>finnarml && finnarml)
|
||
{
|
||
PtrPlusHand(&finnarml,(Handle)FixedSizes,sizeof(short));
|
||
finnarml = 0;
|
||
}
|
||
PtrPlusHand(&size,(Handle)StdSizes,sizeof(short));
|
||
PtrPlusHand(&size,(Handle)FixedSizes,sizeof(short));
|
||
}
|
||
else break;
|
||
}
|
||
|
||
#ifdef USECMM
|
||
/**********************************************************************
|
||
* HaveCMM - do we have the contextual memory manager?
|
||
**********************************************************************/
|
||
Boolean HaveCMM()
|
||
{
|
||
#if !TARGET_RT_MAC_CFM
|
||
return true;
|
||
#else
|
||
return (InitContextualMenus != (void *)kUnresolvedCFragSymbolAddress) &&
|
||
(IsShowContextualMenuClick != (void *)kUnresolvedCFragSymbolAddress) &&
|
||
(ContextualMenuSelect != (void *)kUnresolvedCFragSymbolAddress) &&
|
||
(ProcessIsContextualMenuClient != (void *)kUnresolvedCFragSymbolAddress);
|
||
#endif
|
||
}
|
||
#endif
|
||
|
||
/**********************************************************************
|
||
* HaveVM - do we have VM?
|
||
**********************************************************************/
|
||
Boolean HaveVM(void)
|
||
{
|
||
long value;
|
||
|
||
if (Gestalt(gestaltVMAttr, &value)) return(False);
|
||
return((value&1)!=0);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* HaveOT - OpenTransport is lurking
|
||
**********************************************************************/
|
||
Boolean HaveOT(void)
|
||
{
|
||
long result;
|
||
OSErr err = Gestalt(gestaltOpenTpt, &result);
|
||
|
||
return(!err &&
|
||
(result & gestaltOpenTptPresentMask) &&
|
||
(result & gestaltOpenTptTCPPresentMask));
|
||
}
|
||
|
||
/**********************************************************************
|
||
* HaveOptiMEM - OptiMEM is lurking
|
||
**********************************************************************/
|
||
Boolean HaveOptiMEM(void)
|
||
{
|
||
long result;
|
||
OSErr err = Gestalt('xMe0', &result);
|
||
|
||
return(!err);
|
||
}
|
||
|
||
/************************************************************************
|
||
* MakeWordChars - set the IsWordChar array
|
||
************************************************************************/
|
||
void MakeWordChars(void)
|
||
{
|
||
short i;
|
||
|
||
for (i=0;i<256;i++)
|
||
IsWordChar[i] = (CharacterType(((Ptr)&i)+1,0,nil)&0xf)!=0;
|
||
}
|
||
|
||
#ifdef TWO
|
||
DialogPtr DBSplash;
|
||
void ChangeTEFont(TEHandle teh,short font,short size);
|
||
/************************************************************************
|
||
* Splash - show the splash box
|
||
************************************************************************/
|
||
void Splash(void)
|
||
{
|
||
MyWindowPtr dgWin;
|
||
DialogPtr dg;
|
||
Str255 versionString, regInfo;
|
||
Handle h;
|
||
short t;
|
||
Rect r,portR;
|
||
|
||
VersString(versionString);
|
||
AboutRegisterString(regInfo);
|
||
|
||
MyParamText(versionString,regInfo,"","");
|
||
SetDialogFont(SmallSysFontID());
|
||
dgWin = GetNewMyDialog(ABOUT_ALRT,nil,nil,InFront);
|
||
ConfigFontSetup(dgWin);
|
||
SetDialogFont(0);
|
||
if (dgWin)
|
||
{
|
||
dg = GetMyWindowDialogPtr (dgWin);
|
||
DBSplash = (void*)dg;
|
||
for (t=CountDITL(dg)-1;t>=12;t--) HideDialogItem(dg,t);
|
||
GetDialogItem(dg,5,&t,&h,&r);
|
||
GetPortBounds(GetDialogPort(dg),&portR);
|
||
SizeWindow(GetDialogWindow(dg),portR.right-portR.left,r.bottom+1,False);
|
||
ShowWindow(GetDialogWindow(dg));
|
||
UpdateMyWindow(GetDialogWindow(dg));
|
||
}
|
||
}
|
||
#endif
|
||
|
||
/************************************************************************
|
||
* ConvertSignature - move signature from Eudora Settings to external file
|
||
************************************************************************/
|
||
void ConvertSignature(void)
|
||
{
|
||
Str31 s;
|
||
FSSpec spec;
|
||
Handle sig;
|
||
long newDirId;
|
||
|
||
if (!DirCreate(Root.vRef,Root.dirId,GetRString(s,SIG_FOLDER),&newDirId))
|
||
{
|
||
/*
|
||
* created directory; read old sig
|
||
*/
|
||
GetRString(s,SETTINGS_FILE);
|
||
FSMakeFSSpec(Root.vRef,Root.dirId,s,&spec);
|
||
if (Snarf(&spec,&sig,0)) sig = NuHandle(0);
|
||
/*
|
||
* create new sig file
|
||
*/
|
||
FSMakeFSSpec(Root.vRef,newDirId,GetRString(s,SIGNATURE),&spec);
|
||
Blat(&spec,sig,False);
|
||
#ifdef TWO
|
||
FSMakeFSSpec(Root.vRef,newDirId,GetRString(s,ALT_SIG),&spec);
|
||
SetHandleBig_(sig,0);
|
||
Blat(&spec,sig,False);
|
||
#endif
|
||
ZapHandle(sig);
|
||
}
|
||
else
|
||
{
|
||
if (fnfErr==SigSpec(&spec,0)) FSpCreate(&spec,CREATOR,'TEXT',smSystemScript);
|
||
#ifdef TWO
|
||
if (fnfErr==SigSpec(&spec,1)) FSpCreate(&spec,CREATOR,'TEXT',smSystemScript);
|
||
#endif
|
||
}
|
||
|
||
// Convert old sig preference
|
||
if (CountStrn(PREF2_STRN)<PREF_SIGFILE-100)
|
||
{
|
||
if (PrefIsSet(PREF_SIG)) SetPrefLong(PREF_SIGFILE,SIG_STANDARD);
|
||
else SetPrefLong(PREF_SIGFILE,SIG_NONE);
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
* VersString - get the version number
|
||
************************************************************************/
|
||
PStr VersString(PStr versionString)
|
||
{
|
||
Handle version;
|
||
|
||
if (version = GetResource_(CREATOR,2))
|
||
{
|
||
PCopy(versionString,*version);
|
||
ReleaseResource_(version);
|
||
}
|
||
else
|
||
*versionString = 0;
|
||
|
||
#ifdef NEVER
|
||
if (PETE)
|
||
{
|
||
Str31 editor;
|
||
ComposeString(editor,"\p/Editor %d.%d",GetComponentVersion(PETE)>>16,GetComponentVersion(PETE)&0xffff);
|
||
PCat(versionString,editor);
|
||
}
|
||
#endif
|
||
|
||
return(versionString);
|
||
}
|
||
|
||
/************************************************************************
|
||
* SettingsInit - Initialize with a settings file
|
||
************************************************************************/
|
||
void SettingsInit(FSSpecPtr spec,Boolean system,Boolean changeUserState)
|
||
{
|
||
#ifdef NAG
|
||
InitNagResultType initNagResult;
|
||
#endif
|
||
Str255 scratch;
|
||
uLong aLong;
|
||
OSErr err;
|
||
|
||
StartingUp = true;
|
||
|
||
DateWarning(true); // annoy the user about his timezone
|
||
|
||
SubFolderSpec(0,nil); // clear the subfolder cache
|
||
|
||
MailRoot = Root; // until we create the mail folder
|
||
|
||
ZapHandle(CompactStack);
|
||
StackInit(sizeof(FSSpec),&CompactStack);
|
||
|
||
/*
|
||
* install other AE handlers
|
||
*/
|
||
InstallAERest();
|
||
|
||
if (EjectBuckaroo) {Cleanup();ExitToShell();}
|
||
|
||
ZapHandle(StringCache);
|
||
OpenSettingsFile(spec); /* open our settings file */
|
||
|
||
AuditStartup(kMyPlatformCode,MAJOR_VERSION*100+MINOR_VERSION*10+INC_VERSION,BUILD_VERSION);
|
||
|
||
/*
|
||
* Check out our ... anal
|
||
*/
|
||
AnalFindMine();
|
||
|
||
VicomFactor=GetRLong(VICOM_FACTOR);
|
||
BgYieldInterval=GetRLong(BG_YIELD_INTERVAL);
|
||
FgYieldInterval=GetRLong(FG_YIELD_INTERVAL);
|
||
|
||
ASSERT(Count1Resources(TOC_TYPE)==0);
|
||
|
||
|
||
InitPersonalities();
|
||
ProxyInit();
|
||
BuildSigList();
|
||
OTInitOpenTransport();
|
||
|
||
InitAppearanceMgr(); // Register Appearance and Live Scrolling
|
||
|
||
PrefillSettings();
|
||
|
||
#ifdef NAG
|
||
initNagResult = InitNagging ();
|
||
#endif
|
||
|
||
SwapQDTextFlags(PrefIsSet(PREF_QD_TEXT_ROUTINES) ? kQDUseTrueTypeScalerGlyphs : kQDUseCGTextRendering|kQDUseCGTextMetrics);
|
||
|
||
PETELiveScroll(PETE, PrefIsSet(PREF_LIVE_SCROLL));
|
||
HesiodKill();
|
||
FurrinSort = PrefIsSet(PREF_FURRIN_SORT);
|
||
SyncRW = AutoDoubler || PrefIsSet(PREF_SYNC_IO);
|
||
Offline = PrefIsSet(PREF_OFFLINE);
|
||
UseCTB = PrefIsSet(PREF_TRANS_METHOD);
|
||
CurTrans = GetTCPTrans();
|
||
UnreadStyle = GetRLong(UNREAD_STYLE);
|
||
NewTables = UsingNewTables();
|
||
NoPreflight = PrefIsSet(PREF_NO_CHECK_MEM);
|
||
LogLevel = GetPrefLong(PREF_LOG); // start logging
|
||
LocalizeFiles();
|
||
ConvertSignature();
|
||
CreateMailFolder(); /* make the mail folder and move stuff in it */
|
||
// do this before creating other folders & crap
|
||
#ifdef IMAP
|
||
CreateIMAPMailFolder(); /* make the folder for the IMAP cache */
|
||
RebuildAllIMAPMailboxTrees(); /* and build the personalities IMAP trees. */
|
||
#endif
|
||
CreateItemsFolder(); /* create folder for misc items */
|
||
CreateSpoolfolder(); /* create folder for outgoing spools */
|
||
#ifdef BATCH_DELIVERY_ON
|
||
CreateDeliveryfolder();
|
||
#endif
|
||
CreatePartsfolder(); /* create folder for mhmtl parts */
|
||
CreateCachefolder(); /* create folder for downloading html images */
|
||
FigureOutFont(True); /* figure out what font && size to use */
|
||
CreateBoxes(); /* create In and Out boxes, for later use */
|
||
GetAttFolderSpecLo(&AttFolderSpec);
|
||
PutUpMenus(); /* menus */
|
||
if (err=ConConInit()) DieWithError(COULDNT_INIT_CONCON,err); // ContentConcentrator
|
||
#ifdef IMAP
|
||
// make sure all the personalities have cache folders
|
||
CreateNewPersCaches();
|
||
// initialize the string we'll pass back IMAP errors with.
|
||
gIMAPErrorString[0] = 0;
|
||
#endif
|
||
if (!OptiMEMIs && CurrentSize()+10 K<EstimatePartitionSize(false)) MemoryWarning();
|
||
if (EjectBuckaroo) {Cleanup();ExitToShell();}
|
||
TOCList = nil; /* no open TOC's yet */
|
||
MessList = nil; /* no open messages yet */
|
||
SetSendQueue(); /* set SendQueue if there are queued messages */
|
||
EnableMenus(nil,False); /* enable appropriate items */
|
||
GenAliasList(); /* figure out where the alias lists are */
|
||
WrapWrong = CountResources('Rong') > 0;
|
||
Toshiba = PrefIsSet(PREF_TOSHIBA_FLUSH);
|
||
FakeTabs = PrefIsSet(PREF_TAB_IN_TEXT);
|
||
gNeedRemind = FindRemindLink(); /* see if the user needs to be reminded about any missed links */
|
||
D3 = ThereIsColor && PrefIsSet(PREF_3D);
|
||
if (!PrefIsSet(PREF_SAVE_PASSWORD)) SetPref(PREF_PASS_TEXT,"");
|
||
// Since SCNetworkCheckReachabilityByName is a piece of crap in 10.3 and before
|
||
// we make sure that we don't call it unless the user has explicitly enabled it.
|
||
if ( HaveTheDiseaseCalledOSX ())
|
||
if ( !*GetPref ( scratch, PREF_IGNORE_PPP ))
|
||
SetPref ( PREF_IGNORE_PPP, YesStr );
|
||
if (!*GetPref(scratch,PREF_AUTO_CHECK))
|
||
SetPref(PREF_AUTO_CHECK,GetPrefLong(PREF_INTERVAL)?YesStr:NoStr);
|
||
PersSetAutoCheck();
|
||
PETEAllowIntelligentEdit(PETE,!PrefIsSet(PREF_DUMB_PASTE));
|
||
PETEAnchoredSelection(PETE,PrefIsSet(PREF_ANCHORED_SELECTION));
|
||
|
||
OutgoingMIDListLoad();
|
||
|
||
GetRString(Re,REPLY_INTRO);
|
||
GetRString(Fwd,FWD_PREFIX);
|
||
GetRString(OFwd,OUTLOOK_FW_PREFIX);
|
||
TrimWhite(Re);
|
||
TrimWhite(Fwd);
|
||
TrimWhite(OFwd);
|
||
|
||
GetRString(NewLine,UseCTB ? CTB_NEWLINE : NEWLINE);
|
||
|
||
/*
|
||
* saved password?
|
||
*/
|
||
{
|
||
PersHandle old = CurPers;
|
||
for (CurPers=PersList;CurPers;CurPers=(*CurPers)->next) {
|
||
if(!PrefIsSet(PREF_SAVE_PASSWORD))
|
||
InvalidateCurrentPasswords(False,False);
|
||
else if(CurPers==PersList)
|
||
{
|
||
GetPref(scratch,PREF_PASS_TEXT);
|
||
PCopy((*CurPers)->password,scratch);
|
||
GetPref(scratch,PREF_AUXPW);
|
||
PCopy((*CurPers)->secondPass,scratch);
|
||
}
|
||
}
|
||
CurPers = old;
|
||
}
|
||
|
||
#ifdef HAVE_KEYCHAIN
|
||
if (KeychainAvailable() && !*GetPref(scratch,PREF_KEYCHAIN))
|
||
{
|
||
if (ComposeStdAlert(Normal,KEYCHAIN_WANNA)==1)
|
||
KeychainConvert();
|
||
else SetPref(PREF_KEYCHAIN,NoStr);
|
||
}
|
||
#endif //HAVE_KEYCHAIN
|
||
|
||
/*
|
||
* fix up some older settings
|
||
*/
|
||
ASSERT(resNotFound==Zap1Resource('STR ',973));
|
||
Zap1Resource('STR ',973);
|
||
if (!*GetPref(scratch,PREF_NEWMAIL_SOUND))
|
||
SetPref(PREF_ERROR_SOUND,GetResName(scratch,'snd ',ATTENTION_SND));
|
||
if (!*GetPref(scratch,PREF_NEWMAIL_SOUND))
|
||
SetPref(PREF_NEWMAIL_SOUND,GetResName(scratch,'snd ',NEW_MAIL_SND));
|
||
if (!PrefIsSet(PREF_BINHEX) && !PrefIsSet(PREF_DOUBLE) &&
|
||
!PrefIsSet(PREF_SINGLE) && !PrefIsSet(PREF_UUENCODE))
|
||
{
|
||
GetPref(scratch,PREF_ATT_TYPE);
|
||
if (!*scratch) scratch[1] = '0';
|
||
switch(scratch[1])
|
||
{
|
||
default: SetPref(PREF_DOUBLE,YesStr);break;
|
||
case atmSingle: SetPref(PREF_SINGLE,YesStr);break;
|
||
case atmUU: SetPref(PREF_UUENCODE,YesStr);break;
|
||
case atmHQX: SetPref(PREF_BINHEX,YesStr);break;
|
||
}
|
||
}
|
||
GetPref(scratch,PREF_NO_EZ_OPEN);
|
||
if (!*scratch || scratch[1]=='n') SetPref(PREF_NO_EZ_OPEN,"\p2");
|
||
else if (scratch[1]=='y') SetPref(PREF_NO_EZ_OPEN,"\p0");
|
||
|
||
if (GetPref(scratch,PREF_NO_PREVIEW_READ)[1]=='y') SetPrefLong(PREF_NO_PREVIEW_READ,1);
|
||
|
||
if (LogLevel & LOG_PLUG) LogPlugins();
|
||
|
||
if (CountStrn(900)<PREF_FURRIN_SORT-100)
|
||
{
|
||
SetPref(PREF_TOOLBAR,YesStr);
|
||
SetPref(PREF_TB_VARIATION,"\p1");
|
||
SetPref(PREF_3D,YesStr);
|
||
SetPref(PREF_FURRIN_SORT,NoStr);
|
||
}
|
||
|
||
if (!GetPrefLong(PREF_POP_MODE)) SetPrefLong(PREF_POP_MODE,popRUIDL);
|
||
|
||
switch (GetPref(scratch,PREF_NO_LINES)[1])
|
||
{
|
||
case 'y': SetPrefLong(PREF_NO_LINES,3); break;
|
||
case '\0': SetPrefLong(PREF_NO_LINES,2); break;
|
||
}
|
||
|
||
switch (GetPref(scratch,PREF_SEND_STYLE)[1])
|
||
{
|
||
case 'y': SetPrefLong(PREF_SEND_STYLE,1); break;
|
||
case 'n': case '\0': SetPrefLong(PREF_SEND_STYLE,0); break;
|
||
}
|
||
|
||
switch (GetPref(scratch,PREF_NICK_GEN_OPTIONS)[1])
|
||
{
|
||
case 'y': SetPrefLong(PREF_NICK_GEN_OPTIONS,1); break;
|
||
case 'n': case '\0': SetPrefLong(PREF_NICK_GEN_OPTIONS,0); break;
|
||
}
|
||
|
||
/*
|
||
* colors
|
||
*/
|
||
PeteSetupTextColors(nil,false);
|
||
|
||
/*
|
||
* Is the attachment folder ok?
|
||
*/
|
||
CheckAttachFolder();
|
||
|
||
/*
|
||
* fix old recip menus
|
||
*/
|
||
FixRecipMenu();
|
||
|
||
/*
|
||
* fix arrow settings
|
||
*/
|
||
GetPref(scratch,PREF_SWITCH_MODIFIERS);
|
||
if (scratch[1]=='y' || scratch[1]=='n' || !*scratch)
|
||
SetPrefLong(PREF_SWITCH_MODIFIERS,cmdKey);
|
||
|
||
/*
|
||
* fix connection hours weekend thing
|
||
*/
|
||
aLong = GetPrefLong(PREF_CHECK_HOURS);
|
||
if (!(aLong&(kHourAlwaysWeekendMask|kHourNeverWeekendMask|kHourUseWeekendMask)))
|
||
SetPrefLong(PREF_CHECK_HOURS,aLong|kHourAlwaysWeekendMask);
|
||
|
||
/*
|
||
* install help for transfer menu
|
||
*/
|
||
TransferMenuHelp(TFER_HMNU);
|
||
|
||
#ifdef WINTERTREE
|
||
// Spelling options
|
||
if (HasFeature (featureSpellChecking))
|
||
WinterTreeOptions = GetPrefLong(PREF_WINTERTREE_OPTS);
|
||
#endif
|
||
|
||
/*
|
||
* fix stupid new user settings
|
||
*/
|
||
if (*GetPref(scratch,PREF_POP_SIGH) && !*GetPref(scratch,PREF_STUPID_USER))
|
||
{
|
||
for (CurPers=PersList;CurPers;CurPers=(*CurPers)->next)
|
||
SetStupidStuff();
|
||
}
|
||
|
||
CurPers = PersList;
|
||
|
||
/*
|
||
* OS X AddressBook sync
|
||
*/
|
||
OSXAddressBookSync();
|
||
|
||
InitWazoos();
|
||
|
||
#ifdef LDAP_ENABLED
|
||
RefreshLDAPSettings();
|
||
#endif
|
||
RefreshNicknameWatcherGlobals (false);
|
||
|
||
#ifdef IMAP
|
||
/*
|
||
* Set Offline if shift was pressed before now.
|
||
*/
|
||
if (NoInitialCheck) SetPref(PREF_OFFLINE,YesStr);
|
||
#endif
|
||
|
||
// Initialize emoticons before we open any windows
|
||
EmoInit();
|
||
|
||
/*
|
||
* Upen the toolbar
|
||
*/
|
||
if (ToolbarShowing()) OpenToolbar();
|
||
if (PrefIsSet(PREF_TOOLBAR)) OpenToolbar();
|
||
|
||
/*
|
||
* start measuring face time
|
||
*/
|
||
FMBMain = NewFaceMeasure();
|
||
FaceMeasureBegin(FMBMain);
|
||
|
||
// start recording stats
|
||
InitStats();
|
||
|
||
/*
|
||
* Start showing ads
|
||
*/
|
||
OpenAdWindow();
|
||
|
||
/*
|
||
* Bring Out Yer Dead!
|
||
*/
|
||
if (!EjectBuckaroo) RecallOpenWindows();
|
||
|
||
/*
|
||
* run initial check
|
||
*/
|
||
#ifndef IMAP //Too late, we could be opening and resyncing IMAP windows already
|
||
if (NoInitialCheck) SetPref(PREF_OFFLINE,YesStr);
|
||
#endif
|
||
if (!EjectBuckaroo && PersCheckTicks() && AutoCheckOK())
|
||
CheckNow = True;
|
||
|
||
/*
|
||
* filter messages that were left behind
|
||
*/
|
||
#ifdef THREADING_ON
|
||
CleanRealOutTOC();
|
||
CleanTempOutTOC();
|
||
SetNeedToFilterOut();
|
||
NeedToFilterIn = 1; // make sure we check for delivery stuff
|
||
if (!PrefIsSet(PREF_FOREGROUND_IMAP_FILTERING))
|
||
NeedToFilterIMAP = 1;
|
||
gSkipIMAPBoxes = true; // we can skip any IMAP mailboxes for this first filter pass.
|
||
FilterXferMessages();
|
||
gSkipIMAPBoxes = false;
|
||
#endif
|
||
|
||
//
|
||
// Swap command keys with manual filtering
|
||
if (JunkPrefSwitchCmdJAsked())
|
||
{
|
||
if (JunkPrefSwitchCmdJ()) JunkReassignKeys(true);
|
||
}
|
||
else if (!HaveManualFilters() || kAlertStdAlertOKButton==ComposeStdAlert(Note,USE_CMD_J_FOR_JUNK))
|
||
{
|
||
JunkReassignKeys(true);
|
||
}
|
||
else
|
||
{
|
||
JunkReassignKeys(false);
|
||
}
|
||
SetPrefBit(PREF_JUNK_MAILBOX,bJunkPrefSwitchCmdJAsked);
|
||
|
||
if (GetCurrentPayMode()==EMS_ModePaid)
|
||
ClearPrefBit(PREF_JUNK_MAILBOX,bJunkPrefDeadPluginsWarning);
|
||
|
||
/*
|
||
* send the audit record?
|
||
*/
|
||
if (!NoInitialCheck) RandomSendAudit();
|
||
|
||
#ifdef NAG
|
||
if (initNagResult)
|
||
DoPendingNagDialog (initNagResult);
|
||
#endif
|
||
|
||
StartingUp = false;
|
||
}
|
||
|
||
#ifdef HAVE_KEYCHAIN
|
||
/**********************************************************************
|
||
* KeychainConvert - setup personalities to do the keychain
|
||
**********************************************************************/
|
||
void KeychainConvert(void)
|
||
{
|
||
PushPers(PersList);
|
||
for (CurPers=PersList;CurPers;CurPers=(*CurPers)->next)
|
||
{
|
||
InvalidateCurrentPasswords(False,False);
|
||
SetPref(PREF_SAVE_PASSWORD,YesStr);
|
||
}
|
||
SetPref(PREF_KEYCHAIN,YesStr);
|
||
PopPers();
|
||
}
|
||
#endif //HAVE_KEYCHAIN
|
||
|
||
/**********************************************************************
|
||
* CleanTempFolder - get rid of our stuff in the temp folder
|
||
**********************************************************************/
|
||
void CleanTempFolder(void)
|
||
{
|
||
short vRef;
|
||
long dirId;
|
||
CInfoPBRec hfi;
|
||
Str63 name;
|
||
|
||
FindFolder(Root.vRef,kTemporaryFolderType,True,&vRef,&dirId);
|
||
hfi.hFileInfo.ioNamePtr = name;
|
||
hfi.hFileInfo.ioFDirIndex = 0;
|
||
while (!DirIterate(vRef,dirId,&hfi))
|
||
if (hfi.hFileInfo.ioFlFndrInfo.fdCreator==CREATOR)
|
||
{
|
||
OSErr err;
|
||
err = HDelete(vRef,dirId,name);
|
||
if (!err)
|
||
hfi.hFileInfo.ioFDirIndex--; // Don't skip next entry
|
||
}
|
||
}
|
||
|
||
/**********************************************************************
|
||
*
|
||
**********************************************************************/
|
||
OSErr LocalizeFiles(void)
|
||
{
|
||
FSSpec spec, tocSpec;
|
||
short rootfiles[] = {
|
||
USA_NICKNAME_FOLDER, NICK_FOLDER,
|
||
USA_EUDORA_NICKNAMES, ALIAS_FILE,
|
||
USA_CACHE_ALIAS_FILE, CACHE_ALIAS_FILE,
|
||
USA_PERSONAL_ALIAS_FILE, PERSONAL_ALIAS_FILE,
|
||
USA_STATISTICS_FILE, STATISTICS_FILE,
|
||
USA_ATTACHMENTS_FOLDER, ATTACH_FOLDER,
|
||
USA_SIG_FOLDER, SIG_FOLDER,
|
||
USA_STATION_FOLDER, STATION_FOLDER,
|
||
USA_SPOOL_FOLDER, SPOOL_FOLDER,
|
||
#ifdef BATCH_DELIVERY_ON
|
||
USA_DELIVERY_FOLDER, DELIVERY_FOLDER,
|
||
#endif
|
||
USA_MISPLACED_FOLDER, MISPLACED_FOLDER,
|
||
0,0};
|
||
short mailfiles[] = {
|
||
USA_IN, IN,
|
||
USA_OUT, OUT,
|
||
USA_TRASH, TRASH,
|
||
0,0};
|
||
OSErr err = noErr;
|
||
short *file;
|
||
|
||
spec.vRefNum = Root.vRef;
|
||
spec.parID = Root.dirId;
|
||
for (file=rootfiles;*file;file+=2)
|
||
{
|
||
if (!EqualStrRes(GetRString(spec.name,file[1]),file[0]))
|
||
LocalizeRename(&spec,file[0]);
|
||
}
|
||
spec.vRefNum = MailRoot.vRef;
|
||
spec.parID = MailRoot.dirId;
|
||
for (file=mailfiles;*file;file+=2)
|
||
{
|
||
if (!EqualStrRes(GetRString(spec.name,file[1]),file[0]))
|
||
{
|
||
LocalizeRename(&spec,file[0]);
|
||
Box2TOCSpec(&spec,&tocSpec); // usa .toc name in tocSpec
|
||
GetRString(spec.name,file[1]);
|
||
Box2TOCSpec(&spec,&spec); // local .toc name in spec
|
||
FSpRename(&tocSpec,&spec.name); // will fail if local .toc exists; ok
|
||
}
|
||
}
|
||
|
||
/*
|
||
* a few files in subfolders
|
||
*/
|
||
if (!(err=SubFolderSpec(NICK_FOLDER,&spec)))
|
||
{
|
||
GetRString(spec.name, PHOTO_FOLDER);
|
||
LocalizeRename(&spec, USA_PHOTO_FOLDER);
|
||
#ifdef VCARD
|
||
GetRString(spec.name, VCARD_FOLDER);
|
||
LocalizeRename(&spec, USA_VCARD_FOLDER);
|
||
#endif
|
||
}
|
||
if (!(err=SubFolderSpec(STATION_FOLDER,&spec)))
|
||
{
|
||
GetRString(spec.name,DEFAULT);
|
||
LocalizeRename(&spec,USA_DEFAULT);
|
||
}
|
||
if (!(err=SubFolderSpec(SIG_FOLDER,&spec)))
|
||
{
|
||
GetRString(spec.name,SIGNATURE);
|
||
LocalizeRename(&spec,USA_SIGNATURE);
|
||
GetRString(spec.name,ALT_SIG);
|
||
LocalizeRename(&spec,USA_ALTERNATE);
|
||
}
|
||
return err;
|
||
}
|
||
|
||
/**********************************************************************
|
||
*
|
||
**********************************************************************/
|
||
OSErr LocalizeRename(FSSpecPtr spec,short id)
|
||
{
|
||
Str63 newName;
|
||
FSSpec origSpec = *spec;
|
||
|
||
PCopy(newName,spec->name);
|
||
GetRString(origSpec.name,id);
|
||
return(FSpRename(&origSpec,&newName));
|
||
}
|
||
|
||
/**********************************************************************
|
||
* CreateItemsFolder - make the Eudora Items folder
|
||
**********************************************************************/
|
||
void CreateItemsFolder(void)
|
||
{
|
||
FSSpec spec;
|
||
Str63 folder;
|
||
long junk;
|
||
CInfoPBRec hfi;
|
||
short pluginsVRefNum;
|
||
long pluginsDirID;
|
||
|
||
// Make Eudora Items folder
|
||
FSMakeFSSpec(Root.vRef,Root.dirId,GetRString(folder,ITEMS_FOLDER),&spec);
|
||
FSpDirCreate(&spec,smSystemScript,&junk);
|
||
AFSpGetCatInfo(&spec,&spec,&hfi);
|
||
IsAlias(&spec,&spec);
|
||
ItemsFolder.dirId = SpecDirId(&spec);
|
||
ItemsFolder.vRef = spec.vRefNum;
|
||
|
||
// Make Plugins folder for plugin preferences
|
||
FSMakeFSSpec(ItemsFolder.vRef,ItemsFolder.dirId,GetRString(folder,PLUGINS_FOLDER),&spec);
|
||
IsAlias(&spec,&spec);
|
||
FSpDirCreate(&spec,smSystemScript,&junk);
|
||
pluginsVRefNum = spec.vRefNum;
|
||
pluginsDirID = SpecDirId(&spec);
|
||
|
||
// Make plugin Filter and Nicknames folders inside plugin folder
|
||
FSMakeFSSpec(pluginsVRefNum,pluginsDirID,GetRString(folder,PLUGIN_FILTERS),&spec);
|
||
FSpDirCreate(&spec,smSystemScript,&junk);
|
||
FSMakeFSSpec(pluginsVRefNum,pluginsDirID,GetRString(folder,PLUGIN_NICKNAMES),&spec);
|
||
FSpDirCreate(&spec,smSystemScript,&junk);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* CreateSpoolfolder - make the user's spool folder
|
||
**********************************************************************/
|
||
void CreateSpoolfolder(void)
|
||
{
|
||
FSSpec spec;
|
||
Str63 folder;
|
||
long junk;
|
||
|
||
|
||
FSMakeFSSpec(Root.vRef,Root.dirId,GetRString(folder,SPOOL_FOLDER),&spec);
|
||
FSpDirCreate(&spec,smSystemScript,&junk);
|
||
}
|
||
|
||
#ifdef BATCH_DELIVERY_ON
|
||
/**********************************************************************
|
||
* CreateDeliveryfolder - make the user's delivery folder
|
||
**********************************************************************/
|
||
void CreateDeliveryfolder(void)
|
||
{
|
||
FSSpec spec;
|
||
Str63 folder;
|
||
long junk;
|
||
|
||
FSMakeFSSpec(Root.vRef,Root.dirId,GetRString(folder,DELIVERY_FOLDER),&spec);
|
||
FSpDirCreate(&spec,smSystemScript,&junk);
|
||
}
|
||
#endif
|
||
|
||
/**********************************************************************
|
||
* CreatePartsfolder - make the user's part folder
|
||
**********************************************************************/
|
||
void CreatePartsfolder(void)
|
||
{
|
||
FSSpec spec;
|
||
Str63 folder;
|
||
long junk;
|
||
OSErr err;
|
||
Boolean isFolder, boolJunk;
|
||
Boolean created;
|
||
|
||
|
||
err=FSMakeFSSpec(Root.vRef,Root.dirId,GetRString(folder,PARTS_FOLDER),&spec);
|
||
if (created = err==fnfErr) err = FSpDirCreate(&spec,smSystemScript,&junk);
|
||
|
||
if (!err)
|
||
{
|
||
err = ResolveAliasFile(&spec,True,&isFolder,&boolJunk);
|
||
if (!err && !folder) err = fnfErr;
|
||
}
|
||
}
|
||
|
||
/**********************************************************************
|
||
* CreateCachefolder - make the user's part folder
|
||
**********************************************************************/
|
||
void CreateCachefolder(void)
|
||
{
|
||
FSSpec spec;
|
||
Str63 folder;
|
||
long junk;
|
||
OSErr err;
|
||
|
||
err=FSMakeFSSpec(Root.vRef,Root.dirId,GetRString(folder,CACHE_FOLDER),&spec);
|
||
if (err==fnfErr) FSpDirCreate(&spec,smSystemScript,&junk);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* CreateMailFolder - make the user's mail folder
|
||
**********************************************************************/
|
||
void CreateMailFolder(void)
|
||
{
|
||
FSSpec spec;
|
||
Str63 folder;
|
||
long junk;
|
||
OSErr err;
|
||
Boolean isFolder, boolJunk;
|
||
Boolean created;
|
||
|
||
|
||
err=FSMakeFSSpec(Root.vRef,Root.dirId,GetRString(folder,MAIL_FOLDER_NAME),&spec);
|
||
if (created = err==fnfErr) err = FSpDirCreate(&spec,smSystemScript,&junk);
|
||
|
||
if (!err)
|
||
{
|
||
err = ResolveAliasFile(&spec,True,&isFolder,&boolJunk);
|
||
if (!err && !folder) err = fnfErr;
|
||
}
|
||
if (err) DieWithError(MAIL_FOLDER,err);
|
||
|
||
MailRoot.vRef = spec.vRefNum;
|
||
MailRoot.dirId = SpecDirId(&spec);
|
||
|
||
if (created) MoveMailboxesToMailFolder();
|
||
}
|
||
|
||
/************************************************************************
|
||
* MoveMailboxesToMailFolder - move things to the mail folder
|
||
************************************************************************/
|
||
void MoveMailboxesToMailFolder(void)
|
||
{
|
||
#ifdef BATCH_DELIVERY_ON
|
||
short badIndices[] = {ALIAS_FILE,CACHE_ALIAS_FILE,PERSONAL_ALIAS_FILE,LOG_NAME,OLD_LOG,FILTERS_NAME,SIG_FOLDER,NICK_FOLDER,PHOTO_FOLDER,ATTACH_FOLDER,STATION_FOLDER,SPOOL_FOLDER,ITEMS_FOLDER,MAIL_FOLDER_NAME,IMAP_MAIL_FOLDER_NAME,CACHE_FOLDER,PARTS_FOLDER,LINK_HISTORY_FOLDER,AUDIT_FILE,DELIVERY_FOLDER};
|
||
#else
|
||
short badIndices[] = {ALIAS_FILE,CACHE_ALIAS_FILE,PERSONAL_ALIAS_FILE,LOG_NAME,OLD_LOG,FILTERS_NAME,SIG_FOLDER,NICK_FOLDER,PHOTO_FOLDER,ATTACH_FOLDER,STATION_FOLDER,SPOOL_FOLDER,ITEMS_FOLDER.MAIL_FOLDER_NAME,IMAP_MAIL_FOLDER_NAME,CACHE_FOLDER,PARTS_FOLDER,LINK_HISTORY_FOLDER,AUDIT_FILE};
|
||
#endif
|
||
Str31 badNames[sizeof(badIndices)/sizeof(short)];
|
||
short i,bad;
|
||
CInfoPBRec hfi;
|
||
Str31 name;
|
||
OSErr err;
|
||
FSSpec spec;
|
||
|
||
// load up the list of names we don't like
|
||
for (i=0;i<sizeof(badIndices)/sizeof(short);i++)
|
||
GetRString(badNames[i],badIndices[i]);
|
||
|
||
// Now, go through the root folder, moving as we go
|
||
Zero(hfi);
|
||
hfi.hFileInfo.ioNamePtr = name;
|
||
for (hfi.hFileInfo.ioFDirIndex=i=0;
|
||
!DirIterate(Root.vRef,Root.dirId,&hfi);
|
||
hfi.hFileInfo.ioFDirIndex=++i)
|
||
{
|
||
SimpleMakeFSSpec(Root.vRef,Root.dirId,name,&spec);
|
||
if (HFIIsFolderOrAlias(&hfi) || hfi.hFileInfo.ioFlFndrInfo.fdType==MAILBOX_TYPE || hfi.hFileInfo.ioFlFndrInfo.fdType==TOC_TYPE)
|
||
{
|
||
for (bad=0;bad<sizeof(badIndices)/sizeof(short);bad++)
|
||
if (StringSame(badNames[bad],name)) break;
|
||
if (bad==sizeof(badIndices)/sizeof(short))
|
||
{
|
||
// move it!
|
||
if (err = HMove(Root.vRef,Root.dirId,name,MailRoot.dirId,nil))
|
||
{
|
||
FileSystemError(MOVING_MAILBOXES,name,err);
|
||
if (CommandPeriod) break;
|
||
}
|
||
else i--;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* LogPlugins - log the resources in open files
|
||
**********************************************************************/
|
||
OSErr LogPlugins(void)
|
||
{
|
||
short refN;
|
||
FSSpec spec;
|
||
Str31 volName;
|
||
Handle r;
|
||
OSType type;
|
||
Str255 rName;
|
||
short id;
|
||
short typeCount;
|
||
short resCount;
|
||
|
||
for (GetTopResourceFile(&refN); refN!=AppResFile; GetNextResourceFile(refN,&refN))
|
||
{
|
||
if (GetFileByRef(refN,&spec)) break;
|
||
GetDirName(nil,spec.vRefNum,spec.parID,volName);
|
||
ComposeLogS(LOG_PLUG,nil,"\p%p:%p",volName,spec.name);
|
||
|
||
UseResFile(refN);
|
||
for (typeCount = Count1Types(); typeCount; typeCount--)
|
||
{
|
||
Get1IndType(&type,typeCount);
|
||
for (resCount = Count1Resources(type); resCount; resCount--)
|
||
{
|
||
SetResLoad(False);
|
||
r = Get1IndResource(type,resCount);
|
||
SetResLoad(True);
|
||
if (r)
|
||
{
|
||
GetResInfo(r,&id,&type,rName);
|
||
UseResFile(SettingsRefN);
|
||
ComposeLogS(LOG_PLUG,nil,"\p %O %d %p",type,id,rName);
|
||
UseResFile(refN);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
UseResFile(SettingsRefN);
|
||
return noErr;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* CheckAttachFolder - check to see if the user's real attachment folder exists
|
||
**********************************************************************/
|
||
void CheckAttachFolder(void)
|
||
{
|
||
Str127 pref, volname;
|
||
long dirID;
|
||
|
||
GetPref(pref,PREF_AUTOHEX_VOLPATH);
|
||
if (*pref && !GetVolpath(pref,volname,&dirID))
|
||
{
|
||
switch (ComposeStdAlert(kAlertNoteAlert,NO_ATTACH_FOLDER))
|
||
{
|
||
case kAlertStdAlertOKButton:
|
||
SetPref(PREF_AUTOHEX_VOLPATH,"");
|
||
SetPref(PREF_AUTOHEX_NAME,"");
|
||
break;
|
||
case kAlertStdAlertOtherButton:
|
||
if (GetHexPath(volname,pref))
|
||
{
|
||
SetPref(PREF_AUTOHEX_NAME,volname);
|
||
SetPref(PREF_AUTOHEX_VOLPATH,pref);
|
||
}
|
||
break;
|
||
default:; // leave it for next time
|
||
}
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
* GenAliasList - find the alias list
|
||
************************************************************************/
|
||
void GenAliasList(void)
|
||
{
|
||
Str31 name;
|
||
FSSpec folderSpec;
|
||
AliasDesc ad;
|
||
|
||
/*
|
||
* clear out the old, allocate empty handle for new
|
||
*/
|
||
if (Aliases) ZapHandle(Aliases);
|
||
if (!(Aliases=NuHandle(0L))) DieWithError(MEM_ERR,MemError());
|
||
|
||
#ifdef VCARD
|
||
/*
|
||
* add the Personal Nicknames file (we do this whether or not the feature is turned on)
|
||
*/
|
||
if (HasFeature (featureVCard)) {
|
||
Zero(ad);
|
||
ad.type = personalAddressBook;
|
||
FSMakeFSSpec(Root.vRef,Root.dirId,GetRString(name,PERSONAL_ALIAS_FILE),&ad.spec);
|
||
if (PtrPlusHand_(&ad,Aliases,sizeof(ad))) DieWithError(MEM_ERR,MemError());
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
* add the Eudora Nicknames file
|
||
*/
|
||
Zero(ad);
|
||
ad.type = eudoraAddressBook;
|
||
FSMakeFSSpec(Root.vRef,Root.dirId,GetRString(name,ALIAS_FILE),&ad.spec);
|
||
if (PtrPlusHand_(&ad,Aliases,sizeof(ad))) DieWithError(MEM_ERR,MemError());
|
||
|
||
#ifdef TWO
|
||
/*
|
||
* is there a nicknames folder?
|
||
*/
|
||
if (HasFeature (featureMultipleNicknameFiles) && !SubFolderSpec(NICK_FOLDER,&folderSpec))
|
||
ReadNickFileList (&folderSpec, regularAddressBook, false);
|
||
|
||
/*
|
||
* add the Eudora Nicknames Cache file
|
||
*/
|
||
if (HasFeature (featureNicknameWatching)) {
|
||
Zero(ad);
|
||
ad.type = historyAddressBook;
|
||
FSMakeFSSpec(Root.vRef,Root.dirId,GetRString(name,CACHE_ALIAS_FILE),&ad.spec);
|
||
if (PtrPlusHand_(&ad,Aliases,sizeof(ad))) DieWithError(MEM_ERR,MemError());
|
||
}
|
||
ReadPluginNickFiles(false);
|
||
#endif
|
||
}
|
||
|
||
/************************************************************************
|
||
* UsingNewTables - are we using the new translit table scheme?
|
||
************************************************************************/
|
||
Boolean UsingNewTables(void)
|
||
{
|
||
Boolean found=False;
|
||
Handle table;
|
||
short ind=0;
|
||
Str255 name;
|
||
short id;
|
||
ResType type;
|
||
|
||
SetResLoad(False);
|
||
while (table=GetIndResource_('taBL',++ind))
|
||
{
|
||
GetResInfo(table,&id,&type,&name);
|
||
if (found=(id<1001||id>1003)&&*name) break;
|
||
}
|
||
SetResLoad(True);
|
||
return(found);
|
||
}
|
||
|
||
/************************************************************************
|
||
* OpenNewSettings - open a new settings file, closing things out
|
||
* properly first
|
||
*
|
||
* (10/4/99 jp) Modified a bit for adware to save the settings FSSpec so
|
||
* we can pass it back in on a relaunch.
|
||
************************************************************************/
|
||
void OpenNewSettings(FSSpecPtr spec, Boolean changeUserState, UserStateType newState)
|
||
{
|
||
short menu;
|
||
MenuHandle mHandle;
|
||
|
||
if (!OkSettingsFileSpot(spec))
|
||
{
|
||
if (SettingsRefN) return;
|
||
Cleanup();
|
||
ExitToShell();
|
||
}
|
||
|
||
if (SettingsRefN)
|
||
{
|
||
/*
|
||
* a simulated Quit
|
||
*/
|
||
DoQuit(changeUserState);
|
||
if (changeUserState)
|
||
(*nagState)->state = newState;
|
||
if (!AmQuitting) return;
|
||
Done = False;
|
||
|
||
/*
|
||
* let's get rid of some stuff
|
||
*/
|
||
KillWazoos();
|
||
RemoveBoxMenus();
|
||
#ifdef TWO
|
||
NukeXfUndo();
|
||
#endif
|
||
CloseAdWindow();
|
||
|
||
if (mHandle=GetMHandle(LABEL_HIER_MENU)) TrashMenu(mHandle,3); // kill it to get rid of icon suites
|
||
ZapResMenu(COLOR_HIER_MENU);
|
||
ZapResMenu(SIG_HIER_MENU);
|
||
ZapResMenu(SORT_HIER_MENU);
|
||
ZapResMenu(FONT_HIER_MENU);
|
||
ZapResMenu(MARGIN_HIER_MENU);
|
||
ZapResMenu(TEXT_HIER_MENU);
|
||
if (HasFeature (featureMultiplePersonalities))
|
||
ZapResMenu(PERS_HIER_MENU);
|
||
ZapResMenu(TEXT_SIZE_HIER_MENU);
|
||
ZapResMenu(SERVER_HIER_MENU);
|
||
#ifdef WINTERTREE
|
||
if (HasFeature (featureSpellChecking))
|
||
ZapResMenu(SPELL_HIER_MENU);
|
||
#endif
|
||
|
||
for (menu=APPLE_MENU;menu<MENU_LIMIT;menu++)
|
||
{
|
||
if (mHandle=GetMHandle(menu)) ReleaseResource_(mHandle);
|
||
}
|
||
if (!HMGetHelpMenuHandle(&mHandle) && mHandle) /* the check for nil is needed courtesy of Norton Utilities, crap that it is */
|
||
if (HaveTheDiseaseCalledOSX())
|
||
{
|
||
// destroy the entire menu
|
||
HMGetHelpMenuHandle(nil);
|
||
ReleaseResource_(mHandle);
|
||
}
|
||
else
|
||
// kill our items only
|
||
TrashMenu(mHandle,OriginalHelpCount+1);
|
||
ClearMenuBar();
|
||
ZapAliases();
|
||
ZapHandle(Aliases);
|
||
ZapHistoriesList(true);
|
||
ZapFilters();
|
||
ZapHandle(Filters);
|
||
ConConDispose();
|
||
#ifdef IMAP
|
||
DisposePersIMAPMailboxTrees();
|
||
#endif
|
||
DisposePersonalities();
|
||
ProxyZap();
|
||
}
|
||
AmQuitting = False;
|
||
//if (ToolbarShowing()) OpenToolbar();
|
||
|
||
/*
|
||
* Now, point us at the right directory
|
||
*/
|
||
|
||
(void) IsAlias(spec,spec);
|
||
Root.vRef = spec->vRefNum;
|
||
Root.dirId = spec->parID;
|
||
SettingsFileSpec = *spec;
|
||
|
||
/*
|
||
* keep yer fingers crossed...
|
||
*/
|
||
SettingsInit(spec,False,changeUserState);
|
||
}
|
||
|
||
/************************************************************************
|
||
* OkSettingsFileSpot - does this look like a good spot for Eudora Settings?
|
||
************************************************************************/
|
||
Boolean OkSettingsFileSpot(FSSpecPtr spec)
|
||
{
|
||
Str31 name;
|
||
Str31 otherName;
|
||
short vRef;
|
||
long dirID;
|
||
short i;
|
||
static OSType baaaadPlaces[] = {kAppleMenuFolderType,kControlPanelFolderType,kDesktopFolderType,
|
||
kExtensionFolderType,kFontsFolderType,kPreferencesFolderType,kPrintMonitorDocsFolderType,
|
||
kStartupFolderType,kSystemFolderType,kTemporaryFolderType,kTrashFolderType,kWhereToEmptyTrashFolderType};
|
||
FSSpec otherSpec;
|
||
|
||
// we may need the name
|
||
GetDirName(nil,spec->vRefNum,spec->parID,name);
|
||
|
||
// root volumes no good
|
||
if (spec->parID==2)
|
||
{
|
||
ComposeStdAlert(Stop,NO_EF_DESKTOP,name);
|
||
return(False);
|
||
}
|
||
|
||
// special folders no good
|
||
for (i=0;i<sizeof(baaaadPlaces)/sizeof(OSType);i++)
|
||
if (!FindFolder(spec->vRefNum,baaaadPlaces[i],false,&vRef,&dirID))
|
||
if (spec->vRefNum==vRef && spec->parID==dirID)
|
||
{
|
||
ComposeStdAlert(Stop,NO_EF_DESKTOP,name);
|
||
return(False);
|
||
}
|
||
|
||
if (!FSMakeFSSpec(spec->vRefNum,spec->parID,GetRString(otherName,MAIL_FOLDER_NAME),&otherSpec)) return (True); // we like it!
|
||
if (FSMakeFSSpec(spec->vRefNum,spec->parID,GetRString(otherName,IN),&otherSpec) ||
|
||
FSMakeFSSpec(spec->vRefNum,spec->parID,GetRString(otherName,OUT),&otherSpec))
|
||
return(ComposeStdAlert(Caution,EF_WARNING,name,name)==kAlertStdAlertOKButton);
|
||
|
||
return(True);
|
||
}
|
||
|
||
/**********************************************************************
|
||
*
|
||
**********************************************************************/
|
||
void ZapResMenu(short id)
|
||
{
|
||
MenuHandle mHandle;
|
||
|
||
if (mHandle=GetMHandle(id))
|
||
{
|
||
DeleteMenu(id);
|
||
ReleaseResource_(mHandle);
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
* SetRunType - figure out from the name of the app whether we're prod-
|
||
* uction, testing, or my private version. This is a HACK.
|
||
************************************************************************/
|
||
void SetRunType(void)
|
||
{
|
||
#ifdef DEBUG
|
||
FSSpec appSpec;
|
||
#endif
|
||
|
||
AppResFile = HomeResFile(GetIndResource(CREATOR, 1));
|
||
|
||
#ifdef DEBUG
|
||
GetFileByRef(AppResFile,&appSpec);
|
||
switch (appSpec.name[1])
|
||
{
|
||
case 'P': RunType=Steve;break;
|
||
case 'e': RunType=Debugging;break;
|
||
case 'l': RunType=Debugging;break;
|
||
default: RunType=Production;break;
|
||
}
|
||
#else
|
||
RunType=Production;
|
||
#endif DEBUG
|
||
}
|
||
|
||
/**********************************************************************
|
||
* do what we need before exiting functions
|
||
**********************************************************************/
|
||
void Cleanup()
|
||
{
|
||
#ifdef ETL
|
||
ETLCleanup();
|
||
#endif
|
||
#ifdef THREADING_ON
|
||
KillThreads ();
|
||
#endif
|
||
#ifdef IMAP
|
||
if (KerberosWasUsed() && PrefIsSet(PREF_DIE_DOG)) KerbDestroy();
|
||
if (KerberosWasUsed() && PrefIsSet(PREF_DIE_DOG_USER)) KerbDestroyUser();
|
||
#else
|
||
if (PrefIsSet(PREF_KERBEROS) && PrefIsSet(PREF_DIE_DOG)) KerbDestroy();
|
||
if (PrefIsSet(PREF_KERBEROS) && PrefIsSet(PREF_DIE_DOG_USER)) KerbDestroyUser();
|
||
#endif
|
||
#ifdef MENUSTATS
|
||
NoteMenuSelection(-1);
|
||
#endif
|
||
#ifndef SLOW_CLOSE
|
||
TcpFastFlush(True);
|
||
#endif
|
||
OTCleanUpAfterOpenTransport();
|
||
SaveFeaturesWithExtemeProfanity (gFeatureList);
|
||
if (SettingsRefN) {short refN=SettingsRefN; SettingsRefN=0; CloseResFile(refN);} // fool closeresfile, because it's ok to close settings here
|
||
CloseLog();
|
||
FlushVol(nil,Root.vRef);
|
||
FlushVol(nil,MailRoot.vRef);
|
||
if (PETE) PETECleanup(PETE);
|
||
if (TBTurnedOnBalloons) {TBTurnedOnBalloons = False; HMSetBalloons(False);}
|
||
CleanupUnicode();
|
||
OSXAddressBookSyncCleanup(false);
|
||
}
|
||
|
||
|
||
/************************************************************************/
|
||
/* d o i n i t l d e f - initialize LDEF resource. **/
|
||
/************************************************************************/
|
||
void doInitDEF(short resId,UniversalProcPtr upp,OSType type)
|
||
{
|
||
#pragma options align=mac68k
|
||
struct AbsJMP {
|
||
/* See the LDEF 1001 resource (stub) in Muslin.r for an explanation */
|
||
long LEA;
|
||
short MOVEA;
|
||
short JMP;
|
||
Ptr theAddr;
|
||
};
|
||
#pragma options align=reset
|
||
typedef struct AbsJMP AbsJMP;
|
||
|
||
Handle theResource;
|
||
AbsJMP *theJMP;
|
||
|
||
/* Lifted from some DTS code.
|
||
The LDEF resource is a stub into which we write
|
||
the address of the "real" LDEF (in the application.) The toolbox calls this
|
||
stub, which in turn jumps to our LDEF.
|
||
|
||
This technique not only allows us to debug the LDEF more easily (and give it
|
||
access to the program's globals under 68K), it also simplifies working with
|
||
Mixed Mode (see below) */
|
||
|
||
theResource = GetResource(type,resId);
|
||
theJMP = (AbsJMP*)(*theResource);
|
||
theJMP->theAddr = (Ptr)upp;
|
||
} /* end of doInitLDEF */
|
||
|
||
/************************************************************************/
|
||
/* InitCDEF - setup a CDEF
|
||
/************************************************************************/
|
||
void InitCDEF(short resId,ControlDefProcPtr proc)
|
||
{
|
||
// Register this resId so we will automatically use our CDEF
|
||
ControlDefSpec cdefSpec;
|
||
static ControlCNTLToCollectionUPP conversionProc;
|
||
|
||
cdefSpec.defType = kControlDefProcPtr;
|
||
cdefSpec.u.defProc = NewControlDefUPP(proc);
|
||
if (!conversionProc) conversionProc = NewControlCNTLToCollectionUPP(ControlCNTLToCollection);
|
||
RegisterControlDefinition(resId,&cdefSpec,conversionProc);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* ControlCNTLToCollection - put control values into collection for CDEF
|
||
/************************************************************************/
|
||
pascal OSStatus ControlCNTLToCollection (Rect *bounds, SInt16 value, Boolean visible, SInt16 max, SInt16 min, SInt16 procID, SInt32 refCon, ConstStr255Param title, Collection collection)
|
||
{
|
||
OSErr err;
|
||
|
||
if (!(err = AddCollectionItem(collection,kControlCollectionTagBounds,0,sizeof(Rect),bounds)))
|
||
if (!(err = AddCollectionItem(collection,kControlCollectionTagValue,0, sizeof (value), &value)))
|
||
if (!(err = AddCollectionItem(collection,kControlCollectionTagMinimum,0,sizeof (min), &min)))
|
||
if (!(err = AddCollectionItem(collection,kControlCollectionTagMaximum,0, sizeof (max), &max)))
|
||
if (!(err = AddCollectionItem(collection,kControlCollectionTagVisibility,0,sizeof(visible),&visible)))
|
||
if (!(err = AddCollectionItem(collection,kControlCollectionTagRefCon,0, sizeof (refCon), &refCon)))
|
||
err = AddCollectionItem(collection,kControlCollectionTagTitle,0,title[0],title+1);
|
||
return err;
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* InitLDEF - setup an LDEF
|
||
/************************************************************************/
|
||
void InitLDEF(short resId,ListDefProcPtr proc)
|
||
{
|
||
// Register this resId so we will automatically use our LDEF
|
||
if (RegisterListDefinition)
|
||
{
|
||
ListDefSpec ldefSpec;
|
||
ldefSpec.defType = kListDefUserProcType;
|
||
ldefSpec.u.userProc = NewListDefUPP(proc);
|
||
RegisterListDefinition(resId,&ldefSpec);
|
||
}
|
||
}
|
||
|
||
/**********************************************************************
|
||
* figure out what font and size to use
|
||
**********************************************************************/
|
||
void FigureOutFont(Boolean peteToo)
|
||
{
|
||
Str255 fontName;
|
||
PETEDefaultFontEntry defaultFont;
|
||
int i;
|
||
|
||
/*
|
||
* which font?
|
||
*/
|
||
if (EqualStrRes(GetPref(fontName,PREF_FONT_NAME),APPL_FONT))
|
||
FontID = 1;
|
||
else
|
||
FontID = GetFontID(fontName);
|
||
|
||
/*
|
||
* which fixed font?
|
||
*/
|
||
GetRString(fontName,FIXED_FONT);
|
||
if((FixedID = GetFontID(fontName)) == applFont)
|
||
FixedID = HiWord(ScriptVar(smScriptMonoFondSize));
|
||
|
||
/*
|
||
* how big?
|
||
*/
|
||
FontSize = GetPrefLong(PREF_FONT_SIZE);
|
||
if (!FontSize) FontSize = LoWord(ScriptVar(smScriptAppFondSize));
|
||
|
||
FixedSize = GetRLong(DEF_FIXED_SIZE);
|
||
if (!FixedSize) FixedSize = LoWord(ScriptVar(smScriptMonoFondSize));
|
||
|
||
normFonts[0].fontID = FontID;
|
||
normFonts[0].fontSize = FontSize;
|
||
printNormFonts[0].fontID = GetFontID(GetPref(fontName,PREF_PRINT_FONT));
|
||
printNormFonts[0].fontSize = GetPrefLong(PREF_PRINT_FONT_SIZE);
|
||
if (!printNormFonts[0].fontID) printNormFonts[0].fontID = FontID;
|
||
if (!printNormFonts[0].fontSize) printNormFonts[0].fontSize = FontSize;
|
||
printMonoFonts[0].fontID = monoFonts[0].fontID = FixedID;
|
||
monoFonts[0].fontSize = FixedSize;
|
||
printMonoFonts[0].fontSize = GetPrefLong(PREF_PRINT_FONT_SIZE);
|
||
if (!printMonoFonts[0].fontSize) printNormFonts[0].fontSize = FixedSize;
|
||
|
||
/* Get from the international font settings; will override above if available */
|
||
for(i = 32; --i >= 0; )
|
||
{
|
||
short normID = 0, printNormID = 0, monoID = 0, printMonoID = 0;
|
||
long normSize = 0, printNormSize = 0, monoSize = 0, printMonoSize = 0;
|
||
|
||
GetRString(fontName, IntlFontsStrn+i+1);
|
||
if(fontName[0])
|
||
{
|
||
unsigned char delims[3] = {',',':',0};
|
||
UPtr spotP = &fontName[1];
|
||
|
||
PToken(fontName, GlobalTemp, &spotP, delims);
|
||
if(*GlobalTemp) StringToNum(GlobalTemp, &normSize);
|
||
PToken(fontName, GlobalTemp, &spotP, delims);
|
||
if(*GlobalTemp) GetFNum(GlobalTemp, &normID);
|
||
PToken(fontName, GlobalTemp, &spotP, delims);
|
||
if(*GlobalTemp) StringToNum(GlobalTemp, &monoSize);
|
||
PToken(fontName, GlobalTemp, &spotP, delims);
|
||
if(*GlobalTemp) GetFNum(GlobalTemp, &monoID);
|
||
PToken(fontName, GlobalTemp, &spotP, delims);
|
||
if(*GlobalTemp) StringToNum(GlobalTemp, &printNormSize);
|
||
PToken(fontName, GlobalTemp, &spotP, delims);
|
||
if(*GlobalTemp) GetFNum(GlobalTemp, &printNormID);
|
||
PToken(fontName, GlobalTemp, &spotP, delims);
|
||
if(*GlobalTemp) StringToNum(GlobalTemp, &printMonoSize);
|
||
PToken(fontName, GlobalTemp, &spotP, delims);
|
||
if(*GlobalTemp) GetFNum(GlobalTemp, &printMonoID);
|
||
}
|
||
|
||
if(i != 0)
|
||
{
|
||
long normVal, monoVal;
|
||
|
||
normVal = GetScriptVariable(i, smScriptAppFondSize);
|
||
monoVal = GetScriptVariable(i, smScriptMonoFondSize);
|
||
normFonts[i].fontSize = normSize ? normSize : LoWord(normVal);
|
||
normFonts[i].fontID = normID ? normID : HiWord(normVal);
|
||
monoFonts[i].fontSize = monoSize ? monoSize : LoWord(monoVal);
|
||
monoFonts[i].fontID = monoID ? monoID : HiWord(monoVal);
|
||
printNormFonts[i].fontSize = printNormSize ? printNormSize : normFonts[i].fontSize;
|
||
printNormFonts[i].fontID = printNormID ? printNormID : normFonts[i].fontID;
|
||
printMonoFonts[i].fontSize = printMonoSize ? printMonoSize : monoFonts[i].fontSize;
|
||
printMonoFonts[i].fontID = printMonoID ? printMonoID : monoFonts[i].fontID;
|
||
}
|
||
else
|
||
{
|
||
if(normSize) FontSize = normFonts[i].fontSize = normSize;
|
||
if(normID) FontID = normFonts[i].fontID = normID;
|
||
if(monoSize) FixedSize = monoFonts[i].fontSize = monoSize;
|
||
if(monoID) FixedID = monoFonts[i].fontID = monoID;
|
||
if(printNormSize) printNormFonts[i].fontSize = printNormSize;
|
||
if(printNormID) printNormFonts[i].fontID = printNormID;
|
||
if(printMonoSize) printMonoFonts[i].fontSize = printMonoSize;
|
||
if(printMonoID) printMonoFonts[i].fontID = printMonoID;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* create a spare port for necessities
|
||
*/
|
||
SetupInsurancePort();
|
||
|
||
/*
|
||
* and how big is big?
|
||
*/
|
||
FontWidth = GetWidth(FontID,FontSize);
|
||
FontLead = GetLeading(FontID,FontSize);
|
||
FontDescent = GetDescent(FontID,FontSize);
|
||
FontAscent = GetAscent(FontID,FontSize);
|
||
FontIsFixed = IsFixed(FontID,FontSize);
|
||
|
||
/*
|
||
* and get the widths of boxes
|
||
*/
|
||
GetBoxLines();
|
||
|
||
/*
|
||
* notify pete
|
||
*/
|
||
if (peteToo)
|
||
{
|
||
// save these, because utf8 stuff uses them
|
||
short saveNormFont = normFonts[0].fontID;
|
||
short saveNormFontSize = normFonts[0].fontSize;
|
||
|
||
// handle the new prefs for text region
|
||
// font and size
|
||
if (*GetPref(fontName,PREF_TEXT_FONT))
|
||
{
|
||
short id=0;
|
||
GetFNum(fontName,&id);
|
||
if (id) normFonts[0].fontID = id;
|
||
}
|
||
|
||
{
|
||
short size = GetPrefLong(PREF_TEXT_SIZE);
|
||
if (size) normFonts[0].fontSize = size;
|
||
}
|
||
|
||
for(i = 32; --i >= 0; )
|
||
{
|
||
Zero(defaultFont);
|
||
defaultFont.pdFont = normFonts[i].fontID;
|
||
defaultFont.pdSize = normFonts[i].fontSize;
|
||
PETESetDefaultFont(PETE,nil,&defaultFont);
|
||
|
||
Zero(defaultFont);
|
||
defaultFont.pdFont = printNormFonts[i].fontID;
|
||
defaultFont.pdSize = printNormFonts[i].fontSize;
|
||
defaultFont.pdPrint = True;
|
||
PETESetDefaultFont(PETE,nil,&defaultFont);
|
||
|
||
#ifdef USEFIXEDDEFAULTFONT
|
||
Zero(defaultFont);
|
||
defaultFont.pdFont = monoFonts[i].fontID;
|
||
defaultFont.pdSize = monoFonts[i].fontSize;
|
||
defaultFont.pdFixed = True;
|
||
PETESetDefaultFont(PETE,nil,&defaultFont);
|
||
|
||
Zero(defaultFont);
|
||
defaultFont.pdFont = printMonoFonts[i].fontID;
|
||
defaultFont.pdSize = printMonoFonts[i].fontSize;
|
||
defaultFont.pdFixed = True;
|
||
defaultFont.pdPrint = True;
|
||
PETESetDefaultFont(PETE,nil,&defaultFont);
|
||
#endif
|
||
}
|
||
|
||
// restore these, because utf8 stuff uses them
|
||
normFonts[0].fontID = saveNormFont;
|
||
normFonts[0].fontSize = saveNormFontSize;
|
||
}
|
||
|
||
ReloadStdSizes();
|
||
}
|
||
|
||
/**********************************************************************
|
||
* open (or create) the settings file
|
||
**********************************************************************/
|
||
void OpenSettingsFile(FSSpecPtr spec)
|
||
{
|
||
Str255 settingsName;
|
||
Handle appVersion;
|
||
Handle prefVersion;
|
||
int err;
|
||
FInfo info;
|
||
FSSpec appSpec;
|
||
static short copyMe[] = {PREF2_STRN,PREF3_STRN,PREF4_STRN,RegValStrn,RecentDirServStrn,0};
|
||
short *copyPtr;
|
||
Boolean newSettingsFile;
|
||
enum { kAppVersionNum = MAJOR_VERSION*10000+MINOR_VERSION*100+INC_VERSION };
|
||
FSSpec theSpec;
|
||
|
||
NoMenus = true;
|
||
|
||
/*
|
||
* close it if it's open
|
||
*/
|
||
if (SettingsRefN)
|
||
{
|
||
// CloseResFile won't close the settings file without anger; fool it
|
||
short refN = SettingsRefN;
|
||
SettingsRefN = 0;
|
||
CloseResFile(refN);
|
||
Zero(SettingsSpec);
|
||
}
|
||
|
||
/*
|
||
* and any plug-ins in its directory
|
||
*/
|
||
if (PrefPlugEnd) while (CurResFile()!=PrefPlugEnd) CloseResFile(CurResFile());
|
||
|
||
/*
|
||
* we'll create it before we open it, to avoid the PMSP
|
||
*/
|
||
if (spec && spec->name && !FSpGetFInfo(spec,&info) &&
|
||
info.fdType==SETTINGS_TYPE && info.fdCreator==CREATOR)
|
||
PCopy(settingsName,spec->name);
|
||
else
|
||
{
|
||
if (!spec) spec = &theSpec;
|
||
GetRString(settingsName,SETTINGS_FILE);
|
||
PSCopy(spec->name,settingsName);
|
||
spec->vRefNum = Root.vRef;
|
||
spec->parID = Root.dirId;
|
||
LocalizeRename(spec,USA_SETTINGS);
|
||
}
|
||
FSpCreateResFile(spec,CREATOR,SETTINGS_TYPE,smSystemScript);
|
||
|
||
/*
|
||
* is it sane?
|
||
*/
|
||
SaneSettings(spec);
|
||
SimpleMakeFSSpec (Root.vRef, Root.dirId, settingsName, &SettingsFileSpec);
|
||
|
||
/*
|
||
* grab some stuff from the application resource file first
|
||
*/
|
||
if ((appVersion = GetResource_(CREATOR,1))==nil)
|
||
DieWithError(READ_SETTINGS,ResError());
|
||
HNoPurge(appVersion);
|
||
|
||
/*
|
||
* if there are plug-ins in the Eudora Folder, open them, too
|
||
*/
|
||
GetFileByRef(AppResFile,&appSpec);
|
||
if (appSpec.vRefNum!=Root.vRef || appSpec.parID!=Root.dirId)
|
||
(void) PlugInDir(Root.vRef,Root.dirId);
|
||
|
||
|
||
/*
|
||
* now, open the preferences file
|
||
*/
|
||
if ((SettingsRefN=FSpOpenResFile(spec,fsRdWrPerm))==-1)
|
||
{
|
||
err = ResError();
|
||
DieWithError(err==opWrErr ? SETTINGS_BUSY : OPEN_SETTINGS,err);
|
||
}
|
||
|
||
// keep track of this little puppy
|
||
SettingsSpec = *spec;
|
||
|
||
/*
|
||
* copy the preferences into it if need be
|
||
* "need be" means either the resources aren't now there,
|
||
* or the program version has changed since last time the
|
||
* preferences file was written.
|
||
*/
|
||
if ((prefVersion = GetResource_(CREATOR,1))==nil)
|
||
DieWithError(READ_SETTINGS,ResError());
|
||
HNoPurge(prefVersion);
|
||
|
||
newSettingsFile = HomeResFile(prefVersion)!=SettingsRefN; // No version resource. Most likely a new settings file
|
||
if (newSettingsFile ||
|
||
!StringSame(*prefVersion,*appVersion))
|
||
{
|
||
ReleaseResource_(prefVersion);
|
||
ReleaseResource_(appVersion);
|
||
if (err=ResourceCpy(SettingsRefN,AppResFile,CREATOR,1))
|
||
DieWithError(WRITE_SETTINGS,err);
|
||
if (err=ResourceCpy(SettingsRefN,AppResFile,'STR#',PREF_STRN))
|
||
DieWithError(WRITE_SETTINGS,err);
|
||
MyUpdateResFile(SettingsRefN);
|
||
if (ResError()) DieWithError(WRITE_SETTINGS,ResError());
|
||
}
|
||
else
|
||
{
|
||
ReleaseResource_(prefVersion);
|
||
ReleaseResource_(appVersion);
|
||
}
|
||
|
||
for (copyPtr=copyMe;*copyPtr;copyPtr++)
|
||
if (!(prefVersion=Get1Resource('STR#',*copyPtr)) ||
|
||
HomeResFile(prefVersion)!=SettingsRefN)
|
||
{
|
||
if (err=ResourceCpy(SettingsRefN,AppResFile,'STR#',*copyPtr))
|
||
DieWithError(WRITE_SETTINGS,err);
|
||
}
|
||
|
||
// previous versions copied this in, we don't really want it
|
||
if (prefVersion=Get1Resource('STR#',CmdKeyStrn))
|
||
if (GetHandleSize(prefVersion)==2)
|
||
Zap1Resource('STR#',CmdKeyStrn);
|
||
|
||
// Copy over default wazoos for new settings file or if
|
||
// settings file has never been opened with version 4.0.0 or higher
|
||
if (newSettingsFile || GetPrefLong(PREF_HIGHEST_APP_VERSION) < 4*10000)
|
||
{
|
||
if (!Count1Resources(kWazooListResType))
|
||
{
|
||
ResourceCpy(SettingsRefN,AppResFile,kWazooListResType,kWazooRes1);
|
||
ResourceCpy(SettingsRefN,AppResFile,kWazooListResType,kWazooRes2);
|
||
}
|
||
|
||
/* set default prefs for nickname type-ahead and nickname hiliting */
|
||
SetDefaultNicknameWatcherPrefs();
|
||
}
|
||
|
||
// Copy over default LIGHT wazoos for new settings file or if
|
||
// settings file has never been opened with version 4.3.0 or higher
|
||
if (newSettingsFile || GetPrefLong(PREF_HIGHEST_APP_VERSION) < 403*100)
|
||
{
|
||
if (!Count1Resources(kFreeWazooListResType))
|
||
{
|
||
ResourceCpy(SettingsRefN,AppResFile,kFreeWazooListResType,kWazooRes1);
|
||
ResourceCpy(SettingsRefN,AppResFile,kFreeWazooListResType,kWazooRes2);
|
||
}
|
||
}
|
||
|
||
for (copyPtr=copyMe;*copyPtr;copyPtr++)
|
||
if (RecountStrn(*copyPtr)) Aprintf(OK_ALRT,Caution,FIXED_STRN,*copyPtr);
|
||
|
||
// For new settings files, do not give the preexisting junk mailbox warning
|
||
if (newSettingsFile) SetPrefLong(PREF_JUNK_MAILBOX,GetPrefLong(PREF_JUNK_MAILBOX)|bJunkPrefBoxExistWarning|bJunkPrefNeedIntro);
|
||
|
||
// Update application version preferences
|
||
SetPrefLong(PREF_LAST_APP_VERSION,kAppVersionNum);
|
||
if ((gHighestAppVersionAtLaunch = GetPrefLong(PREF_HIGHEST_APP_VERSION)) < kAppVersionNum)
|
||
SetPrefLong(PREF_HIGHEST_APP_VERSION,kAppVersionNum);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* SaneSettings - make sure a settings file is sane, and then backup
|
||
**********************************************************************/
|
||
void SaneSettings(FSSpecPtr spec)
|
||
{
|
||
Boolean sane;
|
||
FSSpec bkup;
|
||
OSErr err;
|
||
|
||
if ((err=utl_RFSanity(spec,&sane)) || !sane)
|
||
if (!FallbackSettings(spec))
|
||
DieWithError(SETTINGS_BAD,err?err:1);
|
||
|
||
/*
|
||
* is sane. make backup
|
||
*/
|
||
bkup = *spec;
|
||
if (*bkup.name > 26) *bkup.name = 26;
|
||
PSCat(bkup.name,"\p.bkup");
|
||
FSpDupFile(&bkup,spec,True,False);
|
||
}
|
||
|
||
/**********************************************************************
|
||
*
|
||
**********************************************************************/
|
||
Boolean FallbackSettings(FSSpecPtr spec)
|
||
{
|
||
FSSpec backup;
|
||
Boolean sane;
|
||
OSErr err;
|
||
|
||
backup = *spec;
|
||
if (*backup.name > 26) *backup.name = 26;
|
||
PSCat(backup.name,"\p.bkup");
|
||
if (!FSpExists(&backup) && !utl_RFSanity(&backup,&sane) && sane)
|
||
{
|
||
if (ReallyDoAnAlert(USE_BACKUP_ALRT,Note)==1)
|
||
{
|
||
err = FSpExchangeFiles(spec,&backup);
|
||
if (!err) PSCat(spec->name,"\p.bad");
|
||
if (!err) FSpDelete(spec);
|
||
if (!err) err = FSpRename(&backup,spec->name);
|
||
if (err) FileSystemError(READ_SETTINGS,spec->name,err);
|
||
else return(True);
|
||
}
|
||
}
|
||
return(False);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* SystemEudoraFolder - find the directory for us in the system folder.
|
||
* If it doesn't exist, create it.
|
||
*
|
||
* Actually, we now do this:
|
||
* - Look for the folder in the system folder
|
||
* - Look for the folder in the documents folder
|
||
* - Create it in the documents folder
|
||
* - With OSX will also look in the classic folders
|
||
**********************************************************************/
|
||
void SystemEudoraFolder(void)
|
||
{
|
||
CInfoPBRec hfi;
|
||
int err=0;
|
||
FSSpec spec;
|
||
Str31 folder,scratch;
|
||
Boolean system = True;
|
||
|
||
/*
|
||
* now, look for our directory
|
||
*/
|
||
#ifdef DEBUG
|
||
GetRString(folder,RunType==Steve ? STEVE_FOLDER : FOLDER_NAME);
|
||
#else
|
||
GetRString(folder,FOLDER_NAME);
|
||
#endif DEBUG
|
||
|
||
/*
|
||
* try system folder
|
||
*/
|
||
err = FindEudoraFolder(&spec,folder,kOnSystemDisk,kSystemFolderType);
|
||
|
||
/*
|
||
* if system folder failed, try documents folder
|
||
*/
|
||
if (err) err = FindEudoraFolder(&spec,folder,kOnSystemDisk,kDocumentsFolderType);
|
||
|
||
if (err && HaveOSX())
|
||
{
|
||
// Search classic folders
|
||
// Try system folder
|
||
err = FindEudoraFolder(&spec,folder,kClassicDomain,kSystemFolderType);
|
||
// Try documents folder
|
||
if (err) err = FindEudoraFolder(&spec,folder,kClassicDomain,kDocumentsFolderType);
|
||
if (err)
|
||
{
|
||
// Finding the classic documents folder current doesn't work (OS X 10.1.3). Let's try
|
||
// to find it ourselves.
|
||
err = FindFolder(kClassicDomain,kSystemFolderType,False,&spec.vRefNum,&spec.parID);
|
||
if (!err)
|
||
{
|
||
FSMakeFSSpec(spec.vRefNum,spec.parID,nil,&spec); // system folder
|
||
err = FSMakeFSSpec(spec.vRefNum,spec.parID,GetRString(scratch,USA_DOCUMENTS),&spec); // documents folder
|
||
Root.vRef = spec.vRefNum;
|
||
Root.dirId = SpecDirId(&spec);
|
||
err = FSMakeFSSpec(Root.vRef,Root.dirId,folder,&spec);
|
||
if (err==fnfErr) err = LocalizeRename(&spec,USA_EUDORA_FOLDER);
|
||
}
|
||
}
|
||
|
||
// Need to end with OS X documents folder
|
||
if (err) err = FindEudoraFolder(&spec,folder,kOnSystemDisk,kDocumentsFolderType);
|
||
}
|
||
|
||
/*
|
||
* now we are pointed where we think the folder should go. Create it, so that it will
|
||
* exist if we can make it
|
||
*/
|
||
FSpDirCreate(&spec,smSystemScript,&Root.dirId);
|
||
|
||
/*
|
||
* Get info, and possibly resolve alias
|
||
*/
|
||
err = AFSpGetCatInfo(&spec,&spec,&hfi);
|
||
|
||
/*
|
||
* it exists. Is it a folder?
|
||
*/
|
||
if (!err && hfi.hFileInfo.ioFlAttrib&0x10)
|
||
{
|
||
Root.vRef = spec.vRefNum;
|
||
spec.parID = Root.dirId = hfi.hFileInfo.ioDirID;
|
||
GetRString(spec.name,SETTINGS_FILE);
|
||
LocalizeRename(&spec,USA_SETTINGS);
|
||
}
|
||
else if (!err)
|
||
{
|
||
MakeUserFindSettings(&spec);
|
||
system = False;
|
||
}
|
||
if (err) DieWithError(MAIL_FOLDER,err);
|
||
|
||
SettingsInit(&spec,system,false);
|
||
}
|
||
|
||
/************************************************************************
|
||
* FindEudoraFolder - see if Eudora Folder is at specified location, set up FSSpec
|
||
************************************************************************/
|
||
static OSErr FindEudoraFolder(FSSpecPtr spec,StringPtr folder,short vRefNum,OSType folderType)
|
||
{
|
||
OSErr err;
|
||
|
||
if (!(err = FindFolder(vRefNum,folderType,False,&Root.vRef,&Root.dirId)))
|
||
{
|
||
err = FSMakeFSSpec(Root.vRef,Root.dirId,folder,spec);
|
||
if (err==fnfErr) err = LocalizeRename(spec,USA_EUDORA_FOLDER);
|
||
}
|
||
return err;
|
||
}
|
||
|
||
/************************************************************************
|
||
* MakeUserFindSettings - force the user to find a Eudora Settings file
|
||
************************************************************************/
|
||
void MakeUserFindSettings(FSSpecPtr spec)
|
||
{
|
||
Boolean justQuit;
|
||
|
||
justQuit = true;
|
||
if (ReallyDoAnAlert(INSIST_SETTINGS_ALRT,Stop)==1) {
|
||
justQuit = MakeUserFindSettingsNav (spec);
|
||
}
|
||
if (justQuit) {
|
||
Cleanup();
|
||
ExitToShell();
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
* DateWarning - warn the user about the date, if need be. Returns true
|
||
* if date not set
|
||
************************************************************************/
|
||
Boolean DateWarning(Boolean uiOK)
|
||
{
|
||
short vRef;
|
||
long dirId;
|
||
Str63 date;
|
||
CInfoPBRec hfi;
|
||
FSSpec spec;
|
||
short where = -1;
|
||
short bestWhere = REAL_BIG;
|
||
|
||
BuildDateHeader(date,0);
|
||
|
||
if (!*date)
|
||
{
|
||
if (uiOK)
|
||
{
|
||
WarnUser(USE_MAP,0);
|
||
if (!FindFolder(kOnSystemDisk,kControlPanelFolderType,False,&vRef,&dirId))
|
||
{
|
||
hfi.hFileInfo.ioNamePtr = date;
|
||
hfi.hFileInfo.ioFDirIndex = 0;
|
||
while(!DirIterate(vRef,dirId,&hfi))
|
||
if (TypeIsOnListWhere(hfi.hFileInfo.ioFlFndrInfo.fdCreator,DATELOC_TYPE,&where) && where<bestWhere)
|
||
{
|
||
bestWhere = where;
|
||
SimpleMakeFSSpec(vRef,dirId,date,&spec);
|
||
if (!where) break;
|
||
}
|
||
}
|
||
}
|
||
if (bestWhere<REAL_BIG) OpenOtherDoc(&spec,false,false,nil);
|
||
return(true);
|
||
}
|
||
|
||
return(false);
|
||
}
|
||
|
||
#ifdef TWO
|
||
#pragma segment Main
|
||
pascal void FMSError(PStr s);
|
||
pascal void FMSError(PStr s)
|
||
{
|
||
AlertStr(OK_ALRT,Caution,s);
|
||
}
|
||
pascal void FMSFilter(EventRecord *event);
|
||
pascal void FMSFilter(EventRecord *event)
|
||
{
|
||
MiniMainLoop(event);
|
||
}
|
||
#pragma segment Ends
|
||
#endif
|
||
|
||
/**********************************************************************
|
||
* PutUpMenus - set up the menu bar
|
||
**********************************************************************/
|
||
void PutUpMenus()
|
||
{
|
||
int menu;
|
||
MenuHandle mHandle;
|
||
Str63 scratch;
|
||
short key;
|
||
|
||
/*
|
||
* add the standard ones
|
||
*/
|
||
for (menu=APPLE_MENU;menu<MENU_LIMIT;menu++)
|
||
{
|
||
if (mHandle=GetMHandle(menu)) ReleaseResource_(mHandle);
|
||
mHandle = GetMenu(menu+1000);
|
||
if (mHandle==nil)
|
||
DieWithError(GET_MENU,MemError());
|
||
InsertMenu(mHandle,0);
|
||
if (menu==FILE_MENU)
|
||
{
|
||
SInt32 result;
|
||
Gestalt(gestaltMenuMgrAttr,&result);
|
||
if (result&gestaltMenuMgrAquaLayoutMask)
|
||
{
|
||
// No File->Quit menu item under aqua
|
||
DeleteMenuItem(mHandle,FILE_QUIT_ITEM);
|
||
DeleteMenuItem(mHandle,FILE_QUIT_ITEM-1);
|
||
}
|
||
}
|
||
else if (menu==SPECIAL_MENU)
|
||
{
|
||
extern short gDeletedSpecialItem;
|
||
if ( !PrefIsSet ( PREF_SHOW_CHANGE_PASSWORD )) {
|
||
DeleteMenuItem ( mHandle, SPECIAL_CHANGE_ITEM );
|
||
gDeletedSpecialItem = SPECIAL_CHANGE_ITEM;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
if (mHandle=GetMHandle(WINDOW_MENU)) ReleaseResource_(mHandle);
|
||
mHandle = GetMenu(WINDOW_MENU+1000);
|
||
if (mHandle==nil)
|
||
DieWithError(GET_MENU,MemError());
|
||
InsertMenu(mHandle,0);
|
||
#ifdef DEBUG
|
||
if (RunType!=Production)
|
||
{
|
||
InsertMenu(GetMenu(DEBUG_MENU+1000),0);
|
||
AttachHierMenu(DEBUG_MENU,dbAds,AD_SELECT_HIER_MENU);
|
||
GetAndInsertHier(AD_SELECT_HIER_MENU);
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
* take care of special menus
|
||
*/
|
||
BuildBoxMenus(); /* build the menus that refer to Mailboxes */
|
||
|
||
/*
|
||
* the user menus
|
||
*/
|
||
AttachHierMenu(EDIT_MENU,EDIT_TEXT_ITEM,TEXT_HIER_MENU);
|
||
#ifdef WINTERTREE
|
||
if (HasFeature (featureSpellChecking)) {
|
||
AttachHierMenu(EDIT_MENU,EDIT_ISPELL_HOOK_ITEM,SPELL_HIER_MENU);
|
||
GetAndInsertHier(SPELL_HIER_MENU);
|
||
}
|
||
#endif
|
||
GetAndInsertHier(TEXT_HIER_MENU);
|
||
GetAndInsertHier(SIG_HIER_MENU);
|
||
GetAndInsertHier(SERVER_HIER_MENU);
|
||
GetAndInsertHier(ATTACH_MENU);
|
||
GetAndInsertHier(TEXT_SIZE_HIER_MENU);
|
||
AttachHierMenu(TEXT_HIER_MENU,tmFont,FONT_HIER_MENU);
|
||
AttachHierMenu(TEXT_HIER_MENU,tmColor,COLOR_HIER_MENU);
|
||
AttachHierMenu(TEXT_HIER_MENU,tmMargin,MARGIN_HIER_MENU);
|
||
#ifdef NEVER
|
||
AttachHierMenu(CHANGE_HIER_MENU,CHANGE_STATUS_ITEM,STATE_HIER_MENU);
|
||
#endif
|
||
SetupRecipMenus();
|
||
|
||
if (HasFeature (featureStationery))
|
||
BuildStationMenu();
|
||
if (HasFeature (featureMultiplePersonalities))
|
||
BuildPersMenu();
|
||
|
||
/*
|
||
* hier menus
|
||
*/
|
||
GetAndInsertHier(FIND_HIER_MENU);
|
||
GetAndInsertHier(SORT_HIER_MENU);
|
||
GetAndInsertHier(CHANGE_HIER_MENU);
|
||
GetAndInsertHier(COLOR_HIER_MENU);
|
||
AddIconsToColorMenu(GetMHandle(COLOR_HIER_MENU));
|
||
MightSwitch();
|
||
GetAndInsertHier(FONT_HIER_MENU);
|
||
AppendResMenu(GetMHandle(FONT_HIER_MENU),'FONT');
|
||
AfterSwitch();
|
||
GetAndInsertHier(MARGIN_HIER_MENU);
|
||
GetAndInsertHier(TLATE_SEL_HIER_MENU);
|
||
GetAndInsertHier(TLATE_SET_HIER_MENU);
|
||
GetAndInsertHier(TLATE_ATT_HIER_MENU);
|
||
#ifdef TWO
|
||
GetAndInsertHier(STATE_HIER_MENU);
|
||
#endif
|
||
GetAndInsertHier(PRIOR_HIER_MENU);
|
||
GetAndInsertHier(LABEL_HIER_MENU);
|
||
{
|
||
Byte type;
|
||
Handle suite=nil;
|
||
|
||
if ((mHandle=GetMHandle(LABEL_HIER_MENU)) && (GetMenuItemIconHandle(mHandle,1,&type,&suite) || !suite))
|
||
{
|
||
GetIconSuite(&suite,NO_LABEL_SICN,svAllSmallData);
|
||
SetMenuItemIconHandle(mHandle,1,kMenuIconSuiteType,suite);
|
||
}
|
||
}
|
||
|
||
|
||
#ifdef DEBUG
|
||
if (RunType!=Production)
|
||
{
|
||
GetAndInsertHier(WIND_PROP_HIER_MENU);
|
||
AttachHierMenu(WINDOW_MENU,WIN_PROPERTIES_ITEM,WIND_PROP_HIER_MENU);
|
||
}
|
||
#endif
|
||
if (NewTables)
|
||
{
|
||
mHandle = GetMenu(TABLE_HIER_MENU+1000);
|
||
if (CountMenuItems(GetMHandle(CHANGE_HIER_MENU))<CHANGE_TABLE_ITEM)
|
||
{
|
||
AppendMenu(GetMHandle(CHANGE_HIER_MENU),GetMenuTitle(mHandle,scratch));
|
||
}
|
||
AttachHierMenu(CHANGE_HIER_MENU,CHANGE_TABLE_ITEM,TABLE_HIER_MENU);
|
||
InsertMenu(mHandle,-1);
|
||
}
|
||
|
||
// Adjust command keys
|
||
mHandle = GetMHandle(EDIT_MENU);
|
||
GetItemCmd(mHandle,EDIT_PASTE_ITEM,&key);
|
||
if (key)
|
||
{
|
||
SetItemCmd(mHandle,EDIT_QUOTE_ITEM,key);
|
||
SetMenuItemModifiers(mHandle,EDIT_QUOTE_ITEM,kMenuOptionModifier);
|
||
}
|
||
|
||
mHandle = GetMHandle(TEXT_HIER_MENU);
|
||
GetItemCmd(mHandle,tmQuote,&key);
|
||
if (key)
|
||
{
|
||
SetItemCmd(mHandle,tmUnquote,key);
|
||
SetMenuItemModifiers(mHandle,tmUnquote,kMenuOptionModifier);
|
||
}
|
||
|
||
AdjustStupidCommandKeys();
|
||
|
||
AddCustomSortItems();
|
||
|
||
if (HasFeature (featureStyleMargin))
|
||
BuildMarginMenu();
|
||
|
||
#ifdef TWO
|
||
#ifdef ETL
|
||
|
||
ETLInit();
|
||
#endif
|
||
#endif
|
||
|
||
BuildSearchMenu();
|
||
|
||
/*
|
||
* add the help menus
|
||
*/
|
||
AddHelpMenuItems();
|
||
|
||
/*
|
||
* add finder menu items
|
||
*/
|
||
RefreshLabelsMenu();
|
||
|
||
/*
|
||
* add the Word Services menus
|
||
*/
|
||
|
||
AddWSMenuItems();
|
||
|
||
// Scripts menu
|
||
BuildScriptMenu();
|
||
|
||
ChangeCmdKeys();
|
||
|
||
InitSharedMenus((void*)FMSError,(void*)FMSFilter); /* Frontier menusharing */
|
||
|
||
/*
|
||
* draw the menu bar
|
||
*/
|
||
gMenuBarIsSetup = true;
|
||
EnableMenus(nil,false);
|
||
|
||
}
|
||
|
||
/************************************************************************
|
||
* AddCustomSortItems - add custom sorts
|
||
************************************************************************/
|
||
void AddCustomSortItems(void)
|
||
{
|
||
Str255 s;
|
||
Str63 menuItem;
|
||
short i;
|
||
MenuHandle mh = GetMHandle(SORT_HIER_MENU);
|
||
|
||
if (mh)
|
||
for (i=1;*GetRString(s,SortsStrn+i);i++)
|
||
{
|
||
if (i==1) AppendMenu(mh,"\p-");
|
||
if (!InterpretSortString(s,nil,nil,menuItem))
|
||
MyAppendMenu(mh,menuItem);
|
||
else MyAppendMenu(mh,s);
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
* GetAndInsertHier - get a menu and insert it
|
||
************************************************************************/
|
||
void GetAndInsertHier(short menu)
|
||
{
|
||
MenuHandle mHandle;
|
||
|
||
ZapResMenu(menu);
|
||
mHandle = GetMenu(menu+1000);
|
||
if (mHandle==nil) DieWithError(GET_MENU,menu);
|
||
InsertMenu(mHandle,-1);
|
||
}
|
||
|
||
/************************************************************************
|
||
* AddFinderItems - add the items from the Finder's label menu
|
||
************************************************************************/
|
||
void AddFinderItems(MenuHandle mh)
|
||
{
|
||
short item;
|
||
Str255 string;
|
||
RGBColor color;
|
||
Handle suite;
|
||
short mItem;
|
||
|
||
if (mh)
|
||
{
|
||
mItem = CountMenuItems(mh);
|
||
for (item=1;item<=15;item++)
|
||
{
|
||
if (item==8)
|
||
{
|
||
AppendMenu(mh,"\p-");
|
||
DisableItem(mh,CountMenuItems(mh));
|
||
mItem++;
|
||
}
|
||
MyGetLabel(item,&color,string);
|
||
if (!*string) PCatC(string,item);
|
||
MyAppendMenu(mh,string);
|
||
mItem++;
|
||
#ifdef LABEL_ICONS
|
||
RefreshLabelIcon(item,&color);
|
||
if (!GetIconSuite(&suite,LABEL_SICN_BASE+item-1,svAllSmallData))
|
||
SetMenuItemIconHandle(mh,mItem,kMenuIconSuiteType,suite);
|
||
#endif
|
||
if (!BlackWhite(&color))
|
||
{
|
||
SetMenuColor(mh,mItem,&color);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
* RefreshLabelIcon - refresh the icon for a label
|
||
************************************************************************/
|
||
#ifdef LABEL_ICONS
|
||
OSErr RefreshLabelIcon(short item,RGBColor *color)
|
||
{
|
||
Boolean changed;
|
||
OSErr err = RefreshRGBIcon(LABEL_SICN_BASE+item-1,color,LABEL_SICN_TEMPLATE,&changed);
|
||
if (changed) UpdateLabelControls();
|
||
return(err);
|
||
}
|
||
|
||
/************************************************************************
|
||
* UpdateLabelControls - update label controls in windows
|
||
************************************************************************/
|
||
void UpdateLabelControls(void)
|
||
{
|
||
TBarHasChanged = True;
|
||
}
|
||
|
||
#endif
|
||
|
||
/************************************************************************
|
||
* AddIconsToColorMenu - add icons to the color menu
|
||
************************************************************************/
|
||
OSErr AddIconsToColorMenu(MenuHandle mh)
|
||
{
|
||
short item;
|
||
RGBColor color;
|
||
OSErr err = noErr;
|
||
MCEntryPtr mc;
|
||
Handle suite;
|
||
|
||
ASSERT(mh);
|
||
|
||
for (item=CountMenuItems(mh);!err && item;item--)
|
||
{
|
||
if (mc = GetMCEntry(COLOR_HIER_MENU,item))
|
||
{
|
||
color = mc->mctRGB2;
|
||
if (!BlackWhite(&color))
|
||
{
|
||
err = RefreshRGBIcon(COLORS_MENU_ICON_BASE+item-1,&color,COLORS_MENU_ICON_TEMPLATE,nil);
|
||
if (!GetIconSuite(&suite,COLORS_MENU_ICON_BASE+item-1,svAllSmallData))
|
||
SetMenuItemIconHandle(mh,item,kMenuIconSuiteType,suite);
|
||
}
|
||
ASSERT(!err);
|
||
}
|
||
}
|
||
return(err);
|
||
}
|
||
|
||
/************************************************************************
|
||
* AddHelpMenuItems - add items to the help menu
|
||
************************************************************************/
|
||
void AddHelpMenuItems(void)
|
||
{
|
||
Handle resH;
|
||
short r;
|
||
short id;
|
||
OSType type;
|
||
Str255 name;
|
||
MenuHandle hm;
|
||
|
||
if (!HMGetHelpMenuHandle(&hm) && hm) /* the check for nil is needed courtesy of Norton Utilities, crap that it is */
|
||
{
|
||
OriginalHelpCount = CountMenuItems(hm);
|
||
SetResLoad(False);
|
||
for (r = HELP_PICT_BASE; r<HELP_PICT_BASE+50; r++)
|
||
if ((resH=GetResource_('TEXT',r)) || (resH=GetResource_('PICT',r)))
|
||
AddRes2HelpMenu(hm,resH);
|
||
|
||
for (r = 1;(resH=GetIndResource_('TEXT',r)) || (resH=GetIndResource_('PICT',r));r++)
|
||
{
|
||
GetResInfo(resH,&id,&type,name);
|
||
if (id>=HELP_PICT_BASE+50 && id<HELP_PICT_BASE+1000)
|
||
AddRes2HelpMenu(hm,resH);
|
||
}
|
||
SetResLoad(True);
|
||
|
||
AppendMenu(hm,"\p-");DisableItem(hm,CountMenuItems(hm));
|
||
|
||
#ifndef DEATH_BUILD
|
||
#ifdef NAG
|
||
// Append the "Payment & Registration<6F>" menu item
|
||
AppendMenu (hm, GetRString (name, PAY_AND_REGISTER));
|
||
/*
|
||
// Append the "Enter Registration Code<64>" menu item
|
||
if (!RegisteredUser ((*nagState)->state))
|
||
AppendMenu (hm, GetRString (name, ENTER_REG_CODE));
|
||
// Append the "Try Full Features<65>" menu item
|
||
if (LightUser ((*nagState)->state))
|
||
AppendMenu (hm, GetRString (name, TRY_FULL_FEATURES));
|
||
*/
|
||
#else
|
||
AppendMenu(hm,GetRString(name,PURCHASE_EUDORA));
|
||
if (GetPrefLong(PREF_REGISTER)!=0x0fffffff) AppendMenu(hm,GetRString(name,REGISTER_EUDORA));
|
||
#endif
|
||
#endif
|
||
AppendMenu(hm,GetRString(name,INSERT_CONFIGURATION));
|
||
AppendMenu(hm,GetRString(name,HELP_SUGGEST_MTEXT));
|
||
AppendMenu(hm,GetRString(name,HELP_BUG_MTEXT));
|
||
|
||
EndHelpCount = CountMenuItems(hm);
|
||
}
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
*
|
||
**********************************************************************/
|
||
void AddRes2HelpMenu(MenuHandle hm,Handle resH)
|
||
{
|
||
short id;
|
||
OSType type;
|
||
Str255 name;
|
||
|
||
GetResInfo(resH,&id,&type,name);
|
||
if (*name) MyAppendMenu(hm,name);
|
||
else {AppendMenu(hm,"\p-");DisableItem(hm,CountMenuItems(hm));}
|
||
ReleaseResource_(resH);
|
||
}
|
||
|
||
/************************************************************************
|
||
* AddWSMenuItems - add Word Services
|
||
************************************************************************/
|
||
void AddWSMenuItems(void)
|
||
{
|
||
Handle resH;
|
||
short r;
|
||
short id;
|
||
OSType type;
|
||
Str255 name;
|
||
MenuHandle mh;
|
||
|
||
if (mh = GetMHandle(EDIT_MENU))
|
||
{
|
||
SetResLoad(False);
|
||
for (r = 1;resH=GetIndResource_(WS_ALIAS_TYPE,r);r++)
|
||
{
|
||
GetResInfo(resH,&id,&type,name);
|
||
MyAppendMenu(mh,name);
|
||
}
|
||
SetResLoad(True);
|
||
}
|
||
WordServices = NuHandle((r-1)*sizeof(**WordServices));
|
||
if (WordServices)
|
||
{
|
||
WriteZero(LDRef(WordServices),GetHandleSize_(WordServices));
|
||
UL(WordServices);
|
||
}
|
||
}
|
||
|
||
/**********************************************************************
|
||
* HuntSpellswell - find & install spellswell, if not there already
|
||
**********************************************************************/
|
||
void HuntSpellswell(void)
|
||
{
|
||
OSType creator = FetchOSType(SPELLSWELL_CREATOR);
|
||
FSSpec spec;
|
||
OSErr err;
|
||
short dtRef;
|
||
short vRef;
|
||
|
||
if (!(err = GetFileByRef(AppResFile,&spec)))
|
||
{
|
||
vRef = spec.vRefNum;
|
||
if (!(err = DTRef(vRef,&dtRef)))
|
||
{
|
||
if (!(err = DTGetAppl(vRef,dtRef,creator,&spec)))
|
||
{
|
||
if (FileCreatorOf(&spec)==creator)
|
||
{
|
||
InstallSpeller(&spec);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**********************************************************************
|
||
* InferUnread - figure out if a mailbox has unread mail from its label
|
||
* label 0xe means unread
|
||
* if there is an age limit, and mailbox is older, remove label
|
||
*
|
||
* - Added imap parameter to do special things to IMAP mail folders
|
||
**********************************************************************/
|
||
Boolean InferUnread(CInfoPBRec *hfi, Boolean imap)
|
||
{
|
||
CInfoPBRec *info = hfi;
|
||
CInfoPBRec mailboxFileInfo;
|
||
|
||
// if we're looking at an IMAP mailbox, peek inside the folder at the mailbox file.
|
||
if (imap)
|
||
{
|
||
Zero(mailboxFileInfo);
|
||
if (noErr==HGetCatInfo(info->hFileInfo.ioVRefNum,info->hFileInfo.ioDirID,info->hFileInfo.ioNamePtr,&mailboxFileInfo))
|
||
info = &mailboxFileInfo;
|
||
}
|
||
|
||
if ((info->hFileInfo.ioFlFndrInfo.fdFlags&0xe)==0xe)
|
||
{
|
||
uLong minDate;
|
||
FSSpec spec;
|
||
uLong curDate;
|
||
|
||
minDate = GetRLong(UNREAD_LIMIT)*24*3600;
|
||
if (minDate)
|
||
{
|
||
minDate = LocalDateTime()-minDate;
|
||
if (PrefIsSet(PREF_NEW_TOC))
|
||
curDate = info->hFileInfo.ioFlMdDat;
|
||
else
|
||
{
|
||
SimpleMakeFSSpec(info->hFileInfo.ioVRefNum,info->hFileInfo.ioFlParID,info->hFileInfo.ioNamePtr,&spec);
|
||
Box2TOCSpec(&spec,&spec);
|
||
curDate = FSpModDate(&spec);
|
||
}
|
||
if (curDate < minDate)
|
||
{
|
||
info->hFileInfo.ioFlFndrInfo.fdFlags &= ~0xe;
|
||
HSetFInfo(info->hFileInfo.ioVRefNum,info->hFileInfo.ioFlParID,info->hFileInfo.ioNamePtr,&info->hFileInfo.ioFlFndrInfo);
|
||
return(False); /* too old to have really unread mail */
|
||
}
|
||
}
|
||
return(True); /* label set to 1 and no min date or min date ok */
|
||
}
|
||
return(False); /* label not set to 1 */
|
||
}
|
||
|
||
/**********************************************************************
|
||
* BoxFolder - build the mailbox menus according to the files in
|
||
* a mailbox folder.
|
||
*
|
||
* - heavily uglified to add IMAP cache folders to menus
|
||
**********************************************************************/
|
||
void BoxFolder(short vRef,long dirId,MenuHandle *menus,BoxFolderDescPtr bfd, Boolean *anyUnread, Boolean appending,Boolean isIMAP)
|
||
{
|
||
NameType thisOne;
|
||
NameType **names=nil;
|
||
short count=0,i,item,dirItem;
|
||
MenuHandle newMenus[MENU_ARRAY_LIMIT];
|
||
Str15 suffix;
|
||
Str15 tmpsuffix;
|
||
Str32 s;
|
||
Boolean localAnyUnread=False;
|
||
Boolean isIMAPDir = false; // set to true once we know we're processing an IMAP cache directory
|
||
Boolean isSelectable = false;
|
||
Boolean haveIMAPpers = false;
|
||
Boolean isRoot = vRef==MailRoot.vRef && dirId==MailRoot.dirId;
|
||
Boolean junkIsSpecial = isRoot && JunkPrefBoxNoUnread();
|
||
uLong notAgain = 0;
|
||
|
||
/*
|
||
* make sure we're kosher
|
||
*/
|
||
if (bfd->level>MAX_BOX_LEVELS) DieWithError(TOO_MANY_LEVELS,bfd->level);
|
||
AddBoxMap(vRef,dirId);
|
||
|
||
/*
|
||
* get started
|
||
*/
|
||
if ((names=NuHandle(0L))==nil) DieWithError(ALLO_MBOX_LIST,MemError());
|
||
if (!PrefIsSet(PREF_NEW_TOC)) GetRString(suffix,TOC_SUFFIX);
|
||
else *suffix = 0;
|
||
GetRString(tmpsuffix,TEMP_SUFFIX);
|
||
|
||
/*
|
||
* read names of mailbox files
|
||
*/
|
||
for (bfd->hfi.hFileInfo.ioFDirIndex=0;!DirIterate(vRef,dirId,&bfd->hfi);)
|
||
{
|
||
if (HaveOSX() && bfd->hfi.hFileInfo.ioNamePtr[0] && bfd->hfi.hFileInfo.ioNamePtr[1]=='.')
|
||
// On OS X, files beginning with "." are invisible
|
||
goto nextfile;
|
||
|
||
/*
|
||
* make an FSSpec out of the info
|
||
*/
|
||
SimpleMakeFSSpec(vRef,dirId,bfd->hfi.hFileInfo.ioNamePtr,&thisOne.spec);
|
||
|
||
/*
|
||
* aliases at the root level that are marked with the stationery bit
|
||
* mean they were temporary mailboxes and should be cleaned up next
|
||
* time Eudora is launched on this mail folder
|
||
*/
|
||
if (StartingUp && isRoot &&
|
||
(bfd->hfi.hFileInfo.ioFlFndrInfo.fdFlags&(kIsStationery|kIsAlias))==(kIsStationery|kIsAlias))
|
||
{
|
||
if (notAgain != Hash(thisOne.spec.name))
|
||
{
|
||
notAgain = Hash(thisOne.spec.name);
|
||
if (!FSpDelete(&thisOne.spec))
|
||
{
|
||
bfd->hfi.hFileInfo.ioFDirIndex--;
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* is it a special name?
|
||
*/
|
||
if (IsRoot(&thisOne.spec))
|
||
for (i=0;i<bfd->badCount;i++)
|
||
if (StringSame(bfd->badNames[i],bfd->hfi.hFileInfo.ioNamePtr))
|
||
{
|
||
if (i<3 && InferUnread(&bfd->hfi, false))
|
||
MarkHavingUnread(menus[MAILBOX],i+1);
|
||
goto nextfile;
|
||
}
|
||
|
||
|
||
/*
|
||
* is this a special name, IMAP-ly speaking?
|
||
*/
|
||
if (IsSpecialIMAPName(bfd->hfi.hFileInfo.ioNamePtr, NULL))
|
||
{
|
||
isIMAPDir = true;
|
||
goto nextfile;
|
||
}
|
||
|
||
/*
|
||
* Is this another IMAP cache folder?
|
||
*/
|
||
|
||
if (IsFreeMode() && IsIMAPSubPers(&thisOne.spec))
|
||
{
|
||
isIMAPDir = true;
|
||
goto nextfile;
|
||
}
|
||
|
||
/*
|
||
* read the IMAP info from this box, ONLY if it's an IMAP mailbox.
|
||
*/
|
||
if (bfd->hfi.hFileInfo.ioFlFndrInfo.fdType == IMAP_MAILBOX_TYPE)
|
||
if (ReadIMAPMailboxAttributes(&thisOne.spec, &thisOne.imapAttributes)==noErr)
|
||
isIMAPDir = true;
|
||
|
||
/*
|
||
* does this mailbox have the same name as the enclosing folder, and is it an IMAP folder?
|
||
*/
|
||
if (isIMAPDir && StringSame(bfd->enclosingFolderName,bfd->hfi.hFileInfo.ioNamePtr) && IsIMAPMailboxFile(&thisOne.spec))
|
||
{
|
||
if (!(thisOne.imapAttributes&LATT_NOSELECT)) // we're building a menu to list mailboxes within a selectable mailbox
|
||
isSelectable = true;
|
||
|
||
goto nextfile;
|
||
}
|
||
|
||
thisOne.skipIt = false;
|
||
thisOne.isIMAPpers = false;
|
||
thisOne.moveToTop = isIMAP && StringSame(thisOne.spec.name,GetRString(s,IMAP_INBOX_NAME));
|
||
|
||
// is this file a folder?
|
||
thisOne.isDir = HFIIsFolderOrAlias(&bfd->hfi);
|
||
|
||
if (!thisOne.isDir)
|
||
{
|
||
if ((bfd->hfi.hFileInfo.ioFlFndrInfo.fdType!=MAILBOX_TYPE) && (bfd->hfi.hFileInfo.ioFlFndrInfo.fdType!=IMAP_MAILBOX_TYPE)) continue;
|
||
if (*bfd->hfi.hFileInfo.ioNamePtr>*tmpsuffix && EndsWith(bfd->hfi.hFileInfo.ioNamePtr,tmpsuffix))
|
||
TempWarning(bfd->hfi.hFileInfo.ioNamePtr);
|
||
if (*bfd->hfi.hFileInfo.ioNamePtr>31-*suffix)
|
||
{
|
||
TooLong(bfd->hfi.hFileInfo.ioNamePtr);
|
||
continue;
|
||
}
|
||
|
||
if (!junkIsSpecial || !SpecIsJunkSpec(&thisOne.spec))
|
||
{
|
||
if (thisOne.hasUnread = InferUnread(&bfd->hfi,false)) localAnyUnread = True;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
FSSpec tempSpec;
|
||
|
||
// look inside all IMAP mailboxes and folders to see if they contain unread messages
|
||
if (isIMAP)
|
||
{
|
||
if (thisOne.hasUnread = InferUnread(&bfd->hfi, true))
|
||
localAnyUnread = True;
|
||
}
|
||
else
|
||
thisOne.hasUnread = false;
|
||
|
||
if (IsAlias(&thisOne.spec,&tempSpec)) /* resolve alias */
|
||
{
|
||
if (!(thisOne.skipIt=SameSpec(&thisOne.spec,&tempSpec)))
|
||
{
|
||
thisOne.spec.parID = SpecDirId(&tempSpec); /* get dirid of folder */
|
||
thisOne.spec.vRefNum = tempSpec.vRefNum;
|
||
if (tempSpec.parID == IMAPMailRoot.dirId)
|
||
{
|
||
thisOne.isIMAPpers = true;
|
||
haveIMAPpers = true;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
thisOne.spec.parID = bfd->hfi.hFileInfo.ioDirID;
|
||
}
|
||
PtrPlusHand_ (&thisOne,names,sizeof(thisOne));
|
||
if (MemError()) DieWithError(ALLO_MBOX_LIST,MemError());
|
||
count++;
|
||
nextfile:;
|
||
}
|
||
|
||
/*
|
||
* sort them
|
||
*/
|
||
BoxNamesSort(names);
|
||
|
||
/*
|
||
* add the New item
|
||
*/
|
||
if (!appending)
|
||
{
|
||
AppendMenu(menus[TRANSFER],bfd->newText);
|
||
#ifdef TWO
|
||
AppendMenu(menus[MAILBOX],bfd->newText);
|
||
}
|
||
if (isIMAPDir == false && !appending)
|
||
{
|
||
AppendMenu(menus[MAILBOX],bfd->otherText);
|
||
AppendMenu(menus[TRANSFER],bfd->otherText);
|
||
}
|
||
else
|
||
if (isSelectable == true) // this menu represents the contents of a SELECTable IMAP mailbox
|
||
{
|
||
AppendMenu(menus[MAILBOX],bfd->thisBoxText);
|
||
AppendMenu(menus[TRANSFER],bfd->thisBoxText);
|
||
}
|
||
else // this menu represents the contents of a non-SELECTable mailbox - a folder.
|
||
{
|
||
AppendMenu(menus[MAILBOX],"\p-");
|
||
AppendMenu(menus[TRANSFER],"\p-");
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
* stick them into the proper menus
|
||
*/
|
||
{
|
||
for (item=0;item<count;item++)
|
||
{
|
||
if ((*names)[item].isDir || (*names)[item].skipIt) continue;
|
||
thisOne = (*names)[item];
|
||
MyAppendMenu(menus[MAILBOX],thisOne.spec.name);
|
||
GetRString(thisOne.spec.name,TRANSFER_PREFIX);
|
||
PCat(thisOne.spec.name,(*names)[item].spec.name);
|
||
MyAppendMenu(menus[TRANSFER],thisOne.spec.name);
|
||
if (thisOne.hasUnread)
|
||
MarkHavingUnread(menus[MAILBOX],CountMenuItems(menus[MAILBOX]));
|
||
CycleBalls();
|
||
}
|
||
}
|
||
|
||
for (item=0;item<count;item++)
|
||
{
|
||
IMAPMailboxAttributes att;
|
||
|
||
if (!(*names)[item].isDir || (*names)[item].skipIt) continue;
|
||
thisOne = (*names)[item];
|
||
|
||
MyAppendMenu(menus[MAILBOX],thisOne.spec.name);
|
||
if (isIMAPDir && thisOne.hasUnread) MarkHavingUnread(menus[MAILBOX],CountMenuItems(menus[MAILBOX]));
|
||
GetRString(thisOne.spec.name,TRANSFER_PREFIX);
|
||
PCat(thisOne.spec.name,(*names)[item].spec.name);
|
||
MyAppendMenu(menus[TRANSFER],thisOne.spec.name);
|
||
thisOne = (*names)[item];
|
||
|
||
// Special cases when not to stick a submenu onto this guy
|
||
if (isIMAPDir && MailboxAttributes(&thisOne.spec,&att))
|
||
{
|
||
// no submenu on mailboxes that can't have children
|
||
if (att.noInferiors) continue;
|
||
|
||
// no submenu on mailboxes with messages but no children
|
||
if (!att.noSelect && !att.hasChildren) continue;
|
||
}
|
||
|
||
for (i=0;i<MENU_ARRAY_LIMIT;i++)
|
||
{
|
||
dirItem = i*MAX_BOX_LEVELS+bfd->level+1;
|
||
if (!(newMenus[i] = NewMenu(dirItem,thisOne.spec.name)))
|
||
DieWithError(ALLO_MBOX_LIST,MemError());
|
||
AttachHierMenu(GetMenuID(menus[i]),CountMenuItems(menus[i]),dirItem);
|
||
InsertMenu(newMenus[i],-1);
|
||
#ifdef NEVER
|
||
if (HasHelp && !isRoot && !Get1Resource('hmnu',dirItem))
|
||
{
|
||
Handle mHand=GetResource_('hmnu',i*MAX_BOX_LEVELS+1);
|
||
Handle newHand=mHand;
|
||
if (mHand && !HandToHand_(&newHand))
|
||
{
|
||
AddResource_(newHand,'hmnu',dirItem,"");
|
||
SetResAttrs(newHand,resChanged|resPurgeable);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
bfd->level++;
|
||
PCopy(bfd->enclosingFolderName,thisOne.spec.name);
|
||
BoxFolder(thisOne.spec.vRefNum,thisOne.spec.parID,newMenus,bfd,&thisOne.hasUnread,false,isIMAP);
|
||
if (MemError()) DieWithError(ALLO_MBOX_LIST,MemError());
|
||
if (thisOne.hasUnread)
|
||
{
|
||
localAnyUnread = True;
|
||
MarkHavingUnread(menus[MAILBOX],CountMenuItems(menus[MAILBOX]));
|
||
}
|
||
}
|
||
|
||
// If MacOS 8.5 (Appearance 1.1) or greater, make sure
|
||
// menu items 32+ are enabled using menu manager
|
||
if (gHave85MenuMgr)
|
||
{
|
||
count = CountMenuItems(menus[MAILBOX]);
|
||
for (item=32;item<=count;item++)
|
||
{
|
||
EnableMenuItem(menus[MAILBOX],item);
|
||
EnableMenuItem(menus[TRANSFER],item);
|
||
}
|
||
}
|
||
|
||
ZapHandle(names);
|
||
*anyUnread = localAnyUnread || *anyUnread;
|
||
}
|
||
|
||
/************************************************************************
|
||
* MarkHavingUnread - mark a mailbox as having unread messages
|
||
************************************************************************/
|
||
void MarkHavingUnread(MenuHandle mh, short item)
|
||
{
|
||
SetItemStyle(mh,item,UnreadStyle);
|
||
}
|
||
|
||
/************************************************************************
|
||
* BoxNamesSort - sort mailbox names
|
||
************************************************************************/
|
||
void BoxNamesSort(NameType **names)
|
||
{
|
||
NameType last;
|
||
short n = GetHandleSize_(names)/sizeof(last);
|
||
|
||
Zero(last);
|
||
InfiniteString(last.spec.name,sizeof(last.spec.name));
|
||
PtrPlusHand_(&last,names,sizeof(last));
|
||
|
||
QuickSort((void*)LDRef(names),sizeof(last),0,n-1,(void*)NameCompare,(void*)NameSwap);
|
||
UL(names);
|
||
|
||
SetHandleBig_(names,n*sizeof(last));
|
||
}
|
||
|
||
/************************************************************************
|
||
* NameCompare - compare two names
|
||
************************************************************************/
|
||
int NameCompare(NameType *n1, NameType *n2)
|
||
{
|
||
#ifdef IMAP
|
||
if (n1->moveToTop != n2->moveToTop)
|
||
return n1->moveToTop ? -1 : 1;
|
||
#endif
|
||
return(StringComp(n1->spec.name,n2->spec.name));
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* NameSwap - swap two names
|
||
************************************************************************/
|
||
void NameSwap(NameType *n1, NameType *n2)
|
||
{
|
||
NameType temp = *n2;
|
||
*n2 = *n1;
|
||
*n1 = temp;
|
||
}
|
||
|
||
/************************************************************************
|
||
* TempWarning - warn the user about a temp file in his mailbox structure
|
||
************************************************************************/
|
||
void TempWarning(UPtr filename)
|
||
{
|
||
Str255 msg;
|
||
GetRString(msg,TEMP_WARNING);
|
||
MyParamText(msg,filename,"","");
|
||
ReallyDoAnAlert(OK_ALRT,Caution);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* BuildBoxMenus - build the mailbox menus according to the files in
|
||
* our mailbox folder.
|
||
**********************************************************************/
|
||
void BuildBoxMenus()
|
||
{
|
||
BoxFolderDesc bfd;
|
||
short badIndices[] = {IN,OUT,JUNK,TRASH}; // 1st 3 must be in,out,trash
|
||
Str31 badNames[sizeof(badIndices)/sizeof(short)];
|
||
MenuHandle menus[MENU_ARRAY_LIMIT];
|
||
short i;
|
||
Boolean anyUnread;
|
||
|
||
#ifdef DEBUG
|
||
Log(LOG_TPUT,"\pBuildBoxMenus begin");
|
||
#endif
|
||
|
||
/*
|
||
* this may mess with the head of the filters.
|
||
* trash them if we dare
|
||
*/
|
||
if (Filters && !FiltersRefCount) ZapFilters();
|
||
|
||
/*
|
||
* set up descriptor (saves stack space, parameter shuffling)
|
||
*/
|
||
bfd.badNames = badNames;
|
||
bfd.badCount = sizeof(badIndices)/sizeof(short);
|
||
bfd.level = g16bitSubMenuIDs ? BOX_MENU_START-1: 0;
|
||
Zero(bfd.hfi);
|
||
bfd.hfi.hFileInfo.ioNamePtr = bfd.hfi_namePtr;
|
||
|
||
if (BoxMap!=nil) RemoveBoxMenus();
|
||
if ((BoxMap=NuHandle(0L))==nil) DieWithError(ALLO_MBOX_LIST,MemError());
|
||
for (i=0;i<sizeof(badIndices)/sizeof(short);i++)
|
||
GetRString(badNames[i],badIndices[i]);
|
||
GetRString(bfd.newText,NEW_ITEM_TEXT);
|
||
#ifdef TWO
|
||
GetRString(bfd.otherText,OTHER_ITEM_TEXT);
|
||
#ifdef IMAP
|
||
GetRString(bfd.thisBoxText,IMAP_THIS_MAILBOX_NAME);
|
||
GetRString(bfd.enclosingFolderName,MAIL_FOLDER_NAME);
|
||
#endif
|
||
#endif
|
||
|
||
/*
|
||
* stick them into the proper menus
|
||
*/
|
||
menus[MAILBOX] = GetMHandle(MAILBOX_MENU);
|
||
menus[TRANSFER] = GetMHandle(TRANSFER_MENU);
|
||
|
||
/*
|
||
* rename a few
|
||
*/
|
||
{
|
||
short aliases[] = {FILE_ALIAS_IN,FILE_ALIAS_OUT,FILE_ALIAS_JUNK,FILE_ALIAS_TRASH,0};
|
||
Str63 name;
|
||
Str15 prefix;
|
||
|
||
GetRString(prefix,TRANSFER_PREFIX);
|
||
for (i=0;aliases[i];i++)
|
||
{
|
||
GetRString(name,aliases[i]);
|
||
SetMenuItemText(menus[MAILBOX],i+1,name);
|
||
PInsert(name,sizeof(name),prefix,name+1);
|
||
SetMenuItemText(menus[TRANSFER],i+1,name);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* now, do the recursive thing
|
||
*/
|
||
BoxFolder(MailRoot.vRef,MailRoot.dirId,menus,&bfd,&anyUnread,false,false);
|
||
#ifdef IMAP
|
||
if (IMAPExists())
|
||
{
|
||
bfd.level++;
|
||
BoxFolder(IMAPMailRoot.vRef,IMAPMailRoot.dirId,menus,&bfd,&anyUnread,true,true);
|
||
}
|
||
#endif
|
||
#ifdef NEVER
|
||
if (HasHelp) MakeHmnusPurge();
|
||
#endif
|
||
BuildBoxCount();
|
||
#ifdef DEBUG
|
||
Log(LOG_TPUT,"\pBuildBoxMenus end");
|
||
#endif
|
||
}
|
||
|
||
/************************************************************************
|
||
* RemoveBoxMenus - get a clean slate
|
||
************************************************************************/
|
||
void RemoveBoxMenus(void)
|
||
{
|
||
ZapHandle(BoxMap); BoxMap = nil;
|
||
#ifdef NEVER
|
||
TrashHmnu();
|
||
#endif
|
||
CheckBox(nil,False);
|
||
#ifdef TWO
|
||
TrashMenu(GetMHandle(MAILBOX_MENU),MAILBOX_NEW_ITEM);
|
||
#else
|
||
TrashMenu(GetMHandle(MAILBOX_MENU),MAILBOX_FIRST_USER_ITEM);
|
||
#endif
|
||
TrashMenu(GetMHandle(TRANSFER_MENU),TRANSFER_NEW_ITEM);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* BuildStationMenu - build the stationery menu
|
||
**********************************************************************/
|
||
void BuildStationMenu(void)
|
||
{
|
||
MenuHandle mhReply,mhNew;
|
||
Str255 string;
|
||
FSSpec folderSpec;
|
||
CInfoPBRec hfi;
|
||
long newDirId;
|
||
|
||
if (!HasFeature (featureStationery))
|
||
return;
|
||
|
||
/*
|
||
* create the folder
|
||
*/
|
||
DirCreate(Root.vRef,Root.dirId,GetRString(string,STATION_FOLDER),&newDirId);
|
||
|
||
/*
|
||
* wipe out the old menu
|
||
*/
|
||
if (mhReply=GetMHandle(REPLY_WITH_HIER_MENU)) {DeleteMenu(REPLY_WITH_HIER_MENU); DisposeMenu(mhReply);}
|
||
if (mhNew=GetMHandle(NEW_WITH_HIER_MENU)) {DeleteMenu(NEW_WITH_HIER_MENU); DisposeMenu(mhNew);}
|
||
|
||
/*
|
||
* is there a folder?
|
||
*/
|
||
if (!SubFolderSpec(STATION_FOLDER,&folderSpec))
|
||
{
|
||
StationVRef = folderSpec.vRefNum;
|
||
StationDirId = folderSpec.parID;
|
||
|
||
/*
|
||
* attach the menu
|
||
*/
|
||
AttachHierMenu(MESSAGE_MENU,MESSAGE_REPLY_WITH_ITEM,REPLY_WITH_HIER_MENU);
|
||
AttachHierMenu(MESSAGE_MENU,MESSAGE_NEW_WITH_ITEM,NEW_WITH_HIER_MENU);
|
||
|
||
/*
|
||
* create the new menu
|
||
*/
|
||
MyGetItem(GetMHandle(MESSAGE_MENU),MESSAGE_REPLY_WITH_ITEM,string);
|
||
if (mhReply = NewMenu(REPLY_WITH_HIER_MENU,string))
|
||
if (mhNew = NewMenu(NEW_WITH_HIER_MENU,GetRString(string,NEW_MESSAGE_WITH)))
|
||
{
|
||
InsertMenu(mhReply,-1);
|
||
InsertMenu(mhNew,-1);
|
||
|
||
/*
|
||
* iterate through all the files, adding them to the list
|
||
*/
|
||
hfi.hFileInfo.ioNamePtr = string;
|
||
hfi.hFileInfo.ioFDirIndex = 0;
|
||
while (!DirIterate(folderSpec.vRefNum,folderSpec.parID,&hfi))
|
||
if (hfi.hFileInfo.ioFlFndrInfo.fdType==STATIONERY_TYPE)
|
||
{
|
||
MyAppendMenu(mhReply,string);
|
||
MyAppendMenu(mhNew,string);
|
||
}
|
||
|
||
if (!CountMenuItems(mhReply))
|
||
{
|
||
MyAppendMenu(mhReply,GetRString(string,NO_STATIONERY));
|
||
DisableItem(mhReply,1);
|
||
SetItemStyle(mhReply,1,italic);
|
||
MyAppendMenu(mhNew,string);
|
||
DisableItem(mhNew,1);
|
||
SetItemStyle(mhNew,1,italic);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**********************************************************************
|
||
* BuildPersMenu - build the personality menu
|
||
**********************************************************************/
|
||
void BuildPersMenu(void)
|
||
{
|
||
MenuHandle mh;
|
||
Str255 string;
|
||
PersHandle pers;
|
||
|
||
if (!HasFeature (featureMultiplePersonalities))
|
||
return;
|
||
|
||
/*
|
||
* wipe out the old menu
|
||
*/
|
||
if (mh=GetMHandle(PERS_HIER_MENU)) {DeleteMenu(PERS_HIER_MENU); ReleaseResource_(mh);}
|
||
|
||
/*
|
||
* grab the menu
|
||
*/
|
||
GetAndInsertHier(PERS_HIER_MENU);
|
||
|
||
if (mh=GetMHandle(PERS_HIER_MENU))
|
||
{
|
||
for (pers=(*PersList)->next;pers;pers=(*pers)->next)
|
||
MyAppendMenu(mh,PCopy(string,(*pers)->name));
|
||
}
|
||
}
|
||
|
||
/**********************************************************************
|
||
* BuildMarginMenu - build the margin menu
|
||
**********************************************************************/
|
||
void BuildMarginMenu(void)
|
||
{
|
||
MenuHandle mh;
|
||
Str255 scratch;
|
||
Str255 name;
|
||
short i;
|
||
|
||
if (mh=GetMHandle(MARGIN_HIER_MENU)) {TrashMenu(mh,3);}
|
||
|
||
for (i=1;*GetRString(scratch,MarginStrn+i);i++)
|
||
{
|
||
if (!Ascii2Margin(scratch,name,nil))
|
||
{
|
||
if (*name==1 && name[1]=='-') AppendMenu(mh,name);
|
||
else MyAppendMenu(mh,name);
|
||
}
|
||
else AppendMenu(mh,"\p-");
|
||
}
|
||
GetRString(scratch,ADD_BULLETS);
|
||
AppendMenu(mh,scratch);
|
||
}
|
||
|
||
|
||
#ifdef NEVER
|
||
/************************************************************************
|
||
* TrashHmnu - get rid of the help resources for subfolders
|
||
************************************************************************/
|
||
void TrashHmnu(void)
|
||
{
|
||
short i,n;
|
||
Handle hHand;
|
||
|
||
n = GetHandleSize_(BoxMap)/sizeof(long);
|
||
for (i=2;i<=n;i++)
|
||
{
|
||
ZapSettingsResource('hmnu',i);
|
||
ZapSettingsResource('hmnu',i+MAX_BOX_LEVELS);
|
||
}
|
||
MyUpdateResFile(CurResFile());
|
||
}
|
||
|
||
/************************************************************************
|
||
* MakeHmnusPurge - make sure we can purge the Hmnus
|
||
************************************************************************/
|
||
void MakeHmnusPurge(void)
|
||
{
|
||
short i,n;
|
||
Handle hHand;
|
||
|
||
/*
|
||
* first off, get them written out
|
||
*/
|
||
MyUpdateResFile(CurResFile());
|
||
|
||
/*
|
||
* trash 'em
|
||
*/
|
||
n = GetHandleSize_(BoxMap)/sizeof(long);
|
||
SetResLoad(False);
|
||
for (i=1;i<=n;i++)
|
||
{
|
||
if (hHand=Get1Resource('hmnu',i))
|
||
ReleaseResource_(hHand);
|
||
if (hHand=Get1Resource('hmnu',i+MAX_BOX_LEVELS))
|
||
ReleaseResource_(hHand);
|
||
}
|
||
SetResLoad(True);
|
||
}
|
||
#endif
|
||
|
||
#ifdef THREADING_ON
|
||
void CreateTempBox(short which)
|
||
{
|
||
Str63 name;
|
||
int err;
|
||
FSSpec spec,
|
||
spool;
|
||
|
||
if (err=SubFolderSpec(SPOOL_FOLDER,&spool))
|
||
DieWithError(CREATING_MAILBOX,err); // or some other error
|
||
|
||
// create temporary mailbox
|
||
GetRString(name,which);
|
||
if (FSMakeFSSpec(spool.vRefNum,spool.parID,name,&spec))
|
||
if (err=MakeResFile(name,spool.vRefNum,spool.parID,CREATOR,MAILBOX_TYPE))
|
||
DieWithError(CREATING_MAILBOX,err);
|
||
}
|
||
#endif THREADING_ON
|
||
|
||
/**********************************************************************
|
||
* CreateBoxes - Create the "In" and "Out" mailboxes if need be
|
||
**********************************************************************/
|
||
void CreateBoxes()
|
||
{
|
||
Str63 name;
|
||
int err;
|
||
FSSpec spec;
|
||
|
||
#ifdef THREADING_ON
|
||
CreateTempBox(IN_TEMP);
|
||
CreateTempBox(OUT_TEMP);
|
||
#endif THREADING_ON
|
||
|
||
GetRString(name,IN);
|
||
if (FSMakeFSSpec(MailRoot.vRef,MailRoot.dirId,name,&spec))
|
||
if (err=MakeResFile(name,MailRoot.vRef,MailRoot.dirId,CREATOR,MAILBOX_TYPE))
|
||
DieWithError(CREATING_MAILBOX,err);
|
||
GetRString(name,OUT);
|
||
if (FSMakeFSSpec(MailRoot.vRef,MailRoot.dirId,name,&spec))
|
||
if (err=MakeResFile(name,MailRoot.vRef,MailRoot.dirId,CREATOR,MAILBOX_TYPE))
|
||
DieWithError(CREATING_MAILBOX,err);
|
||
GetRString(name,TRASH);
|
||
if (FSMakeFSSpec(MailRoot.vRef,MailRoot.dirId,name,&spec))
|
||
if (err=MakeResFile(name,MailRoot.vRef,MailRoot.dirId,CREATOR,MAILBOX_TYPE))
|
||
DieWithError(CREATING_MAILBOX,err);
|
||
|
||
if (JunkPrefNeedIntro()) JunkIntro();
|
||
GetRString(name,JUNK);
|
||
if (FSMakeFSSpec(MailRoot.vRef,MailRoot.dirId,name,&spec))
|
||
{
|
||
if (err=MakeResFile(name,MailRoot.vRef,MailRoot.dirId,CREATOR,MAILBOX_TYPE))
|
||
DieWithError(CREATING_MAILBOX,err);
|
||
// we made it, we don't need to warn about it
|
||
SetPrefLong(PREF_JUNK_MAILBOX,GetPrefLong(PREF_JUNK_MAILBOX)|bJunkPrefBoxExistWarning);
|
||
}
|
||
else if (FSpIsItAFolder(&spec) || JunkPrefBoxExistWarning())
|
||
PreexistingJunkWarning(&spec);
|
||
|
||
GetRString(name,ALIAS_FILE);
|
||
if (FSMakeFSSpec(Root.vRef,Root.dirId,name,&spec))
|
||
if (err=MakeResFile(name,Root.vRef,Root.dirId,CREATOR,'TEXT'))
|
||
DieWithError(CREATING_ALIAS,err);
|
||
if (HasFeature (featureNicknameWatching))
|
||
{
|
||
GetRString(name,CACHE_ALIAS_FILE);
|
||
if (FSMakeFSSpec(Root.vRef,Root.dirId,name,&spec))
|
||
(void) MakeResFile(name,Root.vRef,Root.dirId,CREATOR,'TEXT'); // No error check, we just won't cache addresses
|
||
}
|
||
#ifdef VCARD
|
||
if (IsVCardAvailable ()) {
|
||
GetRString(name,PERSONAL_ALIAS_FILE);
|
||
if (FSMakeFSSpec(Root.vRef,Root.dirId,name,&spec))
|
||
if (err=MakeResFile(name,Root.vRef,Root.dirId,CREATOR,'TEXT'))
|
||
DieWithError(CREATING_PERSONAL_ALIAS,err);
|
||
}
|
||
#endif
|
||
|
||
GetRString(name,LINK_HISTORY_FILE);
|
||
if (FSMakeFSSpec(Root.vRef,Root.dirId,name,&spec))
|
||
if (err=MakeResFile(name,Root.vRef,Root.dirId,CREATOR,'TEXT'))
|
||
DieWithError(CREATING_LINK_HISTORY,err);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* GetBoxLines - read the horizontal widths of the various mailbox
|
||
* data areas.
|
||
**********************************************************************/
|
||
void GetBoxLines(void)
|
||
{
|
||
Handle strn;
|
||
int count;
|
||
Str255 scratch;
|
||
long rightSide;
|
||
short last=0;
|
||
short offset=0;
|
||
short i;
|
||
|
||
strn=GetResource_('STR#',BoxLinesStrn);
|
||
if (strn==nil) DieWithError(GENERAL,ResError());
|
||
|
||
count = *((short *)*strn);
|
||
if (count<BoxLinesLimit-1)
|
||
{
|
||
RemoveResource(strn); strn = nil;
|
||
strn = GetResource_('STR#',BoxLinesStrn);
|
||
count = *((short *)*strn);
|
||
SetPref(TOC_INVERSION_MATRIX,"");
|
||
}
|
||
|
||
if (!BoxWidths) BoxWidths = NuHandle(count*sizeof(short));
|
||
if (BoxWidths==nil) DieWithError(MEM_ERR,MemError());
|
||
|
||
for(i=0;i<count;i++)
|
||
{
|
||
StringToNum(GetRString(scratch,BoxLinesStrn+i+1),&rightSide);
|
||
(*BoxWidths)[i] = rightSide;
|
||
}
|
||
|
||
BoxInversionSetup();
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* SetupInsurancePort - create a grafport for use when others are unavailable
|
||
************************************************************************/
|
||
void SetupInsurancePort(void)
|
||
{
|
||
if (!InsurancePort)
|
||
{
|
||
MyCreateNewPort(InsurancePort);
|
||
if (!InsurancePort) DieWithError(MEM_ERR,MemError());
|
||
}
|
||
SetPort_(InsurancePort);
|
||
TextFont(FontID);
|
||
TextSize(FontSize);
|
||
}
|
||
|
||
/************************************************************************
|
||
* ModernSystem - is the system 7 or better?
|
||
************************************************************************/
|
||
Boolean ModernSystem(void)
|
||
{
|
||
long resp;
|
||
long sysVers;
|
||
|
||
HasHelp = !Gestalt(gestaltHelpMgrAttr,&resp) &&
|
||
resp&(1L<<gestaltHelpMgrPresent);
|
||
HasPM = !Gestalt(gestaltOSAttr,&resp) && resp&(1L<<gestaltLaunchControl);
|
||
if (HasPM && !Gestalt(gestaltAUXVersion, &resp))
|
||
HasPM = (resp>>8)>=3;
|
||
if (Gestalt(gestaltComponentMgr,&resp)) DieWithError(NEED_COMPONENT_MGR,0);
|
||
return !Gestalt(gestaltSystemVersion, &sysVers) ? sysVers >= 0x0700 : false;
|
||
}
|
||
|
||
void RememberOpenWindows(void)
|
||
{
|
||
DejaVuHandle dvh;
|
||
DejaVu dv;
|
||
short ind;
|
||
WindowPtr theWindow;
|
||
|
||
if (!SettingsRefN) return;
|
||
else UseResFile(SettingsRefN);
|
||
|
||
/*
|
||
* out with the old
|
||
*/
|
||
SetResLoad(False);
|
||
while (dvh=(DejaVuHandle)Get1IndResource(DEJA_VU_TYPE,1))
|
||
{
|
||
SetResLoad(True); RemoveResource((Handle)dvh); SetResLoad(False);
|
||
DisposeHandle((Handle)dvh);
|
||
}
|
||
SetResLoad(True);
|
||
|
||
/*
|
||
* save each window
|
||
*/
|
||
ind = 1000;
|
||
for (theWindow = GetWindowList (); theWindow; theWindow = GetNextWindow (theWindow))
|
||
if (IsKnownWindowMyWindow(theWindow) && IsWindowVisible(theWindow))
|
||
if (RememberWindow(theWindow,&dv))
|
||
if (dvh=NuHandle(sizeof(dv)))
|
||
{
|
||
BMD(&dv,*dvh,sizeof(dv));
|
||
AddMyResource_(dvh,DEJA_VU_TYPE,++ind,"");
|
||
ReleaseResource_(dvh);
|
||
}
|
||
UpdateResFile(SettingsRefN);
|
||
WashMe = false;
|
||
}
|
||
|
||
|
||
/************************************************************************
|
||
* RecallOpenWindows - reopen windows there when we quit
|
||
************************************************************************/
|
||
void RecallOpenWindows(void)
|
||
{
|
||
short ind;
|
||
DejaVuHandle dvh;
|
||
DejaVu dv;
|
||
WindowPtr theWindow;
|
||
|
||
#ifdef TWO
|
||
if (DBSplash != nil)
|
||
{
|
||
DisposDialog_(DBSplash); /* splash screen */
|
||
DBSplash = nil;
|
||
}
|
||
FlushEvents(everyEvent,0);
|
||
#endif
|
||
|
||
UseResFile(SettingsRefN);
|
||
|
||
for (ind=1000+Count1Resources(DEJA_VU_TYPE);!EjectBuckaroo && ind>1000;ind--)
|
||
{
|
||
CycleBalls();
|
||
UseResFile(SettingsRefN);
|
||
if (dvh=(DejaVuHandle)Get1Resource(DEJA_VU_TYPE,ind))
|
||
{
|
||
ActivateMyWindow(FrontWindow(),False);
|
||
dv = **dvh;
|
||
if (GetHandleSize_(dvh)<sizeof(dv)) dv.id = 0;
|
||
ReleaseResource_(dvh);
|
||
RecallWindow(&dv);
|
||
}
|
||
MonitorGrow(True);
|
||
FloatingWinIdle(); // fix any layering problems we might have
|
||
}
|
||
|
||
for (theWindow = GetWindowList (); theWindow; theWindow = GetNextWindow (theWindow))
|
||
{
|
||
Rect rContent;
|
||
Point o;
|
||
|
||
SetPort(GetWindowPort(theWindow));
|
||
GetContentRgnBounds(theWindow,&rContent);
|
||
o.h = o.v = 0;
|
||
GlobalToLocal(&o);
|
||
OffsetRect(&rContent,o.h,o.v);
|
||
InvalWindowRect(theWindow,&rContent);
|
||
if (IsKnownWindowMyWindow(theWindow)) UpdateMyWindow(theWindow);
|
||
}
|
||
|
||
if (IsAdwareMode()) OpenAdWindow();
|
||
}
|
||
|
||
/************************************************************************
|
||
* FolderSniffer - look for a folder in various places, and give a shout
|
||
* for each one found. Similar to OpenPlugins, but general-purpose.
|
||
* OpenPlugins left alone for now, for backward compatibility
|
||
************************************************************************/
|
||
void FolderSniffer(short subfolderID,FolderSnifferFunc sniffer,uLong refCon)
|
||
{
|
||
Str31 subfolderName;
|
||
|
||
GetRString(subfolderName,subfolderID);
|
||
FolderSnifferStr(subfolderName,sniffer,refCon);
|
||
}
|
||
|
||
void FolderSnifferStr(PStr subfolderName,FolderSnifferFunc sniffer,uLong refCon)
|
||
{
|
||
FSSpec spec;
|
||
Str31 name;
|
||
FSSpec appSpec;
|
||
OSErr err;
|
||
|
||
/*
|
||
* in folder with Eudora
|
||
*/
|
||
if (!GetFileByRef(AppResFile,&spec))
|
||
{
|
||
appSpec = spec;
|
||
|
||
// right next to Eudora
|
||
if (!FSMakeFSSpec(spec.vRefNum,spec.parID,subfolderName,&spec))
|
||
{
|
||
IsAlias(&spec,&spec);
|
||
spec.parID = SpecDirId(&spec);
|
||
sniffer(spec.vRefNum,spec.parID,refCon);
|
||
}
|
||
|
||
// subfolder of Eudora Stuff folder
|
||
if (!FSMakeFSSpec(spec.vRefNum,spec.parID,GetRString(name,STUFF_FOLDER),&spec))
|
||
{
|
||
IsAlias(&spec,&spec);
|
||
if (!(err=FSMakeFSSpec(spec.vRefNum,SpecDirId(&spec),subfolderName,&spec)))
|
||
{
|
||
IsAlias(&spec,&spec);
|
||
spec.parID = SpecDirId(&spec);
|
||
sniffer(spec.vRefNum,spec.parID,refCon);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* if we're packaged, in Eudora Stuff folder up and over
|
||
*/
|
||
if (!(err=ParentSpec(&appSpec,&spec)))
|
||
if (!(err=FSMakeFSSpec(spec.vRefNum,spec.parID,GetRString(name,PACKAGE_MACOS_FOLDER),&spec)))
|
||
if (!(err=FSMakeFSSpec(spec.vRefNum,spec.parID,GetRString(name,STUFF_FOLDER),&spec)))
|
||
{
|
||
IsAlias(&spec,&spec);
|
||
if (!(err=FSMakeFSSpec(spec.vRefNum,spec.parID,subfolderName,&spec)))
|
||
{
|
||
IsAlias(&spec,&spec);
|
||
spec.parID = SpecDirId(&spec);
|
||
sniffer(spec.vRefNum,spec.parID,refCon);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* various application support folders/Eudora
|
||
*/
|
||
{
|
||
long domains[]={kUserDomain,kLocalDomain,kSystemDomain,kNetworkDomain};
|
||
FSSpec spec, oldSpec;
|
||
short n = sizeof(domains)/sizeof(domains[0]);
|
||
|
||
Zero(oldSpec);
|
||
while (n-->0)
|
||
if (!FindSubFolderSpec(domains[n],kApplicationSupportFolderType,EUDORA_EUDORA,false,&spec))
|
||
if (!SameSpec(&spec,&oldSpec))
|
||
{
|
||
oldSpec = spec;
|
||
if (!SubFolderSpecOfStr(&spec,subfolderName,false,&spec))
|
||
sniffer(spec.vRefNum,spec.parID,refCon);
|
||
}
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
* OpenPlugIns - open extra Eudora resource files
|
||
************************************************************************/
|
||
void OpenPlugIns(void)
|
||
{
|
||
FSSpec spec;
|
||
Str31 name;
|
||
short vRef;
|
||
long dirId;
|
||
FSSpec appSpec;
|
||
OSErr err;
|
||
|
||
/*
|
||
* in folder with Eudora
|
||
*/
|
||
if (!GetFileByRef(AppResFile,&spec))
|
||
{
|
||
appSpec = spec;
|
||
|
||
PlugInDir(spec.vRefNum,spec.parID);
|
||
|
||
/*
|
||
* in Eudora Stuff folder
|
||
*/
|
||
if (!FSMakeFSSpec(spec.vRefNum,spec.parID,GetRString(name,STUFF_FOLDER),&spec))
|
||
{
|
||
IsAlias(&spec,&spec);
|
||
spec.parID = SpecDirId(&spec);
|
||
PlugInDir(spec.vRefNum,spec.parID);
|
||
}
|
||
|
||
/*
|
||
* if we're packaged, in plugins folder up and over
|
||
*/
|
||
if (!(err=ParentSpec(&appSpec,&spec)))
|
||
if (!(err=FSMakeFSSpec(spec.vRefNum,spec.parID,GetRString(name,PACKAGE_MACOS_FOLDER),&spec)))
|
||
if (!(err=FSMakeFSSpec(spec.vRefNum,spec.parID,GetRString(name,PACKAGE_PLUGINS_FOLDER),&spec)))
|
||
{
|
||
IsAlias(&spec,&spec);
|
||
spec.parID = SpecDirId(&spec);
|
||
PlugInDir(spec.vRefNum,spec.parID);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* in system prefs folder
|
||
*/
|
||
if (PrefsPlugIns && !FindFolder(kOnSystemDisk,kPreferencesFolderType,False,&vRef,&dirId))
|
||
PrefPlugEnd = PlugInDir(vRef,dirId);
|
||
|
||
/*
|
||
* various application support folders/Eudora
|
||
*/
|
||
{
|
||
long domains[]={kUserDomain,kLocalDomain,kSystemDomain,kNetworkDomain};
|
||
FSSpec spec, oldSpec;
|
||
short n = sizeof(domains)/sizeof(domains[0]);
|
||
|
||
Zero(oldSpec);
|
||
while (n-->0)
|
||
if (!FindSubFolderSpec(domains[n],kApplicationSupportFolderType,EUDORA_EUDORA,false,&spec))
|
||
if (!SameSpec(&spec,&oldSpec))
|
||
{
|
||
oldSpec = spec;
|
||
if (!SubFolderSpecOf(&spec,PACKAGE_PLUGINS_FOLDER,false,&spec))
|
||
PlugInDir(spec.vRefNum,spec.parID);
|
||
}
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
* PlugInDir - open plug-ins in a directory
|
||
************************************************************************/
|
||
short PlugInDir(short vRef,long dirId)
|
||
{
|
||
CInfoPBRec hfi;
|
||
Str31 name;
|
||
short refN;
|
||
short lastRefN = CurResFile();
|
||
FSSpec spec;
|
||
|
||
hfi.hFileInfo.ioNamePtr = name;
|
||
hfi.hFileInfo.ioFDirIndex = 0;
|
||
while(!DirIterate(vRef,dirId,&hfi))
|
||
if ((hfi.hFileInfo.ioFlFndrInfo.fdType==PLUG_TYPE ||
|
||
hfi.hFileInfo.ioFlFndrInfo.fdType==HELP_TYPE) &&
|
||
hfi.hFileInfo.ioFlFndrInfo.fdCreator==CREATOR)
|
||
{
|
||
FSMakeFSSpec(vRef,dirId,name,&spec);
|
||
ResolveAliasNoMount(&spec,&spec,nil);
|
||
if ((refN=FSpOpenResFile(&spec, fsRdPerm))==-1)
|
||
FileSystemError(OPEN_SETTINGS,name,ResError());
|
||
else
|
||
{
|
||
lastRefN = refN;
|
||
if (hfi.hFileInfo.ioFlFndrInfo.fdType==HELP_TYPE && !HelpResFile) HelpResFile = refN;
|
||
}
|
||
}
|
||
return(lastRefN);
|
||
}
|
||
|
||
/************************************************************************
|
||
* AwaitStartupAE - wait for our startup AE. If it doesn't come, die.
|
||
************************************************************************/
|
||
void AwaitStartupAE(void)
|
||
{
|
||
EventRecord event;
|
||
uLong giveUp = TickCount() + 60*GetRLong(AE_INITIAL_TIMEOUT_SECS);
|
||
|
||
/*
|
||
* wait for the AE handlers to work their magic, and find us a folder
|
||
* if they don't, just use the standard folder
|
||
*/
|
||
while (!SettingsRefN && TickCount()<giveUp)
|
||
{
|
||
//LOGLINE;
|
||
if (WaitNextEvent(highLevelEventMask,&event,10,nil))
|
||
{
|
||
//LOGLINE;
|
||
(void) AEProcessAppleEvent(&event);
|
||
if (!SettingsRefN) SystemEudoraFolder();
|
||
}
|
||
else
|
||
CyclePendulum();
|
||
}
|
||
//LOGLINE;
|
||
|
||
/*
|
||
* did we get setup? If not, open the standard folder
|
||
*/
|
||
if (!SettingsRefN) SystemEudoraFolder();
|
||
}
|
||
|
||
/************************************************************************
|
||
* InitIntScript - make and use a local copy of 'itl2' in case system resource can't be loaded later
|
||
************************************************************************/
|
||
static void InitIntScript(void)
|
||
{
|
||
Handle hIntl0,hMyIntl0;
|
||
GrafPtr port;
|
||
short saveFont;
|
||
OSErr err = noErr;
|
||
|
||
// Make sure we're using system script by setting textfont of current port to 0
|
||
GetPort(&port);
|
||
if (!port)
|
||
{
|
||
// Oops, nothing set. Use WMgrPort
|
||
GetWMgrPort(&port);
|
||
SetPort(port);
|
||
}
|
||
saveFont = GetPortTextFont(port);
|
||
TextFont(0);
|
||
|
||
if ((hIntl0 = GetIntlResource(2)) &&
|
||
(hMyIntl0 = GetResource('itl2',kMyIntl0)))
|
||
{
|
||
char saveState = HGetState(hIntl0);
|
||
|
||
HNoPurge(hIntl0);
|
||
HLock(hIntl0);
|
||
SetHandleSize(hMyIntl0,0);
|
||
if (!HandAndHand(hIntl0, hMyIntl0))
|
||
{
|
||
ChangedResource(hMyIntl0); // Resource is protected so it won't get written
|
||
}
|
||
else err = MemError();
|
||
HSetState(hIntl0,saveState);
|
||
}
|
||
else err = ResError();
|
||
TextFont(saveFont);
|
||
if (err) DieWithError(INTERNATIONAL_FAILURE,err);
|
||
}
|
||
|
||
/************************************************************************
|
||
* PrefillSettings - process initial settings from a text file
|
||
************************************************************************/
|
||
static void PrefillSettings(void)
|
||
{
|
||
FSSpec spec;
|
||
Handle text;
|
||
Str255 s;
|
||
Ptr queryPtr;
|
||
long queryLen;
|
||
|
||
if (!FindMyFile(&spec,kStuffFolderBit,SETTINGS_PREFILL_FILE))
|
||
if (!Snarf(&spec,&text,0))
|
||
{
|
||
Ptr p = LDRef(text);
|
||
while (*p)
|
||
{
|
||
// Line must start with <x-eudora-setting
|
||
if (*p=='<')
|
||
{
|
||
Ptr pStart = ++p;
|
||
while (*p && *p!='>' && *p!=0x0d && *p!=0x0a) p++;
|
||
if (*p=='>')
|
||
{
|
||
if (!(ParseURLPtr(pStart,p-pStart,s,nil,&queryPtr,&queryLen)))
|
||
if (FindSTRNIndex(ProtocolStrn,s) == proSetting)
|
||
{
|
||
Ptr spot = queryPtr;
|
||
if (PTokenPtr(queryPtr,queryLen,s,&spot,"="))
|
||
{
|
||
long num;
|
||
StringToNum(s,&num);
|
||
if (PTokenPtr(queryPtr,queryLen,s,&spot,""))
|
||
SetPref(num,s);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// Next line
|
||
while (*p && *p!=0x0d && *p!=0x0a) p++;
|
||
while (*p && (*p==0x0d || *p==0x0a)) p++;
|
||
}
|
||
|
||
// Rename file so we don't process it again
|
||
FSpRename(&spec,GetRString(s,SETTINGS_PREFILL_PROCESSED));
|
||
}
|
||
}
|