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 / FFrameView.java @ 141

History | View | Annotate | Download (39.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.Dimension;
27
import java.awt.Font;
28
import java.awt.Graphics;
29
import java.awt.Graphics2D;
30
import java.awt.Image;
31
import java.awt.Point;
32
import java.awt.Rectangle;
33
import java.awt.geom.AffineTransform;
34
import java.awt.geom.Point2D;
35
import java.awt.geom.Rectangle2D;
36
import java.awt.image.BufferedImage;
37

    
38
import javax.swing.SwingUtilities;
39

    
40
import org.cresques.cts.IProjection;
41
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
43
import org.gvsig.andami.PluginServices;
44
import org.gvsig.andami.messages.NotificationManager;
45
import org.gvsig.andami.ui.mdiFrame.NewStatusBar;
46
import org.gvsig.app.project.Project;
47
import org.gvsig.app.project.documents.layout.DefaultLayoutNotification;
48
import org.gvsig.app.project.documents.layout.FLayoutFunctions;
49
import org.gvsig.app.project.documents.layout.FLayoutUtilities;
50
import org.gvsig.app.project.documents.layout.LayoutNotification;
51
import org.gvsig.app.project.documents.view.DefaultViewDocument;
52
import org.gvsig.app.project.documents.view.ViewDocument;
53
import org.gvsig.compat.print.PrintAttributes;
54
import org.gvsig.fmap.dal.exception.ReadException;
55
import org.gvsig.fmap.geom.Geometry;
56
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
57
import org.gvsig.fmap.geom.GeometryLocator;
58
import org.gvsig.fmap.geom.GeometryManager;
59
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
60
import org.gvsig.fmap.geom.primitive.Envelope;
61
import org.gvsig.fmap.mapcontext.MapContext;
62
import org.gvsig.fmap.mapcontext.MapContextException;
63
import org.gvsig.fmap.mapcontext.ViewPort;
64
import org.gvsig.fmap.mapcontext.events.ColorEvent;
65
import org.gvsig.fmap.mapcontext.events.ExtentEvent;
66
import org.gvsig.fmap.mapcontext.events.ProjectionEvent;
67
import org.gvsig.fmap.mapcontext.events.listeners.ViewPortListener;
68
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
69
import org.gvsig.fmap.mapcontext.rendering.legend.events.listeners.LegendListener;
70
import org.gvsig.gui.beans.Messages;
71
import org.gvsig.tools.ToolsLocator;
72
import org.gvsig.tools.dynobject.DynStruct;
73
import org.gvsig.tools.persistence.PersistenceManager;
74
import org.gvsig.tools.persistence.PersistentState;
75
import org.gvsig.tools.persistence.exception.PersistenceException;
76

    
77
/**
78
 * FFrame para introducir una vista en el Layout.
79
 * 
80
 * @author Vicente Caballero Navarro
81
 */
82
public class FFrameView extends FFrame implements ViewPortListener,
83
    LegendListener, IFFrameUseProject, IFFrameUseFMap {
84

    
85
    public static final String PERSISTENCE_DEFINITION_NAME = "FFrameView";
86

    
87
    private static final String MODE_FIELD = "mode";
88
    private static final String TYPESCALE_FIELD = "typeScale";
89
    private static final String EXTENSION_FIELD = "extension";
90
    private static final String QUALITY_FIELD = "quality";
91
    private static final String BLINKED_FIELD = "bLinked";
92
    private static final String MAPUNITS_FIELD = "mapUnits";
93
    private static final String SCALE_FIELD = "scale";
94
    private static final String VIEW_FIELD = "view";
95
    private static final String ENVELOPE_FIELD = "envelope";
96
    private static final String SHOWGRID_FIELD = "showGrid";
97
    private static final String GRID_FIELD = "gridview";
98
    private static final String MAPCONTEXT_FIELD = "mapContext";
99

    
100
    private static final GeometryManager geomManager = GeometryLocator
101
        .getGeometryManager();
102
    private static final Logger logger = LoggerFactory
103
        .getLogger(FFrameView.class);
104
    public static final int PRESENTATION = 0;
105
    public static final int DRAFT = 1;
106
    protected int mode;
107
    protected int typeScale = AUTOMATICO;
108
    protected int extension = 0;
109
    protected int quality = PRESENTATION;
110
    protected boolean linked = true;
111
    protected ViewDocument viewDocument = null;
112
    protected MapContext mapContext = null;
113
    protected double mapScale = 0;
114
    protected int mapUnits = 1; // Meters.
115

    
116
    protected BufferedImage m_image = null;
117
    protected AffineTransform at = null;
118
    protected Project project = null;
119
    protected double scaleAnt;
120
    protected boolean refresh = false;
121
    protected Point origin;
122
    protected Point2D p1;
123
    protected Point2D p2;
124
    protected IFFrame grid;
125
    protected boolean showGrid = false;
126

    
127
    /**
128
     * Creates a new FFrameView object.
129
     */
130
    public FFrameView() {
131
        num++;
132
    }
133

    
134
    /**
135
     * Devuelve una descripci?n del FFrameView.
136
     * 
137
     * @return Descripci?n.
138
     */
139
    public String toString() {
140
        if (getView() == null) {
141
            return "FFrameView " + num + ": " + "Vacio";
142
        }
143

    
144
        return "FFrameView " + num + ": " + getView().getName();
145
    }
146

    
147
    /**
148
     * Rellena la escala de la vista que contiene el fframe.
149
     * 
150
     * @param d
151
     *            escala de la vista.
152
     */
153
    public void setScale(double d) {
154
        mapScale = d;
155
    }
156

    
157
    /**
158
     * Inserta el nuevo extent a la FFrameView.
159
     * 
160
     * @param r
161
     *            Rect?ngulo a ocupar por el FFrameView.
162
     */
163
    public void setNewEnvelope(Envelope r) {
164
        getMapContext().getViewPort().setEnvelope(r);
165
        refresh = true;
166
        mapScale =
167
            FLayoutUtilities.getScaleView(getMapContext().getViewPort(),
168
                getBoundBox().width, getBoundingBox(null).width);
169
        updateScaleCtrl();
170
    }
171
    
172
    /**
173
     * Calculates the resolution (measured on dots per inch, DPI) to be
174
     * considered to draw the FFrameView on screen. It is calculated by
175
     * dividing the width (in pixels) of the FFrame divided by the width
176
     * in inches of the paper.
177
     */
178
    protected double getDrawPaperDPI() {
179
            return (2.54*getBoundingBox(null).width)/getBoundBox().width;        
180
    }
181

    
182
    /**
183
     * Devuelve el FMap de la vista o una clonaci?n de este si se utiliza una
184
     * escala fija.
185
     * 
186
     * @return FMap.
187
     */
188
    public MapContext getMapContext() {
189
        return mapContext;
190
    }
191

    
192
    /**
193
     * Rellena la calidad que se quiere aplicar.
194
     * 
195
     * @param q
196
     *            entero que representa la calidad a aplicar.
197
     */
198
    public void setQuality(int q) {
199
        quality = q;
200
    }
201

    
202
    /**
203
     * Devuelve un entero que representa la calidad que est? seleccionada.
204
     * 
205
     * @return tipo de calidad selccionada.
206
     */
207
    public int getQuality() {
208
        return quality;
209
    }
210

    
211
    /**
212
     * Inserta el ProjectView de donde obtener las propiedades de la vista a
213
     * mostrar.
214
     * 
215
     * @param v
216
     *            Modelo de la vista.
217
     */
218
    public void setView(ViewDocument dvd) {
219
        
220
        viewDocument = dvd;
221
        MapContext mctxt = dvd.getMapContext();
222
        
223
        ViewPort vp = null;
224
        if (getMapContext() != null) {
225
            vp = getMapContext().getViewPort();
226
        }else{
227
            try {
228
                vp = (ViewPort) mctxt.getViewPort().clone();
229
            } catch (CloneNotSupportedException e1) {
230
                NotificationManager.addError("Excepci?n :", e1);
231
            }
232

    
233
        }
234
        vp.setImageSize(new Dimension((int) getBoundingBox(null).width,
235
            (int) getBoundingBox(null).height));
236

    
237
        if (linked){
238
            if (getTypeScale() == AUTOMATICO) {
239
                try {
240
                    mapContext =
241
                        mctxt.createNewFMap(
242
                            (ViewPort) mctxt.getViewPort().clone());
243
                } catch (CloneNotSupportedException e1) {
244
                    NotificationManager.addError("Excepci?n :", e1);
245
                }
246

    
247
                mapContext.getViewPort().setImageSize(
248
                    new Dimension((int) getBoundingBox(null).width,
249
                        (int) getBoundingBox(null).height));
250
                mctxt.getViewPort().addViewPortListener(this);
251
                mctxt.addLayerListener(this);
252
            }else{
253
                if (getTypeScale() == CONSTANTE) {
254
                    mapContext = mctxt.createNewFMap(vp);
255
                    vp.setEnvelope(getNewEnvelope(getScale()));
256
                    mctxt.getViewPort().addViewPortListener(this);
257
                    mctxt.addLayerListener(this);
258
                }else{
259
                    if (getTypeScale() == MANUAL) {
260
                        mapContext = mctxt.createNewFMap(vp);
261
                        vp.setEnvelope(getNewEnvelope(getScale()));
262
                        mctxt.getViewPort()
263
                            .addViewPortListener(this);
264
                        mctxt.addLayerListener(this);
265
                    }
266
                }
267
            }
268
        }else{
269
            if (!linked) {
270

    
271
                if (getTypeScale() == AUTOMATICO) {
272
                    mapContext = mctxt.cloneFMap();
273
                    // (v.getMapContext().getViewPort().cloneViewPort());
274
                    try {
275
                        mapContext.setViewPort((ViewPort) mctxt
276
                            .getViewPort().clone());
277
                    } catch (CloneNotSupportedException e1) {
278
                        NotificationManager.addError("Excepci?n :", e1);
279
                    }
280
                    mapContext.getViewPort().setImageSize(
281
                        new Dimension((int) getBoundingBox(null).width,
282
                            (int) getBoundingBox(null).height));
283
                    mctxt.getViewPort().addViewPortListener(this);
284
                }else{
285
                    if (getTypeScale() == CONSTANTE) {
286
                        mapContext = mctxt.cloneFMap();
287
                        vp.setEnvelope(getNewEnvelope(getScale()));
288
                        mapContext.setViewPort(vp);
289
                        mctxt.getViewPort().addViewPortListener(this);
290
                    }else{
291
                        if (getTypeScale() == MANUAL) {
292
                            mapContext = mctxt.cloneFMap();
293
                            vp.setEnvelope(getNewEnvelope(getScale()));
294
                            mapContext.setViewPort(vp);
295
                            mctxt.getViewPort()
296
                                .addViewPortListener(this);
297
                        }
298
                    }
299
                }               
300
            }
301
        }
302
    }
303

    
304
    /**
305
     * Devuelve el modelo de la vista.
306
     * 
307
     * @return Modelo de la vista.
308
     */
309
    public ViewDocument getView() {
310
        return viewDocument;
311
    }
312

    
313
    /**
314
     * Devuelve un Rect?ngulo que representa el extent de la vista que se
315
     * requiere a partir de una escala.
316
     * 
317
     * @param scale
318
     *            Escala a mostrar.
319
     * 
320
     * @return Rect?ngulo.
321
     */
322
    protected Envelope getNewEnvelope(long scale) {
323
        double hview = getBoundBox().getHeight();
324
        double wview = getBoundBox().getWidth();
325
        double hextent = (scale * hview) / 100.0;
326
        double wextent = (scale * wview) / 100.0;
327

    
328
        if (mapContext.getViewPort().getEnvelope() == null) {
329
            try {
330
                return geomManager.createEnvelope(0, 0, 0, 0, SUBTYPES.GEOM2D);
331
            } catch (CreateEnvelopeException e) {
332
                logger.error("Error creating the envelope", e);
333
                return null;
334
            }
335
        }
336
        double newx =
337
            mapContext.getViewPort().getEnvelope().getCenter(Geometry.DIMENSIONS.X)
338
                - (wextent / 2.0);
339
        double newy =
340
            mapContext.getViewPort().getEnvelope().getCenter(Geometry.DIMENSIONS.Y)
341
                - (hextent / 2.0);
342
        IProjection proj = mapContext.getViewPort().getProjection();
343
        Envelope r = null;
344
        try {
345
            r =
346
                geomManager.createEnvelope(newx, newy, newx + wextent, newy
347
                    + hextent, SUBTYPES.GEOM2D);
348
        } catch (CreateEnvelopeException e) {
349
            logger.error("Error creating the envelope", e);
350
        }
351
        if (!proj.isProjected()) {
352
            Rectangle2D auxR =
353
                new Rectangle2D.Double(newx, newy, wextent, hextent);
354
            Rectangle2D aux =
355
                mapContext.getViewPort().getProjection()
356
                    .getExtent(auxR, scale, wview, hview, 1, 100, 2.54);
357
            try {
358
                r =
359
                    geomManager.createEnvelope(aux.getX(), aux.getY(),
360
                        aux.getMaxX(), aux.getMaxY(), SUBTYPES.GEOM2D);
361
            } catch (CreateEnvelopeException e) {
362
                logger.error("Error creating the envelope", e);
363
            }
364
        }
365
        return r;
366
    }
367

    
368
    /**
369
     * Draws the FFrameView on the provided Graphics, according to the
370
     * provided affine transform and the visible rectangle.
371
     * 
372
     * @param g Graphics2D
373
     * @param at Affine transform to translate sheet coordinates (in cm)
374
     *                                 to screen coordinates (in pixels)
375
     * @param visibleLayoutDocRect visible rectangle
376
     * @param imgBase Image used to speed up the drawing process
377
     */
378
    public void draw(Graphics2D g, AffineTransform at, Rectangle2D visibleLayoutDocRect, BufferedImage imgBase) {
379
        Rectangle2D.Double fframeViewRect = getBoundingBox(at);  
380
        Rectangle originalClip = preDraw(g, fframeViewRect);    
381
        if (intersects(visibleLayoutDocRect, fframeViewRect)) {
382
            if (getMapContext() == null) {
383
                drawEmpty(g);
384
            } else {
385
                if (FLayoutUtilities.hasEditingLayers(getView())) {
386
                    
387
                    /*
388
                     * We are not drawing if any layer is in editing mode
389
                     */
390
                    drawMessage(g, Messages.getText(
391
                        "_Cannot_draw_view_if_layers_in_editing_mode"));
392
                    
393
                } else {
394
                    if (getQuality() == PRESENTATION) {
395
                        try {
396
                            drawPresentation(g, at, fframeViewRect, visibleLayoutDocRect, imgBase);
397
                        } catch (Exception exc) {
398
                            drawMessage(g, FLayoutFunctions.getLastMessage(exc));
399
                        }
400
                        
401
                    } else {
402
                        drawDraft(g);
403
                    }               
404
                }
405
            }
406
        }
407
        postDraw(g, fframeViewRect, visibleLayoutDocRect, imgBase, originalClip, at); 
408
        if (showGrid && grid != null) {           
409
            grid.draw(g, at, visibleLayoutDocRect, imgBase);
410
        }    
411
    }
412
    
413
    private void drawMessage(Graphics2D g, String msg) {
414
        
415
        Rectangle2D r = getBoundingBox(null);
416
        g.setColor(Color.lightGray);
417
        g.fillRect((int) r.getX(), (int) r.getY(), (int) r.getWidth(),
418
            (int) r.getHeight());
419
        g.setColor(Color.darkGray);
420
        g.setStroke(new BasicStroke(2));
421
        g.drawRect((int) r.getX(), (int) r.getY(), (int) r.getWidth(),
422
            (int) r.getHeight());
423
        g.setColor(Color.black);
424

    
425
        int scale = (int) (r.getWidth() / 24);
426
        Font f = new Font("SansSerif", Font.PLAIN, scale);
427
        g.setFont(f);
428

    
429
        g.drawString(msg, (int) (r.getCenterX() - ((msg.length() * scale) / 4)),
430
            (int) (r.getCenterY()));        
431
    }
432

    
433
    protected void drawPresentation(
434
        Graphics2D g,
435
        AffineTransform affineTransform,
436
        Rectangle2D.Double fframeViewRect,
437
        Rectangle2D visibleLayoutDocRect,
438
        BufferedImage imgBase) throws Exception {
439
        
440
        Point mapOrigin = new Point((int)visibleLayoutDocRect.getMinX(), (int)visibleLayoutDocRect.getMaxY());
441

    
442
        ViewPort viewPort = this.getMapContext().getViewPort();
443
        Color theBackColor = viewPort.getBackColor();
444
            int drawWidth = (int)fframeViewRect.width;
445
            int drawHeight = (int)fframeViewRect.height;
446

    
447
        //If the image has to be created...
448
        if (!(origin != null
449
            && origin.equals(mapOrigin)
450
            && affineTransform.getScaleX() == scaleAnt
451
            && m_image != null
452
            && !refresh
453
            && !(fframeViewRect.getWidth() > visibleLayoutDocRect.getWidth() || fframeViewRect.getHeight() > visibleLayoutDocRect.getHeight()))) {
454

    
455
                viewPort.setImageSize(new Dimension(drawWidth, drawHeight));
456
                viewPort.refreshExtent(); // comprobar si es necesario; el setImageSize ya calcula la nueva AT, pero no lanza el evento extentChanged
457
            viewPort.setDPI(getDrawPaperDPI());
458
            m_image =
459
                    new BufferedImage(
460
                                    drawWidth,
461
                                    drawHeight,
462
                                    BufferedImage.TYPE_INT_ARGB);
463

    
464
                Graphics2D gimg = (Graphics2D) m_image.createGraphics();
465
                
466

    
467
                getMapContext().draw(m_image, gimg, getScale());
468
                gimg.dispose();
469
            refresh = false;    
470
        } 
471

    
472
        //Draw the created image
473
        if (theBackColor != null) {
474
            g.setColor(theBackColor);
475
            g.fillRect((int) fframeViewRect.x, (int) fframeViewRect.y,
476
                            (int)fframeViewRect.width,
477
                            (int)fframeViewRect.height);
478
        }
479
        g.drawImage(m_image, 
480
                        (int) fframeViewRect.x,
481
                        (int) fframeViewRect.y,
482
                        null);
483
        
484
        scaleAnt = affineTransform.getScaleX();
485
        origin = mapOrigin;             
486
    }
487

    
488
    protected Rectangle preDraw(Graphics2D g, Rectangle2D.Double fframeViewRect){
489
        Rectangle originalClip = null;
490
        if (g.getClipBounds() != null) {
491
            originalClip = (Rectangle) g.getClipBounds().clone();
492
        }
493
        if (getRotation() != 0) {
494
            g.rotate(Math.toRadians(getRotation()), fframeViewRect.getCenterX(), fframeViewRect.getCenterY()
495
                + (fframeViewRect.height / 2));
496
        }       
497
        g.clipRect((int) fframeViewRect.getMinX(), (int) fframeViewRect.getMinY(),
498
            (int) fframeViewRect.getWidth(), (int) fframeViewRect.getHeight());
499
        return originalClip;
500
    }
501
    
502
    protected void postDraw(Graphics2D g, Rectangle2D.Double fframeViewRect, Rectangle2D visibleLayoutDocRect, BufferedImage imgBase, 
503
        Rectangle originalClip, AffineTransform at){
504
        if (getRotation() != 0) {
505
            g.rotate(Math.toRadians(-getRotation()), fframeViewRect.getCenterX(), fframeViewRect.getCenterY());
506
        }
507
        if (getMapContext() != null) {
508
            setATMap(getMapContext().getViewPort().getAffineTransform());
509
        }
510
        if (originalClip != null) {
511
            g.setClip(originalClip.x, originalClip.y, originalClip.width, originalClip.height);
512
        }            
513
    }
514

    
515
    private Envelope calculateEnvelope() {
516
        if (p1 == null || p2 == null) {
517
            try {
518
                return geomManager.createEnvelope(0, 0, 0, 0, SUBTYPES.GEOM2D);
519
            } catch (CreateEnvelopeException e) {
520
                logger.error("Error creating the envelope", e);
521
            }
522
        }
523
        Envelope r = null;
524
        try {
525
            r =
526
                geomManager.createEnvelope(p1.getX(), p1.getY(), p2.getX(),
527
                    p2.getY(), SUBTYPES.GEOM2D);
528
        } catch (CreateEnvelopeException e) {
529
            logger.error("Error creating the envelope", e);
530
        }
531
        return r;
532
    }
533

    
534
    public void print(Graphics2D g, AffineTransform at, Geometry geom,
535
        PrintAttributes printAttributes) {
536
        Rectangle2D.Double rectangleLayout = getBoundingBox(at);  
537
        
538
        Rectangle originalClip = preDraw(g, rectangleLayout);
539
        print(g, at, printAttributes);
540
        postDraw(g, rectangleLayout, null, null, originalClip, at);
541
        if (showGrid && grid != null) {
542
            grid.print(g, at, geom, printAttributes);
543
        }    
544
    }
545

    
546
    protected void print(Graphics2D g, AffineTransform at, PrintAttributes printAttributes) {
547
        Rectangle2D.Double layoutRectangle = getBoundingBox(at);
548
              
549
        ViewPort viewPort = this.getMapContext().getViewPort();
550
        
551
        Point2D old_offset = viewPort.getOffset();
552
        Dimension old_imgsize = viewPort.getImageSize();
553
        
554
        viewPort.setOffset(new Point2D.Double(layoutRectangle.x, layoutRectangle.y));
555
        viewPort.setImageSize(new Dimension((int) layoutRectangle.width, (int) layoutRectangle.height));
556

    
557
        //Draw the backgroung color of the map
558
        Color theBackColor = viewPort.getBackColor();
559
        if (theBackColor != null) {
560
            g.setColor(theBackColor);
561
            g.fillRect((int) layoutRectangle.x, (int) layoutRectangle.y, viewPort
562
                    .getImageWidth(), viewPort
563
                    .getImageHeight());
564
        }        
565
        
566
        //Print the map
567
        try {
568
            this.getMapContext().print(g, getScale(), printAttributes);
569
        } catch (ReadException e) {
570
            NotificationManager.addError(e.getMessage(), e);
571
        } catch (MapContextException e) {
572
            NotificationManager.addError(e.getMessage(), e);
573
        }      
574
        
575
        // Restore offset, imgsize
576
        viewPort.setOffset(old_offset);
577
        viewPort.setImageSize(old_imgsize);
578
    }
579

    
580
    /**
581
     * Rellena la unidad de medida en la que est? la vista.
582
     * 
583
     * @param i
584
     *            entero que representa la unidad de medida de la vista.
585
     */
586
    public void setMapUnits(int i) {
587
        mapUnits = i;
588
    }
589

    
590
    /**
591
     * Obtiene la unidad de medida en la que est? la vista.
592
     * 
593
     * @return Unidad de medida.
594
     */
595
    public int getMapUnits() {
596
        return mapUnits;
597
    }
598

    
599
    /**
600
     * Devuelve la escala seg?n el tipo de escala que se haya seleccionado al
601
     * a?adida la vista.
602
     * 
603
     * @return escala.
604
     */
605
    public long getScale() {
606
        /*
607
         * if (m_bLinked){
608
         * return getScaleView1(METROS);
609
         * }
610
         */
611
        if (getMapContext() == null) {
612
            return 0;
613
        }
614
        if (getTypeScale() == AUTOMATICO) {
615
            return FLayoutUtilities.getScaleView(getMapContext().getViewPort(),
616
                getBoundBox().width, getBoundingBox(null).width);
617
        } else
618
            if (getTypeScale() == CONSTANTE) {
619
                return (long) mapScale;
620
            } else
621
                if (getTypeScale() == MANUAL) {
622
                    return (long) mapScale;
623
                }
624

    
625
        return (long) mapScale;
626
    }
627

    
628
    /**
629
     * Seleccionar si la vista esta relacionada o no con la original.
630
     * 
631
     * @param b
632
     *            true si est? ligada y false si no lo est?.
633
     */
634
    public void setLinked(boolean b) {
635
        linked = b;
636
    }
637

    
638
    /**
639
     * Devuelve si est? ligada o no el FFrameView con la vista.
640
     * 
641
     * @return True si la vista est? ligada.
642
     */
643
    public boolean getLinked() {
644
        return linked;
645
    }
646

    
647
    /**
648
     * Devuelve la opci?n seleccionada:Rellenar marco de la vista o recorte a
649
     * la vista.
650
     * 
651
     * @return entero que representa la opci?n elegida.
652
     */
653
    public int getExtension() {
654
        return extension;
655
    }
656

    
657
    /**
658
     * Devuelve el tipo de escala que est? seleccionada AUTOMATICO,CONSTANTE o
659
     * MANUAL.
660
     * 
661
     * @return entero que representa el tipo seleccionado.
662
     */
663
    public int getTypeScale() {
664
        return typeScale;
665
    }
666

    
667
    /**
668
     * Rellenar si se quiere:Rellenar marco de la vista o recorte a la vista.
669
     * 
670
     * @param i
671
     *            entero que representa la opci?n elegida.
672
     */
673
    public void setExtension(int i) {
674
        extension = i;
675
    }
676

    
677
    /**
678
     * Rellenar el tipo de escala que se desea.
679
     * 
680
     * @param i
681
     *            entero que representa el tipo de escala.
682
     */
683
    public void setTypeScale(int i) {
684
        typeScale = i;
685
    }
686

    
687
    /**
688
     * Inserta la imagen para repintar el FFrameView.
689
     * 
690
     * @param bi
691
     *            Imagen para repintar.
692
     */
693
    public void setBufferedImage(BufferedImage bi) {
694
        m_image = bi;
695
    }
696

    
697
    /**
698
     * Devuelve la imagen para repintar.
699
     * 
700
     * @return Imagen para repintar.
701
     */
702
    public BufferedImage getBufferedImage() {
703
        return m_image;
704
    }
705

    
706
    /**
707
     * Devuelve la MAtriz de transformaci?n utilizada por la FFrameView.
708
     * 
709
     * @return MAtriz de transformaci?n.
710
     */
711
    public AffineTransform getATMap() {
712
        return at;
713
    }
714

    
715
    /**
716
     * Inserta la matriz de transformaci?n.
717
     * 
718
     * @param transform
719
     *            Matriz de transformaci?n.
720
     */
721
    public void setATMap(AffineTransform transform) {
722
        at = transform;
723
    }
724

    
725
    /**
726
     * Inserta el proyecto.
727
     * 
728
     * @param p
729
     *            Proyecto.
730
     */
731
    public void setProject(Project p) {
732
        project = p;
733
    }
734

    
735
    /**
736
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#getNameFFrame()
737
     */
738
    public String getNameFFrame() {
739
        return PluginServices.getText(this, "Vista") + num;
740
    }
741

    
742
    public String getName() {
743
        return PERSISTENCE_DEFINITION_NAME;
744
    }
745

    
746
    /**
747
     * @see com.iver.cit.gvsig.fmap.ExtentListener#extentChanged(org.gvsig.fmap.mapcontext.events.ExtentEvent)
748
     */
749
    public void extentChanged(ExtentEvent e) {
750
        if (linked){
751
            if (getTypeScale() == AUTOMATICO) {
752
                mapContext.getViewPort().setEnvelope(e.getNewExtent());
753
//                observers.notifyObservers(this, 
754
//                    new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));      
755
                observers.notifyObservers(this, 
756
                        new DefaultLayoutNotification(LayoutNotification.LAYOUT_REFRESH));
757
            } else
758
                if (getTypeScale() == MANUAL) {
759
                    Envelope oldExtent = mapContext.getViewPort().getEnvelope();
760
                    Envelope newExtent = e.getNewExtent();
761
                    double xDif = newExtent.getCenter(0) - oldExtent.getCenter(0);
762
                    double yDif = newExtent.getCenter(1) - oldExtent.getCenter(1);
763
                    try {
764
                        mapContext.getViewPort().setEnvelope(
765
                            geomManager.createEnvelope(oldExtent.getMinimum(0)
766
                                + xDif, oldExtent.getMinimum(1) + yDif,
767
                                oldExtent.getMaximum(0) + xDif,
768
                                oldExtent.getMaximum(1) + yDif, SUBTYPES.GEOM2D));
769
                    } catch (CreateEnvelopeException e1) {
770
                        e1.printStackTrace();
771
                    }
772
                   
773
                    observers.notifyObservers(this, 
774
                        new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));           
775
                  
776
                }
777
            refresh = true;
778
        }
779
        updateScaleCtrl();
780
    }
781

    
782
    /**
783
     * @see org.gvsig.fmap.mapcontext.events.listeners.ViewPortListener#backColorChanged(org.gvsig.fmap.mapcontext.events.ColorEvent)
784
     */
785
    public void backColorChanged(ColorEvent e) {
786
        if (getLinked()) {
787
            mapContext.getViewPort().setBackColor(e.getNewColor());
788
            observers.notifyObservers(this, 
789
                new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));          
790
        }
791
    }
