Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 110149 Details for
Bug 244364
[MPE] [EditorMgmt] Implement a split editor based on AbstractMultiEditor
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
patch implementing split editor support
patch split editor.txt (text/plain), 61.70 KB, created by
Nikolay Botev
on 2008-08-16 12:03:59 EDT
(
hide
)
Description:
patch implementing split editor support
Filename:
MIME Type:
Creator:
Nikolay Botev
Created:
2008-08-16 12:03:59 EDT
Size:
61.70 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.ui >Index: schema/editors.exsd >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui/schema/editors.exsd,v >retrieving revision 1.18 >diff -u -r1.18 editors.exsd >--- schema/editors.exsd 29 Oct 2007 19:09:17 -0000 1.18 >+++ schema/editors.exsd 15 Aug 2008 21:15:24 -0000 >@@ -1,10 +1,10 @@ > <?xml version='1.0' encoding='UTF-8'?> > <!-- Schema file written by PDE --> >-<schema targetNamespace="org.eclipse.ui"> >+<schema targetNamespace="org.eclipse.ui" xmlns="http://www.w3.org/2001/XMLSchema"> > <annotation> >- <appInfo> >+ <appinfo> > <meta.schema plugin="org.eclipse.ui" id="editors" name="Internal and External Editors"/> >- </appInfo> >+ </appinfo> > <documentation> > This extension point is used to add new editors to the > workbench. A editor is a visual component within a >@@ -41,6 +41,11 @@ > </annotation> > > <element name="extension"> >+ <annotation> >+ <appinfo> >+ <meta.element /> >+ </appinfo> >+ </annotation> > <complexType> > <sequence> > <element ref="editor" minOccurs="0" maxOccurs="unbounded"/> >@@ -64,9 +69,9 @@ > <documentation> > an optional name of the extension instance > </documentation> >- <appInfo> >+ <appinfo> > <meta.attribute translatable="true"/> >- </appInfo> >+ </appinfo> > </annotation> > </attribute> > </complexType> >@@ -74,9 +79,9 @@ > > <element name="editor"> > <annotation> >- <appInfo> >+ <appinfo> > <meta.element labelAttribute="name" icon="icon"/> >- </appInfo> >+ </appinfo> > </annotation> > <complexType> > <sequence> >@@ -94,9 +99,9 @@ > <documentation> > a translatable name that will be used in the UI for this editor > </documentation> >- <appInfo> >+ <appinfo> > <meta.attribute translatable="true"/> >- </appInfo> >+ </appinfo> > </annotation> > </attribute> > <attribute name="icon" type="string"> >@@ -105,9 +110,9 @@ > A relative name of the icon that will be used for all resources that match the specified extensions. Editors should provide an icon to make it easy for users to distinguish between different editor types. If you specify a command rather than a class, an icon is not needed. In that case, the workbench > will use the icon provided by the operating system. > </documentation> >- <appInfo> >+ <appinfo> > <meta.attribute kind="resource"/> >- </appInfo> >+ </appinfo> > </annotation> > </attribute> > <attribute name="extensions" type="string"> >@@ -122,9 +127,9 @@ > <documentation> > the name of a class that implements <samp>org.eclipse.ui.IEditorPart</samp>. The attributes <samp>class</samp>, <samp>command</samp>, and <samp>launcher</samp> are mutually exclusive. If this attribute is defined then <samp>contributorClass</samp> should also be defined. > </documentation> >- <appInfo> >+ <appinfo> > <meta.attribute kind="java" basedOn="org.eclipse.ui.part.EditorPart"/> >- </appInfo> >+ </appinfo> > </annotation> > </attribute> > <attribute name="command" type="string"> >@@ -140,9 +145,9 @@ > the name of a class which that implements <samp>org.eclipse.ui.IEditorLauncher</samp>. > A launcher will open an external editor. The attributes <samp>class</samp>, <samp>command</samp>, and <samp>launcher</samp> are mutually exclusive. > </documentation> >- <appInfo> >+ <appinfo> > <meta.attribute kind="java" basedOn="org.eclipse.ui.IEditorLauncher"/> >- </appInfo> >+ </appinfo> > </annotation> > </attribute> > <attribute name="contributorClass" type="string"> >@@ -150,9 +155,9 @@ > <documentation> > the name of a class that implements <samp>org.eclipse.ui.IEditorActionBarContributor</samp>. This attribute should only be defined if the <samp>class</samp> attribute is defined. This class is used to add new actions to the workbench menu and tool bar which reflect the features of the editor type. > </documentation> >- <appInfo> >+ <appinfo> > <meta.attribute kind="java" basedOn="org.eclipse.ui.part.EditorActionBarContributor"/> >- </appInfo> >+ </appinfo> > </annotation> > </attribute> > <attribute name="default" type="boolean" use="default" value="false"> >@@ -191,9 +196,16 @@ > <documentation> > the name of a class that implements <samp>org.eclipse.ui.IEditorMatchingStrategy</samp>. This attribute should only be defined if the <samp>class</samp> attribute is defined. This allows the editor extension to provide its own algorithm for matching the input of one of its editors to a given editor input. > </documentation> >- <appInfo> >+ <appinfo> > <meta.attribute kind="java" basedOn="org.eclipse.ui.IEditorMatchingStrategy"/> >- </appInfo> >+ </appinfo> >+ </annotation> >+ </attribute> >+ <attribute name="splitEditor" type="boolean"> >+ <annotation> >+ <documentation> >+ If set to true instances of this editor will always be opened under a split multi editor container. >+ </documentation> > </annotation> > </attribute> > </complexType> >@@ -201,9 +213,9 @@ > > <element name="contentTypeBinding"> > <annotation> >- <appInfo> >+ <appinfo> > <meta.element labelAttribute="contentTypeId"/> >- </appInfo> >+ </appinfo> > <documentation> > Advertises that the containing editor understands the given content type and is suitable for editing files of that type. > </documentation> >@@ -219,11 +231,10 @@ > </complexType> > </element> > >- > <annotation> >- <appInfo> >+ <appinfo> > <meta.section type="examples"/> >- </appInfo> >+ </appinfo> > <documentation> > The following is an example > of an internal editor extension definition: >@@ -247,9 +258,9 @@ > </annotation> > > <annotation> >- <appInfo> >+ <appinfo> > <meta.section type="apiInfo"/> >- </appInfo> >+ </appinfo> > <documentation> > If the command attribute is used, it will be treated > as an external program command line that will be executed >@@ -311,19 +322,20 @@ > </documentation> > </annotation> > >+ > <annotation> >- <appInfo> >+ <appinfo> > <meta.section type="implementation"/> >- </appInfo> >+ </appinfo> > <documentation> > The workbench provides a "Default Text Editor". The end user product may contain other editors as part of the shipping bundle. In that case, editors will be registered as extensions using the syntax described above. > </documentation> > </annotation> > > <annotation> >- <appInfo> >+ <appinfo> > <meta.section type="copyright"/> >- </appInfo> >+ </appinfo> > <documentation> > Copyright (c) 2002, 2007 IBM Corporation and others.<br> > All rights reserved. This program and the accompanying materials are made >#P org.eclipse.ui.editors >Index: plugin.xml >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.editors/plugin.xml,v >retrieving revision 1.114 >diff -u -r1.114 plugin.xml >--- plugin.xml 1 Apr 2008 10:13:15 -0000 1.114 >+++ plugin.xml 15 Aug 2008 21:15:26 -0000 >@@ -191,7 +191,8 @@ > icon="$nl$/icons/full/obj16/file_obj.gif" > class="org.eclipse.ui.editors.text.TextEditor" > contributorClass="org.eclipse.ui.editors.text.TextEditorActionContributor" >- id="org.eclipse.ui.DefaultTextEditor"> >+ id="org.eclipse.ui.DefaultTextEditor" >+ splitEditor="true"> > <contentTypeBinding > contentTypeId="org.eclipse.core.runtime.text" > /> >#P org.eclipse.ui.workbench >Index: Eclipse UI/org/eclipse/ui/internal/IWorkbenchConstants.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IWorkbenchConstants.java,v >retrieving revision 1.81 >diff -u -r1.81 IWorkbenchConstants.java >--- Eclipse UI/org/eclipse/ui/internal/IWorkbenchConstants.java 22 Mar 2007 19:22:01 -0000 1.81 >+++ Eclipse UI/org/eclipse/ui/internal/IWorkbenchConstants.java 15 Aug 2008 21:15:28 -0000 >@@ -336,6 +336,8 @@ > > public static final String TAG_TRIM_ITEM = "trimItem"; //$NON-NLS-1$ > >+ public static final String TAG_SPLIT_EDITOR = "splitEditor"; //$NON-NLS-1$ >+ > //Fonts > public static final String SMALL_FONT = "org.eclipse.ui.smallFont"; //$NON-NLS-1$ > >Index: Eclipse UI/org/eclipse/ui/internal/WorkbenchPartReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPartReference.java,v >retrieving revision 1.48 >diff -u -r1.48 WorkbenchPartReference.java >--- Eclipse UI/org/eclipse/ui/internal/WorkbenchPartReference.java 21 Jul 2008 18:43:07 -0000 1.48 >+++ Eclipse UI/org/eclipse/ui/internal/WorkbenchPartReference.java 15 Aug 2008 21:15:30 -0000 >@@ -669,6 +669,7 @@ > return; > } > >+ // Dispose nested parts before disposing this part's widgets, so nested parts' widgets can be disposed first. > doDisposeNestedParts(); > > // Disposing the pane disposes the part's widgets. The part's widgets need to be disposed before the part itself. >Index: Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java,v >retrieving revision 1.312 >diff -u -r1.312 WorkbenchPage.java >--- Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java 15 Jul 2008 13:02:37 -0000 1.312 >+++ Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java 15 Aug 2008 21:15:30 -0000 >@@ -110,6 +110,7 @@ > import org.eclipse.ui.internal.util.Util; > import org.eclipse.ui.model.IWorkbenchAdapter; > import org.eclipse.ui.part.AbstractMultiEditor; >+import org.eclipse.ui.part.MultiEditor; > import org.eclipse.ui.presentations.IStackPresentationSite; > > /** >@@ -619,6 +620,18 @@ > if (part != null) { > //part.setFocus(); > PartPane pane = getPane(part); >+ >+ if (part instanceof IEditorPart) { >+ // If the activated part is an inner editor of a multi editor, then we need to focus its >+ // containing multi editor's pane (getPane(part) returns that) and set the part >+ // as the multieditor's active editor. >+ IWorkbenchPart topLevelPart = pane.getPartReference().getPart(false); >+ // MultiEditor backwards compatibility >+ if (topLevelPart instanceof AbstractMultiEditor && !(topLevelPart instanceof MultiEditor)) { >+ ((AbstractMultiEditor) topLevelPart).setActiveInnerEditor((IEditorPart) part); >+ } >+ } >+ > pane.setFocus(); > PartSite site = (PartSite) part.getSite(); > pane.showFocus(true); >Index: Eclipse UI/org/eclipse/ui/internal/EditorReference.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorReference.java,v >retrieving revision 1.35 >diff -u -r1.35 EditorReference.java >--- Eclipse UI/org/eclipse/ui/internal/EditorReference.java 21 Jul 2008 18:43:07 -0000 1.35 >+++ Eclipse UI/org/eclipse/ui/internal/EditorReference.java 15 Aug 2008 21:15:28 -0000 >@@ -11,6 +11,9 @@ > *******************************************************************************/ > package org.eclipse.ui.internal; > >+import java.util.ArrayList; >+import java.util.List; >+ > import org.eclipse.osgi.util.NLS; > > import org.eclipse.swt.SWT; >@@ -97,7 +100,7 @@ > * If the reference is instantiated as a AbstractMultiEditor, we need to dispose the > * inner references correctly. > */ >- private IEditorReference[] multiEditorChildren = null; >+ private ArrayList/*<IEditorReference>*/ multiEditorChildren = null; > > > /** >@@ -319,8 +322,8 @@ > > private void disposeMultiEditorChildren() { > if (multiEditorChildren!=null) { >- for (int i=0; i<multiEditorChildren.length; ++i) { >- EditorReference ref = (EditorReference)multiEditorChildren[i]; >+ for (int i=0; i<multiEditorChildren.size(); ++i) { >+ EditorReference ref = (EditorReference)multiEditorChildren.get(i); > if (ref!=null) { > ref.dispose(); > } >@@ -623,7 +626,7 @@ > > // MultiEditor backwards compatibility > if (part != null && part instanceof MultiEditor) { >- multiEditorChildren = manager.openMultiEditor(this, >+ manager.openMultiEditor(this, > (AbstractMultiEditor) part, (MultiEditorInput) editorInput); > } > if (part instanceof IWorkbenchPart3) { >@@ -685,7 +688,7 @@ > // Create the inner editors of an AbstractMultiEditor (but not MultiEditor) here > // MultiEditor backwards compatibility > if (part != null && part instanceof AbstractMultiEditor && !(part instanceof MultiEditor)) { >- multiEditorChildren = manager.openMultiEditor(this, >+ manager.openMultiEditor(this, > (AbstractMultiEditor) part, (MultiEditorInput) editorInput); > } > >@@ -746,6 +749,41 @@ > protected Composite getPaneControlContainer() { > return (Composite) manager.page.getEditorPresentation().getLayoutPart().getControl(); > } >+ >+ public IEditorReference addMultiEditorChild(String editor, IEditorInput editorInput) { >+ checkReference(); // make sure we're not disposed >+ if (part == null) { >+ throw new RuntimeException("Error: EditorReference part not created yet."); //$NON-NLS-1$ >+ } >+ if (multiEditorChildren == null) { >+ throw new RuntimeException("Error: EditorReference not a reference to a multi-editor."); //$NON-NLS-1$ >+ } >+ >+ try { >+ IEditorReference innerRef = manager.addMultiEditorChild(this, (AbstractMultiEditor) part, editor, editorInput); >+ multiEditorChildren.add(innerRef); >+ innerRef.getEditor(true); >+ return innerRef; >+ } catch (PartInitException e) { >+ throw new RuntimeException(e); >+ } >+ } >+ >+ public void removeMultiEditorChild(int index) { >+ checkReference(); // make sure we're not disposed >+ if (part == null) { >+ throw new RuntimeException("Error: EditorReference part not created yet."); //$NON-NLS-1$ >+ } >+ if (multiEditorChildren == null) { >+ throw new RuntimeException("Error: EditorReference not a reference to a multi-editor."); //$NON-NLS-1$ >+ } >+ >+ EditorReference ref = (EditorReference)multiEditorChildren.get(index); >+ if (ref!=null) { >+ ref.dispose(); >+ } >+ multiEditorChildren.remove(index); >+ } > > /** > * A quick way of finding out if this reference points to a AbstractMultiEditor. >@@ -759,6 +797,36 @@ > return multiEditorChildren!=null || restoredInput instanceof MultiEditorInput; > } > >+ public List getMultiEditorChildren() { >+ if (!isMultiReference()) { >+ throw new RuntimeException("Error: EditorReference not a reference to a multi-editor"); //$NON-NLS-1$ >+ } >+ try { >+ return new ArrayList(internalGetMultiEditorChildren()); >+ } catch (PartInitException e) { >+ throw new RuntimeException("Error: inner editor descriptor not found.", e); //$NON-NLS-1$ >+ } >+ } >+ >+ /** >+ * Direct retrieval and on-demand creation of inner reference list. >+ * @throws PartInitException >+ */ >+ ArrayList internalGetMultiEditorChildren() throws PartInitException { >+ if (multiEditorChildren == null) { >+ // Create inner editor references on demand >+ MultiEditorInput input = (MultiEditorInput) restoredInput; >+ String[] editorArray = input.getEditors(); >+ IEditorInput[] inputArray = input.getInput(); >+ multiEditorChildren = new ArrayList(editorArray.length); >+ for (int i = 0; i < editorArray.length; i++) { >+ IEditorReference innerRef = manager.createMultiEditorChild(this, editorArray[i], inputArray[i]); >+ multiEditorChildren.add(innerRef); >+ } >+ } >+ return multiEditorChildren; >+ } >+ > /** > * Creates and returns an empty editor (<code>ErrorEditorPart</code>). > * >Index: Eclipse UI/org/eclipse/ui/internal/EditorManager.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorManager.java,v >retrieving revision 1.139 >diff -u -r1.139 EditorManager.java >--- Eclipse UI/org/eclipse/ui/internal/EditorManager.java 21 Jul 2008 18:43:07 -0000 1.139 >+++ Eclipse UI/org/eclipse/ui/internal/EditorManager.java 15 Aug 2008 21:15:27 -0000 >@@ -20,18 +20,9 @@ > import java.util.ListIterator; > import java.util.Map; > >-import org.eclipse.osgi.util.NLS; >- >-import org.eclipse.swt.custom.BusyIndicator; >-import org.eclipse.swt.program.Program; >-import org.eclipse.swt.widgets.Composite; >-import org.eclipse.swt.widgets.Display; >-import org.eclipse.swt.widgets.Shell; >- > import org.eclipse.core.commands.AbstractHandler; > import org.eclipse.core.commands.ExecutionEvent; > import org.eclipse.core.commands.IHandler; >- > import org.eclipse.core.runtime.Assert; > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IConfigurationElement; >@@ -45,7 +36,6 @@ > import org.eclipse.core.runtime.SubProgressMonitor; > import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler; > import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker; >- > import org.eclipse.jface.dialogs.IDialogConstants; > import org.eclipse.jface.dialogs.MessageDialog; > import org.eclipse.jface.internal.provisional.action.ICoolBarManager2; >@@ -60,7 +50,12 @@ > import org.eclipse.jface.util.SafeRunnable; > import org.eclipse.jface.viewers.ArrayContentProvider; > import org.eclipse.jface.window.IShellProvider; >- >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.custom.BusyIndicator; >+import org.eclipse.swt.program.Program; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Shell; > import org.eclipse.ui.ActiveShellExpression; > import org.eclipse.ui.IEditorActionBarContributor; > import org.eclipse.ui.IEditorDescriptor; >@@ -100,6 +95,7 @@ > import org.eclipse.ui.internal.part.NullEditorInput; > import org.eclipse.ui.internal.registry.EditorDescriptor; > import org.eclipse.ui.internal.registry.EditorRegistry; >+import org.eclipse.ui.internal.spliteditor.SplitMultiEditorInput; > import org.eclipse.ui.internal.tweaklets.TabBehaviour; > import org.eclipse.ui.internal.tweaklets.Tweaklets; > import org.eclipse.ui.internal.util.Util; >@@ -638,6 +634,15 @@ > WorkbenchMessages.EditorManager_unknownEditorIDMessage, > editorId)); > } >+ >+ // Replace with split editor... >+ if (desc.isSplitEditor()) { >+ if (!(input instanceof MultiEditorInput)) { >+ input = new SplitMultiEditorInput(input, editorId); >+ desc = (EditorDescriptor) reg.findEditor("org.eclipse.ui.editors.SplitMultiEditor"); //$NON-NLS-1$ >+ Assert.isNotNull(desc); >+ } >+ } > > IEditorReference result = openEditorFromDescriptor(desc, input, editorState); > return result; >@@ -742,37 +747,53 @@ > * the AbstractMultiEditor input > * @return the array of inner references to store in the AbstractMultiEditor reference > */ >- IEditorReference[] openMultiEditor(final IEditorReference ref, >+ void openMultiEditor(final EditorReference ref, > final AbstractMultiEditor part, final MultiEditorInput input) >- throws PartInitException { >- >- String[] editorArray = input.getEditors(); >- IEditorInput[] inputArray = input.getInput(); >- >- // find all descriptors >- EditorDescriptor[] descArray = new EditorDescriptor[editorArray.length]; >- IEditorReference refArray[] = new IEditorReference[editorArray.length]; >- IEditorPart partArray[] = new IEditorPart[editorArray.length]; >+ throws PartInitException { >+ >+ // Retrieve all inner references, creating them on demand if necessary >+ ArrayList innerRefList = ref.internalGetMultiEditorChildren(); > >- IEditorRegistry reg = getEditorRegistry(); >- for (int i = 0; i < editorArray.length; i++) { >- EditorDescriptor innerDesc = (EditorDescriptor) reg >- .findEditor(editorArray[i]); >- if (innerDesc == null) { >- throw new PartInitException(NLS.bind( >- WorkbenchMessages.EditorManager_unknownEditorIDMessage, >- editorArray[i])); >- } >- descArray[i] = innerDesc; >- InnerEditor innerRef = new InnerEditor(ref, part, inputArray[i], >- descArray[i]); >- refArray[i] = innerRef; >+ // Create all inner editors >+ IEditorPart partArray[] = new IEditorPart[innerRefList.size()]; >+ for (int i = 0; i < innerRefList.size(); i++) { >+ InnerEditor innerRef = (InnerEditor) innerRefList.get(i); >+ innerRef.setOuterEditorPart(part); > partArray[i] = innerRef.getEditor(true); > } >+ >+ // Register the new inner editors with their parent multi editor. > part.setChildren(partArray); >- return refArray; >+ } >+ >+ IEditorReference addMultiEditorChild(final IEditorReference ref, >+ final AbstractMultiEditor part, String innerEditor, >+ IEditorInput innerEditorInput) throws PartInitException { >+ >+ InnerEditor innerRef = createMultiEditorChild(ref, innerEditor, innerEditorInput); >+ innerRef.setOuterEditorPart(part); >+ return innerRef; > } > >+ InnerEditor createMultiEditorChild(final IEditorReference ref, >+ String innerEditor, IEditorInput innerEditorInput) throws PartInitException { >+ IEditorRegistry reg = getEditorRegistry(); >+ EditorDescriptor innerDesc = (EditorDescriptor) reg.findEditor(innerEditor); >+ if (innerDesc == null) { >+ throw new PartInitException(NLS.bind( >+ WorkbenchMessages.EditorManager_unknownEditorIDMessage, >+ innerEditor)); >+ } >+ InnerEditor innerRef = new InnerEditor(ref, innerEditorInput, innerDesc); >+ // Instead of mimicking the behavior of the openMultiEditor method >+ // precisely, we call getEditor(true) to create the editor part later >+ // from the EditorReference, and return it to the MultiEditor instance >+ // from there. >+ //IEditorPart innerPart = innerRef.getEditor(true); >+ //part.childAdded(innerPart); >+ return innerRef; >+ } >+ > /* > * Opens an editor part. > */ >@@ -1427,12 +1448,20 @@ > > private AbstractMultiEditor outerEditorPart; > >+ private MultiEditorInnerPane innerPane; >+ > public InnerEditor(IEditorReference outerEditor, >- AbstractMultiEditor outerEditorPart, IEditorInput input, >- EditorDescriptor desc) { >+ IEditorInput input, EditorDescriptor desc) { > super(EditorManager.this, input, desc); > this.outerEditor = outerEditor; >+ } >+ >+ public void setOuterEditorPart(AbstractMultiEditor outerEditorPart) { > this.outerEditorPart = outerEditorPart; >+ if (innerPane != null) { >+ innerPane.setMultiEditorCompatibilityMode( >+ outerEditorPart instanceof MultiEditor); >+ } > } > > protected void doDisposePart() { >@@ -1442,13 +1471,15 @@ > > protected PartPane createPane() { > // MultiEditor backwards compatibility >- return new MultiEditorInnerPane( >+ innerPane = new MultiEditorInnerPane( > (EditorPane) ((EditorReference) outerEditor).getPane(), > this, page, editorPresentation.getActiveWorkbook(), > outerEditorPart instanceof MultiEditor); >+ return innerPane; > } > > protected Composite getPaneControlContainer() { >+ Assert.isNotNull(outerEditorPart); > // MultiEditor backwards compatibility > if (outerEditorPart instanceof MultiEditor) { > return super.getPaneControlContainer(); >@@ -1567,7 +1598,10 @@ > editorMem.putString(IWorkbenchConstants.TAG_WORKBOOK, > editorPane.getWorkbook().getID()); > >- if (editor == page.getActivePart()) { >+ IWorkbenchPartReference activePartReference = page.getActivePartReference(); >+ boolean innerEditorActive = activePartReference instanceof InnerEditor; >+ if ((!innerEditorActive && editor == page.getActivePart()) || >+ (innerEditorActive && editor == ((InnerEditor) activePartReference).outerEditorPart)) { > editorMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART, > "true"); //$NON-NLS-1$ > } >Index: Eclipse UI/org/eclipse/ui/internal/MultiEditorInnerPane.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/MultiEditorInnerPane.java,v >retrieving revision 1.13 >diff -u -r1.13 MultiEditorInnerPane.java >--- Eclipse UI/org/eclipse/ui/internal/MultiEditorInnerPane.java 21 Jul 2008 18:43:07 -0000 1.13 >+++ Eclipse UI/org/eclipse/ui/internal/MultiEditorInnerPane.java 15 Aug 2008 21:15:28 -0000 >@@ -44,6 +44,10 @@ > multiEditorCompatibilityMode = multiEditor; > } > >+ void setMultiEditorCompatibilityMode(boolean multiEditorCompatibilityMode) { >+ this.multiEditorCompatibilityMode = multiEditorCompatibilityMode; >+ } >+ > AbstractMultiEditor getMultiEditor() { > return (AbstractMultiEditor) parentPane.getPartReference() > .getPart(true); >@@ -56,11 +60,11 @@ > control.addListener(SWT.Activate, new Listener() { > public void handleEvent(Event event) { > if (event.type == SWT.Activate) { >- IEditorPart part = (IEditorPart) MultiEditorInnerPane.this.getEditorReference().getPart( >- true); >- AbstractMultiEditor multiEditor = getMultiEditor(); >- multiEditor.activateEditor(part); >- multiEditor.setFocus(); >+ if (getInLayout()) { >+ // The multi editor will set the focus to the new >+ // active inner editor >+ getMultiEditor().setFocus(); >+ } > } > } > }); >Index: Eclipse UI/org/eclipse/ui/internal/registry/EditorDescriptor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/EditorDescriptor.java,v >retrieving revision 1.42 >diff -u -r1.42 EditorDescriptor.java >--- Eclipse UI/org/eclipse/ui/internal/registry/EditorDescriptor.java 28 Nov 2007 21:56:44 -0000 1.42 >+++ Eclipse UI/org/eclipse/ui/internal/registry/EditorDescriptor.java 15 Aug 2008 21:15:30 -0000 >@@ -89,6 +89,8 @@ > > private int openMode = 0; > >+ private boolean splitEditor; >+ > private transient IConfigurationElement configurationElement; > > /** >@@ -393,6 +395,13 @@ > return getOpenMode() == OPEN_EXTERNAL; > } > >+ public boolean isSplitEditor() { >+ if (!splitEditor) { >+ splitEditor = new Boolean(this.configurationElement.getAttribute(IWorkbenchConstants.TAG_SPLIT_EDITOR)).booleanValue(); >+ } >+ return splitEditor; >+ } >+ > /** > * Load the object properties from a memento. > * >@@ -406,6 +415,7 @@ > fileName = memento.getString(IWorkbenchConstants.TAG_FILE); > id = Util.safeString(memento.getString(IWorkbenchConstants.TAG_ID)); > pluginIdentifier = memento.getString(IWorkbenchConstants.TAG_PLUGIN); >+ splitEditor = new Boolean(memento.getString(IWorkbenchConstants.TAG_SPLIT_EDITOR)).booleanValue(); > > Integer openModeInt = memento > .getInteger(IWorkbenchConstants.TAG_OPEN_MODE); >@@ -455,6 +465,7 @@ > memento.putString(IWorkbenchConstants.TAG_FILE, getFileName()); > memento.putString(IWorkbenchConstants.TAG_ID, getId()); > memento.putString(IWorkbenchConstants.TAG_PLUGIN, getPluginId()); >+ memento.putBoolean(IWorkbenchConstants.TAG_SPLIT_EDITOR, isSplitEditor()); > > memento.putInteger(IWorkbenchConstants.TAG_OPEN_MODE, getOpenMode()); > // legacy: handle the older attribute names, needed to allow reading of workspace by pre-3.0-RCP eclipses >@@ -568,6 +579,10 @@ > openMode = mode; > } > >+ /* package */void setSplitEditor(boolean newSplitEditor) { >+ splitEditor = newSplitEditor; >+ } >+ > /** > * The id of the plugin which contributed this editor, null for external editors. > */ >Index: Eclipse UI/org/eclipse/ui/part/MultiEditor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/part/MultiEditor.java,v >retrieving revision 1.24 >diff -u -r1.24 MultiEditor.java >--- Eclipse UI/org/eclipse/ui/part/MultiEditor.java 21 Jul 2008 18:43:08 -0000 1.24 >+++ Eclipse UI/org/eclipse/ui/part/MultiEditor.java 15 Aug 2008 21:15:30 -0000 >@@ -129,7 +129,7 @@ > * @param part the nested editor > * @since 3.5 > */ >- public void activateEditor(IEditorPart part) { >+ protected void activateEditor(IEditorPart part) { > IEditorPart oldEditor = getActiveEditor(); > super.activateEditor(part); > updateGradient(oldEditor); >Index: Eclipse UI/org/eclipse/ui/part/AbstractMultiEditor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/part/AbstractMultiEditor.java,v >retrieving revision 1.3 >diff -u -r1.3 AbstractMultiEditor.java >--- Eclipse UI/org/eclipse/ui/part/AbstractMultiEditor.java 21 Jul 2008 18:43:08 -0000 1.3 >+++ Eclipse UI/org/eclipse/ui/part/AbstractMultiEditor.java 15 Aug 2008 21:15:30 -0000 >@@ -12,6 +12,9 @@ > > package org.eclipse.ui.part; > >+import java.util.ArrayList; >+import java.util.Arrays; >+ > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.swt.widgets.Composite; > import org.eclipse.ui.IEditorInput; >@@ -22,6 +25,7 @@ > import org.eclipse.ui.IWorkbenchPart; > import org.eclipse.ui.IWorkbenchPartReference; > import org.eclipse.ui.PartInitException; >+import org.eclipse.ui.internal.EditorReference; > import org.eclipse.ui.internal.EditorSite; > import org.eclipse.ui.internal.PartService; > import org.eclipse.ui.internal.PartSite; >@@ -38,7 +42,7 @@ > > private int activeEditorIndex; > >- private IEditorPart innerEditors[]; >+ private ArrayList/*<IEditorPart>*/ innerEditors; > > private IPartListener2 propagationListener; > >@@ -53,8 +57,8 @@ > * @see IEditorPart#doSave(IProgressMonitor) > */ > public void doSave(IProgressMonitor monitor) { >- for (int i = 0; i < innerEditors.length; i++) { >- IEditorPart e = innerEditors[i]; >+ for (int i = 0; i < innerEditors.size(); i++) { >+ IEditorPart e = (IEditorPart) innerEditors.get(i); > e.doSave(monitor); > } > } >@@ -94,8 +98,8 @@ > * @see IEditorPart#isDirty() > */ > public boolean isDirty() { >- for (int i = 0; i < innerEditors.length; i++) { >- IEditorPart e = innerEditors[i]; >+ for (int i = 0; i < innerEditors.size(); i++) { >+ IEditorPart e = (IEditorPart) innerEditors.get(i); > if (e.isDirty()) { > return true; > } >@@ -114,7 +118,11 @@ > * @see IWorkbenchPart#setFocus() > */ > public void setFocus() { >- innerEditors[activeEditorIndex].setFocus(); >+ getActiveEditor().setFocus(); >+ } >+ >+ public int getActiveEditorIndex() { >+ return activeEditorIndex; > } > > /** >@@ -122,7 +130,7 @@ > * @return the active editor > */ > public final IEditorPart getActiveEditor() { >- return innerEditors[activeEditorIndex]; >+ return activeEditorIndex == -1 ? null : (IEditorPart) innerEditors.get(activeEditorIndex); > } > > /** >@@ -130,7 +138,43 @@ > * @return the inner editors > */ > public final IEditorPart[] getInnerEditors() { >- return innerEditors; >+ return (IEditorPart[]) innerEditors.toArray(new IEditorPart[innerEditors.size()]); >+ } >+ >+ /** >+ * @param editor >+ * @param editorInput >+ * @return the editor part of the newly created inner editor. >+ */ >+ public IEditorPart addEditor(String editor, IEditorInput editorInput) { >+ EditorReference ref = (EditorReference) ((EditorSite) getEditorSite()).getPartReference(); >+ // This method will result in a call-back to the >+ IEditorReference innerRef = ref.addMultiEditorChild(editor, editorInput); >+ IEditorPart innerPart = innerRef.getEditor(true); >+ innerEditors.add(innerPart); >+ innerEditorCreated(innerPart); >+ return innerPart; >+ } >+ >+ /** >+ * >+ * @param editor >+ */ >+ public void removeEditor(IEditorPart editor) { >+ int index = getIndex(editor); >+ if (index == -1) { >+ throw new IllegalArgumentException("Error: inner editor not found: " + editor); //$NON-NLS-1$ >+ } >+ EditorReference ref = (EditorReference) ((EditorSite) getEditorSite()).getPartReference(); >+ ref.removeMultiEditorChild(index); >+ innerEditors.remove(index); >+ if (activeEditorIndex >= index) { >+ if (activeEditorIndex >= innerEditors.size()) { >+ activeEditorIndex = innerEditors.size() - 1; >+ } >+ activeEditorChanged(); >+ } >+ innerEditorRemoved(editor); > } > > /** >@@ -141,29 +185,74 @@ > * @param children > */ > public final void setChildren(IEditorPart[] children) { >- innerEditors = children; >+ innerEditors = new ArrayList(Arrays.asList(children)); > activeEditorIndex = 0; > innerEditorsCreated(); >+ for (int i = 0; i < children.length; i++) { >+ innerEditorCreated(children[i]); >+ } > } > > /** >- * Called as soon as the inner editors have been created and are available. >+ * Called upon editor initialization as soon as the inner editors are available. > */ > protected abstract void innerEditorsCreated(); > >- /** >+ /** >+ * Called after an inner editor has been added, either dynamically via >+ * the addEditor method or upon this editor's creation (after >+ * innerEditorsCreated has been called). >+ * >+ * @param innerEditor >+ * the new inner editor >+ */ >+ protected void innerEditorCreated(IEditorPart innerEditor) { >+ // Implemented optionally in subclasses >+ } >+ >+ /** >+ * Called after an inner editor is removed dynamically via the removeEditor >+ * method. Note that this method is not called upon this editor's destruction. >+ * >+ * @param innerEditor >+ * the inner editor that is being removed >+ */ >+ protected void innerEditorRemoved(IEditorPart innerEditor) { >+ // Implemented optionally in subclasses >+ } >+ >+ /** > * Activates the given nested editor. > * > * @param part the nested editor > * @since 3.0 > */ >- public void activateEditor(IEditorPart part) { >- activeEditorIndex = getIndex(part); >- IEditorPart e = getActiveEditor(); >- EditorSite innerSite = (EditorSite) e.getEditorSite(); >- ((WorkbenchPage) innerSite.getPage()).requestActivation(e); >+ protected void activateEditor(IEditorPart part) { >+ setActiveInnerEditor(part); >+ activeEditorChanged(); > } > >+ /** >+ * Notified when the active inner editor has changed. >+ * @since 3.5 >+ */ >+ protected void activeEditorChanged() { >+ IEditorPart e = getActiveEditor(); >+ if (e != null) { >+ EditorSite innerSite = (EditorSite) e.getEditorSite(); >+ ((WorkbenchPage) innerSite.getPage()).requestActivation(e); >+ } >+ } >+ >+ /** >+ * Updates the active inner editor index. >+ * @param part >+ * @since 3.5 >+ */ >+ public void setActiveInnerEditor(IEditorPart part) { >+ activeEditorIndex = getIndex(part); >+ } >+ > /** > * Returns the index of the given nested editor. > * >@@ -171,12 +260,7 @@ > * @since 3.0 > */ > protected int getIndex(IEditorPart editor) { >- for (int i = 0; i < innerEditors.length; i++) { >- if (innerEditors[i] == editor) { >- return i; >- } >- } >- return -1; >+ return innerEditors.indexOf(editor); > } > > /** >@@ -197,8 +281,8 @@ > if (part == AbstractMultiEditor.this && innerEditors != null) { > PartService partService = ((WorkbenchPage) getSite() > .getPage()).getPartService(); >- for (int i = 0; i < innerEditors.length; i++) { >- IEditorPart editor = innerEditors[i]; >+ for (int i = 0; i < innerEditors.size(); i++) { >+ IEditorPart editor = (IEditorPart) innerEditors.get(i); > IWorkbenchPartReference innerRef = ((PartSite) editor > .getSite()).getPartReference(); > partService.firePartClosed(innerRef); >@@ -214,8 +298,8 @@ > if (part == AbstractMultiEditor.this && innerEditors != null) { > PartService partService = ((WorkbenchPage) getSite() > .getPage()).getPartService(); >- for (int i = 0; i < innerEditors.length; i++) { >- IEditorPart editor = innerEditors[i]; >+ for (int i = 0; i < innerEditors.size(); i++) { >+ IEditorPart editor = (IEditorPart) innerEditors.get(i); > IWorkbenchPartReference innerRef = ((PartSite) editor > .getSite()).getPartReference(); > partService.firePartOpened(innerRef); >Index: plugin.xml >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/plugin.xml,v >retrieving revision 1.24 >diff -u -r1.24 plugin.xml >--- plugin.xml 6 Apr 2005 19:22:31 -0000 1.24 >+++ plugin.xml 15 Aug 2008 21:15:26 -0000 >@@ -8,4 +8,23 @@ > class="org.eclipse.ui.internal.WorkbenchPreferenceInitializer"/> > </extension> > >+ <extension >+ point="org.eclipse.ui.editors"> >+ <editor >+ class="org.eclipse.ui.internal.spliteditor.SplitMultiEditor" >+ default="false" >+ id="org.eclipse.ui.editors.SplitMultiEditor" >+ matchingStrategy="org.eclipse.ui.internal.spliteditor.SplitMultiEditorMatchingStrategy" >+ name="[TODO: SPECIAL SPLIT EDITOR NAME SHOULD BE HIDDEN]"> >+ </editor> >+ </extension> >+ >+ <extension >+ point="org.eclipse.ui.elementFactories"> >+ <factory >+ class="org.eclipse.ui.internal.spliteditor.SplitMultiEditorInputFactory" >+ id="org.eclipse.ui.workbench.spliteditor.SplitMultiEditorInputFactory"> >+ </factory> >+ </extension> >+ > </plugin> >Index: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorMatchingStrategy.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorMatchingStrategy.java >diff -N Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorMatchingStrategy.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorMatchingStrategy.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,59 @@ >+/******************************************************************************* >+ * Copyright (c) 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ ******************************************************************************/ >+ >+package org.eclipse.ui.internal.spliteditor; >+ >+import java.util.List; >+ >+import org.eclipse.ui.IEditorDescriptor; >+import org.eclipse.ui.IEditorInput; >+import org.eclipse.ui.IEditorMatchingStrategy; >+import org.eclipse.ui.IEditorReference; >+import org.eclipse.ui.PartInitException; >+import org.eclipse.ui.internal.EditorReference; >+import org.eclipse.ui.internal.WorkbenchPlugin; >+ >+/** >+ * @since 3.4 >+ * >+ */ >+public class SplitMultiEditorMatchingStrategy implements >+ IEditorMatchingStrategy { >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.ui.IEditorMatchingStrategy#matches(org.eclipse.ui.IEditorReference, org.eclipse.ui.IEditorInput) >+ */ >+ public boolean matches(IEditorReference editorRef, IEditorInput input) { >+ try { >+ SplitMultiEditorInput editorInput = (SplitMultiEditorInput) editorRef.getEditorInput(); >+ if (editorInput.equals(input)) { >+ return true; >+ } >+ List innerEditorRefs = ((EditorReference) editorRef).getMultiEditorChildren(); >+ if (innerEditorRefs != null) { >+ EditorReference innerEditorRef = (EditorReference) innerEditorRefs.get(0); >+ IEditorDescriptor desc = innerEditorRef.getDescriptor(); >+ if (desc != null) { >+ IEditorMatchingStrategy matchingStrategy = desc >+ .getEditorMatchingStrategy(); >+ if (matchingStrategy != null) { >+ return matchingStrategy.matches(innerEditorRef, input); >+ } >+ } >+ } >+ return editorInput.getEditorInput().equals(input); >+ } catch (PartInitException e) { >+ WorkbenchPlugin.log(e); >+ return false; >+ } >+ } >+ >+} >Index: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorInputFactory.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorInputFactory.java >diff -N Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorInputFactory.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorInputFactory.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,57 @@ >+package org.eclipse.ui.internal.spliteditor; >+ >+import org.eclipse.core.runtime.IAdaptable; >+import org.eclipse.ui.IEditorInput; >+import org.eclipse.ui.IElementFactory; >+import org.eclipse.ui.IMemento; >+import org.eclipse.ui.PlatformUI; >+ >+public class SplitMultiEditorInputFactory implements IElementFactory { >+ >+ /** >+ * Default constructor. >+ */ >+ public SplitMultiEditorInputFactory() { >+ super(); >+ } >+ >+ /** >+ * >+ * @param memento >+ */ >+ public IAdaptable createElement(IMemento memento) { >+ String editorId = memento.getString(SplitMultiEditorInput.INNER_EDITOR_ID); >+ String factoryId = memento.getString(SplitMultiEditorInput.INNER_INPUT_FACTORY_ID); >+ >+ if (factoryId == null) { >+ throw new RuntimeException("No factory id."); //$NON-NLS-1$ >+ } >+ IElementFactory factory = PlatformUI.getWorkbench().getElementFactory(factoryId); >+ if (factory == null) { >+ throw new RuntimeException("Bad element factory."); //$NON-NLS-1$ >+ } >+ >+ // Get the input element. >+ IMemento inputMem = memento.getChild(SplitMultiEditorInput.INNER_INPUT); >+ if (inputMem == null) { >+ throw new RuntimeException("Bad inner input child."); //$NON-NLS-1$ >+ } >+ IAdaptable inputObject = factory.createElement(inputMem); >+ if (inputObject == null) { >+ throw new RuntimeException("Create element returned null."); //$NON-NLS-1$ >+ } >+ if (!(inputObject instanceof IEditorInput)) { >+ throw new RuntimeException("Input not instance of IEditorInput."); //$NON-NLS-1$ >+ } >+ IEditorInput innerInput = (IEditorInput) inputObject; >+ SplitMultiEditorInput input = new SplitMultiEditorInput(innerInput, editorId); >+ >+ Integer innerEditorCount = memento.getInteger(SplitMultiEditorInput.INNER_EDITOR_COUNT); >+ if (innerEditorCount != null) { >+ input.setInnerEditorCount(innerEditorCount.intValue()); >+ } >+ >+ return input; >+ } >+ >+} >Index: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplittableContainerClient.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplittableContainerClient.java >diff -N Eclipse UI/org/eclipse/ui/internal/spliteditor/SplittableContainerClient.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/spliteditor/SplittableContainerClient.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,9 @@ >+package org.eclipse.ui.internal.spliteditor; >+ >+public interface SplittableContainerClient { >+ >+ public void showSlave(SplittableContainer container); >+ >+ public void hideSlave(SplittableContainer container); >+ >+} >Index: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplittableContainer.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplittableContainer.java >diff -N Eclipse UI/org/eclipse/ui/internal/spliteditor/SplittableContainer.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/spliteditor/SplittableContainer.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,151 @@ >+package org.eclipse.ui.internal.spliteditor; >+ >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.graphics.Point; >+import org.eclipse.swt.graphics.Rectangle; >+import org.eclipse.swt.layout.FillLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Layout; >+import org.eclipse.swt.widgets.Listener; >+import org.eclipse.swt.widgets.Sash; >+ >+ >+public class SplittableContainer extends Composite { >+ >+ final SplittableContainerClient client; >+ >+ final Sash sash; >+ >+ final Composite master; >+ >+ final Composite slave; >+ >+ int splitRatio; >+ >+ int splitTotal; >+ >+ int sashWidth; >+ >+ int dragMinimum; >+ >+ public SplittableContainer(Composite parent, SplittableContainerClient client, int style) { >+ super(parent, style); >+ super.setLayout(new SplitLayout()); >+ >+ this.sashWidth = 4; >+ >+ this.dragMinimum = 10; >+ >+ this.client = client; >+ >+ master = new Composite(this, SWT.NONE); >+ master.setLayout(new FillLayout()); >+ >+ sash = new Sash(this, SWT.HORIZONTAL); >+ sash.setSize(5, 5); >+ sash.addListener (SWT.Selection, new SashSelectionListener()); >+ >+ slave = new Composite(this, SWT.NONE); >+ slave.setLayout(new FillLayout()); >+ slave.setVisible(false); >+ } >+ >+ public void setLayout(Layout layout) { >+ checkWidget(); >+ } >+ >+ public int getSashWidth() { >+ return sashWidth; >+ } >+ >+ public void setSashWidth(int sashWidth) { >+ if (sashWidth == this.sashWidth) return; >+ this.sashWidth = sashWidth; >+ layout(false); >+ } >+ >+ public int getDragMinimum() { >+ return dragMinimum; >+ } >+ >+ public void setDragMinimum(int dragMinimum) { >+ this.dragMinimum = dragMinimum; >+ } >+ >+ public Composite getMaster() { >+ return master; >+ } >+ >+ public Composite getSlave() { >+ return slave; >+ } >+ >+ public int getSplitRatio() { >+ return splitRatio; >+ } >+ >+ public void setSplitRatio(int splitRatio) { >+ if (splitRatio != this.splitRatio) { >+ this.splitRatio = splitRatio; >+ slave.setVisible(splitRatio > 0); >+ } >+ } >+ >+ private final class SashSelectionListener implements Listener { >+ public void handleEvent (Event e) { >+ if ((e.detail & SWT.DRAG) == 0) { >+ splitRatio = e.y; >+ splitTotal = SplittableContainer.this.getSize().y - sashWidth*2; >+ >+ if (splitRatio < dragMinimum) { >+ splitRatio = 0; >+ if (slave.isVisible()) { >+ client.hideSlave(SplittableContainer.this); >+ slave.setVisible(false); >+ } >+ } else { >+ if (!slave.isVisible()) { >+ client.showSlave(SplittableContainer.this); >+ slave.setVisible(true); >+ } >+ } >+ >+ SplittableContainer.this.layout(); >+ } >+ } >+ } >+ >+ private final class SplitLayout extends Layout { >+ >+ protected Point computeSize(Composite composite, int hint, int hint2, >+ boolean flushCache) { >+ return null; >+ } >+ >+ protected void layout(Composite composite, boolean flushCache) { >+ Rectangle area = composite.getClientArea(); >+ if (area.width <= 1 || area.height <= 1) return; >+ >+ // Calculate split position >+ if (splitTotal == 0) { >+ splitTotal = area.height; >+ } >+ int sashPos = (splitRatio * (area.height - sashWidth*2)) / splitTotal; >+ >+ // Layout slave >+ if (slave.isVisible()) { >+ slave.setBounds(area.x, area.y + sashWidth, area.width, sashPos - sashWidth); >+ } >+ >+ // Layout sash >+ sash.setBounds(area.x, area.y + sashPos, area.width, sashWidth); >+ int sashBottom = sashPos + sashWidth; >+ >+ // Layout master >+ master.setBounds(area.x, area.y + sashBottom, area.width, area.height - sashBottom); >+ } >+ >+ } >+ >+} >Index: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorInput.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorInput.java >diff -N Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorInput.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditorInput.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,174 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.ui.internal.spliteditor; >+ >+import java.util.Arrays; >+ >+import org.eclipse.core.runtime.Assert; >+import org.eclipse.jface.resource.ImageDescriptor; >+import org.eclipse.ui.IEditorInput; >+import org.eclipse.ui.IMemento; >+import org.eclipse.ui.IPersistableElement; >+import org.eclipse.ui.part.MultiEditorInput; >+ >+/** >+ * Implements a SplitMultiEditor input. >+ */ >+public class SplitMultiEditorInput extends MultiEditorInput { >+ >+ protected static final String FACTORY_ID = "org.eclipse.ui.workbench.spliteditor.SplitMultiEditorInputFactory"; //$NON-NLS-1$ >+ >+ protected static final String INNER_EDITOR_ID = "editorId"; //$NON-NLS-1$ >+ >+ protected static final String INNER_EDITOR_COUNT = "editorCount"; //$NON-NLS-1$ >+ >+ protected static final String INNER_INPUT_FACTORY_ID = "factoryId"; //$NON-NLS-1$ >+ >+ protected static final String INNER_INPUT = "input"; //$NON-NLS-1$ >+ >+ private final String editorId; >+ >+ private IEditorInput input; >+ >+ private int innerEditorCount; >+ >+ public SplitMultiEditorInput(IEditorInput input, String editorId) { >+ super(new String[0], new IEditorInput[0]); >+ Assert.isNotNull(editorId); >+ Assert.isNotNull(input); >+ this.editorId = editorId; >+ this.input = input; >+ this.innerEditorCount = 1; >+ } >+ >+ int getInnerEditorCount() { >+ return innerEditorCount; >+ } >+ >+ void setInnerEditorCount(int innerEditorCount) { >+ this.innerEditorCount = innerEditorCount; >+ } >+ >+ /** >+ * >+ * @return the inner editors' id >+ */ >+ public String getEditorId() { >+ return editorId; >+ } >+ >+ /** >+ * >+ * @return the inner editors' input >+ */ >+ public IEditorInput getEditorInput() { >+ return input; >+ } >+ >+ public void setEditorInput(IEditorInput input) { >+ this.input = input; >+ } >+ >+ public IEditorInput[] getInput() { >+ IEditorInput[] editorInputs = new IEditorInput[innerEditorCount]; >+ Arrays.fill(editorInputs, input); >+ return editorInputs; >+ } >+ >+ public String[] getEditors() { >+ String[] editors = new String[innerEditorCount]; >+ Arrays.fill(editors, editorId); >+ return editors; >+ } >+ >+ /* >+ * @see IEditorInput#exists() >+ */ >+ public boolean exists() { >+ return true; >+ } >+ >+ /* >+ * @see IEditorInput#getImageDescriptor() >+ */ >+ public ImageDescriptor getImageDescriptor() { >+ return input.getImageDescriptor(); >+ } >+ >+ /* >+ * @see IEditorInput#getName() >+ */ >+ public String getName() { >+ return input.getName(); >+ } >+ >+ /* >+ * @see IEditorInput#getPersistable() >+ */ >+ public IPersistableElement getPersistable() { >+ if (input.getPersistable() == null) { >+ return null; >+ } >+ >+ return new IPersistableElement() { >+ public String getFactoryId() { >+ return FACTORY_ID; >+ } >+ >+ public void saveState(IMemento memento) { >+ memento.putString(INNER_EDITOR_ID, editorId); >+ memento.putInteger(INNER_EDITOR_COUNT, innerEditorCount); >+ memento.putString(INNER_INPUT_FACTORY_ID, input.getPersistable().getFactoryId()); >+ IMemento inner = memento.createChild(INNER_INPUT); >+ input.getPersistable().saveState(inner); >+ } >+ }; >+ } >+ >+ /* >+ * @see IEditorInput#getToolTipText() >+ */ >+ public String getToolTipText() { >+ return input.getToolTipText(); >+ } >+ >+ /* >+ * @see IAdaptable#getAdapter(Class) >+ */ >+ public Object getAdapter(Class adapter) { >+ return null; >+ } >+ >+ /* (non-Javadoc) >+ * @see java.lang.Object#equals(java.lang.Object) >+ */ >+ public boolean equals(Object obj) { >+ if (this == obj) { >+ return true; >+ } >+ if (!(obj instanceof SplitMultiEditorInput)) { >+ return false; >+ } >+ SplitMultiEditorInput other = (SplitMultiEditorInput) obj; >+ return this.editorId.equals(other.editorId) && this.input.equals(other.input); >+ } >+ >+ /* (non-Javadoc) >+ * @see java.lang.Object#hashCode() >+ */ >+ public int hashCode() { >+ int hash = 0; >+ hash = hash * 37 + editorId.hashCode(); >+ hash = hash * 37 + input.hashCode(); >+ return hash; >+ } >+ >+} >Index: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditor.java >=================================================================== >RCS file: Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditor.java >diff -N Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse UI/org/eclipse/ui/internal/spliteditor/SplitMultiEditor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,202 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2006 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.ui.internal.spliteditor; >+ >+import java.util.Arrays; >+import java.util.HashSet; >+import java.util.Set; >+ >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.ui.IEditorInput; >+import org.eclipse.ui.IEditorPart; >+import org.eclipse.ui.IEditorReference; >+import org.eclipse.ui.IMemento; >+import org.eclipse.ui.IPersistableEditor; >+import org.eclipse.ui.IPropertyListener; >+import org.eclipse.ui.IReusableEditor; >+import org.eclipse.ui.ISaveablesSource; >+import org.eclipse.ui.IWorkbenchPart2; >+import org.eclipse.ui.IWorkbenchPartConstants; >+import org.eclipse.ui.Saveable; >+import org.eclipse.ui.internal.DefaultSaveable; >+import org.eclipse.ui.part.AbstractMultiEditor; >+ >+/** >+ * Implementation of a SplitMultiEditor. This is the testable version copied from bug >+ * 42641. >+ */ >+public class SplitMultiEditor extends AbstractMultiEditor implements ISaveablesSource, IPersistableEditor { >+ >+ private static final String KEY_ACTIVE_EDITOR = "activeEditorIndex"; //$NON-NLS-1$ >+ >+ private static final String KEY_SPLIT_RATIO = "splitRatio"; //$NON-NLS-1$ >+ >+ private final class SplitterClient implements SplittableContainerClient { >+ >+ public void hideSlave(SplittableContainer splittable) { >+ removeEditor(slaveEditor); >+ slaveEditor = null; >+ ((SplitMultiEditorInput) getEditorInput()).setInnerEditorCount(1); >+ } >+ >+ public void showSlave(SplittableContainer splittable) { >+ if (slaveEditor == null) { >+ SplitMultiEditorInput input = (SplitMultiEditorInput) getEditorInput(); >+ slaveEditor = addEditor(input.getEditorId(), input.getEditorInput()); >+ ((SplitMultiEditorInput) getEditorInput()).setInnerEditorCount(2); >+ } >+ } >+ >+ } >+ >+ private final IPropertyListener forwardingPropertyListener = new IPropertyListener() { >+ boolean updating = false; >+ public void propertyChanged(Object source, int propId) { >+ if (!updating) { >+ IEditorPart sourcePart = (IEditorPart) source; >+ if (propId == IWorkbenchPartConstants.PROP_INPUT) { >+ // Handle input change (Save as action) >+ IEditorInput newInput = sourcePart.getEditorInput(); >+ updating = true; >+ try { >+ IEditorPart[] editors = getInnerEditors(); >+ for (int i = 0; i < editors.length; i++) { >+ IEditorPart editor = editors[i]; >+ if (editor != source) { >+ if (editor instanceof IReusableEditor) { >+ ((IReusableEditor) editor).setInput(newInput); >+ } >+ } >+ } >+ } finally { >+ updating = false; >+ } >+ ((SplitMultiEditorInput) getEditorInput()).setEditorInput(newInput); >+ } else if (propId == IWorkbenchPartConstants.PROP_PART_NAME) { >+ // Handle title changes (save as, rename) >+ setPartName(((IWorkbenchPart2) sourcePart).getPartName()); >+ } else if (propId == IWorkbenchPartConstants.PROP_TITLE) { >+ //setTitle(sourcePart.getTitle()); >+ setTitleImage(sourcePart.getTitleImage()); >+ setTitleToolTip(sourcePart.getTitleToolTip()); >+ } else if (propId == IWorkbenchPartConstants.PROP_CONTENT_DESCRIPTION) { >+ setContentDescription(((IWorkbenchPart2) sourcePart).getContentDescription()); >+ } >+ firePropertyChange(propId); >+ } >+ } >+ }; >+ >+ private SplittableContainer container; >+ >+ private int restoredActiveEditorIndex; >+ >+ private int restoredSplitRatio; >+ >+ private IEditorPart slaveEditor; >+ >+ public SplitMultiEditor() { >+ super(); >+ } >+ >+ /* >+ * @see IWorkbenchPart#createPartControl(Composite) >+ */ >+ public void createPartControl(Composite parent) { >+ container = new SplittableContainer(parent, new SplitterClient(), SWT.NONE); >+ container.setSashWidth(4); >+ container.setSplitRatio(restoredSplitRatio); >+ } >+ >+ public void doSave(IProgressMonitor monitor) { >+ getActiveEditor().doSave(monitor); >+ } >+ >+ public boolean isDirty() { >+ Saveable[] saveables = getSaveables(); >+ for (int i = 0; i < saveables.length; i++) { >+ if (saveables[i].isDirty()) { >+ return true; >+ } >+ } >+ return false; >+ } >+ >+ public boolean isSaveAsAllowed() { >+ IEditorPart activeEditor = getActiveEditor(); >+ return (activeEditor instanceof IReusableEditor) && activeEditor.isSaveAsAllowed(); >+ } >+ >+ public Composite getInnerEditorContainer(IEditorReference innerEditor) { >+ if (container.getMaster().getChildren().length == 0) { >+ return container.getMaster(); >+ } >+ return container.getSlave(); >+ } >+ >+ protected void innerEditorsCreated() { >+ setTitleImage(getActiveEditor().getTitleImage()); >+ IEditorPart[] children = getInnerEditors(); >+ if (children.length == 2) { >+ slaveEditor = children[1]; >+ if (container.getSplitRatio() == 0) { >+ // Split ratio was not restored from state for some reason (such as editor creation exception). >+ container.setSplitRatio(container.getSize().y / 2); >+ } >+ } >+ setActiveInnerEditor(children[restoredActiveEditorIndex]); >+ } >+ >+ protected void innerEditorCreated(IEditorPart innerEditor) { >+ innerEditor.addPropertyListener(forwardingPropertyListener); >+ } >+ >+ public Saveable[] getActiveSaveables() { >+ IEditorPart activeEditor = getActiveEditor(); >+ if (activeEditor instanceof ISaveablesSource) { >+ return ((ISaveablesSource) activeEditor).getActiveSaveables(); >+ } >+ return new Saveable[] { new DefaultSaveable(activeEditor) }; >+ } >+ >+ public Saveable[] getSaveables() { >+ Set result = new HashSet(); >+ IEditorPart[] innerEditors = getInnerEditors(); >+ for (int i = 0; i < innerEditors.length; i++) { >+ IEditorPart editor = innerEditors[i]; >+ if (editor instanceof ISaveablesSource) { >+ result.addAll(Arrays.asList(((ISaveablesSource) editor).getSaveables())); >+ } else { >+ result.add(new DefaultSaveable(editor)); >+ } >+ } >+ return (Saveable[]) result.toArray(new Saveable[result.size()]); >+ } >+ >+ public void saveState(IMemento memento) { >+ memento.putInteger(KEY_ACTIVE_EDITOR, getIndex(getActiveEditor())); >+ memento.putInteger(KEY_SPLIT_RATIO, container.getSplitRatio()); >+ } >+ >+ public void restoreState(IMemento memento) { >+ Integer editorIndex = memento.getInteger(KEY_ACTIVE_EDITOR); >+ if (editorIndex != null) { >+ restoredActiveEditorIndex = editorIndex.intValue(); >+ } >+ Integer splitRatio = memento.getInteger(KEY_SPLIT_RATIO); >+ if (splitRatio != null) { >+ restoredSplitRatio = splitRatio.intValue(); >+ } >+ } >+ >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 244364
:
110149
|
189341