Statistics
| Revision:

root / tags / v2_0_0_Build_2047 / applications / appgvSIG / src / org / gvsig / app / project / documents / view / toc / gui / TOC.java @ 38262

History | View | Annotate | Download (39.4 KB)

1 38114 cordinyana
/* gvSIG. Desktop Geographic Information System.
2 7304 caballero
 *
3 38114 cordinyana
 * Copyright ? 2007-2012 gvSIG Association
4 7304 caballero
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17 38114 cordinyana
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19 7304 caballero
 *
20 38114 cordinyana
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22 7304 caballero
 */
23 29598 jpiera
package org.gvsig.app.project.documents.view.toc.gui;
24 7304 caballero
25
import java.awt.BorderLayout;
26
import java.awt.Dimension;
27 38116 cordinyana
import java.awt.Font;
28
import java.awt.FontMetrics;
29 7836 ldiaz
import java.awt.Image;
30 7304 caballero
import java.awt.Point;
31
import java.awt.Rectangle;
32
import java.awt.event.ActionEvent;
33
import java.awt.event.ActionListener;
34
import java.awt.event.ComponentEvent;
35
import java.awt.event.ComponentListener;
36
import java.awt.event.InputEvent;
37
import java.awt.event.MouseAdapter;
38
import java.awt.event.MouseEvent;
39 34928 jjdelcerro
import java.text.MessageFormat;
40 13741 jaume
import java.util.ArrayList;
41 7304 caballero
import java.util.Enumeration;
42
import java.util.HashMap;
43 34928 jjdelcerro
import java.util.Map;
44 7304 caballero
45
import javax.swing.BorderFactory;
46
import javax.swing.JColorChooser;
47
import javax.swing.JComponent;
48
import javax.swing.JDialog;
49
import javax.swing.JScrollPane;
50
import javax.swing.JTree;
51
import javax.swing.SwingUtilities;
52
import javax.swing.event.TreeExpansionEvent;
53
import javax.swing.event.TreeExpansionListener;
54
import javax.swing.tree.DefaultMutableTreeNode;
55
import javax.swing.tree.DefaultTreeModel;
56
import javax.swing.tree.TreePath;
57
import javax.swing.tree.TreeSelectionModel;
58
59 34928 jjdelcerro
import org.slf4j.Logger;
60
import org.slf4j.LoggerFactory;
61
62 29598 jpiera
import org.gvsig.andami.PluginServices;
63
import org.gvsig.andami.messages.NotificationManager;
64 31496 jjdelcerro
import org.gvsig.app.project.documents.view.IContextMenuAction;
65 29598 jpiera
import org.gvsig.app.project.documents.view.toc.DnDJTree;
66
import org.gvsig.app.project.documents.view.toc.ITocItem;
67
import org.gvsig.app.project.documents.view.toc.ITocOrderListener;
68
import org.gvsig.app.project.documents.view.toc.TocItemBranch;
69
import org.gvsig.app.project.documents.view.toc.TocItemLeaf;
70 24759 jmvivo
import org.gvsig.fmap.dal.exception.ReadException;
71 20994 jmvivo
import org.gvsig.fmap.mapcontext.MapContext;
72
import org.gvsig.fmap.mapcontext.events.AtomicEvent;
73
import org.gvsig.fmap.mapcontext.events.listeners.AtomicEventListener;
74
import org.gvsig.fmap.mapcontext.layers.CancelationException;
75
import org.gvsig.fmap.mapcontext.layers.FLayer;
76
import org.gvsig.fmap.mapcontext.layers.FLayers;
77
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
78
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
79
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
80
import org.gvsig.fmap.mapcontext.layers.operations.Classifiable;
81
import org.gvsig.fmap.mapcontext.layers.operations.IHasImageLegend;
82
import org.gvsig.fmap.mapcontext.layers.operations.LayerCollection;
83
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
84 31631 jpiera
import org.gvsig.fmap.mapcontext.rendering.legend.IClassifiedLegend;
85 20994 jmvivo
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
86 31631 jpiera
import org.gvsig.fmap.mapcontext.rendering.legend.ISingleSymbolLegend;
87 20994 jmvivo
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
88
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
89
import org.gvsig.fmap.mapcontext.rendering.legend.events.listeners.LegendListener;
90
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
91
92 7304 caballero
/**
93 38114 cordinyana
 *
94
 * @author fjp
95 7304 caballero
 */
96
public class TOC extends JComponent implements ITocOrderListener,
97 38114 cordinyana
    LegendListener, LayerCollectionListener, TreeExpansionListener,
