/******************************************************************************* * Copyright (c) 2001, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.wst.xsd.ui.internal; import java.io.IOException; import java.io.InputStream; import java.util.List; import org.eclipse.core.internal.resources.ResourceException; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextInputListener; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.events.ShellAdapter; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorActionBarContributor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.IStorageEditorInput; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IGotoMarker; import org.eclipse.ui.part.MultiPageEditorPart; import org.eclipse.ui.part.MultiPageEditorSite; import org.eclipse.wst.sse.core.IStructuredModel; import org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException; import org.eclipse.wst.sse.ui.internal.StructuredTextEditor; import org.eclipse.wst.xml.core.IXMLPreferenceNames; import org.eclipse.wst.xml.ui.StructuredTextEditorXML; import org.w3c.dom.Document; import org.w3c.dom.Node; public class XSDMultiPageEditorPart extends MultiPageEditorPart implements IPropertyListener { /** * */ public XSDMultiPageEditorPart() { super(); } /** * Internal part activation listener */ class PartListener extends ShellAdapter implements IPartListener { private IWorkbenchPart fActivePart; private boolean fIsHandlingActivation = false; private void handleActivation() { if (fIsHandlingActivation) return; if (fActivePart == XSDMultiPageEditorPart.this) { fIsHandlingActivation = true; try { safelySanityCheckState(); } finally { fIsHandlingActivation = false; } } } /** * @see IPartListener#partActivated(IWorkbenchPart) */ public void partActivated(IWorkbenchPart part) { fActivePart = part; handleActivation(); } /** * @see IPartListener#partBroughtToTop(IWorkbenchPart) */ public void partBroughtToTop(IWorkbenchPart part) { } /** * @see IPartListener#partClosed(IWorkbenchPart) */ public void partClosed(IWorkbenchPart part) { } /** * @see IPartListener#partDeactivated(IWorkbenchPart) */ public void partDeactivated(IWorkbenchPart part) { fActivePart = null; } /** * @see IPartListener#partOpened(IWorkbenchPart) */ public void partOpened(IWorkbenchPart part) { } /* * @see ShellListener#shellActivated(ShellEvent) */ public void shellActivated(ShellEvent e) { handleActivation(); } } class TextInputListener implements ITextInputListener { public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { } public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { } } /** The source page index. */ private int fSourcePageIndex; /** The text editor. */ private StructuredTextEditor fTextEditor; private PartListener partListener; /* * This method is just to make firePropertyChanged accessbible from some * (anonomous) inner classes. */ protected void _firePropertyChange(int property) { super.firePropertyChange(property); } /** * Adds the source page of the multi-page editor. */ protected void addSourcePage() throws PartInitException { try { fSourcePageIndex = addPage(fTextEditor, getEditorInput()); setPageText(fSourcePageIndex, XSDEditorPlugin.getXSDString("_UI_TAB_SOURCE")); //$NON-NLS-1$ // the update's critical, to get viewer selection manager and // highlighting to work fTextEditor.update(); firePropertyChange(PROP_TITLE); // Changes to the Text Viewer's document instance should also force an // input refresh fTextEditor.getTextViewer().addTextInputListener(new TextInputListener()); } catch (PartInitException exception) { // dispose editor dispose(); throw new SourceEditingRuntimeException(XSDEditorPlugin.getXSDString("An_error_has_occurred_when1_ERROR_")); //$NON-NLS-1$ } } /* (non-Javadoc) * @see org.eclipse.ui.part.MultiPageEditorPart#createPages() */ protected void createPages() { try { // source page MUST be created before design page, now createSourcePage(); addSourcePage(); setActivePage(); // future_TODO: add a catch block here for any exception the design // page throws and convert it into a more informative message. } catch (PartInitException e) { throw new RuntimeException(e); } } /** * @see org.eclipse.ui.part.MultiPageEditorPart#createSite(org.eclipse.ui.IEditorPart) */ protected IEditorSite createSite(IEditorPart editor) { IEditorSite site = null; if (editor == fTextEditor) { site = new MultiPageEditorSite(this, editor) { /** * @see org.eclipse.ui.part.MultiPageEditorSite#getActionBarContributor() */ public IEditorActionBarContributor getActionBarContributor() { IEditorActionBarContributor contributor = super.getActionBarContributor(); IEditorActionBarContributor multiContributor = XSDMultiPageEditorPart.this.getEditorSite().getActionBarContributor(); // if (multiContributor instanceof XMLMultiPageEditorActionBarContributor) { // contributor = ((XMLMultiPageEditorActionBarContributor) multiContributor).sourceViewerActionContributor; // } return contributor; } }; } else { site = super.createSite(editor); } return site; } /** * Creates the source page of the multi-page editor. */ protected void createSourcePage() throws PartInitException { fTextEditor = createTextEditor(); fTextEditor.setEditorPart(this); // Set the SourceViewerConfiguration now so the text editor won't use // the default configuration first // and switch to the StructuredTextViewerConfiguration later. // DMW removed setSourceViewerConfiguration 3/26/2003 since added // createPartControl to our text editor. // fTextEditor.setSourceViewerConfiguration(); fTextEditor.addPropertyListener(this); } /** * Method createTextEditor. * * @return StructuredTextEditor */ protected StructuredTextEditor createTextEditor() { return new StructuredTextEditorXML(); } public void dispose() { IWorkbenchWindow window = getSite().getWorkbenchWindow(); window.getPartService().removePartListener(partListener); window.getShell().removeShellListener(partListener); getSite().getPage().removePartListener(partListener); if (fTextEditor != null) { fTextEditor.removePropertyListener(this); } // moved to last when added window ... seems like // we'd be in danger of losing some data, like site, // or something. super.dispose(); } /* * (non-Javadoc) Saves the contents of this editor.
Subclasses must
* override this method to implement the open-save-close lifecycle for an
* editor. For greater details, see IEditorPart
* Subclasses must override this method to implement the open-save-close
* lifecycle for an editor. For greater details, see IEditorPart
*
* Subclasses of EditorPart
must implement this method.
* Within the implementation subclasses should verify that the input type
* is acceptable and then save the site and input. Here is sample code:
*
if (!(input instanceof IFileEditorInput)) throw new * PartInitException("Invalid Input: Must be IFileEditorInput"); * setSite(site); setInput(editorInput);*/ protected boolean fileDoesNotExist(IFileEditorInput input, Throwable[] coreException) { boolean result = false; InputStream inStream = null; if ((!(input.exists())) || (!(input.getFile().exists()))) { result = true; } else { try { inStream = input.getFile().getContents(true); } catch (CoreException e) { // very likely to be file not found result = true; coreException[0] = e; } finally { if (input != null) { try { if (inStream != null) { inStream.close(); } } catch (IOException e) { } } } } return result; } public Object getAdapter(Class key) { Object result = null; // DMW: I'm bullet-proofing this because // its been reported (on 4.03 version) a null pointer sometimes // happens here on startup, when an editor has been left // open when workbench shutdown. if (fTextEditor != null) { result = fTextEditor.getAdapter(key); } return result; } /** * IExtendedMarkupEditor method */ public Node getCaretNode() { if (getTextEditor() == null) return null; return getTextEditor().getCaretNode(); } /** * IExtendedSimpleEditor method */ public int getCaretPosition() { if (getTextEditor() == null) return -1; return getTextEditor().getCaretPosition(); } /** * IExtendedSimpleEditor method */ public IDocument getDocument() { if (getTextEditor() == null) return null; return getTextEditor().getDocument(); } /** * IExtendedMarkupEditor method */ public Document getDOMDocument() { if (getTextEditor() == null) return null; return getTextEditor().getDOMDocument(); } /** * IExtendedSimpleEditor method */ public IEditorPart getEditorPart() { return this; } protected IStructuredModel getModel() { IStructuredModel model = null; if (fTextEditor != null) model = fTextEditor.getModel(); return model; } protected IPreferenceStore getPreferenceStore() { return XSDEditorPlugin.getPlugin().getPreferenceStore(); } /** * IExtendedMarkupEditor method */ public List getSelectedNodes() { if (getTextEditor() == null) return null; return getTextEditor().getSelectedNodes(); } /** * IExtendedSimpleEditor method */ public Point getSelectionRange() { if (getTextEditor() == null) return new Point(-1, -1); return getTextEditor().getSelectionRange(); } public StructuredTextEditor getTextEditor() { return fTextEditor; } /* * (non-Javadoc) Method declared on IWorkbenchPart. */ public String getTitle() { String title = null; if (getTextEditor() == null) { if (getEditorInput() != null) { title = getEditorInput().getName(); } } else { title = getTextEditor().getTitle(); } if (title == null) { title = getPartName(); } return title; } /* * (non-Javadoc) Sets the cursor and selection state for this editor to * the passage defined by the given marker.
Subclasses may override.
* For greater details, see IEditorPart
Subclasses must override this method to implement the
* open-save-close lifecycle for an editor. For greater details, see
* IEditorPart
This method returns true
*
if and only if the editor is dirty ( isDirty
).
*