Statistics
| Revision:

svn-gvsig-desktop / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / project / documents / view / legend / gui / LegendManager.java @ 33025

History | View | Annotate | Download (27.9 KB)

1
/*
2
 * Created on 08-feb-2005
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
package com.iver.cit.gvsig.project.documents.view.legend.gui;
45

    
46
import java.awt.BorderLayout;
47
import java.awt.Color;
48
import java.awt.Component;
49
import java.awt.Dimension;
50
import java.awt.FlowLayout;
51
import java.awt.event.ActionListener;
52
import java.io.File;
53
import java.util.ArrayList;
54
import java.util.Enumeration;
55
import java.util.Hashtable;
56
import java.util.prefs.Preferences;
57

    
58
import javax.swing.ImageIcon;
59
import javax.swing.JComponent;
60
import javax.swing.JFileChooser;
61
import javax.swing.JLabel;
62
import javax.swing.JOptionPane;
63
import javax.swing.JPanel;
64
import javax.swing.JScrollPane;
65
import javax.swing.JSplitPane;
66
import javax.swing.JTextArea;
67
import javax.swing.JTree;
68
import javax.swing.tree.DefaultMutableTreeNode;
69
import javax.swing.tree.DefaultTreeCellRenderer;
70
import javax.swing.tree.DefaultTreeModel;
71
import javax.swing.tree.TreePath;
72
import javax.swing.tree.TreeSelectionModel;
73

    
74
import org.gvsig.gui.beans.swing.JButton;
75

    
76
import com.iver.andami.PluginServices;
77
import com.iver.andami.messages.NotificationManager;
78
import com.iver.cit.gvsig.exceptions.layers.LegendLayerException;
79
import com.iver.cit.gvsig.fmap.core.FShape;
80
import com.iver.cit.gvsig.fmap.core.FShapeM;
81
import com.iver.cit.gvsig.fmap.drivers.gvl.FMapGVLDriver;
82
import com.iver.cit.gvsig.fmap.drivers.legend.IFMapLegendDriver;
83
import com.iver.cit.gvsig.fmap.drivers.legend.LegendDriverException;
84
import com.iver.cit.gvsig.fmap.layers.FLayer;
85
import com.iver.cit.gvsig.fmap.layers.FLayers;
86
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
87
import com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable;
88
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
89
import com.iver.cit.gvsig.fmap.rendering.IClassifiedVectorLegend;
90
import com.iver.cit.gvsig.fmap.rendering.ILegend;
91
import com.iver.cit.gvsig.fmap.rendering.IVectorLegend;
92
import com.iver.cit.gvsig.fmap.rendering.SingleSymbolLegend;
93
/**
94
 * Implements the panel which allows the user to control all the information about the
95
 * legends of a layer in order to improve the information that it offers to the user.
96
 * There are options to create, save or load an existing legend.
97
 *
98
 * @author jaume dominguez faus - jaume.dominguez@iver.es
99
 */
