-- EditToolTopImpl.mesa; Edited by Paxton on February 8, 1982 9:50 am

DIRECTORY -- a lot of extra junk in this list
  EditToolPrivate,
  Buttons,
  Convert,
  EditNotify,
  Inline,
  IOStream,
  UndoEvent,
  Labels,
  List,
  Menus,
  MessageWindow,
  NodeAddrs,
  Rope,
  RopeEdit,
  RopeReader,
  Rules,
  RunReader,
  Runtime,
  TextEdit,
  TextFind,
  TextLooks,
  TextLooksSupport,
  TextNode,
  TEditDocument,
  TEditInputOps,
  TEditOps,
  TreeFind,
  UserTerminal,
  ViewerOps,
  ViewerClasses,
  ViewerMenus,
  ViewerSpecs,
  ViewerTools;

EditToolTopImpl: PROGRAM

IMPORTS EditToolPrivate, Buttons, Labels, Menus, MessageWindow,
	Rope, Rules, TEditOps, TextEdit, TextNode,
	ViewerSpecs, ViewerMenus, ViewerOps, ViewerTools  
EXPORTS EditToolPrivate =

{ OPEN ViewerSpecs, EditToolPrivate;

Event: TYPE = UndoEvent.Ref;

entryLeft: PUBLIC CARDINAL ← 5;
heightSoFar: PUBLIC CARDINAL ← entryVSpace*2;

container: PUBLIC ViewerClasses.Viewer;
	
BuildContainer: PROC = {
	containerName: Rope.Ref = IF mainEditTool THEN "   Edit  Tool   " ELSE
		"   Edit  Tool  (extra)  ";
	container ← ViewerOps.CreateViewer[flavor: $Container, name: containerName,
		iconic: TRUE, attributes: right, paint: TRUE];
	container.menu ← editToolMenu;
	};

editToolMenu: Menus.Menu ← Menus.CreateMenu[];

BuildEditToolMenu: PROC = {
	Menus.InsertMenuEntry[editToolMenu, "Interrupt", Interrupt];
	Menus.InsertMenuEntry[editToolMenu, "Destroy", MyDestroy];
	Menus.InsertMenuEntry[editToolMenu, "<-->", ViewerMenus.Move];
	Menus.InsertMenuEntry[editToolMenu, "Grow", ViewerMenus.Grow];
	Menus.InsertMenuEntry[editToolMenu, "Close", ViewerMenus.Close];
	};

MyDestroy: Menus.MenuProc = {
	IF mainEditTool THEN {
		TEditOps.UnRegister[editToolAtom];
		UnRegisterSort[]; UnRegisterSubs[]; UnRegisterSearch[] };
	ViewerMenus.Destroy[parent];
	};

interrupt: PUBLIC BOOLEAN ← FALSE;

Interrupt: Menus.MenuProc = {
	interrupt ← TRUE;
	};

----------------------------
----------------------------

ChangeState: PUBLIC PROC [label: Labels.Label, flag: BOOLEAN, trueAtom, falseAtom: ATOM] = {
	TEditOps.InterpretAtom[label,IF ~flag THEN trueAtom ELSE falseAtom] };

BuildPair: PUBLIC PROC [proc: Buttons.ButtonProc, flag: BOOLEAN, l1, l2: Rope.Ref]
	RETURNS [label: Labels.Label, button: Buttons.Button] = {
	fudge: INTEGER = 1;
	xTemp: INTEGER;
	w: INTEGER = MAX[
		ViewerOps.ComputeStringInfo[Rope.ToString[l1]].width,
		ViewerOps.ComputeStringInfo[Rope.ToString[l2]].width];
	button ← Buttons.Create[">> ", proc,
		entryLeft, heightSoFar, 0, 0,
		NIL, FALSE, container, TRUE, FALSE];
	xTemp ← entryLeft+button.ww+gapSize;
	label ← Labels.Create[IF flag THEN l1 ELSE l2, container,
		xTemp, heightSoFar+fudge, w+15, entryHeight, FALSE];
	label.border ← FALSE;
	heightSoFar ← heightSoFar + entryHeight + entryVSpace;
	};

----------------------------

CycleTriple: PUBLIC PROC [label: Labels.Label, state: [0..2], atom0, atom1, atom2: ATOM] = {
	nextState: ARRAY [0..2] OF [0..2] = [1,2,0];
	nextATOM: ARRAY [0..2] OF ATOM = [atom0,atom1,atom2];
	TEditOps.InterpretAtom[label,nextATOM[nextState[state]]] };

BuildTriple: PUBLIC PROC [proc: Buttons.ButtonProc, state: [0..2], l0, l1, l2: Rope.Ref]
	RETURNS [label: Labels.Label, button: Buttons.Button] = {
	fudge: INTEGER = 1;
	w: INTEGER = MAX[
		ViewerOps.ComputeStringInfo[Rope.ToString[l0]].width,
		ViewerOps.ComputeStringInfo[Rope.ToString[l1]].width,
		ViewerOps.ComputeStringInfo[Rope.ToString[l2]].width];
	labelRopes: ARRAY [0..2] OF Rope.Ref = [l0,l1,l2];
	xTemp: INTEGER;
	button ← Buttons.Create[">> ", proc,
		entryLeft, heightSoFar, 0, 0,
		NIL, FALSE, container, TRUE, FALSE];
	xTemp ← entryLeft+button.ww+gapSize;
	label ← Labels.Create[labelRopes[state], container,
		xTemp, heightSoFar+fudge, w+15, entryHeight, FALSE];
	label.border ← FALSE;
	heightSoFar ← heightSoFar + entryHeight + entryVSpace;
	};


----------------------------

----------------------------

emptyPointSelection: ViewerTools.SelPos ← NEW[ViewerTools.SelPosRec];

DataFieldButton: PUBLIC PROC [arg: ViewerClasses.Viewer] = {
	ViewerTools.SetSelection[arg, NIL]; -- make pending delete selection of field contents
	};

BuildDataFieldPair: PUBLIC PROC [buttonRope: Rope.Ref, buttonProc: Buttons.ButtonProc, lines: CARDINAL ← 2]
	RETURNS [button: Buttons.Button, arg: ViewerClasses.Viewer] = {
	xTemp: CARDINAL;
	fudge: CARDINAL = 2;
	button ← Buttons.Create[buttonRope, buttonProc,
		entryLeft, heightSoFar, 0, 0,
		NIL, FALSE, container, FALSE, FALSE];
	button.border ← FALSE;
	xTemp ← entryLeft+scrollBarW+button.ww;
	arg ← ViewerOps.CreateChild[flavor: $Text, parent: container,
		x: xTemp, y: heightSoFar+fudge,
		w: openRightWidth-xTemp-scrollBarW-5,
		h: entryHeight*lines, paint: FALSE];
	arg.border ← FALSE; arg.scrollable ← TRUE;
	heightSoFar ← heightSoFar + entryHeight*lines + entryVSpace;
	TEditOps.SetTextContents[arg, NIL]; -- clear the field
	};

GetDataNode: PUBLIC PROC [arg: ViewerClasses.Viewer] RETURNS [TextNode.RefTextNode] = {
	tdd: TEditDocument.TEditDocumentData = NARROW[arg.data];
	RETURN [TextNode.NarrowToTextNode[TextNode.FirstChild[tdd.text]]] };	

GetDataLooks: PUBLIC PROC [arg: ViewerClasses.Viewer, name: Rope.Ref]
	RETURNS [looks: TextLooks.Looks] = {
	node: TextNode.RefTextNode ← GetDataNode[arg];
	size: TextNode.Offset = TextEdit.Size[node];
	IF size=0 THEN RETURN [TextLooks.noLooks];
	looks ← TextEdit.FetchLooks[node,0];
	FOR i: TextNode.Offset IN [1..size) DO
		IF TextEdit.FetchLooks[node,i]#looks THEN { OPEN MessageWindow;
			Append[name,TRUE];
			Append[" does not have uniform looks.  Using looks from first char."];
			Blink[]; EXIT };
		ENDLOOP };	

