Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2061 / frameworks / _fwAndami / src / org / gvsig / andami / ui / mdiFrame / MDIFrame.java @ 39425

History | View | Annotate | Download (62.4 KB)

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

    
43
import java.awt.BorderLayout;
44
import java.awt.Component;
45
import java.awt.Dimension;
46
import java.awt.FlowLayout;
47
import java.awt.Insets;
48
import java.awt.event.ActionEvent;
49
import java.awt.event.ActionListener;
50
import java.awt.event.ComponentEvent;
51
import java.awt.event.ComponentListener;
52
import java.awt.event.ContainerEvent;
53
import java.awt.event.ContainerListener;
54
import java.awt.event.MouseAdapter;
55
import java.awt.event.MouseEvent;
56
import java.awt.event.WindowAdapter;
57
import java.awt.event.WindowEvent;
58
import java.util.ArrayList;
59
import java.util.Enumeration;
60
import java.util.HashMap;
61
import java.util.Iterator;
62
import java.util.Map;
63
import java.util.Map.Entry;
64
import java.util.NoSuchElementException;
65
import java.util.StringTokenizer;
66
import java.util.Vector;
67

    
68
import javax.swing.AbstractButton;
69
import javax.swing.ButtonGroup;
70
import javax.swing.ImageIcon;
71
import javax.swing.JComponent;
72
import javax.swing.JFrame;
73
import javax.swing.JMenu;
74
import javax.swing.JMenuBar;
75
import javax.swing.JOptionPane;
76
import javax.swing.JPanel;
77
import javax.swing.JPopupMenu;
78
import javax.swing.JSeparator;
79
import javax.swing.JToolBar;
80
import javax.swing.MenuElement;
81
import javax.swing.SwingUtilities;
82
import javax.swing.Timer;
83
import javax.swing.WindowConstants;
84

    
85
import org.slf4j.Logger;
86
import org.slf4j.LoggerFactory;
87

    
88
import org.gvsig.andami.IconThemeHelper;
89
import org.gvsig.andami.Launcher;
90
import org.gvsig.andami.LibraryExtension;
91
import org.gvsig.andami.PluginServices;
92
import org.gvsig.andami.PluginsLocator;
93
import org.gvsig.andami.actioninfo.ActionInfo;
94
import org.gvsig.andami.actioninfo.ActionInfoManager;
95
import org.gvsig.andami.actioninfo.ActionInfoStatusCache;
96
import org.gvsig.andami.messages.Messages;
97
import org.gvsig.andami.plugins.ExtensionDecorator;
98
import org.gvsig.andami.plugins.IExtension;
99
import org.gvsig.andami.plugins.PluginClassLoader;
100
import org.gvsig.andami.plugins.config.generate.ActionTool;
101
import org.gvsig.andami.plugins.config.generate.Label;
102
import org.gvsig.andami.plugins.config.generate.Menu;
103
import org.gvsig.andami.plugins.config.generate.PopupMenu;
104
import org.gvsig.andami.plugins.config.generate.SelectableTool;
105
import org.gvsig.andami.plugins.config.generate.SkinExtensionType;
106
import org.gvsig.andami.plugins.config.generate.ToolBar;
107
import org.gvsig.andami.ui.mdiManager.MDIManager;
108
import org.gvsig.andami.ui.mdiManager.MDIManagerFactory;
109
import org.gvsig.gui.beans.controls.IControl;
110
import org.gvsig.tools.swing.api.ToolsSwingLocator;
111
import org.gvsig.tools.swing.icontheme.IconTheme;
112

    
113
/**
114
 * Main application window.
115
 * 
116
 * @version $Revision: 39425 $
117
 */
