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 @ 142

History | View | Annotate | Download (35.3 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
import javax.swing.plaf.InternalFrameUI;
40

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

    
82
/**
83
 * FFrame para introducir una vista en el Layout.
84
 * 
85
 * @author Vicente Caballero Navarro
86
 */
87
public class FFrameView extends FFrame implements IFFrameUseProject, IFFrameUseFMap {
88

    
89
    public static final String PERSISTENCE_DEFINITION_NAME = "FFrameView";
90

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

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

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

    
129
        private boolean b_viewOriginatedUpdate = false;
130
        private boolean b_fframeOriginatedUpdate = false;
131
        private boolean b_validCache = false;
132
        protected ViewDocListener viewDocListener = new ViewDocListener();
133
        protected OwnMapContextListener ownMapContextListener = new OwnMapContextListener();
134
                
135

    
136
    /**
137
     * Creates a new FFrameView object.
138
     */
139
    public FFrameView() {
140
        num++;
141
    }
142

    
143
    /**
144
     * Devuelve una descripci?n del FFrameView.
145
     * 
146
     * @return Descripci?n.
147
     */
148
    public String toString() {
149
        if (getView() == null) {
150
            return "FFrameView " + num + ": " + "Vacio";
151
        }
152

    
153
        return "FFrameView " + num + ": " + getView().getName();
154
    }
155

    
156
    /**
157
     * Rellena la escala de la vista que contiene el fframe.
158
     * 
159
     * @param d
160
     *            escala de la vista.
161
     */
162
    public void setScale(double d) {
163
            if (getMapContext()!=null) {
164
                    getMapContext().setScaleView((long) d);
165
            }
166
    }
167

    
168
    /**
169
     * Inserta el nuevo extent a la FFrameView.
170
     * 
171
     * @param r
172
     *            Rect?ngulo a ocupar por el FFrameView.
173
     */
174
    public void setNewEnvelope(Envelope r) {
175
            getMapContext().getViewPort().setEnvelope(r);
176
            updateScaleCtrl();
177
    }
178
    
179
    /**
180
     * Calculates the resolution (measured on dots per inch, DPI) to be
181
     * considered to draw the FFrameView on screen. It is calculated by
182
     * dividing the width (in pixels) of the FFrame divided by the width
183
     * in inches of the paper.
184
     */
185
    protected double getDrawPaperDPI() {
186
            return (2.54*getBoundingBox(null).width)/getBoundBox().width;        
187
    }
188

    
189
    /**
190
     * Devuelve el FMap de la vista o una clonaci?n de este si se utiliza una
191
     * escala fija.
192
     * 
193
     * @return FMap.
194
     */
195
    public MapContext getMapContext() {
196
        return mapContext;
197
    }
198

    
199
    /**
200
     * Rellena la calidad que se quiere aplicar.
201
     * 
202
     * @param q
203
     *            entero que representa la calidad a aplicar.
204
     */
205
    public void setQuality(int q) {
206
        quality = q;
207
    }
208

    
209
    /**
210
     * Devuelve un entero que representa la calidad que est? seleccionada.
211
     * 
212
     * @return tipo de calidad selccionada.
213
     */
214
    public int getQuality() {
215
        return quality;
216
    }
217

    
218
    public void setViewMapContext(MapContext viewMapContext) {
219
            if (viewMapContext!=null) {
220
                    clearViewListeners(viewMapContext);
221
            }
222
            if (mapContext!=null) {
223
                    clearOwnListeners(mapContext);
224
            }
225
            try {
226
                    if (linked){
227
                            mapContext =
228
                                            viewMapContext.createNewFMap(
229
                                                            (ViewPort) viewMapContext.getViewPort().clone());
230
                    }
231
                    else {
232
                            mapContext = viewMapContext.cloneFMap();
233
                            mapContext.setViewPort((ViewPort) viewMapContext
234
                                            .getViewPort().clone());
235
                    }
236
                    ViewPort newViewPort = getMapContext().getViewPort();
237
                    newViewPort.setImageSize(new Dimension((int) getBoundingBox(null).width,
238
                                    (int) getBoundingBox(null).height));
239
                    newViewPort.setDPI(getDrawPaperDPI());
240
                    setListeners();
241
                    updateScaleCtrl();
242
            } catch (CloneNotSupportedException e1) {
243
                    NotificationManager.addError("Excepci?n :", e1);
244
            }
245

    
246
    }
247
    /**
248
     * Inserta el ProjectView de donde obtener las propiedades de la vista a
249
     * mostrar.
250
     * 
251
     * @param v
252
     *            Modelo de la vista.
253
     */
254
    public void setView(ViewDocument dvd) {
255
        viewDocument = dvd;
256
        if (dvd!=null) {
257
            setViewMapContext(dvd.getMapContext());
258
        }
259
    }
260

    
261
    /**
262
     * Devuelve el modelo de la vista.
263
     * 
264
     * @return Modelo de la vista.
265
     */
266
    public ViewDocument getView() {
267
        return viewDocument;
268
    }
269

    
270
    /**
271
     * Draws the FFrameView on the provided Graphics, according to the
272
     * provided affine transform and the visible rectangle.
273
     * 
274
     * @param g Graphics2D
275
     * @param at Affine transform to translate sheet coordinates (in cm)
276
     *                                 to screen coordinates (in pixels)
277
     * @param visibleLayoutDocRect visible rectangle
278
     * @param imgBase Image used to speed up the drawing process
279
     */
280
    public void draw(Graphics2D g, AffineTransform at, Rectangle2D visibleLayoutDocRect, BufferedImage imgBase) {
281
        Rectangle2D.Double fframeViewRect = getBoundingBox(at);  
282
        Rectangle originalClip = preDraw(g, fframeViewRect);    
283
        if (intersects(visibleLayoutDocRect, fframeViewRect)) {
284
            if (getMapContext() == null) {
285
                drawEmpty(g);
286
            } else {
287
                if (FLayoutUtilities.hasEditingLayers(getView())) {
288
                    
289
                    /*
290
                     * We are not drawing if any layer is in editing mode
291
                     */
292
                    drawMessage(g, Messages.getText(
293
                        "_Cannot_draw_view_if_layers_in_editing_mode"));
294
                    
295
                } else {
296
                    if (getQuality() == PRESENTATION) {
297
                        try {
298
                            drawPresentation(g, at, fframeViewRect, visibleLayoutDocRect, imgBase);
299
                        } catch (Exception exc) {
300
                            drawMessage(g, FLayoutFunctions.getLastMessage(exc));
301
                        }
302
                        
303
                    } else {
304
                        drawDraft(g);
305
                    }               
306
                }
307
            }
308
        }
309
        postDraw(g, fframeViewRect, visibleLayoutDocRect, imgBase, originalClip, at); 
310
        if (showGrid && grid != null) {           
311
            grid.draw(g, at, visibleLayoutDocRect, imgBase);
312
        }    
313
    }
314
    
315
    private void drawMessage(Graphics2D g, String msg) {
316
        
317
        Rectangle2D r = getBoundingBox(null);
318
        g.setColor(Color.lightGray);
319
        g.fillRect((int) r.getX(), (int) r.getY(), (int) r.getWidth(),
320
            (int) r.getHeight());
321
        g.setColor(Color.darkGray);
322
        g.setStroke(new BasicStroke(2));
323
        g.drawRect((int) r.getX(), (int) r.getY(), (int) r.getWidth(),
324
            (int) r.getHeight());
325
        g.setColor(Color.black);
326

    
327
        int scale = (int) (r.getWidth() / 24);
328
        Font f = new Font("SansSerif", Font.PLAIN, scale);
329
        g.setFont(f);
330

    
331
        g.drawString(msg, (int) (r.getCenterX() - ((msg.length() * scale) / 4)),
332
            (int) (r.getCenterY()));        
333
    }
334

    
335
    protected void drawPresentation(
336
        Graphics2D g,
337
        AffineTransform affineTransform,
338
        Rectangle2D.Double fframeViewRect,
339
        Rectangle2D visibleLayoutDocRect,
340
        BufferedImage imgBase) throws Exception {
341
        
342
        Point mapOrigin = new Point((int)visibleLayoutDocRect.getMinX(), (int)visibleLayoutDocRect.getMaxY());
343

    
344
        ViewPort viewPort = this.getMapContext().getViewPort();
345
        Color theBackColor = viewPort.getBackColor();
346
            int drawWidth = (int)fframeViewRect.width;
347
            int drawHeight = (int)fframeViewRect.height;
348
/*
349
 * TODO INVERTIR LA CONDICION
350
            if (origin == null ||
351
                            !origin.equals(mapOrigin) ||
352
                            affineTransform.getScaleX() != scaleAnt ||
353
                            m_image == null ||
354
                            !b_validCache ||
355
                            ) { 
356
            }
357
            */
358
        //If the image has to be created...
359
        if (!(origin != null
360
            && origin.equals(mapOrigin)
361
            && affineTransform.getScaleX() == scaleAnt
362
            && m_image != null
363
            && b_validCache
364
            && !(fframeViewRect.getWidth() > visibleLayoutDocRect.getWidth() || fframeViewRect.getHeight() > visibleLayoutDocRect.getHeight()))) {
365

    
366
                viewPort.setImageSize(new Dimension(drawWidth, drawHeight));
367
            viewPort.setDPI(getDrawPaperDPI());
368
            m_image =
369
                    new BufferedImage(
370
                                    drawWidth,
371
                                    drawHeight,
372
                                    BufferedImage.TYPE_INT_ARGB);
373

    
374
            Graphics2D gimg = (Graphics2D) m_image.createGraphics();
375
            getMapContext().draw(m_image, gimg, getScale());
376
            gimg.dispose();
377
            b_validCache = true;
378
        } 
379

    
380
        //Draw the created image
381
        if (theBackColor != null) {
382
            g.setColor(theBackColor);
383
            g.fillRect((int) fframeViewRect.x, (int) fframeViewRect.y,
384
                            (int)fframeViewRect.width,
385
                            (int)fframeViewRect.height);
386
        }
387
        g.drawImage(m_image, 
388
                        (int) fframeViewRect.x,
389
                        (int) fframeViewRect.y,
390
                        null);
391
        
392
        scaleAnt = affineTransform.getScaleX();
393
        origin = mapOrigin;             
394
    }
395

    
396
    protected Rectangle preDraw(Graphics2D g, Rectangle2D.Double fframeViewRect){
397
        Rectangle originalClip = null;
398
        if (g.getClipBounds() != null) {
399
            originalClip = (Rectangle) g.getClipBounds().clone();
400
        }
401
        if (getRotation() != 0) {
402
            g.rotate(Math.toRadians(getRotation()), fframeViewRect.getCenterX(), fframeViewRect.getCenterY()
403
                + (fframeViewRect.height / 2));
404
        }       
405
        g.clipRect((int) fframeViewRect.getMinX(), (int) fframeViewRect.getMinY(),
406
            (int) fframeViewRect.getWidth(), (int) fframeViewRect.getHeight());
407
        return originalClip;
408
    }
409
    
410
    protected void postDraw(Graphics2D g, Rectangle2D.Double fframeViewRect, Rectangle2D visibleLayoutDocRect, BufferedImage imgBase, 
411
        Rectangle originalClip, AffineTransform at){
412
        if (getRotation() != 0) {
413
            g.rotate(Math.toRadians(-getRotation()), fframeViewRect.getCenterX(), fframeViewRect.getCenterY());
414
        }
415
        if (getMapContext() != null) {
416
            setATMap(getMapContext().getViewPort().getAffineTransform());
417
        }
418
        if (originalClip != null) {
419
            g.setClip(originalClip.x, originalClip.y, originalClip.width, originalClip.height);
420
        }            
421
    }
422

    
423
    public void print(Graphics2D g, AffineTransform at, Geometry geom,
424
        PrintAttributes printAttributes) {
425
        Rectangle2D.Double rectangleLayout = getBoundingBox(at);  
426
        
427
        Rectangle originalClip = preDraw(g, rectangleLayout);
428
        print(g, at, printAttributes);
429
        postDraw(g, rectangleLayout, null, null, originalClip, at);
430
        if (showGrid && grid != null) {
431
            grid.print(g, at, geom, printAttributes);
432
        }    
433
    }
434

    
435
    protected void print(Graphics2D g, AffineTransform at, PrintAttributes printAttributes) {
436
        Rectangle2D.Double layoutRectangle = getBoundingBox(at);
437
        
438
        // FIXME: should we clone the mapcontext and viewport before printing ??
439
        // otherwise we will probably have unexpected results if the user modifies
440
        // the layout while printing
441
        ViewPort viewPort = this.getMapContext().getViewPort();
442
        
443
        Point2D old_offset = viewPort.getOffset();
444
        Dimension old_imgsize = viewPort.getImageSize();
445
        
446
        viewPort.setOffset(new Point2D.Double(layoutRectangle.x, layoutRectangle.y));
447
        viewPort.setImageSize(new Dimension((int) layoutRectangle.width, (int) layoutRectangle.height));
448

    
449
        //Draw the backgroung color of the map
450
        Color theBackColor = viewPort.getBackColor();
451
        if (theBackColor != null) {
452
            g.setColor(theBackColor);
453
            g.fillRect((int) layoutRectangle.x, (int) layoutRectangle.y, viewPort
454
                    .getImageWidth(), viewPort
455
                    .getImageHeight());
456
        }        
457
        
458
        //Print the map
459
        try {
460
            this.getMapContext().print(g, getScale(), printAttributes);
461
        } catch (ReadException e) {
462
            NotificationManager.addError(e.getMessage(), e);
463
        } catch (MapContextException e) {
464
            NotificationManager.addError(e.getMessage(), e);
465
        }      
466
        
467
        // Restore offset, imgsize
468
        viewPort.setOffset(old_offset);
469
        viewPort.setImageSize(old_imgsize);
470
    }
471

    
472
    /**
473
     * Rellena la unidad de medida en la que est? la vista.
474
     * 
475
     * @param i
476
     *            entero que representa la unidad de medida de la vista.
477
     */
478
    public void setMapUnits(int i) {
479
        mapUnits = i;
480
    }
481

    
482
    /**
483
     * Obtiene la unidad de medida en la que est? la vista.
484
     * 
485
     * @return Unidad de medida.
486
     */
487
    public int getMapUnits() {
488
        return mapUnits;
489
    }
490

    
491
    /**
492
     * Devuelve la escala seg?n el tipo de escala que se haya seleccionado al
493
     * a?adida la vista.
494
     * 
495
     * @return escala.
496
     */
497
    public long getScale() {
498
            return (long) getMapContext().getScaleView();
499
    }
500

    
501
    /**
502
     * Seleccionar si la vista esta relacionada o no con la original.
503
     * 
504
     * @param b
505
     *            true si est? ligada y false si no lo est?.
506
     */
507
    public void setLinked(boolean b) {
508
        linked = b;
509
        resetListeners();
510
    }
511

    
512
    /**
513
     * Devuelve si est? ligada o no el FFrameView con la vista.
514
     * 
515
     * @return True si la vista est? ligada.
516
     */
517
    public boolean getLinked() {
518
        return linked;
519
    }
520

    
521
    /**
522
     * Devuelve el tipo de escala que est? seleccionada AUTOMATICO o
523
     * MANUAL.
524
     * 
525
     * @return entero que representa el tipo seleccionado.
526
     */
527
    public int getTypeScale() {
528
        return typeScale;
529
    }
530

    
531
    /**
532
     * Rellenar el tipo de escala que se desea.
533
     * 
534
     * @param i
535
     *            entero que representa el tipo de escala.
536
     */
537
    public void setTypeScale(int i) {
538
        typeScale = i;
539
        resetListeners();
540
    }
541

    
542
    /**
543
     * Inserta la imagen para repintar el FFrameView.
544
     * 
545
     * @param bi
546
     *            Imagen para repintar.
547
     */
548
    public void setBufferedImage(BufferedImage bi) {
549
        m_image = bi;
550
    }
551

    
552
    /**
553
     * Devuelve la imagen para repintar.
554
     * 
555
     * @return Imagen para repintar.
556
     */
557
    public BufferedImage getBufferedImage() {
558
        return m_image;
559
    }
560

    
561
    /**
562
     * Devuelve la MAtriz de transformaci?n utilizada por la FFrameView.
563
     * 
564
     * @return MAtriz de transformaci?n.
565
     */
566
    public AffineTransform getATMap() {
567
        return at;
568
    }
569

    
570
    /**
571
     * Inserta la matriz de transformaci?n.
572
     * 
573
     * @param transform
574
     *            Matriz de transformaci?n.
575
     */
576
    public void setATMap(AffineTransform transform) {
577
        at = transform;
578
    }
579

    
580
    /**
581
     * Inserta el proyecto.
582
     * 
583
     * @param p
584
     *            Proyecto.
585
     */
586
    public void setProject(Project p) {
587
        project = p;
588
    }
589

    
590
    /**
591
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#getNameFFrame()
592
     */
593
    public String getNameFFrame() {
594
        return PluginServices.getText(this, "Vista") + num;
595
    }
596

    
597
    public String getName() {
598
        return PERSISTENCE_DEFINITION_NAME;
599
    }
600

    
601
    /**
602
     * DOCUMENT ME!
603
     * 
604
     * @param arg0
605
     *            DOCUMENT ME!
606
     * 
607
     * @return DOCUMENT ME!
608
     */
609
    public boolean compare(Object arg0) {
610
        if (!(arg0 instanceof FFrameView)) {
611
            return false;
612
        }
613

    
614
        if (!this.getName().equals(((FFrameView) arg0).getName())) {
615
            return false;
616
        }
617

    
618
        if (Math.abs(this.getBoundBox().getWidth()
619
            - (((FFrameView) arg0).getBoundBox().getWidth())) > 0.05) {
620
            return false;
621
        }
622
        if (Math.abs(this.getBoundBox().getHeight()
623
            - (((FFrameView) arg0).getBoundBox().getHeight())) > 0.05) {
624
            return false;
625
        }
626

    
627
        if (!this.toString().equals(((FFrameView) arg0).toString())) {
628
            return false;
629
        }
630

    
631
        if (this.getMapContext() != null
632
            && !this.getMapContext()
633
                .equals(((FFrameView) arg0).getMapContext())) {
634
            return false;
635
        }
636

    
637
        if (this.getRotation() != ((FFrameView) arg0).getRotation()) {
638
            return false;
639
        }
640
        return true;
641
    }
642
    
643
    public void updateScaleCtrl() {
644
            NewStatusBar statusbar = PluginServices.getMainFrame().getStatusBar();
645
            MapContext mapContext = this.getMapContext();
646
            statusbar.setMessage("units",
647
                            PluginServices.getText(this, mapContext.getDistanceName()));
648
            statusbar.setControlValue("layout-view-change-scale",
649
                            String.valueOf(getMapContext().getScaleView()));
650
            IProjection proj = mapContext.getViewPort().getProjection();
651
            if (proj != null) {
652
                    statusbar.setMessage("projection", proj.getAbrev());
653
            } else {
654
                    statusbar.setMessage("projection", "");
655
            }
656
    }
657

    
658
    public void fullExtent() throws ReadException {
659
        setNewEnvelope(getMapContext().getFullEnvelope());
660
    }
661

    
662
    public void setPointsToZoom(Point2D px1, Point2D px2) {
663
        p1 = px1;
664
        p2 = px2;
665
    }
666

    
667
    public void movePoints(Point2D px1, Point2D px2) {
668
        double difX = -px2.getX() + px1.getX();
669
        double difY = -px2.getY() + px1.getY();
670
        if (p1 != null) {
671
            p1.setLocation(p1.getX() + difX, p1.getY() + difY);
672
            p2.setLocation(p2.getX() + difX, p2.getY() + difY);
673
        }
674
    }
675

    
676
    /**
677
     * This method deals with places where this fframeview and the cloned
678
     * fframeview (frame) are registered as listeners. The goal should be
679
     * leaving the cloned instance (frame) as listener in the same way
680
     * that 'this' instance is doing.
681
     */
682
    protected void cloneActions(FFrameView frame) {
683
    }
684

    
685
    public Object clone() throws CloneNotSupportedException {
686
        FFrameView frame = (FFrameView) super.clone();
687
        frame.setSelected(this.isSelected());
688
        frame.setTypeScale(this.getTypeScale());
689
        frame.setLinked(linked);
690
        frame.setView(this.getView());
691

    
692
        if (grid != null) {
693
            FFrameGrid newGrid = (FFrameGrid) this.grid.clone();
694
            newGrid.setFFrameDependence(frame);
695
            frame.setGrid(newGrid);
696
        }
697
        cloneActions(frame);
698
        return frame;
699
    }
700

    
701
    public void setGrid(IFFrame grid) {
702
        this.grid = grid;
703
        this.grid.setRotation(this.getRotation());
704
    }
705

    
706
    public IFFrame getGrid() {
707
        return this.grid;
708
    }
709

    
710
    public void setRotation(double rotation) {
711
        super.setRotation(rotation);
712
        if (grid != null) {
713
            grid.setRotation(rotation);
714
        }
715
    }
716

    
717
    public void showGrid(boolean b) {
718
        showGrid = b;
719
    }
720

    
721
    public boolean isShowGrid() {
722
        return showGrid;
723
    }
724

    
725
    public void refreshOriginalExtent() {
726
            /*
727
        if (getTypeScale() == AUTOMATICO) {
728
            viewDocument.getMapContext().getViewPort()
729
                .setEnvelope(getMapContext().getViewPort().getEnvelope());
730
            viewDocument.getMapContext().getViewPort().refreshExtent();
731
        } else
732
            if (getTypeScale() == MANUAL) {
733
                Envelope oldExtent =
734
                    viewDocument.getMapContext().getViewPort().getEnvelope();
735
                Envelope newExtent =
736
                    getMapContext().getViewPort().getEnvelope();
737
                double xDif = newExtent.getCenter(0) - oldExtent.getCenter(0);
738
                double yDif = newExtent.getCenter(1) - oldExtent.getCenter(1);
739
                try {
740
                    viewDocument.getMapContext()
741
                        .getViewPort()
742
                        .setEnvelope(
743
                            geomManager.createEnvelope(oldExtent.getMinimum(0)
744
                                + xDif, oldExtent.getMinimum(1) + yDif,
745
                                oldExtent.getMaximum(0) + xDif,
746
                                oldExtent.getMaximum(1) + yDif, SUBTYPES.GEOM2D));
747
                } catch (CreateEnvelopeException e) {
748
                    e.printStackTrace();
749
                }
750
                viewDocument.getMapContext().getViewPort().refreshExtent();
751
            }
752
            */
753
    }
754

    
755
    public static void registerPersistent() {
756
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
757
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
758
            DynStruct definition =
759
                manager.addDefinition(FFrameView.class,
760
                    PERSISTENCE_DEFINITION_NAME,
761
                    "FFrameView persistence definition", null, null);
762

    
763
            definition.extend(manager
764
                .getDefinition(FFrame.PERSISTENCE_DEFINITION_NAME));
765

    
766
            definition.addDynFieldInt(MODE_FIELD).setMandatory(true);
767
            definition.addDynFieldInt(TYPESCALE_FIELD).setMandatory(true);
768
            definition.addDynFieldInt(EXTENSION_FIELD).setMandatory(true);
769
            definition.addDynFieldInt(QUALITY_FIELD).setMandatory(true);
770
            definition.addDynFieldBoolean(BLINKED_FIELD).setMandatory(true);
771
            definition.addDynFieldInt(MAPUNITS_FIELD).setMandatory(true);
772
            definition.addDynFieldDouble(SCALE_FIELD).setMandatory(false);
773
            definition.addDynFieldObject(VIEW_FIELD)
774
                .setClassOfValue(ViewDocument.class).setMandatory(false);
775
            definition.addDynFieldObject(ENVELOPE_FIELD)
776
                .setClassOfValue(Envelope.class).setMandatory(false);
777
            definition.addDynFieldBoolean(SHOWGRID_FIELD).setMandatory(true);
778
            definition.addDynFieldObject(GRID_FIELD)
779
                .setClassOfValue(IFFrame.class).setMandatory(false);
780
            definition.addDynFieldObject(MAPCONTEXT_FIELD)
781
                .setClassOfValue(MapContext.class).setMandatory(false);
782
        }
783
    }
784

    
785
    @Override
786
    public void loadFromState(PersistentState state)
787
        throws PersistenceException {
788
        super.loadFromState(state);
789
        mode = state.getInt(MODE_FIELD);
790
        typeScale = state.getInt(TYPESCALE_FIELD);
791
        extension = state.getInt(EXTENSION_FIELD);
792
        quality = state.getInt(QUALITY_FIELD);
793
        linked = state.getBoolean(BLINKED_FIELD);
794
        mapUnits = state.getInt(MAPUNITS_FIELD);;
795
        viewDocument = (ViewDocument) state.get(VIEW_FIELD);
796

    
797
        if (state.hasValue(MAPCONTEXT_FIELD)) {
798
            mapContext = (MapContext) state.get(MAPCONTEXT_FIELD);
799
            double mapScale = state.getDouble(SCALE_FIELD);
800
            mapContext.setScaleView((long)mapScale); // FIXME: really needed?? probably already persisted on Mapcontext
801
            mapContext.getViewPort().setEnvelope(
802
                (Envelope) state.get(ENVELOPE_FIELD));
803
        }
804

    
805
        showGrid = state.getBoolean(SHOWGRID_FIELD);
806
        grid = (IFFrame) state.get(GRID_FIELD);
807
    }
808

    
809
    @Override
810
    public void saveToState(PersistentState state) throws PersistenceException {
811
        super.saveToState(state);
812
        state.set(MODE_FIELD, mode);
813
        state.set(TYPESCALE_FIELD, typeScale);
814
        state.set(EXTENSION_FIELD, extension);
815
        state.set(QUALITY_FIELD, quality);
816
        state.set(BLINKED_FIELD, linked);
817
        state.set(MAPUNITS_FIELD, mapUnits);
818
        state.set(VIEW_FIELD, viewDocument);
819

    
820
        if (getMapContext() != null
821
            && getMapContext().getViewPort().getEnvelope() != null) {
822
            state.set(ENVELOPE_FIELD, getMapContext().getViewPort()
823
                .getEnvelope());
824
            state.set(SCALE_FIELD, getMapContext().getScaleView());
825
            state.set(MAPCONTEXT_FIELD, mapContext);
826
        }
827

    
828
        state.set(SHOWGRID_FIELD, showGrid);
829
        state.set(GRID_FIELD, grid);
830
    }
831
    
832
    @Override
833
    public void setBoundBox(Rectangle2D r) {
834
            super.setBoundBox(r);
835
            if (getMapContext()!=null) {
836
                    getMapContext().getViewPort().setImageSize(
837
                                    new Dimension((int)r.getWidth(), (int)r.getHeight()));
838
                    getMapContext().getViewPort().setDPI(getDrawPaperDPI());
839
                    updateScaleCtrl();
840
                    // FIXME: what should we do here? should we invalidate the cache?
841
                    // should we also trigger a Layout redraw?
842
                    refresh();
843
            }
844
    }   
845

    
846
    /**
847
     * getRotation returns rotation of the frame
848
     * getMapRotation returns rotation of the map
849
     * 
850
     * @return in degrees
851
     */
852
    public double getMapRotation() {
853
        return 0;
854
    }
855
    
856
        protected void invalidateLayout() {
857
                b_validCache = false;
858
        observers.notifyObservers(this, 
859
                new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));
860
        }
