D:\Cedric HUGUENIN\Documents\Prepa_2011_2012\Info\CamlGUI\src\camlgui\CamlGUI.java
  1 /*
  2  * To change this template, choose Tools | Templates
  3  * and open the template in the editor.
  4  */
  5 package camlgui;
  6 
  7 
  8 import java.awt.BorderLayout;
  9 import java.awt.Color;
 10 import java.awt.Dimension;
 11 import java.awt.Font;
 12 import java.awt.event.*;
 13 import java.io.*;
 14 import java.util.regex.Matcher;
 15 import java.util.regex.Pattern;
 16 import javax.swing.*;
 17 import javax.swing.event.DocumentEvent;
 18 import javax.swing.event.DocumentListener;
 19 import javax.swing.filechooser.FileSystemView;
 20 import javax.swing.text.MutableAttributeSet;
 21 import javax.swing.text.SimpleAttributeSet;
 22 import javax.swing.text.StyleConstants;
 23 import javax.swing.text.StyledDocument;
 24 
 25 /**
 26  *
 27  * @author Ced
 28  */
 29 public class CamlGUI extends JFrame {
 30 
 31     private JPanel panelMain = new JPanel(new BorderLayout());
 32     private JPanel panelTop = new JPanel(new BorderLayout());
 33     private JPanel panelMid = new JPanel(new BorderLayout());
 34     private JPanel panelBottom = new JPanel();
 35     private JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panelTop, panelMid);
 36     private JButton compilButton = new JButton("Compiler");
 37     private JButton stopButton = new JButton("Stop");
 38     private JButton newInstanceButton = new JButton("Relancer Caml");
 39     private JTextPane textPaneInput = new JTextPane();
 40     private JTextArea textPaneOutput = new JTextArea();
 41     private JScrollPane scrollInput = new JScrollPane(textPaneInput);
 42     private JScrollPane scrollOutput = new JScrollPane(textPaneOutput);
 43     private JMenuBar menuBar = new JMenuBar();
 44     private JMenu fichier = new JMenu("Fichier"),
 45                   interrogation = new JMenu("?");
 46     private JMenuItem compilMenu = new JMenuItem("Compiler"),
 47                       nouveau = new JMenuItem("Nouveau"),
 48                       ouvrir = new JMenuItem("Ouvrir"),
 49                       enregistrer = new JMenuItem("Enregistrer"),
 50                       enregistrerSous = new JMenuItem("Enregistrer sous"),
 51                       quitter = new JMenuItem("Quitter"),
 52                       aide = new JMenuItem("Aide"),
 53                       aPropos = new JMenuItem("À propos");
 54     private OutputStream stdin;
 55     private InputStream stderr;
 56     private InputStream stdout;
 57     private BufferedReader reader;
 58     private BufferedWriter writer;
 59     private String line;
 60     private GetCamlOutput getCamlOutput;
 61     private boolean stop = false;
 62     private String filePath = null;
 63     private String title = "Caml GUI";
 64     private String version = "0.6";
 65     private String system = "Windows";
 66     
 67     /**
 68      * @param args the command line arguments
 69      */
 70     public CamlGUI() throws IOException { // création de la fenêtre
 71         this.setTitle(title);
 72         this.setSize(700,400);
 73         this.setResizable(true);
 74         this.setMinimumSize(new Dimension(400,300));
 75         this.setLocationRelativeTo(null);
 76         this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
 77         this.addWindowListener(new WindowAdapter(){ // action quand on ferme la fenêtre
 78             public void windowClosing(WindowEvent e) {
 79                 closeApp();
 80             }}
 81          );
 82         this.setContentPane(panelMain);
 83         this.setJMenuBar(menuBar);
 84         
 85         //  *********************** Gestion du layout ***********************
 86         panelBottom.add(newInstanceButton);
 87         panelBottom.add(stopButton);
 88         panelBottom.add(compilButton);
 89         panelMid.add(scrollOutput, BorderLayout.CENTER);
 90         panelTop.setMinimumSize(new Dimension(this.getWidth(), this.getHeight()*2/5));// Pour que les deux JTextPane ne soient pas trop déséquilibré
 91         panelTop.add(scrollInput, BorderLayout.CENTER);
 92         panelMain.add(split, BorderLayout.CENTER);
 93         panelMain.add(panelBottom, BorderLayout.SOUTH);
 94         
 95         //  *********************** On configure les zones de saisi et de retour de Caml ***********************
 96         scrollOutput.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
 97         scrollInput.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
 98         textPaneOutput.setEditable(false);
 99         textPaneInput.setFont(new Font("Monospaced", Font.PLAIN, 12)); // Police
100         textPaneOutput.setFont(new Font("Monospaced", Font.PLAIN, 12)); // Police
101         textPaneInput.getDocument().addDocumentListener(new DocumentListener() { // le listener qui lance la colorisation synthaxique
102         public void insertUpdate(DocumentEvent de) {
103                 SyntaxColor syntaxColor = new SyntaxColor(textPaneInput);
104         }
105 
106         public void removeUpdate(DocumentEvent de) {
107                 SyntaxColor syntaxColor = new SyntaxColor(textPaneInput);
108         }
109 
110         public void changedUpdate(DocumentEvent de) {
111             }
112         });
113         
114         //  *********************** Gestion de la JMenuBar ***********************
115         fichier.add(compilMenu);
116         fichier.add(nouveau);
117         fichier.add(ouvrir);
118         fichier.add(enregistrer);
119         fichier.add(enregistrerSous);
120         fichier.add(quitter);
121         fichier.setMnemonic(java.awt.event.KeyEvent.VK_F);
122         compilMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_MASK));
123         nouveau.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_MASK));
124         ouvrir.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_MASK));
125         enregistrer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK));
126         enregistrerSous.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK));
127         interrogation.add(aide);
128         interrogation.add(aPropos);
129         
130         compilMenu.addActionListener(new ActionListener(){
131             public void actionPerformed(ActionEvent event){
132                 compilButton.doClick();
133             }
134         });
135         quitter.addActionListener(new ActionListener(){
136             public void actionPerformed(ActionEvent event){
137                 closeApp();
138             }
139         });
140         aide.addActionListener(new ActionListener(){
141             public void actionPerformed(ActionEvent event){
142                 Help help = new Help(null);
143             }
144         });
145         aPropos.addActionListener(new ActionListener(){
146             public void actionPerformed(ActionEvent event){
147                 About about = new About(null);
148             }
149         });
150         enregistrerSous.addActionListener(new ActionListener() {
151             public void actionPerformed(ActionEvent ae) {
152                 FileSystemView vueSysteme = FileSystemView.getFileSystemView(); 
153                 //récupération des répertoires
154                 File home = vueSysteme.getHomeDirectory(); 
155                 //création et affichage des JFileChooser
156                 JFileChooser homeChooser = new JFileChooser(home);
157                 homeChooser.showSaveDialog(null);
158                 int result = saveToFile(homeChooser.getSelectedFile(), textPaneInput.getText());
159                 if (result == 1) {
160                     filePath = homeChooser.getSelectedFile().getAbsolutePath();
161                     setTitle(title+" - "+homeChooser.getSelectedFile().getName());
162                     textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nFichier enregistré\n*********************\n");
163                     textPaneOutput.setEditable(true);
164                     textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
165                     textPaneOutput.setEditable(false);
166                 }
167             }
168         });
169         enregistrer.addActionListener(new ActionListener() {
170             public void actionPerformed(ActionEvent ae) {
171                 if(filePath != null) {
172                     int result = saveToFile(new File(filePath), textPaneInput.getText());
173                     textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nFichier enregistré\n*********************\n");
174                     textPaneOutput.setEditable(true);
175                     textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
176                     textPaneOutput.setEditable(false);
177                 }
178                 else {
179                     FileSystemView vueSysteme = FileSystemView.getFileSystemView(); 
180                     //récupération des répertoires
181                     File home = vueSysteme.getHomeDirectory(); 
182                     //création et affichage du JFileChooser
183                     JFileChooser homeChooser = new JFileChooser(home);
184                     homeChooser.showSaveDialog(null);
185                     int result = saveToFile(homeChooser.getSelectedFile(), textPaneInput.getText());
186                     if (result == 1) {
187                         filePath = homeChooser.getSelectedFile().getAbsolutePath();
188                         setTitle(title+" - "+homeChooser.getSelectedFile().getName());
189                         textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nFichier enregistré\n*********************\n");
190                         textPaneOutput.setEditable(true);
191                     textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
192                     textPaneOutput.setEditable(false);
193                     }
194                 }
195             }
196         });
197         nouveau.addActionListener(new ActionListener() {
198             public void actionPerformed(ActionEvent ae) {
199                 JOptionPane jop = new JOptionPane();                    
200                 int choice = jop.showConfirmDialog(null, "Voulez-vous sauvegarder votre travail ?", "Sauvegarder ?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
201                 if(choice == JOptionPane.YES_OPTION) {
202                     enregistrer.doClick();
203                     textPaneInput.setText("");
204                     stopButton.doClick();
205                     textPaneOutput.setText("");
206                     newInstanceButton.doClick();
207                     setTitle(title);
208                     filePath = null;
209                 }
210                 else if(choice == JOptionPane.NO_OPTION) {
211                     textPaneInput.setText("");
212                     stopButton.doClick();
213                     textPaneOutput.setText("");
214                     newInstanceButton.doClick();
215                     setTitle(title);
216                     filePath = null;
217                 }
218                 else if(choice == JOptionPane.CANCEL_OPTION || choice == JOptionPane.CLOSED_OPTION) {
219                     // ne rien faire
220                 }
221             }
222         });
223         ouvrir.addActionListener(new ActionListener() {
224             public void actionPerformed(ActionEvent ae) {
225                 JOptionPane jop = new JOptionPane();                    
226                 int choice = jop.showConfirmDialog(null, "Voulez-vous sauvegarder votre travail ?", "Sauvegarder ?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
227                 if(choice == JOptionPane.YES_OPTION) {
228                     enregistrer.doClick();
229                     
230                     FileSystemView vueSysteme = FileSystemView.getFileSystemView(); 
231                     //récupération des répertoires
232                     File home = vueSysteme.getHomeDirectory(); 
233                     //création et affichage du JFileChooser
234                     JFileChooser homeChooser = new JFileChooser(home);
235                     homeChooser.showOpenDialog(null);
236                     filePath = homeChooser.getSelectedFile().getAbsolutePath();
237                     String tmp = "";
238                     String[] lines = from_file_to_string((homeChooser.getSelectedFile()).getAbsolutePath());
239                     if (lines != null) {
240                         for(String str : lines){
241                             tmp = tmp + str +"\n";
242                         }
243                         textPaneInput.setText(tmp);
244                         setTitle(title+" - "+homeChooser.getSelectedFile().getName());
245                     }
246                     stopButton.doClick();
247                     textPaneOutput.setText("");
248                     newInstanceButton.doClick();
249                 }
250                 else if(choice == JOptionPane.NO_OPTION) {
251                     FileSystemView vueSysteme = FileSystemView.getFileSystemView(); 
252                     //récupération des répertoires
253                     File home = vueSysteme.getHomeDirectory(); 
254                     //création et affichage du JFileChooser
255                     JFileChooser homeChooser = new JFileChooser(home);
256                     homeChooser.showOpenDialog(null);
257                     String tmp = "";
258                     filePath = homeChooser.getSelectedFile().getAbsolutePath();
259                     String[] lines = from_file_to_string((homeChooser.getSelectedFile()).getAbsolutePath());
260                     if (lines != null) {
261                         for(String str : lines){
262                             tmp = tmp + str + "\n";
263                         }
264                         textPaneInput.setText(tmp);
265                         setTitle(title+" - "+homeChooser.getSelectedFile().getName());
266                     }
267                     stopButton.doClick();
268                     textPaneOutput.setText("");
269                     newInstanceButton.doClick();
270                 }
271                 else if(choice == JOptionPane.CANCEL_OPTION || choice == JOptionPane.CLOSED_OPTION) {
272                     // rien à faire !
273                 }
274             }
275         });
276         menuBar.add(fichier);
277         menuBar.add(interrogation);
278         
279         //  *********************** Savoir si on est sous Windows ou Linux ***********************
280         try {
281             String systemBits = System.getProperty("sun.arch.data.model");
282             String[] cmd = {"caml/bin/caml"+systemBits+".exe","-stdlib","caml/lib/"};
283             if("Linux".equals(System.getProperty("os.name"))) {
284                 cmd[0] = "camllight";
285                 cmd[1] = "camlgraph";
286                 cmd[2] = "2>&1";
287             }
288 
289             //  *********************** On lance Caml, on connecte les entrées sorties ***********************
290             ProcessBuilder builder = new ProcessBuilder(cmd);
291             builder.redirectErrorStream(true);
292             final Process process = builder.start();
293 
294             stdin = process.getOutputStream ();
295             stderr = process.getErrorStream ();
296             stdout = process.getInputStream ();
297             reader = new BufferedReader (new InputStreamReader(stdout));
298             writer = new BufferedWriter(new OutputStreamWriter(stdin));
299             if ((line = reader.readLine ()) != null) { // On lit le message d'acceuil de Caml qui est sur deux lignes
300                 textPaneOutput.setText(textPaneOutput.getText()+line+"\n");
301             }
302             if ((line = reader.readLine ()) != null) {// On lit le message d'acceuil de Caml qui est sur deux lignes
303                 textPaneOutput.setText(textPaneOutput.getText()+line+"\n");
304             }
305             getCamlOutput = new GetCamlOutput(); // On instancie l'objet qui lit la sortie de Caml
306             getCamlOutput.start(); // on le met en route
307 
308         
309         compilButton.addActionListener(new ActionListener(){
310             public void actionPerformed(ActionEvent event){
311                 String input = null;
312                 if(textPaneInput.getSelectedText() == null) {
313                     input = parseCommand(textPaneInput.getText(), textPaneInput.getCaretPosition());
314                     // rechercher le double point virgule d'avant et le double point virgule d'après
315                 }
316                 else {
317                     input = textPaneInput.getSelectedText();                    
318                 }
319                 try {
320                     writer.write(input);
321                     writer.flush();
322                 } catch (IOException ex) {
323                     textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nErreur lors de l'envoi de la commande à Caml\n*********************\n\n");
324                     textPaneOutput.setEditable(true);
325                 textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
326                 textPaneOutput.setEditable(false);
327                 }
328                 textPaneInput.grabFocus();
329             }
330         });
331         stopButton.addActionListener(new ActionListener(){
332             public void actionPerformed(ActionEvent event){
333                 stop = true;
334                 try { //"/usr/bin/killall -s INT camlgraph"
335                     writer.write("()\\;"); // pour forcer le readLine à s'éxecuter et comme on a changer la valeur de stop,
336                     writer.flush(); //        il ne recommence pas et on peut donc fermer les flux
337                     stdin.close();
338                     reader.close();
339                     writer.close();
340                     stdout.close();
341                     stderr.close();
342                     process.destroy();
343                     newInstanceButton.setEnabled(true);
344                     stopButton.setEnabled(false);
345                     compilButton.setEnabled(false);
346                     textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nÉxecution de CamlLight interrompu\n*********************\n\n");
347                     textPaneOutput.setEditable(true);
348                     textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
349                     textPaneOutput.setEditable(false);
350                 } catch (IOException ex) {
351                     textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nErreur lors de l'interruption de Caml\n*********************\n\n");
352                     textPaneOutput.setEditable(true);
353                     textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
354                     textPaneOutput.setEditable(false);
355                 }
356             }
357         });
358         } catch(IOException e) {
359             JOptionPane jop = new JOptionPane();
360             jop.showMessageDialog(null, "Caml light introuvable", "Erreur", JOptionPane.ERROR_MESSAGE);
361             System.exit(0);
362         }
363         newInstanceButton.setEnabled(false);
364         newInstanceButton.addActionListener(new ActionListener(){
365             public void actionPerformed(ActionEvent event){
366                 try {
367                     stop = false;
368                     newInstanceButton.setEnabled(false);
369                     stopButton.setEnabled(true);
370                     compilButton.setEnabled(true);
371                     //  *********************** Savoir si on est sous Windows ou Linux ***********************
372                     String systemBits = System.getProperty("sun.arch.data.model");
373                     String[] cmd = {"caml/bin/caml"+systemBits+".exe","-stdlib","caml/lib/"};
374                     if("Linux".equals(System.getProperty("os.name"))) {
375                         system = "Linux";
376                         cmd[0] = "camllight";
377                         cmd[1] = "camlgraph";
378                         cmd[2] = "2>&1";
379                     }
380 
381                     //  *********************** On lance Caml, on connecte les entrées sorties ***********************
382                     ProcessBuilder builder = new ProcessBuilder(cmd);
383                     builder.redirectErrorStream(true);
384                     final Process process = builder.start();
385 
386                     stdin = process.getOutputStream ();
387                     stderr = process.getErrorStream ();
388                     stdout = process.getInputStream ();
389 
390                     reader = new BufferedReader (new InputStreamReader(stdout));
391                     writer = new BufferedWriter(new OutputStreamWriter(stdin));
392                     if ((line = reader.readLine ()) != null) { // On lit le message d'acceuil de Caml qui est sur deux lignes
393                         textPaneOutput.setText(textPaneOutput.getText()+line+"\n");
394                     }
395                     if ((line = reader.readLine ()) != null) {// On lit le message d'acceuil de Caml qui est sur deux lignes
396                         textPaneOutput.setText(textPaneOutput.getText()+line+"\n");
397                     }
398                     getCamlOutput = new GetCamlOutput(); // On instancie l'objet qui lit la sortie de Caml
399                     getCamlOutput.start(); // on le met en route
400                 } catch (IOException ex) {
401                     textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nErreur lors de la création de la nouvelle instance de Caml\n*********************\n\n");
402                     textPaneOutput.setEditable(true);
403                 textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
404                 textPaneOutput.setEditable(false);
405                 }
406             }
407         });
408     }
409     
410     class GetCamlOutput extends Thread { // objet qui lit la sortie de Caml
411         public GetCamlOutput() {
412         }
413         public void run() {
414             try {
415                 while ((line = reader.readLine()) != null && stop == false) {
416                     textPaneOutput.setText(textPaneOutput.getText()+line+"\n");
417                     textPaneOutput.setEditable(true);
418                     textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
419                     textPaneOutput.setEditable(false);
420                 }
421             } catch (IOException ex) {
422                 textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nErreur lors de la lecture de la sortie de Caml\n*********************\n\n");
423                 textPaneOutput.setEditable(true);
424                 textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength()-1);
425                 textPaneOutput.setEditable(false);
426             }
427         }
428     }
429     class SyntaxColor {
430         private String[] modelStringToColor = {"rec", "let", "begin", "end", "match",
431         "with", "and", "ref", "int", "float", ":", "::", "\\[", "\\]", "\\(", "\\)", "\\|",
432         "\\[\\|", "\\|\\]", "if", "else", "\\<", "\\>", "\\+", "\\-", "\\*", "\\/",
433         "\\@", "\\-\\>", "\\(\\*", "\\*\\)", "\\#", "\\<\\>", "\\<\\=", "\\>\\=", "\\=",
434         "div", "mod", "do", "done", "for", "while", "failwith", "in", "then", "false", "true",
435         "\\;\\;", "\\;", "type", "list", "char"};
436         
437         public SyntaxColor(JTextPane pane) {
438             String text = pane.getText().replaceAll("\r", "");
439             final StyledDocument doc = pane.getStyledDocument();
440             final MutableAttributeSet normal= new SimpleAttributeSet();
441             StyleConstants.setForeground(normal, Color.black);
442             StyleConstants.setBold(normal, false);
443             
444             SwingUtilities.invokeLater(new Runnable() {
445                 public void run() {
446                     doc.setCharacterAttributes(0,doc.getLength(), normal, true);
447                 }
448             });
449             int n = modelStringToColor.length;
450             for(int i = 0 ; i < n ; i ++) {
451                 Pattern p = Pattern.compile("(^|\\s+)("+modelStringToColor[i]+")(\\s+|$)");
452                 Matcher m = p.matcher(text);
453                 while(m.find() == true) {
454                     MutableAttributeSet attri = new SimpleAttributeSet();
455                     StyleConstants.setForeground(attri, Color.blue);
456                     StyleConstants.setBold(attri, true);
457                     final int start = m.start(2);
458                     final int end = m.end(2);
459                     final int length = end-start;
460                     final MutableAttributeSet style = attri;
461                     
462                     SwingUtilities.invokeLater(new Runnable(){
463                         public void run(){
464                             doc.setCharacterAttributes(start, length, style, true);
465                         }
466                     });
467                 }
468             }
469         }
470     }
471     class About extends JDialog {
472         private JTextPane pane = new JTextPane();
473         private JPanel panel = new JPanel(new BorderLayout());
474         public About(JFrame parent) {
475             this.setTitle(title +"  v "+version);
476             this.setSize(400,200);
477             this.setResizable(true);
478             this.setLocationRelativeTo(null);
479             this.setContentPane(panel);
480             panel.add(pane, BorderLayout.CENTER);
481             pane.setEditable(false);
482             pane.setText(pane.getText()+"Caml GUI est une application écrite en Java par HUGUENIN Cédric.\n\n");
483             pane.setText(pane.getText()+"Caml est distribué sous la licence dont les termes sont précisés dans le fichier \"\\Caml GUI\\CAML\\Copyright.txt\".\n");
484             pane.setText(pane.getText()+"Merci à Jean Mouric pour la compilation de Caml 64 bits.");
485             this.setVisible(true);
486         }
487     }
488     class Help extends JDialog {
489         private JTextPane pane = new JTextPane();
490         private JPanel panel = new JPanel(new BorderLayout());
491         public Help(JFrame parent) {
492             this.setTitle(title +"  v "+version);
493             this.setSize(400,200);
494             this.setResizable(true);
495             this.setLocationRelativeTo(null);
496             this.setContentPane(panel);
497             panel.add(pane, BorderLayout.CENTER);
498             pane.setEditable(false);
499             pane.setText(pane.getText()+"Le bouton \"Compiler\" sert à envoyer à Caml le texte sélectionner ou la commande se trouvant"
500                     + " au niveau du curseur.\n"
501                     + "Il est aussi possible d'appuyer simultanément sur les touches \"Ctrl\" et \"Entrer\".\n"
502                     + "Le bouton \"Stop\" sert à tuer le processus \"Caml\" : utile en cas de boucle infinie.\n"
503                     + "Le bouton \"Relancer Caml\" permet de lancer une nouvelle instance de Caml.");
504             this.setVisible(true);
505         }
506     }
507     public void closeApp() { // Méthode appelée quand on veut fermer la fenêtre
508         JOptionPane jop = new JOptionPane();                    
509         int choice = JOptionPane.showConfirmDialog(null, "Voulez-vous sauvegarder votre travail ?", "Sauvegarder ?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
510         if(choice == JOptionPane.YES_OPTION) {
511             if(filePath != null) {
512                 int result = saveToFile(new File(filePath), textPaneInput.getText());
513                 textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nFichier enregistré\n*********************\n");
514                 textPaneOutput.setEditable(true);
515                 textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
516                 textPaneOutput.setEditable(false);
517             }
518             else {
519                 FileSystemView vueSysteme = FileSystemView.getFileSystemView(); 
520                 //récupération des répertoires
521                 File home = vueSysteme.getHomeDirectory(); 
522                 //création et affichage du JFileChooser
523                 JFileChooser homeChooser = new JFileChooser(home);
524                 homeChooser.showSaveDialog(null);
525                 int result = saveToFile(homeChooser.getSelectedFile(), textPaneInput.getText());
526                 if (result == 1) {
527                     filePath = homeChooser.getSelectedFile().getAbsolutePath();
528                     setTitle(title+" - "+homeChooser.getSelectedFile().getName());
529                     textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nFichier enregistré\n*********************\n");
530                     textPaneOutput.setEditable(true);
531                     textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
532                     textPaneOutput.setEditable(false);
533                 }
534             }
535             try {
536                 stop = true;
537                 writer.write("()\\;"); // pour forcer le readLine à s'éxecuter et comme on a changer la valeur de stop,
538                 writer.flush(); //        il ne recommence pas et on peut donc fermer les flux
539                 stdin.close();
540                 reader.close();
541                 writer.close();
542                 stdout.close();
543                 stderr.close();
544             } catch (IOException ex) {
545                 textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nErreur lors de la fermeture de l'application\n*********************\n\n");
546                 //System.out.println("Erreur lors de la fermeture de l'application");
547                 textPaneOutput.setEditable(true);
548                 textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
549                 textPaneOutput.setEditable(false);
550             }
551             System.exit(0);
552         }
553         else if(choice == JOptionPane.NO_OPTION) {
554             try {
555                 stop = true;
556                 writer.write("()\\;"); // pour forcer le readLine à s'éxecuter et comme on a changer la valeur de stop,
557                 writer.flush(); //        il ne recommence pas et on peut donc fermer les flux
558                 stdin.close();
559                 reader.close();
560                 writer.close();
561                 stdout.close();
562                 stderr.close();
563             } catch (IOException ex) {
564                 textPaneOutput.setText(textPaneOutput.getText()+"\n*********************\nErreur lors de la fermeture de l'application\n*********************\n\n");
565                 //System.out.println("Erreur lors de la fermeture de l'application");
566                 textPaneOutput.setEditable(true);
567                 textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
568                 textPaneOutput.setEditable(false);
569             }
570             System.exit(0);
571         }
572         else if(choice == JOptionPane.CANCEL_OPTION || choice == JOptionPane.CLOSED_OPTION) {
573             // rien à faire !
574         }
575     }
576     public String parseCommand (String text, int pos) {
577         String result = null;
578         int n = text.length();
579         String textt = text.replaceAll("\r", ""); // Pour éviter les décalages dues aux \n dans le substring
580         int firstIndexBefore = textt.substring(0, pos).lastIndexOf(";;");
581         if(text.length() > 1) {
582             if ((pos - firstIndexBefore) <= 2 && pos > 1) { // ne pas prendre comme première occurence le double point virgule où est le curseur;
583                 firstIndexBefore = textt.substring(0, pos-2).lastIndexOf(";;");
584             }
585             if (firstIndexBefore == -1) { // pas de ;; avant : on est au début du document
586                 firstIndexBefore = 0;
587             }
588             else {
589                 firstIndexBefore+=2; // sinon on se place après les ;;
590             }
591             int firstIndexAfter = textt.substring(firstIndexBefore+1, textt.length()).indexOf(";;") + firstIndexBefore+1;
592             if (firstIndexAfter == -1) {
593                 textPaneOutput.setText(textPaneOutput.getText()+"\nDouble point virgule manquant\n");
594                 textPaneOutput.setEditable(true);
595                 textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
596                 textPaneOutput.setEditable(false);
597             }
598             else {
599                 firstIndexAfter+=2;
600                 result = textt.substring(firstIndexBefore, firstIndexAfter);
601             }
602             if(result.indexOf("(*") == -1 && result.indexOf("*)") != -1) { // on est dans un commentaire
603                 boolean fin = false;
604                 while(fin == false && firstIndexBefore > 0) {
605                     firstIndexBefore--;
606                     if(textt.substring(firstIndexBefore, firstIndexAfter).indexOf("(*") != -1 )
607                         fin = true;
608                 }
609                 if(fin == false && firstIndexBefore == 0)
610                 {
611                     textPaneOutput.setText(textPaneOutput.getText()+"\n\n\"*)\" présent mais pas de \"(*\"\n\n");
612                     textPaneOutput.setEditable(true);
613                     textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
614                     textPaneOutput.setEditable(false);
615                     result= "";
616                 } else {
617                     result = textt.substring(firstIndexBefore, firstIndexAfter);
618                 }
619             } else if(result.indexOf("(*") != -1 && result.indexOf("*)") == -1) { // on est dans un commentaire
620                 boolean fin = false;
621                 while(fin == false && firstIndexAfter < n) {
622                     firstIndexAfter++;
623                     if(textt.substring(firstIndexBefore, firstIndexAfter).indexOf("*)") != -1 )
624                         fin = true;
625                 }
626                 if(fin == false && firstIndexAfter == n)
627                 {
628                     textPaneOutput.setText(textPaneOutput.getText()+"\n\n\"(*\" présent mais pas de \"*)\"\n\n");
629                     textPaneOutput.setEditable(true);
630                     textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
631                     textPaneOutput.setEditable(false);
632                     result= "";
633                 } else {
634                     result = textt.substring(firstIndexBefore, firstIndexAfter);
635                 }
636             }
637         }
638         else {
639             result = "";
640         }
641         return result;
642     }
643     public int saveToFile (File file, String content) {
644         FileWriter fw;
645         int result = 0;
646         try {
647             //Création de l'objet
648             fw = new FileWriter(file);
649             //On écrit la chaîne
650             fw.write(content);
651             //On ferme le flux
652             fw.close();
653             result = 1;
654         } catch (IOException e) {
655                 textPaneOutput.setText(textPaneOutput.getText()+"\n *********************\nErreur lors de l'enregistrement du fichier\n*********************\n\n");
656                 textPaneOutput.setEditable(true);
657                 textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
658                 textPaneOutput.setEditable(false);
659         }
660         return result;
661     }
662         
663     public String[] from_file_to_string (String path) { // fonction qui lit un fichier et qui rend un tableau dez String qui contiennent les lignes du fichier
664         InputStreamReader flog;
665         LineNumberReader llog;
666         String myLine;
667         int lineC = 0;
668         if (path == null) {
669             return null;
670         }
671         else {
672             try {
673                 flog = new InputStreamReader(new FileInputStream(path) );
674                 llog = new LineNumberReader(flog);
675                 while ((llog.readLine()) != null) {
676                     lineC++;
677                 }
678             }catch (Exception e) {
679                 textPaneOutput.setText(textPaneOutput.getText()+"\n *********************\nErreur lors du chargement du fichier\n*********************\n\n");
680                 textPaneOutput.setEditable(true);
681                 textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
682                 textPaneOutput.setEditable(false);
683             }
684             String[] ligne = new String[lineC];
685         
686             lineC=0;
687             try {
688 
689                 flog = new InputStreamReader(new FileInputStream(path) );
690                 llog = new LineNumberReader(flog);
691                 while ((myLine = llog.readLine()) != null) {
692                     ligne[lineC]=myLine;
693                     lineC++;
694                 }
695             }catch (Exception e) {
696                 System.err.println("Error : "+e.getMessage());
697                 textPaneOutput.setText(textPaneOutput.getText()+"\n *********************\nErreur lors du chargement du fichier\n*********************\n\n");
698                 textPaneOutput.setEditable(true);
699                 textPaneOutput.setCaretPosition(textPaneOutput.getDocument().getLength());
700                 textPaneOutput.setEditable(false);
701                 line = null;
702             }
703             return ligne;
704         }
705     }
706 
707     public static void main(String[] args) throws IOException {
708         // TODO code application logic here
709         CamlGUI window = new CamlGUI();
710         window.setVisible(true);
711 //        try {                                                              // Look and Feel du système hôte
712 //            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
713 //           SwingUtilities.updateComponentTreeUI(window);
714 //            //force chaque composant de la fenêtre à appeler sa méthode updateUI
715 //        } catch (InstantiationException e) {
716 //        } catch (ClassNotFoundException e) {
717 //        } catch (UnsupportedLookAndFeelException e) {
718 //        } catch (IllegalAccessException e) {}
719     }
720 }