118
@SuppressWarnings("unchecked")
119
public class MDIFrame extends JFrame implements ComponentListener,
120
    ContainerListener, ActionListener, MainFrame {
121

    
122
    private static final long serialVersionUID = -2472484309160847654L;
123

    
124
    private static Logger logger = LoggerFactory.getLogger(MDIFrame.class);
125
    private MDIManager mdiManager = MDIManagerFactory.createManager();
126

    
127
    /** Elementos de la aplicaci�n */
128
    private JMenuBar menuBar = new JMenuBar();
129

    
130
    /** Panel which contains the toolbars */
131
    private JPanel toolBars = new JPanel();
132

    
133
    /** Status bar */
134
    private NewStatusBar bEstado = null;
135

    
136
    /** Asocia los nombres con las barras de herramientas */
137
    private HashMap toolBarMap = new HashMap();
138

    
139
    /** Almacena los grupos de selectableTools */
140
    private HashMap buttonGroupMap = new HashMap();
141
    /**
142
     * Stores the initially selected tools.
143
     * It contains pairs (String groupName, JToolBarToggleButton button)
144
     */
145
    private HashMap initialSelectedTools = new HashMap();
146

    
147
    /**
148
     * Stores the actionCommand of the selected tool, for each group.
149
     * It contains pairs (String groupName, JToolBarToggleButton button)
150
     */
151
    private Map selectedTool = null;
152
    // this should be the same value defined at plugin-config.xsd
153
    private String defaultGroup = "unico";
154

    
155
    /** Asocia los nombres con los popupMenus */
156
    private HashMap popupMap = new HashMap();
157

    
158
    /** Asocia controles con la clase de la extension asociada */
159
    private HashMap controlClass = new HashMap();
160

    
161
    /**
162
     * Asocia la informaci�n sobre las etiquetas que van en la status bar con
163
     * cada extension
164
     */
165
    private HashMap classLabels = new HashMap();
166

    
167
    // private HashMap classControls = new HashMap();
168

    
169
    /** ProgressListeners (ver interfaz com.iver.mdiApp.ui.ProgressListener) */
170
    private ArrayList progressListeners = new ArrayList();
171

    
172
    /** Timer para invocar los enventos de la interfaz anterior */
173
        private Timer progressTimer = null;
174

    
175
    /** Tabla hash que asocia las clases con las extensiones */
176
    private Map classesExtensions = new HashMap<Class<? extends IExtension>, ExtensionDecorator>();
177

    
178
    /** �ltima clase que activ� etiquetas */
179
    private Class lastLabelClass;
180

    
181
    /** Instancia que pone los tooltip en la barra de estado */
182
    private TooltipListener tooltipListener = new TooltipListener();
183
    
184
        private HashMap infoCodedMenus = new HashMap();
185

    
186
    private String titlePrefix;
187

    
188
    private static final String noIcon = "no-icon";
189

    
190
    /**
191
     * Makes some initialization tasks.
192
     * 
193
     * @throws RuntimeException
194
     *             DOCUMENT ME!
195
     */
196
    public void init() {
197
            JPopupMenu.setDefaultLightWeightPopupEnabled(false);
198
        if (!SwingUtilities.isEventDispatchThread()) {
199
            throw new RuntimeException("Not Event Dispatch Thread");
200
        }
201

    
202
        // Se a�aden los listeners del JFrame
203
        this.addWindowListener(new WindowAdapter() {
204

    
205
            @Override
206
            public void windowClosing(WindowEvent e) {
207
                Launcher.closeApplication();
208
            }
209
        });
210
        this.addComponentListener(this);
211
        this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
212

    
213
        // Se configura la barra de menu
214
        setJMenuBar(menuBar);
215

    
216
        // Se configura el layout del JFrame principal
217
        this.getContentPane().setLayout(new BorderLayout());
218

    
219
        /*
220
         * Se configura y se a�ade el JPanel de las barras de
221
         * herramientas
222
         */
223
        FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
224
        layout.setHgap(0);
225
        layout.setVgap(0);
226
        toolBars.setLayout(layout);
227
        getContentPane().add(toolBars, BorderLayout.PAGE_START);
228

    
229
        // Se a�ade la barra de estado a la aplicaci�n
230
        bEstado = new NewStatusBar();
231
        bEstado.message(Messages.getString("StatusBar.Aplicacion_iniciada"), JOptionPane.INFORMATION_MESSAGE);
232
        getContentPane().add(bEstado, BorderLayout.SOUTH);
233

    
234
        this.toolBars.addContainerListener(this);
235

    
236

    
237
        /*
238
         * Setting default values. Persistence is read
239
         * afterwards
240
         */
241
        setSize(
242
            MainFrame.MAIN_FRAME_SIZE_DEFAULT[0],
243
            MainFrame.MAIN_FRAME_SIZE_DEFAULT[1]);
244
        setLocation(
245
            MainFrame.MAIN_FRAME_POS_DEFAULT[0],
246
            MainFrame.MAIN_FRAME_POS_DEFAULT[1]);
247
        setExtendedState(
248
            MainFrame.MAIN_FRAME_EXT_STATE_DEFAULT);
249

    
250
        mdiManager.init(this);
251
        
252
        /*
253
         * pack() would resize the main frame
254
         * 
255
         */
256
        // pack();
257

    
258
    }
259
    
260
    
261

    
262
    /*
263
     * (non-javadoc)
264
     * 
265
     * @see java.awt.Frame.setTitle(String title)
266
     */
267
    @Override
268
    public void setTitle(final String title) {
269
        if (!SwingUtilities.isEventDispatchThread()) {
270
            SwingUtilities.invokeLater(new Runnable() {
271
                public void run() {
272
                        setTitle(title);
273
                }
274
            });
275
            return;
276
        }
277
        super.setTitle(titlePrefix + " : " + title);
278
    }
279

    
280
    /**
281
     * A�ade un modo de operaci�n a la caja de herramientas
282
     * 
283
     * @param ext
284
     *            Texto del boton, si es null no aparece texto
285
     * @param ext
286
     *            Icono del boton, si es null no aparece icono
287
     * @param ext
288
     *            Extensi�n asociada al control
289
     * @param selectableTool
290
     *            Enable text del control
291
     * 
292
     * @throws ClassNotFoundException
293
     * @throws RuntimeException
294
     *             DOCUMENT ME!
295
     */
296
    public void addTool(PluginClassLoader loader, SkinExtensionType ext,
297
        ToolBar toolBar, SelectableTool selectableTool)
298
        throws ClassNotFoundException {
299
        if (!SwingUtilities.isEventDispatchThread()) {
300
            throw new RuntimeException("No Event Dispatch Thread");
301
        }
302
        
303
        Class<? extends IExtension> classExtension = (Class<? extends IExtension>) loader.loadClass(ext.getClassName());
304
        
305
        // Para traducir
306
        PluginServices ps =
307
            PluginServices.getPluginServices(loader.getPluginName());
308

    
309
        JToolBarToggleButton btn;
310
        ImageIcon image =
311
            PluginServices.getIconTheme().get(selectableTool.getIcon());
312

    
313
        if (image != null) {
314
            btn = new JToolBarToggleButton(selectableTool.getText(), image);
315
        } else {
316
            logger.error(PluginServices.getText(this, "Unable_to_find_icon")
317
                + ": " + selectableTool.getIcon());
318
            btn =
319
                new JToolBarToggleButton(selectableTool.getText(),
320
                    PluginServices.getIconTheme().get(noIcon));
321
        }
322

    
323
        org.gvsig.andami.ui.mdiFrame.ToggleButtonModel buttonModel =
324
            new org.gvsig.andami.ui.mdiFrame.ToggleButtonModel();
325
        btn.setModel(buttonModel);
326
        btn.setMargin(new Insets(0, 0, 0, 0));
327
        btn.addMouseListener(tooltipListener);
328
        btn.addActionListener(this);
329
        btn.setFocusable(false);
330
        btn.setActionCommand(selectableTool.getActionCommand());
331
        btn.setToolTipText(selectableTool.getTooltip());
332
        btn.setEnabled(false);
333
        btn.setVisible(false);
334
        String name = toolBar.getName();
335

    
336
        SelectableToolBar jtb = (SelectableToolBar) toolBarMap.get(name);
337

    
338
        if (jtb == null) {
339
            jtb = new SelectableToolBar(name);
340
            jtb.setRollover(true);
341
            jtb.setAndamiVisibility(toolBar.getIsVisible());
342
            toolBarMap.put(name, jtb);
343
            toolBars.add(jtb);
344
        }
345

    
346
        ButtonGroup group;
347
        if (buttonGroupMap.containsKey(selectableTool.getGroup())) {
348
            group = (ButtonGroup) buttonGroupMap.get(selectableTool.getGroup());
349
        } else {
350
            group = new ButtonGroup();
351
            buttonGroupMap.put(selectableTool.getGroup(), group);
352

    
353
        }
354
        jtb.addButton(group, btn);
355
        buttonModel.setGroupName(selectableTool.getGroup());
356

    
357
        if (selectableTool.getIsDefault()) {
358
            btn.setSelected(true);
359
            initialSelectedTools.put(selectableTool.getGroup(),
360
                btn.getActionCommand());
361
        }
362

    
363
        controlClass.put(btn, classExtension);
364

    
365
        if (selectableTool.getName() != null) {
366
            btn.setName(selectableTool.getName());
367
        }
368

    
369
        if (selectableTool.getTooltip() != null) {
370
            btn.setToolTip(ps.getText(selectableTool.getTooltip()));
371
        }
372

    
373
        if (selectableTool.getEnableText() != null) {
374
            btn.setEnableText(ps.getText(selectableTool.getEnableText()));
375
        }
376

    
377
        if (selectableTool.getLast() == true) {
378
            jtb.addSeparator();
379
        }
380
    }
381

    
382
    /**
383
     * A�ade un bot�n a la barra de herramientas
384
     * 
385
     * @param ext
386
     *            Texto del boton, si es null no aparece texto
387
     * @param ext
388
     *            Extensi�n asociada al control
389
     * @param toolBar
390
     *            Icono del boton, si es null no aparece texto
391
     * @param actionTool
392
     *            Tooltip de la barra de herramientas
393
     * 
394
     * @throws ClassNotFoundException
395
     * @throws RuntimeException
396
     *             DOCUMENT ME!
397
     */
398
    public void addTool(PluginClassLoader loader, SkinExtensionType ext,
399
        ToolBar toolBar, ActionTool actionTool) throws ClassNotFoundException {
400
        if (!SwingUtilities.isEventDispatchThread()) {
401
            throw new RuntimeException("No Event Dispatch Thread");
402
        }
403
        Class<? extends IExtension> classExtension = (Class<? extends IExtension>) loader.loadClass(ext.getClassName());
404
        
405
        // Para traducir los textos que vengan
406
        PluginServices ps =
407
            PluginServices.getPluginServices(loader.getPluginName());
408

    
409
        JToolBarButton btn;
410
        ImageIcon image = IconThemeHelper.getImageIcon(actionTool.getIcon());
411

    
412
        if (image != null) {
413
            btn = new JToolBarButton(actionTool.getText(), image);
414
        } else {
415
            logger.error(PluginServices.getText(this, "Unable_to_find_icon")
416
                + ": " + actionTool.getIcon());
417
            btn =
418
                new JToolBarButton(actionTool.getText(), PluginServices
419
                    .getIconTheme().get(noIcon));
420
        }
421

    
422
        btn.setMargin(new Insets(0, 0, 0, 0));
423
        btn.addMouseListener(tooltipListener);
424
        btn.addActionListener(this);
425
        btn.setFocusable(false);
426
        btn.setActionCommand(actionTool.getActionCommand());
427
        btn.setEnabled(false);
428
        btn.setVisible(false);
429

    
430
        String name = toolBar.getName();
431

    
432
        SelectableToolBar jtb = (SelectableToolBar) toolBarMap.get(name);
433

    
434
        if (jtb == null) {
435
            jtb = new SelectableToolBar(name);
436
            jtb.setRollover(true);
437
            jtb.setAndamiVisibility(toolBar.getIsVisible());
438
            toolBarMap.put(name, jtb);
439
            toolBars.add(jtb);
440
        }
441

    
442
        jtb.add(btn);
443

    
444
        controlClass.put(btn, classExtension);
445

    
446
        if (actionTool.getName() != null) {
447
            btn.setName(actionTool.getName());
448
        }
449

    
450
        if (actionTool.getTooltip() != null) {
451
            btn.setToolTip(ps.getText(actionTool.getTooltip()));
452
        }
453

    
454
        if (actionTool.getEnableText() != null) {
455
            btn.setEnableText(ps.getText(actionTool.getEnableText()));
456
        }
457

    
458
        if (actionTool.getLast() == true) {
459
            jtb.addSeparator();
460
        }
461
    }
462

    
463
    /**
464
     * Creates the needed menu structure to add the menu to the bar.
465
     * Returns the father which must hold the menu which was
466
     * provided as parameter.
467
     * 
468
     * Crea la estructura de men�s necesaria para a�adir el menu a la barra.
469
     * Devuelve el padre del cual debe colgar el menu que se pasa como
470
     * par�metro.
471
     * 
472
     * @param menu
473
     *            The Menu whose support is going to be added
474
     * @param loader
475
     *            The plugin's class loader
476
     * 
477
     * @return The proper father for the menu which was provided as parameter
478
     */
479
    private JMenu createMenuAncestors(Menu menu, PluginClassLoader loader) {
480
        MenuElement menuPadre = null;
481

    
482
        PluginServices ps =
483
            PluginServices.getPluginServices(loader.getPluginName());
484

    
485
        String[] menues = menu.getText().split("/");
486
        ArrayList menuList = new ArrayList();
487
        menuList.add(menues[0]);
488
        menuPadre = getMenu(menuList, menuBar);
489

    
490
        JMenu padre = null;
491

    
492
        if (menuPadre == null) {
493
            padre = new JMenu(ps.getText(menues[0]));
494
            padre.setName(menues[0]);
495
            menuBar.add(padre);
496
        } else
497
            if (menuPadre instanceof JMenu) {
498
                padre = (JMenu) menuPadre;
499
            } else {
500
                logger.error(ps
501
                    .getText("error_creating_menu_Ancestor_does_not_exist"));
502
                return null;
503
            }
504

    
505
        // Se crea el resto de menus
506
        ArrayList temp = new ArrayList();
507

    
508
        for (int i = 1; i < (menues.length - 1); i++) {
509
            temp.add(menues[i]);
510
        }
511

    
512
        menuPadre = createMenus(temp, padre);
513

    
514
        return (JMenu) menuPadre;
515
    }
516

    
517
    /**
518
     * A�ade la informaci�n del menu al framework. Debido a que los men�es
519
     * se
520
     * pueden introducir en un orden determinado por el usuario, pero los
521
     * plugins se instalan en un orden arbitrario, primero se almacena la
522
     * informaci�n de todos los menus para luego ordenarlos y posteriormente
523
     * a�adirlos al interfaz
524
     * 
525
     * @param loader
526
     *            Posicion del menu. Se ordena por este campo
527
     * @param ext
528
     *            Array con los nombres de los padres del menu
529
     * @param menu
530
     *            Texto del menu
531
     * 
532
     * @throws ClassNotFoundException
533
     * @throws RuntimeException
534
     *             DOCUMENT ME!
535
     */
536
    public void addMenu(PluginClassLoader loader, SkinExtensionType ext,
537
        Menu menu) throws ClassNotFoundException {
538
        if (!SwingUtilities.isEventDispatchThread()) {
539
            throw new RuntimeException("No Event Dispatch Thread");
540
        }
541
                JMenu menuPadre = createMenuAncestors(menu, loader);
542

    
543
        if (menu.getIs_separator()) {
544
            menuPadre.addSeparator();
545
            return;
546
        }
547

    
548
        JMenuItem nuevoMenu = createJMenuItem(loader, menu);
549
        nuevoMenu.addMouseListener(tooltipListener);
550
        //nuevoMenu.addActionListener(this);
551
        menuPadre.add(nuevoMenu);
552
        Class<? extends IExtension> classExtension = (Class<? extends IExtension>) loader.loadClass(ext.getClassName());
553
        controlClass.put(nuevoMenu, classExtension);
554
    }
555

    
556
    /**
557
     * Dado un array de nombres de menu, encuentra el men�
558
     * 
559
     * @param nombres
560
     *            DOCUMENT ME!
561
     * @param padre
562
     *            DOCUMENT ME!
563
     * 
564
     * @return DOCUMENT ME!
565
     */
566
    private javax.swing.JMenuItem getMenu(ArrayList nombres, MenuElement parent) {
567
        if (parent instanceof javax.swing.JMenu) {
568
            javax.swing.JMenu parentItem = (javax.swing.JMenu) parent;
569

    
570
            for (int i = 0; i < parentItem.getMenuComponentCount(); i++) {
571
                
572
                String item_name = parentItem.getMenuComponent(i).getName(); 
573
                if (((item_name != null) && (item_name.compareTo((String) nombres.get(0)) == 0))
574
                    ||
575
                    /*
576
                     * We also accept "leaf menus" with no name
577
                     * (Project manager, View-1, View-2, etc)
578
                     */
579
                    lastMenuItemWithoutName(parentItem.getMenuComponent(i), nombres))
580
                    {
581
                    
582
                    nombres.remove(0);
583
                    if (nombres.isEmpty()) {
584
                        if (parentItem.getMenuComponent(i) instanceof javax.swing.JMenuItem) {
585
                            return (javax.swing.JMenuItem) parentItem
586
                                .getMenuComponent(i);
587
                        } else {
588
                            logger.error(PluginServices.getText(this,
589
                                "Menu_type_not_supported_")
590
                                + " "
591
                                + parentItem.getMenuComponent(i).getClass()
592
                                    .getName());
593
                            return null;
594
                        }
595
                    } else {
596
                        return getMenu(nombres,
597
                            (MenuElement) parentItem.getMenuComponent(i));
598
                    }
599
                }
600
            }
601
        } else
602
            if (parent instanceof JMenuBar) {
603
                javax.swing.JMenuBar parentItem = (javax.swing.JMenuBar) parent;
604

    
605
                for (int i = 0; i < parentItem.getMenuCount(); i++) {
606
                    if ((parentItem.getMenu(i).getName() != null // not a
607
                                                                 // JToolBar.Separator
608
                        )
609
                        && (parentItem.getMenu(i).getName()
610
                            .compareTo((String) nombres.get(0)) == 0)) {
611
                        nombres.remove(0);
612
                        if (nombres.isEmpty()) {
613
                            if (parentItem.getMenu(i) instanceof javax.swing.JMenuItem) {
614
                                return parentItem.getMenu(i);
615
                            } else {
616
                                logger.error(PluginServices.getText(this,
617
                                    "Menu_type_not_supported_")
618
                                    + " "
619
                                    + parentItem.getMenu(i).getClass()
620
                                        .getName());
621
                                return null;
622
                            }
623
                        } else {
624
                            return getMenu(nombres, parentItem.getMenu(i));
625
                        }
626
                    }
627
                }
628
            } else {
629
                logger.error(PluginServices.getText(this,
630
                    "Menu_type_not_supported_")
631
                    + " "
632
                    + parent.getClass().getName() + " " + parent.toString());
633
            }
634
        return null;
635
    }
636

    
637
    /**
638
     * @param menuComponent
639
     * @param nombres
640
     * @return
641
     */
642
    private boolean lastMenuItemWithoutName(Component mc, ArrayList names) {
643
        
644
        /*
645
         * names must have 1 string
646
         */
647
        if (names == null || names.size() != 1) {
648
            return false;
649
        }
650
        if (!(mc instanceof JMenuItem)) {
651
            return false;
652
        }
653
        JMenuItem jmi = (JMenuItem) mc;
654
        if (jmi.getName() != null) {
655
            /*
656
             * Name must be null, so this is a menu leaf
657
             */
658
            return false;
659
        }
660
        if (jmi.getText() == null) {
661
            return false;
662
        }
663
        return jmi.getText().compareTo((String) names.get(0)) == 0;
664
    }
665

    
666
    /**
667
     * Crea la estructura de menus recursivamente. Por ejemplo, si se le pasa
668
     * en el par�metro nombres el array {"Search", "References", "Workspace"}
669
     * crear� un men� Search, un submen� del anterior que se llamar�
670
     * References y debajo de �ste �ltimo otro menu llamado Workspace
671
     * 
672
     * @param nombres
673
     *            Array con los nombres de los men�s que se quieren crear
674
     * @param padre
675
     *            Menu padre de los men�s creados. Es �til porque es un
676
     *            algoritmo recursivo
677
     * 
678
     * @return Devuelve el men� creado. Al final de toda la recursividad,
679
     *         devolver� el men� de m�s abajo en la jerarqu�a
680
     * 
681
     * @throws RuntimeException
682
     *             DOCUMENT ME!
683
     */
684
    private JMenu createMenus(ArrayList nombres, JMenu padre) {
685
        if (!SwingUtilities.isEventDispatchThread()) {
686
            throw new RuntimeException("No Event Dispatch Thread");
687
        }
688

    
689
        // si no quedan nombres de menu por crear se vuelve: caso base
690
        if (nombres.size() == 0) {
691
            return padre;
692
        }
693

    
694
        // Se busca el menu por si ya existiera para no crearlo otra vez
695
        JMenu buscado = null;
696

    
697
        for (int i = 0; i < padre.getMenuComponentCount(); i++) {
698
            try {
699
                JMenu hijo = (JMenu) padre.getMenuComponent(i);
700

    
701
                if (hijo.getName().compareTo((String) nombres.get(0)) == 0) {
702
                    buscado = hijo;
703
                }
704
            } catch (ClassCastException e) {
705
                /*
706
                 * Se ha encontrado un elemento hoja del arbol de men�es
707
                 */
708
            }
709
        }
710

    
711
        if (buscado != null) {
712
            // Si lo hemos encontrado creamos el resto
713
            nombres.remove(0);
714

    
715
            return createMenus(nombres, buscado);
716
        } else {
717
            // Si no lo hemos encontrado se crea el menu, se a�ade al padre
718
            // y se crea el resto
719
            String nombre = (String) nombres.get(0);
720
            JMenu menuPadre = new JMenu(PluginServices.getText(this, nombre));
721
            menuPadre.setName(nombre);
722
            padre.add(menuPadre);
723

    
724
            nombres.remove(0);
725

    
726
            return createMenus(nombres, menuPadre);
727
        }
728
    }
729

    
730
    /**
731
     * M�todo invocado en respuesta a ciertos eventos de la interfaz que
732
     * pueden
733
     * ocultar botones de las barras de herramientas y que redimensiona �sta
734
     * de manera conveniente para que no se oculte ninguno
735
     */
736
    private void ajustarToolBar() {
737
        int margen = 8;
738
        int numFilas = 1;
739
        double acum = margen;
740

    
741
        int toolHeight = 0;
742

    
743
        for (int i = 0; i < toolBars.getComponentCount(); i++) {
744
            Component c = toolBars.getComponent(i);
745

    
746
            if (!c.isVisible()) {
747
                continue;
748
            }
749

    
750
            double width = c.getPreferredSize().getWidth();
751
            acum = acum + width;
752

    
753
            if (acum > this.getWidth()) {
754
                numFilas++;
755
                acum = width + margen;
756
            }
757

    
758
            if (c.getPreferredSize().getHeight() > toolHeight) {
759
                toolHeight = c.getPreferredSize().height;
760
            }
761
        }
762

    
763
        toolBars.setPreferredSize(new Dimension(this.getWidth(),
764
            (numFilas * toolHeight)));
765

    
766
        toolBars.updateUI();
767
    }
768

    
769
    /**
770
     * DOCUMENT ME!
771
     * 
772
     * @param classesExtensions
773
     */
774
    public void setClassesExtensions(Map<Class<? extends IExtension>, ExtensionDecorator> classesExtensions) {
775
            Map<Class<? extends IExtension>, ExtensionDecorator> extensions = new HashMap<Class<? extends IExtension>, ExtensionDecorator>();
776
            for ( Entry<Class<? extends IExtension>, ExtensionDecorator>  entry: classesExtensions.entrySet()) {
777
                        if( ! (entry.getValue().getExtension() instanceof LibraryExtension) ) {
778
                                extensions.put(entry.getKey(), entry.getValue());
779
                        }
780
                }
781
        this.classesExtensions = extensions;
782
    }
783

    
784
    /**
785
     * Metodo de callback invocado cuando se selecciona un menu o un boton
786
     * de
787
     * la barra de herramientas. Se busca la extensi�n asociada y se ejecuta
788
     * 
789
     * @param e
790
     *            Evento producido
791
     */
792
    public void actionPerformed(ActionEvent e) {
793
        
794
//        org.gvsig.andami.plugins.IExtension ext =
795
//            (org.gvsig.andami.plugins.IExtension) classesExtensions
796
//                .get(controlClass.get(control));
797
            String actionName = "(unknow)";
798
        try {
799
            JComponent control = (JComponent) e.getSource();
800
            actionName = control.getName();
801
            
802
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
803
                ActionInfo action = actionManager.getAction(control.getName());
804
                Object args = null;
805
            if( control instanceof IControl ) {
806
                    args = ((IControl) control).getValue();
807
            }
808
            if( args == null ) {
809
                    action.execute();
810
            } else {
811
                    action.execute(args);                    
812
            }
813
                
814
//            logger.info("{}.execute('{}')", ext.getClass().getSimpleName(), actionCommand);
815
//            ext.execute(actionCommand);
816

    
817
                String actionCommand = e.getActionCommand();
818
            try {
819
                JToolBarToggleButton toggle = (JToolBarToggleButton) control;
820
                ToggleButtonModel model = (ToggleButtonModel) toggle.getModel();
821
                selectedTool.put(model.getGroupName(), actionCommand);
822
            } catch (ClassCastException ex) {
823
            } catch (NullPointerException ex) {
824
            }
825

    
826
        } catch (Throwable ex) {
827
                logger.error("Can't perform action '"+actionName+"'.",ex);
828
//            if (ext == null) {
829
//                logger.error(Messages
830
//                    .getString("No_extension_associated_with_this_event_")
831
//                    + e.getActionCommand());
832
//            }
833
//            NotificationManager.addError(Messages
834
//                .getString("MDIFrame.Error_no_capturado_por_el_usuario"), t);
835
        }
836

    
837
        enableControls();
838
        showMemory();
839
    }
840

    
841
    /**
842
     * DOCUMENT ME!
843
     * 
844
     * @param name
845
     *            DOCUMENT ME!
846
     * @param loader
847
     *            DOCUMENT ME!
848
     * 
849
     * @return DOCUMENT ME!
850
     */
851
    private String getName(String name, PluginClassLoader loader) {
852
        if (name.indexOf('.') == -1) {
853
            return loader.getPluginName() + "." + name;
854
        } else {
855
            return name;
856
        }
857
    }
858

    
859
    /**
860
     * DOCUMENT ME!
861
     * 
862
     * @param loader
863
     *            DOCUMENT ME!
864
     * @param menu
865
     *            DOCUMENT ME!
866
     * 
867
     * @throws RuntimeException
868
     *             DOCUMENT ME!
869
     */
870
    public void addPopupMenu(PluginClassLoader loader, PopupMenu menu) {
871
        if (!SwingUtilities.isEventDispatchThread()) {
872
            throw new RuntimeException("No Event Dispatch Thread");
873
        }
874

    
875
        String name = getName(menu.getName(), loader);
876

    
877
        // Se crea el control popupmenu
878
        JPopUpMenu popupMenu = (JPopUpMenu) popupMap.get(name);
879

    
880
        if (popupMenu == null) {
881
            popupMenu = new JPopUpMenu(menu.getName());
882
            popupMap.put(name, popupMenu);
883
        }
884

    
885
        Menu[] menues = menu.getMenu();
886
        for (int i = 0; i < menues.length; i++) {
887
            JMenuItem nuevoMenu = createJMenuItem(loader, menues[i]);
888
            popupMenu.add(nuevoMenu);
889
        }
890
    }
891

    
892
    /**
893
     * DOCUMENT ME!
894
     * 
895
     * @param loader
896
     * @param menu
897
     * 
898
     * @return
899
     * 
900
     * @throws RuntimeException
901
     *             DOCUMENT ME!
902
     */
903
    private JMenuItem createJMenuItem(PluginClassLoader loader, Menu menu) {
904
        JMenuItem nuevoMenu = null;
905

    
906
        PluginServices ps =
907
            PluginServices.getPluginServices(loader.getPluginName());
908
        
909
        String text = menu.getText();
910
        int n = text.lastIndexOf('/');
911
        if( n>=0  ) {
912
                text = text.substring(n + 1);
913
        }
914
        String translatedText = ps.getText(text);
915

    
916
        IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
917
        if (menu.getIcon() != null) {
918
                if( iconTheme.exists(menu.getIcon()) ) {
919
                        ImageIcon image = iconTheme.get(menu.getIcon());
920
                nuevoMenu = new JMenuItem(translatedText, image);
921
            } else {
922
                nuevoMenu = new JMenuItem(translatedText);
923
                logger.info("menu icon '"+ menu.getIcon()+ "' not exists.");
924
            }
925
        } else {
926
            nuevoMenu = new JMenuItem(translatedText);
927
        }
928
        nuevoMenu.setName(menu.getName());
929
//                if (menu.getMnemonic() != null) {
930
//                        if (menu.getMnemonic().length() != 1) {
931
//                                throw new RuntimeException(
932
//                                                "Mnemonic must be 1 character length");
933
//                        }
934
//                        nuevoMenu.setMnemonic(KeyMapping.getKey(menu.getMnemonic()
935
//                                        .charAt(0)));
936
//                }
937

    
938
        if (menu.getKey() != null) {
939
            nuevoMenu.setAccelerator(KeyMapping.getKeyStroke(menu.getKey()));
940
        }
941

    
942
        nuevoMenu.setActionCommand(menu.getActionCommand());
943

    
944
        if (menu.getTooltip() != null) {
945
            nuevoMenu.setToolTip(ps.getText(menu.getTooltip()));
946
        }
947

    
948
        if (menu.getEnableText() != null) {
949
            nuevoMenu.setEnableText(ps.getText(menu.getEnableText()));
950
        }
951

    
952
        nuevoMenu.setEnabled(true);
953
        nuevoMenu.setVisible(true);
954

    
955
        if( menu.getName() != null ) {
956
                    ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
957
                    final ActionInfo actionInfo = actionManager.getAction(menu.getName());
958
                    if( actionInfo != null ) {
959
                            nuevoMenu.addActionListener(actionInfo);
960
                    }
961
        }
962
        return nuevoMenu;
963
    }
964

    
965
    /**
966
     * Muestra u oculta el menu de nombre 'name'
967
     * 
968
     * @param name
969
     *            Nombre del menu que se quiere mostrar
970
     * @param x
971
     *            Evento de raton
972
     * @param y
973
     *            DOCUMENT ME!
974
     * @param c
975
     *            DOCUMENT ME!
976
     */
977
    private void showPopupMenu(String name, int x, int y, Component c) {
978
        JPopupMenu menu = (JPopupMenu) popupMap.get(name);
979

    
980
        if (menu != null) {
981
            menu.show(c, x, y);
982
        }
983
    }
984

    
985
    /**
986
     * DOCUMENT ME!
987
     * 
988
     * @param name
989
     *            DOCUMENT ME!
990
     * @param listener
991
     *            DOCUMENT ME!
992
     */
993
    public void removePopupMenuListener(String name, ActionListener listener) {
994
        JPopupMenu menu = (JPopupMenu) popupMap.get(name);
995

    
996
        if (menu != null) {
997
            Component[] jmenuitems = menu.getComponents();
998

    
999
            for (int i = 0; i < jmenuitems.length; i++) {
1000
                if (jmenuitems[i] instanceof JMenuItem) {
1001
                    ((JMenuItem) jmenuitems[i]).removeActionListener(listener);
1002
                }
1003
            }
1004
        }
1005
    }
1006

    
1007
    /**
1008
     * DOCUMENT ME!
1009
     * 
1010
     * @param popupName
1011
     * @param c
1012
     *            DOCUMENT ME!
1013
     * @param listener
1014
     * @param loader
1015
     */
1016
    public void addPopupMenuListener(String popupName, Component c,
1017
        ActionListener listener, PluginClassLoader loader) {
1018
        final String name = getName(popupName, loader);
1019

    
1020
        JPopupMenu menu = (JPopupMenu) popupMap.get(name);
1021

    
1022
        if (menu != null) {
1023
            Component[] jmenuitems = menu.getComponents();
1024

    
1025
            for (int i = 0; i < jmenuitems.length; i++) {
1026
                if (jmenuitems[i] instanceof JMenuItem) {
1027
                    ((JMenuItem) jmenuitems[i]).addActionListener(listener);
1028
                }
1029
            }
1030
        }
1031

    
1032
        c.addMouseListener(new MouseAdapter() {
1033

    
1034
            @Override
1035
            public void mousePressed(MouseEvent e) {
1036
                if (e.isPopupTrigger()) {
1037
                    showPopupMenu(name, e.getX(), e.getY(), e.getComponent());
1038
                }
1039
            }
1040

    
1041
            @Override
1042
            public void mouseReleased(MouseEvent e) {
1043
                if (e.isPopupTrigger()) {
1044
                    showPopupMenu(name, e.getX(), e.getY(), e.getComponent());
1045
                }
1046
            }
1047
        });
1048
    }
1049

    
1050
    /**
1051
     * Loop on the controls to enable/disable and show/hide them, according to
1052
     * its associated extension
1053
     * 
1054
     * @throws RuntimeException
1055
     *             DOCUMENT ME!
1056
     */
1057
    public void enableControls() {
1058
        if (!SwingUtilities.isEventDispatchThread()) {
1059
                SwingUtilities.invokeLater(new Runnable() {
1060
                                public void run() {
1061
                                        enableControls();
1062
                                }
1063
                        });
1064
                        return;
1065
        }
1066

    
1067
        ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1068
        ActionInfoStatusCache cache = actionManager.createActionStatusCache();
1069
        
1070
        Iterator e = classesExtensions.values().iterator();
1071

    
1072
//        HashMap estadoExtensiones = new HashMap();
1073
//        HashMap visibilidadExtensiones = new HashMap();
1074
//
1075
//        while (e.hasNext()) {
1076
//            ExtensionDecorator ext = (ExtensionDecorator) e.next();
1077
//
1078
//            try {
1079
//                if (estadoExtensiones.get(ext) == null) {
1080
//                    boolean b;
1081
//                    if (ext.getVisibility() == ExtensionDecorator.ALWAYS_VISIBLE) {
1082
//                        b = true;
1083
//                    } else
1084
//                        if (ext.getVisibility() == ExtensionDecorator.ALWAYS_INVISIBLE) {
1085
//                            b = false;
1086
//                        } else {
1087
//                            if (PluginServices.getExclusiveUIExtension() == null) {
1088
//                                b = ext.isVisible();
1089
//                            } else {
1090
//                                b =
1091
//                                    PluginServices.getExclusiveUIExtension()
1092
//                                        .isVisible(ext.getExtension());
1093
//                            }
1094
//                        }
1095
//                    Boolean visible = new Boolean(b);
1096
//                    Boolean enabled = new Boolean(false);
1097
//
1098
//                    if (visible.booleanValue()) {
1099
//                        if (PluginServices.getExclusiveUIExtension() == null) {
1100
//                            enabled = new Boolean(ext.isEnabled());
1101
//                        } else {
1102
//                            enabled =
1103
//                                new Boolean(PluginServices
1104
//                                    .getExclusiveUIExtension().isEnabled(
1105
//                                        ext.getExtension()));
1106
//                        }
1107
//
1108
//                    }
1109
//
1110
//                    estadoExtensiones.put(ext, enabled);
1111
//                    visibilidadExtensiones.put(ext, visible);
1112
//                }
1113
//            } catch (Throwable e1) {
1114
//                NotificationManager.addError(Messages
1115
//                    .getString("MDIFrame.Error_no_capturado_por_el_usuario"),
1116
//                    e1);
1117
//                estadoExtensiones.put(ext, Boolean.FALSE);
1118
//            }
1119
//        }
1120

    
1121
        // Enable or disable controls, according to its associated extensions
1122
        e = controlClass.keySet().iterator();
1123

    
1124
        while (e.hasNext()) {
1125
            JComponent control = (JComponent) e.next();
1126
            String actionlName = control.getName();
1127
            ActionInfo action = actionManager.getAction(actionlName);
1128
            try {
1129
                boolean enabled = false;
1130
                boolean visible = false;
1131
                
1132
                    if(action == null) {
1133
                  IExtension ext =
1134
                          (IExtension) classesExtensions.get(controlClass.get(control));
1135
                  enabled = ext.isEnabled();
1136
                  visible = ext.isVisible(); 
1137
                    } else {
1138
                            enabled = false;
1139
                    visible = cache.isVisible(action);
1140
                    if( visible ) {
1141
                            enabled = cache.isEnabled(action);
1142
                    }
1143
                    }
1144
                control.setEnabled(enabled);
1145
                control.setVisible(visible);
1146
            } catch (Exception ex) {
1147
                    logger.info("Can't enable/show control '"+actionlName +"'.",ex);
1148
                    this.message("Can't enable/show control '"+actionlName +"'.", JOptionPane.ERROR_MESSAGE);
1149
                control.setEnabled(false);
1150
                control.setVisible(false);
1151
            }
1152
        }
1153

    
1154
        // Loop in the menus to hide the menus that don't have visible children
1155
        for (int i = 0; i < menuBar.getMenuCount(); i++) {
1156
            MenuElement menu = menuBar.getMenu(i);
1157
            hideMenus(menu);
1158
            if (menu instanceof JMenu) {
1159
                // hide (ugly) redundant separators and assign keyboard
1160
                // mnemonics
1161
                Component[] comps = ((JMenu) menu).getMenuComponents();
1162
                // mnemonics have to be unique for each top-level menu
1163
                char mnemonics[] = new char[comps.length];
1164
                if (comps.length > 0) {
1165
                    // Set keyboard mnemonic for this top-level entry
1166
                    String text = ((JMenu) menu).getText();
1167
                    char mnemonic = getMnemonic(text, mnemonics);
1168
                    if (' ' != mnemonic) {
1169
                        ((JMenu) menu).setMnemonic(mnemonic);
1170
                        mnemonics[0] = mnemonic;
1171
                    }
1172
                }
1173
                // now go through all entries in this menu, hid
1174
                // separators if necessary and assing remaining mnemonics
1175
                hideSeparatorsAndMakeMnemonics(menu, mnemonics);
1176
            }
1177
        }
1178

    
1179
        // hide the toolbars that don't contain any visible tool
1180
        Iterator it = toolBarMap.values().iterator();
1181

    
1182
        while (it.hasNext()) {
1183
                JComponent t = (JComponent) it.next();
1184
            boolean todosOcultos = true;
1185

    
1186
            for (int i = 0; i < t.getComponentCount(); i++) {
1187
                if (!(t.getComponent(i) instanceof JSeparator) // separators
1188
                                                               // don't matter
1189
                    && t.getComponent(i).isVisible()) {
1190
                    todosOcultos = false;
1191
                }
1192
            }
1193

    
1194
            if (todosOcultos) {
1195
                t.setVisible(false);
1196
            } else {
1197
                    if(t instanceof SelectableToolBar) {
1198
                            t.setVisible(((SelectableToolBar)t).getAndamiVisibility());
1199
                    } else
1200
                            t.setVisible(true);
1201
            }
1202
        }
1203

    
1204
        if (mdiManager != null) {
1205
            JPanel f = (JPanel) mdiManager.getActiveWindow();
1206

    
1207
            if (f != null) {
1208
                if (lastLabelClass != f.getClass()) {
1209
                    lastLabelClass = f.getClass();
1210

    
1211
                    Label[] lbls = (Label[]) classLabels.get(lastLabelClass);
1212

    
1213
                    if (lbls != null) {
1214
                        bEstado.setLabelSet(lbls);
1215
                    }
1216
                }
1217
            }
1218
        }
1219

    
1220
        ajustarToolBar();
1221

    
1222
        showMemory();
1223
    }
1224
    
1225
    public void refreshControls() {
1226
        if (!SwingUtilities.isEventDispatchThread()) {
1227
                SwingUtilities.invokeLater(new Runnable() {
1228
                                public void run() {
1229
                                        refreshControls();
1230
                                }
1231
                        });
1232
                        return;
1233
        }
1234

    
1235
        ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1236
        ActionInfoStatusCache cache = actionManager.createActionStatusCache();
1237
        IconTheme icontheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1238
        
1239
        Iterator e = controlClass.keySet().iterator();
1240

    
1241
        while (e.hasNext()) {
1242
            JComponent control = (JComponent) e.next();
1243
            String actionlName = control.getName();
1244
            ActionInfo action = actionManager.getAction(actionlName);
1245
            if( action!=null ) {
1246
                    if( control instanceof AbstractButton ) {
1247

    
1248
                    AbstractButton button = (AbstractButton) control;
1249

    
1250
                        if (control instanceof javax.swing.JMenuItem) {
1251
                            
1252
                            if (action.getIconName() != null && action.getIconName().length() > 0) {
1253
                                
1254
                                if( icontheme.exists(action.getIconName()) ) {
1255
                                    button.setIcon(action.getIcon());
1256
                                }
1257
                            }
1258
                            
1259
                        } else {
1260
                            button.setIcon(action.getIcon());
1261
                        }
1262
                    }
1263
            }
1264
        }
1265
        enableControls();
1266
    }
1267

    
1268
    public void message(String msg, int messageTyoe) {
1269
            this.getStatusBar().message(msg, messageTyoe);
1270
        }
1271

    
1272
        /**
1273
     * Establece la visibilidad de un menu y todos sus descendientes en la
1274
     * jerarquia teniendo en cuenta la visibilidad de todos los submenus.
1275
     * 
1276
     * @param menu
1277
     *            Menu que se quiere visualizar
1278
     * 
1279
     * @return Devuelve true si el menu es visible y false en caso contrario
1280
     */
1281
    private boolean hideMenus(MenuElement menu) {
1282
        MenuElement[] submenus = menu.getSubElements();
1283

    
1284
        // Si no tiene hijos se devuelve su visibilidad
1285
        if (submenus.length == 0) {
1286
            return menu.getComponent().isVisible();
1287
        }
1288

    
1289
        /*
1290
         * Si tiene hijos se devuelve true si alg�no de ellos es visible,
1291
         * pero se itera por todos ellos
1292
         */
1293
        boolean visible = false;
1294

    
1295
        for (int i = 0; i < submenus.length; i++) {
1296
            if (hideMenus(submenus[i])) {
1297
                if (!(menu instanceof JPopupMenu)) {
1298
                    menu.getComponent().setVisible(true);
1299
                }
1300

    
1301
                visible = true;
1302
            }
1303
        }
1304

    
1305
        if (visible) {
1306
            return true;
1307
        }
1308

    
1309
        menu.getComponent().setVisible(false);
1310

    
1311
        return false;
1312
    }
1313

    
1314
    /**
1315
     * 
1316
     * Recurse through all menu elements and make sure there are no
1317
     * redundant separators.
1318
     * This method will make sure that a separator only becomes visible
1319
     * if at least one visible non-separator menu entry preceeded it.
1320
     * 
1321
     **/
1322
    private void hideSeparatorsAndMakeMnemonics(MenuElement menu,
1323
        char[] mnemonics) {
1324
        // flag that indicates whether a separator is to be displayed or not
1325
        boolean allowSeparator;
1326

    
1327
        allowSeparator = false; // separator not allowed as very first menu item
1328
        Component[] comps = ((JMenu) menu).getMenuComponents();
1329
        if (comps.length < 1) {
1330
            // zero-length menu: skip
1331
            return;
1332
        }
1333

    
1334
        for (int i = 0; i < comps.length; i++) {
1335
            if (comps[i] instanceof JSeparator) {
1336
                // got a separator: display only if allowed at this position
1337
                if (allowSeparator == true) {
1338
                    // look at all successive menu entries to make sure that at
1339
                    // least one
1340
                    // is visible and not a separator (otherwise, this separator
1341
                    // would
1342
                    // be the last visible item in this menu) -- we don't want
1343
                    // that
1344
                    comps[i].setVisible(false);
1345
                    for (int j = i; j < comps.length; j++) {
1346
                        if (!(comps[j] instanceof JSeparator)) {
1347
                            if (comps[j].isVisible()) {
1348
                                comps[i].setVisible(true); // display separator!
1349
                                break;
1350
                            }
1351
                        }
1352
                    }
1353
                } else {
1354
                    comps[i].setVisible(false);
1355
                }
1356
                allowSeparator = false; // separator is not allowed right after
1357
                                        // another separator
1358
            } else {
1359
                if (comps[i] instanceof JMenu) { // got a submenu: recurse
1360
                                                 // through it
1361
                    // get number of submenu components
1362
                    Component[] scomps = ((JMenu) comps[i]).getMenuComponents();
1363
                    // make a new, fresh array to hold unique mnemonics for this
1364
                    // submenu
1365
                    char[] smnemonics = new char[scomps.length];
1366
                    hideSeparatorsAndMakeMnemonics(((MenuElement) comps[i]),
1367
                        smnemonics);
1368
                    if (comps[i].isVisible()) {
1369
                        allowSeparator = true; // separators are OK after
1370
                                               // visible submenus
1371
                        // Set keyboard mnemonic for this submenu
1372
                        String text = ((JMenu) comps[i]).getText();
1373
                        char mnemonic = getMnemonic(text, mnemonics);
1374
                        if (' ' != mnemonic) {
1375
                            ((JMenu) comps[i]).setMnemonic(mnemonic);
1376
                            mnemonics[i] = mnemonic;
1377
                        }
1378
                    }
1379
                } else {
1380
                    if (comps[i].isVisible()) {
1381
                        if (comps[i] instanceof JMenuItem) {
1382
                            // Set keyboard mnemonic for this menu item
1383
                            String text = ((JMenuItem) comps[i]).getText();
1384
                            char mnemonic = getMnemonic(text, mnemonics);
1385
                            if (' ' != mnemonic) {
1386
                                ((JMenuItem) comps[i]).setMnemonic(mnemonic);
1387
                                mnemonics[i] = mnemonic;
1388
                            }
1389
                        }
1390
                        allowSeparator = true; // separators are OK after
1391
                                               // regular, visible entries
1392
                    }
1393
                }
1394
            }
1395
        }
1396
    }
1397

    
1398
    /**
1399
     * Helper functios for assigning a unique mnemomic char from
1400
     * a pool of unassigned onces, stored in the array "mnemomnics"
1401
     */
1402
    private char getMnemonic(String text, char[] mnemonics) {
1403
        Vector words = new Vector();
1404
        StringTokenizer t = new StringTokenizer(text);
1405
        int maxsize = 0;
1406

    
1407
        while (t.hasMoreTokens()) {
1408
            String word = t.nextToken();
1409
            if (word.length() > maxsize) {
1410
                maxsize = word.length();
1411
            }
1412
            words.addElement(word);
1413
        }
1414
        words.trimToSize();
1415

    
1416
        for (int i = 0; i < maxsize; ++i) {
1417
            char mnemonic = getMnemonic(words, mnemonics, i);
1418
            if (' ' != mnemonic) {
1419
                return mnemonic;
1420
            }
1421
        }
1422

    
1423
        return ' ';
1424
    }
1425

    
1426
    private char getMnemonic(Vector words, char[] mnemonics, int index) {
1427
        int numwords = words.size();
1428

    
1429
        for (int i = 0; i < numwords; ++i) {
1430
            String word = (String) words.elementAt(i);
1431
            if (index >= word.length()) {
1432
                continue;
1433
            }
1434

    
1435
            char c = word.charAt(index);
1436
            if (!isMnemonicExists(c, mnemonics)) {
1437
                /* pick only valid chars */
1438
                if ((c != ':') && (c != '.') && (c != ',') && (c != ';')
1439
                    && (c != '-') && (c != '+') && (c != '/') && (c != '\\')
1440
                    && (c != '\'') && (c != '\"') && (c != ' ') && (c != '=')
1441
                    && (c != '(') && (c != ')') && (c != '[') && (c != ']')
1442
                    && (c != '{') && (c != '}') && (c != '$') && (c != '*')
1443
                    && (c != '&') && (c != '%') && (c != '!') && (c != '?')
1444
                    && (c != '#') && (c != '~') && (c != '_')) {
1445
                    return c;
1446
                }
1447
            }
1448
        }
1449
        return ' ';
1450
    }
1451

    
1452
    private boolean isMnemonicExists(char c, char[] mnemonics) {
1453
        int num = mnemonics.length;
1454
        for (int i = 0; i < num; ++i) {
1455
            if (mnemonics[i] == c) {
1456
                return true;
1457
            }
1458
        }
1459
        return false;
1460
    }
1461

    
1462
    /**
1463
     * Muestra la memoria consumida por el programa
1464
     */
1465
    private void showMemory() {
1466
        Runtime r = Runtime.getRuntime();
1467
        long mem = r.totalMemory() - r.freeMemory();
1468
        logger.debug(PluginServices.getText(this, "memory_usage") + " " + mem
1469
            / 1024 + " KB");
1470
    }
1471

    
1472
    /**
1473
     * DOCUMENT ME!
1474
     * 
1475
     * @return
1476
     */
1477
    public MDIManager getMDIManager() {
1478
        return mdiManager;
1479
    }
1480

    
1481
    /**
1482
     * Establece el mensaje en la barra de estado asociado a una etiqueta
1483
     * 
1484
     * @return DOCUMENT ME!
1485
     */
1486
    public NewStatusBar getStatusBar() {
1487
        return bEstado;
1488
    }
1489

    
1490
    /**
1491
     * You can use this function to select the appropiate
1492
     * tool inside the toolbars
1493
     */
1494
    public void setSelectedTool(String actionCommand) {
1495
        setSelectedTool(defaultGroup, actionCommand);
1496
    }
1497

    
1498
    /**
1499
     * You can use this function to select the appropiate
1500
     * tool inside the toolbars
1501
     */
1502
    public void setSelectedTool(String groupName, String actionCommand) {
1503
        ButtonGroup group = (ButtonGroup) buttonGroupMap.get(groupName);
1504
        if (group == null) {
1505
            return;
1506
        }
1507

    
1508
        Enumeration enumeration = group.getElements();
1509
        while (enumeration.hasMoreElements()) {
1510
            AbstractButton button = (AbstractButton) enumeration.nextElement();
1511
            if (button.getActionCommand().equals(actionCommand)) {
1512
                button.setSelected(true);
1513
            }
1514
        }
1515

    
1516
        selectedTool.put(groupName, actionCommand);
1517
    }
1518

    
1519
    /**
1520
     * You can use this function to select the appropiate
1521
     * tool inside the toolbars
1522
     */
1523
    public void setSelectedTools(Map selectedTools) {
1524
        selectedTool = selectedTools;
1525
        if (selectedTools == null) {
1526
            return;
1527
        }
1528
        Iterator groupNames = selectedTools.keySet().iterator();
1529
        while (groupNames.hasNext()) {
1530
            try {
1531
                String groupName = (String) groupNames.next();
1532
                ButtonGroup group = (ButtonGroup) buttonGroupMap.get(groupName);
1533
                Enumeration enumeration = group.getElements();
1534
                String actionCommand = (String) selectedTools.get(groupName);
1535
                if (actionCommand == null) {
1536
                    continue;
1537
                }
1538
                while (enumeration.hasMoreElements()) {
1539
                    AbstractButton button =
1540
                        (AbstractButton) enumeration.nextElement();
1541
                    if (button.getActionCommand().equals(actionCommand)) {
1542
                        button.setSelected(true);
1543
                    }
1544
                }
1545
            } catch (ClassCastException ex) {
1546
                logger
1547
                    .error("selectedTool should only contain pairs (String groupName, JToolBarToggleButton button)");
1548
            }
1549
        }
1550
    }
1551

    
1552
    /**
1553
     * DOCUMENT ME!
1554
     * 
1555
     * @param clase
1556
     * @param label
1557
     */
1558
    public void setStatusBarLabels(Class<?> clase, Label[] label) {
1559
        classLabels.put(clase, label);
1560
    }
1561

    
1562
    public void removeStatusBarLabels(Class<?> clase) {
1563
        classLabels.remove(clase);
1564
    }
1565

    
1566
    public void addStatusBarControl(Class<?> extensionClass, IControl control) {
1567
        control.addActionListener(this);
1568
        bEstado.addControl(control.getName(), (Component) control);
1569
        controlClass.put(control, extensionClass);
1570
    }
1571
    
1572
    public void addToolBarControl(Class<?> extensionClass, JToolBar control, String name) {
1573
        //toolBarMap.put(name, control); 
1574
        toolBars.add(control);
1575
        controlClass.put(control, extensionClass);
1576
    }
1577

    
1578
    public void removeStatusBarControl(String name) {
1579
        Component c = bEstado.removeControl(name);
1580
        if (c != null) {
1581
            controlClass.remove(c);
1582
        }
1583
    }
1584

    
1585
    /**
1586
     * @see org.gvsig.andami.ui.mdiFrame.MainFrame#removeMenu(org.gvsig.andami.plugins.config.generate.Menu)
1587
     */
1588
    public void removeMenu(Menu menu) {
1589
        JMenuItem delete = (JMenuItem) infoCodedMenus.get(menu);
1590

    
1591
        if (delete == null) {
1592
            throw new NoSuchElementException(menu.getText());
1593
        }
1594

    
1595
        delete.getParent().remove(delete);
1596
        infoCodedMenus.remove(menu);
1597
    }
1598

    
1599
    /**
1600
     * @see org.gvsig.andami.ui.mdiFrame.MainFrame#addMenu(org.gvsig.andami.plugins.config.generate.Menu,
1601
     *      java.awt.event.ActionListener, PluginClassLoader)
1602
     */
1603
    public void addMenu(Menu menu, ActionListener listener,
1604
        PluginClassLoader loader) {
1605
        JMenu menuPadre = createMenuAncestors(menu, loader);
1606

    
1607
        // Se registra y a�ade el menu
1608
        JMenuItem nuevoMenu = createJMenuItem(loader, menu);
1609
        nuevoMenu.addMouseListener(tooltipListener);
1610
        if( listener != null && menu.getName() != null && menu.getName().trim().length()>0 ) {
1611
                    ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1612
                    final ActionInfo actionInfo = actionManager.getAction(menu.getName());
1613
                    if( actionInfo != null ) {
1614
                            nuevoMenu.removeActionListener(actionInfo);
1615
                    }
1616
                nuevoMenu.addActionListener(listener);
1617
        } else {
1618
            /*
1619
             * We also add action listener for menu with
1620
             * no name but with text:
1621
             * 
1622
             * Window/Project manager
1623
             * Window/View - 1
1624
             * Window/View - 2
1625
             * etc
1626
             */
1627
            if( listener != null && menu.getText() != null && menu.getText().trim().length()>0) {
1628
                nuevoMenu.addActionListener(listener);
1629
            }
1630
            
1631
        }
1632
        menuPadre.add(nuevoMenu);
1633

    
1634
        infoCodedMenus.put(menu, nuevoMenu);
1635
    }
1636

    
1637
    /**
1638
     * @see org.gvsig.andami.ui.mdiFrame.MainFrame#changeMenuName(java.lang.String[],
1639
     *      String, org.gvsig.andami.plugins.PluginClassLoader)
1640
     */
1641
    public void changeMenuName(String[] menu, String newName,
1642
        PluginClassLoader loader) {
1643

    
1644
        ArrayList menuList = new ArrayList();
1645
        for (int i = 0; i < menu.length; i++) {
1646
            menuList.add(menu[i]);
1647
        }
1648

    
1649
        javax.swing.JMenuItem newMenu = getMenu(menuList, menuBar);
1650
        if (newMenu == null) {
1651
            throw new NoSuchMenuException(menu[0]);
1652
        } else {
1653
            newMenu.setText(PluginServices.getText(this, newName));
1654
        }
1655
    }
1656

    
1657
    /**
1658
     * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
1659
     */
1660
    public void componentHidden(ComponentEvent arg0) {
1661
    }
1662

    
1663
    /**
1664
     * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
1665
     */
1666
    public void componentMoved(ComponentEvent arg0) {
1667
    }
1668

    
1669
    /**
1670
     * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
1671
     */
1672
    public void componentResized(ComponentEvent arg0) {
1673
        ajustarToolBar();
1674
    }
1675

    
1676
    /**
1677
     * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
1678
     */
1679
    public void componentShown(ComponentEvent arg0) {
1680
    }
1681

    
1682
    /**
1683
     * @see java.awt.event.ContainerListener#componentAdded(java.awt.event.ContainerEvent)
1684
     */
1685
    public void componentAdded(ContainerEvent arg0) {
1686
        ajustarToolBar();
1687
    }
1688

    
1689
    /**
1690
     * @see java.awt.event.ContainerListener#componentRemoved(java.awt.event.ContainerEvent)
1691
     */
1692
    public void componentRemoved(ContainerEvent arg0) {
1693
        ajustarToolBar();
1694
    }
1695

    
1696
    /**
1697
     * DOCUMENT ME!
1698
     * 
1699
     * @author $author$
1700
     * @version $Revision: 39425 $
1701
     */
1702
    public class TooltipListener extends MouseAdapter {
1703

    
1704
        /**
1705
         * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
1706
         */
1707
        @Override
1708
        public void mouseEntered(MouseEvent e) {
1709
            JComponent control = (JComponent) e.getSource();
1710
            EnableTextSupport ets = (EnableTextSupport) e.getSource();
1711

    
1712
            String texto = null;
1713
            texto = control.getToolTipText();
1714

    
1715
            if (texto != null) {
1716
                bEstado.setInfoTextTemporal(texto);
1717
            }
1718
        }
1719

    
1720
        /**
1721
         * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
1722
         */
1723
        @Override
1724
        public void mouseExited(MouseEvent arg0) {
1725
            bEstado.restaurarTexto();
1726
        }
1727

    
1728
        /**
1729
         * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
1730
         */
1731
        @Override
1732
        public void mousePressed(MouseEvent e) {
1733
            bEstado.restaurarTexto();
1734
        }
1735
    }
1736

    
1737
    public String getTitlePrefix() {
1738
        return titlePrefix;
1739
    }
1740

    
1741
    public void setTitlePrefix(String titlePrefix) {
1742
        this.titlePrefix = titlePrefix;
1743
    }
1744

    
1745
    public Map getSelectedTools() {
1746
        return selectedTool;
1747
    }
1748

    
1749
    public HashMap getInitialSelectedTools() {
1750
        return initialSelectedTools;
1751
    }
1752

    
1753
    /**
1754
     * Get a previously added JComponent by name. For example
1755
     * you can use it if you need to obtain a JToolBar to
1756
     * add some customized component.
1757
     * 
1758
     * @param name
1759
     * @return the JComponent or null if none has been found
1760
     */
1761
    public JComponent getComponentByName(String name) {
1762
        Iterator e = controlClass.keySet().iterator();
1763

    
1764
        while (e.hasNext()) {
1765
            JComponent control = (JComponent) e.next();
1766
            String nameCtrl = control.getName();
1767
            if (nameCtrl != null) {
1768
                if (nameCtrl.compareTo(name) == 0) {
1769
                    return control;
1770
                }
1771
            }
1772
        }
1773
        Iterator it = toolBarMap.values().iterator();
1774
        while (it.hasNext()) {
1775
                JComponent t = (JComponent) it.next();
1776
            String nameCtrl = t.getName();
1777
            if (nameCtrl != null) {
1778
                if (nameCtrl.compareTo(name) == 0) {
1779
                    return t;
1780
                }
1781
            }
1782

    
1783
        }
1784

    
1785
        return null;
1786
    }
1787

    
1788
    public SelectableToolBar[] getToolbars() {
1789
        return (SelectableToolBar[]) toolBarMap.values().toArray(
1790
            new SelectableToolBar[0]);
1791
    }
1792

    
1793
    public boolean getToolbarVisibility(String name) {
1794
        JComponent component =
1795
            PluginServices.getMainFrame().getComponentByName(name);
1796
        if ((component != null) && (component instanceof SelectableToolBar)) {
1797
            SelectableToolBar toolBar = (SelectableToolBar) component;
1798
            return toolBar.getAndamiVisibility();
1799
        }
1800
        return false;
1801
    }
1802

    
1803
    public boolean setToolbarVisibility(String name, boolean visibility) {
1804
        JComponent component =
1805
            PluginServices.getMainFrame().getComponentByName(name);
1806
        if ((component != null) && (component instanceof SelectableToolBar)) {
1807
            SelectableToolBar toolBar = (SelectableToolBar) component;
1808
            boolean oldVisibility = toolBar.getAndamiVisibility();
1809
            toolBar.setAndamiVisibility(visibility);
1810
            enableControls();
1811
            return oldVisibility;
1812
        }
1813
        return false;
1814
    }
1815

    
1816
    public javax.swing.JMenuItem getMenuEntry(String[] menuPath) {
1817
        ArrayList menu = new ArrayList();
1818
        for (int i = 0; i < menuPath.length; i++) {
1819
            menu.add(menuPath[i]);
1820
        }
1821
        return getMenu(menu, menuBar);
1822
    }
1823

    
1824
        public void messageDialog(String message, String title, int messageType) {
1825
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1826
                helper.messageDialog(message, title, messageType);
1827
        }
1828

    
1829
        public void messageDialog(String message, String[] messageArgs,
1830
                        String title, int messageType) {
1831
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1832
                helper.messageDialog(message, messageArgs, title, messageType);
1833
        }
1834

    
1835
        public int confirmDialog(String message, String title, int optionType,
1836
                        int messageType) {
1837
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1838
                return helper.confirmDialog(message, title, optionType, messageType);
1839
        }
1840

    
1841
        public String inputDialog(String message, String title, int messageType,
1842
                        String initialValue) {
1843
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1844
                return helper.inputDialog(message, title, messageType, initialValue);
1845
        }
1846

    
1847
        public String inputDialog(String message, String title) {
1848
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1849
                return helper.inputDialog(message, title);
1850
        }
1851

    
1852
        public void showDialog(Component contents, String title) {
1853
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1854
                helper.showDialog(contents, title);
1855
        }
1856

    
1857
        public Component createComponent(Class<? extends Component> theClass,
1858
                        Object... parameters) {
1859
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1860
                return helper.createComponentWithParams(theClass, parameters);
1861
        }
1862

    
1863
        public Component createComponentWithParams(
1864
                        Class<? extends Component> theClass, Object[] parameters) {
1865
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1866
                return helper.createComponentWithParams(theClass, parameters);
1867
        }
1868

    
1869
}