98
    ComponentListener {
99
100
    /**
101 34928 jjdelcerro
     *
102
     */
103
    private static final long serialVersionUID = 5689047685537359038L;
104
105
    /**
106 38114 cordinyana
     * Useful for debug the problems during the implementation.
107
     */
108
    private static Logger logger = LoggerFactory.getLogger(TOC.class);
109 34895 fdiaz
110 38114 cordinyana
    private MapContext mapContext;
111 7304 caballero
112 38114 cordinyana
    private DnDJTree m_Tree;
113 7304 caballero
114 38114 cordinyana
    private DefaultTreeModel m_TreeModel;
115 7304 caballero
116 38114 cordinyana
    private DefaultMutableTreeNode m_Root;
117 7304 caballero
118 38114 cordinyana
    private TOCRenderer m_TocRenderer;
119 7304 caballero
120 38114 cordinyana
    private JScrollPane m_Scroller;
121 7304 caballero
122 38114 cordinyana
    // private ArrayList m_Listeners;
123
    private Map<String, Boolean> m_ItemsExpanded =
124
        new HashMap<String, Boolean>();
125 7304 caballero
126 38114 cordinyana
    private NodeSelectionListener nodeSelectionListener = null;
127 7304 caballero
128 38114 cordinyana
    /**
129
     * Crea un nuevo TOC.
130
     */
131
    public TOC() {
132
        this.setName("TOC");
133
        this.setLayout(new BorderLayout());
134
        this.setMinimumSize(new Dimension(100, 80));
135
        this.setPreferredSize(new Dimension(100, 80));
136 7304 caballero
137 38114 cordinyana
        // Construct the tree.
138
        m_Root = new DefaultMutableTreeNode(java.lang.Object.class);
139
        m_TreeModel = new DefaultTreeModel(m_Root);
140
        m_Tree = new DnDJTree(m_TreeModel);
141 7304 caballero
142 38114 cordinyana
        m_TocRenderer = new TOCRenderer();
143
        m_Tree.setCellRenderer(m_TocRenderer);
144 7304 caballero
145 38114 cordinyana
        m_Tree.setRootVisible(false);
146 7304 caballero
147 38114 cordinyana
        // m_Tree.setExpandsSelectedPaths(true);
148
        // m_Tree.setAutoscrolls(true);
149
        m_Tree.setShowsRootHandles(true);
150 7304 caballero
151 38114 cordinyana
        // Posibilidad de seleccionar de forma aleatoria nodos de la leyenda.
152
        m_Tree.getSelectionModel().setSelectionMode(
153
            TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
154
        nodeSelectionListener = new NodeSelectionListener(m_Tree);
155
        m_Tree.addMouseListener(nodeSelectionListener);
156 38116 cordinyana
        // m_Tree.setBackground(UIManager.getColor("Button.background"));
157
        // m_Tree.setBorder(BorderFactory.createEtchedBorder());
158 7304 caballero
159 38114 cordinyana
        this.addComponentListener(this);
160 7304 caballero
161 38114 cordinyana
        m_Tree.addTreeExpansionListener(this);
162 7304 caballero
163 38114 cordinyana
        m_Tree.addOrderListener(this);
164 7304 caballero
165 38114 cordinyana
        m_Tree.setRowHeight(0); // Para que lo determine el renderer
166 7304 caballero
167 38114 cordinyana
        m_Scroller = new JScrollPane(m_Tree);
168
        m_Scroller.setBorder(BorderFactory.createEmptyBorder());
169 7304 caballero
170 38114 cordinyana
        // scrollPane.setPreferredSize(new Dimension(80,80));
171
        // Add everything to this panel.
172
        /*
173
         * GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c =
174
         * new GridBagConstraints(); setLayout(gridbag); c.fill =
175
         * GridBagConstraints.BOTH; c.weightx = 1.0;
176
         * gridbag.setConstraints(check,c);
177
         */
178
        add(m_Scroller); // , BorderLayout.WEST);
179 7304 caballero
180 38114 cordinyana
        // refresh();
181
    }
182 7304 caballero
183 38114 cordinyana
    /**
184
     * Elimina los listeners que actuan sobre el TOC, lo ?nico que deja hacer es
185
     * desplegar la leyenda de las capas.
186
     */
187
    public void removeListeners() {
188
        m_Tree.removeMouseListener(nodeSelectionListener);
189
        m_Tree.invalidateListeners();
190
    }
191 7304 caballero
192 38114 cordinyana
    /**
193
     * Inserta el FMap.
194
     *
195
     * @param mc
196
     *            FMap.
197
     */
198
    public void setMapContext(MapContext mc) {
199
        mapContext = mc;
200
        mapContext.addAtomicEventListener(new AtomicEventListener() {
201 34928 jjdelcerro
202 38114 cordinyana
            /**
203
             * @see org.gvsig.fmap.mapcontext.events.listeners.AtomicEventListener#atomicEvent(org.gvsig.fmap.mapcontext.events.AtomicEvent)
204
             */
205
            public void atomicEvent(final AtomicEvent e) {
206
                if (!SwingUtilities.isEventDispatchThread()) {
207
                    SwingUtilities.invokeLater(new Runnable() {
208 7304 caballero
209 38114 cordinyana
                        public void run() {
210
                            atomicEvent(e);
211
                        }
212
                    });
213
                    return;
214
                }
215 7304 caballero
216 38114 cordinyana
                if ((e.getLayerCollectionEvents().length > 0)
217
                    || (e.getLegendEvents().length > 0)) {
218
                    refresh();
219
                }
220 7304 caballero
221 38114 cordinyana
                if (e.getLayerEvents().length > 0) {
222
                    repaint();
223
                }
224 7304 caballero
225 38114 cordinyana
                if (e.getExtentEvents().length > 0) {
226
                    repaint();
227
                }
228 38197 vacevedo
                LayerCollectionEvent[] events = e.getLayerCollectionEvents();
229
                for( int i=0; i<events.length ; i++ ) {
230
                   if( events[i].getEventType() == 0 ) { // LayerCollectionEvent.LAYER_ADDED ?? is private
231
                       if (PluginServices.getMainFrame() != null) {
232
                           PluginServices.getMainFrame().enableControls();
233
                       }
234
                   }
235
                }
236 38114 cordinyana
            }
237
        });
238
239
        refresh();
240
    }
241
242
    /**
243
     * DOCUMENT ME!
244
     */
245
    private void setExpandedNodes(DefaultMutableTreeNode node) {
246
        // int i = 0;
247
        // Las claves sobrantes de m_ItemsExpanded (provocadas
248
        // por layerRemove, se quitan en el evento layerRemoved
249
        // de este TOC
250
        DefaultMutableTreeNode n;
251
        @SuppressWarnings("rawtypes")
252 34928 jjdelcerro
        Enumeration enumeration = node.children();
253 7304 caballero
254 38114 cordinyana
        while (enumeration.hasMoreElements()) {
255
            n = (DefaultMutableTreeNode) enumeration.nextElement();
256
            if (n.getChildCount() > 0) {
257
                setExpandedNodes(n);
258
            }
259
            TreePath path = new TreePath(m_TreeModel.getPathToRoot(n));
260
            ITocItem item = (ITocItem) n.getUserObject();
261
            Boolean b = (Boolean) m_ItemsExpanded.get(item.getLabel());
262 7304 caballero
263 38114 cordinyana
            if (b == null) // No estaba en el hash todav?a: valor por defecto
264
            {
265
                m_Tree.expandPath(path);
266 7304 caballero
267 38114 cordinyana
                return;
268
            }
269 7304 caballero
270 38114 cordinyana
            if (b.booleanValue()) {
271
                m_Tree.expandPath(path);
272
            } else {
273
                m_Tree.collapsePath(path);
274
            }
275
        }
276
    }
277 7304 caballero
278 38114 cordinyana
    /*
279
     * (non-Javadoc)
280
     *
281
     * @see com.iver.cit.opensig.gui.IToc#refresh()
282
     */
283
    public void refresh() {
284
        if (!SwingUtilities.isEventDispatchThread()) {
285 34928 jjdelcerro
            SwingUtilities.invokeLater(new Runnable() {
286 38114 cordinyana
287 34928 jjdelcerro
                public void run() {
288
                    refresh();
289
                }
290
            });
291
            return;
292 38114 cordinyana
        }
293
        LayerCollection theLayers = mapContext.getLayers();
294
        m_Root.removeAllChildren();
295
        m_Root.setAllowsChildren(true);
296
        doRefresh(theLayers, m_Root);
297 7304 caballero
298 38114 cordinyana
        m_TreeModel.reload();
299 7304 caballero
300 38114 cordinyana
        setExpandedNodes(m_Root);
301
    }
302 7304 caballero
303 38114 cordinyana
    private void doRefresh(LayerCollection theLayers,
304
        DefaultMutableTreeNode parentNode) {
305
        int width = m_Tree.getWidth();
306
        if (width == 0) {
307 38116 cordinyana
            width = 300;
308 35178 jpiera
        }
309
        Dimension sizeLeaf = new Dimension(width, 15);
310 38116 cordinyana
        // Get the tree font height
311
        Font font = m_Tree.getFont();
312
        FontMetrics metrics = this.getFontMetrics(font);
313
        Dimension sizeBranch = new Dimension(width, metrics.getHeight() + 4);
314 7304 caballero
315 38114 cordinyana
        for (int i = theLayers.getLayersCount() - 1; i >= 0; i--) {
316
            FLayer lyr = theLayers.getLayer(i);
317
            if (!lyr.isInTOC()) {
318
                continue;
319
            }
320
            TocItemBranch elTema = new TocItemBranch(lyr);
321
            elTema.setSize(sizeBranch);
322 7304 caballero
323 38114 cordinyana
            DefaultMutableTreeNode nodeLayer =
324
                new DefaultMutableTreeNode(elTema);
325 7304 caballero
326 38114 cordinyana
            m_TreeModel.insertNodeInto(nodeLayer, parentNode,
327
                parentNode.getChildCount());
328 7304 caballero
329 38114 cordinyana
            if (lyr instanceof LayerCollection) {
330
                LayerCollection group = (LayerCollection) lyr;
331
                doRefresh(group, nodeLayer);
332
            } else {
333
                if (lyr instanceof Classifiable) {// && !(lyr instanceof
334
                                                  // FLyrAnnotation)) {
335 7304 caballero
336 38114 cordinyana
                    Classifiable aux = (Classifiable) lyr;
337
                    ILegend legendInfo = aux.getLegend();
338 7304 caballero
339 38114 cordinyana
                    try {
340
                        if (legendInfo instanceof IClassifiedLegend) {
341
                            IClassifiedLegend cl =
342
                                (IClassifiedLegend) legendInfo;
343
                            String[] descriptions = cl.getDescriptions();
344
                            ISymbol[] symbols = cl.getSymbols();
345 22752 vcaballero
346 38114 cordinyana
                            for (int j = 0; j < descriptions.length; j++) {
347
                                TocItemLeaf itemLeaf;
348
                                itemLeaf =
349
                                    new TocItemLeaf(symbols[j],
350
                                        descriptions[j], aux.getShapeType());
351
                                itemLeaf.setSize(sizeLeaf);
352 22752 vcaballero
353 38114 cordinyana
                                DefaultMutableTreeNode nodeValue =
354
                                    new DefaultMutableTreeNode(itemLeaf);
355
                                m_TreeModel.insertNodeInto(nodeValue,
356
                                    nodeLayer, nodeLayer.getChildCount());
357 22752 vcaballero
358 38114 cordinyana
                            }
359
                        }
360 22752 vcaballero
361 38114 cordinyana
                        if (legendInfo instanceof ISingleSymbolLegend
362
                            && (legendInfo.getDefaultSymbol() != null)) {
363
                            TocItemLeaf itemLeaf;
364
                            itemLeaf =
365
                                new TocItemLeaf(legendInfo.getDefaultSymbol(),
366
                                    legendInfo.getDefaultSymbol()
367
                                        .getDescription(), aux.getShapeType());
368
                            itemLeaf.setSize(sizeLeaf);
369 22752 vcaballero
370 38114 cordinyana
                            DefaultMutableTreeNode nodeValue =
371
                                new DefaultMutableTreeNode(itemLeaf);
372
                            m_TreeModel.insertNodeInto(nodeValue, nodeLayer,
373
                                nodeLayer.getChildCount());
374
                        }
375
                    } catch (ReadException e) {
376
                        logger.error(MessageFormat.format(
377
                            "Can't add leyend of layer {0} to the TOC.", lyr),
378
                            e);
379
                    }
380
                } else
381
                    if (lyr instanceof IHasImageLegend) {
382
                        TocItemLeaf itemLeaf;
383
                        IHasImageLegend aux = (IHasImageLegend) lyr;
384
                        Image image = aux.getImageLegend();
385 10626 caballero
386 38114 cordinyana
                        if (image != null) {
387
                            itemLeaf = new TocItemLeaf();
388
                            itemLeaf.setImageLegend(image, "", new Dimension(
389
                                image.getWidth(null), image.getHeight(null)));// new
390
                                                                              // Dimension(150,200));
391 7691 fjp
392 38114 cordinyana
                            DefaultMutableTreeNode nodeValue =
393
                                new DefaultMutableTreeNode(itemLeaf);
394
                            m_TreeModel.insertNodeInto(nodeValue, nodeLayer,
395
                                nodeLayer.getChildCount());
396
                        }
397
                    }
398
            } // if instanceof layers
399
        }
400
    }
401 7304 caballero
402 38114 cordinyana
    /**
403
     * @see com.iver.cit.opensig.gui.toc.ITocOrderListener#orderChanged(int,
404
     *      int)
405
     */
406
    public void orderChanged(int oldPos, int newPos, FLayers lpd) {
407
        try {
408
            lpd.moveTo(oldPos, newPos);
409
        } catch (CancelationException e) {
410
            logger.error("Can't change order of layers in TOC", e);
411
        }
412
        mapContext.invalidate();
413
    }
414 7304 caballero
415 38114 cordinyana
    public void parentChanged(FLayers lpo, FLayers lpd, FLayer ls) {
416
        lpo.move(ls, lpd);
417
        mapContext.invalidate();
418
    }
419 7304 caballero
420 38114 cordinyana
    /*
421
     * (non-Javadoc)
422
     *
423
     * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.
424
     * ComponentEvent)
425
     */
426
    public void componentHidden(ComponentEvent e) {
427
    }
428 7304 caballero
429 38114 cordinyana
    /*
430
     * (non-Javadoc)
431
     *
432
     * @see
433
     * java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent
434
     * )
435
     */
436
    public void componentMoved(ComponentEvent e) {
437
    }
438 7304 caballero
439 38114 cordinyana
    /*
440
     * (non-Javadoc)
441
     *
442
     * @see java.awt.event.ComponentListener#componentResized(java.awt.event.
443
     * ComponentEvent)
444
     */
445
    public void componentResized(ComponentEvent e) {
446
        DefaultMutableTreeNode n;
447
        @SuppressWarnings("rawtypes")
448 34928 jjdelcerro
        Enumeration enumeration = m_Root.children();
449 7304 caballero
450 38114 cordinyana
        while (enumeration.hasMoreElements()) {
451
            n = (DefaultMutableTreeNode) enumeration.nextElement();
452 7304 caballero
453 38114 cordinyana
            if (n.getUserObject() instanceof TocItemBranch) {
454
                ITocItem item = (ITocItem) n.getUserObject();
455
                Dimension szAnt = item.getSize();
456
                item.setSize(new Dimension(this.getWidth() - 40, szAnt.height));
457
            }
458 7304 caballero
459 38114 cordinyana
        }
460
    }
461 7304 caballero
462 38114 cordinyana
    /*
463
     * (non-Javadoc)
464
     *
465
     * @see
466
     * java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent
467
     * )
468
     */
469
    public void componentShown(ComponentEvent e) {
470
    }
471 7304 caballero
472 38114 cordinyana
    /*
473
     * (non-Javadoc)
474
     *
475
     * @see
476
     * com.iver.cit.gvsig.fmap.layers.LayerListener#legendChanged(com.iver.cit
477
     * .gvsig.fmap.rendering.LegendChangedEvent)
478
     */
479
    public void legendChanged(final LegendChangedEvent e) {
480
        if (!SwingUtilities.isEventDispatchThread()) {
481
            SwingUtilities.invokeLater(new Runnable() {
482
483 34928 jjdelcerro
                public void run() {
484
                    legendChanged(e);
485
                }
486
            });
487 38114 cordinyana
            return;
488
        }
489
        refresh();
490
    }
491 7304 caballero
492 38114 cordinyana
    /*
493
     * (non-Javadoc)
494
     *
495
     * @see
496
     * com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerAdded(com
497
     * .iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
498
     */
499
    public void layerAdded(final LayerCollectionEvent e) {
500
        if (!SwingUtilities.isEventDispatchThread()) {
501 34928 jjdelcerro
            SwingUtilities.invokeLater(new Runnable() {
502 38114 cordinyana
503 34928 jjdelcerro
                public void run() {
504
                    layerAdded(e);
505
                }
506
            });
507
            return;
508 38114 cordinyana
        }
509 34928 jjdelcerro
        refresh();
510 38114 cordinyana
    }
511 7304 caballero
512 38114 cordinyana
    /*
513
     * (non-Javadoc)
514
     *
515
     * @see
516
     * com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerMoved(com
517
     * .iver.cit.gvsig.fmap.layers.LayerPositionEvent)
518
     */
519
    public void layerMoved(final LayerPositionEvent e) {
520
        if (!SwingUtilities.isEventDispatchThread()) {
521 34928 jjdelcerro
            SwingUtilities.invokeLater(new Runnable() {
522 38114 cordinyana
523 34928 jjdelcerro
                public void run() {
524
                    layerMoved(e);
525
                }
526
            });
527
            return;
528 38114 cordinyana
        }
529
        refresh();
530
    }
531 7304 caballero
532 38114 cordinyana
    /*
533
     * (non-Javadoc)
534
     *
535
     * @see
536
     * com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerRemoved(com
537
     * .iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
538
     */
539
    public void layerRemoved(final LayerCollectionEvent e) {
540
        if (!SwingUtilities.isEventDispatchThread()) {
541 34928 jjdelcerro
            SwingUtilities.invokeLater(new Runnable() {
542 38114 cordinyana
543 34928 jjdelcerro
                public void run() {
544
                    layerRemoved(e);
545
                }
546
            });
547
            return;
548 38114 cordinyana
        }
549
        m_ItemsExpanded.remove(e.getAffectedLayer().getName());
550
        refresh();
551
    }
552 7304 caballero
553 38114 cordinyana
    /*
554
     * (non-Javadoc)
555
     *
556
     * @see
557
     * com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerAdding(com
558
     * .iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
559
     */
560
    public void layerAdding(LayerCollectionEvent e) throws CancelationException {
561
    }
562 7304 caballero
563 38114 cordinyana
    /*
564
     * (non-Javadoc)
565
     *
566
     * @see
567
     * com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerMoving(com
568
     * .iver.cit.gvsig.fmap.layers.LayerPositionEvent)
569
     */
570
    public void layerMoving(LayerPositionEvent e) throws CancelationException {
571
    }
572 7304 caballero
573 38114 cordinyana
    /*
574
     * (non-Javadoc)
575
     *
576
     * @see
577
     * com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerRemoving(
578
     * com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
579
     */
580
    public void layerRemoving(LayerCollectionEvent e)
581
        throws CancelationException {
582
    }
583 7304 caballero
584 38114 cordinyana
    /*
585
     * (non-Javadoc)
586
     *
587
     * @see
588
     * com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#activationChanged
589
     * (com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
590
     */
591
    public void activationChanged(LayerCollectionEvent e)
592
        throws CancelationException {
593
        repaint();
594
    }
595 7304 caballero
596 38114 cordinyana
    /*
597
     * (non-Javadoc)
598
     *
599
     * @see
600
     * com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#visibilityChanged
601
     * (com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
602
     */
603
    public void visibilityChanged(final LayerCollectionEvent e)
604
        throws CancelationException {
605
        if (!SwingUtilities.isEventDispatchThread()) {
606 34928 jjdelcerro
            SwingUtilities.invokeLater(new Runnable() {
607 38114 cordinyana
608 34928 jjdelcerro
                public void run() {
609
                    visibilityChanged(e);
610
                }
611
            });
612
            return;
613 38114 cordinyana
        }
614
        repaint();
615
    }
616 7304 caballero
617 38114 cordinyana
    /*
618
     * (non-Javadoc)
619
     *
620
     * @see
621
     * javax.swing.event.TreeExpansionListener#treeCollapsed(javax.swing.event
622
     * .TreeExpansionEvent)
623
     */
624
    public void treeCollapsed(TreeExpansionEvent event) {
625
        TreePath path = event.getPath();
626
        DefaultMutableTreeNode n =
627
            (DefaultMutableTreeNode) path.getLastPathComponent();
628 7304 caballero
629 38114 cordinyana
        if (n.getUserObject() instanceof ITocItem) {
630
            ITocItem item = (ITocItem) n.getUserObject();
631
            Boolean b = Boolean.FALSE;
632 7304 caballero
633 38114 cordinyana
            m_ItemsExpanded.put(item.getLabel(), b);
634
        }
635
    }
636 7304 caballero
637 38114 cordinyana
    /*
638
     * (non-Javadoc)
639
     *
640
     * @see
641
     * javax.swing.event.TreeExpansionListener#treeExpanded(javax.swing.event
642
     * .TreeExpansionEvent)
643
     */
644
    public void treeExpanded(TreeExpansionEvent event) {
645
        TreePath path = event.getPath();
646
        DefaultMutableTreeNode n =
647
            (DefaultMutableTreeNode) path.getLastPathComponent();
648 7304 caballero
649 38114 cordinyana
        if (n.getUserObject() instanceof ITocItem) {
650
            ITocItem item = (ITocItem) n.getUserObject();
651
            Boolean b = Boolean.TRUE;
652 7304 caballero
653 38114 cordinyana
            m_ItemsExpanded.put(item.getLabel(), b);
654
        }
655
    }
656 7304 caballero
657 38114 cordinyana
    /**
658
     * Obtiene el JScrollPane que contiene el TOC
659
     *
660
     * @return JScrollPane que contiene el TOC
661
     */
662
    public JScrollPane getJScrollPane() {
663
        return this.m_Scroller;
664
    }
665 7304 caballero
666 38114 cordinyana
    /**
667
     * DOCUMENT ME!
668
     *
669
     * @return DOCUMENT ME!
670
     */
671
    public DnDJTree getTree() {
672
        return m_Tree;
673
    }
674 7304 caballero
675 38114 cordinyana
    /**
676
     * Clase Listener que reacciona al pulsar sobre el checkbox de un nodo y
677
     * crea un popupmenu al pulsar el bot?n derecho.
678
     */
679
    class NodeSelectionListener extends MouseAdapter implements ActionListener {
680 21299 vcaballero
681 38114 cordinyana
        JTree tree;
682 7304 caballero
683 38114 cordinyana
        JDialog dlg;
684 7304 caballero
685 38114 cordinyana
        JColorChooser colorChooser;
686 7304 caballero
687 38114 cordinyana
        FPopupMenu popmenu = null;
688 13731 jaume
689 38114 cordinyana
        DefaultMutableTreeNode node;
690 13752 jaume
691 38114 cordinyana
        /**
692
         * Crea un nuevo NodeSelectionListener.
693
         *
694
         * @param tree
695
         *            DOCUMENT ME!
696
         */
697
        NodeSelectionListener(JTree tree) {
698
            this.tree = tree;
699
        }
700 21299 vcaballero
701 38114 cordinyana
        /**
702
         * DOCUMENT ME!
703
         *
704
         * @param e
705
         *            DOCUMENT ME!
706
         */
707
        public void mouseClicked(MouseEvent e) {
708
            int x = e.getX();
709
            int y = e.getY();
710
            int row = tree.getRowForLocation(x, y);
711
            TreePath path = tree.getPathForRow(row);
712
            LayerCollection layers = mapContext.getLayers();
713 22752 vcaballero
714 38114 cordinyana
            if (path != null) {
715
                if (e.getClickCount() == 1) {
716
                    // this fixes a bug when double-clicking. JTree by default
717
                    // expands the tree when double-clicking, so we capture a
718
                    // different node in the second click than in the first
719
                    node = (DefaultMutableTreeNode) path.getLastPathComponent();
720
                }
721 22752 vcaballero
722 38114 cordinyana
                if (node != null
723
                    && node.getUserObject() instanceof TocItemBranch) {
724
                    // double click with left button ON A BRANCH/NODE (layer)
725
                    if (e.getClickCount() >= 2
726
                        && e.getButton() == MouseEvent.BUTTON1) {
727
                        e.consume();
728
                        PluginServices.getMDIManager().setWaitCursor();
729
                        try {
730
                            TocItemBranch leaf =
731
                                (TocItemBranch) node.getUserObject();
732 22752 vcaballero
733 38114 cordinyana
                            IContextMenuAction action =
734
                                leaf.getDoubleClickAction();
735
                            if (action != null) {
736
                                /*
737
                                 * if there is an action associated with the
738
                                 * double-clicked element it will be fired for
739
                                 * it and FOR ALL OTHER COMPATIBLES THAT HAVE
740
                                 * BEEN ACTIVATED.
741
                                 */
742
                                ArrayList<FLayer> targetLayers =
743
                                    new ArrayList<FLayer>();
744 22752 vcaballero
745 38114 cordinyana
                                TocItemBranch owner =
746
                                    (TocItemBranch) node.getUserObject();
747 13731 jaume
748 38114 cordinyana
                                FLayer masterLayer = owner.getLayer();
749
                                targetLayers.add(masterLayer);
750
                                FLayer[] actives =
751
                                    mapContext.getLayers().getActives();
752
                                for (int i = 0; i < actives.length; i++) {
753
                                    if (actives[i].getClass().equals(
754
                                        masterLayer.getClass())) {
755
                                        if (actives[i] instanceof FLyrVect) {
756
                                            FLyrVect vectorLayer =
757
                                                (FLyrVect) actives[i];
758
                                            FLyrVect vectorMaster =
759
                                                (FLyrVect) masterLayer;
760
                                            if (vectorLayer.getShapeType() == vectorMaster
761
                                                .getShapeType()) {
762
                                                targetLayers.add(vectorLayer);
763
                                            } else {
764
                                                vectorLayer.setActive(false);
765
                                            }
766
                                        }
767
                                        // TODO for the rest of layer types
768
                                        // (i.e. FLyrRaster)
769
                                    } else {
770
                                        actives[i].setActive(false);
771
                                    }
772
                                }
773
                                action.execute(leaf,
774
                                    targetLayers.toArray(new FLayer[0]));
775
                            }
776
                        } catch (Exception ex) {
777
                            NotificationManager.addError(ex);
778
                        } finally {
779
                            PluginServices.getMDIManager().restoreCursor();
780
                        }
781
                        return;
782
                    }
783 7304 caballero
784 38114 cordinyana
                    TocItemBranch elTema = (TocItemBranch) node.getUserObject();
785
                    FLayer lyr = elTema.getLayer();
786
                    lyr.getMapContext().beginAtomicEvent();
787 7304 caballero
788 38114 cordinyana
                    if (((e.getModifiers() & InputEvent.SHIFT_MASK) != 0)
789
                        && (e.getButton() == MouseEvent.BUTTON1)) {
790
                        FLayer[] activeLayers = layers.getActives();
791
                        if (activeLayers.length > 0) {
792
                            selectInterval(layers, lyr);
793
                        } else {
794
                            updateActive(lyr, !lyr.isActive());
795
                        }
796 7304 caballero
797 38114 cordinyana
                    } else {
798
                        if (!((e.getModifiers() & InputEvent.CTRL_MASK) != 0)
799
                            && (e.getButton() == MouseEvent.BUTTON1)) {
800
                            layers.setAllActives(false);
801
                        }
802
                        if (e.getButton() == MouseEvent.BUTTON1) {
803
                            // lyr.setActive(true);
804
                            updateActive(lyr, !lyr.isActive());
805
                        }
806
                    }
807
                    // Si pertenece a un grupo, lo ponemos activo tambi?n.
808
                    // FLayer parentLayer = lyr.getParentLayer();
809 7304 caballero
810 38114 cordinyana
                    /*
811
                     * if (parentLayer != null) { parentLayer.setActive(true); }
812
                     */
813
                    Point layerNodeLocation =
814
                        tree.getUI().getPathBounds(tree, path).getLocation();
815 7304 caballero
816 38114 cordinyana
                    // Rect?ngulo que representa el checkbox
817
                    Rectangle checkBoxBounds =
818
                        m_TocRenderer.getCheckBoxBounds();
819
                    checkBoxBounds.translate((int) layerNodeLocation.getX(),
820
                        (int) layerNodeLocation.getY());
821 7304 caballero
822 38114 cordinyana
                    if (checkBoxBounds.contains(e.getPoint())) {
823
                        updateVisible(lyr);
824
                    }
825 7304 caballero
826 38114 cordinyana
                    // }
827
                    if (e.getButton() == MouseEvent.BUTTON3) {
828
                        // Boton derecho sobre un nodo del arbol
829
                        // if ((e.getModifiers() & InputEvent.META_MASK) != 0) {
830
                        popmenu = new FPopupMenu(mapContext, node);
831
                        tree.add(popmenu);
832 7304 caballero
833 38114 cordinyana
                        popmenu.show(e.getComponent(), e.getX(), e.getY());
834 7304 caballero
835 38114 cordinyana
                        // }
836
                    }
837 7304 caballero
838 38114 cordinyana
                    lyr.getMapContext().endAtomicEvent();
839
                }
840 13731 jaume
841 38114 cordinyana
                if (node != null && node.getUserObject() instanceof TocItemLeaf) {
842
                    // double click with left button ON A LEAF (ISymbol)
843
                    if (e.getClickCount() >= 2
844
                        && e.getButton() == MouseEvent.BUTTON1) {
845
                        e.consume();
846 21299 vcaballero
847 38114 cordinyana
                        PluginServices.getMDIManager().setWaitCursor();
848
                        try {
849
                            TocItemLeaf leaf =
850
                                (TocItemLeaf) node.getUserObject();
851
                            IContextMenuAction action =
852
                                leaf.getDoubleClickAction();
853
                            if (action != null) {
854
                                /*
855
                                 * if there is an action associated with the
856
                                 * double-clicked element it will be fired for
857
                                 * it and FOR ALL OTHER COMPATIBLES THAT HAVE
858
                                 * BEEN ACTIVATED.
859
                                 */
860
                                ArrayList<FLayer> targetLayers =
861
                                    new ArrayList<FLayer>();
862 21299 vcaballero
863 38114 cordinyana
                                TocItemBranch owner =
864
                                    (TocItemBranch) ((DefaultMutableTreeNode) node
865
                                        .getParent()).getUserObject();
866 21299 vcaballero
867 38114 cordinyana
                                FLayer masterLayer = owner.getLayer();
868
                                targetLayers.add(masterLayer);
869
                                FLayer[] actives =
870
                                    mapContext.getLayers().getActives();
871
                                for (int i = 0; i < actives.length; i++) {
872
                                    if (actives[i].getClass().equals(
873
                                        masterLayer.getClass())) {
874
                                        if (actives[i] instanceof FLyrVect) {
875
                                            FLyrVect vectorLayer =
876
                                                (FLyrVect) actives[i];
877
                                            FLyrVect vectorMaster =
878
                                                (FLyrVect) masterLayer;
879
                                            int masterLayerShapetypeOF_THE_LEGEND =
880
                                                ((IVectorLegend) vectorMaster
881
                                                    .getLegend())
882
                                                    .getShapeType();
883
                                            int anotherVectorLayerShapetypeOF_THE_LEGEND =
884
                                                ((IVectorLegend) vectorLayer
885
                                                    .getLegend())
886
                                                    .getShapeType();
887
                                            if (masterLayerShapetypeOF_THE_LEGEND == anotherVectorLayerShapetypeOF_THE_LEGEND) {
888
                                                targetLayers.add(vectorLayer);
889
                                            } else {
890
                                                vectorLayer.setActive(false);
891
                                            }
892
                                        }
893
                                        // TODO for the rest of layer types
894
                                        // (i.e. FLyrRaster)
895
                                    } else {
896
                                        actives[i].setActive(false);
897
                                    }
898
                                }
899
                                action.execute(leaf,
900
                                    targetLayers.toArray(new FLayer[0]));
901
                            }
902
                        } catch (Exception ex) {
903
                            NotificationManager.addError(ex);
904
                        } finally {
905
                            PluginServices.getMDIManager().restoreCursor();
906
                        }
907
                        return;
908
                    }
909 21299 vcaballero
910 38114 cordinyana
                    // Boton derecho sobre un Simbolo
911
                    // TocItemLeaf auxLeaf = (TocItemLeaf) node.getUserObject();
912
                    // FSymbol theSym = auxLeaf.getSymbol();
913
                    if ((e.getModifiers() & InputEvent.META_MASK) != 0) {
914
                        popmenu = new FPopupMenu(mapContext, node);
915
                        tree.add(popmenu);
916
                        popmenu.show(e.getComponent(), e.getX(), e.getY());
917
                    }
918
                }
919 7304 caballero
920 38114 cordinyana
                ((DefaultTreeModel) tree.getModel()).nodeChanged(node);
921 7304 caballero
922 38114 cordinyana
                if (row == 0) {
923
                    tree.revalidate();
924
                    tree.repaint();
925
                }
926 7304 caballero
927 38114 cordinyana
                if (PluginServices.getMainFrame() != null) {
928
                    PluginServices.getMainFrame().enableControls();
929
                }
930
            } else {
931
                if (e.getButton() == MouseEvent.BUTTON3) {
932
                    popmenu = new FPopupMenu(mapContext, null);
933
                    tree.add(popmenu);
934
                    popmenu.show(e.getComponent(), e.getX(), e.getY());
935
                }
936 10626 caballero
937 38114 cordinyana
            }
938
        }
939 7304 caballero
940 38114 cordinyana
        private void selectInterval(LayerCollection layers, FLayer lyr) {
941
            FLayer[] activeLayers = layers.getActives();
942
            // if (activeLayers[0].getParentLayer() instanceof FLayers &&
943
            // activeLayers[0].getParentLayer().getParentLayer()!=null) {
944
            // selectInterval((LayerCollection)activeLayers[0].getParentLayer(),lyr);
945
            // }
946
            for (int j = 0; j < layers.getLayersCount(); j++) {
947
                FLayer layerAux = layers.getLayer(j);
948
                // Si se cumple esta condici?n es porque la primera capa que nos
949
                // encontramos en el TOC es la que estaba activa
950
                if (activeLayers[0].equals(layerAux)) {
951
                    boolean isSelected = false;
952
                    for (int i = 0; i < layers.getLayersCount(); i++) {
953
                        FLayer layer = layers.getLayer(i);
954
                        if (!isSelected) {
955
                            isSelected = layer.isActive();
956
                        } else {
957
                            updateActive(layer, true);
958
                            if (lyr.equals(layer)) {
959
                                isSelected = false;
960
                            }
961
                        }
962
                    }
963
                    break;
964
                } else
965
                    // Si se cumple esta condici?n es porque la primera capa que
966
                    // nos
967
                    // encontramos en el TOC es la que acabamos de seleccionar
968
                    if (lyr.equals(layerAux)) {
969
                        boolean isSelected = false;
970
                        for (int i = layers.getLayersCount() - 1; i >= 0; i--) {
971
                            FLayer layer = layers.getLayer(i);
972
                            if (!isSelected) {
973
                                isSelected = layer.isActive();
974
                            } else {
975
                                updateActive(layer, true);
976
                                if (lyr.equals(layer)) {
977
                                    isSelected = false;
978
                                }
979
                            }
980
                        }
981
                        break;
982
                    }
983
            }
984 7304 caballero
985 38114 cordinyana
        }
986 7304 caballero
987 38114 cordinyana
        /**
988
         * DOCUMENT ME!
989
         *
990
         * @param lyr
991
         *            DOCUMENT ME!
992
         * @param active
993
         *            DOCUMENT ME!
994
         */
995
        private void updateActive(FLayer lyr, boolean active) {
996
            lyr.setActive(active);
997
            updateActiveChild(lyr);
998
        }
999 7304 caballero
1000 38114 cordinyana
        /**
1001
         * DOCUMENT ME!
1002
         *
1003
         * @param lyr
1004
         *            DOCUMENT ME!
1005
         */
1006
        private void updateActiveChild(FLayer lyr) {
1007
            if (lyr instanceof FLayers) { // Es la raiz de una rama o
1008
                // cualquier nodo intermedio.
1009 7304 caballero
1010 38114 cordinyana
                FLayers layergroup = (FLayers) lyr;
1011 7304 caballero
1012 38114 cordinyana
                for (int i = 0; i < layergroup.getLayersCount(); i++) {
1013
                    layergroup.getLayer(i).setActive(lyr.isActive());
1014
                    updateActiveChild(layergroup.getLayer(i));
1015
                }
1016
            }
1017
        }
1018 7304 caballero
1019 38114 cordinyana
        /**
1020
         * Actualiza la visibilidad de la capas.
1021
         *
1022
         * @param lyr
1023
         *            Capa sobre la que se est? clickando.
1024
         */
1025
        private void updateVisible(FLayer lyr) {
1026
            if (lyr.isAvailable()) {
1027
                lyr.setVisible(!lyr.visibleRequired());
1028
                updateVisibleChild(lyr);
1029
                updateVisibleParent(lyr);
1030
            }
1031
        }
1032 7304 caballero
1033 38114 cordinyana
        /**
1034
         * Actualiza de forma recursiva la visibilidad de los hijos de la capa
1035
         * que se pasa como par?metro.
1036
         *
1037
         * @param lyr
1038
         *            Capa a actualizar.
1039
         */
1040
        private void updateVisibleChild(FLayer lyr) {
1041
            if (lyr instanceof FLayers) { // Es la raiz de una rama o
1042
                                          // cualquier nodo intermedio.
1043 7304 caballero
1044 38114 cordinyana
                FLayers layergroup = (FLayers) lyr;
1045 7304 caballero
1046 38114 cordinyana
                for (int i = 0; i < layergroup.getLayersCount(); i++) {
1047
                    layergroup.getLayer(i).setVisible(lyr.visibleRequired());
1048
                    updateVisibleChild(layergroup.getLayer(i));
1049
                }
1050
            }
1051
        }
1052 7304 caballero
1053 38114 cordinyana
        /**
1054
         * Actualiza de forma recursiva la visibilidad del padre de la capa que
1055
         * se pasa como par?metro.
1056
         *
1057
         * @param lyr
1058
         *            Capa a actualizar.
1059
         */
1060
        private void updateVisibleParent(FLayer lyr) {
1061
            FLayers parent = lyr.getParentLayer();
1062 7304 caballero
1063 38114 cordinyana
            if (parent != null) {
1064
                boolean parentVisible = false;
1065 7304 caballero
1066 38114 cordinyana
                for (int i = 0; i < parent.getLayersCount(); i++) {
1067
                    if (parent.getLayer(i).visibleRequired()) {
1068
                        parentVisible = true;
1069
                    }
1070
                }
1071 7304 caballero
1072 38114 cordinyana
                parent.setVisible(parentVisible);
1073
                updateVisibleParent(parent);
1074
            }
1075
        }
1076 7304 caballero
1077 38114 cordinyana
        /**
1078
         * DOCUMENT ME!
1079
         *
1080
         * @param arg0
1081
         *            DOCUMENT ME!
1082
         */
1083
        public void actionPerformed(ActionEvent arg0) {
1084
        }
1085 7304 caballero
1086 38114 cordinyana
        /**
1087
         * DOCUMENT ME!
1088
         *
1089
         * @param arg0
1090
         *            DOCUMENT ME!
1091
         */
1092
        public void mouseReleased(MouseEvent arg0) {
1093
            super.mouseReleased(arg0);
1094
        }
1095 7304 caballero
1096 38114 cordinyana
        /**
1097
         * DOCUMENT ME!
1098
         *
1099
         * @param arg0
1100
         *            DOCUMENT ME!
1101
         */
1102
        public void mouseEntered(MouseEvent arg0) {
1103
            super.mouseEntered(arg0);
1104
        }
1105
    }
1106
1107 7304 caballero
}