# codeeditor — `u_pbt_codeeditor` #

← Komponentenreferenz · Inhalt des Handbuchs

> Code-Editor mit Syntaxhervorhebung: zehn Sprachen, Zeilennummern, Falten von Regionen, integrierte Suche und Ablegen von Dateien.

> ▶ Live ansehen — Demoanwendung, Kachel Code editor: die Vorschau, der zugehörige Code und diese Seite, nebeneinander.

## Auf einen Blick #

Userobject | `u_pbt_codeeditor`
Item-Klasse | — (Komponente ohne Items)
Wofür | Code, eine SQL-Abfrage oder eine Konfigurationsdatei eingeben oder anzeigen: überall dort, wo ein `multilineedit` zu unleserlich ist
Opt-in-Optionen | `ib_track_caret`, `ib_allow_drop`, `ib_folding`

## Schnellstart #

    // open-Event des Fensters
    uo_editeur.is_syntax = uo_editeur.SYNTAX_SQL
    uo_editeur.is_text   = "SELECT c.name, SUM(o.amount) AS total~r~n" &
                           + "FROM customer c~r~n" &
                           + "WHERE o.status = 'paid'"

    // Zuruecklesen, was der Benutzer tatsaechlich eingegeben hat
    string ls_sql

    ls_sql = uo_editeur.of_get_text()

> `is_text` liefert dasselbe: Die Eingabe des Benutzers landet dort, sobald sie sich gesetzt hat (Event `ue_changed`).

## Unterstützte Sprachen #

`is_syntax` akzeptiert eine dieser Konstanten oder `SYNTAX_NONE` (leere Zeichenkette) für reinen Text ohne Hervorhebung.

Sprache | Konstante | Weitere akzeptierte Schreibweisen
--- | --- | ---
PowerScript | `SYNTAX_POWERSCRIPT` | `pb`, `powerbuilder`
SQL | `SYNTAX_SQL` | `tsql`, `plsql`
JavaScript | `SYNTAX_JAVASCRIPT` | `js`, `jsx`
JSON | `SYNTAX_JSON` | `jsonc`
C-Familie | `SYNTAX_C` · `SYNTAX_CPP` · `SYNTAX_CSHARP` · `SYNTAX_JAVA` | `c++`, `cxx`, `cs`
HTML / XML | `SYNTAX_HTML` · `SYNTAX_XML` | `htm`, `xhtml`, `svg`
CSS | `SYNTAX_CSS` | `scss`, `less`
Python | `SYNTAX_PYTHON` | `py`
YAML | `SYNTAX_YAML` | `yml`
Markdown | `SYNTAX_MARKDOWN` | `md`, `mkd`

Sprachen derselben Familie teilen sich die Hervorhebung (`SYNTAX_JAVA` färbt wie `SYNTAX_C`, `SYNTAX_XML` wie `SYNTAX_HTML`): Die Konstante, die Sie wählen, dokumentiert Ihre Absicht, das Ergebnis auf dem Bildschirm ist dasselbe. Der Wert unterscheidet nicht zwischen Groß- und Kleinschreibung, und ein unbekannter Name fällt ohne Fehler auf reinen Text zurück.

## Eigenschaften #

### Inhalt und Sprache #

Eigenschaft | Typ | Standard | Zweck
--- | --- | --- | ---
`is_text` | string | `""` | Der im Editor angezeigte Code. Beim Zurücklesen liefert er den aktuellen Inhalt, die Eingabe des Benutzers eingeschlossen
`is_syntax` | string | `""` | Sprache der Hervorhebung: Konstanten `SYNTAX_*` (siehe Tabelle oben). `SYNTAX_NONE` = reiner Text
`ib_readonly` | boolean | `false` | Schreibgeschützter Editor: Der Benutzer kann lesen, ohne ändern zu können

### Anzeige #

Eigenschaft | Typ | Standard | Zweck
--- | --- | --- | ---
`ib_line_numbers` | boolean | `true` | Blendet die Zeilennummernleiste links ein oder aus
`ib_current_line` | boolean | `true` | Hebt die Zeile hervor, in der die Einfügemarke steht. Keine Hervorhebung, solange `ib_wrap` aktiv ist.
`ib_folding` | boolean | `false` | Opt-in: erlaubt das Falten von Regionen (`#region`, Blöcke zwischen geschweiften Klammern) über die Leiste
`ib_wrap` | boolean | `false` | Bricht lange Zeilen um, statt seitlich zu scrollen
`ii_tab_size` | integer | `4` | Anzahl der Spalten, die ein Tabulator einnimmt
`is_font_family` | string | `""` | Schriftart des Editors (leer = Schriftart mit fester Zeichenbreite aus dem Design)
`ii_font_size` | integer | `0` | Schriftgröße in Punkt (`0` = Größe aus dem Design)

