Logo dell'UIC Logo TUV

Unione Italiana dei Ciechi e degli Ipovedenti ETS - APS

 

Uiciechi.it

torna alla visualizzazione del numero 05 del Uiciechi.it

Numero 05 del 2021

Titolo: Gli script di Jaws 12. La ricerca rapida di stringhe predeterminate. (3)

Autore: Abramo Volpato.


Articolo:
Gli script di Jaws 12. La ricerca rapida di stringhe predeterminate.

Di Abramo Volpato.

Terza parte.

Esercizio 12.5.4. La funzione AnnullaProgrammato.

FileScript. Default.JSS

Nome. AnnullaProgrammato

Descrizione. Annulla un eventuale avvio programmato di una funzione.

Ritorni. Di tipo Void. Nessuno.

Novità.

1. La funzione integrata "UnScheduleFunction ()", già illustrata nella premessa.

Note.

1. La struttura di controllo che compone la funzione è in sostanza la stessa che abbiamo proposto nell'esempio d'utilizzo del sistema citato nella premessa, nella parte che contiene la funzione integrata "UnScheduleFunction ()"; in più, abbiamo posto solo un'istruzione che annulla il valore dell'avvio programmato, in questo caso memorizzato in una variabile globale, anche per segnalare agli altri elementi di codice l'assenza di questo tipo d'impostazione.

Codice.

Void Function AnnullaProgrammato ()
If gnProgrammato Then; se l'avvio programmato era stato impostato,
UnScheduleFunction (gnProgrammato); lo annulla,
Let gnProgrammato = FALSE; e resetta il valore
EndIf; fine controllo programmazione
EndFunction

Esercizio 12.5.5. La funzione SpostaAElemento.

FileScript. Default.JSS

Nome. SpostaAElemento

Descrizione. Muove il cursore alla colonna in cui inizia l'elemento trovato.

Ritorni. Di tipo Void. Nessuno.

Parametri.

1. sElemento. Il testo cui spostare il cursore. Di tipo String.

2. iPartenza. La colonna di partenza della ricerca. Di tipo Int.

Novità.

1. La funzione integrata "SayFromCursor", (LeggiDalCursore); Pronuncia il testo a partire dal cursore sino al termine della riga corrente.

2. La costante "ARRIVO", la quale contiene il nome di un file audio usato per segnalare lo spostamento al punto desiderato.

Fasi.

1. Le prime due strutture di controllo servono a calcolare la colonna sulla quale dovrebbe posizionarsi il cursore dopo aver trovato l'elemento, dato che ci si dovrebbe comunque trovare nella riga corretta.

2. La successiva struttura rileva invece la colonna corrente del cursore, tramite la funzione nativa di Jaws, oppure leggendo dalla Barra di Stato, sulla base del valore impostato nell'apposita variabile globale.

3. Se non si riesce a leggere la posizione del cursore, un controllo consente casomai di portarsi ad inizio riga; se invece la posizione corrente e quella definitiva sono diverse, viene avviato un ciclo che si sposta di tanti caratteri quanti sono quelli di differenza tra le due posizioni, in avanti o indietro a seconda del valore positivo o negativo del valore di confronto.

4. In ogni caso, viene emesso un segnale acustico, riattivata la sintesi e pronunciato il testo a partire dalla colonna individuata sino a fine riga, tramite la funzione integrata "SayFromCursor ()".

Codice.

Void Function SpostaAElemento (string sElemento, int iPartenza)
Var
Int iPosiz, ; posizione dell'elemento da sinistra nella riga
Int iContraria, ; posizione dell'elemento da destra
Int iAttuale, ; posizione corrente del cursore
Int i; contatore del ciclo

If gnVerso == AVANTI Then; se è attiva la ricerca verso il basso,
; registra la posizione dell'elemento, aggiungendo il valore di partenza
Let iPosiz = iPartenza + StringContains (gsRiga, sElemento)
Else; altrimenti, se si sta cercando verso l'alto,
; registra la posizione, invertendo la stringa in cui cercare
Let iContraria = StringContains (StringReverse (gsRiga), StringReverse (sElemento))
; calcola l'effettiva posizione del cursore, partendo da sinistra
Let iPosiz = StringLength (gsRiga) - ((iContraria + StringLength (sElemento)) - 2)
EndIf; fine controllo posizione
If !iPosiz Then; se per qualche motivo il valore è a zero,
Let iPosiz = PRIMA; imposta il valore alla prima colonna
EndIf; fine controllo colonna finale
If !gnRilevamento Then; se il dato può essere rilevato direttamente,
Let iAttuale = ValoreColonna (); memorizza il numero della colonna corrente
ElIf gnRilevamento == 1 Then; se invece si è impostata la prima modalità alternativa,
Let iAttuale = StringToInt (InfoStato (COLONNA, IsSameScript ())); lo prende dalla Barra di Stato
EndIf; fine controllo rilevazione dati
If gnRilevamento == SECONDA Then; se si è impostato di portarsi comunque ad inizio riga,
If !InizioRiga () Then; se non si è già sulla prima colonna,
JawsHome (); si sposta ad inizio riga
EndIf; fine controllo posizione cursore
ElIf iAttuale != iPosiz Then; se invece la posizione corrente e quella definitiva sono diverse,
For i = 1 To Abs (iAttuale - iPosiz); esegue il numero assoluto degli spostamenti
If iAttuale < iPosiz Then; se la posizione corrente è minore della definitiva,
NextCharacter (); si muove di un carattere in avanti
Else; altrimenti,
PriorCharacter (); torna di un carattere all'indietro
EndIf; fine controllo direzione
EndFor; fine ciclo movimenti
EndIf; fine controllo posizioni
Suona (ARRIVO); avvisa dello spostamento
SpeechOn (); riattiva la sintesi
SayFromCursor (); legge dal cursore sino a fine riga
EndFunction

