%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                    %
% Diplomarbeit von Sven Muessig                                      %
% angefangen am 13-okt-92                                            %
%                                                                    %
% Universitaet Hamburg                                               %
% Fachbereich Informatik                                             %
% Arbeitsbereich DBIS                                                %
%                                                                    %
% Kapitel: Datenvisualisierung in Tycoon                             %
%                                                                    %
% Version vom 03-jul-94                                              %
%                                                                    %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cleardoublepage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Datenvisualisierung in Tycoon}
\label{Kap. Datenvisualisierung in Tycoon}

Ausgangspunkt f"ur die typsichere generische Datenvisualisierung in \ty\ 
ist das Konzept der \e{beliebig kombinierbaren Editoren}. Editoren sind 
Objekte, die eine einheitliche Pr"asentation 
(\e{look}\,) und Dialogsteuerung (\e{feel}\,) gemeinsam haben. Editoren 
dienen der typsicheren Visualisierung atomarer und hierarchisch 
strukturierter Werte des \ty-Objektspeichers. Erm"oglicht wird das durch 
eine f"ur den jeweiligen Datentyp geeignete \e{Bildschirmrepr"asentation}.
Die Daten in der Bildschirmrepr"asentation k"onnen vom Anwender 
interaktiv ver"andert werden.

Die Editoren lassen sich in drei Klassen unterteilen. Die einfachsten
Editoren finden sich in der Klasse der \e{Basiseditoren}. Sie entsprechen
weitgehend den in \ty\ vorhandenen Basistypen. Die Klasse der 
\e{Verbundeditoren} beinhaltet einfache hierarchische Editoren. Sie
entsprechen weitgehend den in \ty\ vorhandenen Typkonstruktoren. Die
Klasse der \e{Massendateneditoren} implementiert generische Editoren zur
Visualisierung von Massendaten. 

In diesem Kapitel werden die Konzepte und die Implementation der
typsicheren generischen Editoren ausf"uhrlich vorgestellt.
Die Vorstellung der Editoren beginnt mit der Beschreibung der 
Funktionalit"at sowie mit Abbildungen "uber die Gestaltung der
graphischen Benutzerschnittstelle. Anschlie"send wird anhand des schon
aus Kapitel \ref{Kap. Datenvisualisierung in bestehenden Systemen}
bekannten Programmbeispiels aus Anhang \ref{Kap. Programmbeispiel} die 
Anwendungsprogrammierung mit der Editorbibliothek vorgestellt. In einem 
weiteren Abschnitt werden ausgew"ahlte Beispiele aus den zur Bibliothek
geh"orenden Schnittstellen und Modulen erl"autert. Es folgt abschlie"send 
ein Abschnitt "uber M"oglichkeiten bei der Erweiterung der Bibliothek 
durch Anwender am Beispiel von abstrakten Datentypen.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Gestaltung der graphischen Benutzerschnittstelle}
\label{Abs. Gestaltung der graphischen BSS}

Die graphische Benutzerschnittstelle der einzelnen Editoren ist durch die
Verwendung des \tnts\ (\VAS\ \ref{Abs. Das NeWS Toolkit}) und \ol\ (\VAS\ 
\ref{Abs. Die OPEN LOOK Anwenderschnittstelle}) in ihrem Aussehen und
Verhalten gepr"agt. Die Auswahl der speziellen Visualisierungen erfolgte
anhand praktischer "Uberlegungen. Der erfolgreiche praktische Einsatz 
des Prototyps (\VGL\ \cite{KiMu92}) sowie der Vergleich mit anderen Systemen
(\VKA\ \ref{Kap. Datenvisualisierung in bestehenden Systemen}) hat die
vorgenommene Gestaltung der Visualisierungen zus"atzlich bekr"aftigt.

Um ein Gef"uhl f"ur das Aussehen und das Verhalten der Editoren zu 
vermitteln, werden in den folgenden Abschnitten alle relevanten 
Komponenten des Systems anhand von Abbildungen vorgestellt. Zu jeder 
Abbildung wird die von der jeweiligen Visualisierung abh"angige
Funktionalit"at ausf"uhrlich beschrieben.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Basiseditoren}
\label{Abs. Basiseditoren 1}

In diesem Abschnitt werden die Visualisierungen der in Tycoon vorhandenen
Basistypen sowie von Aufz"ahlungen und Funktionen vorgestellt. Alle
Editoren verf"ugen "uber einen Grundwert, auf den sie sich zur"ucksetzen
lassen. Der Grundwert kann "uber die Auswahl \s{New} im \s{Edit}-Men"u 
angesprochen werden (\VAS\ \ref{Abs. Rahmen fuer Editoren}).