861
    
862
    protected class ViewDocListener
863
            implements ViewPortListener, LegendListener, LayerCollectionListener {
864

    
865
                public void extentChanged(ExtentEvent e) {
866
                        if (!b_fframeOriginatedUpdate && getTypeScale()==AUTOMATICO) {
867
                                if (getMapContext()!=null) {
868
                                        b_viewOriginatedUpdate = true;
869
                                        getMapContext().getViewPort().setEnvelope(e.getNewExtent());
870
                                        updateScaleCtrl();
871
                                        invalidateLayout();
872
                                        b_viewOriginatedUpdate = false;
873
                                }
874
                        }                        
875
                }
876

    
877
                public void backColorChanged(ColorEvent e) {
878
                        if (!b_fframeOriginatedUpdate && linked) {
879
                                if (getMapContext()!=null) {
880
                                        b_viewOriginatedUpdate = true;
881
                                        mapContext.getViewPort().setBackColor(e.getNewColor());
882
                                        invalidateLayout();
883
                                        b_viewOriginatedUpdate = true;
884
                                }
885
                        }
886
                }
887

    
888
                public void projectionChanged(ProjectionEvent e) {
889
                        if (!b_fframeOriginatedUpdate && getTypeScale()==AUTOMATICO) {
890
                                if (getMapContext()!=null) {
891
                                        b_viewOriginatedUpdate = true;
892
                                        getMapContext().getViewPort().setProjection(e.getNewProjection());
893
                                        invalidateLayout();
894
                                        // FIXME: force also a view redraw someway??
895
                                        b_viewOriginatedUpdate = false;
896
                                }
897
                        }
898
                }
899

    
900
                public void conditionalRedraw() {
901
                        if (!b_fframeOriginatedUpdate && linked) {
902
                                b_viewOriginatedUpdate = true;
903
                                invalidateLayout();
904
                                // the view should also receive the event and update automatically
905
                                b_viewOriginatedUpdate = false;
906
                        }                        
907
                }
908

    
909
                public void legendChanged(LegendChangedEvent e) {
910
                        conditionalRedraw();
911
                }
912

    
913
                public void layerAdded(LayerCollectionEvent e) {
914
                        conditionalRedraw();
915
                }
916

    
917
                public void layerMoved(LayerPositionEvent e) {
918
                        conditionalRedraw();
919
                }
920

    
921
                public void layerRemoved(LayerCollectionEvent e) {
922
                        conditionalRedraw();
923
                }
924

    
925
                public void layerAdding(LayerCollectionEvent e)
926
                                throws CancelationException {
927
                        // nothing needed
928
                }
929

    
930
                public void layerMoving(LayerPositionEvent e)
931
                                throws CancelationException {
932
                        // nothing needed
933
                }
934

    
935
                public void layerRemoving(LayerCollectionEvent e)
936
                                throws CancelationException {
937
                        // nothing needed
938
                }
939

    
940
                public void visibilityChanged(LayerCollectionEvent e)
941
                                throws CancelationException {
942
                        conditionalRedraw();
943
                }
944
    }