Esercizio 12.5.6. La funzione ScorreRighe.

FileScript. Default.JSS

Nome. ScorreRighe

Descrizione. Gestisce la scansione delle righe nel documento, cui sottoporre la ricerca degli elementi preventivamente registrati; il suo lavoro potrà concludersi impostando il riavvio programmato di sé stessa, nel caso di mancato ritrovamento, o fermando la ricerca, nel caso di pressione del tasto Escape.

Ritorni. Di tipo Void. Nessuno.

Parametri.

1. iPartenza. La colonna da cui è partita la ricerca degli elementi. Di tipo Int.

Novità.

1. Le nostre funzioni "PosizioneDocumento ()", "CercaElementi ()", "AnnullaProgrammato ()" e "SpostaAElemento ()".

2. La funzione integrata "ScheduleFunction ()", già presentata nella premessa.

3. La funzione integrata "NextLine ()", che già avevamo incontrato nel secondo capitolo, ma che soltanto ora inseriamo nel nostro codice. Se ricordate, il suo compito è quello di spostare il cursore alla riga sottostante; ha un parametro opzionale, con il quale si può indicare da quale periferica, tastiera, Barra Braille o Mouse, questo comando sia impartito, ma in genere non serve indicarlo.

4. La costante testuale "SCORRE_RIGHE", che contiene il nome di questa stessa funzione, e che dal suo interno viene posta come il soggetto cui sottoporre l'avvio programmato.

5. Le costanti numeriche "INDIETRO" "MAX_RICERCA" e "MAX_RIGHE", equivalenti nell'ordine ai numeri 2, 3000 e 10, il primo indicante la direzione all'indietro, il secondo quanti millesimi deve durare al massimo un ciclo di ricerca, ed il terzo il numero massimo di righe consecutive che devono essere registrate per determinare di essere giunti ad una delle estremità del documento.

Fasi.

1. Come impostazioni iniziali, si fa pronunciare un messaggio, chiamando la nostra funzione "PosizioneDocumento ()",quindi si rileva la posizione corrente del cursore, si cancella l'eventuale impostazione precedente con la nostra "AnnullaProgrammato ()", e si predispone un nuovo avvio della funzione dopo circa tre secondi, tramite la funzione nativa "ScheduleFunction ()".

2. Inizia poi il ciclo di ricerca, che terminerà quando sarà trovato un elemento testuale, e quindi rimosso l'avvio programmato, oppure quando sarà trascorso il tempo massimo consentito.

3. La riga sul cursore viene così acquisita, e poi ripulita da caratteri e spazi inutili; se ancora non vuota, il suo contenuto viene passato alla funzione di ricerca vera e propria, la nostra "CercaElementi ()", .

4. Se la ricerca ha avuto buon esito, si cancella nuovamente il riavvio, interrompendo così il ciclo, e l'elemento testuale restituito viene passato all'altra nostra funzione, "SpostaAElemento ()", che posiziona il cursore alla colonna dove è stato trovato, leggendone infine la parte rimanente di riga.

5. Se invece non si è rilevato alcun elemento, dapprima si controlla che non sia stato premuto il tasto Escape, che causerebbe l'interruzione della ricerca; se così non è, ci si sposta alla riga successiva o precedente, tramite le funzioni integrate "NextLine ()" e "PriorLine ()", dove la riga corrente viene rilevata e portata in minuscolo per il confronto.

6. Viene quindi confrontata la posizione corrente del cursore con quella precedente e, qualora ci si sia mossi di una riga in basso o in alto, il ciclo continua; altrimenti, si annota tale ripetizione in una variabile globale; quando questa variabile, dopo una serie di righe uguali, raggiunge il valore massimo stabilito, si dà per assunto che si sia giunti ad uno degli estremi del documento, impostando il relativo valore ed interrompendo il ciclo.

