Changeset 29006

Show
Ignore:
Timestamp:
29.04.2014 19:09:22 (5 years ago)
Author:
ak19
Message:

Implemented Undo and Redo. Moved a functions around to better organise in sensible groups.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/gli/src/org/greenstone/gatherer/gui/FormatConversionDialog.java

    r29001 r29006  
    1414import org.w3c.dom.*; 
    1515 
    16 //import javax.swing.*; 
    17 import java.awt.Dimension; 
    18  
    1916import java.io.BufferedReader; 
    2017import java.io.BufferedWriter; 
     
    2724import java.io.OutputStreamWriter; 
    2825 
    29  
     26//import java.awt.Dimension; 
    3027import java.awt.*; 
    3128import java.awt.event.*; 
     
    4239// Need to use dictionary for labels 
    4340// convertFormat() for remote GS 
    44 // HTML tidy (put all "<br/>" back to "<br>" in luce/etc/collectionConfig.xml and run again) 
     41// + HTML tidy (put all "<br/>" back to "<br>" in luce/etc/collectionConfig.xml and run again) 
    4542// Help tooltips on buttons 
    46 // Undo, Redo buttons 
     43// + Undo, Redo buttons 
    4744// Split class into dialog/widgets and data processing 
    4845 
     
    7774    private JButton accept_all_button = null; 
    7875    private JButton undo_button = null; 
     76    private JButton redo_button = null; 
    7977    private JButton htmltidy_button = null; 
    8078    private JButton xmltidy_button = null; 
     
    8381    private JLabel count_label = null; 
    8482    private JLabel statusbar = null; 
    85  
     83    private UndoManager undoManager; 
    8684 
    8785    public FormatConversionDialog (File collect_cfg_file, Document xml_file_doc, NodeList gsf_format_gs2_list) { 
     
    9694    setTitle(Dictionary.get("FormatConversionDialog.Title")); 
    9795    setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
    98      
    99     gs2_textarea = new NumberedJTextArea(); 
    100     gs3_textarea = new NumberedJTextArea();  
    101     initTextArea(gs2_textarea); 
    102     initTextArea(gs3_textarea); 
    10396     
    10497 
     
    116109    JPanel button1_panel = new JPanel(); 
    117110    button1_panel.setComponentOrientation(Dictionary.getOrientation()); 
    118     xmltidy_button = new JButton("XML Tidy"); 
     111    undo_button = new JButton("Undo"); 
     112    undo_button.addActionListener(new UndoListener()); 
     113    undo_button.setEnabled(false); 
     114 
     115    redo_button = new JButton("Redo"); 
     116    redo_button.addActionListener(new RedoListener()); 
     117    redo_button.setEnabled(false); 
     118 
     119    xmltidy_button = new JButton("XHTML Tidy"); 
    119120    xmltidy_button.addActionListener(new XMLTidyButtonListener()); 
     121 
     122    button1_panel.add(undo_button); 
     123    button1_panel.add(redo_button); 
    120124    button1_panel.add(xmltidy_button); 
    121125 
     
    135139 
    136140 
     141    // The undoable text areas. Adding the UndoableEditListener has to come after instantiation 
     142    // of the undo and redo buttons, since the listener expects these buttons to already exist 
     143    undoManager = new UndoManager(); 
     144 
     145    gs2_textarea = new NumberedJTextArea(); 
     146    gs3_textarea = new NumberedJTextArea(); 
     147 
     148    CustomUndoableEditListener customUndoableEditListener = new CustomUndoableEditListener(); 
     149    gs2_textarea.getDocument().addUndoableEditListener(customUndoableEditListener); 
     150    gs3_textarea.getDocument().addUndoableEditListener(customUndoableEditListener); 
     151 
     152    initTextArea(gs2_textarea); 
     153    initTextArea(gs3_textarea); 
     154 
     155 
    137156    JPanel centre_panel = new JPanel(); 
    138157    centre_panel.setLayout(new BoxLayout(centre_panel, BoxLayout.Y_AXIS)); 
     
    197216    } 
    198217 
     218    public int getDialogResult() { 
     219    return dlgResult; // OK_OPTION or CANCEL_OPTION 
     220    } 
    199221     
     222    //*************************PROCESSING FUNCTIONS***************************// 
    200223    public static int checkForGS2FormatStatements(File collect_cfg_file) { 
    201224 
     
    243266    } 
    244267 
    245  
    246     public int getDialogResult() { 
    247     return dlgResult; // OK_OPTION or CANCEL_OPTION 
    248     } 
    249268 
    250269    /**  
     
    367386    }  
    368387 
    369     increment(); 
     388    increment(); // modifies the textareas to initialise them 
    370389    setVisible(true); 
    371390    } 
     
    424443    } 
    425444 
    426     // HTML tidy adds all entire HTML tags around a single format statement. This method removes it. 
     445    // HTML tidy adds entire HTML tags around a single format statement. This method removes it. 
    427446    private String removeHTMLTags(int i, String gs3formatstr_notags, boolean startsWithTD) { 
    428447 
     
    461480 
    462481 
    463     //******* ACCESS FUNCTIONS ********* 
     482    //**************** ACCESS FUNCTIONS ***************// 
    464483 
    465484    // gs2 format text is the text string that goes into <gsf:format-gs2/>: <gsf:format-gs2>text</gsf:format-gs2> 
     
    603622    } 
    604623 
    605     //************************* 
     624    //*************************FUNCTIONS THAT INTERACT WITH WIDGETS************************// 
    606625    // increment() loads the next values into the dialog 
    607626    private boolean increment() { 
     
    612631    statusbar.setText(""); 
    613632 
     633    // as we're on a new screen of dialog, need to clear all undo/redo history 
     634    undoManager.discardAllEdits(); 
     635    undo_button.setEnabled(false); 
     636    redo_button.setEnabled(false); 
     637 
    614638    int len = gsf_format_gs2_list.getLength(); 
    615639    count_label.setText((current_index+1) + " / " + len); 
     
    621645    } 
    622646 
     647 
     648    private void setStatus(String msg) { 
     649    statusbar.setText(msg); 
     650    } 
     651    private void setErrorStatus(String msg) { 
     652    statusbar.setBackground(Color.red); 
     653    statusbar.setText(msg); 
     654    } 
     655 
     656 
     657    public void dispose() { 
     658    //System.err.println("@@@@ DIALOG CLOSING!"); 
     659    if(dlgResult != OpenCollectionDialog.CANCEL_OPTION) { 
     660        // Need to remove the <gsf:gs3-root/> siblings of all <gsf:format-gs2/> 
     661        // Then, get the children of each <gsf:gs3-root/> and add these as siblings of <gsf:format-gs2/> 
     662         
     663         
     664        int len = gsf_format_gs2_list.getLength(); 
     665        for(int k=len-1; k >= 0; k--) { 
     666        Element parent = (Element)getParentNode(k);      
     667         
     668        //parent.normalize(); 
     669 
     670        NodeList children = parent.getChildNodes(); 
     671 
     672        // now have to loop/remove nodes in reverse order, since the following loop  
     673        // modifies the very nodelist we're looping over by removing nodes from it 
     674 
     675        int numChildren = children.getLength()-1; 
     676 
     677        for(int i=numChildren; i >= 0; i--) { 
     678        //for(int i = 0; i < children.getLength(); i++) { 
     679            Node child = children.item(i); 
     680 
     681            if(child.getNodeName().equals(GSF_FORMAT_GS2_TAG)) {  
     682            // if we're dealing with gs2-format-stmts, put their textnode contents in CData sections 
     683            // http://www.w3schools.com/xml/xml_cdata.asp 
     684            // This avoids having to look at html-encoded gs2-format tags in the Format pane 
     685 
     686            Element gs2format = (Element)child; 
     687            String gs2formatstr = XMLTools.getElementTextValue(gs2format); 
     688            gs2formatstr = Codec.transform(gs2formatstr, Codec.ESCAPEDHTML_TO_UNESCAPED); 
     689             
     690            Node textNode = XMLTools.getNodeTextNode(gs2format); 
     691            Node cdataSection = gs2format.getOwnerDocument().createCDATASection(gs2formatstr);  
     692            gs2format.replaceChild(cdataSection, textNode); 
     693            }  
     694            else if(child.getNodeName().equals(GSF_GS3_ROOT_TAG)) {  
     695 
     696            // remove GS3 node and append its children to the parent in its place 
     697            // the <gsf:gs3-root /> elements wouldn't be in the xml_file_doc DOM tree 
     698            // unless they were valid XML, so don't need to check for validity here 
     699             
     700            Node gs3root = child; 
     701            NodeList gs3_format_lines = gs3root.getChildNodes(); 
     702 
     703            for(int j = 0; j < gs3_format_lines.getLength(); j++) { 
     704                Node duplicate = gs3_format_lines.item(j).cloneNode(true); 
     705                parent.appendChild(duplicate);               
     706            } 
     707            gs3root = parent.removeChild(gs3root); 
     708            gs3root = null; // finished processing 
     709 
     710            } // else - skip all nodes other than <gsf:format-gs2/> and <gsf:gs3-root/> 
     711        } 
     712        } 
     713  
     714        Element root = xml_file_doc.getDocumentElement(); 
     715        //System.err.println("### XML file to write out:\n" + XMLTools.xmlNodeToString(root)); 
     716         
     717        // Finally, write out the collection xml file 
     718        String[] nonEscapingTagNames = { StaticStrings.FORMAT_STR, StaticStrings.DISPLAYITEM_STR }; 
     719        XMLTools.writeXMLFile(collect_cfg_file, xml_file_doc, nonEscapingTagNames); 
     720         
     721    } 
     722    super.dispose(); 
     723     
     724    } 
     725 
     726    //******************INNER CLASSES including LISTENERS and STREAMGOBBLERS****************// 
    623727 
    624728    /** 
     
    775879    } 
    776880 
    777     public void dispose() { 
    778     //System.err.println("@@@@ DIALOG CLOSING!"); 
    779     if(dlgResult != OpenCollectionDialog.CANCEL_OPTION) { 
    780         // Need to remove the <gsf:gs3-root/> siblings of all <gsf:format-gs2/> 
    781         // Then, get the children of each <gsf:gs3-root/> and add these as siblings of <gsf:format-gs2/> 
    782          
    783          
    784         int len = gsf_format_gs2_list.getLength(); 
    785         for(int k=len-1; k >= 0; k--) { 
    786         Element parent = (Element)getParentNode(k);      
    787          
    788         //parent.normalize(); 
    789  
    790         NodeList children = parent.getChildNodes(); 
    791  
    792         // now have to loop/remove nodes in reverse order, since the following loop  
    793         // modifies the very nodelist we're looping over by removing nodes from it 
    794  
    795         int numChildren = children.getLength()-1; 
    796  
    797         for(int i=numChildren; i >= 0; i--) { 
    798         //for(int i = 0; i < children.getLength(); i++) { 
    799             Node child = children.item(i); 
    800  
    801             if(child.getNodeName().equals(GSF_FORMAT_GS2_TAG)) {  
    802             // if we're dealing with gs2-format-stmts, put their textnode contents in CData sections 
    803             // http://www.w3schools.com/xml/xml_cdata.asp 
    804             // This avoids having to look at html-encoded gs2-format tags in the Format pane 
    805  
    806             Element gs2format = (Element)child; 
    807             String gs2formatstr = XMLTools.getElementTextValue(gs2format); 
    808             gs2formatstr = Codec.transform(gs2formatstr, Codec.ESCAPEDHTML_TO_UNESCAPED); 
    809              
    810             Node textNode = XMLTools.getNodeTextNode(gs2format); 
    811             Node cdataSection = gs2format.getOwnerDocument().createCDATASection(gs2formatstr);  
    812             gs2format.replaceChild(cdataSection, textNode); 
    813             }  
    814             else if(child.getNodeName().equals(GSF_GS3_ROOT_TAG)) {  
    815  
    816             // remove GS3 node and append its children to the parent in its place 
    817             // the <gsf:gs3-root /> elements wouldn't be in the xml_file_doc DOM tree 
    818             // unless they were valid XML, so don't need to check for validity here 
    819              
    820             Node gs3root = child; 
    821             NodeList gs3_format_lines = gs3root.getChildNodes(); 
    822  
    823             for(int j = 0; j < gs3_format_lines.getLength(); j++) { 
    824                 Node duplicate = gs3_format_lines.item(j).cloneNode(true); 
    825                 parent.appendChild(duplicate);               
    826             } 
    827             gs3root = parent.removeChild(gs3root); 
    828             gs3root = null; // finished processing 
    829  
    830             } // else - skip all nodes other than <gsf:format-gs2/> and <gsf:gs3-root/> 
    831         } 
    832         } 
    833   
    834         Element root = xml_file_doc.getDocumentElement(); 
    835         //System.err.println("### XML file to write out:\n" + XMLTools.xmlNodeToString(root)); 
    836          
    837         // Finally, write out the collection xml file 
    838         String[] nonEscapingTagNames = { StaticStrings.FORMAT_STR, StaticStrings.DISPLAYITEM_STR }; 
    839         XMLTools.writeXMLFile(collect_cfg_file, xml_file_doc, nonEscapingTagNames); 
    840          
    841     } 
    842     super.dispose(); 
    843      
    844     } 
    845  
    846881    private class XMLTidyButtonListener implements ActionListener { 
    847882    // run HTML tidy taking input from stdin 
     
    885920    { 
    886921    InputStream is = null; 
    887     StringBuffer outputstr = new StringBuffer(); //String outputstr = ""; 
     922    StringBuffer outputstr = new StringBuffer(); 
    888923    boolean split_newlines = false; 
    889924     
     
    909944        while ( (line = br.readLine()) != null) { 
    910945            //System.out.println("@@@ GOT LINE: " + line); 
    911             outputstr.append(line); // outputstr += line; 
     946            outputstr.append(line); 
    912947            if(split_newlines) { 
    913             outputstr.append("\n"); //outputstr += "\n"; 
     948            outputstr.append("\n"); 
    914949            } 
    915950 
     
    9681003    } 
    9691004 
    970     private void setStatus(String msg) { 
    971     statusbar.setText(msg); 
    972     } 
    973     private void setErrorStatus(String msg) { 
    974     statusbar.setBackground(Color.red); 
    975     statusbar.setText(msg); 
    976     } 
     1005    private class UndoListener implements ActionListener 
     1006    {    
     1007    public void actionPerformed(ActionEvent event) 
     1008    { 
     1009        try { 
     1010        if (undoManager.canUndo()) {                         
     1011            redo_button.setEnabled(true); 
     1012            undoManager.undo();                  
     1013        } 
     1014         
     1015        if (!undoManager.canUndo()) { 
     1016            undo_button.setEnabled(false); 
     1017        } else { 
     1018            undo_button.setEnabled(true); 
     1019        } 
     1020         
     1021        } catch (Exception e) { 
     1022        System.err.println("Exception trying to undo: " + e.getMessage()); 
     1023        } 
     1024    } 
     1025    } 
     1026     
     1027    private class RedoListener implements ActionListener 
     1028    { 
     1029    public void actionPerformed(ActionEvent evt) 
     1030    { 
     1031        try { 
     1032        if (undoManager.canRedo()) { 
     1033            undo_button.setEnabled(true); // the difference with Format4gs3Manager, and no DocumentListener 
     1034            undoManager.redo(); 
     1035        } 
     1036         
     1037        if (!undoManager.canRedo()) { 
     1038            redo_button.setEnabled(false); 
     1039        } else { 
     1040            redo_button.setEnabled(true); 
     1041        } 
     1042         
     1043        } catch (Exception e) { 
     1044        System.err.println("Exception trying to redo: " + e.getMessage()); 
     1045        } 
     1046    } 
     1047    } 
     1048 
     1049    private class CustomUndoableEditListener implements UndoableEditListener { 
     1050    public void undoableEditHappened(UndoableEditEvent evt) 
     1051    { 
     1052         
     1053        undoManager.addEdit(evt.getEdit()); 
     1054        redo_button.setEnabled(false); 
     1055        undo_button.setEnabled(true); 
     1056    } 
     1057    } 
     1058 
    9771059}