View | Details | Raw Unified | Return to bug 244364 | Differences between
and this patch

Collapse All | Expand All

(-)schema/editors.exsd (-30 / +42 lines)
Lines 1-10 Link Here
1
<?xml version='1.0' encoding='UTF-8'?>
1
<?xml version='1.0' encoding='UTF-8'?>
2
<!-- Schema file written by PDE -->
2
<!-- Schema file written by PDE -->
3
<schema targetNamespace="org.eclipse.ui">
3
<schema targetNamespace="org.eclipse.ui" xmlns="http://www.w3.org/2001/XMLSchema">
4
<annotation>
4
<annotation>
5
      <appInfo>
5
      <appinfo>
6
         <meta.schema plugin="org.eclipse.ui" id="editors" name="Internal and External Editors"/>
6
         <meta.schema plugin="org.eclipse.ui" id="editors" name="Internal and External Editors"/>
7
      </appInfo>
7
      </appinfo>
8
      <documentation>
8
      <documentation>
9
         This extension point is used to add new editors to the 
9
         This extension point is used to add new editors to the 
10
workbench.  A editor is a visual component within a 
10
workbench.  A editor is a visual component within a 
Lines 41-46 Link Here
41
   </annotation>
41
   </annotation>
42
42
43
   <element name="extension">
43
   <element name="extension">
44
      <annotation>
45
         <appinfo>
46
            <meta.element />
47
         </appinfo>
48
      </annotation>
44
      <complexType>
49
      <complexType>
45
         <sequence>
50
         <sequence>
46
            <element ref="editor" minOccurs="0" maxOccurs="unbounded"/>
51
            <element ref="editor" minOccurs="0" maxOccurs="unbounded"/>
Lines 64-72 Link Here
64
               <documentation>
69
               <documentation>
65
                  an optional name of the extension instance
70
                  an optional name of the extension instance
66
               </documentation>
71
               </documentation>
67
               <appInfo>
72
               <appinfo>
68
                  <meta.attribute translatable="true"/>
73
                  <meta.attribute translatable="true"/>
69
               </appInfo>
74
               </appinfo>
70
            </annotation>
75
            </annotation>
71
         </attribute>
76
         </attribute>
72
      </complexType>
77
      </complexType>
Lines 74-82 Link Here
74
79
75
   <element name="editor">
80
   <element name="editor">
76
      <annotation>
81
      <annotation>
77
         <appInfo>
82
         <appinfo>
78
            <meta.element labelAttribute="name" icon="icon"/>
83
            <meta.element labelAttribute="name" icon="icon"/>
79
         </appInfo>
84
         </appinfo>
80
      </annotation>
85
      </annotation>
81
      <complexType>
86
      <complexType>
82
         <sequence>
87
         <sequence>
Lines 94-102 Link Here
94
               <documentation>
99
               <documentation>
95
                  a translatable name that will be used in the UI for this editor
100
                  a translatable name that will be used in the UI for this editor
96
               </documentation>
101
               </documentation>
97
               <appInfo>
102
               <appinfo>
98
                  <meta.attribute translatable="true"/>
103
                  <meta.attribute translatable="true"/>
99
               </appInfo>
104
               </appinfo>
100
            </annotation>
105
            </annotation>
101
         </attribute>
106
         </attribute>
102
         <attribute name="icon" type="string">
107
         <attribute name="icon" type="string">
Lines 105-113 Link Here
105
                  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 
110
                  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 
106
will use the icon provided by the operating system.
111
will use the icon provided by the operating system.
107
               </documentation>
112
               </documentation>
108
               <appInfo>
113
               <appinfo>
109
                  <meta.attribute kind="resource"/>
114
                  <meta.attribute kind="resource"/>
110
               </appInfo>
115
               </appinfo>
111
            </annotation>
116
            </annotation>
112
         </attribute>
117
         </attribute>
113
         <attribute name="extensions" type="string">
118
         <attribute name="extensions" type="string">
Lines 122-130 Link Here
122
               <documentation>
127
               <documentation>
123
                  the name of a class that implements &lt;samp&gt;org.eclipse.ui.IEditorPart&lt;/samp&gt;. The attributes &lt;samp&gt;class&lt;/samp&gt;, &lt;samp&gt;command&lt;/samp&gt;, and &lt;samp&gt;launcher&lt;/samp&gt; are mutually exclusive. If this attribute is defined then &lt;samp&gt;contributorClass&lt;/samp&gt; should also be defined.
128
                  the name of a class that implements &lt;samp&gt;org.eclipse.ui.IEditorPart&lt;/samp&gt;. The attributes &lt;samp&gt;class&lt;/samp&gt;, &lt;samp&gt;command&lt;/samp&gt;, and &lt;samp&gt;launcher&lt;/samp&gt; are mutually exclusive. If this attribute is defined then &lt;samp&gt;contributorClass&lt;/samp&gt; should also be defined.
124
               </documentation>
129
               </documentation>
125
               <appInfo>
130
               <appinfo>
126
                  <meta.attribute kind="java" basedOn="org.eclipse.ui.part.EditorPart"/>
131
                  <meta.attribute kind="java" basedOn="org.eclipse.ui.part.EditorPart"/>
127
               </appInfo>
132
               </appinfo>
128
            </annotation>
133
            </annotation>
129
         </attribute>
134
         </attribute>
130
         <attribute name="command" type="string">
135
         <attribute name="command" type="string">
Lines 140-148 Link Here
140
                  the name of a class which that implements &lt;samp&gt;org.eclipse.ui.IEditorLauncher&lt;/samp&gt;. 
145
                  the name of a class which that implements &lt;samp&gt;org.eclipse.ui.IEditorLauncher&lt;/samp&gt;. 
141
A launcher will open an external editor. The attributes &lt;samp&gt;class&lt;/samp&gt;, &lt;samp&gt;command&lt;/samp&gt;, and &lt;samp&gt;launcher&lt;/samp&gt; are mutually exclusive.
146
A launcher will open an external editor. The attributes &lt;samp&gt;class&lt;/samp&gt;, &lt;samp&gt;command&lt;/samp&gt;, and &lt;samp&gt;launcher&lt;/samp&gt; are mutually exclusive.
142
               </documentation>
147
               </documentation>
143
               <appInfo>
148
               <appinfo>
144
                  <meta.attribute kind="java" basedOn="org.eclipse.ui.IEditorLauncher"/>
149
                  <meta.attribute kind="java" basedOn="org.eclipse.ui.IEditorLauncher"/>
145
               </appInfo>
150
               </appinfo>
146
            </annotation>
151
            </annotation>
147
         </attribute>
152
         </attribute>
148
         <attribute name="contributorClass" type="string">
153
         <attribute name="contributorClass" type="string">
Lines 150-158 Link Here
150
               <documentation>
155
               <documentation>
151
                  the name of a class that implements &lt;samp&gt;org.eclipse.ui.IEditorActionBarContributor&lt;/samp&gt;. This attribute should only be defined if the &lt;samp&gt;class&lt;/samp&gt; 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.
156
                  the name of a class that implements &lt;samp&gt;org.eclipse.ui.IEditorActionBarContributor&lt;/samp&gt;. This attribute should only be defined if the &lt;samp&gt;class&lt;/samp&gt; 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.
152
               </documentation>
157
               </documentation>
153
               <appInfo>
158
               <appinfo>
154
                  <meta.attribute kind="java" basedOn="org.eclipse.ui.part.EditorActionBarContributor"/>
159
                  <meta.attribute kind="java" basedOn="org.eclipse.ui.part.EditorActionBarContributor"/>
155
               </appInfo>
160
               </appinfo>
156
            </annotation>
161
            </annotation>
157
         </attribute>
162
         </attribute>
158
         <attribute name="default" type="boolean" use="default" value="false">
163
         <attribute name="default" type="boolean" use="default" value="false">
Lines 191-199 Link Here
191
               <documentation>
196
               <documentation>
192
                  the name of a class that implements &lt;samp&gt;org.eclipse.ui.IEditorMatchingStrategy&lt;/samp&gt;. This attribute should only be defined if the &lt;samp&gt;class&lt;/samp&gt; 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.
197
                  the name of a class that implements &lt;samp&gt;org.eclipse.ui.IEditorMatchingStrategy&lt;/samp&gt;. This attribute should only be defined if the &lt;samp&gt;class&lt;/samp&gt; 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.
193
               </documentation>
198
               </documentation>
194
               <appInfo>
199
               <appinfo>
195
                  <meta.attribute kind="java" basedOn="org.eclipse.ui.IEditorMatchingStrategy"/>
200
                  <meta.attribute kind="java" basedOn="org.eclipse.ui.IEditorMatchingStrategy"/>
196
               </appInfo>
201
               </appinfo>
202
            </annotation>
203
         </attribute>
204
         <attribute name="splitEditor" type="boolean">
205
            <annotation>
206
               <documentation>
207
                  If set to true instances of this editor will always be opened under a split multi editor container.
208
               </documentation>
197
            </annotation>
209
            </annotation>
198
         </attribute>
210
         </attribute>
199
      </complexType>
211
      </complexType>
Lines 201-209 Link Here
201
213
202
   <element name="contentTypeBinding">
214
   <element name="contentTypeBinding">
203
      <annotation>
215
      <annotation>
204
         <appInfo>
216
         <appinfo>
205
            <meta.element labelAttribute="contentTypeId"/>
217
            <meta.element labelAttribute="contentTypeId"/>
206
         </appInfo>
218
         </appinfo>
