Statistics
| Revision:

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

History | View | Annotate | Download (62.1 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.lang.reflect.InvocationTargetException;
59
import java.util.ArrayList;
60
import java.util.Enumeration;
61
import java.util.HashMap;
62
import java.util.Iterator;
63
import java.util.Map;
64
import java.util.Map.Entry;
65
import java.util.NoSuchElementException;
66
import java.util.StringTokenizer;
67
import java.util.Vector;
68

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

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

    
113
/**
114
 * Main application window.
115
 * 
116
 * @version $Revision: 39145 $
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
        // TODO LWS Aqui deber�a cargar los valores salvados de la �ltima
237
        // ejecuci�n.
238
        setSize(700, 580);
239
        setLocation(10, 10);
240
        setExtendedState(MAXIMIZED_BOTH);
241

    
242
        mdiManager.init(this);
243

    
244
        pack();
245

    
246
    }
247

    
248
    /*
249
     * (non-javadoc)
250
     * 
251
     * @see java.awt.Frame.setTitle(String title)
252
     */
253
    @Override
254
    public void setTitle(final String title) {
255
        if (!SwingUtilities.isEventDispatchThread()) {
256
            SwingUtilities.invokeLater(new Runnable() {
257
                public void run() {
258
                        setTitle(title);
259
                }
260
            });
261
            return;
262
        }
263
        super.setTitle(titlePrefix + " : " + title);
264
    }
265

    
266
    /**
267
     * A�ade un modo de operaci�n a la caja de herramientas
268
     * 
269
     * @param ext
270
     *            Texto del boton, si es null no aparece texto
271
     * @param ext
272
     *            Icono del boton, si es null no aparece icono
273
     * @param ext
274
     *            Extensi�n asociada al control
275
     * @param selectableTool
276
     *            Enable text del control
277
     * 
278
     * @throws ClassNotFoundException
279
     * @throws RuntimeException
280
     *             DOCUMENT ME!
281
     */
282
    public void addTool(PluginClassLoader loader, SkinExtensionType ext,
283
        ToolBar toolBar, SelectableTool selectableTool)
284
        throws ClassNotFoundException {
285
        if (!SwingUtilities.isEventDispatchThread()) {
286
            throw new RuntimeException("No Event Dispatch Thread");
287
        }
288
        
289
        Class<? extends IExtension> classExtension = (Class<? extends IExtension>) loader.loadClass(ext.getClassName());
290
        
291
        // Para traducir
292
        PluginServices ps =
293
            PluginServices.getPluginServices(loader.getPluginName());
294

    
295
        JToolBarToggleButton btn;
296
        ImageIcon image =
297
            PluginServices.getIconTheme().get(selectableTool.getIcon());
298

    
299
        if (image != null) {
300
            btn = new JToolBarToggleButton(selectableTool.getText(), image);
301
        } else {
302
            logger.error(PluginServices.getText(this, "Unable_to_find_icon")
303
                + ": " + selectableTool.getIcon());
304
            btn =
305
                new JToolBarToggleButton(selectableTool.getText(),
306
                    PluginServices.getIconTheme().get(noIcon));
307
        }
308

    
309
        org.gvsig.andami.ui.mdiFrame.ToggleButtonModel buttonModel =
310
            new org.gvsig.andami.ui.mdiFrame.ToggleButtonModel();
311
        btn.setModel(buttonModel);
312
        btn.setMargin(new Insets(0, 0, 0, 0));
313
        btn.addMouseListener(tooltipListener);
314
        btn.addActionListener(this);
315
        btn.setFocusable(false);
316
        btn.setActionCommand(selectableTool.getActionCommand());
317
        btn.setToolTipText(selectableTool.getTooltip());
318
        btn.setEnabled(false);
319
        btn.setVisible(false);
320
        String name = toolBar.getName();
321

    
322
        SelectableToolBar jtb = (SelectableToolBar) toolBarMap.get(name);
323

    
324
        if (jtb == null) {
325
            jtb = new SelectableToolBar(name);
326
            jtb.setRollover(true);
327
            jtb.setAndamiVisibility(toolBar.getIsVisible());
328
            toolBarMap.put(name, jtb);
329
            toolBars.add(jtb);
330
        }
331

    
332
        ButtonGroup group;
333
        if (buttonGroupMap.containsKey(selectableTool.getGroup())) {
334
            group = (ButtonGroup) buttonGroupMap.get(selectableTool.getGroup());
335
        } else {
336
            group = new ButtonGroup();
337
            buttonGroupMap.put(selectableTool.getGroup(), group);
338

    
339
        }
340
        jtb.addButton(group, btn);
341
        buttonModel.setGroupName(selectableTool.getGroup());
342

    
343
        if (selectableTool.getIsDefault()) {
344
            btn.setSelected(true);
345
            initialSelectedTools.put(selectableTool.getGroup(),
346
                btn.getActionCommand());
347
        }
348

    
349
        controlClass.put(btn, classExtension);
350

    
351
        if (selectableTool.getName() != null) {
352
            btn.setName(selectableTool.getName());
353
        }
354

    
355
        if (selectableTool.getTooltip() != null) {
356
            btn.setToolTip(ps.getText(selectableTool.getTooltip()));
357
        }
358

    
359
        if (selectableTool.getEnableText() != null) {
360
            btn.setEnableText(ps.getText(selectableTool.getEnableText()));
361
        }
362

    
363
        if (selectableTool.getLast() == true) {
364
            jtb.addSeparator();
365
        }
366
    }
367

    
368
    /**
369
     * A�ade un bot�n a la barra de herramientas
370
     * 
371
     * @param ext
372
     *            Texto del boton, si es null no aparece texto
373
     * @param ext
374
     *            Extensi�n asociada al control
375
     * @param toolBar
376
     *            Icono del boton, si es null no aparece texto
377
     * @param actionTool
378
     *            Tooltip de la barra de herramientas
379
     * 
380
     * @throws ClassNotFoundException
381
     * @throws RuntimeException
382
     *             DOCUMENT ME!
383
     */
384
    public void addTool(PluginClassLoader loader, SkinExtensionType ext,
385
        ToolBar toolBar, ActionTool actionTool) throws ClassNotFoundException {
386
        if (!SwingUtilities.isEventDispatchThread()) {
387
            throw new RuntimeException("No Event Dispatch Thread");
388
        }
389
        Class<? extends IExtension> classExtension = (Class<? extends IExtension>) loader.loadClass(ext.getClassName());
390
        
391
        // Para traducir los textos que vengan
392
        PluginServices ps =
393
            PluginServices.getPluginServices(loader.getPluginName());
394

    
395
        JToolBarButton btn;
396
        ImageIcon image = IconThemeHelper.getImageIcon(actionTool.getIcon());
397

    
398
        if (image != null) {
399
            btn = new JToolBarButton(actionTool.getText(), image);
400
        } else {
401
            logger.error(PluginServices.getText(this, "Unable_to_find_icon")
402
                + ": " + actionTool.getIcon());
403
            btn =
404
                new JToolBarButton(actionTool.getText(), PluginServices
405
                    .getIconTheme().get(noIcon));
406
        }
407

    
408
        btn.setMargin(new Insets(0, 0, 0, 0));
409
        btn.addMouseListener(tooltipListener);
410
        btn.addActionListener(this);
411
        btn.setFocusable(false);
412
        btn.setActionCommand(actionTool.getActionCommand());
413
        btn.setEnabled(false);
414
        btn.setVisible(false);
415

    
416
        String name = toolBar.getName();
417

    
418
        SelectableToolBar jtb = (SelectableToolBar) toolBarMap.get(name);
419

    
420
        if (jtb == null) {
421
            jtb = new SelectableToolBar(name);
422
            jtb.setRollover(true);
423
            jtb.setAndamiVisibility(toolBar.getIsVisible());
424
            toolBarMap.put(name, jtb);
425
            toolBars.add(jtb);
426
        }
427

    
428
        jtb.add(btn);
429

    
430
        controlClass.put(btn, classExtension);
431

    
432
        if (actionTool.getName() != null) {
433
            btn.setName(actionTool.getName());
434
        }
435

    
436
        if (actionTool.getTooltip() != null) {
437
            btn.setToolTip(ps.getText(actionTool.getTooltip()));
438
        }
439

    
440
        if (actionTool.getEnableText() != null) {
441
            btn.setEnableText(ps.getText(actionTool.getEnableText()));
442
        }
443

    
444
        if (actionTool.getLast() == true) {
445
            jtb.addSeparator();
446
        }
447
    }
448

    
449
    /**
450
     * Creates the needed menu structure to add the menu to the bar.
451
     * Returns the father which must hold the menu which was
452
     * provided as parameter.
453
     * 
454
     * Crea la estructura de men�s necesaria para a�adir el menu a la barra.
455
     * Devuelve el padre del cual debe colgar el menu que se pasa como
456
     * par�metro.
457
     * 
458
     * @param menu
459
     *            The Menu whose support is going to be added
460
     * @param loader
461
     *            The plugin's class loader
462
     * 
463
     * @return The proper father for the menu which was provided as parameter
464
     */
465
    private JMenu createMenuAncestors(Menu menu, PluginClassLoader loader) {
466
        MenuElement menuPadre = null;
467

    
468
        PluginServices ps =
469
            PluginServices.getPluginServices(loader.getPluginName());
470

    
471
        String[] menues = menu.getText().split("/");
472
        ArrayList menuList = new ArrayList();
473
        menuList.add(menues[0]);
474
        menuPadre = getMenu(menuList, menuBar);
475

    
476
        JMenu padre = null;
477

    
478
        if (menuPadre == null) {
479
            padre = new JMenu(ps.getText(menues[0]));
480
            padre.setName(menues[0]);
481
            menuBar.add(padre);
482
        } else
483
            if (menuPadre instanceof JMenu) {
484
                padre = (JMenu) menuPadre;
485
            } else {
486
                logger.error(ps
487
                    .getText("error_creating_menu_Ancestor_does_not_exist"));
488
                return null;
489
            }
490

    
491
        // Se crea el resto de menus
492
        ArrayList temp = new ArrayList();
493

    
494
        for (int i = 1; i < (menues.length - 1); i++) {
495
            temp.add(menues[i]);
496
        }
497

    
498
        menuPadre = createMenus(temp, padre);
499

    
500
        return (JMenu) menuPadre;
501
    }
502

    
503
    /**
504
     * A�ade la informaci�n del menu al framework. Debido a que los men�es
505
     * se
506
     * pueden introducir en un orden determinado por el usuario, pero los
507
     * plugins se instalan en un orden arbitrario, primero se almacena la
508
     * informaci�n de todos los menus para luego ordenarlos y posteriormente
509
     * a�adirlos al interfaz
510
     * 
511
     * @param loader
512
     *            Posicion del menu. Se ordena por este campo
513
     * @param ext
514
     *            Array con los nombres de los padres del menu
515
     * @param menu
516
     *            Texto del menu
517
     * 
518
     * @throws ClassNotFoundException
519
     * @throws RuntimeException
520
     *             DOCUMENT ME!
521
     */
522
    public void addMenu(PluginClassLoader loader, SkinExtensionType ext,
523
        Menu menu) throws ClassNotFoundException {
524
        if (!SwingUtilities.isEventDispatchThread()) {
525
            throw new RuntimeException("No Event Dispatch Thread");
526
        }
527
                JMenu menuPadre = createMenuAncestors(menu, loader);
528

    
529
        if (menu.getIs_separator()) {
530
            menuPadre.addSeparator();
531
            return;
532
        }
533

    
534
        JMenuItem nuevoMenu = createJMenuItem(loader, menu);
535
        nuevoMenu.addMouseListener(tooltipListener);
536
        //nuevoMenu.addActionListener(this);
537
        menuPadre.add(nuevoMenu);
538
        Class<? extends IExtension> classExtension = (Class<? extends IExtension>) loader.loadClass(ext.getClassName());
539
        controlClass.put(nuevoMenu, classExtension);
540
    }
541

    
542
    /**
543
     * Dado un array de nombres de menu, encuentra el men�
544
     * 
545
     * @param nombres
546
     *            DOCUMENT ME!
547
     * @param padre
548
     *            DOCUMENT ME!
549
     * 
550
     * @return DOCUMENT ME!
551
     */
552
    private javax.swing.JMenuItem getMenu(ArrayList nombres, MenuElement parent) {
553
        if (parent instanceof javax.swing.JMenu) {
554
            javax.swing.JMenu parentItem = (javax.swing.JMenu) parent;
555

    
556
            for (int i = 0; i < parentItem.getMenuComponentCount(); i++) {
557
                
558
                String item_name = parentItem.getMenuComponent(i).getName(); 
559
                if (((item_name != null) && (item_name.compareTo((String) nombres.get(0)) == 0))
560
                    ||
561
                    /*
562
                     * We also accept "leaf menus" with no name
563
                     * (Project manager, View-1, View-2, etc)
564
                     */
565
                    lastMenuItemWithoutName(parentItem.getMenuComponent(i), nombres))
566
                    {
567
                    
568
                    nombres.remove(0);
569
                    if (nombres.isEmpty()) {
570
                        if (parentItem.getMenuComponent(i) instanceof javax.swing.JMenuItem) {
571
                            return (javax.swing.JMenuItem) parentItem
572
                                .getMenuComponent(i);
573
                        } else {
574
                            logger.error(PluginServices.getText(this,
575
                                "Menu_type_not_supported_")
576
                                + " "
577
                                + parentItem.getMenuComponent(i).getClass()
578
                                    .getName());
579
                            return null;
580
                        }
581
                    } else {
582
                        return getMenu(nombres,
583
                            (MenuElement) parentItem.getMenuComponent(i));
584
                    }
585
                }
586
            }
587
        } else
588
            if (parent instanceof JMenuBar) {
589
                javax.swing.JMenuBar parentItem = (javax.swing.JMenuBar) parent;
590

    
591
                for (int i = 0; i < parentItem.getMenuCount(); i++) {
592
                    if ((parentItem.getMenu(i).getName() != null // not a
593
                                                                 // JToolBar.Separator
594
                        )
595
                        && (parentItem.getMenu(i).getName()
596
                            .compareTo((String) nombres.get(0)) == 0)) {
597
                        nombres.remove(0);
598
                        if (nombres.isEmpty()) {
599
                            if (parentItem.getMenu(i) instanceof javax.swing.JMenuItem) {
600
                                return parentItem.getMenu(i);
601
                            } else {
602
                                logger.error(PluginServices.getText(this,
603
                                    "Menu_type_not_supported_")
604
                                    + " "
605
                                    + parentItem.getMenu(i).getClass()
606
                                        .getName());
607
                                return null;
608
                            }
609
                        } else {
610
                            return getMenu(nombres, parentItem.getMenu(i));
611
                        }
612
                    }
613
                }
614
            } else {
615
                logger.error(PluginServices.getText(this,
616
                    "Menu_type_not_supported_")
617
                    + " "
618
                    + parent.getClass().getName() + " " + parent.toString());
619
            }
620
        return null;
621
    }
622

    
623
    /**
624
     * @param menuComponent
625
     * @param nombres
626
     * @return
627
     */
628
    private boolean lastMenuItemWithoutName(Component mc, ArrayList names) {
629
        
630
        /*
631
         * names must have 1 string
632
         */
633
        if (names == null || names.size() != 1) {
634
            return false;
635
        }
636
        if (!(mc instanceof JMenuItem)) {
637
            return false;
638
        }
639
        JMenuItem jmi = (JMenuItem) mc;
640
        if (jmi.getName() != null) {
641
            /*
642
             * Name must be null, so this is a menu leaf
643
             */
644
            return false;
645
        }
646
        if (jmi.getText() == null) {
647
            return false;
648
        }
649
        return jmi.getText().compareTo((String) names.get(0)) == 0;
650
    }
651

    
652
    /**
653
     * Crea la estructura de menus recursivamente. Por ejemplo, si se le pasa
654
     * en el par�metro nombres el array {"Search", "References", "Workspace"}
655
     * crear� un men� Search, un submen� del anterior que se llamar�
656
     * References y debajo de �ste �ltimo otro menu llamado Workspace
657
     * 
658
     * @param nombres
659
     *            Array con los nombres de los men�s que se quieren crear
660
     * @param padre
661
     *            Menu padre de los men�s creados. Es �til porque es un
662
     *            algoritmo recursivo
663
     * 
664
     * @return Devuelve el men� creado. Al final de toda la recursividad,
665
     *         devolver� el men� de m�s abajo en la jerarqu�a
666
     * 
667
     * @throws RuntimeException
668
     *             DOCUMENT ME!
669
     */
670
    private JMenu createMenus(ArrayList nombres, JMenu padre) {
671
        if (!SwingUtilities.isEventDispatchThread()) {
672
            throw new RuntimeException("No Event Dispatch Thread");
673
        }
674

    
675
        // si no quedan nombres de menu por crear se vuelve: caso base
676
        if (nombres.size() == 0) {
677
            return padre;
678
        }
679

    
680
        // Se busca el menu por si ya existiera para no crearlo otra vez
681
        JMenu buscado = null;
682

    
683
        for (int i = 0; i < padre.getMenuComponentCount(); i++) {
684
            try {
685
                JMenu hijo = (JMenu) padre.getMenuComponent(i);
686

    
687
                if (hijo.getName().compareTo((String) nombres.get(0)) == 0) {
688
                    buscado = hijo;
689
                }
690
            } catch (ClassCastException e) {
691
                /*
692
                 * Se ha encontrado un elemento hoja del arbol de men�es
693
                 */
694
            }
695
        }
696

    
697
        if (buscado != null) {
698
            // Si lo hemos encontrado creamos el resto
699
            nombres.remove(0);
700

    
701
            return createMenus(nombres, buscado);
702
        } else {
703
            // Si no lo hemos encontrado se crea el menu, se a�ade al padre
704
            // y se crea el resto
705
            String nombre = (String) nombres.get(0);
706
            JMenu menuPadre = new JMenu(PluginServices.getText(this, nombre));
707
            menuPadre.setName(nombre);
708
            padre.add(menuPadre);
709

    
710
            nombres.remove(0);
711

    
712
            return createMenus(nombres, menuPadre);
713
        }
714
    }
715

    
716
    /**
717
     * M�todo invocado en respuesta a ciertos eventos de la interfaz que
718
     * pueden
719
     * ocultar botones de las barras de herramientas y que redimensiona �sta
720
     * de manera conveniente para que no se oculte ninguno
721
     */
722
    private void ajustarToolBar() {
723
        int margen = 8;
724
        int numFilas = 1;
725
        double acum = margen;
726

    
727
        int toolHeight = 0;
728

    
729
        for (int i = 0; i < toolBars.getComponentCount(); i++) {
730
            Component c = toolBars.getComponent(i);
731

    
732
            if (!c.isVisible()) {
733
                continue;
734
            }
735

    
736
            double width = c.getPreferredSize().getWidth();
737
            acum = acum + width;
738

    
739
            if (acum > this.getWidth()) {
740
                numFilas++;
741
                acum = width + margen;
742
            }
743

    
744
            if (c.getPreferredSize().getHeight() > toolHeight) {
745
                toolHeight = c.getPreferredSize().height;
746
            }
747
        }
748

    
749
        toolBars.setPreferredSize(new Dimension(this.getWidth(),
750
            (numFilas * toolHeight)));
751

    
752
        toolBars.updateUI();
753
    }
754

    
755
    /**
756
     * DOCUMENT ME!
757
     * 
758
     * @param classesExtensions
759
     */
760
    public void setClassesExtensions(Map<Class<? extends IExtension>, ExtensionDecorator> classesExtensions) {
761
            Map<Class<? extends IExtension>, ExtensionDecorator> extensions = new HashMap<Class<? extends IExtension>, ExtensionDecorator>();
762
            for ( Entry<Class<? extends IExtension>, ExtensionDecorator>  entry: classesExtensions.entrySet()) {
763
                        if( ! (entry.getValue().getExtension() instanceof LibraryExtension) ) {
764
                                extensions.put(entry.getKey(), entry.getValue());
765
                        }
766
                }
767
        this.classesExtensions = extensions;
768
    }
769

    
770
    /**
771
     * Metodo de callback invocado cuando se selecciona un menu o un boton
772
     * de
773
     * la barra de herramientas. Se busca la extensi�n asociada y se ejecuta
774
     * 
775
     * @param e
776
     *            Evento producido
777
     */
778
    public void actionPerformed(ActionEvent e) {
779
        
780
//        org.gvsig.andami.plugins.IExtension ext =
781
//            (org.gvsig.andami.plugins.IExtension) classesExtensions
782
//                .get(controlClass.get(control));
783
            String actionName = "(unknow)";
784
        try {
785
            JComponent control = (JComponent) e.getSource();
786
            actionName = control.getName();
787
            
788
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
789
                ActionInfo action = actionManager.getAction(control.getName());
790
                Object args = null;
791
            if( control instanceof IControl ) {
792
                    args = ((IControl) control).getValue();
793
            }
794
            if( args == null ) {
795
                    action.execute();
796
            } else {
797
                    action.execute(args);                    
798
            }
799
                
800
//            logger.info("{}.execute('{}')", ext.getClass().getSimpleName(), actionCommand);
801
//            ext.execute(actionCommand);
802

    
803
                String actionCommand = e.getActionCommand();
804
            try {
805
                JToolBarToggleButton toggle = (JToolBarToggleButton) control;
806
                ToggleButtonModel model = (ToggleButtonModel) toggle.getModel();
807
                selectedTool.put(model.getGroupName(), actionCommand);
808
            } catch (ClassCastException ex) {
809
            } catch (NullPointerException ex) {
810
            }
811

    
812
        } catch (Throwable ex) {
813
                logger.error("Can't perform action '"+actionName+"'.",ex);
814
//            if (ext == null) {
815
//                logger.error(Messages
816
//                    .getString("No_extension_associated_with_this_event_")
817
//                    + e.getActionCommand());
818
//            }
819
//            NotificationManager.addError(Messages
820
//                .getString("MDIFrame.Error_no_capturado_por_el_usuario"), t);
821
        }
822

    
823
        enableControls();
824
        showMemory();
825
    }
826

    
827
    /**
828
     * DOCUMENT ME!
829
     * 
830
     * @param name
831
     *            DOCUMENT ME!
832
     * @param loader
833
     *            DOCUMENT ME!
834
     * 
835
     * @return DOCUMENT ME!
836
     */
837
    private String getName(String name, PluginClassLoader loader) {
838
        if (name.indexOf('.') == -1) {
839
            return loader.getPluginName() + "." + name;
840
        } else {
841
            return name;
842
        }
843
    }
844

    
845
    /**
846
     * DOCUMENT ME!
847
     * 
848
     * @param loader
849
     *            DOCUMENT ME!
850
     * @param menu
851
     *            DOCUMENT ME!
852
     * 
853
     * @throws RuntimeException
854
     *             DOCUMENT ME!
855
     */
856
    public void addPopupMenu(PluginClassLoader loader, PopupMenu menu) {
857
        if (!SwingUtilities.isEventDispatchThread()) {
858
            throw new RuntimeException("No Event Dispatch Thread");
859
        }
860

    
861
        String name = getName(menu.getName(), loader);
862

    
863
        // Se crea el control popupmenu
864
        JPopUpMenu popupMenu = (JPopUpMenu) popupMap.get(name);
865

    
866
        if (popupMenu == null) {
867
            popupMenu = new JPopUpMenu(menu.getName());
868
            popupMap.put(name, popupMenu);
869
        }
870

    
871
        Menu[] menues = menu.getMenu();
872
        for (int i = 0; i < menues.length; i++) {
873
            JMenuItem nuevoMenu = createJMenuItem(loader, menues[i]);
874
            popupMenu.add(nuevoMenu);
875
        }
876
    }
877

    
878
    /**
879
     * DOCUMENT ME!
880
     * 
881
     * @param loader
882
     * @param menu
883
     * 
884
     * @return
885
     * 
886
     * @throws RuntimeException
887
     *             DOCUMENT ME!
888
     */
889
    private JMenuItem createJMenuItem(PluginClassLoader loader, Menu menu) {
890
        JMenuItem nuevoMenu = null;
891

    
892
        PluginServices ps =
893
            PluginServices.getPluginServices(loader.getPluginName());
894
        
895
        String text = menu.getText();
896
        int n = text.lastIndexOf('/');
897
        if( n>=0  ) {
898
                text = text.substring(n + 1);
899
        }
900
        String translatedText = ps.getText(text);
901

    
902
        IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
903
        if (menu.getIcon() != null) {
904
                if( iconTheme.exists(menu.getIcon()) ) {
905
                        ImageIcon image = iconTheme.get(menu.getIcon());
906
                nuevoMenu = new JMenuItem(translatedText, image);
907
            } else {
908
                nuevoMenu = new JMenuItem(translatedText);
909
                logger.info("menu icon '"+ menu.getIcon()+ "' not exists.");
910
            }
911
        } else {
912
            nuevoMenu = new JMenuItem(translatedText);
913
        }
914
        nuevoMenu.setName(menu.getName());
915
//                if (menu.getMnemonic() != null) {
916
//                        if (menu.getMnemonic().length() != 1) {
917
//                                throw new RuntimeException(
918
//                                                "Mnemonic must be 1 character length");
919
//                        }
920
//                        nuevoMenu.setMnemonic(KeyMapping.getKey(menu.getMnemonic()
921
//                                        .charAt(0)));
922
//                }
923

    
924
        if (menu.getKey() != null) {
925
            nuevoMenu.setAccelerator(KeyMapping.getKeyStroke(menu.getKey()));
926
        }
927

    
928
        nuevoMenu.setActionCommand(menu.getActionCommand());
929

    
930
        if (menu.getTooltip() != null) {
931
            nuevoMenu.setToolTip(ps.getText(menu.getTooltip()));
932
        }
933

    
934
        if (menu.getEnableText() != null) {
935
            nuevoMenu.setEnableText(ps.getText(menu.getEnableText()));
936
        }
937

    
938
        nuevoMenu.setEnabled(true);
939
        nuevoMenu.setVisible(true);
940

    
941
        if( menu.getName() != null ) {
942
                    ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
943
                    final ActionInfo actionInfo = actionManager.getAction(menu.getName());
944
                    if( actionInfo != null ) {
945
                            nuevoMenu.addActionListener(actionInfo);
946
                    }
947
        }
948
        return nuevoMenu;
949
    }
950

    
951
    /**
952
     * Muestra u oculta el menu de nombre 'name'
953
     * 
954
     * @param name
955
     *            Nombre del menu que se quiere mostrar
956
     * @param x
957
     *            Evento de raton
958
     * @param y
959
     *            DOCUMENT ME!
960
     * @param c
961
     *            DOCUMENT ME!
962
     */
963
    private void showPopupMenu(String name, int x, int y, Component c) {
964
        JPopupMenu menu = (JPopupMenu) popupMap.get(name);
965

    
966
        if (menu != null) {
967
            menu.show(c, x, y);
968
        }
969
    }
970

    
971
    /**
972
     * DOCUMENT ME!
973
     * 
974
     * @param name
975
     *            DOCUMENT ME!
976
     * @param listener
977
     *            DOCUMENT ME!
978
     */
979
    public void removePopupMenuListener(String name, ActionListener listener) {
980
        JPopupMenu menu = (JPopupMenu) popupMap.get(name);
981

    
982
        if (menu != null) {
983
            Component[] jmenuitems = menu.getComponents();
984

    
985
            for (int i = 0; i < jmenuitems.length; i++) {
986
                if (jmenuitems[i] instanceof JMenuItem) {
987
                    ((JMenuItem) jmenuitems[i]).removeActionListener(listener);
988
                }
989
            }
990
        }
991
    }
992

    
993
    /**
994
     * DOCUMENT ME!
995
     * 
996
     * @param popupName
997
     * @param c
998
     *            DOCUMENT ME!
999
     * @param listener
1000
     * @param loader
1001
     */
1002
    public void addPopupMenuListener(String popupName, Component c,
1003
        ActionListener listener, PluginClassLoader loader) {
1004
        final String name = getName(popupName, loader);
1005

    
1006
        JPopupMenu menu = (JPopupMenu) popupMap.get(name);
1007

    
1008
        if (menu != null) {
1009
            Component[] jmenuitems = menu.getComponents();
1010

    
1011
            for (int i = 0; i < jmenuitems.length; i++) {
1012
                if (jmenuitems[i] instanceof JMenuItem) {
1013
                    ((JMenuItem) jmenuitems[i]).addActionListener(listener);
1014
                }
1015
            }
1016
        }
1017

    
1018
        c.addMouseListener(new MouseAdapter() {
1019

    
1020
            @Override
1021
            public void mousePressed(MouseEvent e) {
1022
                if (e.isPopupTrigger()) {
1023
                    showPopupMenu(name, e.getX(), e.getY(), e.getComponent());
1024
                }
1025
            }
1026

    
1027
            @Override
1028
            public void mouseReleased(MouseEvent e) {
1029
                if (e.isPopupTrigger()) {
1030
                    showPopupMenu(name, e.getX(), e.getY(), e.getComponent());
1031
                }
1032
            }
1033
        });
1034
    }
1035

    
1036
    /**
1037
     * Loop on the controls to enable/disable and show/hide them, according to
1038
     * its associated extension
1039
     * 
1040
     * @throws RuntimeException
1041
     *             DOCUMENT ME!
1042
     */
1043
    public void enableControls() {
1044
        if (!SwingUtilities.isEventDispatchThread()) {
1045
                SwingUtilities.invokeLater(new Runnable() {
1046
                                public void run() {
1047
                                        enableControls();
1048
                                }
1049
                        });
1050
                        return;
1051
        }
1052

    
1053
        ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1054
        ActionInfoStatusCache cache = actionManager.createActionStatusCache();
1055
        
1056
        Iterator e = classesExtensions.values().iterator();
1057

    
1058
//        HashMap estadoExtensiones = new HashMap();
1059
//        HashMap visibilidadExtensiones = new HashMap();
1060
//
1061
//        while (e.hasNext()) {
1062
//            ExtensionDecorator ext = (ExtensionDecorator) e.next();
1063
//
1064
//            try {
1065
//                if (estadoExtensiones.get(ext) == null) {
1066
//                    boolean b;
1067
//                    if (ext.getVisibility() == ExtensionDecorator.ALWAYS_VISIBLE) {
1068
//                        b = true;
1069
//                    } else
1070
//                        if (ext.getVisibility() == ExtensionDecorator.ALWAYS_INVISIBLE) {
1071
//                            b = false;
1072
//                        } else {
1073
//                            if (PluginServices.getExclusiveUIExtension() == null) {
1074
//                                b = ext.isVisible();
1075
//                            } else {
1076
//                                b =
1077
//                                    PluginServices.getExclusiveUIExtension()
1078
//                                        .isVisible(ext.getExtension());
1079
//                            }
1080
//                        }
1081
//                    Boolean visible = new Boolean(b);
1082
//                    Boolean enabled = new Boolean(false);
1083
//
1084
//                    if (visible.booleanValue()) {
1085
//                        if (PluginServices.getExclusiveUIExtension() == null) {
1086
//                            enabled = new Boolean(ext.isEnabled());
1087
//                        } else {
1088
//                            enabled =
1089
//                                new Boolean(PluginServices
1090
//                                    .getExclusiveUIExtension().isEnabled(
1091
//                                        ext.getExtension()));
1092
//                        }
1093
//
1094
//                    }
1095
//
1096
//                    estadoExtensiones.put(ext, enabled);
1097
//                    visibilidadExtensiones.put(ext, visible);
1098
//                }
1099
//            } catch (Throwable e1) {
1100
//                NotificationManager.addError(Messages
1101
//                    .getString("MDIFrame.Error_no_capturado_por_el_usuario"),
1102
//                    e1);
1103
//                estadoExtensiones.put(ext, Boolean.FALSE);
1104
//            }
1105
//        }
1106

    
1107
        // Enable or disable controls, according to its associated extensions
1108
        e = controlClass.keySet().iterator();
1109

    
1110
        while (e.hasNext()) {
1111
            JComponent control = (JComponent) e.next();
1112
            String actionlName = control.getName();
1113
            ActionInfo action = actionManager.getAction(actionlName);
1114
            try {
1115
                boolean enabled = false;
1116
                boolean visible = false;
1117
                
1118
                    if(action == null) {
1119
                  IExtension ext =
1120
                          (IExtension) classesExtensions.get(controlClass.get(control));
1121
                  enabled = ext.isEnabled();
1122
                  visible = ext.isVisible(); 
1123
                    } else {
1124
                            enabled = false;
1125
                    visible = cache.isVisible(action);
1126
                    if( visible ) {
1127
                            enabled = cache.isEnabled(action);
1128
                    }
1129
                    }
1130
                control.setEnabled(enabled);
1131
                control.setVisible(visible);
1132
            } catch (Exception ex) {
1133
                    logger.info("Can't enable/show control '"+actionlName +"'.",ex);
1134
                    this.message("Can't enable/show control '"+actionlName +"'.", JOptionPane.ERROR_MESSAGE);
1135
                control.setEnabled(false);
1136
                control.setVisible(false);
1137
            }
1138
        }
1139

    
1140
        // Loop in the menus to hide the menus that don't have visible children
1141
        for (int i = 0; i < menuBar.getMenuCount(); i++) {
1142
            MenuElement menu = menuBar.getMenu(i);
1143
            hideMenus(menu);
1144
            if (menu instanceof JMenu) {
1145
                // hide (ugly) redundant separators and assign keyboard
1146
                // mnemonics
1147
                Component[] comps = ((JMenu) menu).getMenuComponents();
1148
                // mnemonics have to be unique for each top-level menu
1149
                char mnemonics[] = new char[comps.length];
1150
                if (comps.length > 0) {
1151
                    // Set keyboard mnemonic for this top-level entry
1152
                    String text = ((JMenu) menu).getText();
1153
                    char mnemonic = getMnemonic(text, mnemonics);
1154
                    if (' ' != mnemonic) {
1155
                        ((JMenu) menu).setMnemonic(mnemonic);
1156
                        mnemonics[0] = mnemonic;
1157
                    }
1158
                }
1159
                // now go through all entries in this menu, hid
1160
                // separators if necessary and assing remaining mnemonics
1161
                hideSeparatorsAndMakeMnemonics(menu, mnemonics);
1162
            }
1163
        }
1164

    
1165
        // hide the toolbars that don't contain any visible tool
1166
        Iterator it = toolBarMap.values().iterator();
1167

    
1168
        while (it.hasNext()) {
1169
                JComponent t = (JComponent) it.next();
1170
            boolean todosOcultos = true;
1171

    
1172
            for (int i = 0; i < t.getComponentCount(); i++) {
1173
                if (!(t.getComponent(i) instanceof JSeparator) // separators
1174
                                                               // don't matter
1175
                    && t.getComponent(i).isVisible()) {
1176
                    todosOcultos = false;
1177
                }
1178
            }
1179

    
1180
            if (todosOcultos) {
1181
                t.setVisible(false);
1182
            } else {
1183
                    if(t instanceof SelectableToolBar) {
1184
                            t.setVisible(((SelectableToolBar)t).getAndamiVisibility());
1185
                    } else
1186
                            t.setVisible(true);
1187
            }
1188
        }
1189

    
1190
        if (mdiManager != null) {
1191
            JPanel f = (JPanel) mdiManager.getActiveWindow();
1192

    
1193
            if (f != null) {
1194
                if (lastLabelClass != f.getClass()) {
1195
                    lastLabelClass = f.getClass();
1196

    
1197
                    Label[] lbls = (Label[]) classLabels.get(lastLabelClass);
1198

    
1199
                    if (lbls != null) {
1200
                        bEstado.setLabelSet(lbls);
1201
                    }
1202
                }
1203
            }
1204
        }
1205

    
1206
        ajustarToolBar();
1207

    
1208
        showMemory();
1209
    }
1210
    
1211
    public void refreshControls() {
1212
        if (!SwingUtilities.isEventDispatchThread()) {
1213
                SwingUtilities.invokeLater(new Runnable() {
1214
                                public void run() {
1215
                                        refreshControls();
1216
                                }
1217
                        });
1218
                        return;
1219
        }
1220

    
1221
        ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1222
        ActionInfoStatusCache cache = actionManager.createActionStatusCache();
1223
        IconTheme icontheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1224
        
1225
        Iterator e = controlClass.keySet().iterator();
1226

    
1227
        while (e.hasNext()) {
1228
            JComponent control = (JComponent) e.next();
1229
            String actionlName = control.getName();
1230
            ActionInfo action = actionManager.getAction(actionlName);
1231
            if( action!=null ) {
1232
                    if( control instanceof AbstractButton ) {
1233

    
1234
                    AbstractButton button = (AbstractButton) control;
1235

    
1236
                        if (control instanceof javax.swing.JMenuItem) {
1237
                            
1238
                            if (action.getIconName() != null && action.getIconName().length() > 0) {
1239
                                
1240
                                if( icontheme.exists(action.getIconName()) ) {
1241
                                    button.setIcon(action.getIcon());
1242
                                }
1243
                            }
1244
                            
1245
                        } else {
1246
                            button.setIcon(action.getIcon());
1247
                        }
1248
                    }
1249
            }
1250
        }
1251
        enableControls();
1252
    }
1253

    
1254
    public void message(String msg, int messageTyoe) {
1255
            this.getStatusBar().message(msg, messageTyoe);
1256
        }
1257

    
1258
        /**
1259
     * Establece la visibilidad de un menu y todos sus descendientes en la
1260
     * jerarquia teniendo en cuenta la visibilidad de todos los submenus.
1261
     * 
1262
     * @param menu
1263
     *            Menu que se quiere visualizar
1264
     * 
1265
     * @return Devuelve true si el menu es visible y false en caso contrario
1266
     */
1267
    private boolean hideMenus(MenuElement menu) {
1268
        MenuElement[] submenus = menu.getSubElements();
1269

    
1270
        // Si no tiene hijos se devuelve su visibilidad
1271
        if (submenus.length == 0) {
1272
            return menu.getComponent().isVisible();
1273
        }
1274

    
1275
        /*
1276
         * Si tiene hijos se devuelve true si alg�no de ellos es visible,
1277
         * pero se itera por todos ellos
1278
         */
1279
        boolean visible = false;
1280

    
1281
        for (int i = 0; i < submenus.length; i++) {
1282
            if (hideMenus(submenus[i])) {
1283
                if (!(menu instanceof JPopupMenu)) {
1284
                    menu.getComponent().setVisible(true);
1285
                }
1286

    
1287
                visible = true;
1288
            }
1289
        }
1290

    
1291
        if (visible) {
1292
            return true;
1293
        }
1294

    
1295
        menu.getComponent().setVisible(false);
1296

    
1297
        return false;
1298
    }
1299

    
1300
    /**
1301
     * 
1302
     * Recurse through all menu elements and make sure there are no
1303
     * redundant separators.
1304
     * This method will make sure that a separator only becomes visible
1305
     * if at least one visible non-separator menu entry preceeded it.
1306
     * 
1307
     **/
1308
    private void hideSeparatorsAndMakeMnemonics(MenuElement menu,
1309
        char[] mnemonics) {
1310
        // flag that indicates whether a separator is to be displayed or not
1311
        boolean allowSeparator;
1312

    
1313
        allowSeparator = false; // separator not allowed as very first menu item
1314
        Component[] comps = ((JMenu) menu).getMenuComponents();
1315
        if (comps.length < 1) {
1316
            // zero-length menu: skip
1317
            return;
1318
        }
1319

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

    
1384
    /**
1385
     * Helper functios for assigning a unique mnemomic char from
1386
     * a pool of unassigned onces, stored in the array "mnemomnics"
1387
     */
1388
    private char getMnemonic(String text, char[] mnemonics) {
1389
        Vector words = new Vector();
1390
        StringTokenizer t = new StringTokenizer(text);
1391
        int maxsize = 0;
1392

    
1393
        while (t.hasMoreTokens()) {
1394
            String word = t.nextToken();
1395
            if (word.length() > maxsize) {
1396
                maxsize = word.length();
1397
            }
1398
            words.addElement(word);
1399
        }
1400
        words.trimToSize();
1401

    
1402
        for (int i = 0; i < maxsize; ++i) {
1403
            char mnemonic = getMnemonic(words, mnemonics, i);
1404
            if (' ' != mnemonic) {
1405
                return mnemonic;
1406
            }
1407
        }
1408

    
1409
        return ' ';
1410
    }
1411

    
1412
    private char getMnemonic(Vector words, char[] mnemonics, int index) {
1413
        int numwords = words.size();
1414

    
1415
        for (int i = 0; i < numwords; ++i) {
1416
            String word = (String) words.elementAt(i);
1417
            if (index >= word.length()) {
1418
                continue;
1419
            }
1420

    
1421
            char c = word.charAt(index);
1422
            if (!isMnemonicExists(c, mnemonics)) {
1423
                /* pick only valid chars */
1424
                if ((c != ':') && (c != '.') && (c != ',') && (c != ';')
1425
                    && (c != '-') && (c != '+') && (c != '/') && (c != '\\')
1426
                    && (c != '\'') && (c != '\"') && (c != ' ') && (c != '=')
1427
                    && (c != '(') && (c != ')') && (c != '[') && (c != ']')
1428
                    && (c != '{') && (c != '}') && (c != '$') && (c != '*')
1429
                    && (c != '&') && (c != '%') && (c != '!') && (c != '?')
1430
                    && (c != '#') && (c != '~') && (c != '_')) {
1431
                    return c;
1432
                }
1433
            }
1434
        }
1435
        return ' ';
1436
    }
1437

    
1438
    private boolean isMnemonicExists(char c, char[] mnemonics) {
1439
        int num = mnemonics.length;
1440
        for (int i = 0; i < num; ++i) {
1441
            if (mnemonics[i] == c) {
1442
                return true;
1443
            }
1444
        }
1445
        return false;
1446
    }
1447

    
1448
    /**
1449
     * Muestra la memoria consumida por el programa
1450
     */
1451
    private void showMemory() {
1452
        Runtime r = Runtime.getRuntime();
1453
        long mem = r.totalMemory() - r.freeMemory();
1454
        logger.debug(PluginServices.getText(this, "memory_usage") + " " + mem
1455
            / 1024 + " KB");
1456
    }
1457

    
1458
    /**
1459
     * DOCUMENT ME!
1460
     * 
1461
     * @return
1462
     */
1463
    public MDIManager getMDIManager() {
1464
        return mdiManager;
1465
    }
1466

    
1467
    /**
1468
     * Establece el mensaje en la barra de estado asociado a una etiqueta
1469
     * 
1470
     * @return DOCUMENT ME!
1471
     */
1472
    public NewStatusBar getStatusBar() {
1473
        return bEstado;
1474
    }
1475

    
1476
    /**
1477
     * You can use this function to select the appropiate
1478
     * tool inside the toolbars
1479
     */
1480
    public void setSelectedTool(String actionCommand) {
1481
        setSelectedTool(defaultGroup, actionCommand);
1482
    }
1483

    
1484
    /**
1485
     * You can use this function to select the appropiate
1486
     * tool inside the toolbars
1487
     */
1488
    public void setSelectedTool(String groupName, String actionCommand) {
1489
        ButtonGroup group = (ButtonGroup) buttonGroupMap.get(groupName);
1490
        if (group == null) {
1491
            return;
1492
        }
1493

    
1494
        Enumeration enumeration = group.getElements();
1495
        while (enumeration.hasMoreElements()) {
1496
            AbstractButton button = (AbstractButton) enumeration.nextElement();
1497
            if (button.getActionCommand().equals(actionCommand)) {
1498
                button.setSelected(true);
1499
            }
1500
        }
1501

    
1502
        selectedTool.put(groupName, actionCommand);
1503
    }
1504

    
1505
    /**
1506
     * You can use this function to select the appropiate
1507
     * tool inside the toolbars
1508
     */
1509
    public void setSelectedTools(Map selectedTools) {
1510
        selectedTool = selectedTools;
1511
        if (selectedTools == null) {
1512
            return;
1513
        }
1514
        Iterator groupNames = selectedTools.keySet().iterator();
1515
        while (groupNames.hasNext()) {
1516
            try {
1517
                String groupName = (String) groupNames.next();
1518
                ButtonGroup group = (ButtonGroup) buttonGroupMap.get(groupName);
1519
                Enumeration enumeration = group.getElements();
1520
                String actionCommand = (String) selectedTools.get(groupName);
1521
                if (actionCommand == null) {
1522
                    continue;
1523
                }
1524
                while (enumeration.hasMoreElements()) {
1525
                    AbstractButton button =
1526
                        (AbstractButton) enumeration.nextElement();
1527
                    if (button.getActionCommand().equals(actionCommand)) {
1528
                        button.setSelected(true);
1529
                    }
1530
                }
1531
            } catch (ClassCastException ex) {
1532
                logger
1533
                    .error("selectedTool should only contain pairs (String groupName, JToolBarToggleButton button)");
1534
            }
1535
        }
1536
    }
1537

    
1538
    /**
1539
     * DOCUMENT ME!
1540
     * 
1541
     * @param clase
1542
     * @param label
1543
     */
1544
    public void setStatusBarLabels(Class<?> clase, Label[] label) {
1545
        classLabels.put(clase, label);
1546
    }
1547

    
1548
    public void removeStatusBarLabels(Class<?> clase) {
1549
        classLabels.remove(clase);
1550
    }
1551

    
1552
    public void addStatusBarControl(Class<?> extensionClass, IControl control) {
1553
        control.addActionListener(this);
1554
        bEstado.addControl(control.getName(), (Component) control);
1555
        controlClass.put(control, extensionClass);
1556
    }
1557
    
1558
    public void addToolBarControl(Class<?> extensionClass, JToolBar control, String name) {
1559
        //toolBarMap.put(name, control); 
1560
        toolBars.add(control);
1561
        controlClass.put(control, extensionClass);
1562
    }
1563

    
1564
    public void removeStatusBarControl(String name) {
1565
        Component c = bEstado.removeControl(name);
1566
        if (c != null) {
1567
            controlClass.remove(c);
1568
        }
1569
    }
1570

    
1571
    /**
1572
     * @see org.gvsig.andami.ui.mdiFrame.MainFrame#removeMenu(org.gvsig.andami.plugins.config.generate.Menu)
1573
     */
1574
    public void removeMenu(Menu menu) {
1575
        JMenuItem delete = (JMenuItem) infoCodedMenus.get(menu);
1576

    
1577
        if (delete == null) {
1578
            throw new NoSuchElementException(menu.getText());
1579
        }
1580

    
1581
        delete.getParent().remove(delete);
1582
        infoCodedMenus.remove(menu);
1583
    }
1584

    
1585
    /**
1586
     * @see org.gvsig.andami.ui.mdiFrame.MainFrame#addMenu(org.gvsig.andami.plugins.config.generate.Menu,
1587
     *      java.awt.event.ActionListener, PluginClassLoader)
1588
     */
1589
    public void addMenu(Menu menu, ActionListener listener,
1590
        PluginClassLoader loader) {
1591
        JMenu menuPadre = createMenuAncestors(menu, loader);
1592

    
1593
        // Se registra y a�ade el menu
1594
        JMenuItem nuevoMenu = createJMenuItem(loader, menu);
1595
        nuevoMenu.addMouseListener(tooltipListener);
1596
        if( listener != null && menu.getName() != null && menu.getName().trim().length()>0 ) {
1597
                    ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1598
                    final ActionInfo actionInfo = actionManager.getAction(menu.getName());
1599
                    if( actionInfo != null ) {
1600
                            nuevoMenu.removeActionListener(actionInfo);
1601
                    }
1602
                nuevoMenu.addActionListener(listener);
1603
        } else {
1604
            /*
1605
             * We also add action listener for menu with
1606
             * no name but with text:
1607
             * 
1608
             * Window/Project manager
1609
             * Window/View - 1
1610
             * Window/View - 2
1611
             * etc
1612
             */
1613
            if( listener != null && menu.getText() != null && menu.getText().trim().length()>0) {
1614
                nuevoMenu.addActionListener(listener);
1615
            }
1616
            
1617
        }
1618
        menuPadre.add(nuevoMenu);
1619

    
1620
        infoCodedMenus.put(menu, nuevoMenu);
1621
    }
1622

    
1623
    /**
1624
     * @see org.gvsig.andami.ui.mdiFrame.MainFrame#changeMenuName(java.lang.String[],
1625
     *      String, org.gvsig.andami.plugins.PluginClassLoader)
1626
     */
1627
    public void changeMenuName(String[] menu, String newName,
1628
        PluginClassLoader loader) {
1629

    
1630
        ArrayList menuList = new ArrayList();
1631
        for (int i = 0; i < menu.length; i++) {
1632
            menuList.add(menu[i]);
1633
        }
1634

    
1635
        javax.swing.JMenuItem newMenu = getMenu(menuList, menuBar);
1636
        if (newMenu == null) {
1637
            throw new NoSuchMenuException(menu[0]);
1638
        } else {
1639
            newMenu.setText(PluginServices.getText(this, newName));
1640
        }
1641
    }
1642

    
1643
    /**
1644
     * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
1645
     */
1646
    public void componentHidden(ComponentEvent arg0) {
1647
    }
1648

    
1649
    /**
1650
     * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
1651
     */
1652
    public void componentMoved(ComponentEvent arg0) {
1653
    }
1654

    
1655
    /**
1656
     * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
1657
     */
1658
    public void componentResized(ComponentEvent arg0) {
1659
        ajustarToolBar();
1660
    }
1661

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

    
1668
    /**
1669
     * @see java.awt.event.ContainerListener#componentAdded(java.awt.event.ContainerEvent)
1670
     */
1671
    public void componentAdded(ContainerEvent arg0) {
1672
        ajustarToolBar();
1673
    }
1674

    
1675
    /**
1676
     * @see java.awt.event.ContainerListener#componentRemoved(java.awt.event.ContainerEvent)
1677
     */
1678
    public void componentRemoved(ContainerEvent arg0) {
1679
        ajustarToolBar();
1680
    }
1681

    
1682
    /**
1683
     * DOCUMENT ME!
1684
     * 
1685
     * @author $author$
1686
     * @version $Revision: 39145 $
1687
     */
1688
    public class TooltipListener extends MouseAdapter {
1689

    
1690
        /**
1691
         * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
1692
         */
1693
        @Override
1694
        public void mouseEntered(MouseEvent e) {
1695
            JComponent control = (JComponent) e.getSource();
1696
            EnableTextSupport ets = (EnableTextSupport) e.getSource();
1697

    
1698
            String texto = null;
1699
            texto = control.getToolTipText();
1700

    
1701
            if (texto != null) {
1702
                bEstado.setInfoTextTemporal(texto);
1703
            }
1704
        }
1705

    
1706
        /**
1707
         * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
1708
         */
1709
        @Override
1710
        public void mouseExited(MouseEvent arg0) {
1711
            bEstado.restaurarTexto();
1712
        }
1713

    
1714
        /**
1715
         * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
1716
         */
1717
        @Override
1718
        public void mousePressed(MouseEvent e) {
1719
            bEstado.restaurarTexto();
1720
        }
1721
    }
1722

    
1723
    public String getTitlePrefix() {
1724
        return titlePrefix;
1725
    }
1726

    
1727
    public void setTitlePrefix(String titlePrefix) {
1728
        this.titlePrefix = titlePrefix;
1729
    }
1730

    
1731
    public Map getSelectedTools() {
1732
        return selectedTool;
1733
    }
1734

    
1735
    public HashMap getInitialSelectedTools() {
1736
        return initialSelectedTools;
1737
    }
1738

    
1739
    /**
1740
     * Get a previously added JComponent by name. For example
1741
     * you can use it if you need to obtain a JToolBar to
1742
     * add some customized component.
1743
     * 
1744
     * @param name
1745
     * @return the JComponent or null if none has been found
1746
     */
1747
    public JComponent getComponentByName(String name) {
1748
        Iterator e = controlClass.keySet().iterator();
1749

    
1750
        while (e.hasNext()) {
1751
            JComponent control = (JComponent) e.next();
1752
            String nameCtrl = control.getName();
1753
            if (nameCtrl != null) {
1754
                if (nameCtrl.compareTo(name) == 0) {
1755
                    return control;
1756
                }
1757
            }
1758
        }
1759
        Iterator it = toolBarMap.values().iterator();
1760
        while (it.hasNext()) {
1761
                JComponent t = (JComponent) it.next();
1762
            String nameCtrl = t.getName();
1763
            if (nameCtrl != null) {
1764
                if (nameCtrl.compareTo(name) == 0) {
1765
                    return t;
1766
                }
1767
            }
1768

    
1769
        }
1770

    
1771
        return null;
1772
    }
1773

    
1774
    public SelectableToolBar[] getToolbars() {
1775
        return (SelectableToolBar[]) toolBarMap.values().toArray(
1776
            new SelectableToolBar[0]);
1777
    }
1778

    
1779
    public boolean getToolbarVisibility(String name) {
1780
        JComponent component =
1781
            PluginServices.getMainFrame().getComponentByName(name);
1782
        if ((component != null) && (component instanceof SelectableToolBar)) {
1783
            SelectableToolBar toolBar = (SelectableToolBar) component;
1784
            return toolBar.getAndamiVisibility();
1785
        }
1786
        return false;
1787
    }
1788

    
1789
    public boolean setToolbarVisibility(String name, boolean visibility) {
1790
        JComponent component =
1791
            PluginServices.getMainFrame().getComponentByName(name);
1792
        if ((component != null) && (component instanceof SelectableToolBar)) {
1793
            SelectableToolBar toolBar = (SelectableToolBar) component;
1794
            boolean oldVisibility = toolBar.getAndamiVisibility();
1795
            toolBar.setAndamiVisibility(visibility);
1796
            enableControls();
1797
            return oldVisibility;
1798
        }
1799
        return false;
1800
    }
1801

    
1802
    public javax.swing.JMenuItem getMenuEntry(String[] menuPath) {
1803
        ArrayList menu = new ArrayList();
1804
        for (int i = 0; i < menuPath.length; i++) {
1805
            menu.add(menuPath[i]);
1806
        }
1807
        return getMenu(menu, menuBar);
1808
    }
1809

    
1810
        public void messageDialog(String message, String title, int messageType) {
1811
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1812
                helper.messageDialog(message, title, messageType);
1813
        }
1814

    
1815
        public void messageDialog(String message, String[] messageArgs,
1816
                        String title, int messageType) {
1817
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1818
                helper.messageDialog(message, messageArgs, title, messageType);
1819
        }
1820

    
1821
        public int confirmDialog(String message, String title, int optionType,
1822
                        int messageType) {
1823
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1824
                return helper.confirmDialog(message, title, optionType, messageType);
1825
        }
1826

    
1827
        public String inputDialog(String message, String title, int messageType,
1828
                        String initialValue) {
1829
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1830
                return helper.inputDialog(message, title, messageType, initialValue);
1831
        }
1832

    
1833
        public String inputDialog(String message, String title) {
1834
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1835
                return helper.inputDialog(message, title);
1836
        }
1837

    
1838
        public void showDialog(Component contents, String title) {
1839
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1840
                helper.showDialog(contents, title);
1841
        }
1842

    
1843
        public Component createComponent(Class<? extends Component> theClass,
1844
                        Object... parameters) {
1845
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1846
                return helper.createComponentWithParams(theClass, parameters);
1847
        }
1848

    
1849
        public Component createComponentWithParams(
1850
                        Class<? extends Component> theClass, Object[] parameters) {
1851
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1852
                return helper.createComponentWithParams(theClass, parameters);
1853
        }
1854

    
1855
}