### Navigation und Interaktionen #

Eigenschaft | Typ | Standard | Zweck
--- | --- | --- | ---
`ib_search_enabled` | boolean | `true` | Aktiviert die integrierte Suchleiste (Strg+F)
`ii_doc_line` | integer | `-1` | Scrollt bis zur angegebenen Zeile und wählt sie aus (Nummerierung ab 1). Keine Hervorhebung, solange `ib_wrap` aktiv ist; das Scrollen funktioniert weiterhin.
`ib_track_caret` | boolean | `false` | Opt-in: löst bei jeder Bewegung der Einfügemarke `ue_caret_changed` aus
`ib_allow_drop` | boolean | `false` | Opt-in: nimmt Dateien aus dem Windows-Explorer entgegen; die vollständigen Pfade kommen über `ue_drop_files` an
`is_theme_style` | string | `fluent` | Visueller Stil der Komponente (Konstanten `THEME_STYLE_*`)
`is_theme_mode` | string | `light` | Helle oder dunkle Variante (Konstanten `THEME_MODE_*`)
`il_theme_accent` | long | `-1` | Akzentfarbe dieser Komponente (`-1` = Akzent des Designs)
`is_tooltip` | string | `""` | Einfacher Tooltip beim Überfahren der Komponente
`is_super_tooltip_title` | string | `""` | Titel des erweiterten Tooltips (hat Vorrang vor `is_tooltip`)
`is_super_tooltip_text` | string | `""` | Text des erweiterten Tooltips (Rich-Markup zulässig)
`is_super_tooltip_image` | string | `""` | Bild des erweiterten Tooltips

## Methoden #

Methode | Zweck
--- | ---
`of_get_text ( )` → string | Liefert den aktuellen Inhalt — denselben Wert wie `is_text`, für Code, der einen Methodenaufruf bevorzugt
`of_find (string as_text)` | Öffnet die Suchleiste und hebt alle Vorkommen des Textes hervor
`of_insert_text (string as_text)` | Fügt Text an der Einfügemarke ein, genau als hätte der Benutzer ihn getippt: Die aktuelle Auswahl wird ersetzt, und die Einfügemarke landet hinter dem Eingefügten. Das ist die Methode hinter einer Schaltfläche Baustein einfügen, wo `is_text` die laufende Arbeit verwerfen würde. Hat der Editor den Fokus, läuft die Einfügung über den Bearbeitungspfad des Browsers, sodass Strg+Z sie weiterhin rückgängig macht
`of_reset ( )` | Setzt alle Eigenschaften auf ihren Standard zurück und leert den Editor
`of_set_redraw (boolean)` | Fasst eine Folge von Änderungen zu einer einzigen Darstellung zusammen
`of_save_as_png (string)` · `of_save_as_jpg (string)` | Exportiert die Darstellung als Bild

## Events #

Event | Ausgelöst wenn
--- | ---
`ue_changed (string as_text)` | Der Benutzer hat den Inhalt geändert und seine Eingabe ist zur Ruhe gekommen; `as_text` trägt den vollständigen neuen Code
`ue_caret_changed (long al_line, long al_col)` | Die Einfügemarke hat sich bewegt; Zeile und Spalte ab 1 gezählt — erfordert `ib_track_caret = true`
`ue_find_result (long al_count, long al_index)` | Eine Suche war erfolgreich: `al_count` Vorkommen gefunden, `al_index` = Rang des gerade hervorgehobenen
`ue_drop_files (string as_files[])` | Dateien wurden aus Windows abgelegt: vollständige Pfade, ein Eintrag pro Datei. Erfordert `ib_allow_drop = true`
`ue_drag_enter ( )` | Ein Dateiziehvorgang gelangt auf den Editor (`ib_allow_drop`)
`ue_drag_leave ( )` | Der Dateiziehvorgang verlässt den Editor
`ue_ready ( )` | Die Komponente ist fertig geladen; alles zuvor Gesendete wurde nachgespielt
`ue_runtime_missing ( )` | Die WebView2-Runtime fehlt: die Komponente bleibt leer
`ue_bg_color (long al_color)` | Die Komponente hat ihre Design-Hintergrundfarbe berechnet; das Userobject hat sie bereits übernommen (`backcolor`)

## Beispiele #