945
    
946
    protected class OwnMapContextListener
947
            implements ViewPortListener, LegendListener, LayerCollectionListener {
948

    
949
                public void extentChanged(ExtentEvent e) {
950
                        if (!b_viewOriginatedUpdate && (getTypeScale() == AUTOMATICO)) {
951
                                if (getView()!=null) {
952
                                        b_fframeOriginatedUpdate = true;
953
                                        getView().getMapContext().getViewPort().setEnvelope(e.getNewExtent());
954
                                        updateScaleCtrl();
955
                                        invalidateLayout();
956
                                        b_fframeOriginatedUpdate = false;
957
                                }
958
                        }                        
959
                }
960

    
961
                public void backColorChanged(ColorEvent e) {
962
                        if (!b_viewOriginatedUpdate && linked) {
963
                                if (getView()!=null) {
964
                                        b_fframeOriginatedUpdate = true;
965
                                        getView().getMapContext().getViewPort().setBackColor(e.getNewColor());
966
                                        invalidateLayout();
967
                                        b_fframeOriginatedUpdate = false;
968
                                }
969
                        }
970
                }
971

    
972
                public void projectionChanged(ProjectionEvent e) {
973
                        if (!b_viewOriginatedUpdate && (getTypeScale() == AUTOMATICO)) {
974
                                if (getView()!=null) {
975
                                        b_fframeOriginatedUpdate = true;
976
                                        getView().getMapContext().getViewPort().setProjection(e.getNewProjection());
977
                                        invalidateLayout();
978
                                        // FIXME: force also a view redraw someway??
979
                                        b_fframeOriginatedUpdate = false;
980
                                }
981
                        }
982
                }
983

    
984
                public void conditionalRedraw() {
985
                        if (!b_viewOriginatedUpdate && linked) {
986
                                b_fframeOriginatedUpdate = true;
987
                                invalidateLayout();
988
                                // the view should also receive the event and update automatically
989
                                b_fframeOriginatedUpdate = false;
990
                        }                        
991
                }
992
                
993
                public void legendChanged(final LegendChangedEvent e) {
994
                        conditionalRedraw();
995
                }
996

    
997
                public void layerAdded(final LayerCollectionEvent e) {
998
                        conditionalRedraw();
999
                }
1000
                
1001
                public void layerMoved(final LayerPositionEvent e) {
1002
                        conditionalRedraw();
1003
                }
1004
                
1005
                public void layerRemoved(final LayerCollectionEvent e) {
1006
                        conditionalRedraw();
1007
                }
1008

    
1009
                public void layerAdding(LayerCollectionEvent e)
1010
                                throws CancelationException {
1011
                        // nothing neededO
1012
                        
1013
                }
1014

    
1015
                public void layerMoving(LayerPositionEvent e)
1016
                                throws CancelationException {
1017
                        // nothing needed
1018
                        
1019
                }
1020

    
1021
                public void layerRemoving(LayerCollectionEvent e)
1022
                                throws CancelationException {
1023
                        // nothing needed
1024
                        
1025
                }
1026

    
1027
                public void visibilityChanged(LayerCollectionEvent e)
1028
                                throws CancelationException {
1029
                        conditionalRedraw();
1030
                }
1031
            
1032
    }
