Bug 287235 -  Provide an API to activate direct edit
diff --git a/examples/gef/org.eclipse.gef.examples.logic.test/META-INF/MANIFEST.MF b/examples/gef/org.eclipse.gef.examples.logic.test/META-INF/MANIFEST.MF
index 369f61b..5f3b888 100644
--- a/examples/gef/org.eclipse.gef.examples.logic.test/META-INF/MANIFEST.MF
+++ b/examples/gef/org.eclipse.gef.examples.logic.test/META-INF/MANIFEST.MF
@@ -13,4 +13,7 @@
  org.eclipse.swt,
  org.eclipse.ui,
  org.eclipse.osgi,
- org.hamcrest
+ org.hamcrest,
+ org.eclipse.gef,
+ org.eclipse.core.runtime,
+ org.apache.log4j
diff --git a/examples/gef/org.eclipse.gef.examples.logic.test/src/org/eclipse/gef/examples/logic/test/OpenGefEditorTest.java b/examples/gef/org.eclipse.gef.examples.logic.test/src/org/eclipse/gef/examples/logic/test/OpenGefEditorTest.java
index 6ba0fe1..9f1d9b4 100644
--- a/examples/gef/org.eclipse.gef.examples.logic.test/src/org/eclipse/gef/examples/logic/test/OpenGefEditorTest.java
+++ b/examples/gef/org.eclipse.gef.examples.logic.test/src/org/eclipse/gef/examples/logic/test/OpenGefEditorTest.java
@@ -11,9 +11,16 @@
 
 package org.eclipse.gef.examples.logic.test;
 
+import java.util.List;
+
+import org.eclipse.gef.examples.logicdesigner.edit.LogicLabelEditPart;
+import org.eclipse.gef.examples.logicdesigner.model.LogicLabel;
 import org.eclipse.swtbot.eclipse.gef.finder.SWTBotGefTestCase;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
 import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor;
 import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.matchers.AbstractMatcher;
+import org.hamcrest.Description;
 
 public class OpenGefEditorTest extends SWTBotGefTestCase {
 
@@ -42,16 +49,6 @@
 		bot.menu("File").menu("Save").click();
 	}
 
-
-	public void testCreateMFile() throws Exception {
-		emfProject.createProject("testM");
-		logicDiagram.createMFile("testM", "test.logicm");
-		final SWTBotGefEditor editor = bot.gefEditor("Logic M Graphical Editor");	
-		createContents(editor);
-		saveCurrentEditor();
-		bot.sleep(3000);	
-	}
-
 	public void testCreateFile() throws Exception {
 
 		emfProject.createProject("test");
@@ -62,6 +59,15 @@
 		bot.sleep(3000);	
 	}
 
+//	public void testCreateMFile() throws Exception {
+//		emfProject.createProject("testM");
+//		logicDiagram.createMFile("testM", "test.logicm");
+//		final SWTBotGefEditor editor = bot.gefEditor("Logic M Graphical Editor");	
+//		createContents(editor);
+//		saveCurrentEditor();
+//		bot.sleep(3000);	
+//	}
+
 	private void createContents(final SWTBotGefEditor editor) {
 
 		editor.activateTool("Circuit");
@@ -89,6 +95,26 @@
 
 		editor.mouseMoveLeftClick(200, 200);
 		editor.mouseMoveLeftClick(230, 230);
+		
+		editor.activateTool("Label");
+		editor.mouseMoveLeftClick(300, 300);
+		List<SWTBotGefEditPart> editParts = editor.editParts(new AbstractMatcher<LogicLabelEditPart>() {
+			@Override
+			protected boolean doMatch(Object item) {
+				if (!(item instanceof LogicLabelEditPart)) {
+					return false;
+				}
+				LogicLabelEditPart editPart = (LogicLabelEditPart) item;
+				LogicLabel label = (LogicLabel) editPart.getModel();
+				return label.getLabelContents().equals("Label");
+			}
+			public void describeTo(Description description) {
+			}
+		});
+
+		editParts.get(0).activateDirectEdit();
+		bot.text();
+		editor.directEditType("123456789=&é(-è_çà");
 
 	}
 }
diff --git a/org.eclipse.swtbot.eclipse.gef.finder/META-INF/MANIFEST.MF b/org.eclipse.swtbot.eclipse.gef.finder/META-INF/MANIFEST.MF
index 4057904..2cb67bf 100644
--- a/org.eclipse.swtbot.eclipse.gef.finder/META-INF/MANIFEST.MF
+++ b/org.eclipse.swtbot.eclipse.gef.finder/META-INF/MANIFEST.MF
@@ -17,6 +17,7 @@
  org.eclipse.draw2d.text,
  org.eclipse.gef,
  org.eclipse.gef.palette,
