Index: java/project/src/org/netbeans/spi/java/project/support/ui/PackageViewChildren.java =================================================================== RCS file: /cvs/java/project/src/org/netbeans/spi/java/project/support/ui/PackageViewChildren.java,v retrieving revision 1.10 diff -u -r1.10 PackageViewChildren.java --- java/project/src/org/netbeans/spi/java/project/support/ui/PackageViewChildren.java 13 May 2004 15:21:47 -0000 1.10 +++ java/project/src/org/netbeans/spi/java/project/support/ui/PackageViewChildren.java 13 May 2004 17:46:59 -0000 @@ -28,8 +28,10 @@ import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; +import javax.swing.Action; import org.netbeans.api.java.queries.AccessibilityQuery; import org.openide.ErrorManager; +import org.openide.actions.FileSystemAction; import org.openide.filesystems.FileAttributeEvent; import org.openide.filesystems.FileChangeListener; import org.openide.filesystems.FileEvent; @@ -46,9 +48,11 @@ import org.openide.nodes.FilterNode; import org.openide.nodes.Node; import org.openide.util.Lookup; +import org.openide.util.LookupListener; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; import org.openide.util.Utilities; +import org.openide.util.actions.Presenter; import org.openide.util.lookup.Lookups; import org.openide.util.lookup.ProxyLookup; import org.openidex.search.SimpleSearchInfo; @@ -331,7 +335,46 @@ } */ + /** For a given Lookup creates new Lookup that converts any PackageNode inside itself into + * all its subnodes. + * + * @param lookup input lookup that may contain, add or remove PackageNode + * @return lookup that is either empty or contains nodes contained in the package + */ + public static Lookup packagesToContent (Lookup lookup) { + return new PackageLookup (lookup); + } + private static final class PackageLookup extends ProxyLookup + implements org.openide.util.LookupListener { + private static final Lookup.Template NODE = new Lookup.Template (PackageNode.class); + + /** Lookup result we take nodes from */ + private Lookup.Result delegate; + + public PackageLookup (Lookup source) { + delegate = source.lookup (NODE); + delegate.addLookupListener ( + (LookupListener)org.openide.util.WeakListeners.create (LookupListener.class, this, delegate) + ); + resultChanged (null); + } + + public void resultChanged(org.openide.util.LookupEvent ev) { + java.util.Collection instances = delegate.allInstances(); + ArrayList lookups = new ArrayList (); + java.util.Iterator it = instances.iterator (); + while (it.hasNext()) { + Node n = (Node)it.next (); + Node[] arr = n.getChildren().getNodes(true); + for (int i = 0; i < arr.length; i++) { + lookups.add (arr[i].getLookup()); + } + } + setLookups ((Lookup[])lookups.toArray (new Lookup[0])); + } + + } private static final class PackageNode extends FilterNode { @@ -355,13 +398,21 @@ private boolean isDefaultPackage; public PackageNode( FileObject root, DataFolder dataFolder ) { - super( dataFolder.getNodeDelegate(), - isEmpty( dataFolder ) ? Children.LEAF : dataFolder.createNodeChildren( NO_FOLDERS_FILTER ), - new ProxyLookup(new Lookup[] {dataFolder.getNodeDelegate().getLookup(), - Lookups.singleton(new SimpleSearchInfo(dataFolder, false))})); + super( + dataFolder.getNodeDelegate(), + isEmpty( dataFolder ) ? Children.LEAF : dataFolder.createNodeChildren( NO_FOLDERS_FILTER ), + new AssignLookup () + ); this.root = root; this.dataFolder = dataFolder; this.isDefaultPackage = root.equals( dataFolder.getPrimaryFile() ); + + AssignLookup asign = (AssignLookup)getLookup (); + asign.assignLookups (new Lookup[] { + dataFolder.getNodeDelegate().getLookup(), + Lookups.singleton(new SimpleSearchInfo(dataFolder, false)), + Lookups.singleton(this), + }); } public String getName() { @@ -490,8 +541,103 @@ return true; } + public javax.swing.Action[] getActions(boolean context) { + javax.swing.Action[] old = super.getActions(context); + javax.swing.Action[] retValue = new javax.swing.Action[old.length]; + for (int i = 0; i < retValue.length; i++) { + if (old[i] instanceof org.openide.actions.FileSystemAction) { + retValue[i] = PkgAction.DEFAULT; + } else { + retValue[i] = old[i]; + } + } + return retValue; + } - } + } // end of PackageNode + private static final class AssignLookup extends ProxyLookup { + public AssignLookup () { + super (new Lookup[0]); + } + + public void assignLookups (Lookup[] arr) { + setLookups (arr); + } + } // end of AssignLookup + /** Special action that delegates file system operations to the + * content of package only, not the whole tree. + */ + private static final class PkgAction + implements javax.swing.Action, org.openide.util.ContextAwareAction, + Presenter.Menu, Presenter.Popup { + static final PkgAction DEFAULT = create ( + Utilities.actionsGlobalContext() + ); + private javax.swing.Action delegate; + + + + private PkgAction (Action d) { + delegate = d; + } + + // + // Presentation stuff + // + + /** @return menu presenter. */ + public javax.swing.JMenuItem getMenuPresenter () { + return ((Presenter.Menu)delegate).getMenuPresenter (); + } + + /** @return popup presenter. */ + public javax.swing.JMenuItem getPopupPresenter () { + return ((Presenter.Popup)delegate).getPopupPresenter (); + } + + // + // Action stuff + // + + public void actionPerformed(java.awt.event.ActionEvent e) { + delegate.actionPerformed (e); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + delegate.addPropertyChangeListener (listener); + } + + public Object getValue(String key) { + return delegate.getValue (key); + } + + public boolean isEnabled() { + return delegate.isEnabled (); + } + + public void putValue(String key, Object value) { + delegate.putValue (key, value); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + delegate.removePropertyChangeListener (listener); + } + + public void setEnabled(boolean b) { + delegate.setEnabled (b); + } + + public javax.swing.Action createContextAwareInstance(Lookup actionContext) { + return create (actionContext); + } + + private static PkgAction create (Lookup context) { + FileSystemAction action = (FileSystemAction)FileSystemAction.get (FileSystemAction.class); + return new PkgAction ( + action.createContextAwareInstance (packagesToContent (context)) + ); + } + } // end of PkgAction } Index: java/project/test/unit/src/org/netbeans/spi/java/project/support/ui/PackageViewLookupTest.java =================================================================== RCS file: java/project/test/unit/src/org/netbeans/spi/java/project/support/ui/PackageViewLookupTest.java diff -N java/project/test/unit/src/org/netbeans/spi/java/project/support/ui/PackageViewLookupTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ java/project/test/unit/src/org/netbeans/spi/java/project/support/ui/PackageViewLookupTest.java 13 May 2004 17:46:59 -0000 @@ -0,0 +1,83 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.spi.java.project.support.ui; + +import java.util.*; +import junit.framework.*; +import org.netbeans.junit.NbTestCase; + +import org.netbeans.api.project.TestUtil; +import org.openide.filesystems.FileLock; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileSystem; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.LocalFileSystem; +import org.openide.loaders.DataObject; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.util.Lookup; +import org.openide.util.lookup.InstanceContent; + +public class PackageViewLookupTest extends PackageViewTest { + private static final Lookup.Template DO = new Lookup.Template (DataObject.class); + + public PackageViewLookupTest(String name) { + super( name ); + } + + + protected void setUp () throws Exception { + super.setUp (); + } + + + protected void assertNodes( Children children, String[] nodeNames, int[] childCount ) { + final Node[] nodes = children.getNodes(true); + if (nodes.length == 0) { + return; + } + + final Node[] currentNode = new Node[1]; + + class Del implements org.openide.util.Lookup.Provider { + public org.openide.util.Lookup getLookup () { + if (currentNode[0] == null) { + return org.openide.util.Lookup.EMPTY; + } + return currentNode[0].getLookup(); + } + } + currentNode[0] = nodes[0]; + Del del = new Del (); + Lookup orig = org.openide.util.lookup.Lookups.proxy (del); + Lookup pkgs = PackageViewChildren.packagesToContent (orig); + + for( int i = 0; i < nodes.length; i++ ) { + currentNode[0] = nodes[i]; + orig.lookup (Object.class); + + Collection c = pkgs.lookup (new Lookup.Template (Node.class)).allInstances (); + if (! (c instanceof List)) { + c = new ArrayList (c); + } + + assertEquals ( + "Nodes for " + i + "th node are the same the node: " + nodes[i], + Arrays.asList (nodes[i].getChildren().getNodes (true)), + c + ); + } + } + +} Index: java/project/test/unit/src/org/netbeans/spi/java/project/support/ui/PackageViewTest.java =================================================================== RCS file: /cvs/java/project/test/unit/src/org/netbeans/spi/java/project/support/ui/PackageViewTest.java,v retrieving revision 1.4 diff -u -r1.4 PackageViewTest.java --- java/project/test/unit/src/org/netbeans/spi/java/project/support/ui/PackageViewTest.java 11 May 2004 22:44:06 -0000 1.4 +++ java/project/test/unit/src/org/netbeans/spi/java/project/support/ui/PackageViewTest.java 13 May 2004 17:46:59 -0000 @@ -31,22 +31,29 @@ System.setProperty("org.netbeans.spi.java.project.support.ui.packageView.TRUNCATE_PACKAGE_NAMES", "true"); } + /** Root directory of the project */ + protected FileObject root; + /** children that represent packages in such project */ + protected Children ch; + public PackageViewTest( String name ) { super( name ); } - - public void testFolders() throws Exception { + protected void setUp () throws Exception { // Prepare test data - FileObject root = TestUtil.makeScratchDir( this ); + root = TestUtil.makeScratchDir( this ); // System.out.println("root " + root.getFileSystem().getClass() ); // Create children FileUtil.createFolder( root, "src" ); - Children ch = PackageView.createPackageView( root.getFileObject( "src" ) ); - + ch = PackageView.createPackageView( root.getFileObject( "src" ) ); + } + + + public void testFolders() throws Exception { FileUtil.createFolder( root, "src/a/b/c" ); assertNodes( ch, @@ -168,11 +175,11 @@ } - public static void assertNodes( Children children, String[] nodeNames ) { + private void assertNodes( Children children, String[] nodeNames ) { assertNodes( children, nodeNames, null ); } - public static void assertNodes( Children children, String[] nodeNames, int[] childCount ) { + protected void assertNodes( Children children, String[] nodeNames, int[] childCount ) { Node[] nodes = children.getNodes(); assertEquals( "Wrong number of nodes.", nodeNames.length, nodes.length ); Index: vcscore/src/org/netbeans/modules/vcscore/VcsFSCommandsAction.java =================================================================== RCS file: /cvs/vcscore/src/org/netbeans/modules/vcscore/VcsFSCommandsAction.java,v retrieving revision 1.12 diff -u -r1.12 VcsFSCommandsAction.java --- vcscore/src/org/netbeans/modules/vcscore/VcsFSCommandsAction.java 10 May 2004 17:07:12 -0000 1.12 +++ vcscore/src/org/netbeans/modules/vcscore/VcsFSCommandsAction.java 13 May 2004 17:47:00 -0000 @@ -61,6 +61,8 @@ import org.netbeans.modules.vcscore.util.Table; import org.netbeans.modules.vcscore.util.WeakList; import org.openide.filesystems.FileSystem; +import org.openide.util.Lookup; +import org.openide.util.LookupListener; /** * The system action with VCS commands, that are provided by the FileSystem. @@ -86,10 +88,10 @@ /** * @return a map of array of FileObjects and their messages if any. */ - private Map getSelectedFileObjectsFromActiveNodes() { + private Map getSelectedFileObjectsFromActiveNodes (Lookup lookup) { Map filesWithMessages = new Table(); ArrayList files = new ArrayList(); - Node[] nodes = getActivatedNodes(); + Node[] nodes = (Node[])lookup.lookup (new Lookup.Template (Node.class)).allInstances().toArray (new Node[0]); for (int i = 0; i < nodes.length; i++) { GroupCookie gc = (GroupCookie) nodes[i].getCookie(GroupCookie.class); if (gc != null) { @@ -206,19 +208,19 @@ * Get a menu item that can present this action in a JMenu. */ public JMenuItem getMenuPresenter() { - return getPresenter(true); + return getPresenter(true, org.openide.util.Utilities.actionsGlobalContext ()); } /** * Get a menu item that can present this action in a JPopupMenu. */ public JMenuItem getPopupPresenter() { - return getPresenter(false); + return getPresenter(false, org.openide.util.Utilities.actionsGlobalContext()); } - private JMenuItem getPresenter(boolean inMenu) { + private JMenuItem getPresenter(boolean inMenu, Lookup lookup) { JInlineMenu menu = new JInlineMenu(); - JMenuItem[] items = createMenuItems(inMenu); + JMenuItem[] items = createMenuItems(inMenu, lookup); if (items.length == 0) return menu; menu.setMenuItems(items); if (inMenu && menu != null) { @@ -227,8 +229,8 @@ return menu; } - public JMenuItem[] createMenuItems(boolean inMenu) { - Map filesWithMessages = getSelectedFileObjectsFromActiveNodes(); + public JMenuItem[] createMenuItems(boolean inMenu, Lookup lookup) { + Map filesWithMessages = getSelectedFileObjectsFromActiveNodes (lookup); //System.out.println("VcsFSCommandsAction.getPresenter(): selected filesWithMessages: "+filesWithMessages); switchableList = new ArrayList(); ArrayList menuItems = new ArrayList(); @@ -479,6 +481,10 @@ return new HelpCtx(VcsFSCommandsAction.class); } + public javax.swing.Action createContextAwareInstance(Lookup actionContext) { + return new DelegateAction (this, actionContext); + } + private static final class MergedCommandSupport extends CommandSupport { private CommandSupport cmdSupport1; @@ -634,4 +640,96 @@ } + /** A delegate action that is usually associated with a specific lookup and + * extract the nodes it operates on from it. Otherwise it delegates to the + * regular NodeAction. + */ + static class DelegateAction extends Object + implements javax.swing.Action, org.openide.util.LookupListener, + org.openide.util.actions.Presenter.Menu, org.openide.util.actions.Presenter.Popup { + /** action to delegate too */ + private VcsFSCommandsAction delegate; + /** lookup we are associated with (or null) */ + private org.openide.util.Lookup.Result result; + /** lookup to work with */ + private Lookup lookup; + /** previous state of enabled */ + private boolean enabled = true; + /** support for listeners */ + private java.beans.PropertyChangeSupport support = new java.beans.PropertyChangeSupport (this); + + public DelegateAction (VcsFSCommandsAction a, Lookup actionContext) { + this.delegate = a; + + this.lookup = actionContext; + this.result = actionContext.lookup (new org.openide.util.Lookup.Template ( + Node.class + )); + this.result.addLookupListener ((LookupListener)org.openide.util.WeakListeners.create ( + LookupListener.class, this, this.result + )); + resultChanged (null); + } + + + /** Overrides superclass method, adds delegate description. */ + public String toString() { + return super.toString() + "[delegate=" + delegate + "]"; // NOI18N + } + + private static final Node[] EMPTY_NODE_ARRAY = new Node[0]; + + /** Nodes are taken from the lookup if any. + */ + public final synchronized Node[] nodes () { + if (result != null) { + return (Node[])result.allInstances().toArray(EMPTY_NODE_ARRAY); + } else { + return EMPTY_NODE_ARRAY; + } + } + + /** Invoked when an action occurs. + */ + public void actionPerformed(java.awt.event.ActionEvent e) { + } + + public void addPropertyChangeListener(java.beans.PropertyChangeListener listener) { + support.addPropertyChangeListener (listener); + } + + public void removePropertyChangeListener(java.beans.PropertyChangeListener listener) { + support.removePropertyChangeListener (listener); + } + + public void putValue(String key, Object o) {} + + public Object getValue(String key) { + return delegate.getValue(key); + } + + public boolean isEnabled() { + return delegate.enable(nodes ()); + } + + public void setEnabled(boolean b) { + } + + public void resultChanged(org.openide.util.LookupEvent ev) { + boolean newEnabled = delegate.enable(nodes ()); + if (newEnabled != enabled) { + support.firePropertyChange (PROP_ENABLED, enabled, newEnabled); + enabled = newEnabled; + } + } + + public javax.swing.JMenuItem getMenuPresenter() { + return delegate.getPresenter (true, lookup); + } + + public javax.swing.JMenuItem getPopupPresenter() { + return delegate.getPresenter (false, lookup); + } + } // end of DelegateAction + } Index: vcscore/src/org/netbeans/modules/vcscore/actions/VcsAllCommandsAction.java =================================================================== RCS file: /cvs/vcscore/src/org/netbeans/modules/vcscore/actions/VcsAllCommandsAction.java,v retrieving revision 1.2 diff -u -r1.2 VcsAllCommandsAction.java --- vcscore/src/org/netbeans/modules/vcscore/actions/VcsAllCommandsAction.java 11 May 2004 15:06:37 -0000 1.2 +++ vcscore/src/org/netbeans/modules/vcscore/actions/VcsAllCommandsAction.java 13 May 2004 17:47:01 -0000 @@ -131,7 +131,7 @@ private static JMenuItem[] getContextMenu(boolean popup) { VcsFSCommandsAction contextAction = (VcsFSCommandsAction) VcsFSCommandsAction.get(VcsFSCommandsAction.class); - JMenuItem[] contextMenu = contextAction.createMenuItems(popup); + JMenuItem[] contextMenu = contextAction.createMenuItems(popup, org.openide.util.Utilities.actionsGlobalContext()); return contextMenu; }