1033

    
1034
    @Deprecated
1035
        public void refresh() {
1036
        // FIXME: what should we do here? do we really need to invalidate cache??
1037
            b_validCache = false;                
1038
        }
1039
    
1040
    protected void resetListeners() {
1041
                if (this.getMapContext()!=null) {
1042
                        clearOwnListeners(this.getMapContext());
1043
                }
1044
                if (this.getView()!=null && this.getView().getMapContext()!=null) {
1045
                        clearViewListeners(this.getView().getMapContext());
1046
                }
1047
            setListeners();
1048
    }
1049
    
1050
    protected void setListeners() {
1051
            if (getView()!=null) {
1052
                    if (linked) {
1053
                            getView().getMapContext().addLayerListener(viewDocListener);
1054
                            getView().getMapContext().getLayers().addLayerCollectionListener(viewDocListener);
1055
                    }
1056
                    if (getTypeScale()==IFFrameUseFMap.AUTOMATICO) {
1057
                            getView().getMapContext().getViewPort().addViewPortListener(viewDocListener);
1058
                    }
1059
            }
1060
            if (getMapContext()!=null) {
1061
                    getMapContext().addLayerListener(ownMapContextListener);
1062
                    getMapContext().getLayers().addLayerCollectionListener(ownMapContextListener);
1063
                    getMapContext().getViewPort().addViewPortListener(ownMapContextListener);
1064
            }
1065
    }