792

    
793
    /**
794
     * @see org.gvsig.fmap.mapcontext.events.listeners.ViewPortListener#projectionChanged(org.gvsig.fmap.mapcontext.events.ProjectionEvent)
795
     */
796
    public void projectionChanged(ProjectionEvent e) {
797
        if (getTypeScale() == AUTOMATICO) {
798
            mapContext.getViewPort().setProjection(e.getNewProjection());
799
            observers.notifyObservers(this, 
800
                new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));      
801
        }
802
    }
803

    
804
    /**
805
     * DOCUMENT ME!
806
     * 
807
     * @param e
808
     *            DOCUMENT ME!
809
     */
810
    public void legendChanged(final LegendChangedEvent e) {
811
        if (!SwingUtilities.isEventDispatchThread()) {
812
            SwingUtilities.invokeLater(new Runnable() {
813

    
814
                public void run() {
815
                    legendChanged(e);
816
                }
817
            });
818
            return;
819
        }
820
        if (getLinked()) {
821
            observers.notifyObservers(this, 
822
                new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));      
823
            refresh = true;
824
        }
825
    }
826

    
827
    /**
828
     * DOCUMENT ME!
829
     * 
830
     * @param arg0
831
     *            DOCUMENT ME!
832
     * 
833
     * @return DOCUMENT ME!
834
     */