207
         <documentation>
219
         <documentation>
208
            Advertises that the containing editor understands the given content type and is suitable for editing files of that type.
220
            Advertises that the containing editor understands the given content type and is suitable for editing files of that type.
209
         </documentation>
221
         </documentation>
Lines 219-229 Link Here
219
      </complexType>
231
      </complexType>
220
   </element>
232
   </element>
221
233
222
223
   <annotation>
234
   <annotation>
224
      <appInfo>
235
      <appinfo>
225
         <meta.section type="examples"/>
236
         <meta.section type="examples"/>
226
      </appInfo>
237
      </appinfo>
227
      <documentation>
238
      <documentation>
228
         The following is an example 
239
         The following is an example 
229
of an internal editor extension definition: 
240
of an internal editor extension definition: 
Lines 247-255 Link Here
247
   </annotation>
258
   </annotation>
248
259
249
   <annotation>
260
   <annotation>
250
      <appInfo>
261
      <appinfo>
251
         <meta.section type="apiInfo"/>
262
         <meta.section type="apiInfo"/>
252
      </appInfo>
263
      </appinfo>
253
      <documentation>
264
      <documentation>
254
         If the command attribute is used, it will be treated 
265
         If the command attribute is used, it will be treated 
255
as an external program command line that will be executed
266
as an external program command line that will be executed
Lines 311-329 Link Here
311
      </documentation>
322
      </documentation>
312
   </annotation>
323
   </annotation>
313
324
325
314
   <annotation>
326
   <annotation>
315
      <appInfo>
327
      <appinfo>
316
         <meta.section type="implementation"/>
328
         <meta.section type="implementation"/>
317
      </appInfo>
329
      </appinfo>
318
      <documentation>
330
      <documentation>
319
         The workbench provides a &quot;Default Text Editor&quot;. 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.
331
         The workbench provides a &quot;Default Text Editor&quot;. 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.
320
      </documentation>
332
      </documentation>
321
   </annotation>
333
   </annotation>
322
334
323
   <annotation>
335
   <annotation>
324
      <appInfo>
336
      <appinfo>
325
         <meta.section type="copyright"/>
337
         <meta.section type="copyright"/>
326
      </appInfo>
338
      </appinfo>
327
      <documentation>
339
      <documentation>
328
         Copyright (c) 2002, 2007 IBM Corporation and others.&lt;br&gt;
340
         Copyright (c) 2002, 2007 IBM Corporation and others.&lt;br&gt;
329
All rights reserved. This program and the accompanying materials are made
341
All rights reserved. This program and the accompanying materials are made
(-)plugin.xml (-1 / +2 lines)
Lines 191-197 Link Here
191
            icon="$nl$/icons/full/obj16/file_obj.gif"
191
            icon="$nl$/icons/full/obj16/file_obj.gif"
192
            class="org.eclipse.ui.editors.text.TextEditor"
192
            class="org.eclipse.ui.editors.text.TextEditor"
193
            contributorClass="org.eclipse.ui.editors.text.TextEditorActionContributor"
193
            contributorClass="org.eclipse.ui.editors.text.TextEditorActionContributor"
194
            id="org.eclipse.ui.DefaultTextEditor">
194
            id="org.eclipse.ui.DefaultTextEditor"
195
            splitEditor="true">
195
            <contentTypeBinding
196
            <contentTypeBinding
196
               contentTypeId="org.eclipse.core.runtime.text"
197
               contentTypeId="org.eclipse.core.runtime.text"
197
            /> 
198
            /> 
(-)Eclipse UI/org/eclipse/ui/internal/IWorkbenchConstants.java (+2 lines)
Lines 336-341 Link Here
336
        
336
        
337
    public static final String TAG_TRIM_ITEM = "trimItem"; //$NON-NLS-1$
337
    public static final String TAG_TRIM_ITEM = "trimItem"; //$NON-NLS-1$
338
338
339
	public static final String TAG_SPLIT_EDITOR = "splitEditor"; //$NON-NLS-1$
340
339
    //Fonts
341
    //Fonts
340
    public static final String SMALL_FONT = "org.eclipse.ui.smallFont"; //$NON-NLS-1$
342
    public static final String SMALL_FONT = "org.eclipse.ui.smallFont"; //$NON-NLS-1$
341
343
(-)Eclipse UI/org/eclipse/ui/internal/WorkbenchPartReference.java (+1 lines)
Lines 669-674 Link Here
669
            return;
669
            return;
670
        }
670
        }
671
        
671
        
672
        // Dispose nested parts before disposing this part's widgets, so nested parts' widgets can be disposed first.
672
        doDisposeNestedParts();
673
        doDisposeNestedParts();
673
        
674
        
674
    	// Disposing the pane disposes the part's widgets. The part's widgets need to be disposed before the part itself.
675
    	// Disposing the pane disposes the part's widgets. The part's widgets need to be disposed before the part itself.
(-)Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java (+13 lines)
Lines 110-115 Link Here
110
import org.eclipse.ui.internal.util.Util;
110
import org.eclipse.ui.internal.util.Util;
111
import org.eclipse.ui.model.IWorkbenchAdapter;
111
import org.eclipse.ui.model.IWorkbenchAdapter;
112
import org.eclipse.ui.part.AbstractMultiEditor;
112
import org.eclipse.ui.part.AbstractMultiEditor;
113
import org.eclipse.ui.part.MultiEditor;
113
import org.eclipse.ui.presentations.IStackPresentationSite;
114
import org.eclipse.ui.presentations.IStackPresentationSite;
114
115
115
/**
116
/**
Lines 619-624 Link Here
619
                        if (part != null) {
620
                        if (part != null) {
620
                            //part.setFocus();
621
                            //part.setFocus();
621
                            PartPane pane = getPane(part);
622
                            PartPane pane = getPane(part);
623
624
                            if (part instanceof IEditorPart) {
625
                            	// If the activated part is an inner editor of a multi editor, then we need to focus its
626
                            	// containing multi editor's pane (getPane(part) returns that) and set the part
627
                            	// as the multieditor's active editor.
628
                            	IWorkbenchPart topLevelPart = pane.getPartReference().getPart(false);
629
                            	// MultiEditor backwards compatibility
630
                            	if (topLevelPart instanceof AbstractMultiEditor && !(topLevelPart instanceof MultiEditor)) {
631
                            		((AbstractMultiEditor) topLevelPart).setActiveInnerEditor((IEditorPart) part);
632
                            	}
633
                            }
634
622
                            pane.setFocus();
635
                            pane.setFocus();
623
                            PartSite site = (PartSite) part.getSite();
636
                            PartSite site = (PartSite) part.getSite();
624
                            pane.showFocus(true);
637
                            pane.showFocus(true);
(-)Eclipse UI/org/eclipse/ui/internal/EditorReference.java (-5 / +73 lines)
Lines 11-16 Link Here
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.ui.internal;
12
package org.eclipse.ui.internal;
13
13
14
import java.util.ArrayList;
15
import java.util.List;
16
14
import org.eclipse.osgi.util.NLS;
17
import org.eclipse.osgi.util.NLS;
15
18
16
import org.eclipse.swt.SWT;
19
import org.eclipse.swt.SWT;
Lines 97-103 Link Here
97
	 * If the reference is instantiated as a AbstractMultiEditor, we need to dispose the
100
	 * If the reference is instantiated as a AbstractMultiEditor, we need to dispose the
98
	 * inner references correctly.
101
	 * inner references correctly.
99
	 */
102
	 */
100
	private IEditorReference[] multiEditorChildren = null;
103
	private ArrayList/*<IEditorReference>*/ multiEditorChildren = null;
101
104
102
    
105
    
