import org.eclipse.swtbot.swt.finder.keyboard.Keyboard;
import org.eclipse.swtbot.swt.finder.keyboard.KeyboardFactory;
import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes;
-import org.eclipse.swtbot.swt.finder.matchers.WidgetOfType;
-import org.eclipse.swtbot.swt.finder.results.VoidResult;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
-import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraph;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraphEntry;
import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractTimeGraphView;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
import org.eclipse.ui.IWorkbenchPart;
import org.junit.Before;
import org.junit.Test;
private static final String FOLLOW_CPU_FORWARD = "Follow CPU Forward";
private static final String SELECT_PREVIOUS_STATE_CHANGE = "Select Previous State Change";
private static final String SELECT_NEXT_STATE_CHANGE = "Select Next State Change";
- private static final String SELECT_NEXT_PROCESS = "Select Next Process";
private static final Keyboard KEYBOARD = KeyboardFactory.getSWTKeyboard();
private static final @NonNull ITmfTimestamp START_TIME = TmfTimestamp.fromNanos(1368000272650993664L);
private static final @NonNull ITmfTimestamp TID1_TIME1 = TmfTimestamp.fromNanos(1368000272651208412L);
TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, START_TIME));
timeGraphIsReadyCondition(new TmfTimeRange(START_TIME, START_TIME));
- /* select first item */
- SWTBotUtils.pressShortcutGoToTreeTop(KEYBOARD);
- fViewBot.toolbarButton(SELECT_NEXT_PROCESS).click();
-
/* set focus on time graph */
- final TimeGraphControl timegraph = fViewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class));
- UIThreadRunnable.syncExec(new VoidResult() {
- @Override
- public void run() {
- timegraph.setFocus();
- }
- });
+ SWTBotTimeGraph timeGraph = new SWTBotTimeGraph(fViewBot.bot());
+ timeGraph.setFocus();
+
+ /* select first item */
+ KEYBOARD.pressShortcut(Keystrokes.HOME);
+ KEYBOARD.pressShortcut(Keystrokes.DOWN);
/* click "Select Next State Change" 3 times */
selectNext.run();
checked = UIThreadRunnable.syncExec(treeCheckCounter);
assertEquals("Filtered", 26, checked.intValue());
bot.button("OK").click();
- treeBot = fViewBot.bot().tree();
- treeItem = treeBot.getTreeItem(LttngTraceGenerator.getName());
- for (int i = 0; i < 25; i++) {
- assertEquals("Filtered Control flow view", "Half-life 3", treeItem.cell(i, 0));
+ SWTBotTimeGraph timeGraph = new SWTBotTimeGraph(fViewBot.bot());
+ SWTBotTimeGraphEntry traceEntry = timeGraph.getEntry(LttngTraceGenerator.getName());
+ for (SWTBotTimeGraphEntry entry : traceEntry.getEntries()) {
+ assertEquals("Filtered Control flow view", "Half-life 3", entry.getText());
}
}
/* set selection to trace start time */
TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, START_TIME));
- fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(START_TIME, START_TIME)));
+ timeGraphIsReadyCondition(new TmfTimeRange(START_TIME, START_TIME));
- /* select first item */
final SWTBotTree tree = fViewBot.bot().tree();
- SWTBotUtils.pressShortcutGoToTreeTop(KEYBOARD);
- fViewBot.toolbarButton(SELECT_NEXT_PROCESS).click();
/* set focus on time graph */
- final TimeGraphControl timegraph = fViewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class));
- UIThreadRunnable.syncExec(new VoidResult() {
- @Override
- public void run() {
- timegraph.setFocus();
- }
- });
+ SWTBotTimeGraph timeGraph = new SWTBotTimeGraph(fViewBot.bot());
+ timeGraph.setFocus();
+
+ /* select first item */
+ KEYBOARD.pressShortcut(Keystrokes.HOME);
+ KEYBOARD.pressShortcut(Keystrokes.DOWN);
/* click "Follow CPU Forward" 3 times */
timeGraphIsReadyCondition(new TmfTimeRange(START_TIME, START_TIME));
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
-import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraph;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraphEntry;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
import org.junit.Before;
import org.junit.Test;
public void testFull() {
SWTBotTree treeCfv = fViewBotCfv.bot().tree();
SWTBotTree treeCp = fViewBotCp.bot().tree();
+ SWTBotTimeGraph timeGraphCp = new SWTBotTimeGraph(fViewBotCp.bot());
assertNotNull(treeCfv.widget);
assertNotNull(treeCp.widget);
SWTBotTreeItem[] allItems = treeCp.getAllItems();
ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
assertNotNull(trace);
- SWTBotTreeItem item = treeCfv.getTreeItem(trace.getName());
- assertNotNull(item);
- item = item.getNode("systemd");
- assertNotNull(item);
- item = item.getNode("we");
- assertNotNull(item);
- item = item.getNode(PROCESS);
- assertNotNull(item);
- final SWTBotTreeItem treeItem = item;
- UIThreadRunnable.syncExec(() -> treeCfv.widget.setTopItem(treeItem.widget));
- item.click();
+ SWTBotTreeItem entry = treeCfv.expandNode(trace.getName(), "systemd", "we", PROCESS);
+ assertNotNull(entry);
+ entry.select();
- SWTBotMenu menu = item.contextMenu("Follow " + PROCESS + "/" + TID);
+ SWTBotMenu menu = entry.contextMenu("Follow " + PROCESS + "/" + TID);
assertEquals("Follow " + PROCESS + "/" + TID, menu.getText());
menu.click();
fBot.waitUntil(new DefaultCondition() {
@Override
public boolean test() throws Exception {
- SWTBotTreeItem[] items = treeCp.getAllItems();
- return EXPECTED_TREE_TEXT.equals(items[0].getNode(0).getText());
+ SWTBotTimeGraphEntry[] entries = timeGraphCp.getEntries();
+ return EXPECTED_TREE_TEXT.equals(entries[0].getEntries()[0].getText());
}
@Override
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.stream.Collectors;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils;
import org.eclipse.tracecompass.tmf.ui.dialog.TmfFileDialogFactory;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraph;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraphEntry;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
import org.eclipse.tracecompass.tmf.ui.views.callstack.CallStackView;
private static final String UST_ID = "org.eclipse.linuxtools.lttng2.ust.tracetype";
private static final String PROJECT_NAME = "TestForCallstack";
+ private static final String TRACE = "glxgears-cyg-profile";
+ private static final String PROCESS = "UNKNOWN";
+ private static final @NonNull String THREAD = "glxgears-16073";
/** The Log4j logger instance. */
private static final Logger fLogger = Logger.getRootLogger();
* Stack frames of consecutive events in the trace
*/
private static final String[] STACK_FRAMES[] = new String[][] {
- { "0x40472b", "0x4045c8", "0x404412", "", "" },
- { "0x40472b", "0x4045c8", "0x404412", "0x40392b", "" },
- { "0x40472b", "0x4045c8", "0x404412", "", "" },
- { "0x40472b", "0x4045c8", "", "", "" },
- { "0x40472b", "0x4045c8", "0x404412", "", "" },
- { "0x40472b", "0x4045c8", "0x404412", "0x40392b", "" },
- { "0x40472b", "0x4045c8", "0x404412", "", "" },
- { "0x40472b", "0x4045c8", "", "", "" },
- { "0x40472b", "0x4045c8", "0x404412", "", "" },
- { "0x40472b", "0x4045c8", "0x404412", "0x40392b", "" },
- { "0x40472b", "0x4045c8", "0x404412", "", "" },
+ { "0x40472b", "0x4045c8", "0x404412" },
+ { "0x40472b", "0x4045c8", "0x404412", "0x40392b" },
+ { "0x40472b", "0x4045c8", "0x404412" },
+ { "0x40472b", "0x4045c8" },
+ { "0x40472b", "0x4045c8", "0x404412" },
+ { "0x40472b", "0x4045c8", "0x404412", "0x40392b" },
+ { "0x40472b", "0x4045c8", "0x404412" },
+ { "0x40472b", "0x4045c8" },
+ { "0x40472b", "0x4045c8", "0x404412" },
+ { "0x40472b", "0x4045c8", "0x404412", "0x40392b" },
+ { "0x40472b", "0x4045c8", "0x404412" },
};
/** Tooltips of the toolbar buttons */
SWTBotUtils.closeView("welcome", fBot);
SWTBotUtils.switchToTracingPerspective();
+ SWTBotUtils.closeView("Statistics", fBot);
/* finish waiting for eclipse to load */
WaitUtils.waitForJobs();
}
*/
@Test
public void testOpenCallstack() {
- String node = "glxgears-cyg-profile";
- String processName = "UNKNOWN";
- String childName = "glxgears-16073";
- List<String> expected = ImmutableList.of("0x40472b", "", "", "", "");
-
SWTBotView viewBot = fBot.viewById(CallStackView.ID);
viewBot.setFocus();
- final SWTBotView viewBot1 = viewBot;
- SWTBotTree tree = viewBot1.bot().tree();
- SWTBotTreeItem treeItem = tree.getTreeItem(node).getNode(processName);
- assertEquals(childName, treeItem.getNodes().get(0));
- List<String> names = treeItem.getNode(childName).getNodes();
- assertEquals(expected, names);
+ assertEquals(Arrays.asList("0x40472b"), getVisibleStackFrames(viewBot));
}
/**
private static List<String> getVisibleStackFrames(final SWTBotView viewBot) {
SWTBotTree tree = viewBot.bot().tree();
- return Arrays.stream(tree.getAllItems())
- // Process entries
- .flatMap(item -> Arrays.stream(item.getItems()))
- // Thread entries
- .flatMap(item -> Arrays.stream(item.getItems()))
- // Callstack entries
- .flatMap(item -> Arrays.stream(item.getItems()))
- .map(item -> item.cell(0))
- .collect(Collectors.toList());
+ List<String> stackFrames = new ArrayList<>();
+ for (SWTBotTreeItem treeItem : tree.expandNode(TRACE, PROCESS, THREAD).getItems()) {
+ String name = treeItem.cell(0);
+ if (!name.isEmpty()) {
+ stackFrames.add(name);
+ }
+ }
+ return stackFrames;
}
private static void goToTime(long timestamp) {
goToTime(TIMESTAMPS[0]);
final SWTBotView viewBot = fBot.viewById(CallStackView.ID);
viewBot.setFocus();
- SWTBotTree tree = viewBot.bot().tree();
Object mapObj = CtfTmfTestTraceUtils.class.getResource("cyg-profile-mapping.txt");
assertTrue(mapObj instanceof URL);
URL mapUrl = (URL) mapObj;
shellBot.button("Browse...", 1).click();
shellBot.button("OK").click();
shellBot.waitUntil(Conditions.shellCloses(activeShell));
- // FIXME: remove when updates are propagated
+ /*
+ * FIXME: Seek to time needed to update the call stack entry names.
+ * Remove when applying symbol configuration correctly updates entries.
+ */
goToTime(TIMESTAMPS[0]);
WaitUtils.waitForJobs();
- List<String> names = new ArrayList<>();
-
- for (SWTBotTreeItem swtBotTreeItem : tree.getAllItems()) {
- for (SWTBotTreeItem items : swtBotTreeItem.getItems()) {
- for (SWTBotTreeItem item : items.getItems()) {
- names.add(item.cell(0));
- }
- }
- }
- List<String> functions = getVisibleStackFrames(viewBot);
- assertEquals(ImmutableList.of("glxgears-16073"), names);
- assertEquals(ImmutableList.of("main", "event_loop", "handle_event", "", ""), functions);
+ SWTBotTimeGraph timeGraph = new SWTBotTimeGraph(viewBot.bot());
+ SWTBotTimeGraphEntry[] threads = timeGraph.getEntry(TRACE, PROCESS).getEntries();
+ assertEquals(1, threads.length);
+ assertEquals(THREAD, threads[0].getText());
+ assertEquals(Arrays.asList("main", "event_loop", "handle_event"), getVisibleStackFrames(viewBot));
}
/**
};
}
+ /**
+ * Condition to check if the selection contains the specified text at the
+ * specified column. The text is checked in any item of the tree selection.
+ *
+ * @param tree
+ * the SWTBot tree
+ * @param column
+ * the column index
+ * @param text
+ * the expected text
+ * @return ICondition for verification
+ */
+ public static ICondition timeGraphSelectionContains(final SWTBotTimeGraph timeGraph, final int column, final String text) {
+ return new SWTBotTestCondition() {
+ @Override
+ public boolean test() throws Exception {
+ TableCollection selection = timeGraph.selection();
+ for (int row = 0; row < selection.rowCount(); row++) {
+ if (selection.get(row, column).equals(text)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return NLS.bind("Time graph selection [0,{0}]: {1} expected: {2}",
+ new Object[] { column, timeGraph.selection().get(0, column), text});
+ }
+ };
+ }
+
private static class EventsTableSelectionCondition extends DefaultCondition {
private long fSelectionTime;
private SWTWorkbenchBot fBot;
/*******************************************************************************
- * Copyright (c) 2015 Ericsson
+ * Copyright (c) 2015, 2016 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared;
-import java.awt.AWTException;
-import java.awt.Robot;
-import java.awt.event.InputEvent;
-
+import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
-import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
import org.eclipse.swtbot.swt.finder.results.Result;
-import org.eclipse.swtbot.swt.finder.results.VoidResult;
import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBotControl;
-import org.hamcrest.SelfDescribing;
/**
- * SWT Bot sash control
+ * SWTBot class representing a Sash
*/
public class SWTBotSash extends AbstractSWTBotControl<Sash> {
*
* @param w
* the sash
- * @param description
- * the description
* @throws WidgetNotFoundException
* if there is no widget
*/
- public SWTBotSash(Sash w, SelfDescribing description) throws WidgetNotFoundException {
- super(w, description);
+ public SWTBotSash(Sash w) throws WidgetNotFoundException {
+ super(w);
}
/**
- * Get the central point of the sash
+ * Get the bounds of the sash
*
- * @return the center point, good for dragging
+ * @return the bounds relative to the parent
*/
- public Point getPoint() {
- return UIThreadRunnable.syncExec(new Result<Point>() {
-
+ public Rectangle getBounds() {
+ return syncExec(new Result<Rectangle>() {
@Override
- public Point run() {
- return widget.toDisplay(0, widget.getSize().y / 2);
+ public Rectangle run() {
+ return widget.getBounds();
}
-
});
}
/**
- * Simulate a drag
+ * Drag the sash from its middle point to the destination point
*
* @param dst
- * to this destination
+ * the destination point relative to the parent
*/
public void drag(final Point dst) {
- final Point src = getPoint();
- /*
- * example of a move
- *
- * dn : MouseEvent{Sash {} time=262463957 data=null button=1
- * stateMask=0x0 x=5 y=59 count=1}
- *
- * move : MouseEvent{Sash {} time=262464038 data=null button=0
- * stateMask=0x80000 x=131 y=103 count=0}
- *
- * move : MouseEvent{Sash {} time=262464171 data=null button=0
- * stateMask=0x80000 x=90 y=116 count=0}
- *
- * up : MouseEvent{Sash {} time=262464796 data=null button=1
- * stateMask=0x80000 x=5 y=116 count=1}
- */
- try {
- final Robot awtRobot = new Robot();
-
- // move a maximum of 10 points / event
- final int magDist = (src.x - dst.x) * (src.x - dst.x) + (src.y - dst.y) * (src.y - dst.y);
-
- final int steps = Math.max(1, (int) Math.sqrt(magDist / 100.0));
-
- final int stepX = (dst.x - src.x) / steps;
- final int stepY = (dst.y - src.y) / steps;
- syncExec(new VoidResult() {
- @Override
- public void run() {
- awtRobot.mouseMove(src.x, src.y);
- SWTBotUtils.delay(15);
- awtRobot.mousePress(InputEvent.BUTTON1_MASK);
+ Rectangle bounds = getBounds();
+ int x = bounds.width / 2;
+ int y = bounds.height / 2;
+ notify(SWT.MouseEnter);
+ notify(SWT.Activate);
+ notify(SWT.Selection, createSelectionEvent(bounds.x + x, bounds.y + y, SWT.NONE));
+ notify(SWT.MouseDown, createMouseEvent(x, y, 1, SWT.NONE, 1));
+ notify(SWT.DragDetect, createMouseEvent(x, y, 0, SWT.NONE, 0));
+ notify(SWT.Move);
+ notify(SWT.Selection, createSelectionEvent(dst.x, dst.y, SWT.NONE));
+ notify(SWT.MouseMove, createMouseEvent(x, y, 0, SWT.BUTTON1, 0));
+ notify(SWT.Selection, createSelectionEvent(dst.x, dst.y, SWT.BUTTON1));
+ notify(SWT.MouseUp, createMouseEvent(x, y, 1, SWT.NONE, 1));
+ notify(SWT.MouseExit);
+ }
- }
- });
- for (int i = 0; i < steps; i++) {
- final int index = i;
- asyncExec(new VoidResult() {
- @Override
- public void run() {
- int x = src.x + index * stepX;
- int y = src.y + index * stepY;
- awtRobot.mouseMove(x, y);
- }
- });
- // drag delay
- SWTBotUtils.delay(10);
+ private Event createSelectionEvent(int x, int y, int stateMask) {
+ return syncExec(new Result<Event>() {
+ @Override
+ public Event run() {
+ boolean vertical = (widget.getStyle() | SWT.VERTICAL) != 0;
+ Point size = widget.getSize();
+ Event event = createSelectionEvent(stateMask);
+ event.x = vertical ? x : 0;
+ event.y = vertical ? 0 : y;
+ event.width = size.x;
+ event.height = size.y;
+ return event;
}
- // drop delay
- SWTBotUtils.delay(100);
- syncExec(new VoidResult() {
- @Override
- public void run() {
- awtRobot.mouseRelease(InputEvent.BUTTON1_MASK);
- }
- });
-
- } catch (final AWTException e) {
- // log.error(e.getMessage(), e);
- throw new RuntimeException(e);
- }
+ });
}
-
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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:
+ * Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetOfType;
+import org.eclipse.swtbot.swt.finder.results.ArrayResult;
+import org.eclipse.swtbot.swt.finder.results.IntResult;
+import org.eclipse.swtbot.swt.finder.results.Result;
+import org.eclipse.swtbot.swt.finder.utils.TableCollection;
+import org.eclipse.swtbot.swt.finder.utils.TableRow;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBotControl;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
+
+/**
+ * SWTBot class representing a time graph
+ */
+public class SWTBotTimeGraph extends AbstractSWTBotControl<TimeGraphControl> {
+
+ /**
+ * Constructor
+ *
+ * @param w the widget
+ * @throws WidgetNotFoundException if the widget is <code>null</code> or widget has been disposed.
+ */
+ public SWTBotTimeGraph(TimeGraphControl w) throws WidgetNotFoundException {
+ super(w);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param bot
+ * a SWTBot instance with which to find a time graph
+ * @throws WidgetNotFoundException
+ * if the widget is <code>null</code> or widget has been
+ * disposed.
+ */
+ public SWTBotTimeGraph(SWTBot bot) throws WidgetNotFoundException {
+ super(bot.widget(WidgetOfType.widgetOfType(TimeGraphControl.class)));
+ }
+
+ /**
+ * Get the root entries of this time graph
+ *
+ * @return the array of root entries
+ */
+ public SWTBotTimeGraphEntry[] getEntries() {
+ return syncExec(new ArrayResult<SWTBotTimeGraphEntry>() {
+ @Override
+ public SWTBotTimeGraphEntry[] run() {
+ List<SWTBotTimeGraphEntry> entries = new ArrayList<>();
+ for (ITimeGraphEntry entry : widget.getExpandedElements()) {
+ if (entry.getParent() == null) {
+ entries.add(new SWTBotTimeGraphEntry(widget, entry));
+ }
+ }
+ return entries.toArray(new SWTBotTimeGraphEntry[0]);
+ }
+ });
+ }
+
+ /**
+ * Get the time graph entry at the specified path relative to the root.
+ *
+ * @param names
+ * the path of names
+ * @return the time graph entry
+ * @throws WidgetNotFoundException
+ * if the entry was not found.
+ */
+ public SWTBotTimeGraphEntry getEntry(String... names) throws WidgetNotFoundException {
+ List<ITimeGraphEntry> entries = Arrays.asList(widget.getExpandedElements());
+ ITimeGraphEntry parent = null;
+ for (String name : names) {
+ boolean found = false;
+ for (ITimeGraphEntry entry : entries) {
+ String label = entry.getName();
+ if (Objects.equals(entry.getParent(), parent) && name.equals(label)) {
+ parent = entry;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ throw new WidgetNotFoundException("Timed out waiting for time graph entry " + name); //$NON-NLS-1$
+ }
+ }
+ return new SWTBotTimeGraphEntry(widget, parent);
+ }
+
+ /**
+ * Gets the table collection representing the selection.
+ *
+ * @return the selection in the time graph
+ */
+ public TableCollection selection() {
+ return syncExec(new Result<TableCollection>() {
+ @Override
+ public TableCollection run() {
+ final TableCollection collection = new TableCollection();
+ ISelection selection = widget.getSelection();
+ if (!selection.isEmpty()) {
+ Object element = ((StructuredSelection) selection).getFirstElement();
+ if (element instanceof ITimeGraphEntry) {
+ TableRow tableRow = new TableRow();
+ SWTBotTimeGraphEntry entry = new SWTBotTimeGraphEntry(widget, (ITimeGraphEntry) element);
+ tableRow.add(entry.getText());
+ collection.add(tableRow);
+ }
+ }
+ return collection;
+ }
+ });
+ }
+
+ /**
+ * Get the name space width
+ *
+ * @return the name space width
+ */
+ public int getNameSpace() {
+ return syncExec(new IntResult() {
+ @Override
+ public Integer run() {
+ return widget.getTimeDataProvider().getNameSpace();
+ }
+ });
+ }
+
+ /**
+ * Set the name space width
+ *
+ * @param nameSpace the name space width
+ */
+ public void setNameSpace(int nameSpace) {
+ int x = widget.getTimeDataProvider().getNameSpace();
+ Rectangle bounds = syncExec(new Result<Rectangle>() {
+ @Override
+ public Rectangle run() {
+ return widget.getBounds();
+ }
+ });
+ int y = bounds.y + bounds.height / 2;
+ notify(SWT.MouseEnter);
+ notify(SWT.MouseMove, createMouseEvent(x, y, 0, SWT.NONE, 0));
+ notify(SWT.Activate);
+ notify(SWT.FocusIn);
+ notify(SWT.MouseDown, createMouseEvent(x, y, 1, SWT.NONE, 1));
+ notify(SWT.DragDetect, createMouseEvent(nameSpace, y, 0, SWT.NONE, 0));
+ notify(SWT.MouseMove, createMouseEvent(nameSpace, y, 1, SWT.BUTTON1, 1));
+ notify(SWT.MouseUp, createMouseEvent(nameSpace, y, 1, SWT.BUTTON1, 1));
+ notify(SWT.MouseMove, createMouseEvent(0, y, 0, SWT.NONE, 0));
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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:
+ * Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.ArrayResult;
+import org.eclipse.swtbot.swt.finder.results.Result;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.waits.WaitForObjectCondition;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBotControl;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotRootMenu;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
+
+/**
+ * SWTBot class representing a time graph entry
+ */
+public class SWTBotTimeGraphEntry extends AbstractSWTBotControl<TimeGraphControl> {
+
+ private final ITimeGraphEntry fEntry;
+
+ /**
+ * Constructor
+ *
+ * @param w the widget
+ * @param entry the time graph entry
+ *
+ * @throws WidgetNotFoundException if the widget is <code>null</code> or widget has been disposed.
+ */
+ public SWTBotTimeGraphEntry(TimeGraphControl w, ITimeGraphEntry entry) throws WidgetNotFoundException {
+ super(w);
+ fEntry = entry;
+ }
+
+
+ @Override
+ protected SWTBotRootMenu contextMenu(final Control control) throws WidgetNotFoundException {
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ Rectangle bounds = widget.getItemBounds(fEntry);
+ if (bounds == null) {
+ return;
+ }
+ final Event event = new Event();
+ event.time = (int) System.currentTimeMillis();
+ event.display = control.getDisplay();
+ event.widget = control;
+ event.x = bounds.x + widget.getTimeDataProvider().getNameSpace() / 2;
+ event.y = bounds.y + bounds.height / 2;
+ control.notifyListeners(SWT.MenuDetect, event);
+ }
+ });
+
+ WaitForObjectCondition<Menu> waitForMenu = Conditions.waitForPopupMenu(control);
+ new SWTBot().waitUntilWidgetAppears(waitForMenu);
+ return new SWTBotRootMenu(waitForMenu.get(0));
+ }
+
+ /**
+ * Get the child entries of this entry
+ *
+ * @return the array of child entries
+ */
+ public SWTBotTimeGraphEntry[] getEntries() {
+ return syncExec(new ArrayResult<SWTBotTimeGraphEntry>() {
+ @Override
+ public SWTBotTimeGraphEntry[] run() {
+ List<SWTBotTimeGraphEntry> entries = new ArrayList<>();
+ for (ITimeGraphEntry entry : widget.getExpandedElements()) {
+ if (fEntry.equals(entry.getParent())) {
+ entries.add(new SWTBotTimeGraphEntry(widget, entry));
+ }
+ }
+ return entries.toArray(new SWTBotTimeGraphEntry[0]);
+ }
+ });
+ }
+
+ /**
+ * Get the child entry of this entry with the given name
+ *
+ * @param name
+ * the name of the entry
+ *
+ * @return the child entry
+ */
+ public SWTBotTimeGraphEntry getEntry(String name) {
+ return syncExec(new Result<SWTBotTimeGraphEntry>() {
+ @Override
+ public SWTBotTimeGraphEntry run() {
+ for (ITimeGraphEntry entry : widget.getExpandedElements()) {
+ if (fEntry.equals(entry.getParent())) {
+ String label = entry.getName();
+ if (name.equals(label)) {
+ return new SWTBotTimeGraphEntry(widget, entry);
+ }
+ }
+ }
+ throw new WidgetNotFoundException("Timed out waiting for time graph entry " + name); //$NON-NLS-1$
+ }
+ });
+ }
+
+ /**
+ * Get the text of this entry
+ *
+ * @return the text
+ */
+ @Override
+ public String getText() {
+ return fEntry.getName();
+ }
+
+ /**
+ * Select this time graph entry
+ *
+ * @return itself
+ */
+ public SWTBotTimeGraphEntry select() {
+ syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ widget.setFocus();
+ widget.selectItem(fEntry, true);
+ }
+ });
+ return this;
+ }
+}
/*******************************************************************************
- * Copyright (c) 2015 Ericsson
+ * Copyright (c) 2015, 2016 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
package org.eclipse.tracecompass.tmf.ui.swtbot.tests.viewers.events;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.IOException;
-import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
-import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
-import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetOfType;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
import org.eclipse.tracecompass.tmf.core.io.BufferedRandomAccessFile;
import org.eclipse.tracecompass.tmf.ui.project.wizards.NewTmfProjectWizard;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotSash;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraph;
import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
import org.eclipse.tracecompass.tmf.ui.views.callstack.CallStackView;
import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView;
import org.eclipse.tracecompass.tmf.ui.views.timechart.TimeChartView;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
import org.eclipse.ui.IFolderLayout;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
}
private static File fLocation;
- private static final BaseMatcher<Sash> SASH_MATCHER = new SashMatcher();
/**
* Initialization, creates a temp trace
}
/**
- * Test 3 views, none overlap, the histogram, the callstack and the
- * timechart are aligned, the histogram is moved, callstack and timechart
- * follow
+ * Test 3 views, none overlap, the histogram, callstack and timechart are
+ * aligned. The histogram is moved, we check that the callstack and
+ * timechart follow.
*/
@Test
- public void testMoveHistogramCallstackFollows() {
+ public void testMoveHistogramOthersFollow() {
fBot = new SWTWorkbenchBot();
- SWTBotUtils.switchToPerspective(AlignPerspectiveFactory1.ID);
- testOverlap(HistogramView.ID, CallStackView.ID);
+ switchToPerspective(AlignPerspectiveFactory1.ID);
+ testAligned(HistogramView.ID, CallStackView.ID, TimeChartView.ID);
}
/**
- * Test 3 views, none overlap, the histogram, the callstack and the
- * timechart are aligned, the callstack is moved, histogram and timechart
- * follow
+ * Test 3 views, none overlap, the histogram, callstack and timechart are
+ * aligned. The callstack is moved, we check that the histogram and
+ * timechart follow.
*/
@Test
- public void testMoveCallstackHistogramFollows() {
+ public void testMoveCallstackOthersFollow() {
fBot = new SWTWorkbenchBot();
- SWTBotUtils.switchToPerspective(AlignPerspectiveFactory1.ID);
- testOverlap(CallStackView.ID, HistogramView.ID);
+ switchToPerspective(AlignPerspectiveFactory1.ID);
+ testAligned(CallStackView.ID, HistogramView.ID, TimeChartView.ID);
}
/**
- * Test 3 views, overlap on the resizing view. The timechart and callstack
- * are overlapping. Test that when the histogram moves, the timechart
- * follows. Hidden views are not tested as their state does not matter until
- * they are displayed
+ * Test 3 views, overlap on the resizing view. The histogram and timechart
+ * are overlapping, and the callstack is aligned. The histogram is moved, we
+ * check that the callstack follows. The hidden timechart is not checked.
*/
@Test
public void testOverlappingHistogramMove() {
fBot = new SWTWorkbenchBot();
- SWTBotUtils.switchToPerspective(AlignPerspectiveFactory2.ID);
- testOverlap(HistogramView.ID, CallStackView.ID);
+ switchToPerspective(AlignPerspectiveFactory2.ID);
+ testAligned(HistogramView.ID, CallStackView.ID);
}
/**
- * Test 3 views, overlap on the resizing view. The timechart and callstack
- * are overlapping. Test that when the timechart moves, the histogram
- * follows. Hidden views are not tested as their state does not matter until
- * they are displayed
+ * Test 3 views, overlap on the resizing view. The histogram and timechart
+ * are overlapping, and the callstack is aligned. The callstack is moved, we
+ * check that the histogram follows. The hidden timechart is not checked.
*/
@Test
- public void testOverlappingTimechartMove() {
+ public void testOverlappingCallstackMove() {
fBot = new SWTWorkbenchBot();
- SWTBotUtils.switchToPerspective(AlignPerspectiveFactory2.ID);
- testOverlap(CallStackView.ID, HistogramView.ID);
+ switchToPerspective(AlignPerspectiveFactory2.ID);
+ testAligned(CallStackView.ID, HistogramView.ID);
}
/**
- * Test 3 views. No overlap. The callstack is not aligned with the
- * histogram, the histogram is moved, we check that the callstack does NOT
- * follow
+ * Test 3 views. No overlap. The histogram and timechart are aligned, but
+ * the callstack is not aligned. The histogram is moved, we check that the
+ * timechart follows and that the callstack does NOT follow.
*/
@Test
public void testNotOverlappingHistogramMove() {
fBot = new SWTWorkbenchBot();
- testNonOverlap(HistogramView.ID, CallStackView.ID);
+ switchToPerspective(AlignPerspectiveFactory3.ID);
+ testAligned(HistogramView.ID, TimeChartView.ID);
+ testNotAligned(HistogramView.ID, CallStackView.ID);
}
/**
- * Test 3 views. No overlap. The callstack is not aligned with the
- * histogram, the callstack is moved, we check that the histogram does NOT
- * follow
+ * Test 3 views. No overlap. The histogram and timechart are aligned, but
+ * the callstack is not aligned. The callstack is moved, we check that the
+ * histogram and timechart do NOT follow.
*/
@Test
public void testNotOverlappingCallstackMove() {
fBot = new SWTWorkbenchBot();
- testNonOverlap(CallStackView.ID, HistogramView.ID);
+ switchToPerspective(AlignPerspectiveFactory3.ID);
+ testNotAligned(CallStackView.ID, HistogramView.ID, TimeChartView.ID);
}
- private static void testNonOverlap(String vId1, String vId2) {
- final int offset = 100;
+ private static void switchToPerspective(String id) {
// switch to the proper perspective and wait for views to align
- SWTBotUtils.switchToPerspective(AlignPerspectiveFactory3.ID);
+ SWTBotUtils.switchToPerspective(id);
WaitUtils.waitForJobs();
SWTBotUtils.delay(SYNC_DELAY);
- // get views
- SWTBotView masterView = fBot.viewById(vId1);
- SWTBotView slaveView = fBot.viewById(vId2);
- final Sash slaveSash = slaveView.bot().widget(SASH_MATCHER, 0);
- SWTBotSash slaveSashBot = new SWTBotSash(slaveSash, null);
- Point before = slaveSashBot.getPoint();
- // move master and wait for slaves to follow
- drag(masterView, offset);
- WaitUtils.waitForJobs();
- SWTBotUtils.delay(SYNC_DELAY);
- // verify that the slave did not follow
- assertEquals(before, slaveSashBot.getPoint());
- // put everything back the way it was
- drag(masterView, -offset);
- SWTBotUtils.delay(SYNC_DELAY);
}
- private static final class SashMatcher extends BaseMatcher<Sash> {
- @Override
- public boolean matches(Object item) {
- return (item instanceof Sash);
+ private static AbstractSWTBot<?> getAlignmentControl(String viewId) {
+ SWTBotView viewBot = fBot.viewById(viewId);
+ switch (viewId) {
+ case HistogramView.ID:
+ case CallStackView.ID:
+ return new SWTBotSash(viewBot.bot().widget(WidgetOfType.widgetOfType(Sash.class)));
+ case TimeChartView.ID:
+ return new SWTBotTimeGraph(viewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class)));
+ default:
+ return null;
}
+ }
- @Override
- public void describeTo(Description description) {
+ private static void testAligned(String masterView, String... slaveViews) {
+ final int offset = 50;
+
+ // select alignment controls and get their original alignment positions
+ AbstractSWTBot<?> master = getAlignmentControl(masterView);
+ int masterOrigin = getAlignmentPosition(master);
+ Map<AbstractSWTBot<?>, Integer> slaveMap = new HashMap<>();
+ for (String slaveView : slaveViews) {
+ AbstractSWTBot<?> slave = getAlignmentControl(slaveView);
+ int slaveOrigin = getAlignmentPosition(slave);
+ slaveMap.put(slave, slaveOrigin);
}
+
+ // change master position
+ setAlignmentPosition(master, masterOrigin + offset);
+
+ // check resulting alignment positions, slaves follow
+ assertEquals(masterOrigin + offset, getAlignmentPosition(master), 2);
+ for (Entry<AbstractSWTBot<?>, Integer> slave : slaveMap.entrySet()) {
+ assertEquals(slave.getValue() + offset, getAlignmentPosition(slave.getKey()), 2);
+ }
+
+ // reset original alignment position
+ setAlignmentPosition(master, masterOrigin);
}
- private static final class SashFormMatcher extends BaseMatcher<SashForm> {
- @Override
- public boolean matches(Object item) {
- return (item instanceof SashForm);
+ private static void testNotAligned(String masterView, String... nonSlaveViews) {
+ final int offset = 50;
+
+ // select alignment controls and get their original alignment positions
+ AbstractSWTBot<?> master = getAlignmentControl(masterView);
+ int masterOrigin = getAlignmentPosition(master);
+ Map<AbstractSWTBot<?>, Integer> nonSlaveMap = new HashMap<>();
+ for (String nonSlaveView : nonSlaveViews) {
+ AbstractSWTBot<?> nonSlave = getAlignmentControl(nonSlaveView);
+ int nonSlaveOrigin = getAlignmentPosition(nonSlave);
+ nonSlaveMap.put(nonSlave, nonSlaveOrigin);
}
- @Override
- public void describeTo(Description description) {
+ // change master position
+ setAlignmentPosition(master, masterOrigin + offset);
+
+ // check resulting alignment positions, non-slaves do not follow
+ assertEquals(masterOrigin + offset, getAlignmentPosition(master), 2);
+ for (Entry<AbstractSWTBot<?>, Integer> nonSlave : nonSlaveMap.entrySet()) {
+ assertEquals((int) nonSlave.getValue(), getAlignmentPosition(nonSlave.getKey()));
}
+
+ // reset original alignment position
+ setAlignmentPosition(master, masterOrigin);
}
- /**
- * Simulate a drag operation using "setWeights"
- */
- private static void drag(final SWTBotView view, final int offset) {
- // this is the final sash form
- final SashForm sashForm = view.bot().widget(new SashFormMatcher(), 0);
- assertNotNull(sashForm);
- // resize widgets using sashform
- UIThreadRunnable.syncExec(new VoidResult() {
- @Override
- public void run() {
- int[] originalWeights = sashForm.getWeights();
- int[] newWeights = Arrays.copyOf(originalWeights, originalWeights.length);
- newWeights[0] += offset;
- newWeights[1] -= offset;
- sashForm.setWeights(newWeights);
- sashForm.getParent().layout();
- }
- });
- // send update signals
- UIThreadRunnable.syncExec(new VoidResult() {
- @Override
- public void run() {
- sashForm.getChildren()[0].notifyListeners(SWT.Resize, null);
- sashForm.getChildren()[1].notifyListeners(SWT.Resize, null);
- /*
- * This one is the most important, the previous two are added to
- * be a good citizen, this event (selection) is the one that
- * triggers an alignment
- */
- sashForm.getChildren()[2].notifyListeners(SWT.Selection, null);
- }
- });
+ private static int getAlignmentPosition(AbstractSWTBot<?> control) {
+ if (control instanceof SWTBotSash) {
+ Rectangle bounds = ((SWTBotSash) control).getBounds();
+ return bounds.x + bounds.width / 2;
+ } else if (control instanceof SWTBotTimeGraph) {
+ return ((SWTBotTimeGraph) control).getNameSpace();
+ }
+ return 0;
}
- private static void testOverlap(String masterView, String slaveView) {
- final int offset = 100;
- final int delta = offset / 2;
- // wait for the perspective switch to propagate alignments
- WaitUtils.waitForJobs();
- SWTBotUtils.delay(SYNC_DELAY);
- // select master and slave parts to observe
- SWTBotView masterViewBot = fBot.viewById(masterView);
- final Sash masterSash = masterViewBot.bot().widget(SASH_MATCHER, 0);
- SWTBotSash masterSashBot = new SWTBotSash(masterSash, null);
-
- SWTBotView slaveViewBot = fBot.viewById(slaveView);
- final Sash slaveSash = slaveViewBot.bot().widget(SASH_MATCHER, 0);
- SWTBotSash slaveSashBot = new SWTBotSash(slaveSash, null);
-
- double masterOriginalSashX = masterSashBot.getPoint().x;
- // check that the views are already aligned
- assertEquals("Approx align", masterOriginalSashX, slaveSashBot.getPoint().x, delta);
- // move sash and wait for alignment
- drag(masterViewBot, offset);
+ private static void setAlignmentPosition(AbstractSWTBot<?> control, int position) {
+ if (control instanceof SWTBotSash) {
+ SWTBotSash sash = (SWTBotSash) control;
+ Rectangle bounds = sash.getBounds();
+ Point dst = new Point(position, bounds.y + bounds.height / 2);
+ sash.drag(dst);
+ } else if (control instanceof SWTBotTimeGraph) {
+ ((SWTBotTimeGraph) control).setNameSpace(position);
+ }
+ // wait for alignment
WaitUtils.waitForJobs();
SWTBotUtils.delay(SYNC_DELAY);
- // check results
- double masterNewSashX = masterSashBot.getPoint().x;
- assertEquals("Approx align", masterNewSashX, slaveSashBot.getPoint().x, delta);
- assertEquals(masterOriginalSashX, masterNewSashX - offset, delta);
- // put things back the way they were
- drag(masterViewBot, -offset);
- SWTBotUtils.delay(SYNC_DELAY);
}
/**
layout.setEditorAreaVisible(true);
// Create the top left folder
- IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
+ IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.4f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
// Create the top right folder
layout.setEditorAreaVisible(true);
// Create the top left folder
- IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
+ IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.4f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
// Create the middle right folder
layout.setEditorAreaVisible(true);
// Create the top left folder
- IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
+ IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.4f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
IFolderLayout bottomLeftFolder = layout.createFolder("bottomLeftFolder", IPageLayout.BOTTOM, 0.5f, "topLeftFolder"); //$NON-NLS-1$
return fItemData.fExpandedItems[index].fEntry;
}
+ /**
+ * Get the bounds of the specified entry
+ *
+ * @param entry the time graph entry
+ * @return the bounds of the entry, or null if the entry is not visible
+ * @since 2.2
+ */
+ public Rectangle getItemBounds(ITimeGraphEntry entry) {
+ int idx = fItemData.findItemIndex(entry);
+ if (idx >= 0) {
+ return getItemRect(getBounds(), idx);
+ }
+ return null;
+ }
+
Rectangle getNameRect(Rectangle bounds, int idx, int nameWidth) {
Rectangle rect = getItemRect(bounds, idx);
rect.width = nameWidth;