VcsAllCommandsAction added. This action merges together the global commands BLD200405101820
authormentlicher@netbeans.org
Mon, 10 May 2004 17:07:12 +0000
changeset 45468fbb7ec8ee32
parent 4545 f57dee785cb4
child 4547 95728c0dac67
VcsAllCommandsAction added. This action merges together the global commands
and context commands. Methods of other actions adjusted so that the VcsAllCommandsAction
can use what it needs to.
This is necessary for issue #42932.
vcscore/src/org/netbeans/modules/vcscore/VcsFSCommandsAction.java
vcscore/src/org/netbeans/modules/vcscore/actions/VcsAllCommandsAction.java
vcscore/src/org/netbeans/modules/vcscore/actions/VcsGlobalCommandsAction.java
     1.1 --- a/vcscore/src/org/netbeans/modules/vcscore/VcsFSCommandsAction.java	Mon May 10 15:44:59 2004 +0000
     1.2 +++ b/vcscore/src/org/netbeans/modules/vcscore/VcsFSCommandsAction.java	Mon May 10 17:07:12 2004 +0000
     1.3 @@ -217,6 +217,17 @@
     1.4      }
     1.5      
     1.6      private JMenuItem getPresenter(boolean inMenu) {
     1.7 +        JInlineMenu menu = new JInlineMenu();
     1.8 +        JMenuItem[] items = createMenuItems(inMenu);
     1.9 +        if (items.length == 0) return menu;
    1.10 +        menu.setMenuItems(items);
    1.11 +        if (inMenu && menu != null) {
    1.12 +            menu.setIcon(getIcon());
    1.13 +        }
    1.14 +        return menu;
    1.15 +    }
    1.16 +    
    1.17 +    public JMenuItem[] createMenuItems(boolean inMenu) {
    1.18          Map filesWithMessages = getSelectedFileObjectsFromActiveNodes();
    1.19          //System.out.println("VcsFSCommandsAction.getPresenter(): selected filesWithMessages: "+filesWithMessages);
    1.20          switchableList = new ArrayList();
    1.21 @@ -224,7 +235,7 @@
    1.22          //CommandsTree[] commands = actionCommandsTree.children();
    1.23          filesByCommandProviders = findCommandProvidersForFiles(filesWithMessages);
    1.24  	//System.out.println("filesByCommandProviders.size() = "+filesByCommandProviders.size());
    1.25 -        if (filesByCommandProviders.size() == 0) return new JInlineMenu(); // return empty JInlineMenu
    1.26 +        if (filesByCommandProviders.size() == 0) return new JMenuItem[] {}; // return empty JInlineMenu
    1.27          CommandsTree commands;
    1.28  	//VcsCommandsProvider provider = null;
    1.29          boolean globalExpertMode;
    1.30 @@ -250,13 +261,10 @@
    1.31                  }
    1.32              }
    1.33          }
    1.34 -        JInlineMenu menu = new JInlineMenu();
    1.35 -        if (commands == null) return menu;
    1.36 -        menu.setMenuItems(createMenuItems(commands, filesWithMessages, inMenu, globalExpertMode));
    1.37 -        if (inMenu && menu != null) {
    1.38 -            menu.setIcon(getIcon());
    1.39 +        if (commands == null) {
    1.40 +            return new JMenuItem[] {};
    1.41          }
    1.42 -        return menu;
    1.43 +        return createMenuItems(commands, filesWithMessages, inMenu, globalExpertMode);
    1.44      }
    1.45      
    1.46      private JMenuItem[] createMenuItems(CommandsTree commands, Map filesWithMessages,
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/vcscore/src/org/netbeans/modules/vcscore/actions/VcsAllCommandsAction.java	Mon May 10 17:07:12 2004 +0000
     2.3 @@ -0,0 +1,270 @@
     2.4 +/*
     2.5 + *                 Sun Public License Notice
     2.6 + * 
     2.7 + * The contents of this file are subject to the Sun Public License
     2.8 + * Version 1.0 (the "License"). You may not use this file except in
     2.9 + * compliance with the License. A copy of the License is available at
    2.10 + * http://www.sun.com/
    2.11 + * 
    2.12 + * The Original Code is NetBeans. The Initial Developer of the Original
    2.13 + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
    2.14 + * Microsystems, Inc. All Rights Reserved.
    2.15 + */
    2.16 +
    2.17 +package org.netbeans.modules.vcscore.actions;
    2.18 +
    2.19 +import java.awt.Component;
    2.20 +import java.awt.event.ActionEvent;
    2.21 +import java.awt.event.ActionListener;
    2.22 +import java.beans.BeanInfo;
    2.23 +import java.beans.PropertyChangeListener;
    2.24 +import java.beans.PropertyChangeEvent;
    2.25 +import java.lang.ref.Reference;
    2.26 +import java.lang.ref.WeakReference;
    2.27 +import java.util.*;
    2.28 +import javax.swing.JMenu;
    2.29 +import javax.swing.JMenuItem;
    2.30 +import javax.swing.JPopupMenu;
    2.31 +import javax.swing.JSeparator;
    2.32 +import javax.swing.MenuElement;
    2.33 +import org.netbeans.modules.vcscore.VcsFSCommandsAction;
    2.34 +import org.netbeans.spi.vcs.VcsCommandsProvider;
    2.35 +
    2.36 +import org.openide.DialogDescriptor;
    2.37 +import org.openide.DialogDisplayer;
    2.38 +import org.openide.NotifyDescriptor;
    2.39 +import org.openide.awt.JInlineMenu;
    2.40 +import org.openide.actions.FileSystemAction;
    2.41 +import org.openide.awt.JMenuPlus;
    2.42 +import org.openide.filesystems.FileSystem;
    2.43 +import org.openide.filesystems.FileObject;
    2.44 +import org.openide.filesystems.FileStateInvalidException;
    2.45 +import org.openide.loaders.DataObject;
    2.46 +import org.openide.nodes.Node;
    2.47 +import org.openide.nodes.BeanNode;
    2.48 +import org.openide.util.HelpCtx;
    2.49 +import org.openide.util.Lookup;
    2.50 +import org.openide.util.LookupEvent;
    2.51 +import org.openide.util.LookupListener;
    2.52 +import org.openide.util.WeakListener;
    2.53 +import org.openide.util.WeakListeners;
    2.54 +import org.openide.util.actions.SystemAction;
    2.55 +import org.openide.util.actions.CallableSystemAction;
    2.56 +import org.openide.util.actions.Presenter;
    2.57 +import org.openide.util.enum.*;
    2.58 +import org.openide.windows.TopComponent.Registry;
    2.59 +import org.openide.windows.WindowManager;
    2.60 +
    2.61 +/**
    2.62 + * Action, that contains all VCS actions.
    2.63 + * It merges the global commands together with context commands.
    2.64 + *
    2.65 + * @author  Martin Entlicher
    2.66 + */
    2.67 +public class VcsAllCommandsAction extends SystemAction implements Presenter.Menu, Presenter.Popup,
    2.68 +                                                                  LookupListener, PropertyChangeListener{
    2.69 +
    2.70 +    static final long serialVersionUID = -2345126396734900262L;
    2.71 +
    2.72 +    private Reference mergedMenuReference;
    2.73 +    private boolean mergedMenuWasInMenu;
    2.74 +    
    2.75 +    private boolean globalListenerAdded;
    2.76 +    private boolean contextListenerAdded;
    2.77 +    
    2.78 +    /* @return menu presenter.
    2.79 +    */
    2.80 +    public JMenuItem getMenuPresenter () {
    2.81 +        return createMergedMenu(false);
    2.82 +    }
    2.83 +
    2.84 +    /* @return popup presenter.
    2.85 +    */
    2.86 +    public JMenuItem getPopupPresenter () {
    2.87 +        return createMergedMenu(true);
    2.88 +    }
    2.89 +    
    2.90 +    private JMenuItem createMergedMenu(boolean popup) {
    2.91 +        MergedMenu mergedMenu = (mergedMenuReference != null) ? (MergedMenu) mergedMenuReference.get() : null;
    2.92 +        if (mergedMenu == null) {
    2.93 +            if (!globalListenerAdded) {
    2.94 +                Lookup.Result globalProvidersRes = Lookup.getDefault().lookup(new Lookup.Template(VcsCommandsProvider.class));
    2.95 +                LookupListener providersLookupListener = (LookupListener) WeakListener.create(LookupListener.class, this, globalProvidersRes);
    2.96 +                globalListenerAdded = true;
    2.97 +            }
    2.98 +            if (!contextListenerAdded) {
    2.99 +                Registry r = WindowManager.getDefault().getRegistry ();
   2.100 +                r.addPropertyChangeListener(WeakListeners.propertyChange(this, r));
   2.101 +            }
   2.102 +            JMenuItem[] globalMenu = getGlobalMenu(popup);
   2.103 +            JMenuItem[] contextMenu = getContextMenu(popup);
   2.104 +            mergedMenu = new MergedMenu(globalMenu, contextMenu);
   2.105 +            mergedMenuReference = new WeakReference(mergedMenu);
   2.106 +            mergedMenuWasInMenu = popup;
   2.107 +        }
   2.108 +        return mergedMenu;
   2.109 +    }
   2.110 +
   2.111 +    /* Getter for name
   2.112 +    */
   2.113 +    public String getName () {
   2.114 +        return org.openide.util.NbBundle.getBundle(VcsCommandsAction.class).getString("CTL_VcsFSActionName");
   2.115 +    }
   2.116 +
   2.117 +    /* Getter for help.
   2.118 +    */
   2.119 +    public HelpCtx getHelpCtx () {
   2.120 +        return new HelpCtx (VcsAllCommandsAction.class);
   2.121 +    }
   2.122 +
   2.123 +    /* Do nothing.
   2.124 +    * This action itself does nothing, it only presents other actions.
   2.125 +    * @param ev ignored
   2.126 +    */
   2.127 +    public void actionPerformed (java.awt.event.ActionEvent e) {}
   2.128 +
   2.129 +    private static JMenuItem[] getGlobalMenu(boolean popup) {
   2.130 +        VcsGlobalCommandsAction globalAction = (VcsGlobalCommandsAction) VcsGlobalCommandsAction.get(VcsGlobalCommandsAction.class);
   2.131 +        JMenuItem[] globalMenu = globalAction.createMenuItems(globalAction.getActivatedFiles(), popup);
   2.132 +        return globalMenu;
   2.133 +    }
   2.134 +    
   2.135 +    private static JMenuItem[] getContextMenu(boolean popup) {
   2.136 +        VcsFSCommandsAction contextAction = (VcsFSCommandsAction) VcsFSCommandsAction.get(VcsFSCommandsAction.class);
   2.137 +        JMenuItem[] contextMenu = contextAction.createMenuItems(popup);
   2.138 +        return contextMenu;
   2.139 +    }
   2.140 +    
   2.141 +    public void propertyChange(PropertyChangeEvent evt) {
   2.142 +        String name = evt.getPropertyName ();
   2.143 +        if (name == null ||
   2.144 +            name.equals (SystemAction.PROP_ENABLED) ||
   2.145 +            name.equals (Registry.PROP_ACTIVATED_NODES)) {
   2.146 +            // change items
   2.147 +            MergedMenu mergedMenu = (mergedMenuReference != null) ? (MergedMenu) mergedMenuReference.get() : null;
   2.148 +            if (mergedMenu != null) {
   2.149 +                mergedMenu.update(getGlobalMenu(mergedMenuWasInMenu), getContextMenu(mergedMenuWasInMenu));
   2.150 +            }
   2.151 +        }
   2.152 +    }
   2.153 +    
   2.154 +    public void resultChanged(LookupEvent ev) {
   2.155 +        MergedMenu mergedMenu = (mergedMenuReference != null) ? (MergedMenu) mergedMenuReference.get() : null;
   2.156 +        if (mergedMenu != null) {
   2.157 +            mergedMenu.update(getGlobalMenu(mergedMenuWasInMenu), getContextMenu(mergedMenuWasInMenu));
   2.158 +        }
   2.159 +    }
   2.160 +    
   2.161 +    private class MergedMenu extends JInlineMenu {
   2.162 +        
   2.163 +        static final long serialVersionUID = 2650151487189209767L;
   2.164 +        
   2.165 +        private JMenuItem[] contextMenu;
   2.166 +        private JMenuItem[] globalMenu;
   2.167 +        private boolean needsChange = false;
   2.168 +        
   2.169 +        public MergedMenu(JMenuItem[] globalMenu, JMenuItem[] contextMenu) {
   2.170 +            this.globalMenu = globalMenu;
   2.171 +            this.contextMenu = contextMenu;
   2.172 +            setMenuItems(mergeMenu(globalMenu, contextMenu));
   2.173 +        }
   2.174 +        
   2.175 +        public void update(JMenuItem[] globalMenu, JMenuItem[] contextMenu) {
   2.176 +            this.globalMenu = globalMenu;
   2.177 +            this.contextMenu = contextMenu;
   2.178 +            needsChange = true;
   2.179 +        }
   2.180 +        
   2.181 +        public void addNotify() {
   2.182 +            if (needsChange) {
   2.183 +                needsChange = false;
   2.184 +                setMenuItems(mergeMenu(globalMenu, contextMenu));
   2.185 +            }
   2.186 +            super.addNotify();
   2.187 +        }
   2.188 +
   2.189 +        // One-level merge of two menus
   2.190 +        private JMenuItem[] mergeMenu(JMenuItem[] m1, JMenuItem[] m2) {
   2.191 +            for (int i = 0; i < m1.length; i++) {
   2.192 +                if (!(m1[i] instanceof JMenu)) continue;
   2.193 +                String text1 = m1[i].getText();
   2.194 +                int j;
   2.195 +                for (j = 0; j < m2.length; j++) {
   2.196 +                    if (!(m2[j] instanceof JMenu)) continue;
   2.197 +                    String text2 = m2[j].getText();
   2.198 +                    if (text1.equals(text2)) {
   2.199 +                        break;
   2.200 +                    }
   2.201 +                }
   2.202 +                if (j < m2.length) {
   2.203 +                    m1[i] = new MergedMenuItem((JMenu) m1[i], (JMenu) m2[j]);
   2.204 +                    JMenuItem[] m2n = new JMenuItem[m2.length - 1];
   2.205 +                    for (int k = 0; k < j; k++) m2n[k] = m2[k];
   2.206 +                    for (int k = j + 1; k < m2.length; k++) m2n[k-1] = m2[k];
   2.207 +                    m2 = m2n;
   2.208 +                }
   2.209 +            }
   2.210 +            if (m2.length == 0) {
   2.211 +                return m1;
   2.212 +            } else {
   2.213 +                JMenuItem[] m = new JMenuItem[m1.length + m2.length];
   2.214 +                for (int k = 0; k < m1.length; k++) {
   2.215 +                    m[k] = m1[k];
   2.216 +                }
   2.217 +                for (int k = 0; k < m2.length; k++) {
   2.218 +                    m[m1.length + k] = m2[k];
   2.219 +                }
   2.220 +                return m;
   2.221 +            }
   2.222 +        }
   2.223 +        
   2.224 +    }
   2.225 +    
   2.226 +    private static class MergedMenuItem extends JMenuPlus {
   2.227 +        
   2.228 +        private JMenu m1;
   2.229 +        private JMenu m2;
   2.230 +        private boolean popupCreated = false;
   2.231 +        
   2.232 +        public MergedMenuItem(JMenu m1, JMenu m2) {
   2.233 +            this.m1 = m1;
   2.234 +            this.m2 = m2;
   2.235 +            setText(m1.getText());
   2.236 +            setMnemonic(m1.getMnemonic());
   2.237 +        }
   2.238 +        
   2.239 +        /** Overrides superclass method. Adds lazy popup menu creation
   2.240 +          * if it is necessary. */
   2.241 +        public JPopupMenu getPopupMenu() {
   2.242 +            if (!popupCreated) createPopup();
   2.243 +            return super.getPopupMenu();
   2.244 +        }
   2.245 +
   2.246 +        private void createPopup() {
   2.247 +            JPopupMenu popupM1 = m1.getPopupMenu();
   2.248 +            //addElements(popupM1.getSubElements());
   2.249 +            addElements(m1);
   2.250 +            add(new JSeparator());
   2.251 +            //addElements(m2.getPopupMenu().getSubElements());
   2.252 +            addElements(m2);
   2.253 +            popupCreated = true;
   2.254 +        }
   2.255 +        
   2.256 +        private void addElements(MenuElement[] elements) {
   2.257 +            for (int i = 0; i < elements.length; i++) {
   2.258 +                Component c = elements[i].getComponent();
   2.259 +                c.getParent().remove(c);
   2.260 +                add(c);
   2.261 +            }
   2.262 +        }
   2.263 +        
   2.264 +        private void addElements(JMenu m) {
   2.265 +            Component[] cs = m.getPopupMenu().getComponents();
   2.266 +            for (int i = 0; i < cs.length; i++) {
   2.267 +                Component c = cs[i];
   2.268 +                c.getParent().remove(c);
   2.269 +                add(c);
   2.270 +            }
   2.271 +        }
   2.272 +    }
   2.273 +}
     3.1 --- a/vcscore/src/org/netbeans/modules/vcscore/actions/VcsGlobalCommandsAction.java	Mon May 10 15:44:59 2004 +0000
     3.2 +++ b/vcscore/src/org/netbeans/modules/vcscore/actions/VcsGlobalCommandsAction.java	Mon May 10 17:07:12 2004 +0000
     3.3 @@ -166,6 +166,16 @@
     3.4      }
     3.5      
     3.6      private JMenuItem getPresenter(boolean inMenu) {
     3.7 +        FileObject[] files = getActivatedFiles();
     3.8 +        JInlineMenu inlineMenu = new JInlineMenu();
     3.9 +        inlineMenu.setMenuItems(createMenuItems(files, inMenu));
    3.10 +        inlineMenuReference = new WeakReference(inlineMenu);
    3.11 +        inlineMenuWasInMenu = inMenu;
    3.12 +        inlineMenu.addPropertyChangeListener(this); // Hack. This object will not be garbage-collected before the inlineMenu
    3.13 +        return inlineMenu;
    3.14 +    }
    3.15 +    
    3.16 +    static FileObject[] getActivatedFiles() {
    3.17          Node[] n = WindowManager.getDefault().getRegistry ().getActivatedNodes ();
    3.18          ArrayList foList = new ArrayList();
    3.19          if (n != null) {
    3.20 @@ -177,15 +187,10 @@
    3.21              }
    3.22          }
    3.23          FileObject[] files = (FileObject[]) foList.toArray(new FileObject[foList.size()]);
    3.24 -        JInlineMenu inlineMenu = new JInlineMenu();
    3.25 -        inlineMenu.setMenuItems(createMenuItems(files, inMenu));
    3.26 -        inlineMenuReference = new WeakReference(inlineMenu);
    3.27 -        inlineMenuWasInMenu = inMenu;
    3.28 -        inlineMenu.addPropertyChangeListener(this); // Hack. This object will not be garbage-collected before the inlineMenu
    3.29 -        return inlineMenu;
    3.30 +        return files;
    3.31      }
    3.32      
    3.33 -    private JMenuItem[] createMenuItems(FileObject[] files, boolean inMenu) {
    3.34 +    JMenuItem[] createMenuItems(FileObject[] files, boolean inMenu) {
    3.35          CommandsTree commands = getGlobalCommands();
    3.36          ArrayList menuItems = new ArrayList();
    3.37          CommandsTree[] subCommands = commands.children();