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

History | View | Annotate | Download (35.1 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.Graphics2D;
29
import java.awt.Point;
30
import java.awt.Rectangle;
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.cresques.cts.IProjection;
37
import org.gvsig.andami.PluginServices;
38
import org.gvsig.andami.messages.NotificationManager;
39
import org.gvsig.andami.ui.mdiFrame.NewStatusBar;
40
import org.gvsig.app.project.Project;
41
import org.gvsig.app.project.documents.layout.DefaultLayoutNotification;
42
import org.gvsig.app.project.documents.layout.FLayoutFunctions;
43
import org.gvsig.app.project.documents.layout.FLayoutUtilities;
44
import org.gvsig.app.project.documents.layout.LayoutNotification;
45
import org.gvsig.app.project.documents.view.ViewDocument;
46
import org.gvsig.compat.print.PrintAttributes;
47
import org.gvsig.fmap.dal.exception.ReadException;
48
import org.gvsig.fmap.geom.Geometry;
49
import org.gvsig.fmap.geom.GeometryLocator;
50
import org.gvsig.fmap.geom.GeometryManager;
51
import org.gvsig.fmap.geom.primitive.Envelope;
52
import org.gvsig.fmap.mapcontext.MapContext;
53
import org.gvsig.fmap.mapcontext.MapContextException;
54
import org.gvsig.fmap.mapcontext.ViewPort;
55
import org.gvsig.fmap.mapcontext.events.ColorEvent;
56
import org.gvsig.fmap.mapcontext.events.ExtentEvent;
57
import org.gvsig.fmap.mapcontext.events.ProjectionEvent;
58
import org.gvsig.fmap.mapcontext.events.listeners.ViewPortListener;
59
import org.gvsig.fmap.mapcontext.layers.CancelationException;
60
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
61
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
62
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
63
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
64
import org.gvsig.fmap.mapcontext.rendering.legend.events.listeners.LegendListener;
65
import org.gvsig.gui.beans.Messages;
66
import org.gvsig.tools.ToolsLocator;
67
import org.gvsig.tools.dynobject.DynStruct;
68
import org.gvsig.tools.persistence.PersistenceManager;
69
import org.gvsig.tools.persistence.PersistentState;
70
import org.gvsig.tools.persistence.exception.PersistenceException;
71
import org.slf4j.Logger;
72
import org.slf4j.LoggerFactory;
73

    
74
/**
75
 * FFrame para introducir una vista en el Layout.
76
 * 
77
 * @author Vicente Caballero Navarro
78
 */
79
public class FFrameView extends FFrame implements IFFrameUseProject, IFFrameUseFMap {
80

    
81
    public static final String PERSISTENCE_DEFINITION_NAME = "FFrameView";
82

    
83
    private static final String MODE_FIELD = "mode";
84
    private static final String TYPESCALE_FIELD = "typeScale";
85
    private static final String QUALITY_FIELD = "quality";
86
    private static final String BLINKED_FIELD = "bLinked";
87
    private static final String MAPUNITS_FIELD = "mapUnits";
88
    private static final String SCALE_FIELD = "scale";
89
    private static final String VIEW_FIELD = "view";
90
    private static final String ENVELOPE_FIELD = "envelope";
91
    private static final String SHOWGRID_FIELD = "showGrid";
92
    private static final String GRID_FIELD = "gridview";
93
    private static final String MAPCONTEXT_FIELD = "mapContext";
94
    // following fields are unused - should be deleted? 
95
    private static final String EXTENSION_FIELD = "extension";
96

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

    
111
    protected BufferedImage m_image = null;
112
    protected AffineTransform at = null;
113
    protected Project project = null;
114
    protected double scaleAnt;
115
    protected Point origin;
116
    protected Point2D p1;
117
    protected Point2D p2;
118
    protected IFFrame grid;
119
    protected boolean showGrid = false;
120

    
121
        private boolean b_viewOriginatedUpdate = false;
122
        private boolean b_fframeOriginatedUpdate = false;
123
        private boolean b_validCache = false;
124
        protected ViewDocListener viewDocListener = new ViewDocListener();
125
        protected OwnMapContextListener ownMapContextListener = new OwnMapContextListener();
126
                
127

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

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

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

    
148
    /**
149
     * Rellena la escala de la vista que contiene el fframe.
150
     * 
151
     * @param d
152
     *            escala de la vista.
153
     */
154
    public void setScale(double d) {
155
            if (getMapContext()!=null) {
156
                    getMapContext().setScaleView((long) d);
157
            }
158
    }
159

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

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

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

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

    
210
    public void setViewMapContext(MapContext viewMapContext) {
211
            if (mapContext!=null) {
212
                    clearOwnListeners(mapContext);
213
            }
214
            try {
215
                    if (linked){
216
                            mapContext =
217
                                            viewMapContext.createNewFMap(
218
                                                            (ViewPort) viewMapContext.getViewPort().clone());
219
                    }
220
                    else {
221
                            mapContext = viewMapContext.cloneFMap();
222
                            mapContext.setViewPort((ViewPort) viewMapContext
223
                                            .getViewPort().clone());
224
                    }
225
                    ViewPort newViewPort = getMapContext().getViewPort();
226
                    newViewPort.setImageSize(new Dimension((int) getBoundingBox(null).width,
227
                                    (int) getBoundingBox(null).height));
228
                    newViewPort.setDPI(getDrawPaperDPI());
229
                    setListeners();
230
                    updateScaleCtrl();
231
            } catch (CloneNotSupportedException e1) {
232
                    NotificationManager.addError("Excepci?n :", e1);
233
            }
234

    
235
    }
236
    /**
237
     * Inserta el ProjectView de donde obtener las propiedades de la vista a
238
     * mostrar.
239
     * 
240
     * @param v
241
     *            Modelo de la vista.
242
     */
243
    public void setView(ViewDocument dvd) {
244
            ViewDocument oldDoc = dvd;
245
            if (oldDoc!=null && oldDoc.getMapContext()!=null) {
246
                    clearViewListeners(oldDoc.getMapContext());
247
            }
248
        viewDocument = dvd;
249
        if (dvd!=null) {
250
            setViewMapContext(dvd.getMapContext());
251
        }
252
    }
253

    
254
    /**
255
     * Devuelve el modelo de la vista.
256
     * 
257
     * @return Modelo de la vista.
258
     */
259
    public ViewDocument getView() {
260
        return viewDocument;
261
    }
262

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

    
320
        int scale = (int) (r.getWidth() / 24);
321
        Font f = new Font("SansSerif", Font.PLAIN, scale);
322
        g.setFont(f);
323

    
324
        g.drawString(msg, (int) (r.getCenterX() - ((msg.length() * scale) / 4)),
325
            (int) (r.getCenterY()));        
326
    }
327

    
328
    protected void drawPresentation(
329
        Graphics2D g,
330
        AffineTransform affineTransform,
331
        Rectangle2D.Double fframeViewRect,
332
        Rectangle2D visibleLayoutDocRect,
333
        BufferedImage imgBase) throws Exception {
334
        
335
        Point mapOrigin = new Point((int)visibleLayoutDocRect.getMinX(), (int)visibleLayoutDocRect.getMaxY());
336

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

    
359
                viewPort.setImageSize(new Dimension(drawWidth, drawHeight));
360
            viewPort.setDPI(getDrawPaperDPI());
361
            m_image =
362
                    new BufferedImage(
363
                                    drawWidth,
364
                                    drawHeight,
365
                                    BufferedImage.TYPE_INT_ARGB);
366

    
367
            Graphics2D gimg = (Graphics2D) m_image.createGraphics();
368
            getMapContext().draw(m_image, gimg, getScale());
369
            gimg.dispose();
370
            b_validCache = true;
371
        } 
372

    
373
        //Draw the created image
374
        if (theBackColor != null) {
375
            g.setColor(theBackColor);
376
            g.fillRect((int) fframeViewRect.x, (int) fframeViewRect.y,
377
                            (int)fframeViewRect.width,
378
                            (int)fframeViewRect.height);
379
        }
380
        g.drawImage(m_image, 
381
                        (int) fframeViewRect.x,
382
                        (int) fframeViewRect.y,
383
                        null);
384
        
385
        scaleAnt = affineTransform.getScaleX();
386
        origin = mapOrigin;             
387
    }