835
    public boolean compare(Object arg0) {
836
        if (!(arg0 instanceof FFrameView)) {
837
            return false;
838
        }
839

    
840
        if (!this.getName().equals(((FFrameView) arg0).getName())) {
841
            return false;
842
        }
843

    
844
        if (Math.abs(this.getBoundBox().getWidth()
845
            - (((FFrameView) arg0).getBoundBox().getWidth())) > 0.05) {
846
            return false;
847
        }
848
        if (Math.abs(this.getBoundBox().getHeight()
849
            - (((FFrameView) arg0).getBoundBox().getHeight())) > 0.05) {
850
            return false;
851
        }
852

    
853
        if (!this.toString().equals(((FFrameView) arg0).toString())) {
854
            return false;
855
        }
856

    
857
        if (this.getMapContext() != null
858
            && !this.getMapContext()
859
                .equals(((FFrameView) arg0).getMapContext())) {
860
            return false;
861
        }
862

    
863
        if (this.getRotation() != ((FFrameView) arg0).getRotation()) {
864
            return false;
865
        }
866
        return true;
867
    }
868

    
869
    /*
870
     * This was causing issues with the notifications
871
     * because different instances were considered the same
872
     * after cloning a frame (the frame is cloned for example
873
     * when the user changes size of frame)
874
     * 
875
    public boolean equals(Object arg0) {
876
        return this.compare(arg0);
877
    }
878
    */
