From c718fdef0bfa044bd9576fcaee40d0313ebe1d30 Mon Sep 17 00:00:00 2001 From: serge-rider Date: Wed, 25 Jan 2017 18:15:27 +0300 Subject: [PATCH] #1178 Advanced paste fix (parse grid + quoted cells) --- .../spreadsheet/SpreadsheetPresentation.java | 78 ++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java index 9d065b8bb4..fdd5b5ce8c 100644 --- a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java +++ b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java @@ -486,10 +486,10 @@ public class SpreadsheetPresentation extends AbstractPresentation implements IRe return; } try (DBCSession session = DBUtils.openUtilSession(VoidProgressMonitor.INSTANCE, dataSource, "Advanced paste")) { - for (String line : strValue.split("\n")) { + for (String[] line : parseGridLines(strValue)) { int colNum = focusPos.col; Object rowElement = spreadsheet.getRowElement(rowNum); - for (String value : line.split("\t")) { + for (String value : line) { if (colNum >= spreadsheet.getColumnCount()) { break; } @@ -545,6 +545,80 @@ public class SpreadsheetPresentation extends AbstractPresentation implements IRe } } + private String[][] parseGridLines(String strValue) { + final char columnDelimiter = '\t'; + final char rowDelimiter = '\n'; + final char trashDelimiter = '\r'; + final char quote = '"'; + + final List lines = new ArrayList<>(); + + final StringBuilder cellValue = new StringBuilder(); + final List curLine = new ArrayList<>(); + boolean inQuote = false; + int length = strValue.length(); + for (int i = 0; i < length; i++) { + char c = strValue.charAt(i); + if (inQuote && c != quote) { + cellValue.append(c); + } else { + switch (c) { + case columnDelimiter: + curLine.add(cellValue.toString()); + cellValue.setLength(0); + break; + case rowDelimiter: + curLine.add(cellValue.toString()); + lines.add(curLine.toArray(new String[curLine.size()])); + curLine.clear(); + cellValue.setLength(0); + break; + case trashDelimiter: + // Ignore + continue; + case quote: + if (inQuote) { + if (i == length - 1 || + strValue.charAt(i + 1) == columnDelimiter || + strValue.charAt(i + 1) == trashDelimiter || + strValue.charAt(i + 1) == rowDelimiter) + { + inQuote = false; + continue; + } + } else if (cellValue.length() == 0) { + // Search for end quote + for (int k = i + 1; k < length; k++) { + if (strValue.charAt(k) == quote && + (k == length - 1 || + strValue.charAt(k + 1) == columnDelimiter || + strValue.charAt(k + 1) == trashDelimiter || + strValue.charAt(k + 1) == rowDelimiter)) + { + inQuote = true; + break; + } + } + if (inQuote) { + continue; + } + } + default: + cellValue.append(c); + break; + } + } + } + if (cellValue.length() > 0) { + curLine.add(cellValue.toString()); + } + if (!curLine.isEmpty()) { + lines.add(curLine.toArray(new String[curLine.size()])); + } + + return lines.toArray(new String[lines.size()][]); + } + @Override public Control getControl() { return spreadsheet; -- GitLab