100
public class LegendManager extends AbstractThemeManagerPage {
101
        private static final long serialVersionUID = 7989057553773181019L;
102
        private static ArrayList<Class<? extends ILegendPanel>> legendPool = new ArrayList<Class<? extends ILegendPanel>>();
103
        private static ArrayList<Class<? extends IFMapLegendDriver>> legendDriverPool = new ArrayList<Class<? extends IFMapLegendDriver>>();
104

    
105
        private FLayer layer;
106
        private ILegend legend; // Le asignaremos la leyenda del primer tema activo.
107
        private Hashtable<Class<? extends ILegendPanel>, ILegendPanel> pages = new Hashtable<Class<? extends ILegendPanel>, ILegendPanel>();
108
        private JPanel topPanel = null;
109
        private JTextArea titleArea = null;
110
        private JPanel preview = null;
111
        private JScrollPane jTitleScrollPane = null;
112
        private JTree jTreeLegends;
113
        private ILegendPanel activePanel;
114
        private JScrollPane legendTreeScrollPane;
115
        private boolean dirtyTree;
116
        private DefaultMutableTreeNode root = new DefaultMutableTreeNode();
117
        private DefaultTreeModel treeModel;
118
        private JScrollPane jPanelContainer;
119
        private JPanel jCentralPanel;
120
        private JSplitPane jSplitPane;
121
        private boolean isTreeListenerDisabled;
122
        private JButton btnSaveLegend;
123
        private JButton btnLoadLegend;
124
        private Hashtable<FLayer, ILegend> table = null;
125
        private boolean empty = true;
126
        private JLabel iconLabel;
127

    
128
        public static String defaultLegendFolderPath;
129
        {
130

    
131
                Preferences prefs = Preferences.userRoot().node( "gvsig.foldering" );
132
                defaultLegendFolderPath = prefs.get("LegendsFolder", "");
133
        }
134
        private ActionListener loadSaveLegendAction = new ActionListener() {
135
                public void actionPerformed(java.awt.event.ActionEvent e) {
136
                        JComponent c = (JComponent) e.getSource();
137
                        if (c.equals(getBtnSaveLegend())) {
138

    
139
                                JLegendFileChooser jfc = new JLegendFileChooser(getLegendDrivers(),true);
140
                                jfc.setAcceptAllFileFilterUsed(false);
141

    
142

    
143
                                File basedir = null;
144

    
145
                                jfc.setCurrentDirectory(basedir);
146
                                if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
147

    
148
                                        File file = jfc.getSelectedFile();
149
                                        String version = jfc.getDriverVersion();
150
                                        IFMapLegendDriver driver = jfc.getSuitableDriver();
151

    
152
                                        if(!(driver instanceof FMapGVLDriver)){
153
                                                Object[] options = {PluginServices.getText(this, "yes"),
154
                                                                PluginServices.getText(this, "no")};
155

    
156
                                                int answer = JOptionPane.showOptionDialog((Component)PluginServices.getMainFrame(),
157
                                                                PluginServices.getText(this, "not_GVL_save_question")+"\n"+
158
                                                                PluginServices.getText(this, "desea_continuar"),
159
                                                                PluginServices.getText(this, "confirmation_dialog"),
160
                                                                JOptionPane.YES_NO_OPTION,
161
                                                                JOptionPane.QUESTION_MESSAGE,
162
                                                                null,
163
                                                                options, options[1]);
164
                                                if (answer!=JOptionPane.OK_OPTION) {
165
                                                        // 'Cancel' pressed or window closed: don't save anythig, exit save dialog
166
                                                        return;
167
                                                }
168
                                        }
169

    
170
                                        if (file.exists()) {
171
                                                Object[] options = {PluginServices.getText(this, "yes"),
172
                                                                PluginServices.getText(this, "no"),
173
                                                                PluginServices.getText(this, "Cancel")};
174

    
175
                                                int answer = JOptionPane.showOptionDialog((Component)PluginServices.getMainFrame(),
176
                                                                PluginServices.getText(this, "fichero_ya_existe_seguro_desea_guardarlo"),
177
                                                                PluginServices.getText(this, "confirmation_dialog"),
178
                                                                JOptionPane.YES_NO_CANCEL_OPTION,
179
                                                                JOptionPane.QUESTION_MESSAGE,
180
                                                                null,
181
                                                                options, options[1]);
182
                                                if (answer!=JOptionPane.OK_OPTION) {
183
                                                        // 'Cancel' pressed or window closed: don't save anythig, exit save dialog
184
                                                        return;
185
                                                }
186
                                        }
187

    
188

    
189
                                        try {
190
                                                driver.write(layer.getMapContext().getLayers(),layer, activePanel.getLegend(), file, version);
191

    
192
                                        } catch (LegendDriverException e1) {
193
                                                int type = e1.getType();
194
                                                String message=PluginServices.getText(this, "could_not_save_legend")+":\n";
195

    
196
                                                if ((type & LegendDriverException.SAVE_LEGEND_ERROR) != 0){
197
                                                        type = type & ~LegendDriverException.SAVE_LEGEND_ERROR;
198
                                                        message += PluginServices.getText(this, "error_writing_file")+".\n";
199
                                                }
200
                                                if ((type & LegendDriverException.UNSUPPORTED_LEGEND_CREATION) != 0){
201
                                                        type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_CREATION;
202
                                                        message += "-"+ PluginServices.getText(this, "legend_format_not_yet_supported")+"\n";
203
                                                }
204
                                                if (type != 0) {
205
                                                        message = "-"+PluginServices.getText(this, "unknown_error")+"\n";
206
                                                }
207
                                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(), message);
208
                                        }
209
                                }
210
                        } else if (c.equals(getBtnLoadLegend())) {
211

    
212
                                JLegendFileChooser jfc = new JLegendFileChooser(getLegendDrivers());
213
                                jfc.setAcceptAllFileFilterUsed(false);
214

    
215
                                if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
216
                                        File file=jfc.getSelectedFile();
217
                                        IFMapLegendDriver driver = jfc.getSuitableDriver();
218
                                        String path = file.getAbsolutePath();
219
                                        defaultLegendFolderPath = path.substring(0, path.lastIndexOf(File.separator));
220

    
221
                                        try {
222
                                                table = driver.read(layer.getMapContext().getLayers(),layer, file);
223

    
224
                                                if(table.containsKey(layer))
225
                                                        applyLegend((ILegend) table.get(layer));
226

    
227

    
228
                                        } catch (LegendDriverException e1) {
229
                                                int type = e1.getType();
230
                                                String message = PluginServices.getText(this, "the_legend_will_not_be_applied")+":\n";
231
                                                boolean hasReason = false;
232

    
233
                                                if ((type & LegendDriverException.CLASSIFICATION_FIELDS_NOT_FOUND) != 0){
234
                                                        type = type & ~LegendDriverException.CLASSIFICATION_FIELDS_NOT_FOUND;
235
                                                        message +="-"+ PluginServices.getText(this, "classification_field_does_not_exists")+"\n";
236
                                                        hasReason = true;
237
                                                }
238
                                                if ((type & LegendDriverException.LEGEND_TYPE_NOT_YET_SUPPORTED) != 0){
239
                                                        type = type & ~LegendDriverException.LEGEND_TYPE_NOT_YET_SUPPORTED;
240
                                                        message += "-"+ PluginServices.getText(this, "legend_type_not_yet_supported")+"\n";
241
                                                        hasReason = true;
242
                                                }
243
                                                if ((type & LegendDriverException.SYMBOL_TYPE_NOT_YET_SUPPORTED) != 0){
244
                                                        type = type & ~LegendDriverException.SYMBOL_TYPE_NOT_YET_SUPPORTED;
245
                                                        message += "-"+ PluginServices.getText(this, "unsupported_symbol_type")+"\n";
246
                                                        hasReason = true;
247
                                                }
248
                                                if ((type & LegendDriverException.LAYER_SHAPETYPE_MISMATCH) != 0){
249
                                                        type = type & ~LegendDriverException.LAYER_SHAPETYPE_MISMATCH;
250
                                                        message += "-"+ PluginServices.getText(this, "layer_geometry_and_legend_types_are_incompatible")+"\n";
251
                                                        hasReason = true;
252
                                                }
253
                                                if ((type & LegendDriverException.PARSE_LEGEND_FILE_ERROR) != 0){
254
                                                        type = type & ~LegendDriverException.PARSE_LEGEND_FILE_ERROR;
255
                                                        message += "-"+ PluginServices.getText(this, "failed_reading_file")+"\n";
256
                                                        hasReason = true;
257
                                                }
258
                                                if ((type & LegendDriverException.UNSUPPORTED_LEGEND_FILE_VERSION) != 0){
259
                                                        type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_FILE_VERSION;
260
                                                        message += "-"+ PluginServices.getText(this, "unsupported_legend_file_version")+"\n";
261
                                                        hasReason = true;
262
                                                }
263
                                                if ((type & LegendDriverException.UNSUPPORTED_LEGEND_READING) != 0){
264
                                                        type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_READING;
265
                                                        message +="-"+ PluginServices.getText(this, "unsupported_legend_file_format")+"\n";
266
                                                        hasReason = true;
267
                                                }
268
                                                if ((type & LegendDriverException.LAYER_NAME_NOT_FOUND) != 0){
269
                                                        type = type & ~LegendDriverException.LAYER_NAME_NOT_FOUND;
270
                                                        message +="-"+ PluginServices.getText(this, "could_not_find_layer")+"\n";
271
                                                        hasReason = true;
272
                                                }
273
                                                if (!hasReason) {
274
                                                        message = "-"+ PluginServices.getText(this, "unknown_error")+"\n";
275
                                                }
276
                                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(), message);
277
                                        }
278
                                        getBtnSaveLegend().setEnabled(activePanel!=null);
279
                                }