----------------------------

HRule: PROC = {
	heightSoFar ← heightSoFar + entryVSpace*2;
	[] ← Rules.Create[parent: container,
		x: 0,
		y: heightSoFar,
		w: openRightWidth,
		h: 1,
		paint: FALSE];
	heightSoFar ← heightSoFar + entryVSpace*2;
	};
	
----------------------------

editToolAtom: ATOM = $EditTool;

Nothing: TEditOps.CommandProc = { };

mainEditTool: PUBLIC BOOLEAN ← NOT TEditOps.IsRegistered[editToolAtom];

IF mainEditTool THEN { -- register everyone
	TEditOps.Register[editToolAtom, Nothing];
	RegisterSort[]; RegisterSubs[]; RegisterSearch[] };

BuildEditToolMenu[];

BuildContainer[];	-- build enclosing viewer

BuildTargetEntry[]; -- the "Search for:" field
heightSoFar ← heightSoFar + entryVSpace;

BuildSearchEntries[]; -- the "Search Forward!" and "Search Backwards!" buttons
heightSoFar ← heightSoFar + entryVSpace;

BuildSearchButtons[]; -- the various choices for seaching
HRule[];

BuildSourceEntry[]; -- the "Replace by:" field
heightSoFar ← heightSoFar + entryVSpace;

BuildDoItEntries[]; -- the "Yes!", "No!", "Substitute!", "Replace!" buttons
heightSoFar ← heightSoFar + entryVSpace;

BuildSubstituteEntry[]; -- the within/after/entire choice

BuildInitCapEntry[]; -- Capitalize like first replaced char or not

BuildOperationEntry[]; -- Do Replace / Do Operations Specified Below
HRule[];

BuildOperationField[]; -- the "Operations:" field
heightSoFar ← heightSoFar + entryVSpace;

BuildGetAndSetOpsEntries[]; -- "GetLastOps!" "SetCom!" "GetCom!"
BuildComNumField[]; -- "Command number [0..9]:" field
HRule[];

BuildSortButtons[]; -- Sort increasing/decreasing; sort text/lines/branches; Sort!
ViewerOps.SetOpenHeight[container, heightSoFar + entryVSpace*2];
HRule[];

BuildPatternDocEntry[]; -- labels explaining special chars for patterns
heightSoFar ← heightSoFar + entryVSpace;


}.

..