1 line
34 KiB
C
Executable File
1 line
34 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 "personalitieswin.h"
|
|
|
|
#define FILE_NUM 87
|
|
/* Copyright (c) 1996 by QUALCOMM Incorporated */
|
|
|
|
#pragma segment PersonWin
|
|
|
|
// Personality Window controls
|
|
enum
|
|
{
|
|
kctlNew=0,
|
|
kctlRemove,
|
|
kctlCheck,
|
|
kctlEdit
|
|
};
|
|
|
|
typedef struct
|
|
{
|
|
ViewList list;
|
|
MyWindowPtr win;
|
|
ControlHandle ctlNew,ctlRemove,ctlCheck,ctlEdit;
|
|
Boolean inited;
|
|
PersHandle newPers; // New personality being renamed
|
|
} WinData;
|
|
static WinData gWin;
|
|
static Boolean gMyCheck;
|
|
|
|
/************************************************************************
|
|
* prototypes
|
|
************************************************************************/
|
|
static void DoDidResize(MyWindowPtr win, Rect *oldContR);
|
|
static void DoZoomSize(MyWindowPtr win,Rect *zoom);
|
|
static void DoUpdate(MyWindowPtr win);
|
|
static Boolean DoClose(MyWindowPtr win);
|
|
static void DoClick(MyWindowPtr win,EventRecord *event);
|
|
static void DoCursor(Point mouse);
|
|
static void DoActivate(MyWindowPtr win);
|
|
static Boolean DoKey(MyWindowPtr win, EventRecord *event);
|
|
static OSErr DoDragHandler(MyWindowPtr win,DragTrackingMessage which,DragReference drag);
|
|
static void DoShowHelp(MyWindowPtr win,Point mouse);
|
|
static Boolean DoMenuSelect(MyWindowPtr win, int menu, int item, short modifiers);
|
|
static long ViewListCallBack(ViewListPtr pView, VLCallbackMessage message, long data);
|
|
static Boolean GetListData(VLNodeInfo *data,short selectedItem);
|
|
static void SetControls(void);
|
|
static void DeletePersonality(void);
|
|
static void NewPersonality(void);
|
|
static void RenamePersonality(StringPtr newName);
|
|
static void ReplyWithPers(MessHandle messH,PersHandle pers,short modifiers);
|
|
static void DoGrow(MyWindowPtr win,Point *newSize);
|
|
static void ProcessPersPassword(Boolean change);
|
|
static void PersIdle(MyWindowPtr win);
|
|
static Boolean PersFind(MyWindowPtr win,PStr what);
|
|
static void OpenSelectedPers(void);
|
|
extern void CopyExtraSigs(MenuHandle mh);
|
|
|
|
typedef enum {
|
|
kOK = 1,
|
|
kCancel,
|
|
kPersName,
|
|
kPopAccount,
|
|
kRealName,
|
|
kReturnAddress,
|
|
kAutoCheck,
|
|
kCheckInverval,
|
|
kCheckManual,
|
|
kLeaveMail,
|
|
kPasswords,
|
|
kKerberos,
|
|
kAPOP,
|
|
kDomain2Add,
|
|
kSMTPServer,
|
|
kStationeryMenu,
|
|
kSignatureMenu,
|
|
kSendManual
|
|
} EditPersDialogEnum;
|
|
|
|
/************************************************************************
|
|
* OpenPersonalitiesWin - open the stationery window
|
|
************************************************************************/
|
|
void OpenPersonalitiesWin(void)
|
|
{
|
|
WindowPtr gWinWinWP;
|
|
|
|
if (!HasFeature (featureMultiplePersonalities))
|
|
return;
|
|
|
|
if (SelectOpenWazoo(PERS_WIN)) return; // Already opened in a wazoo
|
|
|
|
if (!gWin.inited)
|
|
{
|
|
short err=0;
|
|
Rect r;
|
|
|
|
if (!(gWin.win=GetNewMyWindow(PERSONALITIES_WIND,nil,nil,BehindModal,false,false,PERS_WIN)))
|
|
{err=MemError(); goto fail;}
|
|
gWinWinWP = GetMyWindowWindowPtr (gWin.win);
|
|
SetWinMinSize(gWin.win,-1,-1);
|
|
SetPort_(GetWindowPort(gWinWinWP));
|
|
ConfigFontSetup(gWin.win);
|
|
MySetThemeWindowBackground(gWin.win,kThemeListViewBackgroundBrush,False);
|
|
|
|
/*
|
|
* list
|
|
*/
|
|
SetRect(&r,0,0,20,20);
|
|
if (LVNew(&gWin.list,gWin.win,&r,1,ViewListCallBack,kPersonalityDragType))
|
|
{err=MemError(); goto fail;}
|
|
|
|
// controls
|
|
if (!(gWin.ctlNew = NewIconButton(PERS_NEW_CNTL,gWinWinWP)) ||
|
|
!(gWin.ctlRemove = NewIconButton(PERS_REMOVE_CNTL,gWinWinWP)) ||
|
|
!(gWin.ctlCheck = NewIconButton(PERS_CHECK_CNTL,gWinWinWP)) ||
|
|
!(gWin.ctlEdit = NewIconButton(PERS_EDIT_CNTL,gWinWinWP)))
|
|
goto fail;
|
|
|
|
gWin.win->didResize = DoDidResize;
|
|
gWin.win->close = DoClose;
|
|
gWin.win->update = DoUpdate;
|
|
gWin.win->position = PositionPrefsTitle;
|
|
gWin.win->click = DoClick;
|
|
gWin.win->bgClick = DoClick;
|
|
gWin.win->dontControl = true;
|
|
gWin.win->cursor = DoCursor;
|
|
gWin.win->activate = DoActivate;
|
|
gWin.win->help = DoShowHelp;
|
|
gWin.win->menu = DoMenuSelect;
|
|
gWin.win->key = DoKey;
|
|
gWin.win->app1 = DoKey;
|
|
gWin.win->drag = DoDragHandler;
|
|
gWin.win->zoomSize = DoZoomSize;
|
|
gWin.win->grow = DoGrow;
|
|
gWin.win->idle = PersIdle;
|
|
gWin.win->find = PersFind;
|
|
gWin.win->showsSponsorAd = true;
|
|
ShowMyWindow(gWinWinWP);
|
|
MyWindowDidResize(gWin.win,&gWin.win->contR);
|
|
gWin.inited = true;
|
|
return;
|
|
|
|
fail:
|
|
if (gWin.win) CloseMyWindow(GetMyWindowWindowPtr (gWin.win));
|
|
if (err) WarnUser(COULDNT_WIN,err);
|
|
return;
|
|
}
|
|
UserSelectWindow(GetMyWindowWindowPtr(gWin.win));
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoDidResize - resize the window
|
|
************************************************************************/
|
|
static void DoDidResize(MyWindowPtr win, Rect *oldContR)
|
|
{
|
|
#define kListInset 10
|
|
#pragma unused(oldContR)
|
|
ControlHandle ctlList[4];
|
|
Rect r;
|
|
short htAdjustment;
|
|
|
|
// buttons
|
|
ctlList[0] = gWin.ctlNew;
|
|
ctlList[1] = gWin.ctlRemove;
|
|
ctlList[2] = gWin.ctlCheck;
|
|
ctlList[3] = gWin.ctlEdit;
|
|
PositionBevelButtons(win,4,ctlList,kListInset,gWin.win->contR.bottom-INSET-kHtCtl,kHtCtl,RectWi(win->contR));
|
|
|
|
// list
|
|
SetRect(&r,kListInset,win->topMargin+kListInset,gWin.win->contR.right-kListInset,gWin.win->contR.bottom - 2*INSET - kHtCtl);
|
|
if (gWin.win->sponsorAdExists && r.bottom >= gWin.win->sponsorAdRect.top - kSponsorBorderMargin)
|
|
r.bottom = gWin.win->sponsorAdRect.top - kSponsorBorderMargin;
|
|
LVSize(&gWin.list,&r,&htAdjustment);
|
|
|
|
// enable/disble controls
|
|
SetControls();
|
|
|
|
// redraw
|
|
InvalContent(win);
|
|
}
|
|
|
|
/************************************************************************
|
|
* SetControls - enable or disable the controls, based on current situation
|
|
************************************************************************/
|
|
static void SetControls(void)
|
|
{
|
|
VLNodeInfo info;
|
|
short count = LVCountSelection(&gWin.list);
|
|
Boolean fSelect = count!=0;
|
|
|
|
|
|
gWin.win->hasSelection = fSelect;
|
|
|
|
SetGreyControl(gWin.ctlEdit,count!=1);
|
|
SetGreyControl(gWin.ctlCheck,!fSelect || CheckThreadRunning);
|
|
|
|
if (fSelect)
|
|
{
|
|
GetListData(&info,1);
|
|
if (info.rowNum == 1)
|
|
fSelect = false; // Can't remove the dominant personality
|
|
}
|
|
|
|
SetGreyControl(gWin.ctlRemove,!fSelect);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoZoomSize - zoom to only the maximum size of list
|
|
************************************************************************/
|
|
static void DoZoomSize(MyWindowPtr win,Rect *zoom)
|
|
{
|
|
short zoomHi = zoom->bottom-zoom->top;
|
|
short zoomWi = zoom->right-zoom->left;
|
|
short hi, wi;
|
|
|
|
LVMaxSize(&gWin.list, &wi, &hi);
|
|
wi += 2*kListInset;
|
|
hi += 2*kListInset + INSET + kHtCtl;
|
|
|
|
wi = MIN(wi,zoomWi); wi = MAX(wi,win->minSize.h);
|
|
hi = MIN(hi,zoomHi); hi = MAX(hi,win->minSize.v);
|
|
zoom->right = zoom->left+wi;
|
|
zoom->bottom = zoom->top+hi;
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoGrow - adjust grow size
|
|
************************************************************************/
|
|
static void DoGrow(MyWindowPtr win,Point *newSize)
|
|
{
|
|
Rect r,rWin;
|
|
short htControl = ControlHi(gWin.ctlNew);
|
|
short bottomMargin,sponsorMargin;
|
|
|
|
// Get list position
|
|
bottomMargin = INSET*2 + htControl;
|
|
if (win->sponsorAdExists)
|
|
{
|
|
WindowPtr winWP = GetMyWindowWindowPtr (win);
|
|
GetWindowPortBounds(winWP,&rWin);
|
|
sponsorMargin = rWin.bottom - win->sponsorAdRect.top + kSponsorBorderMargin;
|
|
if (sponsorMargin > bottomMargin) bottomMargin = sponsorMargin;
|
|
}
|
|
SetRect(&r,kListInset,win->topMargin+kListInset,newSize->h-kListInset,newSize->v - bottomMargin);
|
|
LVCalcSize(&gWin.list,&r);
|
|
|
|
// Calculate new window height
|
|
newSize->v = r.bottom + bottomMargin;
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoClose - close the window
|
|
************************************************************************/
|
|
static Boolean DoClose(MyWindowPtr win)
|
|
{
|
|
#pragma unused(win)
|
|
|
|
if (gWin.inited)
|
|
{
|
|
// Dispose of list
|
|
LVDispose(&gWin.list);
|
|
gWin.inited = false;
|
|
}
|
|
return(True);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoUpdate - draw the window
|
|
************************************************************************/
|
|
static void DoUpdate(MyWindowPtr win)
|
|
{
|
|
CGrafPtr winPort = GetMyWindowCGrafPtr (win);
|
|
Rect r;
|
|
|
|
r = gWin.list.bounds;
|
|
DrawThemeListBoxFrame(&r,kThemeStateActive);
|
|
LVDraw(&gWin.list,MyGetPortVisibleRegion(winPort), true, false);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoActivate - activate the window
|
|
************************************************************************/
|
|
static void DoActivate(MyWindowPtr win)
|
|
{
|
|
#pragma unused(win)
|
|
LVActivate(&gWin.list, gWin.win->isActive);
|
|
gWin.newPers = nil;
|
|
SetControls();
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoKey - key stroke
|
|
************************************************************************/
|
|
static Boolean DoKey(MyWindowPtr win, EventRecord *event)
|
|
{
|
|
#pragma unused(win)
|
|
short key = (event->message & 0xff);
|
|
|
|
if (LVKey(&gWin.list,event))
|
|
{
|
|
SetControls();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* PersFind - find in the window
|
|
**********************************************************************/
|
|
static Boolean PersFind(MyWindowPtr win,PStr what)
|
|
{
|
|
return FindListView(win,&gWin.list,what);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoClick - click in window
|
|
************************************************************************/
|
|
void DoClick(MyWindowPtr win,EventRecord *event)
|
|
{
|
|
WindowPtr winWP = GetMyWindowWindowPtr (win);
|
|
Point pt;
|
|
ControlHandle hCtl;
|
|
|
|
SetPort(GetMyWindowCGrafPtr(win));
|
|
|
|
if (!LVClick(&gWin.list,event))
|
|
{
|
|
pt = event->where;
|
|
GlobalToLocal(&pt);
|
|
if (!win->isActive)
|
|
{
|
|
SelectWindow_(winWP);
|
|
UpdateMyWindow(winWP); // Have to update manually since no events are processed
|
|
}
|
|
|
|
if (FindControl(pt, winWP, &hCtl))
|
|
{
|
|
if (TrackControl(hCtl,pt,(void *)(-1)))
|
|
{
|
|
long controlId;
|
|
|
|
if (hCtl == gWin.ctlEdit)
|
|
{
|
|
VLNodeInfo info;
|
|
|
|
GetListData(&info,1);
|
|
DoPersSettings(Index2Pers(info.rowNum-1));
|
|
controlId = kctlEdit;
|
|
}
|
|
else if (hCtl == gWin.ctlNew)
|
|
{
|
|
NewPersonality();
|
|
controlId = kctlNew;
|
|
}
|
|
else if (hCtl == gWin.ctlRemove)
|
|
{
|
|
DeletePersonality();
|
|
controlId = kctlRemove;
|
|
}
|
|
else if (hCtl == gWin.ctlCheck)
|
|
{
|
|
gMyCheck =true;
|
|
XferMail(true,false,true,false,true,0);
|
|
gMyCheck =false;
|
|
controlId = kctlCheck;
|
|
}
|
|
|
|
AuditHit((event->modifiers&shiftKey)!=0, (event->modifiers&controlKey)!=0, (event->modifiers&optionKey)!=0, (event->modifiers&cmdKey)!=0, false, GetWindowKind(winWP), AUDITCONTROLID(GetWindowKind(winWP),controlId), event->what);
|
|
}
|
|
}
|
|
}
|
|
SetControls();
|
|
}
|
|
|
|
/************************************************************************
|
|
* NotifyPersonalitiesWin - notify the personalities window that we've
|
|
* been up to no good
|
|
************************************************************************/
|
|
void NotifyPersonalitiesWin(void)
|
|
{
|
|
if (!HasFeature (featureMultiplePersonalities))
|
|
return;
|
|
|
|
if (gWin.inited) InvalidListView(&gWin.list); // Regenerate list
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoCursor - set the cursor properly for the window
|
|
************************************************************************/
|
|
static void DoCursor(Point mouse)
|
|
{
|
|
if (!PeteCursorList(gWin.win->pteList,mouse))
|
|
SetMyCursor(arrowCursor);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoShowHelp - provide help for the window
|
|
************************************************************************/
|
|
static void DoShowHelp(MyWindowPtr win,Point mouse)
|
|
{
|
|
if (PtInRect(mouse,&gWin.list.bounds))
|
|
MyBalloon(&gWin.list.bounds,100,0,PERS_HELP_STRN+1,0,nil);
|
|
else
|
|
ShowControlHelp(mouse,PERS_HELP_STRN+2,gWin.ctlNew,gWin.ctlRemove,gWin.ctlCheck,gWin.ctlEdit,nil);
|
|
}
|
|
|
|
/************************************************************************
|
|
* GetListData - get data for selected item
|
|
************************************************************************/
|
|
static Boolean GetListData(VLNodeInfo *data,short selectedItem)
|
|
{
|
|
return LVGetItem(&gWin.list,selectedItem,data,true);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoMenuSelect - menu choice in the window
|
|
************************************************************************/
|
|
static Boolean DoMenuSelect(MyWindowPtr win, int menu, int item, short modifiers)
|
|
{
|
|
#pragma unused(win,modifiers)
|
|
|
|
switch (menu)
|
|
{
|
|
case FILE_MENU:
|
|
switch(item)
|
|
{
|
|
case FILE_OPENSEL_ITEM:
|
|
OpenSelectedPers();
|
|
return(True);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case EDIT_MENU:
|
|
switch(item)
|
|
{
|
|
case EDIT_SELECT_ITEM:
|
|
if (LVSelectAll(&gWin.list))
|
|
{
|
|
SetControls();
|
|
return(true);
|
|
}
|
|
break;
|
|
|
|
case EDIT_COPY_ITEM:
|
|
LVCopy(&gWin.list);
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
return(False);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ReplayWithPers - generate a reply message with indicated personality
|
|
**********************************************************************/
|
|
static void ReplyWithPers(MessHandle messH,PersHandle pers,short modifiers)
|
|
{
|
|
Boolean all, quote, self;
|
|
MyWindowPtr newWin;
|
|
|
|
if (!HasFeature (featureMultiplePersonalities))
|
|
return;
|
|
|
|
UseFeature (featureMultiplePersonalities);
|
|
|
|
ReplyDefaults(modifiers,&all,&self,"e);
|
|
if (newWin = DoReplyMessage((*messH)->win,all,self,quote,true,0,false,false,true))
|
|
{
|
|
WindowPtr newWinWP = GetMyWindowWindowPtr (newWin);
|
|
messH = (MessHandle)GetMyWindowPrivateData(newWin);
|
|
SetPers((*messH)->tocH,(*messH)->sumNum,pers,false);
|
|
ShowMyWindow(newWinWP);
|
|
UpdateMyWindow(newWinWP);
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* DoDragHandler - handle drags
|
|
**********************************************************************/
|
|
static OSErr DoDragHandler(MyWindowPtr win,DragTrackingMessage which,DragReference drag)
|
|
{
|
|
#pragma unused(win)
|
|
OSErr err = noErr;
|
|
VLNodeInfo targetInfo;
|
|
|
|
if (!DragIsInteresting(drag,MESS_FLAVOR,TOC_FLAVOR,nil))
|
|
return(dragNotAcceptedErr); // Nothing here we want
|
|
|
|
switch (which)
|
|
{
|
|
case kDragTrackingEnterWindow:
|
|
case kDragTrackingLeaveWindow:
|
|
case kDragTrackingInWindow:
|
|
err = LVDrag(&gWin.list,which,drag);
|
|
break;
|
|
case 0xfff:
|
|
// Drop
|
|
if (LVDrop(&gWin.list,&targetInfo))
|
|
{
|
|
PersHandle pers = Index2Pers(targetInfo.rowNum-1);
|
|
UHandle data=nil;
|
|
short modifiers = DragOrMods(drag);
|
|
|
|
if (!(err=MyGetDragItemData(drag,1,MESS_FLAVOR,(void*)&data)))
|
|
{
|
|
ReplyWithPers(**(MessHandle**)data, pers, modifiers);
|
|
}
|
|
else if (!(err=MyGetDragItemData(drag,1,TOC_FLAVOR,(void*)&data)))
|
|
{
|
|
short sumNum;
|
|
TOCHandle tocH;
|
|
|
|
tocH = **(TOCHandle**)data;
|
|
for (sumNum = 0; sumNum < (*tocH)->count; sumNum++)
|
|
{
|
|
if ((*tocH)->sums[sumNum].selected)
|
|
{
|
|
MyWindowPtr tempWin;
|
|
|
|
CycleBalls();
|
|
MiniEvents();
|
|
if (EjectBuckaroo || CommandPeriod) break;
|
|
|
|
if (tempWin = GetAMessage(tocH,sumNum,nil,nil,false))
|
|
{
|
|
WindowPtr tempWinWP = GetMyWindowWindowPtr (tempWin);
|
|
ReplyWithPers((MessHandle)GetMyWindowPrivateData(tempWin), pers, modifiers);
|
|
if (!IsWindowVisible(tempWinWP))
|
|
CloseMyWindow(tempWinWP);
|
|
else
|
|
NotUsingWindow(tempWinWP);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ZapHandle(data);
|
|
|
|
return(err);
|
|
}
|
|
else
|
|
return dragNotAcceptedErr;
|
|
break;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* ViewListCallBack - callback function for List View
|
|
************************************************************************/
|
|
static long ViewListCallBack(ViewListPtr pView, VLCallbackMessage message, long data)
|
|
{
|
|
VLNodeInfo info,*pInfo;
|
|
OSErr err = noErr;
|
|
short i,count;
|
|
PersHandle pers;
|
|
SendDragDataInfo *pSendData;
|
|
|
|
switch (message)
|
|
{
|
|
case kLVAddNodeItems:
|
|
// Add personality names to list
|
|
count = PersCount();
|
|
if (count > 1)
|
|
UseFeature (featureMultiplePersonalities);
|
|
|
|
for (i=1;i<=count;i++)
|
|
{
|
|
Zero(info);
|
|
if (pers = Index2Pers(i-1))
|
|
{
|
|
PCopy(info.name,(*pers)->name);
|
|
info.useLevelZero = true;
|
|
info.iconID = PERSONALITIES_ICON;
|
|
}
|
|
LVAdd(pView, &info);
|
|
}
|
|
break;
|
|
|
|
case kLVOpenItem:
|
|
// New message with personality
|
|
OpenSelectedPers();
|
|
break;
|
|
|
|
case kLVDeleteItem:
|
|
DeletePersonality();
|
|
break;
|
|
|
|
case kLVRenameItem:
|
|
{
|
|
Str31 newName;
|
|
SanitizeFN(newName,(StringPtr)data,MAC_FN_BAD,MAC_FN_REP,false);
|
|
RenamePersonality(newName);
|
|
break;
|
|
}
|
|
case kLVQueryItem:
|
|
pInfo = ( VLNodeInfo *)data;
|
|
switch (pInfo->query)
|
|
{
|
|
case kQuerySelect:
|
|
case kQueryDrag:
|
|
case kQueryDrop:
|
|
case kQueryDCOpens:
|
|
return true;
|
|
case kQueryRename:
|
|
return pInfo->rowNum > 1;
|
|
}
|
|
break;
|
|
|
|
case kLVSendDragData:
|
|
pSendData = (SendDragDataInfo *)data;
|
|
pers = Index2Pers(pSendData->info->rowNum-1);
|
|
err = SetDragItemFlavorData(pSendData->drag, pSendData->itemRef, pSendData->flavor,&pers, sizeof(pers), 0L);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/************************************************************************
|
|
* RenamePersonality - rename the selected personality
|
|
************************************************************************/
|
|
static void RenamePersonality(StringPtr newName)
|
|
{
|
|
VLNodeInfo info;
|
|
PersHandle pers;
|
|
Str255 scratch;
|
|
|
|
if (!*newName) {WarnUser(PERS_MUST_HAVE_NAME,0);return;}
|
|
|
|
GetListData(&info,1);
|
|
if ((pers = Index2Pers(info.rowNum-1)) && (!EqualString(newName,PCopy(scratch,(*pers)->name),true,true)))
|
|
{
|
|
if (gWin.newPers == pers ||
|
|
Aprintf(YES_CANCEL_ALRT,Stop,PERS_RENAME,scratch)==1)
|
|
{
|
|
#ifdef IMAP
|
|
if (IsIMAPPers(pers))
|
|
if (!RenameIMAPPers(pers,newName))
|
|
{
|
|
if (gWin.newPers == pers) DoPersSettings(pers);
|
|
goto Done;
|
|
}
|
|
#endif
|
|
if (!PersSetName(pers,newName))
|
|
{
|
|
InvalidListView(&gWin.list); // Regenerate list
|
|
if (gWin.newPers == pers) DoPersSettings(pers);
|
|
}
|
|
}
|
|
Done:
|
|
gWin.newPers = nil;
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
* DeletePersonality - delete the selected personality
|
|
************************************************************************/
|
|
static void DeletePersonality(void)
|
|
{
|
|
short i;
|
|
VLNodeInfo info;
|
|
Str255 scratch;
|
|
PersHandle pers;
|
|
Boolean fDeleted = false;
|
|
|
|
for (i=1;i<=LVCountSelection(&gWin.list);i++)
|
|
{
|
|
GetListData(&info,i);
|
|
if (info.rowNum == 1)
|
|
continue; // Can't delete dominant personality
|
|
if (pers = FindPersByName(info.name))
|
|
{
|
|
#ifdef IMAP
|
|
if (IsIMAPPers(pers))
|
|
{
|
|
if (ComposeStdAlert(Stop,IMAP_DELETE_CACHE,PCopy(scratch,(*pers)->name))==1)
|
|
{
|
|
DeleteIMAPPers(pers, false);
|
|
PersDelete(pers);
|
|
fDeleted = true;
|
|
}
|
|
else break;
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
if (Aprintf(YES_CANCEL_ALRT,Stop,PERS_DELETE,PCopy(scratch,(*pers)->name))==1)
|
|
{
|
|
PersDelete(pers);
|
|
fDeleted = true;
|
|
}
|
|
else break;
|
|
}
|
|
}
|
|
}
|
|
if (fDeleted)
|
|
{
|
|
InvalidListView(&gWin.list); // Regenerate list
|
|
UpdateMyWindow(GetMyWindowWindowPtr(gWin.win));
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
* NewPersonality - new personality
|
|
************************************************************************/
|
|
static void NewPersonality(void)
|
|
{
|
|
PersHandle pers;
|
|
|
|
if (HasFeature(featureMultiplePersonalities) && (pers=PersNew()))
|
|
{
|
|
UseFeature (featureMultiplePersonalities);
|
|
InvalidListView(&gWin.list); // Regenerate list
|
|
gWin.newPers = pers;
|
|
LVRename(&gWin.list,0,(*pers)->name,false,false); // Allow user to rename the personality
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
* SelectXferMailPers - select which personalities to check mail/send queued messages
|
|
************************************************************************/
|
|
Boolean SelectXferMailPers(Boolean check, Boolean send, Boolean manual)
|
|
{
|
|
// Specify personalities to check/send if Personalities window is active
|
|
// and there are one or more personalities selected
|
|
if (gMyCheck && check && manual && gWin.inited)
|
|
{
|
|
short i;
|
|
PersHandle pers;
|
|
|
|
// Mark the personalities that need to be checked/sent
|
|
for (i=1,pers=PersList;pers;pers=(*pers)->next,i++)
|
|
{
|
|
Boolean selected = LVIsSelected(&gWin.list,i);
|
|
PersPtr pPers = *pers;
|
|
|
|
pPers->doMeNow = check || send;
|
|
pPers->checkMeNow = selected && check;
|
|
pPers->sendMeNow = selected && send;
|
|
pPers->checked = false;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#if 0
|
|
/************************************************************************
|
|
* EditPersonality - edit the selected personality
|
|
************************************************************************/
|
|
static void EditPersonality(void)
|
|
{
|
|
MyWindowPtr dlogWin;
|
|
DialogPtr dlog;
|
|
WindowPtr dlogWP;
|
|
short res;
|
|
extern ModalFilterUPP DlgFilterUPP;
|
|
Str255 scratch;
|
|
long sigId;
|
|
VLNodeInfo info;
|
|
PersHandle pers = nil;
|
|
ControlHandle hSigCntl,hStnyCntl;
|
|
MenuHandle hSigMenu,hStnyMenu,hTempMenu;
|
|
short value,count,i;
|
|
Style style;
|
|
typedef struct
|
|
{
|
|
short item,pref;
|
|
} DlgPrefData;
|
|
static DlgPrefData DlgPrefTable[] =
|
|
{
|
|
// Negative item #'s for check boxes
|
|
// Negative pref #'s for opposite values
|
|
kPopAccount,PREF_POP,
|
|
kRealName,PREF_REALNAME,
|
|
kReturnAddress,PREF_RETURN,
|
|
-kAutoCheck,PREF_AUTO_CHECK,
|
|
kCheckInverval,PREF_INTERVAL,
|
|
-kCheckManual,-PREF_JUST_SAY_NO,
|
|
-kLeaveMail,PREF_LMOS,
|
|
-kPasswords,-PREF_DONT_PASS,
|
|
-kKerberos,PREF_KERBEROS,
|
|
-kAPOP,PREF_APOP,
|
|
kDomain2Add,PREF_AUTOQUAL,
|
|
kSMTPServer,PREF_SMTP,
|
|
-kSendManual,-PREF_PERS_NO_SEND,
|
|
0,0
|
|
};
|
|
DlgPrefData *pDlgPref;
|
|
PersHandle oldCur = CurPers;
|
|
|
|
|
|
GetListData(&info,1);
|
|
pers = Index2Pers(info.rowNum-1);
|
|
if (!pers) return; // Shouldn't happen
|
|
|
|
SetDAFont(SmallSysFont());
|
|
dlogWin = GetNewMyDialog(EDIT_PERSONALITY_DLOG,nil,nil,InFront);
|
|
SetDAFont(0);
|
|
if (!dlog) {(WarnUser(MEM_ERR,ResError())); return;}
|
|
dlog = GetMyWindowDialogPtr (dlogWin);
|
|
dlogWP = GetDialogWindow (dlog);
|
|
SetPort_(GetWindowPort(dlogWP));
|
|
ConfigFontSetup(dlogWin);
|
|
|
|
// fix the dialog controls
|
|
ReplaceAllControls(dlog);
|
|
|
|
SetDIText(dlog,kPersName,(*pers)->name);
|
|
|
|
// Set dialog items from preferences
|
|
CurPers = pers; // Use prefs for indicated personality
|
|
for(pDlgPref=DlgPrefTable;pDlgPref->item;pDlgPref++)
|
|
{
|
|
if (pDlgPref->item < 0)
|
|
// Checkbox item
|
|
SetDItemState(dlog,-pDlgPref->item,pDlgPref->pref<0 ? !PrefIsSet(-pDlgPref->pref) : PrefIsSet(pDlgPref->pref));
|
|
else
|
|
// Text item
|
|
SetDIText(dlog,pDlgPref->item,GetPref(scratch,pDlgPref->pref));
|
|
}
|
|
|
|
// Setup signature menu
|
|
hSigCntl = GetDItemCtl(dlog,kSignatureMenu);
|
|
hSigMenu = (MenuHandle)GetControlPopupMenuHandle(hSigCntl);
|
|
CopyExtraSigs(hSigMenu);
|
|
SetCtlMax(hSigCntl,CountMItems(hSigMenu));
|
|
sigId = SigValidate(GetPrefLong(PREF_SIGFILE));
|
|
switch (sigId)
|
|
{
|
|
case SIG_NONE: value = sigmNone; break;
|
|
case SIG_STANDARD: value = sigmStandard; break;
|
|
case SIG_ALTERNATE: value = sigmAlternate; break;
|
|
default:
|
|
for (value=CountMItems(hSigMenu);value>sigmAlternate;value--)
|
|
{
|
|
MyGetItem(hSigMenu,value,scratch);
|
|
MyLowerStr(scratch);
|
|
if (Hash(scratch)==sigId) break;
|
|
}
|
|
break;
|
|
}
|
|
SetCtlValue(hSigCntl,value);
|
|
|
|
// Setup stationery menu
|
|
hStnyCntl = GetDItemCtl(dlog,kStationeryMenu);
|
|
GetPref(scratch,STATIONERY);
|
|
hStnyMenu = (MenuHandle)GetControlPopupMenuHandle(hStnyCntl);
|
|
hTempMenu = GetMHandle(REPLY_WITH_HIER_MENU);
|
|
count = CountMItems(hTempMenu);
|
|
SetCtlMax(hStnyCntl,count+2);
|
|
GetItemStyle(hTempMenu,1,&style);
|
|
value = 1;
|
|
if (count>1 || !style)
|
|
for (i=1;i<=count;i++)
|
|
{
|
|
MyGetItem(hTempMenu,i,scratch);
|
|
MyAppendMenu(hStnyMenu,scratch);
|
|
if (EqualStrRes(scratch,STATIONERY)) value = i+2;
|
|
}
|
|
SetCtlValue(hStnyCntl,value);
|
|
|
|
CurPers = oldCur; // Restore the current personality
|
|
|
|
// put up the alert
|
|
StartMovableModal(dlog);
|
|
ShowWindow(dlogWP);
|
|
SetMyCursor(arrowCursor);
|
|
|
|
do
|
|
{
|
|
MovableModalDialog(dlog,DlgFilterUPP,&res);
|
|
if (!DialogRadioButtons(dlogWin,res))
|
|
DialogCheckbox(dlogWin,res);
|
|
if (res>kCancel) (dlogWin)->isDirty = true;
|
|
}
|
|
while (res>kCancel);
|
|
|
|
if (dlogWin->isDirty && res==kOK)
|
|
{
|
|
// Save settings
|
|
CurPers = pers; // Use prefs for indicated personality
|
|
for(pDlgPref=DlgPrefTable;pDlgPref->item;pDlgPref++)
|
|
{
|
|
short value, pref;
|
|
if (pDlgPref->item < 0)
|
|
{
|
|
// Checkbox item
|
|
value = GetDItemState(dlog,-pDlgPref->item);
|
|
pref = pDlgPref->pref;
|
|
if (pref<0)
|
|
{
|
|
pref = -pref;
|
|
value = !value;
|
|
}
|
|
SetPref(pref,value?YesStr:NoStr);
|
|
}
|
|
else
|
|
{
|
|
// Text item
|
|
GetDIText(dlog,pDlgPref->item,scratch);
|
|
SetPref(pDlgPref->pref,scratch);
|
|
}
|
|
}
|
|
|
|
// Save signature
|
|
value = GetCtlValue(hSigCntl);
|
|
switch (value)
|
|
{
|
|
case sigmNone: sigId = SIG_NONE; break;
|
|
case sigmStandard: sigId = SIG_STANDARD; break;
|
|
case sigmAlternate: sigId = SIG_ALTERNATE; break;
|
|
default:
|
|
MyGetItem(hSigMenu,value,scratch);
|
|
MyLowerStr(scratch);
|
|
sigId = Hash(scratch);
|
|
break;
|
|
}
|
|
NumToString(sigId,scratch);
|
|
SetPref(PREF_SIGFILE,scratch);
|
|
|
|
// Save stationery
|
|
value = GetCtlValue(hStnyCntl);
|
|
if (value==1)
|
|
PCopy(scratch,NoStr);
|
|
else
|
|
GetItem(hStnyMenu,value,scratch);
|
|
SetPref(STATIONERY,scratch);
|
|
|
|
CurPers = oldCur; // Restore the current personality
|
|
}
|
|
|
|
// close
|
|
EndMovableModal(dlog);
|
|
DisposeDialog_(dlog);
|
|
CurPers = oldCur;
|
|
}
|
|
#endif // EditPersonality
|
|
|
|
/************************************************************************
|
|
* ProcessPassword - change or forget password for selected personalities
|
|
************************************************************************/
|
|
static void ProcessPersPassword(Boolean change)
|
|
{
|
|
short i;
|
|
PersHandle pers;
|
|
PersHandle oldCur = CurPers;
|
|
|
|
if (!HasFeature (featureMultiplePersonalities))
|
|
return;
|
|
|
|
for (i=1,pers=PersList;pers;pers=(*pers)->next,i++)
|
|
{
|
|
if (LVIsSelected(&gWin.list,i))
|
|
{
|
|
CurPers = pers;
|
|
if (change)
|
|
ChangePassword();
|
|
else
|
|
InvalidatePasswords(false,false,false);
|
|
}
|
|
}
|
|
CurPers = oldCur;
|
|
}
|
|
|
|
/************************************************************************
|
|
* ChangePersPassword - change password for selected personalities
|
|
************************************************************************/
|
|
void ChangePersPassword(void)
|
|
{
|
|
ProcessPersPassword(true);
|
|
}
|
|
|
|
/************************************************************************
|
|
* ForgetPersPassword - forget password for selected personalities
|
|
************************************************************************/
|
|
void ForgetPersPassword(void)
|
|
{
|
|
ProcessPersPassword(false);
|
|
}
|
|
|
|
#ifdef IMAP
|
|
/************************************************************************
|
|
* EmptyIMAPPersTrash - empty trash for selected IMAP personalities
|
|
************************************************************************/
|
|
void EmptyIMAPPersTrash(void)
|
|
{
|
|
short i;
|
|
PersHandle pers;
|
|
Boolean warnMe = !PrefIsSet(PREF_NO_TRASH_WARN);
|
|
|
|
PushPers(nil);
|
|
|
|
for (i=1,pers=PersList;pers;pers=(*pers)->next,i++)
|
|
{
|
|
if (LVIsSelected(&gWin.list,i))
|
|
{
|
|
CurPers = pers;
|
|
if (PrefIsSet(PREF_IS_IMAP))
|
|
{
|
|
// Warn the user once what's about to happen
|
|
if (warnMe)
|
|
{
|
|
warnMe = false;
|
|
if (!Mom(EMPTY_BUTTON,0,PREF_NO_TRASH_WARN,IMAP_EMPTY_TRASH_WARN)) break;
|
|
}
|
|
|
|
IMAPEmptyPersTrash();
|
|
}
|
|
}
|
|
}
|
|
|
|
PopPers();
|
|
}
|
|
#endif
|
|
|
|
/************************************************************************
|
|
* DoWeUseSelectedPersonalities - do we use selected personalities?
|
|
************************************************************************/
|
|
// Use only if front window is Personalities window and items are selected
|
|
Boolean DoWeUseSelectedPersonalities(void)
|
|
{
|
|
WindowPtr theWindow;
|
|
|
|
if (!HasFeature (featureMultiplePersonalities))
|
|
return (false);
|
|
|
|
return (theWindow=FrontWindow_()) &&
|
|
GetWindowKind(theWindow) == PERS_WIN &&
|
|
LVCountSelection(&gWin.list);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoWeUseSelectedIMAPPersonalities - do we use selected personalities?
|
|
************************************************************************/
|
|
Boolean DoWeUseSelectedIMAPPersonalities(void)
|
|
{
|
|
Boolean imapSelected = false;
|
|
WindowPtr theWindow;
|
|
short i;
|
|
VLNodeInfo info;
|
|
if (!HasFeature (featureMultiplePersonalities))
|
|
return (false);
|
|
|
|
if ((theWindow=FrontWindow_()) && (GetWindowKind(theWindow) == PERS_WIN))
|
|
{
|
|
for (i=1;(i<=LVCountSelection(&gWin.list)) && !imapSelected;i++)
|
|
{
|
|
GetListData(&info,i);
|
|
imapSelected = IsIMAPPers(Index2Pers(info.rowNum-1));
|
|
}
|
|
}
|
|
|
|
return (imapSelected);
|
|
}
|
|
|
|
/************************************************************************
|
|
* PersIdle - make sure check personality button is in sync with background checking
|
|
************************************************************************/
|
|
static void PersIdle(MyWindowPtr win)
|
|
{
|
|
static Boolean lastCheck;
|
|
|
|
if (gWin.inited && CheckThreadRunning != lastCheck)
|
|
{
|
|
SetControls();
|
|
lastCheck = CheckThreadRunning;
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
* OpenSelectedPers - make new message the selected personalities
|
|
************************************************************************/
|
|
static void OpenSelectedPers(void)
|
|
{
|
|
short i;
|
|
VLNodeInfo info;
|
|
|
|
for (i=1;i<=LVCountSelection(&gWin.list);i++)
|
|
{
|
|
MyWindowPtr win;
|
|
|
|
GetListData(&info,i);
|
|
|
|
if (win = DoComposeNew(nil))
|
|
{
|
|
MessHandle messH = (MessHandle)GetMyWindowPrivateData(win);
|
|
|
|
if (info.rowNum == 1)
|
|
// Dominant personality
|
|
ApplyDefaultStationery(win,True,True);
|
|
else
|
|
SetPers((*messH)->tocH,(*messH)->sumNum,Index2Pers(info.rowNum-1),true);
|
|
ShowMyWindow(GetMyWindowWindowPtr(win));
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef IMAP
|
|
/************************************************************************
|
|
* IsIMAPPers - is this personality IMAP?
|
|
************************************************************************/
|
|
Boolean IsIMAPPers(PersHandle pers)
|
|
{
|
|
PersHandle oldPers = CurPers;
|
|
Boolean result;
|
|
|
|
CurPers = pers;
|
|
result = PrefIsSet(PREF_IS_IMAP);
|
|
CurPers = oldPers;
|
|
return result;
|
|
}
|
|
|
|
/************************************************************************
|
|
* RenameIMAPPers - rename an IMAP personality's cache
|
|
************************************************************************/
|
|
Boolean RenameIMAPPers(PersHandle pers,StringPtr newName)
|
|
{
|
|
// Need to rename IMAP mail cache
|
|
FSSpec spec,newSpec;
|
|
Str32 cacheName;
|
|
OSErr err;
|
|
|
|
if (!HasFeature (featureMultiplePersonalities))
|
|
return (false);
|
|
|
|
PersNameToCacheName(pers, cacheName);
|
|
FSMakeFSSpec(IMAPMailRoot.vRef, IMAPMailRoot.dirId, cacheName, &spec);
|
|
SimpleMakeFSSpec(IMAPMailRoot.vRef, IMAPMailRoot.dirId,newName,&newSpec);
|
|
TellFiltMBRename(&spec,&newSpec,True,True,false);
|
|
if ((err = HRename(spec.vRefNum,spec.parID,spec.name,newName)) && err != fnfErr) // Don't report error if local IMAP cache file not created yet
|
|
{
|
|
(FileSystemError(RENAMING_BOX,spec.name,err));
|
|
return false;
|
|
}
|
|
BuildBoxMenus();
|
|
MBTickle(nil,nil);
|
|
TellFiltMBRename(&spec,&newSpec,True,False,false);
|
|
return true;
|
|
}
|
|
|
|
/************************************************************************
|
|
* DeleteIMAPPers - delete an IMAP personality's cache
|
|
************************************************************************/
|
|
void DeleteIMAPPers(PersHandle pers, Boolean bCacheOnly)
|
|
{
|
|
FSSpec spec;
|
|
Str32 cacheName;
|
|
PersHandle oldPers = CurPers;
|
|
|
|
// go through the personality's mailboxes, making sure they're all closed
|
|
ClosePersMailboxes(pers);
|
|
|
|
// remove the IMAP personality's cache
|
|
PersNameToCacheName(pers, cacheName);
|
|
if (FSMakeFSSpec(IMAPMailRoot.vRef, IMAPMailRoot.dirId, cacheName, &spec)==noErr)
|
|
RemoveIMAPCacheDir(spec);
|
|
LDRef(pers);
|
|
DisposeMailboxTree(&((*pers)->mailboxTree));
|
|
UL(pers);
|
|
|
|
if (!bCacheOnly)
|
|
{
|
|
// this is no longer an IMAP personality
|
|
CurPers = pers;
|
|
SetPref(PREF_IS_IMAP,"");
|
|
CurPers = oldPers;
|
|
}
|
|
|
|
// rebuild the mailbox menus
|
|
BuildBoxMenus();
|
|
MBTickle(nil,nil);
|
|
}
|
|
|
|
/************************************************************************
|
|
* IMAPPersActive - is this personality active?
|
|
************************************************************************/
|
|
Boolean IMAPPersActive(PersHandle pers)
|
|
{
|
|
Boolean result = false;
|
|
TOCHandle tocH = nil;
|
|
PersHandle p = nil;
|
|
MailboxNodeHandle n = nil;
|
|
|
|
// this persoanlity is "active" if there's a mailbox currently visible for it.
|
|
for (tocH=TOCList; tocH && !result; tocH = (*tocH)->next)
|
|
{
|
|
// look at each open, visible TOC
|
|
if ((*tocH)->imapTOC && (*tocH)->win && IsWindowVisible(GetMyWindowWindowPtr((*tocH)->win)))
|
|
{
|
|
n = TOCToMbox(tocH);
|
|
p = TOCToPers(tocH);
|
|
|
|
// does this toc refers to a mailbox owned by pers?
|
|
if (n && p && (p == pers)) result = true;
|
|
}
|
|
}
|
|
|
|
return (result);
|
|
}
|
|
|
|
#endif
|
|
|