### Ein Editor für SQL-Abfragen #

    uo_requete.of_set_redraw(false)

    uo_requete.is_syntax = uo_requete.SYNTAX_SQL
    uo_requete.is_text   = "-- Beste Kunden nach vereinnahmtem Umsatz~r~n" &
                           + "SELECT c.name, SUM(o.amount) AS total~r~n" &
                           + "FROM customer c~r~n" &
                           + "  INNER JOIN orders o ON o.cust_id = c.id~r~n" &
                           + "WHERE o.status = 'paid'~r~n" &
                           + "GROUP BY c.name~r~n" &
                           + "ORDER BY total DESC"

    uo_requete.of_set_redraw(true)

    // clicked-Event von cb_executer
    string ls_sql

    ls_sql = uo_requete.of_get_text()     // die tatsaechliche Eingabe des Benutzers
    of_executer(ls_sql)

### Ein schreibgeschützter Betrachter #

Ideal, um generierten Code, ein Protokoll oder einen Auszug zu zeigen, den der Benutzer lesen, aber nicht ändern soll.

    uo_apercu.is_syntax = uo_apercu.SYNTAX_POWERSCRIPT

    uo_apercu.ib_readonly     = true      // nur lesen, keine Einfuegemarke
    uo_apercu.ib_line_numbers = false     // blendet die Nummernleiste aus
    uo_apercu.ib_current_line = false     // keine Hervorhebung der aktuellen Zeile
    uo_apercu.ib_wrap         = true      // bricht um, statt zu scrollen
    uo_apercu.ii_tab_size     = 2         // Tabulatoren ueber 2 Spalten dargestellt

    uo_apercu.is_text = of_generer_code()

### Die Position der Einfügemarke in einer Statusleiste verfolgen #

    uo_editeur.ib_track_caret = true       // ausdrueckliches Opt-in : sonst gar kein Event

    // ue_caret_changed-Event von uo_editeur : (long al_line, long al_col)
    uo_statut.of_item("pos").is_text = "Zeile " + String(al_line) + ", Sp. " + String(al_col)

Ohne `ib_track_caret` meldet die Einfügemarke nichts: Dieser Auslöser feuert sehr häufig und bleibt abgeschaltet, solange Sie ihn nicht anfordern.

### Suchen und zu einer Zeile springen #

    // Oeffnet die Suchleiste und hebt alle Vorkommen hervor
    uo_editeur.of_find(/*text*/ "ll_total")

    // ue_find_result-Event von uo_editeur : (long al_count, long al_index)
    if al_count = 0 then
        uo_statut.of_item("main").is_text = "Kein Treffer"
    else
        uo_statut.of_item("main").is_text = String(al_index) + " / " + String(al_count)
    end if

    // Direkt zu der Zeile springen, die ein Compiler bemaengelt hat
    uo_editeur.ii_doc_line = ll_ligne_erreur     // scrollt zur Zeile und waehlt sie aus

### Eine aus dem Explorer abgelegte Datei öffnen #

    uo_editeur.ib_allow_drop = true

    // ue_drop_files-Event von uo_editeur : (string as_files[])
    string ls_contenu, ls_ligne
    integer li_fichier

    // as_files[1] traegt den VOLLSTAENDIGEN Pfad der ersten abgelegten Datei
    li_fichier = FileOpen(as_files[1], StreamMode!, Read!)
    if li_fichier > 0 then
        FileReadEx(li_fichier, ls_contenu)
        FileClose(li_fichier)

        uo_editeur.is_syntax = of_langage_selon_extension(as_files[1])
        uo_editeur.is_text   = ls_contenu
    end if

### Auf Änderungen reagieren #

    // ue_changed-Event von uo_editeur : (string as_text)
    ib_modifie = true
    uo_statut.of_item("main").is_text = String(Len(as_text)) + " Zeichen"

Das Event wird erst ausgelöst, wenn die Eingabe zur Ruhe gekommen ist: Fortlaufendes Tippen erzeugt nicht ein Event pro Tastendruck.

## Best Practices #

- Setzen Sie `is_syntax` immer vor `is_text`: Der Code ist schon beim ersten Zeichnen eingefärbt, ohne sichtbares Nachfärben.
- Für eine reine Anzeige ergibt die Kombination `ib_readonly` + `ib_line_numbers = false` + `ib_wrap` einen schlichten Betrachter, der nicht mehr wie ein Editor aussieht.
- Um eine Eingabe abzuholen, lesen Sie `is_text` (oder `of_get_text()`), sobald die Eingabe sich gesetzt hat, oder nehmen Sie den Parameter `as_text` von `ue_changed`.
- `ib_folding` lohnt sich nur bei langen, strukturierten Dateien; lassen Sie es bei kurzen Auszügen ausgeschaltet.
- Klammern Sie das Laden einer großen Datei mit `of_set_redraw(false)` / `of_set_redraw(true)` ein.
- Rufen Sie `of_reset()` auf, bevor Sie ein Dokument anderer Art laden: Sonst bleiben die vorherige Sprache, die Tabulatorbreite oder der Schreibschutzmodus bestehen.

← Komponentenreferenz · Inhalt des Handbuchs