4.2 Gestione dei documenti
4.2.2 Apertura dei documenti: Open e Recent
Con riferimento al menù File in Figura 4.1, la prima funzione che andremo a presentare è quella associata al pulsante "Open".
Premendo su questo pulsante (o utilizzando la scorciatoia da tastiera CTRL+O) apparirà la classica schermata di selezione le. In Figura 4.4 ne viene mostrato un esempio.
Attraverso questa schermata sarà possibile navigare attraverso il le sy- stem locale e selezionare il le da aprire.
Vengono forniti tre possibili tipi di le tra cui selezionare:
1. eXtensible Event Stream: questo tipo di le è quello denito per lo standard XES (la cui estensione è ".xes"). É il tipo di le principale che l'applicazione si pregge di gestire.
2. Comma-Separated Values: questo tipo di le identica i le CSV (la cui estensione è ".csv"). I le CSV sono le testuali il cui contenuto è scritto secondo le speciche di questo standard. Nel sistema i le CSV vengono utilizzati come formato alternativo per la denizione di log di eventi, quindi come possibile formato di export per documenti XES, come eventuale import traducibile in un documento XES e per poter scrivere e generare facilmente log di eventi in formato XES. Parleremo in dettaglio dei le CSV nella Sezione 5.1.
3. Plain Text: questo tipo di le identica i le testuali semplici (la cui estensione è ".txt"). Visto che il sistema si prestava già alla gestione di tipi di le testuali semplici (ovvero senza formattazione, i documenti XES e CSV ne sono un esempio), è stata data la possibilità di scrivere e aprire nell'applicazione qualsiasi le di questo tipo, in modo da poter scrivere o editare delle note ad esempio, oppure aprire e salvare log di eventi o documenti CSV su le di tipo TXT invece che nei formati più standard visti sopra.
Per ogni tipo scelto, la nestra mostra i le con quella estensione, in modo sia da rendere più facile la loro individuazione, sia per evitare che l'utente selezioni le di tipo dierente.
Il percorso del le selezionato a questo punto viene controllato, per veri- care che il le esista e sia eettivamente utilizzabile dal sistema. In caso ne- gativo, l'applicazione comunica con un messaggio questa situazione di errore e propone all'utente di selezionare un altro le da aprire.
Se il le selezionato risulta già aperto in un editor, il sistema porta que- st'ultimo in primo piano e poi informa l'utente con un messaggio, chiedendo di scegliere tra l'opzione di ricaricare il contenuto dell'editor presente nel sistema al quale il le scelto è associato, aprire un nuovo editor con all'in- terno il contenuto del le selezionato ma mantenendo l'editor già aperto con il contenuto presente e con l'associazione al le selezionato, oppure non fare nessuna azione e prendere come valido l'editor già aperto. In Figura 4.5 è mostrata la scelta che l'applicazione propone all'utente nel caso si verichi questa eventualità.
Una volta che il procedimento di selezione del le è completato, la funzione si preoccupa di leggere il contenuto del le ed inserirlo in un nuovo editor (che ricordiamo è un oggetto della classe EventLogEditor):
1 // try-with-resources Statement (close the resource automatically at the end in any case)
2 try (InputStream fileStream = new FileInputStream(selectedSourceFile); BufferedReader fileReader = new BufferedReader(new InputStreamReader(fileStream))) {
3 // if there is not a target editor to reload, it means we are opening a new file 4 if (targetEventLogEditor == null) {
5 // create a new event log editor set with the target file name, the target file content, the absolute path of the target file and its content as not
Figura 4.5: La funzione Open nel caso di le già aperto
6 elmController.newEventLogEditor(targetFile.getFileName().toString(), fileReader, selectedSourceFile, false);
7 } else { // if we have a target editor
8 if (openContentOnly) { // if we have to open a new editor with just the content in it
9 // create a new event log editor set with default name, the target file content, no absolute path and its content as modified
10 elmController.newEventLogEditor(null, fileReader, null, true); 11 } else { // if we have to reload the file instead
12 // set the new content
13 targetEventLogEditor.setTextAreaContent(fileReader);
14 // set the editor content as not modified (because now the editor has the same content of the associated file, so it is saved)
15 if (targetEventLogEditor.isContentModified()) {
16 // if not already set as false, set it
17 targetEventLogEditor.setContentModified(false);
18 // remove the asterisk (if the content is modified, the title has an asterisk at the end)
19 String savedTitle = targetEventLogEditor.getTitle();
21 elmController.modifyJInternalFrameTitles(targetEventLogEditor, savedTitle);
22 }
23 // set the editor content as not validated (because it is a new content)
24 targetEventLogEditor.setContentValidated(false);
25 // the title and the associated file are already set, then no needs to modify them
26 }
27 }
28 // add the path of the opened file to the recent list in the Model 29 elmModel.addRecentLog(selectedSourceFile);
30 } catch(IOException e) {
31 elmView.showErrorMessage("Unable to read the file. Please try again."); 32 }
Il procedimento di lettura è molto semplice, grazie alle funzionalità messe a disposizione dalla classe EventLogEditor, poiché è suciente creare un nuovo oggetto di questa classe passando come parametri il nome della ne- stra, l'oggetto Java aperto sullo streaming dei dati del le, il percorso del le selezionato sul le system (se esiste, in caso di le già aperto e scelta di aprire un nuovo editor, quest'ultimo non avrà alcun le associato) e se l'edi- tor debba considerare il contento come modicato oppure no (come prima, un editor aperto su un le considererà il contenuto come non modicato ri- spetto al le, in quanto appena letto, invece un editor a cui viene passato del testo da visualizzare ma senza le associato, lo considererà come modicato rispetto alla sorgente, in quanto questa non esiste).
Una volta inserita la nestra di editing nel corpo centrale dell'applicazio- ne, viene creato un pulsante di tipo FooterAreaButton ed inserito nella barra dei pulsanti in fondo all'applicazione: questo oggetto servirà da collegamen- to con la nestra creata per poterla selezionare, minimizzare, massimizzare
e chiudere, come descritto nella Sezione 4.1. Vedremo queste funzionalità in dettaglio nella Sezione 6.3.
Come si può notare del codice appena mostrato, alla ne del procedimento di apertura, il percorso del le aperto viene salvato in una struttura dati del modello, una lista a capacità limitata di tipo LIFO implementata dalla classe MostRecentElementList<E>. Questa lista memorizza i percorsi degli ultimi documenti aperti (un solo elemento nella lista per documento, se un documento viene riaperto ed era già nella lista, il suo percorso viene spostato in cima come più recente), in ordine dal più recente al meno recente, in numero limitato (di default il limite è uguale a dieci, ma può essere modicato nelle impostazioni dell'applicazione). Quando la lista è piena ed un nuovo elemento viene inserito in essa, il meno recente viene eliminato per fargli posto.
Quando un utente preme sul pulsante "Recent", quello che apparirà sarà un sotto-menù contenente proprio gli elementi di questa lista, in ordine. Pre- mere su uno di essi equivale a scegliere di riaprire quel documento all'interno del sistema, e questo verrà fatto utilizzando la funzione Open precedentemen- te mostrata: in questo caso la funzione prende direttamente il percorso del le da aprire (e quindi non apre nessuna nestra di scelta), dopodiché eettua gli stessi controlli (le esistente e documento già aperto o meno) e le stesse scelte in base alle risposte dell'utente alle sue richieste. La chiamata della funzione Open fa anche si che il documento appena aperto venga reinserito all'interno della lista dei documenti recenti, spostando di fatto quest'ultimo in cima alla lista stessa rispetto alla posizione in cui si trovava precedentemente.