103
    /**
106
    /**
Lines 319-326 Link Here
319
322
320
	private void disposeMultiEditorChildren() {
323
	private void disposeMultiEditorChildren() {
321
		if (multiEditorChildren!=null) {
324
		if (multiEditorChildren!=null) {
322
			for (int i=0; i<multiEditorChildren.length; ++i) {
325
			for (int i=0; i<multiEditorChildren.size(); ++i) {
323
				EditorReference ref = (EditorReference)multiEditorChildren[i];
326
				EditorReference ref = (EditorReference)multiEditorChildren.get(i);
324
				if (ref!=null) {
327
				if (ref!=null) {
325
					ref.dispose();
328
					ref.dispose();
326
				}
329
				}
Lines 623-629 Link Here
623
                    
626
                    
624
                    // MultiEditor backwards compatibility
627
                    // MultiEditor backwards compatibility
625
                    if (part != null && part instanceof MultiEditor) {
628
                    if (part != null && part instanceof MultiEditor) {
626
    					multiEditorChildren = manager.openMultiEditor(this,
629
    					manager.openMultiEditor(this,
627
    						(AbstractMultiEditor) part, (MultiEditorInput) editorInput);
630
    						(AbstractMultiEditor) part, (MultiEditorInput) editorInput);
628
    				}
631
    				}
629
                    if (part instanceof IWorkbenchPart3) {
632
                    if (part instanceof IWorkbenchPart3) {
Lines 685-691 Link Here
685
            // Create the inner editors of an AbstractMultiEditor (but not MultiEditor) here
688
            // Create the inner editors of an AbstractMultiEditor (but not MultiEditor) here
686
            // MultiEditor backwards compatibility
689
            // MultiEditor backwards compatibility
687
            if (part != null && part instanceof AbstractMultiEditor && !(part instanceof MultiEditor)) {
690
            if (part != null && part instanceof AbstractMultiEditor && !(part instanceof MultiEditor)) {
688
				multiEditorChildren = manager.openMultiEditor(this,
691
				manager.openMultiEditor(this,
689
					(AbstractMultiEditor) part, (MultiEditorInput) editorInput);
692
					(AbstractMultiEditor) part, (MultiEditorInput) editorInput);
690
			}
693
			}
691
            
694
            
Lines 746-751 Link Here
746
	protected Composite getPaneControlContainer() {
749
	protected Composite getPaneControlContainer() {
747
		return (Composite) manager.page.getEditorPresentation().getLayoutPart().getControl();
750
		return (Composite) manager.page.getEditorPresentation().getLayoutPart().getControl();
748
	}
751
	}
752
	
753
	public IEditorReference addMultiEditorChild(String editor, IEditorInput editorInput) {
754
		checkReference(); // make sure we're not disposed
755
		if (part == null) {
756
			throw new RuntimeException("Error: EditorReference part not created yet."); //$NON-NLS-1$
757
		}
758
		if (multiEditorChildren == null) {
759
			throw new RuntimeException("Error: EditorReference not a reference to a multi-editor."); //$NON-NLS-1$
760
		}
761
		
762
		try {
763
			IEditorReference innerRef = manager.addMultiEditorChild(this, (AbstractMultiEditor) part, editor, editorInput);
764
			multiEditorChildren.add(innerRef);
765
			innerRef.getEditor(true);
766
			return innerRef;
767
		} catch (PartInitException e) {
768
			throw new RuntimeException(e);
769
		}
770
	}
771
	
772
	public void removeMultiEditorChild(int index) {
773
		checkReference(); // make sure we're not disposed
774
		if (part == null) {
775
			throw new RuntimeException("Error: EditorReference part not created yet."); //$NON-NLS-1$
776
		}
777
		if (multiEditorChildren == null) {
778
			throw new RuntimeException("Error: EditorReference not a reference to a multi-editor."); //$NON-NLS-1$
779
		}
780
781
		EditorReference ref = (EditorReference)multiEditorChildren.get(index);
782
		if (ref!=null) {
783
			ref.dispose();
784
		}
785
		multiEditorChildren.remove(index);
786
	}
749
    
787
    
750
    /**
788
    /**
751
     * A quick way of finding out if this reference points to a AbstractMultiEditor.
789
     * A quick way of finding out if this reference points to a AbstractMultiEditor.
Lines 759-764 Link Here
759
    	return multiEditorChildren!=null || restoredInput instanceof MultiEditorInput;
797
    	return multiEditorChildren!=null || restoredInput instanceof MultiEditorInput;
760
    }
798
    }
761
799
800
    public List getMultiEditorChildren() {
801
    	if (!isMultiReference()) {
802
    		throw new RuntimeException("Error: EditorReference not a reference to a multi-editor"); //$NON-NLS-1$
803
    	}
804
    	try {
805
			return new ArrayList(internalGetMultiEditorChildren());
806
		} catch (PartInitException e) {
807
			throw new RuntimeException("Error: inner editor descriptor not found.", e); //$NON-NLS-1$
808
		}
809
    }
810
811
	/**
812
	 * Direct retrieval and on-demand creation of inner reference list. 
813
	 * @throws PartInitException 
814
	 */
815
	ArrayList internalGetMultiEditorChildren() throws PartInitException {
816
		if (multiEditorChildren == null) {
817
    		// Create inner editor references on demand
818
    		MultiEditorInput input = (MultiEditorInput) restoredInput;
819
			String[] editorArray = input.getEditors();
820
			IEditorInput[] inputArray = input.getInput();
821
			multiEditorChildren = new ArrayList(editorArray.length);
822
			for (int i = 0; i < editorArray.length; i++) {
823
				IEditorReference innerRef = manager.createMultiEditorChild(this, editorArray[i], inputArray[i]);
824
				multiEditorChildren.add(innerRef);
825
			}
826
    	}
827
		return multiEditorChildren;
828
	}
829
762
	/**
830
	/**
763
	 * Creates and returns an empty editor (<code>ErrorEditorPart</code>).
831
	 * Creates and returns an empty editor (<code>ErrorEditorPart</code>).
764
	 * 
832
	 * 
(-)Eclipse UI/org/eclipse/ui/internal/EditorManager.java (-39 / +73 lines)
Lines 20-37 Link Here
20
import java.util.ListIterator;
20
import java.util.ListIterator;
21
import java.util.Map;
21
import java.util.Map;
22
22
23
import org.eclipse.osgi.util.NLS;
24
25
import org.eclipse.swt.custom.BusyIndicator;
26
import org.eclipse.swt.program.Program;
27
import org.eclipse.swt.widgets.Composite;
28
import org.eclipse.swt.widgets.Display;
29
import org.eclipse.swt.widgets.Shell;
30
31
import org.eclipse.core.commands.AbstractHandler;
23
import org.eclipse.core.commands.AbstractHandler;
32
import org.eclipse.core.commands.ExecutionEvent;
24
import org.eclipse.core.commands.ExecutionEvent;
33
import org.eclipse.core.commands.IHandler;
25
import org.eclipse.core.commands.IHandler;
34
35
import org.eclipse.core.runtime.Assert;
26
import org.eclipse.core.runtime.Assert;
36
import org.eclipse.core.runtime.CoreException;
27
import org.eclipse.core.runtime.CoreException;
37
import org.eclipse.core.runtime.IConfigurationElement;
28
import org.eclipse.core.runtime.IConfigurationElement;
Lines 45-51 Link Here
45
import org.eclipse.core.runtime.SubProgressMonitor;
36
import org.eclipse.core.runtime.SubProgressMonitor;
46
import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
37
import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
47
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
38
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
48
49
import org.eclipse.jface.dialogs.IDialogConstants;
39
import org.eclipse.jface.dialogs.IDialogConstants;
50
import org.eclipse.jface.dialogs.MessageDialog;
40
import org.eclipse.jface.dialogs.MessageDialog;
51
import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
41
import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
Lines 60-66 Link Here
60
import org.eclipse.jface.util.SafeRunnable;
50
import org.eclipse.jface.util.SafeRunnable;
61
import org.eclipse.jface.viewers.ArrayContentProvider;
51
import org.eclipse.jface.viewers.ArrayContentProvider;
62
import org.eclipse.jface.window.IShellProvider;
52
import org.eclipse.jface.window.IShellProvider;
63
53
import org.eclipse.osgi.util.NLS;
54
import org.eclipse.swt.custom.BusyIndicator;
55
import org.eclipse.swt.program.Program;
56
import org.eclipse.swt.widgets.Composite;
57
import org.eclipse.swt.widgets.Display;
58
import org.eclipse.swt.widgets.Shell;
64
import org.eclipse.ui.ActiveShellExpression;
59
import org.eclipse.ui.ActiveShellExpression;
65
import org.eclipse.ui.IEditorActionBarContributor;
60
import org.eclipse.ui.IEditorActionBarContributor;
66
import org.eclipse.ui.IEditorDescriptor;
61
import org.eclipse.ui.IEditorDescriptor;
Lines 100-105 Link Here
100
import org.eclipse.ui.internal.part.NullEditorInput;
95
import org.eclipse.ui.internal.part.NullEditorInput;
101
import org.eclipse.ui.internal.registry.EditorDescriptor;
96
import org.eclipse.ui.internal.registry.EditorDescriptor;
102
import org.eclipse.ui.internal.registry.EditorRegistry;
97
import org.eclipse.ui.internal.registry.EditorRegistry;
98
import org.eclipse.ui.internal.spliteditor.SplitMultiEditorInput;
103
import org.eclipse.ui.internal.tweaklets.TabBehaviour;
99
import org.eclipse.ui.internal.tweaklets.TabBehaviour;
104
import org.eclipse.ui.internal.tweaklets.Tweaklets;
100
import org.eclipse.ui.internal.tweaklets.Tweaklets;
105
import org.eclipse.ui.internal.util.Util;
101
import org.eclipse.ui.internal.util.Util;
Lines 638-643 Link Here
638
					WorkbenchMessages.EditorManager_unknownEditorIDMessage,
634
					WorkbenchMessages.EditorManager_unknownEditorIDMessage,
639
					editorId));
635
					editorId));
640
		}
636
		}
637
		
638
		// Replace with split editor...
639
		if (desc.isSplitEditor()) {
640
			if (!(input instanceof MultiEditorInput)) {
641
				input = new SplitMultiEditorInput(input, editorId);
642
				desc = (EditorDescriptor) reg.findEditor("org.eclipse.ui.editors.SplitMultiEditor"); //$NON-NLS-1$
643
				Assert.isNotNull(desc);
644
			}
645
		}
641
646
642
		IEditorReference result = openEditorFromDescriptor(desc, input, editorState);
647
		IEditorReference result = openEditorFromDescriptor(desc, input, editorState);
643
		return result;
648
		return result;
Lines 742-778 Link Here
742
	 *            the AbstractMultiEditor input
747
	 *            the AbstractMultiEditor input
743
	 * @return the array of inner references to store in the AbstractMultiEditor reference
748
	 * @return the array of inner references to store in the AbstractMultiEditor reference
744
	 */
749
	 */
745
	IEditorReference[] openMultiEditor(final IEditorReference ref,
750
	void openMultiEditor(final EditorReference ref,
746
			final AbstractMultiEditor part, final MultiEditorInput input)
751
			final AbstractMultiEditor part, final MultiEditorInput input)
