Gli script di Jaws 14. Le procedure guidate: gestione dei pulsanti ed elementi base.

Programmiamoli da Soli!

Oltre i confini degli script per Jaws.

Se proponiamo degli elementi di codice, che funzionano regolarmente nella personale configurazione di chi scrive, vuol dire che ciò è comunque fattibile. Chi avesse un minimo di conoscenza dei linguaggi di programmazione, tuttavia, si potrebbe rendere facilmente conto che stiamo forse un po’ uscendo dall’ambito per il quale era stata pensata la possibilità di personalizzare il funzionamento di Jaws.

Se il nostro obiettivo è costruire delle procedure guidate, in queste pagine è comunque spiegato come raggiungerlo. Certo, potrete rendervi conto anche voi che non saranno perfette, tutt’altro, e saranno pure un po’ lente, in quanto devono lavorare sopra ad altre applicazioni, ma funzionano, ed è tutto ciò che conta!

Tornando ai contenuti, in quest’ultimo capitolo termineremo gli elementi di carattere accessorio, per poterci poi dedicare finalmente al cuore della nostra procedura. Il capitolo si chiuderà trattando prima gli script necessari agli iniziali collaudi, e quindi dedicandoci alle altre funzioni di gestione che, come
MuoveDato ()
, si occupano materialmente di utilizzare i dati inseriti per compiere delle azioni concrete.

Così come nel capitolo precedente, all’inizio ci baseremo sui blocchi creati attorno alle funzioni chiamate direttamente dall’elemento principale. Siccome, dopo quelli già affrontati nello scorso capitolo, i blocchi mancanti sono solo tre, inizieremo comunque dal più corposo, dedicato alla gestione delle scelte operate nella finestra di dialogo primaria. Gli altri due, composti ciascuno da una sola funzione, ci consentiranno poi almeno di terminare gli elementi preparatori.

Il primo dei restanti blocchi sarà quello relativo, appunto, alla funzione di gestione delle procedure, ed al collaudo delle funzionalità che ancora mancano per la ricerca di elementi. Gli ultimi due blocchi riguarderanno le macro testuali, con gli script che attivano tale categoria di elaborazione, e gli script a gestione personale, che avranno in più anche qualche altra funzione riservata a questa categoria.

Con la certezza che si tratti davvero dell’ultima volta, vi chiediamo di iniziare ancora completando per prima cosa i nostri file esterni.

Esercizio 14.1.1. Aggiornare il file Personale delle Costanti.


GIU = "giù", ; termine omonimo
MAX_LUNGO = 120, ; numero delle colonne per il sommario nelle voci di scelta
MODIFICA = "Modifica", ; termine omonimo
ELIMINA = "Elimina", ; termine omonimo
DUPLICA = "Duplica", ; termine omonimo
DATI_SCRIPT = 5, ; numero degli elementi nel record di dati sugli script a gestione personale
TABELLA = "Tabella", ; termine omonimo

Esercizio 14.1.2. Aggiornare il file Personale delle Variabili Globali.


Int gnUscita, ; valore per l’uscita dai cicli

Esercizio 14.1.3. Aggiornare il file Personale dei Messaggi.


; raggiunto il numero massimo di voci di elaborazione consentite
@hlpMassimoVoci
Raggiunto il limite massimo di voci.
@@
; voce unica in una finestra di elaborazione
@hlpUnicaVoce
Unica voce presente.
@@
; ultima voce in una finestra di elaborazione
@hlpUltimaVoce
Ultima Voce.
@@
; Prima voce in una finestra di elaborazione
@hlpPrimaVoce
Prima voce.
@@
; campo non valido per la funzione richiesta
@msgNoCampoValido
Impossibile %1re voci a questo livello della procedura.
@@
; conferma cancellazione
@msgCancella
Eliminare %1%2 %3?
@@
; cancellazione riuscita
@msgOkCancella
Rimozione effettuata.
@@
; assenza di script registrati nell’archivio di configurazione personale
@hlpNoArchivioScript
Nessuno script personale registrato.
@@
; tre termini seguiti dal carattere Punto
@msg3Punto
%1. %2. %3.
@@
; titolo per la scelta degli script a gestione personale da duplicare
@ttlDuplicaScript
Selezionare lo script da duplicare. Ok conferma, Esc annulla.
@@
; conferma della duplicazione di uno script
@msgCopiaScript
Script duplicato.
@@
; Errore nella copia di uno script
@msgErroreCopia
Impossibile copiare script.
@@
; frase negativa
@hlpNessuna
Nessuna %1.
@@
; elenco azioni eseguite in una schermata di scelta
@lstEseguiteVoci
modifica|aggiunta|rimozione|duplicazione
@@
; elenco azioni sulle voci in una schermata di scelta
@lstAzioniVoci
modifica|aggiunge|elimina|duplica
@@
; etichetta di pulsante non riconosciuta
@hlpNoEtichetta
Etichetta %1 non riconosciuta.
@@
; trascrizione ambito riuscita
@hlpOkAmbito
Ambito salvato.
@@
;errore nella trascrizione dell’ultimo ambito selezionato nella finestra di scelta
@hlpErroreAmbito
Impossibile aggiungere l’ambito %1.
@@
; titolo che informa dei dati già registrati per lo script rilevato
@ttlScriptPresente
I dati per lo script %1 sono già registrati.
@@
; conferma generica alla sovrascrittura
@msgSovrascrittura
Confermate la sovrascrittura?
@@
; avviso di ricerca avviata
@msgAvvioRicerca
Ricerca in corso...
@@
; macro non registrata
@ttlNoMacro
Nessuna macro %1 alla posizione %2.
@@
; base per titolo nella modifica o aggiunta di una voce in un elenco
@ttlElaboraVoce
%1re %2 alla posizione %3.
@@
; suffisso per la posizione di un elemento
@msgPosizione
alla posizione %1.
@@
; mancata impostazione dei tasti di uno script personale come gli ultimi premuti
@hlpNoUltimiTasti
Impossibile impostare i tasti di attivazione di %1 come gli ultimi premuti.
@@
; mancata impostazione dei tasti di uno script personale come gli ultimi premuti - versione corta
@hlpNoUltimiTasti_corto
Impossibile impostare i tasti.
@@
; base per la chiamata della funzione che esegue gli script dall’Aiuto in linea
@hlpEsegueLink
ImpostaEsegue ("%1", "%2")
@@
; mancato rilevamento dei dati sugli script a gestione personale
@hlpNoDatiScript
Dati dello script personale %1 assenti o incompleti.
@@
; mancato rilevamento dei dati sugli script a gestione personale - versione corta
@hlpNoDatiScript_corto
Errore nei dati personali.
@@
; cursore non posizionato in una tabella o in un foglio elettronico
@hlpNoTabella
Non siamo in una cella.
@@
; ambito di azione degli script non riconosciuto
@hlpNoAmbito
Impossibile riconoscere l’ambito %1 per gli script personali.
@@
; ambito di azione degli script non riconosciuto - versione corta
@hlpNoAmbito_corto
%1 non riconosciuto.
@@

***

Pulsanti e scelte.

Con gli elementi di questo blocco, composto da ben dodici funzioni, affrontiamo il vero motore della procedura, quello che consente di operare delle scelte e di eseguire le azioni conseguenti. Sono concentrate qui, infatti, le funzioni per inserire, modificare, cancellare, spostare o duplicare, le varie voci elaborate, gestendo soprattutto le diverse e variabili pressioni dei pulsanti opzionali.

Come al solito, rinviamo alle note dei singoli elementi per maggiori dettagli, mentre gli argomenti più importanti saranno illustrati da un titolo a parte. E proprio da uno di questi inizieremo subito.

Valori minimi e massimi per validare le pressioni dei tasti.

Per come è stata predisposta, ogni procedura guidata può avere un proprio numero di pulsanti, e ad essi può essere affidato qualsiasi tipo di compito. Non tutti i pulsanti, tuttavia, possono essere validi in tutti i momenti, perché non si può, ad esempio, inserire un’ulteriore voce, se ne sono già state create il numero massimo, oppure spostarne una verso l’alto, se si è già sul primo elemento di un elenco.

Se da un lato tale versatilità è necessaria, dall’altro è altrettanto indispensabile che i controlli sui pulsanti premuti non siano legati troppo alle singole procedure. Per questo, nel caricare la configurazione dei vari tipi di procedura, si è previsto che ogni pulsante si porti appresso dei valori minimi e massimi, i quali ne stabiliscano i limiti d’utilizzo.

Tali valori, confrontati al numero della voce su cui è posizionato il cursore, determinerà di volta in volta se la pressione di un pulsante sia consentita oppure no in quel momento. Il primo elemento di codice che andremo a realizzare, dunque, si occupa proprio di questo, confrontando i valori minimi e massimi dei singoli pulsanti con quello corrente, e restituendo il risultato di tale controllo.

Esercizio 14.2.2. La funzione PulsanteValido.

FileScript.

Default.JSS

Nome.

PulsanteValido

Descrizione.

Determina la validità del pulsante premuto, sulla base del numero totale delle voci e della posizione di quella selezionata, impostando casomai i messaggi d’errore che saranno pronunciati al ritorno nella finestra di dialogo.

Ritorni.

Di tipo Int. L’esito del controllo, TRUE o FALSE.

Parametri.
  1. sNome. L’etichetta del pulsante premuto. Di tipo String.
  2. iTasto. Il valore del tasto suppletivo eventualmente premuto. Di tipo Int.
Novità.
  1. La costante
    GIU
    , la quale corrisponde all’omonimo termine, e che sta ad indicare lo spostamento verso il basso di una voce.
Fasi.
  1. Nella struttura che compone la funzione, una serie di controlli alternativi, legati ai valori minimi e massimi consentiti per il pulsante premuto, restituisce un valore positivo qualora almeno uno di essi sia stato rilevato come vero.
  2. Nel caso invece che nessun controllo sia stato ritenuto valido, un’ulteriore struttura esegue una serie di controlli, per impostare in un avviso il tipo di errore riscontrato, quindi restituisce un risultato nullo.
Note.
  1. Per rendere semplice la loro impostazione, i valori minimi e massimi sono specificati solo quando abbiano un valore diverso da quelli predefiniti, che corrispondono ad 1, come minimo, e il numero totale delle voci elaborate, come massimo; qualora essi non siano stati specificati, i controlli della funzione assumono quindi i valori predefiniti.

Codice.


Int Function PulsanteValido (string sNome, int iTasto)
Var
Int iMinimo, ; valore minimo della voce selezionata
Int iMassimo; valore massimo della voce
; estrae il valore minimo per la sua visualizzazione
Let iMinimo = StringToInt (StringSegment (gsMinimi, PIPE, iTasto))
; estrae anche l’eventuale valore massimo
Let iMassimo = StringToInt (StringSegment (gsMassimi, PIPE, iTasto))
; se il minimo non è specificato, oppure se la voce corrente è maggiore o uguale a tale valore,
If (!iMinimo || gnVoce >= iMinimo)
; e ancora, se è il massimo a non essere specificato, o la voce corrente è minore o uguale a tale valore,
&& (!iMassimo || gnVoce <= iMassimo)
; se poi, il pulsante non è quello di aggiunta, oppure vi è almeno un’altra voce possibile,
&& (sNome != AGGIUNGE || gnTotali <= iMassimo)
; se, infine, non si tratta del pulsante di spostamento in basso, oppure vi è almeno un’altra voce,
&& (sNome != GIU || gnVoce < gnTotali) Then
Return TRUE; restituisce l’esito positivo del controllo
Else; altrimenti, in caso di errore,
; se si è chiesta l’aggiunta di una voce, e il numero delle voci è già al massimo consentito,
If sNome == AGGIUNGE && gnTotali > iMassimo Then
Let gsAvviso = hlpMassimoVoci; imposta un avviso, da far leggere poi
ElIf gnVoce == gnTotali Then; se ci si trova sull’ultima voce,
If gnVoce == 1 Then; se è stata immessa una sola voce,
Let gsAvviso = hlpUnicaVoce; imposta l’avviso da leggere al ritorno nella finestra di dialogo
Else; altrimenti,
Let gsAvviso = hlpUltimaVoce; imposta l’avviso relativo
EndIf; fine controllo ultima voce
ElIf gnVoce == 1 Then; se si è comunque nella prima voce,
Let gsAvviso = hlpPrimaVoce; imposta il relativo avviso
EndIf; fine controllo errori
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo validità pulsante
EndFunction

L’ordine delle chiavi numeriche nei record.

Nei due primi tipi di procedura, quello della ricerca di elementi e delle macro testuali, il numero prestabilito delle voci è da un minimo di 1 ad un massimo di 9. Per il numero limitato delle voci, e soprattutto a causa del valore progressivo che è utilizzato per numerarle, le chiavi dei record con i dati relativi a ciascuna voce devono essere sempre in ordine sequenziale.

In altre parole, ciò significa che la prima voce avrà sempre come chiave il numero 1, la seconda il 2, la terza il 3, e così via. Se però noi dovessimo cancellare una chiave, ad esempio la numero 2, si creerebbe una sequenza irregolare, essendo rimaste solo le chiavi 1 e 3.

Per questo, sarebbe necessario ripristinare l’ordine corretto, rinominando la chiave numero 3 nella numero 2. A tale compito, in particolare,sarà dedicata una nostra funzione, che incontreremo più avanti.

Anche con gli script a gestione personale, se noi dovessimo cancellarne uno che non fosse l’ultimo inserito, si creerebbe un buco nella sequenza corretta. In questo caso, tuttavia, le chiavi dei restanti script registrati non sarebbero rinominate, non solo perché avevamo stabilito un numero massimo ben più elevato di script, ma soprattutto perché il numero della chiave è strettamente correlato allo script reale che serve per attivarli, rendendo perciò molto complicato rinominare tutti i rimanenti script uno ad uno.

Se però noi lasciamo uno o più buchi nella sequenza corretta, quando noi inseriamo un altro script a gestione personale, dovremmo per forza utilizzare la prima chiave libera, in modo da sfruttare al massimo i numeri da 1 a 99, il valore massimo che avevamo prestabilito per questa tipologia di voci. E proprio per individuare quale sia questa prima chiave libera nella sequenza di quelle esistenti, realizzeremo il successivo elemento di codice.

Sull’argomento, va precisato che la voce aggiunta, nel caso degli Elementi di ricerca e delle Macro testuali, sarà sempre inserita sotto alla voce corrente. Ad esempio, se noi avessimo cinque voci, dalla 1 alla 5, e fossimo posizionati sulla numero 3, se premiamo il pulsante per inserirne una nuova, questa sarà immessa come nuova numero 4, facendo scalare la precedente 4 come 5, e la 5 come 6.

Se invece noi volessimo inserire una voce nella prima schermata delle elaborazioni del terzo tipo, quelle ad esempio degli script personali, il nuovo nome di script sarà in ogni caso inserito dopo l’ultimo di quelli presenti. Come detto, tuttavia, se l’elenco sequenziale dei numeri di chiave avesse dei buchi, sarebbe utilizzato il primo numero di chiave libero, altrimenti, se fossero presenti un numero di chiavi uguale al numero massimo di quelle registrate, il nuovo script avrebbe anche in questo caso l’ultima chiave esistente aumentata di un’unità.

Esercizio 14.2.4. La funzione PrimaLibera.

FileScript.

Default.JSS

Nome.

PrimaLibera

Descrizione.

Restituisce la prima chiave libera, in forma testuale, cercando nell’elenco di quelle possibili.

Ritorni.

Di tipo String. La chiave in forma testuale.

Note.
  1. Nel ciclo che costituisce la funzione, il valore usato come limite è quello della costante con il numero massimo di voci.
  2. Non è previsto alcun risultato nullo, anche se la funzione lo restituirebbe in caso di errore, poiché il flusso giunge alla funzione solo se esiste almeno una chiave libera tra quelle registrate.

Codice.


String Function PrimaLibera ()
Var Int i; contatore del ciclo
For i = 1 To MAX_VOCI; scorre i possibili valori
If !LeggeRecord (gsArchivio, gsSezione, IntToString (i)) Then; se il record è vuoto,
Return IntToString (i); restituisce il primo valore non utilizzato
EndIf; fine controllo record
EndFor; fine scansione valori
EndFunction

Esercizio 14.2.5. La funzione AggiornaElenco.

FileScript.

Default.JSS

Nome.

AggiornaElenco

Descrizione.

Toglie o aggiunge una voce all’elenco dei dati registrati, aggiornando l’ordine delle altre voci eventualmente presenti.

Ritorni.

Di tipo Int. True per la riuscita dell’aggiornamento, FALSE per il suo fallimento.

Parametri.
  1. iValore. Il numero della voce selezionata. Di tipo Int.
  2. sCorrente. Se specificato, indica di aggiungere il contenuto del record attivo, inserendolo come ultimi dati di quelli trascritti. Di tipo String. Parametro Opzionale.
Fasi.
  1. All’interno di un’unica struttura di controllo, nel caso si sia lasciato vuoto il secondo parametro, e quindi che si sia cancellata una voce, si fa partire un ciclo che sovrascrive i record esistenti, partendo dalla voce successiva a quella corrente, sino all’ultima registrata.
  2. Nel caso in cui invece si sia specificato il contenuto di un record come parametro, indicando con ciò di dover inserire una nuova voce tra quelle esistenti, il ciclo ne scorre l’elenco a ritroso, partendo dall’ultima registrata e tornando sino a quella corrente, il cui testo è appunto il parametro indicato.
  3. Se durante la trascrizione dei record non si fossero verificati errori, i quali avrebbero quindi già causato il ritorno alla funzione chiamante con un risultato nullo, viene invece restituito un esito positivo.
Note.
  1. Questa è la funzione citata nella premessa, che viene chiamata nei due casi elencati nelle fasi, la cancellazione o l’inserimento di una voce, usando la presenza o meno del secondo parametro per determinare quale tipo di riscrittura dei dati mettere in atto.

Codice.


Int Function AggiornaElenco (int iValore, string sCorrente)
Var
Int i, ; contatore del ciclo
String sDato
If !sCorrente Then; se l’ultimo parametro non è stato specificato,
For i = iValore +1 To gnTotali; scorre le voci per ridurne l’elenco
; rileva il dato relativo alla voce successiva
Let sDato = LeggeRecord (gsArchivio, gsSezione, IntToString (i))
; se il dato non viene salvato,
If !ScriveRecord (gsArchivio, gsSezione, IntToString (i - 1), sDato)
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo scrittura dato
EndFor; fine scansione voci
Else; altrimenti, se si deve aggiungere una voce all’elenco,
For i = gnTotali To iValore Descending; scorre le voci per ridurne l’elenco
If i > iValore Then; se il contatore è superiore all’ultima voce da aggiornare,
; rileva il dato relativo alla voce precedente
Let sDato = LeggeRecord (gsArchivio, gsSezione, IntToString (i - 1))
Else; altrimenti,
Let sDato = sCorrente; imposta la voce passata come parametro
EndIf; fine controllo voce da scrivere
If !ScriveRecord (gsArchivio, gsSezione, IntToString (i), sDato); se il dato non viene salvato,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo scrittura dato
EndFor; fine scansione voci
EndIf; fine controllo tipo di aggiornamento
Return TRUE; se nessun altro controllo è intervenuto, restituisce l’esito positivo
EndFunction

Collaudo.

  1. In questo caso, dopo aver compilato la funzione, evidenziamo di rendere opzionale il secondo parametro.

Esercizio 14.2.6. La funzione AggiungeVoce.

FileScript.

Default.JSS

Nome.

AggiungeVoce

Descrizione.

Inserisce una voce nelle schermate di scelta.

Ritorni.

Di tipo Int. L’esito dell’inserimento, TRUE o FALSE.

Novità.
  1. Le nostre funzioni
    PrimaLibera ()
    e
    AggiornaElenco ().
Fasi.
  1. Un primo controllo serve solo ad impedire che il flusso prosegua qualora la funzione sia chiamata quando si stanno elaborando i campi dal secondo in poi; tale situazione non dovrebbe in teoria mai verificarsi, e potrebbe quindi essere causata solo da un qualche errore nella procedura.
  2. Una seconda struttura imposta la chiave del record da aggiungere all’elenco, sulla base del tipo di elaborazione in atto, e casomai servendosi della nostra funzione
    PrimaLibera ().
  3. Si tenta poi di inserire il testo da aggiungere; se tale aggiunta è annullata, o fallisce per qualche problema, il flusso viene interrotto restituendo un risultato nullo.
  4. Se invece prosegue, si controlla dapprima se esistono ulteriori voci registrate dopo quella appena inserita; se così è, tramite la nostra funzione
    AggiornaElenco ()
    , si fanno scalare le voci presenti, a partire da quella posta subito dopo quella corrente sino all’ultima registrata, in modo da lasciare spazio alla voce appena inserita; se tutto procede al meglio, è aggiornata la posizione della voce attiva nell’elenco, restituendo l’esito positivo, altrimenti viene restituito un risultato nullo.
Note.
  1. Questa rappresenta la prima di una serie di funzioni chiamate a gestire la pressione di un tasto opzionale, che in questo caso è la prima parte del suo nome,
    "Aggiunge".

Codice.


Int Function AggiungeVoce ()
Var String sRecord; dati temporanei
If gnCampo > PRIMA Then; se si è dalla seconda schermata in poi,
Let gsAvviso = FormatString (msgNoCampoValido, AGGIUNGE); formatta l’avviso,
Return FALSE; e interrompe il flusso, restituendo un risultato nullo
EndIf; fine controllo numero campo
If gnTipo == TERZA Then; se si sta elaborando il terzo tipo di procedura,
Let gnValore = gnTotali + 1; pone a video la nuova voce dopo l’ultima presente
Let gsChiave = PrimaLibera (); individua la prima chiave libera tra quelle possibili
Else; altrimenti, nei primi due tipi di procedura,
Let gnValore = gnValore +1; aggiunge la nuova voce appena dopo quella corrente
Let gsChiave = ChiaveCorrente (gnValore); crea la chiave rendendo testuale la posizione
EndIf; fine controllo chiave
; rileva l’eventuale dato esistente
Let sRecord = LeggeRecord (gsArchivio, gsSezione, gsChiave)
; se non vi è stato alcun inserimento,
If !AggiornaCampo (AGGIUNGE, gsSezione, gsChiave, NULLO) Then
Let gsChiave = ChiaveCorrente (gnVoce); ripristina la chiave attiva,
Return FALSE; e restituisce un risultato nullo
EndIf; fine controllo scrittura voce
Delay (ATTESA); sospende temporaneamente il flusso
Let gnTotali = gnTotali + 1; aggiorna il contatore delle voci complessive
If gnValore < gnTotali Then; se vi sono altre voci dopo quella inserita,
If AggiornaElenco (gnValore + 1, sRecord) Then; se l’aggiornamento delle altre voci riesce,
Let gnVoce = gnValore; aggiorna il puntatore della selezione
Else; altrimenti, se l’aggiornamento fallisce,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo esito aggiornamento
Else; altrimenti, se quella inserita è l’ultima voce dell’elenco,
Let gnVoce = gnValore; aggiorna il puntatore della selezione
EndIf; fine controllo primi due tipi di procedura
Return TRUE; se nessun altro controllo è intervenuto, restituisce l’esito positivo
EndFunction