388

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

    
416
    public void print(Graphics2D g, AffineTransform at, Geometry geom,
417
        PrintAttributes printAttributes) {
418
        Rectangle2D.Double rectangleLayout = getBoundingBox(at);  
419
        
420
        Rectangle originalClip = preDraw(g, rectangleLayout);
421
        print(g, at, printAttributes);
422
        postDraw(g, rectangleLayout, null, null, originalClip, at);
423
        if (showGrid && grid != null) {
424
            grid.print(g, at, geom, printAttributes);
425
        }    
426
    }
427

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

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

    
465
    /**
466
     * Rellena la unidad de medida en la que est? la vista.
467
     * 
468
     * @param i
469
     *            entero que representa la unidad de medida de la vista.
470
     */
471
    public void setMapUnits(int i) {
472
        mapUnits = i;
473
    }
474

    
475
    /**
476
     * Obtiene la unidad de medida en la que est? la vista.
477
     * 
478
     * @return Unidad de medida.
479
     */
480
    public int getMapUnits() {
481
        return mapUnits;
482
    }
483

    
484
    /**
485
     * Devuelve la escala seg?n el tipo de escala que se haya seleccionado al
486
     * a?adida la vista.
487
     * 
488
     * @return escala.
489
     */
490
    public long getScale() {
491
            return (long) getMapContext().getScaleView();
492
    }
