DIRECTORY
Containers USING [ChildXBound, ChildYBound],
Menus USING [MouseButton, Menu, MenuProc],
Nut USING[SetNutInfo],
Rope,
TBQueue USING [AppendToTiogaButton, CreateTiogaButton],
TiogaButtons
USING [
TiogaButton, TiogaButtonProc,
CreateViewer, ChangeButtonLooks, DeleteButton, SetStyleFromRope],
TiogaOps USING [InsertRope],
UserProfile USING [Boolean, Token],
ViewerClasses USING [Column, Viewer],
ViewerEvents USING [EventProc, EventRegistration, RegisterEventProc, UnRegisterEventProc],
ViewerOps
USING [AddProp, ComputeColumn, CreateViewer, DestroyViewer,
FetchProp, GrowViewer, OpenIcon, PaintViewer, SetMenu],
ViewerSpecs
USING [bwScreenHeight, openLeftWidth, openRightWidth],
WalnutDefs USING [dontCareMsgSetVersion, Error],
WalnutOps
USING [MsgSet, ServerInfo, ActiveMsgSetName, DeletedMsgSetName,
AcceptNewMail, AddMsg, EnumerateMsgsInSet, GetDisplayProps, GetNewMail,
MsgSetExists, RemoveMsg, SetHasBeenRead],
WalnutDisplayerInternal USING [ DisplayMsgFromMsgSet, MsgCategories],
WalnutMsgSetDisplayerPrivate
USING [
MsgSetInfo, MsgSetInfoRec, MsgSetFieldHandle, MsgSetFieldHandleRec,
MsgInfo, MsgInfoRec,
activeMenu, buildingMenu, deletedMenu, displayerMenu, readOnlyMenu],
WalnutPrintOps USING [PrintMsgList],
WalnutWindowInternal
USING [MsgSetButton,
deletedMsgSetButton, initialActiveIconic, initialActiveOpen, initialActiveRight,
msgSetIcon, msgSetNamePrefix, personalMailDB, readOnlyAccess,
msgSetsVersion, walnutQueue,
GetButton, GetSelectedMsgSets, Report, ReportRope, RetrieveNewMail];
Types
TiogaButton: TYPE = TiogaButtons.TiogaButton;
Viewer: TYPE = ViewerClasses.Viewer;
ROPE: TYPE = Rope.ROPE;
MsgSet: TYPE = WalnutOps.MsgSet;
MsgSetButton: TYPE = WalnutWindowInternal.MsgSetButton;
MsgSetInfo: TYPE = WalnutMsgSetDisplayerPrivate.MsgSetInfo;
MsgSetFieldHandle: TYPE = WalnutMsgSetDisplayerPrivate.MsgSetFieldHandle;
MsgInfo: TYPE = WalnutMsgSetDisplayerPrivate.MsgInfo;
tocDefaultLooks:
PUBLIC
ROPE ←
UserProfile.Token[key: "Walnut.TOCDefaultLooks", default: ""];
tocSelectedLooks:
PUBLIC
ROPE ←
UserProfile.Token[key: "Walnut.TOCSelectedLooks", default: "sb"];
tocUnreadLooks:
PUBLIC
ROPE ←
UserProfile.Token[key: "Walnut.TOCUnreadLooks", default: "i"];
userWantsQMs:
PUBLIC
BOOL ←
UserProfile.Boolean[key: "Walnut.ShowUnreadWithQMs", default: TRUE];
GetMsgSetName:
PUBLIC
PROC[v: Viewer]
RETURNS[msName:
ROPE] = {
of v is a Viewer for a Walnut Entity, then return its name else NIL
msName ← NARROW[ViewerOps.FetchProp[v, $WalnutMsgSetName]];
IF msName = NIL THEN WalnutWindowInternal.Report[" Not a Walnut Message Set viewer"];
};
QDisplayMsgSet:
PUBLIC
PROC[msb: MsgSetButton, oldV: Viewer, shift:
BOOL, repaint:
BOOL]
RETURNS[v: Viewer] = {
IF oldV =
NIL
THEN {
IF msb = NIL THEN RETURN[NIL]; -- no such msgSet
oldV ← msb.msViewer };
IF oldV #
NIL
THEN
IF oldV.destroyed THEN oldV ← msb.msViewer ← NIL;
v ← MSViewer[msb: msb, oldV: oldV, shift: shift];
msb.msViewer ← v;
};
AddNewMsgsToActive:
PUBLIC
PROC[active: MsgSetButton]
RETURNS[responses: LIST OF WalnutOps.ServerInfo, complete: BOOL, numNew: INT] = {
activeV: Viewer = active.msViewer;
msI: MsgSetInfo;
NewMsgProc:
PROC[msg, TOCentry:
ROPE, startOfSubject:
INT] = {
numNew ← numNew + 1;
BuildMsgLineViewer[msI, CreateMsgInfo[msg, FALSE, TOCentry, startOfSubject]];
};
numNew ← 0;
IF activeV =
NIL
OR activeV.destroyed
THEN {
numNew ← -1; -- don't know, won't count
[responses, complete] ← WalnutOps.GetNewMail[WalnutDefs.dontCareMsgSetVersion, NIL];
IF ~complete THEN RETURN;
WalnutOps.AcceptNewMail[WalnutDefs.dontCareMsgSetVersion];
RETURN
};
msI ← NARROW[ViewerOps.FetchProp[activeV, $MsgSetInfo]];
[responses, complete] ← WalnutOps.GetNewMail[active.msgSet.version, NewMsgProc];
IF ~complete THEN RETURN;
WalnutOps.AcceptNewMail[active.msgSet.version];
active.msgSet.version ← active.msgSet.version+1
};
MSViewer:
PROC[msb: MsgSetButton, oldV: Viewer, shift:
BOOL]
RETURNS[msV: Viewer] = {
OPEN WalnutWindowInternal;
iconic: BOOL ← FALSE;
whichSide: ViewerClasses.Column ← left;
msgSet: MsgSet = msb.msgSet;
caption: ROPE = Rope.Concat[msgSet.name, " Messages"];
msI: MsgSetInfo;
IF msgSet.name.Equal[WalnutOps.ActiveMsgSetName,
FALSE]
THEN {
iconic ← initialActiveIconic AND initialActiveOpen;
IF initialActiveRight THEN whichSide ← right
};
IF oldV # NIL THEN IF oldV.destroyed THEN oldV ← NIL;
IF oldV #
NIL
THEN
{ oldMsgSetName:
ROPE =
NARROW[ViewerOps.FetchProp[oldV, $WalnutMsgSetName]];
msI ← NARROW[ViewerOps.FetchProp[oldV, $MsgSetInfo]];
oldV.inhibitDestroy ← TRUE;
IF ~Rope.Equal[msgSet.name, oldMsgSetName,
FALSE]
THEN {
oldV.name ← caption;
WalnutWindowInternal.GetButton[oldMsgSetName].msViewer ← NIL;
WalnutWindowInternal.GetButton[msgSet.name].msViewer ← oldV }
ELSE {
-- check the version to see if all's well
IF msI.button.msgSet.version = WalnutOps.MsgSetExists[
msgSet.name, WalnutWindowInternal.msgSetsVersion].version
THEN {
oldV.inhibitDestroy ← FALSE;
RETURN[oldV]
}
};
ViewerOps.DestroyViewer[msI.tiogaViewer];
msI.selected ← NIL;
msI.lastMFH ← NIL;
msI.tiogaViewer ← NIL;
msV ← oldV;
}
ELSE {
msV ← ViewerOps.CreateViewer[
flavor: $Container,
info: [name: caption, column: whichSide, menu:
NIL,
iconic: iconic, icon: msgSetIcon, scrollable: FALSE, inhibitDestroy: TRUE]];
msI ← NEW[MsgSetInfoRec];
msI.button ← msb;
msI.container ← msV;
msI.destroyER ←
ViewerEvents.RegisterEventProc[DestroyMSViewer, destroy, msV, TRUE];
IF msI.tiogaViewer =
NIL
THEN {
width:
INT ←
IF msV.column = right THEN ViewerSpecs.openRightWidth ELSE
ViewerSpecs.openLeftWidth;
msI.tiogaViewer ← TiogaButtons.CreateViewer[
info: [parent: msV, border: FALSE, ww: width, wh: ViewerSpecs.bwScreenHeight]];
TiogaButtons.SetStyleFromRope[v: msI.tiogaViewer, styleRope: msgSetStyle];
Containers.ChildXBound[msV, msI.tiogaViewer];
Containers.ChildYBound[msV, msI.tiogaViewer];
};
ViewerOps.AddProp[msV, $MsgSetInfo, msI];
Nut.SetNutInfo[msV, $Walnut, "MsgSet", msgSet.name];
ViewerOps.AddProp[msV, $WalnutMsgSetName, msgSet.name];
ViewerOps.AddProp[msV, $IconLabel, msgSet.name];
MsgSetInViewer[msgSet, msI, shift];
};
msgSetStyle:
ROPE ← "BeginStyle
(Cedar) AttachStyle
(header) \"a message header\" {
default
200 pt restIndent
} StyleRule
DestroyMSViewer: ViewerEvents.EventProc = {
msI: MsgSetInfo = NARROW[ViewerOps.FetchProp[viewer, $MsgSetInfo]];
msI.button.msgSet.version ← WalnutDefs.dontCareMsgSetVersion;
msI.button.msViewer ← NIL;
ViewerEvents.UnRegisterEventProc[msI.destroyER, destroy];
};
MsgSetInViewer:
PROC[msgSet: MsgSet, msI: MsgSetInfo, shift:
BOOL] = {
OPEN ViewerOps;
firstUnread, last: INT;
autoScroll: BOOL = UserProfile.Boolean[key: "Walnut.AutoScrollMsgSets", default: TRUE];
v: Viewer = msI.tiogaViewer;
parent: Viewer = v.parent;
menu: Menus.Menu ←
IF WalnutWindowInternal.readOnlyAccess
THEN readOnlyMenu
ELSE
IF msgSet.name.Equal[WalnutOps.ActiveMsgSetName,
FALSE]
THEN
IF WalnutWindowInternal.personalMailDB
THEN activeMenu
ELSE displayerMenu
ELSE
IF msgSet.name.Equal[WalnutOps.DeletedMsgSetName, FALSE] THEN deletedMenu ELSE displayerMenu;
ScrollMsgSet:
PROC = {
IF autoScroll
AND last#-1
THEN
{
IF v.parent.iconic
THEN
{ scroll: ViewerEvents.EventRegistration ←
ViewerEvents.RegisterEventProc[AutoScroll, open, v.parent, FALSE];
after
ViewerOps.AddProp[v.parent, $autoScroll,
NEW[AutoScrollObject ← [scroll, v, firstUnread, last]]];
}
ELSE DoScroll[v, firstUnread, last];
};
SetMenu[parent, menu];
};
[] ← v.class.scroll[v, thumb, 0]; -- position at beginning
IF ~parent.iconic THEN ComputeColumn[parent.column, TRUE];
parent.newVersion ← TRUE; PaintViewer[parent, caption];
SetMenu[parent, buildingMenu];
[firstUnread, last] ← FillInMsgSetWindow[msI, msgSet.name];
ScrollMsgSet[];
ViewerLocks.CallUnderWriteLock[ScrollMsgSet, v];
parent.newVersion ← FALSE; PaintViewer[parent, caption];
IF shift
THEN
{ IF parent.iconic THEN ViewerOps.OpenIcon[parent, shift] ELSE ViewerOps.GrowViewer[parent]};
parent.inhibitDestroy ← FALSE;
};
called with parent & MsgSetFieldHandle 'displaying' msg to be deleted
RemoveFromDisplayedMsgSet:
PROC[msI: MsgSetInfo, msViewer: Viewer, mfH: MsgSetFieldHandle] = {
prev, next: MsgSetFieldHandle;
bt: TiogaButton;
selected: MsgSetFieldHandle ← msI.selected;
bt ← mfH.iButton;
IF selected = mfH
THEN
TiogaButtons.ChangeButtonLooks[
button: bt, addLooks: tocDefaultLooks, removeLooks: tocSelectedLooks];
prev ← mfH.prev;
next ← mfH.next;
take which out of chain of mfh's
IF prev # NIL THEN prev.next ← next;
IF next # NIL THEN next.prev ← prev;
TiogaButtons.DeleteButton[bt];
IF selected = mfH
THEN {
msI.selected ← next;
IF next #
NIL
THEN
TiogaButtons.ChangeButtonLooks[
button: next.iButton, addLooks: tocSelectedLooks, removeLooks: tocDefaultLooks];
};
IF msI.lastMFH = mfH THEN msI.lastMFH ← prev;
msI.button.msgSet.version ← msI.button.msgSet.version+1;
};