280
                        }
281
                }
282

    
283

    
284
                private IFMapLegendDriver[] getLegendDrivers() {
285
                        Class<?>[] legendDriverClasses = legendDriverPool.toArray(new Class[0]);
286
                        ArrayList<IFMapLegendDriver> drivers = new ArrayList<IFMapLegendDriver>();
287
                        for (int i = 0; i < legendDriverClasses.length; i++) {
288
                                String message = PluginServices.getText(this, "adding_legend_file_format_support")+": ";
289
                                try {
290
                                        Class<?> c = legendDriverClasses[i];
291
                                        drivers.add((IFMapLegendDriver) c.newInstance());
292
                                } catch (Exception e) {
293
                                        NotificationManager.addError(message+PluginServices.getText(this, "failed"), e);
294
                                }
295
                                NotificationManager.addInfo(message+PluginServices.getText(this, "OK"));
296

    
297
                        }
298
                        return (IFMapLegendDriver[]) drivers.toArray(new IFMapLegendDriver[0]);
299
                };
300
        };
301

    
302

    
303
        public LegendManager() {
304
                initialize();
305
        }
306

    
307
        private void initialize() {
308
                setLayout(new BorderLayout());
309
                add(getTopPanel(), BorderLayout.NORTH);
310
                add(getSplitPane(), BorderLayout.CENTER);
311
                setSize(500, 360);
312
                treeModel = new DefaultTreeModel(root);
313
        }
