diff -r 687656888bfe core.multiview/nbproject/project.xml
--- a/core.multiview/nbproject/project.xml Tue Feb 02 16:33:18 2010 +0300
+++ b/core.multiview/nbproject/project.xml Wed Feb 03 20:04:18 2010 +0100
@@ -134,6 +134,11 @@
+ org.openide.loaders
+
+
+
+
org.openide.windows
diff -r 687656888bfe core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/Bundle.properties
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/Bundle.properties Wed Feb 03 20:04:18 2010 +0100
@@ -0,0 +1,5 @@
+CTL_SomeAction=XYZ
+LBL_XYZ_loader_name=XYZ Files
+OpenIDE-Module-Name=LineSetIssue
+Services/MIMEResolver/XYZResolver.xml=XYZ Files
+Templates/Other/XYZTemplate.xyz=Empty XYZ file
diff -r 687656888bfe core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/DesignViewDescription.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/DesignViewDescription.java Wed Feb 03 20:04:18 2010 +0100
@@ -0,0 +1,48 @@
+package org.netbeans.core.multiview.issue180221;
+
+import org.netbeans.core.spi.multiview.MultiViewDescription;
+import org.netbeans.core.spi.multiview.MultiViewElement;
+import org.openide.util.HelpCtx;
+import org.openide.windows.TopComponent;
+
+import java.awt.*;
+import java.io.Serializable;
+
+/**
+ * @author David Kaspar
+ */
+public final class DesignViewDescription implements MultiViewDescription, Serializable {
+
+ private static final long serialVersionUID = -1l;
+
+ private XYZDataObject designDataObject;
+
+ public DesignViewDescription (XYZDataObject designDataObject) {
+ this.designDataObject = designDataObject;
+ }
+
+ public int getPersistenceType () {
+ return TopComponent.PERSISTENCE_ONLY_OPENED;
+ }
+
+ public String getDisplayName () {
+ return "Design";
+ }
+
+ public Image getIcon () {
+ return null;
+ }
+
+ public HelpCtx getHelpCtx () {
+ return null;
+ }
+
+ public String preferredID () {
+ return null;
+ }
+
+ public MultiViewElement createElement () {
+ return new DesignViewElement (designDataObject);
+ }
+
+}
diff -r 687656888bfe core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/DesignViewElement.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/DesignViewElement.java Wed Feb 03 20:04:18 2010 +0100
@@ -0,0 +1,96 @@
+package org.netbeans.core.multiview.issue180221;
+
+import org.netbeans.core.spi.multiview.CloseOperationState;
+import org.netbeans.core.spi.multiview.MultiViewElement;
+import org.netbeans.core.spi.multiview.MultiViewElementCallback;
+import org.netbeans.core.spi.multiview.MultiViewFactory;
+import org.openide.awt.UndoRedo;
+import org.openide.util.Lookup;
+
+import javax.swing.*;
+import java.io.IOException;
+import java.io.Serializable;
+import org.openide.windows.TopComponent;
+
+/**
+ * @author David Kaspar
+ */
+public final class DesignViewElement implements MultiViewElement, Serializable {
+
+ public static volatile int COUNTER = 0;
+
+ private static final long serialVersionUID = -1;
+
+ private XYZDataObject designDataObject;
+ private transient MultiViewElementCallback multiViewElementCallback;
+
+ DesignViewElement (XYZDataObject designDataObject) {
+ this.designDataObject = designDataObject;
+ COUNTER ++;
+ init ();
+ }
+
+ private void init () {
+ }
+
+ public JComponent getVisualRepresentation () {
+ return new TopComponent ();
+ }
+
+ public JComponent getToolbarRepresentation () {
+ return new JPanel ();
+ }
+
+ public Action[] getActions () {
+ return new Action[0];
+ }
+
+ public Lookup getLookup () {
+ return designDataObject.getLookup ();
+ }
+
+ public void setMultiViewCallback(MultiViewElementCallback multiViewElementCallback) {
+ this.multiViewElementCallback = multiViewElementCallback;
+ }
+
+ public CloseOperationState canCloseElement () {
+ if (! designDataObject.getEditorSupport ().isLastView (multiViewElementCallback.getTopComponent ()))
+ return CloseOperationState.STATE_OK;
+ return MultiViewFactory.createUnsafeCloseState(SourceViewElement.CLOSING_ID, null, null);
+ }
+
+ private void writeObject (java.io.ObjectOutputStream out) throws IOException {
+ out.writeObject (designDataObject);
+ }
+
+ private void readObject (java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+ Object object = in.readObject ();
+ if (! (object instanceof XYZDataObject))
+ throw new ClassNotFoundException ("DataObject expected but not found"); // NOI18N
+ designDataObject = (XYZDataObject) object;
+ init ();
+ }
+
+ public void componentOpened() {
+ }
+
+ public void componentClosed() {
+ }
+
+ public void componentShowing() {
+ }
+
+ public void componentHidden() {
+ }
+
+ public void componentActivated() {
+ }
+
+ public void componentDeactivated() {
+ }
+
+ public UndoRedo getUndoRedo() {
+ return UndoRedo.NONE;
+ }
+
+}
diff -r 687656888bfe core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/Issue180221Test.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/Issue180221Test.java Wed Feb 03 20:04:18 2010 +0100
@@ -0,0 +1,65 @@
+package org.netbeans.core.multiview.issue180221;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import junit.framework.Test;
+import org.netbeans.core.api.multiview.MultiViewPerspective;
+import org.netbeans.junit.NbModuleSuite;
+import org.netbeans.junit.NbTestCase;
+import org.openide.cookies.OpenCookie;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileSystem;
+import org.openide.filesystems.FileUtil;
+import org.openide.loaders.DataLoaderPool;
+import org.openide.loaders.DataObject;
+
+/**
+ * @author David Kaspar
+ */
+public class Issue180221Test extends NbTestCase {
+
+ public Issue180221Test(String name) {
+ super(name);
+ }
+
+ public static Test suite () {
+ return NbModuleSuite.create(NbModuleSuite.emptyConfiguration().addTest(Issue180221Test.class).gui(false));
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ FileObject fo = FileUtil.createData(FileUtil.getConfigRoot(), "Services/MIMEResolver/XYZResolver.xml");
+ InputStream is = Issue180221Test.class.getResourceAsStream("XYZResolver.xml");
+ OutputStream os = fo.getOutputStream();
+ FileUtil.copy(is, os);
+ is.close ();
+ os.close ();
+
+ FileObject fo2 = FileUtil.createData(FileUtil.getConfigRoot(), "Loaders/text/x-xyz/Factories/XYZDataLoader.instance");
+ fo2.setAttribute("instanceCreate", DataLoaderPool.factory(XYZDataObject.class, "test/x-xyz", null));
+ }
+
+ @Override
+ protected boolean runInEQ() {
+ return true;
+ }
+
+ public void testOpenAt () throws IOException {
+ clearWorkDir();
+ FileObject workDir = FileUtil.toFileObject(getWorkDir());
+ FileObject xyz = workDir.createData("a", "xyz");
+ DataObject d = DataObject.find (xyz);
+ assertTrue ("The DataObject should be XYZDataObject but is: " + d + ".", d instanceof XYZDataObject);
+
+ d.getLookup().lookup(OpenCookie.class).open ();
+ assertEquals("SourceView should NOT be opened.", 0, SourceViewElement.COUNTER);
+ assertEquals("DesignView should be opened.", 1, DesignViewElement.COUNTER);
+
+ XYZDataEditorSupport c = d.getLookup().lookup(XYZDataEditorSupport.class);
+ c.openAt ();
+ assertEquals("SourceView should be opened.", 1, SourceViewElement.COUNTER);
+ }
+
+}
diff -r 687656888bfe core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/SourceViewDescription.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/SourceViewDescription.java Wed Feb 03 20:04:18 2010 +0100
@@ -0,0 +1,48 @@
+package org.netbeans.core.multiview.issue180221;
+
+import org.netbeans.core.spi.multiview.MultiViewDescription;
+import org.netbeans.core.spi.multiview.MultiViewElement;
+import org.openide.util.HelpCtx;
+import org.openide.windows.TopComponent;
+
+import java.awt.*;
+import java.io.Serializable;
+
+/**
+ * @author David Kaspar
+ */
+public final class SourceViewDescription implements MultiViewDescription, Serializable {
+
+ private static final long serialVersionUID = -1l;
+
+ private XYZDataObject designDataObject;
+
+ public SourceViewDescription (XYZDataObject designDataObject) {
+ this.designDataObject = designDataObject;
+ }
+
+ public int getPersistenceType () {
+ return TopComponent.PERSISTENCE_ONLY_OPENED;
+ }
+
+ public String getDisplayName () {
+ return "Source";
+ }
+
+ public Image getIcon () {
+ return null;
+ }
+
+ public HelpCtx getHelpCtx () {
+ return null;
+ }
+
+ public String preferredID () {
+ return null;
+ }
+
+ public MultiViewElement createElement () {
+ return new SourceViewElement (designDataObject);
+ }
+
+}
diff -r 687656888bfe core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/SourceViewElement.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/SourceViewElement.java Wed Feb 03 20:04:18 2010 +0100
@@ -0,0 +1,163 @@
+package org.netbeans.core.multiview.issue180221;
+
+import org.netbeans.core.spi.multiview.CloseOperationState;
+import org.netbeans.core.spi.multiview.MultiViewElement;
+import org.netbeans.core.spi.multiview.MultiViewElementCallback;
+import org.netbeans.core.spi.multiview.MultiViewFactory;
+import org.openide.awt.UndoRedo;
+import org.openide.text.CloneableEditor;
+import org.openide.text.NbDocument;
+import org.openide.util.Lookup;
+
+import javax.swing.*;
+import javax.swing.text.Document;
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * @author David Kaspar
+ */
+public final class SourceViewElement implements MultiViewElement, Serializable {
+
+ public static volatile int COUNTER = 0;
+
+ private static final long serialVersionUID = -1;
+
+ static final String CLOSING_ID = "ID_JAVA_CLOSING"; // NOI18N
+
+ private XYZDataObject designDataObject;
+ private transient DesignCloneableEditor editor;
+ private transient JComponent toolbar;
+ private transient MultiViewElementCallback multiViewElementCallback;
+
+ SourceViewElement (XYZDataObject designDataObject) {
+ COUNTER ++;
+ this.designDataObject = designDataObject;
+ init ();
+ }
+
+ private void init () {
+ XYZDataEditorSupport editorSupport = designDataObject.getEditorSupport ();
+ editor = new DesignCloneableEditor (editorSupport);
+ editorSupport.initializeCloneableEditor (editor);
+ }
+
+ public JComponent getVisualRepresentation () {
+ return editor;
+ }
+
+ public JComponent getToolbarRepresentation () {
+ if (toolbar == null) {
+ JEditorPane pane = editor.getEditorPane ();
+ if (pane != null) {
+ Document doc = pane.getDocument ();
+ if (doc instanceof NbDocument.CustomToolbar)
+ toolbar = ((NbDocument.CustomToolbar) doc).createToolbar (pane);
+ }
+ if (toolbar == null)
+ toolbar = new JPanel ();
+ }
+ return toolbar;
+ }
+
+ public Action[] getActions () {
+ return editor.getActions ();
+ }
+
+ public Lookup getLookup () {
+ return editor.getLookup ();
+ }
+
+ public void componentOpened () {
+ editor.componentOpened ();
+ }
+
+ public void componentClosed () {
+// editor.componentClosed ();
+ }
+
+ public void componentShowing () {
+ editor.componentShowing ();
+ }
+
+ public void componentHidden () {
+ editor.componentOpened ();
+ }
+
+ public void componentActivated () {
+ editor.componentActivated ();
+ }
+
+ public void componentDeactivated () {
+ editor.componentDeactivated ();
+ }
+
+ public UndoRedo getUndoRedo () {
+ return editor.getUndoRedo ();
+ }
+
+ public void setMultiViewCallback (MultiViewElementCallback multiViewElementCallback) {
+ this.multiViewElementCallback = multiViewElementCallback;
+// designDataObject.getEditorSupport ().setMVTC (multiViewElementCallback.getTopComponent ());
+ }
+
+ public CloseOperationState canCloseElement () {
+ if (! designDataObject.getEditorSupport ().isLastView (multiViewElementCallback.getTopComponent ()))
+ return CloseOperationState.STATE_OK;
+ return MultiViewFactory.createUnsafeCloseState(CLOSING_ID, null, null);
+ }
+
+ private void writeObject (java.io.ObjectOutputStream out) throws IOException {
+ out.writeObject (designDataObject);
+ }
+
+ private void readObject (java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+ Object object = in.readObject ();
+ if (! (object instanceof XYZDataObject))
+ throw new ClassNotFoundException ("DataObject expected but not found"); // NOI18N
+ designDataObject = (XYZDataObject) object;
+ init ();
+ }
+
+ private static final class DesignCloneableEditor extends CloneableEditor {
+
+ public DesignCloneableEditor () {
+ }
+
+ public DesignCloneableEditor(XYZDataEditorSupport editorSupport) {
+ super(editorSupport);
+ }
+
+ @Override
+ protected void componentActivated () {
+ super.componentActivated();
+ }
+
+ @Override
+ protected void componentDeactivated () {
+ super.componentDeactivated();
+ }
+
+ @Override
+ protected void componentShowing() {
+ super.componentShowing();
+ }
+
+ @Override
+ protected void componentHidden () {
+ super.componentHidden ();
+ }
+
+ @Override
+ protected void componentOpened() {
+ super.componentOpened();
+ }
+
+ @Override
+ protected void componentClosed() {
+ super.componentClosed();
+ }
+
+ }
+
+}
diff -r 687656888bfe core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/XYZDataEditorSupport.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/XYZDataEditorSupport.java Wed Feb 03 20:04:18 2010 +0100
@@ -0,0 +1,155 @@
+package org.netbeans.core.multiview.issue180221;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Enumeration;
+import javax.swing.text.Position.Bias;
+import org.netbeans.core.api.multiview.MultiViewHandler;
+import org.netbeans.core.api.multiview.MultiViewPerspective;
+import org.netbeans.core.api.multiview.MultiViews;
+import org.netbeans.core.spi.multiview.CloseOperationHandler;
+import org.netbeans.core.spi.multiview.CloseOperationState;
+import org.netbeans.core.spi.multiview.MultiViewDescription;
+import org.netbeans.core.spi.multiview.MultiViewFactory;
+import org.openide.cookies.EditCookie;
+import org.openide.cookies.EditorCookie;
+import org.openide.cookies.OpenCookie;
+import org.openide.cookies.PrintCookie;
+import org.openide.filesystems.FileLock;
+import org.openide.filesystems.FileObject;
+import org.openide.text.CloneableEditor;
+import org.openide.text.CloneableEditorSupport;
+import org.openide.text.DataEditorSupport;
+import org.openide.text.PositionRef;
+import org.openide.windows.CloneableOpenSupport;
+import org.openide.windows.CloneableTopComponent;
+import org.openide.windows.TopComponent;
+
+/**
+ * @author David Kaspar
+ */
+public class XYZDataEditorSupport extends DataEditorSupport implements OpenCookie, EditCookie, EditorCookie, PrintCookie, EditorCookie.Observable {
+
+ private final CloseOperationHandler closeHandler;
+
+ private ViewIndex viewIndex = ViewIndex.SOURCE;
+
+ public XYZDataEditorSupport(XYZDataObject dataObject) {
+ super(dataObject, new Environment (dataObject));
+
+ closeHandler = new CloseHandler (dataObject);
+ }
+
+ @Override
+ public void open() {
+ viewIndex = ViewIndex.DESIGN;
+ super.open();
+
+ showTopComponent (viewIndex);
+ viewIndex = ViewIndex.SOURCE;
+ }
+
+ @Override
+ public void edit() {
+ viewIndex = ViewIndex.SOURCE;
+ super.edit();
+
+ showTopComponent (viewIndex);
+ }
+
+ public void showTopComponent (ViewIndex tabIndex) {
+ TopComponent topComponent = allEditors.getArbitraryComponent ();
+ if (topComponent == null) {
+ final Enumeration enumeration = allEditors.getComponents ();
+ while (topComponent == null && enumeration.hasMoreElements ())
+ topComponent = enumeration.nextElement ();
+ }
+
+ if (topComponent != null) {
+ MultiViewHandler handler = MultiViews.findMultiViewHandler (topComponent);
+ MultiViewPerspective perspective = handler.getPerspectives ()[tabIndex.ordinal ()];
+ handler.requestActive (perspective);
+ handler.requestVisible (perspective);
+ }
+ }
+
+ @Override
+ public void initializeCloneableEditor (CloneableEditor editor) {
+ super.initializeCloneableEditor (editor);
+ }
+
+ @Override
+ protected Pane createPane() {
+ MultiViewDescription[] descriptions = new MultiViewDescription[] {
+ new SourceViewDescription ((XYZDataObject) getDataObject ()),
+ new DesignViewDescription ((XYZDataObject) getDataObject ())
+ };
+ return (CloneableEditorSupport.Pane) MultiViewFactory.createCloneableMultiView (descriptions, descriptions[viewIndex.ordinal ()], closeHandler);
+ }
+
+ public boolean isLastView (TopComponent topComponent) {
+ final Enumeration enumeration = allEditors.getComponents ();
+ while (enumeration.hasMoreElements ()) {
+ TopComponent tc = enumeration.nextElement ();
+ if (topComponent == tc)
+ continue;
+ return false;
+ }
+ return true;
+ }
+
+ public void openAt() {
+ openAt (createPositionRef(0, Bias.Forward), 0);
+ }
+
+ private static class CloseHandler implements CloseOperationHandler, Serializable {
+
+ private static final long serialVersionUID = -1;
+ private XYZDataObject dataObject;
+
+ public CloseHandler (XYZDataObject dataObject) {
+ this.dataObject = dataObject;
+ }
+
+ public boolean resolveCloseOperation(CloseOperationState[] elements) {
+ XYZDataEditorSupport editorSupport = dataObject.getEditorSupport ();
+ boolean can = editorSupport.canClose();
+ if (can)
+ editorSupport.notifyClosed();
+ return can;
+ }
+
+ }
+
+ private static final class Environment extends Env {
+
+ private static final long serialVersionUID = -1l;
+
+ public Environment (XYZDataObject dataObject) {
+ super (dataObject);
+ }
+
+ @Override
+ protected FileObject getFile () {
+ return ((XYZDataObject) getDataObject ()).getPrimaryFile ();
+ }
+
+ @Override
+ protected FileLock takeLock () throws IOException {
+ return ((XYZDataObject) getDataObject ()).getPrimaryEntry().takeLock ();
+ }
+
+ @Override
+ public CloneableOpenSupport findCloneableOpenSupport() {
+ return (CloneableEditorSupport) getDataObject().getCookie (EditorCookie.class);
+ }
+
+ }
+
+ public static enum ViewIndex {
+
+ SOURCE, DESIGN
+
+ }
+
+}
diff -r 687656888bfe core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/XYZDataObject.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/XYZDataObject.java Wed Feb 03 20:04:18 2010 +0100
@@ -0,0 +1,43 @@
+package org.netbeans.core.multiview.issue180221;
+
+import java.io.IOException;
+import org.openide.filesystems.FileObject;
+import org.openide.loaders.DataNode;
+import org.openide.loaders.DataObjectExistsException;
+import org.openide.loaders.MultiDataObject;
+import org.openide.loaders.MultiFileLoader;
+import org.openide.nodes.CookieSet;
+import org.openide.nodes.Node;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node.Cookie;
+import org.openide.util.Lookup;
+
+/**
+ * @author David Kaspar
+ */
+public class XYZDataObject extends MultiDataObject {
+
+ private final XYZDataEditorSupport editorSupport;
+
+ public XYZDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
+ super(pf, loader);
+ CookieSet cookies = getCookieSet();
+ editorSupport = new XYZDataEditorSupport (this);
+ cookies.add((Cookie) editorSupport);
+ }
+
+ @Override
+ protected Node createNodeDelegate() {
+ return new DataNode(this, Children.LEAF, getLookup());
+ }
+
+ @Override
+ public Lookup getLookup() {
+ return getCookieSet().getLookup();
+ }
+
+ XYZDataEditorSupport getEditorSupport() {
+ return editorSupport;
+ }
+
+}
diff -r 687656888bfe core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/XYZResolver.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core.multiview/test/unit/src/org/netbeans/core/multiview/issue180221/XYZResolver.xml Wed Feb 03 20:04:18 2010 +0100
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+