879

    
880
    public void refresh() {
881
        if (viewDocument != null
882
            && (getTypeScale() == MANUAL || getTypeScale() == CONSTANTE)) {
883
            getMapContext().getViewPort().setEnvelope(
884
                getNewEnvelope(getScale()));
885
            updateScaleCtrl();
886
        }
887
        refresh = true;
888
    }
889
    
890
    public void updateScaleCtrl() {
891
            NewStatusBar statusbar = PluginServices.getMainFrame().getStatusBar();
892
            MapContext mapContext = this.getMapContext();
893
            statusbar.setMessage("units",
894
                            PluginServices.getText(this, mapContext.getDistanceName()));
895
            statusbar.setControlValue("layout-view-change-scale",
896
                            String.valueOf(getScale()));
897
            IProjection proj = mapContext.getViewPort().getProjection();
898
            if (proj != null) {
899
                    statusbar.setMessage("projection", proj.getAbrev());
900
            } else {
901
                    statusbar.setMessage("projection", "");
902
            }
903
    }
904

    
905
    public void fullExtent() throws ReadException {
906
        setNewEnvelope(getMapContext().getFullEnvelope());
907
    }
908

    
909
    public void setPointsToZoom(Point2D px1, Point2D px2) {
910
        p1 = px1;
911
        p2 = px2;
912
    }