314

    
315
        private JSplitPane getSplitPane() {
316
                if (jSplitPane == null) {
317
                        jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
318
                        JPanel aux = new JPanel(new BorderLayout(0, 5));
319
                        aux.add(getLegendTreeScrollPane(), BorderLayout.CENTER);
320
                        aux.add(getPreviewPanel(), BorderLayout.SOUTH);
321
                        jSplitPane.setLeftComponent(aux);
322
                        jSplitPane.setRightComponent(getCentralPanel());
323
                        jSplitPane.setDividerLocation(150);
324
                }
325
                return jSplitPane;
326
        }
327

    
328
        private JPanel getCentralPanel() {
329
                if (jCentralPanel == null) {
330
                        jCentralPanel = new JPanel(new BorderLayout(0,10));
331
                        jCentralPanel.add(getTitleScroll(), BorderLayout.NORTH);
332
                        jCentralPanel.add(getJPanelContainer(), BorderLayout.CENTER);
333
                }
334
                return jCentralPanel;
335
        }
336

    
337
        private JScrollPane getJPanelContainer() {
338
                if (jPanelContainer == null) {
339
                        jPanelContainer = new JScrollPane();
340
                }
341
                return jPanelContainer;
342
        }
343

    
344
        /**
345
         * This method initializes jPanel
346
         *
347
         * @return javax.swing.JPanel
348
         */
349
        private JPanel getTopPanel() {
350
                if (topPanel == null) {
351
                        topPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
352
                        topPanel.setPreferredSize(new Dimension(638, 31));
353
                        topPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
354
                        topPanel.add(getBtnSaveLegend(), null);
355
                        topPanel.add(getBtnLoadLegend(), null);
356
                }
357
                return topPanel;
358
        }
359

    
360
        private JButton getBtnSaveLegend() {
361
                if (btnSaveLegend == null) {
362
                        btnSaveLegend = new JButton(PluginServices.getText(this,"Guardar_leyenda")+"...");
363
                        btnSaveLegend.addActionListener(loadSaveLegendAction);
364
                }
365
                return btnSaveLegend;
366
        }
367

    
368
        private JButton getBtnLoadLegend() {
369
                if (btnLoadLegend == null) {
370
                        btnLoadLegend = new JButton(PluginServices.getText(this,"Recuperar_leyenda")+"...");
371
                        btnLoadLegend.addActionListener(loadSaveLegendAction);
372
                }
373
                return btnLoadLegend;
374
        }
375

    
376
        /**
377
         * This method initializes jTextArea
378
         *
379
         * @return javax.swing.JTextArea
380
         */
381
        private JTextArea getTitleArea() {
382
                if (titleArea == null) {
383
                        titleArea = new JTextArea();
384
                        titleArea.setBackground(java.awt.SystemColor.control);
385
                        titleArea.setLineWrap(true);
386
                        titleArea.setRows(0);
387
                        titleArea.setWrapStyleWord(false);
388
                        titleArea.setEditable(false);
389
                        titleArea.setPreferredSize(new java.awt.Dimension(495,40));
390
                }
391
                return titleArea;
392
        }
393
        /**
394
         * This method initializes jPanel1
395
         *
396
         * @return javax.swing.JPanel
397
         */
