Xcos java: remove unnecessary imports
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / palette / PaletteBlockCtrl.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Clement DAVID
4  * Copyright (C) 2011-2015 - Scilab Enterprises - Clement DAVID
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 package org.scilab.modules.xcos.palette;
18
19 import java.awt.Point;
20 import java.awt.datatransfer.Transferable;
21 import java.awt.dnd.DnDConstants;
22 import java.awt.dnd.DragGestureEvent;
23 import java.awt.dnd.DragGestureListener;
24 import java.awt.dnd.DragSource;
25 import java.awt.dnd.InvalidDnDOperationException;
26 import java.awt.event.MouseListener;
27 import java.lang.ref.WeakReference;
28 import java.util.logging.Logger;
29
30 import org.scilab.modules.gui.messagebox.ScilabModalDialog;
31 import org.scilab.modules.gui.messagebox.ScilabModalDialog.IconType;
32 import org.scilab.modules.localization.Messages;
33 import org.scilab.modules.xcos.JavaController;
34 import org.scilab.modules.xcos.Kind;
35 import org.scilab.modules.xcos.block.BasicBlock;
36 import org.scilab.modules.xcos.graph.XcosDiagram;
37 import org.scilab.modules.xcos.graph.model.XcosCellFactory;
38 import org.scilab.modules.xcos.io.scicos.ScicosFormatException;
39 import org.scilab.modules.xcos.palette.listener.PaletteBlockMouseListener;
40 import org.scilab.modules.xcos.palette.model.PaletteBlock;
41 import org.scilab.modules.xcos.palette.view.PaletteBlockView;
42 import org.scilab.modules.xcos.palette.view.PaletteManagerView;
43 import org.scilab.modules.xcos.utils.BlockPositioning;
44 import org.scilab.modules.xcos.utils.XcosMessages;
45
46 import com.mxgraph.swing.handler.mxGraphTransferHandler;
47 import com.mxgraph.swing.util.mxGraphTransferable;
48 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement;
49
50 /**
51  * A palette block is the representation of the block in the palette. All the
52  * operations there are used to render, load and put (on a diagram) a block.
53  */
54 public final class PaletteBlockCtrl {
55     /**
56      * Internal graph used to render each block.
57      */
58     public static final XcosDiagram INTERNAL_GRAPH;
59     static {
60         JavaController controller = new JavaController();
61         INTERNAL_GRAPH = new XcosDiagram(controller, controller.createObject(Kind.DIAGRAM), Kind.DIAGRAM, "");
62         INTERNAL_GRAPH.installListeners();
63     }
64
65     private static final double BLOCK_DEFAULT_POSITION = 10.0;
66     private static final MouseListener MOUSE_LISTENER = new PaletteBlockMouseListener();
67     private static final Logger LOG = Logger.getLogger(PaletteBlockCtrl.class.getName());
68
69     private static final String UNABLE_TO_LOAD_BLOCK = Messages.gettext("Unable to load block from %s .");
70     private static final String LOADING_THE_BLOCK = Messages.gettext("Loading the block") + XcosMessages.DOTS;
71
72     private static PaletteBlockCtrl previouslySelected;
73
74     private final PaletteBlock model;
75     private final PaletteBlockView view;
76
77     private transient WeakReference<Transferable> transferable = new WeakReference<Transferable>(null);
78
79     /**
80      * Default constructor
81      *
82      * @param model
83      *            the block data
84      */
85     public PaletteBlockCtrl(PaletteBlock model) {
86         this.model = model;
87         this.view = new PaletteBlockView(this);
88         installListeners(this.view);
89     }
90
91     /**
92      * @param view
93      *            The view to setup
94      */
95     private void installListeners(PaletteBlockView view) {
96         view.addMouseListener(MOUSE_LISTENER);
97         installDnd();
98     }
99
100     /**
101      * @return the view
102      */
103     public PaletteBlockView getView() {
104         return view;
105     }
106
107     /**
108      * @return the model
109      */
110     public PaletteBlock getModel() {
111         return model;
112     }
113
114     /**
115      * This function is the only access to get the block.
116      *
117      * @return the transferable object
118      * @throws ScicosFormatException
119      *             on decoding error
120      */
121     public synchronized Transferable getTransferable() throws ScicosFormatException {
122         Transferable transfer = transferable.get();
123         if (transfer == null) {
124             BasicBlock block;
125             try {
126                 block = XcosCellFactory.createBlock(model.getName());
127             } catch (ScilabInterpreterManagement.InterpreterException ex) {
128                 LOG.finest(String.format(UNABLE_TO_LOAD_BLOCK, model.getName()));
129                 getView().setEnabled(false);
130                 throw new InvalidDnDOperationException();
131             }
132             getView().setEnabled(true);
133
134             /* Render it and export it */
135             block.getGeometry().setX(BLOCK_DEFAULT_POSITION);
136             block.getGeometry().setY(BLOCK_DEFAULT_POSITION);
137
138             INTERNAL_GRAPH.addCell(block);
139             INTERNAL_GRAPH.selectAll();
140
141             BlockPositioning.updateBlockView(INTERNAL_GRAPH, block);
142
143             mxGraphTransferHandler handler = ((mxGraphTransferHandler) INTERNAL_GRAPH.getAsComponent().getTransferHandler());
144             Object[] cells = new Object[] {block};
145             transfer = new mxGraphTransferable(cells, INTERNAL_GRAPH.getPaintBounds(cells), handler.createTransferableImage(INTERNAL_GRAPH.getAsComponent(), cells));
146             transferable = new WeakReference<Transferable>(transfer);
147
148             INTERNAL_GRAPH.removeCells();
149         }
150         return transfer;
151     }
152
153     /**
154      * This function load the block and render it on the hidden diagram. This
155      * can be time-consuming and each block should be cached on the caller when
156      * possible.
157      *
158      * @return a rendered block
159      */
160     public BasicBlock getBlock() {
161         try {
162             return (BasicBlock) ((mxGraphTransferable) getTransferable()).getCells()[0];
163         } catch (ScicosFormatException e) {
164             LOG.severe(e.toString());
165             return null;
166         }
167     }
168
169     /**
170      * @return true if it is selected, false otherwise
171      */
172     public boolean isSelected() {
173         return this == previouslySelected;
174     }
175
176     /**
177      * @param selected
178      *            the selected state to set
179      */
180     public void setSelected(boolean selected) {
181         if (selected) {
182             if (previouslySelected != null) {
183                 previouslySelected.setSelected(false);
184             }
185             previouslySelected = this;
186         }
187         getView().setSelectedUI(selected);
188     }
189
190     /**
191      * Install the Drag'n'Drop on this instance.
192      */
193     public void installDnd() {
194         // Install the handler for dragging nodes into a graph
195         DragGestureListener dragGestureListener = new DragGestureListener() {
196             @Override
197             public void dragGestureRecognized(DragGestureEvent e) {
198                 if (PaletteManagerView.get() == null) {
199                     PaletteManagerView.restore(null);
200                 }
201                 final PaletteManagerView winView = PaletteManagerView.get();
202                 final DragGestureEvent event = e;
203                 final String msg = String.format(UNABLE_TO_LOAD_BLOCK, getModel().getName());
204
205                 winView.setInfo(LOADING_THE_BLOCK);
206                 try {
207                     Transferable transfer = getTransferable();
208
209                     if (transfer != null) {
210                         event.startDrag(null, null, new Point(), transfer, null);
211                     } else {
212                         throw new InvalidDnDOperationException();
213                     }
214                 } catch (InvalidDnDOperationException exception) {
215                     ScilabModalDialog.show(winView, msg, XcosMessages.XCOS_ERROR, IconType.ERROR_ICON);
216                 } catch (ScicosFormatException ex) {
217                     ScilabModalDialog.show(winView, ex.getMessage(), XcosMessages.XCOS_ERROR, IconType.ERROR_ICON);
218                 } finally {
219                     winView.setInfo(XcosMessages.EMPTY_INFO);
220                 }
221             }
222
223         };
224
225         DragSource dragSource = DragSource.getDefaultDragSource();
226         dragSource.createDefaultDragGestureRecognizer(this.getView(), DnDConstants.ACTION_COPY, dragGestureListener);
227     }
228 }