Estrarre un campo tramite un indice.

Poniamo di avere un record con la chiave
"Tasti"
, il cui contenuto siano tre campi:

  1. Invio.
  2. FrecciaSu.
  3. FrecciaGiù.

Tradotto in una sola riga di dati, il record sarebbe così composto:


Tasti=Invio|FrecciaSu|FrecciaGiù

Per estrarre il contenuto di un campo da questo record, è necessario sapere la posizione che occupa tale contenuto, e poi mettere questo valore come terzo parametro nella funzione nativa
StringSegment ()
. Se noi non conoscessimo tale posizione, dovremmo però servirci dell’altra funzione nativa,
StringSegmentIndex ()
, incontrata nell’ottavo capitolo, ponendo come terzo parametro, stavolta, direttamente la stringa testuale che stiamo cercando.

Nel caso in cui noi avessimo però solo il nome inglese di un tasto, come stringa da cercare, ma avessimo bisogno di ricavarne la traduzione in italiano, dovremmo costruire un record che avesse lo stesso numero di campi di quello originale in italiano, ovviamente con la versione inglese dei tasti, così come il seguente:


Keys=Enter|UpArrow|DownArrow

Questo record, gemello di quello con i tasti nella nostra lingua, prende il nome di
indice
, che a noi serve, appunto, solo ad
"indicarci"
dove sia la posizione del tasto nel record in italiano.

Ad esempio, se noi avessimo da estrarre dal record originale il campo con la versione tradotta del nome inglese del tasto
"UpArrow"
, cioè
"FrecciaSu"
, dovremmo quindi prima cercarne la posizione nel record che ci fa da indice, e poi usare quel valore per estrarre la stringa da noi voluta.

Se noi ipotizziamo di memorizzare il contenuto dei due record in altrettante variabili testuali, che abbiano ciascuna il prefisso
"s"
prima del nome della chiave, noi dovremmo usare le seguenti due istruzioni:


Let iPosiz = StringSegmentIndex (sKeys, PIPE, "UpArrow", TRUE); rileva la posizione,
Return StringSegment (sTasti, PIPE, iPosiz); e restituisce il campo richiesto

Questo, dunque, sarà il compito del nostro prossimo elemento, con l’unica differenza di usare la nostra funzione
CampoTrovato ()
, al posto della prima funzione nativa, poiché in essa avevamo appunto già usato
StringSegmentIndex ()
, oltre all’impostazione di un separatore dei campi predefinito.

Esercizio 14.2.8. La funzione EstraeCampo.

FileScript.

Default.JSS

Nome.

EstraeCampo

Descrizione.

Individua e restituisce il contenuto di un campo in un record usato come indice, per restituirne il contenuto del campo equivalente nel record d’origine.

Ritorni.

Di tipo String. Il contenuto del campo individuato.

Parametri.
  1. sRecord. Il record d’origine da cui estrarre il contenuto del campo individuato nell’indice. Di tipo String.
  2. sCampo. La stringa di cui cercare la presenza tra i campi del record indice. Di tipo String.
  3. sIndice. L’eventuale record parallelo dove effettuare la ricerca; se non specificato, viene utilizzato il record d’origine. Di tipo String. Parametro Opzionale.
  4. sSeparatore. L’eventuale separatore alternativo degli elementi; se non specificato, viene utilizzato il carattere Pipe, Ascii 124. Di tipo String. Parametro Opzionale.
Note.
  1. Così come anticipato nei dettagli dei parametri, qualora il record indice non sia specificato, viene usato come indice lo stesso record d’origine; in questo modo, la funzione non serve a restituire il contenuto del campo, che abbiamo già dovendolo specificare, bensì può essere usata per indicarci soltanto se il campo esista oppure no.

Codice.


String Function EstraeCampo (string sRecord, string sCampo, ; primi due parametri,
string sIndice, string sSeparatore); seconda riga con gli altri due
Var Int iPosiz; posizione del campo nel record
If !sIndice Then; se non è stato indicato un record che faccia da indice,
Let sIndice = sRecord; utilizza l’elenco originale anche per cercare direttamente il campo
EndIf; fine controllo record indice
If CampoTrovato (sIndice, sCampo, iPosiz, sSeparatore) Then; se un campo è stato trovato,
Return StringSegment (sRecord, sSeparatore, iPosiz); lo prende casomai dal record originale
Else; altrimenti,
Return NULLO; restituisce una stringa vuota
EndIf; fine controllo campo
EndFunction

Collaudo.

  1. Anche in questo caso, dopo la compilazione, segnaliamo la necessità di rendere opzionali gli ultimi due parametri.

Esercizio 14.2.9. La funzione ScambiaVoci.

FileScript.

Default.JSS

Nome.

ScambiaVoci

Descrizione.

Registra la voce corrente, scambiandone la posizione nell’elenco con quella precedente o successiva.

Ritorni.

Di tipo Int. True per uno scambio riuscito, FALSE per il fallimento.

Parametri.
  1. sCorrente. Il contenuto della voce selezionata. Di tipo String.
  2. sVerso. Se si specifica la costante GIU, la voce sarà scambiata con quella successiva; se invece si indica qualsiasi altro dato testuale, la voce selezionata sarà scambiata con quella che la precede nell’elenco. Di tipo String.
Novità.
  1. La costante
    GIU
    , che corrisponde all’omonimo termine.
Fasi.
  1. Una prima struttura di controllo imposta un valore, positivo o negativo di un’unità, per incrementare o diminuire il valore della voce corrente, sulla base del parametro specificato.
  2. Dopo aver eseguito le necessarie impostazioni, una seconda struttura tenta di eseguire la scrittura del record da spostare nella nuova posizione; se tale scrittura riesce, allora viene aggiornata la posizione del record appena sovrascritto, copiandolo con la chiave di quello elaborato, e restituendo l’esito positivo.
  3. Se invece la scrittura dei record non riesce, viene restituito un risultato nullo.
Note.
  1. Ecco qui un’altra delle funzioni per la gestione dei tasti premuti, in questo caso
    sposta giù
    e
    "Sposta su".

Codice.


Int Function ScambiaVoci (string sCorrente, string sVerso)
Var
Int iCambia, ; il valore da applicare al puntatore della voce corrente
String sChiave, ; l’ordine progressivo della voce da scambiare in forma testuale
String sRecord; i dati relativi alla voce selezionata.
If sVerso == GIU Then; se si indica la costante omonima,
Let iCambia = 1; imposta un valore positivo, per elaborare la voce successiva
Else; altrimenti, se si specifica qualsiasi altro dato testuale,
Let iCambia = -1; imposta un valore negativo, per elaborare la voce precedente
EndIf; fine controllo valore relativo
; compone la chiave della voce da rendere attiva,
Let sChiave = ChiaveCorrente (gnValore + iCambia)
Let sRecord = LeggeRecord (gsArchivio, gsSezione, sChiave); e ne rileva il dato
; se la voce da spostare, quella corrente, viene salvata nella nuova posizione,
If ScriveRecord (gsArchivio, gsSezione, sChiave, sCorrente) Then
; la voce sovrascritta viene copiata nella posizione precedente,
ScriveRecord (gsArchivio, gsSezione, ChiaveCorrente (gnValore), sRecord)
Let gnVoce = gnValore + iCambia; quindi, viene aggiornato il puntatore delle voci,
Return TRUE; e restituito l’esito positivo
Else; altrimenti, in caso di errore nella scrittura,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo scrittura
EndFunction

Esercizio 14.2.10. La funzione CancellaRecord.

FileScript.

Default.JSS

Nome.

CancellaRecord

Descrizione.

Rimuove la chiave indicata dell’archivio di configurazione di cui si è specificato il nome, senza l’estensione .JCF, presente nella cartella delle Impostazioni personali.

Ritorni.

Di tipo Int. L’esito della cancellazione, TRUE o FALSE.

Parametri.
  1. sArchivio. Il nome, senza estensione, dell’archivio da elaborare. Di tipo String.
  2. sSezione. La sezione dell’archivio in cui operare. Di tipo String.
  3. sChiave. La chiave da rimuovere. Di tipo String.
Note.
  1. Nella struttura di controllo che compone la funzione, la prima via è dedicata alla cancellazione della chiave , qualora quest’ultima sia stata specificata; se questo dato invece non c’è, viene interrotto il flusso, restituendo un risultato nullo, in quanto l’istruzione nativa, priva di una chiave, rimuoverebbe tutto il contenuto della sezione elaborata.

Codice.


Int Function CancellaRecord (string sArchivio, string sSezione, string sChiave)
If sChiave Then; se una chiave da cancellare è specificata,
ImpostaConfigurazione (sArchivio); controlla il nome, casomai aggiungendovi l’estensione,
Return IniRemoveKey (sSezione, sChiave, sArchivio); e ne restituisce l’esito
Else; altrimenti, se una chiave non c’è,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo chiave
EndFunction

Esercizio 14.2.11. La funzione EliminaVoce.

FileScript.

Default.JSS

Nome.

EliminaVoce

Descrizione.

Gestisce la cancellazione di una voce nelle finestre di scelta.

Ritorni.

Di tipo Int. L’esito della cancellazione, TRUE o FALSE.

Novità.
  1. La nostra funzione
    CancellaRecord ().
Fasi.
  1. Il primo controllo è una richiesta di conferma alla cancellazione al quale, se si risponde in modo negativo, il flusso sarà interrotto.
  2. Nella seconda struttura si tenta invece di cancellare il record indicato, tramite la nostra funzione
    CancellaRecord ()
    ; anche in questo caso, se tale azione fallisse, il flusso verrebbe interrotto.
  3. Una volta cancellato il record, un’ultima ed articolata struttura di controllo regola le impostazioni sulla base del tipo di procedura che si sta elaborando; Nel caso dei primi due tipi, qualora non si sia nell’ultima voce visualizzata, si tenta di far scorrere le altre voci, casomai restituendo un risultato nullo qualora tale aggiornamento non riesca.
Note.
  1. Questa è un’altra funzione di gestione, dove anche qui il pulsante che la chiama è quello che compone la prima parte del nome,
    "Elimina".

Codice.


Int Function EliminaVoce ()
Var
String sPrefisso, ; parte iniziale del titolo
String sTitolo; titolo per la conferma alla cancellazione
; mantiene gli ultimi tre caratteri del prefisso per il tipo di procedura
Let sPrefisso = StringRight (StringSegment (lstPrefissiTesto, PIPE, gnTipo), 3)
; formatta il titolo da proporre nella finestra di dialogo
Let sTitolo = FormatString (msgCancella, sPrefisso, gsCategoria, ComponeTermine ())
If !ChiedeConferma (sTitolo) Then; se tale cancellazione non viene confermata,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo conferma
Delay (ATTESA); sospende temporaneamente il flusso
; salva i tasti memorizzati nel record per l’eventuale cancellazione
Let gsRimuoviTasti = LeggeCampo (gsArchivio, gsSezione, gsChiave, SECONDA)
If !CancellaRecord (gsArchivio, gsSezione, gsChiave) Then; se la rimozione fallisce,
Let gsRimuoviTasti = NULLO; resetta il dato,
Return FALSE; e restituisce un risultato nullo
EndIf; fine controllo cancellazione
Let gsAvviso = msgOkCancella; memorizza il messaggio
If gnTipo == TERZA Then; se si sta elaborando il terzo tipo di procedura,
AggiornaTasti (CANCELLA, gsChiave); rimuove le eventuali assegnazioni tasti dello script,
; cancella la chiave anche dall’elenco, per la successiva sincronizzazione
Let gsElenco = CambiaCampo (gsElenco, NULLO, gnVoce)
Delay (ATTESA); sospende temporaneamente il flusso
If gnVoce == gnTotali Then; se ci si trovava sull’ultima voce,
Let gnVoce = gnVoce - 1; sposta la voce corrente a quella precedente
EndIf; fine controllo aggiornamento posizione
Else; altrimenti, se si è in uno dei primi due tipi,
If gnValore < gnTotali Then; se esiste almeno un valore dopo quello corrente,
If AggiornaElenco (gnValore) Then; se è stato aggiornato l’elenco dei dati registrati,
CancellaRecord (gsArchivio,gsSezione, ChiaveCorrente (gnTotali)); cancella l’ultimo dato
Else; altrimenti, in caso di errore,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo rimozione dato
Else; altrimenti, se ci si trovava sull’ultima voce,
Let gnVoce = gnValore - 1; aggiorna il puntatore delle voci
EndIf; fine controllo numero voci
Let gsElenco = CambiaCampo (ChiaviUtente (gsArchivio, gsSezione), ZERO); aggiorna l’elenco delle voci
EndIf; fine controllo tipo procedura
Let gnTotali = StringSegmentCount (gsElenco, PIPE); conta le voci in elenco
If !gnTotali Then; se non esiste più alcuna voce,
Let gnVoce = FALSE; azzera il valore
EndIf; fine controllo voci totali
Let gsChiave = ChiaveCorrente (gnVoce); allinea anche la chiave attiva
Return TRUE; restituisce l’esito positivo
EndFunction

Un archivio con gli script realizzati.

Uno dei vantaggi che si hanno con gli script a gestione personale è quello di avere un vero e proprio archivio di tutti gli script di questo tipo da noi elaborati, che quindi possono essere usati per essere inseriti in tutte le applicazioni dove possono servire. Tutti i dati necessari ad uno script a gestione personale, infatti, stanno in un solo record con cinque campi, che corrisponde al numero di schermate in cui dovremo operare per realizzarne uno.

La funzione che proponiamo di seguito è quella che serve proprio per inserire uno script, proveniente dall’archivio personale, tra quelli a disposizione per le singole applicazioni. Una volta attivato il pulsante di duplicazione, basterà scegliere dall’elenco a video il nome reale dello script da inserire, casomai esaminando i tasti per attivarlo o la prima parte della descrizione, poi premere Invio. Una volta aggiunto all’elenco, lo script duplicato potrà comunque essere anche rinominato, modificato o adattato all’applicazione attiva, oppure lasciato così com’è, se la sua forma risulta già corretta.

Proprio questa funzionalità sarà quella, alla fine del capitolo, che useremo per testare la procedura guidata sugli script a gestione personale.

Esercizio 14.2.13. La funzione DuplicaDati.

FileScript.

Default.JSS

Nome.

DuplicaDati

Descrizione.

Consente di inserire tra gli script a gestione personale dell’applicativo corrente i dati relativi ad uno di tali script, registrati nel file di configurazione personale.

Ritorni.

Di tipo Int. Il valore numerico della scelta effettuata.

Novità.
  1. La costante numerica
    MAX_LUNGO
    , equivalente al valore 120, che corrisponde al numero massimo di caratteri provenienti dal sommario, da utilizzare come voce a video per gli script a gestione personale di cui inserire una copia.
Fasi.
  1. La prima struttura di controllo verifica se vi siano degli script a gestione personale registrati nell’archivio; qualora non ce ne siano, sarà impostato un messaggio d’avviso ed il flusso sarà interrotto.
  2. Dopo aver raccolto le voci già presenti a video, un ciclo scorre gli script registrati, dapprima non aggiungendo all’elenco quelli con un nome già presente, poi formattando lo stesso nome, i tasti di attivazione e la prima parte del sommario per comporre le varie voci di scelta.
  3. Dopo aver riattivato la sintesi, viene proposta una schermata dove scegliere con i tasti di movimento lo script da inserire, da confermare poi con Invio; qualora si premesse invece il tasto Escape, si tornerebbe direttamente alla procedura principale.
  4. Se una scelta viene operata, il nome dello script confermato, ed i suoi dati, sono formattati assieme in un record con chiave numerica, tentando di scriverli nell’archivio per l’applicazione corrente; Se la scrittura riesce, sono aggiornati tutti gli indicatori per inserire e selezionare lo script aggiunto, restituendo l’esito positivo; se infine la scrittura non riuscisse, si tornerebbe alla procedura, senza modificare l’elenco degli script e quello su cui sarà posizionato il cursore.
Note.
  1. Questa invece è l’ultima funzione di gestione, dove la prima parte del nome corrisponde al pulsante da premere per chiamarla,
    "Duplica".

Codice.


Int Function DuplicaDati ()
Var
String sChiavi, ; elenco dei nomi di script
String sPresenti, ; nomi degli script già attivi
Int i, ; contatore del ciclo
String sRecord, ; dati relativi ad uno script
String sNome, ; chiave dei dati sugli script
String sVoce, ; testo della voce a video
String sElenco, ; lista degli script da duplicare
Int iScelta, ; valore della scelta operata
String sSommario, ; sommario dello script
String sChiave; chiave dello script nell’archivio corrente
Let sChiavi = LeggeChiavi (PERSONALE, gsSezione); rileva l’elenco delle chiavi
If !sChiavi Then; se nessuno script è presente nell’archivio di quelli a gestione personale,
Suona (ERRORE1); emette un segnale acustico
Let gsAvviso = hlpNoArchivioScript; imposta un messaggio d’avviso,
Return; e interrompe il flusso
EndIf; fine controllo presenza script
; rileva i nomi degli script già attivi nell’applicazione, portandoli in caratteri minuscoli
Let sPresenti = StringLower (CreaElenco (gsArchivio, gsSezione, PRIMA, PIPE))
; scorre le chiavi relative agli script personali
For i = 1 To StringSegmentCount (sChiavi, PIPE)
; estrae il nome dello script, che funge da chiave del record
Let sNome = StringSegment (sChiavi, PIPE, i)
; se lo script non è già presente,
If !StringSegmentIndex (sPresenti, PIPE, StringLower (sNome), TRUE) Then
Let sRecord = LeggeDato (PERSONALE, gsSezione, sNome); memorizza il record dei dati
; estrae il sommario, togliendo l’eventuale Punto alla fine, e riducendolo in lunghezza
Let sSommario = StringLeft (TogliePunto (StringSegment (sRecord, PIPE, SECONDA)), MAX_LUNGO)
; compone la voce, formattando nome, tasti e sommario in una stringa separata da punti
Let sVoce = FormatString (msg3Punto, sNome, TroncaTesto (sRecord), sSommario)
Let sElenco = CambiaCampo (sElenco, sVoce, ULTIMA); aggiunge la voce all’elenco
EndIf; fine controllo script attivi
EndFor; fine scansione nomi
If !sElenco Then; se nessun script da duplicare è stato rilevato,
Suona (ERRORE1); emette un segnale acustico
Let gsAvviso = hlpNoArchivioScript; imposta un messaggio d’avviso,
Return; e interrompe il flusso
EndIf; fine controllo script validi
SpeechOn (TRUE); riattiva la sintesi
; consente la selezione di uno script di cui inserire copia
Let iScelta = DlgSelectItemInList (sElenco, ttlDuplicaScript, TRUE)
SpeechOff (TRUE); torna a spegnere la sintesi
If !iScelta Then; se nessuna scelta è stata effettuata,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo scelta
; ricava il nome dello script, che funge da chiave del record
Let sNome = TroncaTesto (StringSegment (sElenco, PIPE, iScelta), PUNTO)
; rileva anche il record dall’archivio personale
Let sRecord = LeggeDato (PERSONALE, gsSezione, sNome)
; pone i dati estratti in un nuovo record
Let sRecord =FormatString (msg2Pipe, sNome, sRecord)
Let sChiave = PrimaLibera (); individua la prima chiave libera tra quelle possibili
If ScriveRecord (NULLO, gsSezione, sChiave, sRecord) Then; se la scrittura riesce,
Let gsElenco = CambiaCampo (gsElenco, sChiave, ULTIMA); aggiorna l’elenco delle voci
Delay (ATTESA); sospende temporaneamente il flusso
Let gsNuoviTasti = CambiaCampo (gsNuoviTasti, sChiave, ULTIMA) ; annota i tasti cambiati
Let gsChiave = sChiave; rende globale la chiave definita
Let gnVoce = StringSegmentCount (gsElenco, PIPE);adegua la posizione della voce attiva,
Let gnTotali = gnVoce; ed allinea anche il totale delle voci presenti
Let gnAggiorna = TRUE; imposta il valore per l’uscita dal primo ciclo
Let gsAvviso = msgCopiaScript; imposta anche il messaggio,
Return TRUE; e restituisce l’esito positivo
Else; altrimenti, se la scrittura fallisce,
Let gsAvviso = msgErroreCopia; imposta il messaggio,
Return FALSE; e restituisce un risultato nullo
EndIf; fine controllo scrittura
EndFunction

Esercizio 14.2.14. La funzione EsitoPulsanti.

FileScript.

Default.JSS

Nome.

EsitoPulsanti

Descrizione.

Svolge le azioni previste sulla base dei tasti premuti, casomai impostando un avviso che sarà pronunciato al ritorno nella finestra di dialogo.

Ritorni.

Di tipo Int. TRUE, per un’azione eseguita correttamente; FALSE, per un pulsante non valido, o per un’azione interrotta.

Novità.
  1. Le nostre funzioni
    PulsanteValido (),
    AggiungeVoce (),
    EstraeCampo (),
    EliminaVoce (),
    ScambiaVoci ()
    e
    DuplicaDati ().
  2. Le costanti testuali
    MODIFICA,
    ELIMINA
    e
    DUPLICA
    , che corrispondono ciascuna al termine omonimo.