913

    
914
    public void movePoints(Point2D px1, Point2D px2) {
915
        double difX = -px2.getX() + px1.getX();
916
        double difY = -px2.getY() + px1.getY();
917
        if (p1 != null) {
918
            p1.setLocation(p1.getX() + difX, p1.getY() + difY);
919
            p2.setLocation(p2.getX() + difX, p2.getY() + difY);
920
        }
921
    }
922

    
923
    /**
924
     * This method deals with places where this fframeview and the cloned
925
     * fframeview (frame) are registered as listeners. The goal should be
926
     * leaving the cloned instance (frame) as listener in the same way
927
     * that 'this' instance is doing.
928
     */
929
    protected void cloneActions(FFrameView frame) {
930
        if (viewDocument == null || viewDocument.getMapContext() == null) {
931
            return;
932
        }
933
        
934
        frame.setTypeScale(this.getTypeScale());
935
        frame.setLinked(linked);
936
        
937
        if (linked) {
938
            if (getTypeScale() == AUTOMATICO) {
939
                frame.viewDocument.getMapContext().getViewPort().addViewPortListener(frame);
940
                frame.viewDocument.getMapContext().addLayerListener(frame);
941
            } else
942
                if (getTypeScale() == CONSTANTE) {
943
                    frame.viewDocument.getMapContext().getViewPort().removeViewPortListener(frame);
944
                    frame.viewDocument.getMapContext().addLayerListener(frame);
945
                } else
946
                    if (getTypeScale() == MANUAL) {
947
                        frame.viewDocument.getMapContext().getViewPort().removeViewPortListener(frame);
948
                        frame.viewDocument.getMapContext().addLayerListener(frame);
949
                    }
950
        } else
951
            if (!linked) {
952
                if (getTypeScale() == AUTOMATICO) {
953
                    frame.viewDocument.getMapContext().getViewPort().addViewPortListener(frame);
954
                } else
955
                    if (getTypeScale() == CONSTANTE) {
956
                        frame.viewDocument.getMapContext().getViewPort().removeViewPortListener(frame);
957
                    } else
958
                        if (getTypeScale() == MANUAL) {
959
                            frame.viewDocument.getMapContext().getViewPort().removeViewPortListener(frame);
960
                        }
961
            }
962
        /*
963
        ((FFrameView) frame).viewDocument.getMapContext().removeLayerListener(
964
            (FFrameView) frame);
965
        ((FFrameView) frame).viewDocument.getMapContext().getViewPort()
966
            .removeViewPortListener((FFrameView) frame);
967
        */
968
    }
