001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal;
011:
012: import org.eclipse.core.runtime.IAdaptable;
013: import org.eclipse.core.runtime.IPath;
014: import org.eclipse.core.runtime.IStatus;
015: import org.eclipse.core.runtime.Path;
016: import org.eclipse.jface.preference.IPreferenceStore;
017: import org.eclipse.jface.resource.ImageDescriptor;
018: import org.eclipse.osgi.util.NLS;
019: import org.eclipse.swt.SWT;
020: import org.eclipse.swt.graphics.Point;
021: import org.eclipse.swt.layout.FillLayout;
022: import org.eclipse.swt.widgets.Composite;
023: import org.eclipse.ui.IEditorInput;
024: import org.eclipse.ui.IEditorPart;
025: import org.eclipse.ui.IPersistableEditor;
026: import org.eclipse.ui.IEditorReference;
027: import org.eclipse.ui.IEditorRegistry;
028: import org.eclipse.ui.IElementFactory;
029: import org.eclipse.ui.IMemento;
030: import org.eclipse.ui.IPersistableElement;
031: import org.eclipse.ui.IReusableEditor;
032: import org.eclipse.ui.IWorkbenchPage;
033: import org.eclipse.ui.IWorkbenchPart;
034: import org.eclipse.ui.IWorkbenchPart2;
035: import org.eclipse.ui.IWorkbenchPart3;
036: import org.eclipse.ui.IWorkbenchPartConstants;
037: import org.eclipse.ui.PartInitException;
038: import org.eclipse.ui.PlatformUI;
039: import org.eclipse.ui.internal.editorsupport.ComponentSupport;
040: import org.eclipse.ui.internal.misc.StatusUtil;
041: import org.eclipse.ui.internal.misc.UIStats;
042: import org.eclipse.ui.internal.part.NullEditorInput;
043: import org.eclipse.ui.internal.registry.EditorDescriptor;
044: import org.eclipse.ui.internal.registry.EditorRegistry;
045: import org.eclipse.ui.internal.tweaklets.TabBehaviour;
046: import org.eclipse.ui.internal.tweaklets.Tweaklets;
047: import org.eclipse.ui.internal.util.Util;
048: import org.eclipse.ui.part.IWorkbenchPartOrientation;
049: import org.eclipse.ui.part.MultiEditor;
050: import org.eclipse.ui.part.MultiEditorInput;
051: import org.eclipse.ui.statushandlers.StatusManager;
052:
053: public class EditorReference extends WorkbenchPartReference implements
054: IEditorReference {
055:
056: /**
057: *
058: */
059: private final EditorManager manager;
060:
061: private IMemento editorMemento;
062:
063: private IMemento editorState = null;
064:
065: /**
066: * Flag that lets us detect malfunctioning editors that don't fire PROP_INPUT events.
067: * It is never needed for a correctly-functioning
068: */
069: private boolean expectingInputChange = false;
070:
071: /**
072: * Flag that determines whether we've already reported that this editor is malfunctioning.
073: * This prevents us from spamming the event log if we repeatedly detect the same error in
074: * a particular editor. If we ever detect an editor is violating its public contract in
075: * a way we can recover from (such as a missing property change event), we report the error
076: * once and then silently ignore errors from the same editor.
077: */
078: private boolean reportedMalfunctioningEditor = false;
079:
080: /**
081: * User-readable name of the editor's input
082: */
083: String name;
084:
085: String factoryId;
086:
087: IEditorInput restoredInput;
088:
089: /**
090: * If the reference is instantiated as a MultiEditor, we need to dispose the
091: * inner references correctly.
092: */
093: private IEditorReference[] multiEditorChildren = null;
094:
095: /**
096: * @param manager
097: * The editor manager for this reference
098: * @param input
099: * our input
100: * @param desc
101: * the descriptor from the declaration
102: */
103: public EditorReference(EditorManager manager, IEditorInput input,
104: EditorDescriptor desc) {
105: this (manager, input, desc, null);
106: }
107:
108: /**
109: * @param manager
110: * The editor manager for this reference
111: * @param input
112: * our input
113: * @param desc
114: * the descriptor from the declaration
115: * @param editorState
116: * propogate state from another editor. Can be <code>null</code>.
117: */
118: public EditorReference(EditorManager manager, IEditorInput input,
119: EditorDescriptor desc, IMemento editorState) {
120: this .manager = manager;
121: initListenersAndHandlers();
122: restoredInput = input;
123: this .editorState = editorState;
124: init(desc.getId(), desc.getLabel(),
125: "", desc.getImageDescriptor(), desc.getLabel(), ""); //$NON-NLS-1$//$NON-NLS-2$
126: }
127:
128: /**
129: * Constructs a new editor reference for use by editors being restored from
130: * a memento.
131: */
132: EditorReference(EditorManager manager, IMemento memento) {
133: this .manager = manager;
134: initListenersAndHandlers();
135: this .editorMemento = memento;
136: if (EditorManager.useIPersistableEditor()) {
137: editorState = editorMemento
138: .getChild(IWorkbenchConstants.TAG_EDITOR_STATE);
139: } else {
140: editorState = null;
141: }
142: String id = memento.getString(IWorkbenchConstants.TAG_ID);
143: String title = memento.getString(IWorkbenchConstants.TAG_TITLE);
144: String tooltip = Util.safeString(memento
145: .getString(IWorkbenchConstants.TAG_TOOLTIP));
146: String partName = memento
147: .getString(IWorkbenchConstants.TAG_PART_NAME);
148:
149: IMemento propBag = memento
150: .getChild(IWorkbenchConstants.TAG_PROPERTIES);
151: if (propBag != null) {
152: IMemento[] props = propBag
153: .getChildren(IWorkbenchConstants.TAG_PROPERTY);
154: for (int i = 0; i < props.length; i++) {
155: propertyCache.put(props[i].getID(), props[i]
156: .getTextData());
157: }
158: }
159:
160: // For compatibility set the part name to the title if not found
161: if (partName == null) {
162: partName = title;
163: }
164:
165: // Get the editor descriptor.
166: EditorDescriptor desc = null;
167: if (id != null) {
168: desc = getDescriptor(id);
169: }
170: // desc may be null if id is null or desc is not found, but findImage below handles this
171: String location = memento
172: .getString(IWorkbenchConstants.TAG_PATH);
173: IPath path = location == null ? null : new Path(location);
174: ImageDescriptor iDesc = this .manager.findImage(desc, path);
175:
176: this .name = memento.getString(IWorkbenchConstants.TAG_NAME);
177: if (this .name == null) {
178: this .name = title;
179: }
180: setPinned("true".equals(memento.getString(IWorkbenchConstants.TAG_PINNED))); //$NON-NLS-1$
181:
182: IMemento inputMem = memento
183: .getChild(IWorkbenchConstants.TAG_INPUT);
184: if (inputMem != null) {
185: this .factoryId = inputMem
186: .getString(IWorkbenchConstants.TAG_FACTORY_ID);
187: }
188:
189: init(id, title, tooltip, iDesc, partName, ""); //$NON-NLS-1$
190: }
191:
192: public EditorDescriptor getDescriptor() {
193: return getDescriptor(getId());
194: }
195:
196: /**
197: * @since 3.1
198: *
199: * @param id
200: * @return
201: */
202: private EditorDescriptor getDescriptor(String id) {
203: EditorDescriptor desc;
204: IEditorRegistry reg = WorkbenchPlugin.getDefault()
205: .getEditorRegistry();
206: desc = (EditorDescriptor) reg.findEditor(id);
207: return desc;
208: }
209:
210: /**
211: * Initializes the necessary editor listeners and handlers
212: */
213: private void initListenersAndHandlers() {
214: // Create a property change listener to track the "close editors automatically"
215: // preference and show/remove the pin icon on editors
216: // Only 1 listener will be created in the EditorManager when necessary
217: this .manager.checkCreateEditorPropListener();
218: // Create a keyboard shortcut handler for pinning editors
219: // Only 1 handler will be created in the EditorManager when necessary
220: this .manager.checkCreatePinEditorShortcutKeyHandler();
221: }
222:
223: protected PartPane createPane() {
224: return new EditorPane(this , this .manager.page,
225: this .manager.editorPresentation.getActiveWorkbook());
226: }
227:
228: /**
229: * This method is called when there should be a change in the editor pin
230: * status (added or removed) so that it will ask its presentable part
231: * to fire a PROP_TITLE event in order for the presentation to request
232: * the new icon for this editor
233: */
234: public void pinStatusUpdated() {
235: firePropertyChange(IWorkbenchPart.PROP_TITLE);
236: }
237:
238: public String getFactoryId() {
239: IEditorPart editor = getEditor(false);
240: if (editor != null) {
241: IPersistableElement persistable = editor.getEditorInput()
242: .getPersistable();
243: if (persistable != null) {
244: return persistable.getFactoryId();
245: }
246: return null;
247: }
248: return factoryId;
249: }
250:
251: protected String computePartName() {
252: if (part instanceof IWorkbenchPart2) {
253: return super .computePartName();
254: } else {
255: return getRawTitle();
256: }
257: }
258:
259: public String getName() {
260: if (part != null) {
261: return getEditor(false).getEditorInput().getName();
262: }
263: return name;
264: }
265:
266: public IEditorPart getEditor(boolean restore) {
267: return (IEditorPart) getPart(restore);
268: }
269:
270: protected void releaseReferences() {
271: super .releaseReferences();
272: editorMemento = null;
273: editorState = null;
274: name = null;
275: factoryId = null;
276: restoredInput = null;
277: }
278:
279: void setName(String name) {
280: this .name = name;
281: }
282:
283: public IMemento getMemento() {
284: return editorMemento;
285: }
286:
287: public IWorkbenchPage getPage() {
288: return this .manager.page;
289: }
290:
291: protected void doDisposePart() {
292: if (multiEditorChildren != null) {
293: for (int i = 0; i < multiEditorChildren.length; ++i) {
294: EditorReference ref = (EditorReference) multiEditorChildren[i];
295: if (ref != null) {
296: ref.dispose();
297: }
298: }
299: multiEditorChildren = null;
300: }
301:
302: if (part != null) {
303: EditorSite site = (EditorSite) ((IEditorPart) part)
304: .getEditorSite();
305: manager.disposeEditorActionBars((EditorActionBars) site
306: .getActionBars());
307: site.dispose();
308: }
309:
310: this .manager.checkDeleteEditorResources();
311:
312: super .doDisposePart();
313: editorMemento = null;
314: editorState = null;
315: restoredInput = new NullEditorInput();
316: }
317:
318: public IEditorInput getEditorInput() throws PartInitException {
319: if (isDisposed()) {
320: if (!(restoredInput instanceof NullEditorInput)) {
321: restoredInput = new NullEditorInput();
322: }
323: return restoredInput;
324: }
325:
326: IEditorPart part = getEditor(false);
327: if (part != null) {
328: return part.getEditorInput();
329: }
330: return getRestoredInput();
331: }
332:
333: private IEditorInput getRestoredInput() throws PartInitException {
334: if (restoredInput != null) {
335: return restoredInput;
336: }
337:
338: // Get the input factory.
339: IMemento editorMem = getMemento();
340: if (editorMem == null) {
341: throw new PartInitException(NLS.bind(
342: WorkbenchMessages.EditorManager_no_persisted_state,
343: getId(), getName()));
344: }
345: IMemento inputMem = editorMem
346: .getChild(IWorkbenchConstants.TAG_INPUT);
347: String factoryID = null;
348: if (inputMem != null) {
349: factoryID = inputMem
350: .getString(IWorkbenchConstants.TAG_FACTORY_ID);
351: }
352: if (factoryID == null) {
353: throw new PartInitException(
354: NLS
355: .bind(
356: WorkbenchMessages.EditorManager_no_input_factory_ID,
357: getId(), getName()));
358: }
359: IAdaptable input = null;
360: String label = null; // debugging only
361: if (UIStats.isDebugging(UIStats.CREATE_PART_INPUT)) {
362: label = getName() != null ? getName() : factoryID;
363: }
364: try {
365: UIStats.start(UIStats.CREATE_PART_INPUT, label);
366: IElementFactory factory = PlatformUI.getWorkbench()
367: .getElementFactory(factoryID);
368: if (factory == null) {
369: throw new PartInitException(
370: NLS
371: .bind(
372: WorkbenchMessages.EditorManager_bad_element_factory,
373: new Object[] { factoryID,
374: getId(), getName() }));
375: }
376:
377: // Get the input element.
378: input = factory.createElement(inputMem);
379: if (input == null) {
380: throw new PartInitException(
381: NLS
382: .bind(
383: WorkbenchMessages.EditorManager_create_element_returned_null,
384: new Object[] { factoryID,
385: getId(), getName() }));
386: }
387: } finally {
388: UIStats.end(UIStats.CREATE_PART_INPUT, input, label);
389: }
390: if (!(input instanceof IEditorInput)) {
391: throw new PartInitException(
392: NLS
393: .bind(
394: WorkbenchMessages.EditorManager_wrong_createElement_result,
395: new Object[] { factoryID, getId(),
396: getName() }));
397: }
398: restoredInput = (IEditorInput) input;
399: return restoredInput;
400: }
401:
402: /* (non-Javadoc)
403: * @see org.eclipse.ui.IWorkbenchPartReference#getTitleImage()
404: * This method will append a pin to the icon of the editor
405: * if the "automatically close editors" option in the
406: * preferences is enabled and the editor has been pinned.
407: */
408: public ImageDescriptor computeImageDescriptor() {
409: ImageDescriptor descriptor = super .computeImageDescriptor();
410: if (!isPinned()) {
411: return descriptor;
412: }
413:
414: // Check if the pinned preference is set
415: IPreferenceStore prefStore = WorkbenchPlugin.getDefault()
416: .getPreferenceStore();
417: boolean bUsePin = prefStore
418: .getBoolean(IPreferenceConstants.REUSE_EDITORS_BOOLEAN)
419: || ((TabBehaviour) Tweaklets.get(TabBehaviour.KEY))
420: .alwaysShowPinAction();
421:
422: if (!bUsePin) {
423: return descriptor;
424: }
425:
426: ImageDescriptor pinDesc = this .manager.getEditorPinImageDesc();
427: if (pinDesc == null) {
428: return descriptor;
429: }
430:
431: return new OverlayIcon(descriptor, pinDesc, new Point(16, 16));
432: }
433:
434: /**
435: * Wrapper for restoring the editor. First, this delegates to busyRestoreEditorHelper
436: * to do the real work of restoring the view. If unable to restore the editor, this
437: * method tries to substitute an error part and return success.
438: *
439: * @param ref_
440: * @param manager TODO
441: * @return
442: */
443: protected IWorkbenchPart createPart() {
444: if (EditorRegistry.EMPTY_EDITOR_ID.equals(getId())) {
445: return getEmptyEditor(getDescriptor());
446: }
447: PartInitException exception = null;
448:
449: IWorkbenchPart result = null;
450:
451: // Try to restore the editor -- this does the real work of restoring the editor
452: //
453: try {
454: result = createPartHelper();
455: } catch (PartInitException e) {
456: exception = e;
457: }
458:
459: // If unable to create the part, create an error part instead
460: // and pass the error to the status handling facility
461: if (exception != null) {
462:
463: IStatus originalStatus = exception.getStatus();
464: IStatus logStatus = StatusUtil.newStatus(originalStatus,
465: NLS.bind("Unable to create editor ID {0}: {1}", //$NON-NLS-1$
466: getId(), originalStatus.getMessage()));
467: IStatus displayStatus = StatusUtil
468: .newStatus(
469: originalStatus,
470: WorkbenchMessages.EditorManager_unableToCreateEditor);
471:
472: // Pass the error to the status handling facility
473: StatusManager.getManager().handle(logStatus);
474: StatusManager.getManager().handle(displayStatus,
475: StatusManager.SHOW);
476:
477: ErrorEditorPart part = new ErrorEditorPart(displayStatus);
478:
479: IEditorInput input;
480: try {
481: input = getEditorInput();
482: } catch (PartInitException e1) {
483: input = new NullEditorInput();
484: }
485:
486: EditorPane pane = (EditorPane) getPane();
487:
488: pane.createControl((Composite) manager.page
489: .getEditorPresentation().getLayoutPart()
490: .getControl());
491:
492: EditorDescriptor descr = getDescriptor();
493:
494: EditorSite site = new EditorSite(this , part, manager.page,
495: descr);
496:
497: site.setActionBars(new EditorActionBars(manager.page, site
498: .getWorkbenchWindow(), getId()));
499:
500: part.init(site, input);
501:
502: Composite parent = (Composite) pane.getControl();
503: Composite content = new Composite(parent, SWT.NONE);
504: content.setLayout(new FillLayout());
505:
506: try {
507: part.createPartControl(content);
508: } catch (Exception e) {
509: content.dispose();
510: StatusUtil.handleStatus(e, StatusManager.SHOW
511: | StatusManager.LOG);
512: return null;
513: }
514:
515: result = part;
516: }
517:
518: return result;
519: }
520:
521: protected void partPropertyChanged(Object source, int propId) {
522:
523: // Detect badly behaved editors that don't fire PROP_INPUT events
524: // when they're supposed to. This branch is only needed to handle
525: // malfunctioning editors.
526: if (propId == IWorkbenchPartConstants.PROP_INPUT) {
527: expectingInputChange = false;
528: }
529:
530: super .partPropertyChanged(source, propId);
531: }
532:
533: /**
534: * Attempts to set the input of the editor to the given input. Note that the input
535: * can't always be changed for an editor. Editors that don't implement IReusableEditor
536: * can't have their input changed once they've been materialized.
537: *
538: * @since 3.1
539: *
540: * @param input new input
541: * @return true iff the input was actually changed
542: */
543: public boolean setInput(IEditorInput input) {
544:
545: if (part != null) {
546: if (part instanceof IReusableEditor) {
547: IReusableEditor editor = (IReusableEditor) part;
548:
549: expectingInputChange = true;
550:
551: editor.setInput(input);
552:
553: // If the editor never fired a PROP_INPUT event, log the fact that we've discovered
554: // a buggy editor and fire the event for free. Firing the event for free isn't required
555: // and cannot be relied on (it only works if the input change was triggered by this
556: // method, and there are definitely other cases where events will still be lost),
557: // but older versions of the workbench did this so we fire it here in the spirit
558: // of playing nice.
559: if (expectingInputChange) {
560:
561: // Log the fact that this editor is broken
562: reportMalfunction("Editor is not firing a PROP_INPUT event in response to IReusableEditor.setInput(...)"); //$NON-NLS-1$
563:
564: // Fire the property for free (can't be relied on since there are other ways the input
565: // can change, but we do it here to be consistent with older versions of the workbench)
566: firePropertyChange(IWorkbenchPartConstants.PROP_INPUT);
567: }
568:
569: return editor.getEditorInput() == input;
570:
571: } else {
572: // Can't change the input if the editor already exists and isn't an IReusableEditor
573: return false;
574: }
575: } else {
576: // Changing the input is trivial and always succeeds if the editor doesn't exist yet
577: if (input != restoredInput) {
578: restoredInput = input;
579:
580: firePropertyChange(IWorkbenchPartConstants.PROP_INPUT);
581: }
582: }
583:
584: return true;
585: }
586:
587: /**
588: * Reports a recoverable malfunction in the system log. A recoverable malfunction would be
589: * something like failure to fire an expected property change. Only the first malfunction is
590: * recorded to avoid spamming the system log with repeated failures in the same editor.
591: *
592: * @since 3.1
593: *
594: * @param string
595: */
596: private void reportMalfunction(String string) {
597: if (!reportedMalfunctioningEditor) {
598: reportedMalfunctioningEditor = true;
599:
600: String errorMessage = "Problem detected with part " + getId(); //$NON-NLS-1$
601: if (part != null) {
602: errorMessage += " (class = " + part.getClass().getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
603: }
604:
605: errorMessage += ": " + string; //$NON-NLS-1$
606:
607: StatusManager.getManager().handle(
608: StatusUtil.newStatus(getDescriptor().getPluginId(),
609: errorMessage, null));
610: }
611: }
612:
613: private IEditorPart createPartHelper() throws PartInitException {
614:
615: // Things that will need to be disposed if an exception occurs (listed
616: // in the order they
617: // need to be disposed, and set to null if they haven't been created yet)
618: Composite content = null;
619: IEditorPart part = null;
620: EditorActionBars actionBars = null;
621: EditorSite site = null;
622:
623: try {
624: IEditorInput editorInput = getEditorInput();
625:
626: // Get the editor descriptor.
627: String editorID = getId();
628: EditorDescriptor desc = getDescriptor();
629:
630: if (desc == null) {
631: throw new PartInitException(
632: NLS
633: .bind(
634: WorkbenchMessages.EditorManager_missing_editor_descriptor,
635: editorID));
636: }
637:
638: if (desc.isInternal()) {
639: // Create an editor instance.
640: try {
641: UIStats.start(UIStats.CREATE_PART, editorID);
642: part = manager.createPart(desc);
643:
644: if (part != null && part instanceof MultiEditor) {
645: multiEditorChildren = manager.openMultiEditor(
646: this , (MultiEditor) part,
647: (MultiEditorInput) editorInput);
648: }
649: if (part instanceof IWorkbenchPart3) {
650: createPartProperties((IWorkbenchPart3) part);
651: }
652: } finally {
653: UIStats.end(UIStats.CREATE_PART, this , editorID);
654: }
655:
656: } else if (desc.getId().equals(
657: IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID)) {
658:
659: part = ComponentSupport.getSystemInPlaceEditor();
660:
661: if (part == null) {
662: throw new PartInitException(
663: WorkbenchMessages.EditorManager_no_in_place_support);
664: }
665: } else {
666: throw new PartInitException(
667: NLS
668: .bind(
669: WorkbenchMessages.EditorManager_invalid_editor_descriptor,
670: editorID));
671: }
672: // Create a pane for this part
673: PartPane pane = getPane();
674:
675: pane.createControl((Composite) manager.page
676: .getEditorPresentation().getLayoutPart()
677: .getControl());
678:
679: // Create controls
680: int style = SWT.NONE;
681: if (part instanceof IWorkbenchPartOrientation) {
682: style = ((IWorkbenchPartOrientation) part)
683: .getOrientation();
684: }
685:
686: // Link everything up to the part reference (the part reference itself should not have
687: // been modified until this point)
688: site = manager.createSite(this , part, desc, editorInput);
689:
690: // if there is saved state that's appropriate, pass it on
691: if (part instanceof IPersistableEditor
692: && editorState != null) {
693: ((IPersistableEditor) part).restoreState(editorState);
694: }
695:
696: // Remember the site and the action bars (now that we've created them, we'll need to dispose
697: // them if an exception occurs)
698: actionBars = (EditorActionBars) site.getActionBars();
699:
700: Composite parent = (Composite) pane.getControl();
701: content = new Composite(parent, style);
702:
703: content.setLayout(new FillLayout());
704:
705: try {
706: UIStats.start(UIStats.CREATE_PART_CONTROL, editorID);
707: part.createPartControl(content);
708:
709: parent.layout(true);
710: } finally {
711: UIStats
712: .end(UIStats.CREATE_PART_CONTROL, part,
713: editorID);
714: }
715:
716: // The editor should now be fully created. Exercise its public interface, and sanity-check
717: // it wherever possible. If it's going to throw exceptions or behave badly, it's much better
718: // that it does so now while we can still cancel creation of the part.
719: PartTester.testEditor(part);
720:
721: return part;
722:
723: } catch (Exception e) {
724: // Dispose anything which we allocated in the try block
725: if (content != null) {
726: try {
727: content.dispose();
728: } catch (RuntimeException re) {
729: StatusManager.getManager().handle(
730: StatusUtil.newStatus(
731: WorkbenchPlugin.PI_WORKBENCH, re));
732: }
733: }
734:
735: if (part != null) {
736: try {
737: part.dispose();
738: } catch (RuntimeException re) {
739: StatusManager.getManager().handle(
740: StatusUtil.newStatus(
741: WorkbenchPlugin.PI_WORKBENCH, re));
742: }
743: }
744:
745: if (actionBars != null) {
746: try {
747: manager.disposeEditorActionBars(actionBars);
748: } catch (RuntimeException re) {
749: StatusManager.getManager().handle(
750: StatusUtil.newStatus(
751: WorkbenchPlugin.PI_WORKBENCH, re));
752: }
753: }
754:
755: if (site != null) {
756: try {
757: site.dispose();
758: } catch (RuntimeException re) {
759: StatusManager.getManager().handle(
760: StatusUtil.newStatus(
761: WorkbenchPlugin.PI_WORKBENCH, re));
762: }
763: }
764:
765: throw new PartInitException(StatusUtil
766: .getLocalizedMessage(e), StatusUtil.getCause(e));
767: }
768:
769: }
770:
771: /**
772: * A quick way of finding out if this reference points to a MultiEditor.
773: * It depends on the fact that a MultiEditor does not lazily
774: * instantiate it's child editors.
775: *
776: * @return true if it has inner editor reference or the input is
777: * MultiEditorInput.
778: */
779: public boolean isMultiReference() {
780: return multiEditorChildren != null
781: || restoredInput instanceof MultiEditorInput;
782: }
783:
784: /**
785: * @param b
786: * @return
787: */
788: public IEditorPart getEmptyEditor(EditorDescriptor descr) {
789: ErrorEditorPart part = new ErrorEditorPart();
790:
791: IEditorInput input;
792: try {
793: input = getEditorInput();
794: } catch (PartInitException e1) {
795: input = new NullEditorInput();
796: }
797:
798: EditorPane pane = (EditorPane) getPane();
799:
800: pane.createControl((Composite) manager.page
801: .getEditorPresentation().getLayoutPart().getControl());
802:
803: EditorSite site = new EditorSite(this , part, manager.page,
804: descr);
805:
806: site.setActionBars(new EditorActionBars(manager.page, site
807: .getWorkbenchWindow(), getId()));
808:
809: part.init(site, input);
810:
811: Composite parent = (Composite) pane.getControl();
812: Composite content = new Composite(parent, SWT.NONE);
813: content.setLayout(new FillLayout());
814:
815: try {
816: part.createPartControl(content);
817: } catch (Exception e) {
818: content.dispose();
819: StatusManager.getManager().handle(
820: StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
821: e));
822: return null;
823: }
824:
825: this .part = part;
826: // Add a dispose listener to the part. This dispose listener does nothing but log an exception
827: // if the part's widgets get disposed unexpectedly. The workbench part reference is the only
828: // object that should dispose this control, and it will remove the listener before it does so.
829:
830: part.setPartName("(Empty)"); //$NON-NLS-1$
831: refreshFromPart();
832: releaseReferences();
833:
834: if (((WorkbenchPage) getPage()).getActiveEditorReference() != this) {
835: fireInternalPropertyChange(INTERNAL_PROPERTY_OPENED);
836: }
837:
838: return part;
839: }
840: }
|