Changeset 29006 for main


Ignore:
Timestamp:
2014-04-29T19:09:22+12:00 (10 years ago)
Author:
ak19
Message:

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

File:
1 edited

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}
Note: See TracChangeset for help on using the changeset viewer.