Remove unused fields
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / graph / ScilabGraph.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.graph;
14
15 import java.awt.Color;
16 import java.util.List;
17
18 import org.scilab.modules.graph.utils.ScilabGraphMessages;
19 import org.scilab.modules.gui.tab.Tab;
20 import org.scilab.modules.gui.utils.UIElementMapper;
21 import org.scilab.modules.gui.window.ScilabWindow;
22 import org.scilab.modules.xcos.utils.XcosComponent;
23
24 import com.mxgraph.swing.mxGraphComponent;
25 import com.mxgraph.swing.mxGraphOutline;
26 import com.mxgraph.swing.handler.mxKeyboardHandler;
27 import com.mxgraph.swing.handler.mxRubberband;
28 import com.mxgraph.swing.util.mxGraphActions;
29 import com.mxgraph.util.mxEvent;
30 import com.mxgraph.util.mxEventObject;
31 import com.mxgraph.util.mxUndoManager;
32 import com.mxgraph.util.mxUndoableEdit;
33 import com.mxgraph.util.mxUndoableEdit.mxUndoableChange;
34 import com.mxgraph.view.mxGraph;
35
36 /**
37  * Represent the base diagram of Xcos.
38  *
39  * It performs generic operations like undo/redo management, action clean-up,
40  * modification state management, Tab association, etc...
41  */
42 public class ScilabGraph extends mxGraph {
43
44     private final mxUndoManager undoManager = new mxUndoManager();
45     private final XcosComponent component;
46
47     private String title = ScilabGraphMessages.UNTITLED;
48     private String savedFile = null;
49     private boolean modified = false;
50     private Tab parentTab;
51     private boolean opened = false;
52     private boolean redoInAction = false;
53     private int undoCounter = 0;
54     private boolean readOnly = false;
55     private Color originalColor = null;
56     private transient mxRubberband rubberBand;
57
58     /**
59      * Manage the modification state on change
60      */
61     protected mxIEventListener changeTracker = new mxIEventListener() {
62         public void invoke(Object source, mxEventObject evt) {
63             setModified(true);
64         }
65     };
66
67     /**
68      * Manage the undo/redo on change
69      */
70     protected mxIEventListener undoHandler = new mxIEventListener() {
71         public void invoke(Object source, mxEventObject evt) {
72
73             if (!redoInAction) {
74                 undoManager.undoableEditHappened((mxUndoableEdit) evt.getArgAt(0));
75                 incrementUndoCounter();
76             }
77         }
78     };
79
80     /**
81      * Manage the selection on change
82      */
83     mxIEventListener selectionHandler = new mxIEventListener() {
84         public void invoke(Object source, mxEventObject evt) {
85             List<mxUndoableChange> changes = ((mxUndoableEdit) evt.getArgAt(0)).getChanges();
86             setSelectionCells(getSelectionCellsForChanges(changes));
87         }
88     };
89
90     /**
91      * Default constructor:
92      *     - disable unused actions
93      *     - install listeners
94      *     - Replace JGraphX components by specialized components if needed.
95      */
96     public ScilabGraph() {
97         super();
98
99         /*
100          * Disabling the default connected action and event listeners.
101          */
102         mxGraphActions.getSelectNextAction().setEnabled(false);
103         mxGraphActions.getSelectPreviousAction().setEnabled(false);
104         mxGraphActions.getSelectChildAction().setEnabled(false);
105         mxGraphActions.getSelectParentAction().setEnabled(false);
106
107         // Undo / Redo capabilities
108         getModel().addListener(mxEvent.UNDO, undoHandler);
109         getView().addListener(mxEvent.UNDO, undoHandler);
110
111         // Keeps the selection in sync with the command history
112
113         undoManager.addListener(mxEvent.UNDO, selectionHandler);
114         undoManager.addListener(mxEvent.REDO, selectionHandler);
115
116         component = new XcosComponent(this);
117         //      component = new mxGraphComponent(this);
118
119         // Adds rubberband selection
120         rubberBand = new mxRubberband(component);
121
122         // Modified property change
123         getModel().addListener(mxEvent.CHANGE, changeTracker);
124
125         // addKeyListener(new XcosShortCut());
126         // setMarqueeHandler(new XcosPortAction());
127         // getGraphLayoutCache().setFactory(new DiagrammFactory());
128         // setPortsScaled(true);
129         // setVisible(true);
130         // Control-drag should clone selection
131         // this.setCloneable(true);
132         // this.setPortsVisible(true);
133
134         // Enable edit without final RETURN keystroke
135         // this.setInvokesStopCellEditing(true);
136     }
137
138     /**
139      * @return The previously saved file or null.
140      */
141     public String getSavedFile() {
142         return savedFile;
143     }
144
145     /**
146      * @param savedFile The new saved file
147      */
148     public void setSavedFile(String savedFile) {
149         this.savedFile = savedFile;
150     }
151
152     /**
153      * @return true, if the graph has been modified ; false otherwise.  
154      */
155     public boolean isModified() {
156         return modified;
157     }
158
159     /**
160      * Modify the state of the diagram.
161      * @param modified The new modified state. 
162      * @category UseEvent
163      */
164     public void setModified(boolean modified) {
165         boolean oldValue = this.modified;
166         this.modified = modified;
167
168         getAsComponent().firePropertyChange("modified", oldValue, modified);
169     }
170
171     /**
172      * @param title The new title of the tab
173      */
174     public void setTitle(String title) {
175         this.title = title;
176     }
177
178     /**
179      * @return The current Tab title
180      */
181     public String getTitle() {
182         return title;
183     }
184
185     /**
186      * @return The component associated with the current graph.
187      */
188     public mxGraphComponent getAsComponent() {
189         return component;
190     }
191
192     /**
193      * Undo the last action
194      * @see com.mxgraph.util.mxUndoManager
195      */
196     public void undo() {
197         decrementUndoCounter();
198         redoInAction = true;
199         undoManager.undo();
200         redoInAction = false;
201     }
202
203     /**
204      * Redo the last action
205      * com.mxgraph.util.mxUndoManager
206      */
207     public void redo() {
208         incrementUndoCounter();
209         redoInAction = true;
210         undoManager.redo();
211         redoInAction = false;
212     }
213
214     /**
215      * Used internally to manage the modified state on undo/redo
216      */
217     private void incrementUndoCounter() {
218         if (undoCounter < Integer.MAX_VALUE) {
219             undoCounter++;
220         }
221     }
222
223     /**
224      * Used internally to manage the modified state on undo/redo
225      */
226     private void decrementUndoCounter() {
227         if (undoCounter > Integer.MIN_VALUE) {
228             undoCounter--;
229         }
230     }
231
232     /**
233      * Used internally to manage the modified state on undo/redo
234      */
235     protected boolean isZeroUndoCounter() {
236         return (undoCounter == 0);
237     }
238
239     /**
240      * Used internally to manage the modified state on undo/redo
241      */
242     protected void resetUndoCounter() {
243         undoCounter = 0;
244     }
245
246     @Deprecated
247     public void zoom() {
248         // this.setScale(2 * this.getScale());
249     }
250
251     @Deprecated
252     public void unzoom() {
253         // this.setScale(this.getScale() / 2);
254     }
255
256     @Deprecated
257     public void delete() {
258         // if (!isSelectionEmpty()) {
259         // getModel().remove(getDescendants(getSelectionCells()));
260         // }
261     }
262
263     /**
264      * @return The associated Tab
265      */
266     public Tab getParentTab() {
267         return parentTab;
268     }
269
270     /**
271      * @param parentTab The new associated Tab
272      */
273     public void setParentTab(Tab parentTab) {
274         this.parentTab = parentTab;
275     }
276
277     /**
278      * The instance can be not visible but used (when using SuperBlock). The
279      * openned flag is true in this case and also when the Window/Tab is
280      * visible.
281      * @param opened Openned state 
282      */
283     public void setOpened(boolean opened) {
284         this.opened = opened;
285     }
286
287     /**
288      * @return Openned state
289      */
290     public boolean isOpened() {
291         return opened;
292     }
293
294     /**
295      * Set the associated Window/Tab visible or not.
296      * @param visible State of visibility
297      */
298     public void setVisible(boolean visible) {
299         if (parentTab != null) {
300             ScilabWindow xcosWindow = (ScilabWindow) UIElementMapper.getCorrespondingUIElement(parentTab.getParentWindowId());
301             xcosWindow.setVisible(visible);
302         }
303     }
304
305     /**
306      * Check if the associated Window/Tab is visible 
307      * @return State of visibility
308      */
309     public boolean isVisible() {
310         if (parentTab != null) {
311             ScilabWindow xcosWindow = (ScilabWindow) UIElementMapper.getCorrespondingUIElement(parentTab.getParentWindowId());
312             return xcosWindow.isVisible();
313         }
314
315         return false;
316     }
317
318     /**
319      * A read-only state will disable all actions in the graph.
320      * @param readOnly Read-only state
321      */
322     public void setReadOnly(boolean readOnly) {
323         this.readOnly = readOnly;
324         
325         setCellsLocked(readOnly);
326         if(isReadonly()) {
327             setOriginalColor(getAsComponent().getBackground());
328             getAsComponent().setBackground(new Color(240, 240, 240));
329         } else {
330             getAsComponent().setBackground(getOriginalColor());
331         }
332     }
333
334     /**
335      * @return True if actions are not allowed, false otherwise.
336      */
337     public boolean isReadonly() {
338         return readOnly;
339     }
340
341     /**
342      * Useful function for the read-only property
343      */
344     private void setOriginalColor(Color originalColor) {
345         this.originalColor = originalColor;
346     }
347
348     /**
349      * Useful function for the read-only property
350      */
351     private Color getOriginalColor() {
352         if(originalColor != null){
353             return originalColor;
354         }
355         return Color.WHITE;
356     }
357
358     /**
359      * @return The associated RubberBand
360      * @see com.mxgraph.swing.handler.mxRubberband
361      */
362     public mxRubberband getRubberBand() {
363         return rubberBand;
364     }
365
366     /**
367      * @return The undo manager associated with this graph
368      */
369         protected final mxUndoManager getUndoManager() {
370                 return undoManager;
371         }
372 }