969

    
970
    public Object clone() throws CloneNotSupportedException {
971
        FFrameView frame = (FFrameView) super.clone();
972

    
973
        frame.setSelected(this.getSelected() != IFFrame.NOSELECT);
974

    
975
        if (grid != null) {
976
            FFrameGrid newGrid = (FFrameGrid) this.grid.clone();
977
            newGrid.setFFrameDependence(frame);
978
            frame.setGrid(newGrid);
979
        }
980
        cloneActions(frame);
981
        return frame;
982
    }
983

    
984
    public void setGrid(IFFrame grid) {
985
        this.grid = grid;
986
        this.grid.setRotation(this.getRotation());
987
    }
988

    
989
    public IFFrame getGrid() {
990
        return this.grid;
991
    }
992

    
993
    public void setRotation(double rotation) {
994
        super.setRotation(rotation);
995
        if (grid != null) {
996
            grid.setRotation(rotation);
997
        }
998
    }
999

    
1000
    public void showGrid(boolean b) {
1001
        showGrid = b;
1002
    }
1003

    
1004
    public boolean isShowGrid() {
1005
        return showGrid;
1006
    }
1007

    
1008
    public void refreshOriginalExtent() {
1009
        if (getTypeScale() == AUTOMATICO) {
1010
            viewDocument.getMapContext().getViewPort()
1011
                .setEnvelope(getMapContext().getViewPort().getEnvelope());
1012
            viewDocument.getMapContext().getViewPort().refreshExtent();
1013
        } else
1014
            if (getTypeScale() == MANUAL) {
1015
                Envelope oldExtent =
1016
                    viewDocument.getMapContext().getViewPort().getEnvelope();
1017
                Envelope newExtent =
1018
                    getMapContext().getViewPort().getEnvelope();
1019
                double xDif = newExtent.getCenter(0) - oldExtent.getCenter(0);
1020
                double yDif = newExtent.getCenter(1) - oldExtent.getCenter(1);
1021
                try {
1022
                    viewDocument.getMapContext()
1023
                        .getViewPort()
1024
                        .setEnvelope(
1025
                            geomManager.createEnvelope(oldExtent.getMinimum(0)
1026
                                + xDif, oldExtent.getMinimum(1) + yDif,
1027
                                oldExtent.getMaximum(0) + xDif,
1028
                                oldExtent.getMaximum(1) + yDif, SUBTYPES.GEOM2D));
1029
                } catch (CreateEnvelopeException e) {
1030
                    e.printStackTrace();
1031
                }
1032
                viewDocument.getMapContext().getViewPort().refreshExtent();
1033
            }
1034
    }