Fasi.
  1. Una prima breve struttura di controllo verifica la validità del tasto premuto, grazie alla nostra funzione
    PulsanteValido ()
    ; se la pressione non fosse corretta, sarebbe impostato un messaggio, emesso un segnale acustico, e interrotto il flusso.
  2. All’interno della restante struttura, che analizza la pressione dei singoli tasti validi, la prima via viene intrapresa quando si vuole aggiungere una voce a quelle già presenti, tramite la quasi omonima nostra funzione
    AggiungeVoce ()
    ; in questa, come in tutte le altre vie di questo tipo, se l’azione collegata al pulsante premuto non riesce, o viene interrotta, si imposta un messaggio d’avviso e s’interrompe il flusso restituendo un risultato nullo.
  3. Le successive tre vie della struttura causano delle azioni solo di spostamento, rispettivamente, alla schermata precedente, successiva, o la prima; in questo caso, sono modificati solo dei valori per il cambio schermata, e non sono previsti risultati nulli.
  4. La via alternativa alle prime quattro è quella che gestisce tutti gli altri tasti, iniziando subito col rilevare il contenuto del campo corrente; poi, ciascuna via della struttura interna a questa mantiene lo schema di quella iniziale; nel dettaglio, una funzione è sempre chiamata a compiere l’azione prevista dal pulsante, con il flusso che s’interrompe solo nel caso di errori o interruzioni provocate dall’utente; in queste fasi sono di volta in volta chiamate, a seconda del pulsante premuto, le nostre funzioni
    EstraeCampo (),
    EliminaVoce (),
    ScambiaVoci ()
    e
    DuplicaDati ().
  5. Unica eccezione in tal senso è la pressione del tasto
    "Modifica"
    quando ci si trova nella gestione degli script personali, e nel secondo campo; in questo caso, infatti, viene attivata l’attesa dei tasti di attivazione degli script che, se ricordate, si realizza uscendo temporaneamente dalla procedura, e chiamando nel contempo quella con le funzioni hook.
  6. Un’altra possibilità di interruzione del flusso con un risultato nullo la si ha nel caso in cui l’etichetta del pulsante premuto, ripulita dagli eventuali caratteri E Commerciale, non sia riconosciuta tra quelle abbinate ad una qualche azione da compiere.
  7. In tutti i casi in cui un pulsante valido sia stato premuto, ed il flusso non venga interrotto, al termine della struttura principale si ritorna all’elemento chiamante restituendo un valore positivo.

Codice.


Int Function EsitoPulsanti ()
Var
String sNome, ; nome ripulito del pulsante premuto
String sDato; dato temporaneo
; estrae l’etichetta del pulsante premuto
Let sDato = StringSegment (gsEtichette, PIPE, gnTasto)
; rileva il termine con la E Commerciale, lo memorizza e poi lo ripulisce dal carattere speciale
Let sNome = NoAmpersand (StringSegment (sDato, SPACE, StringSegmentIndex (sDato, SPACE, AMPERSAND)))
Let gnVoce = gnValore; allinea il puntatore delle voci alla posizione corrente
If !PulsanteValido (sNome, gnTasto) Then; se la pressione del pulsante non è valida,
Suona (ERRORE1); emette un suono di avviso,
Return FALSE; e restituisce un risultato nullo
EndIf; fine controllo validità
If sNome == AGGIUNGE Then; se si vuole aggiungere una voce,
If !AggiungeVoce () Then; se l’aggiunta non riesce, imposta l’avviso
Let gsAvviso = FormatString (hlpNessuna, EstraeCampo(lstEseguiteVoci, sNome, lstAzioniVoci))
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo esito aggiunta
ElIf sNome == PRECEDENTE Then; se si vuole tornare ad un livello di scelta precedente,
Let gnCampo = gnCampo -1; sposta indietro il puntatore dei campi,
Let gnAggiorna = TRUE; e imposta il valore per l’uscita dal ciclo nella funzione chiamante
ElIf sNome == SUCCESSIVO Then; se invece si vuole andare al livello successivo,
Let gnTasto = -1; simula la pressione della conferma
ElIf sNome == TORNA Then; se si vuole tornare alla schermata iniziale,
Let gnCampo = PRIMA; imposta il valore relativo
Let gnAggiorna = TRUE; e imposta quello per l’uscita dal ciclo nella funzione chiamante
Else; altrimenti, se si vuole agire sulle voci esistenti,
Let sDato = LeggeCampo(gsArchivio, gsSezione, gsChiave); rileva il dato relativo alla voce
If sNome == MODIFICA Then; se si vuole modificare la voce corrente,
If gsCategoria == SCRIPTS ; se si stanno elaborando gli script a gestione personale,
&& gnCampo == SECONDA Then; e ci si trova nella fase di immissione tasti,
Let gnFerma = CATTURA; imposta di attenderne la pressione,
Return FALSE; e restituisce un risultato nullo
Else; altrimenti, in tutti gli altri casi,
; se l’aggiornamento fallisce, imposta l’avviso
If !AggiornaCampo (sNome, gsSezione, gsChiave, sDato) Then
Let gsAvviso = FormatString (hlpNessuna, EstraeCampo(lstEseguiteVoci, sNome, lstAzioniVoci))
Return FALSE; e restituisce un risultato nullo
Else; altrimenti, se la modifica riesce,
Delay (ATTESA); sospende temporaneamente il flusso
If gsCategoria == SCRIPTS Then; se si stanno elaborando gli script a gestione personale,
Let gnCambiati = TRUE; attiva il controllo nell’archivio
EndIf; fine secondo controllo categoria
EndIf; fine controllo esito aggiunta
EndIf; fine primo controllo categoria
ElIf sNome == ELIMINA Then; se invece la voce corrente s’intende cancellarla,
If !EliminaVoce () Then; se la cancellazione non riesce, imposta l’avviso
Let gsAvviso = FormatString (hlpNessuna, EstraeCampo(lstEseguiteVoci, sNome, lstAzioniVoci))
Return FALSE; e restituisce un risultato nullo
EndIf; fine controllo esito cancellazione
ElIf sNome == GIU ; se si vuole spostare la posizione della voce più in basso,
|| sNome == SU Then; oppure, se la si vuole spostare verso l’alto,
If !ScambiaVoci (sDato, sNome) Then; se lo scambio con la voce richiesta non riesce,
Let gsAvviso = FormatString (hlpErroreDato, SALVA); formatta e memorizza l’avviso
Return FALSE; e restituisce un risultato nullo
EndIf; fine controllo scambio tra le voci
ElIf sNome == DUPLICA Then; se si vuole selezionare uno script archiviato di cui inserire una copia,
If !DuplicaDati () Then; se tale inserimento fallisce, formatta il messaggio
Let gsAvviso = FormatString (hlpNessuna, EstraeCampo(lstEseguiteVoci, sNome, lstAzioniVoci))
Return FALSE; e restituisce un risultato nullo
EndIf; fine controllo duplicazione
Else; altrimenti, se l’etichetta non è stata riconosciuta,
Let gsAvviso = FormatString (hlpNoEtichetta, sNome); formatta e memorizza un avviso
Return FALSE; e restituisce un risultato nullo
EndIf; fine controllo azioni di modifica
EndIf; fine controllo etichette
Return TRUE; restituisce l’esito positivo
EndFunction

Esercizio 14.2.15. La funzione NuovoAmbito.

FileScript.

Default.JSS

Nome.

NuovoAmbito

Descrizione.

Controlla, e casomai aggiorna o imposta, l’ambito su cui si è usciti dalla schermata di scelta.

Ritorni.

Di tipo Int. TRUE, per un ambito di funzionamento degli script correttamente aggiornato; FALSE; per nessun aggiornamento.

Fasi.
  1. Una prima struttura di controllo verifica che l’ambito da aggiornare non sia uguale a quello già memorizzato; se così è, il flusso s’interrompe restituendo un risultato nullo.
  2. Dopo aver rilevato il record corrente, una seconda struttura inizia col controllare che un record sia presente; se così è, dapprima lo si aggiorna con il nuovo ambito, poi si tenta di trascriverlo nell’archivio; se la scrittura riesce, si imposta un avviso e viene restituito l’esito positivo.
  3. Se un record non esiste, oppure se la scrittura non riesce, si imposta un messaggio d’errore e viene invece restituito un risultato nullo.
Note.
  1. Questa funzione agisce dopo aver selezionato o modificato gli ambiti, nella sola schermata che abbiamo anticipato essere l’ultima nella procedura di elaborazione degli script a gestione personale.

Codice.


Int Function NuovoAmbito ()
Var
String sDato, ; dato temporaneo
String sRecord; elenco di dati
Let sDato = ChiaveCorrente (gnValore); estrae l’ambito selezionato all’uscita
If sDato == gsAmbito Then; se quello estratto è uguale all’ultimo registrato,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo congruenza ambiti
Let sRecord = LeggeRecord (gsArchivio, gsSezione, gsChiave); rileva l’intero record di dati
If sRecord Then; se i dati sono stati rilevati,
Let sRecord = CambiaCampo (sRecord, sDato, gnCampo); aggiunge o aggiorna l’ambito rilevato
If ScriveRecord (gsArchivio, gsSezione, gsChiave, sRecord) Then; se la scrittura riesce,
Let gsAvviso = hlpOkAmbito; imposta un avviso sull’esito,
Return TRUE; e restituisce l’esito positivo
EndIf; fine controllo scrittura
EndIf; fine controllo record
; se il flusso non è stato interrotto, imposta un messaggio d’errore
Let gsAvviso = FormatString (hlpErroreAmbito, sDato)
Return FALSE; e restituisce un risultato nullo
EndFunction

Esercizio 14.2.16. La funzione ScelteProcedura.

FileScript.

Default.JSS

Nome.

ScelteProcedura

Descrizione.

Analizza le possibili scelte attive nella finestra di dialogo.

Ritorni.

Di tipo Int. TRUE, se le scelte confermano il flusso; FALSE, nel caso si attivi l’attesa dell’immissione dei nuovi tasti di attivazione negli script.

Novità.
  1. Le nostre funzioni
    EsitoPulsanti ()
    e
    NuovoAmbito ().
Fasi.
  1. Una prima struttura di controllo intercetta il flusso nel caso in cui si stia uscendo dalla schermata iniziale, eseguendo le impostazioni relative.
  2. La seconda struttura interviene quando è stato premuto un tasto opzionale; se così è, tramite la nostra funzione
    EsitoPulsanti ()
    , si verifica poi se il controllo sui pulsanti abbia restituito un risultato nullo e, in tal caso, se si sia attivata l’attesa dei tasti di attivazione; se tutte queste condizioni sono rispettate, viene avviata la nostra funzione di cattura tasti.
  3. La terza struttura si occupa invece di intercettare la pressione del tasto Invio, quando non si sia nella schermata iniziale e non sia ancora stata chiesta l’uscita dalla procedura; se così è, sono effettuate due serie di impostazioni, la prima valida se ci si trova nell’ultimo campo della procedura, ed in tal caso chiamando anche la nostra funzione
    NuovoAmbito ()
    , mentre l’altra entra in azione in tutti gli altri campi dal secondo al quarto.
  4. Se si esce regolarmente dall’ultima struttura, viene restituito alla funzione chiamante un valore positivo.
Note.
  1. Questa funzione prevede vari livelli delle strutture di controllo, annidati tra di essi; tale conformazione non può però essere semplificata, in quanto è necessario che il flusso, una volta che si presentino determinate condizioni, sia comunque intercettato, a prescindere dal fatto che poi gli ulteriori livelli di controllo risultino positivi, andando così ancora più in profondità nella struttura.

Codice.


Int Function ScelteProcedura ()
If gnCampo == PRIMA Then; se si sta uscendo dalla prima schermata,
ScriveNumerico (gsArchivio, gsSezione, ZERO, gnValore); annota l’ultima voce selezionata,
Let gsChiave = ChiaveCorrente (gnValore); ne estrae la chiave corrispondente,
Let gsAttiva = LeggeCampo (gsArchivio, gsSezione, gsChiave); ed imposta la voce corrente
EndIf; fine controllo campo
If gnTasto > FALSE Then; se è stato premuto uno dei pulsanti opzionali,
If !EsitoPulsanti () Then; se le azioni sui pulsanti hanno dato esito negativo,
If gnFerma ==CATTURA Then; se si è indicato di specificare i tasti di attivazione,
CatturaDato (); chiama l’apposita funzione,
Let gnFerma = FALSE; annulla il valore per il ritorno alla schermata di scelta,
Return FALSE; e restituisce un risultato nullo
EndIf; fine controllo cattura tasti
EndIf; fine controllo esito elaborazione
ElIf gnCampo == PRIMA ; se invece si è premuta la conferma, provenendo dalla prima schermata,
&& gnTasto != -2 Then; ed il tasto non è stato settato per il cambio campo,
Let gnUscita = TRUE; ne segna la conclusione
EndIf; fine controllo tasti
If gnTasto < FALSE ; se si è premuta la conferma, dalla seconda schermata in poi,
&& !gnUscita Then; e non è stata ancora determinata l’uscita da entrambi i cicli,
If gnCampo == gnMaxCampi Then; se il campo corrente coincide con il massimo possibile,
If gsCategoria == SCRIPTS ; se si stanno elaborando gli script a gestione personale,
&& NuovoAmbito () Then; e l’ambito è stato impostato o aggiornato,
Let gnCambiati = TRUE; attiva il controllo nell’archivio
EndIf; fine controllo categoria
Let gnCampo = PRIMA; torna alla schermata iniziale,
Let gnAggiorna = TRUE; e imposta il valore per consentire l’uscita solo dal primo ciclo
Else; altrimenti, se si stanno elaborando più campi,
Let gnCampo = gnCampo + 1; porta avanti il numero dei campi
Let gnAggiorna = TRUE; e consente l’uscita dal primo ciclo
EndIf; fine controllo tipo conclusione
EndIf; fine controllo tasti premuti
Return TRUE; restituisce l’esito positivo
EndFunction

***

La gestione dell’archivio centrale.

Questo breve blocco è composto da una sola funzione, la quale come detto viene chiamata direttamente dall’elemento principale del sistema. Così come in molti altri casi, la funzione che segue faceva parte del codice iniziale, a cui è stata sottratta per semplificarne la comprensione.

Il suo compito è di gestire sia il controllo del numero di dati inseriti per un record, sia la registrazione degli script nell’archivio personale, posto nella cartella con le impostazioni per l’Utente.

Esercizio 14.3.1. La funzione AggiornaArchivio.

FileScript.

Default.JSS

Nome.

AggiornaArchivio

Descrizione.

Controlla, e casomai aggiunge, i dati dei nuovi script nell’archivio personale, consentendo di sovrascrivere un’eventuale registrazione già presente che avesse in comune almeno il nome dello script.

Ritorni.

Di tipo Void. Nessuno.

Fasi.
  1. Una prima struttura di controllo verifica se i campi del record corrente siano nel numero esatto; se così non è, il flusso viene interrotto.
  2. Dopo aver rilevato i dati necessari, una seconda struttura controlla se nell’archivio personale esistano già degli script con il nome di quello appena creato; se così è, viene proposta la conferma all’eventuale sovrascrittura dei dati registrati; se non si conferma la sovrascrittura, il flusso s’interrompe.
  3. Se invece il flusso prosegue, viene rimosso il primo campo del record originale, quello che avrebbe il nome dello script come chiave, e si aggiornano i dati nell’archivio; sulla base dell’esito della scrittura, viene impostato un avviso.

Codice.


Void Function AggiornaArchivio ()
Var
String sRecord, ; dati del nuovo script
String sNome, ; nome dello script
String sDati, ; dati dell’eventuale script archiviato
String sTitolo; titolo per la finestra di dialogo
If !NumeroDati (gsChiave, sRecord) Then; se i dati registrati non sono completi,
Return; interrompe il flusso
EndIf; fine controllo numero dati
Let gnCambiati = FALSE; annulla il valore
Let sNome = StringSegment (sRecord, PIPE, PRIMA); estrae il nome dal primo elemento del record
Let sDati = LeggeDato (PERSONALE, gsSezione, sNome); rileva l’eventuale presenza dello script
If sDati Then; se nell’archivio sono già presenti dei dati con lo stesso nome di script,
Let sTitolo = FormatString (ttlScriptPresente, sNome); formatta il titolo per la sovrascrittura
If !ChiedeConferma (sTitolo, msgSovrascrittura, FALSE, SECONDA) Then; se la conferma non c’è,
Return; interrompe il flusso
EndIf; fine controllo sovrascrittura
EndIf; fine controllo presenza dati
Let sRecord = CambiaCampo (sRecord, NULLO, PRIMA); rimuove il primo campo del record
If ScriveRecord (PS_FILE, gsSezione, sNome, sRecord) Then; se la scrittura riesce,
Let gsAvviso = hlpScritturaOk_corto; imposta l’avviso
Else; altrimenti, se i dati non sono stati registrati,
Let gsAvviso = hlpNoScrittura_corto; segnala l’errore
EndIf; fine controllo scrittura
EndFunction

***

Le azioni di chiusura.

Un altro piccolo passo, ma ora possiamo dire davvero di essere giunti alla fine degli elementi preparatori. Anche in questo caso, come nel precedente, si tratta di un pezzo che in origine apparteneva alla procedura generale, ma che in questa forma risulta sicuramente più leggibile.

Il suo compito, come si evince dal titolo, è quello di gestire le azioni compiute al termine dell’elaborazione, sulla base del tipo di procedura trattata.

Esercizio 14.4.1. La funzione FineElaborazione.

FileScript.

Default.JSS

Nome.

FineElaborazione

Descrizione.

Esegue le azioni ed i controlli per la conclusione della procedura guidata, chiamando le funzioni di gestione connesse alle procedure elaborate.

Ritorni.

Di tipo Void. Nessuno.

Note.
  1. La funzione è composta principalmente da un’unica struttura di controllo che, sulla base della categoria della procedura elaborata, indirizza per le relative vie dove sono chiamate le funzioni collegate.
  2. Nel caso degli script a gestione personale, nella terza via della struttura, dopo la chiamata della relativa funzione, è eseguito comunque l’eventuale aggiornamento dei tasti di attivazione eventualmente inseriti o aggiornati.
  3. In ogni caso, usciti dalla struttura principale, sono azzerati valori e dati delle variabili globali usate dalla procedura.

Codice.


Void Function FineElaborazione ()
Var String sTasti; combinazione tasti per attivare lo script
SpeechOn (TRUE); riattiva la sintesi
Delay (ATTESA); sospende temporaneamente il flusso
If gsCategoria == ELEMENTO Then; se si stanno elaborando gli elementi da ricercare,
; segnala l’avvio di una ricerca direttamente dalla procedura,
SayMessage (OT_ERROR, msgAvvioRicerca)
Let gsOggetto = SUCCESSIVO; reimposta l’oggetto dell’azione,
CallFunctionByName (gsChiama + DATO, gsSuffisso); e chiama la funzione
ElIf gsCategoria == MACRO Then; se sono invece da inserire le macro testuali,
; chiama la funzione passando, tra i dati, quello numerico come conversione della voce d’uscita
CallFunctionByName (gsChiama + DATO, gsSuffisso, IntToString (gnValore), TRUE)
ElIf gsCategoria == SCRIPTS Then; se invece si deve attivare uno script a gestione personale,
; chiama la funzione, ponendo il nome del file corrente come suffisso e la chiave come valore
CallFunctionByName (gsChiama + DATO, gsSuffisso, gsOggetto, gsChiave)
AggiornaTasti (); e trascrive le eventuali assegnazioni tasti modificate
EndIf; fine controllo categoria
ResettaCampi (); ripulisce la memoria dalle impostazioni
EndFunction

***

L’elemento principale della procedura.

Dopo tanti elementi accessori, siamo finalmente giunti al centro del nostro lavoro, la funzione che viene chiamata per gestire le procedure guidate. Oltre allo strumento principale, in questo blocco troveremo anche gli script tramite i quali iniziare a collaudarle, completando in particolare le funzionalità della ricerca di stringhe predeterminate.

Innanzi tutto va detto che sinora, lungo questo capitolo e nei precedenti, abbiamo cercato di cogliere ogni possibile spunto per iniziare a parlare di come sia strutturata la procedura. Giunti ora a realizzare materialmente la funzione che la gestisce, invece, possiamo entrare nel dettaglio di come sia fatto il suo codice.

I due cicli principali.

La funzione che andremo tra poco a realizzare, in estrema sintesi, si può ridurre a soli due cicli
"While-EndWhile"
, l’uno dentro all’altro:

  1. Un ciclo principale, tramite il quale si entra nella procedura e si impostano i dati per la singola schermata, come il titolo della finestra di dialogo e i pulsanti attivi.
  2. Un ciclo secondario, dove si aggiornano i dati per la singola voce visualizzata, e viene eseguita l’istruzione che propone la finestra di scelta, che ricordiamo essere
    DlgSelectItemInList ().

Ogni volta che il flusso arriva all’ingresso di entrambi i cicli, quindi all’istruzione
"While"
, viene portato a zero un valore il quale, finché rimarrà tale, farà continuare il ciclo. Per far uscire il flusso dai cicli, quindi, sarà sufficiente rendere positivi questi valori di controllo.

Nel dettaglio, se si imposta come positivo uno solo dei due valori, uscendo così dal ciclo secondario, di norma si cambierà solo la schermata, aggiornandone i relativi dati. Se invece saranno resi positivi entrambi i valori, si uscirà sia dal ciclo secondario, sia da quello principale, ponendo così fine alla procedura.

In altre parole, di fronte alla finestra di dialogo proposta da
DlgSelectItemInList ()
, la pressione dei vari pulsanti potrà creare tre situazioni principali:

  1. Se saranno premuti i pulsanti per agire sulle voci selezionate , ad esempio per modificarle, aggiungerne di nuove o cancellarle, non sarà cambiato nessuno dei due valori di controllo dei cicli; in questo modo, usciti dalla finestra di dialogo, il flusso tornerà all’inizio del ciclo secondario, limitandosi a modificare le impostazioni per la voce attiva, ed a riproporre la finestra di dialogo aggiornata.
  2. Nelle procedure a più campi, come quella per gli script a gestione personale, se saranno premuti i tasti per andare alla schermata successiva o precedente, o ancora tornare a quella principale, sarà reso positivo il solo valore che controlla il ciclo secondario; così, il flusso potrà uscire da quest’ultimo per tornare all’inizio del ciclo principale, dove saranno impostati i dati relativi alla nuova schermata, quindi si rientrerà nel secondo ciclo dove sarà riproposta la nuova versione della finestra di dialogo.
  3. Se infine si premeranno i tasti Invio o Escape, e si confermeranno tali scelte, sarà invece sempre modificato il primo valore di controllo, causando quindi almeno il cambio della schermata; quando, in tutti i tipi di procedura, i citati tasti saranno premuti dalla schermata principale, sarà reso positivo anche il secondo valore, così da causare la fine dell’elaborazione.

Questa breve introduzione teorica, lungi dal voler chiarire il funzionamento del codice che segue, serve però a fornire almeno le chiavi di lettura per coloro che non avessero mai avuto modo di confrontarsi con questo tipo di elementi.

Come sempre, sarà il collaudo a chiarire, più e meglio di molte parole, il funzionamento del tutto, e la buona notizia è che dovrete aspettare per questo ancora davvero molto poco.

