PBToolboxAI v4 ← Site

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 #

Userobjectu_pbt_codeeditor
Classe degli item— (componente senza item)
Serve perImmettere o visualizzare codice, una query SQL, un file di configurazione: ovunque un multilineedit risulti poco leggibile
Opzioni opt-inib_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_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.

LinguaggioCostanteAltre grafie accettate
PowerScriptSYNTAX_POWERSCRIPTpb, powerbuilder
SQLSYNTAX_SQLtsql, plsql
JavaScriptSYNTAX_JAVASCRIPTjs, jsx
JSONSYNTAX_JSONjsonc
Famiglia CSYNTAX_C · SYNTAX_CPP · SYNTAX_CSHARP · SYNTAX_JAVAc++, cxx, cs
HTML / XMLSYNTAX_HTML · SYNTAX_XMLhtm, xhtml, svg
CSSSYNTAX_CSSscss, less
PythonSYNTAX_PYTHONpy
YAMLSYNTAX_YAMLyml
MarkdownSYNTAX_MARKDOWNmd, 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àTipoPredefinitoRuolo
is_textstring""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_syntaxstring""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_readonlybooleanfalseEditor in sola lettura: l'utente consulta senza poter modificare
ib_modifiedbooleanfalsetrue 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àTipoPredefinitoRuolo
ib_line_numbersbooleantrueMostra 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_linebooleantrueEvidenzia la riga in cui si trova il cursore; in modalità ib_wrap la fascia copre tutte le righe visive della riga
ib_foldingbooleanfalseOpt-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_wrapbooleanfalseManda a capo le righe lunghe invece di scorrere lateralmente
ii_tab_sizeinteger4Numero 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_familystring""Carattere dell'editor (vuoto = carattere a spaziatura fissa del tema)
ii_font_sizeinteger0Dimensione del carattere in pixel (0 = dimensione del tema)
ProprietàTipoPredefinitoRuolo
ib_search_enabledbooleantrueAttiva la barra di ricerca integrata (Ctrl+F, Ctrl+H per sostituire — vedere «Tastiera»); a false, of_find restituisce -4
ib_find_match_casebooleanfalseOpzione 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_wordbooleanfalseOpzione 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_regexbooleanfalseOpzione 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_linelong0Porta 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_linelong1La 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_columnlong1La 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_caretbooleanfalseOpt-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_dropbooleanfalseOpt-in: accetta il rilascio di file da Esplora file di Windows; i percorsi completi arrivano tramite ue_drop_files
is_theme_stylestring""Stile visivo del componente (costanti THEME_STYLE_*); vuoto = quello dell'applicazione, seguito a ogni cambio
is_theme_modestring""Variante chiara o scura (costanti THEME_MODE_*); vuoto = quella dell'applicazione, seguita a ogni cambio
il_theme_accentlong-1Colore d'accento di questo componente (-1 = accento dell'applicazione, o quello del tema)
is_tooltipstring""Tooltip semplice mostrato al passaggio del mouse sul componente
is_super_tooltip_titlestring""Titolo del tooltip avanzato (prevale su is_tooltip)
is_super_tooltip_textstring""Testo del tooltip avanzato (markup avanzato accettato)
is_super_tooltip_imagestring""Immagine del tooltip avanzato

Metodi #

MetodoRuolo
of_get_text ( ) → stringRestituisce 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 ( ) → stringRestituisce 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 #

EventAttivato 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 #

TastoEffetto
TabRientra fino al punto di tabulazione successivo (ii_tab_size); più righe selezionate: rientra tutto il blocco
Maiusc+TabRiduce il rientro della riga o del blocco
InvioNuova riga con lo stesso rientro, un livello in più dopo {, ( o [
Ctrl+FApre la barra di ricerca, riempita con la selezione (ib_search_enabled)
Ctrl+HApre la barra con la sua riga di sostituzione (solo editor modificabile)
F3 · Maiusc+F3Occorrenza 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
EscChiude 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 #

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.

MembriRuoloDescritto in
of_resetRiportare il componente a zero3.6 Riportare un componente a zero: of_reset()
of_register_shortcut · of_clear_shortcutsScorciatoie da tastiera del componente3.5 Le scorciatoie da tastiera
of_is_created · of_is_ready · of_get_last_errorSe è nato, se è pronto, cosa è fallito3.7 Diagnostica
of_save_as_png · of_save_as_jpgEsportare il rendering in immagine3.8 Esportare il rendering come immagine
of_set_redrawRaggruppare le modifiche in un solo ridisegno3.10 Buone pratiche
of_preload_iconsIcone mostrate senza ritardoVisualizzazione istantanea: of_icon
of_set_translationTradurre una dicitura del componente5.2 Adattare un'etichetta: of_set_translation
of_focus_webviewDare il focus al componente6.4 Tastiera e focus
of_print · of_print_to_pdfStampare, o scrivere un PDF6.9 Stampare
of_set_property · of_get_property · of_component_namePilotare una proprietà per nome3.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.


← Riferimento dei componenti · Sommario della guida