1035

    
1036
    public static void registerPersistent() {
1037
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
1038
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
1039
            DynStruct definition =
1040
                manager.addDefinition(FFrameView.class,
1041
                    PERSISTENCE_DEFINITION_NAME,
1042
                    "FFrameView persistence definition", null, null);
1043

    
1044
            definition.extend(manager
1045
                .getDefinition(FFrame.PERSISTENCE_DEFINITION_NAME));
1046

    
1047
            definition.addDynFieldInt(MODE_FIELD).setMandatory(true);
1048
            definition.addDynFieldInt(TYPESCALE_FIELD).setMandatory(true);
1049
            definition.addDynFieldInt(EXTENSION_FIELD).setMandatory(true);
1050
            definition.addDynFieldInt(QUALITY_FIELD).setMandatory(true);
1051
            definition.addDynFieldBoolean(BLINKED_FIELD).setMandatory(true);
1052
            definition.addDynFieldInt(MAPUNITS_FIELD).setMandatory(true);
1053
            definition.addDynFieldDouble(SCALE_FIELD).setMandatory(true);
1054
            definition.addDynFieldObject(VIEW_FIELD)
1055
                .setClassOfValue(ViewDocument.class).setMandatory(false);
1056
            definition.addDynFieldObject(ENVELOPE_FIELD)
1057
                .setClassOfValue(Envelope.class).setMandatory(false);
1058
            definition.addDynFieldBoolean(SHOWGRID_FIELD).setMandatory(true);
1059
            definition.addDynFieldObject(GRID_FIELD)
1060
                .setClassOfValue(IFFrame.class).setMandatory(false);
1061
            definition.addDynFieldObject(MAPCONTEXT_FIELD)
1062
                .setClassOfValue(MapContext.class).setMandatory(false);
1063
        }