Esercizio 14.5.2. La funzione ElaboraDato.

FileScript.

Default.JSS

Nome.

ElaboraDato

Descrizione.

Propone una procedura guidata, sulla base dei dati registrati per la categoria memorizzata.

Ritorni.

Di tipo Void. Nessuno.

Parametri.
  1. sSuffisso. L’estensione, o il nome del file corrente, cui si riferiscono i dati registrati. Di tipo String.
  2. iAiuto. Se valorizzato con True, attiva l’omonima fase. Di tipo Int.
Novità.
  1. Le nostre funzioni
    InizializzaProcedura (),
    VociCampo (),
    CreaVoci (),
    ControllaProgrammato (),
    UscitaProcedura (),
    ScelteProcedura (),
    AggiornaArchivio ()
    e
    FineElaborazione ().
Fasi.
  1. Una prima semplice struttura di controllo verifica se esistono i dati per configurare la procedura; se così non è, saranno creati; se però in essi vi è un qualche errore, e non si conferma il loro aggiornamento, si chiama la nostra funzione d’uscita ed il flusso viene interrotto.
  2. Una seconda struttura controlla che i dati per il singolo campo della procedura analizzata siano validi, tramite la nostra funzione
    InizializzaProcedura ()
    ; se si verifica un errore, s’interrompe il flusso.
  3. Dopo aver azzerato il relativo valore, si entra nel ciclo principale, dove si controlla dapprima se siano validi, stavolta, i dati per la singola schermata; anche in questo caso, se è stata riscontrata qualche irregolarità, il flusso viene interrotto.
  4. Si entra poi nel ciclo secondario, dopo averne azzerato il valore d’ingresso; qui, si controlla dapprima che vi siano delle voci da visualizzare, tramite la nostra funzione
    VociCampo ()
    , altrimenti viene data la possibilità di inserirle direttamente; qualora si verificasse un qualche errore, o si rinunciasse all’inserimento, si fermerebbe il flusso.
  5. Un’ulteriore struttura si occupa di presentare la finestra di scelta, che sarà preceduta dal richiamo delle nostre funzioni
    CreaVoci ()
    e
    ControllaProgrammato ()
    ,a meno che non si sia impostato un valore per il suo salto; in quest’ultimo caso, ci si limita ad annullare tale valore, ed impostarne uno per simulare la pressione del tasto Invio alla finestra di dialogo.
  6. La struttura successiva gestisce le scelte operate, o soltanto simulate, nella finestra di dialogo; nella prima via della struttura si controlla la pressione del tasto Escape, tramite la nostra funzione
    UscitaProcedura ()
    , la quale in realtà abbandona l’elaborazione solo se ci si trova nella schermata principale, altrimenti si tornerà a quest’ultima; nella seconda via della struttura, invece, la nostra funzione
    ScelteProcedura ()
    gestisce la pressione di tutti gli altri tasti, interrompendo l’elaborazione solo nel caso in cui si sia prima avviata l’attesa dei tasti di attivazione negli script a gestione personale.
  7. In un ulteriore controllo, poi, se risulta che almeno un dato di uno script a gestione personale sia stato modificato, viene chiamata la nostra funzione
    AggiornaArchivio ()
    per registrare tale variazione.
  8. Usciti dal ciclo secondario, l’unica impostazione che si attua è l’azzeramento del valore sull’avvio ritardato della sintesi, i cui messaggi saranno quindi nuovamente pronunciati in modo immediato.
  9. Usciti anche dal ciclo principale, se il valore di controllo dei cicli era stato impostato, tramite la nostra funzione
    FineProcedura ()
    , si determina l’azione che si deve compiere all’uscita dalle fasi di scelta, chiamando una delle funzioni relative alla categoria elaborata.
Note.
  1. Per individuare più facilmente i cicli
    "While-EndWhile"
    , si è lasciata una riga vuota prima del’istruzione di azzeramento del valore di controllo, la quale precede il comando iniziale del ciclo, e dopo il suo comando di chiusura.
  2. Nonostante la lunghezza della funzione, e soprattutto la sua complessità, si è riusciti ad utilizzare solo un paio di variabili locali, grazie al sistematico uso di quelle globali.

Codice.


Void Function ElaboraDato (string sSuffisso, int iAiuto)
Var
String sVoci, ; elenco effettivo proposto a video
String sTitolo; titolo composto per la finestra di dialogo principale
If !ArchivioDati () Then; se il file di configurazione è mancante o incompleto,
PronunciaUscita (); esegue delle operazioni di chiusura, leggendo la riga corrente,
Return; e interrompe il flusso
EndIf; fine controllo file configurazione
If !InizializzaProcedura (sSuffisso) Then; se i settaggi sono falliti,
Return; interrompe il flusso
EndIf; fine controllo iniziale
Let gnUscita = FALSE; azzera il valore per consentire l’ingresso nel ciclo
While !gnUscita; continua finché il valore rimane a zero
If !DatiSchermata () Then; se i dati non sono stati memorizzati,
Return; interrompe il flusso
EndIf; fine controllo presenza dati
Let gnAggiorna = FALSE; azzera il valore per consentire l’ingresso nel ciclo
While !gnAggiorna && !gnUscita; continua finché entrambi i valori rimangono azzerati
If !VociCampo () Then; se il caricamento delle voci non si è concluso regolarmente,
Return; interrompe il flusso
EndIf; fine controllo voci e campo procedura
Let sVoci = CreaVoci (); genera l’elenco da proporre a video
If sVoci ; se l’elenco delle voci non è vuoto,
&& (gnTipo <= SECONDA ; e si è nei primi due tipi di procedura,
|| !gnSalta) Then; oppure, non è stato indicato il salto della scelta voce,
Let gsVoce = StringSegment (sVoci, BELL, gnVoce); memorizza la voce corrente
ControllaProgrammato (); verifica se spegnere e riattivare in modo programmato la sintesi
Let sTitolo = AggiungePunto (TroncaTesto (gsTitolo)); prende la prima parte del titolo globale
; propone la finestra di dialogo principale
Let gnValore = DlgSelectItemInList (sVoci, sTitolo, FALSE, gnVoce, gsEtichette, gnTasto)
Let gnStato = ControllaSintesi (FALSE, TRUE); spegne la sintesi, con l’azzeramento del buffer
Else; altrimenti, se si è nella elaborazione a più campi, e si è indicato di saltare la scelta,
If !gnValore Then; se si è al primo passaggio, ed il valore è a zero,
Let gnValore = PRIMA; simula la selezione della prima voce
EndIf; fine controllo voce attiva
Let gnTasto = -2; imposta un valore negativo, per consentire il passaggio al livello successivo
Let gnSalta = FALSE; annulla l’indicazione di salto
EndIf; fine controllo tipo procedura
If !gnValore Then; se si è abbandonata la procedura,
If UscitaProcedura ()Then; se la conclusione della procedura è stata confermata,
Return; interrompe il flusso
EndIf; fine controllo conclusione
Else; altrimenti, in tutti gli altri casi,
If !ScelteProcedura () Then; se si è scelto di immettere i tasti di attivazione degli script,
Return; interrompe il flusso
EndIf; fine controllo scelte possibili
EndIf; fine controllo scelta
EndWhile; fine ciclo schermata
Let gnStato = FALSE; azzera il valore, per la riattivazione incondizionata della sintesi
If gsCategoria == SCRIPTS ; se si stanno elaborando gli script a gestione personale,
&&gnCampo == PRIMA ; e ci si trova nella prima schermata,
&& gnCambiati Then; e se, infine, uno script è stato appena rinnovato, almeno in un suo campo,
AggiornaArchivio (); controlla la presenza dei dati per lo script nell’archivio personale
EndIf; fine controllo nuovi dati negli script
EndWhile; fine ciclo elaborazione campi
If gnUscita Then; se la procedura si è chiusa con una conferma delle impostazioni,
FineElaborazione (); esegue le azioni conclusive della procedura
EndIf; fine controllo uscita
EndFunction

Collaudo.

  1. Se dopo la compilazione è tutto a posto, portate ancora un po’ di pazienza: solo qualche altro script, e poi finalmente proveremo a far funzionare la nostra procedura.

Esercizio 14.5.3. Lo script TitoloFinestra.

FileScript.

Default.JSS

Nome.

TitoloFinestra

Sommario.

Gestisce la lettura del titolo della finestra corrente.

Descrizione.

Nelle finestre di dialogo di Jaws, se la variabile globale gsTitolo non è vuota, ne viene pronunciato il suo contenuto, o solo la sua prima parte qualora vi sia registrato un carattere Pipe, Ascii 124; altrimenti, in tutti gli altri casi, viene eseguito lo script nativo.

TastiAttivazione.

Insert+T

Novità.
  1. Lo script nativo
    SayWindowTitle
    , (LeggiTitoloFinestra), il quale pronuncia il titolo della finestra corrente.
Note.
  1. Questo script svolge un doppio compito: se il controllo sulle condizioni poste è positivo, viene pronunciato un contenuto memorizzato in una nostra variabile globale, altrimenti sarà eseguito lo script di Jaws
    SayWindowTitle ()
    , quello che in origine è abbinato alla combinazione
    Insert+T.
  2. Per questo motivo, durante la creazione dello script, quando noi daremo la citata combinazione come tasti per attivarlo, alla richiesta di conferma alla sovrascrittura dovremmo quindi cliccare su
    "Ok"
    , così da togliere allo script nativo la possibilità di intervenire con questa combinazione tasti.

Codice.


Script TitoloFinestra ()
If InHJDialog () ; se si è in una finestra di dialogo di Jaws,
&& gsTitolo Then; e un titolo per tale finestra è stato impostato,
; pronuncia la prima parte del titolo memorizzato, aggiungendovi un carattere Punto
SayMessage (OT_HELP, AggiungePunto (TroncaTesto (gsTitolo)))
Else; altrimenti, in tutti gli altri casi,
PerformScript SayWindowTitle(); attiva lo script nativo
EndIf; fine controllo finestra
EndScript

Collaudo.

  1. Se la compilazione va a buon fine, come collaudo provate a premere la combinazione
    Insert+T
    , in una qualsiasi finestra , ma per il momento vi dovrebbero essere recitate le normali informazioni fornite in questi casi. Quelle da noi impostate in una variabile globale, invece, saranno pronunciate in un’altra situazione, un paio di elementi più avanti, mentre staremo testando la nostra procedura di elaborazione guidata.

Esercizio 14.5.4. Lo script ElaboraElementoRicerca.

FileScript.

Default.JSS

Nome.

ElaboraElementoRicerca

Sommario.

Avvia la procedura di elaborazione degli elementi di ricerca.

Descrizione.

Chiama la funzione che gestisce le procedure guidate, la quale consente in questo caso di elaborare gli elementi di ricerca disponibili per i documenti con l’estensione di quello corrente.

TastiAttivazione.

Windows+0

Note.
  1. Non vi è nessuna novità in questo script, perché dal suo interno chiameremo la solita funzione di gestione, la quale ricaverà come sempre le necessarie istruzioni dal nome stesso dello script; è invece importante evidenziare l’utilizzo della combinazione suggerita, soprattutto il fatto di aver premuto il tasto
    "Windows"
    assieme al numero 0, perché proprio questo suffisso numerico sarà la costante che riguarderà anche gli altri tasti scelti per avviare le procedure guidate.

Codice.


Script ElaboraElementoRicerca ()
GestisceDato (); chiama l’apposita funzione
EndScript

Il collaudo della procedura per la ricerca di stringhe predeterminate.

Eccoci dunque arrivati al momento tanto atteso: se avete compilato correttamente lo script, seguite questi passi:

  1. Restate pure nell’Editor di Jaws, purché abbiate aperto un file script qualsiasi, con estensione
    ".JSS".
  2. Premete i tasti di attivazione dello script appena compilato,
    Windows+0
    , e la procedura dovrebbe visualizzare una finestra di dialogo con il seguente contenuto:
  3. 
    Nessun Elemento per l’estensione .jss
    Immetterlo ora?
    

  4. Il cursore sarà posizionato sul tasto
    "Ok"
    , e quindi premendo Invio confermerete la nuova immissione. Si entrerà così in un campo dove poter scrivere, e la finestra di dialogo avrà stavolta questi messaggi:
  5. 
    Aggiungere l’Elemento in posizione 1.
    Invio conferma, Esc annulla.
    

  6. Inserite il termine
    "Script"
    , senza virgolette e lasciando dopo uno spazio, quindi premete Invio. Si aprirà così la schermata di scelta della nostra procedura guidata, la quale avrà il seguente titolo:
  7. 
    Selezionare l’elemento da elaborare, e Cliccare sull’azione da compiere
    

  8. Il cursore sarà posizionato sulla prima voce dell’elenco, che avrà il seguente testo:
  9. 
    1. Script
    

Sfruttiamo l’Aiuto in linea.

Adesso, pur avendo una sola voce nell’elenco, abbiamo una serie di opzioni possibili. Senza spendere altre parole, approfittiamo del molto lavoro fin qui fatto, leggendo le informazioni che ci fornisce l’Aiuto in linea, quello che abbiamo aggiornato nell’undicesimo capitolo.

Seguite allora questi passi:

  1. Premete i tasti di attivazione dell’Aiuto in linea,
    Windows+H
    . Sarà visualizzata una finestra informativa, il cui contenuto sarà il seguente:
  2. 
    Informazioni sulla finestra di dialogo:
    Selezionare l’elemento da elaborare, e Cliccare sull’azione da compiere.
    Pulsanti disponibili:
    Modifica Elemento. Alt+M.
    Aggiunge Elemento. Alt+I.
    Elimina Elemento. Alt+L.
    Sposta giù. Alt+G.
    Sposta su. Alt+S.
    Avvia ricerca. Ok, oppure Alt+O.
    Annulla. Esc, oppure Alt+A.
    Visualizza questa schermata d’Aiuto. Windows+H.
    Premere Escape per chiudere questo messaggio.
    

  3. Essendosi proposta una schermata del Visualizzatore virtuale, possiamo già muoverci tra le informazioni con i tasti freccia. Come potete esaminare, dall’alto in basso, sono elencati tutti i tasti che hanno una qualche funzione dentro alla finestra di scelta della procedura. Così come l’Aiuto in linea sugli script attivi, queste righe di informazione sono anche dei link, che si possono cliccare direttamente con Invio per eseguirne la funzione descritta.
  4. Approfittiamo di questa opzione, e cerchiamo nella schermata d’aiuto la riga che contiene
    "Aggiunge Elemento. Alt+I."
    , e premiamo Invio.
  5. Si tornerà nel campo d’editazione precedente, dove saremo chiamati ad inserire la voce contrassegnata dal numero 2. qui dunque inseriamo
    "& Function"
    , anche in questo caso senza virgolette e rispettando gli spazi lasciati prima e dopo la parola chiave delle funzioni. Fondamentale sarà porre il carattere E Commerciale prima del termine, ma separato da uno spazio, che sta ad indicare che questa stringa che noi abbiamo immesso dovrà essere cercata all’interno della riga, non dal suo inizio. Una volta certi di aver inserito il testo corretto, premete Invio per confermare l’inserimento.
  6. Aggiungete ancora una voce, premendo
    Alt+I
    . Quando si aprirà il campo d’editazione, inserite stavolta la stessa parola chiave di prima, ma senza né la E Commerciale, né lo spazio iniziale, conservando però il secondo spazio, scrivendo
    "Function"
    , quindi premete Invio.
  7. Una volta tornati alla finestra di scelta, e posizionati sulla terza voce appena inserita, premete Invio, avviando così la ricerca che, se tutto va bene, dovrebbe concludersi sull’intestazione del primo elemento di codice verso il basso.
  8. In realtà, essendo noi dentro all’Editor di Jaws, ci siamo mossi sfruttando ancora la funzione nativa per lo spostamento all’elemento di codice successivo,
    "F2"
    , esattamente come avremmo fatto anche con la precedente versione dello script
    MuoveElementoSuccessivo ()
    , che se ricordate si attiva con
    Windows+FrecciaGiù
    . se volete quindi sfruttare quanto fatto per utilizzare la stessa combinazione anche in altri applicativi, dobbiamo aggiornare in modo definitivo il citato script, e l’altro suo contrario.

Esercizio 14.5.7. La versione definitiva di MuoveElementoSuccessivo ().

FileScript.

Default.JSS

Nome.

MuoveElementoSuccessivo

Sommario.

Si muove all’elemento successivo.

Descrizione.

Nella finestra principale dell’Editor di Script, esegue i comandi nativi per spostarsi all’elemento di codice successivo; in tutte le altre finestre di editazione, muove al successivo elemento di ricerca tra quelli registrati per l’estensione del documento corrente

Note.
  1. La modifica alla versione precedente di questo script, ed a quella che segue, si attua svuotando tutto il contenuto tra l’intestazione ed il comando di chiusura, ponendo il solo richiamo alla nostra funzione di gestione; in caso di dubbi, esaminare la forma indicata di seguito, o nello spazio di codice dello script che segue immediatamente questo.

Codice.


Script MuoveElementoSuccessivo ()
GestisceDato (); chiama l’apposita funzione.
EndScript

Collaudo.

  1. Dopo aver compilato correttamente, poiché le regole per l’attuale script valgono anche per il successivo, attendete quindi di modificare anche il prossimo codice, prima di effettuare il collaudo di entrambi.

Esercizio 14.5.8. La versione definitiva di MuoveElementoPrecedente ().

FileScript.

Default.JSS

Nome.

MuoveElementoPrecedente

Sommario.

Si muove all’elemento Precedente.

Descrizione.

Nella finestra principale dell’Editor di Script, esegue i comandi nativi per spostarsi all’elemento di codice Precedente; in tutte le altre finestre di editazione, muove al Precedente elemento di ricerca tra quelli registrati per l’estensione del documento corrente

Codice.


Script MuoveElementoPrecedente ()
GestisceDato (); chiama l’apposita funzione.
EndScript

Collaudo.

  1. Se per la compilazione non ci sono problemi, semplicemente, da dentro l’Editor di Script premete i tasti
    Windows+FrecciaGiù ()
    , e
    Windows+FrecciaSu ()
    ; dovreste passare, nell’ordine, all’elemento di codice, script o funzione che sia, successivo o precedente.
  2. Se vi sembra che nulla negli effetti degli script sia cambiato, avete proprio ragione: di diverso da prima, quando avevamo l’altra versione che chiamava direttamente in causa i comandi nativi, c’è solo che ora tali comandi sono attivati dalla nostra funzione
    MuoveDato ()
    , a sua volta chiamata dalla nostra
    GestisceDato ()
    , che abbiamo inserito nel corpo degli script appena aggiornati.
  3. Per poter esaminare qualcosa di nuovo, quindi, proseguite con il prossimo titolo.

Le stringhe memorizzate per estensione.

I tre elementi di ricerca che abbiamo memorizzato da dentro l’Editor di Jaws, non sono stati registrati per questo particolare applicativo, bensì per tutti i documenti che abbiano un’estensione
".JSS"
. Questo fa sì che, appunto, qualsiasi file con tale estensione, essendo un semplice file di testo, può essere ad esempio aperto con il Blocco Note e, grazie alla nostra funzione, possiamo replicare anche in quell’ambiente il passaggio all’elemento di codice successivo o precedente usando, ovviamente, gli stessi comandi usati dentro all’Editor.

Per fare una prova pratica di quanto affermato, seguite questi passi.

  1. Chiudete l’Editor di Script, ed andate nella cartella in cui sono presenti i file con le impostazioni dell’Utente, servendovi degli appositi collegamenti tra le Utilities di Jaws.
  2. Qui selezionate un qualsiasi file script, quelli con estensione
    ".JSS"
    , purché non sia quello predefinito
    Default.JSS
    , e soprattutto che abbia un certo numero di script e funzioni, in modo da poter rapidamente passare dall’uno all’altro. L’importante è che, così come avevamo fatto nell’undicesimo capitolo, lo apriate non cliccandoci sopra, bensì selezionando il comando
    "Apri con..."
    e, tra le varie opzioni proposte, clicchiate sul Blocco Note o su Wordpad, o comunque un qualsiasi altro editor testuale in cui abbiate registrato una finestra di Editing.
  3. Una volta aperto il file script con tale applicativo, che non deve quindi essere l’Editor di Jaws, potrete agire sulle combinazioni tasti per andare al successivo e precedente elemento di ricerca,
    Windows+FrecciaGiù
    e
    Windows+FrecciaSu.
  4. Se tali elementi non sono nelle vicinanze, dopo circa tre secondi sentirete un avviso che la ricerca è in corso, avvertendovi di premere il tasto Escape per interromperla. Quando uno script o una funzione è rilevata dalla procedura, la ricerca si arresta emettendo un segnale acustico, e leggendo dalla parola chiave individuata sino a fine riga. Se invece si arriva ad uno degli estremi del documento, senza più incontrare alcun elemento di codice, sentirete l’avviso di essere giunti alla fine o all’inizio del documento corrente.

La ricerca dei singoli elementi.

Forse la ricerca di stringhe predeterminate per l’estensione
".JSS"
può non apparire molto utile, in quanto i file script sono aperti quasi sempre con l’Editor di Jaws, che prevede già questo modo rapido di spostarsi tra gli elementi di codice. Se però noi volessimo raggiungere rapidamente non l’intestazione, bensì i comandi di chiusura di script e funzioni, oppure, l’inizio o la fine di un ciclo
"While-EndWhile"
, o l’inizio o la fine di un ciclo
"For-EndFor"
, ecco che la nostra procedura può rivelarsi indispensabile, anche nei documenti con estensione
"JSS".

Per capire come fare, tuttavia, dovremmo dotarci di due serie di script, come quelle create nell’undicesimo capitolo. A tale scopo, se ricordate, ci basterà realizzare solo il primo esemplare, e poi lasciando che Jaws rielabori per noi gli script rimanenti.

Esercizio 14.5.11. Lo script MuoveSingoloSuccessivo1.

FileScript.

Default.JSS

Nome.

MuoveSingoloSuccessivo1

Sommario.

Cerca il prossimo elemento 1.

Descrizione.

Attiva la ricerca del successivo elemento tra quelli registrati per l’estensione del documento corrente, e identificato dal numero 1.

TastiAttivazione.

Windows+1

