Index: nbproject/project.properties =================================================================== RCS file: /cvs/editor/nbproject/project.properties,v retrieving revision 1.17.6.1 diff -u -r1.17.6.1 project.properties --- nbproject/project.properties 18 Jan 2006 19:08:01 -0000 1.17.6.1 +++ nbproject/project.properties 30 Mar 2006 09:59:11 -0000 @@ -18,5 +18,5 @@ javadoc.title=Editor Module API test.unit.cp.extra=${editor.dir}/modules/org-netbeans-modules-editor-fold.jar:${java/editor.dir}/modules/org-netbeans-modules-java-editor.jar:${java/editor/lib.dir}/modules/org-netbeans-modules-java-editor-lib.jar:${nb_all}/openide/text/build/test/unit/classes -test.unit.run.cp.extra=${test.unit.cp.extra} +test.unit.run.cp.extra=${test.unit.cp.extra}:${editor/util.dir}/modules/org-netbeans-modules-editor-util.jar test.qa-functional.cp.extra=${editor.dir}/modules/org-netbeans-modules-editor-fold.jar:${java/editor.dir}/modules/org-netbeans-modules-java-editor.jar:${java/editor/lib.dir}/modules/org-netbeans-modules-java-editor-lib.jar Index: src/org/netbeans/modules/editor/NbEditorToolBar.java =================================================================== RCS file: /cvs/editor/src/org/netbeans/modules/editor/NbEditorToolBar.java,v retrieving revision 1.18.2.1 diff -u -r1.18.2.1 NbEditorToolBar.java --- src/org/netbeans/modules/editor/NbEditorToolBar.java 18 Jan 2006 19:09:29 -0000 1.18.2.1 +++ src/org/netbeans/modules/editor/NbEditorToolBar.java 30 Mar 2006 09:59:12 -0000 @@ -38,7 +38,6 @@ import javax.swing.AbstractAction; import javax.swing.AbstractButton; import javax.swing.Action; -import javax.swing.ActionMap; import javax.swing.ImageIcon; import javax.swing.InputMap; @@ -81,7 +80,7 @@ import org.openide.util.Lookup; import org.openide.util.TopologicalSortException; import org.openide.util.actions.Presenter; -import org.openide.util.lookup.Lookups; +import org.openide.util.lookup.ProxyLookup; /** * Editor toolbar component. @@ -592,25 +591,51 @@ } } - private Lookup createActionContext() { + /** + * Not private because of the tests. + */ + Lookup createActionContext() { JTextComponent c = getComponent(); - DataObject dobj = (c != null) ? NbEditorUtilities.getDataObject(c.getDocument()) : null; + Lookup nodeLookup = null; + DataObject dobj = (c != null) ? NbEditorUtilities.getDataObject(c.getDocument()) : null; if (dobj != null){ - Node node = dobj.getNodeDelegate(); - return Lookups.singleton(node); + nodeLookup = dobj.getNodeDelegate().getLookup(); } - - Lookup lookup = null; + + Lookup ancestorLookup = null; for (java.awt.Component comp = c; comp != null; comp = comp.getParent()) { if (comp instanceof Lookup.Provider) { - lookup = ((Lookup.Provider)comp).getLookup (); + Lookup lookup = ((Lookup.Provider)comp).getLookup (); if (lookup != null) { + ancestorLookup = lookup; break; } } } - return lookup; + + if (nodeLookup == null) { + return ancestorLookup; + } else if (ancestorLookup == null) { + return nodeLookup; + } + assert nodeLookup != null && ancestorLookup != null; + + Node node = (Node)nodeLookup.lookup(Node.class); + boolean ancestorLookupContainsNode = false; + + Iterator it = ancestorLookup.lookup(new Lookup.Template(Node.class)).allInstances().iterator(); + while (it.hasNext()) { + if (it.next().equals(node)) { + ancestorLookupContainsNode = true; + } + } + + if (ancestorLookupContainsNode) { + return ancestorLookup; + } else { + return new ProxyLookup(new Lookup[] { nodeLookup, ancestorLookup }); + } } private void processButton(AbstractButton button) { Index: test/unit/src/org/netbeans/modules/editor/NbEditorToolBarTest.java =================================================================== RCS file: test/unit/src/org/netbeans/modules/editor/NbEditorToolBarTest.java diff -N test/unit/src/org/netbeans/modules/editor/NbEditorToolBarTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ test/unit/src/org/netbeans/modules/editor/NbEditorToolBarTest.java 30 Mar 2006 09:59:12 -0000 @@ -0,0 +1,162 @@ +/* + * 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-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.netbeans.modules.editor; + +import java.net.URL; +import javax.swing.JEditorPane; +import javax.swing.JPanel; +import javax.swing.text.Document; +import org.netbeans.junit.NbTestCase; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.LocalFileSystem; +import org.openide.loaders.DataObject; +import org.openide.nodes.Node; +import org.openide.util.Lookup; +import org.openide.util.lookup.Lookups; + +/** + * + * @author Andrei Badea + */ +public class NbEditorToolBarTest extends NbTestCase { + + public NbEditorToolBarTest(String testName) { + super(testName); + } + + public boolean runInEQ() { + return true; + } + + protected void setUp() throws Exception { + super.setUp(); + + clearWorkDir(); + + EditorTestLookup.setLookup( + new URL[] { + EditorTestConstants.EDITOR_LAYER_URL, + }, + new Object[] {}, + getClass().getClassLoader() + ); + } + + /** + * Tests that the action context for the context-aware toolbar actions + * is the first Lookup.Provider ancestor. + */ + public void testActionContextAncestorsLookupProviderIsPreferred() throws Exception { + JPanel parent1 = new LookupPanel(Lookups.singleton(new Foo() { })); + JPanel parent2 = new LookupPanel(Lookups.singleton(new Bar() { })); + parent1.add(parent2); + JEditorPane editor = new JEditorPane(); + editor.setEditorKit(new NbEditorKit()); + parent2.add(editor); + DataObject docDataObject = createDataObject(); + assertNotNull(docDataObject); + editor.getDocument().putProperty(Document.StreamDescriptionProperty, docDataObject); + + NbEditorToolBar toolbar = new NbEditorToolBar(editor); + Lookup actionContext = toolbar.createActionContext(); + assertNotNull(actionContext.lookup(Bar.class)); + assertNotNull(actionContext.lookup(Node.class)); + assertNull(actionContext.lookup(Foo.class)); + } + + /** + * Tests that the action context for the context-aware toolbar actions + * is the DataObject corresponding to the current document if there is no + * Lookup.Provider ancestor. + */ + public void testActionContextFallbackToDataObject() throws Exception { + JPanel parent = new JPanel(); + JEditorPane editor = new JEditorPane(); + editor.setEditorKit(new NbEditorKit()); + parent.add(editor); + DataObject docDataObject = createDataObject(); + assertNotNull(docDataObject); + editor.getDocument().putProperty(Document.StreamDescriptionProperty, docDataObject); + + NbEditorToolBar toolbar = new NbEditorToolBar(editor); + Lookup actionContext = toolbar.createActionContext(); + assertNotNull(actionContext.lookup(Node.class)); + assertNull(actionContext.lookup(Foo.class)); + } + + /** + * Tests that the action context for the context-aware toolbar actions + * is null if there is no Lookup.Provider ancestor and no DataObject + * corresponding to the current document. + */ + public void testActionContextNullWhenNoDataObject() { + JPanel parent = new JPanel(); + JEditorPane editor = new JEditorPane(); + editor.setEditorKit(new NbEditorKit()); + parent.add(editor); + + NbEditorToolBar toolbar = new NbEditorToolBar(editor); + Lookup actionContext = toolbar.createActionContext(); + assertNull(actionContext); + } + + /** + * Tests that the action context for the context-aware toolbar actions + * contains the node corresponding to the current document only once, even + * though the node is both contained in an ancestor Lookup.Provider and + * obtained as the node delegate of the DataObject of the current document. + */ + public void testActionContextLookupContainsNodeOnlyOnce() throws Exception { + DataObject docDataObject = createDataObject(); + assertNotNull(docDataObject); + JPanel parent = new LookupPanel(Lookups.fixed(new Object[] { new Bar() { }, docDataObject.getNodeDelegate().getLookup() })); + JEditorPane editor = new JEditorPane(); + editor.setEditorKit(new NbEditorKit()); + parent.add(editor); + editor.getDocument().putProperty(Document.StreamDescriptionProperty, docDataObject); + + NbEditorToolBar toolbar = new NbEditorToolBar(editor); + Lookup actionContext = toolbar.createActionContext(); + assertNotNull(actionContext.lookup(Bar.class)); + assertNotNull(actionContext.lookup(Node.class)); + assertEquals(1, actionContext.lookup(new Lookup.Template(Node.class)).allInstances().size()); + } + + private DataObject createDataObject() throws Exception { + getWorkDir().mkdirs(); + LocalFileSystem lfs = new LocalFileSystem(); + lfs.setRootDirectory(getWorkDir()); + FileObject fo = lfs.getRoot().createData("file", "txt"); + return DataObject.find(fo); + } + + private static final class LookupPanel extends JPanel implements Lookup.Provider { + + private final Lookup lookup; + + public LookupPanel(Lookup lookup) { + this.lookup = lookup; + } + + public Lookup getLookup() { + return lookup; + } + } + + private static interface Foo { + } + + private static interface Bar { + } +}