[146877] [ACC] Need keyboard equivalent of drag and drop
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/BaseDragAndDropCommand.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/BaseDragAndDropCommand.java
index a0baa3e..84a8ef4 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/BaseDragAndDropCommand.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/BaseDragAndDropCommand.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 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
@@ -19,6 +19,7 @@
 import org.eclipse.draw2d.Graphics;
 import org.eclipse.draw2d.IFigure;
 import org.eclipse.draw2d.Polyline;
+import org.eclipse.draw2d.PositionConstants;
 import org.eclipse.draw2d.RoundedRectangle;
 import org.eclipse.draw2d.geometry.Point;
 import org.eclipse.draw2d.geometry.PointList;
@@ -413,4 +414,17 @@
     return new Rectangle(x, y, width, height);
   }
 
+  protected void handleKeyboardDragAndDrop(XSDBaseFieldEditPart leftField, XSDBaseFieldEditPart rightField, int direction)
+  {
+    target = leftField;
+    if (direction == PositionConstants.SOUTH)
+    {
+      if (itemToDrag == target)
+        return;
+      target = rightField;
+    }
+    this.location = null;
+    if (target != null)
+      this.location = target.getFigure().getBounds().getCenter();
+  }
 }
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/XSDAttributeDragAndDropCommand.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/XSDAttributeDragAndDropCommand.java
index bd4a191..2822f61 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/XSDAttributeDragAndDropCommand.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/XSDAttributeDragAndDropCommand.java
@@ -14,6 +14,7 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.eclipse.draw2d.PositionConstants;
 import org.eclipse.draw2d.geometry.Point;
 import org.eclipse.gef.EditPart;
 import org.eclipse.gef.EditPartViewer;
@@ -21,6 +22,7 @@
 import org.eclipse.gef.requests.ChangeBoundsRequest;
 import org.eclipse.wst.xsd.ui.internal.actions.MoveXSDAttributeAction;
 import org.eclipse.wst.xsd.ui.internal.adapters.XSDAttributeDeclarationAdapter;
+import org.eclipse.wst.xsd.ui.internal.adapters.XSDWildcardAdapter;
 import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.BaseFieldEditPart;
 import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.CompartmentEditPart;
 import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.ComplexTypeEditPart;
@@ -31,6 +33,7 @@
 import org.eclipse.wst.xsd.ui.internal.design.figures.GenericGroupFigure;
 import org.eclipse.xsd.XSDAttributeDeclaration;
 import org.eclipse.xsd.XSDConcreteComponent;
+import org.eclipse.xsd.XSDWildcard;
 
 public class XSDAttributeDragAndDropCommand extends BaseDragAndDropCommand
 {
@@ -43,6 +46,35 @@
     setup();
   }
 