398
        private JPanel getPreviewPanel() {
399
                if (preview == null) {
400
                        preview = new JPanel();
401
                        preview.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
402
                        preview.setBackground(java.awt.SystemColor.text);
403
                        preview.setLayout(new BorderLayout(5,5));
404
                        preview.add(getIconLabel());
405
                        preview.setPreferredSize(new Dimension(
406
                                        getSplitPane().getDividerLocation(),
407
                                        130));
408
                        preview.setBackground(Color.white);
409
                }
410
                return preview;
411
        }
412

    
413
        private JLabel getIconLabel() {
414
                if (iconLabel == null) {
415
                        iconLabel = new JLabel();
416
                        iconLabel.setVerticalAlignment(JLabel.CENTER);
417
                        iconLabel.setHorizontalAlignment(JLabel.CENTER);
418
                }
419

    
420
                return iconLabel;
421
        }
422

    
423
        /**
424
         * This method initializes jScrollPane
425
         *
426
         * @return javax.swing.JScrollPane
427
         */
428
        private JScrollPane getLegendTreeScrollPane() {
429
                if (legendTreeScrollPane == null) {
430
                        legendTreeScrollPane = new JScrollPane();
431
                        legendTreeScrollPane.setViewportView(getJTreeLegends());
432
                }
433
                return legendTreeScrollPane;
434
        }
435

    
436
        /**
437
         * <p>Adds a new fully-featured legend panel to the LegendManager.<br></p>
438
         *
439
         * <p><b>CAUTION:</b> Trying to add a child page whose parent hasn't been added yet
440
         * causes the application to fall in an infinite loop. This is a known
441
         * bug, sorry. Just avoid this case or try to fix it (lol).<br></p>
442
         *
443
         * <p><b>Notice</b> that there is no type check so if you add a non-ILegendPanel class,
444
         * you'll have a runtime error later.</p>
445
         * @param page, Class of type ILegendPanel
446
         */
447
        public static void addLegendPage(Class<? extends ILegendPanel> iLegendPanelClass) {
448
                if (!legendPool.contains(iLegendPanelClass)) {
449
                        legendPool.add(iLegendPanelClass);
450
                }
451
        }
452

    
453
        /**
454
         * Causes the component to be autofilled with the legend pages that
455
         * were added through the static method addLegendPage(ILegendPanel page)
456
         */
457
        private void fillDialog() {
458
                if (empty) {
459
                        for (int i = 0; i < legendPool.size(); i++) {
460
                                Class<?> pageClass = (Class<?>) legendPool.get(i);
461
                                ILegendPanel page;
462
                                try {
463
                                        try {
464
                                                page = (ILegendPanel) pageClass.newInstance();
465
                                        } catch (NoClassDefFoundError ex) {
466
                                                NotificationManager.addWarning("Trying to look for this class:" + pageClass.getName(), ex);
467
                                                continue;
468
                                        }
469
                                        if (page.isSuitableFor(layer)) {
470
                                                // this legend can be applied to this layer
471
                                                pages.put(page.getClass(), page);
472

    
473
                                                if (dirtyTree) {
474
                                                        // rebuild page tree
475
                                                        dirtyTree = false;
476

    
477
                                                        ArrayList<ILegendPanel> legList = new ArrayList<ILegendPanel>(pages.values());
478
                                                        ArrayList<ILegendPanel> alreadyAdded = new ArrayList<ILegendPanel>();
479
                                                        DefaultTreeModel model = new DefaultTreeModel(root);
480
                                                        while (legList.size()>0) {
481
                                                                ILegendPanel legend = (ILegendPanel) legList.get(0);
482
                                                                Class<? extends ILegendPanel> parent = legend.getParentClass();
483
                                                                while (parent != null &&
484
                                                                                !alreadyAdded.contains(pages.get(parent))) {
485
                                                                        legend = (ILegendPanel) pages.get(parent);
486
                                                                }
487
                                                                doInsertNode(model, legend);
488
                                                                legList.remove(legend);
489
                                                                alreadyAdded.add(legend);
490
                                                        }
491
                                                        treeModel = model;
492
                                                        jTreeLegends.setModel(model);
493
                                                }
494
                                                doInsertNode(treeModel, page);
495

    
496
                                        }
497
                                        getJTreeLegends().setModel(treeModel);
498

    
499
                                } catch (InstantiationException e) {
500
                                        NotificationManager.addError("Trying to instantiate an interface" +
501
                                                        " or abstract class + "+pageClass.getName(), e);
502
                                } catch (IllegalAccessException e) {
503
                                        NotificationManager.addError("IllegalAccessException: does " +
504
                                                        pageClass.getName()        + " class have an anonymous" +
505
                                                        " constructor?", e);
506
                                }
507
                        }
508
                        getJTreeLegends().repaint();
509
                        empty = false;
510
                }
511
        }
