blob: b272a316abf09ecd35d6d32afd8f1fa0c03141f9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 Ketan Padegaonkar 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:
* Ketan Padegaonkar - initial API and implementation
*******************************************************************************/
package org.eclipse.swtbot.eclipse.spy;
import java.util.Iterator;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.swt.widgets.Decorations;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tracker;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.swtbot.swt.finder.finders.ControlFinder;
import org.eclipse.swtbot.swt.finder.finders.PathGenerator;
import org.eclipse.swtbot.swt.finder.resolvers.IChildrenResolver;
import org.eclipse.swtbot.swt.finder.resolvers.IParentResolver;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
import org.eclipse.swtbot.swt.finder.utils.TreePath;
class EclipseWidgetTracker implements Runnable {
protected IChildrenResolver childrenResolver;
protected ControlFinder controlFinder;
protected Display display;
protected IParentResolver parentResolver;
protected EclipseSpy view;
EclipseWidgetTracker(EclipseSpy view, IChildrenResolver childrenResolver, IParentResolver parentResolver) {
this.view = view;
this.childrenResolver = childrenResolver;
this.parentResolver = parentResolver;
}
// public void clickOnToolbar(Control control) {
// if (control instanceof ToolBar) {
// ToolBar toolbar = (ToolBar) control;
// Display display = toolbar.getDisplay();
//
// Point cursorLocation = Display.getCurrent().getCursorLocation();
//
// Event event = new Event();
// event.display = display;
//
// event.button = 1;
// event.type = SWT.MouseDown;
//
// event.doit = true;
// event.x = cursorLocation.x;
// event.y = cursorLocation.y;
//
// // display.post(event);
//
// event.type = SWT.MouseUp;
// // display.post(event);
// }
// }
public String getClassName(Object o) {
if (o == null)
return null;
int i = o.getClass().getName().lastIndexOf('.');
return o.getClass().getName().substring(i + 1);
}
public void getCompositeInformation(Control control, StringBuffer buf) {
List<Widget> children = childrenResolver.getChildren(control);
buf.append("\nChildren: " + children.size() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
for (Iterator<Widget> iterator = children.iterator(); iterator.hasNext();)
buf.append("\t" + iterator.next() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
buf.append("\n"); //$NON-NLS-1$
}
public void getWidgetId(Control control, StringBuffer buf) {
buf.append("Widget's SWTBot ID: "); //$NON-NLS-1$
Object widgetId = control.getData(SWTBotPreferences.DEFAULT_KEY);
if (widgetId != null) {
buf.append(widgetId.toString());
} else {
buf.append("<no SWTBot ID set>"); //$NON-NLS-1$
}
buf.append("\n"); //$NON-NLS-1$
}
public void getLayoutInformation(Control control, StringBuffer buf) {
buf.append("Layout Information: \n"); //$NON-NLS-1$
buf.append(SWTUtils.toString(control) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
buf.append("\tStyle: " + getStyle(control) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
buf.append("\tLayout Data: " + control.getLayoutData() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
buf.append("\tBounds: " + control.getBounds() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
buf.append("\n"); //$NON-NLS-1$
}
public void getLocationInformation(Control control, StringBuffer buf) {
TreePath path = controlFinder.getPath(control);
String stringFromPath = new PathGenerator().getPathAsString(path);
buf.append("Location: \n").append(stringFromPath).append("\n\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
public void getParentInformation(Control control, StringBuffer buf) {
Composite parent = control.getParent();
if (parent != null) {
buf.append("Parent Tree:\n"); //$NON-NLS-1$
TreePath parents = controlFinder.getPath(control).getParentPath();
int segmentCount = parents.getSegmentCount();
for (int i = segmentCount - 1; i >= 0; i--) {
String prefix = ""; //$NON-NLS-1$
Widget segment = (Widget) parents.getSegment(i);
for (int j = 0; j < segmentCount - i - 1; j++)
prefix += "\t"; //$NON-NLS-1$
buf.append(prefix + renderWidget(segment) + "[" + SWTUtils.widgetIndex(segment) + "]" + "@" + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
if (segment instanceof Composite) {
buf.append(prefix + "\t Layout: " + getClassName(((Composite) segment).getLayout()) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
buf.append(prefix + "\t LayoutData: " + getClassName(((Control) segment).getLayoutData()) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
buf.append("\n"); //$NON-NLS-1$
}
}
public void getSiblingInformation(Control control, StringBuffer buf) {
Widget[] siblings = SWTUtils.siblings(control);
buf.append("Siblings: " + siblings.length + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
for (int i = 0; i < siblings.length; i++) {
Widget sibling = siblings[i];
if (sibling == control)
buf.append("\t[*]"); //$NON-NLS-1$
else
buf.append("\t "); //$NON-NLS-1$
if (sibling instanceof Control)
buf.append(renderWidget(sibling) + ": Layout Data: " //$NON-NLS-1$
+ ((Control) sibling).getLayoutData() + "\n"); //$NON-NLS-1$
else
buf.append(renderWidget(sibling) + "\n"); //$NON-NLS-1$
}
buf.append("\n"); //$NON-NLS-1$
}
private String renderWidget(Widget sibling) {
return SWTUtils.toString(sibling);
}
@Override
public void run() {
if ((view.output == null) || view.output.isDisposed() || !view.actionMonitor.isChecked())
return;
display = view.output.getDisplay();
controlFinder = new ControlFinder();
Control control = display.getCursorControl();
display.getCursorLocation();
if (control == null) {
view.output.setText(""); //$NON-NLS-1$
view.lastWidget = 0;
} else if (control != view.lastWidget) {
view.lastWidget = control;
StringBuffer buf = new StringBuffer();
getInformation(control, buf);
// clickOnToolbar(control);
view.output.setText(buf.toString());
}
display.timerExec(100, view.trackWidgets);
}
private void getInformation(Control control, StringBuffer buf) {
getToggleInformation(control, buf);
getLocationInformation(control, buf);
getWidgetId(control, buf);
getLayoutInformation(control, buf);
getCompositeInformation(control, buf);
getSiblingInformation(control, buf);
getParentInformation(control, buf);
}
private void getToggleInformation(Control control, StringBuffer buf) {
buf.append("To toggle, or freeze info on a particular control, press CTRL+SHIFT: \n").append("\n\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
String getStyle(Widget w) {
int style = w.getStyle();
String result = ""; //$NON-NLS-1$
if (style == SWT.DEFAULT)
return "DEFAULT - bad!"; //$NON-NLS-1$
if ((style & 1 << 1) != 0)
if ((w instanceof CTabFolder) || (w instanceof StyledText) || (w instanceof List) || (w instanceof Text)
|| (w instanceof Table) || (w instanceof Tree))
result += "MULTI | "; //$NON-NLS-1$
else if (w instanceof Menu)
result += "BAR | "; //$NON-NLS-1$
else if ((w instanceof Label) || (w instanceof MenuItem) || (w instanceof ToolItem))
result += "SEPARATOR | "; //$NON-NLS-1$
else if (w instanceof Button)
result += "TOGGLE | "; //$NON-NLS-1$
else if (w instanceof ProgressBar)
result += "INDETERMINATE | "; //$NON-NLS-1$
else
result += "BAR or SEPARATOR or TOGGLE or MULTI or INDETERMINATE or DBCS | "; //$NON-NLS-1$
if ((style & 1 << 2) != 0)
if ((w instanceof Menu) || (w instanceof ToolItem) || (w instanceof CoolItem) || (w instanceof Combo))
result += "DROP_DOWN | "; //$NON-NLS-1$
else if (w instanceof Button)
result += "ARROW | "; //$NON-NLS-1$
else if ((w instanceof CTabFolder) || (w instanceof StyledText) || (w instanceof List)
|| (w instanceof Text) || (w instanceof Table) || (w instanceof Tree))
result += "SINGLE | "; //$NON-NLS-1$
else if ((w instanceof Label) || (w instanceof Group))
result += "SHADOW_IN | "; //$NON-NLS-1$
else if (w instanceof Decorations)
result += "TOOL | "; //$NON-NLS-1$
else
result += "ALPHA or TOOL or SINGLE or ARROW or DROP_DOWN or SHADOW_IN | "; //$NON-NLS-1$
if ((style & 1 << 3) != 0)
if (w instanceof Menu)
result += "POP_UP | "; //$NON-NLS-1$
else if ((w instanceof Button) || (w instanceof MenuItem) || (w instanceof ToolItem))
result += "PUSH | "; //$NON-NLS-1$
else if ((w instanceof Combo) || (w instanceof Text) || (w instanceof StyledText))
result += "READ_ONLY | "; //$NON-NLS-1$
else if ((w instanceof Label) || (w instanceof Group) || (w instanceof ToolBar))
result += "SHADOW_OUT | "; //$NON-NLS-1$
else if (w instanceof Decorations)
result += "NO_TRIM | "; //$NON-NLS-1$
else
result += "POP_UP or PUSH or READ_ONLY or SHADOW_OUT or NO_TRIM or NATIVE | "; //$NON-NLS-1$
if ((style & 1 << 4) != 0)
if ((w instanceof Button) || (w instanceof MenuItem) || (w instanceof ToolItem))
result += "RADIO | "; //$NON-NLS-1$
else if (w instanceof Group)
result += "SHADOW_ETCHED_IN | "; //$NON-NLS-1$
else if ((w instanceof Decorations) || (w instanceof Tracker))
result += "RESIZE | "; //$NON-NLS-1$
else
result += "RESIZE or SHADOW_ETCHED_IN or RADIO or PHONETIC | "; //$NON-NLS-1$
if ((style & 1 << 5) != 0)
if ((w instanceof Button) || (w instanceof MenuItem) || (w instanceof ToolItem) || (w instanceof Table)
|| (w instanceof Tree))
result += "CHECK | "; //$NON-NLS-1$
else if ((w instanceof Label) || (w instanceof Group))
result += "SHADOW_NONE | "; //$NON-NLS-1$
else if (w instanceof Decorations)
result += "TITLE | "; //$NON-NLS-1$
else
result += "ROMAN or CHECK or SHADOW_NONE or TITLE | "; //$NON-NLS-1$
if ((style & 1 << 6) != 0)
if (w instanceof MenuItem)
result += "CASCADE | "; //$NON-NLS-1$
else if ((w instanceof StyledText) || (w instanceof Label) || (w instanceof Text) || (w instanceof ToolBar))
result += "WRAP | "; //$NON-NLS-1$
else if (w instanceof Combo)
result += "SIMPLE | "; //$NON-NLS-1$
else if (w instanceof Group)
result += "SHADOW_ETCHED_OUT | "; //$NON-NLS-1$
else if ((w instanceof Decorations) || (w instanceof CTabFolder) || (w instanceof CTabItem))
result += "CLOSE | "; //$NON-NLS-1$
else
result += "CLOSE or MENU or CASCADE or WRAP or SIMPLE or SHADOW_ETCHED_OUT | "; //$NON-NLS-1$
if ((style & 1 << 7) != 0)
if (w instanceof Decorations)
result += "MIN | "; //$NON-NLS-1$
else if ((w instanceof Button) || (w instanceof Tracker))
result += "UP | "; //$NON-NLS-1$
else if (w instanceof CTabFolder)
result += "TOP | "; //$NON-NLS-1$
else
result += "MIN or UP or TOP | "; //$NON-NLS-1$
if ((style & 1 << 8) != 0)
result += "HORIZONTAL | "; //$NON-NLS-1$
if ((style & 1 << 9) != 0)
result += "VERTICAL | "; //$NON-NLS-1$
if ((style & 1 << 10) != 0)
if (w instanceof Decorations)
result += "MAX | "; //$NON-NLS-1$
else if ((w instanceof Button) || (w instanceof Tracker))
result += "DOWN | "; //$NON-NLS-1$
else if (w instanceof CTabFolder)
result += "BOTTOM | "; //$NON-NLS-1$
else
result += "MAX or DOWN or BOTTOM | "; //$NON-NLS-1$
if ((style & 1 << 11) != 0)
result += "BORDER | "; //$NON-NLS-1$
if ((style & 1 << 12) != 0)
result += "CLIP_CHILDREN | "; //$NON-NLS-1$
if ((style & 1 << 13) != 0)
result += "CLIP_SIBLINGS | "; //$NON-NLS-1$
if ((style & 1 << 14) != 0)
result += "ON_TOP or LEAD or LEFT | "; //$NON-NLS-1$
if ((style & 1 << 15) != 0)
if (w instanceof Shell)
result += "PRIMARY_MODAL | "; //$NON-NLS-1$
else if (w instanceof Table)
result += "HIDE_SELECTION | "; //$NON-NLS-1$
else
result += "PRIMARY_MODAL or HIDE_SELECTION | "; //$NON-NLS-1$
if ((style & 1 << 16) != 0)
if ((w instanceof StyledText) || (w instanceof Table))
result += "FULL_SELECTION | "; //$NON-NLS-1$
else if (w instanceof Shell)
result += "APPLICATION_MODAL | "; //$NON-NLS-1$
else if (w instanceof ProgressBar)
result += "SMOOTH | "; //$NON-NLS-1$
else
result += "FULL_SELECTION or SMOOTH or APPLICATION_MODAL | "; //$NON-NLS-1$
if ((style & 1 << 17) != 0)
if (w instanceof Shell)
result += "SYSTEM_MODAL | "; //$NON-NLS-1$
else if ((w instanceof Button) || (w instanceof Label) || (w instanceof TableColumn)
|| (w instanceof Tracker) || (w instanceof ToolBar))
result += "TRAIL | "; //$NON-NLS-1$
else
result += "SYSTEM_MODAL or TRAIL or RIGHT | "; //$NON-NLS-1$
if ((style & 1 << 18) != 0)
result += "NO_BACKGROUND | "; //$NON-NLS-1$
if ((style & 1 << 19) != 0)
result += "NO_FOCUS | "; //$NON-NLS-1$
if ((style & 1 << 20) != 0)
result += "NO_REDRAW_RESIZE | "; //$NON-NLS-1$
if ((style & 1 << 21) != 0)
result += "NO_MERGE_PAINTS | "; //$NON-NLS-1$
if ((style & 1 << 22) != 0)
if (w instanceof Text)
result += "PASSWORD | "; //$NON-NLS-1$
else if (w instanceof Composite)
result += "NO_RADIO_GROUP | "; //$NON-NLS-1$
else
result += "NO_RADIO_GROUP or PASSWORD | "; //$NON-NLS-1$
if ((style & 1 << 23) != 0)
result += "FLAT | "; //$NON-NLS-1$
if ((style & 1 << 24) != 0)
if ((w instanceof Button) || (w instanceof Label) || (w instanceof TableColumn))
result += "CENTER | "; //$NON-NLS-1$
else
result += "EMBEDDED or CENTER | "; //$NON-NLS-1$
if ((style & 1 << 25) != 0)
result += "LEFT_TO_RIGHT | "; //$NON-NLS-1$
if ((style & 1 << 26) != 0)
result += "RIGHT_TO_LEFT | "; //$NON-NLS-1$
if ((style & 1 << 27) != 0)
result += "MIRRORED | "; //$NON-NLS-1$
if ((style & 1 << 28) != 0)
result += "VIRTUAL | "; //$NON-NLS-1$
int lastOr = result.lastIndexOf("|"); //$NON-NLS-1$
if (lastOr == result.length() - 2)
result = result.substring(0, result.length() - 2);
return result;
}
}