1 line
105 KiB
C
Executable File
1 line
105 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. */
|
|
|
|
#define FILE_NUM 70
|
|
/* Copyright (c) 1994 by QUALCOMM Incorporated */
|
|
|
|
#include "toolbar.h"
|
|
#include "toolbarpopup.h"
|
|
#pragma segment Toolbar
|
|
|
|
typedef struct ButtonData
|
|
{
|
|
TBButtonEnum kind;
|
|
long select;
|
|
long modifiers;
|
|
Handle data;
|
|
ControlHandle cntl;
|
|
Str255 title;
|
|
Style style;
|
|
Boolean reinitBox;
|
|
short slots;
|
|
} ButtonData, *BDPtr, **BDHandle;
|
|
|
|
typedef struct TBGlobals
|
|
{
|
|
ToolbarVEnum varCode;
|
|
Boolean vertical;
|
|
short wi;
|
|
short hi;
|
|
short exCount;
|
|
short exPixels;
|
|
short space;
|
|
BDHandle bd;
|
|
//ControlHandle controls[2];
|
|
Rect strucRect;
|
|
uLong downTicks;
|
|
uLong dragTicks;
|
|
Boolean ignore;
|
|
DragReference oldDrag;
|
|
ControlHandle beingDragged;
|
|
Boolean droppedOnMe;
|
|
Boolean dragInteresting;
|
|
ControlHandle dragHilite;
|
|
ControlHandle lastCntl;
|
|
Boolean messageBeingDragged;
|
|
Boolean deleted;
|
|
Boolean forceEnable;
|
|
short n;
|
|
Boolean fKeys;
|
|
Rect tip;
|
|
ControlHandle tipCntl;
|
|
PortSaveStuff stuff;
|
|
uLong idleTicks;
|
|
uLong lastIdleRunTicks;
|
|
ControlRef taskProgButton;
|
|
ControlHandle searchUserPane;
|
|
ControlHandle searchGo;
|
|
ControlHandle searchEdit;
|
|
ControlHandle searchPopup;
|
|
PETEHandle searchPTE;
|
|
short searchItem;
|
|
StackHandle searchStack;
|
|
Rect screenRect;
|
|
} TBG, **TBGHandle;
|
|
|
|
typedef struct TBMenu
|
|
{
|
|
Boolean doingButton;
|
|
Boolean doingMenuSelect;
|
|
short menuId;
|
|
short item;
|
|
} TBMenu;
|
|
|
|
#ifdef DEBUG
|
|
TBGHandle TBGDB;
|
|
#endif
|
|
|
|
#define ForceEnable (*(TBGHandle)GetMyWindowPrivateData(Win))->forceEnable
|
|
#define VarCode (*(TBGHandle)GetMyWindowPrivateData(Win))->varCode
|
|
#define Deleted (*(TBGHandle)GetMyWindowPrivateData(Win))->deleted
|
|
#define Vertical (*(TBGHandle)GetMyWindowPrivateData(Win))->vertical
|
|
#define Controls (*(TBGHandle)GetMyWindowPrivateData(Win))->controls
|
|
#define Hi (*(TBGHandle)GetMyWindowPrivateData(Win))->hi
|
|
#define Space (*(TBGHandle)GetMyWindowPrivateData(Win))->space
|
|
#define Wi (*(TBGHandle)GetMyWindowPrivateData(Win))->wi
|
|
#define ExCount (*(TBGHandle)GetMyWindowPrivateData(Win))->exCount
|
|
#define ExPixels (*(TBGHandle)GetMyWindowPrivateData(Win))->exPixels
|
|
#define BD (*(TBGHandle)GetMyWindowPrivateData(Win))->bd
|
|
#define Dirty Win->isDirty
|
|
#define DroppedOnMe (*(TBGHandle)GetMyWindowPrivateData(Win))->droppedOnMe
|
|
#define StrucRect (*(TBGHandle)GetMyWindowPrivateData(Win))->strucRect
|
|
#define N (*(TBGHandle)GetMyWindowPrivateData(Win))->n
|
|
#define DownTicks (*(TBGHandle)GetMyWindowPrivateData(Win))->downTicks
|
|
#define DragTicks (*(TBGHandle)GetMyWindowPrivateData(Win))->dragTicks
|
|
#define Ignore (*(TBGHandle)GetMyWindowPrivateData(Win))->ignore
|
|
#define OldDrag (*(TBGHandle)GetMyWindowPrivateData(Win))->oldDrag
|
|
#define DragInteresting (*(TBGHandle)GetMyWindowPrivateData(Win))->dragInteresting
|
|
#define BeingDragged (*(TBGHandle)GetMyWindowPrivateData(Win))->beingDragged
|
|
#define DragHilite (*(TBGHandle)GetMyWindowPrivateData(Win))->dragHilite
|
|
#define LastCntl (*(TBGHandle)GetMyWindowPrivateData(Win))->lastCntl
|
|
#define TipCntl (*(TBGHandle)GetMyWindowPrivateData(Win))->tipCntl
|
|
#define FKeys (*(TBGHandle)GetMyWindowPrivateData(Win))->fKeys
|
|
#define MessageBeingDragged (*(TBGHandle)GetMyWindowPrivateData(Win))->messageBeingDragged
|
|
#define Tip (*(TBGHandle)GetMyWindowPrivateData(Win))->tip
|
|
#define ForceEnable (*(TBGHandle)GetMyWindowPrivateData(Win))->forceEnable
|
|
#define Stuff (*(TBGHandle)GetMyWindowPrivateData(Win))->stuff
|
|
#define IdleTicks (*(TBGHandle)GetMyWindowPrivateData(Win))->idleTicks
|
|
#define LastIdleRunTicks (*(TBGHandle)GetMyWindowPrivateData(Win))->lastIdleRunTicks
|
|
#define TaskProgButton (*(TBGHandle)GetMyWindowPrivateData(Win))->taskProgButton
|
|
#define SearchUserPane (*(TBGHandle)GetMyWindowPrivateData(Win))->searchUserPane
|
|
#define SearchGo (*(TBGHandle)GetMyWindowPrivateData(Win))->searchGo
|
|
#define SearchEdit (*(TBGHandle)GetMyWindowPrivateData(Win))->searchEdit
|
|
#define SearchPopup (*(TBGHandle)GetMyWindowPrivateData(Win))->searchPopup
|
|
#define SearchPTE (*(TBGHandle)GetMyWindowPrivateData(Win))->searchPTE
|
|
#define SearchItem (*(TBGHandle)GetMyWindowPrivateData(Win))->searchItem
|
|
#define SearchStack (*(TBGHandle)GetMyWindowPrivateData(Win))->searchStack
|
|
#define ScreenRect (*(TBGHandle)GetMyWindowPrivateData(Win))->screenRect
|
|
|
|
void TBMonitorMonitor(void);
|
|
Boolean TBButtonInterested(ControlHandle theCtl);
|
|
long TBExtractMenu(BDPtr bd,short *mnu,short *item);
|
|
OSErr TBSetButtonType(ControlHandle button);
|
|
|
|
#define IsRecipMenu(m) (NEW_TO_HIER_MENU<=(m) && (m)<=INSERT_TO_HIER_MENU)
|
|
#define IsStationMenu(m) ((m)==REPLY_WITH_HIER_MENU || (m)==NEW_WITH_HIER_MENU)
|
|
|
|
#define ToolbarStrnID (HasFeature (featureCustomizeToolbar) ? ToolbarProStrn : ToolbarLightStrn)
|
|
|
|
#define TBAR_DRAG_FLAVOR 'TBAR'
|
|
#define TB_ALIAS_TYPE 'EuTA'
|
|
|
|
typedef struct
|
|
{
|
|
short id;
|
|
OSType type;
|
|
OSType creator;
|
|
} TBAliasData, *TBAliasPtr, **TBAliasHandle;
|
|
|
|
MyWindowPtr Win;
|
|
TBMenu gTBMenu;
|
|
|
|
#define HideControl(c) SetControlVisibility((c),false,false)
|
|
#define ShowControl(c) SetControlVisibility((c),true,false)
|
|
|
|
/**********************************************************************
|
|
* Prototypes
|
|
**********************************************************************/
|
|
void TBPlaceControls(Rect *screenRect,short *windowWide, short *windowHi);
|
|
OSErr TBNewButton(short which);
|
|
void ToolbarButton(MyWindowPtr win,ControlHandle button,long modifiers,short part);
|
|
OSErr LoadToolbarButton(short i);
|
|
void SizeToolbar(short max);
|
|
short Menu2Icon(short menu,short item,short modifiers);
|
|
short Key2Icon(short key,short modifiers);
|
|
Boolean ConfigureTBButton(short which);
|
|
void ToolClick(MyWindowPtr win, EventRecord *event);
|
|
void InstallButtonMenu(short i, short menu, short item,PStr itemText,short modifiers,void *data,long size);
|
|
void InstallButtonFile(short i, FSSpecPtr spec);
|
|
void InstallButtonKey(short i, long key,short modifiers);
|
|
Boolean ToolbarClose(MyWindowPtr win);
|
|
void SaveToolbar(void);
|
|
void FlipToolbar(void);
|
|
void ToolbarUpdate(MyWindowPtr win);
|
|
PStr ModifierNames(PStr string,short modifiers);
|
|
Boolean TBInterStice(Point pt,short *which);
|
|
void TBBalloon(ControlHandle cntl);
|
|
Boolean TBInstSpecialMenus(short menu,short item,short modifiers,PStr itemStr,PStr titleStr);
|
|
Boolean TBSpecialStr(short menu,PStr itemStr,short *item,short *modifiers);
|
|
Boolean TBMovedMenu(short *menu,PStr itemStr,short *item);
|
|
Boolean ToolControl(Point pt, MyWindowPtr win);
|
|
void TBButton2String(ButtonData *bd, PStr s);
|
|
void TBDelButton(ControlHandle cntl);
|
|
Boolean ToolDrag(ControlHandle theCtl, EventRecord *event);
|
|
OSErr TBDragHandler(MyWindowPtr win,DragTrackingMessage which,DragReference drag);
|
|
void TBDragHilite(DragReference drag,ControlHandle cntl);
|
|
OSErr TBDrop(DragReference drag, short which, Boolean replacing);
|
|
void InstallButtonSpec(short which, FSSpecPtr spec);
|
|
void TBZapButtonData(short which);
|
|
void InstallButtonAliasId(short which,short id,OSType type, OSType creator,PStr name);
|
|
void TBFileButton(BDPtr bdp);
|
|
OSErr LoadButtonString(short i,PStr s);
|
|
OSErr ToolbarMailbox(short which,FSSpecPtr spec);
|
|
OSErr TBMessageDrop(DragReference drag,short which);
|
|
Boolean TBIsMboxButton(ControlHandle theCtl);
|
|
Boolean TBIsNicknameButton(ControlHandle theCtl);
|
|
void TBTipLo(ControlHandle cntl);
|
|
void TBDrawTip(void);
|
|
Boolean ToolbarMenu(MyWindowPtr win, int menu, int item, short modifiers);
|
|
OSErr SetPrinterIcon(ControlHandle button);
|
|
OSErr SetNicknameIcon(ControlHandle button, PStr nickname);
|
|
#define TBTip(x) do{if (Win && TipCntl!=(x)) TBTipLo(x);}while(0)
|
|
void TBButtonClose(short which);
|
|
PStr TBGetCTitle(ControlHandle cntl,PStr title);
|
|
void TBSetCTitle(ControlHandle theCtl,PStr title);
|
|
void TBIdle(MyWindowPtr win);
|
|
void InstallButtonAd(short i,TBAdInfo *pAd);
|
|
void InstallButtonNickname (short i, PStr nickname);
|
|
Boolean TBRename (TBButtonEnum kind, PStr oldName, PStr newName);
|
|
short TBBoxishMenu(short which,FSSpecPtr spec,PStr s,short mnu,short itm);
|
|
OSErr TBReinitBox(short which);
|
|
void DeletingButton(BDPtr pBD);
|
|
void MessageDragPopup (ControlHandle button, Boolean vertical);
|
|
static void TaskProgAnimate(ControlRef control);
|
|
#define TB_RESTORE_STUFF do{LDRef((TBGHandle)GetMyWindowPrivateData(Win));SetPortStuff(&Stuff);UL((TBGHandle)GetMyWindowPrivateData(Win));}while(0);
|
|
#define TB_SAVE_STUFF do{LDRef((TBGHandle)GetMyWindowPrivateData(Win));DisposePortStuff(&Stuff);SavePortStuff(&Stuff);UL((TBGHandle)GetMyWindowPrivateData(Win));}while(0);
|
|
ControlHandle TBNewSearchEdit(WindowPtr winWP);
|
|
void TBSearchStart(PStr searchMe);
|
|
void TBSearchEmpty(void);
|
|
void TBSearchPopup(Point pt);
|
|
void TBSearchFocus(Boolean focus);
|
|
void TBDragPreProcess(PETEHandle pte,DragTrackingMessage message,DragReference drag);
|
|
void TBDragPostProcess(PETEHandle pte,DragTrackingMessage message,DragReference drag);
|
|
|
|
#pragma segment Toolbar
|
|
/**********************************************************************
|
|
* OpenToolbar - open the toolbar
|
|
**********************************************************************/
|
|
void OpenToolbar(void)
|
|
{
|
|
MyWindowPtr win;
|
|
WindowPtr winWP;
|
|
short i,n;
|
|
|
|
if (Win) {CloseMyWindow(GetMyWindowWindowPtr(Win)); Win=nil; return;}
|
|
|
|
win = GetNewMyWindowWithClass(TBAR_WIND,nil,nil,BehindModal,False,False,TBAR_WIN,PrefIsSet(PREF_TB_FLOATING) ? kFloatingWindowClass: kToolbarWindowClass);
|
|
winWP = GetMyWindowWindowPtr (win);
|
|
if (win)
|
|
{
|
|
Win = win;
|
|
SetMyWindowPrivateData(Win,(long)NewZH(TBG));
|
|
#ifdef DEBUG
|
|
TBGDB = (TBGHandle)GetMyWindowPrivateData(Win);
|
|
#endif
|
|
i = GetPrefLong(PREF_TB_VARIATION)+1;
|
|
VarCode = i;
|
|
if (PrefIsSet(PREF_TB_VERT)) Vertical = True; else Vertical = False;
|
|
SetPort_(GetWindowPort(winWP));
|
|
TextFont(SmallSysFontID());
|
|
TextSize(9);
|
|
MySetThemeWindowBackground(win,kThemeActiveUtilityWindowBackgroundBrush,False);
|
|
SetThemeTextColor(kThemeActiveWindowHeaderTextColor,RectDepth(&Win->contR),True);
|
|
TB_SAVE_STUFF;
|
|
n = CountStrn(ToolbarStrnID);
|
|
SizeToolbar(n);
|
|
for (i=1;i<=n;i++)
|
|
{
|
|
if (LoadToolbarButton(i)) break;
|
|
}
|
|
win->button = ToolbarButton;
|
|
win->click = ToolClick;
|
|
win->isRunt = True;
|
|
win->bgClick = ToolClick;
|
|
win->close = ToolbarClose;
|
|
win->update = ToolbarUpdate;
|
|
win->cursor = ToolbarCursor;
|
|
win->menu = ToolbarMenu;
|
|
win->dontControl = True;
|
|
win->dontActivate = True;
|
|
win->idle = TBIdle;
|
|
win->idleInterval = 60;
|
|
win->drag = HasFeature (featureCustomizeToolbar) ? TBDragHandler : nil;
|
|
win->position = PositionPrefsTitle;
|
|
win->dontDrawControls = True;
|
|
win->windowType = PrefIsSet(PREF_TB_FLOATING) ? kFloating : kDockable;
|
|
ShowMyWindow(winWP);
|
|
PositionDockedWindow(winWP);
|
|
|
|
// Because of the mini-dialog, we no longer do this
|
|
// Add web search
|
|
// if (!GetPrefBit(PREF_SEARCH_WEB_BITS,prefSearchWebTBButtonInstalled))
|
|
// TBAddMenuButton(FIND_HIER_MENU,FIND_SEARCH_WEB_ITEM,ComposeRString(GlobalTemp,SEARCH_NOTHING_FMT,SEARCH_FOR_WEB));
|
|
|
|
// Add any in-your-face plug-ins to the toolbar
|
|
ETLAddToToolbar();
|
|
|
|
GetStructureRgnBounds(winWP,&StrucRect);
|
|
ToolbarNudgeAll(true);
|
|
PositionDockedWindows();
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBIdle - idle loop for the toolbar
|
|
* Will ordinarily defer to other events, but if called with nil does not defer
|
|
**********************************************************************/
|
|
void TBIdle(MyWindowPtr win)
|
|
{
|
|
WindowPtr WinWP = GetMyWindowWindowPtr(Win); // Yeah, seems like these are the same... or are they?
|
|
WindowPtr winWP = GetMyWindowWindowPtr(win); // Safer for now to just treat them as different
|
|
ButtonData bd;
|
|
short mnu, item;
|
|
short i;
|
|
short lite;
|
|
Boolean fiddle = False;
|
|
Style style;
|
|
MenuHandle mh;
|
|
static uLong styleTicks;
|
|
Boolean reStyle;
|
|
ControlHandle cntl;
|
|
|
|
if (win && (FrontWindowNeedsUpdate(WinWP) || !IsWindowVisible(winWP)))
|
|
{
|
|
return; // if there's anything else to do or toolbar is invisible, go away
|
|
}
|
|
|
|
if (LastIdleRunTicks >= NonNullTicks) return; // nothing has happened lately; go away
|
|
|
|
LastIdleRunTicks = NonNullTicks;
|
|
|
|
if (!InBG)
|
|
{
|
|
SetPort_(GetMyWindowCGrafPtr(Win));
|
|
TB_RESTORE_STUFF;
|
|
TBMonitorMonitor();
|
|
if (reStyle = (TickCount()-styleTicks>90)) styleTicks = TickCount();
|
|
GetRootControl(WinWP,&cntl);
|
|
ActivateControl(cntl);
|
|
EnableMenuItems(False);
|
|
|
|
// clear labels
|
|
if (keyFocusedFloater==Win && Win->pte) PeteNoLabel(Win->pte,0,0xffffffff,0xff);
|
|
|
|
// Update buttons
|
|
for (i=0;i<N;i++)
|
|
{
|
|
if ((*BD)[i].reinitBox) TBReinitBox(i);
|
|
|
|
bd = (*BD)[i];
|
|
|
|
if (bd.kind==tbkMenu)
|
|
{
|
|
if (TBExtractMenu(&bd,&mnu,&item))
|
|
{
|
|
if (reStyle && (mh=GetMHandle(mnu)))
|
|
{
|
|
GetItemStyle(mh,item,&style);
|
|
if (bd.style != style)
|
|
{
|
|
(*BD)[i].style = style;
|
|
SetBevelStyle(bd.cntl,style);
|
|
}
|
|
if (mnu==LABEL_HIER_MENU)
|
|
{
|
|
Str255 s;
|
|
MyGetItem(mh,item,s);
|
|
TBSetCTitle(bd.cntl,s);
|
|
}
|
|
#ifdef NEVER // unfortunately, doesn't work
|
|
GetItemColor(mnu,item,&color);
|
|
SetBevelColor(bd.cntl,&color);
|
|
#endif
|
|
}
|
|
if (mnu==MAILBOX_MENU || mnu==TRANSFER_MENU) item=1; //avoid looking at the separator bar, dummy.
|
|
mnu = MailboxKindaMenu(mnu,item,nil,nil);
|
|
if (mnu==MAILBOX_MENU || mnu==TRANSFER_MENU) item=1; //avoid looking at the separator bar, dummy.
|
|
if (mnu==FILE_MENU && item==FILE_QUIT_ITEM && HaveTheDiseaseCalledOSX())
|
|
{
|
|
// enable Quit anytime In is enabled
|
|
mnu=MAILBOX_MENU;
|
|
item=1;
|
|
}
|
|
lite = !ModalWindow&&(ForceEnable||IsEnabled(mnu,item))?0:255;
|
|
}
|
|
}
|
|
else
|
|
lite = ModalWindow||NoMenus ? 255 : 0;
|
|
if (GetControlHilite(bd.cntl)!=lite)
|
|
{
|
|
HiliteControl(bd.cntl,lite);
|
|
if (Space<0 && lite==255)
|
|
{
|
|
fiddle = True;
|
|
if (i>0 && GetControlHilite((*BD)[i-1].cntl)!=255)
|
|
Draw1Control((*BD)[i-1].cntl);
|
|
}
|
|
else fiddle = False;
|
|
}
|
|
else
|
|
{
|
|
if (fiddle && GetControlHilite(bd.cntl)!=255)
|
|
Draw1Control(bd.cntl);
|
|
fiddle = False;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBMonitorMonitor - watch the monitor and see if it changes
|
|
**********************************************************************/
|
|
void TBMonitorMonitor(void)
|
|
{
|
|
Rect screenRect;
|
|
GDHandle junk;
|
|
short i = GetPrefLong(PREF_NW_DEV);
|
|
Boolean hasMB;
|
|
|
|
if (i)
|
|
{
|
|
utl_GetIndGD(i,&junk,&screenRect,&hasMB);
|
|
if (hasMB) screenRect.top += GetMBarHeight();
|
|
}
|
|
else
|
|
{
|
|
GetQDGlobalsScreenBitsBounds(&screenRect);
|
|
screenRect.top += GetMBarHeight();
|
|
}
|
|
|
|
if (!AboutSameRect(&screenRect,&ScreenRect)) SizeToolbar(N);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBReinitBox - read the mailbox back out of a toolbar button
|
|
**********************************************************************/
|
|
OSErr TBReinitBox(short which)
|
|
{
|
|
// Yowza. We be changin' it
|
|
short mnu = (((*BD)[which].select)>>16)&0xffff;
|
|
short item;
|
|
Str63 s;
|
|
FSSpec spec;
|
|
Boolean xfer = mnu==TRANSFER_MENU;
|
|
|
|
if (!ToolbarMailbox(which+1,&spec))
|
|
if (!Spec2Menu(&spec,xfer,&mnu,&item))
|
|
{
|
|
*s = 0;
|
|
if (xfer) GetRString(s,TRANSFER_PREFIX);
|
|
PSCat(s,spec.name);
|
|
|
|
mnu = TBBoxishMenu(which,&spec,s,mnu,item);
|
|
InstallButtonMenu(GetControlReference((*BD)[which].cntl),mnu,0,s,0,&spec,sizeof(FSSpec));
|
|
Dirty = true;
|
|
}
|
|
(*BD)[which].reinitBox = false;
|
|
return noErr;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBForceIdle - force the toolbar through an idle loop
|
|
**********************************************************************/
|
|
void TBForceIdle(void)
|
|
{
|
|
if (Win) LastIdleRunTicks = 0;
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
Boolean TBButtonInterested(ControlHandle theCtl)
|
|
{
|
|
Str255 sTitle;
|
|
|
|
GetControlTitle(theCtl,sTitle);
|
|
return (!MessageBeingDragged && !*sTitle ||
|
|
MessageBeingDragged && (TBIsMboxButton(theCtl)||TBIsNicknameButton(theCtl))); // Don't drag onto ads
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
OSErr TBDragHandler(MyWindowPtr win,DragTrackingMessage which,DragReference drag)
|
|
{
|
|
#pragma unused(win)
|
|
WindowPtr WinWP = GetMyWindowWindowPtr(Win);
|
|
OSErr err=noErr;
|
|
Point mouse;
|
|
short stice;
|
|
Rect r;
|
|
RgnHandle rgn;
|
|
ControlHandle theCtl=nil;
|
|
|
|
if (drag!=OldDrag)
|
|
{
|
|
Boolean interesting = DragIsInteresting(drag,TBAR_DRAG_FLAVOR,flavorTypeHFS,flavorTypeDirectory,TOC_FLAVOR,MESS_FLAVOR,kMBDragType,kNickDragType,nil);
|
|
OldDrag = drag;
|
|
DragInteresting = interesting;
|
|
|
|
if (interesting && DragIsInteresting(drag,TOC_FLAVOR,MESS_FLAVOR,nil))
|
|
MessageBeingDragged = True;
|
|
else MessageBeingDragged = False;
|
|
}
|
|
|
|
if (!DragInteresting) return(dragNotAcceptedErr);
|
|
|
|
SetPort_(GetMyWindowCGrafPtr(Win));
|
|
TB_RESTORE_STUFF;
|
|
GetDragMouse(drag,&mouse,nil);
|
|
GlobalToLocal(&mouse);
|
|
|
|
switch (which)
|
|
{
|
|
case kDragTrackingInWindow:
|
|
if (!MessageBeingDragged && TBInterStice(mouse,&stice) && (rgn=NewRgn()))
|
|
{
|
|
if (DragHilite) TBDragHilite(drag,nil);
|
|
SetMyCursor(Vertical ? SPREAD_CURS_V : SPREAD_CURS);
|
|
if (Vertical)
|
|
InsetRect(&r,-10,3);
|
|
else
|
|
InsetRect(&r,3,-10);
|
|
RectRgn(rgn,&r);
|
|
ShowDragHilite(drag,rgn,True);
|
|
DisposeRgn(rgn);
|
|
}
|
|
else if (FindControl(mouse,WinWP,&theCtl) && theCtl!=TaskProgButton)
|
|
{
|
|
SetMyCursor(arrowCursor);
|
|
if (!TBButtonInterested(theCtl))
|
|
TBDragHilite(drag,nil);
|
|
else
|
|
TBDragHilite(drag,theCtl);
|
|
}
|
|
else TBDragHilite(drag,nil);
|
|
err = noErr;
|
|
break;
|
|
case kDragTrackingLeaveWindow:
|
|
SetMyCursor(arrowCursor);
|
|
TBDragHilite(drag,nil);
|
|
err = noErr;
|
|
break;
|
|
case 0xfff:
|
|
DroppedOnMe = True;
|
|
if (!DragInteresting) return(dragNotAcceptedErr);
|
|
if (TBInterStice(mouse,&stice))
|
|
{
|
|
err = TBDrop(drag,stice,False);
|
|
}
|
|
else if (FindControl(mouse,WinWP,&theCtl))
|
|
{
|
|
if (!TBButtonInterested(theCtl)) return(dragNotAcceptedErr);
|
|
err = TBDrop(drag,GetControlReference(theCtl),True);
|
|
}
|
|
else err = dragNotAcceptedErr;
|
|
break;
|
|
}
|
|
|
|
TBTip(theCtl);
|
|
|
|
return(err);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBDrop - handle something dropped on the toolbar
|
|
**********************************************************************/
|
|
OSErr TBDrop(DragReference drag, short which, Boolean replacing)
|
|
{
|
|
short i, n;
|
|
OSErr err = noErr;
|
|
Boolean dirty = False;
|
|
Handle data = nil;
|
|
FSSpec spec;
|
|
Str255 string;
|
|
|
|
n = MyCountDragItems(drag);
|
|
|
|
TBDragHilite(drag,nil);
|
|
|
|
if (MessageBeingDragged)
|
|
{
|
|
TBMessageDrop(drag,which);
|
|
}
|
|
else
|
|
{
|
|
for (i=1;i<=n && !err; i++, which++)
|
|
{
|
|
if (!(err=MyGetDragItemData(drag,i,TBAR_DRAG_FLAVOR,&data)))
|
|
{
|
|
if (BeingDragged)
|
|
{
|
|
if (!replacing) {TBNewButton(which); which++;}
|
|
|
|
if (replacing && GetControlReference(BeingDragged)==which)
|
|
{
|
|
err = dragNotAcceptedErr;
|
|
}
|
|
else
|
|
{
|
|
DeletingButton(&(*BD)[which-1]);
|
|
PCopy(string,*data);
|
|
LoadButtonString(which,string);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!replacing) {TBNewButton(which); which++;}
|
|
else DeletingButton(&(*BD)[which-1]);
|
|
PCopy(string,*data);
|
|
LoadButtonString(which,string);
|
|
}
|
|
if (!err) Dirty = True;
|
|
}
|
|
else if (!(err=MyGetDragItemData(drag,i,flavorTypeHFS,&data)))
|
|
{
|
|
// File drag from Finder
|
|
if (!replacing) {TBNewButton(which);}
|
|
else { replacing = False; DeletingButton(&(*BD)[which-1]); which--;}
|
|
|
|
spec = (*(struct HFSFlavor**)data)->fileSpec;
|
|
|
|
InstallButtonSpec(which+1,&spec);
|
|
Dirty = True;
|
|
}
|
|
else if (!(err=MyGetDragItemData(drag,i,kMBDragType,&data)))
|
|
{
|
|
// Mailbox drag from Mailboxes window
|
|
MBDragPtr pDragData;
|
|
|
|
if (!replacing) {TBNewButton(which);}
|
|
else { replacing = False; DeletingButton(&(*BD)[which-1]); which--;}
|
|
|
|
pDragData = (MBDragPtr)*data;
|
|
InstallButtonMenu(which+1, MailboxKindaMenu(pDragData->menuID,pDragData->menuItem,pDragData->name,&pDragData->spec),0,pDragData->name,nil,&pDragData->spec,sizeof(FSSpec));
|
|
Dirty = True;
|
|
}
|
|
else if (!(err=MyGetDragItemData(drag,i,kNickDragType,&data)))
|
|
{
|
|
Str31 nickname;
|
|
Handle notes;
|
|
long offset;
|
|
short ab,
|
|
nick;
|
|
|
|
notes = nil;
|
|
offset = 0;
|
|
if (!GetNickFlavorDragData (data, &offset, &ab, &nick, nickname, nil, ¬es)) {
|
|
if (!replacing) {TBNewButton(which);}
|
|
else { replacing = False; DeletingButton(&(*BD)[which-1]); which--;}
|
|
|
|
// Make the toolbar button link to this recipient in the "New Message To" menu
|
|
InstallButtonNickname (which + 1, nickname);
|
|
Dirty = True;
|
|
}
|
|
ZapHandle (notes);
|
|
}
|
|
ZapHandle(data);
|
|
}
|
|
}
|
|
return(err);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* TBMessageDrop - Drop a message (or group of messages from a TOC) onto
|
|
* a toolbar button.
|
|
*
|
|
* If the drop is on a nickname button, the message(s)
|
|
* will be sent to the target nickname. Without any
|
|
* modifiers accompanying the drop, the action will be
|
|
* "forward to". By holding down some as of yet defined
|
|
* modifier the action is changed to "redirect to".
|
|
**********************************************************************/
|
|
OSErr TBMessageDrop(DragReference drag,short which)
|
|
{
|
|
FSSpec spec;
|
|
OSErr err;
|
|
FSSpec ***data;
|
|
|
|
err = noErr;
|
|
// Are we dropping the message onto a nickname?
|
|
if ((*BD)[which-1].kind == tbkNick) {
|
|
UHandle data=nil;
|
|
TOCHandle tocH = nil;
|
|
|
|
TextAddrHandle toWhom;
|
|
|
|
if (toWhom = NuHandle ((*BD)[which-1].title[0]))
|
|
BlockMoveData (&(*BD)[which-1].title[1], *toWhom, (*BD)[which-1].title[0]);
|
|
|
|
if (!(err=MyGetDragItemData(drag,1,MESS_FLAVOR,(void*)&data)))
|
|
{
|
|
tocH = (***(MessHandle**)data)->tocH;
|
|
}
|
|
else if (!(err=MyGetDragItemData(drag,1,TOC_FLAVOR,(void*)&data)))
|
|
tocH = **(TOCHandle**) data;
|
|
// Make sure the toolbar popup is closed if we're tracking
|
|
CloseToolbarPopup ();
|
|
if (tocH)
|
|
DoIterativeThingy (tocH, PrefIsSet (PREF_REDIRECT_MSG_DROPS_ON_TB_NICKS) ? MESSAGE_REDISTRIBUTE_ITEM : MESSAGE_FORWARD_ITEM, CurrentModifiers (), toWhom);
|
|
ZapHandle(data);
|
|
ZapHandle(toWhom);
|
|
}
|
|
else {
|
|
// tell the dragger where the destination is and let it do the work
|
|
if (!(err=ToolbarMailbox(which,&spec)))
|
|
if (!(err=MyGetDragItemData(drag,1,'euXX',(void*)&data)))
|
|
{
|
|
***data = spec;
|
|
}
|
|
}
|
|
return(err);
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
Boolean TBIsMboxButton(ControlHandle theCtl)
|
|
{
|
|
ButtonData bd = (*BD)[GetControlReference(theCtl)-1];
|
|
long mnu;
|
|
|
|
if (bd.kind!=tbkMenu) return(False);
|
|
mnu = (bd.select>>16)&0xffff;
|
|
return ((mnu==MAILBOX_MENU || mnu==TRANSFER_MENU) && bd.data);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TellToolMBRename - make sure we know that a mailbox is being renamed
|
|
**********************************************************************/
|
|
OSErr TellToolMBRename(FSSpecPtr spec,FSSpecPtr newSpec,Boolean folder,Boolean will,Boolean dontWarn)
|
|
{
|
|
short i;
|
|
Boolean isIMAPMailbox = IsIMAPCacheFolder(newSpec);
|
|
|
|
if (ToolbarShowing() && !will)
|
|
{
|
|
for (i=0;i<N;i++)
|
|
{
|
|
if (TBIsMboxButton((*BD)[i].cntl))
|
|
{
|
|
FSSpec buttonSpec;
|
|
|
|
if (!ToolbarMailbox(i+1,&buttonSpec))
|
|
{
|
|
if (isIMAPMailbox)
|
|
{
|
|
FSSpec scratch;
|
|
|
|
// IMAP mailbox cache _files_ are stored in the toolbar buttonSpec.
|
|
Zero(scratch);
|
|
ParentSpec(&buttonSpec, &scratch);
|
|
buttonSpec.parID = scratch.parID;
|
|
}
|
|
|
|
if (SameSpec(&buttonSpec,spec))
|
|
{
|
|
(*BD)[i].reinitBox = true;
|
|
**(FSSpecPtr*)(*BD)[i].data = *newSpec;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return noErr;
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
Boolean TBIsNicknameButton(ControlHandle theCtl)
|
|
{
|
|
return ((*BD)[GetControlReference(theCtl)-1].kind==tbkNick);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void TBSetCTitle(ControlHandle theCtl,PStr title)
|
|
{
|
|
PCopy((*BD)[GetControlReference(theCtl)-1].title,title);
|
|
if (VarHasName(VarCode)) MySetControlTitle(theCtl,title);
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void InstallButtonSpec(short which, FSSpecPtr spec)
|
|
{
|
|
ButtonData bd;
|
|
AliasHandle alias;
|
|
FSSpec settings;
|
|
short id;
|
|
FInfo info;
|
|
|
|
TBZapButtonData(which);
|
|
bd = (*BD)[which-1];
|
|
|
|
bd.kind = tbkFile;
|
|
TBSetCTitle(bd.cntl,spec->name);
|
|
PCopy(bd.title,spec->name);
|
|
|
|
GetFileByRef(SettingsRefN,&settings);
|
|
|
|
if (NewAlias(&settings,spec,&alias)) return;
|
|
|
|
UseResFile(SettingsRefN);
|
|
id = MyUniqueID(TB_ALIAS_TYPE);
|
|
|
|
AddMyResource_(alias,TB_ALIAS_TYPE,id,"");
|
|
if (ResError())
|
|
{
|
|
ZapHandle(alias);
|
|
return;
|
|
}
|
|
|
|
MyUpdateResFile(SettingsRefN);
|
|
|
|
if (FSpIsItAFolder(spec)) info.fdType = 'fdrp';
|
|
else AFSpGetFInfo(spec,spec,&info);
|
|
|
|
if (bd.data = NuHandle(sizeof(TBAliasData)))
|
|
{
|
|
(*(TBAliasHandle)bd.data)->id = id;
|
|
(*(TBAliasHandle)bd.data)->type = info.fdType;
|
|
(*(TBAliasHandle)bd.data)->creator = info.fdCreator;
|
|
}
|
|
|
|
if (VarHasIcon(VarCode))
|
|
if (info.fdType=='fdrp')
|
|
SetBevelIcon(bd.cntl,kGenericFolderIconResource,nil,nil,nil);
|
|
else
|
|
SetBevelIcon(bd.cntl,0,info.fdType,info.fdCreator,nil);
|
|
|
|
(*BD)[which-1] = bd;
|
|
if (TaskProgButton==bd.cntl) TaskProgButton = nil;
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void TBZapButtonData(short which)
|
|
{
|
|
RGBColor color;
|
|
Zero(color);
|
|
//if ((*BD)[which-1].kind == tbkFile && (*BD)[which-1].data)
|
|
//ZapSettingsResource(TB_ALIAS_TYPE,(*(TBAliasHandle)((*BD)[which-1].data))->id);
|
|
ZapHandle((*BD)[which-1].data);
|
|
if ((*BD)[which-1].cntl) SetBevelColor((*BD)[which-1].cntl,&color);
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void TBButtonClose(short which)
|
|
{
|
|
if ((*BD)[which-1].cntl) KillBevelIcon((*BD)[which-1].cntl);
|
|
ZapHandle((*BD)[which-1].data);
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void TBDragHilite(DragReference drag,ControlHandle cntl)
|
|
{
|
|
ControlHandle oldDragHilite = DragHilite;
|
|
Point mouse;
|
|
|
|
HideDragHilite(drag);
|
|
|
|
if (DragHilite && DragHilite!=BeingDragged && DragHilite!=cntl) {
|
|
SetControlValue(DragHilite,0);
|
|
// Don't close a toolbar popup if the mouse isin the window
|
|
GetDragMouse (drag, &mouse, nil);
|
|
if (!MouseInToolbarPopup (mouse, cntl ? false : true))
|
|
CloseToolbarPopup ();
|
|
}
|
|
if (cntl) SetControlValue(cntl,1);
|
|
DragHilite = cntl;
|
|
|
|
if (MessageBeingDragged)
|
|
if (cntl && (*BD)[GetControlReference(cntl) - 1].kind == tbkNick)
|
|
if (oldDragHilite != DragHilite && (!oldDragHilite || (oldDragHilite && (*BD)[GetControlReference(oldDragHilite) - 1].kind != tbkNick)))
|
|
DragTicks = TickCount ();
|
|
else
|
|
if (TickCount () > DragTicks + GetRLong (NICK_BUTTON_DRAG_TICKS))
|
|
MessageDragPopup (cntl, !Vertical);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* ToolbarNudgeAll - nudge all windows
|
|
**********************************************************************/
|
|
void ToolbarNudgeAll(Boolean gently)
|
|
{
|
|
WindowPtr winWP;
|
|
MyWindowPtr win;
|
|
for (winWP=FrontWindow_();winWP;winWP=GetNextWindow(winWP)) {
|
|
win = GetWindowMyWindowPtr (winWP);
|
|
if (win!=Win) ToolbarNudge(win,gently);
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolbarUpdate - update the toolbar; really just sets the bg color
|
|
**********************************************************************/
|
|
void ToolbarUpdate(MyWindowPtr win)
|
|
{
|
|
WindowPtr WinWP;
|
|
short i;
|
|
Str15 numStr;
|
|
ControlHandle cntl;
|
|
ControlHandle root;
|
|
Rect r, rr;
|
|
SAVE_STUFF;
|
|
|
|
TextFont(SmallSysFontID());
|
|
TextSize(9);
|
|
|
|
if (FKeys && PrefIsSet(PREF_SHOW_FKEYS))
|
|
{
|
|
short h,v;
|
|
short bh, bv;
|
|
|
|
bh = bv = 0;
|
|
|
|
TextSize(9);
|
|
TextFace(condense|italic);
|
|
if (ThereIsColor) SetForeGrey(k8Grey7);
|
|
for (i=0;i<N && i<15;i++)
|
|
{
|
|
ComposeRString(numStr,FKEY_FMT,i+1);
|
|
GetControlBounds((*BD)[i].cntl,&r);
|
|
rr = r;
|
|
if (Vertical)
|
|
{
|
|
h = r.right+INSET;
|
|
v = r.bottom-INSET;
|
|
}
|
|
else
|
|
{
|
|
h = r.left+INSET;
|
|
v = r.bottom+10;
|
|
}
|
|
MoveTo(h,v);
|
|
DrawString(numStr);
|
|
}
|
|
}
|
|
REST_STUFF;
|
|
PenNormal();
|
|
|
|
WinWP = GetMyWindowWindowPtr(Win);
|
|
GetRootControl(GetMyWindowWindowPtr(win),&root);
|
|
// Draw dimmed cntls first
|
|
for (cntl=GetControlList(WinWP);cntl;cntl=GetNextControl(cntl))
|
|
if (cntl!=root && !IsControlActive(cntl)) Draw1Control(cntl);
|
|
// Undimmed ones next
|
|
for (cntl=GetControlList(WinWP);cntl;cntl=GetNextControl(cntl))
|
|
if (cntl!=root && IsControlActive(cntl)) Draw1Control(cntl);
|
|
|
|
TBDrawTip();
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void TBDrawTip(void)
|
|
{
|
|
Rect r=Tip;
|
|
if (TipCntl)
|
|
{
|
|
PortSaveStuff old;
|
|
Str255 title;
|
|
//Style style;
|
|
|
|
PushGWorld();
|
|
SetPort_(GetMyWindowCGrafPtr(Win));
|
|
SavePortStuff(&old);
|
|
TextSize(9);
|
|
TextFace(0);
|
|
EraseRect(&r);
|
|
TBGetCTitle(TipCntl,title);
|
|
MoveTo(Tip.left,Tip.bottom-2);
|
|
//if (!GetBevelStyle(TipCntl,&style)) TextFace(style); //seems to be bug in GetControlData for bevels; this isn't working correctly
|
|
DrawString(title);
|
|
SetPortStuff(&old);
|
|
DisposePortStuff(&old);
|
|
PopGWorld();
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void TBTipLo(ControlHandle cntl)
|
|
{
|
|
Rect r = Tip,rCntl;
|
|
Str255 title;
|
|
|
|
// anything to do?
|
|
if (TipCntl==cntl) return;
|
|
if (r.bottom==0) return;
|
|
|
|
PushGWorld();
|
|
SetPort_(GetMyWindowCGrafPtr(Win));
|
|
TB_RESTORE_STUFF;
|
|
|
|
// clear the old one
|
|
if (r.left!=r.right)
|
|
{
|
|
EraseRect(&r);
|
|
InvalWindowRect(GetMyWindowWindowPtr(Win),&r);
|
|
r.left = r.right = 0;
|
|
}
|
|
|
|
// show the new one
|
|
TipCntl = nil;
|
|
if (cntl)
|
|
{
|
|
long controlRef = GetControlReference(cntl)-1;
|
|
if (0<=controlRef && controlRef<N)
|
|
{
|
|
TBGetCTitle(cntl,title);
|
|
if (*title)
|
|
{
|
|
GetControlBounds(cntl,&rCntl);
|
|
r.left = rCntl.left + INSET;
|
|
r.right = r.left + StringWidth(title) + 2;
|
|
r.top = rCntl.bottom;
|
|
r.bottom = r.top+12;
|
|
if (r.right>Win->contR.right) OffsetRect(&r,Win->contR.right-2-r.right,0);
|
|
r.right += 6;
|
|
Tip = r;
|
|
InvalWindowRect(GetMyWindowWindowPtr(Win),&r);
|
|
}
|
|
TipCntl = cntl;
|
|
}
|
|
}
|
|
|
|
UpdateMyWindow(GetMyWindowWindowPtr(Win));
|
|
PopGWorld();
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
PStr TBGetCTitle(ControlHandle cntl,PStr title)
|
|
{
|
|
Str31 menuStr;
|
|
MenuHandle mh;
|
|
ButtonData bd = (*BD)[GetControlReference(cntl)-1];
|
|
short menu;
|
|
|
|
PCopy(title,bd.title);
|
|
if (bd.kind==tbkMenu)
|
|
{
|
|
menu = bd.select>>16;
|
|
if ((IsRecipMenu(menu) || IsStationMenu(menu)) && (mh=GetMHandle(bd.select>>16)))
|
|
{
|
|
GetMenuTitle(mh,menuStr);
|
|
PCatC(menuStr,' ');
|
|
PInsert(title,256,menuStr,title+1);
|
|
}
|
|
}
|
|
return(title);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBInterStice - is a point (local coords) in a toolbar interstice?
|
|
**********************************************************************/
|
|
Boolean TBInterStice(Point pt,short *which)
|
|
{
|
|
short i;
|
|
Boolean found = false;
|
|
short slop = MAX(4,ExPixels/2);
|
|
short hSlop = Vertical ? 0 : slop;
|
|
short vSlop = Vertical ? slop : 0;
|
|
Rect rOuter,rInner;
|
|
|
|
for (i=0;i<N;i++)
|
|
{
|
|
GetControlBounds((*BD)[i].cntl,&rInner);
|
|
rOuter = rInner;
|
|
InsetRect(&rOuter,-hSlop,-vSlop);
|
|
InsetRect(&rInner,hSlop,vSlop);
|
|
if (PtInRect(pt,&rOuter) && !PtInRect(pt,&rInner))
|
|
{
|
|
if (Vertical && pt.v > (rOuter.bottom+rOuter.top)/2) i++;
|
|
if (!Vertical && pt.h > (rOuter.right+rOuter.left)/2) i++;
|
|
*which = i;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return(false);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolbarClose - deallocate memory
|
|
**********************************************************************/
|
|
Boolean ToolbarClose(MyWindowPtr win)
|
|
{
|
|
#pragma unused(win)
|
|
short i, n;
|
|
|
|
if (Dirty) SaveToolbar();
|
|
|
|
if (BD)
|
|
{
|
|
n = HandleCount(BD);
|
|
for (i=1;i<=n;i++) TBButtonClose(i);
|
|
}
|
|
DisposeHandle((Handle)GetMyWindowPrivateData(Win));
|
|
SetMyWindowPrivateData(Win,0);
|
|
Win = nil;
|
|
return(True);
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void SaveToolbar(void)
|
|
{
|
|
Handle r = nil;
|
|
ButtonData bd;
|
|
Str255 s;
|
|
short i;
|
|
short n = HandleCount(BD);
|
|
|
|
UseResFile(SettingsRefN);
|
|
|
|
ZapSettingsResource('STR#',ToolbarStrnID);
|
|
|
|
if (r = NuHTempOK(2))
|
|
{
|
|
**(short**)r = 0;
|
|
AddMyResource(r,'STR#',ToolbarStrnID,"");
|
|
}
|
|
else return;
|
|
|
|
for (i=0;i<n;i++)
|
|
{
|
|
bd = (*BD)[i];
|
|
TBButton2String(&bd,s);
|
|
ChangeStrn(ToolbarStrnID,i+1,s);
|
|
}
|
|
|
|
Dirty = False;
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void TBButton2String(ButtonData *bd, PStr s)
|
|
{
|
|
MenuHandle mh;
|
|
Str255 menuStr, itemStr;
|
|
TBAliasData tbd;
|
|
Str63 mods;
|
|
short menu, item;
|
|
short cookedMods;
|
|
FSSpec spec, junk;
|
|
Str255 title;
|
|
|
|
*s = 0;
|
|
switch(bd->kind)
|
|
{
|
|
case tbkMenu:
|
|
PCopy(title,bd->title);
|
|
|
|
// Save the entire pathname for mailboxes
|
|
TBExtractMenu(bd,&menu,&item);
|
|
if (IsMailboxChoice(menu,item) && menu!=MAILBOX_MENU && menu!=TRANSFER_MENU)
|
|
{
|
|
GetTransferParams(menu,item,&spec,nil);
|
|
// I don't understand why the following was done:
|
|
// if (IsIMAPMailboxFile(&spec)) spec.parID = SpecDirId(&spec);
|
|
// sd 3/10/03
|
|
|
|
// grab its full path name, unless we're dealing with a grafted mailbox.
|
|
if (!IsAlias(&spec,&junk)) Box2Path(&spec, title);
|
|
}
|
|
|
|
menu = (bd->select>>16)&0xffff;
|
|
item = (bd->select)&0xffff;
|
|
if (mh=GetMHandle(menu))
|
|
{
|
|
if (menu==LABEL_HIER_MENU)
|
|
NumToString(Menu2Label(item),itemStr);
|
|
else
|
|
PCopy(itemStr,title);
|
|
cookedMods = bd->modifiers;
|
|
if (menu==MESSAGE_MENU && item==MESSAGE_REPLY_ITEM) cookedMods &= ~optionKey;
|
|
ModifierNames(mods,cookedMods);
|
|
if (*itemStr > *mods && !CompareText(mods+1,itemStr+1,*mods,*mods,nil))
|
|
{
|
|
*itemStr -= *mods;
|
|
BMD(itemStr+1+*mods,itemStr+1,*itemStr);
|
|
}
|
|
GetMenuTitle(mh,menuStr);
|
|
ComposeRString(s,TB_FMT,bd->modifiers,TBButtonStrn+bd->kind,menuStr,itemStr);
|
|
}
|
|
break;
|
|
|
|
case tbkKey:
|
|
NumToString(bd->select,itemStr);
|
|
ComposeRString(s,TB_FMT,bd->modifiers,TBButtonStrn+bd->kind,itemStr,"");
|
|
break;
|
|
|
|
case tbkFile:
|
|
tbd = **(TBAliasHandle)bd->data;
|
|
NumToString(tbd.id,menuStr);
|
|
PCopy(itemStr,bd->title);
|
|
PCatC(itemStr,':');
|
|
*itemStr += 8;
|
|
BMD(&tbd.type,itemStr+*itemStr-7,4);
|
|
BMD(&tbd.creator,itemStr+*itemStr-3,4);
|
|
ComposeRString(s,TB_FMT,bd->modifiers,TBButtonStrn+bd->kind,menuStr,itemStr);
|
|
break;
|
|
|
|
case tbkAd:
|
|
NumToString(bd->select,itemStr);
|
|
ComposeRString(s,TB_FMT,bd->modifiers,TBButtonStrn+bd->kind,itemStr,bd->title);
|
|
break;
|
|
|
|
case tbkNick:
|
|
ComposeRString(s,TB_FMT,bd->modifiers,TBButtonStrn+bd->kind,bd->title,"");
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolClick - handle a click in the toolbar
|
|
**********************************************************************/
|
|
void ToolClick(MyWindowPtr win, EventRecord *event)
|
|
{
|
|
WindowPtr winWP = GetMyWindowWindowPtr(win);
|
|
Point pt = event->where;
|
|
short which;
|
|
Boolean did;
|
|
|
|
// Don't allow command clicks in light
|
|
if (!HasFeature (featureCustomizeToolbar) && event->modifiers&cmdKey)
|
|
return;
|
|
|
|
UseFeature (featureCustomizeToolbar);
|
|
|
|
SetPort_(GetMyWindowCGrafPtr(Win));
|
|
TB_RESTORE_STUFF;
|
|
GlobalToLocal(&pt);
|
|
|
|
LastIdleRunTicks = 0;
|
|
TBIdle(nil);
|
|
if (event->modifiers&cmdKey && TBInterStice(pt,&which))
|
|
{
|
|
while (WaitMouseUp()) {WNE(0,nil,0);}
|
|
GetMouse(&pt);
|
|
if (TBInterStice(pt,&which))
|
|
{
|
|
TBNewButton(which);
|
|
Deleted = false;
|
|
did = ConfigureTBButton(which+1);
|
|
if (!Deleted && !did)
|
|
TBDelButton((*BD)[which].cntl);
|
|
|
|
AuditHit((event->modifiers&shiftKey)!=0, (event->modifiers&controlKey)!=0, (event->modifiers&optionKey)!=0, (event->modifiers&cmdKey)!=0, false, GetWindowKind(winWP), AUDITCONTROLID(GetWindowKind(winWP),which), event->what);
|
|
}
|
|
}
|
|
else if ((event->modifiers&(cmdKey+optionKey))==cmdKey+optionKey)
|
|
{
|
|
// Drag toolbar
|
|
DragMyWindow(winWP,event->where);
|
|
}
|
|
else if (SearchPTE && PtInPETE(pt,SearchPTE))
|
|
{
|
|
// Focus in the search field if we haven't already
|
|
if (!Win->pte)
|
|
{
|
|
TBSearchFocus(true);
|
|
}
|
|
else
|
|
PeteEditWFocus (Win, SearchPTE, peeEvent, (void *) event, nil);
|
|
|
|
}
|
|
else
|
|
{
|
|
if (SearchPopup && PtInControl(pt,SearchPopup))
|
|
{
|
|
if (!(event->modifiers&cmdKey)) TBSearchPopup(pt);
|
|
}
|
|
else if (SearchGo && PtInControl(pt,SearchGo) && (event->modifiers&cmdKey))
|
|
;// ignore
|
|
else
|
|
{
|
|
if (event->modifiers&cmdKey)
|
|
{
|
|
ForceEnable = True;
|
|
LastIdleRunTicks = 0;
|
|
TBIdle(nil);
|
|
ForceEnable = False;
|
|
}
|
|
ToolControl(pt,Win);
|
|
}
|
|
}
|
|
}
|
|
|
|
Boolean ToolDrag(ControlHandle theCtl, EventRecord *event)
|
|
{
|
|
DragReference drag;
|
|
ButtonData bd;
|
|
Str255 s;
|
|
RgnHandle rgn;
|
|
Rect r;
|
|
Boolean result = False;
|
|
|
|
if (!Ignore && MyWaitMouseMoved(event->where,True))
|
|
{
|
|
Ignore = True;
|
|
|
|
/*
|
|
* allow the item to be dragged
|
|
*/
|
|
if (MyNewDrag(Win,&drag)) return(False);
|
|
|
|
/*
|
|
* the flavor is toolbar button
|
|
*/
|
|
bd = (*BD)[GetControlReference(theCtl)-1];
|
|
TBButton2String(&bd,s);
|
|
AddDragItemFlavor(drag, 1, TBAR_DRAG_FLAVOR, s, *s+1, 0);
|
|
|
|
BeingDragged = theCtl;
|
|
DroppedOnMe = False;
|
|
/*
|
|
* build the region
|
|
*/
|
|
if (rgn = NewRgn())
|
|
{
|
|
GetControlBounds(theCtl,&r);
|
|
RectRgn(rgn,&r);
|
|
InsetRect(&r,1,1);
|
|
RgnMinusRect(rgn,&r);
|
|
GlobalizeRgn(rgn);
|
|
GetRegionBounds(rgn,&r); SetDragItemBounds(drag, 1, &r);
|
|
if (!MyTrackDrag(drag,event,rgn))
|
|
{
|
|
/*
|
|
* drag accepted
|
|
*/
|
|
if (!(MainEvent.modifiers&optionKey) && !(CurrentModifiers()&optionKey))
|
|
result = (DroppedOnMe || DragTargetWasTrash(drag));
|
|
}
|
|
DisposeRgn(rgn);
|
|
}
|
|
MyDisposeDrag(drag);
|
|
BeingDragged = nil;
|
|
}
|
|
return(result);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolControl - handle controls in the toolbar
|
|
**********************************************************************/
|
|
Boolean ToolControl(Point pt, MyWindowPtr win)
|
|
{
|
|
WindowPtr winWP = GetMyWindowWindowPtr (win);
|
|
ControlHandle cntl;
|
|
short part;
|
|
EventRecord event;
|
|
|
|
Deleted = False;
|
|
if (part = FindControl(pt,winWP,&cntl))
|
|
{
|
|
DownTicks = TickCount();
|
|
Ignore = False;
|
|
|
|
event = MainEvent;
|
|
HiliteControl(cntl,1);
|
|
if (HasFeature (featureCustomizeToolbar) && event.modifiers&cmdKey && ToolDrag(cntl,&event))
|
|
{
|
|
UseFeature (featureCustomizeToolbar);
|
|
TBDelButton(cntl);
|
|
}
|
|
else
|
|
{
|
|
part = TrackControl(cntl,pt,nil);
|
|
HiliteControl(cntl,1);
|
|
if (!Ignore && part) (*win->button)(win,cntl,event.modifiers,part);
|
|
}
|
|
if (!Deleted) HiliteControl(cntl,0);
|
|
|
|
AuditHit((event.modifiers&shiftKey)!=0, (event.modifiers&controlKey)!=0, (event.modifiers&optionKey)!=0, (event.modifiers&cmdKey)!=0, false, GetWindowKind(winWP), AUDITCONTROLID(GetWindowKind(winWP),GetControlReference(cntl)), event.what);
|
|
return(True);
|
|
}
|
|
return(False);
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
OSErr TBNewButton(short which)
|
|
{
|
|
WindowPtr WinWP = GetMyWindowWindowPtr (Win);
|
|
ButtonData bd;
|
|
OSErr err;
|
|
short n = HandleCount(BD);
|
|
ControlHandle button = GetNewControl(TB_CNTL,WinWP);
|
|
short i;
|
|
|
|
|
|
Zero(bd);
|
|
if (!button) err = MemError();
|
|
else err=PtrPlusHand_(&bd,BD,sizeof(bd));
|
|
|
|
if (err) WarnUser(MEM_ERR,err);
|
|
else
|
|
{
|
|
TBSetButtonType(button);
|
|
for (i=n;i>which;i--) (*BD)[i] = (*BD)[i-1];
|
|
bd.cntl = button;
|
|
(*BD)[which] = bd;
|
|
Dirty = True;
|
|
if (button)
|
|
{
|
|
(*BD)[which].cntl = button;
|
|
for (i=0;i<=n;i++)
|
|
if ((*BD)[i].cntl) SetControlReference((*BD)[i].cntl,i+1);
|
|
SizeToolbar(n+1);
|
|
UpdateMyWindow(WinWP);
|
|
}
|
|
}
|
|
return(err);
|
|
}
|
|
|
|
/************************************************************************
|
|
* TBSetButtonType - set the appropriate uglification button type
|
|
************************************************************************/
|
|
OSErr TBSetButtonType(ControlHandle button)
|
|
{
|
|
ControlButtonContentInfo ci;
|
|
OSErr err;
|
|
|
|
// set font and size while we're at it
|
|
SetBevelFontSize(button,SmallSysFontID(),GetRLong(TB_BUTTON_FONT_SIZE));
|
|
|
|
// now set the type
|
|
Zero(ci);
|
|
ci.contentType = !VarHasIcon(VarCode) ? kControlContentTextOnly : kControlContentIconSuiteRes;
|
|
err = SetControlData(button,0,kControlBevelButtonContentTag,sizeof(ci),(void*)&ci);
|
|
|
|
ShowControl(button);
|
|
return(err);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void FlipToolbar(void)
|
|
{
|
|
VarCode++;
|
|
if (VarCode==tbvLimit)
|
|
{
|
|
VarCode = 1;
|
|
Vertical = !Vertical;
|
|
}
|
|
SizeToolbar(CountStrn(ToolbarStrnID));
|
|
UpdateMyWindow(GetMyWindowWindowPtr(Win));
|
|
ToolbarNudgeAll(true);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolbarRect - Rect of the toolbar
|
|
**********************************************************************/
|
|
void ToolbarRect(Rect *r)
|
|
{
|
|
if (Win)
|
|
{
|
|
*r = StrucRect;
|
|
if(!EmptyRect(r)) InsetRect(r,-1,-1);
|
|
}
|
|
else SetRect(r,-REAL_BIG,-REAL_BIG,-REAL_BIG,-REAL_BIG);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolbarNudge - nudge a window out of the way of any docked windows
|
|
**********************************************************************/
|
|
Boolean ToolbarNudge(MyWindowPtr win,Boolean gently)
|
|
{
|
|
WindowPtr winWP = GetMyWindowWindowPtr (win);
|
|
Rect newRect;
|
|
Point corner;
|
|
Boolean intersects;
|
|
|
|
#ifdef FLOAT_WIN
|
|
if (IsFloating(winWP)) return (false);
|
|
#endif //FLOAT_WIN
|
|
|
|
if (intersects=ToolbarNudgeRect(win, &newRect, gently))
|
|
{
|
|
SetPort_(GetWindowPort(winWP));
|
|
corner.h=newRect.left;
|
|
corner.v=newRect.top;
|
|
LocalToGlobal(&corner);
|
|
MoveWindow(winWP,corner.h,corner.v,False);
|
|
}
|
|
return(intersects);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* ToolbarNudgeRect - nudge a rect out of the way of any docked windows
|
|
**********************************************************************/
|
|
Boolean ToolbarNudgeRect(MyWindowPtr win, Rect *newRect, Boolean gently)
|
|
{
|
|
WindowPtr winWP = GetMyWindowWindowPtr(win);
|
|
Rect bounds;
|
|
Rect intersect;
|
|
Rect winRect;
|
|
Point corner;
|
|
MyWindowPtr dockWin;
|
|
WindowPtr dockWinWP;
|
|
Boolean nudged = false;
|
|
Rect testRect;
|
|
|
|
GetStructureRgnBounds(winWP,&winRect);
|
|
|
|
// "Gently" means we'll only move windows whose title bars are completely covered
|
|
if (gently)
|
|
{
|
|
RgnHandle rgn = NewRgn();
|
|
if (rgn)
|
|
{
|
|
if (GetWindowRegion)
|
|
if (!GetWindowRegion(winWP,kWindowTitleBarRgn,rgn))
|
|
if (!EmptyRgn(rgn))
|
|
GetRegionBounds(rgn,&testRect);
|
|
DisposeRgn(rgn);
|
|
}
|
|
}
|
|
|
|
|
|
GetPortBounds(GetWindowPort(winWP),newRect);
|
|
for (dockWinWP=FrontWindow();dockWinWP;dockWinWP=GetNextWindow(dockWinWP))
|
|
{
|
|
dockWin = GetWindowMyWindowPtr (dockWinWP);
|
|
if (IsKnownWindowMyWindow(dockWinWP) && dockWin->windowType == kDockable && IsWindowVisible(dockWinWP))
|
|
{
|
|
GetStructureRgnBounds(dockWinWP,&bounds);
|
|
|
|
// For gentle motion, check for only completely covered title bars
|
|
if (gently)
|
|
{
|
|
SectRect(&bounds,&testRect,&intersect);
|
|
if (!AboutSameRect(&intersect,&testRect)) continue; // ignore
|
|
}
|
|
|
|
// Either title bar is covered, or we're being rough
|
|
if (SectRect(&bounds,&winRect,&intersect))
|
|
{
|
|
short overlapTop, overlapBottom, overlapLeft, overlapRight, overlapHi, overlapWi;
|
|
corner.h = corner.v = 0;
|
|
|
|
// The first order of business is to figure out exactly how we're overlapping
|
|
overlapBottom = intersect.top == bounds.top ? RectHi(intersect) : 0;
|
|
overlapTop = intersect.bottom == bounds.bottom ? RectHi(intersect) : 0;
|
|
overlapRight = intersect.left == bounds.left ? RectWi(intersect) : 0;
|
|
overlapLeft = intersect.right == bounds.right ? RectWi(intersect) : 0;
|
|
overlapHi = MAX(overlapTop,overlapBottom);
|
|
overlapWi = MAX(overlapLeft,overlapRight);
|
|
|
|
// We'll move the window the least we can
|
|
if (overlapHi && (!overlapWi || overlapHi < overlapWi))
|
|
{
|
|
if (overlapTop) corner.v = overlapTop;
|
|
else corner.v = - overlapBottom;
|
|
}
|
|
else if (overlapWi)
|
|
{
|
|
if (overlapLeft) corner.h = overlapLeft;
|
|
else corner.h = -overlapRight;
|
|
}
|
|
|
|
OffsetRect(newRect, corner.h, corner.v);
|
|
nudged = true;
|
|
}
|
|
}
|
|
}
|
|
return nudged;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolbarSect - does a rectangle overlap the toolbar?
|
|
**********************************************************************/
|
|
Boolean ToolbarSect(Rect *r)
|
|
{
|
|
Rect tb, sect;
|
|
if (Win)
|
|
{
|
|
ToolbarRect(&tb);
|
|
return (SectRect(&tb,r,§));
|
|
}
|
|
else return(False);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolbarReduce - reduce a rectangle to fit the toolbar
|
|
**********************************************************************/
|
|
void ToolbarReduce(Rect *r)
|
|
{
|
|
if (Win)
|
|
{
|
|
Rect tb;
|
|
ToolbarRect(&tb);
|
|
if (Vertical) r->left += RectWi(tb);
|
|
else r->top += RectHi(tb);
|
|
}
|
|
}
|
|
|
|
#pragma segment ToolbarMain
|
|
|
|
#ifdef TASK_PROGRESS_ON
|
|
/**********************************************************************
|
|
* ToolbarIdleControls
|
|
**********************************************************************/
|
|
void ToolbarIdleControls(void)
|
|
{
|
|
WindowPtr WinWP = GetMyWindowWindowPtr (Win);
|
|
|
|
if (WinWP && TaskProgButton && IsWindowVisible(WinWP) && TickCount()-IdleTicks>20)
|
|
{
|
|
PushGWorld();
|
|
SetPort_(GetWindowPort(WinWP));
|
|
TaskProgAnimate(TaskProgButton);
|
|
PopGWorld();
|
|
IdleTicks=TickCount();
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolbarUserPaneIdle
|
|
**********************************************************************/
|
|
#define NUM_TP_ICONS (TASK_PROGRESS5_ICON - TASK_PROGRESS_ICON + 1)
|
|
|
|
static void TaskProgAnimate(ControlRef control)
|
|
{
|
|
short id;
|
|
static short frame=0;
|
|
static unsigned long lastTick=0;
|
|
|
|
if (NewError)
|
|
{
|
|
if (TickCount() - lastTick < 60)
|
|
return;
|
|
id = frame ? TASK_PROGRESS_ERROR_ICON : TASK_PROGRESS_ICON;
|
|
if (frame++)
|
|
frame=0;
|
|
}
|
|
else
|
|
{
|
|
// if (TickCount() - lastTick < 12)
|
|
// return;
|
|
if (!(CheckThreadRunning || SendThreadRunning))
|
|
{
|
|
if (frame == 1)
|
|
return;
|
|
}
|
|
id = TASK_PROGRESS_ICON + frame;
|
|
if (++frame >= (NUM_TP_ICONS - 1))
|
|
frame = 0;
|
|
}
|
|
lastTick = TickCount();
|
|
|
|
SetBevelIcon(control,id,0,0,nil);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* IsTPIdleControlVisible
|
|
**********************************************************************/
|
|
Boolean IsTPIdleControlVisible(void)
|
|
{
|
|
return Win && VarHasIcon(VarCode) && TaskProgButton != nil;
|
|
}
|
|
#endif
|
|
|
|
/**********************************************************************
|
|
* ToolbarCursor - set the cursor for the toolbar
|
|
**********************************************************************/
|
|
void ToolbarCursor(Point mouse)
|
|
{
|
|
WindowPtr WinWP = GetMyWindowWindowPtr (Win);
|
|
ControlHandle cntl;
|
|
Rect r;
|
|
short which;
|
|
static long firstTicks;
|
|
|
|
LocalToGlobal(&mouse);
|
|
|
|
if (PtInRgn(mouse,MyGetWindowContentRegion(WinWP)))
|
|
{
|
|
PushGWorld();
|
|
SetPort_(GetWindowPort(WinWP));
|
|
TBIdle(nil);
|
|
GlobalToLocal(&mouse);
|
|
if (HasFeature (featureCustomizeToolbar) && CurrentModifiers()&cmdKey && TBInterStice(mouse,&which))
|
|
{
|
|
TBTip(nil);
|
|
SetMyCursor(Vertical ? SPREAD_CURS_V : SPREAD_CURS);
|
|
}
|
|
else if (PeteCursorList(Win->pteList,mouse))
|
|
;
|
|
else if (FindControl(mouse,WinWP,&cntl))
|
|
{
|
|
SetMyCursor(arrowCursor);
|
|
GetControlBounds(cntl,&r);
|
|
TBTip(cntl);
|
|
}
|
|
else
|
|
{
|
|
TBTip(nil);
|
|
SetRect(&r,mouse.h,mouse.v,mouse.h+1,mouse.v+1);
|
|
SetMyCursor(arrowCursor);
|
|
}
|
|
PopGWorld();
|
|
}
|
|
else
|
|
{
|
|
SetMyCursor(arrowCursor);
|
|
PushGWorld();
|
|
SetPort_(GetWindowPort(WinWP));
|
|
TBTip(nil);
|
|
PopGWorld();
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void ShowToolbar(void)
|
|
{
|
|
WindowPtr WinWP = GetMyWindowWindowPtr (Win);
|
|
|
|
if (WinWP && !IsWindowVisible(WinWP))
|
|
{
|
|
//DebugStr("\pShowToolbar;sc");
|
|
TBIdle(nil);
|
|
ShowHide(WinWP,true);
|
|
StashStructure(Win);
|
|
GetStructureRgnBounds(WinWP,&StrucRect);
|
|
TBTip(nil);
|
|
}
|
|
}
|
|
|
|
void HideToolbar(void)
|
|
{
|
|
WindowPtr WinWP = GetMyWindowWindowPtr (Win);
|
|
|
|
if (WinWP && IsWindowVisible(WinWP))
|
|
{
|
|
//DebugStr("\pHideToolbar;sc");
|
|
StashStructure(Win);
|
|
ShowHide(WinWP,false);
|
|
//TBTip(nil);
|
|
}
|
|
}
|
|
void ToolbarBack(void)
|
|
{
|
|
// if (Win && GetNextWindow(GetMyWindowWindowPtr(Win)))
|
|
// SendBehind(GetMyWindowWindowPtr(Win),nil);
|
|
}
|
|
|
|
Boolean ToolbarShowing(void) {return(Win!=nil);}
|
|
/**********************************************************************
|
|
* TBEventFilter - filter events to see if the toolbar is interested
|
|
**********************************************************************/
|
|
Boolean TBEventFilter(EventRecord *event,Boolean oldResult)
|
|
{
|
|
if (Win)
|
|
{
|
|
OldDrag = (DragReference)-1;
|
|
if (!InBG)
|
|
if (event->what==activateEvt)
|
|
TBSearchFocus(false);
|
|
else if (event->what==mouseDown)
|
|
{
|
|
WindowPtr winWP;
|
|
short wPart = FindWindow_(event->where,&winWP);
|
|
MyWindowPtr win = GetWindowMyWindowPtr (winWP);
|
|
if (win && win!=Win) TBSearchFocus(false);
|
|
}
|
|
else
|
|
{
|
|
if (event->what==keyDown)
|
|
if (!(event->modifiers&cmdKey))
|
|
if (!ModalWindow)
|
|
if (!DragFxxkOff)
|
|
{
|
|
short b;
|
|
Byte k;
|
|
Byte c = event->message&charCodeMask;
|
|
|
|
if ((c==returnChar || c==enterChar) && Win->pte)
|
|
{
|
|
// hit return with focus in the search field
|
|
// start search
|
|
TBSearchStart(nil);
|
|
event->what = nullEvent;
|
|
}
|
|
else if (FKeys)
|
|
{
|
|
k = (event->message&keyCodeMask)>>8;
|
|
for (b=0;b<N && b<15;b++)
|
|
if (FunctionKeys[b]==k)
|
|
{
|
|
TBIdle(nil);
|
|
if (IsControlActive((*BD)[b].cntl))
|
|
{
|
|
HiliteControl((*BD)[b].cntl,1);
|
|
ToolbarButton(Win,(*BD)[b].cntl,event->modifiers,1);
|
|
HiliteControl((*BD)[b].cntl,0);
|
|
}
|
|
else SysBeep(20L);
|
|
event->what = nullEvent;
|
|
return(False);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return(oldResult);
|
|
}
|
|
|
|
/************************************************************************
|
|
* TBDisable - turn off the toolbar completely
|
|
************************************************************************/
|
|
void TBDisable(void)
|
|
{
|
|
WindowPtr WinWP = GetMyWindowWindowPtr (Win);
|
|
ControlHandle cntl;
|
|
|
|
if (ToolbarShowing())
|
|
{
|
|
PushGWorld();
|
|
SetPort_(GetWindowPort(WinWP));
|
|
GetRootControl(WinWP,&cntl);
|
|
DeactivateControl(cntl);
|
|
PopGWorld();
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
Boolean ToolbarMenu(MyWindowPtr win, int menu, int item, short modifiers)
|
|
{
|
|
#pragma unused(win,modifiers)
|
|
if (menu==FILE_MENU && item==FILE_SAVE_ITEM)
|
|
{
|
|
if (Dirty) SaveToolbar();
|
|
return(True);
|
|
}
|
|
else return(False);
|
|
}
|
|
#pragma segment Toolbar
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void TBDelButton(ControlHandle cntl)
|
|
{
|
|
short which = GetControlReference(cntl);
|
|
short n = HandleCount(BD);
|
|
short i;
|
|
|
|
TBZapButtonData(which);
|
|
if (which<n)
|
|
{
|
|
BMD(&(*BD)[which],&(*BD)[which-1],sizeof(**BD)*(n-which));
|
|
for (i=which;i<n;i++) SetControlReference((*BD)[i-1].cntl,i);
|
|
}
|
|
SetHandleSize((Handle)BD,GetHandleSize((Handle)BD)-sizeof(**BD));
|
|
Dirty = True;
|
|
Deleted = True;
|
|
DisposeControl(cntl);
|
|
if (cntl == TaskProgButton)
|
|
TaskProgButton = nil;
|
|
SizeToolbar(n-1);
|
|
TipCntl = LastCntl = nil;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBRemoveDefunctMenuButton - remove a button referring to a menu item
|
|
* we no longer have
|
|
**********************************************************************/
|
|
OSErr TBRemoveDefunctMenuButton(short menu,short item)
|
|
{
|
|
short i;
|
|
ButtonData bd;
|
|
|
|
for (i=0;i<N;i++)
|
|
{
|
|
bd = (*BD)[i];
|
|
if (bd.kind == tbkMenu && (bd.select>>16L)==menu && ((unsigned short)bd.select)==item)
|
|
{
|
|
TBDelButton(bd.cntl);
|
|
i--; //reexamine buttons
|
|
}
|
|
}
|
|
return noErr; /* nothing to return here */
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBRemoveDefunctNicknameButton - remove a button referring to a nickname
|
|
* we no longer have
|
|
**********************************************************************/
|
|
void TBRemoveDefunctNicknameButton(PStr nickname)
|
|
{
|
|
ButtonData bd;
|
|
short i;
|
|
|
|
if (Win)
|
|
for (i = 0;i < N; i++) {
|
|
bd = (*BD)[i];
|
|
if (bd.kind == tbkNick && StringSame (bd.title, nickname)) {
|
|
TBDelButton (bd.cntl);
|
|
i--; //reexamine buttons
|
|
}
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* LoadToolbarButton - load buttons in the toolbar
|
|
**********************************************************************/
|
|
OSErr LoadToolbarButton(short i)
|
|
{
|
|
Str255 s;
|
|
return(LoadButtonString(i,GetRString(s,ToolbarStrnID+i)));
|
|
}
|
|
|
|
/**********************************************************************
|
|
* LoadButtonString - load a string into a button
|
|
**********************************************************************/
|
|
OSErr LoadButtonString(short i,PStr s)
|
|
{
|
|
Str255 menuStr, itemStr;
|
|
Str31 pfix;
|
|
short menu, item;
|
|
UPtr spot;
|
|
FSSpec spec;
|
|
void *dataPtr = nil;
|
|
long size;
|
|
Boolean wasXfer;
|
|
short modifiers;
|
|
long key;
|
|
Boolean mailbox;
|
|
ControlHandle button = (*BD)[i-1].cntl;
|
|
OSType type, creator;
|
|
Str255 scratch;
|
|
|
|
if (button)
|
|
{
|
|
TBSetCTitle(button,"");
|
|
spot = s+1;
|
|
if (PToken(s,menuStr,&spot,":"))
|
|
{
|
|
StringToNum(menuStr,&key);
|
|
modifiers = key;
|
|
if (PToken(s,menuStr,&spot,":"))
|
|
{
|
|
TBButtonEnum buttonKind = FindSTRNIndex(TBButtonStrn,menuStr);
|
|
if (buttonKind==tbkMenu)
|
|
{
|
|
if (PToken(s,menuStr,&spot,":") &&
|
|
PToken(s,itemStr,&spot,"\377"))
|
|
{
|
|
if (menu=FindMenuByName(menuStr))
|
|
{
|
|
if (menu==FILE_MENU && HaveTheDiseaseCalledOSX() && EqualStrRes(itemStr,FILE_QUIT_ITEM_STR))
|
|
{
|
|
item = FILE_QUIT_ITEM;
|
|
}
|
|
else
|
|
{
|
|
SetMenuTexts(modifiers,True);
|
|
item = 0;
|
|
|
|
PCopy(scratch,itemStr);
|
|
PSCat(scratch,"\p<I");
|
|
|
|
if (mailbox = ((menu==MAILBOX_MENU||menu==TRANSFER_MENU) &&
|
|
!EqualStrRes(scratch,NEW_ITEM_TEXT) &&
|
|
!EqualStrRes(scratch,OTHER_ITEM_TEXT)))
|
|
{
|
|
if (wasXfer = (menu==TRANSFER_MENU))
|
|
{
|
|
menu==MAILBOX_MENU;
|
|
TrimPrefix(itemStr,GetRString(pfix,TRANSFER_PREFIX));
|
|
}
|
|
|
|
if (EqualStrRes(itemStr,FILE_ALIAS_IN)) GetRString(scratch,IN);
|
|
else if (EqualStrRes(itemStr,FILE_ALIAS_OUT)) GetRString(scratch,OUT);
|
|
else if (EqualStrRes(itemStr,FILE_ALIAS_JUNK)) GetRString(scratch,JUNK);
|
|
else if (EqualStrRes(itemStr,FILE_ALIAS_TRASH)) GetRString(scratch,TRASH);
|
|
else PCopy(scratch,itemStr);
|
|
|
|
if (!BoxSpecByName(&spec,scratch))
|
|
{
|
|
dataPtr = &spec;
|
|
size = sizeof(FSSpec);
|
|
|
|
// Display only the mailbox name in the toolbar.
|
|
Zero(scratch);
|
|
BMD(itemStr+1, scratch, itemStr[0]);
|
|
PathToMailboxName (scratch, itemStr, ':');
|
|
|
|
PCopy(scratch,itemStr);
|
|
if (wasXfer) PCopy(itemStr,pfix);
|
|
else *itemStr = 0;
|
|
PCat(itemStr,scratch);
|
|
}
|
|
else menu=0;
|
|
}
|
|
}
|
|
if (TBSpecialStr(menu,itemStr,&item,&modifiers) ||
|
|
TBMovedMenu(&menu,itemStr,&item) ||
|
|
GetMHandle(menu) && (mailbox || (item=FindItemByName(GetMHandle(menu),itemStr))))
|
|
{
|
|
InstallButtonMenu(i,menu,item,itemStr,modifiers,dataPtr,size);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (buttonKind==tbkKey)
|
|
{
|
|
if (PToken(s,menuStr,&spot,":"))
|
|
{
|
|
StringToNum(menuStr,&key);
|
|
InstallButtonKey(i,key,modifiers);
|
|
}
|
|
}
|
|
else if (buttonKind==tbkFile)
|
|
{
|
|
if (PToken(s,menuStr,&spot,":"))
|
|
if (PToken(s,itemStr,&spot,":"))
|
|
{
|
|
StringToNum(menuStr,&key);
|
|
BMD(spot,&type,4);
|
|
BMD(spot+4,&creator,4);
|
|
InstallButtonAliasId(i,key,type,creator,itemStr);
|
|
}
|
|
}
|
|
else if (buttonKind==tbkAd)
|
|
{
|
|
TBAdInfo adInfo;
|
|
|
|
if (PToken(s,menuStr,&spot,":"))
|
|
if (PToken(s,adInfo.title,&spot,":"))
|
|
{
|
|
adInfo.adId.server = modifiers;
|
|
StringToNum(menuStr,&adInfo.adId.ad);
|
|
adInfo.deleted = false;
|
|
adInfo.iconSuite = AdGetTBIcon(adInfo.adId);
|
|
InstallButtonAd(i,&adInfo);
|
|
}
|
|
}
|
|
else if (buttonKind==tbkNick)
|
|
{
|
|
if (PToken(s,menuStr,&spot,":"))
|
|
InstallButtonNickname(i, menuStr);
|
|
}
|
|
}
|
|
}
|
|
HiliteControl(button,255);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void InstallButtonAliasId(short which,short id,OSType type,OSType creator,PStr name)
|
|
{
|
|
ButtonData bd;
|
|
TBAliasData tbd;
|
|
|
|
TBZapButtonData(which);
|
|
bd = (*BD)[which-1];
|
|
bd.kind = tbkFile;
|
|
bd.modifiers = 0;
|
|
tbd.id = id;
|
|
tbd.type = type;
|
|
tbd.creator = creator;
|
|
if (bd.data = NuHandle(sizeof(tbd)))
|
|
**(TBAliasHandle)bd.data = tbd;
|
|
if (VarHasIcon(VarCode))
|
|
if (type=='fdrp')
|
|
SetBevelIcon(bd.cntl,kGenericFolderIconResource,nil,nil,nil);
|
|
else
|
|
SetBevelIcon(bd.cntl,nil,type,creator,nil);
|
|
(*BD)[which-1] = bd;
|
|
TBSetCTitle(bd.cntl,name);
|
|
if (TaskProgButton==bd.cntl) TaskProgButton = nil;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBSpecialStr - fix up some menu items that vary with preferences
|
|
**********************************************************************/
|
|
Boolean TBSpecialStr(short menu,PStr itemStr,short *item,short *modifiers)
|
|
{
|
|
Str63 searchWebStr;
|
|
|
|
if (menu==FILE_MENU && EqualStrRes(itemStr,CHECK_MAIL))
|
|
*item = FILE_CHECK_ITEM;
|
|
else if (menu==EDIT_MENU && EqualStrRes(itemStr,UNDO))
|
|
*item = EDIT_UNDO_ITEM;
|
|
else if (menu==FIND_HIER_MENU && StringSame(itemStr,ComposeRString(searchWebStr,SEARCH_NOTHING_FMT,SEARCH_FOR_WEB)))
|
|
*item = FIND_SEARCH_WEB_ITEM;
|
|
else if (menu==MESSAGE_MENU && (EqualStrRes(itemStr,REPLY)||EqualStrRes(itemStr,REPLY_ALL)))
|
|
{
|
|
*item = MESSAGE_REPLY_ITEM;
|
|
if ((0==EqualStrRes(itemStr,REPLY_ALL)) != (0==PrefIsSet(PREF_REPLY_ALL)))
|
|
*modifiers |= optionKey;
|
|
else
|
|
*modifiers &= ~optionKey;
|
|
}
|
|
else if (menu==MESSAGE_MENU &&
|
|
(EqualStrRes(itemStr,QUEUE_M_ITEM)||EqualStrRes(itemStr,SEND_M_ITEM)||
|
|
EqualStrRes(itemStr,OLD_QUEUE_M_ITEM)||EqualStrRes(itemStr,OLD_SEND_M_ITEM)))
|
|
{
|
|
*item = MESSAGE_QUEUE_ITEM;
|
|
if ((0==EqualStrRes(itemStr,SEND_M_ITEM)) != (0==PrefIsSet(PREF_AUTO_SEND)))
|
|
*modifiers |= optionKey;
|
|
else
|
|
*modifiers &= ~optionKey;
|
|
}
|
|
else if (menu==LABEL_HIER_MENU && AllDigits(itemStr+1,*itemStr) && *itemStr<3)
|
|
{
|
|
long label;
|
|
StringToNum(itemStr,&label);
|
|
*item = Label2Menu(label);
|
|
MyGetItem(GetMHandle(menu),*item,itemStr);
|
|
return true;
|
|
}
|
|
#ifdef IMAP
|
|
else if (menu==SERVER_HIER_MENU)
|
|
{
|
|
*item = FindSTRNIndex(ServerMenuStrnStrn,itemStr);
|
|
if (*item > ksvmLimit) *item -= ksvmLimit;
|
|
return (true); // leave itemStr set to be used on the button
|
|
}
|
|
#endif
|
|
else if (menu==TABLE_HIER_MENU)
|
|
;// no fixup needed
|
|
else return(False);
|
|
|
|
*itemStr = 0;
|
|
return(True);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBMovedMenu - fix up some menu items that have moved since the last version
|
|
**********************************************************************/
|
|
Boolean TBMovedMenu(short *menu,PStr itemStr,short *item)
|
|
{
|
|
short winItems[] = { WIN_ALIASES_ITEM,WIN_PH_ITEM,WIN_FILTERS_ITEM,WIN_MAILBOX_ITEM };
|
|
short i;
|
|
Str32 s;
|
|
|
|
if (*menu==SPECIAL_MENU)
|
|
{
|
|
// Tool windows moved from Speical menu to Window menu
|
|
MenuHandle windowMenu = GetMHandle(WINDOW_MENU);
|
|
|
|
for (i=0;i<sizeof(winItems)/sizeof(short);i++)
|
|
{
|
|
if (StringSame(itemStr,MyGetItem(windowMenu,winItems[i],s)))
|
|
{
|
|
*menu = WINDOW_MENU;
|
|
*item = winItems[i];
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolbarAddMenuButton - add a menu item to the end of the toolbar
|
|
**********************************************************************/
|
|
Boolean TBAddMenuButton(short menu,short item,PStr itemText)
|
|
{
|
|
short i;
|
|
short n;
|
|
ButtonData bd;
|
|
|
|
if (!Win) return false; // No toolbar!
|
|
|
|
// Make sure the item isn't already in the toolbar
|
|
n = N;
|
|
for (i=0;i<n;i++)
|
|
{
|
|
bd = (*BD)[i];
|
|
if (bd.kind == tbkMenu && (bd.select>>16L)==menu && ((unsigned short)bd.select)==item)
|
|
{
|
|
return false; // It's already there
|
|
}
|
|
}
|
|
|
|
// Create new button
|
|
if (!TBNewButton(n))
|
|
InstallButtonMenu(n+1,menu,item,itemText,0,nil,0);
|
|
|
|
return true; // Successfully added
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBAddAdButton - add an ad to the toolbar
|
|
**********************************************************************/
|
|
void TBAddAdButtons(TBAdHandle hTBAds)
|
|
{
|
|
short numAds,buttonIdx,i;
|
|
short n;
|
|
|
|
if (!Win) return; // No toolbar!
|
|
|
|
// Delete any ad buttons no longer in use
|
|
numAds = HandleCount(hTBAds);
|
|
for(buttonIdx=N-1;buttonIdx>=0;buttonIdx--)
|
|
{
|
|
BDPtr pBD = &(*BD)[buttonIdx];
|
|
|
|
if (pBD->kind == tbkAd)
|
|
{
|
|
Boolean found = false;
|
|
AdId adId;
|
|
|
|
adId.ad = pBD->select;
|
|
adId.server = pBD->modifiers;
|
|
for(i=0;i<numAds;i++)
|
|
{
|
|
if (SameAd(&(*hTBAds)[i].adId,&adId))
|
|
{
|
|
if (!(*hTBAds)[i].deleted)
|
|
{
|
|
found = true;
|
|
(*hTBAds)[i].deleted = true; // We don't want to ad it again
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (!found)
|
|
TBDelButton(pBD->cntl);
|
|
}
|
|
}
|
|
|
|
// Install ad buttons
|
|
LDRef(hTBAds);
|
|
for(i=0;i<numAds;i++)
|
|
{
|
|
// Create new button
|
|
if (!(*hTBAds)[i].deleted && !TBNewButton(n=N))
|
|
InstallButtonAd(n+1,&(*hTBAds)[i]);
|
|
}
|
|
UL(hTBAds);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* InstallButtonAd - put an ad in a button
|
|
**********************************************************************/
|
|
void InstallButtonAd(short i,TBAdInfo *pAd)
|
|
{
|
|
BDPtr pBD = &(*BD)[i-1];
|
|
ControlHandle button = (*BD)[i-1].cntl;
|
|
|
|
pBD->kind = tbkAd;
|
|
pBD->select = pAd->adId.ad;
|
|
pBD->modifiers = pAd->adId.server;
|
|
PCopy(pBD->title,pAd->title);
|
|
if (VarHasIcon(VarCode)) SetBevelIcon(pBD->cntl,0,0,0,pAd->iconSuite);
|
|
TBSetCTitle(button,pAd->title);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* TBUpdateAdButtonIcon - need to redraw this button ad
|
|
**********************************************************************/
|
|
void TBUpdateAdButtonIcon(AdId setAdId,Handle iconSuite)
|
|
{
|
|
short i;
|
|
AdId adId;
|
|
|
|
if (Win)
|
|
{
|
|
for (i=0;i<N;i++)
|
|
{
|
|
BDPtr pBD = &(*BD)[i];
|
|
|
|
if (pBD->kind == tbkAd)
|
|
{
|
|
adId.ad = pBD->select;
|
|
adId.server = pBD->modifiers;
|
|
if (SameAd(&setAdId,&adId))
|
|
{
|
|
if (VarHasIcon(VarCode)) SetBevelIcon(pBD->cntl,0,0,0,iconSuite);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
* InstallButtonNickname - put a nickname in a button
|
|
**********************************************************************/
|
|
void InstallButtonNickname (short i, PStr nickname)
|
|
{
|
|
ButtonData bd;
|
|
ControlHandle button = (*BD)[i-1].cntl;
|
|
|
|
button = (*BD)[i - 1].cntl;
|
|
Zero (bd);
|
|
bd.cntl = button;
|
|
bd.kind = tbkNick;
|
|
PCopy (bd.title, nickname);
|
|
(*BD)[i - 1] = bd;
|
|
if (VarHasIcon(VarCode))
|
|
SetNicknameIcon (button, nickname);
|
|
TBSetCTitle (button, nickname);
|
|
if (TaskProgButton==button) TaskProgButton = nil;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* TBRename - rename a toolbar button of a particular kind
|
|
**********************************************************************/
|
|
Boolean TBRename (TBButtonEnum kind, PStr oldName, PStr newName)
|
|
|
|
{
|
|
ButtonData bd;
|
|
short i;
|
|
|
|
// Find the button with the old name
|
|
if (Win)
|
|
for (i = 0; i < N; ++i) {
|
|
bd = (*BD)[i];
|
|
if (bd.kind == kind && StringSame (bd.title, oldName)) {
|
|
PCopy (bd.title, newName);
|
|
(*BD)[i] = bd;
|
|
TBSetCTitle (bd.cntl, newName);
|
|
Dirty = True;
|
|
return (true);
|
|
}
|
|
}
|
|
return (false);
|
|
}
|
|
|
|
Boolean TBRenameNickButton (PStr oldName, PStr newName)
|
|
|
|
{
|
|
return (TBRename (tbkNick, oldName, newName));
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* InstallButtonMenu - put a menu choice in a button
|
|
**********************************************************************/
|
|
void InstallButtonMenu(short i, short menu, short item,PStr itemText,short modifiers,void *data,long size)
|
|
{
|
|
Handle dataH;
|
|
ControlHandle button = (*BD)[i-1].cntl;
|
|
Str255 itemStr;
|
|
Str255 titleStr;
|
|
ButtonData bd;
|
|
short id;
|
|
Boolean special=False;
|
|
MenuHandle mh;
|
|
Handle suite;
|
|
Byte type;
|
|
|
|
Zero(bd);
|
|
bd.select = (menu<<16L)|item;
|
|
bd.modifiers = modifiers;
|
|
bd.kind = tbkMenu;
|
|
bd.cntl = button;
|
|
TBZapButtonData(i);
|
|
|
|
if (menu==FIND_HIER_MENU && item==FIND_SEARCH_WEB_ITEM) SetPrefBit(PREF_SEARCH_WEB_BITS,prefSearchWebTBButtonInstalled);
|
|
|
|
if (data)
|
|
{
|
|
if (dataH = NuHandle(size)) BMD(data,*dataH,size);
|
|
bd.data = dataH;
|
|
}
|
|
if (mh=GetMHandle(menu))
|
|
{
|
|
if (!itemText || !*itemText)
|
|
{
|
|
if (!(special=TBInstSpecialMenus(menu,item,modifiers,itemStr,titleStr)))
|
|
MyGetItem(GetMHandle(menu),item,itemStr);
|
|
}
|
|
else PCopy(itemStr,itemText);
|
|
}
|
|
else *itemStr = 0;
|
|
if (IsRecipMenu(menu) || IsStationMenu(menu))
|
|
bd.data = NuDHTempOK(itemStr,*itemStr+1);
|
|
(*BD)[i-1] = bd;
|
|
if (!special) ModifierNames(titleStr,modifiers);
|
|
PSCat(titleStr,itemStr);
|
|
if (VarHasIcon(VarCode))
|
|
{
|
|
#ifdef TASK_PROGRESS_ON //
|
|
if (menu==WINDOW_MENU && item==WIN_TASKS_ITEM)
|
|
{
|
|
TaskProgButton = button;
|
|
}
|
|
else if (TaskProgButton==button)
|
|
{
|
|
TaskProgButton = nil;
|
|
}
|
|
#endif
|
|
if (menu==FILE_MENU && (item==FILE_PRINT_ITEM||item==FILE_PRINT_ONE_ITEM) && !SetPrinterIcon(button))
|
|
;
|
|
else if (menu==SCRIPTS_MENU)
|
|
{
|
|
FSSpec spec;
|
|
SInt32 gestaltResult;
|
|
IconRef iconRef;
|
|
SInt16 theLabel;
|
|
Boolean custIcon = false;
|
|
|
|
// Check for a custom icon. We need Icon Services to do this
|
|
if (!GetScriptFolderSpec(&spec))
|
|
if (!Gestalt(gestaltIconUtilitiesAttr,&gestaltResult) &&
|
|
(gestaltResult&gestaltIconUtilitiesHasIconServices) &&
|
|
GetIconRefFromFile)
|
|
{
|
|
GetMenuItemText(GetMHandle(menu),item,spec.name);
|
|
if (!GetIconRefFromFile(&spec,&iconRef,&theLabel))
|
|
{
|
|
SetBevelIconIconRef(bd.cntl,iconRef);
|
|
custIcon = true;
|
|
}
|
|
}
|
|
if (!custIcon)
|
|
SetBevelIcon(bd.cntl,nil,'osas','ToyS',nil);
|
|
}
|
|
/* I don't believe we really want to do this anymore since we now have true nickname buttons (jp)...
|
|
else if (menu == NEW_TO_HIER_MENU && !SetNicknameIcon(button, itemText))
|
|
; */
|
|
else if (suite = ETLMenu2Icon(menu,item))
|
|
{
|
|
SetBevelIcon(button,0,0,0,suite);
|
|
}
|
|
else if (menu==MESSAGE_MENU && item==MESSAGE_JUNK_ITEM)
|
|
{
|
|
SetBevelIcon(button,MAKE_JUNK_ICON,0,0,nil);
|
|
}
|
|
else if (menu==EMOTICON_HIER_MENU && !GetMenuItemIconHandle(GetMHandle(menu),item,&type,&suite) && suite)
|
|
{
|
|
Handle dupSuite;
|
|
DupIconSuite(suite,&dupSuite,false);
|
|
SetBevelIcon(button,0,0,0,dupSuite);
|
|
}
|
|
else
|
|
{
|
|
if (!(id = Names2Icon(itemStr,titleStr))) id = Menu2Icon(menu,item,modifiers);
|
|
SetBevelIcon(button,id,0,0,nil);
|
|
}
|
|
}
|
|
TBSetCTitle(button,titleStr);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* SetPrinterIcon - put the current printer in a toolbar button icon
|
|
**********************************************************************/
|
|
OSErr SetPrinterIcon(ControlHandle button)
|
|
{
|
|
AliasHandle res = GetResource_('alis',-8192);
|
|
FSSpec spec;
|
|
Boolean changed;
|
|
OSErr err;
|
|
FInfo info;
|
|
|
|
if (!res) return(resNotFound);
|
|
Zero(spec);
|
|
if (!(err=ResolveAlias(nil,res,&spec,&changed)))
|
|
if (!(err=FSpGetFInfo(&spec,&info)))
|
|
{
|
|
KillBevelIcon(button);
|
|
SetBevelIcon(button,0,info.fdType,info.fdCreator,nil);
|
|
}
|
|
return(err);
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* SetNicknameIcon - put a nickname photo into a toolbar button icon
|
|
**********************************************************************/
|
|
OSErr SetNicknameIcon(ControlHandle button, PStr nickname)
|
|
|
|
{
|
|
FSSpec urlSpec;
|
|
Str255 tag;
|
|
Handle urlString;
|
|
OSErr theError;
|
|
IconRef iconRef;
|
|
SInt32 gestaltResult;
|
|
SInt16 theLabel;
|
|
long hashName;
|
|
short ab,
|
|
nick;
|
|
|
|
theError = resNotFound;
|
|
urlString = nil;
|
|
if (nickname) {
|
|
hashName = NickHash (nickname);
|
|
for (ab = 0; ab < NAliases; ++ab) {
|
|
nick = NickMatchFound(((*Aliases)[ab].theData), hashName, nickname, ab);
|
|
if (ValidNickname (nick))
|
|
break;
|
|
}
|
|
if (ValidNickname (nick))
|
|
if (urlString = GetTaggedFieldValue (ab, nick, GetRString (tag, ABReservedTagsStrn + abTagPicture))) {
|
|
theError = URLStringToSpec (urlString, &urlSpec);
|
|
if (!theError)
|
|
if (!Gestalt(gestaltIconUtilitiesAttr,&gestaltResult) && (gestaltResult&gestaltIconUtilitiesHasIconServices) && GetIconRefFromFile)
|
|
if (!GetIconRefFromFile (&urlSpec, &iconRef, &theLabel)) {
|
|
KillBevelIcon(button);
|
|
theError = SetBevelIconIconRef (button, iconRef);
|
|
}
|
|
}
|
|
}
|
|
// If an error occurs -- or if we're actually intending to assign a generic icon,
|
|
// assign a generic nickname icon
|
|
if (theError || !urlString)
|
|
SetBevelIcon (button, ValidNickname (nick) ? ABSetIcon (ab, nick) : NICKNAME_ICON, 0, 0, nil);
|
|
ZapHandle (urlString);
|
|
return (theError);
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
* TBInstSpecialMenus - install special menus
|
|
**********************************************************************/
|
|
Boolean TBInstSpecialMenus(short menu,short item,short modifiers,PStr itemStr,PStr titleStr)
|
|
{
|
|
ModifierNames(titleStr,modifiers);
|
|
if (menu==FILE_MENU && item==FILE_CHECK_ITEM)
|
|
{
|
|
if (!(modifiers&optionKey)) GetRString(itemStr,CHECK_MAIL);
|
|
else return(false);
|
|
}
|
|
else if (menu==FILE_MENU && item==FILE_QUIT_ITEM && HaveTheDiseaseCalledOSX())
|
|
{
|
|
GetRString(itemStr,FILE_QUIT_ITEM_STR);
|
|
return true;
|
|
}
|
|
else if (menu==FIND_HIER_MENU && item==FIND_SEARCH_WEB_ITEM)
|
|
{
|
|
ComposeRString(itemStr,SEARCH_NOTHING_FMT,SEARCH_FOR_WEB);
|
|
return true;
|
|
}
|
|
else if (menu==EDIT_MENU && item==EDIT_UNDO_ITEM) GetRString(itemStr,UNDO);
|
|
//#ifdef NEVER
|
|
else if (menu==MESSAGE_MENU && item==MESSAGE_REPLY_ITEM)
|
|
{
|
|
ModifierNames(titleStr,modifiers&~optionKey);
|
|
if (modifiers & optionKey)
|
|
GetRString(itemStr,PrefIsSet(PREF_REPLY_ALL)?REPLY:REPLY_ALL);
|
|
else
|
|
GetRString(itemStr,PrefIsSet(PREF_REPLY_ALL)?REPLY_ALL:REPLY);
|
|
}
|
|
else if (menu==MESSAGE_MENU && item==MESSAGE_QUEUE_ITEM)
|
|
{
|
|
ModifierNames(titleStr,modifiers&~optionKey);
|
|
if (modifiers & optionKey)
|
|
GetRString(itemStr,PrefIsSet(PREF_AUTO_SEND)?QUEUE_M_ITEM:SEND_M_ITEM);
|
|
else
|
|
GetRString(itemStr,PrefIsSet(PREF_AUTO_SEND)?SEND_M_ITEM:QUEUE_M_ITEM);
|
|
}
|
|
//#endif
|
|
else return(False);
|
|
return(True);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ModifierNames - write out the names of the modifier keys
|
|
**********************************************************************/
|
|
PStr ModifierNames(PStr string,short modifiers)
|
|
{
|
|
*string = 0;
|
|
if (modifiers & shiftKey) PCatR(string,SHIFT_PLUS);
|
|
if (modifiers & optionKey) PCatR(string,OPTION_PLUS);
|
|
if (modifiers & cmdKey && HasFeature (featureCustomizeToolbar)) PCatR(string,COMMAND_PLUS);
|
|
if (modifiers & controlKey) PCatR(string,CONTROL_PLUS);
|
|
return(string);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* InstallButtonKey - put a keystroke in a button
|
|
**********************************************************************/
|
|
void InstallButtonKey(short i, long key,short modifiers)
|
|
{
|
|
short id = Key2Icon(key,modifiers);
|
|
ControlHandle button = (*BD)[i-1].cntl;
|
|
Str255 itemStr;
|
|
Str63 modStr;
|
|
Str31 keyName;
|
|
short fmt = SPECIAL_KEY_FMT;
|
|
uShort smallKey;
|
|
|
|
(*BD)[i-1].select = key;
|
|
(*BD)[i-1].modifiers = modifiers;
|
|
(*BD)[i-1].kind = tbkKey;
|
|
TBZapButtonData(i);
|
|
if (VarHasIcon(VarCode)) SetBevelIcon(button,id,0,0,nil);
|
|
|
|
smallKey = key & 0xff;
|
|
|
|
if (smallKey<=' ')
|
|
{
|
|
GetRString(keyName,KeyNameStrn+(smallKey+1));
|
|
fmt = SPECIAL_KEY_FMT;
|
|
}
|
|
else
|
|
{
|
|
keyName[0] = 1;
|
|
keyName[1] = (UnadornKey(key,modifiers))&0xff;
|
|
fmt = KEY_FMT;
|
|
}
|
|
ComposeRString(itemStr,fmt,ModifierNames(modStr,modifiers),keyName);
|
|
TBSetCTitle(button,itemStr);
|
|
if (TaskProgButton==button) TaskProgButton = nil;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* Key2Icon - find the right icon for a keystroke
|
|
**********************************************************************/
|
|
short Key2Icon(short key, short modifiers)
|
|
{
|
|
#pragma unused(key,modifiers)
|
|
return(KEY_ICON);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* Menu2Icon - get the icon for a menu item
|
|
**********************************************************************/
|
|
short Menu2Icon(short menu,short item,short modifiers)
|
|
{
|
|
Handle r;
|
|
Str255 menuName;
|
|
Str63 modName;
|
|
MenuHandle mh;
|
|
short id;
|
|
RGBColor color;
|
|
|
|
if (menu==kHMHelpMenuID) menu = HELP_NOTMENU;
|
|
|
|
if (mh=GetMHandle(menu)) GetMenuTitle(mh,menuName);
|
|
|
|
if (id=Names2Icon(menuName,ModifierNames(modName,modifiers))) return(id);
|
|
|
|
SetResLoad(false);
|
|
r = GetResource('ICN#',menu*20+item);
|
|
SetResLoad(true);
|
|
if (r) return(menu*20+item);
|
|
|
|
SetResLoad(false);
|
|
r = GetResource('ICN#',menu*20);
|
|
SetResLoad(true);
|
|
if (r) return(menu*20);
|
|
|
|
switch(menu)
|
|
{
|
|
case MAILBOX_MENU:
|
|
return(MAILBOX_ICON);
|
|
break;
|
|
|
|
case HELP_NOTMENU: return(-16490);
|
|
|
|
#ifdef LABEL_ICONS
|
|
case LABEL_HIER_MENU:
|
|
if (item<=2) return(LABEL_SICN_TEMPLATE);
|
|
else if (item<=9) return(LABEL_SICN_BASE+item-3);
|
|
else return(LABEL_SICN_BASE+item-4);
|
|
break;
|
|
|
|
case COLOR_HIER_MENU:
|
|
id = TOOLBAR_COLOR_SICN_BASE+item;
|
|
if (item<=2) DEFAULT_COLOR(color);
|
|
else GetItemColor(menu,item,&color);
|
|
RefreshRGBIcon(id,&color,TOOLBAR_COLOR_SICN_TEMPLATE,nil);
|
|
return(id);
|
|
break;
|
|
#endif
|
|
|
|
default: return(MENU_ICON);
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolbarMailbox - return the mailbox represented by a toolbar button
|
|
**********************************************************************/
|
|
OSErr ToolbarMailbox(short which,FSSpecPtr spec)
|
|
{
|
|
ButtonData bd;
|
|
short mnu;
|
|
|
|
bd = (*BD)[which-1];
|
|
if (bd.kind!=tbkMenu) return(fnfErr);
|
|
mnu = (bd.select>>16)&0xffff;
|
|
if ((mnu==MAILBOX_MENU || mnu==TRANSFER_MENU) && bd.data)
|
|
{
|
|
if (spec) *spec = **(FSSpecHandle)bd.data;
|
|
return(noErr);
|
|
}
|
|
return(fnfErr);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ToolbarButton - execute a button press in the toolbar
|
|
**********************************************************************/
|
|
void ToolbarButton(MyWindowPtr win,ControlHandle button,long modifiers,short part)
|
|
{
|
|
#pragma unused(win,part)
|
|
WindowPtr topWin = FrontWindow_();
|
|
short mnu, item;
|
|
long select;
|
|
EventRecord event;
|
|
short controlRef = GetControlReference(button)-1;
|
|
ButtonData bd;
|
|
Boolean hasBD;
|
|
Boolean swap;
|
|
AdId adId;
|
|
|
|
SetPort_(GetMyWindowCGrafPtr(Win));
|
|
TB_RESTORE_STUFF;
|
|
|
|
if (hasBD = (0<=controlRef && controlRef<N)) bd = (*BD)[controlRef];
|
|
|
|
if (!hasBD && modifiers&cmdKey) return; // punt if we try to customize something we can't
|
|
|
|
if (HasFeature (featureCustomizeToolbar) && modifiers&cmdKey)
|
|
{
|
|
UseFeature (featureCustomizeToolbar);
|
|
ConfigureTBButton(GetControlReference(button));
|
|
}
|
|
else if (button==SearchGo)
|
|
{
|
|
if (!(modifiers&cmdKey)) TBSearchStart(nil);
|
|
}
|
|
else if (hasBD)
|
|
{
|
|
modifiers |= bd.modifiers;
|
|
// hmmmmmmmmmmmmm. A few things check this rather than the
|
|
// modifiers passed in. I'm not sure this is a good idea,
|
|
// but I'm going to try it for now. SD 3/19/03
|
|
MainEvent.modifiers = modifiers;
|
|
switch(bd.kind)
|
|
{
|
|
case tbkMenu:
|
|
if (select = bd.select)
|
|
{
|
|
EnableMenuItems(False);
|
|
select = TBExtractMenu(&bd,&mnu,&item);
|
|
if (mnu==FILE_MENU && item==FILE_QUIT_ITEM)
|
|
PleaseQuit = true;
|
|
else if (IsEnabled(mnu,item))
|
|
{
|
|
if (DoWebFindWarning(mnu,item))
|
|
{
|
|
swap = (mnu==MESSAGE_MENU && item==MESSAGE_QUEUE_ITEM && (modifiers&optionKey));
|
|
if (swap) {TogglePref(PREF_AUTO_SEND);modifiers&=~optionKey;}
|
|
DoMenu(topWin,select,modifiers);
|
|
if (swap) TogglePref(PREF_AUTO_SEND);
|
|
}
|
|
}
|
|
else
|
|
SysBeep(20);
|
|
}
|
|
break;
|
|
|
|
case tbkKey:
|
|
Zero(event);
|
|
event.what = keyDown;
|
|
event.modifiers = modifiers;
|
|
event.message = bd.select;
|
|
event.when = TickCount();
|
|
HandleEvent(&event);
|
|
break;
|
|
|
|
case tbkFile:
|
|
TBFileButton(&bd);
|
|
break;
|
|
|
|
case tbkAd:
|
|
adId.ad = bd.select;
|
|
adId.server = bd.modifiers;
|
|
AdUserClick(adId);
|
|
break;
|
|
|
|
case tbkNick:
|
|
// A click on a nickname toolbar button should behave like a click in the recipient buttons of the address book
|
|
{
|
|
MyWindowPtr win = TopCompositionWindow (false, false);
|
|
GrafPtr oldPort;
|
|
MessHandle messH;
|
|
HeadSpec hs;
|
|
long start;
|
|
Boolean wantExpansion;
|
|
|
|
if (win && CompHeadFind (messH = Win2MessH(win), TO_HEAD, &hs)) {
|
|
wantExpansion = ((modifiers & optionKey) != 0);
|
|
if (HasFeature (featureNicknameWatching) && PrefIsSet (PREF_NICK_AUTO_EXPAND))
|
|
wantExpansion = true;
|
|
GetPort (&oldPort);
|
|
SetPort_ (GetMyWindowCGrafPtr (win));
|
|
PeteSelect (win, win->pte, hs.stop, hs.stop);
|
|
PetePrepareUndo (win->pte, peUndoPaste, -1, -1, &start, nil);
|
|
InsertCommaIfNeedBe (TheBody, &hs);
|
|
InsertAlias (win->pte, &hs, bd.title, wantExpansion, start, false);
|
|
ShowMyWindow (GetMyWindowWindowPtr (win));
|
|
UpdateSum (messH, SumOf(messH)->offset, SumOf(messH)->length);
|
|
SetPort_ (oldPort);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ConfigureTBButton(GetControlReference(button));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* TBExtractMenu - get menu stuff from a button
|
|
**********************************************************************/
|
|
long TBExtractMenu(BDPtr bd,short *mnu,short *item)
|
|
{
|
|
long select = bd->select;
|
|
Str255 itemStr;
|
|
FSSpec spec;
|
|
|
|
*mnu = (select>>16)&0xffff;
|
|
*item = select&0xffff;
|
|
if (IsRecipMenu(*mnu) || IsStationMenu(*mnu))
|
|
{
|
|
if (bd->data)
|
|
{
|
|
PCopy(itemStr,*bd->data);
|
|
if (*item=FindItemByName(GetMHandle(*mnu),itemStr))
|
|
select = (*mnu)<<16L | *item;
|
|
}
|
|
}
|
|
else if ((*mnu==MAILBOX_MENU || *mnu==TRANSFER_MENU) && *item!=MAILBOX_NEW_ITEM && *item!=MAILBOX_OTHER_ITEM)
|
|
{
|
|
spec = **(FSSpecHandle)bd->data;
|
|
Spec2Menu(&spec,*mnu==TRANSFER_MENU,mnu,item);
|
|
select = *mnu<<16L | *item;
|
|
}
|
|
return(select);
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void TBFileButton(BDPtr bdp)
|
|
{
|
|
short id = (*(TBAliasHandle)bdp->data)->id;
|
|
AliasHandle res = GetResource_(TB_ALIAS_TYPE,id);
|
|
FSSpec settings, spec;
|
|
Boolean changed;
|
|
OSErr err;
|
|
Str255 name;
|
|
|
|
GetControlTitle(bdp->cntl,name);
|
|
|
|
if (res)
|
|
{
|
|
GetFileByRef(SettingsRefN,&settings);
|
|
err = ResolveAlias(&settings,res,&spec,&changed);
|
|
if (!err)
|
|
{
|
|
if (changed) ChangedResource((Handle)res);
|
|
OpenOtherDoc(&spec,False,false,nil);
|
|
}
|
|
else FileSystemError(TB_NO_FILE,name,err);
|
|
}
|
|
else
|
|
{
|
|
if (AlertStr(TBAR_REM_ALRT,Note,name)==OK)
|
|
TBDelButton(bdp->cntl);
|
|
}
|
|
}
|
|
|
|
/**********************************************************************
|
|
* ConfigureTBButton - configure a toolbar button
|
|
**********************************************************************/
|
|
Boolean ConfigureTBButton(short which)
|
|
{
|
|
WindowPtr theWindow;
|
|
DialogPtr dgPtr;
|
|
MyWindowPtr dgPtrWin;
|
|
EventRecord event;
|
|
Str255 s;
|
|
FSSpec spec;
|
|
ControlHandle button = (*BD)[which-1].cntl;
|
|
Boolean val = False;
|
|
|
|
TBTip(button);
|
|
TBTipLo(nil);
|
|
|
|
HiliteControl(button,1);
|
|
|
|
EnableMenus(nil,True);
|
|
EnableMenuItems(True);
|
|
|
|
DrawMenuBar();
|
|
|
|
SetMyCursor(arrowCursor); SFWTC = True;
|
|
|
|
// dgPtr = GetNewDialog(TBAR_MENU_DLOG,nil,InFront);
|
|
// DrawDialog(dgPtr);
|
|
dgPtrWin = GetNewMyDialog (TBAR_MENU_DLOG,nil,nil,InFront);
|
|
dgPtr = GetMyWindowDialogPtr (dgPtrWin);
|
|
if (!dgPtrWin || !dgPtr)
|
|
return (false);
|
|
|
|
SetPort_(GetWindowPort(GetDialogWindow(dgPtr)));
|
|
ActivateMyWindow(GetDialogWindow(dgPtr),true);
|
|
PushModalWindow(GetDialogWindow(dgPtr));
|
|
|
|
Zero(gTBMenu);
|
|
gTBMenu.doingButton = true;
|
|
|
|
/*
|
|
* now, let the user choose something:
|
|
*/
|
|
again:
|
|
FlushEvents(mDownMask|mUpMask|keyDownMask,0);
|
|
for (;!InBG;)
|
|
{
|
|
if (WNE(mDownMask|keyDownMask|updateMask,&event,REAL_BIG))
|
|
{
|
|
SetPort_(GetWindowPort(GetDialogWindow(dgPtr)));
|
|
if (event.what==updateEvt) MiniMainLoop(&event);
|
|
else if (gTBMenu.menuId)
|
|
break;
|
|
else if (event.what==mouseDown)
|
|
{
|
|
ControlHandle cntl;
|
|
short wPart = FindWindow_(event.where,&theWindow);
|
|
|
|
if (wPart==inMenuBar) break;
|
|
else if (wPart==inContent)
|
|
{
|
|
Point pt = event.where;
|
|
GlobalToLocal(&pt);
|
|
if (FindControl(pt,theWindow,&cntl)) break;
|
|
}
|
|
}
|
|
else if (event.what==keyDown)
|
|
break;
|
|
}
|
|
}
|
|
SetPort_(GetMyWindowCGrafPtr(Win));
|
|
if (gTBMenu.menuId) goto stupidApplicationMenuCrap;
|
|
|
|
if (((event.message&charCodeMask)=='.') && (event.modifiers&cmdKey) ||
|
|
((event.message&charCodeMask)==escChar) &&
|
|
(((event.message&keyCodeMask)>>8)==escKey)) event.what=nullEvent;
|
|
|
|
//Dprintf("\p%d %d.%d",event.what,event.where.h,event.where.v);
|
|
if (event.what==mouseDown)
|
|
{
|
|
switch(FindWindow_(event.where,&theWindow))
|
|
{
|
|
case inContent:
|
|
{
|
|
Point pt = event.where;
|
|
ControlHandle cntl, remove;
|
|
Rect r;
|
|
short junk;
|
|
|
|
SetPort_(GetWindowPort(GetDialogWindow(dgPtr)));
|
|
GlobalToLocal(&pt);
|
|
if (FindControl(pt,theWindow,&cntl))
|
|
{
|
|
if (!TrackControl(cntl,pt,nil))
|
|
if (!HaveTheDiseaseCalledOSX()) goto again; // Under Jaguar, this TrackControl
|
|
// fails the first time, for reasons
|
|
// I do not understand and do not currently
|
|
// have the patience to discover. The user who
|
|
// pulls the mouse of the button will just
|
|
// have to suffer SD 9/4/02
|
|
GetDialogItem(dgPtr,2,&junk,(void*)&remove,&r);
|
|
if (cntl==remove) //remove button
|
|
{
|
|
SetPort_(GetMyWindowCGrafPtr(Win));
|
|
DeletingButton(&(*BD)[GetControlReference(button)-1]);
|
|
TBDelButton(button);
|
|
Deleted = True;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case inMenuBar:
|
|
{
|
|
long mSelect;
|
|
short mnu, itm;
|
|
|
|
SetMenuTexts(event.modifiers,True);
|
|
gTBMenu.doingMenuSelect = true;
|
|
gTBMenu.menuId = gTBMenu.item = 0;
|
|
mSelect = MenuSelect(event.where);
|
|
gTBMenu.doingMenuSelect = false;
|
|
stupidApplicationMenuCrap: if (gTBMenu.menuId)
|
|
{
|
|
// We received an AppleEvent indicating which
|
|
// menu item
|
|
|
|
mnu = gTBMenu.menuId;
|
|
itm = gTBMenu.item;
|
|
event.modifiers = CurrentModifiers()&~cmdKey;
|
|
}
|
|
else if (PleaseQuit)
|
|
{
|
|
mnu = FILE_MENU;
|
|
itm = FILE_QUIT_ITEM;
|
|
PleaseQuit = false;
|
|
}
|
|
else
|
|
{
|
|
mnu = (mSelect>>16)&0xffff;
|
|
itm = mSelect & 0xffff;
|
|
}
|
|
HiliteMenu(0);
|
|
if (!itm)
|
|
{
|
|
short menuItem;
|
|
|
|
// No item selected. See if it's an IMAP hybrid mailbox. Since
|
|
// it has a submenu, we have to call MenuChoice.
|
|
mSelect = MenuChoice();
|
|
mnu = (mSelect>>16)&0xffff;
|
|
menuItem = mSelect & 0xffff;
|
|
if (IsMailboxChoice(mnu,menuItem) && mnu!=MAILBOX_MENU && mnu!=TRANSFER_MENU)
|
|
{
|
|
short vRef;
|
|
long dirID;
|
|
|
|
MenuID2VD(mnu,&vRef,&dirID);
|
|
if (IsIMAPVD(vRef,dirID))
|
|
itm = menuItem; // IMAP hybrid mailbox
|
|
}
|
|
}
|
|
*spec.name = 0;
|
|
if (mnu&&itm)
|
|
{
|
|
MyGetItem(GetMHandle(mnu),itm,s);
|
|
if (IsMailboxChoice(mnu,itm))
|
|
mnu = TBBoxishMenu(which,&spec,s,mnu,itm);
|
|
if (mnu)
|
|
{
|
|
if (*spec.name)
|
|
InstallButtonMenu(GetControlReference(button),mnu,0,s,event.modifiers,&spec,sizeof(FSSpec));
|
|
else
|
|
InstallButtonMenu(GetControlReference(button),mnu,itm,nil,event.modifiers,nil,0);
|
|
Dirty = True;
|
|
val = True;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if (event.what==keyDown)
|
|
{
|
|
SetPort_(GetMyWindowCGrafPtr(Win));
|
|
InstallButtonKey(GetControlReference(button),event.message,event.modifiers);
|
|
Dirty = True;
|
|
val = True;
|
|
}
|
|
|
|
PopModalWindow();
|
|
TBTip(nil);
|
|
DisposeDialog_(dgPtr);
|
|
if (!Deleted) HiliteControl(button,0);
|
|
SFWTC = True;
|
|
Zero(gTBMenu);
|
|
return(val);
|
|
}
|
|
|
|
short TBBoxishMenu(short which,FSSpecPtr spec,PStr s,short mnu,short itm)
|
|
{
|
|
if ((mnu==MAILBOX_MENU || mnu==TRANSFER_MENU) && (itm==MAILBOX_NEW_ITEM ||itm==MAILBOX_OTHER_ITEM))
|
|
;
|
|
else if (!(mnu==MAILBOX_MENU || mnu==TRANSFER_MENU) &&
|
|
(itm==TRANSFER_NEW_ITEM-TRANSFER_BAR1_ITEM || itm==TRANSFER_OTHER_ITEM-TRANSFER_BAR1_ITEM))
|
|
{
|
|
Boolean doWarn = true;
|
|
|
|
if (itm==TRANSFER_OTHER_ITEM-TRANSFER_BAR1_ITEM)
|
|
{
|
|
// If IMAP mailbox, this is actually "This Mailbox", not "Other..."
|
|
short vRefNum;
|
|
long dirID;
|
|
|
|
MenuID2VD(mnu,&vRefNum,&dirID);
|
|
if (IsIMAPVD(vRefNum,dirID))
|
|
{
|
|
// IMAP. It's "This Mailbox"
|
|
mnu = MailboxKindaMenu(mnu,itm,s,spec);
|
|
if (*spec->name) PCopy(s,spec->name);
|
|
doWarn = false;
|
|
}
|
|
}
|
|
if (doWarn)
|
|
{
|
|
mnu = 0;
|
|
WarnUser(CANT_ADD_NESTED,0);
|
|
}
|
|
}
|
|
else
|
|
mnu = MailboxKindaMenu(mnu,itm,s,spec);
|
|
|
|
return mnu;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* SizeToolbar - how big should the toobar be?
|
|
**********************************************************************/
|
|
void SizeToolbar(short max)
|
|
{
|
|
WindowPtr WinWP = GetMyWindowWindowPtr (Win);
|
|
Str63 s;
|
|
Str31 token;
|
|
UPtr spot;
|
|
long h, v;
|
|
short totalHi, totalWi;
|
|
ControlHandle button;
|
|
short i;
|
|
Boolean big = VarCode==tbvBig||VarCode==tbvBigName;
|
|
Rect screenRect;
|
|
GDHandle junk;
|
|
Boolean hasMB;
|
|
long exPixels, exCount, space;
|
|
|
|
i = GetPrefLong(PREF_NW_DEV);
|
|
if (i)
|
|
{
|
|
utl_GetIndGD(i,&junk,&screenRect,&hasMB);
|
|
if (hasMB) screenRect.top += GetMBarHeight();
|
|
}
|
|
else
|
|
{
|
|
GetQDGlobalsScreenBitsBounds(&screenRect);
|
|
screenRect.top += GetMBarHeight();
|
|
}
|
|
|
|
ScreenRect = screenRect;
|
|
|
|
/*
|
|
* convenient place to check this
|
|
*/
|
|
if (PrefIsSet(PREF_TB_FKEYS))
|
|
FKeys = True;
|
|
else
|
|
FKeys = False;
|
|
|
|
if (!max) max = 1;
|
|
|
|
/*
|
|
* anchored in UL corner
|
|
*/
|
|
if (!IsWindowVisible(WinWP)) MoveWindow(WinWP,screenRect.left+1,screenRect.top,False);
|
|
|
|
/*
|
|
* make sure we have enough selectors
|
|
*/
|
|
if (!BD)
|
|
{
|
|
button = (void*)NuHandleClear(max*sizeof(ButtonData));
|
|
BD = (void*)button;
|
|
}
|
|
else if ((i=HandleCount(BD))<max)
|
|
{
|
|
SetHandleBig((Handle)BD,max*sizeof(ButtonData));
|
|
if (!MemError())
|
|
{
|
|
LDRef(BD);
|
|
WriteZero(*BD+i,(max-i)*sizeof(ButtonData));
|
|
UL(BD);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* make sure we have enough controls
|
|
*/
|
|
for (i=0;i<max;i++)
|
|
{
|
|
if (!(*BD)[i].cntl)
|
|
{
|
|
button = GetNewControl(TB_CNTL,WinWP);
|
|
if (button)
|
|
{
|
|
SetControlReference(button,i+1);
|
|
TBSetButtonType(button);
|
|
}
|
|
(*BD)[i].cntl = button;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Search control?
|
|
*/
|
|
if (!PrefIsSet(PREF_NO_TB_SEARCH))
|
|
{
|
|
if (!SearchUserPane)
|
|
{
|
|
StackHandle stack;
|
|
|
|
// make 'em
|
|
button = GetNewControl(TB_SEARCH_USER_CNTL,WinWP);
|
|
SearchUserPane = button;
|
|
button = GetNewControl(TB_SEARCH_GO_CNTL,WinWP);
|
|
SearchGo = button;
|
|
button = GetNewControl(TB_SEARCH_POPUP,WinWP);
|
|
SearchPopup = button;
|
|
button = TBNewSearchEdit(WinWP);
|
|
SearchEdit = button;
|
|
StackInit(sizeof(Str255),&stack);
|
|
if (!(SearchPopup && SearchGo && SearchEdit && stack))
|
|
{
|
|
// if we didn't get'em, kill 'em
|
|
ZapControl(SearchPopup);
|
|
ZapControl(SearchEdit);
|
|
ZapControl(SearchGo);
|
|
ZapControl(SearchUserPane);
|
|
ZapHandle(stack);
|
|
}
|
|
else
|
|
{
|
|
short id = SEARCH_WEB_ICON;
|
|
IconAlignmentType align = kAlignAbsoluteCenter;
|
|
|
|
// Panes and alignment and other rote crap
|
|
EmbedControl(SearchGo,SearchUserPane);
|
|
SetControlData(SearchGo,0,kControlIconResourceIDTag,sizeof(id),(void*)&id);
|
|
SetControlData(SearchGo,0,kControlIconAlignmentTag,sizeof(align),(void*)&align);
|
|
EmbedControl(SearchPopup,SearchUserPane);
|
|
TBSearchEmpty();
|
|
SearchStack = stack;
|
|
}
|
|
}
|
|
}
|
|
else if (SearchUserPane)
|
|
{
|
|
ZapControl(SearchUserPane);
|
|
TipCntl = nil;
|
|
}
|
|
|
|
/*
|
|
* figure cell sizes based on variation code
|
|
*/
|
|
GetRString(s,ToolbarSizesStrn+VarCode);
|
|
spot = s+1;
|
|
StringToNum(PToken(s,token,&spot,","),&h);
|
|
StringToNum(PToken(s,token,&spot,","),&v);
|
|
exCount = GetRLong(TOOLBAR_EXTRA_COUNT); if (!exCount) exCount = 1000;
|
|
exPixels = GetRLong(TOOLBAR_EXTRA_PIXELS);
|
|
space = GetRLong(TOOLBAR_SEP_PIXELS);
|
|
Hi = v;
|
|
Wi = h;
|
|
ExPixels = exPixels;
|
|
ExCount = exCount;
|
|
Space = space;
|
|
|
|
/*
|
|
* place them
|
|
*/
|
|
N = max;
|
|
TBPlaceControls(&screenRect, &totalWi, &totalHi);
|
|
|
|
if (!PrefIsSet(PREF_NO_TB_BALL) && !Vertical && (VarCode==tbvBig||VarCode==tbvSmall))
|
|
{
|
|
Tip.bottom = totalHi-1;
|
|
}
|
|
else Tip.bottom = 0;
|
|
Tip.top = Tip.bottom-10;
|
|
|
|
SizeWindow(WinWP,totalWi,totalHi,False);
|
|
GetPortBounds(GetWindowPort(WinWP),&Win->contR);
|
|
|
|
InvalContent(Win);
|
|
}
|
|
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void GetButtonAlignment(ToolbarVEnum varCode, ControlButtonTextAlignment *alignment, ControlButtonTextPlacement *placement, short *textOffset, ControlButtonGraphicAlignment *gAlignment, Point *gOffset)
|
|
{
|
|
*textOffset = 0;
|
|
gOffset->h = gOffset->v = 0;
|
|
|
|
switch(varCode)
|
|
{
|
|
case tbvBigName: // big icons & names
|
|
*placement = kControlBevelButtonPlaceBelowGraphic;
|
|
*alignment = kControlBevelButtonAlignTextCenter;
|
|
*gAlignment = kControlBevelButtonAlignTop;
|
|
gOffset->v = 2;
|
|
break;
|
|
case tbvBig: // big icons
|
|
*placement = kControlBevelButtonPlaceToRightOfGraphic;
|
|
*alignment = kControlBevelButtonAlignTextFlushRight;
|
|
*gAlignment = kControlBevelButtonAlignCenter;
|
|
*textOffset = 500;
|
|
gOffset->v = 2;
|
|
break;
|
|
case tbvSmallName: // small icons & names
|
|
*placement = kControlBevelButtonPlaceToRightOfGraphic;
|
|
*alignment = kControlBevelButtonAlignTextFlushLeft;
|
|
*gAlignment = kControlBevelButtonAlignLeft;
|
|
gOffset->h = 2;
|
|
break;
|
|
case tbvSmall: // small icons only
|
|
*placement = kControlBevelButtonPlaceToRightOfGraphic;
|
|
*alignment = kControlBevelButtonAlignTextFlushRight;
|
|
*gAlignment = kControlBevelButtonAlignCenter;
|
|
*textOffset = 500;
|
|
break;
|
|
case tbvName: // text only
|
|
*placement = kControlBevelButtonPlaceBelowGraphic;
|
|
*alignment = kControlBevelButtonAlignTextCenter;
|
|
*gAlignment = kControlBevelButtonAlignTop;
|
|
break;
|
|
}
|
|
}
|
|
/**********************************************************************
|
|
*
|
|
**********************************************************************/
|
|
void TBPlaceControls(Rect *screenRect,short *windowWide, short *windowHi)
|
|
{
|
|
short i;
|
|
ControlHandle button;
|
|
ControlButtonTextPlacement placement;
|
|
ControlButtonTextAlignment alignment;
|
|
ControlButtonGraphicAlignment gAlignment;
|
|
short textOffset = 0;
|
|
Point gOffset = {0,0};
|
|
short h, v;
|
|
short wi, hi;
|
|
short vFactor = Vertical ? 1 : 0;
|
|
short hFactor = 1-vFactor;
|
|
short maxH = 0;
|
|
short maxV = 0;
|
|
short extraCount = 0;
|
|
short hWrap = RectWi(*screenRect)-GetRLong(TB_H_DESK_MARGIN);
|
|
short vWrap = RectHi(*screenRect)-GetRLong(TB_V_DESK_MARGIN);
|
|
short nextSlots;
|
|
short fKeyHi = 0;
|
|
short fKeyWi = 0;
|
|
short fKeyWiSave;
|
|
short tipHi = 0;
|
|
Rect r;
|
|
short searchPaneHi = 0;
|
|
short searchPaneWi = 0;
|
|
short wraps = 0;
|
|
|
|
// allow room for search button
|
|
if (SearchUserPane)
|
|
{
|
|
searchPaneWi = ControlWi(SearchUserPane);
|
|
searchPaneHi = ControlHi(SearchUserPane);
|
|
hWrap -= ExPixels + searchPaneWi;
|
|
vWrap -= ExPixels + searchPaneHi;
|
|
}
|
|
|
|
// allow room for fkey labels
|
|
if (FKeys && PrefIsSet(PREF_SHOW_FKEYS))
|
|
{
|
|
fKeyWi += vFactor*GetRLong(TB_FKEY_LABEL_WIDE); // yes, vFactor
|
|
fKeyHi += hFactor*10; // yes, hFactor
|
|
}
|
|
if (!PrefIsSet(PREF_NO_TB_BALL) && !Vertical && (VarCode==tbvBig||VarCode==tbvSmall))
|
|
tipHi = 12;
|
|
fKeyHi = MAX(fKeyHi,tipHi);
|
|
fKeyWiSave = fKeyWi;
|
|
|
|
// setup alignment stuff
|
|
GetButtonAlignment (VarCode, &alignment, &placement, &textOffset, &gAlignment, &gOffset);
|
|
|
|
h = v = ExPixels;
|
|
|
|
for (i=0;i<N;i++)
|
|
{
|
|
if (i>14)
|
|
{
|
|
fKeyHi = tipHi;
|
|
fKeyWi = 0;
|
|
}
|
|
|
|
button=(*BD)[i].cntl;
|
|
|
|
SetControlData(button,0,kControlBevelButtonTextAlignTag,sizeof(alignment),(void*)&alignment);
|
|
SetControlData(button,0,kControlBevelButtonTextPlaceTag,sizeof(placement),(void*)&placement);
|
|
SetControlData(button,0,kControlBevelButtonTextOffsetTag,sizeof(textOffset),(void*)&textOffset);
|
|
SetControlData(button,0,kControlBevelButtonGraphicAlignTag,sizeof(gAlignment),(void*)&gAlignment);
|
|
SetControlData(button,0,kControlBevelButtonGraphicOffsetTag,sizeof(gOffset),(void*)&gOffset);
|
|
|
|
wi = Wi*(1 + hFactor*(*BD)[i].slots);
|
|
hi = Hi*(1 + vFactor*(*BD)[i].slots);
|
|
|
|
MoveMyCntl(button,h,v,wi,hi);
|
|
|
|
maxH = MAX(maxH,h+wi+fKeyWi);
|
|
maxV = MAX(maxV,v+hi+fKeyHi);
|
|
|
|
extraCount++;
|
|
|
|
v += vFactor*(hi + Space);
|
|
if (!(extraCount%ExCount)) v += vFactor*ExPixels;
|
|
h += hFactor*(wi + Space);
|
|
if (!(extraCount%ExCount)) h += hFactor*ExPixels;
|
|
|
|
|
|
if (i<N-1)
|
|
{
|
|
nextSlots = i<N-1 ? (*BD)[i+1].slots : 0;
|
|
if (v+vFactor*(1+nextSlots)*Hi>vWrap)
|
|
{
|
|
v = ExPixels;
|
|
h = maxH+ExPixels;
|
|
extraCount = 0;
|
|
wraps++;
|
|
}
|
|
else if (h+hFactor*(1+nextSlots)*Wi>hWrap)
|
|
{
|
|
h = ExPixels;
|
|
v = maxV+ExPixels;
|
|
extraCount = 0;
|
|
wraps++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// basic sizing
|
|
if (windowWide)
|
|
{
|
|
*windowWide = maxH+ExPixels;
|
|
if (!Vertical && SearchUserPane) *windowWide += ControlWi(SearchUserPane)+ExPixels;
|
|
}
|
|
if (windowHi)
|
|
{
|
|
*windowHi = maxV+ExPixels;
|
|
if (Vertical && SearchUserPane) *windowHi += ControlHi(SearchUserPane)+ExPixels;
|
|
}
|
|
|
|
// The search button
|
|
if (SearchUserPane)
|
|
{
|
|
// If the search button is forcing the window higher or wider, make sure the buttons
|
|
// grow to where they need to be
|
|
if (Vertical)
|
|
{
|
|
if (fKeyWiSave+Wi < searchPaneWi && !wraps)
|
|
{
|
|
// we're going to have to make the buttons wider to fill in the space
|
|
Wi = searchPaneWi-fKeyWiSave;
|
|
for (i=0;i<N;i++)
|
|
SizeControl((*BD)[i].cntl,Wi,Hi);
|
|
}
|
|
}
|
|
|
|
hi = ControlHi(SearchUserPane);
|
|
if (Vertical)
|
|
{
|
|
if (*windowWide) *windowWide = MAX(*windowWide,ControlWi(SearchUserPane)+2*ExPixels);
|
|
MoveMyCntl(SearchUserPane,ExPixels,maxV+ExPixels,0,hi);
|
|
}
|
|
else
|
|
{
|
|
if (*windowHi) *windowHi = MAX(*windowHi,ControlHi(SearchUserPane)+2*ExPixels);
|
|
MoveMyCntl(SearchUserPane,maxH+ExPixels,ExPixels+(Hi-hi)/2,0,hi);
|
|
}
|
|
// Now, move the embedded controls to the right places
|
|
GetControlBounds(SearchUserPane,&r);
|
|
MoveMyCntl(SearchPopup,r.left+1,r.top+(RectHi(r)-ControlHi(SearchPopup))/2,0,0);
|
|
MoveMyCntl(SearchGo,r.right-ControlWi(SearchGo),r.top+(RectHi(r)-ControlHi(SearchGo))/2,0,0);
|
|
MoveMyCntl(SearchEdit,r.left+MAX_APPEAR_RIM+ControlWi(SearchPopup)+1,r.top+(RectHi(r)-ControlHi(SearchGo))/2,
|
|
ControlWi(SearchUserPane)-2-2*MAX_APPEAR_RIM-ControlWi(SearchPopup)-ControlWi(SearchGo),
|
|
RectHi(r)-2*MAX_APPEAR_RIM);
|
|
GetControlBounds(SearchEdit,&r);
|
|
PeteDidResize(SearchPTE,&r);
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
* AssignCmdKey - (re)assign command keys
|
|
************************************************************************/
|
|
void AssignCmdKey(short modifiers)
|
|
{
|
|
|
|
}
|
|
|
|
/************************************************************************
|
|
* ChangeCmdKeys - go through the cmd key string and change cmd keys
|
|
************************************************************************/
|
|
void ChangeCmdKeys(void)
|
|
{
|
|
Str255 s;
|
|
UPtr spot;
|
|
Str31 token;
|
|
long num;
|
|
EventRecord event;
|
|
MenuHandle mh;
|
|
short newMods;
|
|
Str31 menuStr;
|
|
Str31 itemStr;
|
|
short menu;
|
|
short item;
|
|
short i;
|
|
|
|
if (*GetRString(s,CmdKeyStrn+1))
|
|
{
|
|
Zero(event);
|
|
event.what = keyDown;
|
|
EnableMenuItems(true);
|
|
|
|
for (i=1;;i++)
|
|
{
|
|
// grab the string
|
|
GetRString(s,CmdKeyStrn+i);
|
|
if (!*s) break;
|
|
spot = s+1;
|
|
// first word is modifiers
|
|
PToken(s,token,&spot," ");
|
|
StringToNum(token,&num);
|
|
event.modifiers = num;
|
|
// next word is message
|
|
PToken(s,token,&spot," ");
|
|
StringToNum(token,&num);
|
|
event.message = num;
|
|
// next word are new modifiers
|
|
PToken(s,token,&spot," ");
|
|
StringToNum(token,&num);
|
|
newMods = num;
|
|
// next the menu name
|
|
PToken(s,menuStr,&spot,":");
|
|
menu = FindMenuByName(menuStr);
|
|
// and the item name
|
|
PToken(s,itemStr,&spot,"\377");
|
|
if (menu) item = FindItemByName(GetMHandle(menu),itemStr);
|
|
|
|
if (menu && item && event.message)
|
|
{
|
|
// is it assigned now?
|
|
if ((num=MyMenuKeyLo(&event,false))&0xffff0000)
|
|
if (mh=GetMHandle((num>>16)&0xffff))
|
|
SetItemCmd(mh,num&0xffff,0);
|
|
|
|
// and assign
|
|
mh = GetMHandle(menu);
|
|
SetItemCmd(mh,item,UnadornMessage(&event));
|
|
SetMenuItemModifiers(mh,item,
|
|
(event.modifiers&cmdKey ? 0:kMenuNoCommandModifier)|
|
|
(event.modifiers&optionKey ? kMenuOptionModifier:0)|
|
|
(event.modifiers&shiftKey ? kMenuShiftModifier:0)|
|
|
(event.modifiers&controlKey ? kMenuControlModifier:0));
|
|
}
|
|
}
|
|
EnableMenuItems(false);
|
|
HiliteMenu(0);
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* TBNewSearchEdit - create the search button & edit region
|
|
************************************************************************/
|
|
ControlHandle TBNewSearchEdit(WindowPtr winWP)
|
|
{
|
|
MyWindowPtr win=GetWindowMyWindowPtr(winWP);
|
|
GrafPtr oldPort;
|
|
OSErr err;
|
|
PETEDocInitInfo pi;
|
|
PETEHandle pte;
|
|
ControlHandle cntl = nil;
|
|
DECLARE_UPP(PetePaneDraw,ControlUserPaneDraw);
|
|
|
|
GetPort(&oldPort);
|
|
SetPort_(GetMyWindowCGrafPtr(win));
|
|
|
|
DefaultPII(win,False,0,&pi);
|
|
SetRect(&pi.inRect,0,0,20,20);
|
|
pi.docWidth = 80;
|
|
|
|
if (!(err=PeteCreate(win,&pte,peClearAllReturns|peNoStyledPaste,&pi)))
|
|
{
|
|
PETEMarkDocDirty(PETE,pte,False);
|
|
(*PeteExtra(pte))->frame = true;
|
|
PeteFontAndSize(pte,GetPortTextFont(GetQDGlobalsThePort()),GetPortTextSize(GetQDGlobalsThePort()));
|
|
(*PeteExtra(pte))->infinitelyWide = True;
|
|
(*PeteExtra(pte))->dragPreProcess = TBDragPreProcess;
|
|
(*PeteExtra(pte))->dragPostProcess = TBDragPostProcess;
|
|
SearchPTE = pte;
|
|
|
|
if (cntl=NewControl(winWP,&pi.inRect,"",True,0,0,0,kControlUserPaneProc,(uLong)pte))
|
|
{
|
|
INIT_UPP(PetePaneDraw,ControlUserPaneDraw);
|
|
SetControlData(cntl,0,kControlUserPaneDrawProcTag,sizeof(PetePaneDrawUPP),(void*)&PetePaneDrawUPP);
|
|
}
|
|
}
|
|
CleanPII(&pi);
|
|
if (err) WarnUser(PETE_ERR,err);
|
|
|
|
SetPort_(oldPort);
|
|
return(cntl);
|
|
}
|
|
|
|
/************************************************************************
|
|
* DeletingButton - process deleting ad button
|
|
************************************************************************/
|
|
void DeletingButton(BDPtr pBD)
|
|
{
|
|
if (pBD->kind == tbkAd)
|
|
{
|
|
AdId adId;
|
|
|
|
adId.ad = pBD->select;
|
|
adId.server = pBD->modifiers;
|
|
AdDeleteButton(adId);
|
|
}
|
|
}
|
|
|
|
|
|
void MessageDragPopup (ControlHandle button, Boolean vertical)
|
|
{
|
|
CGrafPtr oldPort;
|
|
Rect buttonRect;
|
|
Point offsetPt;
|
|
|
|
GetControlBounds(button,&buttonRect);
|
|
|
|
// Put the button rectangle into global coordinates
|
|
offsetPt.h = offsetPt.v = 0;
|
|
LocalToGlobal (&offsetPt);
|
|
OffsetRect (&buttonRect, offsetPt.h, offsetPt.v);
|
|
|
|
GetPort (&oldPort);
|
|
if (OpenToolbarPopup (&buttonRect, VarCode, 2, vertical)) {
|
|
AddMenuToToolbarPopup (0, MESSAGE_MENU, MESSAGE_FORWARD_ITEM,(*BD)[GetControlReference(button)-1].title);
|
|
AddMenuToToolbarPopup (1, MESSAGE_MENU, MESSAGE_REDISTRIBUTE_ITEM, (*BD)[GetControlReference(button)-1].title);
|
|
}
|
|
SetPort (oldPort);
|
|
}
|
|
|
|
/************************************************************************
|
|
* ConfiguringToolbar - do indicated menu item if configuring the toolbar
|
|
************************************************************************/
|
|
Boolean ConfiguringToolbarMenuItem(short menuId,short item)
|
|
{
|
|
if (gTBMenu.doingButton)
|
|
{
|
|
gTBMenu.menuId = menuId;
|
|
gTBMenu.item = item;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/************************************************************************
|
|
* TBSearchStart - start a search from the mini-dialog
|
|
************************************************************************/
|
|
void TBSearchStart(PStr searchMe)
|
|
{
|
|
Str255 searchFor;
|
|
|
|
if (!searchMe)
|
|
{
|
|
searchMe = searchFor;
|
|
if (Win->pte)
|
|
{
|
|
PeteSString(searchFor,SearchPTE);
|
|
if (IsAllLWSP(searchFor)) *searchFor = 0;
|
|
}
|
|
else *searchFor = 0;
|
|
}
|
|
|
|
// Add to recent searches
|
|
if (0>StackStringFind(searchMe,SearchStack))
|
|
{
|
|
if ((*SearchStack)->elCount>=GetRLong(RECENT_SEARCH_LIMIT))
|
|
StackPop(nil,SearchStack);
|
|
StackQueue(searchMe,SearchStack);
|
|
}
|
|
|
|
// Now go do it
|
|
if (SearchItem>1)
|
|
{
|
|
short findItem = FIND_SEARCH_ITEM;
|
|
MyWindowPtr win = nil;
|
|
|
|
switch (SearchItem)
|
|
{
|
|
case 2: findItem=FIND_SEARCH_ITEM; break;
|
|
case 3: findItem=FIND_SEARCH_ALL_ITEM; break;
|
|
case 4: findItem=FIND_SEARCH_BOX_ITEM; break;
|
|
case 5: findItem=FIND_SEARCH_FOLDER_ITEM; break;
|
|
default: ASSERT(0);
|
|
}
|
|
|
|
win = SearchOpen(findItem);
|
|
|
|
if (win)
|
|
{
|
|
SearchNewFindStringLo(searchMe,true);
|
|
StartSearch(win);
|
|
}
|
|
}
|
|
else
|
|
DoWebFindStr(searchMe);
|
|
|
|
TBSearchFocus(false);
|
|
}
|
|
|
|
/************************************************************************
|
|
* TBSearchEmpty - empty the search field and put in fake text
|
|
************************************************************************/
|
|
void TBSearchEmpty(void)
|
|
{
|
|
Str255 s;
|
|
PETETextStyle ps;
|
|
|
|
switch (SearchItem)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
ComposeRString(s,SEARCH_NOTHING_FMT,SEARCH_FOR_WEB);
|
|
break;
|
|
case 2:
|
|
ComposeRString(s,SEARCH_NOTHING_FMT,SEARCH_FOR_EMAIL);
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
MyGetItem(GetMHandle(FIND_HIER_MENU),FIND_SEARCH_ALL_ITEM-3+SearchItem,s);
|
|
break;
|
|
default:
|
|
ASSERT(0);
|
|
*s = 0;
|
|
break;
|
|
}
|
|
|
|
PeteSetString(s,SearchPTE);
|
|
GetRColor(&ps.tsColor,FAKE_CONTENT_COLOR);
|
|
PETESetTextStyle(PETE,SearchPTE,0,0xffff,&ps,peColorValid);
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* TBSearchPopup - let the user choose to make us money or be productive
|
|
************************************************************************/
|
|
void TBSearchPopup(Point pt)
|
|
{
|
|
MenuHandle mh = NewMenu(CONTEXT_MENU,"");
|
|
Str255 s;
|
|
long sel;
|
|
short mnu, itm;
|
|
|
|
// Fill the menu with recent searches
|
|
if ((*SearchStack)->elCount)
|
|
{
|
|
for (itm=0;itm<(*SearchStack)->elCount;itm++)
|
|
{
|
|
StackItem(s,itm,SearchStack);
|
|
MyAppendMenu(mh,s);
|
|
}
|
|
AppendMenu(mh,"\p-");
|
|
}
|
|
|
|
if (!SearchItem) SearchItem = 1;
|
|
|
|
// The search-where items
|
|
AppendMenu(mh,ComposeRString(s,SEARCH_NOTHING_FMT,SEARCH_FOR_WEB));
|
|
AppendMenu(mh,ComposeRString(s,SEARCH_NOTHING_FMT,SEARCH_FOR_EMAIL));
|
|
CopyMenuItem(GetMHandle(FIND_HIER_MENU),FIND_SEARCH_ALL_ITEM,mh,REAL_BIG);
|
|
CopyMenuItem(GetMHandle(FIND_HIER_MENU),FIND_SEARCH_BOX_ITEM,mh,REAL_BIG);
|
|
CopyMenuItem(GetMHandle(FIND_HIER_MENU),FIND_SEARCH_FOLDER_ITEM,mh,REAL_BIG);
|
|
SetItemMark(mh,CountMenuItems(mh)-SearchItem+5,diamondChar);
|
|
LocalToGlobal(&pt);
|
|
|
|
sel = AFPopUpMenuSelect(mh,pt.v,pt.h,-1);
|
|
mnu = (sel>>16)&0xffff;
|
|
itm = sel&0xffff;
|
|
|
|
// Did the user choose anything valid?
|
|
if (mnu&&itm)
|
|
{
|
|
// focus in the search window
|
|
TBSearchFocus(true);
|
|
|
|
if ((*SearchStack)->elCount && itm<=(*SearchStack)->elCount)
|
|
{
|
|
// recent item
|
|
StackItem(s,itm-1,SearchStack);
|
|
PeteSetString(s,SearchPTE);
|
|
}
|
|
else // search where?
|
|
{
|
|
SearchItem = itm - CountMenuItems(mh) + 5;
|
|
if (*PeteString(s,SearchPTE))
|
|
TBSearchStart(s);
|
|
}
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
* TBSearchFocus - focus or unfocus on the search field
|
|
************************************************************************/
|
|
void TBSearchFocus(Boolean focus)
|
|
{
|
|
if (SearchPTE)
|
|
{
|
|
if (focus)
|
|
{
|
|
if (!Win->pte)
|
|
{
|
|
PeteSetTextPtr(SearchPTE,nil,0);
|
|
PetePlain(SearchPTE,0,0xffff,peAllValid);
|
|
PetePlain(SearchPTE,kPETECurrentStyle,kPETECurrentStyle,peAllValid);
|
|
PeteFocus(Win,SearchPTE,true);
|
|
PeteActiveLock(SearchPTE);
|
|
}
|
|
}
|
|
else if (Win->pte)
|
|
{
|
|
PeteFocus(Win,nil,true);
|
|
PeteActiveLock(nil);
|
|
TBSearchEmpty();
|
|
}
|
|
}
|
|
}
|
|
|
|
/************************************************************************
|
|
* TBDragPreProcess - clear out fake text on drag
|
|
************************************************************************/
|
|
void TBDragPreProcess(PETEHandle pte,DragTrackingMessage message,DragReference drag)
|
|
{
|
|
if (message==kDragTrackingEnterWindow)
|
|
TBSearchFocus(true);
|
|
}
|
|
|
|
/************************************************************************
|
|
* TBDragPostProcess - launch search after drop
|
|
************************************************************************/
|
|
void TBDragPostProcess(PETEHandle pte,DragTrackingMessage message,DragReference drag)
|
|
{
|
|
if (message==kDragTrackingLeaveWindow && !PeteLen(SearchPTE))
|
|
TBSearchFocus(false);
|
|
else if (message==0x0fff)
|
|
{
|
|
Str255 s;
|
|
PeteString(s,SearchPTE);
|
|
if (!IsAllLWSP(s)) TBSearchStart(s);
|
|
TBSearchEmpty();
|
|
}
|
|
}
|