VoiceEditInterceptImpl.mesa:
routines to pick up edit events which affect voice viewers and pass control away from normal tioga actions.
Ades, April 22, 1986 9:26:57 pm PST
This code stinks for a number of reasons
i) it only picks up a subset of the events which could affect a voice viewer
ii) it SHARES an Impl !!!!!!! - TEditInputImpl to be precise. This occurs only in InterceptEdit, for reasons explained above that procedure
iii) it redefines the 'notify proc' for the $Text class!! - it does exactly what the ousted notify proc would do in the case of non-voice viewers, by calling a TEditInputImpl procedure. At the cost of another procedure call it could be more clean my saving the ousted procedure and calling that, but since I've had to import the Impl anyhow . . . .
The way things should be is that either an equivalent package to tioga is produced specially for voice editing windows or TEditInputOps is rewritten to call TiogaVoice code for viewers managed by TiogaVoice [detectable from the properties that those viewers have].
DIRECTORY
Commander USING [CommandProc, Register],
MessageWindow USING [Clear],
SourceMarkerTracking USING [TrackDeletes],
TEditDocument USING [SelectionId],
ViewerClasses USING [Viewer, NotifyProc, ViewerClass],
ViewerOps USING [FetchProp, FetchViewerClass],
VoiceEditOps USING [Delete, Copy, Transpose, Mumble],
VoiceMarkers USING [TextInput, BackSpace, BackWord],
Rope USING [ROPE, FromChar, FromRefText],
TEditInput USING [CommandProc, Register, UnRegister, editState, RecordRef],
TEditInputImpl USING [editObject, pdelState, pDel, sel, selState, mouseColor, editMessage, InterpInput],
TEditInputOps USING [Delete, Copy, CopyFormat, CopyLooks, Transpose, TransposeLooks, TransposeFormat],
TEditSelection USING [pSel, sSel, MakeSelection],
TiogaOps USING [GetSelection];
VoiceEditInterceptImpl: CEDAR PROGRAM IMPORTS Commander, MessageWindow, SourceMarkerTracking, TEditInput, TEditInputImpl, TEditInputOps, TEditSelection, TiogaOps, VoiceEditOps, VoiceMarkers, Rope, ViewerOps SHARES TEditInputImpl = BEGIN
InterceptAllInput: ViewerClasses.NotifyProc = {
IF ViewerOps.FetchProp[self, $voiceViewerInfo] = NIL
THEN TEditInputImpl.InterpInput[self, input] -- just what the real one does
ELSE
{ passOnList, endOfPassOnList:
LIST
OF
REF
ANY ←
NIL;
FOR currItem:
LIST
OF
REF
ANY ← input, currItem.rest
WHILE currItem #
NIL
DO
WITH currItem.first
SELECT
FROM
z: REF CHAR =>
{
IF passOnList #
NIL
THEN
{ TEditInputImpl.InterpInput[self, passOnList];
passOnList ← NIL
};
VoiceMarkers.TextInput[self, Rope.FromChar[z^]]
};
z: Rope.ROPE =>
{
IF passOnList #
NIL
THEN
{ TEditInputImpl.InterpInput[self, passOnList];
passOnList ← NIL
};
VoiceMarkers.TextInput[self, z]
};
z: REF TEXT =>
{
IF passOnList #
NIL
THEN
{ TEditInputImpl.InterpInput[self, passOnList];
passOnList ← NIL
};
VoiceMarkers.TextInput[self, Rope.FromRefText[z]]
};
ENDCASE =>
IF passOnList = NIL
THEN
{ passOnList ←
CONS[currItem.first,
NIL];
endOfPassOnList ← passOnList
}
ELSE
{ endOfPassOnList.rest ←
CONS[currItem.first,
NIL];
endOfPassOnList ← endOfPassOnList.rest
}
ENDLOOP;
IF passOnList # NIL THEN TEditInputImpl.InterpInput[self, passOnList]
}
};
InterceptBackSpace: TEditInput.CommandProc = {
IF TestPrimary[] = normal THEN RETURN;
VoiceMarkers.BackSpace[viewer];
RETURN [quit: TRUE]
};
InterceptBackWord: TEditInput.CommandProc = {
IF TestPrimary[] = normal THEN RETURN;
VoiceMarkers.BackWord[viewer];
RETURN [quit: TRUE]
};
InterceptDelete: TEditInput.CommandProc = {
IF TestPrimary[] = normal
THEN SourceMarkerTracking.TrackDeletes[]
ELSE
{ VoiceEditOps.Delete[];
RETURN [quit: TRUE]
};
};
InterceptEdit: TEditInput.CommandProc = {
this part of the code is extremely sordid: it really needs to be in TEditInputImpl and for that reason it references private variables from TEditInputImpl 23 times: it gets called in front of the Tioga DoEdit procedure and returns quit=FALSE under all circumstances in order to prevent the real one ever being called
quit ← TRUE;
IF TEditSelection.pSel.viewer =
NIL
THEN {
IF TEditSelection.sSel.viewer # NIL THEN TEditSelection.MakeSelection[NIL,secondary]; -- get rid of secondary
recordAtom ← FALSE }
ELSE
IF TEditInput.editState = tolimbo
THEN {
recordAtom ← FALSE; TEditInput.RecordRef[$Delete]; CheckDelete[TRUE] }
ELSE IF TEditSelection.sSel.viewer = NIL THEN recordAtom ← FALSE
ELSE {
RecordEditObject:
PROC = {
TEditInput.RecordRef[
SELECT TEditInputImpl.editObject
FROM
text => $EditText,
looks => $EditLooks,
format => $EditFormat,
ENDCASE => ERROR] };
recordAtom ← TRUE;
SELECT TEditInput.editState
FROM
reset, abort => recordAtom ← FALSE;
toprimary => {
TEditInput.RecordRef[$GetSecondary];
TEditInput.RecordRef[$ToPrimary];
RecordEditObject[];
SELECT TEditInputImpl.editObject FROM
text => {
IF TEditSelection.pSel.pendingDelete THEN TEditInput.RecordRef[$MakePDel];
CheckCopy[primary] };
looks => CheckCopyLooks[primary];
format => CheckCopyFormat[primary];
ENDCASE => ERROR };
tosecondary => {
TEditInput.RecordRef[$GetSecondary];
TEditInput.RecordRef[$ToSecondary];
RecordEditObject[];
SELECT TEditInputImpl.editObject FROM
text => {
IF TEditSelection.pSel.pendingDelete THEN TEditInput.RecordRef[$MakePDel];
CheckCopy[secondary] };
looks => CheckCopyLooks[secondary];
format => CheckCopyFormat[secondary];
ENDCASE => ERROR };
toboth => {
TEditInput.RecordRef[$GetSecondary];
TEditInput.RecordRef[$ToBoth];
RecordEditObject[];
SELECT TEditInputImpl.editObject FROM
text => CheckTranspose[];
looks => CheckTransposeLooks[];
format => CheckTransposeFormat[];
ENDCASE => ERROR };
ENDCASE => ERROR };
TEditInput.editState ← reset; TEditInputImpl.editObject ← text;
TEditInputImpl.pdelState ← reset; TEditInputImpl.pDel ← FALSE; TEditInputImpl.selState ← reset; TEditInputImpl.sel ← primary;
TEditInputImpl.mouseColor ← red; -- put these back to normal
IF TEditInputImpl.editMessage # NIL THEN MessageWindow.Clear[];
TEditInputImpl.editMessage ← NIL };
selectionTypes: TYPE = {bothNormal, primaryVoice, secondaryVoice, bothVoice};
TestSelections:
PROC
RETURNS [types: selectionTypes] = {
types ← IF ViewerOps.FetchProp[TiogaOps.GetSelection[primary].viewer, $voiceViewerInfo] = NIL THEN
( IF ViewerOps.FetchProp[TiogaOps.GetSelection[secondary].viewer, $voiceViewerInfo] = NIL THEN bothNormal ELSE secondaryVoice )
ELSE
( IF ViewerOps.FetchProp[TiogaOps.GetSelection[secondary].viewer, $voiceViewerInfo] = NIL THEN primaryVoice ELSE bothVoice )
};
primaryType: TYPE = {normal, voice};
TestPrimary:
PROC
RETURNS [type: primaryType] = {
type ← IF ViewerOps.FetchProp[TiogaOps.GetSelection[primary].viewer, $voiceViewerInfo] = NIL THEN normal ELSE voice
};
CheckDelete: PROC [saveForPaste: BOOL ← TRUE] = {
this and the following series of 'Check' procedures test if the proposed edit is applied to normal text: if so they first call the appropriate SourceMarkerTracking routine and then pass control to TEditInputOps [just like TEditInputImpl.DoEdit always would], otherwise they pass control to VoiceEditOps
SELECT TestPrimary[]
FROM
normal =>
{ SourceMarkerTracking.TrackDeletes[];
TEditInputOps.Delete[saveForPaste]
};
voice => VoiceEditOps.Delete[]
ENDCASE
CheckCopy:
PROC [target: TEditDocument.SelectionId ← primary] = {
SELECT TestSelections[]
FROM
bothNormal => TEditInputOps.Copy[target];
bothVoice => VoiceEditOps.Copy[target];
ENDCASE => VoiceEditOps.Mumble["Copy", "voice and text"]
};
CheckCopyFormat:
PROC [target: TEditDocument.SelectionId ← primary] = {
SELECT TestSelections[]
FROM
bothNormal => TEditInputOps.CopyFormat[target];
bothVoice => VoiceEditOps.Mumble["Copy format", "two voice"]
ENDCASE => VoiceEditOps.Mumble["Copy format", "voice and text"]
};
CheckCopyLooks:
PROC [target: TEditDocument.SelectionId ← primary] = {
SELECT TestSelections[]
FROM
bothNormal => TEditInputOps.CopyLooks[target];
bothVoice => VoiceEditOps.Mumble["Copy looks", "two voice"]
ENDCASE => VoiceEditOps.Mumble["Copy looks", "voice and text"]
};
CheckTranspose:
PROC [target: TEditDocument.SelectionId ← primary] = {
SELECT TestSelections[]
FROM
bothNormal => TEditInputOps.Transpose[target];
bothVoice => VoiceEditOps.Transpose[target];
ENDCASE => VoiceEditOps.Mumble["Transpose", "voice and text"]
};
CheckTransposeFormat:
PROC [target: TEditDocument.SelectionId ← primary] = {
SELECT TestSelections[]
FROM
bothNormal => TEditInputOps.TransposeFormat[target];
bothVoice => VoiceEditOps.Mumble["Transpose format", "two voice"]
ENDCASE => VoiceEditOps.Mumble["Transpose format", "voice and text"]
};
CheckTransposeLooks:
PROC [target: TEditDocument.SelectionId ← primary] = {
SELECT TestSelections[]
FROM
bothNormal => TEditInputOps.TransposeLooks[target];
bothVoice => VoiceEditOps.Mumble["Transpose looks", "two voice"]
ENDCASE => VoiceEditOps.Mumble["Transpose looks", "voice and text"]
};
textClassDescriptor: ViewerClasses.ViewerClass ← ViewerOps.FetchViewerClass[$Text];
realNotifyProc: ViewerClasses.NotifyProc ← textClassDescriptor.notify;
this just whilst under development . . .
HereWeGoAgain: Commander.CommandProc = {
textClassDescriptor: ViewerClasses.ViewerClass ← ViewerOps.FetchViewerClass[$Text];
textClassDescriptor.notify ← realNotifyProc;
TEditInput.UnRegister[$BackSpace, InterceptBackSpace];
TEditInput.UnRegister[$BackWord, InterceptBackWord];
TEditInput.UnRegister[$Delete, InterceptDelete];
TEditInput.UnRegister[$DoEdit, InterceptEdit];
};
Commander.Register[key: "ReadyToRoll", proc: HereWeGoAgain, doc: "ReadyToRoll: do it before running this again!"];
TEditInput.Register[$BackSpace, InterceptBackSpace];
TEditInput.Register[$BackWord, InterceptBackWord];
TEditInput.Register[$Delete, InterceptDelete];
TEditInput.Register[$DoEdit, InterceptEdit];
stand back - this is the dangerous bit . . .
textClassDescriptor.notify ← InterceptAllInput;
END.