DEFINITION MODULE ListEditor;

	(********************************************************)
	(*							*)
	(*		"Generic" list editor			*)
	(*							*)
	(*  Programmer:		P. Moylan			*)
	(*  Last edited:	13 February 1991		*)
	(*  Status:		OK				*)
	(*							*)
	(********************************************************)

FROM SYSTEM IMPORT
    (* type *)	ADDRESS;

FROM Windows IMPORT
    (* type *)	Window;

FROM FieldEditor IMPORT
    (* type *)	FieldType, WriteProc, EditProc;

(************************************************************************)
(*									*)
(*  The editor in this module is "generic" in a limited sense.  It	*)
(*  performs screen editing of a linear list, but obviously it has to	*)
(*  make some assumptions about the linkage method by which the list	*)
(*  is implemented.  The list must have the general form		*)
(*									*)
(*	 TYPE List = POINTER TO	RECORD					*)
(*				    next: List;				*)
(*				    component: some pointer type;	*)
(*				END (*RECORD*)				*)
(*									*)
(*  Notice however that this definition module actually defines lists	*)
(*  and components in terms of type ADDRESS, so that there is no	*)
(*  requirement that the caller's types and field names match the	*)
(*  above definition.							*)
(*									*)
(*  The caller is required to supply, via FieldEditor.DefineFieldType,	*)
(*  procedures which write and edit list components.			*)
(*									*)
(*  The procedures in this module obey the rules set by module		*)
(*  FieldEditor.  In the case where a list of lists is being edited,	*)
(*  the component editor can simply call EditList to do its job for it.	*)
(*									*)
(************************************************************************)

TYPE
    ListFormat;		(* is private *)
    List = ADDRESS;

(************************************************************************)

PROCEDURE DefineListFormat (header, separator, trailer: ARRAY OF CHAR;
				ComponentType: FieldType): ListFormat;

    (* Sets up the output format for a class of lists.  The header is	*)
    (* what is written before the first component; the separator is	*)
    (* what is written between the components; and the trailer is what	*)
    (* is written after the last component.  For an empty list, only	*)
    (* the header and trailer will be written.  ComponentType		*)
    (* implicitly specifies the procedures which will be used to write	*)
    (* and edit the components of the list.				*)

PROCEDURE DiscardFormat (format: ListFormat);

    (* A notification from the user that this format will not be used	*)
    (* again (unless it is redefined by another call to procedure	*)
    (* DefineListFormat).  Use of this procedure is optional, but is	*)
    (* recommended for the sake of "clean" memory management.		*)

PROCEDURE WriteList (w: Window;  L: List;  format: ListFormat);

    (* Writes L on the screen, including its delimiters.  This		*)
    (* procedure is not actually used in this module, but is provided	*)
    (* as something that a client module may find useful.		*)

PROCEDURE EditList (w: Window;  VAR (*INOUT*) L: List;  format: ListFormat);

    (* Edits a list at the current cursor position in window w.  We	*)
    (* leave this procedure on seeing a keyboard character which does	*)
    (* not belong to us.  The cursor is left just beyond the "trailer"	*)
    (* string which terminates the displayed form of the list.  The	*)
    (* terminating keystroke is returned to the keyboard driver so that	*)
    (* it can still be read by the caller.				*)

END ListEditor.
