Statistics
| Revision:

svn-document-layout / branches / usability_v2 / org.gvsig.app.document.layout.app / org.gvsig.app.document.layout.app.mainplugin / src / main / java / org / gvsig / app / project / documents / layout / fframes / FFrame.java @ 147

History | View | Annotate | Download (28.2 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.app.project.documents.layout.fframes;
23

    
24
import java.awt.BasicStroke;
25
import java.awt.Color;
26
import java.awt.Font;
27
import java.awt.Graphics2D;
28
import java.awt.Image;
29
import java.awt.Rectangle;
30
import java.awt.event.MouseEvent;
31
import java.awt.geom.AffineTransform;
32
import java.awt.geom.Point2D;
33
import java.awt.geom.Rectangle2D;
34
import java.awt.image.BufferedImage;
35

    
36
import org.gvsig.andami.PluginServices;
37
import org.gvsig.andami.ui.mdiManager.IWindow;
38
import org.gvsig.app.project.ProjectManager;
39
import org.gvsig.app.project.documents.Document;
40
import org.gvsig.app.project.documents.layout.Attributes;
41
import org.gvsig.app.project.documents.layout.DefaultLayoutManager;
42
import org.gvsig.app.project.documents.layout.FLayoutUtilities;
43
import org.gvsig.app.project.documents.layout.FrameChangedNotificationImpl;
44
import org.gvsig.app.project.documents.layout.LayoutContext;
45
import org.gvsig.app.project.documents.layout.LayoutControl;
46
import org.gvsig.app.project.documents.layout.LayoutDocument;
47
import org.gvsig.app.project.documents.layout.LayoutManager;
48
import org.gvsig.app.project.documents.layout.LayoutNotification;
49
import org.gvsig.app.project.documents.layout.gui.LayoutPanel;
50
import org.gvsig.tools.ToolsLocator;
51
import org.gvsig.tools.dynobject.DynStruct;
52
import org.gvsig.tools.observer.Observable;
53
import org.gvsig.tools.observer.ObservableHelper;
54
import org.gvsig.tools.observer.Observer;
55
import org.gvsig.tools.persistence.PersistenceManager;
56
import org.gvsig.tools.persistence.PersistentState;
57
import org.gvsig.tools.persistence.exception.PersistenceException;
58
import org.slf4j.Logger;
59
import org.slf4j.LoggerFactory;
60

    
61
/**
62
 * Clase que implementa la interface IFFrame con los m�todos por defecto de
63
 * todos los FFrames que extenderan de este, dejando uno como m�todo
64
 * abstracto para implementar por todos los FFrames para ser dibujados.
65
 * 
66
 * @author Vicente Caballero Navarro
67
 */
68
public abstract class FFrame implements IFFrame {
69

    
70
    public static final String PERSISTENCE_DEFINITION_NAME = "FFrame";
71

    
72
    private static final String BOUNDINGBOX_FIELD = "boundingBox";
73
    private static final String SELECTED_FIELD = "selected";
74
    private static final String TAG_FIELD = "tag";
75
    private static final String ROTATION_FIELD = "rotation";
76
    private static final String LEVEL_FIELD = "level";
77
    private static final String NUM_FIELD = "num";
78
        private static final String DOCUMENT_FIELD = "layoutDocument";
79
        private static final String LAYOUT_CONTEXT_FIELD = "layoutContext";
80

    
81
    protected static final Logger LOG = LoggerFactory.getLogger(FFrame.class);
82

    
83
    protected Rectangle2D.Double m_BoundBox = new Rectangle2D.Double();
84
    // initially identity
85
    protected AffineTransform lastAT = AffineTransform.getShearInstance(0,0);
86
    // private Rectangle2D.Double m_BoundingBox = new Rectangle2D.Double();
87
    
88
    protected int m_Selected = 0;
89
    protected Rectangle n = new Rectangle();
90
    protected Rectangle ne = new Rectangle();
91
    protected Rectangle e = new Rectangle();
92
    protected Rectangle se = new Rectangle();
93
    protected Rectangle s = new Rectangle();
94
    protected Rectangle so = new Rectangle();
95
    protected Rectangle o = new Rectangle();
96
    protected Rectangle no = new Rectangle();
97
    private String tag = null;
98
    protected int num = 0;
99
    private double m_rotation = 0;
100
    private int level = -1;
101
    private Rectangle2D lastMoveRect;
102
    protected FrameFactory frameFactory;
103

    
104
    private static Image iNEResize = null;
105
    private static Image iEResize = null;
106
    private static Image iNResize = null;
107
    private static Image iMove = null;
108
    private static Image iSEResize = null;
109

    
110
    protected LayoutManager layoutManager = null;
111
    private LayoutContext layoutContext = null;
112
    private Document document = null;
113
        
114
    protected ObservableHelper observers;
115
    
116
    public FFrame() {
117
        super();
118
        layoutManager =
119
            (LayoutManager) ProjectManager.getInstance().getDocumentManager(
120
                DefaultLayoutManager.TYPENAME);
121
        observers = new ObservableHelper();
122
    }
123

    
124
    /**
125
     * Dibuja los handlers sobre el boundingBox en el graphics que se pasa como
126
     * par�metro.
127
     * 
128
     * @param g
129
     *            Graphics sobre el que dibujar.
130
     */
131
    public void drawHandlers(Graphics2D g) {
132
        int size = 10;
133
        Rectangle2D r = getBoundingBox(null);
134
        Point2D p = new Point2D.Double();
135
        g.rotate(Math.toRadians(getRotation()), r.getX() + (r.getWidth() / 2),
136
            r.getY() + (r.getHeight() / 2));
137

    
138
        AffineTransform atRotate = new AffineTransform();
139
        atRotate.rotate(Math.toRadians(getRotation()), r.getX()
140
            + (r.getWidth() / 2), r.getY() + (r.getHeight() / 2));
141

    
142
        g.fillRect((int) r.getX() - size, (int) r.getY() - size, size, size);
143
        atRotate.transform(
144
            new Point2D.Double(r.getX() - size, r.getY() - size), p);
145
        no.setRect((int) p.getX(), (int) p.getY(), size, size);
146

    
147
        g.fillRect((int) r.getMaxX(), (int) r.getY() - size, size, size);
148
        atRotate.transform(new Point2D.Double(r.getMaxX(), r.getY() - size), p);
149
        ne.setRect((int) p.getX(), (int) p.getY(), size, size);
150

    
151
        g.fillRect((int) r.getX() - size, (int) r.getMaxY(), size, size);
152
        atRotate.transform(new Point2D.Double(r.getX() - size, r.getMaxY()), p);
153
        so.setRect((int) p.getX(), (int) p.getY(), size, size);
154

    
155
        g.fillRect((int) r.getMaxX(), (int) r.getMaxY(), size, size);
156
        atRotate.transform(new Point2D.Double(r.getMaxX(), r.getMaxY()), p);
157
        se.setRect((int) p.getX(), (int) p.getY(), size, size);
158

    
159
        g.fillRect((int) r.getCenterX() - (size / 2), (int) r.getY() - size,
160
            size, size);
161
        atRotate
162
            .transform(new Point2D.Double(r.getCenterX() - (size / 2), r.getY()
163
                - size), p);
164
        n.setRect((int) p.getX(), (int) p.getY(), size, size);
165

    
166
        g.fillRect((int) r.getCenterX() - (size / 2), (int) r.getMaxY(), size,
167
            size);
168
        atRotate.transform(
169
            new Point2D.Double(r.getCenterX() - (size / 2), r.getMaxY()), p);
170
        s.setRect((int) p.getX(), (int) p.getY(), size, size);
171

    
172
        g.fillRect((int) r.getX() - size, (int) r.getCenterY() - (size / 2),
173
            size, size);
174
        atRotate.transform(new Point2D.Double(r.getX() - size, r.getCenterY()
175
            - (size / 2)), p);
176
        o.setRect((int) p.getX(), (int) p.getY(), size, size);
177

    
178
        g.fillRect((int) r.getMaxX(), (int) r.getCenterY() - (size / 2), size,
179
            size);
180
        atRotate.transform(new Point2D.Double(r.getMaxX(), r.getCenterY()
181
            - (size / 2)), p);
182
        e.setRect((int) p.getX(), (int) p.getY(), size, size);
183
        g.rotate(Math.toRadians(-getRotation()), r.getX() + (r.getWidth() / 2),
184
            r.getY() + (r.getHeight() / 2));
185
    }
186

    
187
    /**
188
     * Establece que tipo de selecci�n se realiza sobre el fframe.
189
     * 
190
     * @param p
191
     *            punto sobre el que se debe de establecer si se selecciona o no
192
     *            el fframe.
193
     */
194
    public void setSelected(Point2D p, MouseEvent e) {
195
        doSetSelected(getContains(p));
196
    }
197

    
198
    /**
199
     * Actualiza el BoundBox del FFrame a partir de su rect�ngulo en pixels y
200
     * la matriz de transformaci�n.
201
     * 
202
     * @param r
203
     *            Rect�ngulo.
204
     * @param at
205
     *            Matriz de transformaci�n.
206
     */
207
    public void updateRect(Rectangle2D r, AffineTransform at) {
208
        Rectangle2D.Double rec = FLayoutUtilities.toSheetRect(r, at);
209
        rec.setRect((int) rec.getMinX(), (int) rec.getMinY(),
210
            (int) rec.getWidth(), (int) rec.getHeight());
211
        setBoundBox(rec);
212
    }
213

    
214
    /**
215
     * Devuelve el rect�ngulo a partir del desplazamiento en el eje x y el
216
     * desplazamiento en el eje y.
217
     * 
218
     * @param difx
219
     *            desplazamiento sobre el eje x.
220
     * @param dify
221
     *            desplazamiento sobre el eje y.
222
     * 
223
     * @return rect�ngulo modificado en funci�n del desplazamiento
224
     *         realizado.
225
     */
226
    public Rectangle2D getMovieRect(int difx, int dify) {
227
        double x = 0;
228
        double y = 0;
229
        double w = 0;
230
        double h = 0;
231

    
232
        lastMoveRect =
233
            new Rectangle2D.Double(this.getBoundingBox(null).x,
234
                this.getBoundingBox(null).y, this.getBoundingBox(null).width,
235
                this.getBoundingBox(null).height);
236
        Rectangle2D.Double rec = this.getBoundingBox(null);
237
        int difn = 0;
238
        difn = difx;
239
        x = lastMoveRect.getX();
240
        y = lastMoveRect.getY();
241
        w = lastMoveRect.getWidth();
242
        h = lastMoveRect.getHeight();
243

    
244
        switch (this.getSelected()) {
245
        case (RECT):
246
            lastMoveRect.setRect((x + difx), (y + dify), w, h);
247

    
248
            break;
249

    
250
        case (N):
251

    
252
            if ((y + dify) > rec.getMaxY()) {
253
                y = rec.getMaxY();
254
            } else {
255
                y = y + dify;
256
            }
257

    
258
            lastMoveRect.setRect(x, y, w, Math.abs(h - dify));
259

    
260
            break;
261

    
262
        case (O):
263

    
264
            if ((x + difx) > rec.getMaxX()) {
265
                x = rec.getMaxX();
266
            } else {
267
                x = x + difx;
268
            }
269

    
270
            lastMoveRect.setRect(x, y, Math.abs(w - difx), h);
271

    
272
            break;
273

    
274
        case (S):
275

    
276
            if (y > (rec.getMaxY() + dify)) {
277
                y = rec.getMaxY() + dify;
278
            }
279

    
280
            lastMoveRect.setRect(x, y, w, Math.abs(h + dify));
281

    
282
            break;
283

    
284
        case (E):
285

    
286
            if (x > (rec.getMaxX() + difx)) {
287
                x = rec.getMaxX() + difx;
288
            }
289

    
290
            lastMoveRect.setRect(x, y, Math.abs(w + difx), h);
291

    
292
            break;
293

    
294
        case (NE):
295

    
296
            if ((y - difn) > rec.getMaxY()) {
297
                y = rec.getMaxY();
298
                x = rec.getMaxX() + difn;
299
            } else {
300
                y = y - difn;
301
            }
302

    
303
            lastMoveRect.setRect(x, y, Math.abs(w + difn), Math.abs(h + difn));
304

    
305
            break;
306

    
307
        case (NO):
308

    
309
            if ((y + difn) > rec.getMaxY()) {
310
                y = rec.getMaxY();
311
                x = rec.getMaxX();
312
            } else {
313
                x = x + difn;
314
                y = y + difn;
315
            }
316

    
317
            lastMoveRect.setRect(x, y, Math.abs(w - difn), Math.abs(h - difn));
318

    
319
            break;
320

    
321
        case (SE):
322

    
323
            if (y > (rec.getMaxY() + difn)) {
324
                y = rec.getMaxY() + difn;
325
                x = rec.getMaxX() + difn;
326
            }
327

    
328
            lastMoveRect.setRect(x, y, Math.abs(w + difn), Math.abs(h + difn));
329

    
330
            break;
331

    
332
        case (SO):
333

    
334
            if ((x + difn) > rec.getMaxX()) {
335
                x = rec.getMaxX();
336
                y = rec.getMaxY() - difn;
337
            } else {
338
                x = x + difn;
339
            }
340

    
341
            lastMoveRect.setRect(x, y, Math.abs(w - difn), Math.abs(h - difn));
342

    
343
            break;
344

    
345
        default:
346
            lastMoveRect.setRect((x), (y), w, h);
347
        }
348

    
349
        return lastMoveRect;
350
    }
351

    
352
    /**
353
     * Devuelve el rect�ngulo que representa el �ltimo generado al desplazar
354
     * o modificar el tama�o del fframe.
355
     * 
356
     * @return Rectangle2D
357
     * 
358
     */
359
    public Rectangle2D getLastMoveRect() {
360
        return lastMoveRect;
361
    }
362

    
363
    /**
364
     * Devuelve un entero que representa el tipo de selecci�n que se ha
365
     * realizado sobre el fframe.
366
     * 
367
     * @return tipo de selecci�n que se ha realizado.
368
     */
369
    public int getSelected() {
370
        return m_Selected;
371
    }
372
    
373
    public boolean isSelected() {
374
            return getSelected()!=IFFrame.NOSELECT;
375
    }
376

    
377
    /**
378
     * Devuelve true, si el punto que se pasa como par�metro esta contenido
379
     * dentro del boundingbox del fframe.
380
     * 
381
     * @param p
382
     *            punto a comprobar.
383
     * 
384
     * @return true si el punto esta dentro del boundingbox.
385
     */
386
    public boolean contains(Point2D p) {
387
        return getBoundingBox(null).contains(p.getX(), p.getY());
388
    }
389

    
390
    /**
391
     * Devuelve un entero que representa donde esta contenido el punto que se
392
     * pasa como par�metro.
393
     * 
394
     * @param p
395
     *            punto a comparar.
396
     * 
397
     * @return entero que representa como esta contenido el punto.
398
     */
399
    public int getContains(Point2D p) {
400
        if (n.contains(p.getX(), p.getY())) {
401
            return N;
402
        } else
403
            if (ne.contains(p.getX(), p.getY())) {
404
                return NE;
405
            } else
406
                if (e.contains(p.getX(), p.getY())) {
407
                    return E;
408
                } else
409
                    if (se.contains(p.getX(), p.getY())) {
410
                        return SE;
411
                    } else
412
                        if (s.contains(p.getX(), p.getY())) {
413
                            return S;
414
                        } else
415
                            if (so.contains(p.getX(), p.getY())) {
416
                                return SO;
417
                            } else
418
                                if (o.contains(p.getX(), p.getY())) {
419
                                    return O;
420
                                } else
421
                                    if (no.contains(p.getX(), p.getY())) {
422
                                        return NO;
423
                                    } else
424
                                        if (getBoundingBox(null).contains(
425
                                            p.getX(), p.getY())) {
426
                                            return RECT;
427
                                        }
428

    
429
        return NOSELECT;
430
    }
431

    
432
    /**
433
     * Devuelve el Cursor adecuado seg�n como est� contenido el punto, si es
434
     * para desplazamiento, o cambio de tama�o.
435
     * 
436
     * @param p
437
     *            punto a comprobar.
438
     * 
439
     * @return Cursor adecuado a la posici�n.
440
     */
441
    public Image getMapCursor(Point2D p) {
442
        int select = getContains(p);
443

    
444
        switch (select) {
445
        case (N):
446
            return iNResize;
447

    
448
        case (NE):
449
            return iNEResize;
450

    
451
        case (E):
452
            return iEResize;
453

    
454
        case (SE):
455
            return iSEResize;
456

    
457
        case (S):
458
            return iNResize;
459

    
460
        case (SO):
461
            return iNEResize;
462

    
463
        case (O):
464
            return iEResize;
465

    
466
        case (NO):
467
            return iSEResize;
468

    
469
        case (RECT):
470
            return iMove;
471
        }
472

    
473
        return null;
474
    }
475

    
476
    /**
477
     * Este m�todo se implementa en cada una de las fframe, ya que cada una se
478
     * dibuja de una forma diferente sobre el graphics. M�todo que dibuja
479
     * sobre el graphics que se le pasa como par�metro, seg�n la
480
     * transformada
481
     * afin que se debe de aplicar y el rect�ngulo que se debe de dibujar.
482
     * M�todo que dibuja sobre el graphics que se le pasa como par�metro,
483
     * seg�n la transformada afin que se debe de aplicar y el rect�ngulo que
484
     * se debe de dibujar.
485
     * 
486
     * @param g
487
     *            Graphics
488
     * @param at
489
     *            Transformada afin.
490
     * @param r
491
     *            rect�ngulo sobre el que hacer un clip.
492
     * @param imgBase
493
     *            DOCUMENT ME!
494
     */
495
    public abstract void draw(Graphics2D g, AffineTransform at, Rectangle2D r,
496
        BufferedImage imgBase);
497

    
498
    /**
499
     * Returns the bounding box (in pixels) of this FFrame, based on the provided
500
     * AffineTransform. If the AffineTransform is null, it returns the last
501
     * calculated bounding box.
502
     * 
503
     * @param at Affine transform to apply to the sheet coordinates to get the
504
     *                  bounding box in pixels.
505
     * @return Rectangle representing the bounding box (in pixels) of this
506
     * FFrame
507
     */
508
    public Rectangle2D.Double getBoundingBox(AffineTransform at) {
509
        if (at != null) {
510
            lastAT = (AffineTransform) at.clone();
511
        }
512
        return FLayoutUtilities.fromSheetRect(m_BoundBox, lastAT);
513
    }
514

    
515
    /**
516
     * Rellena con el rect�ngulo que se pasa como par�metro el boundBox(en
517
     * cent�metros) del fframe del cual con una transformaci�n se podr�
518
     * calcular el BoundingBox (en pixels).
519
     * 
520
     * @param r
521
     *            Rect�ngulo en cent�metros.
522
     */
523
    public void setBoundBox(Rectangle2D r) {
524
        if (r == null) {
525
            LOG.info("Warning: BBOX set to NULL in FFrame!");
526
            m_BoundBox = null;
527
        } else {
528
            m_BoundBox = new Rectangle2D.Double(r.getX(), r.getY(),
529
                r.getWidth(), r.getHeight());
530
        }
531
    }
532

    
533
    /**
534
     * Returns the bounding box in centimeters of this FFrame
535
     * Returns the rectangle that represents the FFrame in centimeters.
536
     * 
537
     * @return The bounding box of this FFrame, measured in centimeters.
538
     */
539
    public Rectangle2D.Double getBoundBox() {
540
        return m_BoundBox;
541
    }
542

    
543
    /**
544
     * Pasando como par�metro true, se toma como que esta seleccionado el
545
     * fframe y si es false como que esta sin seleccionar, de esta forma se
546
     * selecciona un fframe directamente sin comprobar si un punto esta
547
     * contenido en �l.
548
     * 
549
     * @param b
550
     *            true si se quiere seleccionar y false si se quiere
551
     *            deseleccionar.
552
     */
553
    public void setSelected(boolean b) {
554
        if (b) {
555
                doSetSelected(IFFrame.RECT);
556
        } else {
557
                doSetSelected(IFFrame.NOSELECT);
558
        }
559
    }
560
    
561
    protected void doSetSelected(int selectedStatus) {
562
            m_Selected = selectedStatus;
563
    }
564

    
565
    /**
566
     * Dibuja sobre el graphics el rect�ngulo del fframe en modo borrador.
567
     * 
568
     * @param g
569
     *            Graphics so bre el que dibujar.
570
     */
571
    public void drawDraft(Graphics2D g) {
572
        Rectangle2D r = getBoundingBox(null);
573

    
574
        g.setColor(Color.lightGray);
575
        g.fillRect((int) r.getX(), (int) r.getY(), (int) r.getWidth(),
576
            (int) r.getHeight());
577
        g.setColor(Color.black);
578
        g.drawRect((int) r.getX(), (int) r.getY(), (int) r.getWidth() - 1,
579
            (int) r.getHeight() - 1);
580
        int scale = (int) (r.getWidth() / 12);
581
        Font f = new Font("SansSerif", Font.PLAIN, scale);
582
        g.setFont(f);
583
        g.drawString(getName(),
584
            (int) (r.getCenterX() - ((getName().length() * scale) / 4)),
585
            (int) (r.getCenterY()));
586
    }
587

    
588
    /**
589
     * Rellena con el n�mero de FFrame.
590
     * 
591
     * @param i
592
     *            n�mero
593
     */
594
    public void setNum(int i) {
595
        num = i;
596
    }
597

    
598
    /**
599
     * Draws the FFrame rectangle on the provided Graphics2D, only showing the
600
     * FFrame name on an empty rectangle.
601
     * 
602
     * @param g The graphics to draw on
603
     */
604
    public void drawEmpty(Graphics2D g) {
605
        Rectangle2D r = getBoundingBox(null);
606
        g.setColor(Color.lightGray);
607
        g.fillRect((int) r.getX(), (int) r.getY(), (int) r.getWidth(),
608
            (int) r.getHeight());
609
        g.setColor(Color.darkGray);
610
        g.setStroke(new BasicStroke(2));
611
        g.drawRect((int) r.getX(), (int) r.getY(), (int) r.getWidth(),
612
            (int) r.getHeight());
613
        g.setColor(Color.black);
614

    
615
        int scale = (int) (r.getWidth() / 12);
616
        Font f = new Font("SansSerif", Font.PLAIN, scale);
617
        g.setFont(f);
618

    
619
        String s =
620
            this.getNameFFrame() + " " + PluginServices.getText(this, "vacia");
621

    
622
        g.drawString(s, (int) (r.getCenterX() - ((s.length() * scale) / 4)),
623
            (int) (r.getCenterY()));
624
    }
625

    
626
    /**
627
     * Devuelve true si el rect�ngulo primero es null o si es distinto de null
628
     * e intersecta.
629
     * 
630
     * @param rv
631
     *            Rect�ngulo
632
     * @param r
633
     *            Rect�ngulo
634
     * 
635
     * @return True si intersecta o es null.
636
     */
637
    public boolean intersects(Rectangle2D rv, Rectangle2D r) {
638
        return (((rv != null) && rv.intersects(r)) || (rv == null));
639
    }
640

    
641
    /**
642
     * Rellena el tag del FFrame.
643
     * 
644
     * @param s
645
     *            String que representa el valor a guardar en el tag.
646
     */
647
    public void setTag(String s) {
648
        tag = s;
649
    }
650

    
651
    /**
652
     * Devuelve el tag.
653
     * 
654
     * @return tag.
655
     */
656
    public String getTag() {
657
        return tag;
658
    }
659

    
660
    /**
661
     * Dibuja sobre el graphics que se pasa como par�metro el icono que
662
     * representa que contiene un tag.
663
     * 
664
     * @param g
665
     *            Graphics sobre el que dibujar el icono.
666
     */
667
    public void drawSymbolTag(Graphics2D g) {
668
        Rectangle2D rec = getBoundingBox(null);
669
        g.rotate(Math.toRadians(getRotation()), rec.getX()
670
            + (rec.getWidth() / 2), rec.getY() + (rec.getHeight() / 2));
671

    
672
        try {
673
            Image image =
674
                PluginServices.getIconTheme().get("symboltag-icon").getImage();
675
            g.drawImage(image, (int) rec.getX(), (int) rec.getCenterY(), 30,
676
                30, null);
677
        } catch (NullPointerException npe) {
678
        }
679

    
680
        g.rotate(Math.toRadians(-getRotation()), rec.getX()
681
            + (rec.getWidth() / 2), rec.getY() + (rec.getHeight() / 2));
682
    }
683

    
684
    /**
685
     * Rellenar la rotaci�n para aplicar al FFrame.
686
     * 
687
     * @param rotation
688
     *            rotaci�n que se quiere aplicar.
689
     */
690
    public void setRotation(double rotation) {
691
        m_rotation = rotation;
692
    }
693

    
694
    /**
695
     * Devuelve la rotaci�n del FFrame.
696
     * 
697
     * @return Rotaci�n del FFrame.
698
     */
699
    public double getRotation() {
700
        return m_rotation;
701
    }
702

    
703
    /**
704
     * Devuelve el nivel en el que se encuentra el FFrame.
705
     * 
706
     * @return nivel
707
     */
708
    public int getLevel() {
709
        return level;
710
    }
711

    
712
    /**
713
     * Inserta el nivel al que se encuentra el FFrame.
714
     * 
715
     * @param l
716
     *            entero que refleja el nivel del FFrame.
717
     */
718
    public void setLevel(int l) {
719
        level = l;
720
    }
721

    
722
    @Override
723
    public Object clone() throws CloneNotSupportedException {
724
        IFFrame frame = (IFFrame) super.clone();
725
        frame.setBoundBox(this.getBoundBox());
726
        return frame;
727
    }
728

    
729
    public void setFrameFactory(FrameFactory flf) {
730
        frameFactory = flf;
731
    }
732

    
733
    public FrameFactory getFrameFactory() {
734
        return frameFactory;
735
    }
736

    
737
    /**
738
     * Initilizes the static icons
739
     */
740
    public static void initializeIcons() {
741
        iNEResize =
742
            PluginServices.getIconTheme().get("neresize-icon").getImage();
743
        iEResize = PluginServices.getIconTheme().get("eresize-icon").getImage();
744
        iNResize = PluginServices.getIconTheme().get("nresize-icon").getImage();
745
        iMove = PluginServices.getIconTheme().get("graphic-move-icon").getImage();
746
        iSEResize =
747
            PluginServices.getIconTheme().get("sereresize-icon").getImage();
748
    }
749

    
750
    public static void registerPersistent() {
751
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
752
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
753
            DynStruct definition =
754
                manager.addDefinition(FFrame.class,
755
                    PERSISTENCE_DEFINITION_NAME,
756
                    "FFrame persistence definition", null, null);
757

    
758
            definition.addDynFieldObject(BOUNDINGBOX_FIELD)
759
                .setClassOfValue(Rectangle2D.class).setMandatory(true);
760
            definition.addDynFieldInt(SELECTED_FIELD).setMandatory(true);
761
            definition.addDynFieldString(TAG_FIELD).setMandatory(false);
762
            definition.addDynFieldDouble(ROTATION_FIELD).setMandatory(true);
763
            definition.addDynFieldInt(LEVEL_FIELD).setMandatory(true);
764
            definition.addDynFieldInt(NUM_FIELD).setMandatory(true);
765
            definition.addDynFieldObject(DOCUMENT_FIELD).setClassOfValue(LayoutDocument.class).setMandatory(false);
766
            definition.addDynFieldObject(LAYOUT_CONTEXT_FIELD).setClassOfValue(LayoutContext.class).setMandatory(false);
767
        }
768

    
769
        Attributes.registerPersistent();
770
        AbstractFFrameViewDependence.registerPersistent();
771
        FFrameBasic.registerPersistent();
772
        FFrameGraphics.registerPersistent();
773
        FFrameSymbol.registerPersistent();
774
        FFrameGrid.registerPersistent();
775
        FFrameGroup.registerPersistent();
776
        FFrameTable.registerPersistent();
777
        FFrameLegend.registerPersistent();
778
        FFramePicture.registerPersistent();
779
        FFrameNorth.registerPersistent();
780
        FFrameScaleBar.registerPersistent();
781
        FFrameText.registerPersistent();
782
        FFrameView.registerPersistent();
783
        FFrameOverView.registerPersistent();
784
    }
785

    
786
    public void loadFromState(PersistentState state)
787
        throws PersistenceException {
788
        m_BoundBox = (Rectangle2D.Double) state.get(BOUNDINGBOX_FIELD);
789
        m_Selected = state.getInt(SELECTED_FIELD);
790
        tag = state.getString(TAG_FIELD);
791
        m_rotation = state.getDouble(ROTATION_FIELD);
792
        level = state.getInt(LEVEL_FIELD);
793
        num = state.getInt(NUM_FIELD);
794
        if (state.hasValue(DOCUMENT_FIELD)) {
795
                setDocument((LayoutDocument)state.get(DOCUMENT_FIELD ));
796
        }
797
        if (state.hasValue(LAYOUT_CONTEXT_FIELD)) {
798
                setLayoutContext((LayoutContext) state.get(LAYOUT_CONTEXT_FIELD));
799
        }
800
    }
801

    
802
    public void saveToState(PersistentState state) throws PersistenceException {
803
        state.set(BOUNDINGBOX_FIELD, getBoundBox());
804
        state.set(SELECTED_FIELD, m_Selected);
805
        state.set(TAG_FIELD, getTag());
806
        state.set(ROTATION_FIELD, getRotation());
807
        state.set(LEVEL_FIELD, getLevel());
808
        state.set(NUM_FIELD, num);
809
        state.set(DOCUMENT_FIELD, getDocument());
810
        state.set(LAYOUT_CONTEXT_FIELD, getLayoutContext());
811
    }
812

    
813
    public void addObserver(Observer o) {
814
        observers.addObserver(o);        
815
    }
816

    
817
    public void deleteObserver(Observer o) {
818
      observers.deleteObserver(o);        
819
    }
820

    
821
    public void deleteObservers() {
822
       observers.deleteObservers();        
823
    }
824
    
825
    /*
826
     * (non-Javadoc)
827
     * @see org.gvsig.tools.dispose.Disposable#dispose()
828
     */
829
        public void dispose() {
830
                
831
        }
832
        
833
        /**
834
         * This method is called just before the FFrame is going to
835
         * be added to the Layout
836
         */
837
        protected void beforeAdded() {}
838
        
839
        /**
840
         * This method is called just before the FFrame is going to
841
         * be removed from the Layout
842
         */
843
        protected void beforeRemoved() {}
844
        
845
        /**
846
         * This method is called just after the FFrame has been
847
         * added to the Layout
848
         */
849
        protected void afterAdded() {}
850
        
851
        
852
        /**
853
         * This method is called just before the FFrame is going to
854
         * be removed from the Layout
855
         */
856
        protected void afterRemoved() {}
857
        
858
        public void update(Observable observable, Object notification) {
859
                if ((notification != null) && (notification instanceof FrameChangedNotificationImpl)){
860
                        FrameChangedNotificationImpl layoutNotification = (FrameChangedNotificationImpl)notification;
861
                        if (this.equals(layoutNotification.getFrame()) && FrameChangedNotificationImpl.FRAME_ADDED.equals(layoutNotification.getType())){
862
                                afterAdded();
863
                        }else if (this.equals(layoutNotification.getFrame()) && FrameChangedNotificationImpl.FRAME_ADDING.equals(layoutNotification.getType())){
864
                                beforeAdded();
865
                        }else if (this.equals(layoutNotification.getFrame()) && FrameChangedNotificationImpl.FRAME_REMOVING.equals(layoutNotification.getType())){
866
                                beforeRemoved();
867
                        }else if (this.equals(layoutNotification.getFrame()) && FrameChangedNotificationImpl.FRAME_REMOVED.equals(layoutNotification.getType())){
868
                                afterRemoved();
869
                        }
870
                }
871
        }
872

    
873
        public LayoutContext getLayoutContext() {
874
                return layoutContext;
875
        }
876

    
877
        public void setLayoutContext(LayoutContext layoutContext) {
878
                this.layoutContext = layoutContext;
879
        }
880

    
881
        public Document getDocument() {
882
                return document;
883
        }
884

    
885
        public void setDocument(Document document) {
886
                this.document = document;
887
        }
888
}