512

    
513
        @SuppressWarnings("unchecked")
514
        private DefaultMutableTreeNode findNode(Class searchID) {
515
                String title;
516
                try {
517
                        title = ((ILegendPanel) Class.forName(searchID.getName()).newInstance()).getTitle();
518
                } catch (Exception e) {
519
                        // this should be impossible, but anyway this case will be treat as the node does not
520
                        // exist.
521
                        return null;
522
                }
523

    
524
                Enumeration e = root.breadthFirstEnumeration();
525
                while (e.hasMoreElements()) {
526
                        DefaultMutableTreeNode nodeAux = (DefaultMutableTreeNode) e.nextElement();
527
                        if (nodeAux != null) {
528
                                ILegendPanel legend = (ILegendPanel) nodeAux.getUserObject();
529
                                if (legend == null) continue; // Root node
530
                                if (legend.getTitle().equals(title)) {
531
                                        return nodeAux;
532
                                }
533
                        }
534
                }
535
                return null;
536
        }
537

    
538
        private void doInsertNode(DefaultTreeModel treeModel, ILegendPanel page) {
539
                dirtyTree = ((page.getParentClass() != null) && (findNode(page.getParentClass())==null));
540
                if (findNode(page.getClass()) != null) // It is already added
541
                        return;
542
                if (page.getParentClass() != null) {
543
                        if (pages.containsKey(page.getParentClass())) {
544
                                ILegendPanel parent = (ILegendPanel) pages.get(page.getParentClass());
545
                                DefaultMutableTreeNode nodeParent = findNode(parent.getClass());
546
                                if (nodeParent == null) {
547
                                        // the parent is empty
548
                                        // Recursively add it
549
                                        doInsertNode(treeModel, parent);
550
                                } else {
551
                                        DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(page);
552
                                        int children = nodeParent.getChildCount();
553
                                        int pos=0;
554
                                        for (int i = 0; i < children; i++) {
555
                                                DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeModel.getChild(nodeParent, i);
556
                                                if (node.getUserObject() instanceof ILegendPanel) {
557
                                                        String pageTitle = ((ILegendPanel) node.getUserObject()).getTitle();
558
                                                        if (pageTitle.compareTo(page.getTitle()) < 0) ++pos;
559
                                                }
560
                                        }
561
                                        treeModel.insertNodeInto(nodeValue, nodeParent, pos);
562
                                }
563
                        }
564
                } else {
565
                        // First level node
566
                        DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(page);
567
                        int children = root.getChildCount();
568
                        int pos=0;
569
                        for (int i = 0; i < children; i++) {
570
                                DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeModel.getChild(root, i);
571
                                if (node.getUserObject() instanceof ILegendPanel) {
572
                                        String pageTitle = ((ILegendPanel) node.getUserObject()).getTitle();
573
                                        if (pageTitle.compareTo(page.getTitle()) < 0) ++pos;
574
                                }
575
                        }
576
                        treeModel.insertNodeInto(nodeValue, root, pos);
577
                }
578
        }
579

    
580
        private JScrollPane getTitleScroll() {
581
                if (jTitleScrollPane == null) {
582
                        jTitleScrollPane = new JScrollPane();
583
                        jTitleScrollPane.setBounds(2, 2, 498, 42);
584
                        jTitleScrollPane.setViewportView(getTitleArea());
585
                }
586
                return jTitleScrollPane;
587
        }
588

    
589
        private JTree getJTreeLegends() {
590
                if (jTreeLegends == null) {
591
                        jTreeLegends = new JTree();
592
                        jTreeLegends.setRootVisible(false);
593
                        MyTreeCellRenderer treeCellRenderer = new MyTreeCellRenderer();
594
                        treeCellRenderer.setOpenIcon(null);
595
                        treeCellRenderer.setClosedIcon(null);
596
                        treeCellRenderer.setLeafIcon(null);
597

    
598
                        jTreeLegends.setCellRenderer(treeCellRenderer);
599
                        jTreeLegends.setShowsRootHandles(true);
600
                        jTreeLegends.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
601
                                public void valueChanged(javax.swing.event.TreeSelectionEvent e) {
602
                                        if (isTreeListenerDisabled) return;
603
                                        DefaultMutableTreeNode node = (DefaultMutableTreeNode)
604
                                        jTreeLegends.getLastSelectedPathComponent();
605

    
606
                                        if (node == null) return;
607
                                        setActivePage((ILegendPanel) node.getUserObject());
608
                                        getBtnSaveLegend().setEnabled(activePanel!=null);
609
                                }
610
                        });