7. Una volta terminato il ciclo, qualora non sia programmato alcun riavvio della funzione, se si è alle estremità del documento, viene letto un appropriato messaggio; altrimenti, viene pronunciato solo il contenuto della riga corrente.

8. Se, infine, la funzione deve riavviarsi dopo il tempo programmato, il flusso termina senza alcuna altra azione, nell'attesa di una nuova chiamata.

Note.

1. Nel caso in cui non si trovi un elemento, il nuovo avvio programmato non è la conseguenza della fine del ciclo di ricerca: il fatto che l'uno finisca quando inizia l'altro, ovvero la sincronizzazione tra essi, viene creata dall'uso dello stesso valore, quello della costante "MAX_RICERCA", sia per i decimi di ritardo dell'avvio programmato, divisi per il valore 100, sia per i millesimi trascorsi dall'inizio del ciclo, confrontati con il risultato della funzione nativa "GetTickCount ()".

2. a proposito del valore reimpostato nella costante "MAX_RICERCA", se ne è usato uno in millesimi per avere un confronto diretto con il risultato della citata funzione nativa, che viene effettuato ad ogni iterazione del ciclo, mentre la divisione per 100 dell'altro valore viene effettuata solo ad ogni nuova chiamata della funzione, e corrisponde ai tre secondi di ciclo massimo citati nella premessa.

3. Le righe consecutive che si devono contare per causare l'interruzione del lavoro sono inizialmente impostate a 10; è comunque in teoria possibile che anche dentro ad un documento vi siano una serie di almeno dieci righe consecutive, ad esempio vuote, ed in questo caso la procedura si fermerebbe anche senza aver raggiunto i limiti del documento; qualora si sia soliti utilizzare documenti con queste caratteristiche, è sempre possibile aumentare il numero di ripetizioni, anche se questo crea un ritardo nel cogliere l'eventuale fine reale del documento stesso.

Codice.

Void Function ScorreRighe (int iPartenza)
Var
Int iStart, ; tempo d'inizio della procedura
String sTesto, ; testo senza spazi e tabulazioni
String sElemento, ; singolo elemento di ricerca
Int iEstremi; indicatore di raggiunto limite del documento

If !iPartenza Then; se non si è all'inizio della ricerca,
PosizioneDocumento (); legge la percentuale o le righe del documento corrente, oppure altri tipi di avviso
ElIf gnVerso == INDIETRO Then; se in ogni caso la ricerca è verso l'alto,
Let iPartenza = FALSE; resetta il valore
EndIf; fine controllo parametri
Let iStart = GetTickCount (); registra il momento d'inizio della procedura
; lancia l'eventuale nuovo avvio programmato della funzione
AnnullaProgrammato (); resetta la programmazione di una nuova ricerca
Let gnProgrammato = ScheduleFunction (SCORRE_RIGHE, MAX_RICERCA / 100)
; continua il ciclo finché la programmazione non sia interrotta o si superi il tempo massimo
While gnProgrammato && (GetTickCount () - iStart) < MAX_RICERCA
; rimuove dalla stringa memorizzata spazi iniziali e finali, e caratteri di tabulazione
Let sTesto = TagliaSpazi (ToglieTab (gsRiga))
If sTesto Then; se vi è ancora del contenuto nella riga,
Let sElemento = CercaElementi (sTesto, iPartenza); esegue la ricerca degli elementi
If sElemento Then; se un elemento è stato trovato,
AnnullaProgrammato (); resetta la programmazione di una nuova ricerca
SpostaAElemento (sElemento, iPartenza); sposta il cursore all'inizio dell'elemento trovato,
Return; e interrompe il flusso
EndIf; fine controllo esito
EndIf; fine controllo testo
If gnProgrammato Then; se nessun elemento è stato ancora trovato,
If GetCurrentScriptKeyName () == ESC Then; se si è premuto il tasto Escape,
SpeechOn (); riattiva la sintesi
SayMessage (OT_ERROR, msgStopRicerca); avvisa dell'azione,
AnnullaProgrammato (); e resetta la programmazione di una nuova ricerca, interrompendo il ciclo
Else; altrimenti, se la ricerca continua,
If gnVerso == AVANTI Then; se la ricerca avviene verso il basso,
NextLine (); si muove alla riga successiva
Else; Altrimenti,
PriorLine (); torna alla riga precedente
EndIf; fine controllo direzione
Refresh (); resetta la schermata
Let gsRiga = StringLower (RigaCorrente ()); registra la riga sul cursore, portandola in minuscolo
If gsRiga == gsPrecedente Then; se la riga attuale è la stessa della precedente,
Let gnRipeti = gnRipeti + 1; aggiorna il contatore
Else; altrimenti,
Let gsPrecedente = gsRiga; aggiorna la variabile globale
Let gnRipeti = FALSE; e resetta il contatore
EndIf; fine controllo riga precedente
If gnRipeti < MAX_RIGHE Then; se non si è raggiunto il limite massimo delle ripetizioni,
If iPartenza Then; se il valore è impostato,
Let iPartenza = FALSE; lo resetta
EndIf; fine controllo impostazione iniziale
Else; Altrimenti, se si è raggiunta una delle due estremità del documento,
AnnullaProgrammato (); resetta la programmazione di una nuova ricerca
Let iEstremi = TRUE; annota la situazione
EndIf; fine controllo posizione
EndIf; fine controllo prosecuzione ricerca
EndIf; fine controllo ritrovamento e tasti premuti
EndWhile; fine ciclo ricerca
If !gnProgrammato Then; se non è impostato alcun riavvio della funzione,
SpeechOn (); riattiva la sintesi
If iEstremi Then; se è stata raggiunta un'estremità del documento,
If gnVerso == AVANTI Then; se ci si doveva muovere verso il basso, formatta e legge l'avviso
SayFormattedMessage (OT_ERROR, ttlContinuaCerca, StringChopLeft (msgFine, 3), _A, msgFine)
Else; altrimenti, in caso di ricerca verso l'alto, formatta e pronuncia l'avviso
SayFormattedMessage (OT_ERROR, ttlContinuaCerca, StringChopLeft (msgInizio, 2), _O, msgInizio)
EndIf; fine controllo direzione
EndIf; fine controllo estremi documento
SayLine ()
EndIf; fine controllo funzioni
EndFunction

