Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe Commits: afde2be0 by Tony Chemit at 2020-07-08T10:48:09+02:00 [SYNCHRO AVANCEE][REFERENTIEL] Améliorer la coche des cases - Closes #1546 - - - - - 77bb17d0 by Tony Chemit at 2020-07-08T10:48:36+02:00 Change data synchro action keystroke to be conform with referential syncho - - - - - 17 changed files: - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/actions/DataSourceInformation.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/ReferentialSynchroUIHandler.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/actions/Start.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/ReferentialSelectionTree.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/ReferentialSelectionTreeCellRenderer.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/ReferentialSelectionTreePaneHandler.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModel.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModelsBuilder.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/actions/DataSourceInformation.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/actions/RegisterTaskActionSupport.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/actions/SelectAll.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/actions/SelectUnselect.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/actions/UnselectAll.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/node/ReferentialPropertyUpdatedNode.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/node/ReferentialTypeSynchroNode.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/node/ReferentialUpdatedSynchroNode.java - client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/node/SynchroNodeSupport.java Changes: ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/data/tree/actions/DataSourceInformation.java ===================================== @@ -40,7 +40,7 @@ import static io.ultreia.java4all.i18n.I18n.t; public class DataSourceInformation extends DataSelectionTreePaneActionSupport { public DataSourceInformation() { - super("", t("observe.action.info.storage.tip"), "information", ObserveKeyStrokesSupport.KEY_STROKE_DATA_SOURCE_INFORMATION); + super("", t("observe.action.info.storage.tip"), "information", ObserveKeyStrokesSupport.KEY_STROKE_CONFIGURE_LOCAL_SOURCE); } @Override @@ -55,4 +55,12 @@ public class DataSourceInformation extends DataSelectionTreePaneActionSupport { JOptionPane.INFORMATION_MESSAGE); } + + @Override + public void init() { + if (ui.isRight()) { + setKeyStroke(ObserveKeyStrokesSupport.KEY_STROKE_CONFIGURE_REMOTE_SOURCE); + } + defaultInit(getInputMap(ui, getInputMapCondition()), getActionMap(ui)); + } } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/ReferentialSynchroUIHandler.java ===================================== @@ -26,7 +26,6 @@ import fr.ird.observe.client.datasource.actions.AdminStep; import fr.ird.observe.client.datasource.actions.AdminTabUIHandler; import fr.ird.observe.client.datasource.actions.AdminUIModel; import fr.ird.observe.client.datasource.actions.config.ConfigUI; -import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.actions.SelectUnselect; import fr.ird.observe.client.datasource.editor.wizard.StorageUIModel; import fr.ird.observe.client.util.UIHelper; import fr.ird.observe.services.configuration.ObserveDataSourceInformation; @@ -66,7 +65,7 @@ public class ReferentialSynchroUIHandler extends AdminTabUIHandler<ReferentialSy configUI.getStepModel().addPropertyChangeListener(StorageUIModel.VALID_PROPERTY_NAME, evt -> updateSynchroModes()); configUI.getExtraConfig().add(extraConfig); super.afterInit(ui); - SelectUnselect.init(ui.getLeftTreePane(), null, new SelectUnselect(ui.getRightTreePane())); +// SelectUnselect.init(ui.getLeftTreePane(), null, new SelectUnselect(ui.getRightTreePane())); ui.getLeftTreePane().init(); ui.getRightTreePane().init(); } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/actions/Start.java ===================================== @@ -134,25 +134,25 @@ public class Start extends ReferentialSynchroUIActionSupport { sendMessage(message); - tree.addMouseListener(new MouseAdapter() { - @Override - public void mouseReleased(MouseEvent e) { - if (e.getClickCount() == 2) { - TreePath path = tree.getClosestPathForLocation(e.getX(), e.getY()); - Object lastPathComponent = path.getLastPathComponent(); - if (lastPathComponent instanceof SynchroNodeSupport) { - SynchroNodeSupport node = (SynchroNodeSupport) lastPathComponent; - if(node instanceof ReferentialPropertyUpdatedNode && !node.getRoot().isShowProperties()) { - // we can not modify property to update or revert in such mode - return; - } - boolean newValue = !node.isSelected(); - log.info(String.format("Node: %s - new selected value: %s", node, newValue)); - tree.getTreeModel().setValueAt(node, newValue); - } - } - } - }); +// tree.addMouseListener(new MouseAdapter() { +// @Override +// public void mouseReleased(MouseEvent e) { +// if (e.getClickCount() == 2) { +// TreePath path = tree.getClosestPathForLocation(e.getX(), e.getY()); +// Object lastPathComponent = path.getLastPathComponent(); +// if (lastPathComponent instanceof SynchroNodeSupport) { +// SynchroNodeSupport node = (SynchroNodeSupport) lastPathComponent; +// if(node instanceof ReferentialPropertyUpdatedNode && !node.getRoot().isShowProperties()) { +// // we can not modify property to update or revert in such mode +// return; +// } +// boolean newValue = !node.isSelected(); +// log.info(String.format("Node: %s - new selected value: %s", node, newValue)); +// tree.getTreeModel().setValueAt(node, newValue); +// } +// } +// } +// }); } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/ReferentialSelectionTree.java ===================================== @@ -22,12 +22,17 @@ package fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree * #L% */ +import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.node.RootSynchroNode; +import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.node.SynchroNodeSupport; import fr.ird.observe.client.util.UIHelper; import org.jdesktop.swingx.JXTree; +import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; +import java.util.Collections; +import java.util.Set; /** * @author Tony Chemit - dev@tchemit.fr @@ -52,4 +57,16 @@ public class ReferentialSelectionTree extends JXTree { return (ReferentialSynchronizeTreeModel) getModel(); } + public Set<SynchroNodeSupport> getSelectedNodes() { + TreePath[] selectedRow = getSelectionPaths(); + if (selectedRow == null || selectedRow.length == 0) { + return Collections.emptySet(); + } + ImmutableSet.Builder<SynchroNodeSupport> resultBuilder = ImmutableSet.builder(); + for (TreePath treePath : selectedRow) { + SynchroNodeSupport node = (SynchroNodeSupport) treePath.getLastPathComponent(); + resultBuilder.add(node); + } + return resultBuilder.build(); + } } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/ReferentialSelectionTreeCellRenderer.java ===================================== @@ -35,8 +35,6 @@ import javax.swing.UIManager; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; -import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.util.Objects; /** @@ -45,12 +43,10 @@ import java.util.Objects; */ public class ReferentialSelectionTreeCellRenderer extends DefaultXTreeCellRenderer implements WithDecoratorService { - private final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyy HH:mm"); - private final JPanel panel; private final JCheckBox selected; private final Icon unselectedIcon; - private Icon partialIcon; + private final Icon partialIcon; ReferentialSelectionTreeCellRenderer() { selected = new JCheckBox(); @@ -60,10 +56,11 @@ public class ReferentialSelectionTreeCellRenderer extends DefaultXTreeCellRender panel.add(this, BorderLayout.CENTER); partialIcon = Objects.requireNonNull(UIManager.getIcon("checkbox.partial")); unselectedIcon = Objects.requireNonNull(UIManager.getIcon("checkbox.empty")); - selected.setIcon(unselectedIcon); +// selected.setIcon(unselectedIcon); Icon selectedIcon = Objects.requireNonNull(UIManager.getIcon("checkbox.selected")); selected.setSelectedIcon(selectedIcon); } + @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { @@ -79,15 +76,21 @@ public class ReferentialSelectionTreeCellRenderer extends DefaultXTreeCellRender setIcon(icon); setToolTipText(text); - - if (!(node instanceof ReferentialPropertyUpdatedNode) || node.getRoot().isShowProperties()) { - boolean selected = node.isSelected(); - this.selected.setSelected(selected); - panel.add(this.selected, BorderLayout.WEST); - this.selected.setIcon(selected || !node.isPartialSelected() ? unselectedIcon : partialIcon); + boolean selectedState; + Icon selectedIcon = unselectedIcon; + if (node.isLeaf()) { + selectedState = node.isSelected(); } else { - panel.remove(this.selected); + // node is selected (says has the icon selected) only if all his children are selected + selectedState = node.isFullySelected(); + if (!selectedState && node.isPartialSelected()) { + // use partial icon, only if node is partial selected + selectedIcon = partialIcon; + } } + selected.setSelected(selectedState); + selected.setIcon(selectedIcon); + selected.setEnabled(!(node instanceof ReferentialPropertyUpdatedNode) || node.getRoot().isShowProperties()); panel.setPreferredSize(new Dimension(getPreferredSize().width + 20, getPreferredSize().height + 2)); return panel; } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/ReferentialSelectionTreePaneHandler.java ===================================== @@ -32,6 +32,7 @@ import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree. import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.actions.RegisterDelete; import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.actions.RegisterRevert; import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.actions.RegisterSkip; +import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.actions.SelectUnselect; import org.nuiton.jaxx.runtime.spi.UIHandler; import java.awt.BorderLayout; @@ -53,7 +54,7 @@ public class ReferentialSelectionTreePaneHandler implements UIHandler<Referentia RegisterDeactivateWithReplacement.init(ui, ui.deactivateWithReplace, new RegisterDeactivateWithReplacement(ui, isLeft)); RegisterDelete.init(ui, ui.delete, new RegisterDelete(ui, isLeft)); RegisterSkip.init(ui, ui.skip, new RegisterSkip(ui, isLeft)); - + SelectUnselect.init(ui, null, new SelectUnselect(ui)); if (!isLeft) { ui.remove(ui.getMiddleActions()); ui.add(ui.getMiddleActions(), BorderLayout.WEST); ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModel.java ===================================== @@ -33,13 +33,13 @@ import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree. import fr.ird.observe.dto.referential.ReferentialDto; import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.Collection; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; -import java.util.Optional; import java.util.function.Predicate; /** @@ -50,8 +50,6 @@ import java.util.function.Predicate; public class ReferentialSynchronizeTreeModel extends DefaultTreeModel { public static final String SELECTED_COUNT = "selectedCount"; - -// private static final Logger log = LogManager.getLogger(ReferentialSynchronizeTreeModel.class); public static final String SELECTED = "selected"; private static final long serialVersionUID = 1L; private static final String SELECTION_EMPTY = "selectionEmpty"; @@ -59,13 +57,19 @@ public class ReferentialSynchronizeTreeModel extends DefaultTreeModel { private final ImmutableSetMultimap<Class<? extends ReferentialDto>, String> idsOnlyExistOnThisSide; + /** + * List of selected referential nodes. + * + * <b>Be ware, a node present here means it is selected or partial selected!</b> + */ + private final List<ReferentialSynchroNodeSupport> selected; private boolean canAdd; private boolean canUpdate; private boolean canDelete; private boolean canRevert; - private List<ReferentialSynchroNodeSupport> selected; private boolean adjusting; + private int oldSelectedCount; ReferentialSynchronizeTreeModel(RootSynchroNode root, ImmutableSetMultimap<Class<? extends ReferentialDto>, String> idsOnlyExistOnThisSide) { @@ -75,50 +79,33 @@ public class ReferentialSynchronizeTreeModel extends DefaultTreeModel { } public void setValueAt(SynchroNodeSupport node, boolean value) { - node.setSelected(value); - boolean oldSelectionEmpty = isSelectionEmpty(); - int oldSelectedCount = getSelectedCount(); - - if (node instanceof ReferentialPropertyUpdatedNode) { - // this node can not be selected - if (!adjusting) { - updateSelectedActions(); - nodeChanged(node); - } - return; + boolean wasAdjusting = adjusting; + if (!wasAdjusting) { + setAdjusting(true); } - if (node instanceof ReferentialSynchroNodeSupport) { - if (value) { - selected.add((ReferentialSynchroNodeSupport) node); - } else { - selected.remove(node); - } - if (!adjusting) { - nodeChanged(node.getParent()); - nodeChanged(node); - } - } else { - if (!adjusting) { - nodeChanged(node); - } - Enumeration<?> children = node.children(); - while (children.hasMoreElements()) { - ReferentialSynchroNodeSupport child = (ReferentialSynchroNodeSupport) children.nextElement(); - if (value) { - selected.add(child); - } else { - selected.remove(child); - } - if (!adjusting) { - nodeChanged(child); + try { + if (node instanceof ReferentialTypeSynchroNode) { + ReferentialTypeSynchroNode node1 = (ReferentialTypeSynchroNode) node; + node1.updateSelect(value); + Enumeration<? extends TreeNode> children = node1.children(); + while (children.hasMoreElements()) { + ReferentialSynchroNodeSupport childNode = (ReferentialSynchroNodeSupport) children.nextElement(); + updateSelected(value, childNode); } + } else if (node instanceof ReferentialSynchroNodeSupport) { + ReferentialSynchroNodeSupport node1 = (ReferentialSynchroNodeSupport) node; + node1.updateSelect(value); + updateSelected(value, node1); + } else if (node instanceof ReferentialPropertyUpdatedNode) { + ReferentialPropertyUpdatedNode node1 = (ReferentialPropertyUpdatedNode) node; + node1.updateSelect(value); + updateSelected(node1.getParent().isSelected(), node1.getParent()); + } + } finally { + if (!wasAdjusting) { + setAdjusting(false); } } - - if (!adjusting) { - fireSelectedChanged(oldSelectionEmpty, oldSelectedCount); - } - } public int getSelectedCount() { @@ -129,7 +116,6 @@ public class ReferentialSynchronizeTreeModel extends DefaultTreeModel { return selected.isEmpty(); } - public List<ReferentialSynchroNodeSupport> getSelected() { return selected; } @@ -145,10 +131,9 @@ public class ReferentialSynchronizeTreeModel extends DefaultTreeModel { canDelete |= node.isCanDelete(); boolean canUpdate = node.isCanUpdate(); boolean canRevert = node.isCanRevert(); - if ((canUpdate || canRevert) && getRoot().isShowProperties() && node instanceof ReferentialUpdatedSynchroNode) { - ReferentialUpdatedSynchroNode node1 = (ReferentialUpdatedSynchroNode) node; - Optional<ImmutableSet<String>> selectedPropertyNames = node1.getPropertyNamesSelected(); - canUpdate = canRevert = selectedPropertyNames.map(t -> t.size() > 0).orElse(false); + if ((canUpdate || canRevert) && node instanceof ReferentialUpdatedSynchroNode) { + // in this special cas, ask if node is really selected (means not without selected children) + canUpdate = canRevert = !node.isNotSelected(); } this.canUpdate |= canUpdate; this.canRevert |= canRevert; @@ -192,23 +177,44 @@ public class ReferentialSynchronizeTreeModel extends DefaultTreeModel { } public void clearSelection() { - - boolean oldSelectionEmpty = isSelectionEmpty(); - int oldSelectedCount = getSelectedCount(); - - for (ReferentialSynchroNodeSupport node : selected) { - node.setSelected(false); - nodeChanged(node); - nodeChanged(node.getParent()); + setAdjusting(true); + try { + for (ReferentialSynchroNodeSupport node : selected) { + node.updateSelect(false); + nodeChanged(node); + nodeChanged(node.getParent()); + } + selected.clear(); + } finally { + setAdjusting(false); } + } - selected.clear(); - - pcs.firePropertyChange(SELECTION_EMPTY, oldSelectionEmpty, isSelectionEmpty()); - pcs.firePropertyChange(SELECTED_COUNT, oldSelectedCount, getSelectedCount()); - pcs.firePropertyChange(SELECTED, null, selected); + public void removeReferenceNodes(Collection<SynchroNodeSupport> removedNodes) { + setAdjusting(true); + try { + for (SynchroNodeSupport removedNode : removedNodes) { + if (removedNode instanceof ReferentialPropertyUpdatedNode) { + removedNode.updateSelect(false); + removeNodeFromParent(removedNode); + continue; + } - updateSelectedActions(); + if (removedNode instanceof ReferentialSynchroNodeSupport) { + ReferentialSynchroNodeSupport removedNode1 = (ReferentialSynchroNodeSupport) removedNode; + removedNode1.updateSelect(false); + selected.remove(removedNode1); + ReferentialTypeSynchroNode typeNode = removedNode1.getParent(); + if (typeNode.getChildCount() == 1) { + removeNodeFromParent(typeNode); + } else { + removeNodeFromParent(removedNode); + } + } + } + } finally { + setAdjusting(false); + } } @Override @@ -232,44 +238,30 @@ public class ReferentialSynchronizeTreeModel extends DefaultTreeModel { pcs.removePropertyChangeListener(name, listener); } + private void updateSelected(boolean value, ReferentialSynchroNodeSupport node) { + if (value) { + selected.add(node); + } else { + selected.remove(node); + } + } + private void fireSelectedChanged(boolean oldSelectionEmpty, int oldSelectedCount) { + if (adjusting) { + return; + } + updateSelectedActions(); pcs.firePropertyChange(SELECTION_EMPTY, oldSelectionEmpty, isSelectionEmpty()); - pcs.firePropertyChange(SELECTED_COUNT, oldSelectedCount, getSelectedCount()); + pcs.firePropertyChange(SELECTED_COUNT, null, getSelectedCount()); pcs.firePropertyChange(SELECTED, null, selected); - updateSelectedActions(); } - public void removeReferenceNodes(Collection<SynchroNodeSupport> removedNodes) { - - boolean oldSelectionEmpty = isSelectionEmpty(); - int oldSelectedCount = getSelectedCount(); - - adjusting = true; - - try { - for (SynchroNodeSupport removedNode : removedNodes) { - - if (removedNode instanceof ReferentialPropertyUpdatedNode) { - removedNode.setSelected(false); - removeNodeFromParent(removedNode); - continue; - } - - if (removedNode instanceof ReferentialSynchroNodeSupport) { - ReferentialSynchroNodeSupport removedNode1 = (ReferentialSynchroNodeSupport) removedNode; - removedNode1.setSelected(false); - selected.remove(removedNode1); - ReferentialTypeSynchroNode typeNode = removedNode1.getParent(); - if (typeNode.getChildCount() == 1) { - removeNodeFromParent(typeNode); - } else { - removeNodeFromParent(removedNode); - } - } - } - } finally { - adjusting = false; - fireSelectedChanged(oldSelectionEmpty, oldSelectedCount); + public void setAdjusting(boolean adjusting) { + this.adjusting = adjusting; + if (adjusting) { + oldSelectedCount = getSelectedCount(); + } else { + fireSelectedChanged(oldSelectedCount == 0, oldSelectedCount); } } } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModelsBuilder.java ===================================== @@ -61,14 +61,13 @@ import java.util.Objects; public class ReferentialSynchronizeTreeModelsBuilder { private static final Logger log = LogManager.getLogger(ReferentialSynchronizeTreeModelsBuilder.class); - private final boolean showProperties; + private final DifferentialEngine engine; private final RootSynchroNode leftRootNode; private final RootSynchroNode rightRootNode; private final ProgressionModel progressionModel; public ReferentialSynchronizeTreeModelsBuilder(ReferentialSynchronizeMode synchronizeMode, boolean showProperties, DifferentialEngine engine, ProgressionModel progressionModel) { - this.showProperties = showProperties; this.engine = Objects.requireNonNull(engine); this.leftRootNode = new RootSynchroNode(true, Objects.requireNonNull(synchronizeMode).isLeftWrite(), showProperties); this.rightRootNode = new RootSynchroNode(false, synchronizeMode.isRightWrite(), showProperties); @@ -119,11 +118,11 @@ public class ReferentialSynchronizeTreeModelsBuilder { boolean leftCanWrite = leftRootNode.isCanWrite(); CreateAddNode leftAddNode = new CreateAddNode(rightCanWrite, leftCanWrite); - CreateUpdateNode leftUpdateNode = new CreateUpdateNode(rightCanWrite, leftCanWrite, showProperties); + CreateUpdateNode leftUpdateNode = new CreateUpdateNode(rightCanWrite, leftCanWrite); create(leftRootNode, leftAddNode, leftUpdateNode, leftDiff); CreateAddNode rightAddNode = new CreateAddNode(leftCanWrite, rightCanWrite); - CreateUpdateNode rightUpdateNode = new CreateUpdateNode(leftCanWrite, rightCanWrite, showProperties); + CreateUpdateNode rightUpdateNode = new CreateUpdateNode(leftCanWrite, rightCanWrite); create(rightRootNode, rightAddNode, rightUpdateNode, rightDiff); ReferentialSynchronizeTreeModel leftTreeModel = new ReferentialSynchronizeTreeModel(leftRootNode, leftAddNode.getIds()); @@ -171,17 +170,15 @@ public class ReferentialSynchronizeTreeModelsBuilder { private final boolean canCopy; private final boolean canRevert; - private final boolean showProperties; - protected CreateUpdateNode(boolean canCopy, boolean canRevert, boolean showProperties) { + protected CreateUpdateNode(boolean canCopy, boolean canRevert) { this.canCopy = canCopy; this.canRevert = canRevert; - this.showProperties = showProperties; } public void createNode(ReferentialTypeSynchroNode typeNode, Differential diffState) { - DifferentialPropertyList modifiedProperties; + DifferentialPropertyList modifiedProperties = null; if (canCopy || canRevert) { modifiedProperties = diffState.getPropertiesModification(); @@ -191,8 +188,6 @@ public class ReferentialSynchronizeTreeModelsBuilder { return; } log.debug(String.format("Modified properties: %s on %s", modifiedProperties, diffState.getId())); - } else { - modifiedProperties = null; } ReferentialSynchroNodeSupport node = new ReferentialUpdatedSynchroNode(diffState, canCopy, canRevert); typeNode.add(node); ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/actions/DataSourceInformation.java ===================================== @@ -40,7 +40,7 @@ import static io.ultreia.java4all.i18n.I18n.t; public class DataSourceInformation extends ReferentialSelectionTreePaneActionSupport { public DataSourceInformation() { - super("", t("observe.action.info.storage.tip"), "information", ObserveKeyStrokesSupport.KEY_STROKE_DATA_SOURCE_INFORMATION); + super("", t("observe.action.info.storage.tip"), "information", ObserveKeyStrokesSupport.KEY_STROKE_CONFIGURE_LOCAL_SOURCE); } @Override @@ -55,4 +55,12 @@ public class DataSourceInformation extends ReferentialSelectionTreePaneActionSup JOptionPane.INFORMATION_MESSAGE); } + + @Override + public void init() { + if (ui.isRight()) { + setKeyStroke(ObserveKeyStrokesSupport.KEY_STROKE_CONFIGURE_REMOTE_SOURCE); + } + defaultInit(getInputMap(ui, getInputMapCondition()), getActionMap(ui)); + } } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/actions/RegisterTaskActionSupport.java ===================================== @@ -247,7 +247,7 @@ public abstract class RegisterTaskActionSupport extends ReferentialSelectionTree DifferentialPropertyList includedProperties = null; Set<ReferentialPropertyUpdatedNode> toRemove = new LinkedHashSet<>(); Differential userObject = node.getUserObject(); - boolean toOtherSide = taskType.toOtherSide(); + boolean toOtherSide = taskType != null && taskType.toOtherSide(); if (!node.isLeaf() && node instanceof ReferentialUpdatedSynchroNode) { ReferentialUpdatedSynchroNode node1 = (ReferentialUpdatedSynchroNode) node; includedPropertyNames = node1.getPropertyNamesSelected().orElse(null); ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/actions/SelectAll.java ===================================== @@ -27,8 +27,8 @@ import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree. import fr.ird.observe.client.util.ObserveKeyStrokesSupport; import javax.swing.SwingUtilities; -import javax.swing.tree.TreePath; import java.awt.event.ActionEvent; +import java.util.Collections; import static io.ultreia.java4all.i18n.I18n.t; @@ -44,17 +44,8 @@ public class SelectAll extends ReferentialSelectionTreePaneActionSupport { @Override protected void doActionPerformed(ActionEvent e, ReferentialSelectionTreePane ui) { - ReferentialSelectionTree tree = ui.getTree(); - SwingUtilities.invokeLater(() -> { - int l = tree.getRowCount(); - for (int i = 0; i < l; i++) { - TreePath path = tree.getPathForRow(i); - tree.addSelectionPath(path); - } - SelectUnselect.select(tree); - }); - + SelectUnselect.selectUnSelect(tree, Collections.singleton(tree.getTreeModel().getRoot()), n -> true); SwingUtilities.invokeLater(tree::repaint); } } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/actions/SelectUnselect.java ===================================== @@ -24,9 +24,11 @@ package fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.ReferentialSelectionTree; import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.ReferentialSelectionTreePane; +import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.ReferentialSynchronizeTreeModel; import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.node.ReferentialPropertyUpdatedNode; import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.node.ReferentialSynchroNodeSupport; import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.node.ReferentialTypeSynchroNode; +import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.node.RootSynchroNode; import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.node.SynchroNodeSupport; import fr.ird.observe.client.util.ObserveKeyStrokesSupport; import org.apache.logging.log4j.LogManager; @@ -34,12 +36,20 @@ import org.apache.logging.log4j.Logger; import javax.swing.ActionMap; import javax.swing.InputMap; +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.Collections; +import java.util.Enumeration; import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; import java.util.Set; +import java.util.function.Function; /** * @author Tony Chemit - dev@tchemit.fr @@ -49,11 +59,16 @@ public class SelectUnselect extends ReferentialSelectionTreePaneActionSupport { private static final Logger log = LogManager.getLogger(SelectUnselect.class); - private final ReferentialSelectionTreePane opposite; +// private final ReferentialSelectionTreePane opposite; public SelectUnselect(ReferentialSelectionTreePane opposite) { super(null, null, null, ObserveKeyStrokesSupport.KEY_STROKE_SPACE); - this.opposite = opposite; +// this.opposite = opposite; + } + + @Override + protected int getInputMapCondition() { + return JComponent.WHEN_FOCUSED; } @Override @@ -79,7 +94,7 @@ public class SelectUnselect extends ReferentialSelectionTreePaneActionSupport { @Override public void init() { defaultInit(ui); - defaultInit(opposite); +// defaultInit(opposite); } @Override @@ -90,7 +105,14 @@ public class SelectUnselect extends ReferentialSelectionTreePaneActionSupport { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { - actionPerformed(new ActionEvent(getUi().getTree(), 0, "yo")); + ReferentialSelectionTree tree = ui.getTree(); + TreePath path = tree.getClosestPathForLocation(e.getX(), e.getY()); + Object lastPathComponent = path.getLastPathComponent(); + if (lastPathComponent instanceof SynchroNodeSupport) { + SynchroNodeSupport node = (SynchroNodeSupport) lastPathComponent; + selectUnSelect(tree, Collections.singleton(node), n -> !n.isSelected()); +// actionPerformed(new ActionEvent(getUi().getTree(), 0, "Coming from mouse click")); + } } } }); @@ -110,56 +132,81 @@ public class SelectUnselect extends ReferentialSelectionTreePaneActionSupport { @Override protected void doActionPerformed(ActionEvent e, ReferentialSelectionTreePane ui) { ReferentialSelectionTree tree = ui.getTree(); - if (tree.isFocusOwner()) { - selectUnSelect(tree); - } else { - selectUnSelect(opposite.getTree()); - } + selectUnSelect(tree, tree.getSelectedNodes(), n -> !n.isSelected()); +// if (tree.isFocusOwner()) { +// selectUnSelect(tree); +// } else { +// selectUnSelect(opposite.getTree()); +// } } - protected static void selectUnSelect(ReferentialSelectionTree tree) { - TreePath[] selectedRow = tree.getSelectionPaths(); - if (selectedRow == null || selectedRow.length == 0) { + protected static void selectUnSelect(ReferentialSelectionTree tree, Set<SynchroNodeSupport> selectedNodes, Function<SynchroNodeSupport, Boolean> function) { + if (selectedNodes.isEmpty()) { return; } - Set<SynchroNodeSupport> nodes = new LinkedHashSet<>(); - for (TreePath treePath : selectedRow) { - SynchroNodeSupport node = (SynchroNodeSupport) treePath.getLastPathComponent(); - if (node instanceof ReferentialPropertyUpdatedNode && !node.getRoot().isShowProperties()) { - // we can not modify property to update or revert in such mode + boolean showProperties = tree.getTreeModel().getRoot().isShowProperties(); + + // Get all typed nodes in selection + Set<SynchroNodeSupport> typeNodes = new LinkedHashSet<>(); + // Get all referential nodes in selection + Set<SynchroNodeSupport> referentialNodes = new LinkedHashSet<>(); + // Get all property nodes in selection + Set<SynchroNodeSupport> propertyNodes = new LinkedHashSet<>(); + for (SynchroNodeSupport node : selectedNodes) { + if (node instanceof ReferentialPropertyUpdatedNode) { + if (!showProperties) { + // we can not modify selected property in such mode + continue; + } + propertyNodes.add(node); + continue; + } + if (node instanceof ReferentialTypeSynchroNode) { + typeNodes.add(node); continue; } if (node instanceof ReferentialSynchroNodeSupport) { - if (nodes.contains(node.getParent())) { - continue; + referentialNodes.add(node); + } + if (node instanceof RootSynchroNode) { + RootSynchroNode node1 = (RootSynchroNode) node; + Enumeration<TreeNode> children = node1.children(); + while (children.hasMoreElements()) { + ReferentialTypeSynchroNode childNode = (ReferentialTypeSynchroNode) children.nextElement(); + referentialNodes.add(childNode); } - } else if (node instanceof ReferentialTypeSynchroNode) { - nodes.add(node); } - tree.getTreeModel().setValueAt(node, !node.isSelected()); } - } - protected static void select(ReferentialSelectionTree tree) { - TreePath[] selectedRow = tree.getSelectionPaths(); - if (selectedRow == null || selectedRow.length == 0) { - return; - } - Set<SynchroNodeSupport> nodes = new LinkedHashSet<>(); - for (TreePath treePath : selectedRow) { - SynchroNodeSupport node = (SynchroNodeSupport) treePath.getLastPathComponent(); - if (node instanceof ReferentialPropertyUpdatedNode && !node.getRoot().isShowProperties()) { - // we can not modify property to update or revert in such mode - continue; - } - if (node instanceof ReferentialSynchroNodeSupport) { - if (nodes.contains(node.getParent())) { - continue; + // To collect all nodes to modify (type nodes are always modified) + List<SynchroNodeSupport> nodesToModify = new LinkedList<>(typeNodes); + + // Removes referential node if his type node is also selected + referentialNodes.removeIf(node -> typeNodes.contains(node.getParent())); + // Retained referential nodes need to be modified + nodesToModify.addAll(referentialNodes); + + // Remove property node if one of his ancestor is also selected + propertyNodes.removeIf(node -> referentialNodes.contains(node.getParent()) || typeNodes.contains(node.getParent().getParent())); + // Retained property nodes need to be modified + nodesToModify.addAll(propertyNodes); + + if (!nodesToModify.isEmpty()) { + ReferentialSynchronizeTreeModel treeModel = tree.getTreeModel(); + treeModel.setAdjusting(true); + + try { + for (SynchroNodeSupport node : nodesToModify) { + boolean newSelectedValue = function.apply(node); + log.info(String.format("Change selection of node: %s to value? %b", node, newSelectedValue)); + treeModel.setValueAt(node, newSelectedValue); } - } else if (node instanceof ReferentialTypeSynchroNode) { - nodes.add(node); + } finally { + treeModel.setAdjusting(false); } - tree.getTreeModel().setValueAt(node, true); + + log.info("Some modification in tree need a repaint"); + SwingUtilities.invokeLater(tree::repaint); } } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/actions/UnselectAll.java ===================================== @@ -24,10 +24,12 @@ package fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.ReferentialSelectionTree; import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.ReferentialSelectionTreePane; +import fr.ird.observe.client.datasource.actions.synchronize.referential.ng.tree.node.RootSynchroNode; import fr.ird.observe.client.util.ObserveKeyStrokesSupport; import javax.swing.SwingUtilities; import java.awt.event.ActionEvent; +import java.util.Collections; import static io.ultreia.java4all.i18n.I18n.t; @@ -44,17 +46,8 @@ public class UnselectAll extends ReferentialSelectionTreePaneActionSupport { @Override protected void doActionPerformed(ActionEvent e, ReferentialSelectionTreePane ui) { ReferentialSelectionTree tree = ui.getTree(); - - SwingUtilities.invokeLater(() -> { - - tree.getTreeModel().clearSelection(); - tree.clearSelection(); - - if (!tree.getTreeModel().getRoot().isLeaf()) { - tree.addSelectionRow(0); - } - }); - + RootSynchroNode root = tree.getTreeModel().getRoot(); + SelectUnselect.selectUnSelect(tree, Collections.singleton(root), n -> false); SwingUtilities.invokeLater(tree::repaint); } } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/node/ReferentialPropertyUpdatedNode.java ===================================== @@ -48,8 +48,6 @@ public class ReferentialPropertyUpdatedNode extends SynchroNodeSupport { String rightValue = left ? property.getNewValueLabel(decoratorService) : property.getOldValueLabel(decoratorService); this.label = property.getPropertyNameLabel(dtoType, decoratorService); this.modificationLabel = String.format("<i>( %s )</i>", t("observe.actions.synchro.referential.property.modified", leftValue, rightValue)); - // by default all properties are selected - setSelected(true); } public DifferentialProperty getModifiedProperty() { ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/node/ReferentialTypeSynchroNode.java ===================================== @@ -27,7 +27,6 @@ import fr.ird.observe.dto.referential.ReferentialDto; import fr.ird.observe.dto.tree.I18nTreeHelper; import javax.swing.UIManager; -import java.util.Enumeration; /** * Created on 09/08/16. @@ -47,37 +46,26 @@ public class ReferentialTypeSynchroNode extends SynchroNodeSupport { return (RootSynchroNode) super.getParent(); } - @Override - public boolean isSelected() { - Enumeration<?> children = children(); - while (children.hasMoreElements()) { - SynchroNodeSupport node = (SynchroNodeSupport) children.nextElement(); - if (!node.isSelected()) { - return false; - } - } - return !isLeaf(); - } - - @Override - public void setSelected(boolean selected) { - Enumeration<?> children = children(); - while (children.hasMoreElements()) { - SynchroNodeSupport node = (SynchroNodeSupport) children.nextElement(); - node.setSelected(selected); - } - } - - public ReferentialSynchroNodeSupport getChild(String id) { - Enumeration<?> children = children(); - while (children.hasMoreElements()) { - ReferentialSynchroNodeSupport o = (ReferentialSynchroNodeSupport) children.nextElement(); - if (id.equals(o.getUserObject().getId())) { - return o; - } - } - return null; - } +// @Override +// public boolean isSelected() { +// Enumeration<?> children = children(); +// while (children.hasMoreElements()) { +// SynchroNodeSupport node = (SynchroNodeSupport) children.nextElement(); +// if (!node.isSelected()) { +// return false; +// } +// } +// return !isLeaf(); +// } +// +// @Override +// public void setSelected(boolean selected) { +// Enumeration<?> children = children(); +// while (children.hasMoreElements()) { +// SynchroNodeSupport node = (SynchroNodeSupport) children.nextElement(); +// node.setSelected(selected); +// } +// } @SuppressWarnings("unchecked") @Override ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/node/ReferentialUpdatedSynchroNode.java ===================================== @@ -57,8 +57,4 @@ public class ReferentialUpdatedSynchroNode extends ReferentialSynchroNodeSupport return Optional.ofNullable(oneSelected ? includedPropertyNamesBuilder.build() : null); } - @Override - public boolean isPartialSelected() { - return false; - } } ===================================== client-datasource-actions/src/main/java/fr/ird/observe/client/datasource/actions/synchronize/referential/ng/tree/node/SynchroNodeSupport.java ===================================== @@ -38,7 +38,7 @@ public abstract class SynchroNodeSupport extends DefaultMutableTreeNode implemen private static final long serialVersionUID = 1L; - private transient Icon icon; + private final transient Icon icon; private transient boolean selected; protected SynchroNodeSupport(Icon icon, Object userObject) { @@ -46,7 +46,6 @@ public abstract class SynchroNodeSupport extends DefaultMutableTreeNode implemen this.icon = icon; } - public abstract String toString(DecoratorService decoratorService); public Icon getIcon() { @@ -65,25 +64,50 @@ public abstract class SynchroNodeSupport extends DefaultMutableTreeNode implemen return selected; } - public void setSelected(boolean selected) { - this.selected = selected; + public boolean isPartialSelected() { + if (isLeaf()) { + return false; + } + int selectedCount = getSelectedCount(); + int childCount = getChildCount(); + return selectedCount > 0 && selectedCount < childCount; } - public boolean isPartialSelected() { - if (isSelected()) { + public boolean isFullySelected() { + if (isLeaf()) { return false; } + int selectedCount = getSelectedCount(); + int childCount = getChildCount(); + return selectedCount == childCount; + } + + public boolean isNotSelected() { if (isLeaf()) { return false; } + int selectedCount = getSelectedCount(); + return selectedCount == 0; + } + + public int getSelectedCount() { + int result = 0; Enumeration<?> children = children(); while (children.hasMoreElements()) { - SynchroNodeSupport nodeSupport = (SynchroNodeSupport) children.nextElement(); - if (nodeSupport.isSelected()) { - return true; + SynchroNodeSupport childNode = (SynchroNodeSupport) children.nextElement(); + if (childNode.isSelected()) { + result++; } } - return false; + return result; + } + + public void updateSelect(boolean selected) { + if (selected) { + select(true); + } else { + unselect(true); + } } @Override @@ -95,4 +119,49 @@ public abstract class SynchroNodeSupport extends DefaultMutableTreeNode implemen public SynchroNodeSupport getParent() { return (SynchroNodeSupport) super.getParent(); } + + protected void select(boolean first) { + if (first) { + setSelectedDeeply(true); + } else { + setSelected(true); + } + SynchroNodeSupport parent = getParent(); + if (parent.isRoot()) { + return; + } + if (!parent.isNotSelected()) { + parent.select(false); + } + } + + protected void unselect(boolean first) { + if (first) { + setSelectedDeeply(false); + } else { + setSelected(false); + } + SynchroNodeSupport parent = getParent(); + if (parent.isRoot()) { + return; + } + if (parent.isNotSelected()) { + // no more selection on parent + parent.unselect(false); + } + } + + protected void setSelected(boolean selected) { + this.selected = selected; + } + + private void setSelectedDeeply(boolean selected) { + setSelected(selected); + // Reset all all children + Enumeration<?> children = children(); + while (children.hasMoreElements()) { + SynchroNodeSupport node = (SynchroNodeSupport) children.nextElement(); + node.setSelectedDeeply(selected); + } + } } View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/compare/69869bd516ef63ce7b09f65fa... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/compare/69869bd516ef63ce7b09f65fa... You're receiving this email because of your account on gitlab.com.
participants (1)
-
Tony CHEMIT