611
                        jTreeLegends.putClientProperty("JTree.linestyle", "Angled");
612
                        jTreeLegends.getSelectionModel().
613
                        setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
614
                }
615
                return jTreeLegends;
616
        }
617

    
618
        private void setActivePage(ILegendPanel page) {
619
                if (page.getPanel() == null) {
620
                        // this is what happens when the user clicked in a parent node
621
                        // which only acts as a folder, and does not manage any legend
622
                        // then it expands and selects the first child
623
                        DefaultMutableTreeNode node = findNode(page.getClass());
624
                        if (treeModel.getChildCount(node)>0) {
625
                                DefaultMutableTreeNode dmn = (DefaultMutableTreeNode) treeModel.getChild(node, 0);
626
                                page = (ILegendPanel) dmn.getUserObject();
627
                                setActivePage(page);
628
                                expandAndSelect(page);
629
                        } else {
630
                                activePanel = null;
631
                                getTitleArea().setText("");
632
                                jPanelContainer.setViewportView(null);
633
                                setIcon(null);
634
                        }
635
                } else {
636
                        // show the page
637
                        activePanel = page;
638
                        setIcon(activePanel.getIcon());
639

    
640
                        activePanel.setData(layer, legend);
641
                        getTitleArea().setText(activePanel.getDescription());
642
                        jPanelContainer.setViewportView(activePanel.getPanel());
643
                }
644
        }
645

    
646

    
647
        private void setIcon(ImageIcon icon) {
648
                getIconLabel().setIcon(icon);
649
        }
650

    
651

    
652
        private class MyTreeCellRenderer extends DefaultTreeCellRenderer {
653
                private static final long serialVersionUID = -6013698992263578041L;
654

    
655
                public MyTreeCellRenderer() {}
656

    
657
                public Component getTreeCellRendererComponent(
658
                                JTree tree,
659
                                Object value,
660
                                boolean sel,
661
                                boolean expanded,
662
                                boolean leaf,
663
                                int row,
664
                                boolean hasFocus) {
665

    
666
                        super.getTreeCellRendererComponent(
667
                                        tree, value, sel,
668
                                        expanded, leaf, row,
669
                                        hasFocus);
670
                        if (value instanceof DefaultMutableTreeNode)
671
                        {
672
                                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
673
                                if (node.getUserObject() instanceof ILegendPanel)
674
                                {
675
                                        ILegendPanel legend = (ILegendPanel) node.getUserObject();
676
                                        this.setText(
677
                                                        legend.getPanel() == null ? "<html><b>"+legend.getTitle()+"</b></html>":legend.getTitle());
678
                                }
679
                        }
680
                        return this;
681
                }
682

    
683
        }
684

    
685
        private void expandAndSelect(Object node) {
686
                isTreeListenerDisabled = true;
687
                // will expand the tree and select the node
688
                int i = 0;
689
                boolean exit = false;
690

    
691
                TreePath tp = null;
692
                // find the page in the tree
693
                while (i<jTreeLegends.getRowCount() && !exit) {
694
                        //see if this row is the node that we are looking for
695

    
696
                        tp = jTreeLegends.getPathForRow(i);
697
                        Object[] obj = tp.getPath();
698
                        for (int j = 0; j < obj.length && !exit ; j++) {
699
                                Object o = ((DefaultMutableTreeNode) obj[j]).getUserObject();
700

    
701
                                if (o!=null        && o.getClass().equals(node.getClass())        && o.equals(node)) {
702
                                        // found it! collapse the tree
703
                                        while (i>=0) {
704
                                                jTreeLegends.collapseRow(i);
705
                                                i--;
706
                                        }
707
                                        exit = true;
708
                                }
709
                        }
710
                        jTreeLegends.expandRow(i);
711
                        i++;
712
                }
713

    
714
                // expand the tree and set the selection
715
                if (tp != null) {
716
                        jTreeLegends.expandPath(tp);
717
                        jTreeLegends.setSelectionPath(tp);
718
                }
719
                isTreeListenerDisabled = false;
720
        }
721

    
722
        public String getName() {
723
                return PluginServices.getText(this,"Simbologia");
724
        }
725

    
726
        public void acceptAction() {
727
                // automatically handled by the ThemeManagerWindow
728
        }