Collaudo.

1. Anche se ci si trova alla fine di un corposo blocco, oltre a verificare il buon esito della compilazione, un primo collaudo del nostro codice lo potremo effettuare solo al termine del capitolo.

12.6. Gestione delle ricerche.

Realizzato lo strumento di ricerca, che ha coinvolto ben 25 funzioni, siamo infine giunti al codice che ci consente di cercare in modo rapido delle stringhe predeterminate, che abbiamo definito anche "Elementi di ricerca".

Si parte subito con il pezzo principale, che si occupa di gestire ogni tipo di ricerca rapida da noi prevista. Il suo nome è composto dall'azione svolta, "Muove", e dal classico suffisso "Dato", quest'ultimo già utilizzato più volte sinora.

Essa consente in particolare di cercare quattro tipi di elementi testuali:

1. I commenti ad inizio riga, dove il carattere Punto e Virgola è posto sulla prima colonna.

2. Singoli elementi di ricerca, richiamati direttamente da combinazioni tasti con suffisso numerico da 1 a 9.

3. Elementi di codice dentro all'Editor di Jaws, come stanno già facendo gli script "MuoveElementoSuccessivo ()" e "MuoveElementoPrecedente ()".

4. Gruppi di elementi testuali, di cui avviare la ricerca con gli stessi tasti dei due script appena citati, "Windows+FrecciaGiù" e "Windows+FrecciaSu", ma che ricercano i soli elementi impostati per l'estensione del documento corrente.

In realtà, per il momento riusciremo a testare solo il primo di questi tipi, realizzando i due script che concluderanno il capitolo, e ci consentiranno finalmente di effettuare un qualche collaudo. L'altra funzione elaborata in questo blocco finale è l'ennesima, e stavolta definitiva, versione di "GestisceDato ()", la quale si occupa materialmente di chiamare il principale elemento di codice, del quale inizieremo ad occuparci ora.

Esercizio 12.6.1. La funzione MuoveDato.

FileScript. Default.JSS

Nome. MuoveDato

Descrizione. Gestisce i vari tipi di ricerca di elementi nel documento corrente, determinando se utilizzare le funzioni native o se servirsi dell'apposita procedura.

Ritorni. Di tipo Void. Nessuno.

Parametri.

1. sEstensione. L'estensione del documento corrente, che determina i tipi di dati da cercare. Di tipo String.

2. sProg. L'eventuale numero progressivo che identifica l'elemento da ricercare. Di tipo String. Parametro Opzionale.

3. iAiuto. Se valorizzato con TRUE, attiva l'omonima fase. Di tipo Int. Parametro Opzionale.

Novità.

1. Le nostre funzioni "ArchivioDati ()", "CercaVoci ()", "MisuraMovimento ()" e "ScorreRighe ()".

2. La costante "PUNTO_VIRGOLA", che contiene l'omonimo carattere.

3. Le costanti "COMMENTO" e "SINGOLO", che equivalgono all'omonimo termine.

Fasi.

1. La prima via della struttura principale consente di raggiungere un commento nel codice, e consta soltanto nell'impostare il carattere Punto e Virgola come l'elenco degli elementi da cercare, e come conseguenza il valore 1 come numero di tali elementi.

