blob: b00f1d3cab10cabc9a27bb5319152f0ebebb1c98 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.xsd.editor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.INavigationLocation;
import org.eclipse.ui.INavigationLocationProvider;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.eclipse.wst.sse.ui.internal.contentoutline.ConfigurableContentOutlinePage;
import org.eclipse.wst.xml.core.internal.document.NodeImpl;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xsd.adt.actions.AddFieldAction;
import org.eclipse.wst.xsd.adt.actions.BaseSelectionAction;
import org.eclipse.wst.xsd.adt.actions.DeleteAction;
import org.eclipse.wst.xsd.adt.actions.SetInputToGraphView;
import org.eclipse.wst.xsd.adt.actions.ShowPropertiesViewAction;
import org.eclipse.wst.xsd.adt.design.editparts.RootContentEditPart;
import org.eclipse.wst.xsd.adt.editor.ADTMultiPageEditor;
import org.eclipse.wst.xsd.adt.facade.IModel;
import org.eclipse.wst.xsd.editor.internal.adapters.CategoryAdapter;
import org.eclipse.wst.xsd.editor.internal.adapters.XSDAdapterFactory;
import org.eclipse.wst.xsd.editor.internal.adapters.XSDBaseAdapter;
import org.eclipse.wst.xsd.editor.internal.design.editparts.XSDEditPartFactory;
import org.eclipse.wst.xsd.editor.internal.navigation.DesignViewNavigationLocation;
import org.eclipse.wst.xsd.editor.internal.navigation.MultiPageEditorTextSelectionNavigationLocation;
import org.eclipse.wst.xsd.editor.internal.utils.OpenOnSelectionHelper;
import org.eclipse.wst.xsd.ui.common.actions.AddXSDAttributeDeclarationAction;
import org.eclipse.wst.xsd.ui.common.actions.AddXSDAttributeGroupDefinitionAction;
import org.eclipse.wst.xsd.ui.common.actions.AddXSDComplexTypeDefinitionAction;
import org.eclipse.wst.xsd.ui.common.actions.AddXSDElementAction;
import org.eclipse.wst.xsd.ui.common.actions.AddXSDModelGroupAction;
import org.eclipse.wst.xsd.ui.common.actions.AddXSDModelGroupDefinitionAction;
import org.eclipse.wst.xsd.ui.common.actions.AddXSDSimpleTypeDefinitionAction;
import org.eclipse.wst.xsd.ui.common.actions.DeleteXSDConcreteComponentAction;
import org.eclipse.wst.xsd.ui.common.actions.OpenInNewEditor;
import org.eclipse.wst.xsd.ui.common.actions.SetMultiplicityAction;
import org.eclipse.wst.xsd.ui.common.actions.SetTypeAction;
import org.eclipse.wst.xsd.ui.internal.text.XSDModelReconcileAdapter;
import org.eclipse.xsd.XSDComponent;
import org.eclipse.xsd.XSDCompositor;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.impl.XSDSchemaImpl;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class InternalXSDMultiPageEditor extends ADTMultiPageEditor implements ITabbedPropertySheetPageContributor, IPropertyListener, INavigationLocationProvider
{
ResourceSet resourceSet;
Resource xsdResource;
// IModel model;
IStructuredModel structuredModel;
XSDSchema xsdSchema;
private OutlineTreeSelectionChangeListener fOutlineListener;
private SourceEditorSelectionListener fSourceEditorSelectionListener;
private XSDSelectionManagerSelectionListener fXSDSelectionListener;
private StructuredTextEditor structuredTextEditor;
public IModel buildModel(IFileEditorInput editorInput)
{
try
{
EPackage.Registry reg = EPackage.Registry.INSTANCE;
XSDPackage xsdPackage = (XSDPackage) reg.getEPackage(XSDPackage.eNS_URI);
xsdSchema = xsdPackage.getXSDFactory().createXSDSchema();
resourceSet = XSDSchemaImpl.createResourceSet();
IFile resourceFile = editorInput.getFile();
structuredModel = StructuredModelManager.getModelManager().getModelForEdit(resourceFile);
// If the resource is in the workspace....
// otherwise the user is trying to open an external file
if (resourceFile != null)
{
String pathName = resourceFile.getFullPath().toString();
xsdResource = resourceSet.getResource(URI.createPlatformResourceURI(pathName), true);
resourceSet.getResources().add(xsdResource);
Object obj = xsdResource.getContents().get(0);
if (obj instanceof XSDSchema)
{
xsdSchema = (XSDSchema) obj;
xsdSchema.setElement(((IDOMModel) structuredModel).getDocument().getDocumentElement());
model = (IModel) XSDAdapterFactory.getInstance().adapt(xsdSchema);
}
// If the input schema is from the WSDL Editor, then use that inline schema
if (editorInput instanceof XSDFileEditorInput)
{
xsdSchema = ((XSDFileEditorInput) editorInput).getSchema();
model = (IModel) XSDAdapterFactory.getInstance().adapt(xsdSchema);
}
if (xsdSchema.getElement() != null)
// TODO (cs) ... we need to look into performance issues when we add elements
// seems to be that formatting is causig lots of notification and things get terribly slow
// I'm specializing the method below to add an isModelStateChanging check that should
// help here ... but we need to investigate further
new XSDModelReconcileAdapter(xsdSchema.getElement().getOwnerDocument(), xsdSchema)
{
public void handleNotifyChange(INodeNotifier notifier, int eventType, Object feature, Object oldValue, Object newValue, int index)
{
if (notifier instanceof NodeImpl)
{
NodeImpl nodeImpl = (NodeImpl)notifier;
if (!nodeImpl.getModel().isModelStateChanging())
{
//System.out.println("handleNotifyChange " + eventType);
super.handleNotifyChange(notifier, eventType, feature, oldValue, newValue, index);
}
}
}
};
xsdResource.setModified(false);
}
}
catch (StackOverflowError e)
{
}
catch (Exception ex)
{
}
return model;
}
public void dispose()
{
structuredModel.releaseFromEdit();
if (fOutlinePage != null)
{
if (fOutlinePage instanceof ConfigurableContentOutlinePage && fOutlineListener != null)
{
((ConfigurableContentOutlinePage) fOutlinePage).removeDoubleClickListener(fOutlineListener);
}
if (fOutlineListener != null)
{
fOutlinePage.removeSelectionChangedListener(fOutlineListener);
}
}
getSelectionManager().removeSelectionChangedListener(fXSDSelectionListener);
super.dispose();
}
protected void configureGraphicalViewer()
{
super.configureGraphicalViewer();
// get edit part factory from extension
EditPartFactory editPartFactory = XSDEditorPlugin.getDefault().getXSDEditorConfiguration().getEditPartFactory();
if (editPartFactory != null)
{
graphicalViewer.setEditPartFactory(editPartFactory);
}
else
{
// otherwise use default
graphicalViewer.setEditPartFactory(new XSDEditPartFactory());
}
}
public Object getAdapter(Class type)
{
if (type == org.eclipse.ui.views.properties.IPropertySheetPage.class)
{
XSDTabbedPropertySheetPage page = new XSDTabbedPropertySheetPage(this);
return page;
}
else if (type == ISelectionProvider.class)
{
return selectionManager;
}
else if (type == XSDSchema.class)
{
return xsdSchema;
}
else if (type == IContentOutlinePage.class)
{
Object adapter = super.getAdapter(type);
if (adapter != null)
{
IContentOutlinePage page = (IContentOutlinePage) adapter;
fOutlineListener = new OutlineTreeSelectionChangeListener();
page.addSelectionChangedListener(fOutlineListener);
if (page instanceof ConfigurableContentOutlinePage)
{
((ConfigurableContentOutlinePage) page).addDoubleClickListener(fOutlineListener);
}
return page;
}
}
else if (type == XSDElementReferenceEditManager.class)
{
IEditorInput editorInput = getEditorInput();
if (editorInput instanceof IFileEditorInput)
{
IFileEditorInput fileEditorInput = (IFileEditorInput) editorInput;
// TODO (cs) currently we assume the schema editor will only ever edit a
// single schema
/// but if we want to enable the schema editor to edit wsdl files we
// should pass in
// an array of schemas
// hmm.. perhaps just pass in a ResourceSet
XSDSchema[] schemas = {xsdSchema};
return new XSDElementReferenceEditManager(fileEditorInput.getFile(), schemas);
}
}
else if (type == XSDTypeReferenceEditManager.class)
{
IEditorInput editorInput = getEditorInput();
if (editorInput instanceof IFileEditorInput)
{
IFileEditorInput fileEditorInput = (IFileEditorInput) editorInput;
// TODO (cs) currently we assume the schema editor will only ever edit a
// single schema
// but if we want to enable the schema editor to edit wsdl files we
// should pass in
// an array of schemas
// hmm.. perhaps just pass in a ResourceSet
XSDSchema[] schemas = {xsdSchema};
return new XSDTypeReferenceEditManager(fileEditorInput.getFile(), schemas);
}
}
else if (type == ITextEditor.class)
{
return getTextEditor();
}
else if (type == ISelectionMapper.class)
{
return new XSDSelectionMapper();
}
return super.getAdapter(type);
}
public String getContributorId()
{
return "org.eclipse.wst.xsd.editor";
}
public XSDSchema getXSDSchema()
{
return xsdSchema;
}
public StructuredTextEditor getTextEditor()
{
return structuredTextEditor;
}
protected void createSourcePage()
{
try
{
structuredTextEditor = new StructuredTextEditor();
int index = addPage(structuredTextEditor, getEditorInput());
setPageText(index, "Source");
structuredTextEditor.update();
structuredTextEditor.setEditorPart(this);
structuredTextEditor.addPropertyListener(this);
firePropertyChange(PROP_TITLE);
}
catch (PartInitException e)
{
ErrorDialog.openError(getSite().getShell(), "Error creating nested text editor", null, e.getStatus());
}
}
/**
* Method openOnGlobalReference. The comp argument is a resolved xsd schema
* object from another file. This is created and called from another schema
* model to allow F3 navigation to open a new editor and choose the referenced
* object within that editor context
*
* @param comp
*/
public void openOnGlobalReference(XSDConcreteComponent comp)
{
XSDNamedComponent namedComponent = openOnSelectionHelper.openOnGlobalReference(comp);
if (namedComponent != null)
{
XSDBaseAdapter adapter = (XSDBaseAdapter) XSDAdapterFactory.getInstance().adapt(namedComponent);
getSelectionManager().setSelection(new StructuredSelection(adapter));
IAction action = getActionRegistry().getAction(SetInputToGraphView.ID);
if (action != null)
{
action.run();
}
}
}
protected OpenOnSelectionHelper openOnSelectionHelper;
public OpenOnSelectionHelper getOpenOnSelectionHelper()
{
return openOnSelectionHelper;
}
/**
* Creates the pages of the multi-page editor.
*/
protected void createPages()
{
model = buildModel((IFileEditorInput) getEditorInput());
selectionProvider = getSelectionManager();
getEditorSite().setSelectionProvider(selectionProvider);
createGraphPage();
createSourcePage();
openOnSelectionHelper = new OpenOnSelectionHelper(getTextEditor(), getXSDSchema());
ISelectionProvider provider = getTextEditor().getSelectionProvider();
fSourceEditorSelectionListener = new SourceEditorSelectionListener();
if (provider instanceof IPostSelectionProvider)
{
((IPostSelectionProvider) provider).addPostSelectionChangedListener(fSourceEditorSelectionListener);
}
else
{
provider.addSelectionChangedListener(fSourceEditorSelectionListener);
}
fXSDSelectionListener = new XSDSelectionManagerSelectionListener();
getSelectionManager().addSelectionChangedListener(fXSDSelectionListener);
}
protected void createActions()
{
super.createActions();
ActionRegistry registry = getActionRegistry();
BaseSelectionAction action = new AddFieldAction(this);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new DeleteAction(this);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new AddXSDElementAction(this, AddXSDElementAction.ID, "Add Element", false);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new AddXSDElementAction(this, AddXSDElementAction.REF_ID, "Add Element Ref", true);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new AddXSDModelGroupAction(this, XSDCompositor.SEQUENCE_LITERAL, AddXSDModelGroupAction.SEQUENCE_ID);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new AddXSDModelGroupAction(this, XSDCompositor.CHOICE_LITERAL, AddXSDModelGroupAction.CHOICE_ID);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new AddXSDModelGroupAction(this, XSDCompositor.ALL_LITERAL, AddXSDModelGroupAction.ALL_ID);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new AddXSDModelGroupDefinitionAction(this, false);
action.setId(AddXSDModelGroupDefinitionAction.MODELGROUPDEFINITION_ID);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new AddXSDModelGroupDefinitionAction(this, true);
action.setId(AddXSDModelGroupDefinitionAction.MODELGROUPDEFINITIONREF_ID);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new AddXSDComplexTypeDefinitionAction(this);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new AddXSDSimpleTypeDefinitionAction(this);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new AddXSDAttributeDeclarationAction(this);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new OpenInNewEditor(this);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new ShowPropertiesViewAction(this);
registry.registerAction(action);
action = new AddXSDAttributeGroupDefinitionAction(this);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
action = new DeleteXSDConcreteComponentAction(this);
action.setSelectionProvider(getSelectionManager());
registry.registerAction(action);
SetTypeAction setNewComplexTypeAction = new SetTypeAction("New...", SetTypeAction.SET_NEW_TYPE_ID, this);
setNewComplexTypeAction.setSelectionProvider(getSelectionManager());
registry.registerAction(setNewComplexTypeAction);
SetTypeAction setExistingTypeAction = new SetTypeAction("Browse...", SetTypeAction.SELECT_EXISTING_TYPE_ID, this);
setExistingTypeAction.setSelectionProvider(getSelectionManager());
registry.registerAction(setExistingTypeAction);
addMultiplicityMenu(registry);
}
protected void addMultiplicityMenu(ActionRegistry registry)
{
SetMultiplicityAction oneMultiplicity = new SetMultiplicityAction(this, "1..1 (" + "Required" + ")", SetMultiplicityAction.REQUIRED_ID);
oneMultiplicity.setMaxOccurs(1);
oneMultiplicity.setMinOccurs(1);
oneMultiplicity.setSelectionProvider(getSelectionManager());
registry.registerAction(oneMultiplicity);
SetMultiplicityAction zeroOrMoreMultiplicity = new SetMultiplicityAction(this, "0..* (" + "Zero or more" + ")", SetMultiplicityAction.ZERO_OR_MORE_ID);
zeroOrMoreMultiplicity.setMaxOccurs(-1);
zeroOrMoreMultiplicity.setMinOccurs(0);
zeroOrMoreMultiplicity.setSelectionProvider(getSelectionManager());
registry.registerAction(zeroOrMoreMultiplicity);
SetMultiplicityAction zeroOrOneMultiplicity = new SetMultiplicityAction(this, "0..1 (" + "Optional" + ")", SetMultiplicityAction.ZERO_OR_ONE_ID);
zeroOrOneMultiplicity.setMaxOccurs(1);
zeroOrOneMultiplicity.setMinOccurs(0);
zeroOrOneMultiplicity.setSelectionProvider(getSelectionManager());
registry.registerAction(zeroOrOneMultiplicity);
SetMultiplicityAction oneOrMoreMultiplicity = new SetMultiplicityAction(this, "1..* (" + "One or more" + ")", SetMultiplicityAction.ONE_OR_MORE_ID);
oneOrMoreMultiplicity.setMaxOccurs(-1);
oneOrMoreMultiplicity.setMinOccurs(1);
oneOrMoreMultiplicity.setSelectionProvider(getSelectionManager());
registry.registerAction(oneOrMoreMultiplicity);
}
/**
* Closes all project files on project close.
*/
public void resourceChanged(final IResourceChangeEvent event)
{
if (event.getType() == IResourceChangeEvent.PRE_CLOSE)
{
Display.getDefault().asyncExec(new Runnable()
{
public void run()
{
IWorkbenchPage[] pages = getSite().getWorkbenchWindow().getPages();
for (int i = 0; i < pages.length; i++)
{
if (((FileEditorInput) structuredTextEditor.getEditorInput()).getFile().getProject().equals(event.getResource()))
{
IEditorPart editorPart = pages[i].findEditor(structuredTextEditor.getEditorInput());
pages[i].closeEditor(editorPart, true);
}
}
}
});
}
}
/**
* Returns <code>true</code> if the command stack is dirty
*
* @see org.eclipse.ui.ISaveablePart#isDirty()
*/
public boolean isDirty()
{
super.isDirty();
return structuredTextEditor.isDirty() || getCommandStack().isDirty();
}
/*
* This method is just to make firePropertyChanged accessbible from some
* (anonomous) inner classes.
*/
protected void _firePropertyChange(int property)
{
super.firePropertyChange(property);
}
/**
* Posts the update code "behind" the running operation.
*/
protected void postOnDisplayQue(Runnable runnable)
{
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
if (windows != null && windows.length > 0)
{
Display display = windows[0].getShell().getDisplay();
display.asyncExec(runnable);
}
else
runnable.run();
}
/**
* Indicates that a property has changed.
*
* @param source
* the object whose property has changed
* @param propId
* the id of the property which has changed; property ids are
* generally defined as constants on the source class
*/
public void propertyChanged(Object source, int propId)
{
switch (propId)
{
// had to implement input changed "listener" so that
// strucutedText could tell it containing editor that
// the input has change, when a 'resource moved' event is
// found.
case IEditorPart.PROP_INPUT :
case IEditorPart.PROP_DIRTY : {
if (source == structuredTextEditor)
{
if (structuredTextEditor.getEditorInput() != getEditorInput())
{
setInput(structuredTextEditor.getEditorInput());
// title should always change when input changes.
// create runnable for following post call
Runnable runnable = new Runnable()
{
public void run()
{
_firePropertyChange(IWorkbenchPart.PROP_TITLE);
}
};
// Update is just to post things on the display queue
// (thread). We have to do this to get the dirty
// property to get updated after other things on the
// queue are executed.
postOnDisplayQue(runnable);
}
}
break;
}
case IWorkbenchPart.PROP_TITLE : {
// update the input if the title is changed
if (source == structuredTextEditor)
{
if (structuredTextEditor.getEditorInput() != getEditorInput())
{
setInput(structuredTextEditor.getEditorInput());
}
}
break;
}
default : {
// propagate changes. Is this needed? Answer: Yes.
if (source == structuredTextEditor)
{
firePropertyChange(propId);
}
break;
}
}
}
/**
* Listener on SSE's outline page's selections that converts DOM selections
* into xsd selections and notifies XSD selection manager
*/
class OutlineTreeSelectionChangeListener implements ISelectionChangedListener, IDoubleClickListener
{
public OutlineTreeSelectionChangeListener()
{
}
private ISelection getXSDSelection(ISelection selection)
{
ISelection sel = null;
if (selection instanceof IStructuredSelection)
{
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
Object o = structuredSelection.getFirstElement();
if (o != null)
sel = new StructuredSelection(o);
}
return sel;
}
/**
* Determines DOM node based on object (xsd node)
*
* @param object
* @return
*/
private Object getObjectForOtherModel(Object object)
{
Node node = null;
if (object instanceof Node)
{
node = (Node) object;
}
else if (object instanceof XSDComponent)
{
node = ((XSDComponent) object).getElement();
}
else if (object instanceof CategoryAdapter)
{
node = ((CategoryAdapter) object).getXSDSchema().getElement();
}
else if (object instanceof XSDBaseAdapter)
{
if (((XSDBaseAdapter) object).getTarget() instanceof XSDConcreteComponent)
{
node = ((XSDConcreteComponent) ((XSDBaseAdapter) object).getTarget()).getElement();
}
}
// the text editor can only accept sed nodes!
//
if (!(node instanceof IDOMNode))
{
node = null;
}
return node;
}
public void doubleClick(DoubleClickEvent event)
{
/*
* Selection in outline tree changed so set outline tree's selection into
* editor's selection and say it came from outline tree
*/
if (getSelectionManager() != null && getSelectionManager().getEnableNotify())
{
ISelection selection = getXSDSelection(event.getSelection());
if (selection != null)
{
getSelectionManager().setSelection(selection, fOutlinePage);
}
if (getTextEditor() != null && selection instanceof IStructuredSelection)
{
int start = -1;
int length = 0;
Object o = ((IStructuredSelection) selection).getFirstElement();
if (o != null)
o = getObjectForOtherModel(o);
if (o instanceof IndexedRegion)
{
start = ((IndexedRegion) o).getStartOffset();
length = ((IndexedRegion) o).getEndOffset() - start;
}
if (start > -1)
{
getTextEditor().selectAndReveal(start, length);
}
}
}
}
public void selectionChanged(SelectionChangedEvent event)
{
/*
* Selection in outline tree changed so set outline tree's selection into
* editor's selection and say it came from outline tree
*/
if (getSelectionManager() != null && getSelectionManager().getEnableNotify())
{
ISelection selection = getXSDSelection(event.getSelection());
if (selection != null)
{
getSelectionManager().setSelection(selection, fOutlinePage);
}
}
}
}
/**
* Listener on SSE's source editor's selections that converts DOM selections
* into xsd selections and notifies XSD selection manager
*/
private class SourceEditorSelectionListener implements ISelectionChangedListener
{
/**
* Determines XSD node based on object (DOM node)
*
* @param object
* @return
*/
private Object getXSDNode(Object object)
{
// get the element node
Element element = null;
if (object instanceof Node)
{
Node node = (Node) object;
if (node != null)
{
if (node.getNodeType() == Node.ELEMENT_NODE)
{
element = (Element) node;
}
else if (node.getNodeType() == Node.ATTRIBUTE_NODE)
{
element = ((Attr) node).getOwnerElement();
}
}
}
Object o = element;
if (element != null)
{
Object modelObject = getXSDSchema().getCorrespondingComponent(element);
if (modelObject != null)
{
o = modelObject;
o = XSDAdapterFactory.getInstance().adapt((Notifier) modelObject);
}
}
return o;
}
public void selectionChanged(SelectionChangedEvent event)
{
if (getSelectionManager().getEnableNotify() && getActivePage() == 1)
{
ISelection selection = event.getSelection();
if (selection instanceof IStructuredSelection)
{
List xsdSelections = new ArrayList();
for (Iterator i = ((IStructuredSelection) selection).iterator(); i.hasNext();)
{
Object domNode = i.next();
Object xsdNode = getXSDNode(domNode);
if (xsdNode != null)
{
xsdSelections.add(xsdNode);
}
}
if (!xsdSelections.isEmpty())
{
StructuredSelection xsdSelection = new StructuredSelection(xsdSelections);
getSelectionManager().setSelection(xsdSelection, getTextEditor().getSelectionProvider());
}
}
}
}
}
/**
* Listener on XSD's selection manager's selections that converts XSD
* selections into DOM selections and notifies SSE's selection provider
*/
private class XSDSelectionManagerSelectionListener implements ISelectionChangedListener
{
/**
* Determines DOM node based on object (xsd node)
*
* @param object
* @return
*/
private Object getObjectForOtherModel(Object object)
{
Node node = null;
if (object instanceof Node)
{
node = (Node) object;
}
else if (object instanceof XSDComponent)
{
node = ((XSDComponent) object).getElement();
}
else if (object instanceof CategoryAdapter)
{
node = ((CategoryAdapter) object).getXSDSchema().getElement();
}
else if (object instanceof XSDBaseAdapter)
{
if (((XSDBaseAdapter) object).getTarget() instanceof XSDConcreteComponent)
{
node = ((XSDConcreteComponent) ((XSDBaseAdapter) object).getTarget()).getElement();
}
}
// the text editor can only accept sed nodes!
//
if (!(node instanceof IDOMNode))
{
node = null;
}
return node;
}
public void selectionChanged(SelectionChangedEvent event)
{
// do not fire selection in source editor if selection event came
// from source editor
if (event.getSource() != getTextEditor().getSelectionProvider())
{
ISelection selection = event.getSelection();
if (selection instanceof IStructuredSelection)
{
List otherModelObjectList = new ArrayList();
for (Iterator i = ((IStructuredSelection) selection).iterator(); i.hasNext();)
{
Object modelObject = i.next();
Object otherModelObject = getObjectForOtherModel(modelObject);
if (otherModelObject != null)
{
otherModelObjectList.add(otherModelObject);
}
}
if (!otherModelObjectList.isEmpty())
{
// here's an ugly hack... if we allow text selections to fire during
// SetInputToGraphView action we screw up the navigation history!
//
//TODO (cs) ... we need to prevent the source editor from messing up the navigation history
//
if (getActivePage() == 1)
{
StructuredSelection nodeSelection = new StructuredSelection(otherModelObjectList);
getTextEditor().getSelectionProvider().setSelection(nodeSelection);
}
}
}
}
}
}
public INavigationLocation createEmptyNavigationLocation()
{
if (getActivePage() == 0)
{
return new DesignViewNavigationLocation(this);
}
else
{
return new MultiPageEditorTextSelectionNavigationLocation(getTextEditor(), false);
}
}
public INavigationLocation createNavigationLocation()
{
if (getActivePage() == 0)
{
try
{
RootEditPart rootEditPart = graphicalViewer.getRootEditPart();
EditPart editPart = rootEditPart.getContents();
if (editPart instanceof RootContentEditPart)
{
RootContentEditPart rootContentEditPart = (RootContentEditPart)editPart;
Object input = rootContentEditPart.getInput();
if (input instanceof Adapter)
{
XSDConcreteComponent concreteComponent = (XSDConcreteComponent)((Adapter)input).getTarget();
return new DesignViewNavigationLocation(this, concreteComponent);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
else
{
return new MultiPageEditorTextSelectionNavigationLocation(getTextEditor(), true);
}
}
}