X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2Ftechtype%2Ftable%2FTechTypeTableDataProvider.java;h=af0e28d07bc84be4b9b01ab221105b2f3c5269a9;hb=3424ba8b4dd8e368badce8515bca96a99be518f4;hp=534be1dafe5a57d2dfef57884de4b6e676203017;hpb=d99e6afb3299fd1bd7cdf150b7d5f950c61b1959;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableDataProvider.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableDataProvider.java index 534be1da..af0e28d0 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableDataProvider.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTableDataProvider.java @@ -1,43 +1,122 @@ package org.simantics.district.network.ui.techtype.table; import java.io.IOException; +import java.io.StringReader; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; import java.util.List; -import java.util.stream.Collectors; +import java.util.stream.IntStream; import org.apache.commons.csv.CSVRecord; +import org.eclipse.core.runtime.ListenerList; import org.eclipse.nebula.widgets.nattable.data.IDataProvider; +import org.eclipse.nebula.widgets.nattable.sort.SortDirectionEnum; import org.simantics.district.imports.DistrictImportUtils; +import org.simantics.district.network.techtype.TechTypeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TechTypeTableDataProvider implements IDataProvider { + private final static Logger LOGGER = LoggerFactory.getLogger(TechTypeTableDataProvider.class); + private List records = new ArrayList<>(); - private List filteredRecords = new ArrayList<>(); - private String filter = ""; + private boolean[] enabled; + private String filter = null; + private List variables = null; + private List headers = null; + private int[] filteredRows; + + private ListenerList enableListeners = new ListenerList(); + + private int[] sortedRows; - public TechTypeTableDataProvider() { + private static final Comparator VALUE_COMPARATOR = (a, b) -> { + try { + double da = Double.valueOf(a.replace(",", ".")); + double db = Double.valueOf(b.replace(",", ".")); + return Double.compare(da, db); + } catch (NumberFormatException e) { + return TechTypeUtils.compareNatural(a, b); + } + }; + + public TechTypeTableDataProvider(String data, int[] enabledList) { + setData(data); + setEnabledFlags(enabledList); + } + + public TechTypeTableDataProvider(String data) { // load csv + setData(data); + } + + public void setEnabledFlags(int[] enabledList) { + this.enabled = new boolean[records.size()]; + if (enabledList != null) { + for (int i : enabledList) { + if (i >= 0 && i < enabled.length) + enabled[i] = true; + } + } + } - setPath("C:\\projektit\\apros\\Semantum_VTT_Fortum portaali 2018-17-12\\järvenpää\\qgis\\TechTypeData.csv"); + public String getVariableName(int columnIndex) { + return variables != null && columnIndex > 0 && columnIndex <= variables.size() ? variables.get(columnIndex - 1) : null; } - public Object getHeaderValue(int columnIndex) { - if (records.isEmpty()) { + public int getVariableIndex(String variableName) { + return variables != null ? variables.indexOf(variableName) + 1 : -1; + } + + public CSVRecord getRecord(int rowIndex) { + return records.get(recordIndex(rowIndex)); + } + + public boolean isEnabled(int rowIndex) { + return enabled[recordIndex(rowIndex)]; + } + + private int recordIndex(int rowIndex) { + return sortedRows[filteredRows[rowIndex]]; + } + + public String getHeaderValue(int columnIndex) { + if (headers == null) { return ""; + } else if (columnIndex == 0) { + return "Enabled"; + } else { + return headers.get(columnIndex - 1); } - return records.get(0).get(columnIndex); } @Override public Object getDataValue(int columnIndex, int rowIndex) { - return filteredRecords.get(rowIndex + 1).get(columnIndex); + if (columnIndex == 0) { + return isEnabled(rowIndex); + } + return getRecord(rowIndex).get(columnIndex - 1); } @Override public void setDataValue(int columnIndex, int rowIndex, Object newValue) { + if (columnIndex == 0) { + boolean value = Boolean.parseBoolean((String) newValue); + enabled[recordIndex(rowIndex)] = value; + fireEnableEvent(rowIndex, value); + } + } + + public void addEnableListener(EnableListener listener) { + enableListeners.add(listener); + } + private void fireEnableEvent(int rowIndex, boolean newValue) { + enableListeners.forEach(l -> l.rowEnabled(rowIndex, newValue)); } @Override @@ -45,46 +124,135 @@ public class TechTypeTableDataProvider implements IDataProvider { if (records.isEmpty()) { return 0; } - return records.get(0).size(); + return records.get(0).size() + 1; } @Override public int getRowCount() { - return filteredRecords.size() - 1; + return filteredRows.length; } public boolean isEditable(int columnIndex, int rowIndex) { - return false; + return columnIndex == 0; } public void setFilter(String text) { - this.filter = text.toLowerCase(); + this.filter = text != null ? text.toLowerCase() : null; - filteredRecords = records.stream().filter(record -> { - for (int i = 0; i < record.size(); i++) { - String columnContent = record.get(i); - if (columnContent.toLowerCase().contains(filter)) { - return true; - } + filteredRows = IntStream.range(0, records.size()) + .filter(k -> isMatch(records.get(sortedRows[k]), filter)) + .toArray(); + } + + private static boolean isMatch(CSVRecord record, String filterString) { + if (filterString == null || filterString.isEmpty()) + return true; + + for (int i = 0; i < record.size(); i++) { + String columnContent = record.get(i); + if (columnContent.toLowerCase().contains(filterString)) { + return true; } - return false; - }).collect(Collectors.toList()); + } + + return false; } + /** + * Read a CSV file into table contents. + * + * Set path to null to create an empty table. + * + * @param path The path of the CSV file to be read. + */ public void setPath(String path) { records.clear(); - filteredRecords.clear(); - Path techTypeCsv = Paths.get(path); - try { - DistrictImportUtils.consumeCSV(techTypeCsv, ';', false, record -> { - records.add(record); - return true; - }); - } catch (IOException e) { - e.printStackTrace(); + + if (path != null) { + Path techTypeCsv = Paths.get(path); + try { + DistrictImportUtils.consumeCSV(techTypeCsv, ';', false, record -> { + records.add(record); + return true; + }); + } catch (IOException e) { + e.printStackTrace(); + } + } + + enabled = new boolean[records.size()]; + sortedRows = IntStream.range(0, records.size()).toArray(); + + setFilter(null); + } + + /** + * Set table data contents to a given string of CSV data. + * + * Set 'data' to null to create an empty table. + * + * @param data The CSV data to be shown in the table. + */ + public void setData(String data) { + records.clear(); + + if (data != null) { + long ncommas = data.chars().filter(c -> c == ',').count(); + long nsemis = data.chars().filter(c -> c == ';').count(); + char delim = nsemis > ncommas ? ';' : ','; + StringReader reader = new StringReader(data); + try { + DistrictImportUtils.consumeCSV(reader, delim, false, record -> { + records.add(record); + return true; + }); + } catch (IOException e) { + LOGGER.error("Error reading CSV file", e); + return; + } + + CSVRecord header = records.remove(0); + CSVRecord units = records.remove(0); + + variables = new ArrayList<>(); + headers = new ArrayList<>(); + + Iterator it = header.iterator(); + Iterator uit = units.iterator(); + + while (it.hasNext()) { + String variable = it.next().trim(); + String unit = uit.hasNext() ? uit.next().trim() : null; + + variables.add(variable); + headers.add(variable + (unit != null && !unit.isEmpty() && !(unit.startsWith("(") && unit.endsWith(")")) ? " [" + unit + "]" : "")); + } } + + enabled = new boolean[records.size()]; + sortedRows = IntStream.range(0, records.size()).toArray(); - setFilter(""); + setFilter(null); + } + + public void sortBy(int columnIndex, SortDirectionEnum sortDirection) { + + if (columnIndex >= 0 && !sortDirection.equals(SortDirectionEnum.NONE)) { + Comparator comparator = columnIndex == 0 ? + Comparator.comparing(k -> enabled[sortedRows[(int) k]]) : + Comparator.comparing(k -> records.get(sortedRows[(int) k]).get(columnIndex-1), VALUE_COMPARATOR); + + if (sortDirection.equals(SortDirectionEnum.DESC)) + comparator = comparator.reversed(); + + sortedRows = IntStream.range(0, records.size()) + .mapToObj(i -> i) + .sorted(comparator) + .mapToInt(i -> sortedRows[i]) + .toArray(); + } else { + sortedRows = IntStream.range(0, records.size()).toArray(); + } } -} +} \ No newline at end of file