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.

Abbildung 16-50: Beispiel eines treeview-Objekts

Definition

{ export | reexport } { model } treeview { <Bezeichner> }
{
  <Standardattribute>
  <Allgemeine Attribute>
  <Geometrieattribute>
  <Hierarchieattribute>
  <Layoutattribute>
  <Textattribute>
  <Objektspezifische Attribute>
}

Der Benutzer kann interaktiv zwei unterschiedliche Aktionen durchführen:

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:

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

open, close

.index

Benutzeraktion Öffnen bzw. Schließen eines Teilbaumes

activate

.index

Selektion wechselt auf einen anderen Eintrag

select

.index

Einfachklick auf einen Eintrag (Selektion)

dbselect

.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

activate

close

cut

dbselect

extevent

focus

help

hscroll

key

open

paste

scroll

select

vscroll

Kinder

document

record

transformer

Vater

groupbox

layoutbox

module

notepage

splitbox

toolbar

window

Menü

Popup-Menü

Methoden

:childcount()

:childindex()

:delete()

:exchange()

:find()

:insert()

:parent()

:reparent()

48.1 Attribute

.acc_label

.acc_text

.accelerator

.activeitem

.bgc

.bordercolor

.borderraster

.borderwidth

.class

.content[integer]

.control

.cursor

.cut_pending

.cut_pending_changed

.dialog

.document[integer]

.external

.external[integer]

.fgc

.firstchar

.firstrecord

.focus

.focusitem

.font

.function

.groupbox

.height

.help

.index

.itemcount

.label

.lastrecord

.layoutbox

.level[integer]

.mapped

.member[integer]

.membercount

.menu

.model

.notepage

.open[integer]

options[enum]

.parent

.picture[integer]

.posraster

.real_height

.real_sensitive

.real_visible

.real_width

.real_x

.real_y

.record[integer]

.recordcount

.scope

.sizeraster

.statushelp

.style[enum]

.toolbar

.toolhelp

.topitem

.userdata

.userdata[integer]

.visible

.width

.window

.xauto

.xleft

.xright

.yauto

.ybottom

.ytop

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

.activeitem

Aktives Element des Objekts.

.borderraster

Legt die Art der Geometrieberechnung bei aktivem Raster fest. Die detaillierte Beschreibung finden sie in der Attribut-Beschreibung in der „Attributreferenz“.

.content[integer]

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“.

.firstchar

Nummer des ersten angezeigten Zeichens (horizontale Scroll-Position).

.itemcount

Gesamtzahl der Einträge des Treeview.

.level[integer]

Legt die Einrückung des jeweiligen Eintrags fest.

Bitte beachten Sie auch das Kapitel „.content und contentspezifische Attribute“.

.open[integer]

Legt fest, ob ein Knoten geöffnet ist oder nicht.

Bitte beachten Sie auch das Kapitel „.content und contentspezifische Attribute“.

options[enum]

Optionen des Objekts.

Indizes:

  • opt_center_toolhelp (nur IDM für Windows)
  • opt_rightclick_selects (nur IDM für Windows)
  • opt_scroll_on_focus (nur IDM für Motif)

.picture[integer]

Angezeigtes Bild des jeweiligen Eintrags.

Bitte beachten Sie auch das Kapitel „.content und contentspezifische Attribute“.

.style[enum]

Legt das Aussehen der Linien, Knöpfe und des obersten Eintrags (root Eintrag) fest.

.topitem

Erstes angezeigtes Element des Treeview bei vertikalem Scrollen.

.userdata[integer]

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:

  1. 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.
  2. Optionales Bildchen zu einem Texteintrag. (Ref.: Attribute .picture[])
  3. 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(); }
  }
}

Abbildung 16-51: Fenster mit treeview-Objekt