+ org.eclipse.gef.requests,
  org.eclipse.gef.ui.palette,
  org.eclipse.gef.ui.parts,
  org.eclipse.jface.viewers,
diff --git a/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefEditPart.java b/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefEditPart.java
index e2034ef..f3094d6 100644
--- a/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefEditPart.java
+++ b/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefEditPart.java
@@ -21,6 +21,7 @@
 import org.eclipse.draw2d.geometry.Rectangle;
 import org.eclipse.gef.EditPart;
 import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.requests.DirectEditRequest;
 import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
 import org.eclipse.swtbot.swt.finder.results.Result;
 import org.eclipse.swtbot.swt.finder.results.VoidResult;
@@ -48,8 +49,21 @@
 		this.part = part;
 	}
 
-	
+	/**
+	 * get the parent, or null if this is the root edit part.
+	 */
+	public SWTBotGefEditPart parent() {
+		return UIThreadRunnable.syncExec(new Result<SWTBotGefEditPart>() {
+			public SWTBotGefEditPart run() {
+				return graphicalEditor.createEditPart(part.getParent());
+			}
+		});
+	}
 
+	/**
+	 * Get the children of this edit part.
+	 * @return the edit part's children
+	 */
 	@SuppressWarnings("unchecked")
 	public List<SWTBotGefEditPart> children() {
 		return UIThreadRunnable.syncExec(new Result<List<SWTBotGefEditPart>>() {
@@ -64,7 +78,7 @@
 	}
 
 	/**
-	 * find descendants that match
+	 * find descendants that match.
 	 * 
 	 * @param matcher the matcher that matches against {@link org.eclipse.gef.EditPart}
 	 * 
@@ -148,17 +162,25 @@
 		});
 		return this;
 	}
+
+	public SWTBotGefEditPart activateDirectEdit() {
+		return activateDirectEdit(null);
+	}
 	
-	/**
-	 * get the parent, or null if this is the root edit part.
-	 */
-	public SWTBotGefEditPart parent() {
-		return UIThreadRunnable.syncExec(new Result<SWTBotGefEditPart>() {
-			public SWTBotGefEditPart run() {
-				return graphicalEditor.createEditPart(part.getParent());
+	
+	public SWTBotGefEditPart activateDirectEdit(final Object feature) {
+		UIThreadRunnable.asyncExec(new VoidResult() {
+			public void run() {
+				DirectEditRequest request = new DirectEditRequest();
+				if (feature != null)
+					request.setDirectEditFeature(feature);
+				part().performRequest(request);
 			}
 		});
+		return this;
 	}
+
+
 	
 	/**
 	 * provide a description of this edit part that is useful for debugging purposes.
diff --git a/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefEditor.java b/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefEditor.java
index 18936cb..83fcfa9 100644
--- a/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefEditor.java
+++ b/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefEditor.java
@@ -35,9 +35,7 @@
 import org.eclipse.gef.palette.ToolEntry;
 import org.eclipse.gef.ui.parts.GraphicalViewerImpl;
 import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
 import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
@@ -225,7 +223,6 @@
         return editDomain;
     }
 
-    //TODO should be in a separate class
     /**
      * type the given text into the graphical editor, presuming that it is
      * already in 'direct edit' mode.
@@ -237,73 +234,14 @@
     public void directEditType(String text) throws WidgetNotFoundException {
         List<Text> controls = bot.getFinder().findControls(getWidget(), new IsInstanceOf<Text>(Text.class), true);
         if (controls.size() == 1) {
-            final Text textControl = controls.get(0);
-            UIThreadRunnable.syncExec(new VoidResult() {
-                public void run() {
-                    textControl.setText("");
-                }
-            });
-            for (int x = 0; x < text.length(); ++x) {
-                final char c = text.charAt(x);
-                UIThreadRunnable.syncExec(new VoidResult() {
-                    public void run() {
-                        textControl.setFocus();
-                        textControl.notifyListeners(SWT.KeyDown, keyEvent(SWT.NONE, c, 0));
-                        textControl.notifyListeners(SWT.KeyUp, keyEvent(SWT.NONE, c, 0));
-                        textControl.setText(textControl.getText() + c);
-                    }
-                });
-                try {
-                    Thread.sleep(50L);
-                } catch (InterruptedException e) {
-                }
-            }
-
-            // apply the value with a default selection event
-            UIThreadRunnable.syncExec(new VoidResult() {
-                public void run() {
-                    textControl.setFocus();
-                    textControl.notifyListeners(SWT.DefaultSelection, createEvent());
-                }
-            });
+            final Text textControl = controls.get(0);	
+            canvas.typeText(textControl, text);
         } else {
             throw new WidgetNotFoundException(String.format("Expected to find one text control, but found %s.  Is the editor in direct-edit mode?", controls.size()));
         }
     }
 
     /**
-     * @param c
-     *            the character.
-     * @param modificationKey
-     *            the modification key.
-     * @param keyCode
-     *            the keycode.
-     * @return a key event with the specified keys.
-     * @see Event#keyCode
-     * @see Event#character
-     * @see Event#stateMask
-     * @since 1.2
-     */
-    @Deprecated
-    protected Event keyEvent(int modificationKey, char c, int keyCode) {
-        Event keyEvent = createEvent();
-        keyEvent.stateMask = modificationKey;
-        keyEvent.character = c;
-        keyEvent.keyCode = keyCode;
-
-        return keyEvent;
-    }
-
-    @Deprecated
-    protected Event createEvent() {
-        Event event = new Event();
-        event.time = (int) System.currentTimeMillis();
-        event.widget = getWidget();
-        event.display = bot.getDisplay();
-        return event;
-    }
-
-    /**
      * 
      * @param matcher
      *            the matcher that matches on {@link org.eclipse.gef.EditPart}
@@ -499,20 +437,14 @@
 	                return child;
 	            }
 	           
-	           // find label in children
-	           if (findLabelFigure(figure, label))  {
 	               SWTBotGefEditPart childEditPart = getEditPart(child, label);
 	               if (childEditPart!=null) {
 	                   return childEditPart;
 	               }
-	               return child;
-	           }
-	           
-	           // find label in connections
-	           SWTBotGefEditPart childEditPart = getEditPart(child, label);
-	           if (childEditPart != null) {
-	               return childEditPart;
-	           }
+	               
+	               if (findLabelFigure(figure, label))
+	            	   return child;
+	               return null;
 	       }
 	       return null;
 	   }
diff --git a/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefFigureCanvas.java b/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefFigureCanvas.java
index 870dd3c..7207f55 100644
--- a/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefFigureCanvas.java
+++ b/org.eclipse.swtbot.eclipse.gef.finder/src/org/eclipse/swtbot/eclipse/gef/finder/widgets/SWTBotGefFigureCanvas.java
@@ -14,7 +14,11 @@
 import org.eclipse.draw2d.EventDispatcher;
 import org.eclipse.draw2d.FigureCanvas;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Text;
 import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
 import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBotControl;
 
 /**
@@ -72,4 +76,53 @@
         eventDispatcher.dispatchMouseExited(wrapMouseEvent(xPosition, yPosition, 0, 0, 0));
     }
     
+    public void typeText(final Text textControl, final String text) {
+    	oldTypeText(textControl, text);
+    	//TODO need to improve type text before that
+    	//final SWTBotText textBot = new SWTBotText(textControl);
+        //textBot.typeText(text + "\r");          
+    }
+    
+    private void oldTypeText(final Text textControl, final String text) {
+        
+        UIThreadRunnable.syncExec(new VoidResult() {
+            public void run() {
+                textControl.setText("");
+            }
+        });
+        for (int x = 0; x < text.length(); ++x) {
+            final char c = text.charAt(x);
+            UIThreadRunnable.syncExec(new VoidResult() {
+                public void run() {
+                    textControl.setFocus();
+                    textControl.notifyListeners(SWT.KeyDown, keyEvent(SWT.NONE, c, 0));
+                    textControl.notifyListeners(SWT.KeyUp, keyEvent(SWT.NONE, c, 0));
+                    textControl.setText(textControl.getText() + c);
+                }
+            });
+            try {
+                Thread.sleep(50L);
+            } catch (InterruptedException e) {
+            }
+        }
+
+        // apply the value with a default selection event
+        UIThreadRunnable.syncExec(new VoidResult() {
+            public void run() {
+                textControl.setFocus();
+                textControl.notifyListeners(SWT.DefaultSelection, createEvent());
+            }
+        });
+    }
+    
+    private Event keyEvent(int modificationKey, char c, int keyCode) {
+        Event keyEvent = createEvent();
+        keyEvent.stateMask = modificationKey;
+        keyEvent.character = c;
+        keyEvent.keyCode = keyCode;
+        return keyEvent;
+    }
+
+    
+    
 }