493

    
494
    /**
495
     * Seleccionar si la vista esta relacionada o no con la original.
496
     * 
497
     * @param b
498
     *            true si est? ligada y false si no lo est?.
499
     */
500
    public void setLinked(boolean b) {
501
        linked = b;
502
        resetListeners();
503
    }
504

    
505
    /**
506
     * Devuelve si est? ligada o no el FFrameView con la vista.
507
     * 
508
     * @return True si la vista est? ligada.
509
     */
510
    public boolean getLinked() {
511
        return linked;
512
    }
513

    
514
    /**
515
     * Devuelve el tipo de escala que est? seleccionada AUTOMATICO o
516
     * MANUAL.
517
     * 
518
     * @return entero que representa el tipo seleccionado.
519
     */
520
    public int getTypeScale() {
521
        return typeScale;
522
    }
523

    
524
    /**
525
     * Rellenar el tipo de escala que se desea.
526
     * 
527
     * @param i
528
     *            entero que representa el tipo de escala.
529
     */
530
    public void setTypeScale(int i) {
531
        typeScale = i;
532
        resetListeners();
533
    }
534

    
535
    /**
536
     * Inserta la imagen para repintar el FFrameView.
537
     * 
538
     * @param bi
539
     *            Imagen para repintar.
540
     */
541
    public void setBufferedImage(BufferedImage bi) {
542
        m_image = bi;
543
    }
544

    
545
    /**
546
     * Devuelve la imagen para repintar.
547
     * 
548
     * @return Imagen para repintar.
549
     */
550
    public BufferedImage getBufferedImage() {
551
        return m_image;
552
    }
553

    
554
    /**
555
     * Devuelve la MAtriz de transformaci?n utilizada por la FFrameView.
556
     * 
557
     * @return MAtriz de transformaci?n.
558
     */
559
    public AffineTransform getATMap() {
560
        return at;
561
    }
562

    
563
    /**
564
     * Inserta la matriz de transformaci?n.
565
     * 
566
     * @param transform
567
     *            Matriz de transformaci?n.
568
     */
569
    public void setATMap(AffineTransform transform) {
570
        at = transform;
571
    }
572

    
573
    /**
574
     * Inserta el proyecto.
575
     * 
576
     * @param p
577
     *            Proyecto.
578
     */
579
    public void setProject(Project p) {
580
        project = p;
581
    }
582

    
583
    /**
584
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#getNameFFrame()
585
     */
586
    public String getNameFFrame() {
587
        return PluginServices.getText(this, "Vista") + num;
588
    }
589

    
590
    public String getName() {
591
        return PERSISTENCE_DEFINITION_NAME;
592
    }
593

    
594
    /**
595
     * DOCUMENT ME!
596
     * 
597
     * @param arg0
598
     *            DOCUMENT ME!
599
     * 
600
     * @return DOCUMENT ME!
601
     */