2. La seconda via della struttura si occupa invece di trovare i singoli elementi di ricerca; per prima cosa viene riconvertita la categoria, poi si controlla l'esistenza dei file di configurazione, tramite la nostra funzione "ArchivioDati ()"; di seguito, si controlla che una stringa per l'elemento richiesto sia registrata, grazie alla nostra "CercaVoci ()"; se così non è, i tasti premuti per attivare gli script sono ripetuti, passandoli all'applicazione; altrimenti, il flusso continua, limitando anche in questo caso ad 1 gli elementi da ricercare.

3. La terza via della struttura è, come detto, la stessa funzionalità già coperta dall'attuale forma degli script per lo spostamento agli elementi di codice successivo e precedente; per questo, viene solo riproposto il contenuto di tale script.

4. La quarta via della struttura, quella che riguarda la ricerca dei gruppi di elementi, ripropone i controlli inseriti nella seconda, con la differenza che, nel caso non si trovino delle stringhe registrate del tipo indicato, il flusso viene semplicemente interrotto senza ripetere i tasti premuti; se invece gli elementi di ricerca sono stati trovati, ne viene inoltre creato un elenco, casomai ridotto, sulla base delle impostazioni attive.

5. Se non si sono verificati errori, il flusso esce dalla struttura principale ed imposta la direzione della ricerca, verso il basso o verso l'alto;

6. Poi, la nostra funzione "MisuraMovimento ()" approfitta della necessità di muovere il cursore di un carattere, al fine di evitare riletture durante le ricerche in sequenza, per controllare che Jaws riesca a leggere le righe e le colonne del documento; se anche così non fosse, il flusso comunque continua, e si interrompe solo qualora ci si trovi ad uno degli estremi del documento, pronunciando il messaggio relativo.

7. Infine, se tutto procede, sono impostati gli ultimi valori necessari al sistema, viene spenta la sintesi e chiamata la nostra funzione "ScorreRighe ()", che avvia materialmente la procedura di ricerca.

Note.

1. Nonostante nell'immediato si riesca a sfruttare solo la prima opzione tra le quattro consentite, così come detto nella premessa, la funzione è comunque già nella sua versione definitiva, predisposta a soddisfare anche gli altri tipi di ricerca previsti.

Codice.

Void Function MuoveDato (string sEstensione, string sProg, int iAiuto)
Var
String sSezione, ; nome della sezione da elaborare
Int iPartenza; colonna da dove è partita la ricerca

If gsCategoria == COMMENTO Then; se si sta cercando un commento ad inizio riga,
Let gsElenco = PUNTO_VIRGOLA; pone il carattere omonimo come unico elemento da cercare
Let gnTotali = 1; Imposta il valore
ElIf gsCategoria == SINGOLO Then; ancora, se il dato da cercare è un singolo elemento di ricerca,
Let gsCategoria = ELEMENTO; imposta la categoria reale
If !ArchivioDati () Then; se il file di configurazione è mancante o incompleto,
Return; interrompe il flusso
EndIf; fine controllo file configurazione
Let sSezione = gsCategoria + sEstensione; compone la sezione dove leggere i dati
Let gsElenco = StringLower (LeggeRecord (gsArchivio, sSezione, sProg)); tenta di rilevare il dato, portandolo casomai in minuscolo
If !gsElenco Then; se il dato non è registrato,
TypeCurrentScriptKey (); ripete i tasti premuti,
Return; e interrompe il flusso
EndIf; fine controllo dati
Let gnTotali = 1; Imposta il valore
ElIf SiamoNellaFinestra (MANAGER) ; se si è nell'Editor di Script,
&& sEstensione == JSS Then; e se si sta elaborando un file script,
If gsOggetto == SUCCESSIVO Then; se la ricerca è verso il basso,
TypeKey (F2); richiama il relativo comando originale
Else; altrimenti, se la ricerca è verso l'alto,
TypeKey (SHIFT_F2); richiama il relativo comando originale
EndIf; fine controllo direzione
Refresh (); resetta la schermata
SayLine (); legge la riga corrente,
Return; e interrompe il flusso
ElIf gsCategoria == ELEMENTO Then; se invece si deve cercare tra gli elementi registrati per l'estensione corrente,
If !ArchivioDati () Then; se il file di configurazione è mancante o errato,
Return; interrompe il flusso
EndIf; fine controllo archivio dati
Let sSezione = gsCategoria + sEstensione; compone la sezione dove leggere i dati
CercaVoci (sSezione, sEstensione); raccoglie i dati
If !gnTotali Then; se nessuna voce è ancora registrata,
Return; interrompe il flusso
EndIf; fine controllo numero voci
; compone la lista delle voci da cercare, portandole in caratteri minuscoli
Let gsElenco = StringLower (CreaElenco (gsArchivio, sSezione, PRIMA))
Let gnTotali = StringSegmentCount (gsElenco, BELL); aggiorna il numero delle voci valide per la ricerca
EndIf; fine controllo categorie
If gsOggetto == SUCCESSIVO Then; se la ricerca è verso il basso,
Let gnVerso = AVANTI; imposta il valore corrispondente alla direzione indicata
Else; altrimenti, se si deve cercare verso l'alto,
Let gnVerso = INDIETRO; imposta il valore corrispondente alla direzione indicata
EndIf; fine controllo direzione
If !MisuraMovimento (gnVerso, iPartenza) Then; se il cursore è fermo a fine o inizio documento,
Return; interrompe il flusso
EndIf; fine controllo spostamento
Let gsRiga = RigaCorrente (gnVerso); rileva il testo sulla base del verso impostato
Let gnPrimo = FALSE; azzera il valore per far leggere le istruzioni su come interrompere la ricerca
SpeechOff (); spegne la sintesi
ScorreRighe (iPartenza); chiama l'apposita funzione, specificando i parametri della ricerca iniziale
EndFunction