1064
    }
1065

    
1066
    @Override
1067
    public void loadFromState(PersistentState state)
1068
        throws PersistenceException {
1069
        super.loadFromState(state);
1070
        mode = state.getInt(MODE_FIELD);
1071
        typeScale = state.getInt(TYPESCALE_FIELD);
1072
        extension = state.getInt(EXTENSION_FIELD);
1073
        quality = state.getInt(QUALITY_FIELD);
1074
        linked = state.getBoolean(BLINKED_FIELD);
1075
        mapUnits = state.getInt(MAPUNITS_FIELD);
1076
        mapScale = state.getDouble(SCALE_FIELD);
1077
        viewDocument = (ViewDocument) state.get(VIEW_FIELD);
1078

    
1079
        if (state.hasValue(MAPCONTEXT_FIELD)) {
1080
            mapContext = (MapContext) state.get(MAPCONTEXT_FIELD);
1081
            mapContext.getViewPort().setEnvelope(
1082
                (Envelope) state.get(ENVELOPE_FIELD));
1083
        }
1084

    
1085
        showGrid = state.getBoolean(SHOWGRID_FIELD);
1086
        grid = (IFFrame) state.get(GRID_FIELD);
1087
    }
1088

    
1089
    @Override
1090
    public void saveToState(PersistentState state) throws PersistenceException {
1091
        super.saveToState(state);
1092
        state.set(MODE_FIELD, mode);
1093
        state.set(TYPESCALE_FIELD, typeScale);
1094
        state.set(EXTENSION_FIELD, extension);
1095
        state.set(QUALITY_FIELD, quality);
1096
        state.set(BLINKED_FIELD, linked);
1097
        state.set(MAPUNITS_FIELD, mapUnits);
1098
        state.set(SCALE_FIELD, mapScale);
1099
        state.set(VIEW_FIELD, viewDocument);
1100

    
1101
        if (getMapContext() != null
1102
            && getMapContext().getViewPort().getEnvelope() != null) {
1103
            state.set(ENVELOPE_FIELD, getMapContext().getViewPort()
1104
                .getEnvelope());
1105
            state.set(MAPCONTEXT_FIELD, mapContext);
1106
        }
1107

    
1108
        state.set(SHOWGRID_FIELD, showGrid);
1109
        state.set(GRID_FIELD, grid);
1110
    }
1111
    
1112
    @Override
1113
    public void setBoundBox(Rectangle2D r) {      
1114
        super.setBoundBox(r);
1115
        refresh();
1116
    }   
1117

    
1118
    /**
1119
     * getRotation returns rotation of the frame
1120
     * getMapRotation returns rotation of the map
1121
     * 
1122
     * @return in degrees
1123
     */
1124
    public double getMapRotation() {
1125
        return 0;
1126
    }
1127
}