729

    
730
        public void cancelAction() {
731
                // does nothing
732
        }
733

    
734
        public void applyAction() {
735
                if(activePanel != null){
736
                        legend = activePanel.getLegend();
737

    
738

    
739
                        if (table != null && table.size() > 1)
740
                                applyRestOfLegends(table,layer.getMapContext().getLayers());
741

    
742
                        /* try to apply the legend to all the active layers that
743
                 can accept it */
744
                        FLayer[] activeLyrs = layer.getMapContext().getLayers().getActives();
745
                        for (int i=0; i < activeLyrs.length; i++) {
746
                                FLayer laux=activeLyrs[i];
747

    
748
                                if (activeLyrs[i] instanceof FLayers){
749
                                        laux=getFirstActiveLayerVect((FLayers)activeLyrs[i]);
750
                                }
751

    
752
                                if (laux instanceof ClassifiableVectorial) {
753
                                        ClassifiableVectorial aux2 = (ClassifiableVectorial) laux;
754
                                        try {
755
                                                if (legend instanceof IClassifiedVectorLegend) {
756
                                                        // Es una leyenda que necesita un recordset con un
757
                                                        // nombre de campo. Comprobamos que ese recordset
758
                                                        // tiene ese nombre de campo y es del tipo esperado
759
                                                        IClassifiedVectorLegend cl = (IClassifiedVectorLegend) legend;
760

    
761
                                                        if (aux2 instanceof AlphanumericData) {
762

    
763
                                                                if (cl.getValues().length==0) {
764
                                                                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this,"no_es_posible_aplicar_leyenda_vacia"));
765
                                                                        return;
766
                                                                }
767

    
768
                                                                aux2.setLegend((IVectorLegend) legend);
769
                                                        }
770
                                                }
771
                                                else if (legend instanceof SingleSymbolLegend)
772
                                                        aux2.setLegend((IVectorLegend) legend);
773
                                        } catch (LegendLayerException e) {
774
                                                NotificationManager.addError(PluginServices.getText(this, "legend_exception"), e);
775
                                        }
776
                                }
777
                        }
778
                }
779
        }
780

    
781
        private void applyRestOfLegends(Hashtable<FLayer, ILegend> table2,FLayers layers) {
782

    
783
                for(int i = 0; i < layers.getLayersCount(); i++) {
784
                        FLayer my_layer= layers.getLayer(i);
785

    
786
                        if(!(my_layer instanceof FLayers)){
787
                                if(my_layer instanceof ClassifiableVectorial){
788
                                        try {
789
                                                if(table.containsKey(my_layer)){
790
                                                        ClassifiableVectorial lyr = (ClassifiableVectorial)my_layer;
791
                                                        lyr.setLegend((IVectorLegend) table.get(my_layer));
792
                                                }
793

    
794
                                        } catch (LegendLayerException e) {
795
                                                // TODO Auto-generated catch block
796
                                                e.printStackTrace();
797
                                        }
798
                                }
799
                        }
800
                        else
801
                                applyRestOfLegends(table,(FLayers) my_layer);
802
                }
803
        }
804

    
805
        @Override
806
        public void setModel(FLayer layer) {
807
                this.layer = layer;
808
                applyLegend(((Classifiable) layer).getLegend());
809
        }
810

    
811
        /**
812
         * Applies the legend to the layer.
813
         *
814
         * @param aLegend , legend that the user wants to apply
815
         */
816
        private void applyLegend(ILegend aLegend) {
817
                this.legend = aLegend;
818
                fillDialog();
819
                Enumeration<Class<? extends ILegendPanel>> en = pages.keys();
820
                while (en.hasMoreElements()) {
821
                        ILegendPanel page = (ILegendPanel) pages.get(en.nextElement());
822
                        if (legend.getClass().equals(page.getLegendClass())) {
823
                                setActivePage(page);
824
                                expandAndSelect(page);
825
                                return;
826
                        }
827
                }
828
                NotificationManager.addWarning(
829
                                PluginServices.getText(this,
830
                                                "caution_no_registered_panel_associated_to_" +
831
                                                "loaded_legend_the_legend_wont_be_applied"));
832
        }
833

    
834
        public static void addLegendDriver(Class<? extends IFMapLegendDriver> legendDriverClass) {
835
                if (!legendDriverPool.contains(legendDriverClass)) {
836
                        legendDriverPool.add(legendDriverClass);
837
                }
838
        }
839
}