Statistics
| Revision:

root / branches / v2_0_0_prep / frameworks / _fwAndami / src / org / gvsig / andami / ui / mdiFrame / MDIFrame.java @ 38806

History | View | Annotate | Download (60.2 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: 38806 $
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
                if ((parentItem.getMenuComponent(i).getName() != null // not a
558
                                                                      // JToolBar.Separator
559
                    )
560
                    && (parentItem.getMenuComponent(i).getName()
561
                        .compareTo((String) nombres.get(0)) == 0)) {
562
                    nombres.remove(0);
563
                    if (nombres.isEmpty()) {
564
                        if (parentItem.getMenuComponent(i) instanceof javax.swing.JMenuItem) {
565
                            return (javax.swing.JMenuItem) parentItem
566
                                .getMenuComponent(i);
567
                        } else {
568
                            logger.error(PluginServices.getText(this,
569
                                "Menu_type_not_supported_")
570
                                + " "
571
                                + parentItem.getMenuComponent(i).getClass()
572
                                    .getName());
573
                            return null;
574
                        }
575
                    } else {
576
                        return getMenu(nombres,
577
                            (MenuElement) parentItem.getMenuComponent(i));
578
                    }
579
                }
580
            }
581
        } else
582
            if (parent instanceof JMenuBar) {
583
                javax.swing.JMenuBar parentItem = (javax.swing.JMenuBar) parent;
584

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

    
617
    /**
618
     * Crea la estructura de menus recursivamente. Por ejemplo, si se le pasa
619
     * en el par�metro nombres el array {"Search", "References", "Workspace"}
620
     * crear� un men� Search, un submen� del anterior que se llamar�
621
     * References y debajo de �ste �ltimo otro menu llamado Workspace
622
     * 
623
     * @param nombres
624
     *            Array con los nombres de los men�s que se quieren crear
625
     * @param padre
626
     *            Menu padre de los men�s creados. Es �til porque es un
627
     *            algoritmo recursivo
628
     * 
629
     * @return Devuelve el men� creado. Al final de toda la recursividad,
630
     *         devolver� el men� de m�s abajo en la jerarqu�a
631
     * 
632
     * @throws RuntimeException
633
     *             DOCUMENT ME!
634
     */
635
    private JMenu createMenus(ArrayList nombres, JMenu padre) {
636
        if (!SwingUtilities.isEventDispatchThread()) {
637
            throw new RuntimeException("No Event Dispatch Thread");
638
        }
639

    
640
        // si no quedan nombres de menu por crear se vuelve: caso base
641
        if (nombres.size() == 0) {
642
            return padre;
643
        }
644

    
645
        // Se busca el menu por si ya existiera para no crearlo otra vez
646
        JMenu buscado = null;
647

    
648
        for (int i = 0; i < padre.getMenuComponentCount(); i++) {
649
            try {
650
                JMenu hijo = (JMenu) padre.getMenuComponent(i);
651

    
652
                if (hijo.getName().compareTo((String) nombres.get(0)) == 0) {
653
                    buscado = hijo;
654
                }
655
            } catch (ClassCastException e) {
656
                /*
657
                 * Se ha encontrado un elemento hoja del arbol de men�es
658
                 */
659
            }
660
        }
661

    
662
        if (buscado != null) {
663
            // Si lo hemos encontrado creamos el resto
664
            nombres.remove(0);
665

    
666
            return createMenus(nombres, buscado);
667
        } else {
668
            // Si no lo hemos encontrado se crea el menu, se a�ade al padre
669
            // y se crea el resto
670
            String nombre = (String) nombres.get(0);
671
            JMenu menuPadre = new JMenu(PluginServices.getText(this, nombre));
672
            menuPadre.setName(nombre);
673
            padre.add(menuPadre);
674

    
675
            nombres.remove(0);
676

    
677
            return createMenus(nombres, menuPadre);
678
        }
679
    }
680

    
681
    /**
682
     * M�todo invocado en respuesta a ciertos eventos de la interfaz que
683
     * pueden
684
     * ocultar botones de las barras de herramientas y que redimensiona �sta
685
     * de manera conveniente para que no se oculte ninguno
686
     */
687
    private void ajustarToolBar() {
688
        int margen = 8;
689
        int numFilas = 1;
690
        double acum = margen;
691

    
692
        int toolHeight = 0;
693

    
694
        for (int i = 0; i < toolBars.getComponentCount(); i++) {
695
            Component c = toolBars.getComponent(i);
696

    
697
            if (!c.isVisible()) {
698
                continue;
699
            }
700

    
701
            double width = c.getPreferredSize().getWidth();
702
            acum = acum + width;
703

    
704
            if (acum > this.getWidth()) {
705
                numFilas++;
706
                acum = width + margen;
707
            }
708

    
709
            if (c.getPreferredSize().getHeight() > toolHeight) {
710
                toolHeight = c.getPreferredSize().height;
711
            }
712
        }
713

    
714
        toolBars.setPreferredSize(new Dimension(this.getWidth(),
715
            (numFilas * toolHeight)));
716

    
717
        toolBars.updateUI();
718
    }
719

    
720
    /**
721
     * DOCUMENT ME!
722
     * 
723
     * @param classesExtensions
724
     */
725
    public void setClassesExtensions(Map<Class<? extends IExtension>, ExtensionDecorator> classesExtensions) {
726
            Map<Class<? extends IExtension>, ExtensionDecorator> extensions = new HashMap<Class<? extends IExtension>, ExtensionDecorator>();
727
            for ( Entry<Class<? extends IExtension>, ExtensionDecorator>  entry: classesExtensions.entrySet()) {
728
                        if( ! (entry.getValue().getExtension() instanceof LibraryExtension) ) {
729
                                extensions.put(entry.getKey(), entry.getValue());
730
                        }
731
                }
732
        this.classesExtensions = extensions;
733
    }
734

    
735
    /**
736
     * Metodo de callback invocado cuando se selecciona un menu o un boton
737
     * de
738
     * la barra de herramientas. Se busca la extensi�n asociada y se ejecuta
739
     * 
740
     * @param e
741
     *            Evento producido
742
     */
743
    public void actionPerformed(ActionEvent e) {
744
        
745
//        org.gvsig.andami.plugins.IExtension ext =
746
//            (org.gvsig.andami.plugins.IExtension) classesExtensions
747
//                .get(controlClass.get(control));
748
            String actionName = "(unknow)";
749
        try {
750
            JComponent control = (JComponent) e.getSource();
751
            actionName = control.getName();
752
            
753
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
754
                ActionInfo action = actionManager.getAction(control.getName());
755
                Object args = null;
756
            if( control instanceof IControl ) {
757
                    args = ((IControl) control).getValue();
758
            }
759
            if( args == null ) {
760
                    action.execute();
761
            } else {
762
                    action.execute(args);                    
763
            }
764
                
765
//            logger.info("{}.execute('{}')", ext.getClass().getSimpleName(), actionCommand);
766
//            ext.execute(actionCommand);
767

    
768
                String actionCommand = e.getActionCommand();
769
            try {
770
                JToolBarToggleButton toggle = (JToolBarToggleButton) control;
771
                ToggleButtonModel model = (ToggleButtonModel) toggle.getModel();
772
                selectedTool.put(model.getGroupName(), actionCommand);
773
            } catch (ClassCastException ex) {
774
            } catch (NullPointerException ex) {
775
            }
776

    
777
        } catch (Throwable ex) {
778
                logger.error("Can't perform action '"+actionName+"'.",ex);
779
//            if (ext == null) {
780
//                logger.error(Messages
781
//                    .getString("No_extension_associated_with_this_event_")
782
//                    + e.getActionCommand());
783
//            }
784
//            NotificationManager.addError(Messages
785
//                .getString("MDIFrame.Error_no_capturado_por_el_usuario"), t);
786
        }
787

    
788
        enableControls();
789
        showMemory();
790
    }
791

    
792
    /**
793
     * DOCUMENT ME!
794
     * 
795
     * @param name
796
     *            DOCUMENT ME!
797
     * @param loader
798
     *            DOCUMENT ME!
799
     * 
800
     * @return DOCUMENT ME!
801
     */
802
    private String getName(String name, PluginClassLoader loader) {
803
        if (name.indexOf('.') == -1) {
804
            return loader.getPluginName() + "." + name;
805
        } else {
806
            return name;
807
        }
808
    }
809

    
810
    /**
811
     * DOCUMENT ME!
812
     * 
813
     * @param loader
814
     *            DOCUMENT ME!
815
     * @param menu
816
     *            DOCUMENT ME!
817
     * 
818
     * @throws RuntimeException
819
     *             DOCUMENT ME!
820
     */
821
    public void addPopupMenu(PluginClassLoader loader, PopupMenu menu) {
822
        if (!SwingUtilities.isEventDispatchThread()) {
823
            throw new RuntimeException("No Event Dispatch Thread");
824
        }
825

    
826
        String name = getName(menu.getName(), loader);
827

    
828
        // Se crea el control popupmenu
829
        JPopUpMenu popupMenu = (JPopUpMenu) popupMap.get(name);
830

    
831
        if (popupMenu == null) {
832
            popupMenu = new JPopUpMenu(menu.getName());
833
            popupMap.put(name, popupMenu);
834
        }
835

    
836
        Menu[] menues = menu.getMenu();
837
        for (int i = 0; i < menues.length; i++) {
838
            JMenuItem nuevoMenu = createJMenuItem(loader, menues[i]);
839
            popupMenu.add(nuevoMenu);
840
        }
841
    }
842

    
843
    /**
844
     * DOCUMENT ME!
845
     * 
846
     * @param loader
847
     * @param menu
848
     * 
849
     * @return
850
     * 
851
     * @throws RuntimeException
852
     *             DOCUMENT ME!
853
     */
854
    private JMenuItem createJMenuItem(PluginClassLoader loader, Menu menu) {
855
        JMenuItem nuevoMenu = null;
856

    
857
        PluginServices ps =
858
            PluginServices.getPluginServices(loader.getPluginName());
859
        
860
        String text = menu.getText();
861
        int n = text.lastIndexOf('/');
862
        if( n>=0  ) {
863
                text = text.substring(n + 1);
864
        }
865
        String translatedText = ps.getText(text);
866

    
867
        IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
868
        if (menu.getIcon() != null) {
869
                if( iconTheme.exists(menu.getIcon()) ) {
870
                        ImageIcon image = iconTheme.get(menu.getIcon());
871
                nuevoMenu = new JMenuItem(translatedText, image);
872
            } else {
873
                nuevoMenu = new JMenuItem(translatedText);
874
                logger.info("menu icon '"+ menu.getIcon()+ "' not exists.");
875
            }
876
        } else {
877
            nuevoMenu = new JMenuItem(translatedText);
878
        }
879
        nuevoMenu.setName(menu.getName());
880
//                if (menu.getMnemonic() != null) {
881
//                        if (menu.getMnemonic().length() != 1) {
882
//                                throw new RuntimeException(
883
//                                                "Mnemonic must be 1 character length");
884
//                        }
885
//                        nuevoMenu.setMnemonic(KeyMapping.getKey(menu.getMnemonic()
886
//                                        .charAt(0)));
887
//                }
888

    
889
        if (menu.getKey() != null) {
890
            nuevoMenu.setAccelerator(KeyMapping.getKeyStroke(menu.getKey()));
891
        }
892

    
893
        nuevoMenu.setActionCommand(menu.getActionCommand());
894

    
895
        if (menu.getTooltip() != null) {
896
            nuevoMenu.setToolTip(ps.getText(menu.getTooltip()));
897
        }
898

    
899
        if (menu.getEnableText() != null) {
900
            nuevoMenu.setEnableText(ps.getText(menu.getEnableText()));
901
        }
902

    
903
        nuevoMenu.setEnabled(true);
904
        nuevoMenu.setVisible(true);
905

    
906
        if( menu.getName() != null ) {
907
                    ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
908
                    final ActionInfo actionInfo = actionManager.getAction(menu.getName());
909
                    if( actionInfo != null ) {
910
                            nuevoMenu.addActionListener(actionInfo);
911
                    }
912
        }
913
        return nuevoMenu;
914
    }
915

    
916
    /**
917
     * Muestra u oculta el menu de nombre 'name'
918
     * 
919
     * @param name
920
     *            Nombre del menu que se quiere mostrar
921
     * @param x
922
     *            Evento de raton
923
     * @param y
924
     *            DOCUMENT ME!
925
     * @param c
926
     *            DOCUMENT ME!
927
     */
928
    private void showPopupMenu(String name, int x, int y, Component c) {
929
        JPopupMenu menu = (JPopupMenu) popupMap.get(name);
930

    
931
        if (menu != null) {
932
            menu.show(c, x, y);
933
        }
934
    }
935

    
936
    /**
937
     * DOCUMENT ME!
938
     * 
939
     * @param name
940
     *            DOCUMENT ME!
941
     * @param listener
942
     *            DOCUMENT ME!
943
     */
944
    public void removePopupMenuListener(String name, ActionListener listener) {
945
        JPopupMenu menu = (JPopupMenu) popupMap.get(name);
946

    
947
        if (menu != null) {
948
            Component[] jmenuitems = menu.getComponents();
949

    
950
            for (int i = 0; i < jmenuitems.length; i++) {
951
                if (jmenuitems[i] instanceof JMenuItem) {
952
                    ((JMenuItem) jmenuitems[i]).removeActionListener(listener);
953
                }
954
            }
955
        }
956
    }
957

    
958
    /**
959
     * DOCUMENT ME!
960
     * 
961
     * @param popupName
962
     * @param c
963
     *            DOCUMENT ME!
964
     * @param listener
965
     * @param loader
966
     */
967
    public void addPopupMenuListener(String popupName, Component c,
968
        ActionListener listener, PluginClassLoader loader) {
969
        final String name = getName(popupName, loader);
970

    
971
        JPopupMenu menu = (JPopupMenu) popupMap.get(name);
972

    
973
        if (menu != null) {
974
            Component[] jmenuitems = menu.getComponents();
975

    
976
            for (int i = 0; i < jmenuitems.length; i++) {
977
                if (jmenuitems[i] instanceof JMenuItem) {
978
                    ((JMenuItem) jmenuitems[i]).addActionListener(listener);
979
                }
980
            }
981
        }
982

    
983
        c.addMouseListener(new MouseAdapter() {
984

    
985
            @Override
986
            public void mousePressed(MouseEvent e) {
987
                if (e.isPopupTrigger()) {
988
                    showPopupMenu(name, e.getX(), e.getY(), e.getComponent());
989
                }
990
            }
991

    
992
            @Override
993
            public void mouseReleased(MouseEvent e) {
994
                if (e.isPopupTrigger()) {
995
                    showPopupMenu(name, e.getX(), e.getY(), e.getComponent());
996
                }
997
            }
998
        });
999
    }
1000

    
1001
    /**
1002
     * Loop on the controls to enable/disable and show/hide them, according to
1003
     * its associated extension
1004
     * 
1005
     * @throws RuntimeException
1006
     *             DOCUMENT ME!
1007
     */
1008
    public void enableControls() {
1009
        if (!SwingUtilities.isEventDispatchThread()) {
1010
                SwingUtilities.invokeLater(new Runnable() {
1011
                                public void run() {
1012
                                        enableControls();
1013
                                }
1014
                        });
1015
                        return;
1016
        }
1017

    
1018
        ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1019
        ActionInfoStatusCache cache = actionManager.createActionStatusCache();
1020
        
1021
        Iterator e = classesExtensions.values().iterator();
1022

    
1023
//        HashMap estadoExtensiones = new HashMap();
1024
//        HashMap visibilidadExtensiones = new HashMap();
1025
//
1026
//        while (e.hasNext()) {
1027
//            ExtensionDecorator ext = (ExtensionDecorator) e.next();
1028
//
1029
//            try {
1030
//                if (estadoExtensiones.get(ext) == null) {
1031
//                    boolean b;
1032
//                    if (ext.getVisibility() == ExtensionDecorator.ALWAYS_VISIBLE) {
1033
//                        b = true;
1034
//                    } else
1035
//                        if (ext.getVisibility() == ExtensionDecorator.ALWAYS_INVISIBLE) {
1036
//                            b = false;
1037
//                        } else {
1038
//                            if (PluginServices.getExclusiveUIExtension() == null) {
1039
//                                b = ext.isVisible();
1040
//                            } else {
1041
//                                b =
1042
//                                    PluginServices.getExclusiveUIExtension()
1043
//                                        .isVisible(ext.getExtension());
1044
//                            }
1045
//                        }
1046
//                    Boolean visible = new Boolean(b);
1047
//                    Boolean enabled = new Boolean(false);
1048
//
1049
//                    if (visible.booleanValue()) {
1050
//                        if (PluginServices.getExclusiveUIExtension() == null) {
1051
//                            enabled = new Boolean(ext.isEnabled());
1052
//                        } else {
1053
//                            enabled =
1054
//                                new Boolean(PluginServices
1055
//                                    .getExclusiveUIExtension().isEnabled(
1056
//                                        ext.getExtension()));
1057
//                        }
1058
//
1059
//                    }
1060
//
1061
//                    estadoExtensiones.put(ext, enabled);
1062
//                    visibilidadExtensiones.put(ext, visible);
1063
//                }
1064
//            } catch (Throwable e1) {
1065
//                NotificationManager.addError(Messages
1066
//                    .getString("MDIFrame.Error_no_capturado_por_el_usuario"),
1067
//                    e1);
1068
//                estadoExtensiones.put(ext, Boolean.FALSE);
1069
//            }
1070
//        }
1071

    
1072
        // Enable or disable controls, according to its associated extensions
1073
        e = controlClass.keySet().iterator();
1074

    
1075
        while (e.hasNext()) {
1076
            JComponent control = (JComponent) e.next();
1077
            String actionlName = control.getName();
1078
            ActionInfo action = actionManager.getAction(actionlName);
1079
            try {
1080
                boolean enabled = false;
1081
                boolean visible = false;
1082
                
1083
                    if(action == null) {
1084
                  IExtension ext =
1085
                          (IExtension) classesExtensions.get(controlClass.get(control));
1086
                  enabled = ext.isEnabled();
1087
                  visible = ext.isVisible(); 
1088
                    } else {
1089
                            enabled = false;
1090
                    visible = cache.isVisible(action);
1091
                    if( visible ) {
1092
                            enabled = cache.isEnabled(action);
1093
                    }
1094
                    }
1095
                control.setEnabled(enabled);
1096
                control.setVisible(visible);
1097
            } catch (Exception ex) {
1098
                    logger.info("Can't enable/show control '"+actionlName +"'.",ex);
1099
                    this.message("Can't enable/show control '"+actionlName +"'.", JOptionPane.ERROR_MESSAGE);
1100
                control.setEnabled(false);
1101
                control.setVisible(false);
1102
            }
1103
        }
1104

    
1105
        // Loop in the menus to hide the menus that don't have visible children
1106
        for (int i = 0; i < menuBar.getMenuCount(); i++) {
1107
            MenuElement menu = menuBar.getMenu(i);
1108
            hideMenus(menu);
1109
            if (menu instanceof JMenu) {
1110
                // hide (ugly) redundant separators and assign keyboard
1111
                // mnemonics
1112
                Component[] comps = ((JMenu) menu).getMenuComponents();
1113
                // mnemonics have to be unique for each top-level menu
1114
                char mnemonics[] = new char[comps.length];
1115
                if (comps.length > 0) {
1116
                    // Set keyboard mnemonic for this top-level entry
1117
                    String text = ((JMenu) menu).getText();
1118
                    char mnemonic = getMnemonic(text, mnemonics);
1119
                    if (' ' != mnemonic) {
1120
                        ((JMenu) menu).setMnemonic(mnemonic);
1121
                        mnemonics[0] = mnemonic;
1122
                    }
1123
                }
1124
                // now go through all entries in this menu, hid
1125
                // separators if necessary and assing remaining mnemonics
1126
                hideSeparatorsAndMakeMnemonics(menu, mnemonics);
1127
            }
1128
        }
1129

    
1130
        // hide the toolbars that don't contain any visible tool
1131
        Iterator it = toolBarMap.values().iterator();
1132

    
1133
        while (it.hasNext()) {
1134
                JComponent t = (JComponent) it.next();
1135
            boolean todosOcultos = true;
1136

    
1137
            for (int i = 0; i < t.getComponentCount(); i++) {
1138
                if (!(t.getComponent(i) instanceof JSeparator) // separators
1139
                                                               // don't matter
1140
                    && t.getComponent(i).isVisible()) {
1141
                    todosOcultos = false;
1142
                }
1143
            }
1144

    
1145
            if (todosOcultos) {
1146
                t.setVisible(false);
1147
            } else {
1148
                    if(t instanceof SelectableToolBar) {
1149
                            t.setVisible(((SelectableToolBar)t).getAndamiVisibility());
1150
                    } else
1151
                            t.setVisible(true);
1152
            }
1153
        }
1154

    
1155
        if (mdiManager != null) {
1156
            JPanel f = (JPanel) mdiManager.getActiveWindow();
1157

    
1158
            if (f != null) {
1159
                if (lastLabelClass != f.getClass()) {
1160
                    lastLabelClass = f.getClass();
1161

    
1162
                    Label[] lbls = (Label[]) classLabels.get(lastLabelClass);
1163

    
1164
                    if (lbls != null) {
1165
                        bEstado.setLabelSet(lbls);
1166
                    }
1167
                }
1168
            }
1169
        }
1170

    
1171
        ajustarToolBar();
1172

    
1173
        showMemory();
1174
    }
1175
    
1176
    public void refreshControls() {
1177
        if (!SwingUtilities.isEventDispatchThread()) {
1178
                SwingUtilities.invokeLater(new Runnable() {
1179
                                public void run() {
1180
                                        refreshControls();
1181
                                }
1182
                        });
1183
                        return;
1184
        }
1185

    
1186
        ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1187
        ActionInfoStatusCache cache = actionManager.createActionStatusCache();
1188
        
1189
        Iterator e = controlClass.keySet().iterator();
1190

    
1191
        while (e.hasNext()) {
1192
            JComponent control = (JComponent) e.next();
1193
            String actionlName = control.getName();
1194
            ActionInfo action = actionManager.getAction(actionlName);
1195
            if( action!=null ) {
1196
                    if( control instanceof AbstractButton ) {
1197
                            AbstractButton button = (AbstractButton) control;
1198
                            button.setIcon(action.getIcon());
1199
                    }
1200
            }
1201
        }
1202
        enableControls();
1203
    }
1204

    
1205
    public void message(String msg, int messageTyoe) {
1206
            this.getStatusBar().message(msg, messageTyoe);
1207
        }
1208

    
1209
        /**
1210
     * Establece la visibilidad de un menu y todos sus descendientes en la
1211
     * jerarquia teniendo en cuenta la visibilidad de todos los submenus.
1212
     * 
1213
     * @param menu
1214
     *            Menu que se quiere visualizar
1215
     * 
1216
     * @return Devuelve true si el menu es visible y false en caso contrario
1217
     */
1218
    private boolean hideMenus(MenuElement menu) {
1219
        MenuElement[] submenus = menu.getSubElements();
1220

    
1221
        // Si no tiene hijos se devuelve su visibilidad
1222
        if (submenus.length == 0) {
1223
            return menu.getComponent().isVisible();
1224
        }
1225

    
1226
        /*
1227
         * Si tiene hijos se devuelve true si alg�no de ellos es visible,
1228
         * pero se itera por todos ellos
1229
         */
1230
        boolean visible = false;
1231

    
1232
        for (int i = 0; i < submenus.length; i++) {
1233
            if (hideMenus(submenus[i])) {
1234
                if (!(menu instanceof JPopupMenu)) {
1235
                    menu.getComponent().setVisible(true);
1236
                }
1237

    
1238
                visible = true;
1239
            }
1240
        }
1241

    
1242
        if (visible) {
1243
            return true;
1244
        }
1245

    
1246
        menu.getComponent().setVisible(false);
1247

    
1248
        return false;
1249
    }
1250

    
1251
    /**
1252
     * 
1253
     * Recurse through all menu elements and make sure there are no
1254
     * redundant separators.
1255
     * This method will make sure that a separator only becomes visible
1256
     * if at least one visible non-separator menu entry preceeded it.
1257
     * 
1258
     **/
1259
    private void hideSeparatorsAndMakeMnemonics(MenuElement menu,
1260
        char[] mnemonics) {
1261
        // flag that indicates whether a separator is to be displayed or not
1262
        boolean allowSeparator;
1263

    
1264
        allowSeparator = false; // separator not allowed as very first menu item
1265
        Component[] comps = ((JMenu) menu).getMenuComponents();
1266
        if (comps.length < 1) {
1267
            // zero-length menu: skip
1268
            return;
1269
        }
1270

    
1271
        for (int i = 0; i < comps.length; i++) {
1272
            if (comps[i] instanceof JSeparator) {
1273
                // got a separator: display only if allowed at this position
1274
                if (allowSeparator == true) {
1275
                    // look at all successive menu entries to make sure that at
1276
                    // least one
1277
                    // is visible and not a separator (otherwise, this separator
1278
                    // would
1279
                    // be the last visible item in this menu) -- we don't want
1280
                    // that
1281
                    comps[i].setVisible(false);
1282
                    for (int j = i; j < comps.length; j++) {
1283
                        if (!(comps[j] instanceof JSeparator)) {
1284
                            if (comps[j].isVisible()) {
1285
                                comps[i].setVisible(true); // display separator!
1286
                                break;
1287
                            }
1288
                        }
1289
                    }
1290
                } else {
1291
                    comps[i].setVisible(false);
1292
                }
1293
                allowSeparator = false; // separator is not allowed right after
1294
                                        // another separator
1295
            } else {
1296
                if (comps[i] instanceof JMenu) { // got a submenu: recurse
1297
                                                 // through it
1298
                    // get number of submenu components
1299
                    Component[] scomps = ((JMenu) comps[i]).getMenuComponents();
1300
                    // make a new, fresh array to hold unique mnemonics for this
1301
                    // submenu
1302
                    char[] smnemonics = new char[scomps.length];
1303
                    hideSeparatorsAndMakeMnemonics(((MenuElement) comps[i]),
1304
                        smnemonics);
1305
                    if (comps[i].isVisible()) {
1306
                        allowSeparator = true; // separators are OK after
1307
                                               // visible submenus
1308
                        // Set keyboard mnemonic for this submenu
1309
                        String text = ((JMenu) comps[i]).getText();
1310
                        char mnemonic = getMnemonic(text, mnemonics);
1311
                        if (' ' != mnemonic) {
1312
                            ((JMenu) comps[i]).setMnemonic(mnemonic);
1313
                            mnemonics[i] = mnemonic;
1314
                        }
1315
                    }
1316
                } else {
1317
                    if (comps[i].isVisible()) {
1318
                        if (comps[i] instanceof JMenuItem) {
1319
                            // Set keyboard mnemonic for this menu item
1320
                            String text = ((JMenuItem) comps[i]).getText();
1321
                            char mnemonic = getMnemonic(text, mnemonics);
1322
                            if (' ' != mnemonic) {
1323
                                ((JMenuItem) comps[i]).setMnemonic(mnemonic);
1324
                                mnemonics[i] = mnemonic;
1325
                            }
1326
                        }
1327
                        allowSeparator = true; // separators are OK after
1328
                                               // regular, visible entries
1329
                    }
1330
                }
1331
            }
1332
        }
1333
    }
1334

    
1335
    /**
1336
     * Helper functios for assigning a unique mnemomic char from
1337
     * a pool of unassigned onces, stored in the array "mnemomnics"
1338
     */
1339
    private char getMnemonic(String text, char[] mnemonics) {
1340
        Vector words = new Vector();
1341
        StringTokenizer t = new StringTokenizer(text);
1342
        int maxsize = 0;
1343

    
1344
        while (t.hasMoreTokens()) {
1345
            String word = t.nextToken();
1346
            if (word.length() > maxsize) {
1347
                maxsize = word.length();
1348
            }
1349
            words.addElement(word);
1350
        }
1351
        words.trimToSize();
1352

    
1353
        for (int i = 0; i < maxsize; ++i) {
1354
            char mnemonic = getMnemonic(words, mnemonics, i);
1355
            if (' ' != mnemonic) {
1356
                return mnemonic;
1357
            }
1358
        }
1359

    
1360
        return ' ';
1361
    }
1362

    
1363
    private char getMnemonic(Vector words, char[] mnemonics, int index) {
1364
        int numwords = words.size();
1365

    
1366
        for (int i = 0; i < numwords; ++i) {
1367
            String word = (String) words.elementAt(i);
1368
            if (index >= word.length()) {
1369
                continue;
1370
            }
1371

    
1372
            char c = word.charAt(index);
1373
            if (!isMnemonicExists(c, mnemonics)) {
1374
                /* pick only valid chars */
1375
                if ((c != ':') && (c != '.') && (c != ',') && (c != ';')
1376
                    && (c != '-') && (c != '+') && (c != '/') && (c != '\\')
1377
                    && (c != '\'') && (c != '\"') && (c != ' ') && (c != '=')
1378
                    && (c != '(') && (c != ')') && (c != '[') && (c != ']')
1379
                    && (c != '{') && (c != '}') && (c != '$') && (c != '*')
1380
                    && (c != '&') && (c != '%') && (c != '!') && (c != '?')
1381
                    && (c != '#') && (c != '~') && (c != '_')) {
1382
                    return c;
1383
                }
1384
            }
1385
        }
1386
        return ' ';
1387
    }
1388

    
1389
    private boolean isMnemonicExists(char c, char[] mnemonics) {
1390
        int num = mnemonics.length;
1391
        for (int i = 0; i < num; ++i) {
1392
            if (mnemonics[i] == c) {
1393
                return true;
1394
            }
1395
        }
1396
        return false;
1397
    }
1398

    
1399
    /**
1400
     * Muestra la memoria consumida por el programa
1401
     */
1402
    private void showMemory() {
1403
        Runtime r = Runtime.getRuntime();
1404
        long mem = r.totalMemory() - r.freeMemory();
1405
        logger.debug(PluginServices.getText(this, "memory_usage") + " " + mem
1406
            / 1024 + " KB");
1407
    }
1408

    
1409
    /**
1410
     * DOCUMENT ME!
1411
     * 
1412
     * @return
1413
     */
1414
    public MDIManager getMDIManager() {
1415
        return mdiManager;
1416
    }
1417

    
1418
    /**
1419
     * Establece el mensaje en la barra de estado asociado a una etiqueta
1420
     * 
1421
     * @return DOCUMENT ME!
1422
     */
1423
    public NewStatusBar getStatusBar() {
1424
        return bEstado;
1425
    }
1426

    
1427
    /**
1428
     * You can use this function to select the appropiate
1429
     * tool inside the toolbars
1430
     */
1431
    public void setSelectedTool(String actionCommand) {
1432
        setSelectedTool(defaultGroup, actionCommand);
1433
    }
1434

    
1435
    /**
1436
     * You can use this function to select the appropiate
1437
     * tool inside the toolbars
1438
     */
1439
    public void setSelectedTool(String groupName, String actionCommand) {
1440
        ButtonGroup group = (ButtonGroup) buttonGroupMap.get(groupName);
1441
        if (group == null) {
1442
            return;
1443
        }
1444

    
1445
        Enumeration enumeration = group.getElements();
1446
        while (enumeration.hasMoreElements()) {
1447
            AbstractButton button = (AbstractButton) enumeration.nextElement();
1448
            if (button.getActionCommand().equals(actionCommand)) {
1449
                button.setSelected(true);
1450
            }
1451
        }
1452

    
1453
        selectedTool.put(groupName, actionCommand);
1454
    }
1455

    
1456
    /**
1457
     * You can use this function to select the appropiate
1458
     * tool inside the toolbars
1459
     */
1460
    public void setSelectedTools(Map selectedTools) {
1461
        selectedTool = selectedTools;
1462
        if (selectedTools == null) {
1463
            return;
1464
        }
1465
        Iterator groupNames = selectedTools.keySet().iterator();
1466
        while (groupNames.hasNext()) {
1467
            try {
1468
                String groupName = (String) groupNames.next();
1469
                ButtonGroup group = (ButtonGroup) buttonGroupMap.get(groupName);
1470
                Enumeration enumeration = group.getElements();
1471
                String actionCommand = (String) selectedTools.get(groupName);
1472
                if (actionCommand == null) {
1473
                    continue;
1474
                }
1475
                while (enumeration.hasMoreElements()) {
1476
                    AbstractButton button =
1477
                        (AbstractButton) enumeration.nextElement();
1478
                    if (button.getActionCommand().equals(actionCommand)) {
1479
                        button.setSelected(true);
1480
                    }
1481
                }
1482
            } catch (ClassCastException ex) {
1483
                logger
1484
                    .error("selectedTool should only contain pairs (String groupName, JToolBarToggleButton button)");
1485
            }
1486
        }
1487
    }
1488

    
1489
    /**
1490
     * DOCUMENT ME!
1491
     * 
1492
     * @param clase
1493
     * @param label
1494
     */
1495
    public void setStatusBarLabels(Class<?> clase, Label[] label) {
1496
        classLabels.put(clase, label);
1497
    }
1498

    
1499
    public void removeStatusBarLabels(Class<?> clase) {
1500
        classLabels.remove(clase);
1501
    }
1502

    
1503
    public void addStatusBarControl(Class<?> extensionClass, IControl control) {
1504
        control.addActionListener(this);
1505
        bEstado.addControl(control.getName(), (Component) control);
1506
        controlClass.put(control, extensionClass);
1507
    }
1508
    
1509
    public void addToolBarControl(Class<?> extensionClass, JToolBar control, String name) {
1510
        //toolBarMap.put(name, control); 
1511
        toolBars.add(control);
1512
        controlClass.put(control, extensionClass);
1513
    }
1514

    
1515
    public void removeStatusBarControl(String name) {
1516
        Component c = bEstado.removeControl(name);
1517
        if (c != null) {
1518
            controlClass.remove(c);
1519
        }
1520
    }
1521

    
1522
    /**
1523
     * @see org.gvsig.andami.ui.mdiFrame.MainFrame#removeMenu(org.gvsig.andami.plugins.config.generate.Menu)
1524
     */
1525
    public void removeMenu(Menu menu) {
1526
        JMenuItem delete = (JMenuItem) infoCodedMenus.get(menu);
1527

    
1528
        if (delete == null) {
1529
            throw new NoSuchElementException(menu.getText());
1530
        }
1531

    
1532
        delete.getParent().remove(delete);
1533
        infoCodedMenus.remove(menu);
1534
    }
1535

    
1536
    /**
1537
     * @see org.gvsig.andami.ui.mdiFrame.MainFrame#addMenu(org.gvsig.andami.plugins.config.generate.Menu,
1538
     *      java.awt.event.ActionListener, PluginClassLoader)
1539
     */
1540
    public void addMenu(Menu menu, ActionListener listener,
1541
        PluginClassLoader loader) {
1542
        JMenu menuPadre = createMenuAncestors(menu, loader);
1543

    
1544
        // Se registra y a�ade el menu
1545
        JMenuItem nuevoMenu = createJMenuItem(loader, menu);
1546
        nuevoMenu.addMouseListener(tooltipListener);
1547
        if( listener != null && menu.getName() != null && menu.getName().trim().length()>0 ) {
1548
                    ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1549
                    final ActionInfo actionInfo = actionManager.getAction(menu.getName());
1550
                    if( actionInfo != null ) {
1551
                            nuevoMenu.removeActionListener(actionInfo);
1552
                    }
1553
                nuevoMenu.addActionListener(listener);
1554
        }
1555
        menuPadre.add(nuevoMenu);
1556

    
1557
        infoCodedMenus.put(menu, nuevoMenu);
1558
    }
1559

    
1560
    /**
1561
     * @see org.gvsig.andami.ui.mdiFrame.MainFrame#changeMenuName(java.lang.String[],
1562
     *      String, org.gvsig.andami.plugins.PluginClassLoader)
1563
     */
1564
    public void changeMenuName(String[] menu, String newName,
1565
        PluginClassLoader loader) {
1566

    
1567
        ArrayList menuList = new ArrayList();
1568
        for (int i = 0; i < menu.length; i++) {
1569
            menuList.add(menu[i]);
1570
        }
1571

    
1572
        javax.swing.JMenuItem newMenu = getMenu(menuList, menuBar);
1573
        if (newMenu == null) {
1574
            throw new NoSuchMenuException(menu[0]);
1575
        } else {
1576
            newMenu.setText(PluginServices.getText(this, newName));
1577
        }
1578
    }
1579

    
1580
    /**
1581
     * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
1582
     */
1583
    public void componentHidden(ComponentEvent arg0) {
1584
    }
1585

    
1586
    /**
1587
     * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
1588
     */
1589
    public void componentMoved(ComponentEvent arg0) {
1590
    }
1591

    
1592
    /**
1593
     * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
1594
     */
1595
    public void componentResized(ComponentEvent arg0) {
1596
        ajustarToolBar();
1597
    }
1598

    
1599
    /**
1600
     * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
1601
     */
1602
    public void componentShown(ComponentEvent arg0) {
1603
    }
1604

    
1605
    /**
1606
     * @see java.awt.event.ContainerListener#componentAdded(java.awt.event.ContainerEvent)
1607
     */
1608
    public void componentAdded(ContainerEvent arg0) {
1609
        ajustarToolBar();
1610
    }
1611

    
1612
    /**
1613
     * @see java.awt.event.ContainerListener#componentRemoved(java.awt.event.ContainerEvent)
1614
     */
1615
    public void componentRemoved(ContainerEvent arg0) {
1616
        ajustarToolBar();
1617
    }
1618

    
1619
    /**
1620
     * DOCUMENT ME!
1621
     * 
1622
     * @author $author$
1623
     * @version $Revision: 38806 $
1624
     */
1625
    public class TooltipListener extends MouseAdapter {
1626

    
1627
        /**
1628
         * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
1629
         */
1630
        @Override
1631
        public void mouseEntered(MouseEvent e) {
1632
            JComponent control = (JComponent) e.getSource();
1633
            EnableTextSupport ets = (EnableTextSupport) e.getSource();
1634

    
1635
            String texto = null;
1636
            texto = control.getToolTipText();
1637

    
1638
            if (texto != null) {
1639
                bEstado.setInfoTextTemporal(texto);
1640
            }
1641
        }
1642

    
1643
        /**
1644
         * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
1645
         */
1646
        @Override
1647
        public void mouseExited(MouseEvent arg0) {
1648
            bEstado.restaurarTexto();
1649
        }
1650

    
1651
        /**
1652
         * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
1653
         */
1654
        @Override
1655
        public void mousePressed(MouseEvent e) {
1656
            bEstado.restaurarTexto();
1657
        }
1658
    }
1659

    
1660
    public String getTitlePrefix() {
1661
        return titlePrefix;
1662
    }
1663

    
1664
    public void setTitlePrefix(String titlePrefix) {
1665
        this.titlePrefix = titlePrefix;
1666
    }
1667

    
1668
    public Map getSelectedTools() {
1669
        return selectedTool;
1670
    }
1671

    
1672
    public HashMap getInitialSelectedTools() {
1673
        return initialSelectedTools;
1674
    }
1675

    
1676
    /**
1677
     * Get a previously added JComponent by name. For example
1678
     * you can use it if you need to obtain a JToolBar to
1679
     * add some customized component.
1680
     * 
1681
     * @param name
1682
     * @return the JComponent or null if none has been found
1683
     */
1684
    public JComponent getComponentByName(String name) {
1685
        Iterator e = controlClass.keySet().iterator();
1686

    
1687
        while (e.hasNext()) {
1688
            JComponent control = (JComponent) e.next();
1689
            String nameCtrl = control.getName();
1690
            if (nameCtrl != null) {
1691
                if (nameCtrl.compareTo(name) == 0) {
1692
                    return control;
1693
                }
1694
            }
1695
        }
1696
        Iterator it = toolBarMap.values().iterator();
1697
        while (it.hasNext()) {
1698
                JComponent t = (JComponent) it.next();
1699
            String nameCtrl = t.getName();
1700
            if (nameCtrl != null) {
1701
                if (nameCtrl.compareTo(name) == 0) {
1702
                    return t;
1703
                }
1704
            }
1705

    
1706
        }
1707

    
1708
        return null;
1709
    }
1710

    
1711
    public SelectableToolBar[] getToolbars() {
1712
        return (SelectableToolBar[]) toolBarMap.values().toArray(
1713
            new SelectableToolBar[0]);
1714
    }
1715

    
1716
    public boolean getToolbarVisibility(String name) {
1717
        JComponent component =
1718
            PluginServices.getMainFrame().getComponentByName(name);
1719
        if ((component != null) && (component instanceof SelectableToolBar)) {
1720
            SelectableToolBar toolBar = (SelectableToolBar) component;
1721
            return toolBar.getAndamiVisibility();
1722
        }
1723
        return false;
1724
    }
1725

    
1726
    public boolean setToolbarVisibility(String name, boolean visibility) {
1727
        JComponent component =
1728
            PluginServices.getMainFrame().getComponentByName(name);
1729
        if ((component != null) && (component instanceof SelectableToolBar)) {
1730
            SelectableToolBar toolBar = (SelectableToolBar) component;
1731
            boolean oldVisibility = toolBar.getAndamiVisibility();
1732
            toolBar.setAndamiVisibility(visibility);
1733
            enableControls();
1734
            return oldVisibility;
1735
        }
1736
        return false;
1737
    }
1738

    
1739
    public javax.swing.JMenuItem getMenuEntry(String[] menuPath) {
1740
        ArrayList menu = new ArrayList();
1741
        for (int i = 0; i < menuPath.length; i++) {
1742
            menu.add(menuPath[i]);
1743
        }
1744
        return getMenu(menu, menuBar);
1745
    }
1746

    
1747
        public void messageDialog(String message, String title, int messageType) {
1748
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1749
                helper.messageDialog(message, title, messageType);
1750
        }
1751

    
1752
        public void messageDialog(String message, String[] messageArgs,
1753
                        String title, int messageType) {
1754
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1755
                helper.messageDialog(message, messageArgs, title, messageType);
1756
        }
1757

    
1758
        public int confirmDialog(String message, String title, int optionType,
1759
                        int messageType) {
1760
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1761
                return helper.confirmDialog(message, title, optionType, messageType);
1762
        }
1763

    
1764
        public String inputDialog(String message, String title, int messageType,
1765
                        String initialValue) {
1766
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1767
                return helper.inputDialog(message, title, messageType, initialValue);
1768
        }
1769

    
1770
        public String inputDialog(String message, String title) {
1771
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1772
                return helper.inputDialog(message, title);
1773
        }
1774

    
1775
        public void showDialog(Component contents, String title) {
1776
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1777
                helper.showDialog(contents, title);
1778
        }
1779

    
1780
        public Component createComponent(Class<? extends Component> theClass,
1781
                        Object... parameters) {
1782
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1783
                return helper.createComponentWithParams(theClass, parameters);
1784
        }
1785

    
1786
        public Component createComponentWithParams(
1787
                        Class<? extends Component> theClass, Object[] parameters) {
1788
                DefaultThreadSafeDialogs helper = new DefaultThreadSafeDialogs(this, this.bEstado);
1789
                return helper.createComponentWithParams(theClass, parameters);
1790
        }
1791

    
1792
}