747
			throws PartInitException {
752
	throws PartInitException {
748
753
		
749
		String[] editorArray = input.getEditors();
754
		// Retrieve all inner references, creating them on demand if necessary
750
		IEditorInput[] inputArray = input.getInput();
755
		ArrayList innerRefList = ref.internalGetMultiEditorChildren();
751
752
		// find all descriptors
753
		EditorDescriptor[] descArray = new EditorDescriptor[editorArray.length];
754
		IEditorReference refArray[] = new IEditorReference[editorArray.length];
755
		IEditorPart partArray[] = new IEditorPart[editorArray.length];
756
756
757
		IEditorRegistry reg = getEditorRegistry();
757
		// Create all inner editors
758
		for (int i = 0; i < editorArray.length; i++) {
758
		IEditorPart partArray[] = new IEditorPart[innerRefList.size()];
759
			EditorDescriptor innerDesc = (EditorDescriptor) reg
759
		for (int i = 0; i < innerRefList.size(); i++) {
760
					.findEditor(editorArray[i]);
760
			InnerEditor innerRef = (InnerEditor) innerRefList.get(i);
761
			if (innerDesc == null) {
761
			innerRef.setOuterEditorPart(part);
762
				throw new PartInitException(NLS.bind(
763
						WorkbenchMessages.EditorManager_unknownEditorIDMessage,
764
						editorArray[i]));
765
			}
766
			descArray[i] = innerDesc;
767
			InnerEditor innerRef = new InnerEditor(ref, part, inputArray[i],
768
					descArray[i]);
769
			refArray[i] = innerRef;
770
			partArray[i] = innerRef.getEditor(true);
762
			partArray[i] = innerRef.getEditor(true);
771
		}
763
		}
764
765
		// Register the new inner editors with their parent multi editor.
772
		part.setChildren(partArray);
766
		part.setChildren(partArray);
773
		return refArray;
767
	}
768
	
769
	IEditorReference addMultiEditorChild(final IEditorReference ref,
770
			final AbstractMultiEditor part, String innerEditor,
771
			IEditorInput innerEditorInput) throws PartInitException {
772
		
773
		InnerEditor innerRef = createMultiEditorChild(ref, innerEditor, innerEditorInput);
774
		innerRef.setOuterEditorPart(part);
775
		return innerRef;
774
	}
776
	}
775
777
778
	InnerEditor createMultiEditorChild(final IEditorReference ref,
779
			String innerEditor, IEditorInput innerEditorInput) throws PartInitException {
780
		IEditorRegistry reg = getEditorRegistry();
781
		EditorDescriptor innerDesc = (EditorDescriptor) reg.findEditor(innerEditor);
782
		if (innerDesc == null) {
783
			throw new PartInitException(NLS.bind(
784
					WorkbenchMessages.EditorManager_unknownEditorIDMessage,
785
					innerEditor));
786
		}
787
		InnerEditor innerRef = new InnerEditor(ref, innerEditorInput, innerDesc);
788
		// Instead of mimicking the behavior of the openMultiEditor method
789
		// precisely, we call getEditor(true) to create the editor part later
790
		// from the EditorReference, and return it to the MultiEditor instance
791
		// from there.
792
		//IEditorPart innerPart = innerRef.getEditor(true);
793
		//part.childAdded(innerPart);
794
		return innerRef;
795
	}
796
	
776
	/*
797
	/*
777
	 * Opens an editor part.
798
	 * Opens an editor part.
778
	 */
799
	 */
Lines 1427-1438 Link Here
1427
1448
1428
		private AbstractMultiEditor outerEditorPart;
1449
		private AbstractMultiEditor outerEditorPart;
1429
1450
1451
		private MultiEditorInnerPane innerPane;
1452
1430
		public InnerEditor(IEditorReference outerEditor,
1453
		public InnerEditor(IEditorReference outerEditor,
1431
				AbstractMultiEditor outerEditorPart, IEditorInput input,
1454
				IEditorInput input, EditorDescriptor desc) {
1432
				EditorDescriptor desc) {
1433
			super(EditorManager.this, input, desc);
1455
			super(EditorManager.this, input, desc);
1434
			this.outerEditor = outerEditor;
1456
			this.outerEditor = outerEditor;
1457
		}
1458
1459
		public void setOuterEditorPart(AbstractMultiEditor outerEditorPart) {
1435
			this.outerEditorPart = outerEditorPart;
1460
			this.outerEditorPart = outerEditorPart;
1461
			if (innerPane != null) {
1462
				innerPane.setMultiEditorCompatibilityMode(
1463
						outerEditorPart instanceof MultiEditor);
1464
			}
1436
		}
1465
		}