602
    public boolean compare(Object arg0) {
603
        if (!(arg0 instanceof FFrameView)) {
604
            return false;
605
        }
606

    
607
        if (!this.getName().equals(((FFrameView) arg0).getName())) {
608
            return false;
609
        }
610

    
611
        if (Math.abs(this.getBoundBox().getWidth()
612
            - (((FFrameView) arg0).getBoundBox().getWidth())) > 0.05) {
613
            return false;
614
        }
615
        if (Math.abs(this.getBoundBox().getHeight()
616
            - (((FFrameView) arg0).getBoundBox().getHeight())) > 0.05) {
617
            return false;
618
        }
619

    
620
        if (!this.toString().equals(((FFrameView) arg0).toString())) {
621
            return false;
622
        }
623

    
624
        if (this.getMapContext() != null
625
            && !this.getMapContext()
626
                .equals(((FFrameView) arg0).getMapContext())) {
627
            return false;
628
        }
629

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

    
651
    public void fullExtent() throws ReadException {
652
        setNewEnvelope(getMapContext().getFullEnvelope());
653
    }
654

    
655
    public void setPointsToZoom(Point2D px1, Point2D px2) {
656
        p1 = px1;
657
        p2 = px2;
658
    }
659

    
660
    public void movePoints(Point2D px1, Point2D px2) {
661
        double difX = -px2.getX() + px1.getX();
662
        double difY = -px2.getY() + px1.getY();
663
        if (p1 != null) {
664
            p1.setLocation(p1.getX() + difX, p1.getY() + difY);
665
            p2.setLocation(p2.getX() + difX, p2.getY() + difY);
666
        }
667
    }
668

    
669
    /**
670
     * This method deals with places where this fframeview and the cloned
671
     * fframeview (frame) are registered as listeners. The goal should be
672
     * leaving the cloned instance (frame) as listener in the same way
673
     * that 'this' instance is doing.
674
     */
675
    protected void cloneActions(FFrameView frame) {
676
    }
677

    
678
    public Object clone() throws CloneNotSupportedException {
679
        FFrameView frame = (FFrameView) super.clone();
680
        frame.viewDocListener = new ViewDocListener();
681
        frame.ownMapContextListener = new OwnMapContextListener();
682
        frame.setSelected(this.isSelected());
683
        frame.setTypeScale(this.getTypeScale());
684
        frame.setLinked(linked);
685
        frame.setView(this.getView());
686

    
687
        if (grid != null) {
688
            FFrameGrid newGrid = (FFrameGrid) this.grid.clone();
689
            newGrid.setFFrameDependence(frame);
690
            frame.setGrid(newGrid);
691
        }
692
        cloneActions(frame);
693
        return frame;
694
    }
695

    
696
    public void setGrid(IFFrame grid) {
697
        this.grid = grid;
698
        this.grid.setRotation(this.getRotation());
699
    }
700

    
701
    public IFFrame getGrid() {
702
        return this.grid;
703
    }
704

    
705
    public void setRotation(double rotation) {
706
        super.setRotation(rotation);
707
        if (grid != null) {
708
            grid.setRotation(rotation);
709
        }
710
    }
711

    
712
    public void showGrid(boolean b) {
713
        showGrid = b;
714
    }
715

    
716
    public boolean isShowGrid() {
717
        return showGrid;
718
    }
719

    
720
    public void refreshOriginalExtent() {
721
            /*
722
        if (getTypeScale() == AUTOMATICO) {
723
            viewDocument.getMapContext().getViewPort()
724
                .setEnvelope(getMapContext().getViewPort().getEnvelope());
725
            viewDocument.getMapContext().getViewPort().refreshExtent();
726
        } else
727
            if (getTypeScale() == MANUAL) {
728
                Envelope oldExtent =
729
                    viewDocument.getMapContext().getViewPort().getEnvelope();
730
                Envelope newExtent =
731
                    getMapContext().getViewPort().getEnvelope();
732
                double xDif = newExtent.getCenter(0) - oldExtent.getCenter(0);
733
                double yDif = newExtent.getCenter(1) - oldExtent.getCenter(1);
734
                try {
735
                    viewDocument.getMapContext()
736
                        .getViewPort()
737
                        .setEnvelope(
738
                            geomManager.createEnvelope(oldExtent.getMinimum(0)
739
                                + xDif, oldExtent.getMinimum(1) + yDif,
740
                                oldExtent.getMaximum(0) + xDif,
741
                                oldExtent.getMaximum(1) + yDif, SUBTYPES.GEOM2D));
742
                } catch (CreateEnvelopeException e) {
743
                    e.printStackTrace();
744
                }
745
                viewDocument.getMapContext().getViewPort().refreshExtent();
746
            }
747
            */
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(FFrameView.class,
755
                    PERSISTENCE_DEFINITION_NAME,
756
                    "FFrameView persistence definition", null, null);
757

    
758
            definition.extend(manager
759
                .getDefinition(FFrame.PERSISTENCE_DEFINITION_NAME));
760

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

    
780
    @Override
781
    public void loadFromState(PersistentState state)
782
        throws PersistenceException {
783
        super.loadFromState(state);
784
        mode = state.getInt(MODE_FIELD);
785
        typeScale = state.getInt(TYPESCALE_FIELD);
786
        quality = state.getInt(QUALITY_FIELD);
787
        linked = state.getBoolean(BLINKED_FIELD);
788
        mapUnits = state.getInt(MAPUNITS_FIELD);;
789
        viewDocument = (ViewDocument) state.get(VIEW_FIELD);
790

    
791
        if (state.hasValue(MAPCONTEXT_FIELD)) {
792
            mapContext = (MapContext) state.get(MAPCONTEXT_FIELD);
793
            double mapScale = state.getDouble(SCALE_FIELD);
794
            mapContext.setScaleView((long)mapScale); // FIXME: really needed?? probably already persisted on Mapcontext
795
            mapContext.getViewPort().setEnvelope(
796
                (Envelope) state.get(ENVELOPE_FIELD));
797
        }
798

    
799
        showGrid = state.getBoolean(SHOWGRID_FIELD);
800
        grid = (IFFrame) state.get(GRID_FIELD);
801
    }
802

    
803
    @Override
804
    public void saveToState(PersistentState state) throws PersistenceException {
805
        super.saveToState(state);
806
        state.set(MODE_FIELD, mode);
807
        state.set(TYPESCALE_FIELD, typeScale);
808
        state.set(QUALITY_FIELD, quality);
809
        state.set(BLINKED_FIELD, linked);
810
        state.set(MAPUNITS_FIELD, mapUnits);
811
        state.set(VIEW_FIELD, viewDocument);
812

    
813
        if (getMapContext() != null
814
            && getMapContext().getViewPort().getEnvelope() != null) {
815
            state.set(ENVELOPE_FIELD, getMapContext().getViewPort()
816
                .getEnvelope());
817
            state.set(SCALE_FIELD, getMapContext().getScaleView());
818
            state.set(MAPCONTEXT_FIELD, mapContext);
819
        }
820

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

    
839
    /**
840
     * getRotation returns rotation of the frame
841
     * getMapRotation returns rotation of the map
842
     * 
843
     * @return in degrees
844
     */
845
    public double getMapRotation() {
846
        return 0;
847
    }
848
    
849
        protected void invalidateLayout() {
850
                b_validCache = false;
851
        observers.notifyObservers(this, 
852
                new DefaultLayoutNotification(LayoutNotification.LAYOUT_INVALIDATED));
853
        }
854
    
855
    protected class ViewDocListener
856
            implements ViewPortListener, LegendListener, LayerCollectionListener {
857

    
858
                public void extentChanged(ExtentEvent e) {
859
                        if (!b_fframeOriginatedUpdate && getTypeScale()==AUTOMATICO) {
860
                                if (getMapContext()!=null) {
861
                                        b_viewOriginatedUpdate = true;
862
                                        getMapContext().getViewPort().setEnvelope(e.getNewExtent());
863
                                        updateScaleCtrl();
864
                                        invalidateLayout();
865
                                        b_viewOriginatedUpdate = false;
866
                                }
867
                        }                        
868
                }
869

    
870
                public void backColorChanged(ColorEvent e) {
871
                        if (!b_fframeOriginatedUpdate && linked) {
872
                                if (getMapContext()!=null) {
873
                                        b_viewOriginatedUpdate = true;
874
                                        mapContext.getViewPort().setBackColor(e.getNewColor());
875
                                        invalidateLayout();
876
                                        b_viewOriginatedUpdate = true;
877
                                }
878
                        }
879
                }
880

    
881
                public void projectionChanged(ProjectionEvent e) {
882
                        if (!b_fframeOriginatedUpdate && getTypeScale()==AUTOMATICO) {
883
                                if (getMapContext()!=null) {
884
                                        b_viewOriginatedUpdate = true;
885
                                        getMapContext().getViewPort().setProjection(e.getNewProjection());
886
                                        invalidateLayout();
887
                                        // FIXME: force also a view redraw someway??
888
                                        b_viewOriginatedUpdate = false;
889
                                }
890
                        }
891
                }
892

    
893
                public void conditionalRedraw() {
894
                        if (!b_fframeOriginatedUpdate && linked) {
895
                                b_viewOriginatedUpdate = true;
896
                                invalidateLayout();
897
                                // the view should also receive the event and update automatically
898
                                b_viewOriginatedUpdate = false;
899
                        }                        
900
                }
901

    
902
                public void legendChanged(LegendChangedEvent e) {
903
                        conditionalRedraw();
904
                }
905

    
906
                public void layerAdded(LayerCollectionEvent e) {
907
                        conditionalRedraw();
908
                }
909

    
910
                public void layerMoved(LayerPositionEvent e) {
911
                        conditionalRedraw();
912
                }
913

    
914
                public void layerRemoved(LayerCollectionEvent e) {
915
                        conditionalRedraw();
916
                }
917

    
918
                public void layerAdding(LayerCollectionEvent e)
919
                                throws CancelationException {
920
                        // nothing needed
921
                }
922

    
923
                public void layerMoving(LayerPositionEvent e)
924
                                throws CancelationException {
925
                        // nothing needed
926
                }
927

    
928
                public void layerRemoving(LayerCollectionEvent e)
929
                                throws CancelationException {
930
                        // nothing needed
931
                }
932

    
933
                public void visibilityChanged(LayerCollectionEvent e)
934
                                throws CancelationException {
935
                        conditionalRedraw();
936
                }
937
    }
938
    
939
    protected class OwnMapContextListener
940
            implements ViewPortListener, LegendListener, LayerCollectionListener {
941

    
942
                public void extentChanged(ExtentEvent e) {
943
                        if (!b_viewOriginatedUpdate && (getTypeScale() == AUTOMATICO)) {
944
                                if (getView()!=null) {
945
                                        b_fframeOriginatedUpdate = true;
946
                                        getView().getMapContext().getViewPort().setEnvelope(e.getNewExtent());
947
                                        updateScaleCtrl();
948
                                        invalidateLayout();
949
                                        b_fframeOriginatedUpdate = false;
950
                                }
951
                        }                        
952
                }
953

    
954
                public void backColorChanged(ColorEvent e) {
955
                        if (!b_viewOriginatedUpdate && linked) {
956
                                if (getView()!=null) {
957
                                        b_fframeOriginatedUpdate = true;
958
                                        getView().getMapContext().getViewPort().setBackColor(e.getNewColor());
959
                                        invalidateLayout();
960
                                        b_fframeOriginatedUpdate = false;
961
                                }
962
                        }
963
                }
964

    
965
                public void projectionChanged(ProjectionEvent e) {
966
                        if (!b_viewOriginatedUpdate && (getTypeScale() == AUTOMATICO)) {
967
                                if (getView()!=null) {
968
                                        b_fframeOriginatedUpdate = true;
969
                                        getView().getMapContext().getViewPort().setProjection(e.getNewProjection());
970
                                        invalidateLayout();
971
                                        // FIXME: force also a view redraw someway??
972
                                        b_fframeOriginatedUpdate = false;
973
                                }
974
                        }
975
                }
976

    
977
                public void conditionalRedraw() {
978
                        if (!b_viewOriginatedUpdate && linked) {
979
                                b_fframeOriginatedUpdate = true;
980
                                invalidateLayout();
981
                                // the view should also receive the event and update automatically
982
                                b_fframeOriginatedUpdate = false;
983
                        }                        
984
                }
985
                
986
                public void legendChanged(final LegendChangedEvent e) {
987
                        conditionalRedraw();
988
                }
989

    
990
                public void layerAdded(final LayerCollectionEvent e) {
991
                        conditionalRedraw();
992
                }
993
                
994
                public void layerMoved(final LayerPositionEvent e) {
995
                        conditionalRedraw();
996
                }
997
                
998
                public void layerRemoved(final LayerCollectionEvent e) {
999
                        conditionalRedraw();
1000
                }
1001

    
1002
                public void layerAdding(LayerCollectionEvent e)
1003
                                throws CancelationException {
1004
                        // nothing neededO
1005
                        
1006
                }
1007

    
1008
                public void layerMoving(LayerPositionEvent e)
1009
                                throws CancelationException {
1010
                        // nothing needed
1011
                        
1012
                }
1013

    
1014
                public void layerRemoving(LayerCollectionEvent e)
1015
                                throws CancelationException {
1016
                        // nothing needed
1017
                        
1018
                }
1019

    
1020
                public void visibilityChanged(LayerCollectionEvent e)
1021
                                throws CancelationException {
1022
                        conditionalRedraw();
1023
                }
1024
            
1025
    }
1026

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