import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.nebula.widgets.nattable.NatTable;
+import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
+import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.copy.command.CopyDataCommandHandler;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer;
+import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
+import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.reorder.RowReorderLayer;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
+import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
+import org.eclipse.nebula.widgets.nattable.style.Style;
+import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.widgets.Text;
import org.simantics.Simantics;
import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.WriteRequest;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.request.PossibleActiveModel;
+import org.simantics.district.network.techtype.requests.PossibleTechTypeKeyName;
+import org.simantics.district.network.techtype.requests.PossibleTechTypeTable;
import org.simantics.district.network.techtype.requests.WriteTechTypeTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TechTypeTable extends Composite {
+ private static final String INVALID_LABEL = "INVALID";
+
private final static Logger LOGGER = LoggerFactory.getLogger(TechTypeTable.class);
NatTable table;
private TechTypeTableSortModel sortModel;
private Resource componentType;
+ private Resource tableResource;
+
+ protected Set<String> validationResult;
- public TechTypeTable(Composite parent, int style, Resource componentType, String data) {
+ public TechTypeTable(Composite parent, int style, Resource componentType, Resource tableResource, String data) {
super(parent, style);
this.componentType = componentType;
+ this.tableResource = tableResource;
defaultInitializeUI(data);
}
// directly as body layer is also working.
bodyDataProvider = new TechTypeTableDataProvider(data);
bodyDataLayer = new DataLayer(bodyDataProvider);
-
+
RowReorderLayer rowReorderLayer = new RowReorderLayer(
columnHideShowLayer = new ColumnHideShowLayer(bodyDataLayer));
table = new NatTable(parent, NatTable.DEFAULT_STYLE_OPTIONS | SWT.BORDER, gridLayer, false);
GridDataFactory.fillDefaults().grab(true, true).applyTo(table);
+
+ // Show entries labeled "INVALID" with red text
+ table.addConfiguration(new AbstractRegistryConfiguration() {
+ @Override
+ public void configureRegistry(IConfigRegistry configRegistry) {
+ Style cellStyle = new Style();
+ cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_RED);
+ configRegistry.registerConfigAttribute(
+ CellConfigAttributes.CELL_STYLE,
+ cellStyle,
+ DisplayMode.NORMAL,
+ INVALID_LABEL
+ );
+ }
+ });
// Register a CopyDataCommandHandler that also copies the headers and
// uses the configured IDisplayConverters
table.configure();
}
+ private static String getKeyColumnName(Resource componentType) {
+ String keyName = null;
+ if (componentType != null) {
+ try {
+ keyName = Simantics.getSession().syncRequest(new PossibleTechTypeKeyName(componentType));
+ } catch (DatabaseException e) {
+ LOGGER.error("Failed to read possible tech type key name for {}", componentType, e);
+ }
+ }
+ return keyName.startsWith("_") ? keyName.substring(1) : keyName;
+ }
+
@Override
public void dispose() {
cpb.dispose();
}
try {
- Simantics.getSession().syncRequest(new WriteTechTypeTable(componentType, data));
+ Simantics.getSession().syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ graph.syncRequest(new WriteTechTypeTable(componentType, data));
+ Resource model = graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
+ if (model != null) {
+ tableResource = graph.syncRequest(new PossibleTechTypeTable(model, componentType));
+ }
+ }
+ });
} catch (DatabaseException e) {
LOGGER.error("Failed to write tech type table data to model", e);
}
setTechTypeData(data);
+ setValidationResult(null);
}
public void setTechTypeData(String data) {
this.componentType = componentType;
}
-}
+ /**
+ * Set results of a validation operation
+ *
+ * Invalid entries are designated by a string of the form "<type_code>/<property_name>".
+ *
+ * This method must be called in the SWT thread.
+ *
+ * @param result A set of strings representing invalid entries
+ */
+ public void setValidationResult(Set<String> result) {
+ if (result != null && result.isEmpty())
+ result = null;
+
+ this.validationResult = result;
+ if (result != null) {
+ String keyName = getKeyColumnName(componentType);
+
+ bodyDataLayer.setConfigLabelAccumulator(new IConfigLabelAccumulator() {
+ @Override
+ public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition) {
+ if (keyName != null) {
+ int keyColumn = bodyDataProvider.getVariableIndex(keyName);
+ if (keyColumn >= 0) {
+ String key = (String) bodyDataProvider.getDataValue(keyColumn, rowPosition);
+ String columnName = bodyDataProvider.getVariableName(columnPosition);
+
+ if (validationResult.contains(key + "/" + columnName)) {
+ configLabels.addLabel(INVALID_LABEL);
+ }
+ }
+ }
+ }
+ });
+ } else {
+ bodyDataLayer.setConfigLabelAccumulator(null);
+ }
+
+ table.refresh();
+ }
+ /**
+ * Get a resource representation of the currently open table, or null if
+ * table is not stored in the model.
+ */
+ public Resource getCurrentTable() {
+ return tableResource;
+ }
+}