DIRECTORY
BasicTime USING [Now],
Commander USING [CommandProc, Handle, Register],
CommanderOps USING [NextArgument],
Containers,
FileNames USING [ConvertToSlashFormat],
FS USING [ComponentPositions, Error, ExpandName, PagesForBytes],
Icons USING [IconFlavor, NewIconFromFile],
IO,
MailBasics USING [RNameList],
Menus,
PFS USING [GetWDir, RopeFromPath],
Process USING [Detach],
Rope,
Rules USING [Create],
SendMailOps USING [userRNameList, ChangeUserRNameList, IsThisTheCurrentUser],
SystemNames USING [UserName],
TBQueue USING [Queue, Create, QueueClientAction],
UserProfile USING [Boolean, Token],
ViewerClasses USING [Column, Viewer],
ViewerEvents USING [EventProc, EventRegistration, RegisterEventProc],
ViewerOps,
ViewerSpecs USING[openLeftWidth, openTopY, openRightWidth],
WalnutDefs USING [Error],
WalnutOps USING [LogLength, MsgSet, dontCareMsgSetVersion, CopyToExpungeLog, CreateWalnutOpsHandle, ExpungeMsgs, ReadArchiveFile, Shutdown, ValidOpsHandle],
WalnutViewer USING [FirstLabel, tiogaButtonHeight, MakeRuler, MakeTypescript],
WalnutInternal USING [blankMenu, BuildWalnutMenus, ChangeMenu, CreateMsgMenu, CreateMsgSetMenus, DestroyAllMsgSetButtons, DisableNewMail, displayMsgSetInIcon, DoArchive, DoWaitCall, DoStartupCall, FlushWQueue, GetButton, HowToPrint, OpenTS, QDisplayMsgSet, QuitWalnut, RestartWalnut, ShowMsgSetButtons, TakeDownWalnutViewers, WalnutNotifier, workingMenu],
WalnutRegistryPrivate USING [NotifyForEvent],
WalnutWindowPrivate USING [MsgSetButton, WalnutHandle, WalnutHandleRec, WalnutIcons, WalnutIconsRec],
WalnutWindow USING [GetNewMail, OutCome, Report, ReportFormat],
WalnutWindowSidedoor
USING [];
WalnutWindowCommandsImpl:
CEDAR
MONITOR
IMPORTS
FS, PFS,
BasicTime, Commander, CommanderOps,
Containers, FileNames, Icons, Rules, TBQueue,
IO, Process, Rope, SendMailOps,
SystemNames, UserProfile,
ViewerEvents, ViewerOps, ViewerSpecs,
WalnutDefs, WalnutOps, WalnutRegistryPrivate,
WalnutInternal, WalnutViewer, WalnutWindow
EXPORTS WalnutInternal, WalnutWindow, WalnutWindowSidedoor =
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
Viewer: TYPE = ViewerClasses.Viewer;
tiogaButtonHeight: INTEGER = WalnutViewer.tiogaButtonHeight;
MsgSetButton: TYPE = WalnutWindowPrivate.MsgSetButton;
WalnutHandle: TYPE = WalnutWindowPrivate.WalnutHandle;
WalnutHandleRec: PUBLIC TYPE = WalnutWindowPrivate.WalnutHandleRec;
HowToPrint: TYPE = WalnutInternal.HowToPrint;
InitialNotifyLabel:
PUBLIC
ROPE ¬
" ";
walnutVersion: ROPE = "Walnut 7.1";
msgSetIcon: PUBLIC Icons.IconFlavor ¬ tool;
msgIcon: PUBLIC Icons.IconFlavor ¬ tool;
labelledWalnutIcons: PUBLIC WalnutWindowPrivate.WalnutIcons;
unLabelledWalnutIcons: PUBLIC WalnutWindowPrivate.WalnutIcons;
alternateWalnutIcons: PUBLIC WalnutWindowPrivate.WalnutIcons;
iconFilePathName: PUBLIC ROPE ¬ NIL;
previousUser: PUBLIC ROPE ¬ NIL;
gettingOrganized: PUBLIC BOOL ¬ FALSE;
readyToGo: PUBLIC CONDITION;
initialActiveIconic: PUBLIC BOOL ¬ FALSE;
initialActiveRight: PUBLIC BOOL ¬ TRUE;
initialActiveOpen: PUBLIC BOOL ¬ TRUE;
walnutHandleList: LIST OF WalnutHandle;
invocationDirectory: PUBLIC ROPE ¬ PFS.RopeFromPath[PFS.GetWDir[]];
searchRules: PUBLIC LIST OF REF ANY;
* * * * * * * * * * exported to WalnutWindow - these all wait for completion
StartUp:
PUBLIC
PROC[rootFile:
ROPE, dontDoMail:
BOOL ¬
FALSE]
RETURNS[wH: WalnutHandle] = {
wA: WalnutArgs = ParseCmdLine[NIL, rootFile];
wH ¬ GetHandleForRootFile[wA.rootName];
IF wH # NIL AND wH.walnut # NIL THEN RETURN[NIL];
wH ¬ CreateNewHandle[wA];
DoStartup[wH, FALSE, wA]
};
Expunge:
PUBLIC PROC[wH: WalnutHandle] = {
Ep:
PROC = {
ENABLE UNWIND => { ChangeMenu[wH, wH.walnutMenu, FALSE] };
ok: BOOL ¬ TRUE;
didCopy: BOOL ¬ FALSE;
exp: ROPE;
Quitting[wH, TRUE];
WalnutWindow.ReportFormat[wH, "\n****** Starting expunge at %g\n", [time[BasicTime.Now[]]] ];
BEGIN
ENABLE
ABORTED => { ok ¬
FALSE;
CONTINUE };
bytesInDestroyedMsgs:
INT =
WalnutOps.ExpungeMsgs[wH.opsH, WalnutOps.dontCareMsgSetVersion];
IF bytesInDestroyedMsgs = 0
THEN
WalnutWindow.Report[wH, "No messages were expunged - log rewrite not done"]
ELSE didCopy ¬ WalnutOps.CopyToExpungeLog[wH.opsH];
IF ~ok
THEN
WalnutWindow.Report[wH,
"\n***** Expunge failed or aborted; some changes have been aborted"];
IF didCopy
THEN {
len: INT = WalnutOps.LogLength[wH.opsH];
WalnutWindow.ReportFormat[wH, "Log length is now %g bytes (%g pages)\n",
[integer[len]], [integer[FS.PagesForBytes[len]]] ];
WalnutWindow.ReportFormat[wH, "***** Expunge complete at %g\n",
[time[BasicTime.Now[]]] ];
}
ELSE WalnutWindow.Report[wH, exp];
WalnutOps.Shutdown[wH.opsH];
IF ~RestartWalnut[wH: wH, scavengeFirst: FALSE, firstTime: TRUE] THEN RETURN;
ChangeMenu[wH, wH.walnutMenu, FALSE];
};
[] ¬ DoWaitCall[wH, Ep];
};
Scavenge:
PUBLIC
PROC[rootFile:
ROPE, dontDoMail:
BOOL]
RETURNS[wH: WalnutHandle]= {
wA: WalnutArgs ¬ ParseCmdLine[NIL, rootFile];
IF wA.rootName = NIL THEN RETURN;
wA.dontDoMail ¬ dontDoMail;
DoScavenge[wA];
RETURN[GetHandleForRootFile[wA.rootName]];
};
WriteArchiveFile:
PUBLIC
PROC[wH: WalnutHandle, fileName:
ROPE, msgSetList:
LIST
OF
ROPE] = {
Waf:
PROC = {
msList: LIST OF WalnutOps.MsgSet;
FOR mL:
LIST
OF
ROPE ¬ msgSetList, mL.rest
UNTIL mL =
NIL
DO
msList ¬ CONS[ [mL.first, WalnutOps.dontCareMsgSetVersion], msList];
ENDLOOP;
[] ¬ DoArchive[wH: wH, fileName: fileName, msList: msList, append: FALSE] };
[] ¬ DoWaitCall[wH, Waf];
};
GetHandleList:
PUBLIC
ENTRY
PROC
RETURNS[
LIST
OF WalnutHandle] = {
ENABLE UNWIND => NULL;
RETURN[walnutHandleList]
};
GetHandleForRootFile:
PUBLIC
ENTRY
PROC[rootFile:
ROPE]
RETURNS[wH: WalnutHandle] = {
ENABLE UNWIND => NULL;
fullName: ROPE ¬ FS.ExpandName[rootFile].fullFName;
FOR whL:
LIST
OF WalnutHandle ¬ walnutHandleList, whL.rest
UNTIL whL =
NIL
DO
IF fullName.Equal[whL.first.opsH.rootName, FALSE] THEN RETURN[whL.first];
ENDLOOP;
};
GetHandleForSegment:
PUBLIC
ENTRY
PROC[segment:
ATOM]
RETURNS[wH: WalnutHandle] = {
ENABLE UNWIND => NULL;
FOR whL: LIST OF WalnutHandle ← walnutHandleList, whL.rest UNTIL whL = NIL DO
IF whL.first.opsH.segmentID.segment = segment THEN RETURN[whL.first];
ENDLOOP;
};
GetHandleForMail:
PUBLIC
ENTRY
PROC
RETURNS[wH: WalnutHandle] = {
ENABLE UNWIND => NULL;
FOR whL:
LIST
OF WalnutHandle ¬ walnutHandleList, whL.rest
UNTIL whL =
NIL
DO
IF whL.first.personalMailDB THEN RETURN[whL.first];
ENDLOOP
};
GetRootFileForHandle:
PUBLIC
PROC[wH: WalnutHandle]
RETURNS[rootFile:
ROPE] =
{ IF wH.opsH # NIL THEN RETURN[wH.opsH.rootName] };
GetSegmentForHandle:
PUBLIC
PROC[wH: WalnutHandle]
RETURNS[segment:
ATOM] = {
IF wH.opsH # NIL THEN RETURN[wH.opsH.segmentID.segment]
};
GetHandleForViewer:
PUBLIC
ENTRY
PROC[v: ViewerClasses.Viewer]
RETURNS[wH: WalnutHandle] = {
ENABLE UNWIND => NULL;
CheckList:
PROC[vL:
LIST
OF Viewer]
RETURNS[found:
BOOL ¬
FALSE] = {
FOR xL:
LIST
OF Viewer ¬ vL, xL.rest
UNTIL xL =
NIL
DO
IF xL.first = thisV THEN RETURN[TRUE];
ENDLOOP;
};
thisV: Viewer ¬ v;
UNTIL thisV.parent = NIL DO thisV ¬ thisV.parent; ENDLOOP; -- top
FOR whL:
LIST
OF WalnutHandle ¬ walnutHandleList, whL.rest
UNTIL whL =
NIL
DO
IF whL.first.walnut = thisV THEN RETURN[whL.first];
IF CheckList[whL.first.msgSetViewerList] THEN RETURN[whL.first];
IF CheckList[whL.first.msgViewerList] THEN RETURN[whL.first];
IF CheckList[whL.first.wallabyViewerList] THEN RETURN[whL.first];
ENDLOOP;
RETURN[NIL];
};
IsHandleActive: PUBLIC ENTRY PROC[wH: WalnutHandle]
RETURNS[yes: BOOL] = { RETURN[wH.walnut # NIL] };
* * * * * * * * * * * * local procedures
WalnutArgs: TYPE = REF WalnutArgsRec;
WalnutArgsRec:
TYPE =
RECORD[
dirName, rootName, captionName, rootUserName, baseRootName: ROPE,
dontDoMail, userAskedForReadOnly, masContinue: BOOL ¬ FALSE,
dontUseNumber: BOOL ¬ FALSE
];
ParseCmdLine:
PROC[cmd: Commander.Handle, nameArg:
ROPE ¬
NIL]
RETURNS[wA: WalnutArgs] = {
cp: FS.ComponentPositions;
arg, rName: ROPE;
defaultPattern: ROPE = "[Luther.alpine]<%g>Walnut.Root";
user: ROPE ¬ SystemNames.UserName[];
wA ¬ NEW[WalnutArgsRec];
IF cmd #
NIL
THEN {
arg ¬ CommanderOps.NextArgument[cmd];
IF arg #
NIL
THEN
IF arg.Fetch[0] = '-
THEN {
SELECT arg.Fetch[1]
FROM
'c => wA.masContinue ¬ TRUE;
'n => wA.dontDoMail ¬ TRUE;
'r => wA.userAskedForReadOnly ¬ TRUE;
ENDCASE;
arg ¬ CommanderOps.NextArgument[cmd];
};
}
ELSE arg ¬ nameArg;
wA.dirName ¬ arg;
IF wA.dirName.Length = 0
THEN {
rName ¬ UserProfile.Token[key: "Walnut.WalnutRootFile", default: ""];
IF rName.Length[] = 0 THEN rName ¬ IO.PutFR1[defaultPattern, [rope[user]] ];
wA.captionName ¬ walnutVersion;
wA.dontUseNumber ¬ TRUE;
}
ELSE {
SELECT wA.dirName.Fetch[0]
FROM
'[, '/ => rName ¬ wA.dirName;
ENDCASE => rName ¬ IO.PutFR1[defaultPattern, [rope[wA.dirName]] ];
wA.captionName ¬ Rope.Cat[walnutVersion, " {", wA.dirName, "}"];
};
[wA.rootName, cp, ] ¬ FS.ExpandName[rName, NIL];
IF cp.ext.length = 0 THEN wA.rootName ¬ wA.rootName.Concat[".Root"];
wA.rootUserName ¬ wA.rootName.Substr[cp.dir.start, cp.dir.length];
wA.baseRootName ¬ FileNames.ConvertToSlashFormat[wA.rootName.Substr[0, cp.ext.start-1]];
};
DoStartup:
PROC[wH: WalnutHandle, scavengeFirst:
BOOL, wA: WalnutArgs] = {
Su:
PROC[
BOOL] = {
BuildWalnutControlWindow[wH, wA.captionName];
IF ~RestartWalnut[
wH: wH, scavengeFirst: scavengeFirst, firstTime: TRUE] THEN RETURN;
WalnutWindow.Report[wH, "\n ...Ready"];
};
IF DoStartupCall[wH, Su] # flushed
THEN {
AddGoodHandle[wH];
};
};
startScavMsg: ROPE = "\n ***** Starting scavenge @ %g, using rootFile %g ";
endScavMsg: ROPE = "\n ***** Scavenge finished @ %g\n";
DoScavenge:
PROC[wA: WalnutArgs] = {
Sp:
PROC[isRunning:
BOOL] = {
ENABLE UNWIND => { ChangeMenu[wH, wH.walnutMenu, FALSE] };
IF isRunning
THEN {
Quitting[wH, TRUE];
WalnutOps.Shutdown[wH.opsH];
WalnutWindow.ReportFormat[wH, startScavMsg, [time[BasicTime.Now[]]], [rope[wA.rootName]] ];
wH.walnut.name ¬ wA.captionName;
ViewerOps.PaintViewer[wH.walnut, caption];
IF ~RestartWalnut[wH: wH, scavengeFirst:
TRUE, firstTime:
FALSE]
THEN RETURN;
WalnutWindow.ReportFormat[wH, endScavMsg, [time[BasicTime.Now[]]] ];
ChangeMenu[wH, wH.walnutMenu, FALSE];
}
ELSE {
BuildWalnutControlWindow[wH, wA.captionName];
IF ~RestartWalnut[
wH: wH, scavengeFirst: TRUE, firstTime: TRUE] THEN RETURN;
WalnutWindow.Report[wH, "\n ...Ready"];
};
};
wH: WalnutHandle ¬ GetHandleForRootFile[wA.rootName];
IF wH = NIL THEN wH ¬ CreateNewHandle[wA];
IF DoStartupCall[wH, Sp] # flushed
THEN {
AddGoodHandle[wH];
};
};
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
InitIcons:
PROC = {
iconFilePathName: ROPE = "Walnut.icons";
one: Icons.IconFlavor;
labelledWalnutIcons ¬ NEW[WalnutWindowPrivate.WalnutIconsRec];
unLabelledWalnutIcons ¬ NEW[WalnutWindowPrivate.WalnutIconsRec];
alternateWalnutIcons ¬ NEW[WalnutWindowPrivate.WalnutIconsRec];
one ¬ Icons.NewIconFromFile[iconFilePathName, 0 ! FS.Error => GOTO notFound];
unLabelledWalnutIcons[regular] ¬ one;
unLabelledWalnutIcons[haveNewMail] ¬ Icons.NewIconFromFile[iconFilePathName, 5];
unLabelledWalnutIcons[expunging] ¬ Icons.NewIconFromFile[iconFilePathName, 3];
unLabelledWalnutIcons[broken] ¬ Icons.NewIconFromFile[iconFilePathName, 14];
labelledWalnutIcons[regular] ¬ Icons.NewIconFromFile[iconFilePathName, 11];
labelledWalnutIcons[haveNewMail] ¬ Icons.NewIconFromFile[iconFilePathName, 12];
labelledWalnutIcons[broken] ¬ unLabelledWalnutIcons[broken];
alternateWalnutIcons[regular] ¬ Icons.NewIconFromFile[iconFilePathName, 15];
alternateWalnutIcons[haveNewMail] ¬ Icons.NewIconFromFile[iconFilePathName, 16];
alternateWalnutIcons[expunging] ¬ Icons.NewIconFromFile[iconFilePathName, 17];
alternateWalnutIcons[broken] ¬ Icons.NewIconFromFile[iconFilePathName, 18];
msgSetIcon¬ Icons.NewIconFromFile[iconFilePathName, 1];
msgIcon¬ Icons.NewIconFromFile[iconFilePathName, 2];
};