\begin{description}
  \item [Ganzzahlen:]
        Werte des Datentyps \s{Int} werden durch ein numerisches
		Eingabefeld repr"asentiert. Mit Hilfe der beiden Kn"opfe auf 
		der	rechten Seite des Feldes ist eine schrittweise In- bzw.\ 
		Dekrementierung des angezeigten Wertes m"oglich. Ein solcher
		Editor kann auf seinen Grundwert, in diesem Fall \s{0}, 
		zur"uckgesetzt werden.		

        \psbild{0.8#1}{editenv}{Integer.ps}

  \item [Flie"skommazahlen:]
        Werte des Datentyps \s{Real} werden in der gleichen Weise
        repr"asentiert wie ganzzahlige Werte. Es gibt jedoch keine
		Kn"opfe zum In- bzw. Dekrementieren. Der Grundwert ist \s{0.0}.

        \psbild{0.8#1}{editenv}{Real.ps}

  \item [Zeichen:]
        Einzelne Zeichen (\s{Char}) werden durch ein alphanumerisches 
		Eingabefeld der L"ange eins repr"asentiert. Der Grundwert ist
		ein leeres Zeichen (\s{'\,'}).
		
        \psbild{0.8#1}{editenv}{Char.ps}

  \item [Zeichenketten:]
        Werte des Datentyps \s{String} werden durch ein alphanumerisches 
		Eingabefeld repr"asentiert. Reicht der zur Verf"ugung stehende
		Platz nicht aus, so erscheinen an beiden R"andern Kn"opfe, mit 
		denen es m"oglich ist, durch den Text zu navigieren. Zwei weitere
        Zeichenketteneditoren erm"oglichen die Visualisierung von nur
        lesbaren (\e{read-only}\,) und festen Werten. Der Grundwert ist
		eine leere Zeichenkette (\s{''''}).

        \psbild{0.8#1}{editenv}{String.ps}

  \item [Boole'sche-Werte:]
        Boole'sche Werte (\s{Bool}) werden durch ein Ja/Nein-Feld
		repr"asentiert. Der Wert \s{true} entspricht dabei einem H"akchen
		im Feld. Der Grundwert ist \s{false}.

        \psbild{0.8#1}{editenv}{Bool.ps}

  \item [Aufz"ahlungen:]
        Auf der Typebene von \ty\ wird ein Aufz"ahlungstyp als degeneriertes
        Tuple mit Varianten (\s{\k{Tuple} \k{case} \dots\ \k{end}})
        dargestellt. Werte von Aufz"ahlungstypen werden durch eine
		Exklusivauswahl	an einem Abk"urzungsmen"uknopf visualisiert. Die
		Werte der Aufz"ahlung sind die Eintr"age in der Auswahl. Der 
		aktuelle Wert ist rechts neben dem Men"uknopf zu finden. Als
		Grundwert ist jeweils die erste Variante gew"ahlt. 

        \psbild{0.8#1}{editenv}{Enumeration.ps}

  \item [Funktionen:]
        Funktionswerte der Form \s{\k{fun}() :\k{Ok}} werden durch einen
        Knopf repr"asentiert. Die parameterlose Funktion wird ausgef"uhrt,
        wenn der Knopf gedr"uckt wird. Der Grundwert f"ur Funktionen ist
		\k{fun}() \k{ok}.

        \psbild{0.8#1}{editenv}{Function.ps}

\end{description}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Verbundeditoren}
\label{Abs. Verbundeditoren 1}

In der gleichen Weise wie auf der Typebene von \ty\ werden auch Editoren
f"ur strukturierte Werte systematisch durch Aggregation ihrer Komponenten
erzeugt. Als Komponenten von Verbundeditoren kommen nicht nur die im letzten
Abschnitt vorgestellten Basiseditoren in Betracht, sondern alle definierten
Editoren k"onnen als Komponenten verwendet werden. 

Dabei sei zun"achst darauf hingewiesen, da"s Verbundeditoren typischerweise 
zwei Visualisierungen haben. Die erste Visualisierung ist f"ur alle
Verbundeditoren unabh"angig von ihren Komponenten gleich. Sie wird 
benutzt, wenn ein Verbundeditor als Komponente in einem anderen Editor
eingeschachtelt ist.

\psbild{0.8#1}{editenv}{Display.ps}

Nach einem Druck auf den Knopf "offnet sich ein weiteres Fenster, in dem die 
eigentliche Visualisierung des Editors dargestellt wird. Eine genaue 
Beschreibung der Funktionalit"at der beiden Verbundeditoren folgt in der 
folgenden Aufz"ahlung.

\begin{description}
  \item [Verbunde:]
        Werte von Verbundtypen (\s{\k{Tuple} \dots\ \k{end}}) werden durch
		ihre Komponenten dargestellt. Alle Komponenten werden linksb"undig,
		die Namen der Komponenten rechtsb"undig dargestellt. Der Grundwert
		ergibt sich aus den Grundwerten der Komponenten.

        \psbild{0.8#1}{editenv}{Tuple.ps}

  \item [Varianten:]
        Werte von Variantentypen werden durch die Kombination von 
		Aufz"ahlungstyp und Verbund visualisiert. Die verschiedenen Varianten
		sind "uber einen Abk"urzungsmen"uknopf ausw"ahlbar. Jede Variante
		beinhaltet einen Verbund zur Visualisierung der Komponenten. Die
		jeweils ausgew"ahlte Variante wird rechts neben dem Men"uknopf
		dargestellt. Der Grundwert ergibt sich aus den Grundwerten der
		Komponenten der ersten Variante.

        \psbild{0.8#1}{editenv}{Variant.ps}

\end{description}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Massendateneditoren}
\label{Abs. Massendateneditoren 1}

Die n"achste Stufe nach den Verbundeditoren bilden die Massendateneditoren.
Massendatentypen bestehen meist aus der Kombination eines Basis- oder 
Verbundtyps mit einem Kollektionstyp wie Liste oder Menge. Entsprechend
sind die Visualisierungen der Massendatentypen aufgebaut. Wie schon im 
vorherigen Abschnitt erw"ahnt, haben hierarchische Editoren typischerweise
zwei Visualisierungen, eine f"ur eingeschachtelte Editoren und eine f"ur
den eigentlichen Editor. Grundwerte ist jeweils eine leere Kollektion.

\begin{description}
  \item [Iterationen:]
        Iterationen werden im Prinzip wie Verbunde visualisiert. Sie
		enthalten jedoch zus"atzlich einen Rollbalken, mit dem innerhalb
		der	Datenstruktur navigiert werden kann. Au"serdem kennt ein
		Iterationseditor die Anzahl seiner Elemente und die Position des
		angezeigten Elements.

        \psbild{0.8#1}{editenv}{Iteration.ps}

  \item [Tabellen:]
        Tabellen bilden die zweite Darstellungsm"oglichkeit f"ur Massendaten.
		Im Gegensatz zum Iterationseditor, in dem immer nur ein Datensatz
		\zZt\ angezeigt werden kann, k"onnen in einem Tabelleneditor
		mehrere Datens"atze gleichzeitig angezeigt werden. Die Komponenten
		werden spaltenweise dargestellt, wobei die Namen der Komponenten die
		Spalten"uberschriften bilden. Ein Rollbalken am rechten Rand
		erm"oglicht die Navigation in der Tabelle. Auch ein Tabelleneditor
		kennt die Anzahl seiner Elemente. In der Tabelle selbst k"onnen 
		die Daten nicht manipuliert werden. Durch die Selektion einer Zeile
		wird ein Verbundeditor ge"offnet, in dem der entsprechende Datensatz
		angezeigt und manipuliert werden kann.
		
        \psbild{0.8#1}{editenv}{Table.ps}

\end{description}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Rahmen f"ur Editoren}
\label{Abs. Rahmen fuer Editoren}

Alle in den letzten drei Abschnitten vorgestellten Visualisierungen f"ur
Editoren k"onnen in dieser Form nicht in einem Fenstersystem verwendet 
werden. Um solche Visualisierungen sinnvoll einsetzen zu k"onnen, bedarf
es eines Rahmens, der eine Grundfunktionalit"at zur Verf"ugung stellt.
Ein solcher Rahmen ist in Abbildung \ref{Abb. Rahmen} dargestellt. Bei
dem Rahmen handelt es sich, je nach Hierarchiestufe, entweder um ein
Grundfenster oder um ein Aufklappfenster. Die Funktionalit"at ist jedoch
f"ur beide Rahmen weitgehend gleich. 

\begin{figure}[htb]
  \psbild{0.8#1}{editenv}{Frame.ps}
  \caption{Grundrahmen f"ur Editoren}
  \label{Abb. Rahmen}
\end{figure}

Unterschieden werden die Rahmen lediglich beim Schlie"sen. W"ahrend
Grundfenster ausschlie"slich durch Auswahl des Men"upunktes \s{Quit} aus
dem Men"u der Kopfzeile des Fensters geschlossen werden k"onnen, k"onnen
Aufklappfenster sowohl durch Herausziehen der Stecknadel als auch durch 
Auswahl des Men"upunktes \s{Dismiss} geschlossen werden.

Beim Schlie"sen eines Rahmens werden intern zwei F"alle unterschieden.
Sind die Werte im Editor nicht ge"andert worden, so wird der Rahmen
sofort ohne Nachfrage geschlossen. Sind die Werte in einem Editor jedoch
ge"andert worden und noch nicht gesichert, so erscheint eine Abfrage.
Dadurch ist es dem Anwender m"oglich, den Editor mit oder ohne Sicherung
der Daten zu verlassen oder in den denselben zur"uckzukehren.

Unter der Kopfzeile des Rahmens befindet sich die Men"uzeile. Diese 
besteht aus zwei Teilen, dem eigentlichen Men"u auf der linken Seite und
einem Datenaustauschfeld auf der rechten Seite. Direkt unter der 
Men"uzeile wird die Visualisierung des eigentlichen Editors eingesetzt.
Als Visualisierungen kommen alle in den vorherigen Abschnitten vorgestellten
Editoren in Frage. Unter dem Editor befinden sich noch zwei Kn"opfe und
die Fu"szeile.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Kopfzeile}

In der Kopfzeile des Rahmens wird der Name des direkt integrierten 
Editors angezeigt. 


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Men"us}

Unter der Kopfzeile des Rahmens befindet sich die Men"uzeile. Auf der
linken Seite der Men"uzeile sind zwei Men"ukn"opfe zu finden. Unter den
beiden Men"ukn"opfen (\s{Edit} und \s{View}) befinden sich mehrere
Men"ueintr"age, mit denen entsprechend assoziierte \ty-Funktionen aufgerufen
werden k"onnen. In Tabelle \ref{Tab. Menueeintraege} sind alle 
Men"ueintr"age der beiden Men"upunkte mit ihren Submen"ueintr"agen und der
dazugeh"origen Funktionalit"at aufgef"uhrt und erl"autert. 

\begin{table}[htb]
  \begin{center}
    \begin{tabular}{|l|l|l|l|l|}
      \hline
      {\bf Men"u} & {\bf Eintrag} & {\bf Subeintrag} & {\bf Funktionalit"at} \\
      \hline
      \hline
      \s{Edit} & \s{Edit}  &              & "Offnet Editor mit ausgew"ahltem Element. \\
               & \s{New}   & \s{Here}     & F"ugt Element an aktueller Position ein. \\
               &           & \s{Behind}   & F"ugt Element hinter aktueller Position ein. \\
               & \s{Cut}   & \s{This}     & L"oscht aktuelles Element bzw.\ setzt Grundwert. \\
               &           & \s{All}      & L"oscht alle Elemente. \\
               &           & \s{Selected} & L"oscht ausgew"ahlte Elemente. \\
               & \s{Copy}  &              & Kopiert in Puffer. \\
               & \s{Paste} &              & Kopiert aus Puffer. \\
      \hline
      \s{View} & \s{Properties} &         & Grundeinstellungen setzen. \\
               & \s{Show Path}  &         & Zeigt Pfad zum Editor an. \\
      \hline
    \end{tabular}
  \end{center}
  \caption{Funktionalit"at der Men"uzeile im Rahmen}
  \label{Tab. Menueeintraege}
\end{table}

Nicht alle Men"ueintr"age stehen in allen Editoren zur Verf"ugung. 
Zum Beispiel macht es keinen Sinn, in einen Basiseditor ein neues Element
einzuf"ugen (\e{new}\,) oder einen neuen Editor mit dem gleichen Element
zu "offnen (\e{edit}\,). Alle in einem Editor nicht zur Verf"ugung 
stehende Men"ueintr"age sind als inaktiv markiert. Sie k"onnen daher vom
Anwender auch nicht angew"ahlt werden.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Datenaustauschfeld}

Auf der rechten Seite der Men"uzeile befindet sich ein Datenaustauschfeld.
Das Feld er\-m"og\-licht das symbolische Austauschen von Daten (\VAS\
\ref{Abs. Moeglichkeiten des Datenaustauschs}). 

Beim Datenaustausch k"onnen zwei Arten unterschieden werden, zum einen 
der Austausch von Daten zwischen Editoren (\e{internal data exchange}\,) 
und zum anderen der Austausch von Daten zwischen einem Editor und einem 
anderen Programm (\e{external data exchange}\,). Der externe Datenaustausch 
kann \zB\ als Import- bzw. Exportfunktion verwendet werden. F"ur Anwender
besteht jedoch hinsichtlich des Ablaufs kein Unterschied. Die Daten werden
in einem Fenster symbolisch "uber das Datenaustauschfeld oder direkt mit 
der Maus aufgenommen. So aufgenommene Daten k"onnen mit der Maus "uber 
den Bildschirm bewegt und "uber einem anderen Fenster oder 
Datenaustauschfeld fallengelassen werden. Die beiden am Datenaustausch
beteiligten Anwendungsprogramme sind durch das Aufnehmen und Fallenlassen
der Daten informiert und regeln den eigentlichen Austausch selbst"andig.
 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Kn"opfe}

Unter dem Editor befinden sich zwei Kn"opfe. Sie dienen dem Datenaustausch
zwischen Anwendung und Editor. Der \s{Reset}-Knopf liest den aktuellen
Wert aus der zugrundeliegenden Datenstruktur bzw.\ Variable aus und zeigt
ihn auf dem Bildschirm an und der \s{Apply}-Knopf schreibt den aktuellen
Wert in die Datenstruktur bzw.\ Variable unter Beachtung eventueller 
Integrit"atsbedingungen zur"uck.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Fu"szeile}

In der Fu"szeile des Rahmens werden R"uckmeldungen f"ur Anwender 
ausgegeben. Die linke Seite ist dabei f"ur Warn- und Fehlermeldungen, 
wie verletzte Integrit"atsbedingungen, vorgesehen. Auf der rechten Seite
werden Zustandsmeldungen, wie \zB\ die Nummer des aktuellen Elements und
die Gesamtzahl aller Elemente im Editor, angezeigt.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Anwendungsprogrammierung am Beispiel}
\label{Abs. Anwendungsprogrammierung am Beispiel}

Nachdem in den vorherigen Abschnitten die Bildschirmrepr"asentationen der 
einzelnen Editoren und des Rahmens vorgestellt worden sind, werden 
nachfolgend anhand von einfachen Beispielen einige Verwendungsm"oglichkeiten
der generischen Editoren aufgezeigt. Zuvor wird anhand einer schematischen
Abbildung der Datenflu"s zwischen den Programmvariablen und dem Bildschirm
dargestellt.

\begin{figure}[htb]
  \psbild{0.8#1}{editenv}{Ablauf.ps}
  \caption{Datenflu"s bei der Visualisierung}
  \label{Abb. Ablauf}
\end{figure}

Gesteuert wird der Datenflu"s von den einzelnen verwendeten Editoren.
In Abbildung \ref{Abb. Ablauf} ist zu sehen, wie "uber die Funktion \s{get}
die Programmvariablen ausgelesen werden. Die Editoren bereiten die Werte,
je nach Typ, entsprechend auf und reichen sie an tiefere Schichten weiter.
Erst "uber das Modul \s{wire} aus dem \s{newsenv} findet die Kommunikation 
mit dem \xns\ statt. Der Server ist f"ur den Bildschirmaufbau und die 
Kommunikation mit dem Anwender verantwortlich. Umgekehrt werden die Aktionen
vom Anwender "uber das Modul \s{wire} an die Editoren weitergeleitet. Sie
sind dann daf"ur verantwortlich, die evtl.\ ver"anderten Werte unter
Beachtung vorhandener Integrit"atsbedingungen "uber die \s{set}-Funktion
in die Programmvariablen zur"uckzuschreiben.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Visualisierung unstrukturierter Werte}
\label{Abs. Anzeigen von einfachen Werten}

Das nachfolgende Beispiel zeigt, wie auf einfache Weise ein Editor f"ur
Zeichenketten erzeugt werden kann. Daf"ur mu"s das nachfolgende 
\ty-Kodefragment ausgef"uhrt werden. Der Anwender bekommt dann den
abgebildeten Editor (\VAB\ \ref{Abb. Zeichenketteneditor})
zur Verf"ugung gestellt.

\begin{xple}
     \k{import}
        editor  action

     \k{let} \k{var} name = ''Meyer''
     \k{let} \k{var} continue = true
     \k{let} quit :Action.T = \k{fun}() continue := false
     \k{let} dispatch = \k{fun}() continue 
	 
     \k{let} stringEditor = editor.newString(''My First Editor''
        \k{let} get = \k{fun}() name
        \k{let} set = \k{fun}(new :String) name := new)

     \k{begin}
        editor.display(stringEditor  quit  editor.somewhere)
        editor.waitAndDispatch(dispatch)
        name
     \k{end}
\end{xple}

\begin{figure}[htb]
  \psbild{0.8#1}{editenv}{StringEditor.ps}
  \caption{Einfacher Editor zum Anzeigen einer Zeichenkette}
  \label{Abb. Zeichenketteneditor}
\end{figure}

Die gesamte Flexibilit"at der Editoren liegt in den Funktionen \s{get}
und \s{set}. Mit Hilfe der Funktion \s{get} kann nicht nur eine einfache
Variable ausgelesen werden, sondern es ist auch m"oglich, Werte aus
beliebig komplizierten Strukturen auszulesen bzw.\ zu berechnen.

\begin{xple}
     \k{let} get = \k{fun}() person.address.street
     \k{let} get = \k{fun}() data.netto ** data.tax
\end{xple}

Die Funktion \s{set} dient dem Zur"uckschreiben des Wertes in die 
zugrundeliegende Variable der Datenstruktur. Dadurch k"onnen an dieser
Stelle beliebige Integrit"atsbedingungen getestet werden und es ist
m"oglich, auf unzul"assige Werte hinzuweisen.

\begin{xple}
     \k{let} set = \k{fun}(new :String)
        \k{if} string.empty(new) \k{then}
           \k{raise} editor.illegal \k{with} ''No name specified'' \k{end}
        \k{else}
           name := new
        \k{end}
\end{xple}

In diesem Beispiel wird gepr"uft, ob der Anwender einen Namen eingegeben
hat. Ist dies nicht der Fall, so wird eine Ausnahme ausgel"ost. In der
Fu"szeile des Editors erscheint die Meldung \s{''No name specified''}.
Der Anwender kann den Wert des Editors "andern. Der Editor kann erst
verlassen werden, wenn keine Integrit"atsbedingung mehr verletzt oder
der neue Wert nicht in die Datenstruktur "ubernommen wird.

In dem Beispiel kommen noch weitere Funktionen vor. Ihre Aufgabe wird im
folgenden erl"autert. Mit der Funktion \s{waitAndDispatch} (\VSE\
\pageref{Prg. waitAndDispatch}) wartet das Anwendungsprogramm in einer
Schleife auf ankommende Ereignisse. Nach jedem Ereignis wird "uber die 
\s{dispatch}-Funktion gepr"uft, ob die Nachrichtenschleife verlassen 
werden soll. Dieser Zustand tritt ein, wenn ein Anwender \s{Quit} aus 
dem Men"u des Grundrahmens ausw"ahlt. In diesem Fall setzt die Funktion
\s{quit} die Variable \s{continue} auf \s{false} und die Funktion 
\s{waitAndDispatch} wird verlassen. Der Editor kann durch einen erneuten
Aufruf der Funktion \s{display} wieder angezeigt werden. Vor dem 
Einstieg in die Nachrichtenschleife mit \s{waitAndDispatch} mu"s die 
Variable \s{continue} unbedingt wieder auf \s{true} gesetzt werden, da
ansonsten die Schleife sofort wieder verlassen wird.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Visualisierung strukturierter Werte}
\label{Abs. Anzeigen von Datensaetzen}

Das zweite Beispiel soll verdeutlichen, wie aus einem Anwendungsprogramm
heraus ganze Datens"atze angezeigt und ge"andert werden k"onnen. Das
Modul \s{world} mit den Datenstrukturen und Editordefinitionen, auf die
im folgenden Bezug genommen wird, befindet sich im Anhang 
\ref{Sec. PrgBsb Tycoon}. Das Ergebnis eines Aufrufs der Funktion \s{go}
des Moduls \s{world} ist in Abbildung \ref{Abb. Personeneditor} zu finden. 

\begin{figure}[htb]
  \psbild{0.65#1}{editenv}{TycoonPerson.ps}
  \caption{Editor f"ur das Programmbeispiel aus Anhang
           \protect\ref{Kap. Programmbeispiel}}
  \label{Abb. Personeneditor}
\end{figure}

Das Modul \s{world} importiert zun"achst andere Module, deren Funktionen
im weiteren gebraucht werden. Anschlie"send werden die Datenstrukturen
definiert. Bevor die Editoren implementiert werden k"onnen, m"ussen noch
einige Hilfsfunktionen definiert werden. Zum Beispiel wird f"ur den Aufruf
eines Iterationseditors eine Funktion zum Erzeugen eines neuen Elements
(\s{newPerson}) ben"otigt, da es in \ty\ keine uninitialisierten Variablen
gibt. 

F"ur den Editor zum Visualisieren von Werten des Aufz"ahlungstyps 
\s{FamilyStatus} m"ussen zus"atzlich zwei weitere Funktionen definiert
werden. Die eine Funktion dient dem Berechnen der Ordinalit"at eines
Wertes und die andere erlaubt das Abbilden von Aufz"ahlungswerten auf
Zeichenketten. Die Abbildungsfunktion erzeugt eine Iteration von Paaren.
Die Paare bestehen jeweils aus einem Wert des Typs \s{FamilyStatus} und 
der Zeichenkette, auf die der Wert abgebildet werden soll. Die Zeichenkette
wird zum Visualisieren der Werte von Aufz"ahlungstypen verwendet.

Die eigentlichen Editoren k"onnen nun definiert werden. Die Definition
l"auft dabei in der gleichen Weise ab wie schon bei dem einfachen
Editor im vorherigen Abschnitt. Auch die Integrit"atsbedingungen werden
in der gleichen Weise aufgef"uhrt. Einmal definierte Editoren k"onnen
dabei in die Definition von komplexeren Editoren eingef"ugt werden. Ein
Beispiel daf"ur ist der \s{addressEditor} im \s{personEditor}.

Zum Anzeigen des Editors wird die Funktion \s{display} benutzt. 
Anschlie"send wird wieder in einer Schleife auf ankommende Ereignisse 
gewartet. 


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Module und Schnittstellen der Editorbibliothek}
\label{Abs. Module und Schnittstellen der Editorbibliothek}

Die Editorbibliothek (\s{editenv}) implementiert die in der Einleitung
zu diesem Kapitel vorgestellten typsicheren generischen Editoren. Die
Bibliothek greift dabei in vielf"altiger Weise auf andere Bibliotheken,
insbesondere auf das \s{stdenv} und das \s{newsenv} zur"uck. Im einzelnen
besteht die Editorbibliothek, wie auch in Abbildung \ref{Abb. Modulstruktur} 
dargestellt ist, aus elf Modulen, die sich in vier Schichten anordnen
lassen. Angemerkt sei jedoch, da"s Abbildung \ref{Abb. Modulstruktur}
nicht die komplexen Importbeziehungen, die innerhalb der Bibliothek 
bestehen, wiedergibt.

\begin{figure}[htb]
  \psbild{0.85#1}{editenv}{Modulstruktur.ps}
  \caption{Struktur der Editorbibliothek}
  \label{Abb. Modulstruktur}
\end{figure}

Die unterste Schicht wird von den Hilfsmodulen \s{newsUtil}, \s{editorUtil},
\s{editorMenu}, \s{editorButtons}, \s{editorTarget} und \s{editorWindow} 
gebildet. Das Modul \s{editorRep} aus der zweiten Schicht definiert im 
wesentlichen das abstrakte Protokoll, "uber das die Editoren angesprochen 
werden. In Schicht drei befinden sich die eigentlichen Editorimplementationen
(\s{simpleEditors}, \s{recordEditors} und \s{bulkEditors}). Das Modul 
\s{editor} der obersten Schicht bildet die einzige nach au"sen hin sichtbare 
Schnittstelle. Alle wichtigen Definitionen werden an dieses Modul 
durchgereicht. In den folgenden Abschnitten werden die Konzepte und 
wichtigsten Implementationsideen der einzelnen Module ausf"uhrlich 
vorgestellt.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Abstraktes Datenstrukturmodell}
\label{Abs. Abstraktes Datenstrukturmodell}

Im Modul \s{editorRep} wird das Protokoll definiert, "uber das alle
Editoren angesprochen werden. Dar"uber hinaus sind in diesem Modul alle
Funktionen zu finden, die auf beliebige Editoren angewendet werden
k"onnen.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Protokoll}

Das Protokoll f"ur Editoren ist eine Schnittstelle, die es erm"oglicht,
verschiedene Arten von Editoren in eine gemeinsame Umgebung zu integrieren
und in objektorientierter Form anzusprechen \cite{KGZ93}. Alle definierten 
Editoren m"ussen mindestens die folgenden Komponenten haben, damit sie sich
in die Umgebung nahtlos einf"ugen:

\begin{figure}[t]
\begin{xple}
    \k{Let} \k{Rec} T $<$:\k{Ok} = 
       \k{Tuple}
          hidden :Hidden(T)
          label :DisplayItem
          separateWindow :Bool
          menuActions :MenuActions
          create() :\k{Ok}
          destroy() :\k{Ok}
          apply() :Bool
          refresh() :\k{Ok}
          show() :\k{Ok}
          hide() :\k{Ok}
          getValue() :ValueRep
          setValue(:ValueRep) :\k{Ok}
          toString() :Iter.T(String)
       \k{end}
\end{xple}
\end{figure}

Im folgenden werden die einzelnen Komponenten des Protokolls ausf"uhrlich
beschrieben. Die erste Komponente (\s{hidden}) dient der Zusammenfassung
interner Daten, die zum Aufbau und zur Verwaltung einer hierarchischen 
Struktur ben"otigt werden. Alle Komponenten dieser Substruktur sind 
modifizierbar, da sich ihre Werte dynamisch "andern k"onnen. In der 
jetzigen Implementation k"onnen alle Komponenten des Tupels durch Anwender
ver"andert werden. Da dieser Effekt nicht gew"unscht ist, sollte die 
Komponente eigentlich nicht im Protokoll erscheinen. Mit Hilfe des 
Konzepts der Subtypisierung lie"se sich die Komponente aus der
Schnittstelle des Moduls entfernen. Der Typ \s{Hidden} hat die
folgende Struktur:

\begin{xple}
    \k{Let} Hidden(EditorT $<$:\k{Ok}) $<$:\k{Ok} =
       \k{Tuple}
          \k{var} guiId :Object.T
          \k{var} windowId :Window.T
          \k{var} menuBar :MenuBar
          \k{var} target :DropTarget.T
          \k{var} buttons :Buttons.T
          state :set.T(State)
          \k{var} key :Bool
          \k{var} modified :Bool
          \k{var} parent :optional.T(EditorT)
       \k{end} 
\end{xple}

In der \s{guiId} wird der Identifikator f"ur die Bildschirmrepr"asentation
des Editors gehalten. Dies ist notwendig, da an die Objekte Nachrichten 
geschickt werden m"ussen, \zB\ um einen neuen Wert darzustellen oder 
weitere Rahmen zu "offnen. In den vier folgenden Komponenten sind nur dann
Eintr"age, wenn sich der Editor direkt in einem Rahmen befindet. In der
\s{windowId} steht der Identifikator f"ur den Rahmen, im \s{menuBar} f"ur
die Men"uzeile, im \s{target} f"ur das Datenaustauschfeld und in 
\s{buttons} f"ur die Kn"opfe.

Die Variable \s{state} repr"asentiert den Zustand des Editors. Wie am Typ
der Komponente (\s{set.T(State)}) zu sehen ist, kann ein Editor mehrere
Zust"ande gleichzeitig haben. In Tabelle \ref{Tab. Editorstati} werden alle
zul"assigen Zust"ande erkl"art.

\begin{table}[htb]
  \begin{center}
    \begin{tabular}{|l|l|}
      \hline
      {\bf Zustand} & {\bf Bedeutung} \\
      \hline
      \hline
      new      & W"ahrend der Initialisierung mit \s{newEditor}. \\ 
      exists   & Nach Erzeugung mit \s{create} gesetzt. \\
      sub      & Markiert Subeditoren. \\
      visible  & Gesetzt, solange sich der Editor auf dem Bildschirm befindet. \\
      windowed & Gesetzt, wenn sich ein Editor direkt in einem Rahmen befindet. \\
      \hline
    \end{tabular}
  \end{center}
  \caption{Zul"assige Zust"ande f"ur Editoren}
  \label{Tab. Editorstati}
\end{table}

Die beiden folgenden Komponenten fungieren als Schalter. Mit dem Schalter
\s{key} kann ein Basiseditor als Schl"usselfeld ausgezeichnet werden und
der Schalter \s{modified} gibt an, ob der Wert in der 
Bildschirmrepr"asentation ge"andert worden ist. Ist der Wert nicht 
ge"andert worden, so m"ussen der Wert und evtl.\ vorhandene Subwerte
bei Aufruf der Methode \s{apply} nicht zur"uckgeschrieben werden. Aufgrund
von nicht abzupr"ufenden Integrit"atsbedingungen ergeben sich
Geschwindigkeitsvorteile. Beim Verlassen eines nicht ge"anderten Editors kann
auf die Sicherheitsnachfrage verzichtet werden. Die \s{apply}-Methode setzt
den Schalter nach erfolgreicher Ausf"uhrung zur"uck.

Mit der letzten Komponente (\s{parent}) wird die hierarchische Struktur
der Editoren aufgebaut. Da \ty\ keine uninitialisierten Variablen zul"a"st,
mu"s diese Komponente zun"achst mit einem Nullwert initialisiert werden.

Nachdem alle Komponenten des Typs \s{Hidden} beschrieben worden sind, 
k"onnen nun die weiteren Komponenten des Protokolls beschrieben werden.
Die Komponente \s{label} repr"asentiert den Namen des Editors. Er wird 
f"ur Basiseditoren links neben dem Editor angezeigt. Hierarchische
Editoren haben den Namen in der Kopfzeile ihres Rahmens.

Die Komponente \s{separateWindow} wird bei der Erzeugung des Editors
gesetzt. Sie bestimmt, ob der Editor in einem eigenen Rahmen dargestellt
werden soll. Dabei ist zun"achst eine Unterscheidung zwischen Grund- und
Aufklappfenster nicht wichtig. Die Variable bekommt bisher f"ur Verbund-,
Varianten- und Iterationseditoren den Wert \s{true}.

In der Komponente \s{menuActions} sind die Aktionen vermerkt, die 
ausgef"uhrt werden sollen, wenn Men"upunkte im Rahmen des Editors
angew"ahlt werden. Eine genaue Beschreibung der Men"upunkte ist in
Tabelle \ref{Tab. Menueeintraege} auf Seite 
\pageref{Tab. Menueeintraege} zu finden.

Alle weiteren Komponenten des Protokolls sind funktionalen Typs. Sie
m"ussen von allen Editoren ausgef"uhrt werden k"onnen. Die funktionalen
Komponenten dienen dem Erzeugen und L"oschen von Editoren, dem 
Zur"uckschreiben von Werten, dem erneuten Lesen von noch nicht 
zur"uckgeschriebenen Werten, dem Anzeigen auf und dem Entfernen von
Editoren vom Bildschirm. Weitere funktionale Komponenten erm"oglichen 
den Datenaustausch mit anderen Editoren. Die Funktionen k"onnen als 
Nachrichten aufgefa"st werden, die an die einzelnen Editoren geschickt
werden k"onnen. In jedem Editor mu"s deshalb implementiert werden, wie
er auf die verschiedenen Nachrichten reagiert.

Die erste Nachricht, die an einen Editor geschickt werden mu"s, bevor
er auf andere Nachrichten reagieren kann, ist \s{create}. In dieser
Methode ist implementiert, wie die Bildschirmrepr"asentation auf der
\n-Seite aufgebaut und initialisiert wird. Die Datenstrukturen zur
Verwaltung der \ty-Seite werden schon beim Erzeugen des Editors mit
\s{newEditor} angelegt und initialisiert.

Die Nachricht \s{destroy} bewirkt genau das Gegenteil. Die
Bildschirmrepr"asentation auf der \n-Seite wird gel"oscht und alle
Informationen der \ty-Seite werden entsprechend ver"andert. Dies gilt
auch f"ur Editoren, die direkt in einen Rahmen integriert sind. Weitere 
Nachrichten kann ein Editor erst nach erneutem Erhalt der Nachricht
\s{create} verarbeiten.

Die folgenden beiden Nachrichten dienen dem Datenaustausch zwischen
der Datenstruktur und der Bildschirmrepr"asentation. Auf die Nachricht 
\s{refresh} mu"s ein Editor den Wert aus der Variablen der Datenstruktur
auslesen und ihn in seine Bildschirmrepr"asentation schreiben und auf
die Nachricht \s{apply} mu"s er den Wert aus seiner Bildschirmrepr"asentation 
auslesen und in die zugrundeliegende Variable der Datenstruktur 
zur"uckschreiben. 

Zwei weitere Methoden implementieren das Anzeigen und Entfernen des Editors
auf bzw.\ von dem Bildschirm. Die Methode \s{show} zeigt einen Editor auf
dem Bildschirm an bzw.\ aktiviert seine Bildschirmrepr"asentation und die
Methode \s{hide} entfernt einen Editor vom Bildschirm bzw.\ deaktiviert
seine Bildschirmrepr"asentation.

Um den Datenaustausch zwischen Editoren verschiedenen Typs zu vereinfachen,
ist das nachfolgend beschriebene Protokoll vorgesehen. Jeder Editor kann
"uber die beiden Methoden \s{getValue} und \s{setValue} mit anderen
Editoren Daten austauschen.

\begin{figure}[h]
\begin{xple}
    \k{Let} \k{Rec} ValueRep $<$:\k{Ok} =
       \k{Tuple}
          \k{case} simpleV \k{with} value :String 
          \k{case} executableV \k{with} function :Action.T 
          \k{case} recordV \k{with} fields :Iter.T(ValueRep) 
          \k{case} bulkV \k{with} data :Iter.T(ValueRep) 
          \k{case} multiV \k{with} value :String 
       \k{end}
\end{xple}
\label{Prg. Datenaustauschprotokoll}
\end{figure}

Einfache Editoren (\s{simpleV}) haben ihren Wert im Feld \s{value}.
Auch Funktionen (\s{executableV}) werden durch ihren Wert repr"asentiert
(\s{function}). Verbunde (\s{recordV}) werden durch eine Iteration "uber
ihre Komponenten repr"asentiert. Massendaten (\s{bulkV}) werden "uber eine
Iteration ihrer Werte repr"asentiert. 

Die letzte im Protokoll der Editoren definierte Nachricht (\s{toString}) 
wandelt den Wert einer Bildschirmrepr"asentation in einem Editor in eine 
Zeichenkette um und gibt ihn zur"uck. Die Funktion findet im Zusammenhang
mit dem Datenaustausch zwischen Editoren Verwendung.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Allgemeine Funktionen}

Neben dem Protokoll f"ur einen Editor sind in dem Modul \s{editorRep} auch
Funktionen zu finden, die auf alle Editoren angewendet werden k"onnen.
Das sind \zB\ Funktionen, die feststellen, ob ein Editor sichtbar ist,
oder die aus einem Editor einen Subeditor machen. Die Konzepte der 
wichtigsten Funktionen werden nachfolgend beschrieben.

Zu jeder funktionalen Komponente des Protokolls existiert eine
korrespondierende Funktion, die den objektorientierten Programmierstil
der hierarchisch strukturierten Editoren unterst"utzt. Die Funktionen 
k"onnen jeweils in zwei Teile aufgeteilt werden. Der eine Teil ist f"ur
alle Editoren gleich. In ihm werden die Zustandsinformation ausgewertet
bzw.\ gesetzt. Im anderen Teil wird die Nachricht an den "ubergebenen
Editor propagiert. Die Funktionen werden in der gleichen Reihenfolge
beschrieben wie die Komponenten des Protokolls. Grunds"atzlich testen 
alle Funktionen vorher den Zustand des Editors ab und geben, falls
notwendig, entsprechende Meldungen aus. In Abbildung 
\ref{Abb. Statusuebergaenge} sind alle m"oglichen Zustands"uberg"ange 
dargestellt. In den Klammern stehen jeweils die zus"atzlichen Zust"ande
von Editoren, die direkt in einem Rahmen integriert sind. Sie werden in
Abschnitt \ref{Abs. Hilfsmodule} noch ausf"uhrlich beschrieben.

\begin{figure}[htb]
  \psbild{0.8#1}{editenv}{Stati.ps}
  \caption{M"ogliche Zustands"uberg"ange der Editoren}
  \label{Abb. Statusuebergaenge}
\end{figure}

Beim Erzeugen der \n-Repr"asentation mit \s{create} wird im Editor der
Zustand \s{new} gel"oscht. Als neue Zustandsinformation wird im Editor 
\s{exists} gesetzt. Umgekehrt setzt die \s{destroy}-Funktion den Zustand
des Editors wieder auf \s{new}.

Die \s{show}-Funktion kann nur schon erzeugte Editoren anzeigen.
Aus diesem Grund wird dies vor der Weiterpropagierung abgepr"uft. 
Andersherum kann die \s{hide}-Funktion nur Editoren vom Bildschirm
entfernen, die sichtbar sind. Wird ein Rahmen geschlossen, so sind 
alle darin dargestellten Editoren nicht mehr sichtbar. Ein geschlossener,
nicht mehr sichtbarer Rahmen wird nicht gel"oscht. Er l"a"st sich wieder
"offnen, ohne ihn neu zu erzeugen.

Die Funktion \s{refresh} dient dem Lesen von Werten aus der
zugrundeliegenden Datenstruktur. Die Funktion wird implizit durch das
System aufgerufen, wenn ein Rahmen zum ersten Mal ge"offnet und wenn ein
geschlossener Rahmen wieder ge"offnet wird. Die Funktion kann auch
explizit vom Anwender aufgerufen werden, um von ihm ver"anderte, aber 
noch nicht zur"uckgeschriebene Werte erneut aus der Datenstruktur zu 
lesen.

Schreibt ein beliebiger Editor seine Werte in die Variable der 
zugrundeliegenden Datenstruktur zur"uck, so k"onnen dabei 
Integrit"atsbedingungen verletzt werden. In der Funktion \s{apply} wird
das Zur"uckschreiben deshalb "uber das \k{try}-Konstrukt von \ty\ 
aufgerufen. Tritt beim Zur"uckschreiben ein Fehler auf, so wird eine
Ausnahmebehandlung ausgel"ost. Sie gibt den Text des Fehlers in der 
Fu"szeile des Editors aus, in dem der Fehler aufgetreten ist. Aus
Geschwindigkeitsgr"unden arbeitet diese Funktion, wie auch die 
\s{refresh}-Funktion, nur auf sichtbaren Editoren.

Neben den Protokollfunktionen ist in diesem Modul eine weitere wichtige
Funktion implementiert. 

\begin{figure}[htb]
\begin{xple}
    \k{let} waitAndDispatch(f() :Bool) :\k{Ok} =
       \k{while} f() \k{do}
          wire.flush()
          action.waitAndDispatch()
       \k{end}
\end{xple}
\label{Prg. waitAndDispatch}
\end{figure}

Die Funktion kann als Hauptnachrichtenschleife in Anwenderprogrammen
verwendet werden. Der Funktion wird eine boole'sche Funktion als 
Parameter "ubergeben. Intern wird in einer Schleife die boole'sche 
Funktion ausgewertet und auf ankommende Nachrichten von \xns\ gewartet.
Nachrichten werden an ihre Empf"anger weitergeleitet. Ist das Ergebnis
der "ubergebenen Funktion nicht mehr \s{true}, so wird die Schleife und
damit auch die Funktion verlassen. 

Eine Vielzahl weiterer Funktionen erm"oglicht das Abtesten und Erkennen 
definierter Zu\-st"an\-de von Editoren. Da diese Funktionen f"ur das weitere
Verst"andnis nicht von Bedeutung sind, werden sie in diesem Zusammenhang
nicht weiter behandelt.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Hilfsmodule}
\label{Abs. Hilfsmodule}

In diesem Abschnitt werden die Hilfsmodule der Editorbibliothek beschrieben.
Im einzelnen sind das die Module \s{newsUtil}, \s{editorUtil}, \s{editorMenu},
\s{editorButtons}, \s{editorTarget} und \s{editorWindow}. Die Hilfsmodule
bilden die unterste Schicht des in Abbildung \ref{Abb. Modulstruktur} auf Seite 
\pageref{Abb. Modulstruktur} gezeigten Schichtenmodells.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{newsUtil}

Das Modul \s{newsUtil} fa"st im wesentlichen Sequenzen mit Funktionsaufrufen
in Module des \s{newsenv} zusammen. Dadurch k"onnen die Module der 
Editorbibliothek auf abstrakte Schnittstellenkomponenten zur"uckgreifen.
Zum Beispiel werden ein Grund- und ein Aufklappfenster inklusive der
Ereignisbehandlung zur Verf"ugung gestellt. Die Fenster sind die Grundlage
der Rahmen f"ur die Editoren. Daneben sind auch verschiedene Funktionen 
zur Behandlung von Rollbalken und Rollisten zu finden. Ein Rollbalken wird
im Iterationseditor zum Navigieren ben"otigt und die Rolliste nimmt die
Elemente des Tabelleneditors auf.

Erw"ahnenswert ist noch die durch die Funktion \s{setChildPos}
implementierte intelligente Positionsberechnung f"ur das Anzeigen von
Subrahmen. In der Funktion wird in Abh"angigkeit von der Position und der
Gr"o"se des Vaterrahmens die neue Position berechnet. Die neue Position
wird so bestimmt, da"s der neue Rahmen vollst"andig auf dem Bildschirm 
sichtbar ist.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{editorUtil}

Im Modul \s{editorUtil} befinden sich Funktionen zum Konvertieren
verschiedener Datentypen. Die Funktionen werden f"ur den
anwendungs"ubergreifenden Datenaustausch ben"otigt. 


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{editorMenu}

Das Modul \s{editorMenu} definiert eine f"ur alle Editoren einheitliche
Men"uzeile. Wie schon in Abbildung \ref{Abb. Rahmen} auf Seite 
\pageref{Abb. Rahmen} dargestellt, besteht die Men"uzeile aus den beiden
Men"upunkten \s{Edit} und \e{View}.

Die einzelnen Men"ueintr"age k"onnen beim Erzeugen des Men"us mit 
\ty-Funktionen assoziiert werden. Dar"uber hinaus ist es m"oglich, die
benannten Men"ueintr"age einzeln je nach Zustand der Anwendung zu
aktivieren bzw.\ zu deaktivieren.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{editorButtons}

Die einzige Funktion dieses Moduls erzeugt die beiden Kn"opfe, die sich
unter dem eigentlichen Editor im Rahmen befinden. Dabei k"onnen Name
und Funktionalit"at der Kn"opfe bestimmt werden. Der linke Knopf wird
als vorausgew"ahlter Knopf eingerichtet. Im allgemeinen wird der linke
Knopf zum Speichern der Daten im Editor und der rechte zum Zur"uckschreiben 
verwendet.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{editorTarget}

Das Modul \s{editorTarget} exportiert Funktionen zur Erzeugung und
Manipulation des Datenaustauschfeldes. Das Datenaustauschfeld befindet
sich ganz rechts in der Men"uzeile des Rahmens in Abbildung \ref{Abb. Rahmen}
auf Seite \pageref{Abb. Rahmen}. Es dient dem anwendungs"ubergreifenden
Datenaustausch.

Wie schon in Abschnitt \ref{Abs. Rahmen fuer Editoren} erw"ahnt, k"onnen 
beim Datenaustausch zwei Arten unterschieden werden. Der Austausch von 
Daten zwischen Editoren kann dabei auf typisierte Weise erfolgen. Die 
Daten werden "uber ein definiertes Protokoll (\VSE\ 
\pageref{Prg. Datenaustauschprotokoll}) zwischen Quell- und Zieleditor
ausgetauscht. Hingegen ist f"ur den Austausch zwischen einem Editor 
und einem externen Programm eine geeignete Repr"asentation zu finden.

Der Austausch von Daten zwischen Editoren erfolgt "uber die beiden
Protokollfunktionen \s{getValue} und \s{setValue}. Dabei wird der Wert
des Editors in eine austauschf"ahige Struktur (\s{ValueRep}) verpackt. Der 
Zieleditor versucht, die Daten aus der Struktur der Reihe nach auf seine
Komponenten zu verteilen.

F"ur den Austausch zwischen einem Editor und einem externen Programm,
\zB\ dem \ow-Da\-tei\-ma\-na\-ger, mu"s eine geeignete Austauschrepr"asentation
gefunden werden. Als einfache Repr"asentation kommen mit Tabulator oder
Komma separierte Listen in Frage. Pro Zeile w"urde jeweils ein Datensatz
ausgegeben werden. Die Werte der Felder sind durch einen Tabulator oder
ein Komma voneinander getrennt. In solchen Listen k"onnten allerdings
in den Zeilen nur Basiswerte ausgegeben werden. F"ur NF$^{2}$-Daten 
m"u"sten geeignetere Repr"asentationen gefunden werden. 


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{editorWindow}

Das Modul \s{editorWindow} ist das wichtigste der Hilfsmodule. Es stellt
die Rahmen f"ur die Editoren zur Verf"ugung. Wie schon erw"ahnt, wird bei
den Rahmen zwischen Grund- und Aufklappfenstern unterschieden. Daher
gibt es auch zwei Funktionen, die die unterschiedlichen Anforderungen
ber"ucksichtigen. Mit dem Rahmen werden auch die Men"uzeile, das 
Datenaustauschfeld und die beiden Kn"opfe erzeugt, in den Rahmen eingef"ugt
und initialisiert. Beide Funktionen treffen, wenn sie aufgerufen werden,
auf eine der drei folgenden Situationen:

\blist
  \item Der Rahmen existiert noch nicht oder
  \item er existiert bereits, wird aber momentan nicht angezeigt, oder
  \item er existiert und wird bereits angezeigt.
\elist

Im ersten Fall wird zun"achst der einzusetzende Editor mit seinen direkten
Komponenten und ein entsprechender Rahmen erzeugt. Anschlie"send werden die
Men"uzeile, das Datenaustauschfeld, der Editor und die beiden Kn"opfe im
Rahmen plaziert. Der fertige Editor kann auf dem Bildschirm angezeigt werden,
nachdem sein Zustand auf \s{windowed} ge"andert worden ist. Beim
Initialisieren eines Subeditors wird zus"atzlich der Vater vermerkt.

Im zweiten Fall m"ussen Editor und Rahmen nicht neu erzeugt werden, da sie
noch existieren und momentan nur nicht sichtbar sind. Deswegen wird der
Editor nur wieder angezeigt und die Werte werden neu ausgelesen. Aus internen
Gr"unden mu"s die Ereignisbehandlung neu initialisiert und aktiviert
werden.

Der dritte Fall ist der einfachste, da der Rahmen nicht nur existiert, sondern
auch angezeigt wird. Daher wird hier nur der Rahmen in den Vordergrund geholt.

Das Modul exportiert neben den beiden Funktionen noch eine feste 
Positionsangabe. Die Position kann verwendet werden um den Basisrahmen 
anzuzeigen. Alle weiteren Subrahmen werden relativ zum Vaterrahmen durch
die intelligente Positionsberechnung plaziert.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Editoren}
\label{Abs. Editoren}

Die Implementation der Editoren gestaltet sich unter Benutzung des Protokolls
und der im vorherigen Abschnitt beschriebenen Hilfsmodule sehr "ubersichtlich. 
Trotzdem werden die einzelnen Editoren in separaten Modulen implementiert.
Erst das Modul \s{editor} (\VAS\ \ref{Abs. Schnittstelle zum Anwender}) 
bildet eine zusammenfassende Schnittstelle f"ur den Anwender. Nur "uber
diese Schnittstelle kann auf die Editorbibliothek zugegriffen werden. 
In diesem Abschnitt werden die einzelnen Module der Reihe nach vorgestellt.

Jedes Modul fa"st die Implementationen von unterschiedlichen Editoren einer
der vier Klassen zusammen. Die einfachsten Editoren finden sich in der 
Klasse der \e{Basiseditoren}. Sie entsprechen weitgehend den in \ty\ 
vorhandenen Basistypen. Die Klasse der \e{Ver\-bund\-edi\-to\-ren}\,
beinhaltet einfache hierarchische Editoren. Sie entsprechen weitgehend den
in \ty\ vorhandenen Typkonstruktoren. Die dritte Klasse 
(\e{Massendateneditoren}\,) implementiert Editoren zur Verwaltung von
Massendaten. 

Wie in Abbildung \ref{Abb. Ablauf} auf Seite \pageref{Abb. Ablauf} 
dargestellt, kommunizieren die Editoren mit den Programmvariablen "uber
zwei bei der Instanziierung "ubergebene Funktionen (\s{get} und
\s{set}). Die \s{get}-Funktion dient dem Auslesen des Wertes aus der 
zugrundeliegenden Datenstruktur. Die \s{set}-Funktion dient dagegen dem
Zur"uckschreiben des Wertes in die Datenstruktur. An dieser Stelle k"onnen
vom Anwender Integrit"atsbedingungen formuliert werden. Durch die
Instanziierung werden die einzelnen Komponenten des im Abschnitt 
\ref{Abs. Abstraktes Datenstrukturmodell} beschriebenen Protokolls mit den
f"ur den Editor wichtigen Informationen belegt.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection{Basiseditoren}
\label{Abs. Basiseditoren}

Das Modul \s{simpleEditors} definiert Funktionen zur Erzeugung von 
Basiseditoren. Das sind Editoren zur Visualisierung von Werten der 
\ty-Basistypen sowie von Aufz"ahlungstypen und parameterlosen Funktionen 
ohne R"uckgabewert. In Tabelle \ref{Tab. Basiseditoren} sind alle in
diesem Modul implementierten Editoren mit den entsprechenden Typen
aufgef"uhrt.

\begin{table}[htb]
  \begin{center}
    \begin{tabular}{|l|l|l|l|}
      \hline
      {\bf Editor} & {\bf Name} & {\bf Typ} \\
      \hline
      \hline
      Ganzzahlen        & \s{newInt}         & \k{var} \s{Int} \\
      Flie"skommazahlen & \s{newReal}        & \k{var} \s{Real} \\  
      Zeichen           & \s{newChar}        & \k{var} \s{Char} \\ 
      Zeichenketten     & \s{newString}      & \k{var} \s{String} \\ 
      Boole'sche Werte  & \s{newBool}        & \k{var} \s{Bool} \\ 
      Aufz"ahlungen     & \s{newEnum}        & \k{var} \k{Tuple} \k{case} \s{\dots}\ \k{end} \\
      \hline
      Konstanten        & \s{newStringConst} & \s{String} \\ 
      Konstanten        & \s{newStringVal}   & \k{var} \s{String} \\ 
      \hline
      Funktionen        & \s{newFun}         & \s{\k{Fun}() :\k{Ok}} \\
      Nullwerte         & \s{newEmpty}       & \\          
      \hline
    \end{tabular}
  \end{center}
  \caption{Basiseditoren}
  \label{Tab. Basiseditoren}
\end{table}

Am Beispiel eines Editors f"ur ganze Zahlen soll die Vorgehensweise bei
der Implementation beschrieben werden.

\begin{xple}
    newInt(l :DisplayItem  get() :Int  set(:Int) :\k{Ok}) :T
\end{xple}

An der Signatur ist zu erkennen, da"s ein Editor neben seinem Namen (\s{l}),
der in diesem Fall in der Kopfzeile des Rahmens angezeigt wird, zwei
funktionale Parameter (\s{get} und \s{set}) "ubergeben bekommt.

\begin{xple}
    \k{let} hidden = editorRep.newHidden() 
    \k{let} label = l
    \k{let} separateWindow = false
\end{xple}

Die Komponente \s{hidden} erh"alt mit der Funktion \s{newHidden} die
Standardvorbelegungen. Der in \s{l} "ubergebene Name des Editors wird
in der Komponente \s{label} gespeichert. Alle einfachen Editoren
werden in dem Rahmen angezeigt, in dem sie erzeugt worden sind. Aus diesem
Grund wird die Komponente \s{separateWindow} auf \s{false} gesetzt.

\begin{xple}
    \k{let} menuActions :MenuActions =
       iter.enum \k{of} 
          \k{tuple} editorMenu.new \k{fun}() numericField.setValue(hidden.guiId 0) \k{end}
       \k{end}
\end{xple}

Die Men"uzeile wird nur mit einer einzigen Funktion, f"ur den 
Men"ueintrag \s{new}, belegt, \dh\ alle
anderen Men"ueintr"age sind nicht selektierbar. Die Funktion hinter
dem Men"ueintrag \s{new} setzt den Wert des Editors auf den
Grundwert \s{0}.

Auch die funktionalen Komponenten eines Editors f"ur ganze Zahlen sind auf
einfache Weise zu beschreiben. 

\begin{xple}
    \k{let} create() :\k{Ok} =
       \k{begin}
          hidden.guiId := numericField.create(object.framebuffer)
          textField.setMinimumVisible(hidden.guiId 10)
       \k{end}
\end{xple}

Die \s{create}-Funktion erzeugt ein auf zehn Zeichen beschr"anktes 
numerisches Eingabefeld. Der Identifikator f"ur die erzeugte 
Schnittstellenkomponente wird in der Komponente \s{hidden.guiId}
vermerkt. Er wird von anderen funktionalen Komponenten noch ben"otigt.

\begin{xple}
    \k{let} apply() :Bool =
       \k{begin}
          set(numericField.getValue(hidden.guiId))
          true
       \k{end}
\end{xple}

Die Funktion \s{apply} verwendet die "ubergebene Funktion \s{set} zum
Zur"uckschreiben der Werte aus dem Editor in die zugrundeliegende
Datenstruktur. Um den Wert aus dem numerischen Eingabefeld zu bekommen,
wird die Funktion \s{getValue} aus dem entsprechenden Modul aufgerufen. 

\begin{xple}
    \k{let} refresh() :\k{Ok} =
       numericField.setValue(hidden.guiId get())
\end{xple}

Die \s{refresh}-Funktion beschreibt den umgekehrten Weg. Unter Verwendung
der "ubergebenen Funktion \s{get} wird der Wert aus der Datenstruktur
ausgelesen und als Parameter der Funktion \s{setValue} benutzt. Im Editor
wird mit dieser Methode ein Wert gesetzt.

\begin{xple}
    \k{let} show() :\k{Ok} =
       canvas.setVisualState(hidden.guiId layout.active)

    \k{let} hide() :\k{Ok} =
       canvas.setVisualState(hidden.guiId layout.inactive)
\end{xple}

Die Funktionen \s{show} und \s{hide} aktivieren bzw.\ deaktivieren das
numerische Eingabefeld "uber die Funktion \s{canvas.setVisualState}.

\begin{xple}
    \k{let} getValue() :ValueRep =
       \k{tuple} \k{case} simpleV \k{of} ValueRep \k{with}
          \k{let} value = fmt.int(numericField.getValue(hidden.guiId))
       \k{end}
\end{xple}

Die Komponente \s{getValue} liest den Wert auf die gleiche Weise aus
dem Editor wie die \s{apply}-Funktion. Die Funktion setzt den 
gelesenen Wert in die Datenaustauschrepr"asentation f"ur einfache 
Editoren (\s{simpleV}) ein. Dazu wird der Wert in eine Zeichenkette 
konvertiert.

\begin{xple}
    \k{let} setValue(v :ValueRep) :\k{Ok} =
       \k{case} v
       \k{when} simpleV \k{with} v \k{then}
          numericField.setValue(hidden.guiId editorUtil.stringToInt(v.value))
       \k{else}
          \k{ok}
       \k{end}
\end{xple}

Den umgekehrten Weg geht die \s{setValue}-Funktion. Sie testet die
Datenaustauschrepr"asentation auf \s{simpleV} und schreibt im 
Erfolgsfall den umgewandelten Wert in den Editor.

\begin{xple}
    \k{let} toString() :Iter.T(String) =
       iter.singleton(fmt.int(get()))
\end{xple}

Die letzte Komponente gibt den Wert des Editors als Iteration mit
einem Element zur"uck.

Die Instanziierungen f"ur die anderen einfachen Editoren laufen alle in 
der gleichen Weise ab. Lediglich der Aufz"ahlungseditor (\s{newEnum}),
der Funktionseditor (\s{newFunction}) und der leere Editor (\s{newEmpty}) 
haben eine von den anderen einfachen Editoren abweichende Signatur. 

Einem Aufz"ahlungseditor werden zus"atzlich zu den beiden Funktionen 
\s{get} und \s{set} eine Ordnungsfunktion (\s{ord}) und eine Funktion
zum Erzeugen einer Iteration von Paaren (\s{pairs}) "ubergeben.

\begin{xple}
    newEnum(O $<$:\k{Ok}  l :DisplayItem  get() :O  set(:O) :\k{Ok}
          ord(:O) :Int  pairs() :Iter.T(\k{Tuple} :O :String \k{end})) :T
\end{xple}

Ohne die beiden zus"atzlichen Parameter w"are es f"ur die beiden
Funktionen \s{set} und \s{get} nicht m"oglich, Werte zu lesen oder
zu schreiben. Die Funktion \s{ord} gibt f"ur einen Wert eines 
Typs \s{O} die Ordinalit"at zur"uck. Die Funktion \s{pairs} erzeugt
eine Iteration von Paaren "uber alle Werte des 
Typs \s{O}. Ein Paar besteht jeweils aus einem Wert des Typs \s{O}
und einer Zeichenkette. Mit Hilfe der Funktion k"onnen Werte eines
beliebig komplexen Typs angezeigt werden. Der Anwender ist 
verantwortlich daf"ur, da"s aus einem Wert des Typs \s{O} eine 
sinnvolle Zeichenkette gebildet wird. Dieses Konzept erm"oglicht 
es, aus Tupeln nur bestimmte Komponenten f"ur die Bildung der 
Zeichenkette zu benutzen. Nach der Beschreibung der beiden 
Funktionen \s{ord} und \s{pairs} soll nun die Vorgehensweise der
Funktionen \s{apply} und \s{refresh} beschrieben werden. In der 
Funktion \s{apply} wird die erste Zeichenkette in der Iteration 
gesucht, die der ausgew"ahlten entspricht. Der in diesem Paar 
vermerkte Wert des Typs \s{O} wird in die Datenstruktur 
zur"uckgeschrieben. In der Funktion \s{refresh} wird die "ubergebene
Funktion \s{ord} ben"otigt. Mit Hilfe dieser Funktion wird in der 
Iteration der Wert gesucht, der dem Inhalt der Datenstruktur an 
dieser Stelle entspricht. Die diesem Wert zugeordnete Zeichenkette
wird im Editor ausgegeben.

Die Signatur eines Editors zur Ausf"uhrung von Funktionen hat die 
folgende Form:

\begin{xple}
    newFunction(l :DisplayItem  name :DisplayItem  f :Action.T) :T
\end{xple}

Wie an der Signatur zu sehen ist, werden einem Funktionseditor keine
\s{set} und \s{get}-Funk\-tio\-nen "ubergeben. Neben dem Namen des Editors
beschreiben die weiteren Parameter den Namen (\s{name}), der auf dem Knopf 
zum Ansto"sen der Funktion steht, sowie die anzusto"sende Funktion (\s{f}) 
selbst. Der interne Aufbau des Editors gestaltet sich aus diesem Grund
auch sehr einfach, denn die \s{apply}- und die \s{refresh}-Funktionen
entfallen.

Noch einfacher ist der Aufbau des leeren Editors. Als Parameter wird
nur der Name des Editors "ubergeben.

\begin{xple}
    newEmpty(l :DisplayItem) :T
\end{xple}

Bevor im weiteren auf die komplexeren Editoren eingegangen wird, sollen
hier noch einige Bemerkungen zu zwei einfachen Editoren aufgef"uhrt werden.
Werte in den beiden Editoren \s{newStringVal} und \s{newStringConst} sind
nicht ver"anderbar. Dabei wird dem \s{newStringVal}-Editor nur eine 
\s{get}-Funktion "ubergeben. Die Werte werden hier in der gleichen Weise
erzeugt wie bei einem \s{newString}-Editor. Dem \s{newStringConst}-Editor
wird bei der Instanziierung hingegen eine Zeichenkettenkonstante "ubergeben,
die f"ur alle Werte einer Datenstruktur gleich ist.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection{Verbundeditoren}
\label{Abs. Verbundeditoren}

Verbundeditoren sind einfache hierarchische Editoren. Die beiden im Modul
\s{recordEditors} implementierten Editoren entsprechen zwei in \ty\ 
vorhandenen Typkonstruktoren (\VTB\ \ref{Tab. Verbundeditoren}).

\begin{table}[htb]
  \begin{center}
    \begin{tabular}{|l|l|l|l|}
      \hline
      {\bf Editor} & {\bf Name} & {\bf Typ} \\
      \hline
      \hline
      Verbunde  & \s{newRecord}  & \s{\k{Tuple} \dots\ \k{end}} \\
      Varianten & \s{newVariant} & \s{\k{Tuple} \k{case} \dots\ \k{end}} \\  
      \hline
    \end{tabular}
  \end{center}
  \caption{Verbundeditoren}
  \label{Tab. Verbundeditoren}
\end{table}

Als erster hierarchischer Editor wird der Verbundeditor (\s{newRecord}\,) 
vorgestellt. Ein solcher Editor kann seinerseits einfache, strukturierte und
multimediale Editoren enthalten. Diese werden in einem Feld bei der 
Instanziierung mit "ubergeben. Die Signatur eines Verbundeditors hat die
folgende Form:

\begin{xple}
    newRecord(l :DisplayItem.T  fields :Iter.T(Editor.T)) :Editor.T
\end{xple}

Wie an der Signatur zu sehen ist, erwartet der Verbundeditor eine 
Iteration von Editoren beliebiger Typen. Einem Verbundeditor m"ussen keine
\s{get}- und \s{set}-Funktionen "ubergeben werden, da alle in einem Verbund 
integrierten Editoren diese Funktionen selbst beinhalten.

Das Protokoll eines solchen Editors wird wie folgt definiert: die
Komponente \s{hidden} wird genau wie bei den einfachen Editoren mit
dem Ergebnis der Funktion \s{newHidden} vorbelegt. Da ein ge"offneter
Verbundeditor in einem eigenen Fenster dargestellt werden soll, wird
die Komponente \s{separateWindow} anders als bei den einfachen 
Editoren belegt. 

Komplexer gestaltet sich die Implementation der \s{create}-Funktion.
Ein Verbundeditor wird durch einen speziellen Beh"alter 
(\e{calculated panel}\,) visualisiert. Die einzelnen in der
Iteration "ubergebenen Editoren m"ussen an geeigneten Stellen
im Beh"alter plaziert werden. Wie schon fr"uher erw"ahnt, werden
die Namen der Editoren rechtsb"undig und die Editoren selbst
linksb"undig in den Beh"alter eingef"ugt. Bei den Editoren
mu"s zus"atzlich zwischen einfachen und hierarchischen Editoren
unterschieden werden. F"ur jeden einfachen Editor wird nach 
seinem Namen die durch die jeweilige \s{guiId} identifizierte 
Bildschirmrepr"asentation in den Beh"alter eingef"ugt. F"ur 
hierarchische Editoren wird nach dem Namen statt der
Bildschirmrepr"asentation des Subeditors ein Knopf in den Beh"alter
eingef"ugt. An den Knopf ist eine Aktion gebunden, die, wenn der
Knopf gedr"uckt wird, einen Subrahmen "offnet, in dem der 
hierarchische Subeditor dargestellt wird.

Die anderen funktionalen Komponenten des Verbundeditors propagieren 
die entsprechende Nachricht an die in den Verbund integrierten 
Editoren.

Der zweite in diesem Modul implementierte Editor ist der 
Varianteneditor. Ein solcher Editor kann als Kombination von
einem Aufz"ahlungs- und einem Verbundeditor begriffen werden.
Diese Tatsache ist auch an der Signatur des Varianteneditors zu
erkennen.

\begin{xple}
  newVariant(O $<$:\k{Ok}  l :DisplayItem  get() :O  set(:O) :\k{Ok} 
     ord(:O) :Int  variants :Iter.T(\k{Tuple} :O :T \k{end})) :T
\end{xple}

Wie an der Signatur zu sehen ist, erwartet der Varianteneditor im
Gegensatz zum Ver\-bund\-edi\-tor wieder eine \s{get}- und \s{set}-Funktion.
Daneben werden eine Ordnungsfunktion (\s{ord}) und eine Funktion
zum Erzeugen einer Iteration von Paaren (\s{variants}) "ubergeben.
Die Funktion \s{ord} berechnet die Ordinalit"at der Varianten.
Die Funktion \s{variants} erzeugt eine Iteration von Paaren aus
Variante und dazugeh"origem Editor.

Varianteneditoren werden wie Verbundeditoren durch einen
speziellen Beh"alter repr"asentiert. In den Beh"alter werden ein 
Abk"urzungsmen"uknopf zum Ausw"ahlen der Variante und der zu der
Variante geh"orende Editor eingef"ugt. Erschwerend kommt hinzu,
da"s die Variante und damit auch der Editor dynamisch ge"andert
werden k"onnen. Aus diesem Grund ist beim Varianteneditor auch 
die \s{refresh}-Funktion komplexer. 

Die intern zum "Andern der Variante verwendete Funktion \s{change} 
und die \s{refresh}-Funktion machen intensiven Gebrauch von den
"ubergebenen Parametern. W"ahrend die \s{change}-Funk\-tion die neue
Variante durch die interaktive Auswahl des Anwenders erh"alt, bekommt
die \s{refresh}-Funktion die neue Variante durch die \s{get}-Funktion.
Beide Funktionen m"ussen den zur alten Variante geh"orenden Editor
aus dem Beh"alter entfernen, den neuen Editor einf"ugen und, da der
neue Editor mehr oder weniger Komponenten als der alte enthalten kann,
die Gr"o"se des Beh"alters neu bestimmen.

Die anderen funktionalen Komponenten des Varianteneditors propagieren 
die entsprechende Nachricht an den zur aktuellen Variante geh"orenden
Editor.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection{Massendateneditoren}
\label{Abs. Massendateneditoren}

In diesem Abschnitt werden Editoren beschrieben, die das Anzeigen von
Massendaten erm"oglichen. Alle Module, die einen Kollektionstyp 
exportieren, wie \zB\ \s{set} oder \s{list}, verf"ugen "uber eine
\s{elements}-Funktion. Mit Hilfe dieser Funktion ist es m"oglich,
beliebige Kollektionen auf die von den Massendateneditoren verwendete
Datenstruktur \s{LinkedList} abzubilden. Diese Datenstruktur eignet
sich besonders deswegen als Grundlage f"ur die Datenvisualisierung,
weil ihre Elemente ver"anderbar und an eine Position gebunden sind.
Mit den Massendateneditoren kann daher eine gro"se Bandbreite von 
Datenstrukturen visualisiert werden. Wie in Tabelle 
\ref{Tab. Massendateneditoren} zu sehen ist, gibt es zwei
Massendateneditoren. Einen Iterationseditor zum satzweisen direkten
Editieren von Massendaten und einen Tabelleneditor zum gleichzeitigen
Anzeigen von mehreren Datens"atzen.

\begin{table}[htb]
  \begin{center}
    \begin{tabular}{|l|l|l|l|}
      \hline
      {\bf Editor} & {\bf Name} & {\bf Typ} \\
      \hline
      \hline
      Iterationen & \s{newIter}  & \s{LinkedList.T(\s{\dots})} \\
      Tabellen    & \s{newTable} & \s{LinkedList.T(\s{\dots})} \\  
      \hline
    \end{tabular}
  \end{center}
  \caption{Massendateneditoren}
  \label{Tab. Massendateneditoren}
\end{table}

Die Signaturen der beiden Massendateneditoren unterscheiden sich nicht.
Sie haben die folgende Form:

\begin{xple}
    newIter, newTable(E $<$:\k{Ok}  l :DisplayItem  get() :LinkedList.T(E) 
       newElement() :E  elementEditor(:Cursor(E)) :T) :T
\end{xple}

Die beiden Funktionen \s{get} und \s{set} haben die gleiche Aufgabe wie
bei den einfachen Editoren. Der Anwender mu"s f"ur das Einf"ugen von
Elementen in die Datenstruktur eine Funktion "ubergeben, die ein neues
Element erzeugt (\s{newElement}). Dies ist notwendig, da in \ty\ keine
uninitialisierten Variablen m"oglich sind. Als Alternative w"are es denkbar,
statt der Funktion einfach ein Element zu "ubergeben. Dies ist aber nicht
m"oglich, da in diesem Fall alle neuen Elemente eine Referenz auf dieses 
Element enthielten. "Anderungen an einem neuen Element w"aren in allen neuen
Elementen sichtbar. Als letztes erwartet dieser Editor einen Subeditor,
der zur "Anderung eines Elements der Iteration dient. Die Elemente
werden "uber einen \e{Cursor} ver"andert. Der Cursor ist als Tupel mit 
einer modifizierbaren Komponente implementiert.

\begin{xple}
    \k{Let} Cursor(E $<$:\k{Ok}) $<$:\k{Ok} =
       \k{Tuple} \k{var} x :E \k{end}
\end{xple}

Zus"atzlich m"ussen die Daten aus der Datenstruktur im Editor 
gehalten werden, denn sie werden erst nach einer \s{apply}-Nachricht 
zur"uckgeschrieben. Intern werden die Elemente in einer von dem Modul
\s{linkedList} angebotenen Struktur gehalten.

Das Protokoll eines solchen Editors wird wie folgt definiert: die
Komponente \s{hidden} wird genau wie bei den einfachen Editoren mit
dem Ergebnis der Funktion \s{newHidden} vorbelegt. Da ein ge"offneter
Iterationseditor in einem eigenen Fenster dargestellt werden soll, wird
die Komponente \s{separateWindow} anders als bei den einfachen 
Editoren belegt. 

Die Implementation der \s{create}-Funktion ist wie bei allen 
hierarchischen Editoren komplexer als bei den Basiseditoren.
Ein Iterationseditor wird durch einen speziellen Beh"alter
(\e{border bag}\,) repr"asentiert. Ein solcher Beh"alter kann
bis zu f"unf Klienten an fest vordefinierten Positionen aufnehmen.
Der zur Navigation ben"otigte Rollbalken wird oben in den Beh"alter
eingef"ugt. In die Mitte des Beh"alters wird der Elementeditor
eingef"ugt.

Auch die \s{refresh}-Funktion beinhaltet wieder zus"atzliche Logik,
denn es mu"s sichergestellt werden, da"s nur auf den vorhandenen
Elementen der Iteration navigiert wird. Die Funktion mu"s zus"atzlich
auch auf eine leere Iteration richtig reagieren k"onnen. Ist die
Iteration nicht leer, so wird der Cursor mit dem neuen Element
gef"ullt und der Wert auf dem Bildschirm ausgegeben. Alle anderen
funktionalen Komponenten propagieren die Nachrichten an den
Elementeditor weiter. 

Auf einem Iterationseditor sind eine Vielzahl von Funktionen
ausf"uhrbar. Die Funktionen k"onnen durch Ausw"ahlen der
entsprechenden Men"ueintr"age angesto"sen werden. Zum Beispiel
kann mit \s{New} ein neues Element an der aktuellen Position
eingef"ugt oder durch \s{Cut All} alle Elemente der Iteration
gel"oscht werden.

Mit einem Tabelleneditor ist es m"oglich, mehrere Datens"atze 
gleichzeitig anzuzeigen. Aus diesem Grund ist er auch anders aufgebaut.
Das zentrale graphische Element des Editors ist eine Tabelle. Die
einzelnen Felder werden in Form von Spalten in der Tabelle dargestellt.
Rechts neben der Tabelle befindet sich ein Rollbalken. Er erm"oglicht
die Navigation in der Tabelle.

Das eigentliche Problem beim Tabelleneditor ist die "Ubergabe der
Datens"atze an die Tabelle. Daf"ur stehen grunds"atzlich zwei Strategien
zur Verf"ugung. Zum einen k"onnen alle Datens"atze zu Beginn an die 
Tabelle "ubergeben werden. In diesem Fall kann die gesamte Behandlung 
der Navigation von der Tabelle selbst "ubernommen werden. Die "Ubergabe
von sehr vielen Datens"atzen an die Tabelle kann jedoch viel Zeit in 
Anspruch nehmen. Deswegen ist von dieser Vorgehensweise abzuraten.

Die zweite Strategie sieht vor, immer nur so viele Datens"atze an die
Tabelle zu "ubergeben, wie gleichzeitig sichtbar sind. In diesem
Fall mu"s die Navigation durch eine optimierende Funktion selbst
implementiert werden. Der Vorteil ist jedoch der wesentlich geringere
Anfangsaufwand. Genau wie beim Iterationseditor mu"s auch hier zwischen
einer leeren und einer gef"ullten Iteration unterschieden werden. Eine
leere Iteration wird durch eine leere Tabelle dargestellt. Bei einer
gef"ullten Iteration gibt es f"unf unterschiedliche 
Navigationsm"oglichkeiten

Wenn eine Zeile abw"arts navigiert wird, dann wird ein neues Element
unten angeh"angt und das oben herausfallende Element wird gel"oscht.
Wenn mehrere Zeilen abw"arts navigiert wird, werden abwechselnd
so viele neue Elemente unten angeh"angt und oben gel"oscht werden, wie
die Sicht verschoben worden ist. Entsprechendes gilt f"ur die beiden
F"alle beim aufw"arts Navigieren. Optimierend wird nur dann
eingegriffen, wenn um mehr Zeilen navigiert wird, als in der Tabelle
gleichzeitig sichtbar sind. In diesem Fall werden alle Elemente der 
Tabelle gel"oscht. Anschlie"send werden	so viele Elemente ab der
aktuellen Position in die Tabelle eingef"ugt, wie maximal gleichzeitig
sichtbar sind. Dieser Fall tritt auch auf, wenn noch gar keine Elemente 
in der Tabelle sind.

In einem Tabelleneditor k"onnen die Datens"atze nicht direkt ver"andert
werden. Um einen Datensatz zu ver"andern, kann durch Selektion einer
Zeile ein Elementeditor ge"offnet werden. Nach der Selektion wird
das ausgew"ahlte Element in den Cursor geladen und der Editor mit
diesem Element ge"offnet. Als Problem ergibt sich, da"s die
Bildschirmrepr"asentation des Tabelleneditors ge"andert werden mu"s,
nachdem eine sichtbare Zeile ge"andert worden ist.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Schnittstelle zum Anwendungsprogramm}
\label{Abs. Schnittstelle zum Anwender}

Das Modul \s{editor} dient als Schnittstelle zum Anwender der Bibliothek.
Nur "uber dieses Modul ist der Zugriff auf die Editorbibliothek m"oglich. 
Es reicht die in den anderen Modulen definierten Editoren zum Anwender 
durch. Dazu importiert es die Module \s{simpleEditors}, \s{recordEditors}
und \s{bulkEditors}. Auch das Protokoll wird "uber dieses Modul dem Anwender
zug"anglich gemacht. Die Funktion zum Anzeigen von Editoren wird vom Modul
\s{editorWindow} importiert und zum Anwender exportiert.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Benutzerdefinierte Editoren}
\label{Abs. Benutzerdefinierte Editoren}

Der Anwender der Editorbibliothek hat die M"oglichkeit, eigene Editoren
in die Umgebung zu integrieren. Dazu ist es lediglich notwendig, alle vom
Protokoll (\VAS\ \ref{Abs. Abstraktes Datenstrukturmodell}) vorgegebenen
Anforderungen zu erf"ullen. In diesem Abschnitt wird die Vorgehensweise
bei der Implementation eines Editors zum Abspielen von Audiodaten 
beschrieben.

In der \ty-Bibliothek \s{machineenv} befindet sich das Modul \s{audio}
\cite{MMM93}. Dieses Modul erm"oglicht \ty-Programmen das Aufnehmen, 
Editieren und Abspielen von Audiodaten. Dazu sind in dem Modul neben dem
abstrakten Datentyp \s{audio.T} verschiedene Funktionen implementiert,
die auf Werten dieses Typs arbeiten.

Der Editor zum Abspielen von Audiodaten wird an der Benutzerschnittstelle
durch einen Knopf repr"asentiert. Wird der Knopf gedr"uckt, so werden die
Daten an den Audioausgang "ubergeben und dort abgespielt.
		
\psbild{0.8#1}{editenv}{Audio.ps}

\pagebreak

Die Signatur des Editors hat die folgende Form:

\begin{xple}
    newAudio(l :DisplayItem  get() :audio.T) :Editor.T
\end{xple}

Die Implementation gestaltet sich sehr einfach. Importiert werden mu"s
neben anwendungsspezifischen Modulen nur das Modul \s{editor}. Alle 
zur Implementation ben"otigten Typen und Funktionen werden von diesem
Modul exportiert. Anschlie"send k"onnen der Reihe nach alle durch
das Protokoll der Editoren definierten Komponenten und Funktionen
implementiert werden. Zum Beispiel wird durch die \s{create}-Funktion
ein Knopf erzeugt. Der Knopf wird mit der folgenden \ty-Funktion
assoziiert:

\begin{xple}
    \k{let} play() :\k{Ok} = audio.play(get())
\end{xple}

Durch Dr"ucken des Knopfes werden die Audiodaten "uber einen Audioausgang
abgespielt. Da der Wert in der derzeitigen Version nicht "anderbar ist,
entf"allt die Implementation der \s{apply}-Funktion. Die anderen
Funktionen des Protokolls k"onnen analog zu denen des Editors f"ur
ganze Zahlen definiert werden (\VAS\ \ref{Abs. Basiseditoren}).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% End of text                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