Note.
  1. Il tasto di attivazione scelto per attivare questo script, così come tutti gli altri che saranno utilizzati per la serie di script che andremo a creare,
    "Windows"
    più una cifra da 1 a 9, nel sistema operativo avrebbero già una loro funzione, che è quella di richiamare l’applicazione presente nell’apposita barra con il numero usato dopo il tasto
    "Windows"
    ; a prescindere da quanto siano utilizzate tali scelte rapide, all’interno della funzione
    MuoveDato ()
    , si è predisposto che, nel caso si prema il tasto
    "Windows"
    assieme ad uno dei tasti numerici da 1 a 9, qualora non vi sia registrato alcun elemento di ricerca per quell’estensione, si attivi comunque la funzione originale del tasto.

Codice.


Script MuoveSingoloSuccessivo1 ()
GestisceDato (); chiama l’apposita funzione.
EndScript

Collaudo.

  1. Dopo aver compilato correttamente, posizionatevi dentro al corpo dello script, e premete
    Shift+Control+Windows+P
    , per attivare lo script
    CreaSerie ().
  2. Nella finestra di dialogo che compare, confermate con Invio la scelta del valore 9 come numero di suffisso dell’ultimo script da creare, quindi confermate ulteriormente la creazione degli script proposta, quindi attendete la conclusione della procedura di generazione degli script.
  3. Per fare una prima prova parziale degli script creati, tornate al primo script della serie,
    MuoveSingoloSuccessivo1 ()
    , e premete la combinazione
    Windows+1
    . Sarete così posizionati sull’intestazione del successivo script, in quanto avrete cercato solo l’elemento di ricerca che avevamo registrato come numero 1, che era appunto la parola chiave
    "Script".
  4. Se volete, premete ancora un paio di volte la stessa combinazione, spostandovi così alle intestazioni degli script successivi. Siccome così facendo non avreste un comportamento diverso da quello che potreste avere premendo la ricerca dell’elemento successivo, provate allora a premere la combinazione
    Windows+2
    , la quale cerca a sua volta l’elemento di ricerca registrato con il numero 2, e quindi la parola chiave
    "Function".
  5. Dato che dovreste essere posizionati in mezzo agli script della serie appena creata, e da lì alla fine dello script non dovrebbe esserci alcuna funzione, la ricerca non dovrebbe avere alcun esito, continuando a scorrere verso il basso sino alla conclusione del file script predefinito.
  6. A questo punto, si potrebbe pensare di trovare un modo per ripetere la singola ricerca anche all’indietro, ma di questo si occuperà la prossima serie di script che andremo ora a realizzare.

Esercizio 14.5.12. Lo script MuoveSingoloPrecedente1.

FileScript.

Default.JSS

Nome.

MuoveSingoloPrecedente1

Sommario.

Cerca il precedente elemento 1.

Descrizione.

Attiva la ricerca del precedente elemento tra quelli registrati per l’estensione del documento corrente, e identificato dal numero 1.

TastiAttivazione.

Shift+Windows+1

Note.
  1. La combinazione scelta per questo script richiama la precedente, in quanto vi aggiunge soltanto il tasto
    "Shift"
    , in modo del tutto analogo a quanto si fa in alcuni funzioni di ripetizione di ricerca, ad esempio, nell’Editor di Script, dove si usa il tasto funzione
    "F3"
    per ripetere una ricerca in avanti, e
    "Shift+F3"
    per ripeterla all’indietro.

Codice.


Script MuoveSingoloPrecedente1 ()
GestisceDato (); chiama l’apposita funzione.
EndScript

Collaudo.

  1. Dopo aver compilato, ripetete le operazioni di prima, posizionandovi dentro al corpo dello script e premendo
    Shift+Control+Windows+P
    . Confermate poi la scelta del valore 9, quindi premete Invio anche alla successiva richiesta, e attendete la conclusione della procedura.
  2. Se non siete in fondo al file script, andatevi, e da lì premete
    Shift+Windows+1
    , ed il cursore dovrebbe fermarsi nell’intestazione dello script
    MuoveSingoloPrecedente9 ()
    . Se volete, provate a premere anche
    Shift+Windows+2
    , e la ricerca dovrebbe iniziare un movimento all’indietro sino alla prima funzione esistente. Poiché la prima dovrebbe essere la nostra
    ElaboraDato ()
    , la ricerca potrebbe protrarsi per più di qualche secondo, ma alla fine si dovrebbe giungere a destinazione.
  3. Per sfruttare al massimo i singoli elementi di ricerca, completiamo la registrazione delle stringhe testuali necessarie, premendo
    Windows+0
    , da dentro l’Editor di Script con aperto il file script predefinito. Nella schermata che si presenta, contenente i tre elementi sinora memorizzati, premete ripetutamente
    Alt+I
    ,inserendo come elementi di ricerca i comandi posti di seguito, e confermando la stringa immessa premendo Invio dopo ciascun termine:
    • While
    • EndWhile
    • For
    • EndFor
    • EndScript
    • EndFunction
  4. Non lasciate spazi né prima, né dopo il termine. Dopo aver immesso queste ulteriori sei stringhe, dovreste così aver completato il numero massimo di elementi disponibili, che abbiamo stabilito essere 9. Se adesso provate ancora una vota a premere
    Alt+I
    , infatti, sarà emesso un segnale acustico di errore, e la sintesi pronuncerà con la voce del cursore Jaws il seguente messaggio:
  5. Alt+I"Raggiunto il limite massimo di voci."

  6. In ogni caso, uscite dalla procedura di elaborazione premendo il tasto Escape. Una volta tornati all’Editor, se non ci siete già, andate all’inizio della funzione
    ElaboraDato ()
    , e premete la combinazione
    Windows+4
    ; dovreste così posizionarvi all’inizio del ciclo
    "While"
    principale, poiché quella che avete premuto è proprio la ricerca rapida di tale parola chiave.
  7. Premete ora la scelta rapida
    Windows+5
    , che corrisponde al comando di chiusura ciclo,
    "EndWhile"
    , e dovreste posizionarvi sulla prima occorrenza di tale termine. Poiché in questa funzione i cicli
    "While"
    erano due, l’uno dentro all’altro, il primo comando di chiusura incontrato corrisponde in realtà a quello relativo al ciclo più interno, quello secondario. Se da lì premete ora il comando per tornare indietro,
    Shift+Windows+4
    , tornerete quindi al comando di inizio ciclo, ma quello secondario, non il precedente, che invece raggiungerete premendo un’altra volta la citata combinazione tasti.

Ridurre il numero degli elementi da ricercare.

Sperimentando la ricerca per singoli elementi, abbiamo così registrato tutte e nove le stringhe possibili per l’estensione
".JSS"
. Se noi torniamo ad aprire un file con tale estensione tramite il Blocco Note, e torniamo invece ad usare i comandi di spostamento agli elementi successivo o precedente,
Windows+FrecciaGiù
o
Windows+FrecciaSu
, il cursore si fermerà al primo elemento trovato, cercando tra gli elementi registrati fino a quello sul quale abbiamo avviato la ricerca, premendo Invio direttamente dall’interno della procedura.

In pratica, se noi ad esempio volessimo limitare la ricerca alle sole tre parole chiave di script o funzioni, allora dovremmo almeno una volta rientrare nella procedura con
Windows+0
, selezionare la terza voce dell’elenco e quindi premere Invio per avviare la ricerca. Da quel momento in poi, tutte le volte che si premeranno i tasti
Windows+FrecciaGiù
o
Windows+FrecciaSu
, la ricerca sarà limitata alle prime tre voci dell’elenco.

Se invece noi volessimo allargare questa ricerca generica anche ai comandi di apertura e chiusura dei cicli
"While"
, dovremmo invece far partire la ricerca cliccando sulla quinta voce dell’elenco, e così via. Una volta impostate, per non cambiare le proprie preferenze, si potranno sempre effettuare delle modifiche al contenuto, al numero ed alla posizione degli elementi di ricerca, purché si abbandoni la fase di elaborazione premendo il tasto Escape.

Elementi di ricerca per tutte le estensioni.

Per i file script, almeno nell’Editor di Jaws, sono già presenti dei comandi nativi per lo spostamento tra elementi di codice, e per questo il nostro sistema è più utile per spostarsi alle singole parole chiave . Tale procedura è invece indispensabile nei documenti di tutte le altre estensioni, per i quali non sono previsti sistemi di ricerca neppure dentro allo stesso Editor di Script.

Per averne la riprova, seguite questi passi:

  1. Aprite con l’Editor di Jaws un qualsiasi file tasti, quelli con estensione
    ".JKM"
    , ad esempio
    Default.JKM.
  2. Avviate la procedura guidata per gli elementi di ricerca, premendo
    Windows+0
    , ed il sistema vi avvertirà che non sono registrati degli elementi per tale estensione.
  3. Cogliete l’occasione per inserire il solo carattere Aperta Quadra, quindi confermate con Invio. Da adesso in poi, premendo i tasti per gli elementi successivo e precedente,
    Windows+FrecciaGiù
    e
    Windows+FrecciaSu
    , vi sposterete alle etichette di sezione presenti nel file, come ad esempio
    "Common Keys"
    , oppure
    "Desktop Keys".
  4. Se voleste fare un’altra prova, aprendo i file Messaggi, quelli con estensione
    ".JSM"
    , ripetete il passaggio al punto 2, e quindi inserite il solo carattere Punto e Virgola,
    ";"
    . In questo modo, usando i soliti tasti di movimento, vi sposterete tra le intestazioni dei messaggi, quelle che hanno appunto tale carattere ad inizio riga.

A margine di quanto appena illustrato, se ricordate, lo spostamento al carattere Punto e Virgola, tramite il nostro sistema, era previsto anche dagli script
MuoveCommentoSuccessivo ()
e
MuoveCommentoPrecedente ()
, che abbiamo realizzato alla fine del dodicesimo capitolo . Di tali script, tuttavia, se ne consiglia l’uso appunto nei soli file con estensione
".JSS"
,dove hanno il compito di spostarsi tra i commenti che occupano tutta una riga, mentre per i file Messaggi si consiglia di usare il sistema appena illustrato.

Questo, infatti, porta a servirsi dei tasti
Windows+FrecciaGiù
e
"Windows+FrecciaSu"
per cercare gli elementi eventualmente registrati in qualsiasi tipo di documento, senza star lì a pensare troppo quale estensione il file abbia, oppure quale applicativo si stia usando. le uniche condizioni sono che siano applicazioni per le quali, come detto, sia stato registrato un tipo di finestra di
"Editing"
, ed il massimo di nove elementi registrabili per ciascuna estensione.

***

Le macro testuali .

Fin dai primi capitoli avevamo realizzato degli script che inserivano stringhe predefinite nel documento corrente, il cui nome era
InserisceFirma ()
e
AperturaCodice ()
. Successivamente, prima nel decimo capitolo e poi in quello scorso, avevamo creato altri tre script,
MetteMacroTesto3 (),
MetteMacroTesto4 ()
e
MetteMacroTesto5 ()
, che ci sono serviti per compiere senza errori delle modifiche a elementi di codice nativi di Jaws.

In quei casi le stringhe immesse nel testo erano state preimpostate, memorizzandole in costanti o messaggi. Ora che ci siamo dotati di una nostra procedura per l’inserimento e la registrazione di stringhe testuali, ne approfittiamo per allargare a tale tipo di strumenti il sistema appena creato.

Per fare questo, realizzeremo la versione definitiva della funzione creata nel sesto capitolo,
MetteTesto ()
, la quale si occupava di scrivere materialmente le stringhe nel documento. Per omologarla alla procedura, ne creeremo una nuova versione,il cui nome avrà solo la prima parte in comune, mentre per la seconda useremo il suffisso predefinito di questo tipo di funzioni, e cioè
"Dato".

Per completare la sezione, in modo analogo a quella precedente, faremo uno script per avviare la procedura di inserimento stringhe, che d’ora in poi chiameremo
"macro"
, ed una serie che avrà comunque un suffisso numerico da 1 a 9, con un nome che esamineremo poi da cosa sia composto.

Durante i collaudi, infine, capiremo meglio quali siano le caratteristiche peculiari di questa opzione, rispetto agli elementi di ricerca. In particolare, anticipiamo già che le macro saranno sempre legate alle estensioni, e che avranno un suffisso numerico da 1 a 9, ma potranno essere articolate in più serie, le quali saranno a loro volta legate a particolari combinazioni tasti.

Esercizio 14.6.1. La funzione MetteDato.

FileScript.

Default.JSS

Nome.

MetteDato

Descrizione.

Inserisce nel documento attivo il contenuto della macro testuale avente l’oggetto ed il numero progressivo specificati.

Ritorni.

Di tipo Void. Nessuno.

Parametri.
  1. sEstensione. L’estensione dei file cui sono associati i dati registrati. Di tipo String.
  2. sProg. Il numero progressivo in forma testuale che identifica il dato. Di tipo String.
  3. iAiuto. Se valorizzato con TRUE, attiva l’omonima fase. Di tipo Int.
Note.
  1. Il codice della funzione corrisponde per poco più di un terzo con quella originaria,
    MetteTesto ()
    , quindi conviene senz’altro riscriverlo da zero; continueremo comunque ad usare anche l’altra versione, che serve, per esempio, a realizzare le serie di script.

Codice.


Void Function MetteDato (string sEstensione, string sProg, int iAiuto)
Var
String sSezione, ; nome della sezione con i dati
String sMacro, ;testo della macro
String sTitolo, ; titolo della finestra di dialogo
String sMessaggio, ; testo del messaggio nel corpo della finestra
String sChiavi, ; elenco delle chiavi presenti
Int i, ; contatore del ciclo
Int iRighe, ; numero delle righe copiate
String sRiga; singolo segmento da scrivere
If !ArchivioDati () Then; se il file di configurazione è mancante o incompleto,
Return; interrompe il flusso
EndIf; fine controllo file configurazione
Let sSezione = gsCategoria + gsOggetto + sEstensione; compone la sezione dove cercare i dati
Let gnMultiple = TRUE; imposta l’immissione di testo su più righe
Let sMacro = LeggeRecord (gsArchivio, sSezione, sProg); rileva il testo della macro
If !sMacro Then; se nessun testo è presente,
Let sTitolo = FormatString (ttlNoMacro, gsOggetto, sProg); compone il titolo della conferma,
Let sMessaggio = FormatString (msgImmissione, _A); e ne formatta anche il messaggio
If ChiedeConferma (sTitolo, sMessaggio) Then; se si conferma l’l’inserimento della macro,
; rileva le chiavi delle macro registrate per l’estensione del documento corrente
Let sChiavi = CambiaCampo (ChiaviUtente (gsArchivio, sSezione), ZERO)
; compone il numero progressivo con quello delle macro registrate aumentato di un’unità
Let sProg = IntToString (StringSegmentCount (sChiavi, PIPE) + 1)
; memorizza il dato eventualmente immesso
Let sMacro = InserisceTesto (FormatString (ttlElaboraVoce, AGGIUNGE, gsCategoria, sProg))
If sMacro Then; se una nuova macro è stata immessa,
If !ScriveRecord (gsArchivio, sSezione, sProg, sMacro) Then; se la macro non si registra,
Let sMacro = NULLO; resetta la macro per impedire la successiva scrittura
If iAiuto Then; se è attiva la fase, legge l’avviso
SayFormattedMessage (OT_ERROR, hlpNoScrittura, hlpNoScrittura_corto, gsArchivio)
EndIf; fine controllo aiuto
Return; in ogni caso, interrompe il flusso
EndIf; fine controllo scrittura macro
EndIf; fine controllo immissione macro
EndIf; fine controllo conferma prosecuzione
EndIf; fine controllo presenza macro
If !sMacro Then; se un testo comunque non è stato rilevato,
If iAiuto Then; se è attiva la fase Aiuto, formatta e pronuncia l’avviso
SayFormattedMessage (OT_ERROR, hlpNoDato, hlpNoDato_corto, FormatString (msgPosizione, sProg))
EndIf; fine controllo aiuto
Return; in ogni caso, interrompe il flusso
EndIf; fine controllo presenza dato
; converte il testo della macro, sostituendo gli eventuali separatori con un carattere Ascii 13
Let sMacro = InverteForma (sMacro, TRUE, CR)
SpeechOff (); spegne la sintesi
; esegue un ciclo, ripetendolo per il numero di segmenti nella stringa
For i = 1 To StringSegmentCount (sMacro, CR)
If i > 1 Then; dal secondo passaggio in poi,
EnterKey (); simula la pressione di Invio, per creare una nuova riga
Let iRighe = iRighe + 1; aggiorna il contatore delle righe copiate
Pause (); sospende momentaneamente il flusso
EndIf; fine controllo passaggi
Let sRiga = StringSegment (sMacro, CR, i); estrae il segmento equivalente ad una riga,
TypeString (sRiga); e lo trascrive nel documento
EndFor; fine ciclo scansione testo
If StringRight (sMacro, 1) == CR Then; se l’ultimo carattere del testo è quello di ritorno a capo,
EnterKey (); crea un’ulteriore riga
Let iRighe = iRighe + 1; aggiorna il numero complessivo delle righe
EndIf; fine controllo ultimo carattere
SpeechOn (); riattiva la sintesi
If iRighe Then; se sono state copiate delle righe intere,
If iRighe > 1 Then; se le righe sono più di una,
Let sRiga =FormatString (msgMettiRighe, iRighe); formatta il dato con il numero di righe
EndIf; fine controllo numero righe
SayUsingVoice (VCTX_JAWSCURSOR, sRiga, OT_HELP); legge il testo con la voce del cursore Jaws,
EndIf; fine controllo righe copiate
Delay (ATTESA); sospende temporaneamente il flusso
SayLine (); legge la riga corrente
EndFunction

Collaudo.

  1. Come nel caso precedente, limitatevi per il momento a compilare, perché il collaudo lo faremo con il prossimo script.

Esercizio 14.6.2. Lo script ElaboraMacroTesto.

FileScript.

Default.JSS

Nome.

ElaboraMacroTesto

Sommario.

Avvia la procedura di elaborazione delle macro denominate Testo.

Descrizione.

Chiama la funzione che gestisce le procedure guidate, la quale consente in questo caso di elaborare le macro disponibili per i documenti con l’estensione di quello corrente, e identificate con il termine Testo.

TastiAttivazione.

Shift+Control+0

Note.
  1. La combinazione tasti suggerita per attivare lo script, se avete notato, ha la stessa base di quella adottata per i nostri script che iniziavano con
    "MetteMacroTesto"
    , avendo però in questo caso il suffisso numerico 0; tale suffisso, infatti, è quello usato per indicare proprio una delle nostre procedure guidate per l’elaborazione dei dati.
  2. la differenza sostanziale rispetto alla procedura per gli elementi di ricerca è che qui, con le macro testuali, le voci da elaborare si possono inserire su più righe, e durante il collaudo analizzeremo anche come fare.

Codice.


Script ElaboraMacroTesto ()
GestisceDato (); chiama l’apposita funzione
EndScript

Collaudo.

  1. Dopo aver compilato, restate nell’Editor di Jaws, e dalla sua schermata principale premete la combinazione di avvio procedura,
    Shift+Control+0
    ; si presenterà una richiesta di conferma analoga a quella già incontrata con gli elementi di ricerca, che dovrebbe essere la seguente:
  2. 
    Nessuna Macro per l’estensione .JSS
    Immetterla ora?
    

  3. Il cursore sarà posizionato sul pulsante
    "Ok"
    , che consigliamo di cliccare con Invio; si entrerà così nel campo di immissione testo, mentre il titolo ed il corpo della finestra di dialogo pronunciati da Jaws saranno i seguenti:
  4. 
    Aggiungere la MacroTesto numero 1.
    Control+Invio nuova riga. Invio conferma, Esc annulla.
    

  5. La novità, come accennato nelle note, è la possibilità chiarita dalle istruzioni di poter inserire il testo anche su più righe, creando una nuova riga tramite la combinazione
    Control+Invio
    ; ed approfittiamo subito di questa opportunità, inserendo dapprima la nostra etichetta di inizio codice,
    "; _Ps Codice"
    , ovviamente senza virgolette, quindi premendo per due volte la citata combinazione per la nuova riga, e concludendo poi l’immissione con Invio.
  6. Si Aprirà di seguito la schermata principale della procedura, dove il testo appena inserito sarà preceduto dal numero 1; nel dettaglio, i ritorni a capo inseriti con
    Control+Invio
    saranno visualizzati con il nostro separatore di voce, costituito da due punti esclamativi dentro ad una coppia di parentesi quadre, come rappresentato di seguito:
  7. 
    1. ; _Ps Codice[!!][!!]
    

  8. Dovreste essere rimasti alla fine del file script, al momento di avviare la procedura di elaborazione; anche se così non fosse, provate ora a premere il tasto Invio: dovreste tornare all’Editor di Jaws, con inserite l’iscrizione appena immessa e la riga vuota associata; dopo aver verificato che ciò sia realmente accaduto, premete due volte
    Control+Z
    per annullare l’operazione, in quanto le righe immesse sono state due, ed il sistema le registra come due operazioni distinte.
  9. In ogni caso, Portatevi alla fine del file script corrente, casomai create una riga vuota se non ci fosse, quindi eseguite lo script
    AperturaCodice ()
    , premendo la combinazione
    Shift+Control+2
    . Nel file script aperto saranno scritte cinque righe, le nostre dichiarazioni per includere i file esterni, che voi dovete selezionare e tagliare, rimuovendole così dal file script.
  10. Riaprite la procedura guidata con
    Shift+Control+0
    , quindi inserite una nuova voce, premendo l’apposito pulsante o la scelta rapida
    Alt+I
    . Nel campo d’inserimento che si apre, incollate il contenuto che avevate tagliato prima dal file script, quindi premete Invio per confermare il testo immesso, e tornare alla schermata principale.
  11. Ripetete la procedura illustrata nei punti 6 e 7, eseguendo uno alla volta i tre citati script,
    MetteMacroTesto3 (),
    MetteMacroTesto4 ()
    e
    MetteMacroTesto5 ()
    . Essi vanno eseguiti premendo
    "Shift+Control"
    assieme ai numeri 3, 4 e 5, inserendo poi il loro contenuto in altrettante nuove voci di macro.
  12. Al termine, la schermata principale della procedura di elaborazione dovrebbe avere l’aspetto indicato di seguito, dove solo la voce numero 2 è stata ridotta per motivi di lunghezza:
  13. 
    1. ; _Ps Codice[!!][!!]
    2. ; Include "HJConst.JSH"; file costanti predefinito di Jaws[!!]Include "_PsConst.JSH"; ...
    3. ScriveSegno (iCurCharPos); registra il dato con l’apposita funzione[!!]
    4. GestisceDato (TORNA, APERTURA); _Ps Codice[!!]
    5. InterrompeAttesa (strKeyName); chiama l’apposita funzione[!!]
    

  14. Uscite per il momento dalla schermata principale della nostra procedura; passiamo subito, prima di dimenticarcene, a cancellare i cinque script di cui abbiamo spostato il contenuto dentro alle altrettante voci sopra elencate, ovvero
    InserisceFirma (),
    AperturaCodice (),
    MetteMacroTesto3 (),
    MetteMacroTesto4 ()
    e
    MetteMacroTesto5 ()
    ; è importante usiate il comando apposito dell’Editor di Jaws,
    "Cancella script"
    dal menu Script, perché è necessario eliminare anche le relative assegnazioni dei tasti nel file
    Default.JKM
    ; al termine delle cancellazioni, salvate compilando, e procediamo realizzando il prototipo per la nuova serie di script.

