blob: 0f995916fe6b6eca6ec12b7d189b2a41dffd50ba [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.pde.internal.ui.editor.schema;
import java.util.Arrays;
import java.util.Iterator;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.action.*;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.IModelChangedEvent;
import org.eclipse.pde.internal.core.ICoreConstants;
import org.eclipse.pde.internal.core.ischema.*;
import org.eclipse.pde.internal.core.schema.*;
import org.eclipse.pde.internal.ui.PDEPlugin;
import org.eclipse.pde.internal.ui.PDEUIMessages;
import org.eclipse.pde.internal.ui.editor.*;
import org.eclipse.pde.internal.ui.editor.actions.CollapseAction;
import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
import org.eclipse.pde.internal.ui.parts.TreePart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
public class ElementSection extends TreeSection {
private TreeViewer fTreeViewer;
private Schema fSchema;
private NewElementAction fNewElementAction = new NewElementAction();
private NewAttributeAction fNewAttributeAction = new NewAttributeAction();
private Clipboard fClipboard;
private SchemaRearranger fRearranger;
private CollapseAction fCollapseAction;
class ContentProvider extends DefaultContentProvider implements ITreeContentProvider {
public Object[] getElements(Object object) {
if (object instanceof Schema) {
Schema schema = (Schema) object;
return schema.getElements();
}
return new Object[0];
}
public Object[] getChildren(Object parent) {
Object[] children = new Object[0];
if (parent instanceof ISchemaElement) {
Object[] types = new Object[0];
Object[] attributes = ((ISchemaElement) parent).getAttributes();
ISchemaType type = ((ISchemaElement) parent).getType();
if (type instanceof ISchemaComplexType) {
Object compositor = ((ISchemaComplexType) type).getCompositor();
if (compositor != null)
types = new Object[] {compositor};
}
children = new Object[types.length + attributes.length];
System.arraycopy(types, 0, children, 0, types.length);
System.arraycopy(attributes, 0, children, types.length, attributes.length);
} else if (parent instanceof ISchemaCompositor) {
children = ((ISchemaCompositor) parent).getChildren();
}
return children;
}
public Object getParent(Object child) {
if (child instanceof ISchemaObject)
return ((ISchemaObject) child).getParent();
return null;
}
public boolean hasChildren(Object parent) {
if (parent instanceof ISchemaAttribute || parent instanceof ISchemaObjectReference)
return false;
return getChildren(parent).length > 0;
}
}
public ElementSection(PDEFormPage page, Composite parent) {
super(page, parent, Section.DESCRIPTION, new String[] {PDEUIMessages.SchemaEditor_ElementSection_newElement, PDEUIMessages.SchemaEditor_ElementSection_newAttribute, PDEUIMessages.SchemaEditor_ElementSection_newChoice, PDEUIMessages.SchemaEditor_ElementSection_newSequence, PDEUIMessages.SchemaEditor_ElementSection_remove});
getSection().setText(PDEUIMessages.SchemaEditor_ElementSection_title);
getSection().setDescription(PDEUIMessages.SchemaEditor_ElementSection_desc);
}
public void createClient(Section section, FormToolkit toolkit) {
Composite container = createClientContainer(section, 2, toolkit);
createTree(container, toolkit);
toolkit.paintBordersFor(container);
section.setClient(container);
initialize();
createSectionToolbar(section, toolkit);
}
/**
* @param section
* @param toolkit
*/
private void createSectionToolbar(Section section, FormToolkit toolkit) {
ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
ToolBar toolbar = toolBarManager.createControl(section);
final Cursor handCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND);
toolbar.setCursor(handCursor);
// Cursor needs to be explicitly disposed
toolbar.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if ((handCursor != null) && (handCursor.isDisposed() == false)) {
handCursor.dispose();
}
}
});
// Add collapse action to the tool bar
fCollapseAction = new CollapseAction(fTreeViewer, PDEUIMessages.ExtensionsPage_collapseAll);
toolBarManager.add(fCollapseAction);
toolBarManager.update(true);
section.setTextClient(toolbar);
}
private void createTree(Composite container, FormToolkit toolkit) {
TreePart treePart = getTreePart();
createViewerPartControl(container, SWT.MULTI, 2, toolkit);
fTreeViewer = treePart.getTreeViewer();
fTreeViewer.setContentProvider(new ContentProvider());
fTreeViewer.setLabelProvider(PDEPlugin.getDefault().getLabelProvider());
PDEPlugin.getDefault().getLabelProvider().connect(this);
initDragAndDrop();
}
protected void initDragAndDrop() {
fClipboard = new Clipboard(fTreeViewer.getControl().getDisplay());
int ops = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
Transfer[] transfers = new Transfer[] {ModelDataTransfer.getInstance(), TextTransfer.getInstance()};
ElementSectionDragAdapter dragAdapter = new ElementSectionDragAdapter(fTreeViewer);
fTreeViewer.addDragSupport(ops, transfers, dragAdapter);
fTreeViewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, new ElementSectionDropAdapter(dragAdapter, this));
}
protected TreeViewer getTreeViewer() {
return fTreeViewer;
}
public void refresh() {
fTreeViewer.refresh();
super.refresh();
if (fTreeViewer.getSelection().isEmpty() && fSchema.getElementCount() > 0) {
fTreeViewer.setSelection(new StructuredSelection(fSchema.getElements()[0]));
}
}
protected void buttonSelected(int index) {
switch (index) {
case 0 :
handleNewElement();
break;
case 1 :
handleNewAttribute();
break;
case 2 :
addCompositor(ISchemaCompositor.CHOICE);
break;
case 3 :
addCompositor(ISchemaCompositor.SEQUENCE);
break;
case 4 :
final ISelection selection = fTreeViewer.getSelection();
handleDelete((IStructuredSelection) selection);
break;
}
}
private void addCompositor(int kind) {
Object selection = ((IStructuredSelection) fTreeViewer.getSelection()).getFirstElement();
ISchemaElement sourceElement = null;
Object current = selection;
while (current instanceof ISchemaCompositor)
current = ((ISchemaCompositor) current).getParent();
if (current instanceof ISchemaElement)
sourceElement = (ISchemaElement) current;
if (sourceElement != null)
new NewCompositorAction(sourceElement, selection, kind).run();
}
public void dispose() {
if (fClipboard != null) {
fClipboard.dispose();
fClipboard = null;
}
PDEPlugin.getDefault().getLabelProvider().disconnect(this);
super.dispose();
}
public boolean doGlobalAction(String actionId) {
boolean cut = actionId.equals(ActionFactory.CUT.getId());
if (cut || actionId.equals(ActionFactory.DELETE.getId())) {
// Get the current selection
IStructuredSelection sel = (IStructuredSelection) fTreeViewer.getSelection();
// Get the first selected object
Object selectedObject = sel.getFirstElement();
// Ensure we have a selection
if (selectedObject == null) {
return true;
}
handleDelete(sel);
// if cutting delete here and let the editor transfer
// the selection to the clipboard
return !cut;
}
if (actionId.equals(ActionFactory.PASTE.getId())) {
doPaste();
return true;
}
return false;
}
public boolean setFormInput(Object object) {
if (object instanceof ISchemaElement || object instanceof ISchemaAttribute || object instanceof ISchemaCompositor) {
fTreeViewer.setSelection(new StructuredSelection(object), true);
ISelection selection = fTreeViewer.getSelection();
if (selection != null && !selection.isEmpty())
return true;
if (object instanceof ISchemaElement) {
ISchemaElement found = fSchema.findElement(((ISchemaElement) object).getName());
if (found != null)
fTreeViewer.setSelection(new StructuredSelection(found), true);
return found != null;
}
}
return false;
}
protected void fillContextMenu(IMenuManager manager) {
final ISelection selection = fTreeViewer.getSelection();
final Object object = ((IStructuredSelection) selection).getFirstElement();
MenuManager submenu = new MenuManager(PDEUIMessages.Menus_new_label);
if (object == null) {
fNewElementAction.setSchema(fSchema);
fNewElementAction.setEnabled(fSchema.isEditable());
submenu.add(fNewElementAction);
}
if (object != null) {
ISchemaElement element = null;
if (object instanceof SchemaElement)
element = (SchemaElement) object;
else if (object instanceof SchemaAttribute)
element = (SchemaElement) ((SchemaAttribute) object).getParent();
if (element != null && !(element instanceof ISchemaRootElement) && !(element instanceof ISchemaObjectReference)) {
fNewAttributeAction.setElement((SchemaElement) element);
fNewAttributeAction.setEnabled(fSchema.isEditable());
submenu.add(fNewAttributeAction);
}
}
if (object instanceof SchemaElement || object instanceof SchemaCompositor) {
ISchemaElement sourceElement = null;
ISchemaObject schemaObject = (ISchemaObject) object;
while (schemaObject != null) {
if (schemaObject instanceof ISchemaElement) {
sourceElement = (ISchemaElement) schemaObject;
break;
}
schemaObject = schemaObject.getParent();
}
if (sourceElement != null) {
if (object instanceof SchemaCompositor || sourceElement.getType() instanceof ISchemaSimpleType || ((ISchemaComplexType) sourceElement.getType()).getCompositor() == null) {
if (submenu.getItems().length > 0)
submenu.add(new Separator());
submenu.add(new NewCompositorAction(sourceElement, object, ISchemaCompositor.CHOICE));
submenu.add(new NewCompositorAction(sourceElement, object, ISchemaCompositor.SEQUENCE));
}
if (object instanceof SchemaCompositor) {
boolean seperatorAdded = false;
ISchemaElement[] elements = sourceElement.getSchema().getResolvedElements();
Arrays.sort(elements);
for (int i = 0; i < elements.length; i++) {
if (!(elements[i] instanceof SchemaRootElement)) {
if (!seperatorAdded) {
submenu.add(new Separator());
seperatorAdded = true;
}
submenu.add(new NewReferenceAction(sourceElement, object, elements[i]));
}
}
}
}
}
manager.add(submenu);
if (object != null) {
if (!(object instanceof ISchemaRootElement)) {
if (manager.getItems().length > 0)
manager.add(new Separator());
if (!(object instanceof ISchemaAttribute && ((ISchemaAttribute) object).getParent() instanceof ISchemaRootElement)) {
Action deleteAction = new Action() {
public void run() {
handleDelete((IStructuredSelection) selection);
}
};
deleteAction.setText(PDEUIMessages.Actions_delete_label);
deleteAction.setEnabled(fSchema.isEditable());
manager.add(deleteAction);
}
}
}
getPage().getPDEEditor().getContributor().contextMenuAboutToShow(manager);
manager.add(new Separator());
}
private void handleDelete(IStructuredSelection selection) {
IStructuredSelection nextSelection = null;
Object selectionSource = null;
for (Iterator iter = selection.iterator(); iter.hasNext();) {
Object thisObject = iter.next();
// Do the delete and generate a new selection in one of the following cases:
// 1. No selection has been generated
// 2. This object is higher up in the hierarchy than the previous
// object used to generate the selection
// 3. The object selected for deletion is currently set as the next selection
IStructuredSelection result = handleDelete(thisObject, nextSelection == null || schemaObjectHigherThan(thisObject, selectionSource) || nextSelection.getFirstElement().equals(thisObject));
if (result != null) {
nextSelection = result;
selectionSource = thisObject;
}
}
if (nextSelection != null)
getTreeViewer().setSelection(nextSelection);
}
private IStructuredSelection handleDelete(Object object, boolean generateSelection) {
IStructuredSelection newSelection = null;
if (!isEditable()) {
Display.getCurrent().beep();
} else if (object instanceof ISchemaRootElement) {
// Semantic rule: The root "extension" element of a schema
// cannot be removed
// Produce audible beep
Display.getCurrent().beep();
} else if (object instanceof SchemaElementReference) {
newSelection = handleReferenceDelete((SchemaElementReference) object, generateSelection);
} else if (object instanceof ISchemaElement) {
newSelection = handleElementDelete((ISchemaElement) object, generateSelection);
} else if (object instanceof ISchemaAttribute) {
ISchemaAttribute att = (ISchemaAttribute) object;
if (!(att.getParent() instanceof ISchemaRootElement)) {
newSelection = handleAttributeDelete(att, generateSelection);
} else {
// Semantic rule: Attributes of the root "extension" element
// of a schema cannot be removed
// Produce audible beep
Display.getCurrent().beep();
}
} else if (object instanceof ISchemaCompositor) {
newSelection = handleCompositorDelete((ISchemaCompositor) object, generateSelection);
}
return newSelection;
}
private IStructuredSelection handleReferenceDelete(SchemaElementReference ref, boolean generateSelection) {
IStructuredSelection newSelection = null;
if (generateSelection) {
SchemaCompositor parent = (SchemaCompositor) ref.getParent();
ISchemaObject[] children = parent.getChildren();
int index = getNewSelectionIndex(getArrayIndex(children, ref), children.length);
if (index == -1)
newSelection = new StructuredSelection(parent);
else
newSelection = new StructuredSelection(children[index]);
}
fRearranger.deleteReference(ref);
return newSelection;
}
private IStructuredSelection handleElementDelete(ISchemaElement element, boolean generateSelection) {
IStructuredSelection newSelection = null;
if (generateSelection) {
ISchema parent = element.getSchema();
ISchemaElement[] children = parent.getElements();
int index = getNewSelectionIndex(getArrayIndex(children, element), children.length);
if (index != -1)
newSelection = new StructuredSelection(children[index]);
}
fRearranger.deleteElement(element);
return newSelection;
}
private IStructuredSelection handleAttributeDelete(ISchemaAttribute att, boolean generateSelection) {
IStructuredSelection newSelection = null;
if (generateSelection) {
ISchemaElement parent = (ISchemaElement) att.getParent();
ISchemaAttribute[] children = parent.getAttributes();
int index = getNewSelectionIndex(getArrayIndex(children, att), children.length);
if (index == -1) {
ISchemaType type = parent.getType();
if (type instanceof ISchemaComplexType) {
ISchemaCompositor comp = ((ISchemaComplexType) type).getCompositor();
if (comp != null)
newSelection = new StructuredSelection(comp);
else
newSelection = new StructuredSelection(parent);
}
} else
newSelection = new StructuredSelection(children[index]);
}
fRearranger.deleteAttribute(att);
return newSelection;
}
private IStructuredSelection handleCompositorDelete(ISchemaCompositor comp, boolean generateSelection) {
IStructuredSelection newSelection = null;
if (generateSelection) {
ISchemaObject parent = comp.getParent();
if (parent instanceof ISchemaElement) {
ISchemaElement element = (ISchemaElement) parent;
ISchemaAttribute[] attributes = element.getAttributes();
if (attributes.length > 0)
newSelection = new StructuredSelection(attributes[0]);
else
newSelection = new StructuredSelection(element);
} else {
ISchemaCompositor parentComp = (ISchemaCompositor) parent;
ISchemaObject[] children = parentComp.getChildren();
int index = getNewSelectionIndex(getArrayIndex(children, comp), children.length);
if (index == -1)
newSelection = new StructuredSelection(parent);
else
newSelection = new StructuredSelection(children[index]);
}
}
fRearranger.deleteCompositor(comp);
return newSelection;
}
// returns true if object a is a SchemaObject higher in the hierarchy than object b
// returns false if b is higher or they are equal
private boolean schemaObjectHigherThan(Object a, Object b) {
if (!(b instanceof ISchemaObject))
return true;
if (!(a instanceof ISchemaObject))
return false;
return (computeNestLevel((ISchemaObject) a) < computeNestLevel((ISchemaObject) b));
}
// determines how deeply nested an ISchemaObject is
// returns 0 if this is an element, 1 if it's a direct child, etc.
private int computeNestLevel(ISchemaObject o) {
int result = 0;
while ((o instanceof SchemaElementReference) || !(o instanceof ISchemaElement)) {
o = o.getParent();
result++;
}
return result;
}
private void handleNewAttribute() {
Object object = ((IStructuredSelection) fTreeViewer.getSelection()).getFirstElement();
if (object != null) {
SchemaElement element = null;
if (object instanceof SchemaElement)
element = (SchemaElement) object;
else if (object instanceof SchemaAttribute)
element = (SchemaElement) ((SchemaAttribute) object).getParent();
if (element != null && !(element instanceof ISchemaRootElement)) {
fNewAttributeAction.setElement(element);
fNewAttributeAction.run();
}
}
}
private void handleNewElement() {
fNewElementAction.setSchema(fSchema);
fNewElementAction.run();
}
public void initialize() {
this.fSchema = (Schema) getPage().getModel();
fRearranger = new SchemaRearranger(fSchema);
fTreeViewer.setInput(fSchema);
boolean isEditable = fSchema.isEditable();
getTreePart().setButtonEnabled(0, isEditable);
getTreePart().setButtonEnabled(1, false);
getTreePart().setButtonEnabled(2, isEditable);
getTreePart().setButtonEnabled(3, isEditable);
getTreePart().setButtonEnabled(4, isEditable);
}
public void handleModelChanged(IModelChangedEvent e) {
if (e.getChangedProperty() != null && e.getChangedProperty().equals(ISchemaObject.P_DESCRIPTION))
return;
if (e.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
handleModelEventWorldChanged(e);
return;
}
Object[] objects = e.getChangedObjects();
for (int i = 0; i < objects.length; i++) {
Object obj = objects[0];
if (obj instanceof SchemaElementReference) {
fTreeViewer.refresh(((SchemaElementReference) obj).getCompositor());
if (e.getChangeType() == IModelChangedEvent.INSERT)
fTreeViewer.setSelection(new StructuredSelection(obj), true);
} else if (obj instanceof ISchemaElement || obj instanceof ISchemaAttribute) {
if (e.getChangeType() == IModelChangedEvent.CHANGE) {
String changeProp = e.getChangedProperty();
if (changeProp != null && (changeProp.equals(ISchemaObject.P_NAME) || changeProp.equals(SchemaAttribute.P_KIND)))
fTreeViewer.update(obj, null);
Object typeCheck = e.getNewValue();
if (typeCheck instanceof ISchemaComplexType && changeProp.equals(SchemaElement.P_TYPE) && obj instanceof ISchemaElement) {
fTreeViewer.refresh(typeCheck);
fTreeViewer.setSelection(new StructuredSelection(typeCheck), true);
} else {
fTreeViewer.refresh(obj);
}
} else if (e.getChangeType() == IModelChangedEvent.INSERT) {
ISchemaObject sobj = (ISchemaObject) obj;
ISchemaObject parent = sobj.getParent();
fTreeViewer.refresh(parent);
fTreeViewer.setSelection(new StructuredSelection(obj), true);
} else if (e.getChangeType() == IModelChangedEvent.REMOVE) {
fTreeViewer.remove(obj);
// the new selection is handled by the handleDelete method for cuts and deletes,
// for moves it is handled by the subsequent insert
}
} else if (obj instanceof ISchemaCompositor || obj instanceof ISchemaObjectReference) {
final ISchemaObject sobj = (ISchemaObject) obj;
ISchemaObject parent = sobj.getParent();
if (e.getChangeType() == IModelChangedEvent.CHANGE) {
fTreeViewer.refresh(sobj);
} else if (e.getChangeType() == IModelChangedEvent.INSERT) {
fTreeViewer.add(parent, sobj);
fTreeViewer.getTree().getDisplay().asyncExec(new Runnable() {
public void run() {
fTreeViewer.setSelection(new StructuredSelection(sobj), true);
}
});
} else if (e.getChangeType() == IModelChangedEvent.REMOVE) {
fTreeViewer.remove(sobj);
// the new selection is handled by the handleDelete method for cuts and deletes,
// for moves it is handled by the subsequent insert
}
} else if (obj instanceof ISchemaComplexType) {
// first compositor added/removed
ISchemaCompositor comp = ((ISchemaComplexType) obj).getCompositor();
fTreeViewer.refresh(comp);
if (comp != null)
fTreeViewer.refresh(comp.getParent());
if (e.getChangeType() == IModelChangedEvent.INSERT || e.getChangeType() == IModelChangedEvent.CHANGE) {
ISchemaComplexType type = (ISchemaComplexType) obj;
final ISchemaCompositor compositor = type.getCompositor();
if (compositor != null) {
fTreeViewer.getTree().getDisplay().asyncExec(new Runnable() {
public void run() {
fTreeViewer.setSelection(new StructuredSelection(compositor), true);
}
});
}
}
} else if (obj instanceof ISchema) {
if (!ISchemaObject.P_NAME.equals(e.getChangedProperty()))
fTreeViewer.refresh();
}
}
}
/**
* @param event
*/
private void handleModelEventWorldChanged(IModelChangedEvent event) {
// Note: Cannot use event. There are no changed objects within it
// This method acts like a refresh
initialize();
// TODO: MP: REVERT: LOW: Update initialize with this once Bug #171897 is fixed
ISchemaElement root = fSchema.getSchema().findElement(ICoreConstants.EXTENSION_NAME);
// Ensure the root element is present
if (root == null) {
return;
}
// Select the root extension element
fTreeViewer.setSelection(new StructuredSelection(root), true);
// Collapse tree to the first level
fTreeViewer.expandToLevel(1);
}
protected void selectionChanged(IStructuredSelection selection) {
// getPage().getManagedForm().fireSelectionChanged(this, selection);
getPage().getPDEEditor().setSelection(selection);
updateButtons();
}
/* (non-Javadoc)
* @see org.eclipse.pde.internal.ui.editor.StructuredViewerSection#setFocus()
*/
public void setFocus() {
if (fTreeViewer != null) {
fTreeViewer.getTree().setFocus();
getPage().getPDEEditor().setSelection(fTreeViewer.getSelection());
}
}
private void updateButtons() {
if (!fSchema.isEditable())
return;
IStructuredSelection selection = (IStructuredSelection) fTreeViewer.getSelection();
ISchemaObject sobject = (ISchemaObject) selection.getFirstElement();
boolean canAddAttribute = false;
if (sobject instanceof ISchemaElement) {
if (!(sobject instanceof ISchemaRootElement) && !(sobject instanceof ISchemaObjectReference))
canAddAttribute = true;
} else if (sobject instanceof ISchemaAttribute) {
ISchemaElement element = (ISchemaElement) (sobject.getParent());
if (!(element instanceof ISchemaRootElement))
canAddAttribute = true;
}
getTreePart().setButtonEnabled(1, canAddAttribute);
boolean canAddCompositor = false;
if (sobject instanceof ISchemaCompositor || (sobject instanceof ISchemaElement && !(sobject instanceof SchemaElementReference) && (((ISchemaElement) sobject).getType() instanceof ISchemaSimpleType || ((ISchemaComplexType) ((ISchemaElement) sobject).getType()).getCompositor() == null)))
canAddCompositor = true;
getTreePart().setButtonEnabled(2, canAddCompositor);
getTreePart().setButtonEnabled(3, canAddCompositor);
boolean canRemove = false;
for (Iterator iter = selection.iterator(); iter.hasNext();) {
sobject = (ISchemaObject) iter.next();
if (sobject != null && !(sobject instanceof ISchemaRootElement) && !(sobject instanceof ISchemaAttribute && sobject.getParent() instanceof ISchemaRootElement)) {
canRemove = true;
break;
}
}
getTreePart().setButtonEnabled(4, canRemove);
}
private ISchemaObject getSibling(Object target, Object object) {
if (target instanceof ISchemaElement && object instanceof ISchemaElement)
return (ISchemaElement) target;
if (target instanceof ISchemaAttribute && object instanceof ISchemaAttribute)
return (ISchemaAttribute) target;
if (target instanceof SchemaElementReference && object instanceof ISchemaElement)
return (SchemaElementReference) target;
return null;
}
private ISchemaObject getRealTarget(Object target, Object object) {
if (object instanceof ISchemaElement || object instanceof ISchemaObjectReference) {
if (target instanceof SchemaElementReference)
return ((SchemaElementReference) target).getCompositor();
if (target instanceof ISchemaCompositor)
return (ISchemaCompositor) target;
if (object instanceof ISchemaElement)
return fSchema;
}
if (object instanceof ISchemaAttribute) {
if (target instanceof ISchemaAttribute) {
// add it to the parent of the selected attribute
return ((ISchemaAttribute) target).getParent();
}
if (target instanceof ISchemaElement)
return (ISchemaElement) target;
}
if (object instanceof ISchemaCompositor) {
if (target instanceof SchemaElementReference)
return ((SchemaElementReference) target).getCompositor();
if (target instanceof ISchemaElement)
return (ISchemaElement) target;
if (target instanceof ISchemaCompositor)
return (ISchemaCompositor) target;
}
return null;
}
protected boolean canPaste(Object target, Object[] objects) {
for (int i = 0; i < objects.length; i++) {
Object obj = objects[i];
if (obj instanceof ISchemaAttribute && target instanceof ISchemaAttribute) {
continue;
} else if (obj instanceof ISchemaObjectReference && target instanceof ISchemaCompositor) {
continue;
} else if (target instanceof ISchemaElement && !(target instanceof ISchemaObjectReference) && !(obj instanceof ISchemaRootElement)) {
continue;
}
return false;
}
return true;
}
protected void handleDoubleClick(IStructuredSelection selection) {
super.handleDoubleClick(selection);
Object object = selection.getFirstElement();
if (object instanceof SchemaElementReference) {
ISchemaElement element = ((SchemaElementReference) object).getReferencedElement();
if (element == null) {
String name = ((SchemaElementReference) object).getName();
MessageDialog.openWarning(getPage().getSite().getShell(), PDEUIMessages.ElementSection_missingRefElement, NLS.bind(PDEUIMessages.SchemaIncludesSection_missingWarningMessage, name));
return;
}
ISchema schema = element.getSchema();
if (schema.equals(fSchema))
fireSelection(new StructuredSelection(element));
else {
ISchemaInclude[] includes = fSchema.getIncludes();
for (int i = 0; i < includes.length; i++) {
if (includes[i].getIncludedSchema().equals(schema)) {
String location = includes[i].getLocation();
SchemaEditor.openToElement(new Path(location), element);
break;
}
}
}
}
}
protected void fireSelection(ISelection selection) {
if (selection == null)
selection = fTreeViewer.getSelection();
fTreeViewer.setSelection(selection);
}
protected void doPaste(Object target, Object[] objects) {
handleOp(target, objects, DND.DROP_COPY);
}
public void handleOp(Object currentTarget, Object[] objects, int currentOperation) {
for (int i = 0; i < objects.length; i++) {
if (!(objects[i] instanceof ISchemaObject))
continue;
ISchemaObject object = (ISchemaObject) objects[i];
ISchemaObject realTarget = getRealTarget(currentTarget, object);
ISchemaObject sibling = getSibling(currentTarget, object);
if (realTarget == null)
continue;
switch (currentOperation) {
case DND.DROP_COPY :
doPaste(realTarget, sibling, object);
break;
case DND.DROP_MOVE :
doMove(realTarget, sibling, object);
break;
case DND.DROP_LINK :
doLink(realTarget, sibling, object);
break;
}
}
}
private void doLink(ISchemaObject realTarget, ISchemaObject sibling, ISchemaObject object) {
if (realTarget instanceof ISchemaCompositor && object instanceof ISchemaElement) {
fRearranger.linkReference((ISchemaCompositor) realTarget, (ISchemaElement) object, sibling);
}
}
private void doMove(ISchemaObject realTarget, ISchemaObject sibling, ISchemaObject object) {
if (object instanceof ISchemaCompositor) {
fRearranger.moveCompositor(realTarget, (ISchemaCompositor) object);
} else if (object instanceof SchemaElementReference) {
fRearranger.moveReference((SchemaElementReference) object, (ISchemaCompositor) realTarget, sibling);
} else if (object instanceof ISchemaElement) {
fRearranger.moveElement(realTarget, (ISchemaElement) object, sibling);
} else if (object instanceof ISchemaAttribute) {
fRearranger.moveAttribute((ISchemaElement) realTarget, (ISchemaAttribute) object, sibling != null ? (ISchemaAttribute) sibling : null);
}
}
private void doPaste(ISchemaObject realTarget, ISchemaObject sibling, ISchemaObject object) {
if (object instanceof ISchemaCompositor) {
fRearranger.pasteCompositor(realTarget, (ISchemaCompositor) object, sibling);
} else if (object instanceof SchemaElementReference) {
fRearranger.pasteReference(realTarget, (SchemaElementReference) object, sibling);
} else if (object instanceof ISchemaElement) {
fRearranger.pasteElement((ISchemaElement) object, sibling);
} else if (object instanceof ISchemaAttribute) {
fRearranger.pasteAttribute((ISchemaElement) realTarget, (ISchemaAttribute) object, sibling);
}
}
}