Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / project / documents / view / legend / gui / LegendManager.java @ 41400

History | View | Annotate | Download (38.8 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.app.project.documents.view.legend.gui;
25

    
26
import java.awt.BorderLayout;
27
import java.awt.Color;
28
import java.awt.Component;
29
import java.awt.Dimension;
30
import java.awt.FlowLayout;
31
import java.awt.event.ActionListener;
32
import java.io.File;
33
import java.io.FileInputStream;
34
import java.io.FileNotFoundException;
35
import java.io.FileOutputStream;
36
import java.io.InputStream;
37
import java.io.OutputStream;
38
import java.util.ArrayList;
39
import java.util.Enumeration;
40
import java.util.Hashtable;
41
import java.util.Iterator;
42
import java.util.List;
43
import java.util.prefs.Preferences;
44

    
45
import javax.swing.ImageIcon;
46
import javax.swing.JButton;
47
import javax.swing.JComponent;
48
import javax.swing.JFileChooser;
49
import javax.swing.JLabel;
50
import javax.swing.JOptionPane;
51
import javax.swing.JPanel;
52
import javax.swing.JScrollPane;
53
import javax.swing.JSplitPane;
54
import javax.swing.JTextArea;
55
import javax.swing.JTree;
56
import javax.swing.filechooser.FileFilter;
57
import javax.swing.tree.DefaultMutableTreeNode;
58
import javax.swing.tree.DefaultTreeCellRenderer;
59
import javax.swing.tree.DefaultTreeModel;
60
import javax.swing.tree.MutableTreeNode;
61
import javax.swing.tree.TreePath;
62
import javax.swing.tree.TreeSelectionModel;
63

    
64
import org.slf4j.Logger;
65
import org.slf4j.LoggerFactory;
66

    
67
import org.gvsig.andami.PluginServices;
68
import org.gvsig.andami.messages.NotificationManager;
69
import org.gvsig.app.ApplicationLocator;
70
import org.gvsig.fmap.geom.Geometry;
71
import org.gvsig.fmap.mapcontext.MapContextLocator;
72
import org.gvsig.fmap.mapcontext.MapContextManager;
73
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
74
import org.gvsig.fmap.mapcontext.exceptions.WriteLegendException;
75
import org.gvsig.fmap.mapcontext.layers.FLayer;
76
import org.gvsig.fmap.mapcontext.layers.FLayers;
77
import org.gvsig.fmap.mapcontext.layers.operations.Classifiable;
78
import org.gvsig.fmap.mapcontext.layers.operations.ClassifiableVectorial;
79
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
80
import org.gvsig.fmap.mapcontext.rendering.legend.IClassifiedVectorLegend;
81
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
82
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
83
import org.gvsig.fmap.mapcontext.rendering.legend.driver.ILegendReader;
84
import org.gvsig.fmap.mapcontext.rendering.legend.driver.ILegendWriter;
85
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
86
import org.gvsig.i18n.Messages;
87
import org.gvsig.symbology.swing.SymbologySwingLocator;
88
import org.gvsig.symbology.swing.SymbologySwingManager;
89
import org.gvsig.tools.ToolsLocator;
90
import org.gvsig.tools.persistence.PersistenceManager;
91

    
92
/**
93
 * Implements the panel which allows the user to control all the information
94
 * about the
95
 * legends of a layer in order to improve the information that it offers to the
96
 * user.
97
 * There are options to create, save or load an existing legend.
98
 * 
99
 * @author jaume dominguez faus - jaume.dominguez@iver.es
100
 */
101
public class LegendManager extends AbstractThemeManagerPage {
102

    
103
    private static final Logger logger =
104
        LoggerFactory.getLogger(LegendManager.class);
105
    
106
    private static final long serialVersionUID = 7989057553773181019L;
107
//    private static ArrayList<Class<? extends ILegendPanel>> legendPool =
108
//        new ArrayList<Class<? extends ILegendPanel>>();
109
    // private static ArrayList<Class<? extends IFMapLegendDriver>>
110
    // legendDriverPool = new ArrayList<Class<? extends IFMapLegendDriver>>();
111

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

    
136
    public static String defaultLegendFolderPath;
137
    {
138

    
139
        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
140
        defaultLegendFolderPath = prefs.get("LegendsFolder", "");
141
    }
142
    
143
    private ActionListener loadSaveLegendAction = new ActionListener() {
144

    
145
        public void actionPerformed(java.awt.event.ActionEvent e) {
146
            JComponent c = (JComponent) e.getSource();
147
            if (c.equals(getBtnSaveLegend())) {
148
                
149
                try {
150
                    saveLegend();
151
                } catch (Exception exc) {
152
                    JOptionPane.showMessageDialog(
153
                        ApplicationLocator.getManager().getRootComponent(),
154
                        Messages.getText("_Unable_to_save_legend")
155
                        + "\n\n" + exc.getMessage(),
156
                        Messages.getText("legend"),
157
                        JOptionPane.WARNING_MESSAGE);
158
                    return;
159
                }
160

    
161
            } else
162
                if (c.equals(getBtnLoadLegend())) {
163
                    try {
164
                        loadLegend();
165
                    } catch (Exception e1) {
166
                        JOptionPane.showMessageDialog(
167
                            ApplicationLocator.getManager().getRootComponent(),
168
                            Messages.getText("_Unable_to_read_legend")
169
                            + "\n\n" + e1.getMessage(),
170
                            Messages.getText("legend"),
171
                            JOptionPane.WARNING_MESSAGE);
172
                        return;
173
                    }
174
                }
175
        }
176

    
177
        private void saveLegend() throws Exception {
178
            
179
            List<LegendFileFilter> filters = getLegendFileFilters(true);
180
            if (filters.size() == 0) {
181
                JOptionPane.showMessageDialog(
182
                    ApplicationLocator.getManager().getRootComponent(),
183
                    Messages.getText("_No_output_format_available"),
184
                    Messages.getText("legend"),
185
                    JOptionPane.WARNING_MESSAGE);
186
                return;
187
            }
188

    
189
            ILegend legend = activePanel.getLegend();
190
            MapContextManager mcoman = MapContextLocator.getMapContextManager();
191
            
192
            JFileChooser fileChooser = new JFileChooser();
193
            fileChooser.setAcceptAllFileFilterUsed(false);
194
            
195
            for (int i=0; i<filters.size(); i++) {
196
                fileChooser.addChoosableFileFilter(filters.get(i));
197
            }
198

    
199
            if (fileChooser.showSaveDialog(
200
                ApplicationLocator.getManager().getRootComponent())
201
                == JFileChooser.APPROVE_OPTION) {
202
                
203
                LegendFileFilter lff = (LegendFileFilter) fileChooser.getFileFilter();
204
                
205
                File selfile = fileChooser.getSelectedFile();
206
                if (!selfile.getAbsolutePath().toLowerCase().endsWith(
207
                    "." + lff.getFileExtension().toLowerCase())) {
208
                    
209
                    selfile = new File(selfile.getAbsolutePath() +
210
                        "." + lff.getFileExtension().toLowerCase());
211
                }
212
                
213
                ILegendWriter lw = null;
214
                lw = mcoman.createLegendWriter(legend.getClass(), lff.getFileExtension());
215
                
216
                if (lw == null) {
217
                    throw new WriteLegendException(legend,
218
                        new Exception("Unable to create legend writer."));
219
                } else {
220
                    lw.write(legend, selfile, lff.getFileExtension());
221
                }
222
            }
223
        }
224

    
225
        /**
226
         * 
227
         * @param writing true for writing; false for reading
228
         * @return
229
         */
230
        private List<LegendFileFilter> getLegendFileFilters(boolean writing) {
231
            
232
            List<LegendFileFilter> resp = new ArrayList<LegendFileFilter>();
233
            MapContextManager mcoman = MapContextLocator.getMapContextManager();
234
            List wformats = null;
235
            
236
            if (writing) {
237
                wformats = mcoman.getLegendWritingFormats();
238
            } else {
239
                wformats = mcoman.getLegendReadingFormats();
240
            }
241
            
242
            String fmt = null;
243
            for (int i=0; i<wformats.size(); i++) {
244
                fmt = (String) wformats.get(i);
245
                fmt = getFileExtension(fmt);
246
                if (fmt != null) {
247
                    resp.add(new LegendFileFilter(fmt));
248
                }
249
            }
250
            return resp;
251
        }
252
        
253
        
254
        /**
255
         * Returns null if mime format is not parsed properly
256
         * 
257
         * @param fmt MIME format
258
         * 
259
         * @return
260
         */
261
        private String getFileExtension(String fmt) {
262
            // Example: "text/xml; subtype=gml/2.1.2" => "gml"
263
            if (fmt == null) {
264
                return null;
265
            }
266
            String[] parts = fmt.split(";");
267
            String aux = "";
268
            if (parts.length > 1) {
269
                aux = parts[1].trim();
270
            } else {
271
                aux = parts[0].trim();
272
            }
273
            parts = aux.split("=");
274
            if (parts.length > 1) {
275
                aux = parts[1].trim();
276
                // Example: aux = "gml/2.1.2"
277
                parts = aux.split("/");
278
                return parts[0].length() == 0 ? null : parts[0].toLowerCase();
279
            } else {
280
                aux = parts[0].trim();
281
                // Example: "text/xml"
282
                parts = aux.split("/");
283
                if (parts.length > 1) {
284
                    return parts[1].length() == 0 ? null : parts[1].toLowerCase();
285
                } else {
286
                    return aux.length() == 0 ? null : aux.toLowerCase();
287
                }
288
            }
289
        }        
290

    
291
        private void loadLegend() throws Exception {
292
            
293
            List<LegendFileFilter> filters = getLegendFileFilters(false);
294
            if (filters.size() == 0) {
295
                JOptionPane.showMessageDialog(
296
                    ApplicationLocator.getManager().getRootComponent(),
297
                    Messages.getText("_No_input_format_available"),
298
                    Messages.getText("legend"),
299
                    JOptionPane.WARNING_MESSAGE);
300
                return;
301
            }
302

    
303
            JFileChooser fileChooser = new JFileChooser();
304
            fileChooser.setAcceptAllFileFilterUsed(false);
305
            
306
            for (int i=0; i<filters.size(); i++) {
307
                fileChooser.addChoosableFileFilter(filters.get(i));
308
            }
309

    
310
            // open a file
311
            if (fileChooser.showOpenDialog((Component) PluginServices
312
                .getMainFrame()) == JFileChooser.APPROVE_OPTION) {
313
                
314
                File file = fileChooser.getSelectedFile();
315
                LegendFileFilter lff = (LegendFileFilter) fileChooser.getFileFilter();
316
                MapContextManager mcoman = MapContextLocator.getMapContextManager();
317
                ILegendReader lr = mcoman.createLegendReader(lff.getFileExtension());
318
                
319
                ILegend leg = lr.read(file, Geometry.TYPES.GEOMETRY);
320
                applyLegend(leg);
321
            }
322
        }
323
    };
324

    
325
    //
326
    // JLegendFileChooser jfc = new
327
    // JLegendFileChooser(getLegendDrivers(),true);
328
    // jfc.setAcceptAllFileFilterUsed(false);
329
    //
330
    //
331
    // File basedir = null;
332
    // jfc.setCurrentDirectory(basedir);
333
    // if (jfc.showSaveDialog((Component) PluginServices.getMainFrame())
334
    // == JFileChooser.APPROVE_OPTION) {
335
    //
336
    // File file = jfc.getSelectedFile();
337
    // String version = jfc.getDriverVersion();
338
    // IFMapLegendDriver driver = jfc.getSuitableDriver();
339
    //
340
    // if(!(driver instanceof FMapGVLDriver)){
341
    // Object[] options = {PluginServices.getText(this, "yes"),
342
    // PluginServices.getText(this, "no")};
343
    //
344
    // int answer =
345
    // JOptionPane.showOptionDialog((Component)PluginServices.getMainFrame(),
346
    // PluginServices.getText(this, "not_GVSLEG_save_question")+"\n"+ //GVL
347
    // changed to GVSLEG, be aware
348
    // PluginServices.getText(this, "desea_continuar"),
349
    // PluginServices.getText(this, "confirmation_dialog"),
350
    // JOptionPane.YES_NO_OPTION,
351
    // JOptionPane.QUESTION_MESSAGE,
352
    // null,
353
    // options, options[1]);
354
    // if (answer!=JOptionPane.OK_OPTION) {
355
    // // 'Cancel' pressed or window closed: don't save anythig, exit
356
    // save dialog
357
    // return;
358
    // }
359
    // }
360
    //
361
    // if (file.exists()) {
362
    // Object[] options = {PluginServices.getText(this, "yes"),
363
    // PluginServices.getText(this, "no"),
364
    // PluginServices.getText(this, "Cancel")};
365
    //
366
    // int answer =
367
    // JOptionPane.showOptionDialog((Component)PluginServices.getMainFrame(),
368
    // PluginServices.getText(this,
369
    // "fichero_ya_existe_seguro_desea_guardarlo"),
370
    // PluginServices.getText(this, "confirmation_dialog"),
371
    // JOptionPane.YES_NO_CANCEL_OPTION,
372
    // JOptionPane.QUESTION_MESSAGE,
373
    // null,
374
    // options, options[1]);
375
    // if (answer!=JOptionPane.OK_OPTION) {
376
    // // 'Cancel' pressed or window closed: don't save anythig, exit
377
    // save dialog
378
    // return;
379
    // }
380
    // }
381
    //
382
    //
383
    // try {
384
    // driver.write(layer.getMapContext().getLayers(),layer,
385
    // activePanel.getLegend(), file, version);
386
    //
387
    // } catch (LegendDriverException e1) {
388
    // int type = e1.getType();
389
    // String message=PluginServices.getText(this,
390
    // "could_not_save_legend")+":\n";
391
    //
392
    // if ((type & LegendDriverException.SAVE_LEGEND_ERROR) != 0){
393
    // type = type & ~LegendDriverException.SAVE_LEGEND_ERROR;
394
    // message += PluginServices.getText(this,
395
    // "error_writing_file")+".\n";
396
    // }
397
    // if ((type & LegendDriverException.UNSUPPORTED_LEGEND_CREATION) !=
398
    // 0){
399
    // type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_CREATION;
400
    // message += "-"+ PluginServices.getText(this,
401
    // "legend_format_not_yet_supported")+"\n";
402
    // }
403
    // if (type != 0) {
404
    // message = "-"+PluginServices.getText(this, "unknown_error")+"\n";
405
    // }
406
    // JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
407
    // message);
408
    // }
409
    // }
410
    // } else if (c.equals(getBtnLoadLegend())) {
411
    //
412
    // JLegendFileChooser jfc = new
413
    // JLegendFileChooser(getLegendDrivers());
414
    // jfc.setAcceptAllFileFilterUsed(false);
415
    //
416
    // if (jfc.showOpenDialog((Component) PluginServices.getMainFrame())
417
    // == JFileChooser.APPROVE_OPTION) {
418
    // File file=jfc.getSelectedFile();
419
    // IFMapLegendDriver driver = jfc.getSuitableDriver();
420
    // String path = file.getAbsolutePath();
421
    // defaultLegendFolderPath = path.substring(0,
422
    // path.lastIndexOf(File.separator));
423
    //
424
    // try {
425
    // table = driver.read(layer.getMapContext().getLayers(),layer,
426
    // file);
427
    //
428
    // if(table.containsKey(layer))
429
    // applyLegend((ILegend) table.get(layer));
430
    //
431
    //
432
    // } catch (LegendDriverException e1) {
433
    // int type = e1.getType();
434
    // String message = PluginServices.getText(this,
435
    // "the_legend_will_not_be_applied")+":\n";
436
    // boolean hasReason = false;
437
    //
438
    // if ((type &
439
    // LegendDriverException.CLASSIFICATION_FIELDS_NOT_FOUND) != 0){
440
    // type = type &
441
    // ~LegendDriverException.CLASSIFICATION_FIELDS_NOT_FOUND;
442
    // message +="-"+ PluginServices.getText(this,
443
    // "classification_field_does_not_exists")+"\n";
444
    // hasReason = true;
445
    // }
446
    // if ((type & LegendDriverException.LEGEND_TYPE_NOT_YET_SUPPORTED)
447
    // != 0){
448
    // type = type &
449
    // ~LegendDriverException.LEGEND_TYPE_NOT_YET_SUPPORTED;
450
    // message += "-"+ PluginServices.getText(this,
451
    // "legend_type_not_yet_supported")+"\n";
452
    // hasReason = true;
453
    // }
454
    // if ((type & LegendDriverException.SYMBOL_TYPE_NOT_YET_SUPPORTED)
455
    // != 0){
456
    // type = type &
457
    // ~LegendDriverException.SYMBOL_TYPE_NOT_YET_SUPPORTED;
458
    // message += "-"+ PluginServices.getText(this,
459
    // "unsupported_symbol_type")+"\n";
460
    // hasReason = true;
461
    // }
462
    // if ((type & LegendDriverException.LAYER_SHAPETYPE_MISMATCH) !=
463
    // 0){
464
    // type = type & ~LegendDriverException.LAYER_SHAPETYPE_MISMATCH;
465
    // message += "-"+ PluginServices.getText(this,
466
    // "layer_geometry_and_legend_types_are_incompatible")+"\n";
467
    // hasReason = true;
468
    // }
469
    // if ((type & LegendDriverException.PARSE_LEGEND_FILE_ERROR) != 0){
470
    // type = type & ~LegendDriverException.PARSE_LEGEND_FILE_ERROR;
471
    // message += "-"+ PluginServices.getText(this,
472
    // "failed_reading_file")+"\n";
473
    // hasReason = true;
474
    // }
475
    // if ((type &
476
    // LegendDriverException.UNSUPPORTED_LEGEND_FILE_VERSION) != 0){
477
    // type = type &
478
    // ~LegendDriverException.UNSUPPORTED_LEGEND_FILE_VERSION;
479
    // message += "-"+ PluginServices.getText(this,
480
    // "unsupported_legend_file_version")+"\n";
481
    // hasReason = true;
482
    // }
483
    // if ((type & LegendDriverException.UNSUPPORTED_LEGEND_READING) !=
484
    // 0){
485
    // type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_READING;
486
    // message +="-"+ PluginServices.getText(this,
487
    // "unsupported_legend_file_format")+"\n";
488
    // hasReason = true;
489
    // }
490
    // if ((type & LegendDriverException.LAYER_NAME_NOT_FOUND) != 0){
491
    // type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_READING;
492
    // message +="-"+ PluginServices.getText(this,
493
    // "could_not_find_layer")+"\n";
494
    // hasReason = true;
495
    // }
496
    // if (!hasReason) {
497
    // message = "-"+ PluginServices.getText(this,
498
    // "unknown_error")+"\n";
499
    // }
500
    // JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
501
    // message);
502
    // }
503
    // }
504
    // }
505

    
506
    // private IFMapLegendDriver[] getLegendDrivers() {
507
    // Class<?>[] legendDriverClasses = legendDriverPool.toArray(new Class[0]);
508
    // ArrayList<IFMapLegendDriver> drivers = new
509
    // ArrayList<IFMapLegendDriver>();
510
    // for (int i = 0; i < legendDriverClasses.length; i++) {
511
    // String message = PluginServices.getText(this,
512
    // "adding_legend_file_format_support")+": ";
513
    // try {
514
    // Class<?> c = legendDriverClasses[i];
515
    // drivers.add((IFMapLegendDriver) c.newInstance());
516
    // } catch (Exception e) {
517
    // NotificationManager.addError(message+PluginServices.getText(this,
518
    // "failed"), e);
519
    // }
520
    // NotificationManager.addInfo(message+PluginServices.getText(this, "OK"));
521
    //
522
    // }
523
    // return (IFMapLegendDriver[]) drivers.toArray(new IFMapLegendDriver[0]);
524
    // };
525

    
526
    private String getExtension(File f) {
527
        String ext = null;
528
        String s = f.getName();
529
        int i = s.lastIndexOf('.');
530

    
531
        if (i > 0 && i < s.length() - 1) {
532
            // ext = s.substring(i + 1).toLowerCase();
533
            ext = s.substring(i).toLowerCase();
534
        }
535
        return ext;
536
    }
537

    
538
    public LegendManager() {
539
        initialize();
540
    }
541

    
542
    private void initialize() {
543
        setLayout(new BorderLayout());
544
        add(getTopPanel(), BorderLayout.NORTH);
545
        add(getSplitPane(), BorderLayout.CENTER);
546
        setSize(500, 360);
547
        treeModel = new DefaultTreeModel(root);
548
    }
549

    
550
    private JSplitPane getSplitPane() {
551
        if (jSplitPane == null) {
552
            jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
553
            JPanel aux = new JPanel(new BorderLayout(0, 5));
554
            aux.add(getLegendTreeScrollPane(), BorderLayout.CENTER);
555
            aux.add(getPreviewPanel(), BorderLayout.SOUTH);
556
            jSplitPane.setLeftComponent(aux);
557
            jSplitPane.setRightComponent(getCentralPanel());
558
            jSplitPane.setDividerLocation(150);
559
        }
560
        return jSplitPane;
561
    }
562

    
563
    private JPanel getCentralPanel() {
564
        if (jCentralPanel == null) {
565
            jCentralPanel = new JPanel(new BorderLayout(0, 10));
566
            jCentralPanel.add(getTitleScroll(), BorderLayout.NORTH);
567
            jCentralPanel.add(getJPanelContainer(), BorderLayout.CENTER);
568
        }
569
        return jCentralPanel;
570
    }
571

    
572
    private JScrollPane getJPanelContainer() {
573
        if (jPanelContainer == null) {
574
            jPanelContainer = new JScrollPane();
575
        }
576
        return jPanelContainer;
577
    }
578

    
579
    /**
580
     * This method initializes jPanel
581
     * 
582
     * @return javax.swing.JPanel
583
     */
584
    private JPanel getTopPanel() {
585
        if (topPanel == null) {
586
            topPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
587
            topPanel.setPreferredSize(new Dimension(638, 31));
588
            topPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
589
                null, "",
590
                javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
591
                javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
592
            topPanel.add(getBtnSaveLegend(), null);
593
            topPanel.add(getBtnLoadLegend(), null);
594
        }
595
        return topPanel;
596
    }
597

    
598
    private JButton getBtnSaveLegend() {
599
        if (btnSaveLegend == null) {
600
            btnSaveLegend =
601
                new JButton(PluginServices.getText(this, "Guardar_leyenda")
602
                    + "...");
603
            btnSaveLegend.addActionListener(loadSaveLegendAction);
604
        }
605
        return btnSaveLegend;
606
    }
607

    
608
    private JButton getBtnLoadLegend() {
609
        if (btnLoadLegend == null) {
610
            btnLoadLegend =
611
                new JButton(PluginServices.getText(this, "Recuperar_leyenda")
612
                    + "...");
613
            btnLoadLegend.addActionListener(loadSaveLegendAction);
614
        }
615
        return btnLoadLegend;
616
    }
617

    
618
    /**
619
     * This method initializes jTextArea
620
     * 
621
     * @return javax.swing.JTextArea
622
     */
623
    private JTextArea getTitleArea() {
624
        if (titleArea == null) {
625
            titleArea = new JTextArea();
626
            titleArea.setBackground(java.awt.SystemColor.control);
627
            titleArea.setLineWrap(true);
628
            titleArea.setRows(0);
629
            titleArea.setWrapStyleWord(false);
630
            titleArea.setEditable(false);
631
            titleArea.setPreferredSize(new java.awt.Dimension(495, 40));
632
        }
633
        return titleArea;
634
    }
635

    
636
    /**
637
     * This method initializes jPanel1
638
     * 
639
     * @return javax.swing.JPanel
640
     */
641
    private JPanel getPreviewPanel() {
642
        if (preview == null) {
643
            preview = new JPanel();
644
            preview.setBorder(javax.swing.BorderFactory
645
                .createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
646
            preview.setBackground(java.awt.SystemColor.text);
647
            preview.setLayout(new BorderLayout(5, 5));
648
            preview.add(getIconLabel());
649
            preview.setPreferredSize(new Dimension(getSplitPane()
650
                .getDividerLocation(), 130));
651
            preview.setBackground(Color.white);
652
        }
653
        return preview;
654
    }
655

    
656
    private JLabel getIconLabel() {
657
        if (iconLabel == null) {
658
            iconLabel = new JLabel();
659
            iconLabel.setVerticalAlignment(JLabel.CENTER);
660
            iconLabel.setHorizontalAlignment(JLabel.CENTER);
661
        }
662

    
663
        return iconLabel;
664
    }
665

    
666
    /**
667
     * This method initializes jScrollPane
668
     * 
669
     * @return javax.swing.JScrollPane
670
     */
671
    private JScrollPane getLegendTreeScrollPane() {
672
        if (legendTreeScrollPane == null) {
673
            legendTreeScrollPane = new JScrollPane();
674
            legendTreeScrollPane.setViewportView(getJTreeLegends());
675
        }
676
        return legendTreeScrollPane;
677
    }
678

    
679
    /**
680
     * <p>
681
     * Adds a new fully-featured legend panel to the LegendManager.<br>
682
     * </p>
683
     * 
684
     * <p>
685
     * <b>CAUTION:</b> Trying to add a child page whose parent hasn't been added
686
     * yet causes the application to fall in an infinite loop. This is a known
687
     * bug, sorry. Just avoid this case or try to fix it (lol).<br>
688
     * </p>
689
     * 
690
     * @param page
691
     *            , Class of type ILegendPanel
692
     * @deprecated use SymbologySwingManager.registerLegendEditor
693
     */
694
    public static void addLegendPage(Class<? extends ILegendPanel> iLegendPanelClass) {
695
        SymbologySwingManager manager = SymbologySwingLocator.getSwingManager();
696
        manager.registerLegendEditor(iLegendPanelClass);
697
    }
698

    
699
    /**
700
     * Causes the component to be autofilled with the legend pages that
701
     * were added through the static method addLegendPage(ILegendPanel page)
702
     */
703
    private void fillDialog() {
704
        if (empty) {
705
            SymbologySwingManager manager = SymbologySwingLocator.getSwingManager();
706
              
707
            Iterator<ILegendPanel> it = manager.getLegendEditors(layer).iterator();
708
            while( it.hasNext() ) {
709
                ILegendPanel page = it.next();
710
                pages.put(page.getClass(), page); 
711
            }
712
            
713
            Enumeration<ILegendPanel> enume = pages.elements();
714
            while (enume.hasMoreElements()) {
715
                ILegendPanel page = enume.nextElement();
716
                doInsertNode(treeModel, page);
717
            }
718
            getJTreeLegends().setModel(treeModel);
719
            getJTreeLegends().repaint();
720
            empty = false;
721
        }
722
    }
723

    
724
    @SuppressWarnings("unchecked")
725
    private DefaultMutableTreeNode findNode(Class searchID) {
726
        String title;
727
        try {
728
            title =
729
                ((ILegendPanel) Class.forName(searchID.getName()).newInstance())
730
                    .getTitle();
731
        } catch (Exception e) {
732
            // this should be impossible, but anyway this case will be treat as
733
            // the node does not
734
            // exist.
735
            return null;
736
        }
737

    
738
        Enumeration e = root.breadthFirstEnumeration();
739
        while (e.hasMoreElements()) {
740
            DefaultMutableTreeNode nodeAux =
741
                (DefaultMutableTreeNode) e.nextElement();
742
            if (nodeAux != null) {
743
                ILegendPanel legend = (ILegendPanel) nodeAux.getUserObject();
744
                if (legend == null)
745
                    continue; // Root node
746
                if (legend.getTitle().equals(title)) {
747
                    return nodeAux;
748
                }
749
            }
750
        }
751
        return null;
752
    }
753

    
754
    /**
755
     * If parent_node == null, add to root.
756
     * Returns added node
757
     * 
758
     * @param tm
759
     * @param parent_node
760
     * @param item
761
     */
762
    private MutableTreeNode insertNodeHere(
763
        DefaultTreeModel tm,
764
        MutableTreeNode parent_node,
765
        ILegendPanel item) {
766
        
767
        MutableTreeNode pn = null;
768
        
769
        if (parent_node == null) {
770
            pn = root;
771
        } else {
772
            pn = parent_node;
773
        }
774
        
775
        DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(item);
776
        int children = pn.getChildCount();
777
        int pos = 0;
778
        String pTitle = null;
779
        
780
        for (int i = 0; i < children; i++) {
781
            DefaultMutableTreeNode node =
782
                (DefaultMutableTreeNode) tm.getChild(pn, i);
783
            if (node.getUserObject() instanceof ILegendPanel) {
784
                pTitle = ((ILegendPanel) node.getUserObject()).getTitle();
785
                if (pTitle.compareTo(item.getTitle()) < 0) {
786
                    pos++;
787
                }
788
            }
789
        }
790
        tm.insertNodeInto(nodeValue, pn, pos);
791
        return nodeValue;
792
    }
793
    
794
    /**
795
     * Returns inserted node
796
     * 
797
     * @param tm
798
     * @param page
799
     * @return
800
     */
801
    private MutableTreeNode doInsertNode(DefaultTreeModel tm, ILegendPanel page) {
802
        
803
        if (tm == null || page == null) {
804
            return null;
805
        }
806
        
807
        MutableTreeNode aux = findNode(page.getClass()); 
808
        if (aux != null) {
809
            return aux;
810
        }
811

    
812
        Class parent_class = page.getParentClass();
813
        
814
        if (parent_class != null) {
815
            if (pages.containsKey(parent_class)) {
816
                ILegendPanel parent = (ILegendPanel) pages.get(parent_class);
817
                
818
                aux = doInsertNode(tm, parent); 
819
                if (aux != null) {
820
                    return insertNodeHere(tm, aux, page);
821
                } else {
822
                    return null;
823
                }
824
                
825
            } else {
826
                return null;
827
            }
828
        } else {
829
            // add to root
830
            return insertNodeHere(tm, null, page);
831
        }
832
        
833

    
834
    }
835
    
836
    
837
    
838
    
839

    
840
    private JScrollPane getTitleScroll() {
841
        if (jTitleScrollPane == null) {
842
            jTitleScrollPane = new JScrollPane();
843
            jTitleScrollPane.setBounds(2, 2, 498, 42);
844
            jTitleScrollPane.setViewportView(getTitleArea());
845
        }
846
        return jTitleScrollPane;
847
    }
848

    
849
    private JTree getJTreeLegends() {
850
        if (jTreeLegends == null) {
851
            jTreeLegends = new JTree();
852
            jTreeLegends.setRootVisible(false);
853
            MyTreeCellRenderer treeCellRenderer = new MyTreeCellRenderer();
854
            treeCellRenderer.setOpenIcon(null);
855
            treeCellRenderer.setClosedIcon(null);
856
            treeCellRenderer.setLeafIcon(null);
857

    
858
            jTreeLegends.setCellRenderer(treeCellRenderer);
859
            jTreeLegends.setShowsRootHandles(true);
860
            jTreeLegends
861
                .addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
862

    
863
                    public void valueChanged(
864
                        javax.swing.event.TreeSelectionEvent e) {
865
                        if (isTreeListenerDisabled)
866
                            return;
867
                        DefaultMutableTreeNode node =
868
                            (DefaultMutableTreeNode) jTreeLegends
869
                                .getLastSelectedPathComponent();
870

    
871
                        if (node == null)
872
                            return;
873
                        setActivePage((ILegendPanel) node.getUserObject());
874
                    }
875
                });
876
            jTreeLegends.putClientProperty("JTree.linestyle", "Angled");
877
            jTreeLegends.getSelectionModel().setSelectionMode(
878
                TreeSelectionModel.SINGLE_TREE_SELECTION);
879
        }
880
        return jTreeLegends;
881
    }
882

    
883
    private void setActivePage(ILegendPanel page) {
884
        if (page.getPanel() == null) {
885
            // this is what happens when the user clicked in a parent node
886
            // which only acts as a folder, and does not manage any legend
887
            // then it expands and selects the first child
888
            DefaultMutableTreeNode node = findNode(page.getClass());
889
            if (treeModel.getChildCount(node) > 0) {
890
                DefaultMutableTreeNode dmn =
891
                    (DefaultMutableTreeNode) treeModel.getChild(node, 0);
892
                page = (ILegendPanel) dmn.getUserObject();
893
                setActivePage(page);
894
                expandAndSelect(page);
895
            }
896
        } else {
897
            // show the page
898
            activePanel = page;
899
            setIcon(activePanel.getIcon());
900

    
901
            activePanel.setData(layer, legend);
902
            getTitleArea().setText(activePanel.getDescription());
903
            jPanelContainer.setViewportView(activePanel.getPanel());
904
        }
905
    }
906

    
907
    private void setIcon(ImageIcon icon) {
908
        getIconLabel().setIcon(icon);
909
    }
910

    
911
    private class MyTreeCellRenderer extends DefaultTreeCellRenderer {
912

    
913
        private static final long serialVersionUID = -6013698992263578041L;
914

    
915
        public MyTreeCellRenderer() {
916
        }
917

    
918
        public Component getTreeCellRendererComponent(JTree tree, Object value,
919
            boolean sel, boolean expanded, boolean leaf, int row,
920
            boolean hasFocus) {
921

    
922
            super.getTreeCellRendererComponent(tree, value, sel, expanded,
923
                leaf, row, hasFocus);
924
            if (value instanceof DefaultMutableTreeNode) {
925
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
926
                if (node.getUserObject() instanceof ILegendPanel) {
927
                    ILegendPanel legend = (ILegendPanel) node.getUserObject();
928
                    this
929
                        .setText(legend.getPanel() == null ? "<html><b>"
930
                            + legend.getTitle() + "</b></html>" : legend
931
                            .getTitle());
932
                }
933
            }
934
            return this;
935
        }
936

    
937
    }
938

    
939
    private void expandAndSelect(Object node) {
940
        isTreeListenerDisabled = true;
941
        // will expand the tree and select the node
942
        int i = 0;
943
        boolean exit = false;
944

    
945
        TreePath tp = null;
946
        // find the page in the tree
947
        while (i < jTreeLegends.getRowCount() && !exit) {
948
            // see if this row is the node that we are looking for
949

    
950
            tp = jTreeLegends.getPathForRow(i);
951
            Object[] obj = tp.getPath();
952
            for (int j = 0; j < obj.length && !exit; j++) {
953
                Object o = ((DefaultMutableTreeNode) obj[j]).getUserObject();
954

    
955
                if (o != null && o.getClass().equals(node.getClass())
956
                    && o.equals(node)) {
957
                    // found it! collapse the tree
958
                    while (i >= 0) {
959
                        jTreeLegends.collapseRow(i);
960
                        i--;
961
                    }
962
                    exit = true;
963
                }
964
            }
965
            jTreeLegends.expandRow(i);
966
            i++;
967
        }
968

    
969
        // expand the tree and set the selection
970
        if (tp != null) {
971
            jTreeLegends.expandPath(tp);
972
            jTreeLegends.setSelectionPath(tp);
973
        }
974
        isTreeListenerDisabled = false;
975
    }
976

    
977
    public String getName() {
978
        return PluginServices.getText(this, "Simbologia");
979
    }
980

    
981
    public void acceptAction() {
982
        // automatically handled by the ThemeManagerWindow
983
    }
984

    
985
    public void cancelAction() {
986
        // does nothing
987
    }
988

    
989
    public void applyAction() {
990
        legend = activePanel.getLegend();
991

    
992
        if (table != null && table.size() > 1)
993
            applyRestOfLegends(table, layer.getMapContext().getLayers());
994

    
995
        /*
996
         * try to apply the legend to all the active layers that
997
         * can accept it
998
         */
999
        FLayer[] activeLyrs = layer.getMapContext().getLayers().getActives();
1000
        for (int i = 0; i < activeLyrs.length; i++) {
1001
            FLayer laux = activeLyrs[i];
1002

    
1003
            if (activeLyrs[i] instanceof FLayers) {
1004
                laux = getFirstActiveLayerVect((FLayers) activeLyrs[i]);
1005
            }
1006

    
1007
            if (laux instanceof ClassifiableVectorial) {
1008
                ClassifiableVectorial aux2 = (ClassifiableVectorial) laux;
1009
                try {
1010
                    if (legend instanceof IClassifiedVectorLegend) {
1011
                        // Es una leyenda que necesita un recordset con un
1012
                        // nombre de campo. Comprobamos que ese recordset
1013
                        // tiene ese nombre de campo y es del tipo esperado
1014
                        IClassifiedVectorLegend cl =
1015
                            (IClassifiedVectorLegend) legend;
1016

    
1017
                        if (aux2 instanceof FLyrVect) {
1018

    
1019
                            if (cl.getValues().length == 0) {
1020
                                JOptionPane.showMessageDialog(
1021
                                    (Component) PluginServices.getMainFrame(),
1022
                                    PluginServices.getText(this,
1023
                                        "no_es_posible_aplicar_leyenda_vacia"));
1024
                                return;
1025
                            }
1026

    
1027
                            aux2.setLegend((IVectorLegend) legend);
1028
                        }
1029
                    } else
1030
                        if (legend instanceof IVectorLegend) {
1031
                            aux2.setLegend((IVectorLegend) legend);
1032
                        }
1033
                } catch (LegendLayerException e) {
1034
                    NotificationManager.addError(PluginServices.getText(this,
1035
                        "legend_exception"), e);
1036
                }
1037
            }
1038
        }
1039
    }
1040

    
1041
    private void applyRestOfLegends(Hashtable<FLayer, ILegend> table2,
1042
        FLayers layers) {
1043

    
1044
        for (int i = 0; i < layers.getLayersCount(); i++) {
1045
            FLayer my_layer = layers.getLayer(i);
1046

    
1047
            if (!(my_layer instanceof FLayers)) {
1048
                if (my_layer instanceof ClassifiableVectorial) {
1049
                    try {
1050
                        if (table.containsKey(my_layer)) {
1051
                            ClassifiableVectorial lyr =
1052
                                (ClassifiableVectorial) my_layer;
1053
                            lyr.setLegend((IVectorLegend) table.get(my_layer));
1054
                        }
1055

    
1056
                    } catch (LegendLayerException e) {
1057
                        // TODO Auto-generated catch block
1058
                        e.printStackTrace();
1059
                    }
1060
                }
1061
            } else
1062
                applyRestOfLegends(table, (FLayers) my_layer);
1063
        }
1064
    }
1065

    
1066
    @Override
1067
    public void setModel(FLayer layer) {
1068
        this.layer = layer;
1069
        applyLegend(((Classifiable) layer).getLegend());
1070
    }
1071

    
1072
    /**
1073
     * Applies the legend to the layer.
1074
     * 
1075
     * @param aLegend
1076
     *            , legend that the user wants to apply
1077
     */
1078
    private void applyLegend(ILegend aLegend) {
1079
        this.legend = aLegend;
1080
        fillDialog();
1081
        Enumeration<Class<? extends ILegendPanel>> en = pages.keys();
1082
        while (en.hasMoreElements()) {
1083
            ILegendPanel page = (ILegendPanel) pages.get(en.nextElement());
1084
            if (legend.getClass().equals(page.getLegendClass())) {
1085
                setActivePage(page);
1086
                expandAndSelect(page);
1087
                return;
1088
            }
1089
        }
1090
        NotificationManager.addWarning(PluginServices.getText(this,
1091
            "caution_no_registered_panel_associated_to_"
1092
                + "loaded_legend_the_legend_wont_be_applied"));
1093
    }
1094

    
1095
    // public static void addLegendDriver(Class<? extends IFMapLegendDriver>
1096
    // legendDriverClass) {
1097
    // if (!legendDriverPool.contains(legendDriverClass)) {
1098
    // legendDriverPool.add(legendDriverClass);
1099
    // }
1100
    // }
1101
}