001    /*
002      Copyright (C) 2002-2003 Renaud Pawlak <renaud@aopsys.com>
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public
015      License along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
017    */
018    
019    package org.objectweb.jac.ide.diagrams;
020    
021    import CH.ifa.draw.framework.*;
022    import CH.ifa.draw.standard.*;
023    import java.awt.*;
024    import java.util.*;
025    import org.apache.log4j.Logger;
026    import org.objectweb.jac.core.Wrappee;
027    import org.objectweb.jac.core.Wrapping;
028    import org.objectweb.jac.core.rtti.ClassItem;
029    import org.objectweb.jac.core.rtti.ClassRepository;
030    import org.objectweb.jac.core.rtti.CollectionItem;
031    import org.objectweb.jac.core.rtti.FieldItem;
032    import org.objectweb.jac.ide.ModelElement;
033    import org.objectweb.jac.util.Log;
034    
035    public class GenericObjectFigure extends CompositeFigure 
036        implements ModelElementFigure
037    {
038        static Logger logger = Logger.getLogger("figures");
039        
040            public void close() {}
041        public static int SHAPE_RECT=0;
042        public static int SHAPE_ROUNDRECT=1;
043    
044        private static final int BORDER = 3;
045        private Rectangle fDisplayBox;
046    
047        Vector fieldFigures=new Vector();
048    
049        int shape=SHAPE_RECT;
050       
051        /**
052         * Get the value of shape.
053         * @return value of shape.
054         */
055        public int getShape() {
056            return shape;
057        }
058       
059        /**
060         * Set the value of shape.
061         * @param v  Value to assign to shape.
062         */
063        public void setShape(int  v) {
064            this.shape = v;
065        }
066    
067        DrawingView view;
068          
069        org.objectweb.jac.ide.GenericFigure genericFigure;
070       
071        /**
072         * Get the value of genericFigure.
073         * @return value of genericFigure.
074         */
075        public org.objectweb.jac.ide.GenericFigure getGenericFigure() {
076            return genericFigure;
077        }
078       
079        /**
080         * Set the value of genericFigure.
081         * @param v  Value to assign to genericFigure.
082         */
083        public void setGenericFigure(org.objectweb.jac.ide.GenericFigure  v) {
084            this.genericFigure = v;
085        }
086       
087        public GenericObjectFigure() {}
088    
089        public GenericObjectFigure(org.objectweb.jac.ide.GenericFigure fig, 
090                                   org.objectweb.jac.ide.Package pack,
091                                   DrawingView view) {
092            this.genericFigure = fig;
093            this.containerPackage = pack;
094            this.view = view;
095            initialize();
096        }
097    
098        void initFields() {
099            if (substance == null) {
100                logger.warn("UNRESOLVED OBJECT!");
101            } else {
102                logger.debug("init generic object figure "+substance);
103                FieldItem[] fields=null;
104                ClassItem substClass=ClassRepository.get().getClass(substance);
105                if(substClass.getAttribute("Gui.attributesOrder")!=null) {
106                    fields=(FieldItem[])substClass.getAttribute("Gui.attributesOrder");
107                } else {
108                    fields=substClass.getPrimitiveFields();
109                }
110                for(int i=0;i<fields.length;i++) {
111                    if(!fields[i].isPrimitive()) continue;
112                    logger.debug("  adding field "+fields[i]+" subtance="+substance);
113                    AttributeValueFigure ff=new AttributeValueFigure(fields[i],substance);
114                    ff.setFont(defaultFont);
115                    fieldFigures.add(ff);
116                    add(ff);
117                }
118                Wrapping.invokeRoleMethod((Wrappee)substance,"addView",new Object[]{this});
119            }
120        }
121    
122        void removeAllMembers() {
123            FigureEnumeration it = figures();
124            // skip the title
125            it.nextFigure();
126            while (it.hasMoreElements()) {
127                Figure f = it.nextFigure();
128                logger.debug("removing "+f);
129                remove(f);
130            }
131            fieldFigures.clear();
132        }
133    
134        protected void basicMoveBy(int x, int y) {
135            fDisplayBox.translate(x, y);
136            super.basicMoveBy(x, y);
137        } 
138    
139        public Rectangle displayBox() {
140            return new Rectangle(
141                fDisplayBox.x,
142                fDisplayBox.y,
143                fDisplayBox.width,
144                fDisplayBox.height);
145        }
146    
147        public void basicDisplayBox(Point origin, Point corner) {
148            fDisplayBox = new Rectangle(origin);
149            fDisplayBox.add(corner);
150            layout();
151        }
152    
153        protected void drawBorder(Graphics g) {
154          
155            Rectangle r = displayBox();      
156          
157            g.setColor(Color.white);
158            if(shape==SHAPE_RECT)
159                g.fillRect(r.x, r.y, r.width, r.height);
160            else if(shape==SHAPE_ROUNDRECT)
161                g.fillRoundRect(r.x, r.y, r.width, r.height,7,7);
162          
163            g.setColor(Color.black);
164            if(shape==SHAPE_RECT)
165                g.drawRect(r.x, r.y, r.width, r.height);
166            else if(shape==SHAPE_ROUNDRECT)
167                g.drawRoundRect(r.x, r.y, r.width, r.height,7,7);
168    
169            // should be customizable
170    
171            /*  Figure f = figureAt(0);
172                Rectangle rf = f.displayBox();
173          
174                g.drawLine(r.x,r.y+rf.height+1,r.x+r.width,r.y+rf.height+1);
175          
176                if( fieldFigures.size() > 0 ) {
177                f = (Figure) fieldFigures.get(0);
178                rf = f.displayBox();
179                g.drawLine(r.x,rf.y,r.x+r.width,rf.y);
180                }*/
181          
182        }
183    
184        public void draw(Graphics g) {
185            drawBorder(g);
186            super.draw(g);
187        }
188    
189        public Vector handles() {
190            Vector handles = new Vector();
191            handles.addElement(new NullHandle(this, RelativeLocator.northWest()));
192            handles.addElement(new NullHandle(this, RelativeLocator.northEast()));
193            handles.addElement(new NullHandle(this, RelativeLocator.southWest()));
194            handles.addElement(new NullHandle(this, RelativeLocator.southEast()));
195            return handles;
196        }
197    
198        private void initialize() {
199            fDisplayBox = new Rectangle(0, 0, 0, 0);
200        }
201    
202        Font defaultFont=new Font("Helvetica", Font.PLAIN, 10);
203       
204        /**
205         * Get the value of defaultFont.
206         * @return value of defaultFont.
207         */
208        public Font getDefaultFont() {
209            return defaultFont;
210        }
211       
212        /**
213         * Set the value of defaultFont.
214         * @param v  Value to assign to defaultFont.
215         */
216        public void setDefaultFont(Font  v) {
217            this.defaultFont = v;
218        }
219       
220       
221        public void layout() {
222            Point partOrigin = new Point(fDisplayBox.x, fDisplayBox.y);
223            partOrigin.translate(BORDER, BORDER);
224            Dimension extent = new Dimension(0, 0);
225          
226            Iterator it = fieldFigures.iterator();
227          
228            while(it.hasNext()) {
229                Figure f = (Figure)it.next();
230             
231                Dimension partExtent = f.size();
232                Point corner = new Point(
233                    partOrigin.x+partExtent.width,
234                    partOrigin.y+partExtent.height);
235                f.basicDisplayBox(partOrigin, corner);
236             
237                extent.width = Math.max(extent.width, partExtent.width);
238                extent.height += partExtent.height;
239                partOrigin.y += partExtent.height;
240            }
241            fDisplayBox.width = extent.width + 2*BORDER;
242            fDisplayBox.height = extent.height + 2*BORDER;
243        }
244    
245        private boolean needsLayout() {
246            /*              Dimension extent = new Dimension(0, 0);
247    
248                    FigureEnumeration k = figures();
249                    while (k.hasMoreElements()) {
250                    Figure f = k.nextFigure();
251                    extent.width = Math.max(extent.width, f.size().width);
252                    }
253                    int newExtent = extent.width + 2*BORDER;
254                    return newExtent != fDisplayBox.width;*/
255            return true;
256        }
257    
258        public void update(FigureChangeEvent e) {
259            if (needsLayout()) {
260                layout();
261                changed();
262            }
263        }
264    
265        public void figureChanged(FigureChangeEvent e) {
266            update(e);
267        }
268    
269    
270        public void figureRemoved(FigureChangeEvent e) {
271            update(e);
272        }
273    
274        Object substance;
275       
276        // View interface
277        /*
278          public void refreshViewItem(org.objectweb.jac.core.rtti.FieldItem field, 
279          org.objectweb.jac.core.rtti.MethodItem method, Object[] args) {
280          refreshView();
281          }
282    
283          public void setFocus(org.objectweb.jac.core.rtti.FieldItem field, Object extraOption) {}
284    
285          public void refreshView() {
286          if( DiagramView.init ) return;
287          DiagramView.init = true;
288          removeAllMembers();
289          initFields();
290          layout();
291          changed();
292          DiagramView.refreshFigure(this);
293          //editor().validate();
294          DiagramView.init = false;
295          }
296    
297          public void close() {}
298        */
299    
300        /**
301         * Get the value of substance.
302         * @return value of substance.
303         */
304        public ModelElement getSubstance() {
305            return (ModelElement)substance;
306        }
307       
308        /**
309         * Set the value of substance.
310         * @param v  Value to assign to substance.
311         */
312        public void setSubstance(Object  v) {
313            this.substance = v;
314        }
315    
316        CollectionItem collection;
317       
318        /**
319         * Get the value of collection.
320         * @return value of collection.
321         */
322        public CollectionItem getCollection() {
323            return collection;
324        }
325       
326        /**
327         * Set the value of collection.
328         * @param v  Value to assign to collection.
329         */
330        public void setCollection(CollectionItem v) {
331            this.collection = v;
332        }
333       
334        org.objectweb.jac.ide.Package containerPackage;
335    
336        /**
337         * Get the value of containerPackage.
338         * @return value of containerPackage.
339         */
340        public org.objectweb.jac.ide.Package getContainerPackage() {
341            return containerPackage;
342        }
343       
344        /**
345         * Set the value of containerPackage.
346         * @param v  Value to assign to containerPackage.
347         */
348        public void setContainerPackage(org.objectweb.jac.ide.Package  v) {
349            this.containerPackage = v;
350        }
351    
352    }