package org.geogebra.desktop.gui.view.spreadsheet; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.text.DecimalFormatSymbols; import javax.swing.text.MutableAttributeSet; import javax.swing.text.html.HTML; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.parser.ParserDelegator; import org.geogebra.common.gui.view.spreadsheet.DataImport; import org.geogebra.common.main.App; import org.geogebra.common.util.debug.Log; import org.geogebra.desktop.main.AppD; /** * Utility class with methods to handle importing data into the spreadsheet. * * @author G. Sturr * */ public class DataImportD extends DataImport { static DataFlavor HTMLflavor; static { try { HTMLflavor = new DataFlavor("text/html;class=java.lang.String"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static boolean hasHTMLFlavor(Transferable t) { return t.isDataFlavorSupported(HTMLflavor); } /** * Returns a string object extracted from the given Transferable. If the * DataFlavor is "text/html;class=java.lang.String" an attempt is made to * convert the transferable object into a CSV string (e.g. data transferred * from Excel) * * @param contents * @return */ public static String convertTransferableToString(Transferable contents) { String transferString = null; // exit if no content if (contents == null) { return null; } // print available data formats in Transferable contents for (int i = 0; i < contents.getTransferDataFlavors().length; i++) { // System.out.println(contents.getTransferDataFlavors()[i]); } // try to extract a string from the Transferable try { // System.out.println("is HTML? " + // contents.isDataFlavorSupported(HTMLflavor)); if (hasHTMLFlavor(contents)) { transferString = DataImportD.convertHTMLTableToCSV( (String) contents.getTransferData(HTMLflavor)); // transferString = (String) contents // .getTransferData(DataFlavor.stringFlavor); } } catch (UnsupportedFlavorException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // no HTML found, try plain text if (transferString == null && contents.isDataFlavorSupported(DataFlavor.stringFlavor)) { try { transferString = (String) contents .getTransferData(DataFlavor.stringFlavor); // Application.debug("pasting from String: "+buf); } catch (Exception ex) { Log.debug("transferable has no String"); // ex.printStackTrace(); // app.showError(ex.getMessage()); } } return transferString; } /** * Converts HTML table into CSV */ public static String convertHTMLTableToCSV(String HTMLTableString) { final StringBuilder sbHTML = new StringBuilder(); // System.out.println("html: " + HTMLTableString); try { // prepare the parser HTMLEditorKit.ParserCallback callback = new HTMLEditorKit.ParserCallback() { boolean foundTable = false; boolean firstInRow = true; boolean firstColumn = true; boolean finished = false; @Override public void handleText(char[] data, int pos) { if (foundTable && !finished) { // if string contains a comma, surround the string with // quotes "" boolean containsComma = false; boolean appendQuotes = false; for (int i = 0; i < data.length; i++) { if (data[i] == ',') { containsComma = true; } } if (containsComma && (data[0] != '"' || data[data.length - 1] != '"')) { appendQuotes = true; } if (appendQuotes) { sbHTML.append('"'); } for (int i = 0; i < data.length; i++) { sbHTML.append(data[i]); } if (appendQuotes) { sbHTML.append('"'); } } } @Override public void handleStartTag(HTML.Tag tag, MutableAttributeSet attrSet, int pos) { if (tag == HTML.Tag.TABLE) { // Application.debug("table"); if (foundTable) { finished = true; } foundTable = true; firstColumn = true; sbHTML.setLength(0); } else if (foundTable && tag == HTML.Tag.TR) { // Application.debug("TR"); if (!firstColumn) { sbHTML.append("\n"); } firstInRow = true; firstColumn = false; } else if (foundTable && (tag == HTML.Tag.TD || tag == HTML.Tag.TH)) { // Application.debug("TD"); if (!firstInRow) { sbHTML.append(","); } firstInRow = false; } else if (!foundTable) { // Application.debug("TR without table"); sbHTML.setLength(0); if (tag == HTML.Tag.TR) { foundTable = true; // HTML fragment without <TABLE> firstInRow = true; firstColumn = false; } } } }; // parse the text Reader reader = new StringReader(HTMLTableString); new ParserDelegator().parse(reader, callback, true); } catch (Exception e) { Log.debug("clipboard: no HTML"); } if (sbHTML.length() != 0) { // found HTML table to paste as CSV return sbHTML.toString(); } return null; } static String[] getDefaultSeparators(App app) { String[] separators = new String[2]; // Get decimal and thousands separators DecimalFormatSymbols dfs = new DecimalFormatSymbols( ((AppD) app).getLocale()); separators[0] = Character.toString(dfs.getDecimalSeparator()); separators[1] = Character.toString(dfs.getGroupingSeparator()); return separators; } }