package open.dolphin.stampbox; import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import open.dolphin.client.ClientContext; import open.dolphin.client.LocalStampTreeNodeTransferable; import open.dolphin.client.OrderList; import open.dolphin.client.OrderListTransferable; import open.dolphin.client.ReflectAction; import open.dolphin.infomodel.IInfoModel; import open.dolphin.infomodel.InfoModelTransferable; import open.dolphin.infomodel.ModuleInfoBean; import open.dolphin.infomodel.ModuleModel; /** * StampTreePopupAdapter * * @author Kazushi Minagawa */ public class StampTreePopupAdapter extends MouseAdapter { private final String[] POP_MENUS; private final String[] POP_METHODS; public StampTreePopupAdapter() { super(); String line = ClientContext.getMyBundle(StampTreePopupAdapter.class).getString("items.popMenu"); POP_MENUS = line.split(","); POP_METHODS = new String[]{"createNewFolder","renameNode","-","deleteNode"}; } @Override public void mousePressed(MouseEvent evt) { maybePopup(evt); } @Override public void mouseReleased(MouseEvent evt) { maybePopup(evt); } private void maybePopup(MouseEvent evt) { if (evt.isPopupTrigger()) { // イベントソースの StampTree を取得する StampTree tree = (StampTree)evt.getSource(); int x = evt.getX(); int y = evt.getY(); // クリック位置へのパスを得る TreePath destPath = tree.getPathForLocation(x, y); if (destPath == null) { return; } // クリック位置の Node を得る StampTreeNode node = (StampTreeNode)destPath.getLastPathComponent(); // Copy boolean canCopy = true; // エディタから発行...はコピーできない if (node.isLeaf()) { // Leaf なので StampInfo  を得る ModuleInfoBean info = (ModuleInfoBean)node.getUserObject(); // Editable if (!info.isEditable() ) { //Toolkit.getDefaultToolkit().beep(); //return; canCopy = false; } } // Paste は厄介 boolean canPaste = canPaste(tree.getEntity()); // Popupする JPopupMenu popup = createPopuoMenu(tree, canCopy, canPaste); popup.show(evt.getComponent(),x, y); } } private JPopupMenu createPopuoMenu(final JTree tree, boolean canCopy, boolean canPaste) { java.util.ResourceBundle bundle = ClientContext.getMyBundle(StampTreePopupAdapter.class); String actionText = bundle.getString("actionText.copy"); AbstractAction copy = new AbstractAction(actionText) { @Override public void actionPerformed(ActionEvent ae) { Action a = tree.getActionMap().get(TransferHandler.getCopyAction().getValue(Action.NAME)); if (a != null) { a.actionPerformed(new ActionEvent(tree, ActionEvent.ACTION_PERFORMED, null)); } } }; copy.setEnabled(canCopy); actionText = bundle.getString("actionText.paste"); AbstractAction paste = new AbstractAction(actionText) { @Override public void actionPerformed(ActionEvent ae) { Action a = tree.getActionMap().get(TransferHandler.getPasteAction().getValue(Action.NAME)); if (a != null) { a.actionPerformed(new ActionEvent(tree, ActionEvent.ACTION_PERFORMED, null)); } } }; paste.setEnabled(canPaste); JPopupMenu popMenu = new JPopupMenu (); popMenu.add(new JMenuItem(copy)); popMenu.add(new JMenuItem(paste)); popMenu.addSeparator(); for (int i = 0; i < POP_MENUS.length; i++) { String name = POP_MENUS[i]; String method = POP_METHODS[i]; if (name.equals("-")) { popMenu.addSeparator(); } else { ReflectAction action = new ReflectAction(name, (Object)tree, method); JMenuItem item = new JMenuItem(action); popMenu.add(item); } } return popMenu; } /** * クリップボードのコンテントがPaste可能かどうかを返す。 * @param targetEntity ペースト先のentity * @return 可能な時 true */ private boolean canPaste(String targetEntity) { // Clipboard内のTransferable Transferable tr = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); if (tr==null) { return false; } // カルテペインからのペースト if (tr.isDataFlavorSupported(OrderListTransferable.orderListFlavor)) { return canPasteOrder(tr, targetEntity); } // Textペースト if (tr.isDataFlavorSupported(DataFlavor.stringFlavor) && (targetEntity.equals(IInfoModel.ENTITY_TEXT)||targetEntity.equals(IInfoModel.ENTITY_PATH))){ return true; } // 病名ペースト if (tr.isDataFlavorSupported(InfoModelTransferable.infoModelFlavor)) { boolean pasteOk = (targetEntity.equals(IInfoModel.ENTITY_DIAGNOSIS)); pasteOk = pasteOk || (targetEntity.equals(IInfoModel.ENTITY_PATH)); return pasteOk; } // StampTreeNodeペースト if (tr.isDataFlavorSupported(LocalStampTreeNodeTransferable.localStampTreeNodeFlavor)) { return canPasteTreeNode(tr, targetEntity); } return false; } /** * オーダーがペースト可能かどうかを返す。 * @param tr オーダーを保持しているTransferable * @param targetEntity ペースト先のentity * @return 可能な時 true */ private boolean canPasteOrder(Transferable tr, String targetEntity) { try { OrderList list = (OrderList)tr.getTransferData(OrderListTransferable.orderListFlavor); ModuleModel pasteStamp = list.orderList[0]; // ToDo multiple drag & drop String pasteEntity = pasteStamp.getModuleInfoBean().getEntity(); // testStamp // 同一entity boolean match = pasteEntity.equals(targetEntity); // 受けてがパスの場合 match = match || (targetEntity.equals(IInfoModel.ENTITY_PATH)); return match; } catch (UnsupportedFlavorException | IOException ex) { ex.printStackTrace(System.err); } return false; } /** * StampTreeNodeがペースト可能かどうかを返す。 * @param tr StampTreeNodeを保持しているTransferable * @param targetEntity ペースト先のentity * @return 可能な時 true */ private boolean canPasteTreeNode(Transferable tr, String targetEntity) { try { StampTreeNode test = (StampTreeNode)tr.getTransferData(LocalStampTreeNodeTransferable.localStampTreeNodeFlavor); // 葉以外はfalse if (!test.isLeaf()) { return false; } DefaultMutableTreeNode node = (DefaultMutableTreeNode)test; StampTreeNode root = (StampTreeNode)node.getRoot(); Object o = root.getUserObject(); if (o!=null && o instanceof TreeInfo) { TreeInfo info = (TreeInfo)o; return entityMatch(info.getEntity(), targetEntity); } else { return false; } } catch (UnsupportedFlavorException | IOException ex) { ex.printStackTrace(System.err); } return false; } /** * Entity間のマッチングを返す。 * @param pasteEntity ペーストするentity * @param targetEntity ペースト先のentity * @return ペースト可能な時 true */ private boolean entityMatch(String pasteEntity, String targetEntity) { // 同一entity boolean match = pasteEntity.equals(targetEntity); // 受けてがパスの場合 match = match || (targetEntity.equals(IInfoModel.ENTITY_PATH)); // 検体検査 -> (生体検査 | 細菌検査) match = match || (pasteEntity.equals(IInfoModel.ENTITY_LABO_TEST) && (targetEntity.equals(IInfoModel.ENTITY_PHYSIOLOGY_ORDER) || targetEntity.equals(IInfoModel.ENTITY_BACTERIA_ORDER))); // 生体検査 -> (検体検査 | 細菌検査) match = match || (pasteEntity.equals(IInfoModel.ENTITY_PHYSIOLOGY_ORDER) && (targetEntity.equals(IInfoModel.ENTITY_LABO_TEST) || targetEntity.equals(IInfoModel.ENTITY_BACTERIA_ORDER))); // 細菌検査 -> (検体検査 | 生体検査) match = match || (pasteEntity.equals(IInfoModel.ENTITY_BACTERIA_ORDER) && (targetEntity.equals(IInfoModel.ENTITY_LABO_TEST) || targetEntity.equals(IInfoModel.ENTITY_PHYSIOLOGY_ORDER))); return match; } }