From: <gjo...@us...> - 2007-07-11 19:13:32
|
Revision: 2445 http://abbot.svn.sourceforge.net/abbot/?rev=2445&view=rev Author: gjohnsto Date: 2007-07-11 12:13:27 -0700 (Wed, 11 Jul 2007) Log Message: ----------- abbot.swt --------- Fixed drag-n-drop problems (I hope): o abbot.swt.Robot: o Added mouseDragDrop(int sx, int sy, int tx, int ty). o Removed: o mouseDrag(int buttons). o mouseDrop(int buttons). o Other internal changes, including caching of display & monitor bounds. o abbot.swt.tester.Robot: o Added: o dragDrop(Widget source, Widget target, int buttons) o dragDrop(Widget source, int tx, int ty, int buttons) o dragDrop(int sx, int sy, int tx, int ty, int buttons) o Removed all other drag*(*) & drop*(*) methods. o WidgetTester: o Added: o actionDragDrop(Widget source, Widget target, int buttons). o actionDragDrop(Widget source, tx, ty, int buttons). o actionDragDrop(int sx, int sy, int tx, int ty, int buttons). o Removed all other actionDrag*(*) and actionDrop(*) methods. abbot.swt.tester.Robot: o Fixed an intermittent UI thread hang problem in delay(long time). o Added some checking to click(Widget widget, int x, int y, int mask). WidgetTester & WIdgetTesterFactory: o Simplified *Tester caching and Factory management. o Fixed a bug in management of added *Tester packages. TreeItemTester: o "Finalized" fix for "jumpy tree" problem. Log: o Added Log.debug(String format, Object... args). abbot.swt.eclipse ----------------- Popups & ShellTextHandler: o Fixed bug that caused SWTExceptions ("widget is disposed") in some cases. InvokeNewWizard: o Use strings from resource bundles rather than hard-coded ones. Moved remaining useful functionality in abbotx to abbot.swt.eclipse: o Moved xxx to abbot.swt.eclipse.jobs. o In WorkbenchUtilities: o Added getActivePage(boolean activate). o Added getActiveShell() & getActiveShell(boolean activate). o Renamed getActiveWorkbenchWindow() to getActiveWindow(). o Added getActiveWindow(boolean activate). o In WorkspaceUtilities: o Added getFile(String fullPath) & getFile(IPath fullPath). o Added class abbot.swt.utilities.Check. abbot.swt.gef ------------- o Fixed bug in EditPartHierarchyImpl.getParent(EditPart) that returned the parent of the hierarchy's root EditPart rather than null. o Fixed similar bug in FigureHierarchyImpl.getParent(IFigure). o Fixed bug in FigureCanvasTester static initialization incorrectly adding its package to the WidgetTesterFactory. o In FigureTester, adapted to changes in abbot.swt drag-n-drop API. Modified Paths: -------------- abbot.swt/trunk/abbot.swt.eclipse/META-INF/MANIFEST.MF abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/popups/Popups.java abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/popups/ShellTextHandler.java abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/InvokeNewWizard.java abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/WorkbenchUtilities.java abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/WorkspaceUtilities.java Added Paths: ----------- abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/jobs/ abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/jobs/Jobs.java Modified: abbot.swt/trunk/abbot.swt.eclipse/META-INF/MANIFEST.MF =================================================================== --- abbot.swt/trunk/abbot.swt.eclipse/META-INF/MANIFEST.MF 2007-07-09 14:46:18 UTC (rev 2444) +++ abbot.swt/trunk/abbot.swt.eclipse/META-INF/MANIFEST.MF 2007-07-11 19:13:27 UTC (rev 2445) @@ -15,6 +15,7 @@ Bundle-Vendor: IBM Export-Package: abbot.swt.eclipse, abbot.swt.eclipse.fixture, + abbot.swt.eclipse.jobs, abbot.swt.eclipse.junit.extensions, abbot.swt.eclipse.popups, abbot.swt.eclipse.utils, Added: abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/jobs/Jobs.java =================================================================== --- abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/jobs/Jobs.java (rev 0) +++ abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/jobs/Jobs.java 2007-07-11 19:13:27 UTC (rev 2445) @@ -0,0 +1,159 @@ +package abbot.swt.eclipse.jobs; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; + +import abbot.swt.Log; + +public class Jobs { + + /** + * Names of Jobs to be ignored by {@link #join()} and {@link #join(long)}. + */ + private static Set<String> ignored = new HashSet<String>(); + + /** + * Add a Job name to the ones to be ignored by {@link #join()} and {@link #join(long)}. + * + * @param name - + * the name of the Job to ignore + */ + public static synchronized void ignore(String name) { + // Log.debug("Jobs: Ignoring Jobs named {0}", name); + ignored.add(name); + } + + /** + * Remove a Job name from the ones to be ignored by {@link #join()} and {@link #join(long)}. + * + * @param name - + * the name of the Job to no longer ignore + */ + public static synchronized void unignore(String name) { + // Log.debug("Jobs: Unignoring Jobs named {0}", name); + ignored.remove(name); + } + + /** + * Remove all Job names from the ones to be ignored by {@link #join()} and {@link #join(long)}. + */ + public static synchronized void unignoreAll() { + // Log.debug("Jobs: Unignoring all Jobs"); + ignored.clear(); + } + + /** + * Wait for all currently waiting, executing and sleeping Jobs to complete <em>except</em> for + * those currently being ignored. + */ + public static void join() { + Log.debug("Jobs: Joining all Jobs"); + checkThread(); + Job[] jobs = getJobs(); + for (int i = 0; i < jobs.length; i++) { + Job job = jobs[i]; + if (shouldJoin(job)) + join(job); + } + Log.debug("Jobs: Joining all Jobs complete"); + } + + private static void checkThread() { + Display display = PlatformUI.getWorkbench().getDisplay(); + if (display.getThread() == Thread.currentThread()) + throw new IllegalStateException("on display thread"); + } + + private static Job[] getJobs() { + return Job.getJobManager().find(null); + } + + private static boolean shouldJoin(Job job) { + return job.getPriority() != Job.DECORATE && !ignored.contains(job.getName()); + } + + private static boolean join(Job job) { + Log.debug("Jobs: Joining Job: {0}", job); + try { + job.join(); + Log.debug("Jobs: Joining Job complete: {0}", job); + return true; + } catch (InterruptedException exception) { + // Fall through to return false. + } + Log.debug("Jobs: Joining Job interrupted: {0}", job); + return false; + } + + /** + * Wait for Jobs to complete. + * + * @param timeout - + * the number of milliseconds to wait for any one job. Once the wait on a job has + * exceeded this value, the job is skipped. + */ + public static void join(long timeout) { + Log.debug("Jobs: Joining all Jobs (timeout {0} ms.", timeout); + checkThread(); + Job[] jobs = getJobs(); + for (int i = 0; i < jobs.length; i++) { + Job job = jobs[i]; + if (shouldJoin(job)) + join(job, timeout); + } + Log.debug("Jobs: Joining all Jobs complete", timeout); + } + + private static void join(Job job, long timeout) { + + Log.debug("Jobs: Joining Job ({0} ms.): {1}", timeout, job); + + // Create and start a Thread to join the Job. + Joiner joiner = new Joiner(job); + joiner.start(); + + // Wait at most timeout milliseconds for the joiner Thread to finish. + try { + joiner.join(timeout); + if (joiner.isAlive()) { + joiner.quit(); + Log.debug("Jobs: Joining Job timed out: {0}", job); + } else { + Log.debug("Jobs: Joining Job complete: {0}", job); + } + } catch (InterruptedException e) { + Log.debug("Jobs: Joining Job interrupted: {0}", job); + } + } + + private static class Joiner extends Thread { + + private final Job job; + + private boolean done; + + public Joiner(Job job) { + this.job = job; + } + + public void run() { + while (!done) { + try { + job.join(); + } catch (InterruptedException exception) { + // Empty block intended. + } + } + } + + public void quit() { + done = true; + interrupt(); + } + } + +} Modified: abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/popups/Popups.java =================================================================== --- abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/popups/Popups.java 2007-07-09 14:46:18 UTC (rev 2444) +++ abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/popups/Popups.java 2007-07-11 19:13:27 UTC (rev 2445) @@ -34,7 +34,7 @@ public static synchronized void addHandler(Handler handler) { if (handlers == null) { - handlers = new HashSet(); + handlers = new HashSet<Handler>(); listener = new Listener() { public void handleEvent(Event event) { Popups.handleEvent(event); @@ -74,7 +74,7 @@ // We care only about visible, modal Shells. if (event.widget instanceof Shell) { Shell shell = (Shell) event.widget; - if (shell.isVisible() && (shell.getStyle() & ANY_MODAL) != 0) { + if (!shell.isDisposed() && shell.isVisible() && (shell.getStyle() & ANY_MODAL) != 0) { // Let the first handler that can handle it, um, handle it. final Handler handler = getHandler(event); Modified: abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/popups/ShellTextHandler.java =================================================================== --- abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/popups/ShellTextHandler.java 2007-07-09 14:46:18 UTC (rev 2444) +++ abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/popups/ShellTextHandler.java 2007-07-11 19:13:27 UTC (rev 2445) @@ -42,42 +42,45 @@ public void handle(Event event) { final Shell shell = (Shell) event.widget; - try { + if (!shell.isDisposed()) { + try { - // Find the button. - WidgetMatcher matcher = new WidgetTextMatcher(buttonText, Button.class); - WidgetFinder finder = WidgetFinderImpl.getDefault(); - final Button button = (Button) finder.find(shell, matcher); + // Find the button. + WidgetMatcher matcher = new WidgetTextMatcher(buttonText, Button.class); + WidgetFinder finder = WidgetFinderImpl.getDefault(); + final Button button = (Button) finder.find(shell, matcher); - // Wait for it to become enabled. - final ButtonTester buttonTester = ButtonTester.getButtonTester(); - Robot.getDefault().wait(new Condition() { - public boolean test() { - return buttonTester.isEnabled(button); - } - }, BUTTON_ENABLED_TIMEOUT, BUTTON_ENABLED_INTERVAL); + // Wait for it to become enabled. + final ButtonTester buttonTester = ButtonTester.getButtonTester(); + Robot.getDefault().wait(new Condition() { + public boolean test() { + return buttonTester.isEnabled(button); + } + }, BUTTON_ENABLED_TIMEOUT, BUTTON_ENABLED_INTERVAL); - // Click it. - buttonTester.actionClick(button); + // Click it. + buttonTester.actionClick(button); - } catch (FinderException exception) { + } catch (FinderException exception) { - // Error: Problem finding button. Forcibly close the shell and throw a RuntimeException. - shell.getDisplay().syncExec(new Runnable() { - public void run() { - shell.close(); - } - }); - throw new RuntimeException(exception); - } finally { + // Error: Problem finding button. Forcibly close the shell and throw a + // RuntimeException. + shell.getDisplay().syncExec(new Runnable() { + public void run() { + shell.close(); + } + }); + throw new RuntimeException(exception); + } finally { - // Wait for the shell to close. - final ShellTester shellTester = ShellTester.getShellTester(); - shellTester.wait(new Condition() { - public boolean test() { - return !shellTester.isVisible(shell); - } - }, SHELL_CLOSED_TIMEOUT, SHELL_CLOSED_INTERVAL); + // Wait for the shell to close. + final ShellTester shellTester = ShellTester.getShellTester(); + shellTester.wait(new Condition() { + public boolean test() { + return shell.isDisposed(); + } + }, SHELL_CLOSED_TIMEOUT, SHELL_CLOSED_INTERVAL); + } } } Modified: abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/InvokeNewWizard.java =================================================================== --- abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/InvokeNewWizard.java 2007-07-09 14:46:18 UTC (rev 2444) +++ abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/InvokeNewWizard.java 2007-07-11 19:13:27 UTC (rev 2445) @@ -6,13 +6,15 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; import abbot.swt.finder.WidgetFinder; import abbot.swt.finder.WidgetFinderImpl; import abbot.swt.finder.generic.FinderException; import abbot.swt.finder.matchers.WidgetClassMatcher; -import abbot.swt.finder.matchers.WidgetTextMatcher; import abbot.swt.tester.ActionFailedException; +import abbot.swt.tester.ItemPath; import abbot.swt.tester.MenuTester; import abbot.swt.tester.ShellTester; import abbot.swt.tester.TreeItemTester; @@ -29,16 +31,22 @@ public class InvokeNewWizard extends TestCase { - private static final String NEW_WIZARD_TITLE = "New"; + // private static final String NEW_WIZARD_TITLE = "New"; - private static final String FILE_NEW_OTHER_PATH = "&File/&New\tAlt+Shift+N/&Other..."; + // File/New/Other... + private static final ItemPath FileNewOtherPath = new ItemPath(new String[] { + IDEWorkbenchMessages.Workbench_file, + IDEWorkbenchMessages.Workbench_new + "\tAlt+Shift+N", + WorkbenchMessages.NewWizardAction_text }); + // private static final String FILE_NEW_OTHER_PATH = "&File/&New\tAlt+Shift+N/&Other..."; + // testers used to find new wizard final static TreeItemTester treeItemTester = (TreeItemTester) WidgetTester .getTester(TreeItem.class); /** - * This method will invoke a new wizard by going to File > New > Other and then navigated the + * This method will invoke a new wizard by going to File > New > Other and then navigate the * wizard tree. * * @param wizardTreePath @@ -68,22 +76,20 @@ Menu bar = ShellTester.getShellTester().getMenuBar(shell); if (bar == null) throw new ActionFailedException("no menu bar"); - MenuTester.getMenuTester().actionClickItem(bar, FILE_NEW_OTHER_PATH); - WidgetTester.waitForShellShowing(NEW_WIZARD_TITLE); + MenuTester.getMenuTester().actionClickItem(bar, FileNewOtherPath); + Shell wizardShell = ShellTester.waitVisible(WorkbenchMessages.NewWizard_title); // Get the wizard's wizard selection tree. - Tree tree = findTree(); + Tree tree = findTree(wizardShell); // Double-click the specified wizard tree item. TreeTester treeTester = TreeTester.getTreeTester(); treeTester.actionDoubleClickItem(tree, path, delimiter); } - private static Tree findTree() { + private static Tree findTree(Shell shell) { try { WidgetFinder finder = WidgetFinderImpl.getDefault(); - Shell shell = (Shell) finder.find(new WidgetTextMatcher(NEW_WIZARD_TITLE, Shell.class, - true)); return (Tree) finder.find(shell, new WidgetClassMatcher(Tree.class)); } catch (FinderException exception) { throw new ActionFailedException(exception); Modified: abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/WorkbenchUtilities.java =================================================================== --- abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/WorkbenchUtilities.java 2007-07-09 14:46:18 UTC (rev 2444) +++ abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/WorkbenchUtilities.java 2007-07-11 19:13:27 UTC (rev 2445) @@ -14,6 +14,7 @@ import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.part.FileEditorInput; import abbot.swt.script.Condition; import abbot.swt.tester.ShellTester; @@ -30,7 +31,7 @@ public class WorkbenchUtilities { /** - * Gets the workbench. This is just a convenience method and is exactly equivalent to + * Gets the workbench. This is just a convenience method and is equivalent to * {@link PlatformUI#getWorkbench()}. * * @return the {@link IWorkbench} @@ -39,12 +40,72 @@ return PlatformUI.getWorkbench(); } + /** + * Gets the {@link Display} of the current workbench. + * + * @return the {@link Display} of the current workbench + */ public static Display getDisplay() { return getWorkbench().getDisplay(); } + public static IWorkbenchWindow getActiveWindow() { + return getActiveWindow(false); + } + + public static IWorkbenchWindow getActiveWindow(boolean activate) { + + // Get the active workbench window. + final IWorkbench workbench = getWorkbench(); + Display display = workbench.getDisplay(); + IWorkbenchWindow window = (IWorkbenchWindow) Displays.syncExec( + display, + new Result<IWorkbenchWindow>() { + public IWorkbenchWindow result() { + return workbench.getActiveWorkbenchWindow(); + } + }); + + // If there isn't one and activate was specified then activate the first visible workbench + // window (if any). + if (window == null && activate) { + final IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); + window = (IWorkbenchWindow) Displays.syncExec(display, new Result<IWorkbenchWindow>() { + public IWorkbenchWindow result() { + for (IWorkbenchWindow window : windows) { + Shell shell = window.getShell(); + if (shell.isVisible()) { + shell.setActive(); + return window; + } + } + return null; + } + }); + } + + return window; + } + + public static Shell getActiveShell() { + return getActiveShell(false); + } + + public static Shell getActiveShell(boolean activate) { + return getActiveWindow(activate).getShell(); + } + + public static IWorkbenchPage getActivePage() { + return getActivePage(true); + } + + public static IWorkbenchPage getActivePage(boolean activate) { + IWorkbenchWindow window = getActiveWindow(activate); + return window.getActivePage(); + } + public static IEditorPart getActiveEditor() { - IWorkbenchWindow window = getActiveWorkbenchWindow(); + IWorkbenchWindow window = getActiveWindow(); if (window != null) { IWorkbenchPage page = window.getActivePage(); if (page != null) @@ -53,24 +114,6 @@ return null; } - protected static IWorkbenchWindow getActiveWorkbenchWindow() { - final IWorkbenchWindow[] window = new IWorkbenchWindow[1]; - final IWorkbench workbench = getWorkbench(); - workbench.getDisplay().syncExec(new Runnable() { - public void run() { - window[0] = workbench.getActiveWorkbenchWindow(); - } - }); - return window[0]; - } - - protected static IWorkbenchPage getActivePage() { - IWorkbenchWindow window = getActiveWorkbenchWindow(); - if (window != null) - return window.getActivePage(); - return null; - } - public static interface EditorReferenceMatcher { boolean matches(IEditorReference reference); } @@ -132,33 +175,9 @@ * @return the {@link IEditorPart} of the editor that was found, or <code>null</code> if none. */ public static IEditorPart findEditor(final IFile file) throws PartInitException { - - // Try to find an editor that has an IFileEditorInput on the specified file, - // also saving the first exception we get (if any). - final PartInitException[] exception = new PartInitException[1]; - IEditorPart editor = findEditor(new EditorReferenceMatcher() { - public boolean matches(IEditorReference editor) { - try { - IEditorInput input = editor.getEditorInput(); - if (input instanceof IFileEditorInput) - return ((IFileEditorInput) input).getFile().equals(file); - } catch (PartInitException e) { - exception[0] = e; - } - return false; - } - }, true); - - // If we found it, return it (regardless of whether or not we got an exception. - if (editor != null) - return editor; - - // We didn't find it. If we got an exception then rethrow it. - if (exception[0] != null) - throw exception[0]; - - // We didn't find it and got no exception, so just return null; - return null; + IWorkbenchPage page = getActivePage(); + IEditorInput input = new FileEditorInput(file); + return page.findEditor(input); } /** @@ -203,7 +222,8 @@ page.activate(editor); } }); - assert editor == page.getActiveEditor(); + if (editor != page.getActiveEditor()) + throw new RuntimeException("could not activate " + editor); } public static IEditorPart openEditor(IFile file, String editorId) throws PartInitException { Modified: abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/WorkspaceUtilities.java =================================================================== --- abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/WorkspaceUtilities.java 2007-07-09 14:46:18 UTC (rev 2444) +++ abbot.swt/trunk/abbot.swt.eclipse/src/abbot/swt/eclipse/utils/WorkspaceUtilities.java 2007-07-11 19:13:27 UTC (rev 2445) @@ -55,6 +55,14 @@ getProject(name).delete(true, true, null); } + public static IFile getFile(String fullPath) { + return getFile(new Path(fullPath)); + } + + public static IFile getFile(IPath fullPath) { + return getWorkspaceRoot().getFile(fullPath); + } + public static IFile createFile(String projectName, String fileName, InputStream source) throws CoreException { IProject project = getProject(projectName); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |