48 treeview
Das treeview-Objekt bietet die Möglichkeit hierarchische Informationen in einer Baumstruktur darzustellen. Dabei können Äste des Baumes (man spricht auch von Teilbäumen) zugeklappt werden, um die Übersichtlichkeit zu erhöhen. Die Programmierung entspricht weitgehend der einer listbox, allerdings ist nur eine Einfachselektion erlaubt.
Definition
{ export | reexport } { model } treeview { <Bezeichner> } { <Standardattribute> <Allgemeine Attribute> <Geometrieattribute> <Hierarchieattribute> <Layoutattribute> <Textattribute> <Objektspezifische Attribute> }
Der Benutzer kann interaktiv zwei unterschiedliche Aktionen durchführen:
-
Öffnen/Schließen eines Teilbaumes
Dies kann entweder durch Umschalten des +/- Knopfes oder durch ein Doppelklick auf den Text geschehen.
-
Selektion
Einfach- oder Doppelklick auf einen Eintrag oder Wechsel des Eintrages über die Tastatursteuerung. Zur Tastatursteuerung gehören die Cursortasten Links, Rechts, Hoch, Runter, Bild Hoch, Bild Runter, Pos 1 und Ende, wobei Links/Rechts bei der ersten Betätigung den Effekt hat, den Teilbaum zu Schließen/Öffnen und erst wenn dieser Zustand erfüllt ist, nach Oben/Unten zu gehen.
Das Treeview ist auf den Fenstersystemen Motif und MS-Windows verfügbar, allerdings erlaubt nur die MS-Windows-Plattform die Darstellung mit Bildern und allen Darstellungsstilen (Detaillierte Unterschiede sind in Ref: Attribute .style[] notiert). Bei allen anderen Plattformen erfolgt eine rein textuelle Darstellung.
Diese textuelle "Emulation" hat neben den sichtbaren Unterschieden noch andere Bedienungsunterschiede:
- Der +/- Knopf kann nicht getrennt angesteuert werden, das Öffnen/Schließen eines Teilbaumes geschieht nur über einen Doppelklick.
- Bei der Tastatursteuerung mittels Links oder Rechts wird der Öffnungszustand des Teilbaumes nicht verändert.
Für das vollständige Setzen des Treeview-Inhaltes inklusive .open[], .level[] und .picture[] von C- oder COBOL-Seite aus wurden keine neuen Schnittstellenfunktionen eingeführt, sondern die vorhandenen Funktionen DM_SetVectorValues() und DM_GetVectorValues() sind zu benutzen.
Folgende Ereignisse werden aufgrund von interaktiven Benutzeraktionen erzeugt:
Ereigniss(e) |
Belegte Attribute am thisevent |
Auslösung |
---|---|---|
.index |
Benutzeraktion Öffnen bzw. Schließen eines Teilbaumes |
|
.index |
Selektion wechselt auf einen anderen Eintrag |
|
.index |
Einfachklick auf einen Eintrag (Selektion) |
|
.index |
Doppelklick auf einen Eintrag |
Daneben gibt es noch weitere Standard-Events die in der nachfolgenden Tabelle aufgelistet sind und deren Bedeutung im Handbuch "Regelsprache" beschrieben ist.
Ereignisse
Kinder
Vater
Menü
Methoden
48.1 Attribute
48.2 Spezifische Attribute
Das Aussehen des Treeviews wird durch das Zusammenspiel der Attribute .content[integer], .level[integer], .picture[integer], .open[integer] und .style[enum] bestimmt.
Attribut | Beschreibung |
---|---|
Aktives Element des Objekts. |
|
Legt die Art der Geometrieberechnung bei aktivem Raster fest. Die detaillierte Beschreibung finden sie in der Attribut-Beschreibung in der „Attributreferenz“. |
|
Wert des I-ten Elements des Treeview, die Werte werden nicht vom Modell auf die Instanzen vererbt! Bitte beachten Sie auch das Kapitel „.content und contentspezifische Attribute“. |
|
Nummer des ersten angezeigten Zeichens (horizontale Scroll-Position). |
|
Gesamtzahl der Einträge des Treeview. |
|
Legt die Einrückung des jeweiligen Eintrags fest. Bitte beachten Sie auch das Kapitel „.content und contentspezifische Attribute“. |
|
Legt fest, ob ein Knoten geöffnet ist oder nicht. Bitte beachten Sie auch das Kapitel „.content und contentspezifische Attribute“. |
|
Optionen des Objekts. Indizes:
|
|
Angezeigtes Bild des jeweiligen Eintrags. Bitte beachten Sie auch das Kapitel „.content und contentspezifische Attribute“. |
|
Legt das Aussehen der Linien, Knöpfe und des obersten Eintrags (root Eintrag) fest. |
|
Erstes angezeigtes Element des Treeview bei vertikalem Scrollen. |
|
Userdata für beliebige Daten zu jedem Eintrag des Objekts. |
Weitere Informationen erhalten Sie in den folgenden Kapiteln bzw. in der „Attributreferenz“.
48.2.1 .content und contentspezifische Attribute
Der Inhalt des Treeviews wird im Attribut .content[integer] gesetzt. Dabei müssen die einzelnen Einträge (und damit der Index I) aufeinanderfolgend (1, 2, 3, …) sein.
Das Attribut .level[integer] legt danach die Einrückung des jeweiligen Eintrags fest. Soll ein Bild angezeigt werden, so wird dieses im Attribut .picture[integer] definiert.
Das Attribut .open[integer] legt fest, ob der jeweilige Knoten geöffnet ist oder nicht.
Anmerkung
Es ist zu beachten, dass erst durch Setzen des .content[I] der weitere Zugriff auf die contentspezifischen Attribute dieses Eintrags erlaubt ist. Daher muss zuerst der Content und danach die contentspezifischen Attribute gesetzt werden.
48.2.2 Hinweis zu veralteten Attributen
Die veralteten Attribute .focusitem und .focusable werden nicht mehr unterstützt und erzeugen eine ignoring
Warnung beim Setzen und Zurücksetzen (setinherit) sowie ein fail beim Auslesen dieser Attribute.
48.3 Informationsinhalt
Die hierarchische Information wird in Attribut-Feldern gespeichert. Pro Eintrag (= Knoten des hierarchischen Baums) wird in den Attributen .content[] und .picture[] ein statischer Text und ein Muster gespeichert, im .level[]-Attribut wird durch einen Zahlenwert die hierarchische Beziehung definiert. Zum Sichtbar/Unsichtbar-machen von Teilbäumen dient das boolsche .open[]-Attribut.
Diese Attribute dienen zum Aufnehmen von dynamischer Information und werden deshalb nicht vererbt! Der Indizierungsbereich geht für das .content[]-Attribut von 1 ... n, wobei n der Wert von .itemcount repräsentiert. Für die Attribute .level[], .picture[] und .open[] ist der Index-Bereich von 0 ... n definiert, das 0-te Element dient als Default-Wert für ungesetzte Werte im Indexbereich 1 ... n. Genau wie bei der Listbox kann die Feldgröße über das .itemcount-Attribut definiert oder dynamisch, durch das Sezten des n+1-ten .content[]-Feldes, um einen Eintrag vergrößert werden.
48.4 Baumkonzept
Die Abbildung der Einträge 1 ... n in eine hierarchischen Struktur, ein Baum mit Vater-Kind-Beziehungen, wird über das .level[]-Attribut definiert. Dessen Integer-Wert stellt quasi eine Einrückungstiefe
dar, allerdings ist nicht so sehr der absolute Wert entscheidend, sondern der Unterschied zum Vorgänger. Ist der Wert im Vergleich zum Vorgänger größer, so ist der Eintrag ein Kind des Vorgängers, ist er gleich, so handelt es sich um Geschwister, ist er aber kleiner, so handelt es sich um ein Kind eines weiter oben liegenden Vorgängers, dessen Einrückungstiefe
noch kleiner ist. Wenn kein Vater im Indexbereich 1 ... n zu finden ist, so spricht man auch von einer Wurzel.
Beispiel
Index I |
.content[I] |
.level[I] |
---|---|---|
1 |
A |
1 |
2 |
B |
2 |
3 |
C |
3 |
4 |
D |
3 |
5 |
E |
1 |
6 |
F |
2 |
ergibt die Baumstruktur:
Für eine detailliertere Definition siehe auch Attribut .level[integer] in der „Attributreferenz“.
Alle von der Listbox bekannten Methoden lassen sich auch beim Treeview anwenden, allerdings wirken sie in gleicher Weise auch auf die Attribute .level[], .open[] und .picture[]. Zusätzlich gibt es spezielle Methoden für die Manipulation und Abfrage der Baumstruktur.
Äquivalent zur Listbox erlaubt das Attribut .activeitem, einen Eintrag im Bereich 1 ... n des Baumes als selektiert zu setzen, bzw. den Selektionsstatus abzufragen. Die Selektierbarkeit hängt dabei mit der Sichtbarkeit des Eintrages im Baum zusammen, somit auch mit den Attributen .level[] und .open[]. Dabei gilt für die Regelsprache genauso wie für die interaktive Bedienung: Beim Setzen von .activeitem werden alle Väter auf .open[] := true gesetzt, wird umgekehrt ein Teilbaum mittels .open[I] := false unsichtbar gesetzt, obwohl ein Kind darin selektiert ist, erhält der Eintrag I nun die Selektion und .activeitem wird dementsprechend umgesetzt.
48.5 Darstellung
Die Darstellung unterscheidet sich im Vergleich zur Listbox durch folgende Punkte:
- Repräsentation der hierarchischen Beziehung von Einträgen über die Einrückung und optional zusätzlich durch Linien (Ref. Attribute .style[] und Attribute .level[]). Von Teilbäumen, deren Wurzel unsichtbar gesetzt ist (.open[] ist false), wird nur die Wurzel dargestellt.
- Optionales Bildchen zu einem Texteintrag. (Ref.: Attribute .picture[])
- Optionaler +/- Knopf, der bei Einträgen mit Kindern sichtbar wird und zum Öffnen(+)/Schließen(-) eines Teilbaumes dient. (Ref. Attribut .open[])
Ansonsten gelten alle für die Listbox relevanten Geometrie- und Layoutattribute.
48.6 Anmerkungen zum IDM für Windows
Zur Benutzung einer Radmaus zum Scrollen bitte Kapitel „Radmaus bzw. Radmausunterstützung unter Microsoft Windows“ beachten.
Das Treeview-Objekt unter Microsoft Windows lässt zwar Texte mit beliebiger Länge zu, es werden aber nur die ersten 260 Zeichen dargestellt. Da sich dieses Verhalten in neueren Versionen der "comctl32.dll" (> 6.0) ändern kann, erzeugt der IDM keine Meldung, wenn der Text zu lang ist.
48.7 Anmerkung zum IDM für Motif
Klarstellung einiger Benutzerereignisse für das Motif-WSI
select |
Kommt beim Mausklick auf einen Eintrag oder der Betätigung der Space-Taste auf den aktiven Eintrag. Ebenso wird das select-Ereignis ausgelöst, wenn mittels Cursortasten (Aufwärts, Abwärts, Pos 1, Ende) im Baum navigiert wird. |
dbselect |
Wird durch einen Doppelklick bzw. Return analog zum select-Ereignis ausgelöst. Zusätzlich wird der Öffnungszustand des Teilbaums (einschließlich der dementsprechenden open- bzw. close-Ereignisse) geändert. |
open, close |
Wird ausgelöst durch Doppelklick, Return bzw. Klick auf "+-"-Button und zeigt an, ob der Teilbaum geöffnet bzw. geschlossen wurde. |
activate |
Zeigt an, dass sich die Aktivierung geändert hat und wird durch Mausklick als auch durch einen Wechsel des aktiven Eintrags mittels Tastatur ausgelöst. |
Ein Treeview kann bei .options[opt_scroll_on_focus] = false per Tastaturnavigation unerreichbar sein, falls sich der aktive Eintrag außerhalb des sichtbaren Bereichs befindet. Er bleibt aber per Mausklick fokussierbar.
48.8 Anmerkung zum IDM für Qt
In den Qt-Versionen 4.x gibt es beim Treeview-Objekt einen Darstellungsfehler (QTBUG-9352), der unter Umständen bewirkt, dass Einträge entweder abgeschnitten oder überhaupt nicht dargestellt werden. Dies liegt daran, dass Qt die Spaltenbreite für die Anzeige der Treeview-Einträge nur anhand der Einträge im sichtbaren Bereich (+/- einem Offset) berechnet. Das heißt, dass dieser Effekt in einem Treeview mit besonders vielen Einträgen, deren Länge sich teilweise deutlich unterscheidet, zu tragen kommen kann. Ebenso betroffen sind Treeviews, die besonders viele Einträge mit vielen Hierarchiestufen enthalten.
Workaround
Als Workaround sollte man in diesem Fall den längsten Eintrag (im Sinne von benötigtem Darstellungsbereich, also Einrückung und Text) vor dem initialen Sichtbarmachen des Treeviews in den angezeigten Bereich bringen (z.B. über .topitem).
48.9 Beispiel
dialog Dialog window Wn { .active false; .xleft 229; .width 446; .ytop 131; .height 180; .title "Beispielfenster"; child treeview Tv { .xleft 38; .width 163; .ytop 15; .height 151; .content[1] "Firma A"; .content[2] "Mueller"; .content[3] "Meier"; .content[4] "Firma B"; .content[5] "Schulz"; .content[6] "Schmidt"; .content[7] "Fischer"; .activeitem 1; .firstchar 1; .style[style_lines] true; .style[style_buttons] true; .style[style_root] true; .level[2] 2; .level[3] 2; .level[5] 2; .level[6] 2; .level[7] 2; integer Index; boolean Select := false; on select { if Tv.Select then Tv:reparent(Tv.Index, 1, Tv.activeitem, Tv.activeitem); Tv.Select := false; St.text := ""; endif } } child pushbutton Pb_rep { .xleft 240; .width 194; .ytop 26; .text "Firma angliedern"; on select { variable integer Index; Tv.Index := Tv.activeitem; St.text := "Waehlen sie eine neue Firma"; Tv.Select := true; } } child statictext St { .xleft 241; .ytop 72; .text ""; } child pushbutton Pb_Exit { .xleft 355; .width 78; .ytop 132; .text "Exit"; on select { exit(); } } }