Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe Commits: 34e5df83 by tchemit at 2019-07-04T11:26:30Z [PS][FAD] Gestion visuelle de la hiérarchie des matériaux sélectionnée - Closes #1323 - - - - - 9 changed files: - client-configuration/src/main/config/Client.ini - client-configuration/src/main/i18n/getters/config.getter - client-core/src/main/java/fr/ird/observe/client/ui/content/data/ps/observation/dcp/FloatingObjectPartsTableCellRenderer.java - client-core/src/main/java/fr/ird/observe/client/ui/content/data/ps/observation/dcp/FloatingObjectPartsTreeNode.java - client-core/src/main/java/fr/ird/observe/client/ui/content/data/ps/observation/dcp/FloatingObjectPartsTreeTable.java - client-core/src/main/java/fr/ird/observe/client/ui/content/data/ps/observation/dcp/FloatingObjectPartsTreeTableModel.java - observe-i18n/src/main/i18n/translations/observe_en_GB.properties - observe-i18n/src/main/i18n/translations/observe_es_ES.properties - observe-i18n/src/main/i18n/translations/observe_fr_FR.properties Changes: ===================================== client-configuration/src/main/config/Client.ini ===================================== @@ -608,6 +608,12 @@ key = ui.dcp.error.color type = color defaultValue = java.awt.Color[r=255,g=100,b=100] +[option floatingObjectMaterialNotEditableColor] +description = observe.config.ui.dcp.not.editable.color +key = ui.dcp.not.editable.color +type = color +defaultValue = java.awt.Color[r=193,g=250,b=250] + [option showMnemonic] description = observe.config.ui.showMnemonic key = ui.showMnemonic ===================================== client-configuration/src/main/i18n/getters/config.getter ===================================== @@ -91,6 +91,7 @@ observe.config.temperature.format observe.config.ui.autoPopupNumberEditor observe.config.ui.changeSynchroSrc observe.config.ui.dcp.error.color +observe.config.ui.dcp.not.editable.color observe.config.ui.focusBorderColor observe.config.ui.fullscreen observe.config.ui.loadLocalStorage ===================================== client-core/src/main/java/fr/ird/observe/client/ui/content/data/ps/observation/dcp/FloatingObjectPartsTableCellRenderer.java ===================================== @@ -60,7 +60,7 @@ public class FloatingObjectPartsTableCellRenderer implements TableCellRenderer { Objects.requireNonNull(node); TableCellRenderer renderer = objectRenderer; Object newValue = value; - boolean enabled = node.isEditable() && table.isCellEditable(row, column) && node.isEnabled(); + boolean enabled = node.isEditable() && table.isCellEditable(row, column) && node.isEnabled(column); if (node.isBoolean()) { if (node.isColumnEditable(column)) { newValue = value == null ? null : Boolean.valueOf(String.valueOf(value)); ===================================== client-core/src/main/java/fr/ird/observe/client/ui/content/data/ps/observation/dcp/FloatingObjectPartsTreeNode.java ===================================== @@ -98,10 +98,10 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im @Override public boolean isEditable(int column) { - return column > 0 && getUserObject().enabled && getUserObject().editable && isColumnEditable(column); + return column > 0 && isEnabled(column) && getUserObject().editable && isColumnEditable(column); } - public boolean isColumnEditable(int column) { + boolean isColumnEditable(int column) { return getUserObject().isColumnEditable(column); } @@ -132,6 +132,17 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im public boolean isEnabled() { return getUserObject().enabled; } + public boolean isEnabled(int column) { + boolean result = getUserObject().enabled; + if (result) { + if (column==1) { + result = isRealEnabledOnArriving(); + } else if (column==2) { + result = isRealEnabledOnLeaving(); + } + } + return result; + } public String getId() { return getUserObject().dto.getId(); @@ -178,6 +189,38 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im return (FloatingObjectPartsTreeNode) super.getParent(); } + boolean isRealEnabledOnArriving() { + return getUserObject().isRealEnabledOnArriving(); + } + + boolean isRealEnabledOnLeaving() { + return getUserObject().isRealEnabledOnLeaving(); + } + + void setRealEnabledOnArriving(boolean realEnabled) { + FloatingObjectPartsTreeNode parent = getParent(); + if (parent != null) { + if (realEnabled) { + parent.getUserObject().decSelectedChildCountOnArriving(); + } else { + parent.getUserObject().incSelectedChildCountOnArriving(); + } + parent.setRealEnabledOnArriving(realEnabled); + } + } + + void setRealEnabledOnLeaving(boolean realEnabled) { + FloatingObjectPartsTreeNode parent = getParent(); + if (parent != null) { + if (realEnabled) { + parent.getUserObject().decSelectedChildCountOnLeaving(); + } else { + parent.getUserObject().incSelectedChildCountOnLeaving(); + } + parent.setRealEnabledOnLeaving(realEnabled); + } + } + ImmutableSet<FloatingObjectPartsTreeNode> getShell() { ImmutableSet.Builder<FloatingObjectPartsTreeNode> allNodesBuilder = ImmutableSet.builder(); @@ -192,7 +235,7 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im } } - boolean withMandatoryConstraintsOnChildren() { + public boolean withMandatoryConstraintsOnChildren() { ObjectMaterialHierarchyDto userObject = getUserObject().dto; return userObject == null || userObject.isChildSelectionMandatory(); } @@ -212,18 +255,6 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im } - private FloatingObjectPartsTreeNode getFirstAncestorNeedOneSelection(int column) { - if (withMandatoryConstraintsOnChildren()) { - if (parent == null) { - return this; - } - if (withValue(column)) { - return this; - } - } - return getParent().getFirstAncestorNeedOneSelection(column); - } - void computeMandatoryValidState(boolean whenArriving, boolean whenLeaving) { FloatingObjectPartsTreeNodeContext userObject = getUserObject(); FloatingObjectPartsTreeNode parent = getParent(); @@ -247,19 +278,26 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im } } -// void computeFormulaValidState(boolean whenArriving, boolean whenLeaving) { -// FloatingObjectPartsTreeNodeContext userObject = getUserObject(); -// ObjectMaterialHierarchyDto dto = Objects.requireNonNull(userObject.dto); -// if (whenArriving && userObject.validWhenArriving) { -// Object value = userObject.getValueAt(1); -// userObject.validWhenArriving = dto.isValid(value); -// } -// if (whenLeaving && userObject.validWhenLeaving) { -// Object value = userObject.getValueAt(2); -// userObject.validWhenLeaving = dto.isValid(value); -// } -// -// } + void computeValidationValidState() { + getUserObject().computeValidationValidState(); + } + + void resetRealEnabled() { + getUserObject().selectedChildCountOnArriving = 0; + getUserObject().selectedChildCountOnLeaving = 0; + } + + private FloatingObjectPartsTreeNode getFirstAncestorNeedOneSelection(int column) { + if (withMandatoryConstraintsOnChildren()) { + if (parent == null) { + return this; + } + if (withValue(column)) { + return this; + } + } + return getParent().getFirstAncestorNeedOneSelection(column); + } private void setCompanions(ImmutableSet.Builder<FloatingObjectPartsTreeNode> companionsBuilder) { if (companionsBuilder != null) { @@ -308,10 +346,6 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im return dto != null && !dto.isChildrenMultiSelectable() && !isLeaf(); } - public void computeValidationValidState() { - getUserObject().computeValidationValidState(); - } - //TODO Improve the design, we should not store anything in uiModel and separate leaving and arriving data private static class FloatingObjectPartsTreeNodeContext { @@ -319,7 +353,7 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im private final FloatingObjectUIModel uiModel; // dto (null for root) private final ObjectMaterialHierarchyDto dto; - // Is the node is enabled (hierarchic value) ? + // Is the node is enabled (from hierarchic value) ? private final boolean enabled; // Is this node editable ? private final boolean editable; @@ -327,6 +361,7 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im private final boolean exclusive; // Is the node use validation on his value ? private final boolean useValidation; + // Referential locale to decorate private final ReferentialLocale referentialLocale; // Is this node (on arriving) need at least one child selected ? (if editable then node must be selected) private boolean needOneSelectionOnLeaving; @@ -344,6 +379,9 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im private ImmutableSet<FloatingObjectPartsTreeNode> companions; // Internal to store debug node text private String text; + // Count of children selected (if none is selected then the node can be edited (from GUI if a child is selected then any parent node is not enabled) ? + private int selectedChildCountOnArriving = 0; + private int selectedChildCountOnLeaving = 0; FloatingObjectPartsTreeNodeContext(FloatingObjectUIModel uiModel) { this.uiModel = Objects.requireNonNull(uiModel); @@ -431,7 +469,7 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im return text; } - public void computeValidationValidState() { + void computeValidationValidState() { if (uiModel.isArriving()) { Object value = uiModel.getWhenArriving(dto.getId()); valueValidOnArriving = dto.isValid(value); @@ -441,5 +479,29 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im valueValidOnLeaving = dto.isValid(value); } } + + boolean isRealEnabledOnArriving() { + return selectedChildCountOnArriving == 0; + } + + void incSelectedChildCountOnArriving() { + this.selectedChildCountOnArriving++; + } + + void decSelectedChildCountOnArriving() { + this.selectedChildCountOnArriving--; + } + + boolean isRealEnabledOnLeaving() { + return selectedChildCountOnLeaving == 0; + } + + void incSelectedChildCountOnLeaving() { + this.selectedChildCountOnLeaving++; + } + + void decSelectedChildCountOnLeaving() { + this.selectedChildCountOnLeaving--; + } } } ===================================== client-core/src/main/java/fr/ird/observe/client/ui/content/data/ps/observation/dcp/FloatingObjectPartsTreeTable.java ===================================== @@ -83,6 +83,7 @@ public class FloatingObjectPartsTreeTable extends JXTreeTable { FloatingObjectPartsTreeTableModel treeTableModel = getTreeTableModel(); treeTableModel.reset(true); + treeTableModel.computeRealEnabledState(); if (expandTree) { expandAll(); @@ -172,6 +173,24 @@ public class FloatingObjectPartsTreeTable extends JXTreeTable { return true; }, ObserveSwingApplicationContext.get().getConfig().getFloatingObjectMaterialErrorColor(), Color.WHITE)); + addHighlighter(new ColorHighlighter((renderer, adapter) -> { + JXTreeTable component = (JXTreeTable) adapter.getComponent(); + int row = adapter.convertRowIndexToModel(adapter.row); + FloatingObjectPartsTreeNode node = (FloatingObjectPartsTreeNode) component.getPathForRow(row).getLastPathComponent(); + boolean realEnabled1 = node.isRealEnabledOnArriving(); + boolean realEnabled2 = node.isRealEnabledOnLeaving(); + boolean nodeEditable = node.isEditable(); + switch (adapter.convertRowIndexToModel(adapter.column)) { + case 0: + return false; + case 1: + return model.isArriving() && nodeEditable && !realEnabled1; + case 2: + return model.isLeaving() && nodeEditable && !realEnabled2; + } + return true; + }, ObserveSwingApplicationContext.get().getConfig().getFloatingObjectMaterialNotEditableColor(), Color.BLACK)); + InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW); ActionMap actionMap = getActionMap(); inputMap.put(ObserveKeyStrokes.KEY_STROKE_EXPAND_TREE_TABLE_NODE,"expandNode"); ===================================== client-core/src/main/java/fr/ird/observe/client/ui/content/data/ps/observation/dcp/FloatingObjectPartsTreeTableModel.java ===================================== @@ -24,6 +24,7 @@ package fr.ird.observe.client.ui.content.data.ps.observation.dcp; import com.google.common.collect.ImmutableSet; import fr.ird.observe.client.ui.content.data.ps.observation.FloatingObjectUIModel; +import fr.ird.observe.dto.IdDto; import fr.ird.observe.dto.data.ps.observation.ObjectMaterialHierarchyDto; import io.ultreia.java4all.i18n.I18n; import org.apache.logging.log4j.LogManager; @@ -33,6 +34,8 @@ import org.jdesktop.swingx.treetable.TreeTableNode; import java.util.Arrays; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; /** * Created by tchemit on 05/08/17. @@ -81,7 +84,6 @@ public class FloatingObjectPartsTreeTableModel extends DefaultTreeTableModel { continue; } mandatoryNodesBuilder.add(node); - if (node.withMandatoryConstraintsOnChildren()) { needOneSelectionNodesBuilder.add(node); } @@ -123,6 +125,13 @@ public class FloatingObjectPartsTreeTableModel extends DefaultTreeTableModel { previousNode.ifPresent(p -> log.info("Previous selected node: " + p)); super.setValueAt(value, node, column); previousNode.ifPresent(t -> super.setValueAt(null, t, column)); + boolean realEnabled = !"true".equals(value); + log.info(String.format("Real enabled? %s", realEnabled)); + if (column == 1) { + treeNode.setRealEnabledOnArriving(realEnabled); + } else if (column == 2) { + treeNode.setRealEnabledOnLeaving(realEnabled); + } if (adjusting) { return; } @@ -146,6 +155,20 @@ public class FloatingObjectPartsTreeTableModel extends DefaultTreeTableModel { uiModel.getBean().setMaterialsValid(!notValid); } + public void computeRealEnabledState() { + Set<String> whenArriving = uiModel.getWhenArriving().keySet().stream().map(IdDto::getId).collect(Collectors.toSet()); + Set<String> whenLeaving = uiModel.getWhenLeaving().keySet().stream().map(IdDto::getId).collect(Collectors.toSet()); + allNodes.forEach(FloatingObjectPartsTreeNode::resetRealEnabled); + for (FloatingObjectPartsTreeNode node : allNodes) { + if (whenArriving.contains(node.getId())) { + node.setRealEnabledOnArriving(false); + } + if (whenLeaving.contains(node.getId())) { + node.setRealEnabledOnLeaving(false); + } + } + } + public boolean isAdjusting() { return adjusting; } ===================================== observe-i18n/src/main/i18n/translations/observe_en_GB.properties ===================================== @@ -2706,6 +2706,7 @@ observe.config.temperature.format=Default temperature format observe.config.ui.autoPopupNumberEditor=Flag sets to true when number editor show automaticly popup observe.config.ui.changeSynchroSrc=Flag sets to true if you can change local source in admin tasks observe.config.ui.dcp.error.color=Color to notify errors while validating floating object materials. +observe.config.ui.dcp.not.editable.color=Color to notify not editable floating object material nodes. observe.config.ui.focusBorderColor=Color of the focus container border observe.config.ui.fullscreen=Flag sets to true to lauch application in full screen mode observe.config.ui.loadLocalStorage=Flag sets to true to load local data source when application starts ===================================== observe-i18n/src/main/i18n/translations/observe_es_ES.properties ===================================== @@ -2706,6 +2706,7 @@ observe.config.temperature.format=Unidad de temperatura observe.config.ui.autoPopupNumberEditor=Para mostrar automáticamente el editor numérico durante la edición de un número observe.config.ui.changeSynchroSrc=Para autorizar la seleción de la base fuente durante las operaciones sobre la base observe.config.ui.dcp.error.color=Color para notificar los errores sobre la composición de dcps +observe.config.ui.dcp.not.editable.color=Color to notify not editable floating object material nodes \#TODO observe.config.ui.focusBorderColor=Color del borde de la zona que tiene el foco observe.config.ui.fullscreen=Para mostrar la aplicación en modo pantalla completa observe.config.ui.loadLocalStorage=Cargar la base local al iniciar la aplicación ===================================== observe-i18n/src/main/i18n/translations/observe_fr_FR.properties ===================================== @@ -2706,6 +2706,7 @@ observe.config.temperature.format=Unité de température observe.config.ui.autoPopupNumberEditor=Pour afficher automatiquement l'éditeur numérique lors de l'édition d'un nombre observe.config.ui.changeSynchroSrc=Pour autoriser la sélection de la base source dans les opérations sur base observe.config.ui.dcp.error.color=Couleur pour notifier les erreurs sur la composition des dcps +observe.config.ui.dcp.not.editable.color=Couleur pour notifier les nœuds non éditables dans l'arbre des matériaux de dcp. observe.config.ui.focusBorderColor=Couleur de la bordure de la zone qui a le focus observe.config.ui.fullscreen=Pour afficher l'application en mode pleine écran observe.config.ui.loadLocalStorage=Charger la base locale au démarrage de l'application View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/commit/34e5df832d773ea7a01a426ca1fe... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/commit/34e5df832d773ea7a01a426ca1fe... You're receiving this email because of your account on gitlab.com.