Collaudo.

1. Nell'attesa di poter finalmente provare il nostro lavoro, tra un paio di elementi, ricordatevi di porre come opzionali gli ultimi due parametri di questa funzione.

Esercizio 12.6.2. L'ultimo aggiornamento di GestisceDato.

FileScript. Default.JSS

Nome. GestisceDato

Novità.

1. Le costanti "ESEGUE", "MUOVE" e "METTE", che equivalgono tutte all'omonimo termine, le quali stanno ad indicare le azioni compiute dagli script legati alle diverse procedure da approntare.

Note.

1. Le modifiche alla precedente versione iniziano coll’eliminare la riga contenente l'istruzione "|| sAzione == TORNA Then", inserendo al suo posto le successive due righe di codice:

|| sAzione == TORNA ; o si vuole ritornarvi,
|| sAzione == ESEGUE Then; o, infine, se si vuole attivare uno script a gestione personale,

2. Poi, a partire dalla riga successiva all'istruzione "CallFunctionByName (sAzione + DATO, sNomeFile, sOggetto, sProg, iAiuto)", conviene eliminare tutto il codice fino al comando di fine funzione, "EndFunction", per inserire la restante parte della nuova versione:

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

3. Come al solito, è sempre possibile controllare il testo che segue, sostituendo tutto il codice con quello nuovo; anche in questo caso, come nella funzione precedente, la versione proposta sarà comunque quella definitiva.

Codice.

Void Function GestisceDato (string sAzione, string sOggetto)
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) Then; se non vi sono dati sul file aperto,
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

Esercizio 12.6.3. Lo script MuoveCommentoPrecedente.

FileScript. Default.JSS

Nome. MuoveCommentoPrecedente

Sommario. Si muove alla riga di commento precedente.

Descrizione. Cerca verso l'inizio del documento corrente la prima riga che inizia con il carattere Punto e Virgola, spostandovi se la trova.

TastiAttivazione. Shift+Windows+UpArrow

Codice.

Script MuoveCommentoPrecedente ()
GestisceDato ()
EndScript

Collaudo.

1. Giunti al primo script, una volta compilato correttamente, potremo già ora iniziare a raccogliere i frutti del nostro lavoro, ma chiediamo un altro briciolo di pazienza, quella che serve a realizzare anche il prossimo ed ultimo elemento del capitolo.

Esercizio 12.6.4. Lo script MuoveCommentoSuccessivo.

FileScript. Default.JSS

Nome. MuoveCommentoSuccessivo

Sommario. Si muove alla riga di commento successiva.

Descrizione. Cerca verso la fine del documento corrente la prima riga che inizia con il carattere Punto e Virgola, spostandovi se la trova.

TastiAttivazione. Shift+Windows+DownArrow

Codice.

Script MuoveCommentoSuccessivo ()
GestisceDato ()
EndScript

Collaudo.

1. Compilato lo script, portatevi all'inizio di una funzione di un certo volume, come le ultime "GestisceDato ()" o "MetteDato ()".

2. Premete i tasti di attivazione per la ricerca dei commenti verso il basso, "Shift+Windows+FrecciaGiù", e il cursore dovrebbe posizionarsi nella prima riga che inizia con il carattere Punto e Virgola.

3. Premete ancora una volta la stessa combinazione, per portarvi sulla seconda riga di commento, quindi provate a tornare al commento precedente, premendo "Shift+Windows+FrecciaSu"; dovreste tornare alla prima riga incontrata.

4. Questo sistema di ricerca rapida è utile, in particolare, quando in fase di messa a punto degli script, magari per fare una prova, si pone un carattere Punto e Virgola per impedire l'esecuzione di una particolare istruzione; poi, una volta concluso le modifiche, se gli script realizzati funzionano lo stesso, si potrà ripassare velocemente il codice eliminando in modo definitivo tutte le istruzioni che avevamo nascosto dietro un carattere di commento.

