Xcos load: do not duplicate children
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / graph / PaletteDiagram.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Antoine ELIAS
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.1-en.txt
10  *
11  */
12
13 package org.scilab.modules.xcos.graph;
14
15 import java.io.File;
16 import java.util.ArrayList;
17 import java.util.List;
18
19 import javax.swing.ScrollPaneConstants;
20
21 import org.scilab.modules.xcos.Kind;
22 import org.scilab.modules.xcos.block.BasicBlock;
23 import org.scilab.modules.xcos.block.SplitBlock;
24 import org.scilab.modules.xcos.block.TextBlock;
25 import org.scilab.modules.xcos.io.XcosFileType;
26 import org.scilab.modules.xcos.link.BasicLink;
27 import org.scilab.modules.xcos.palette.view.PaletteComponent;
28 import org.scilab.modules.xcos.utils.BlockPositioning;
29 import org.scilab.modules.xcos.utils.XcosConstants;
30
31 import com.mxgraph.model.mxGeometry;
32
33 /**
34  * @author Antoine ELIAS
35  *
36  */
37 public class PaletteDiagram extends XcosDiagram {
38
39     private static final int BLOCK_MAX_WIDTH = (int) (XcosConstants.PALETTE_BLOCK_WIDTH * 0.8); // 80%
40     private static final int BLOCK_MAX_HEIGHT = (int) (XcosConstants.PALETTE_BLOCK_HEIGHT * 0.8); // 80%
41
42     private String name;
43     private String fileName;
44     private double windowWidth;
45
46     /**
47      * Constructor
48      */
49     public PaletteDiagram(long uid) {
50         super(uid, Kind.DIAGRAM);
51         setComponent(new PaletteComponent(this));
52
53         setTitle(PaletteDiagram.class.getName());
54
55         setCellsLocked(true);
56         setGridVisible(false);
57         setCellsDeletable(false);
58         setCellsEditable(false);
59         this.getAsComponent().setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
60
61         getUndoManager().setEventsEnabled(false);
62     }
63
64     /**
65      * @param diagramFileName
66      *            palette file
67      * @return status
68      */
69     public boolean openDiagramAsPal(String diagramFileName) {
70         File theFile = new File(diagramFileName);
71
72         if (theFile.exists()) {
73             try {
74                 final XcosFileType filetype = XcosFileType.findFileType(theFile);
75                 filetype.load(diagramFileName, this);
76             } catch (Exception e) {
77                 return false;
78             }
79             setName(theFile.getName());
80             setFileName(theFile.getAbsolutePath());
81             getRubberBand().setEnabled(false);
82
83             /* change some diagram parameters */
84             /* delete all links */
85             List<Object> tobeRemoved = new ArrayList<Object>();
86             for (int i = 0; i < getModel().getChildCount(getDefaultParent()); i++) {
87                 Object obj = getModel().getChildAt(getDefaultParent(), i);
88                 if (obj instanceof BasicLink || obj instanceof SplitBlock || obj instanceof TextBlock) {
89                     tobeRemoved.add(obj);
90                 }
91             }
92             for (Object object : tobeRemoved) {
93                 getModel().remove(object);
94             }
95
96             return true;
97         }
98         return false;
99     }
100
101     /**
102      * @param newWidth
103      *            update diagram width
104      */
105     public void updateDiagram(double newWidth) {
106
107         if (newWidth == windowWidth) {
108             return;
109         }
110
111         int oldRowItem = (int) (newWidth / (XcosConstants.PALETTE_BLOCK_WIDTH + XcosConstants.PALETTE_HMARGIN));
112         int maxRowItem = (int) (windowWidth / (XcosConstants.PALETTE_BLOCK_WIDTH + XcosConstants.PALETTE_HMARGIN));
113
114         // only compute for signifiant changes
115         if (oldRowItem == maxRowItem) {
116             return;
117         }
118
119         windowWidth = newWidth;
120         int blockCount = 0;
121
122         getModel().beginUpdate();
123         for (int i = 0; i < getModel().getChildCount(getDefaultParent()); i++) {
124             Object obj = getModel().getChildAt(getDefaultParent(), i);
125             if (obj instanceof BasicBlock) {
126                 BasicBlock block = (BasicBlock) obj;
127                 block.setGeometry(getNewBlockPosition(block.getGeometry(), blockCount));
128                 BlockPositioning.updateBlockView(this, block);
129                 blockCount++;
130             }
131         }
132         getModel().endUpdate();
133         refresh();
134         setModified(false);
135     }
136
137     /**
138      * @param geom
139      *            current block geometry
140      * @param blockCount
141      *            block index
142      * @return new geometry
143      */
144     private mxGeometry getNewBlockPosition(mxGeometry geom, int blockCount) {
145
146         int maxRowItem = (int) (windowWidth / (XcosConstants.PALETTE_BLOCK_WIDTH + XcosConstants.PALETTE_HMARGIN));
147         if (maxRowItem <= 0) {
148             maxRowItem = 1;
149         }
150         int row = blockCount % maxRowItem;
151         int col = blockCount / maxRowItem;
152         double x = geom.getX();
153         double y = geom.getY();
154         double w = geom.getWidth();
155         double h = geom.getHeight();
156
157         if (geom.getWidth() > BLOCK_MAX_WIDTH || geom.getHeight() > BLOCK_MAX_HEIGHT) {
158             // update block size to fill "block area"
159             double ratio = Math.min(BLOCK_MAX_HEIGHT / h, BLOCK_MAX_WIDTH / w);
160             w *= ratio;
161             h *= ratio;
162         }
163
164         x = row * (XcosConstants.PALETTE_BLOCK_WIDTH + XcosConstants.PALETTE_HMARGIN);
165         x += (XcosConstants.PALETTE_BLOCK_WIDTH - w) / 2;
166         y = col * (XcosConstants.PALETTE_BLOCK_HEIGHT + XcosConstants.PALETTE_VMARGIN);
167         y += (XcosConstants.PALETTE_BLOCK_HEIGHT - h) / 2;
168
169         return new mxGeometry(x, y, w, h);
170     }
171
172     /**
173      * @return name
174      */
175     public String getName() {
176         return name;
177     }
178
179     /**
180      * @param name
181      *            palette name
182      */
183     public void setName(String name) {
184         this.name = name;
185     }
186
187     /**
188      * Always return false as we cannot draw links on the palette diagram.
189      *
190      * @param cell
191      *            the cell we are workling on
192      * @return always false
193      * @see org.scilab.modules.xcos.graph.XcosDiagram#isCellConnectable(java.lang.Object)
194      */
195     @Override
196     public boolean isCellConnectable(Object cell) {
197         return false;
198     }
199
200     /**
201      * @param fileName
202      *            palette filename
203      */
204     public void setFileName(String fileName) {
205         this.fileName = fileName;
206     }
207
208     /**
209      * @return palette filename
210      */
211     public String getFileName() {
212         return fileName;
213     }
214
215 }