Esercizio 14.6.3. Lo script MetteMacroTesto1.

FileScript.

Default.JSS

Nome.

MetteMacroTesto1

Sommario.

Inserisce la macro Testo numero 1.

Descrizione.

Inserisce alla posizione del cursore la macro testuale identificata con il termine Testo ed il numero 1, tra quelle registrate per l’estensione del documento corrente.

TastiAttivazione.

Shift+Control+1

Note.
  1. Come avete potuto notare, il nome ha la stessa base dei tre script che abbiamo appena eliminato, i quali di diverso avevano solo il suffisso; siccome lo scopo è crearne una serie tramite il nostro apposito script, faremo prima a rifarli nuovi, con il sommario e la descrizione corretta, anziché andare manualmente a modificarne contenuto e documentazione.
  2. Per quanto riguarda i tasti di attivazione, essi seguono fedelmente la linea dettata da quelli che eseguono lo script di avvio della procedura,cambiando solo il suffisso numerico da 0 ad 1; questa sarà la regola da seguire anche più avanti, quando faremo altri esempi di macro testuali.

Codice.


Script MetteMacroTesto1 ()
GestisceDato (); chiama l’apposita funzione
EndScript

Collaudo.

  1. Dopo aver compilato, seguite nuovamente le fasi illustrate per già due volte in questo capitolo, posizionandovi all’interno dello script e premendo
    Shift+Control+Windows+P
    per eseguire lo script che ne crea le serie.
  2. Confermate poi la scelta del valore 9, quindi premete Invio anche alla successiva richiesta, e attendete la conclusione della procedura.
  3. Se anche la compilazione al termine della serie di script ha avuto successo, sarebbe possibile ora completare il collaudo, eseguendo i singoli script, e così inserendo nel documento le stringhe impostate come macro testuali, secondo lo schema proposto di seguito:
    • Voce Numero = Script MetteMacroTestoNumero, attivato con Shift+Control+Numero.
  4. Nel caso in cui si voglia completare l’elenco delle possibili macro testuali, cioè 9 per ciascuna estensione di file, i nomi di script che bisognerà richiamare, e quindi le combinazioni tasti da premere, dovranno seguire la sequenza, e corrispondenza numerica, come nello schema appena presentato.

Inserire una macro non ancora registrata.

Nel caso delle macro appena inserite, essendo queste soltanto cinque, se premessimo la combinazione
Shift+Control+9
, non avremmo una macro registrata per tale suffisso numerico. La procedura, in tal caso, vi avvertirebbe del fatto, e vi proporrebbe di poterla inserire direttamente.

Se a tale richiesta premete Escape, tornerete al documento senza nessuna modifica. Se invece confermerete la sua creazione, e poi al campo di editazione successivo sarà immesso un testo da registrare come macro, la macro verrà sia creata, e sarà quindi a disposizione da quel momento in poi, sia inserita nel documento aperto.

Da notare che la macro inserita avrà il numero di un’unità superiore a quello totale delle macro già registrate, non quindi necessariamente quello che si era tentato di premere. Ad esempio, nel caso citato, avendo noi registrato solo cinque voci, premendo uno qualsiasi dei tasti dal 6 al 9, assieme alla combinazione
"Shift+Control"
, sarà in ogni caso registrata la macro numero 6.

Non si tratta, tuttavia, di un errore, ma del limite strutturale di dover avere le chiavi dei record relativi alle diverse voci che procedono in ordine sequenziale. Come già accennato in precedenza, infatti, non si possono saltare dei numeri di voce, almeno per quel che riguarda gli elementi di ricerca e le macro testuali.

Moltiplicare le macro per le singole estensioni.

Avere nove stringhe registrabili per ciascuna estensione spesso non è sufficiente per coprire tutte le nostre esigenze di macro testuali. Chi scrive, ad esempio, si è costruito ben sei serie di script, che porta le macro disponibili per ciascuna estensione ad un massimo di 54. Questa grande disponibilità, tuttavia, è stata sfruttata interamente solo con l’estensione dei file script,
".JSS"
, mentre con altre estensioni la si è utilizzata molto meno.

In ogni caso, l’unico limite sta, come spesso accade, nel riuscire a trovare delle combinazioni tasti libere, o almeno non utilizzate nei documenti di editing. Una volta trovati i tasti, sarà sufficiente individuare un termine identificativo qualsiasi, che andrà posto come terza parte del nome dello script, sia in quello che avvia la procedura, sia nel nome che inserisce le macro nei documenti.

Così, allo stesso modo in cui prima avevamo usato la base
"Shift+Control"
per i tasti di attivazione, ed il termine
"Testo"
per identificare la serie di macro, potremmo usare ad esempio i tasti, ed i termini, seguenti:

  • Alt+da 0 a 9. Termine Alt.
  • Control+da 0 a 9. Termine Control.
  • Alt+Control+da 0 a 9. Termine Base.
  • Shift+Control+Windows+da 0 a 9. Termine Windows.
  • Alt+Control+Windows+da 0 a 9. Termine Extra.

Poi, da un elenco di tasti e termini come quello proposto, noi per ciascuno di essi dovremmo realizzare:

  1. Uno script di avvio della procedura, che abbia un nome con la base
    "ElaboraMacro"
    , seguito dal termine individuato, e dal suffisso numerico 0, come ad esempio
    ElaboraMacroAlt0.
  2. Una serie di script, i quali abbiano la base
    "MetteMacro"
    , seguita ancora dal termine identificativo, ma con un suffisso numerico crescente da 1 a 9, ad esempio
    MetteMacroAlt1.

Alcuni esempi di macro testuali.

Per completare l’argomento, a chi interessa l’applicazione pratica delle macro, proponiamo di seguito tre esempi di nove voci da usare dentro ai file script, tutte legate ovviamente agli script per Jaws. Queste serie saranno casomai da porre sulle varie combinazioni tasti, e con il termine identificativo, che si preferisce

In generale, le macro possono avere tutti i contenuti che è possibile esprimere con dei tasti, ad eccezione del carattere Pipe, Ascii 124, che non può essere presente in quanto causerebbe degli errori nel conteggiare i campi dei record.

Prima serie:


1. StringSegment (s, PIPE, i)
2. Pause ()[!!]
3. Var[!!]
4. Return
5. SayMessage (OT_ERROR,
6. If Then; se
7. SayFormattedMessage (OT_ERROR,
8. Let
9. EndIf; fine controllo

Seconda serie:


1. StringSegmentCount (s, PIPE)
2. FormatString (
3. String s
4. Return TRUE; restituisce l’esito positivo[!!]
5. SayMessage (OT_HELP,
6. While ; continua finché
7. SayFormattedMessage (OT_HELP,
8. ElIf Then; se
9. EndWhile; fine ciclo

Terza serie:


1. StringSegmentIndex (s, PIPE, TRUE)
2. StringReplaceSubstrings (
3. Int i
4. Return FALSE; restituisce un risultato nullo[!!]
5. SayUsingVoice (VCTX_JAWSCURSOR, , OT_HELP);
6. For i = 1 To ; scorre
7. SayUsingVoice (VCTX_PCCURSOR, , OT_HELP);
8. Else; altrimenti,[!!]
9. EndFor; fine scansione

Le serie di voci in orizzontale o in verticale.

Se noi volessimo considerare le macro come celle di una tabella, le serie che noi abbiamo proposto sarebbero in verticale, perché ciascuna macro è posta sotto all’altra. D’altro canto, se noi ponessimo queste tre serie di macro l’una affiancata all’altra, le tre diverse voci che hanno il numero 1 apparterebbero tutte alla stessa riga, quindi si potrebbero leggere come una serie posta in orizzontale.

Se questo può essere un modo per ricordarle meglio, allora le varie serie di nove macro, possono essere casomai raggruppate, o trovare delle corrispondenze, proprio nei due citati versi. Nelle tre serie proposte, ad esempio, le tre macro che hanno il numero 1 contengono le tre diverse funzioni che iniziano con
"StringSegment"
, oppure le macro con il numero 3 sono tutte legate alle dichiarazioni di variabili,
"Var",
"String"
e
"Int"
, e quindi si possono considerare raggruppate in orizzontale.

Allo stesso modo, le macro con il numero 6 sono le istruzioni di inizio,
"If",
"While"
e
"For"
, ed in ciascuna serie esse trovano la loro istruzione di fine nella macro numero 9,
"EndIf",
"EndWhile"
e
"EndFor"
, e quindi possono essere considerate come in una sorta di mini serie verticale.

In questo caso, tuttavia, ciascuno ha un modo per aiutarsi a memorizzare, anche sulla base di come si è abituati a farlo. L’importante è aver capito come funziona lo strumento, mentre spetta a ciascuno poterlo eventualmente personalizzare nel suo utilizzo.

***

Gli script a Gestione personale .

Dei tre tipi previsti di procedura, quella per gli script a gestione personale è di gran lunga la più articolata, e quella che in sostanza ha generato l’esigenza del maggior numero di condizioni nel codice, e di funzioni specifiche alla loro elaborazione. Tanta è la complessità nel realizzarla, quanto il suo utilizzo è in realtà poi molto semplice, ridotto all’essenziale. L’intento, speriamo riuscito, è quello di semplificare al massimo la creazione di nuovi script, o meglio, di nuove azioni che noi vogliamo far compiere a questi strumenti, così indispensabili per migliorare la nostra efficacia al computer.

Rinviando per i dettagli alle note ed ai titoli sui singoli elementi, sarà il collaudo a far chiarezza sui passaggi necessari a realizzare uno script a gestione personale. Partiremo da zero, facendo un esempio di semplice script, di cui faremo una versione per ciascuno dei quattro applicativi in cui abbiamo lavorato in queste pagine.

L’unico aspetto da evidenziare è che, diversamente da quanto accade con gli elementi di ricerca e le macro testuali, qui gli script realizzati saranno validi soltanto per l’applicativo dentro alla quale si lancia la procedura guidata per la loro creazione. Esiste però l’archivio personale, che abbiamo più volte citato, dove sarà registrata una copia di tutti gli script realizzati con lo stesso nome: da qui, infatti, si potrà attingere per duplicarne il contenuto nelle varie applicazioni , così come faremo anche nel primo nostro esempio di utilizzo.

Eseguire gli script personali dall’Aiuto in linea.

L’aspetto più interessante dell’Aiuto in linea, sia quello nativo di Jaws, sia la versione da noi predisposta, è la possibilità di eseguire gli script elencati direttamente dal suo interno. Se con gli script di tipo tradizionale questo è stato sinora possibile, con quelli a gestione personale sono necessari due accorgimenti in più:

  1. Uscire dal Visualizzatore virtuale non appena si clicca per eseguire lo script.
  2. Impostare i tasti abbinati allo script da eseguire come fossero stati gli ultimi premuti.

Ad occuparsi del primo aspetto saranno due funzioni native di Jaws:

  1. UserBufferIsActive
    , (E’AtivoBufferUtente), che restituisce TRUE o FALSE, qualora il Visualizzatore virtuale sia attivo oppure no. Senza parametri.
  2. UserBufferDeactivate
    , (DisattivaBufferUtente), che fa scomparire il Visualizzatore virtuale, restituendo TRUE o FALSE come esito di tale azione. Senza parametri.

Circa il secondo obiettivo tra quelli citati, l’impostazione dei tasti come fossero gli ultimi ad essere premuti, ricorreremo invece al comando nativo già visto nell’undicesimo capitolo,
SetLastScriptKey ().

Per quanto riguarda gli elementi in cui porre le varie istruzioni, le prime due saranno inserite in un’apposita struttura di controllo all’inizio di
GestisceDato ()
, di cui realizzeremo quindi la versione definitiva. Circa il comando d’impostazione tasti, diversamente, creeremo sia un nuovo elemento, prodotto qui di seguito, sia modificheremo una nostra funzione, quella che aggiunge il testo al Visualizzatore virtuale.

Esercizio 14.7.2. La funzione ImpostaEsegue.

FileScript.

Default.JSS

Nome.

ImpostaEsegue

Descrizione.

Imposta i tasti specificati come se fossero gli ultimi premuti; se tale impostazione riesce, si esegue lo script ad essi abbinato, altrimenti viene proposto un messaggio d’errore.

Ritorni.

Di tipo Void. Nessuno.

Parametri.
  1. sTasti. I tasti di attivazione di cui simulare la pressione. Di tipo String.
  2. sNome. Il nome dello script da eseguire. Di tipo String.
Note.
  1. Nell’unica struttura di controllo che compone la funzione, la prima via viene seguita qualora l’impostazione dei tasti specificati come gli ultimi premuti riesca, eseguendo lo script di cui si è indicato il nome tramite l’apposita funzione nativa; altrimenti, un avviso informerà sul tipo di errore verificatosi.
  2. Pur essendo stata creata in particolare per gli script a gestione personale, la funzione è ovviamente compatibile anche con tutti gli altri tipi di script, nativi o tradizionali che siano, che si intenda far eseguire direttamente dall’Aiuto in linea.

Codice.


Void Function ImpostaEsegue (string sTasti, string sNome)
If SetLastScriptKey (sTasti) Then; se riesce l’impostazione dei tasti come ultimi premuti,
PerformScriptByName (sNome); esegue lo script indicato
Else; altrimenti, in caso di errore, formatta e legge l’avviso
SayFormattedMessage (OT_ERROR, hlpNoUltimiTasti, hlpNoUltimiTasti_corto, gsVoce)
EndIf; fine controllo impostazione tasti
EndFunction

Esercizio 14.7.3. La versione modificata di AggiornaVisualizzatore ().

FileScript.

Default.JSS

Nome.

AggiornaVisualizzatore

Novità.
  1. La prima chiamata della nostra funzione
    ImpostaEsegue ()
    , anche se nascosta nel comando che deve essere formattato come secondo parametro dell’istruzione nativa.
Note.
  1. La modifica va apportata al secondo parametro dell’istruzione con
    UserBufferAddText ()
    , posta nella prima via della struttura, cambiando il nome del messaggio base da formattare ed aggiungendo i tasti come primo termine, usando la seguente riga di codice:
  2. 
    FormatString (hlpEsegueLink, sTasto, sNome), ; formatta anche il comando da eseguire,
    

  3. In caso di dubbi, sostituite la precedente versione con quella posta di seguito.

Codice.


Void Function AggiornaVisualizzatore (string sTasto, string sNome, ; primi due parametri,
string sAlias, string sInfo, string sPrimo, string sUltimo); seconda riga con gli altri quattro
If !sPrimo Then; se si stanno aggiornando le normali voci,
UserBufferAddText ( ; compone la riga d’informazioni, comprensiva del link,
FormatString (hlpInfoScript, sInfo, sTasto), ; formatta il testo da visualizzare,
FormatString (hlpEsegueLink, sTasto, sNome), ; formatta anche il comando da eseguire,
sAlias); e aggiunge il nome virtuale per l’elenco dei link
Else; altrimenti, per le serie di voci,
UserBufferAddText ( ; compone la riga d’informazioni, formattando i caratteri variabili
FormatString (hlpInfoSerie, ToglieUltimo (sInfo), ToglieUltimo (sTasto), sPrimo, sUltimo))
EndIf; fine controllo parametri
EndFunction

Esercizio 14.7.4. La versione definitiva di GestisceDato ().

FileScript.

Default.JSS

Nome.

GestisceDato

Novità.
  1. Le funzioni integrate
    UserBufferIsActive ()
    e
    UserBufferDeactivate ()
    , presentate nell’introduzione.
Note.
  1. La modifica principale consiste in un’unica struttura di controllo, posta all’inizio del codice, che contiene entrambe le funzioni native citate tra le novità, da inserire in questa forma:
  2. 
    If UserBufferIsActive () Then; se il Visualizzatore virtuale è attivo,
    UserBufferDeactivate (); lo rimuove dallo schermo
    EndIf; fine controllo Visualizzatore virtuale
    

  3. Cogliamo l’occasione di questa modifica per consentire di attivare la modalità aiuto anche nella chiamata della funzione
    DocumentoCorrente ()
    , la cui istruzione dovrebbe quindi assumere l’aspetto seguente:
  4. 
    If !DocumentoCorrente (sNomeFile, sSuffisso, iAiuto) Then; se non vi sono dati sul file,
    

  5. Come al solito, potete anche direttamente inserire la nuova versione nella forma posta di seguito.

Codice.


Void Function GestisceDato (string sAzione, string sOggetto)
If UserBufferIsActive () Then; se il Visualizzatore virtuale è attivo,
UserBufferDeactivate (); lo rimuove dallo schermo
EndIf; fine controllo Visualizzatore virtuale
If !SiamoNellaFinestra (EDITING) Then; se non si è nella finestra corretta,
If !(sAzione + sOggetto) Then; se non sono stati specificati dei parametri,
TypeCurrentScriptKey (); ripete i tasti premuti,
EndIf; fine controllo parametri
Return; interrompe il flusso
EndIf; fine controllo finestra
Var
Int iAiuto, ; stato di attivazione della fase Aiuto
Int iNoVoce, ; imposta la disattivazione della fase Aiuto
String sProg, ; eventuale numero progressivo indicato tramite il nome dello script
String sCategoria, ; tipologia dell’azione da compiere
String sDato, ; dato testuale da sottoporre all’azione
String sNomeFile, ; nome completo del documento aperto
String sSuffisso; dato suppletivo da passare come parametro
Let iAiuto = IsSameScript (); rileva l’eventuale doppia pressione dei tasti di attivazione
If !sAzione Then; se l’azione da compiere non è stata specificata come parametro,
Let sProg = SeparaParole (sAzione, sCategoria, sOggetto); estrae i dati dal nome script
Else; altrimenti
Let iNoVoce = SALTA; imposta la successiva disattivazione della fase Aiuto
EndIf; fine controllo parametro
If sAzione == PRONUNCIA Then; se si sono chieste azioni di lettura,
If sCategoria == STATO Then; se si sono richiesti dati dalla barra di stato,
Let sDato = InfoStato (sOggetto, iAiuto); rileva il dato dalla funzione generica
Else; altrimenti, in tutti gli altri casi,
; Rileva il dato dalla funzione di cui si compone il nome
Let sDato = NoZero (CallFunctionByName (sCategoria + sOggetto))
EndIf; fine controllo categoria
CallFunctionByName (sAzione + DATO, sOggetto, sDato, iAiuto); esegue l’azione
ElIf sAzione == CERCA Then; se invece si sono chieste delle ricerche,
CercaDato (sCategoria, sOggetto, iAiuto); esegue l’azione
Else; se invece servono operazioni su documenti,
If !DocumentoCorrente (sNomeFile, sSuffisso, iAiuto) Then; se non vi sono dati sul file,
If iAiuto Then; se è attiva la fase Aiuto,
SayFormattedMessage (OT_ERROR, hlpNoDato, hlpNoDato_corto, msgTitolo); legge l’avviso
EndIf; fine controllo aiuto
Return; in ogni caso, interrompe il flusso
EndIf; fine controllo documento
If sAzione == SALVA; se si vuole il salvataggio di un contrassegno,
|| sAzione == TORNA ; o si vuole ritornarvi,
|| sAzione == ESEGUE Then; o, infine, se si vuole attivare uno script a gestione personale,
If !iNoVoce Then; se l’impostazione non è disattivata,
Let iAiuto = TRUE; imposta la fase
EndIf; fine controllo disattivazione
CallFunctionByName (sAzione + DATO, sNomeFile, sOggetto, sProg, iAiuto); esegue l’azione
Else; altrimenti, in tutti i casi in cui è necessario un suffisso,
If sCategoria == SCRIPTS Then; se si stanno elaborando gli script a gestione personale,
Let sSuffisso = sNomeFile; passa il nome del file parametro al posto dell’estensione
ElIf !sSuffisso Then; se un suffisso non è stato rilevato,
If iAiuto Then; se è attiva la fase,
SayMessage (OT_ERROR, hlpNoEst, hlpNoEst_corto); legge l’avviso
EndIf; fine controllo aiuto
Return; in ogni caso, interrompe il flusso
EndIf; fine controllo suffisso
; rende globali i dati rilevati
Let gsCategoria = sCategoria
Let gsOggetto = sOggetto
If sAzione == MUOVE ; se si è chiesto di muoversi ad un elemento,
|| sAzione == METTE Then; oppure, di inserire del testo nel documento corrente,
CallFunctionByName (sAzione + DATO, sSuffisso, sProg, iAiuto); esegue l’azione
ElIf sAzione == ELABORA Then; se invece si è chiesto di avviare una procedura guidata,
If gsCategoria == ELEMENTO Then; se si stanno configurando gli elementi di ricerca,
Let gsOggetto = NULLO; resetta il dato
EndIf; fine controllo oggetto
CallFunctionByName (sAzione + DATO, sSuffisso, iAiuto); esegue l’azione
Else; se invece l’azione non è stata riconosciuta,
If iAiuto Then; se la fase è attiva,
SayFormattedMessage (OT_ERROR, hlpNoAzione, hlpNoAzione_corto, sAzione); legge l’avviso
EndIf; fine controllo Aiuto
EndIf; fine controllo azioni con suffisso
EndIf; fine controllo azioni su documenti
EndIf; fine controllo generale azioni
EndFunction

Gli altri elementi per la gestione degli script.

Da qui alla fine della sezione produrremo il restante codice da utilizzare in modo specifico per gli script a gestione personale. Inizieremo con la classica funzione principale, quella con il suffisso
"Dato"
, non prima però di averne realizzato altre due, che sono di supporto al citato elemento.

Sul fronte degli script, produrremo anche in questo caso quello per avviare la procedura guidata, che si attiva con una combinazione tasti da premere assieme al tasto 0. La serie di script, invece, sarà in questo caso composta da ben 99 elementi, lo stesso numero che avevamo fissato come limite massimo per questa categoria.

Esercizio 14.7.6. La funzione RilevaScript.

FileScript.

Default.JSS

Nome.

RilevaScript

Descrizione.

Rileva, controlla, e casomai trasmette per riferimento, i dati relativi allo script a gestione personale, registrato per l’applicazione corrente al numero passato come parametro.

Ritorni.

Di tipo Int. TRUE, se i dati sono stati rilevati correttamente; FALSE, se lo script non è stato registrato.

Parametri.
  1. sChiave. Il numero progressivo dello script, che funge da chiave del record. Di tipo String.
  2. sNome. Per Riferimento. Il nome dello script. Di tipo String.
  3. sComandi. Per Riferimento. L’elenco dei comandi da eseguire. Di tipo String.
  4. sAmbito. Per Riferimento. L’ambito in cui deve essere eseguito lo script. Di tipo String.
Fasi.
  1. Nella prima struttura di controllo, grazie ad una nostra funzione, è verificato il numero di dati del record; se tale numero non è quello stabilito, il flusso s’interrompe restituendo un risultato nullo.
  2. Dopo aver estratto il nome ed i tasti di attivazione dello script dal record, si controlla se la chiamata non sia avvenuta durante l’elaborazione tramite la procedura, e che i tasti premuti non siano quelli dello script; se così è, il flusso s’interrompe restituendo un risultato nullo.
  3. Se invece il flusso continua, gli altri dati necessari si estraggono dal record, e sono trasmessi per riferimento alla funzione chiamante, restituendo poi l’esito positivo del controllo.

Codice.


Int Function RilevaScript (string sChiave, string ByRef sNome, ; primi due parametri,
string ByRef sComandi, string ByRef sAmbito); seconda riga con gli altri due
Var
String sRecord, ; dati dello script
String sTasti; tasti di attivazione dello script
If !NumeroDati (sChiave, sRecord) Then; se il numero di dati del record non è corretto,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo numero dati
Let sNome = StringSegment (sRecord, PIPE, PRIMA); rileva dal record il nome dello script,
Let sTasti = StringSegment (sRecord, PIPE, SECONDA); ed i tasti di attivazione
If gsAttiva != sNome ; se lo script non è stato avviato dalla procedura di elaborazione,
&& sTasti != GetCurrentScriptKeyName () Then; ed i tasti sono diversi da quelli premuti,
Return FALSE; restituisce un risultato nullo
EndIf; fine controllo tasti
Let sComandi = StringSegment (sRecord, PIPE, QUARTA); prende i comandi da eseguire,
Let sAmbito = StringSegment (sRecord, PIPE, DATI_SCRIPT); l’ambito in cui operare,
Return TRUE; e restituisce l’esito positivo
EndFunction

Esercizio 14.7.7. La funzione ComandiScript.

FileScript.

Default.JSS

Nome.

ComandiScript

Descrizione.

Gestisce l’esecuzione materiale dei comandi, distinguendo tra i nomi dei tasti di cui simulare la pressione dalla tastiera, e caratteri da inviare all’applicazione.

Ritorni.

Di tipo Void. Nessuno.

Parametri.
  1. sNome. Il nome virtuale dello script. Di tipo String.
  2. sComandi. L’elenco dei comandi da eseguire. Di tipo String.
Fasi.
  1. Dopo aver tentato di leggere il nome virtuale dello script, si spegne la sintesi e si avvia un ciclo per scorrere i comandi immessi come parametro.
  2. All’interno del ciclo, un controllo determina se il comando estratto sia una combinazione tasti oppure un singolo carattere, chiamando le apposite funzioni native.
  3. Al termine del ciclo, viene riattivata la sintesi, e pronunciata la riga corrente.

Codice.


Void Function ComandiScript (string sNome, string sComandi)
Var
Int iStato, ; attiva il ripristino della sintesi
Int i, ; contatore del ciclo
String sDato; singolo comando da eseguire nella serie
SayUsingVoice (VCTX_JAWSCURSOR, sNome, OT_HELP); legge l’alias assegnato allo script
Let iStato = ControllaSintesi (FALSE); spegne la sintesi, impostandone lo stato attuale
; scorre l’elenco delle serie di tasti, eventualmente divisi dal separatore di voce
For i =1 To StringSegmentCount (sComandi, SPV)
Let sDato = TagliaSpazi (StringSegment (sComandi, SPV, i)); estrae il singolo comando
If StringLength (sDato) > 1 Then; se la stringa è un tasto di cui simulare la pressione,
TypeKey (sDato); richiama la funzione per le combinazioni di tasti
Pause ()
Else; altrimenti,
TypeString (sDato); richiama la funzione per i singoli caratteri
EndIf; fine controllo tipo pressione
EndFor; fine ciclo comandi
ControllaSintesi (iStato, TRUE); ripristina la sintesi con lo svuotamento del buffer,
SayLine (); e legge la riga corrente
EndFunction

Esercizio 14.7.8. La funzione EsegueDato.

FileScript.

Default.JSS

Nome.

EsegueDato

Descrizione.

Esegue i comandi impostati tramite gli script a gestione personale.

Ritorni.

Di tipo Void. Nessuno.

Parametri.
  1. sNomeFile. Il nome, completo di estensione, del documento corrente. Di tipo String.
  2. sOggetto. Il suffisso assegnato al nome della categoria, che compone assieme al prefisso Scripts il nome della sezione in cui sono registrati i dati relativi agli stessi script personali. Di tipo String.
  3. sProg. Il numero progressivo dello script, che corrisponde alla chiave dei dati registrati negli archivi di configurazione per l’applicativo corrente. Di tipo String.
Novità.
  1. Le nostre funzioni
    RilevaScript ()
    e
    ComandiScript ().
  2. La costante numerica
    DATI_SCRIPT
    , equivalente al valore 5, che corrisponde ai campi che devono essere presenti in un record per ritenerlo valido.
  3. La costante
    TABELLA
    , che corrisponde all’omonimo termine, e che in questo caso rappresenta l’ambito in cui far eseguire uno script a gestione personale, dentro appunto una tabella o un foglio di calcolo.
Fasi.
  1. Una prima struttura di controllo verifica che il record abbia tutti i dati necessari ad essere eseguito, tramite la nostra funzione
    RilevaScript ()
    ; se così non è, e se la modalità Aiuto risulta attiva, viene pronunciato un messaggio d’errore; in ogni caso, il flusso viene interrotto, restituendo un risultato nullo.
  2. Una seconda struttura più articolata tende ad intercettare l’ambito impostato; se una via lo individua, tra quelli possibili, sono poi eventualmente effettuati ulteriori controlli sul fatto che tutte le condizioni siano rispettate; se così non è, e se la modalità Aiuto risulta attiva, viene pronunciato un messaggio d’errore; a prescindere dal messaggio, il flusso viene interrotto, restituendo un risultato nullo.
  3. Se tutti i controlli suppletivi non hanno alcun esito, il flusso arriva all’ultima istruzione del codice, la quale esegue materialmente lo script tramite la nostra funzione
    ComandiScript ().
Note.
  1. Abbiamo già sommariamente illustrato cosa s’intenda per
    "ambito"
    , come ultimo campo delle impostazioni per gli script a gestione personale; qui, nel dettaglio, l’importanza di questo dato testuale è ben rappresentata dal fatto che i suoi controlli prendano gran parte della funzione che stiamo realizzando.

Codice.


Void Function EsegueDato (string sNomeFile, string sOggetto, string sProg)
Var
Int iAiuto, ; indicatore dell’omonima fase
String sTipi, ; elenco dei tipi di finestra registrati
String sNome, ; alias, o nome virtuale, dello script personale da eseguire
String sComandi, ; elenco dei comandi da eseguire
String sAmbito; contesto in cui lo script personale deve essere eseguito
Let iAiuto = IsSameScript (); rileva l’eventuale doppia pressione dei tasti di attivazione
Let gsArchivio = NULLO; resetta il dato per la lettura dal file dell’applicativo corrente
Let gnMaxCampi =DATI_SCRIPT; imposta il valore come numero massimo di campi
Let gsSezione = SCRIPTS + sOggetto; compone la sezione dei dati nell’archivio
Let sTipi = LeggeChiavi (PERSONALE, TIPI_FINESTRE); rileva i tipi di finestra registrati
If !RilevaScript (sProg, sNome, sComandi, sAmbito) Then; se i dati non sono stati rilevati,
If iAiuto Then; se è attiva la fase, formatta e legge l’avviso
SayFormattedMessage (OT_ERROR, hlpNoDatiScript, hlpNoDatiScript_corto, sProg)
EndIf; fine controllo aiuto
TypeCurrentScriptKey (); in ogni caso, ripete i tasti di attivazione,
Return; e interrompe il flusso
EndIf; fine controllo dati
If sAmbito == TABELLA Then; se l’ambito indicato impone di verificare che si sia in una tabella,
If !InTable () Then; se poi la funzione nativa non lo conferma,
If iAiuto Then; se è attiva la fase,
SayMessage (OT_ERROR, hlpNoTabella); legge l’avviso
EndIf; fine controllo aiuto
TypeCurrentScriptKey (); in ogni caso, ripete i tasti di attivazione,
Return; e interrompe il flusso
EndIf; fine controllo presenza tabella
ElIf CampoTrovato (lstAmbitiScript, sAmbito) Then; se invece è uno degli altri predefiniti,
; salva la posizione corrente, ed opera sulle annotazioni per il file
SalvaDato (sNomeFile, sAmbito)
ElIf CampoTrovato (sTipi, sAmbito) Then; se invece è un tipo di finestra,
If sAmbito != EDITING Then; se il tipo di finestra da controllare non è l’Editing,
If !SiamoNellaFinestra (sAmbito) Then; se non si è nella finestra impostata,
If iAiuto Then; se è attiva la fase, legge l’avviso
SayMessage (OT_ERROR,hlpNoFinestra, hlpNoFinestra_corto)
EndIf; fine controllo aiuto
TypeCurrentScriptKey (); in ogni caso, ripete i tasti di attivazione,
Return; e interrompe il flusso
EndIf; fine controllo finestra
EndIf; fine controllo Editing
ElIf sAmbito != NESSUNO Then; altrimenti, se l’ambito registrato non è stato riconosciuto,
If iAiuto Then; se è attiva la fase, formatta e legge l’avviso
SayFormattedMessage (OT_ERROR, hlpNoAmbito, hlpNoAmbito_corto, sAmbito)
EndIf; fine controllo aiuto
Return FALSE; in ogni caso, restituisce un risultato nullo
EndIf; fine controllo ambito
ComandiScript (sNome, sComandi); chiama la funzione che esegue le azioni dello script
EndFunction

Collaudo.

  1. Così come nei precedenti casi, limitatevi a compilare correttamente, poiché il collaudo di questo tipo di procedura sarà effettuato con il prossimo elemento di codice.

Esercizio 14.7.9. Lo script ElaboraScriptsPersonali.

FileScript.

Default.JSS

Nome.

ElaboraScriptsPersonali

Sommario.

Avvia la procedura di elaborazione degli script a gestione personale.

Descrizione.

Chiama la funzione che gestisce le procedure guidate, la quale consente in questo caso di elaborare gli script a gestione personale disponibili per l’applicazione corrente.

TastiAttivazione.

Shift+Control+JAWSKey+0

Note.
  1. In questo caso, i tasti di attivazione sono davvero solo suggeriti, in quanto dipende da quelli che avete liberi nella vostra configurazione; se dovete, o volete, personalizzare la combinazione base, cercate almeno di mantenere il suffisso numerico 0, il quale è stato utilizzato sinora per identificare gli script che richiamano la nostra procedura.

Codice.


Script ElaboraScriptsPersonali ()
GestisceDato (); chiama l’apposita funzione
EndScript

Il collaudo degli script a gestione personale.

  1. Una volta eseguita la compilazione del codice, da dentro L’Editor di Jaws, portatevi alla sua fine, nello stesso codice, e create una riga vuota dove scrivete un contenuto qualsiasi, ad esempio
    "; testo da cancellare"
    , avendo l’avvertenza di porre un carattere Punto e Virgola ad inizio riga per poterla casomai salvare senza errori. Andate a capo riga e, sempre premettendo un Punto e Virgola, scrivete un secondo contenuto, ad esempio
    "Riga da mantenere"
    , quindi tornate sulla prima riga scritta.
  2. Premete i tasti di attivazione dello script appena realizzato, che se avete seguito il nostro suggerimento sono
    Shift+Control+TastoJaws+0
    . Apparirà una finestra di dialogo che avrà il seguente contenuto:
  3. 
    Nessuno Scripts per l’applicazione Editor di script.
    Immetterlo ora?
    

  4. Come al solito, il cursore sarà posizionato sul tasto
    "Ok"
    , che dovete quindi premere per avviare la procedura d’inserimento dei dati. Si entrerà in un campo di editazione, e le istruzioni a video saranno le seguenti:
  5. 
    Aggiungere il nome dello script .
    Invio conferma, Esc annulla.
    

  6. Il nostro obiettivo sarà realizzare uno script che cancelli il contenuto della riga sul cursore. Dovendo inserire un nome che ci spieghi la sua funzione, digitiamo quindi
    "CancellaRiga"
    , e premiamo Invio. Sarà proposta una nuova finestra di dialogo, il cui contenuto sarà il seguente:
  7. 
    Premere i tasti di attivazione dello script CancellaRiga.
    Invio conferma, Esc annulla.
    

  8. A questo punto vi trovate in una fase del tutto simile a quella che si propone quando, nella procedura guidata di creazione di un nuovo script, nell’Editor di Jaws, arrivate nel campo denominato
    "Assegna a"
    . Nel dettaglio, qualsiasi tasto, o combinazione di tasti, voi premiate, la procedura li considera i tasti di attivazione che voi avete scelto per avviare lo script
    "CancellaRiga"
    . Le uniche tre eccezioni sono i tasti che vi chiediamo di provare, elencati di seguito:
    • Escape, che propone una conferma all’uscita dall’inserimento . In questo caso, cliccate per confermare la scelta predefinita, Annulla, tornando così alla schermata precedente.
    • Invio, con il quale si confermano i tasti scelti. Poiché, se avete seguito fedelmente i passaggi proposti, non dovreste aver premuto alcun altro tasto valido, la procedura vi avviserà che non sono stati ancora definiti dei tasti, proponendovi di tornare all’inserimento, cosa che vi consigliamo di fare premendo di nuovo Invio.
    • Insert+T, il comando di lettura titolo della finestra, che in questo caso si limita a rileggere il messaggio proposto all’ingresso nella schermata.
  9. Come detto, qualsiasi altro tasto sarà considerato come potenzialmente un tasto di attivazione. Per questo , sarete avvertiti se i tasti premuti sono già abbinati ad un altro script, di cui sarà fornito il tipo ed il nome, mentre le possibili opzioni saranno di due tipi:
    • Nel caso di tasti già utilizzati da script di tipo tradizionale, nativi o creati dall’Utente, vi sarà proposta una conferma alla sovrascrittura di tali tasti;come nel caso della procedura guidata di Jaws, la scelta predefinita sarà l’annullamento, e quindi il ritorno alla schermata d’inserimento, mentre per sovrascrivere i tasti si dovrà premere una volta Tab e poi confermare con Invio.
    • Nel caso di tasti già utilizzati da altri script a gestione personale, vi sarà invece impedito di utilizzare tali tasti, suggerendovi di modificarli prima tramite la nostra procedura, e comunque consentendo solo di poter confermare il ritorno all’inserimento.
  10. In ogni caso, come tasti di attivazione per il nostro script, premete la combinazione
    Shift+Alt+J
    , che è abbastanza strana per non essere già occupata, quindi premete Invio per confermare tali tasti. La sintesi pronuncerà, con la voce del cursore Jaws, un avviso con l’esito della registrazione dei tasti, quindi sarà proposta una nuova schermata , o campo d’inserimento, con il seguente messaggio:
  11. 
    Aggiungere il Sommario dello script CancellaRiga.
    Invio conferma, Esc annulla.
    

  12. In questo tipo di script, per semplificarne la gestione, si è optato per specificare solo il sommario, e non quindi anche una descrizione. Per questo , il testo da immettere come sommario potrebbe anche essere un po’ più dettagliato, ma si consiglia comunque di esprimerlo al massimo con 120 caratteri. Nel nostro caso, potete scrivere ad esempio
    "Elimina il contenuto della riga sul cursore."
    , confermando poi il testo con Invio. Si passerà quindi al campo successivo, il cui messaggio sarà il seguente:
  13. 
    Aggiungere le Azioni compiute dallo script CancellaRiga.
    Control+Invio nuova riga. Invio conferma, Esc annulla.
    

  14. Se avete notato, la seconda riga di istruzioni propone la novità di poter esprimere un contenuto su più righe. Qui, infatti, ogni singolo comando, o azione, che si vorrà far compiere a Jaws, dovrà essere espresso in una riga a sé stante, la quale sarà da creare, dunque, premendo la combinazione
    "Control+Invio"
    . Ricordiamo inoltre che i comandi possibili sono tutti i tasti e le combinazioni gestite direttamente dal sistema, non quindi tasti che attivano script di Jaws, e per di più con il loro nome in inglese. Ad esempio,
    "Enter"
    sarà per
    "Invio",
    "End"
    per il tasto
    "Fine",
    "Home"
    per quello omonimo, e così via. Per chi non conoscesse la lingua, ricordiamo che la modalità Aiuto tastiera di Jaws, come prima informazione, recita appunto il nome in inglese dei tasti.
  15. Se in una riga di comandi è presente un solo carattere, la procedura darà per scontato che si tratti di un carattere singolo, da inviare all’applicazione così com’è. In questa forma si possono quindi specificare i caratteri che sono ad esempio dei tasti caldi nei menu, come la lettera
    "S"
    nel menu File che sta per
    "Salva"
    , oppure anche una lettera o un numero che per qualche motivo si deve inserire nel documento, o in un campo di editazione attivato dai comandi precedenti.
  16. Nel caso del nostro script, noi dobbiamo ricreare una sequenza di azioni che ci consenta in ogni circostanza di cancellare una riga, sia essa vuota, sia che abbia del contenuto; questa particolare sequenza prevede di portarsi alla sua fine, scrivere un carattere qualsiasi per garantirci di avere comunque qualcosa da selezionare, quindi attivare la selezione dal termine della riga sino al suo inizio, ed infine premere il tasto di cancellazione due volte, la prima per rimuovere il contenuto, l’altra per eliminare la restante riga vuota. Avendo l’avvertenza di premere la combinazione di nuova riga ad ogni tasto, o carattere, la sequenza citata dovrà quindi essere inserita in questa forma:
  17. 
    End
    x
    Shift+Home
    Delete
    Delete
    

  18. Come potete notare, sono in totale cinque righe, delle quali quattro di comandi, ed una in cui è presente un solo carattere
    ""
    , che rappresenta un contenuto da poter selezionare anche nel caso di una riga in origine vuota. Quando avete concluso l’inserimento, premete Invio per confermare. Vi si proporrà l’ultimo campo di elaborazione, che questa volta è una casella di scelta, il cui messaggio sarà il seguente:
  19. 
    Selezionare l’ambito in cui far agire CancellaRiga, e cliccare sull’azione da compiere.
    

  20. All’ingresso della nuova schermata ci si troverà sull’elenco degli ambiti possibili, i quali sono come detto predefiniti, e quindi non se ne può variare il numero direttamente. In questo caso, il cursore sarà sul primo ambito,
    "Nessuno"
    , opzione che lascia agire lo script in una qualsiasi finestra registrata come
    "Editing"
    . Poiché questo è il caso del nostro script, premete Invio per confermare la scelta, completando in tal modo i cinque campi da inserire, e tornando poi alla schermata principale della procedura.

Elaborare i dati sugli script a gestione personale.

Seguendo i passi illustrati per creare il nostro primo script di questo speciale tipo, dovremmo ora trovarci nella schermata principale della procedura guidata. Qui, il modo più semplice per avere una panoramica sulle varie possibilità è premere l’Aiuto in linea, il cui contenuto, senza intestazione ed istruzioni di chiusura, dovrebbe essere il seguente:


Selezionare lo script da elaborare, e cliccare sull’azione da compiere.
Pulsanti disponibili:
Modifica nome. Alt+M.
Aggiunge script. Alt+I.
Duplica dall’elenco. Alt+D.
Elimina script. Alt+L.
Campo successivo. Alt+U.
Esegue script. Ok, oppure Alt+O
Annulla. Esc, oppure Alt+A.
Visualizza questa schermata d’Aiuto. Windows+H.

Qui, rispetto a quanto già analizzato in precedenza, è ancora possibile inserire un nuovo script o eliminarne uno di già presente, oppure soltanto modificarne il nome. Non ci sono invece i due tasti di spostamento delle voci, sostituiti da uno che duplica gli script nell’archivio, ed un altro che porta alla successiva schermata.

Così come per gli elementi di ricerca e le macro testuali, premendo Invio si eseguirà l’azione selezionata, che in questo caso è lo script per cancellare la riga corrente. Se volete, poiché abbiamo avviato la procedura da una riga scritta appositamente, potete anche premere Invio, per testare appieno il nostro lavoro.

Se così avete fatto, sarete tornati nella finestra principale dell’Editor di Jaws. La riga da cui eravamo partiti non dovrebbe esserci più, ed il cursore dovrebbe essere posizionato all’inizio dell’altra riga che avevamo predisposto, così da evidenziare che le righe cancellate sono soltanto una.

Qualora abbiate fatto questa prova, premete ancora una volta
Shift+Control+TastoJaws+0
, per tornare a conoscere i nostri speciali script, dove completeremo la panoramica sul loro funzionamento.

Elaborare i tasti di attivazione.

Dalla schermata principale, per passare al secondo campo di elaborazione, cliccate sul pulsante
"Campo successivo"
, o sulla scelta rapida
"Alt+U"
. In generale, per sottolineare il cambio di schermata , la procedura emetterà una nota di valore crescente, nel caso in cui si vada ad una schermata successiva, oppure una nota inferiore, qualora si stia tornando ad una schermata precedente.

In ogni caso, ci si troverà sulla solita finestra di scelta, quella generata dalla funzione nativa
DlgSelectItemInList ()
, dove i tasti da noi inseriti durante la creazione dello script,
"Shift+Alt+J"
, sono riportati nell’unica voce presente. Per sapere cosa poter fare, ancora una volta, consigliamo di premere l’Aiuto in linea,
"Windows+H"
, il cui contenuto informativo sarà stavolta il seguente:


Modifica i Tasti per attivare CancellaRiga.
Pulsanti disponibili:
Modifica Tasti. Alt+M.
Campo successivo. Alt+U.
Campo precedente. Alt+R.
Torna all’inizio. Alt+T.
Campo successivo. Ok, oppure Alt+O
Annulla. Esc, oppure Alt+A.
Visualizza questa schermata d’Aiuto. Windows+H.

Qui, dunque, non si può ne inserire una nuova voce, e neppure cancellarla, mentre sarà possibile modificare il dato, che nel caso di questa schermata sono i tasti di attivazione. Attivando il pulsante di modifica, direttamente o tramite la scelta rapida
"Alt+M"
, sarà richiamata la stessa interfaccia di attesa tasti descritta nella fase di inserimento dello script.

Oltre al pulsante per passare al campo di elaborazione successivo, la cui funzione è qui duplicata dal tasto
"Ok"
,ci sarà ora anche quello per tornare indietro, e quello per andare in ogni caso alla schermata principale, che, solo in questo caso, coincide con quello di ritorno al campo precedente. Un’ultima annotazione riguarda il tasto Escape che, nei campi dal secondo in poi, di fatto risulta una duplicazione della scelta rapida
"Alt+T"
,in quanto la sua pressione fa tornare alla schermata principale.

Elaborare sommario e azioni dello script.

Dalla schermata dei tasti di attivazione, premendo un’altra volta la scelta rapida
"Alt+U"
, oppure il tasto Invio, si passa al campo dove elaborare il Sommario, e da qui si può passare a quello delle azioni da far compiere agli script. Entrambe queste schermate sono del tutto simili a quella appena illustrata, con gli stessi pulsanti da poter premere e con gli stessi effetti sui dati elaborati nella procedura.

Mentre la modifica del sommario è un’ipotesi più remota, appare già più probabile che si debba essere chiamati a modificare le azioni compiute dallo script. Questo può accadere, ad esempio, quando inserendo una serie di tasti per far compiere le relative azioni, si è premuto per errore il tasto Invio anziché Control+Invio, e con questo concludendo l’inserimento delle azioni prima di averle completate.

Anche noi, propagando gli script personali ai vari applicativi di nostro interesse, saremo tra poco chiamati a modificare una copia di uno script. In quel caso, ed in ogni altra occasione in cui sarà necessario, si dovrà solo premere la scelta rapida per la modifica,
Alt+M
, per tornare al campo d’inserimento su più righe.

A questo proposito, va chiarito che, nella finestra di scelta, le azioni da compiere sono comunque riepilogate a video in una sola riga, così come succede con le macro testuali. Nel caso di più azioni, per distinguerle, tra ciascuna di esse è posto un separatore di voce, la coppia di quadre aperta e chiusa con dentro i due punti esclamativi.

Elaborare gli ambiti degli script.

Trattiamo a parte questa schermata poiché, pur essendo anch’essa prodotta dalla più volte citata funzione nativa di scelta, essa rimane la stessa sia nella fase di creazione degli script, sia in fase di rielaborazione.

L’elenco degli ambiti, come già detto, è infatti costituito sia da dei dati fissi predefiniti, sia dall’elenco dei tipi di finestra registrati. Per questo, l’ambito da impostare può essere solo selezionato e confermato scegliendolo dall’elenco, come ad esempio
Esce
, che esegue lo script personale simulando poi l’uscita dall’applicazione attiva e salvando il documento corrente.

Questa schermata, essendo l’ultimo campo da elaborare, mantiene disponibile soltanto il pulsante per tornare indietro, il campo con le azioni da compiere, e quello per tornare alla finestra principale, premendo la scelta rapida
"Alt+T"
. Alla prima schermata si tornerà anche in caso di conferma con Invio all’ambito desiderato, scelta che porterà alla registrazione di tale termine.

A prescindere dalla via per la quale si torni alla prima schermata, qui sarà comunque eseguito un controllo sull’esistenza, tra gli script presenti nell’archivio, di quello eventualmente creato o aggiornato.

Interrompere la creazione di uno script.

Come abbiamo già esaminato nella funzione
NumeroDati ()
, la procedura controlla e richiede che i dati specificati in una procedura guidata a più campi, siano sempre nel numero impostato come massimo. Nel caso degli script a gestione personale, tale limite è fissato a cinque, tanti sono i campi per i quali impostare o selezionare un dato.

Per questo, prima di uscire dalla procedura, viene sempre eseguito un controllo sul fatto che i dati inseriti siano completi. Se così non fosse, sarebbe proposta una conferma tramite la quale l’Utente viene avvisato che, confermando l’uscita, i record incompleti saranno cancellati.

Per provare questa, ed altre, funzionalità della procedura per gli script a gestione personale, seguite allora questi passi.

  1. Se siete usciti dalla procedura, o se non siete nemmeno nell’Editor di Jaws, rientrate dapprima in quest’ultimo, poi avviate la procedura di elaborazione degli script a gestione personale, premendo
    Shift+Control+TastoJaws+0
    . Una volta avviata, in qualsiasi momento, per sapere esattamente in quale fase vi trovate, potete premere la combinazione
    "Insert+T"
    ; grazie al nostro script abbinato ai tasti citati,
    TitoloFinestra ()
    , se esiste un messaggio da noi impostato, esso sarà pronunciato al posto delle solite informazioni fornite da Jaws circa la finestra attiva.
  2. La prima schermata della procedura dovrebbe contenere ancora l’unico script da noi creato,
    "CancellaRiga ()"
    ; provate allora ad inserirne uno nuovo, cliccando sul pulsante
    "Aggiunge"
    , oppure premendo la scelta rapida
    "Alt+I".
  3. Nel campo d’inserimento che si propone, mettete un nome a caso, poiché di questo script non concluderemo la procedura, ad esempio
    "Pippo".
  4. Una volta premuto Invio per confermarlo, sarà dunque proposta l’interfaccia di attesa immissione tasti. Qui, provate subito a premere il tasto Escape; alla richiesta di conferma all’uscita, cliccate sull’opzione predefinita, il pulsante
    "Annulla"
    , per tornare all’inserimento.
  5. Qui provate allora a premere Invio, senza non aver specificato alcuna combinazione di tasti, e la procedura come detto vi avviserà sul fatto; confermate anche in questo caso la scelta predefinita, che è quella di tornare di nuovo all’inserimento.
  6. Ora provate invece a premere dei tasti abbinati ad uno script nativo di Jaws, ad esempio
    TastoJaws+FrecciaSu
    per leggere la riga corrente; la procedura vi avviserà che i tasti sono già utilizzati, chiedendo conferma alla loro sovrascrittura; come detto nelle note relative, la stessa cosa capita qualora i tasti premuti fossero utilizzati da un vostro script tradizionale, ad esempio
    Alt+F4
    occupati da
    EsceProgramma ()
    . In ogni caso, premete ancora una volta Invio per attivare la scelta predefinita, cioè il ritorno all’inserimento.
  7. Ora invece terminate davvero la fase di elaborazione, premendo Escape o Invio, ed in ogni caso passate all’altro pulsante per confermare l’abbandono dell’inserimento. Tornerete in questo modo alla schermata principale, avendo comunque selezionata la voce con il nome da voi assegnato a questo script di prova.
  8. Ora premete Escape, per uscire dalla procedura; essa allora vi proporrà una finestra di dialogo dal contenuto come il seguente:
  9. 
    1 record, Pippo, con dati incompleti.
    Continuando, tali record saranno rimossi.
    

  10. Il cursore sarà posizionato sul pulsante
    "Annulla"
    che, se confermato, vi riporterà dentro alla procedura per completare l’immissione dei dati necessari allo script; se invece dovete eliminare lo script incompleto, così come in questo caso, andate al pulsante
    "Ok"
    , e confermatelo; un messaggio vi avviserà dell’esito della rimozione.

Duplicare gli script negli altri applicativi.

Quando noi impostiamo uno script a gestione personale, se confermiamo una scelta con Invio nell’ultimo campo degli ambiti, una copia del nostro script viene registrata in una sezione speciale del nostro file di configurazione personale. Per questo motivo, nella prima schermata della procedura, esiste anche il pulsante per duplicare uno di quelli presenti nel citato archivio.

Una volta premuto il pulsante
"Duplica dall’elenco"
, o la scelta rapida
"Alt+D"
, verrà visualizzato l’elenco degli script a gestione personale da voi realizzati, per tutte le applicazioni. Da questo elenco si potrà selezionare lo script desiderato, che premendo Invio sarà aggiunto a quelli validi per l’applicazione attiva in quel momento.

Oltre a questa duplicazione diretta, quando non esistono ancora degli script di questo tipo per un qualche applicativo, esiste un altro modo per copiarli dall’archivio, che andremo subito a sperimentare.

Inseriamo CancellaRiga nel Blocco Note.

Per prima cosa aprite il Blocco Note, con un documento anche vuoto, quindi avviate la procedura per gli script a gestione personale con
Shift+Control+TastoJaws+0
. Se la procedura non si avvia, nonostante abbiate comunque registrato il tipo
"Editing"
come finestra per l’applicazione, provate a premere due volte velocemente la combinazione per attivare la modalità Aiuto, e sentire quale potrebbe essere il problema.

Una volta avviata la procedura, non avendo ancora impostato nulla per questa applicazione, sarà proposta la solita finestra di dialogo che avvisa della mancanza, e chiede se inserire un nuovo script. Stavolta, anziché confermarla, premete il tasto Escape a tale richiesta, e sarà proposta una finestra di scelta con questo contenuto:


Selezionare lo script da duplicare. Ok conferma, Esc annulla.

Il cursore sarà posizionato sull’unica voce presente nell’archivio, quella del nostro script per rimuovere la riga sul cursore, e le informazioni fornite saranno le seguenti:


CancellaRiga. Shift+Alt+J. Elimina il contenuto della riga sul cursore.

Come potete notare, sono riportati di ciascuno script, oltre ovviamente al nome da noi assegnato, anche i tasti di attivazione ed il testo del sommario, o almeno i suoi primi 120 caratteri. Per questo motivo, quando si parlava del sommario, si era indicato di provare a rispettare tale limite.

In ogni caso, per inserirlo tra gli script a gestione personale per il Blocco Note, basterà premere Invio; dopo essere tornati sulla finestra di elaborazione, un avviso vi informerà sull’esito della copia.

A questo punto, potete provare anche a cliccare il comando ufficiale, per duplicare uno script dall’archivio, premendo
"Alt+D"
; Sarà emesso un segnale acustico d’errore, e verrà visualizzato anche l’avviso che non è possibile alcuna duplicazione, in quanto, come già detto, dall’elenco degli script a disposizione sono tolti quelli con un nome già presente tra quelli attivi per l’applicazione, e quindi proprio il nostro
"CancellaRiga ()"
che è l’unico già presente.

Inserire CancellaRiga () anche in Microsoft Wordpad.

Dentro a Wordpad, in modo diverso dagli altri due editor finora trattati, sono sempre selezionati anche i caratteri di controllo a fine riga, Ascii 13 e 10, quando si utilizzano i comandi di selezione del sistema. Per tale ragione, i comandi da far eseguire tramite il nostro script a gestione personale sono diversi, anche se più semplici, rispetto a quelli che avevamo inserito in precedenza.

Non ci limiteremo, dunque, a copiare lo script archiviato, ma lo modificheremo nel solo campo che riguarda tali comandi. Approfitteremo della variazione, infine, per aggiornare i dati memorizzati nell’archivio, così da poterli utilizzare nell’ultimo applicativo di nostro interesse.

Provate quindi a seguire questi passi:

  1. Aprite Microsoft Wordpad, con un documento anche vuoto, e ripetete i passaggi per copiare il nostro script
    CancellaRiga ()
    dall’archivio personale.
  2. Premete in sequenza per tre volte consecutive la scelta rapida per passare al campo successivo,
    "Alt+U"
    . Fate attenzione a ripetere la pressione solo quando sia stata già proposta la nuova schermata, considerando la necessaria lentezza della procedura.
  3. Quando arrivate nel campo per elaborare le azioni, premete
    "Alt+M"
    per avviare la modifica, e sarà proposto il solito spazio d’inserimento con i dati attuali registrati su più righe. Modificate la forma presente con quella indicata di seguito, dove i comandi passano, da cinque che erano, a tre soltanto:
  4. 
    Home
    Shift+End
    Delete
    

  5. Ricordatevi di premere Control+Invio ad ogni fine riga, quindi concludete la modifica confermando con Invio.
  6. tornate ora alla prima schermata, premendo
    Alt+T
    . Poiché è stata operata una modifica, la procedura vi chiederà se volete aggiornare la copia dello script
    "CancellaRiga ()"
    registrata nell’archivio personale. Approfittate di questa occasione, e spostatevi sul pulsante
    "Ok"
    per dare la conferma alla sovrascrittura dei dati esistenti, e sarete informati sull’esito di tale registrazione.

Registrare CancellaRiga anche in Microsoft Word.

Concludiamo il giro tra gli applicativi di nostro interesse trattando il software principale del pacchetto Office. Qui in realtà faremo molto presto, in quanto basterà duplicare la copia registrata, seguendo gli stessi passi compiuti con il Blocco Note. Esattamente come in quel caso, poi, se avete salvato le modifiche apportate con Wordpad, i comandi dovrebbero andare bene così come sono.

Diversamente, come compito per casa, spetta a voi adattarne la forma affinché possano funzionare anche in questo programma.

Eseguire con i tasti gli script a gestione personale.

A prescindere dal fatto che abbiate provato ad eseguire il nostro script
CancellaRiga ()
direttamente da dentro la procedura, è chiaro che tale opzione può essere utile in prevalenza quando si apre la stessa procedura per un altro motivo, come il primo inserimento dello script o una sua modifica successiva.

Anche nel caso dei nostri speciali script, quindi, il modo normale di attivarli è quello di agire sui loro tasti di attivazione. Per raggiungere tale obiettivo, però, ci manca un fondamentale passaggio, che forse qualcuno di voi ha già individuato.

Per capire quale esso sia, provate ad attivare l’unico script fin qui realizzato, premendo i tasti
Shift+Alt+J
. Potete farlo da qualsiasi punto, senza nessun problema, in quanto Jaws non cancellerà nulla, e si limiterà a proporvi il seguente messaggio d’errore:


chiamata ad uno script sconosciuto per:
EseguePersonali1

Come avevamo anticipato nel Capitolo 11, il nome conosciuto da Jaws dei nostri script a gestione personale è quello reale, composto da una base comune,
"EseguePersonali"
, ed un suffisso numerico. Così, mentre il nome da noi dato al nostro script è
"CancellaRiga ()"
, esso, per Jaws, ha il nome mostrato nell’avviso.

Poiché noi abbiamo stabilito di poter creare un massimo di 99 script a gestione personale, sia pure per ciascun applicativo, è dunque necessario che noi si realizzi una serie di script con il nome base illustrato, ed un suffisso numerico da 1 a 99.

Ed è ciò che ora andremo a fare.

Esercizio 14.7.15. Lo script EseguePersonali1.

FileScript.

Default.JSS

Nome.

EseguePersonali1

Note.
  1. Come potete notare, il nostro script base deve essere privo di documentazione, in quanto saremo noi di volta in volta a crearla compilando tutti i campi della nostra procedura guidata. E tanto meno servono dei tasti di attivazione, che saremo noi a decidere, non adesso, bensì di volta in volta che andremo ad elaborare uno script a gestione personale.
  2. Per realizzare il prototipo dello script, quindi, sarà sufficiente entrare nella schermata di Jaws per la creazione di un nuovo script, digitare il nome, poi passare nel campo successivo dove premere una volta la barra spazio, quindi premere Invio per tornare all’Editor.
  3. Quello che guadagniamo in documentazione, tuttavia, lo dobbiamo investire nel codice, in quanto non sarà sufficiente la sola istruzione di richiamo alla funzione di gestione dei dati. O meglio, tale chiamata sarà condizionata ad un controllo sul fatto di non essere già in una nostra procedura, ad esempio come quella di elaborazione guidata, momento in cui i tasti premuti saranno invece reindirizzati verso l’applicazione sottostante.

Codice.


Script EseguePersonali1 ()
If !InHJDialog () Then; se non si è dentro ad una procedura di Jaws,
GestisceDato (); chiama l’apposita funzione
Else; altrimenti,
TypeCurrentScriptKey (); ripete la pressione dei tasti di attivazione dello script
EndIf; fine controllo dialogo
EndScript

Collaudo.

  1. Dopo aver compilato lo script, assicuratevi di essere con il cursore al suo interno, quindi eseguite quello nostro per creare le serie, tramite la pressione di
    Shift+Control+Windows+P.
  2. Subito, prima di poter specificare quanti nuovi script creare, sarete avvisati che quello su cui siete posizionati,
    EseguePersonali1 ()
    , non ha alcun tasto di attivazione registrato. Confermate la prosecuzione.
  3. Una volta proposto il numero di script da realizzare, andate fino in fondo per selezionare il numero 99, quindi confermate la successiva richiesta.
  4. Dato l’ingente numero, dovrete attendere almeno un paio di minuti per concludere il lavoro, il cui stato di avanzamento vi sarà fornito dal numero progressivo dello script in elaborazione.
  5. Al termine, createvi una riga da poter cancellare, in uno qualsiasi degli applicativi da voi trattati, e premete la combinazione scelta in fase di primo inserimento,
    Shift+Alt+J.
  6. Se tutto funziona, allora avete finito, ma finito per davvero! Per concludere solo qualche consiglio, e poi l’unico limite sarà la vostra fantasia!

Altri esempi di script a gestione personale.

Proponiamo di seguito altri quattro esempi di speciali script, che possono essere validi soprattutto per l’Editor di Jaws, ma che almeno come spunto si possono adattare anche ad altri applicativi.

I dati da inserire nei cinque campi degli script sono preceduti da un’etichetta che ne ricorda la funzione, in modo analogo a quanto si è fatto nelle schede per gli elementi di codice.

Andare al numero di riga.

Questo script è utile per chi è abituato a seguire i tasti funzione del pacchetto Office della Microsoft. Così come in Word ed in Excel, ad esempio, premendo
"F5"
ci si sposta ad uno degli elementi selezionabili, in modo più lineare dentro agli editor testuali, come quello di Jaws ed il Blocco Note, tramite la scelta rapida
"Control+G"
si attiva il comando di spostamento al numero di riga da inserire poi nel campo di editazione. Inoltre, poiché potrebbe essere utile, o necessario, tornare al punto dal quale si è attivato il comando, si può usare come ambito la parola chiave
Salva
, la quale crea un contrassegno di quelli temporanei, che sono comunque salvati nell’elenco degli ultimi memorizzati.

Nome.

VaiA

TastiAttivazione.

F5

Sommario.

Consente di muoversi in un determinato punto del documento.

Azioni.

Control+G

Ambito.

Salva

Salvare una copia del documento corrente.

Prendendo spunto dall’esempio precedente, nel pacchetto Office con il tasto funzione
F12
si fa comparire la finestra di dialogo per creare una copia del documento corrente. con i dati posti di seguito, invece, si porta questo comando nell’Editor di Jaws, sfruttando i comandi del menu File.

In questo caso, come ambito di utilizzo, si può mettere il termine
Chiude
, che simula l’abbandono del documento corrente, ma senza uscire dall’applicativo.

Nome.

SalvaConNome

TastiAttivazione.

F12

Sommario.

Consente di salvare una copia del documento corrente.

Azioni.

Alt+F[!!]C

Ambito.

Chiude

Tagliare il contenuto della riga negli appunti.

Lo script proposto funziona negli editor testuali, come quello di Jaws ed il Blocco Note. Allo stesso modo di quello appena realizzato,
CancellaRiga ()
, la forma sarebbe un po’ diversa per Microsoft Word e Wordpad, in quanto non serve l’ultimo comando di cancellazione per eliminare la riga vuota.

Nome.

TagliaRiga

TastiAttivazione.

Alt+JAWSKey+UpArrow

Sommario.

Taglia il contenuto della riga corrente negli appunti.

Azioni.

Home[!!]Shift+End[!!]Control+X[!!]Delete

Ambito.

Nessuno

Scorrere i nomi degli ultimi file dall’alto in basso.

Spesso negli applicativi è possibile riaprire un documento, presente nell’elenco degli ultimi file aperti, digitando il numero progressivo che lo stesso documento occupa nell’elenco. Ciò presuppone, tuttavia, che si conosca a memoria tale elenco, oppure si può andare a tentativi. Lo script che si propone, invece, risale il menu file posizionandosi sul primo dei documenti elencati, potendoli così scorrere dal più recente al più vecchio.

Anche in questo caso la versione proposta funziona nell’Editor di Jaws, sebbene nelle sue ultime versioni che hanno fino a dieci documenti elencati, e per questo bisogna inserire ben undici comandi di Freccia in su,
"UpArrow"
, in inglese. Qualora si usi ancora la precedente versione, che ne fornisce solo quattro, può essere conveniente anche solo risalire a mano il menu, oppure è necessario ridurre i comandi di spostamento verso l’alto, a solo cinque occorrenze.

Nome.

UltimiFile

TastiAttivazione.

Alt+E

Sommario.

Si porta sull’elenco degli ultimi documenti elaborati.

Azioni.

Alt+F[!!]UpArrow[!!]UpArrow[!!]UpArrow[!!]UpArrow[!!]UpArrow[!!]UpArrow[!!]UpArrow[!!]UpArrow[!!]UpArrow[!!]UpArrow[!!]UpArrow

Ambito.

Nessuno

***

Riepilogo.

Il percorso per arrivare sin qui è stato davvero lungo, causa la volontà di essere didascalici nelle spiegazioni del codice, e di ciò chiediamo scusa. La speranza è quella di aver dato qualche utile informazione e, casomai, di aver fatto venir voglia a qualcuno di tirarsi su le maniche.

Un grazie va rivolto a tutti per la pazienza e l’attenzione che sono state dedicate a queste pagine. Un ringraziamento particolare va a Nunziante Esposito, che mi ha sempre sostenuto anche nei momenti più difficili di quest’opera, ed a Franco Mazzon, che ospita la versione aggiornata e con il download del codice, sul suo sito all’indirizzo www.norobot.it.

Speriamo, almeno, sia stato apprezzato l’approccio, con una didattica progressiva intervallata dagli esempi pratici, tentando così di costruire un qualcosa che ancora non c’era. Ora, esaurito questo viaggio negli script per Jaws, il percorso potrebbe continuare verso altri linguaggi ed altri ambienti, sempre alla ricerca di una migliore autonomia al computer.

E dopo migliaia di parole, ne restano da dire in sostanza solo altre due: buon lavoro!

L’Autore

Download

File script da scaricare, per gli utenti di Jaws fino alla versione 18
Archivio da scaricare, per gli utenti dalla versione 2018 in poi

Per ulteriori spiegazioni, scrivere a:

Abramo Volpato