1 line
25 KiB
C
Executable File
1 line
25 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 "signaturewin.h"
|
|
|
|
#define FILE_NUM 86
|
|
/* Copyright (c) 1996 by QUALCOMM Incorporated */
|
|
|
|
#pragma segment SignaturesWin
|
|
|
|
// Signature Window controls
|
|
enum
|
|
{
|
|
kctlNew=0,
|
|
kctlRemove,
|
|
kctlEdit
|
|
};
|
|
|
|
typedef enum { kNewSig,kRemoveSig,ControlCount } ControlEnum;
|
|
typedef struct
|
|
{
|
|
ViewList list;
|
|
MyWindowPtr win;
|
|
ControlHandle ctlNew,ctlRemove;
|
|
ControlHandle ctlEdit;
|
|
Boolean inited;
|
|
} WinData;
|
|
static WinData gWin;
|
|
|
|
Handle ghSigList;
|
|
|
|
/************************************************************************
|
|
* 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 long ViewListCallBack(ViewListPtr pView, VLCallbackMessage message, long data);
|
|
static Boolean DoMenuSelect(MyWindowPtr win, int menu, int item, short modifiers);
|
|
static void OpenSig(short item);
|
|
static Boolean GetListData(VLNodeInfo *data,short selectedItem);
|
|
static void NewSigFile(void);
|
|
static void DeleteSig(void);
|
|
static void GetSigSpec(short index, FSSpecPtr pSpec, StringPtr name);
|
|
static void OpenSelectedSigs(void);
|
|
static void DoGrow(MyWindowPtr win,Point *newSize);
|
|
static void CloseTextWindow(FSSpecPtr spec);
|
|
static void RenameTextWindow(FSSpecPtr spec,StringPtr newName);
|
|
static Boolean SigFind(MyWindowPtr win,PStr what);
|
|
static void SetControls(void);
|
|
|
|
|
|
/************************************************************************
|
|
* OpenSignaturesWin - open the stationery window
|
|
************************************************************************/
|
|
void OpenSignaturesWin(void)
|
|
{
|
|
WindowPtr gWinWinWP;
|
|
if (SelectOpenWazoo(SIG_WIN)) return; // Already opened in a wazoo
|
|
|
|
if (!gWin.inited)
|
|
{
|
|
short err=0;
|
|
Rect r;
|
|
|
|
if (!(gWin.win=GetNewMyWindow(SIGNATURES_WIND,nil,nil,BehindModal,false,false,SIG_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);
|
|
|
|
// controls
|
|
if (HasFeature (featureSignatures))
|
|
if (!(gWin.ctlNew = NewIconButton(SIG_NEW_CNTL,gWinWinWP)))
|
|
goto fail;
|
|
if (!(gWin.ctlRemove = NewIconButton(SIG_REMOVE_CNTL,gWinWinWP)))
|
|
goto fail;
|
|
if (!(gWin.ctlEdit = NewIconButton(SIG_EDIT_CNTL,gWinWinWP))) goto fail;
|
|
|
|
|
|
// list
|
|
SetRect(&r,0,0,20,20);
|
|
if (LVNew(&gWin.list,gWin.win,&r,1,ViewListCallBack,'TEXT'))
|
|
{err=MemError(); 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->grow = DoGrow;
|
|
gWin.win->find = SigFind;
|
|
|
|
// gWin.win->drag = DoDragHandler;
|
|
gWin.win->zoomSize = DoZoomSize;
|
|
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));
|
|
}
|
|
|
|
/**********************************************************************
|
|
* SignatureCount - return number of signatures
|
|
**********************************************************************/
|
|
short SignatureCount(void)
|
|
{
|
|
if (!ghSigList)
|
|
BuildSigList();
|
|
if (ghSigList)
|
|
return *(short *)*ghSigList;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* GetSignatureName - return name of indicated signature
|
|
**********************************************************************/
|
|
void GetSignatureName(short item,StringPtr s)
|
|
{
|
|
short count;
|
|
|
|
if ((count = SignatureCount()) && item <= count)
|
|
{
|
|
StringPtr pName;
|
|
short i;
|
|
|
|
pName = *ghSigList+sizeof(short);
|
|
for(i=1;i<item;i++,pName += *pName + 1);
|
|
PCopy(s,pName);
|
|
}
|
|
else
|
|
*s = 0;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* GetSignatureIcon - return icon resID for menu of indicated signature
|
|
**********************************************************************/
|
|
short GetSignatureIcon(short item)
|
|
{
|
|
switch(item)
|
|
{
|
|
case 1: return SIG_SICN;
|
|
case 2: return ALT_SIG_SICN;
|
|
default: return (HasFeature (featureSignatures) ? N_SIG_SICN : PRO_ONLY_ICON);
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* DoDidResize - resize the window
|
|
************************************************************************/
|
|
static void DoDidResize(MyWindowPtr win, Rect *oldContR)
|
|
{
|
|
#define kListInset 10
|
|
#pragma unused(oldContR)
|
|
Rect r;
|
|
short htAdjustment;
|
|
short i=0;
|
|
ControlHandle ctlList[3];
|
|
|
|
// buttons
|
|
if (HasFeature (featureSignatures))
|
|
ctlList[i++] = gWin.ctlNew;
|
|
ctlList[i++] = gWin.ctlRemove;
|
|
ctlList[i++] = gWin.ctlEdit;
|
|
PositionBevelButtons(win,i,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);
|
|
}
|
|
|
|
/************************************************************************
|
|
* 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)
|
|
{
|
|
CGrafPtr winPort = GetMyWindowCGrafPtr(win);
|
|
Rect r,rPort;
|
|
short htControl = ControlHi(gWin.ctlNew);
|
|
short bottomMargin,sponsorMargin;
|
|
|
|
// Get list position
|
|
bottomMargin = INSET*2 + htControl;
|
|
if (win->sponsorAdExists)
|
|
{
|
|
GetPortBounds(winPort,&rPort);
|
|
sponsorMargin = rPort.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;
|
|
Rect r;
|
|
|
|
winPort = GetMyWindowCGrafPtr(win);
|
|
|
|
r = gWin.list.bounds;
|
|
DrawThemeListBoxFrame(&r,kThemeStateActive);
|
|
LVDraw(&gWin.list, nil, true, false);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoActivate - activate the window
|
|
************************************************************************/
|
|
static void DoActivate(MyWindowPtr win)
|
|
{
|
|
#pragma unused(win)
|
|
LVActivate(&gWin.list, gWin.win->isActive);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoKey - key stroke
|
|
************************************************************************/
|
|
static Boolean DoKey(MyWindowPtr win, EventRecord *event)
|
|
{
|
|
#pragma unused(win)
|
|
short key = (event->message & 0xff);
|
|
Boolean fResult;
|
|
|
|
fResult = LVKey(&gWin.list,event);
|
|
SetControls();
|
|
return fResult;
|
|
}
|
|
|
|
/************************************************************************
|
|
* DoClick - click in window
|
|
************************************************************************/
|
|
void DoClick(MyWindowPtr win,EventRecord *event)
|
|
{
|
|
WindowPtr winWP = GetMyWindowWindowPtr(win);
|
|
Point pt;
|
|
ControlHandle hCtl;
|
|
|
|
SetPort(GetWindowPort(winWP));
|
|
|
|
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 (HasFeature (featureSignatures))
|
|
{
|
|
if (hCtl == gWin.ctlNew)
|
|
{
|
|
NewSigFile();
|
|
controlId = kctlNew;
|
|
}
|
|
else if (hCtl == gWin.ctlRemove)
|
|
{
|
|
DeleteSig();
|
|
controlId = kctlRemove;
|
|
}
|
|
else if (hCtl == gWin.ctlEdit)
|
|
{
|
|
OpenSelectedSigs();
|
|
controlId = kctlEdit;
|
|
}
|
|
}
|
|
else {
|
|
if (hCtl == gWin.ctlEdit)
|
|
{
|
|
OpenSelectedSigs();
|
|
controlId = kctlEdit;
|
|
}
|
|
else if (hCtl == gWin.ctlRemove)
|
|
{
|
|
DeleteSig();
|
|
controlId = kctlRemove;
|
|
}
|
|
}
|
|
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();
|
|
}
|
|
|
|
/**********************************************************************
|
|
* SigFind - find in the window
|
|
**********************************************************************/
|
|
static Boolean SigFind(MyWindowPtr win,PStr what)
|
|
{
|
|
return FindListView(win,&gWin.list,what);
|
|
}
|
|
|
|
/************************************************************************
|
|
* 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,SIG_HELP_STRN+1,0,nil);
|
|
else
|
|
if (HasFeature (featureSignatures))
|
|
ShowControlHelp(mouse,SIG_HELP_STRN+2,gWin.ctlNew,gWin.ctlRemove,gWin.ctlEdit,nil);
|
|
else
|
|
ShowControlHelp(mouse,SIG_HELP_STRN+3,gWin.ctlRemove,gWin.ctlEdit,nil);
|
|
}
|
|
|
|
/************************************************************************
|
|
* 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:
|
|
OpenSelectedSigs();
|
|
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);
|
|
}
|
|
|
|
#if 0
|
|
/**********************************************************************
|
|
* DoDragHandler - handle drags
|
|
*
|
|
* Can do internal dragging of mailboxes or external dragging and dropping
|
|
* of messages
|
|
**********************************************************************/
|
|
static OSErr DoDragHandler(MyWindowPtr win,DragTrackingMessage which,DragReference drag)
|
|
{
|
|
OSErr err = noErr;
|
|
|
|
// gfMessageDrag = DragIsInteresting(drag,MESS_FLAVOR,TOC_FLAVOR,nil); // Dragging messages
|
|
// gfBoxDrag = LVDragFlavor() == kMBDragType; // Dragging mailboxes
|
|
|
|
// if (!gfMessageDrag && !gfBoxDrag)
|
|
// return(dragNotAcceptedErr); // Nothing here we want
|
|
|
|
switch (which)
|
|
{
|
|
case dragTrackingEnterWindow:
|
|
case dragTrackingLeaveWindow:
|
|
case dragTrackingInWindow:
|
|
err = LVDrag(&gWin.list,which,drag);
|
|
break;
|
|
case 0xfff:
|
|
// Drop
|
|
if (gfBoxDrag)
|
|
// Mailbox drag
|
|
err = LVDrag(&gWin.list,which,drag);
|
|
else
|
|
{
|
|
// Message drag
|
|
VLNodeInfo targetInfo;
|
|
if (LVDrop(&gWin.list,&targetInfo))
|
|
{
|
|
FSSpec spec,*pTOCSpec;
|
|
TOCHandle tocH;
|
|
short sumNum;
|
|
OSErr err;
|
|
UHandle data=nil;
|
|
short vRef;
|
|
long dirID;
|
|
|
|
// Get spec of mailbox dropped on
|
|
MBMenuFile(targetInfo.nodeID, &vRef, &dirID);
|
|
FSMakeFSSpec(vRef,dirID,targetInfo.name,&spec);
|
|
|
|
if (!(err=MyGetDragItemData(drag,1,MESS_FLAVOR,(void*)&data)))
|
|
{
|
|
tocH = (***(MessHandle**)data)->tocH;
|
|
sumNum = (***(MessHandle**)data)->sumNum;
|
|
}
|
|
else if (!(err=MyGetDragItemData(drag,1,TOC_FLAVOR,(void*)&data)))
|
|
{
|
|
tocH = **(TOCHandle**)data;
|
|
sumNum = -1;
|
|
}
|
|
ZapHandle(data);
|
|
|
|
// Can't move to own mailbox
|
|
pTOCSpec = &(*tocH)->spec;
|
|
if (pTOCSpec->vRefNum==spec.vRefNum && pTOCSpec->parID==spec.parID && StringSame(pTOCSpec->name,spec.name))
|
|
// Dragging to own mailbox
|
|
return dragNotAcceptedErr;
|
|
|
|
if (!err)
|
|
{
|
|
if (sumNum==-1) MoveSelectedMessages(tocH,&spec,(DragOrMods(drag)&optionKey)!=0);
|
|
else
|
|
{
|
|
// if (!(DragOrMods(drag)&optionKey)) EzOpen(tocH,sumNum,0,DragOrMods(drag),True,True);
|
|
if (!(DragOrMods(drag)&optionKey)) {
|
|
#ifndef clarenceBug821
|
|
#ifdef TWO
|
|
AddXfUndo(tocH,TOCBySpec(&spec),sumNum);
|
|
#endif
|
|
#endif
|
|
EzOpen(tocH,sumNum,0,DragOrMods(drag),True,True);
|
|
}
|
|
MoveMessage(tocH,sumNum,&spec,(DragOrMods(drag)&optionKey)!=0);
|
|
}
|
|
}
|
|
return(err);
|
|
}
|
|
else
|
|
return dragNotAcceptedErr;
|
|
|
|
}
|
|
break;
|
|
}
|
|
return err;
|
|
}
|
|
#endif
|
|
|
|
/************************************************************************
|
|
* GetListData - get data for selected item
|
|
************************************************************************/
|
|
Boolean GetListData(VLNodeInfo *data,short selectedItem)
|
|
{
|
|
return LVGetItem(&gWin.list,selectedItem,data,true);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* BuildSigList - build the signature list
|
|
**********************************************************************/
|
|
void BuildSigList(void)
|
|
{
|
|
Str255 string;
|
|
FSSpec folderSpec;
|
|
CInfoPBRec hfi;
|
|
long newDirId;
|
|
short count;
|
|
Boolean extraSignatures = false;
|
|
|
|
// create the folder
|
|
DirCreate(Root.vRef,Root.dirId,GetRString(string,SIG_FOLDER),&newDirId);
|
|
|
|
// is there a folder?
|
|
if (!SubFolderSpec(SIG_FOLDER,&folderSpec))
|
|
{
|
|
// setup list handle
|
|
if (ghSigList)
|
|
SetHandleSize(ghSigList,sizeof(short));
|
|
else
|
|
{
|
|
ghSigList = NuHandle(2);
|
|
if (!ghSigList)
|
|
return;
|
|
}
|
|
|
|
GetRString(string,FILE_ALIAS_STANDARD); // Standard signature
|
|
PtrAndHand(string, ghSigList, *string+1);
|
|
GetRString(string,FILE_ALIAS_ALTERNATE); // Alternate signature
|
|
PtrAndHand(string, ghSigList, *string+1);
|
|
count = 2;
|
|
|
|
/*
|
|
* iterate through all the files, adding them to the list
|
|
*/
|
|
//Multiple Signatures - allow only the standard and alternate sigs in light
|
|
hfi.hFileInfo.ioNamePtr = string;
|
|
hfi.hFileInfo.ioFDirIndex = 0;
|
|
while (!DirIterate(folderSpec.vRefNum,folderSpec.parID,&hfi))
|
|
{
|
|
if (!(hfi.hFileInfo.ioFlAttrib&0x10) && !EqualStrRes(string,SIGNATURE) && !EqualStrRes(string,ALT_SIG) && (hfi.hFileInfo.ioFlFndrInfo.fdType=='TEXT'))
|
|
{
|
|
extraSignatures = true;
|
|
PtrAndHand(string, ghSigList, *string+1);
|
|
count++;
|
|
}
|
|
}
|
|
if (extraSignatures)
|
|
UseFeature (featureSignatures);
|
|
|
|
*(short *)*ghSigList = count;
|
|
}
|
|
|
|
if (gWin.inited)
|
|
InvalidListView(&gWin.list); // Regenerate list
|
|
}
|
|
|
|
/************************************************************************
|
|
* SetControls - enable or disable the controls, based on current situation
|
|
************************************************************************/
|
|
static void SetControls(void)
|
|
{
|
|
Boolean fSelect,fRemove;
|
|
|
|
fSelect = LVCountSelection(&gWin.list)!=0;
|
|
gWin.win->hasSelection = fSelect;
|
|
|
|
// Determine if "Remove" and "Edit" buttons need to be greyed
|
|
if (fRemove = fSelect)
|
|
{
|
|
// Make sure that selection doesn't include any non-removeable items
|
|
short i;
|
|
VLNodeInfo data;
|
|
|
|
for (i=1;i<=LVCountSelection(&gWin.list);i++)
|
|
{
|
|
GetListData(&data,i);
|
|
if (data.rowNum <= 2)
|
|
{
|
|
// Here's an item that can't be removed
|
|
fRemove = false;
|
|
}
|
|
if (!HasFeature (featureSignatures) && data.rowNum > 2)
|
|
fSelect = false;
|
|
}
|
|
}
|
|
SetGreyControl(gWin.ctlRemove,!fRemove);
|
|
SetGreyControl(gWin.ctlEdit,!fSelect);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* NewSigFile - create a new signature file
|
|
**********************************************************************/
|
|
static void NewSigFile(void)
|
|
{
|
|
FSSpec spec,folderSpec;
|
|
OSErr err;
|
|
|
|
//Multiple Signatures - allow only the standard and alternate sigs in light
|
|
if (!HasFeature (featureSignatures))
|
|
return;
|
|
|
|
UseFeature (featureSignatures);
|
|
|
|
if (SubFolderSpec(SIG_FOLDER,&folderSpec)) return;
|
|
|
|
// Make a unique "untitled" name
|
|
MakeUniqueUntitledSpec (folderSpec.vRefNum, folderSpec.parID, UNTITLED, &spec);
|
|
|
|
if (err=FSpCreate(&spec,CREATOR,'TEXT',smSystemScript))
|
|
{
|
|
FileSystemError(CREATE_SIG,&spec.name,err);
|
|
return;
|
|
}
|
|
|
|
BuildSigList();
|
|
|
|
LVRename(&gWin.list,0,spec.name,true, false); // Allow user to rename the signature file
|
|
}
|
|
|
|
/**********************************************************************
|
|
* DeleteSig - delete signature file(s)
|
|
**********************************************************************/
|
|
static void DeleteSig(void)
|
|
{
|
|
FSSpec spec;
|
|
short i;
|
|
VLNodeInfo info;
|
|
|
|
//Multiple Signatures - allow only the standard and alternate sigs in light
|
|
for (i=1;i<=LVCountSelection(&gWin.list);i++)
|
|
{
|
|
GetListData(&info,i);
|
|
if (info.rowNum > 2)
|
|
{
|
|
GetSigSpec(info.rowNum, &spec, info.name);
|
|
CloseTextWindow(&spec);
|
|
FSpTrash(&spec);
|
|
}
|
|
}
|
|
|
|
BuildSigList();
|
|
}
|
|
|
|
/**********************************************************************
|
|
* CloseTextWindow - find and close any text window associated with the file
|
|
**********************************************************************/
|
|
static void CloseTextWindow(FSSpecPtr spec)
|
|
{
|
|
WindowPtr winWP;
|
|
MyWindowPtr win;
|
|
|
|
//Multiple Signatures - allow only the standard and alternate sigs in light
|
|
for (winWP=FrontWindow_();winWP;winWP=GetNextWindow(winWP))
|
|
{
|
|
win = GetWindowMyWindowPtr(winWP);
|
|
if (GetWindowKind(winWP) == TEXT_WIN)
|
|
{
|
|
FSSpec winSpec = (*(TextDHandle)GetMyWindowPrivateData(win))->spec;
|
|
if (SameSpec(spec,&winSpec))
|
|
{
|
|
// Close the window. Don't save changes
|
|
win->isDirty = False;
|
|
PeteCleanList(win->pte);
|
|
CloseMyWindow(winWP);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* RenameTextWindow - find and rename any text window associated with the file
|
|
**********************************************************************/
|
|
static void RenameTextWindow(FSSpecPtr spec,StringPtr newName)
|
|
{
|
|
WindowPtr winWP;
|
|
MyWindowPtr win;
|
|
|
|
//Multiple Signatures - allow only the standard and alternate sigs in light
|
|
for (winWP=FrontWindow_();winWP;winWP=GetNextWindow(winWP))
|
|
{
|
|
win = GetWindowMyWindowPtr(winWP);
|
|
if (GetWindowKind(winWP) == TEXT_WIN)
|
|
{
|
|
FSSpec winSpec = (*(TextDHandle)GetMyWindowPrivateData(win))->spec;
|
|
if (SameSpec(spec,&winSpec))
|
|
{
|
|
PCopy((*(TextDHandle)GetMyWindowPrivateData(win))->spec.name,newName); // Adjust file spec
|
|
SetWTitle_(winWP,newName);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* ViewListCallBack - callback function for List View
|
|
************************************************************************/
|
|
static long ViewListCallBack(ViewListPtr pView, VLCallbackMessage message, long data)
|
|
{
|
|
VLNodeInfo info,*pInfo;
|
|
OSErr err = noErr;
|
|
short i,count;
|
|
FSSpec spec;
|
|
SendDragDataInfo *pSendData;
|
|
Handle hData;
|
|
|
|
count = SignatureCount();
|
|
switch (message)
|
|
{
|
|
case kLVAddNodeItems:
|
|
// Add signature names to list
|
|
for (i=1;i<=count;i++)
|
|
{
|
|
Zero(info);
|
|
info.useLevelZero = true;
|
|
info.iconID = GetSignatureIcon(i);
|
|
GetSignatureName(i,info.name);
|
|
LVAdd(pView, &info);
|
|
}
|
|
break;
|
|
|
|
case kLVOpenItem:
|
|
OpenSelectedSigs();
|
|
break;
|
|
|
|
case kLVRenameItem:
|
|
{
|
|
Str31 newName;
|
|
SanitizeFN(newName,(StringPtr)data,MAC_FN_BAD,MAC_FN_REP,false);
|
|
if (EqualStrRes(newName,FILE_ALIAS_STANDARD) || EqualStrRes(newName,FILE_ALIAS_ALTERNATE))
|
|
ComposeStdAlert (Caution,NAME_IN_USE);
|
|
else
|
|
{
|
|
GetListData(&info,1);
|
|
if (info.rowNum > 2)
|
|
UseFeature (featureSignatures);
|
|
GetSigSpec(info.rowNum, &spec, info.name);
|
|
if (err = HRename(spec.vRefNum,spec.parID,spec.name,newName))
|
|
FileSystemError(CANT_RENAME_ERR,spec.name,err);
|
|
else
|
|
RenameTextWindow(&spec,newName);
|
|
}
|
|
BuildSigList();
|
|
break;
|
|
}
|
|
|
|
case kLVQueryItem:
|
|
pInfo = ( VLNodeInfo *)data;
|
|
switch (pInfo->query)
|
|
{
|
|
case kQuerySelect:
|
|
case kQueryDrag:
|
|
case kQueryDrop:
|
|
case kQueryDCOpens:
|
|
return true;
|
|
case kQueryRename:
|
|
return pInfo->rowNum >= 3; // Can't rename standard or alternate
|
|
}
|
|
return false;
|
|
break;
|
|
|
|
case kLVDeleteItem:
|
|
DeleteSig();
|
|
break;
|
|
|
|
case kLVSendDragData:
|
|
// Get context of sig file for drag
|
|
pSendData = (SendDragDataInfo *)data;
|
|
GetSigSpec(pSendData->info->rowNum, &spec, pSendData->info->name);
|
|
if (!Snarf(&spec, &hData, nil))
|
|
{
|
|
HLock(hData);
|
|
SetDragItemFlavorData(pSendData->drag, pSendData->itemRef, pSendData->flavor,*hData, GetHandleSize(hData), 0L);
|
|
DisposeHandle(hData);
|
|
}
|
|
break;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/************************************************************************
|
|
* GetSigSpec - get the file spec for a signature
|
|
************************************************************************/
|
|
static void GetSigSpec(short index, FSSpecPtr pSpec, StringPtr name)
|
|
{
|
|
SubFolderSpec(SIG_FOLDER,pSpec);
|
|
if (index <= 2)
|
|
GetRString(pSpec->name,index==2?ALT_SIG:SIGNATURE);
|
|
else
|
|
PCopy(pSpec->name,name); // Use file name
|
|
}
|
|
|
|
/************************************************************************
|
|
* OpenSelectedSigs - open the selected signature(s)
|
|
************************************************************************/
|
|
static void OpenSelectedSigs(void)
|
|
{
|
|
// Open selected signatures
|
|
VLNodeInfo info;
|
|
short i;
|
|
FSSpec spec;
|
|
|
|
for (i=1;i<=LVCountSelection(&gWin.list);i++)
|
|
{
|
|
GetListData(&info,i);
|
|
if (info.rowNum <= 2 || HasFeature (featureSignatures)) {
|
|
GetSigSpec(info.rowNum, &spec, info.name);
|
|
OpenText(&spec,nil,nil,nil,true,nil,false,false);
|
|
}
|
|
}
|
|
} |