# codeeditor — `u_pbt_codeeditor` #

← Riferimento dei componenti · Sommario della guida

> Editor di codice con evidenziazione della sintassi: dieci linguaggi, numeri di riga, compressione delle regioni, ricerca integrata e rilascio di file.

> ▶ Vederlo dal vivo — Applicazione dimostrativa, riquadro Code editor: l'anteprima, il codice che lo produce e questa pagina, affiancati.

## In breve #

Userobject | `u_pbt_codeeditor`
Classe degli item | — (componente senza item)
Serve per | Immettere o visualizzare codice, una query SQL, un file di configurazione: ovunque un `multilineedit` risulti poco leggibile
Opzioni opt-in | `ib_track_caret`, `ib_allow_drop`, `ib_folding`

## Avvio rapido #

    // event open della finestra
    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'"

    // Rileggere cio che l'utente ha realmente digitato
    string ls_sql

    ls_sql = uo_editeur.of_get_text()

> `is_text` restituisce la stessa cosa: la digitazione dell'utente vi arriva non appena l'immissione si posa (event `ue_changed`).

## Linguaggi riconosciuti #

`is_syntax` accetta una di queste costanti, oppure `SYNTAX_NONE` (stringa vuota) per testo semplice senza evidenziazione.

Linguaggio | Costante | Altre grafie accettate
--- | --- | ---
PowerScript | `SYNTAX_POWERSCRIPT` | `pb`, `powerbuilder`
SQL | `SYNTAX_SQL` | `tsql`, `plsql`
JavaScript | `SYNTAX_JAVASCRIPT` | `js`, `jsx`
JSON | `SYNTAX_JSON` | `jsonc`
Famiglia C | `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`

I linguaggi di una stessa famiglia condividono l'evidenziazione (`SYNTAX_JAVA` colora come `SYNTAX_C`, `SYNTAX_XML` come `SYNTAX_HTML`): la costante scelta documenta la Sua intenzione, il risultato sullo schermo è lo stesso. Il valore non distingue tra maiuscole e minuscole e un nome sconosciuto ricade sul testo semplice, senza errore.

## Proprietà #

### Contenuto e linguaggio #

Proprietà | Tipo | Predefinito | Ruolo
--- | --- | --- | ---
`is_text` | string | `""` | Il codice visualizzato nell'editor. In lettura restituisce il contenuto vivo, digitazione dell'utente compresa
`is_syntax` | string | `""` | Linguaggio di evidenziazione: costanti `SYNTAX_*` (vedere la tabella qui sopra). `SYNTAX_NONE` = testo semplice
`ib_readonly` | boolean | `false` | Editor in sola lettura: l'utente consulta senza poter modificare

### Visualizzazione #

Proprietà | Tipo | Predefinito | Ruolo
--- | --- | --- | ---
`ib_line_numbers` | boolean | `true` | Mostra o nasconde il margine dei numeri di riga, a sinistra
`ib_current_line` | boolean | `true` | Evidenzia la riga in cui si trova il cursore. Nessuna evidenziazione con `ib_wrap` attivo.
`ib_folding` | boolean | `false` | Opt-in: consente la compressione delle regioni (`#region`, blocchi tra parentesi graffe) dal margine
`ib_wrap` | boolean | `false` | Manda a capo le righe lunghe invece di scorrere lateralmente
`ii_tab_size` | integer | `4` | Numero di colonne occupate da una tabulazione
`is_font_family` | string | `""` | Carattere dell'editor (vuoto = carattere a spaziatura fissa del tema)
`ii_font_size` | integer | `0` | Dimensione del carattere in punti (`0` = dimensione del tema)

### Navigazione e interazioni #

Proprietà | Tipo | Predefinito | Ruolo
--- | --- | --- | ---
`ib_search_enabled` | boolean | `true` | Attiva la barra di ricerca integrata (Ctrl+F)
`ii_doc_line` | integer | `-1` | Scorre fino alla riga indicata e la seleziona (numerazione a partire da 1). Nessuna evidenziazione con `ib_wrap` attivo; lo scorrimento continua a funzionare.
`ib_track_caret` | boolean | `false` | Opt-in: attiva `ue_caret_changed` a ogni spostamento del cursore
`ib_allow_drop` | boolean | `false` | Opt-in: accetta il rilascio di file da Esplora file di Windows; i percorsi completi arrivano tramite `ue_drop_files`
`is_theme_style` | string | `fluent` | Stile visivo del componente (costanti `THEME_STYLE_*`)
`is_theme_mode` | string | `light` | Variante chiara o scura (costanti `THEME_MODE_*`)
`il_theme_accent` | long | `-1` | Colore d'accento di questo componente (`-1` = accento del tema)
`is_tooltip` | string | `""` | Tooltip semplice mostrato al passaggio del mouse sul componente
`is_super_tooltip_title` | string | `""` | Titolo del tooltip avanzato (prevale su `is_tooltip`)
`is_super_tooltip_text` | string | `""` | Testo del tooltip avanzato (markup avanzato accettato)
`is_super_tooltip_image` | string | `""` | Immagine del tooltip avanzato

## Metodi #

Metodo | Ruolo
--- | ---
`of_get_text ( )` → string | Restituisce il contenuto vivo — lo stesso valore di `is_text`, per il codice che preferisce una chiamata di metodo
`of_find (string as_text)` | Apre la barra di ricerca ed evidenzia tutte le occorrenze del testo
`of_insert_text (string as_text)` | Inserisce del testo al cursore, esattamente come se l'utente l'avesse digitato: la selezione corrente viene sostituita e il cursore si posa dopo l'inserimento. È il metodo dietro un pulsante inserisci frammento, là dove `is_text` getterebbe via il lavoro in corso. Quando l'editor ha il fuoco, l'inserimento passa per il percorso di modifica del browser, quindi Ctrl+Z lo annulla ancora
`of_reset ( )` | Riporta tutte le proprietà al valore predefinito e svuota l'editor
`of_set_redraw (boolean)` | Raggruppa una raffica di modifiche in un unico rendering
`of_save_as_png (string)` · `of_save_as_jpg (string)` | Esporta il rendering come immagine