1437
1466
1438
		protected void doDisposePart() {
1467
		protected void doDisposePart() {
Lines 1442-1454 Link Here
1442
1471
1443
		protected PartPane createPane() {
1472
		protected PartPane createPane() {
1444
			// MultiEditor backwards compatibility
1473
			// MultiEditor backwards compatibility
1445
			return new MultiEditorInnerPane(
1474
			innerPane = new MultiEditorInnerPane(
1446
					(EditorPane) ((EditorReference) outerEditor).getPane(),
1475
					(EditorPane) ((EditorReference) outerEditor).getPane(),
1447
					this, page, editorPresentation.getActiveWorkbook(),
1476
					this, page, editorPresentation.getActiveWorkbook(),
1448
					outerEditorPart instanceof MultiEditor);
1477
					outerEditorPart instanceof MultiEditor);
1478
			return innerPane;
1449
		}
1479
		}
1450
1480
1451
		protected Composite getPaneControlContainer() {
1481
		protected Composite getPaneControlContainer() {
1482
			Assert.isNotNull(outerEditorPart);
1452
			// MultiEditor backwards compatibility
1483
			// MultiEditor backwards compatibility
1453
			if (outerEditorPart instanceof MultiEditor) {
1484
			if (outerEditorPart instanceof MultiEditor) {
1454
				return super.getPaneControlContainer();
1485
				return super.getPaneControlContainer();
Lines 1567-1573 Link Here
1567
				editorMem.putString(IWorkbenchConstants.TAG_WORKBOOK,
1598
				editorMem.putString(IWorkbenchConstants.TAG_WORKBOOK,
1568
						editorPane.getWorkbook().getID());
1599
						editorPane.getWorkbook().getID());
1569
1600
1570
				if (editor == page.getActivePart()) {
1601
				IWorkbenchPartReference activePartReference = page.getActivePartReference();
1602
				boolean innerEditorActive = activePartReference instanceof InnerEditor;
1603
				if ((!innerEditorActive && editor == page.getActivePart()) ||
1604
						(innerEditorActive && editor == ((InnerEditor) activePartReference).outerEditorPart)) {
1571
					editorMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
1605
					editorMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
1572
							"true"); //$NON-NLS-1$
1606
							"true"); //$NON-NLS-1$
1573
				}
1607
				}
(-)Eclipse UI/org/eclipse/ui/internal/MultiEditorInnerPane.java (-5 / +9 lines)
Lines 44-49 Link Here
44
        multiEditorCompatibilityMode = multiEditor;
44
        multiEditorCompatibilityMode = multiEditor;
45
    }
45
    }
46
46
47
	void setMultiEditorCompatibilityMode(boolean multiEditorCompatibilityMode) {
48
		this.multiEditorCompatibilityMode = multiEditorCompatibilityMode;
49
	}
50
47
	AbstractMultiEditor getMultiEditor() {
51
	AbstractMultiEditor getMultiEditor() {
48
		return (AbstractMultiEditor) parentPane.getPartReference()
52
		return (AbstractMultiEditor) parentPane.getPartReference()
49
                .getPart(true);
53
                .getPart(true);
Lines 56-66 Link Here
56
			control.addListener(SWT.Activate, new Listener() {
60
			control.addListener(SWT.Activate, new Listener() {
57
				public void handleEvent(Event event) {
61
				public void handleEvent(Event event) {
58
					if (event.type == SWT.Activate) {
62
					if (event.type == SWT.Activate) {
59
						IEditorPart part = (IEditorPart) MultiEditorInnerPane.this.getEditorReference().getPart(
63
						if (getInLayout()) {
60
								true);
64
							// The multi editor will set the focus to the new
61
						AbstractMultiEditor multiEditor = getMultiEditor();
65
							// active inner editor
62
						multiEditor.activateEditor(part);
66
							getMultiEditor().setFocus();
63
						multiEditor.setFocus();
67
						}
64
					}
68
					}
65
				}
69
				}
66
			});
70
			});
(-)Eclipse UI/org/eclipse/ui/internal/registry/EditorDescriptor.java (+15 lines)
Lines 89-94 Link Here
89
89
90
    private int openMode = 0;
90
    private int openMode = 0;
91
91
92
    private boolean splitEditor;
93
92
    private transient IConfigurationElement configurationElement;
94
    private transient IConfigurationElement configurationElement;
93
95
94
	/**
96
	/**
Lines 393-398 Link Here
393
        return getOpenMode() == OPEN_EXTERNAL;
395
        return getOpenMode() == OPEN_EXTERNAL;
394
    }
396
    }
395
397
398
    public boolean isSplitEditor() {
399
    	if (!splitEditor) {
400
    		splitEditor = new Boolean(this.configurationElement.getAttribute(IWorkbenchConstants.TAG_SPLIT_EDITOR)).booleanValue();
401
    	}
402
    	return splitEditor;
403
    }
404
396
    /**
405
    /**
397
     * Load the object properties from a memento.
406
     * Load the object properties from a memento.
398
     * 
407
     * 
Lines 406-411 Link Here
406
        fileName = memento.getString(IWorkbenchConstants.TAG_FILE);
415
        fileName = memento.getString(IWorkbenchConstants.TAG_FILE);
407
        id = Util.safeString(memento.getString(IWorkbenchConstants.TAG_ID));
416
        id = Util.safeString(memento.getString(IWorkbenchConstants.TAG_ID));
408
        pluginIdentifier = memento.getString(IWorkbenchConstants.TAG_PLUGIN);
417
        pluginIdentifier = memento.getString(IWorkbenchConstants.TAG_PLUGIN);
418
        splitEditor = new Boolean(memento.getString(IWorkbenchConstants.TAG_SPLIT_EDITOR)).booleanValue();
409
419
410
        Integer openModeInt = memento
420
        Integer openModeInt = memento
411
                .getInteger(IWorkbenchConstants.TAG_OPEN_MODE);
421
                .getInteger(IWorkbenchConstants.TAG_OPEN_MODE);
Lines 455-460 Link Here
455
        memento.putString(IWorkbenchConstants.TAG_FILE, getFileName());
465
        memento.putString(IWorkbenchConstants.TAG_FILE, getFileName());
456
        memento.putString(IWorkbenchConstants.TAG_ID, getId());
466
        memento.putString(IWorkbenchConstants.TAG_ID, getId());
457
        memento.putString(IWorkbenchConstants.TAG_PLUGIN, getPluginId());
467
        memento.putString(IWorkbenchConstants.TAG_PLUGIN, getPluginId());
468
        memento.putBoolean(IWorkbenchConstants.TAG_SPLIT_EDITOR, isSplitEditor());
458
469
459
        memento.putInteger(IWorkbenchConstants.TAG_OPEN_MODE, getOpenMode());
470
        memento.putInteger(IWorkbenchConstants.TAG_OPEN_MODE, getOpenMode());
460
        // legacy: handle the older attribute names, needed to allow reading of workspace by pre-3.0-RCP eclipses
471
        // legacy: handle the older attribute names, needed to allow reading of workspace by pre-3.0-RCP eclipses
Lines 568-573 Link Here
568
        openMode = mode;
579
        openMode = mode;
569
    }
580
    }
570
581
582
    /* package */void setSplitEditor(boolean newSplitEditor) {
583
    	splitEditor = newSplitEditor;
584
    }
585
571
    /**
586
    /**
572
     * The id of the plugin which contributed this editor, null for external editors.
587
     * The id of the plugin which contributed this editor, null for external editors.
573
     */
588
     */
(-)Eclipse UI/org/eclipse/ui/part/MultiEditor.java (-1 / +1 lines)
Lines 129-135 Link Here
129
     * @param part the nested editor
129
     * @param part the nested editor
130
     * @since 3.5
130
     * @since 3.5
131
     */
131
     */
132
    public void activateEditor(IEditorPart part) {
132
    protected void activateEditor(IEditorPart part) {
133
        IEditorPart oldEditor = getActiveEditor();
133
        IEditorPart oldEditor = getActiveEditor();
134
        super.activateEditor(part);
134
        super.activateEditor(part);
135
        updateGradient(oldEditor);
135
        updateGradient(oldEditor);
(-)Eclipse UI/org/eclipse/ui/part/AbstractMultiEditor.java (-26 / +110 lines)
Lines 12-17 Link Here
12
12
13
package org.eclipse.ui.part;
13
package org.eclipse.ui.part;
14
14
15
import java.util.ArrayList;
16
import java.util.Arrays;
17
15
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.swt.widgets.Composite;
19
import org.eclipse.swt.widgets.Composite;
17
import org.eclipse.ui.IEditorInput;
20
import org.eclipse.ui.IEditorInput;
Lines 22-27 Link Here
22
import org.eclipse.ui.IWorkbenchPart;
25
import org.eclipse.ui.IWorkbenchPart;
23
import org.eclipse.ui.IWorkbenchPartReference;
26
import org.eclipse.ui.IWorkbenchPartReference;
24
import org.eclipse.ui.PartInitException;
27
import org.eclipse.ui.PartInitException;
28
import org.eclipse.ui.internal.EditorReference;
25
import org.eclipse.ui.internal.EditorSite;
29
import org.eclipse.ui.internal.EditorSite;
26
import org.eclipse.ui.internal.PartService;
30
import org.eclipse.ui.internal.PartService;
27
import org.eclipse.ui.internal.PartSite;
31
import org.eclipse.ui.internal.PartSite;
Lines 38-44 Link Here
38
42
39
    private int activeEditorIndex;
43
    private int activeEditorIndex;
40
44
41
    private IEditorPart innerEditors[];
45
    private ArrayList/*<IEditorPart>*/ innerEditors;
42
46
43
	private IPartListener2 propagationListener;
47
	private IPartListener2 propagationListener;
44
48
Lines 53-60 Link Here
53
     * @see IEditorPart#doSave(IProgressMonitor)
57
     * @see IEditorPart#doSave(IProgressMonitor)
54
     */
58
     */
55
    public void doSave(IProgressMonitor monitor) {
59
    public void doSave(IProgressMonitor monitor) {
56
        for (int i = 0; i < innerEditors.length; i++) {
60
        for (int i = 0; i < innerEditors.size(); i++) {
57
            IEditorPart e = innerEditors[i];
61
            IEditorPart e = (IEditorPart) innerEditors.get(i);
58
            e.doSave(monitor);
62
            e.doSave(monitor);
59
        }
63
        }
60
    }
64
    }
Lines 94-101 Link Here
94
     * @see IEditorPart#isDirty()
98
     * @see IEditorPart#isDirty()
95
     */
99
     */
96
    public boolean isDirty() {
100
    public boolean isDirty() {
97
        for (int i = 0; i < innerEditors.length; i++) {
101
        for (int i = 0; i < innerEditors.size(); i++) {
98
            IEditorPart e = innerEditors[i];
102
            IEditorPart e = (IEditorPart) innerEditors.get(i);
99
            if (e.isDirty()) {
103
            if (e.isDirty()) {
100
				return true;
104
				return true;
101
			}
105
			}
Lines 114-120 Link Here
114
     * @see IWorkbenchPart#setFocus()
118
     * @see IWorkbenchPart#setFocus()
115
     */
119
     */
116
    public void setFocus() {
120
    public void setFocus() {
117
        innerEditors[activeEditorIndex].setFocus();
121
        getActiveEditor().setFocus();
122
    }
123
124
    public int getActiveEditorIndex() {
125
    	return activeEditorIndex;
118
    }
126
    }
119
127
120
    /**
128
    /**
Lines 122-128 Link Here
122
     * @return the active editor
130
     * @return the active editor
123
     */
131
     */
124
    public final IEditorPart getActiveEditor() {
132
    public final IEditorPart getActiveEditor() {
125
        return innerEditors[activeEditorIndex];
133
        return activeEditorIndex == -1 ? null : (IEditorPart) innerEditors.get(activeEditorIndex);
126
    }
134
    }
127
135
128
    /**
136
    /**
Lines 130-136 Link Here
130
     * @return the inner editors
138
     * @return the inner editors
131
     */
139
     */
132
    public final IEditorPart[] getInnerEditors() {
140
    public final IEditorPart[] getInnerEditors() {
133
        return innerEditors;
141
        return (IEditorPart[]) innerEditors.toArray(new IEditorPart[innerEditors.size()]);
142
    }
143
144
    /**
145
	 * @param editor  
146
     * @param editorInput 
147
     * @return the editor part of the newly created inner editor.
148
	 */
149
    public IEditorPart addEditor(String editor, IEditorInput editorInput) {
150
    	EditorReference ref = (EditorReference) ((EditorSite) getEditorSite()).getPartReference();
151
    	// This method will result in a call-back to the 
152
    	IEditorReference innerRef = ref.addMultiEditorChild(editor, editorInput);
153
    	IEditorPart innerPart = innerRef.getEditor(true);
154
    	innerEditors.add(innerPart);
155
    	innerEditorCreated(innerPart);
156
    	return innerPart;
157
    }
158
159
    /**
160
     * 
161
     * @param editor 
162
     */
163
    public void removeEditor(IEditorPart editor) {
164
    	int index = getIndex(editor);
165
    	if (index == -1) {
166
    		throw new IllegalArgumentException("Error: inner editor not found: " + editor); //$NON-NLS-1$
167
    	}
168
    	EditorReference ref = (EditorReference) ((EditorSite) getEditorSite()).getPartReference();
169
    	ref.removeMultiEditorChild(index);
170
    	innerEditors.remove(index);
171
    	if (activeEditorIndex >= index) {
172
    		if (activeEditorIndex >= innerEditors.size()) {
173
    			activeEditorIndex = innerEditors.size() - 1;
174
    		}
175
    		activeEditorChanged();
176
    	}
177
    	innerEditorRemoved(editor);
134
    }
178
    }
135
179
136
    /**
180
    /**
Lines 141-169 Link Here
141
     * @param children 
185
     * @param children 
142
     */
186
     */
143
    public final void setChildren(IEditorPart[] children) {
187
    public final void setChildren(IEditorPart[] children) {
144
        innerEditors = children;
188
        innerEditors = new ArrayList(Arrays.asList(children));
145
        activeEditorIndex = 0;
189
        activeEditorIndex = 0;
146
        innerEditorsCreated();
190
        innerEditorsCreated();
191
        for (int i = 0; i < children.length; i++) {
192
        	innerEditorCreated(children[i]);
193
        }
147
    }
194
    }
148
195
149
	/**
196
	/**
150
	 * Called as soon as the inner editors have been created and are available.
197
	 * Called upon editor initialization as soon as the inner editors are available.
151
	 */
198
	 */
152
	protected abstract void innerEditorsCreated();
199
	protected abstract void innerEditorsCreated();
153
200
154
    /**
201
	/**
202
	 * Called after an inner editor has been added, either dynamically via
203
	 * the addEditor method or upon this editor's creation (after
204
	 * innerEditorsCreated has been called).
205
	 * 
206
	 * @param innerEditor
207
	 *            the new inner editor
208
	 */
209
	protected void innerEditorCreated(IEditorPart innerEditor) {
210
		// Implemented optionally in subclasses
211
	}
212
213
	/**
214
	 * Called after an inner editor is removed dynamically via the removeEditor
215
	 * method. Note that this method is not called upon this editor's destruction.
216
	 * 
217
	 * @param innerEditor
218
	 *            the inner editor that is being removed
219
	 */
220
	protected void innerEditorRemoved(IEditorPart innerEditor) {
221
		// Implemented optionally in subclasses
222
	}
223
224
	/**
155
     * Activates the given nested editor.
225
     * Activates the given nested editor.
156
     * 
226
     * 
157
     * @param part the nested editor
227
     * @param part the nested editor
158
     * @since 3.0
228
     * @since 3.0
159
     */
229
     */
160
    public void activateEditor(IEditorPart part) {
230
    protected void activateEditor(IEditorPart part) {
161
        activeEditorIndex = getIndex(part);
231
        setActiveInnerEditor(part);
162
        IEditorPart e = getActiveEditor();
232
        activeEditorChanged();
163
        EditorSite innerSite = (EditorSite) e.getEditorSite();
164
        ((WorkbenchPage) innerSite.getPage()).requestActivation(e);
165
    }
233
    }
166
234
235
	/**
236
	 * Notified when the active inner editor has changed.
237
	 * @since 3.5
238
	 */
239
	protected void activeEditorChanged() {
240
		IEditorPart e = getActiveEditor();
241
        if (e != null) {
242
        	EditorSite innerSite = (EditorSite) e.getEditorSite();
243
        	((WorkbenchPage) innerSite.getPage()).requestActivation(e);
244
        }
245
	}
246
247
	/**
248
	 * Updates the active inner editor index.
249
	 * @param part
250
	 * @since 3.5
251
	 */
252
    public void setActiveInnerEditor(IEditorPart part) {
253
		activeEditorIndex = getIndex(part);
254
	}
255
167
    /**
256
    /**
168
     * Returns the index of the given nested editor.
257
     * Returns the index of the given nested editor.
169
     * 
258
     * 
Lines 171-182 Link Here
171
     * @since 3.0
260
     * @since 3.0
172
     */
261
     */
173
    protected int getIndex(IEditorPart editor) {
262
    protected int getIndex(IEditorPart editor) {
174
        for (int i = 0; i < innerEditors.length; i++) {
263
    	return innerEditors.indexOf(editor);
175
            if (innerEditors[i] == editor) {
176
				return i;
177
			}
178
        }
179
        return -1;
180
    }
264
    }
181
265
182
    /**
266
    /**
Lines 197-204 Link Here
197
				if (part == AbstractMultiEditor.this && innerEditors != null) {
281
				if (part == AbstractMultiEditor.this && innerEditors != null) {
198
					PartService partService = ((WorkbenchPage) getSite()
282
					PartService partService = ((WorkbenchPage) getSite()
199
							.getPage()).getPartService();
283
							.getPage()).getPartService();
200
					for (int i = 0; i < innerEditors.length; i++) {
284
					for (int i = 0; i < innerEditors.size(); i++) {
201
						IEditorPart editor = innerEditors[i];
285
						IEditorPart editor = (IEditorPart) innerEditors.get(i);
202
						IWorkbenchPartReference innerRef = ((PartSite) editor
286
						IWorkbenchPartReference innerRef = ((PartSite) editor
203
								.getSite()).getPartReference();
287
								.getSite()).getPartReference();
204
						partService.firePartClosed(innerRef);
288
						partService.firePartClosed(innerRef);
Lines 214-221 Link Here
214
				if (part == AbstractMultiEditor.this && innerEditors != null) {
298
				if (part == AbstractMultiEditor.this && innerEditors != null) {
215
					PartService partService = ((WorkbenchPage) getSite()
299
					PartService partService = ((WorkbenchPage) getSite()
216
							.getPage()).getPartService();
300
							.getPage()).getPartService();
217
					for (int i = 0; i < innerEditors.length; i++) {
301
					for (int i = 0; i < innerEditors.size(); i++) {
218
						IEditorPart editor = innerEditors[i];
302
						IEditorPart editor = (IEditorPart) innerEditors.get(i);
219
						IWorkbenchPartReference innerRef = ((PartSite) editor
303
						IWorkbenchPartReference innerRef = ((PartSite) editor
220
								.getSite()).getPartReference();
304
								.getSite()).getPartReference();
221
						partService.firePartOpened(innerRef);
305
						partService.firePartOpened(innerRef);
(-)plugin.xml (+19 lines)
Lines 8-11 Link Here
8
            class="org.eclipse.ui.internal.WorkbenchPreferenceInitializer"/>
8
            class="org.eclipse.ui.internal.WorkbenchPreferenceInitializer"/>
9
   </extension>
9
   </extension>
10
10
11
   <extension
12
         point="org.eclipse.ui.editors">
13
      <editor
14
            class="org.eclipse.ui.internal.spliteditor.SplitMultiEditor"
15
            default="false"
16
            id="org.eclipse.ui.editors.SplitMultiEditor"
17
            matchingStrategy="org.eclipse.ui.internal.spliteditor.SplitMultiEditorMatchingStrategy"
18
            name="[TODO: SPECIAL SPLIT EDITOR NAME SHOULD BE HIDDEN]">
19
      </editor>
20
   </extension>
21
22
   <extension
23
         point="org.eclipse.ui.elementFactories">
24
      <factory
25
            class="org.eclipse.ui.internal.spliteditor.SplitMultiEditorInputFactory"
26
            id="org.eclipse.ui.workbench.spliteditor.SplitMultiEditorInputFactory">
27
      </factory>
28
   </extension>
29
11
</plugin>
30
</plugin>
(-)Eclipse (+59 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.ui.internal.spliteditor;
13
14
import java.util.List;
15
16
import org.eclipse.ui.IEditorDescriptor;
17
import org.eclipse.ui.IEditorInput;
18
import org.eclipse.ui.IEditorMatchingStrategy;
19
import org.eclipse.ui.IEditorReference;
20
import org.eclipse.ui.PartInitException;
21
import org.eclipse.ui.internal.EditorReference;
22
import org.eclipse.ui.internal.WorkbenchPlugin;
23
24
/**
25
 * @since 3.4
26
 *
27
 */
28
public class SplitMultiEditorMatchingStrategy implements
29
		IEditorMatchingStrategy {
30
31
	/* (non-Javadoc)
32
	 * @see org.eclipse.ui.IEditorMatchingStrategy#matches(org.eclipse.ui.IEditorReference, org.eclipse.ui.IEditorInput)
33
	 */
34
	public boolean matches(IEditorReference editorRef, IEditorInput input) {
35
		try {
36
			SplitMultiEditorInput editorInput = (SplitMultiEditorInput) editorRef.getEditorInput();
37
			if (editorInput.equals(input)) {
38
				return true;
39
			}
40
			List innerEditorRefs = ((EditorReference) editorRef).getMultiEditorChildren();
41
			if (innerEditorRefs != null) {
42
				EditorReference innerEditorRef = (EditorReference) innerEditorRefs.get(0);
43
				IEditorDescriptor desc = innerEditorRef.getDescriptor();
44
				if (desc != null) {
45
					IEditorMatchingStrategy matchingStrategy = desc
46
							.getEditorMatchingStrategy();
47
					if (matchingStrategy != null) {
48
						return matchingStrategy.matches(innerEditorRef, input);
49
					}
50
				}
51
			}
52
			return editorInput.getEditorInput().equals(input);
53
		} catch (PartInitException e) {
54
			WorkbenchPlugin.log(e);
55
			return false;
56
		}
57
	}
58
59
}
(-)Eclipse (+57 lines)
Added Link Here
1
package org.eclipse.ui.internal.spliteditor;
2
3
import org.eclipse.core.runtime.IAdaptable;
4
import org.eclipse.ui.IEditorInput;
5
import org.eclipse.ui.IElementFactory;
6
import org.eclipse.ui.IMemento;
7
import org.eclipse.ui.PlatformUI;
8
9
public class SplitMultiEditorInputFactory implements IElementFactory {
10
11
	/**
12
	 * Default constructor.
13
	 */
14
	public SplitMultiEditorInputFactory() {
15
		super();
16
	}
17
18
	/**
19
	 *
20
	 * @param memento
21
	 */
22
	public IAdaptable createElement(IMemento memento) {
23
		String editorId = memento.getString(SplitMultiEditorInput.INNER_EDITOR_ID);
24
		String factoryId = memento.getString(SplitMultiEditorInput.INNER_INPUT_FACTORY_ID);
25
26
        if (factoryId == null) {
27
            throw new RuntimeException("No factory id."); //$NON-NLS-1$
28
        }
29
        IElementFactory factory = PlatformUI.getWorkbench().getElementFactory(factoryId);
30
        if (factory == null) {
31
        	throw new RuntimeException("Bad element factory."); //$NON-NLS-1$
32
        }
33
34
        // Get the input element.
35
        IMemento inputMem = memento.getChild(SplitMultiEditorInput.INNER_INPUT);
36
        if (inputMem == null) {
37
        	throw new RuntimeException("Bad inner input child."); //$NON-NLS-1$
38
        }
39
        IAdaptable inputObject = factory.createElement(inputMem);
40
        if (inputObject == null) {
41
        	throw new RuntimeException("Create element returned null."); //$NON-NLS-1$
42
        }
43
        if (!(inputObject instanceof IEditorInput)) {
44
            throw new RuntimeException("Input not instance of IEditorInput."); //$NON-NLS-1$
45
        }
46
        IEditorInput innerInput = (IEditorInput) inputObject;
47
        SplitMultiEditorInput input = new SplitMultiEditorInput(innerInput, editorId);
48
49
        Integer innerEditorCount = memento.getInteger(SplitMultiEditorInput.INNER_EDITOR_COUNT);
50
        if (innerEditorCount != null) {
51
        	input.setInnerEditorCount(innerEditorCount.intValue());
52
        }
53
54
		return input;
55
	}
56
57
}
(-)Eclipse (+9 lines)
Added Link Here
1
package org.eclipse.ui.internal.spliteditor;
2
3
public interface SplittableContainerClient {
4
5
	public void showSlave(SplittableContainer container);
6
7
	public void hideSlave(SplittableContainer container);
8
9
}
(-)Eclipse (+151 lines)
Added Link Here
1
package org.eclipse.ui.internal.spliteditor;
2
3
import org.eclipse.swt.SWT;
4
import org.eclipse.swt.graphics.Point;
5
import org.eclipse.swt.graphics.Rectangle;
6
import org.eclipse.swt.layout.FillLayout;
7
import org.eclipse.swt.widgets.Composite;
8
import org.eclipse.swt.widgets.Event;
9
import org.eclipse.swt.widgets.Layout;
10
import org.eclipse.swt.widgets.Listener;
11
import org.eclipse.swt.widgets.Sash;
12
13
14
public class SplittableContainer extends Composite {
15
16
	final SplittableContainerClient client;
17
18
	final Sash sash;
19
20
	final Composite master;
21
22
	final Composite slave;
23
24
	int splitRatio;
25
26
	int splitTotal;
27
28
	int sashWidth;
29
30
	int dragMinimum;
31
32
	public SplittableContainer(Composite parent, SplittableContainerClient client, int style) {
33
		super(parent, style);
34
		super.setLayout(new SplitLayout());
35
36
		this.sashWidth = 4;
37
38
		this.dragMinimum = 10;
39
40
		this.client = client;
41
42
		master = new Composite(this, SWT.NONE);
43
		master.setLayout(new FillLayout());
44
45
		sash = new Sash(this, SWT.HORIZONTAL);
46
		sash.setSize(5, 5);
47
		sash.addListener (SWT.Selection, new SashSelectionListener());
48
49
		slave = new Composite(this, SWT.NONE);
50
		slave.setLayout(new FillLayout());
51
		slave.setVisible(false);
52
	}
53
54
	public void setLayout(Layout layout) {
55
		checkWidget();
56
	}
57
58
	public int getSashWidth() {
59
		return sashWidth;
60
	}
61
62
	public void setSashWidth(int sashWidth) {
63
		if (sashWidth == this.sashWidth) return;
64
		this.sashWidth = sashWidth;
65
		layout(false);
66
	}
67
68
	public int getDragMinimum() {
69
		return dragMinimum;
70
	}
71
72
	public void setDragMinimum(int dragMinimum) {
73
		this.dragMinimum = dragMinimum;
74
	}
75
76
	public Composite getMaster() {
77
		return master;
78
	}
79
80
	public Composite getSlave() {
81
		return slave;
82
	}
83
84
	public int getSplitRatio() {
85
		return splitRatio;
86
	}
87
88
	public void setSplitRatio(int splitRatio) {
89
		if (splitRatio != this.splitRatio) {
90
			this.splitRatio = splitRatio;
91
			slave.setVisible(splitRatio > 0);
92
		}
93
	}
94
95
	private final class SashSelectionListener implements Listener {
96
		public void handleEvent (Event e) {
97
			if ((e.detail & SWT.DRAG) == 0) {
98
				splitRatio = e.y;
99
				splitTotal = SplittableContainer.this.getSize().y - sashWidth*2;
100
101
				if (splitRatio < dragMinimum) {
102
					splitRatio = 0;
103
					if (slave.isVisible()) {
104
						client.hideSlave(SplittableContainer.this);
105
						slave.setVisible(false);
106
					}
107
				} else {
108
					if (!slave.isVisible()) {
109
						client.showSlave(SplittableContainer.this);
110
						slave.setVisible(true);
111
					}
112
				}
113
114
				SplittableContainer.this.layout();
115
			}
116
		}
117
	}
118
119
	private final class SplitLayout extends Layout {
120
121
		protected Point computeSize(Composite composite, int hint, int hint2,
122
				boolean flushCache) {
123
			return null;
124
		}
125
126
		protected void layout(Composite composite, boolean flushCache) {
127
			Rectangle area = composite.getClientArea();
128
			if (area.width <= 1 || area.height <= 1) return;
129
130
			// Calculate split position
131
			if (splitTotal == 0) {
132
				splitTotal = area.height;
133
			}
134
			int sashPos = (splitRatio * (area.height - sashWidth*2)) / splitTotal;
135
136
			// Layout slave
137
			if (slave.isVisible()) {
138
				slave.setBounds(area.x, area.y + sashWidth, area.width, sashPos - sashWidth);
139
			}
140
141
			// Layout sash
142
			sash.setBounds(area.x, area.y + sashPos, area.width, sashWidth);
143
			int sashBottom = sashPos + sashWidth;
144
145
			// Layout master
146
			master.setBounds(area.x, area.y + sashBottom, area.width, area.height - sashBottom);
147
		}
148
149
	}
150
151
}
(-)Eclipse (+174 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.internal.spliteditor;
12
13
import java.util.Arrays;
14
15
import org.eclipse.core.runtime.Assert;
16
import org.eclipse.jface.resource.ImageDescriptor;
17
import org.eclipse.ui.IEditorInput;
18
import org.eclipse.ui.IMemento;
19
import org.eclipse.ui.IPersistableElement;
20
import org.eclipse.ui.part.MultiEditorInput;
21
22
/**
23
 * Implements a SplitMultiEditor input.
24
 */
25
public class SplitMultiEditorInput extends MultiEditorInput {
26
27
	protected static final String FACTORY_ID = "org.eclipse.ui.workbench.spliteditor.SplitMultiEditorInputFactory"; //$NON-NLS-1$
28
29
	protected static final String INNER_EDITOR_ID = "editorId"; //$NON-NLS-1$
30
31
	protected static final String INNER_EDITOR_COUNT = "editorCount"; //$NON-NLS-1$
32
33
	protected static final String INNER_INPUT_FACTORY_ID = "factoryId"; //$NON-NLS-1$
34
35
	protected static final String INNER_INPUT = "input"; //$NON-NLS-1$
36
37
	private final String editorId;
38
39
	private IEditorInput input;
40
41
	private int innerEditorCount;
42
43
	public SplitMultiEditorInput(IEditorInput input, String editorId) {
44
		super(new String[0], new IEditorInput[0]);
45
		Assert.isNotNull(editorId);
46
		Assert.isNotNull(input);
47
		this.editorId = editorId;
48
		this.input = input;
49
		this.innerEditorCount = 1;
50
	}
51
52
	int getInnerEditorCount() {
53
		return innerEditorCount;
54
	}
55
56
	void setInnerEditorCount(int innerEditorCount) {
57
		this.innerEditorCount = innerEditorCount;
58
	}
59
60
	/**
61
	 *
62
	 * @return the inner editors' id
63
	 */
64
	public String getEditorId() {
65
		return editorId;
66
	}
67
68
	/**
69
	 *
70
	 * @return the inner editors' input
71
	 */
72
	public IEditorInput getEditorInput() {
73
		return input;
74
	}
75
76
	public void setEditorInput(IEditorInput input) {
77
		this.input = input;
78
	}
79
80
	public IEditorInput[] getInput() {
81
		IEditorInput[] editorInputs = new IEditorInput[innerEditorCount];
82
		Arrays.fill(editorInputs, input);
83
		return editorInputs;
84
	}
85
86
	public String[] getEditors() {
87
		String[] editors = new String[innerEditorCount];
88
		Arrays.fill(editors, editorId);
89
		return editors;
90
	}
91
92
	/*
93
	 * @see IEditorInput#exists()
94
	 */
95
	public boolean exists() {
96
		return true;
97
	}
98
99
	/*
100
	 * @see IEditorInput#getImageDescriptor()
101
	 */
102
	public ImageDescriptor getImageDescriptor() {
103
		return input.getImageDescriptor();
104
	}
105
106
	/*
107
	 * @see IEditorInput#getName()
108
	 */
109
	public String getName() {
110
		return input.getName();
111
	}
112
113
	/*
114
	 * @see IEditorInput#getPersistable()
115
	 */
116
	public IPersistableElement getPersistable() {
117
		if (input.getPersistable() == null) {
118
			return null;
119
		}
120
121
		return new IPersistableElement() {
122
            public String getFactoryId() {
123
                return FACTORY_ID;
124
            }
125
126
            public void saveState(IMemento memento) {
127
                memento.putString(INNER_EDITOR_ID, editorId);
128
                memento.putInteger(INNER_EDITOR_COUNT, innerEditorCount);
129
                memento.putString(INNER_INPUT_FACTORY_ID, input.getPersistable().getFactoryId());
130
                IMemento inner = memento.createChild(INNER_INPUT);
131
                input.getPersistable().saveState(inner);
132
            }
133
        };
134
	}
135
136
	/*
137
	 * @see IEditorInput#getToolTipText()
138
	 */
139
	public String getToolTipText() {
140
		return input.getToolTipText();
141
	}
142
143
	/*
144
	 * @see IAdaptable#getAdapter(Class)
145
	 */
146
	public Object getAdapter(Class adapter) {
147
		return null;
148
	}
149
150
	/* (non-Javadoc)
151
	 * @see java.lang.Object#equals(java.lang.Object)
152
	 */
153
	public boolean equals(Object obj) {
154
		if (this == obj) {
155
			return true;
156
		}
157
		if (!(obj instanceof SplitMultiEditorInput)) {
158
			return false;
159
		}
160
		SplitMultiEditorInput other = (SplitMultiEditorInput) obj;
161
		return this.editorId.equals(other.editorId) && this.input.equals(other.input);
162
	}
163
164
	/* (non-Javadoc)
165
	 * @see java.lang.Object#hashCode()
166
	 */
167
	public int hashCode() {
168
		int hash = 0;
169
		hash = hash * 37 + editorId.hashCode();
170
		hash = hash * 37 + input.hashCode();
171
		return hash;
172
	}
173
174
}
(-)Eclipse (+202 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.internal.spliteditor;
12
13
import java.util.Arrays;
14
import java.util.HashSet;
15
import java.util.Set;
16
17
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.swt.SWT;
19
import org.eclipse.swt.widgets.Composite;
20
import org.eclipse.ui.IEditorInput;
21
import org.eclipse.ui.IEditorPart;
22
import org.eclipse.ui.IEditorReference;
23
import org.eclipse.ui.IMemento;
24
import org.eclipse.ui.IPersistableEditor;
25
import org.eclipse.ui.IPropertyListener;
26
import org.eclipse.ui.IReusableEditor;
27
import org.eclipse.ui.ISaveablesSource;
28
import org.eclipse.ui.IWorkbenchPart2;
29
import org.eclipse.ui.IWorkbenchPartConstants;
30
import org.eclipse.ui.Saveable;
31
import org.eclipse.ui.internal.DefaultSaveable;
32
import org.eclipse.ui.part.AbstractMultiEditor;
33
34
/**
35
 * Implementation of a SplitMultiEditor. This is the testable version copied from bug
36
 * 42641.
37
 */
38
public class SplitMultiEditor extends AbstractMultiEditor implements ISaveablesSource, IPersistableEditor {
39
40
	private static final String KEY_ACTIVE_EDITOR = "activeEditorIndex"; //$NON-NLS-1$
41
42
	private static final String KEY_SPLIT_RATIO = "splitRatio"; //$NON-NLS-1$
43
44
	private final class SplitterClient implements SplittableContainerClient {
45
46
		public void hideSlave(SplittableContainer splittable) {
47
			removeEditor(slaveEditor);
48
			slaveEditor = null;
49
			((SplitMultiEditorInput) getEditorInput()).setInnerEditorCount(1);
50
		}
51
52
		public void showSlave(SplittableContainer splittable) {
53
			if (slaveEditor == null) {
54
				SplitMultiEditorInput input = (SplitMultiEditorInput) getEditorInput();
55
				slaveEditor = addEditor(input.getEditorId(), input.getEditorInput());
56
				((SplitMultiEditorInput) getEditorInput()).setInnerEditorCount(2);
57
			}
58
		}
59
60
	}
61
62
	private final IPropertyListener forwardingPropertyListener = new IPropertyListener() {
63
		boolean updating = false;
64
		public void propertyChanged(Object source, int propId) {
65
			if (!updating) {
66
				IEditorPart sourcePart = (IEditorPart) source;
67
				if (propId == IWorkbenchPartConstants.PROP_INPUT) {
68
					// Handle input change (Save as action)
69
					IEditorInput newInput = sourcePart.getEditorInput();
70
					updating = true;
71
					try {
72
						IEditorPart[] editors = getInnerEditors();
73
						for (int i = 0; i < editors.length; i++) {
74
							IEditorPart editor = editors[i];
75
							if (editor != source) {
76
								if (editor instanceof IReusableEditor) {
77
									((IReusableEditor) editor).setInput(newInput);
78
								}
79
							}
80
						}
81
					} finally {
82
						updating = false;
83
					}
84
					((SplitMultiEditorInput) getEditorInput()).setEditorInput(newInput);
85
				} else if (propId == IWorkbenchPartConstants.PROP_PART_NAME) {
86
					// Handle title changes (save as, rename)
87
					setPartName(((IWorkbenchPart2) sourcePart).getPartName());
88
				} else if (propId == IWorkbenchPartConstants.PROP_TITLE) {
89
					//setTitle(sourcePart.getTitle());
90
					setTitleImage(sourcePart.getTitleImage());
91
					setTitleToolTip(sourcePart.getTitleToolTip());
92
				} else if (propId == IWorkbenchPartConstants.PROP_CONTENT_DESCRIPTION) {
93
					setContentDescription(((IWorkbenchPart2) sourcePart).getContentDescription());
94
				}
95
				firePropertyChange(propId);
96
			}
97
		}
98
	};
99
100
	private SplittableContainer container;
101
102
	private int restoredActiveEditorIndex;
103
104
	private int restoredSplitRatio;
105
106
	private IEditorPart slaveEditor;
107
108
	public SplitMultiEditor() {
109
		super();
110
	}
111
112
	/*
113
	 * @see IWorkbenchPart#createPartControl(Composite)
114
	 */
115
	public void createPartControl(Composite parent) {
116
		container = new SplittableContainer(parent, new SplitterClient(), SWT.NONE);
117
		container.setSashWidth(4);
118
		container.setSplitRatio(restoredSplitRatio);
119
	}
120
121
	public void doSave(IProgressMonitor monitor) {
122
		getActiveEditor().doSave(monitor);
123
	}
124
125
	public boolean isDirty() {
126
    	Saveable[] saveables = getSaveables();
127
    	for (int i = 0; i < saveables.length; i++) {
128
    		if (saveables[i].isDirty()) {
129
    			return true;
130
    		}
131
		}
132
    	return false;
133
	}
134
135
	public boolean isSaveAsAllowed() {
136
		IEditorPart activeEditor = getActiveEditor();
137
		return (activeEditor instanceof IReusableEditor) && activeEditor.isSaveAsAllowed();
138
	}
139
140
	public Composite getInnerEditorContainer(IEditorReference innerEditor) {
141
		if (container.getMaster().getChildren().length == 0) {
142
			return container.getMaster();
143
		}
144
		return container.getSlave();
145
	}
146
147
	protected void innerEditorsCreated() {
148
		setTitleImage(getActiveEditor().getTitleImage());
149
		IEditorPart[] children = getInnerEditors();
150
        if (children.length == 2) {
151
        	slaveEditor = children[1];
152
        	if (container.getSplitRatio() == 0) {
153
        		// Split ratio was not restored from state for some reason (such as editor creation exception).
154
        		container.setSplitRatio(container.getSize().y / 2);
155
        	}
156
        }
157
        setActiveInnerEditor(children[restoredActiveEditorIndex]);
158
	}
159
160
	protected void innerEditorCreated(IEditorPart innerEditor) {
161
		innerEditor.addPropertyListener(forwardingPropertyListener);
162
	}
163
164
	public Saveable[] getActiveSaveables() {
165
		IEditorPart activeEditor = getActiveEditor();
166
		if (activeEditor instanceof ISaveablesSource) {
167
			return ((ISaveablesSource) activeEditor).getActiveSaveables();
168
		}
169
		return new Saveable[] { new DefaultSaveable(activeEditor) };
170
	}
171
172
	public Saveable[] getSaveables() {
173
		Set result = new HashSet();
174
		IEditorPart[] innerEditors = getInnerEditors();
175
		for (int i = 0; i < innerEditors.length; i++) {
176
			IEditorPart editor = innerEditors[i];
177
			if (editor instanceof ISaveablesSource) {
178
				result.addAll(Arrays.asList(((ISaveablesSource) editor).getSaveables()));
179
			} else {
180
				result.add(new DefaultSaveable(editor));
181
			}
182
		}
183
		return (Saveable[]) result.toArray(new Saveable[result.size()]);
184
	}
185
186
	public void saveState(IMemento memento) {
187
		memento.putInteger(KEY_ACTIVE_EDITOR, getIndex(getActiveEditor()));
188
		memento.putInteger(KEY_SPLIT_RATIO, container.getSplitRatio());
189
	}
190
191
	public void restoreState(IMemento memento) {
192
		Integer editorIndex = memento.getInteger(KEY_ACTIVE_EDITOR);
193
		if (editorIndex != null) {
194
			restoredActiveEditorIndex = editorIndex.intValue();
195
		}
196
		Integer splitRatio = memento.getInteger(KEY_SPLIT_RATIO);
197
		if (splitRatio != null) {
198
			restoredSplitRatio = splitRatio.intValue();
199
		}
200
	}
201
202
}

Return to bug 244364