12.10. Riepilogo.

La sensazione potrebbe essere quella di una montagna che abbia partorito un topolino, data la mole del lavoro svolto nel capitolo e le poche applicazioni che siamo riusciti a concretizzare. Più di così, tuttavia, non si poteva proprio fare, almeno senza aver prodotto il codice che manca, ovvero quello che ci consente di avviare delle procedure guidate per l'inserimento delle stringhe testuali da cercare o inserire nei documenti.

Nel dettaglio, la ricerca del commento ad inizio riga è l'unica che possiamo realizzare in questo momento perché, appunto, è l'unico caso in cui l'elemento da ricercare non è solo "predeterminato", cioè stabilito a priori, bensì è "Predefinito", cioè già stabilito in modo definitivo ed invariabile nel carattere Punto e Virgola.

Per questo, l'obiettivo dei prossimi capitoli sarà quello di realizzare le procedure guidate che ci consentano di specificare, modificare o cancellare le stringhe da registrare, per poter poi essere utilizzate per la loro ricerca o il loro inserimento nei nostri documenti.

12.10.1. Elementi di Codice Personale.

ConverteInBell. File script: Predefinito. Funzione.
- Converte il carattere o la stringa indicati nel carattere Bell, Ascii 7.

ConfigurazioneCampi. File script: Predefinito. Funzione.
- Consente di impostare il file configurazione con le fasi delle procedure guidate.

FileUtente. File script: Predefinito. Funzione.
- Determina se il file specificato esista nella cartella delle Impostazioni personali.

ArchivioDati. File script: Predefinito. Funzione.
- Imposta in una variabile globale il nome dell'archivio dove leggere i dati, controllando l'esistenza ed il corretto funzionamento anche dell'apposito file relativo alla procedura.

PersonaFemminile. File script: Predefinito. Funzione.
- Determina quale vocale femminile restituire, sulla base del valore immesso come parametro.

PersonaMaschile. File script: Predefinito. Funzione.
- Determina quale vocale maschile restituire, sulla base del valore immesso come parametro.

ScambiaTitoli. File script: Predefinito. Funzione.
- Se si indica un primo parametro, esso viene registrato in una variabile globale riservata al titolo, salvando l'eventuale precedente contenuto in una variabile locale trasmessa per riferimento; inoltre, sarà azzerato il dato di un'altra variabile globale dedicata alle etichette dei pulsanti nelle finestre di dialogo, anche qui salvandone casomai il contenuto in una variabile locale trasmessa per riferimento. Nel caso in cui non si indichi un primo parametro, i valori delle variabili locali sono riassegnati alle rispettive variabili globali.

ChiedeConferma. File script: Predefinito. Funzione.
- Consente di proporre la finestra di dialogo in formato Windows, potendo personalizzare con i parametri titolo, messaggio, opzioni dei tasti, pulsante predefinito e presenza dei suoni. Ciascuna impostazione avrà comunque un valore predefinito, che consentirà anche di non indicare alcun parametro. In quest'ultimo caso, la funzione proporrà una conferma all'uscita dalla procedura.

ProsegueFlusso. File script: Predefinito. Funzione.
- Consente di proseguire o interrompere la creazione di nuovi elementi durante l'utilizzo di una procedura.

ComponeTermine. File script: Predefinito. Funzione.
- Controlla quale termine da formattare andrà restituito, sulla base del tipo di procedura attiva.

CreaElenco. File script: Predefinito. Funzione.
- Crea un elenco di elementi da utilizzare in ricerche e confronti.

InverteForma. File script: Predefinito. Funzione.
- Converte i caratteri di fine riga nei separatori di voce, lasciando vuoto il secondo parametro o ponendovi il valore FALSE, oppure, viceversa, dai separatori di voce ai caratteri di fine riga, ponendo TRUE nel secondo parametro. Come sequenza di fine riga, sarà utilizzata quella classica, Ascii 13 e 10, nel caso in cui come terzo parametro non sia indicato nulla, altrimenti si utilizzerà quella specificata.

InserisceTesto. File script: Predefinito. Funzione.
- Consente di inserire del testo in un normale campo d'immissione stile Windows; nel caso non si specifichi nulla, o si abbandoni l'inserimento, viene proposta una ulteriore conferma se uscire o se tornare all'immissione di testo. Se si specifica un elenco di stringhe testuali come quarto parametro, si controlla che il testo immesso non sia già presente nell'elenco, casomai costringendo a modificarlo. Se non si specifica nulla come quinto parametro, qualora si immetta anche un carattere Pipe, Ascii 124, viene segnalata la necessità di rimuoverlo.

ConfermaAzioni. File script: Predefinito. Funzione.
- Controlla se le azioni immesse corrispondano a dei tasti riconosciuti come validi, casomai consentendo di aggiungerli all'archivio di quelli memorizzati come tali sul file di configurazione personale.

