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 {
- @SuppressWarnings("unused")
private final static Logger LOGGER = LoggerFactory.getLogger(TechTypeTableDataProvider.class);
private List<CSVRecord> records = new ArrayList<>();
- private List<CSVRecord> filteredRecords = new ArrayList<>();
- private String filter = "";
+ private boolean[] enabled;
+ private String filter = null;
private List<String> variables = null;
private List<String> headers = null;
+ private int[] filteredRows;
+ private ListenerList<EnableListener> enableListeners = new ListenerList<EnableListener>();
+
+ private int[] sortedRows;
+
+ private boolean showEnabled = true;
+
+ private static final Comparator<? super String> 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);
+ showEnabled = enabledList != null;
+ }
+
public TechTypeTableDataProvider(String data) {
- // load csv
setData(data);
+ showEnabled = false;
+ }
+
+ 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;
+ }
+ }
+
+ showEnabled = enabledList != null;
+ }
+
+ public boolean isCheckBoxColumn(int columnIndex) {
+ return isEnabledColumn(columnIndex);
}
public String getVariableName(int columnIndex) {
- return variables != null && columnIndex < variables.size() ? variables.get(columnIndex) : null;
+ return variables != null && columnIndex > 0 && columnIndex <= variables.size()
+ ? variables.get(columnIndex - columnOffset())
+ : null;
}
+ private int columnOffset() {
+ return showEnabled ? 1 : 0;
+ }
+
public int getVariableIndex(String variableName) {
- return variables != null ? variables.indexOf(variableName) : -1;
+ return variables != null ? variables.indexOf(variableName) + columnOffset() : -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 "<empty>";
+ } else if (isEnabledColumn(columnIndex)) {
+ return "Enabled";
+ } else {
+ return headers.get(columnIndex - columnOffset());
}
- return headers.get(columnIndex);
}
@Override
public Object getDataValue(int columnIndex, int rowIndex) {
- return filteredRecords.get(rowIndex).get(columnIndex);
+ if (isEnabledColumn(columnIndex)) {
+ return isEnabled(rowIndex);
+ }
+ return getRecord(rowIndex).get(columnIndex - columnOffset());
}
@Override
public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
+ if (isEnabledColumn(columnIndex)) {
+ 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
if (records.isEmpty()) {
return 0;
}
- return records.get(0).size();
+ return records.get(0).size() + columnOffset();
}
@Override
public int getRowCount() {
- return filteredRecords.size();
+ return filteredRows.length;
}
public boolean isEditable(int columnIndex, int rowIndex) {
- return false;
+ return isEnabledColumn(columnIndex);
}
+ private boolean isEnabledColumn(int columnIndex) {
+ return showEnabled && 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;
}
/**
*/
public void setPath(String path) {
records.clear();
- filteredRecords.clear();
+
if (path != null) {
Path techTypeCsv = Paths.get(path);
try {
}
}
- setFilter("");
+ enabled = new boolean[records.size()];
+ sortedRows = IntStream.range(0, records.size()).toArray();
+
+ setFilter(null);
}
/**
*/
public void setData(String data) {
records.clear();
- filteredRecords.clear();
+
if (data != null) {
long ncommas = data.chars().filter(c -> c == ',').count();
long nsemis = data.chars().filter(c -> c == ';').count();
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)) {
+ int offset = columnOffset();
+ Comparator<Integer> comparator = isEnabledColumn(columnIndex) ?
+ Comparator.comparing(k -> enabled[sortedRows[(int) k]]) :
+ Comparator.comparing(k -> records.get(sortedRows[(int) k]).get(columnIndex-offset), 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