From 4f8582760845646a6d72d4abb4cad41041b099ef Mon Sep 17 00:00:00 2001 From: Ivan Nikitka <70625960+Ivan-nikitko@users.noreply.github.com> Date: Fri, 3 Mar 2023 09:32:54 +0100 Subject: [PATCH] fix bugs, refactoring --- .../modeler/action/DefaultActionManager.java | 2 + .../dbimport/DragAndDropNodeAction.java | 124 ++++++++++++++++++ .../editor/dbimport/DraggableTreePanel.java | 93 +++++-------- 3 files changed, 161 insertions(+), 58 deletions(-) create mode 100644 modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/DragAndDropNodeAction.java diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DefaultActionManager.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DefaultActionManager.java index 0319ddb2f0..7bcb7c146e 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DefaultActionManager.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/DefaultActionManager.java @@ -31,6 +31,7 @@ import org.apache.cayenne.modeler.action.dbimport.AddIncludeTableAction; import org.apache.cayenne.modeler.action.dbimport.AddSchemaAction; import org.apache.cayenne.modeler.action.dbimport.DeleteNodeAction; +import org.apache.cayenne.modeler.action.dbimport.DragAndDropNodeAction; import org.apache.cayenne.modeler.action.dbimport.EditNodeAction; import org.apache.cayenne.modeler.action.dbimport.MoveImportNodeAction; import org.apache.cayenne.modeler.action.dbimport.MoveInvertNodeAction; @@ -124,6 +125,7 @@ public DefaultActionManager(@Inject Application application, @Inject Configurati registerAction(new EditNodeAction(application)).setAlwaysOn(true); registerAction(new DeleteNodeAction(application)).setAlwaysOn(true); registerAction(new MoveImportNodeAction(application)).setAlwaysOn(true); + registerAction(new DragAndDropNodeAction(application)).setAlwaysOn(true); registerAction(new LoadDbSchemaAction(application)).setAlwaysOn(true); registerAction(new SortNodesAction(application)).setAlwaysOn(true); registerAction(new MoveInvertNodeAction(application)).setAlwaysOn(true); diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/DragAndDropNodeAction.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/DragAndDropNodeAction.java new file mode 100644 index 0000000000..42bd7d7ca5 --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/dbimport/DragAndDropNodeAction.java @@ -0,0 +1,124 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.modeler.action.dbimport; + +import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering; +import org.apache.cayenne.modeler.Application; +import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode; +import org.apache.cayenne.modeler.editor.dbimport.DbImportModel; +import org.apache.cayenne.modeler.editor.dbimport.DbImportSorter; + +import javax.swing.JTree; +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.Collections; + +/** + * @since 5.0 + */ +public class DragAndDropNodeAction extends TreeManipulationAction { + + private static final String ACTION_NAME = "DragAndDrop"; + private DbImportTreeNode[] nodes; + private DbImportTreeNode dropLocationParentNode; + private DbImportTreeNode sourceParentNode; + private JTree.DropLocation dropLocation; + + public DragAndDropNodeAction(Application application) { + super(ACTION_NAME, application); + } + + @Override + public void performAction(ActionEvent e) { + DbImportModel model = (DbImportModel) tree.getModel(); + ReverseEngineering reverseEngineeringOldCopy = new ReverseEngineering(tree.getReverseEngineering()); + + for (DbImportTreeNode node : nodes) { + if (checkDropPossibility(node)) { + int index = calculateDropIndex(); + model.insertNodeInto(node, dropLocationParentNode, index); + } + } + getProjectController().setDirty(true); + DbImportSorter.syncUserObjectItems(dropLocationParentNode); + DbImportSorter.syncUserObjectItems(sourceParentNode); + putReverseEngineeringToUndoManager(reverseEngineeringOldCopy); + model.reload(dropLocationParentNode); + tree.expandTree(new ArrayList<>(Collections.singletonList(dropLocationParentNode))); + } + + private int calculateDropIndex() { + int index = dropLocation.getChildIndex(); + //check is our node moving inside a one node + if (sourceParentNode == dropLocationParentNode) { + + int childCount = dropLocationParentNode.getChildCount(); + int childIndex = dropLocation.getChildIndex(); + if (childIndex == childCount) { + index = childCount - 1; + } + } + //If target node is collapsed + if (index == -1) { + index = dropLocationParentNode.getChildCount(); + } + return index; + } + + private boolean checkDropPossibility(DbImportTreeNode node) { + // Don't allow a node to be dropped onto itself + if (node == dropLocationParentNode) { + return false; + } + // Don't allow a node to be dropped onto one of its descendants + for (DbImportTreeNode childNode : node.getChildNodes()) { + if (isNodeAncestor(childNode, dropLocationParentNode)) { + return false; + } + } + return true; + } + + private boolean isNodeAncestor(DbImportTreeNode node1, DbImportTreeNode node2) { + if (node2 == null) { + return false; + } + if (node2.getParent() == node1) { + return true; + } + return isNodeAncestor(node1, node2.getParent()); + } + + public void setNodes(DbImportTreeNode[] nodes) { + this.nodes = nodes; + } + + public void setDropLocationParentNode(DbImportTreeNode dropLocationParentNode) { + this.dropLocationParentNode = dropLocationParentNode; + } + + public void setSourceParentNode(DbImportTreeNode sourceParentNode) { + this.sourceParentNode = sourceParentNode; + } + + public void setDropLocation(JTree.DropLocation dropLocation) { + this.dropLocation = dropLocation; + } +} diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DraggableTreePanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DraggableTreePanel.java index 6eca868fc8..ceb84dfe95 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DraggableTreePanel.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbimport/DraggableTreePanel.java @@ -38,6 +38,7 @@ import org.apache.cayenne.modeler.action.dbimport.AddIncludeProcedureAction; import org.apache.cayenne.modeler.action.dbimport.AddIncludeTableAction; import org.apache.cayenne.modeler.action.dbimport.AddSchemaAction; +import org.apache.cayenne.modeler.action.dbimport.DragAndDropNodeAction; import org.apache.cayenne.modeler.action.dbimport.MoveImportNodeAction; import org.apache.cayenne.modeler.action.dbimport.MoveInvertNodeAction; import org.apache.cayenne.modeler.action.dbimport.TreeManipulationAction; @@ -360,7 +361,6 @@ public void valueChanged(TreeSelectionEvent e) { private class TargetTreeTransferHandler extends TransferHandler { private DbImportTreeNode sourceParentNode; - DbImportModel model = (DbImportModel) targetTree.getModel(); @Override protected Transferable createTransferable(JComponent c) { @@ -398,6 +398,7 @@ public Object getTransferData(DataFlavor flavor) { @Override protected void exportDone(JComponent source, Transferable data, int action) { if (importSourceTree == ImportSourceTree.TARGET_TREE && sourceParentNode != null) { + DbImportModel model = (DbImportModel) targetTree.getModel(); model.reload(sourceParentNode); } } @@ -409,6 +410,18 @@ public int getSourceActions(JComponent c) { @Override public boolean canImport(TransferSupport support) { + JTree.DropLocation dropLocation = (JTree.DropLocation) support.getDropLocation(); + DbImportTreeNode dropLocationParentNode = (DbImportTreeNode) dropLocation.getPath().getLastPathComponent(); + + List> allowedItemsList = insertableLevels.get(dropLocationParentNode.getUserObject().getClass()); + DbImportTreeNode[] nodes = getNodesFromSupport(support); + if (nodes != null && allowedItemsList != null) { + for (DbImportTreeNode node : nodes) { + if (!allowedItemsList.contains(node.getUserObject().getClass())) { + return false; + } + } + } return support.isDrop(); } @@ -430,16 +443,8 @@ private boolean importDataFromSourceTree(TransferSupport support) { if (!canBeMoved()) { return false; } - Transferable transferable = support.getTransferable(); - DbImportTreeNode[] transferData = null; - try { - for (DataFlavor dataFlavor : transferable.getTransferDataFlavors()) { - transferData = (DbImportTreeNode[]) transferable.getTransferData(dataFlavor); - } - } catch (IOException | UnsupportedFlavorException e) { - return false; - } - if (transferData != null) { + DbImportTreeNode[] nodes = getNodesFromSupport(support); + if (nodes != null) { MoveImportNodeAction action = projectController.getApplication().getActionManager() .getAction(MoveImportNodeAction.class); action.setSourceTree(sourceTree); @@ -453,65 +458,37 @@ private boolean importDataFromSourceTree(TransferSupport support) { private boolean importDataFromTargetTree(TransferSupport support) { JTree.DropLocation dropLocation = (JTree.DropLocation) support.getDropLocation(); - TreePath dropLocationPath = dropLocation.getPath(); - - DbImportTreeNode dropLocationParentNode = (DbImportTreeNode) dropLocationPath.getLastPathComponent(); - Transferable transferable = support.getTransferable(); - - int dropIndex = dropLocation.getChildIndex(); - if (dropIndex == -1) { - dropIndex = dropLocationParentNode.getChildCount(); + DbImportTreeNode dropLocationParentNode = (DbImportTreeNode) dropLocation.getPath().getLastPathComponent(); + + DbImportTreeNode[] nodes = getNodesFromSupport(support); + if (nodes != null) { + DragAndDropNodeAction action = projectController.getApplication().getActionManager() + .getAction(DragAndDropNodeAction.class); + action.setDropLocationParentNode(dropLocationParentNode); + action.setSourceParentNode(sourceParentNode); + action.setDropLocation(dropLocation); + action.setNodes(nodes); + action.setTree(targetTree); + action.performAction(null); + return true; } + return false; + } + private DbImportTreeNode[] getNodesFromSupport(TransferSupport support) { + Transferable transferable = support.getTransferable(); DbImportTreeNode[] nodes = null; try { for (DataFlavor dataFlavor : transferable.getTransferDataFlavors()) { nodes = (DbImportTreeNode[]) transferable.getTransferData(dataFlavor); } - if (nodes != null) { - for (DbImportTreeNode node : nodes) { - if (checkDropPossibility(dropLocationParentNode, node)) return false; - model.insertNodeInto(node, dropLocationParentNode, dropIndex++); - } - targetTree.expandPath(dropLocationPath); - DbImportSorter.syncUserObjectItems(dropLocationParentNode); - model.reload(dropLocationParentNode); - projectController.setDirty(true); - return true; - } } catch (IOException | UnsupportedFlavorException e) { - return false; - } - return false; - } - - private boolean checkDropPossibility(DbImportTreeNode dropLocationParentNode, DbImportTreeNode node) { - // Don't allow a node to be dropped onto itself - if (node == dropLocationParentNode) { - return true; - } - // Don't allow a node to be dropped onto one of its descendants - for (DbImportTreeNode childNode : node.getChildNodes()) { - if (isNodeAncestor(childNode, dropLocationParentNode)) { - return true; - } - } - return false; - } - - - private boolean isNodeAncestor(DbImportTreeNode node1, DbImportTreeNode node2) { - if (node2 == null) { - return false; + return null; } - if (node2.getParent() == node1) { - return true; - } - return isNodeAncestor(node1, node2.getParent()); + return nodes; } } - private class SourceTreeSelectionListener implements TreeSelectionListener { @Override public void valueChanged(TreeSelectionEvent e) {