ChiaveGlobale. File script: Predefinito. Funzione.
- Determina la chiave testuale, duplicando il dato registrato nella omonima variabile globale oppure, se questa è vuota, prendendo la prima dell'elenco memorizzato nella variabile globale riservata a questo tipo di dato.

ScriveCampo. File script: Predefinito. Funzione.
- Scrive il dato passato come parametro nel campo indicato del record specificato.

AggiornaCampo. File script: Predefinito. Funzione.
- Gestisce l'aggiornamento dei campi di un record.

CercaVoci. File script: Predefinito. Funzione.
- Rileva le voci di dati registrate nella sezione e nell'archivio della categoria specificata, consentendo di avviare l'inserimento della prima voce, qualora non ve ne siano ancora di presenti.

InizioRiga. File script: Predefinito. Funzione.
- Determina se il cursore attivo si trova all'inizio della riga corrente.

MisuraMovimento. File script: Predefinito. Funzione.
- Muove il cursore in avanti o indietro di un carattere, sulla base del valore indicato nel primo parametro, determinando se nel documento corrente la procedura riesce a rilevare la posizione del cursore come colonne e righe.

PosizioneDocumento. File script: Predefinito. Funzione.
- Pronuncia lo stato di avanzamento della ricerca, leggendo la percentuale elaborata del documento corrente, se rilevabile, oppure il numero della riga sul cursore.

CercaElementi. File script: Predefinito. Funzione.
- Scorre gli elementi da cercare, restituendo il primo elemento trovato nel testo passato come parametro.

AnnullaProgrammato. File script: Predefinito. Funzione.
- Annulla un eventuale avvio programmato di una funzione.

SpostaAElemento. File script: Predefinito. Funzione.
- Muove il cursore alla colonna in cui inizia l'elemento trovato.

ScorreRighe. File script: Predefinito. Funzione.
- Gestisce la scansione delle righe nel documento, cui sottoporre la ricerca degli elementi preventivamente registrati; il suo lavoro potrà concludersi impostando il riavvio programmato di sé stessa, nel caso di mancato ritrovamento, o fermando la ricerca, nel caso di pressione del tasto Escape.

MuoveDato. File script: Predefinito. Funzione.
- Gestisce i vari tipi di ricerca di elementi nel documento corrente, determinando se utilizzare le funzioni native o se servirsi dell'apposita procedura.

GestisceDato. File script: Predefinito. Funzione.
- Raccoglie le richieste di azioni sui dati, verificandone la correttezza e smistando il flusso verso gli opportuni elementi di codice.

MuoveCommentoPrecedente. File script: Predefinito. Shift+Windows+UpArrow.
- Si muove alla riga di commento precedente.

MuoveCommentoSuccessivo. File script: Predefinito. Shift+Windows+DownArrow.
- Si muove alla riga di commento successiva.

12.10.2. Script, Funzioni e Comandi di Jaws.

FileExists. (FileEsiste).
- Restituisce un valore positivo se esiste un file dal nome e dal percorso indicati.

IsScriptKey. (SonoTastiDiScript).
- Restituisce un valore positivo se si indicano tasti, o la combinazione di tasti, che possono attivare uno script.

GetPriorCharacter. (OttieniCaratterePrecedente).
- Restituisce uno o più caratteri che precedono la posizione del cursore attivo.

ScheduleFunction. (ProgrammaFunzione).
- Attiva l'avvio differito della funzione indicata come parametro iniziale, per i decimi di secondo specificati come ulteriore parametro.

UnScheduleFunction. (DeprogrammaFunzione).
- Cancella l'avvio differito di una funzione, qualora sia stato registrato nel valore numerico passato come parametro.

SayFromCursor. (LeggiDalCursore).
- Pronuncia il testo a partire dal cursore sino al termine della riga corrente.

12.10.3. Voci di Glossario.

elemento di ricerca.
- Stringa testuale da ricercare all'interno del documento corrente.

riga unica.
- Formato di un testo nel quale gli eventuali contenuti di più righe sono posti l'uno accanto all'altro, divisi tra loro da una speciale stringa di separazione composta da una coppia di parentesi quadre con dentro due punti esclamativi.

su più righe.
- Formato di un testo nel quale gli eventuali diversi contenuti sono suddivisi da normali caratteri di fine riga, Ascii 13 e 10.

avvio programmato.
- Richiamo di una funzione che avviene solo dopo il numero di decimi di secondo impostati.

Muove.
- Azione in cui si sposta il cursore verso una posizione o un elemento qualsiasi nel documento corrente.

Per ulteriori spiegazioni, scrivere a: Abramo Volpato, oppure, a: Nunziante Esposito



Torna alla pagina iniziale della consultazione delle riviste

Oppure effettua una ricerca per:


Scelta Rapida