+  public XSDAttributeDragAndDropCommand(XSDBaseFieldEditPart itemToDrag, XSDBaseFieldEditPart leftField, XSDBaseFieldEditPart rightField, int direction)
+  {
+    super(itemToDrag.getViewer(), null); 
+    this.itemToDrag = itemToDrag;
+    canExecute = false;
+    handleKeyboardDragAndDrop(leftField, rightField, direction);
+  }
+  
+  protected void handleKeyboardDragAndDrop(XSDBaseFieldEditPart leftField, XSDBaseFieldEditPart rightField, int direction)
+  {
+    super.handleKeyboardDragAndDrop(leftField, rightField, direction);
+    if (direction == PositionConstants.NORTH)
+    {
+      if (target == null)
+      {
+        target = rightField;
+        this.location = target.getFigure().getBounds().getTop();
+      }
+      else if (!(leftField.getModel() instanceof XSDAttributeDeclarationAdapter)
+                 || leftField.getModel() instanceof XSDWildcardAdapter)
+      {
+        target = rightField;
+        this.location = target.getFigure().getBounds().getTop();
+      }
+    }
+    setup();
+  }
+
+  
   protected void setup()
   {
     canExecute = false;
@@ -74,18 +106,19 @@
   {
     commonSetup(siblings, movingEditPart);
 
-    if (previousRefComponent instanceof XSDAttributeDeclaration && nextRefComponent instanceof XSDAttributeDeclaration)
+    if ((previousRefComponent instanceof XSDAttributeDeclaration || previousRefComponent instanceof XSDWildcard) 
+        && (nextRefComponent instanceof XSDAttributeDeclaration || nextRefComponent instanceof XSDWildcard))
     {
-      XSDConcreteComponent parent = ((XSDAttributeDeclaration) previousRefComponent).getContainer().getContainer();
+      XSDConcreteComponent parent = previousRefComponent.getContainer().getContainer();
       if (closerSibling == BELOW_IS_CLOSER)
       {
-        parent = ((XSDAttributeDeclaration) nextRefComponent).getContainer().getContainer();
+        parent = nextRefComponent.getContainer().getContainer();
       }
       action = new MoveXSDAttributeAction(parent, xsdComponentToDrag, previousRefComponent, nextRefComponent);
     }
-    else if (previousRefComponent == null && nextRefComponent instanceof XSDAttributeDeclaration)
+    else if (previousRefComponent == null && (nextRefComponent instanceof XSDAttributeDeclaration || nextRefComponent instanceof XSDWildcard))
     {
-      XSDConcreteComponent parent = ((XSDAttributeDeclaration) nextRefComponent).getContainer().getContainer();
+      XSDConcreteComponent parent = nextRefComponent.getContainer().getContainer();
       if (closerSibling == ABOVE_IS_CLOSER)
       {
         if (leftSiblingEditPart == null)
@@ -104,7 +137,7 @@
     }
     else if (previousRefComponent instanceof XSDAttributeDeclaration && nextRefComponent == null)
     {
-      XSDConcreteComponent parent = ((XSDAttributeDeclaration) previousRefComponent).getContainer().getContainer();
+      XSDConcreteComponent parent = previousRefComponent.getContainer().getContainer();
       if (closerSibling == ABOVE_IS_CLOSER)
       {
         action = new MoveXSDAttributeAction(parent, xsdComponentToDrag, previousRefComponent, nextRefComponent);
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/XSDElementDragAndDropCommand.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/XSDElementDragAndDropCommand.java
index 3bb6b7c..84fb6db 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/XSDElementDragAndDropCommand.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/commands/XSDElementDragAndDropCommand.java
@@ -14,6 +14,7 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.eclipse.draw2d.PositionConstants;
 import org.eclipse.draw2d.geometry.Point;
 import org.eclipse.gef.EditPart;
 import org.eclipse.gef.EditPartViewer;
@@ -21,6 +22,7 @@
 import org.eclipse.gef.requests.ChangeBoundsRequest;
 import org.eclipse.wst.xsd.ui.internal.actions.MoveXSDElementAction;
 import org.eclipse.wst.xsd.ui.internal.adapters.XSDElementDeclarationAdapter;
+import org.eclipse.wst.xsd.ui.internal.adapters.XSDWildcardAdapter;
 import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.BaseFieldEditPart;
 import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.CompartmentEditPart;
 import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.ComplexTypeEditPart;
@@ -34,6 +36,7 @@
 import org.eclipse.xsd.XSDConcreteComponent;
 import org.eclipse.xsd.XSDElementDeclaration;
 import org.eclipse.xsd.XSDModelGroup;
+import org.eclipse.xsd.XSDWildcard;
 
 
 public class XSDElementDragAndDropCommand extends BaseDragAndDropCommand
@@ -48,6 +51,34 @@
     this.location = location;
     setup();
   }
+  
+  public XSDElementDragAndDropCommand(XSDBaseFieldEditPart itemToDrag, XSDBaseFieldEditPart leftField, XSDBaseFieldEditPart rightField, int direction)
+  {
+    super(itemToDrag.getViewer(), null); 
+    this.itemToDrag = itemToDrag;
+    canExecute = false;
+    handleKeyboardDragAndDrop(leftField, rightField, direction);
+  }
+  
+  protected void handleKeyboardDragAndDrop(XSDBaseFieldEditPart leftField, XSDBaseFieldEditPart rightField, int direction)
+  {
+    super.handleKeyboardDragAndDrop(leftField, rightField, direction);
+    if (direction == PositionConstants.NORTH)
+    {
+      if (target == null)
+      {
+        target = rightField;
+        this.location = target.getFigure().getBounds().getTop();
+      }
+      else if (!(leftField.getModel() instanceof XSDElementDeclarationAdapter)
+                 || leftField.getModel() instanceof XSDWildcardAdapter)
+      {
+        target = rightField;
+        this.location = target.getFigure().getBounds().getTop();
+      }
+    }
+    setup();
+  }
 
   protected void setup()
   {
@@ -80,14 +111,15 @@
     commonSetup(siblings, movingEditPart);
 
     // Can common this code up with XSDAttributeDragAndDropCommand... 
-    if (previousRefComponent instanceof XSDElementDeclaration && nextRefComponent instanceof XSDElementDeclaration)
+    if ((previousRefComponent instanceof XSDElementDeclaration || previousRefComponent instanceof XSDWildcard)
+        && (nextRefComponent instanceof XSDElementDeclaration || nextRefComponent instanceof XSDWildcard)) 
     {
-      XSDModelGroup modelGroup = (XSDModelGroup) ((XSDElementDeclaration) previousRefComponent).getContainer().getContainer();
+      XSDModelGroup modelGroup = (XSDModelGroup) previousRefComponent.getContainer().getContainer();
       if (parentEditPart != null)
         modelGroup = ((ModelGroupEditPart) parentEditPart).getXSDModelGroup();
       action = new MoveXSDElementAction(modelGroup, xsdComponentToDrag, previousRefComponent, nextRefComponent);
     }
-    else if (previousRefComponent == null && nextRefComponent instanceof XSDElementDeclaration)
+    else if (previousRefComponent == null && (nextRefComponent instanceof XSDElementDeclaration || nextRefComponent instanceof XSDWildcard))
     {
       if (closerSibling == ABOVE_IS_CLOSER)
       {
@@ -102,13 +134,14 @@
       }
       else
       {
-        XSDModelGroup modelGroup = (XSDModelGroup) ((XSDElementDeclaration) nextRefComponent).getContainer().getContainer();
+        XSDModelGroup modelGroup = (XSDModelGroup) nextRefComponent.getContainer().getContainer();
         action = new MoveXSDElementAction(modelGroup, xsdComponentToDrag, previousRefComponent, nextRefComponent);
       }
     }
-    else if (previousRefComponent instanceof XSDElementDeclaration && nextRefComponent == null)
+    else if ((previousRefComponent instanceof XSDElementDeclaration || previousRefComponent instanceof XSDWildcard)  
+        && nextRefComponent == null)
     {
-      XSDModelGroup modelGroup = (XSDModelGroup) ((XSDElementDeclaration) previousRefComponent).getContainer().getContainer();
+      XSDModelGroup modelGroup = (XSDModelGroup)previousRefComponent.getContainer().getContainer();
       if (parentEditPart != null)
         modelGroup = ((ModelGroupEditPart) parentEditPart).getXSDModelGroup();
       if (closerSibling == ABOVE_IS_CLOSER)
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/InternalXSDMultiPageEditor.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/InternalXSDMultiPageEditor.java
index 9b7a648..3133251 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/InternalXSDMultiPageEditor.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/InternalXSDMultiPageEditor.java
@@ -75,6 +75,7 @@
 import org.eclipse.wst.xsd.ui.internal.adt.actions.SetInputToGraphView;
 import org.eclipse.wst.xsd.ui.internal.adt.actions.ShowPropertiesViewAction;
 import org.eclipse.wst.xsd.ui.internal.adt.design.DesignViewGraphicalViewer;
+import org.eclipse.wst.xsd.ui.internal.adt.design.IKeyboardDrag;
 import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.RootContentEditPart;
 import org.eclipse.wst.xsd.ui.internal.adt.editor.ADTMultiPageEditor;
 import org.eclipse.wst.xsd.ui.internal.adt.editor.EditorMode;
@@ -318,6 +319,10 @@
     {
       return xsdSchema;
     }
+    else if (type == IKeyboardDrag.class)
+    {
+      return new KeyboardDragImpl();
+    }
     else if (type == IContentOutlinePage.class)
     {
       Object adapter = super.getAdapter(type);
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/KeyboardDragImpl.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/KeyboardDragImpl.java
index d8fb847..a5dc0fa 100644
--- a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/KeyboardDragImpl.java
+++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/editor/KeyboardDragImpl.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2006 IBM Corporation and others.
+ * Copyright (c) 2001, 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
@@ -10,12 +10,68 @@
  *******************************************************************************/
 package org.eclipse.wst.xsd.ui.internal.editor;
 
+import org.eclipse.gef.EditPart;
 import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.xsd.ui.internal.adapters.XSDAttributeDeclarationAdapter;
+import org.eclipse.wst.xsd.ui.internal.adapters.XSDElementDeclarationAdapter;
 import org.eclipse.wst.xsd.ui.internal.adt.design.IKeyboardDrag;
+import org.eclipse.wst.xsd.ui.internal.adt.design.editpolicies.KeyBoardAccessibilityEditPolicy;
+import org.eclipse.wst.xsd.ui.internal.commands.BaseDragAndDropCommand;
+import org.eclipse.wst.xsd.ui.internal.commands.XSDAttributeDragAndDropCommand;
+import org.eclipse.wst.xsd.ui.internal.commands.XSDElementDragAndDropCommand;
+import org.eclipse.wst.xsd.ui.internal.design.editparts.XSDBaseFieldEditPart;
+import org.eclipse.xsd.XSDWildcard;
 
-public class KeyboardDragImpl implements IKeyboardDrag {
+public class KeyboardDragImpl implements IKeyboardDrag
+{
+  public void performKeyboardDrag(GraphicalEditPart movingElement, int direction)
+  {
+    KeyBoardAccessibilityEditPolicy policy = (KeyBoardAccessibilityEditPolicy) movingElement.getEditPolicy(KeyBoardAccessibilityEditPolicy.KEY);
 
-	public void performKeyboardDrag(GraphicalEditPart movingElement, int direction) {
+    EditPart rightElement = policy.getRelativeEditPart(movingElement, direction);
+    policy = (KeyBoardAccessibilityEditPolicy) rightElement.getEditPolicy(KeyBoardAccessibilityEditPolicy.KEY);
+    EditPart leftElement = (policy != null) ? policy.getRelativeEditPart(rightElement, direction) : null;
 
-	}
+    XSDBaseFieldEditPart movingField = (XSDBaseFieldEditPart) movingElement;
+    XSDBaseFieldEditPart leftField = (XSDBaseFieldEditPart) leftElement;
+    XSDBaseFieldEditPart rightField = (XSDBaseFieldEditPart) rightElement;
+    
+    Object movingObject = movingField.getModel();
+    
+    BaseDragAndDropCommand command = null;
+    if (movingObject instanceof XSDElementDeclarationAdapter || movingObject instanceof XSDWildcard)
+    {
+      command = new XSDElementDragAndDropCommand(movingField, leftField, rightField, direction);
+    }
+    else if (movingObject instanceof XSDAttributeDeclarationAdapter)
+    {
+      command = new XSDAttributeDragAndDropCommand(movingField, leftField, rightField, direction);
+    }
+    
+    if (command != null && command.canExecute())
+    {
+      command.execute();
+      // This is to reselect the moved item
+      try
+      {
+        IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
+        if (editor != null && editor.getAdapter(ISelectionProvider.class) != null)
+        {
+          ISelectionProvider provider = (ISelectionProvider) editor.getAdapter(ISelectionProvider.class);
+          if (provider != null)
+          {
+            provider.setSelection(new StructuredSelection(movingElement.getModel()));
+          }
+        }
+      }
+      catch (Exception e)
+      {
+
+      }
+    }
+  }
 }