## Event #

Event | Attivato quando
--- | ---
`ue_changed (string as_text)` | L'utente ha modificato il contenuto e la sua digitazione si è stabilizzata; `as_text` porta il nuovo codice completo
`ue_caret_changed (long al_line, long al_col)` | Il cursore si è spostato; riga e colonna contate a partire da 1 — richiede `ib_track_caret = true`
`ue_find_result (long al_count, long al_index)` | Una ricerca è andata a buon fine: `al_count` occorrenze trovate, `al_index` = posizione di quella messa in evidenza
`ue_drop_files (string as_files[])` | Alcuni file sono stati rilasciati da Windows: percorsi completi, una voce per file. Richiede `ib_allow_drop = true`
`ue_drag_enter ( )` | Un trascinamento di file entra nell'editor (`ib_allow_drop`)
`ue_drag_leave ( )` | Il trascinamento di file lascia l'editor
`ue_ready ( )` | Il componente ha terminato il caricamento; tutto ciò che è stato inviato prima è stato riprodotto
`ue_runtime_missing ( )` | Il runtime WebView2 è assente: il componente resta vuoto
`ue_bg_color (long al_color)` | Il componente ha calcolato il colore di sfondo del proprio tema; l'userobject lo ha già adottato (`backcolor`)

## Esempi #

### Un editor di query SQL #

    uo_requete.of_set_redraw(false)

    uo_requete.is_syntax = uo_requete.SYNTAX_SQL
    uo_requete.is_text   = "-- Migliori clienti per fatturato incassato~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)

    // event clicked di cb_executer
    string ls_sql

    ls_sql = uo_requete.of_get_text()     // la digitazione reale dell'utente
    of_executer(ls_sql)

### Un visualizzatore in sola lettura #

Ideale per presentare codice generato, un registro o un estratto che l'utente deve leggere senza modificarlo.

    uo_apercu.is_syntax = uo_apercu.SYNTAX_POWERSCRIPT

    uo_apercu.ib_readonly     = true      // sola consultazione, nessun cursore di immissione
    uo_apercu.ib_line_numbers = false     // nasconde il margine dei numeri
    uo_apercu.ib_current_line = false     // nessuna evidenziazione della riga corrente
    uo_apercu.ib_wrap         = true      // manda a capo invece di scorrere
    uo_apercu.ii_tab_size     = 2         // tabulazioni visualizzate su 2 colonne

    uo_apercu.is_text = of_generer_code()

### Seguire la posizione del cursore in una barra di stato #

    uo_editeur.ib_track_caret = true       // adesione esplicita : altrimenti nessun evento

    // event ue_caret_changed di uo_editeur : (long al_line, long al_col)
    uo_statut.of_item("pos").is_text = "Riga " + String(al_line) + ", col. " + String(al_col)

Senza `ib_track_caret`, il cursore non riporta nulla: questo trigger ha una frequenza elevata e rimane disattivato finché non lo richiede.

### Cercare e andare a una riga #

    // Apre la barra di ricerca ed evidenzia tutte le occorrenze
    uo_editeur.of_find(/*testo*/ "ll_total")

    // event ue_find_result di uo_editeur : (long al_count, long al_index)
    if al_count = 0 then
        uo_statut.of_item("main").is_text = "Nessuna occorrenza"
    else
        uo_statut.of_item("main").is_text = String(al_index) + " / " + String(al_count)
    end if

    // Andare direttamente alla riga segnalata da un compilatore
    uo_editeur.ii_doc_line = ll_ligne_erreur     // scorre e seleziona la riga

### Aprire un file rilasciato da Esplora file #

    uo_editeur.ib_allow_drop = true

    // event ue_drop_files di uo_editeur : (string as_files[])
    string ls_contenu, ls_ligne
    integer li_fichier

    // as_files[1] porta il percorso COMPLETO del primo file rilasciato
    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

### Reagire alle modifiche #

    // event ue_changed di uo_editeur : (string as_text)
    ib_modifie = true
    uo_statut.of_item("main").is_text = String(Len(as_text)) + " caratteri"

L'event viene attivato solo una volta stabilizzata la digitazione: un'immissione continua non genera un event per ogni tasto.

## Buone pratiche #

- Imposti sempre `is_syntax` prima di `is_text`: il codice è colorato fin dalla prima visualizzazione, senza ricolorazione visibile.
- Per una visualizzazione in sola consultazione, la combinazione `ib_readonly` + `ib_line_numbers = false` + `ib_wrap` offre un visualizzatore sobrio che non sembra più un editor.
- Per recuperare un'immissione, legga `is_text` (oppure `of_get_text()`) una volta posata la digitazione, o prenda il parametro `as_text` di `ue_changed`.
- `ib_folding` ha senso solo su file lunghi e strutturati; lo lasci disattivato per brevi estratti.
- Racchiuda il caricamento di un file di grandi dimensioni tra `of_set_redraw(false)` e `of_set_redraw(true)`.
- Chiami `of_reset()` prima di caricare un documento di natura diversa: senza di esso, il linguaggio, la dimensione di tabulazione o la modalità di sola lettura precedenti restano attivi.

← Riferimento dei componenti · Sommario della guida