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 e sostituzione, indicatori di diagnosi nel margine 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_editor.is_syntax = uo_editor.SYNTAX_SQL
uo_editor.is_text = "SELECT c.name, SUM(o.amount) AS total~r~n" &
+ "FROM customer c~r~n" &
+ "WHERE o.status = 'paid'"
// Local variables
string ls_sql
// Rileggere cio che l'utente ha realmente digitato
ls_sql = uo_editor.of_get_text()
is_textrestituisce la stessa cosa: la digitazione dell'utente vi arriva non appena l'immissione si posa (eventue_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, con i fine riga ricevuti: un testo in CRLF si rilegge in CRLF, un testo con solo CR in CR, ripiegato o no; un testo che li mescola si rilegge in CRLF. Un nuovo testo si visualizza dalla prima riga, cancella gli indicatori di of_add_marker e non risulta modificato (ib_modified) |
is_syntax | string | "" | Linguaggio di evidenziazione: costanti SYNTAX_* (vedere la tabella qui sopra). SYNTAX_NONE = testo semplice. Si rilegge come è stato scritto: SYNTAX_CSHARP resta SYNTAX_CSHARP, anche se C# condivide la grammatica del C |
ib_readonly | boolean | false | Editor in sola lettura: l'utente consulta senza poter modificare |
ib_modified | boolean | false | true non appena il testo differisce da quello dichiarato salvato: un nuovo is_text non è modificato, la digitazione, of_insert_text o una sostituzione lo rendono modificato, annullare fino al testo salvato lo riporta a false. Lo rimetta a false dopo il salvataggio; true lo forza |
Visualizzazione #
| Proprietà | Tipo | Predefinito | Ruolo |
|---|---|---|---|
ib_line_numbers | boolean | true | Mostra o nasconde il margine dei numeri di riga, a sinistra; nascosti, un margine stretto conserva gli indicatori di compressione e le diagnosi di of_add_marker |
ib_current_line | boolean | true | Evidenzia la riga in cui si trova il cursore; in modalità ib_wrap la fascia copre tutte le righe visive della riga |
ib_folding | boolean | false | Opt-in: consente la compressione delle regioni #region … #endregion (//#region in PowerScript, JavaScript o C) dal margine: #region parte ripiegata, #regionopen aperta; gli indicatori restano anche con ib_line_numbers = false. È una modalità di lettura: finché è attiva l'editor non accetta la digitazione, perché l'area di inserimento contiene allora il testo ripiegato e non il sorgente; attivarla su regioni chiuse dimentica anche la cronologia di Ctrl+Z. Un indicatore si raggiunge da tastiera (Tab); Invio o Spazio lo comprime o lo espande |
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, da 1 a 12 (qualsiasi altro valore torna a 4); Invio dopo una parentesi aperta rientra di questa larghezza |
is_font_family | string | "" | Carattere dell'editor (vuoto = carattere a spaziatura fissa del tema) |
ii_font_size | integer | 0 | Dimensione del carattere in pixel (0 = dimensione del tema) |
Navigazione e interazioni #
| Proprietà | Tipo | Predefinito | Ruolo |
|---|---|---|---|
ib_search_enabled | boolean | true | Attiva la barra di ricerca integrata (Ctrl+F, Ctrl+H per sostituire — vedere «Tastiera»); a false, of_find restituisce -4 |
ib_find_match_case | boolean | false | Opzione di ricerca: trova solo il testo con le stesse maiuscole/minuscole. Il pulsante Aa della barra è lo stesso interruttore; vale per of_find, of_replace e of_replace_all |
ib_find_whole_word | boolean | false | Opzione di ricerca: trova il testo solo come parola intera (il _ fa parte della parola: ls_a non viene trovato in ls_ab). Pulsante ab della barra |
ib_find_regex | boolean | false | Opzione di ricerca: il testo è un'espressione regolare (sintassi JavaScript); la sostituzione di of_replace può allora usare $1, $& e $<name>. Un'espressione non valida non trova nulla, incornicia il campo in rosso e fa restituire -5 a of_replace. Pulsante .* della barra |
il_doc_line | long | 0 | Porta la riga indicata al centro della vista e la segna con una fascia d'accento (numerazione a partire da 1, come il margine) — la riga indicata da una documentazione o da un risultato di ricerca. Il cursore e la selezione dell'utente non si spostano (il_caret_line sposta il cursore). Una riga nascosta in una regione ripiegata apre quella regione; la fascia viene disegnata anche in modalità ib_wrap. 0 cancella la fascia; una riga oltre la fine del testo non segna nulla e si rilegge come è stata scritta; ogni nuovo is_text cancella la fascia |
il_caret_line | long | 1 | La riga del cursore, a partire da 1, letta dal vivo (ripiegato: quella del margine). Scriverla pone il cursore all'inizio di quella riga e la porta sullo schermo — il «vai alla riga» di un errore di compilazione; una riga nascosta in una regione ripiegata apre quella regione, una riga oltre la fine si ferma all'ultima. Con ib_track_caret, ue_caret_changed segue, come per un clic — nulla quando il cursore resta dov'è |
il_caret_column | long | 1 | La colonna del cursore, a partire da 1, letta dal vivo: la posizione del carattere nella sua riga (una tabulazione conta per uno). Scriverla sposta il cursore lungo la sua riga; oltre la fine della riga si ferma a quella fine. Con ib_track_caret, ue_caret_changed segue, come per un clic |
ib_track_caret | boolean | false | Opt-in: attiva ue_caret_changed a ogni spostamento del cursore — gesto dell'utente o ordine del suo codice; un nuovo documento (is_text, un caricamento) non dice nulla 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 | "" | Stile visivo del componente (costanti THEME_STYLE_*); vuoto = quello dell'applicazione, seguito a ogni cambio |
is_theme_mode | string | "" | Variante chiara o scura (costanti THEME_MODE_*); vuoto = quella dell'applicazione, seguita a ogni cambio |
il_theme_accent | long | -1 | Colore d'accento di questo componente (-1 = accento dell'applicazione, o quello 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, vi inserisce il testo ed evidenzia tutte le occorrenze, secondo le opzioni ib_find_* (ripiegato, solo nelle righe visibili). La prima occorrenza a partire dal cursore viene portata sullo schermo; il cursore stesso si sposta solo quando l'utente chiude la barra. Un testo vuoto svuota il campo e cancella le evidenziazioni. Restituisce 0 una volta applicato, -4 quando ib_search_enabled vale false, -2 se il componente non è creato |
of_insert_text (string as_text) | Inserisce testo al cursore, esattamente come se l'utente lo avesse digitato: la selezione corrente viene sostituita, il cursore si posa dopo l'inserimento e questo viene portato sullo schermo. È il metodo di un pulsante inserisci un frammento, dove is_text butterebbe via il lavoro in corso. Durante una ricerca, l'inserimento avviene al cursore dell'utente, mai sull'occorrenza. Quando il focus è nell'editor o nella sua barra di ricerca, l'inserimento passa per il percorso di modifica del browser: Ctrl+Z lo annulla ancora. Attiva ue_changed, e con ib_track_caret ue_caret_changed segue, come per una digitazione. Nulla viene inserito finché l'editor è in sola lettura (ib_readonly) o ripiegato (ib_folding). Restituisce 0 una volta applicato, -4 in sola lettura o ripiegato, -5 su un testo vuoto, -2 se il componente non è creato |
of_replace (string as_find, string as_replace) | Sostituisce la prima occorrenza di as_find a partire dal cursore (ripartendo dall'inizio) e la porta sullo schermo; valgono le opzioni ib_find_*, e con ib_find_regex la sostituzione può usare $1, $& e $<name>. Un Ctrl+Z la annulla. Con ib_track_caret, ue_caret_changed segue quando il cursore si sposta. Restituisce il numero di occorrenze sostituite (1, o 0 se non ce n'è nessuna), -4 in sola lettura o ripiegato, -5 su una ricerca vuota o un'espressione non valida, -2 se il componente non è creato |
of_replace_all (string as_find, string as_replace) | Sostituisce tutte le occorrenze di as_find, in un solo passo di annullamento. Stesse opzioni e stessi codici di of_replace; restituisce il numero di occorrenze sostituite |
of_selected_text ( ) → string | Restituisce il testo selezionato dall'utente, letto dal vivo ("" senza selezione), con i fine riga di is_text |
of_select_range (long al_from_line, long al_from_col, long al_to_line, long al_to_col) | Seleziona da (riga, colonna) a (riga, colonna), tutto a partire da 1, e porta la selezione sullo schermo; il cursore si pone all'estremità indicata per ultima, e una colonna oltre la fine della sua riga si ferma a quella fine. Con ib_track_caret, ue_caret_changed segue, come per un trascinamento. Restituisce 0 una volta applicato, -5 su una riga fuori dal documento o una colonna inferiore a 1, -4 quando l'editor è ripiegato, -2 se il componente non è creato |
of_line_count ( ) | Restituisce il numero di righe del documento, ripiegato o no, letto dal vivo — il limite di una casella «vai alla riga» |
of_add_marker (long al_line, string as_kind, string as_tooltip) | Segna una riga del margine con una diagnosi — MARKER_ERROR, MARKER_WARNING o MARKER_INFO — e un tooltip (markup accettato): ciò che dice un compilatore, là dove lo dice. Più indicatori possono condividere una riga: il più grave dà l'icona, il tooltip li elenca tutti. Appartengono al documento: un nuovo is_text li cancella. Restituisce 0 una volta applicato, -5 su una riga fuori dal documento o un tipo sconosciuto, -2 se il componente non è creato |
of_remove_marker (long al_line) | Rimuove tutti gli indicatori di una riga. Restituisce 0 una volta rimossi, -5 se la riga non ne porta nessuno, -2 se il componente non è creato |
of_clear_markers ( ) | Rimuove tutti gli indicatori del margine. Restituisce 0 una volta applicato, -2 se il componente non è creato |
of_marker_count ( ) | Restituisce il numero di indicatori del margine, letto dal vivo (due su una riga contano per due) |
of_reset ( ) | Riporta tutte le proprietà al valore predefinito e svuota l'editor. Restituisce 0 una volta applicato, -2 se il componente non è creato |
of_set_redraw (boolean) | Raggruppa una raffica di modifiche in un unico rendering. Restituisce 0 una volta applicato, -2 se il componente non è creato |
of_save_as_png (string) · of_save_as_jpg (string) | Esporta il rendering come immagine. Restituisce 0 una volta scritta l'immagine, -4 se la scrittura fallisce, -2 se il componente non è creato |
Event #
| Event | Attivato quando |
|---|---|
ue_changed ( ) | L'utente ha modificato il contenuto e la digitazione si è stabilizzata — attivato anche dopo of_insert_text o una sostituzione. L'evento non porta nulla: riempirlo imponeva di rileggere tutto il documento a ogni digitazione posata, per un'applicazione che il più delle volte vuole solo sapere che è cambiato. Chi vuole il codice lo chiede — is_text o of_get_text(); ib_modified dice se differisce dal testo salvato |
ue_caret_changed (long al_line, long al_col) | Il cursore si è spostato (tasto, clic, trascinamento, digitazione, o il suo codice); riga e colonna contate a partire da 1, la riga essendo quella del margine quando l'editor è ripiegato, la colonna la posizione del carattere nella sua riga (una tabulazione conta per uno). Il suo codice lo attiva come il gesto (il_caret_line, il_caret_column, of_select_range, of_insert_text, of_replace); nulla quando il cursore resta dov'è, e un nuovo documento (is_text, un caricamento) non dice nulla del cursore — richiede ib_track_caret = true |
ue_find_result (long al_count, long al_index) | Una ricerca è terminata, o passa a un'altra occorrenza: al_count occorrenze trovate, al_index = posizione di quella messa in evidenza (a partire da 1). Durante la digitazione viene sollevato solo se il conteggio cambia; chiudere la barra non lo solleva; nemmeno una ricerca vuota |
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) |
Tastiera #
| Tasto | Effetto |
|---|---|
| Tab | Rientra fino al punto di tabulazione successivo (ii_tab_size); più righe selezionate: rientra tutto il blocco |
| Maiusc+Tab | Riduce il rientro della riga o del blocco |
| Invio | Nuova riga con lo stesso rientro, un livello in più dopo {, ( o [ |
| Ctrl+F | Apre la barra di ricerca, riempita con la selezione (ib_search_enabled) |
| Ctrl+H | Apre la barra con la sua riga di sostituzione (solo editor modificabile) |
| F3 · Maiusc+F3 | Occorrenza successiva · precedente, dal codice o dalla barra |
| Invio · Maiusc+Invio (barra) | Occorrenza successiva · precedente; nel campo di sostituzione, Invio sostituisce l'occorrenza corrente e Ctrl+Invio le sostituisce tutte |
| Esc | Chiude la barra e pone il cursore sull'occorrenza corrente |
| Tab, poi Invio o Spazio (margine) | Raggiunge un indicatore di compressione, lo comprime o lo espande (ib_folding) |
La colonna riportata da ue_caret_changed e il_caret_column è la posizione del carattere nella sua riga: una tabulazione conta per uno, qualunque sia la sua larghezza sullo schermo.
Esempi #
Un editor di query SQL #
// Sospendere il disegno durante l'impostazione
uo_query.of_set_redraw(/*on*/ false)
// Colorazione SQL, poi la query da mostrare
uo_query.is_syntax = uo_query.SYNTAX_SQL
uo_query.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"
// Un solo ridisegno, tutto in una volta
uo_query.of_set_redraw(/*on*/ true)
// event clicked di cb_execute
string ls_sql
// Eseguire la query cosi come digitata
ls_sql = uo_query.of_get_text() // la digitazione reale dell'utente
of_execute(ls_sql)
Un visualizzatore in sola lettura #
Ideale per presentare codice generato, un registro o un estratto che l'utente deve leggere senza modificarlo.
// Colorazione PowerScript
uo_preview.is_syntax = uo_preview.SYNTAX_POWERSCRIPT
// Un visualizzatore in sola lettura: niente cursore, niente margine, niente evidenziazione
uo_preview.ib_readonly = true // sola consultazione, nessun cursore di immissione
uo_preview.ib_line_numbers = false // nasconde il margine dei numeri
uo_preview.ib_current_line = false // nessuna evidenziazione della riga corrente
uo_preview.ib_wrap = true // manda a capo invece di scorrere
uo_preview.ii_tab_size = 2 // tabulazioni visualizzate su 2 colonne
// Il codice da mostrare
uo_preview.is_text = of_generate_code()
Seguire la posizione del cursore in una barra di stato #
// Segnalare ogni spostamento del cursore (ue_caret_changed)
uo_editor.ib_track_caret = true // adesione esplicita : altrimenti nessun evento
// event ue_caret_changed di uo_editor : (long al_line, long al_col)
uo_status.of_panel(/*key*/ "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_editor.of_find(/*text*/ "ll_total")
// event ue_find_result di uo_editor : (long al_count, long al_index)
if al_count = 0 then
uo_status.of_panel(/*key*/ "main").is_text = "Nessuna occorrenza"
else
uo_status.of_panel(/*key*/ "main").is_text = String(al_index) + " / " + String(al_count)
end if
// Andare alla riga segnalata da un compilatore e segnarla nel margine
uo_editor.of_add_marker(/*line*/ ll_error_line, /*kind*/ uo_editor.MARKER_ERROR, /*tooltip*/ ls_error_text)
uo_editor.il_caret_line = ll_error_line // il cursore ci va, la riga arriva sullo schermo
uo_editor.of_focus_webview() // l'utente corregge subito
Aprire un file rilasciato da Esplora file #
// Accept files dropped from the Explorer
uo_editor.ib_allow_drop = true
// event ue_drop_files di uo_editor : (string as_files[])
string ls_content
integer li_file
// as_files[1] porta il percorso COMPLETO del primo file rilasciato
li_file = FileOpen(as_files[1], StreamMode!, Read!)
if li_file > 0 then
FileReadEx(li_file, ls_content)
FileClose(li_file)
// Colorare secondo l'estensione del file, poi mostrarne il contenuto
uo_editor.is_syntax = of_syntax_for_extension(as_files[1])
uo_editor.is_text = ls_content
end if
Reagire alle modifiche #
// event ue_changed di uo_editor : ( )
cb_save.enabled = uo_editor.ib_modified // annullare fino al testo salvato lo riporta a false
// event clicked di cb_save
if of_save_script(uo_editor.is_text) = 1 then
uo_editor.ib_modified = false // il testo salvato diventa il riferimento
cb_save.enabled = false
end if
L'event viene attivato solo una volta stabilizzata la digitazione: un'immissione continua non genera un event per ogni tasto.
Rinominare una variabile in tutto lo script #
// Local variables
long ll_count
// Solo parole intere: ll_total2 e un'altra variabile
uo_editor.ib_find_whole_word = true
ll_count = uo_editor.of_replace_all(/*find*/ "ll_total", /*replace*/ "ldc_amount") // un solo Ctrl+Z annulla tutto
Buone pratiche #
- Imposti sempre
is_syntaxprima diis_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_wrapoffre un visualizzatore sobrio che non sembra più un editor. - Per recuperare un'immissione, legga
is_text(oppureof_get_text()) una volta posata la digitazione — cioè dentro il suoue_changed, che le dice quando. ib_foldingha senso solo su file lunghi e strutturati; lo lasci disattivato per brevi estratti. Lo spenga prima di permettere le modifiche: uno schema ripiegato si legge, non si modifica, eof_get_text()rende sempre il sorgente intero, regioni chiuse comprese.- Racchiuda il caricamento di un file di grandi dimensioni tra
of_set_redraw(false)eof_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. - Dopo un salvataggio, rimetta
ib_modifiedafalse: tornatruealla prima digitazione, efalsese l'utente annulla fino al testo salvato. - Per mostrare gli errori di una compilazione,
of_clear_markers()poi unof_add_markerper diagnosi, eil_caret_linesulla prima.
Ereditato dalla base comune #
Questi membri esistono su tutti i componenti visivi — non sono propri di questo. Sono descritti una sola volta, nei capitoli trasversali; questa tabella dice solo dove leggerli.
| Membri | Ruolo | Descritto in |
|---|---|---|
of_reset | Riportare il componente a zero | 3.6 Riportare un componente a zero: of_reset() |
of_register_shortcut · of_clear_shortcuts | Scorciatoie da tastiera del componente | 3.5 Le scorciatoie da tastiera |
of_is_created · of_is_ready · of_get_last_error | Se è nato, se è pronto, cosa è fallito | 3.7 Diagnostica |
of_save_as_png · of_save_as_jpg | Esportare il rendering in immagine | 3.8 Esportare il rendering come immagine |
of_set_redraw | Raggruppare le modifiche in un solo ridisegno | 3.10 Buone pratiche |
of_preload_icons | Icone mostrate senza ritardo | Visualizzazione istantanea: of_icon |
of_set_translation | Tradurre una dicitura del componente | 5.2 Adattare un'etichetta: of_set_translation |
of_focus_webview | Dare il focus al componente | 6.4 Tastiera e focus |
of_print · of_print_to_pdf | Stampare, o scrivere un PDF | 6.9 Stampare |
of_set_property · of_get_property · of_component_name | Pilotare una proprietà per nome | 3.1 Il motore delle proprietà |
Due aiuti non sono ereditati: of_icon e of_escape_markup vivono su n_pbt_utils. Ne dichiari uno — n_pbt_utils lnv_utils, niente da creare — e li chiami su di esso.