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%2FTechTypeTable.java;h=8ee627a57989c09a79732b4773281c1a1b493352;hb=5fb5ec8d095bfcf9bccbd6be506e509b72643fa5;hp=eb83c902ddf535c9bcd8ae236de40913d33bf4a6;hpb=dcb686d6fff0610d4c26d0149e90996822b08836;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTable.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTable.java index eb83c902..8ee627a5 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTable.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/techtype/table/TechTypeTable.java @@ -4,11 +4,14 @@ import java.io.IOException; 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; @@ -31,9 +34,15 @@ import org.eclipse.nebula.widgets.nattable.hover.config.BodyHoverStylingBindings 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; @@ -43,13 +52,20 @@ import org.eclipse.swt.widgets.Composite; 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.district.network.ui.techtype.requests.WriteTechTypeTableRequest; +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; @@ -69,10 +85,14 @@ public class TechTypeTable extends Composite { private TechTypeTableSortModel sortModel; private Resource componentType; + private Resource tableResource; + + protected Set 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); } @@ -120,7 +140,7 @@ public class TechTypeTable extends Composite { // directly as body layer is also working. bodyDataProvider = new TechTypeTableDataProvider(data); bodyDataLayer = new DataLayer(bodyDataProvider); - + RowReorderLayer rowReorderLayer = new RowReorderLayer( columnHideShowLayer = new ColumnHideShowLayer(bodyDataLayer)); @@ -167,6 +187,21 @@ public class TechTypeTable extends Composite { 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 @@ -187,6 +222,18 @@ public class TechTypeTable extends Composite { 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(); @@ -196,20 +243,85 @@ public class TechTypeTable extends Composite { public void setTechTypePath(String path) { String data; try { - data = Files.lines(Paths.get(path)).collect(Collectors.joining("\n")); + data = Files.lines(Paths.get(path), Charset.defaultCharset()).collect(Collectors.joining("\n")); } catch (IOException e) { LOGGER.error("Failed to read contents of file '{}' as {}", path, Charset.defaultCharset(), e); return; } try { - Simantics.getSession().syncRequest(new WriteTechTypeTableRequest(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) { bodyDataProvider.setData(data); table.refresh(true); } + public void setComponentType(Resource componentType) { + this.componentType = componentType; + } + + /** + * Set results of a validation operation + * + * Invalid entries are designated by a string of the form "/". + * + * This method must be called in the SWT thread. + * + * @param result A set of strings representing invalid entries + */ + public void setValidationResult(Set 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; + } }