package org.geogebra.desktop.gui.view.spreadsheet;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import org.geogebra.common.gui.view.spreadsheet.CellRange;
import org.geogebra.common.gui.view.spreadsheet.CopyPasteCut;
import org.geogebra.common.gui.view.spreadsheet.DataImport;
import org.geogebra.common.gui.view.spreadsheet.RelativeCopy;
import org.geogebra.common.kernel.StringTemplate;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.main.App;
import org.geogebra.common.util.Charsets;
import org.geogebra.common.util.StringUtil;
public class CopyPasteCutD extends CopyPasteCut {
public CopyPasteCutD(App app) {
super(app);
}
@Override
public void copy(int column1, int row1, int column2, int row2,
boolean skipGeoCopy) {
/*
* disabled as we don't want commas when pasting from spreadsheet into
* other parts of GeoGebra eg input bar also see
* DataImport.parseExternalData()
*
* //boolean changeDecimalSeparator = '.' != decimalSeparator; if
* (changeDecimalSeparator) { Log.debug(
* "changing decimal separator to: "+decimalSeparator); }
*/
// copy tab-delimited geo values into the external buffer
if (getCellBufferStr() == null) {
setCellBufferStr(new StringBuilder());
} else {
getCellBufferStr().setLength(0);
}
for (int row = row1; row <= row2; ++row) {
for (int column = column1; column <= column2; ++column) {
GeoElement value = RelativeCopy.getValue(app, column, row);
if (value != null) {
String valueStr = value
.toValueString(StringTemplate.maxPrecision);
getCellBufferStr().append(valueStr);
}
if (column != column2) {
getCellBufferStr().append('\t');
}
}
if (row != row2) {
getCellBufferStr().append('\n');
}
}
// store the tab-delimited values in the clipboard
Toolkit toolkit = Toolkit.getDefaultToolkit();
Clipboard clipboard = toolkit.getSystemClipboard();
StringSelection stringSelection = new StringSelection(
getCellBufferStr().toString());
clipboard.setContents(stringSelection, null);
// store copies of the actual geos in the internal buffer
if (skipGeoCopy) {
setCellBufferGeo(null);
} else {
sourceColumn1 = column1;
sourceRow1 = row1;
setCellBufferGeo(RelativeCopy.getValues(app, column1, row1, column2,
row2));
}
}
@Override
/** Paste data from the clipboard */
public boolean paste(int column1, int row1, int column2, int row2) {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable contents = clipboard.getContents(null);
return paste(column1, row1, column2, row2, contents);
}
/**
* Pastes data from given Transferable into the given spreadsheet cells.
*
* @param column1
* first column of the target cell range
* @param row1
* first row of the target cell range
* @param column2
* last column of the target cell range
* @param row2
* last row of the target cell range
* @param contents
* @return
*/
public boolean paste(int column1, int row1, int column2, int row2,
Transferable contents) {
boolean succ = false;
boolean isCSV = false;
String transferString = null;
// extract a String from the Transferable contents
transferString = DataImportD.convertTransferableToString(contents);
if (transferString == null) {
return false;
}
isCSV = DataImportD.hasHTMLFlavor(contents);
// System.out.println("transfer string: " + transferString);
// test if the transfer string is the same as the internal cell copy
// string. If true, then we have a tab-delimited list of cell geos and
// can paste them with relative cell references
boolean doInternalPaste = getCellBufferStr() != null
&& transferString.equals(getCellBufferStr().toString());
if (doInternalPaste && getCellBufferGeo() != null) {
// use the internal field cellBufferGeo to paste geo copies
// with relative cell references
succ = pasteInternalMultiple(column1, row1, column2, row2);
} else {
// use the transferString data to create and paste new geos
// into the target cells without relative cell references
String[][] data = DataImport.parseExternalData(app, transferString,
isCSV);
succ = pasteExternalMultiple(data, column1, row1, column2, row2);
// Application.debug("newline index "+buf.indexOf("\n"));
// Application.debug("length "+buf.length());
}
return succ;
}
// default pasteFromFile: clear spreadsheet and then paste from upper left
// corner
public boolean pasteFromURL(URL url) {
CellRange cr = new CellRange(app, 0, 0, 0, 0);
return pasteFromURL(url, cr, true);
}
public boolean pasteFromURL(URL url, CellRange targetRange,
boolean clearSpreadsheet) {
// read file
StringBuilder contents = new StringBuilder();
boolean isCSV = getExtension(url.getFile()).equals("csv");
try {
InputStream is = url.openStream();
BufferedReader input = new BufferedReader(
new InputStreamReader(is, Charsets.UTF_8));
try {
String line = null;
while ((line = input.readLine()) != null) {
contents.append(line);
contents.append(System.getProperty("line.separator"));
}
} finally {
input.close();
}
} catch (IOException ex) {
ex.printStackTrace();
return false;
}
// System.out.println(dataFile.getName() + ": " + contents.capacity());
boolean succ = true;
String[][] data = DataImport.parseExternalData(app,
contents.toString(), isCSV);
if (data != null) {
if (clearSpreadsheet) {
deleteAll();
}
succ = pasteExternalMultiple(data, targetRange);
} else {
succ = false;
}
return succ;
}
/**
* Return the extension portion of the file's name.
*
* @param f
* @return "ext" for file "filename.ext"
*/
private static String getExtension(String filename) {
if (filename != null) {
int i = filename.lastIndexOf('.');
if (i > 0 && i < filename.length() - 1) {
return StringUtil.toLowerCase(filename.substring(i + 1));
}
}
return null;
}
}