1066
    protected void clearOwnListeners(MapContext mapContext) {
1067
            mapContext.removeLayerListener(ownMapContextListener);
1068
            mapContext.getViewPort().removeViewPortListener(ownMapContextListener);
1069
            mapContext.getLayers().removeLayerCollectionListener(ownMapContextListener);
1070
    }
1071
    protected void clearViewListeners(MapContext mapContext) {
1072
            mapContext.removeLayerListener(viewDocListener);
1073
            mapContext.getViewPort().removeViewPortListener(viewDocListener);
1074
            mapContext.getLayers().removeLayerCollectionListener(viewDocListener);
1075
    }
1076
    
1077
    /*
1078
     * (non-Javadoc)
1079
     * @see org.gvsig.tools.dispose.Disposable#dispose()
1080
     */
1081
        public void dispose() {
1082
                try {
1083
                        if (this.getMapContext()!=null) {
1084
                                clearOwnListeners(this.getMapContext());
1085
                        }
1086
                        if (this.getView()!=null && this.getView().getMapContext()!=null) {
1087
                                clearViewListeners(this.getView().getMapContext());
1088
                        }
1089
                }
1090
                catch (Exception ex) {}
1091
                this.viewDocument = null;
1092
                this.mapContext = null;
1093
        }
1094
    
1095
}