X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=tmf%2Forg.eclipse.tracecompass.tmf.ui%2Fsrc%2Forg%2Feclipse%2Ftracecompass%2Ftmf%2Fui%2Fwidgets%2Ftimegraph%2Fwidgets%2FTimeGraphControl.java;h=2f5c35895a97bfd14661edb75131ff0076479f36;hb=refs%2Fheads%2Fnext-previous-event;hp=2b949633942e5a457f02c29ccedcf5dd474c95aa;hpb=25033fefb1d755a3fdedf3eeafaa4fbc951fba69;p=deliverable%2Ftracecompass.git
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java
index 2b94963394..2f5c35895a 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java
@@ -27,9 +27,11 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Queue;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jface.action.IStatusLineManager;
@@ -39,6 +41,7 @@ import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
@@ -70,6 +73,7 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal;
@@ -153,6 +157,7 @@ public class TimeGraphControl extends TimeGraphBaseControl
private int fDragButton;
private int fDragX0 = 0;
private int fDragX = 0;
+ private boolean fHasNamespaceFocus = false;
private long fDragTime0 = 0; // used to preserve accuracy of modified selection
private int fIdealNameSpace = 0;
private long fTime0bak;
@@ -239,6 +244,15 @@ public class TimeGraphControl extends TimeGraphBaseControl
return fTimeGraphProvider;
}
+ /**
+ * Gets the time data provider used by this viewer.
+ *
+ * @return The time data provider, or null
if not set
+ */
+ public ITimeDataProvider getTimeDataProvider() {
+ return fTimeProvider;
+ }
+
/**
* Gets the color map used by this timegraph viewer.
*
@@ -321,6 +335,12 @@ public class TimeGraphControl extends TimeGraphBaseControl
listener.widgetSelected(null);
}
}
+
+ if (null != fSelectionChangedListeners) {
+ for (ISelectionChangedListener listener : fSelectionChangedListeners) {
+ listener.selectionChanged(new SelectionChangedEvent(this, getSelection()));
+ }
+ }
}
/**
@@ -575,6 +595,108 @@ public class TimeGraphControl extends TimeGraphBaseControl
}
}
+ /**
+ * Set the expanded state of a given entry to certain relative level.
+ * It will call fireTreeEvent() for each changed entry. At the end
+ * it will call redraw().
+ *
+ * @param entry
+ * The entry
+ * @param level
+ * level to expand to or negative for all levels
+ * @param expanded
+ * True if expanded, false if collapsed
+ */
+ private void setExpandedState(ITimeGraphEntry entry, int level, boolean expanded) {
+ setExpandedStateInt(entry, level, expanded);
+ redraw();
+ }
+
+ /**
+ * Set the expanded state of a given entry and its children to the first
+ * level that has one collapsed entry.
+ *
+ * @param entry
+ * The entry
+ */
+ private void setExpandedStateLevel(ITimeGraphEntry entry) {
+ int level = findExpandedLevel(entry);
+ if (level >= 0) {
+ setExpandedStateInt(entry, level, true);
+ redraw();
+ }
+ }
+
+ /*
+ * Inner class for finding relative level with at least one
+ * collapsed entry.
+ */
+ private class SearchNode {
+ SearchNode(ITimeGraphEntry e, int l) {
+ entry = e;
+ level = l;
+ }
+ ITimeGraphEntry entry;
+ int level;
+ }
+
+ /**
+ * Finds the relative level with at least one collapsed entry.
+ *
+ * @param entry
+ * the start entry
+ * @return the found level or -1 if all levels are already expanded.
+ */
+ private int findExpandedLevel(ITimeGraphEntry entry) {
+ Queue queue = new LinkedList<>();
+ SearchNode root = new SearchNode(entry, 0);
+ SearchNode node = root;
+ queue.add(root);
+
+ while (!queue.isEmpty()) {
+ node = queue.remove();
+ if (node.entry.hasChildren() && !getExpandedState(node.entry)) {
+ return node.level;
+ }
+ for (ITimeGraphEntry e : node.entry.getChildren()) {
+ if (e.hasChildren()) {
+ SearchNode n = new SearchNode(e, node.level + 1);
+ queue.add(n);
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Set the expanded state of a given entry to certain relative level.
+ * It will call fireTreeEvent() for each changed entry. No redraw is done.
+ *
+ * @param entry
+ * The entry
+ * @param level
+ * level to expand to or negative for all levels
+ * @param expanded
+ * True if expanded, false if collapsed
+ */
+ private void setExpandedStateInt(ITimeGraphEntry entry, int aLevel, boolean expanded) {
+ int level = aLevel;
+ if ((level > 0) || (level < 0)) {
+ level--;
+ if (entry.hasChildren()) {
+ for (ITimeGraphEntry e : entry.getChildren()) {
+ setExpandedStateInt(e, level, expanded);
+ }
+ }
+ }
+ Item item = fItemData.findItem(entry);
+ if (item != null && item.fExpanded != expanded) {
+ item.fExpanded = expanded;
+ fItemData.updateExpandedItems();
+ fireTreeEvent(item.fEntry, item.fExpanded);
+ }
+ }
+
/**
* Collapses all nodes of the viewer's tree, starting with the root.
*/
@@ -712,6 +834,14 @@ public class TimeGraphControl extends TimeGraphBaseControl
}
}
+ @Override
+ public boolean setFocus() {
+ if ((fTimeProvider != null) && fTimeProvider.getNameSpace() > 0) {
+ fHasNamespaceFocus = true;
+ }
+ return super.setFocus();
+ }
+
@Override
public ISelection getSelection() {
TimeGraphSelection sel = new TimeGraphSelection();
@@ -719,10 +849,9 @@ public class TimeGraphControl extends TimeGraphBaseControl
if (null != trace && null != fTimeProvider) {
long selectedTime = fTimeProvider.getSelectionBegin();
ITimeEvent event = Utils.findEvent(trace, selectedTime, 0);
+ sel.add(trace);
if (event != null) {
sel.add(event);
- } else {
- sel.add(trace);
}
}
return sel;
@@ -2292,6 +2421,29 @@ public class TimeGraphControl extends TimeGraphBaseControl
if (fVerticalZoomAlignEntry != null) {
setElementPosition(fVerticalZoomAlignEntry.getKey(), fVerticalZoomAlignEntry.getValue());
}
+ } else if ((e.character == '+' || e.character == '=') && ((e.stateMask & SWT.CTRL) == 0)) {
+ if (fHasNamespaceFocus) {
+ ITimeGraphEntry entry = getSelectedTrace();
+ setExpandedState(entry, 0, true);
+ } else {
+ zoomIn();
+ }
+ } else if (e.character == '-' && ((e.stateMask & SWT.CTRL) == 0)) {
+ if (fHasNamespaceFocus) {
+ ITimeGraphEntry entry = getSelectedTrace();
+ if ((entry != null) && entry.hasChildren()) {
+ setExpandedState(entry, -1, false);
+ }
+ } else {
+ zoomOut();
+ }
+ } else if ((e.character == '*') && ((e.stateMask & SWT.CTRL) == 0)) {
+ if (fHasNamespaceFocus) {
+ ITimeGraphEntry entry = getSelectedTrace();
+ if ((entry != null) && entry.hasChildren()) {
+ setExpandedStateLevel(entry);
+ }
+ }
}
if (idx >= 0) {
selectItem(idx, false);
@@ -2493,6 +2645,12 @@ public class TimeGraphControl extends TimeGraphBaseControl
}
fMouseOverSplitLine = mouseOverSplitLine;
}
+
+ if (e.x >= fTimeProvider.getNameSpace()) {
+ fHasNamespaceFocus = false;
+ } else {
+ fHasNamespaceFocus = true;
+ }
updateCursor(e.x, e.stateMask);
updateStatusLine(e.x);
}
@@ -2624,6 +2782,10 @@ public class TimeGraphControl extends TimeGraphBaseControl
redraw();
updateCursor(e.x, e.stateMask);
fTimeGraphScale.setDragRange(fDragX0, fDragX);
+ } else {
+ idx = getItemIndexAtY(e.y);
+ selectItem(idx, false);
+ fireSelectionChanged();
}
}
}
@@ -2976,7 +3138,7 @@ public class TimeGraphControl extends TimeGraphBaseControl
* Returns this control's filters.
*
* @return an array of viewer filters
- * @since 2.0
+ * @since 1.2
*/
public @NonNull ViewerFilter[] getFilters() {
return Iterables.toArray(fFilters, ViewerFilter.class);
@@ -2987,7 +3149,7 @@ public class TimeGraphControl extends TimeGraphBaseControl
*
* @param filters
* an array of viewer filters, or null
- * @since 2.0
+ * @since 1.2
*/
public void setFilters(@NonNull ViewerFilter[] filters) {
fFilters.clear();
@@ -3172,6 +3334,7 @@ public class TimeGraphControl extends TimeGraphBaseControl
if (null == fTimeProvider) {
return;
}
+ Point p = toControl(e.x, e.y);
if (e.detail == SWT.MENU_MOUSE) {
if (fPendingMenuDetectEvent == null) {
/* Feature in Linux. The MenuDetectEvent is received before mouseDown.
@@ -3179,10 +3342,16 @@ public class TimeGraphControl extends TimeGraphBaseControl
* This allows for the method to detect if mouse is used to drag zoom.
*/
fPendingMenuDetectEvent = e;
+ /*
+ * Prevent the platform to show the menu when returning. The
+ * menu will be shown (see below) when this method is called
+ * again during mouseup().
+ */
+ e.doit = false;
return;
}
fPendingMenuDetectEvent = null;
- if (fDragState != DRAG_ZOOM || fDragX != fDragX0) {
+ if ((p.x >= fTimeProvider.getNameSpace()) && (fDragState != DRAG_ZOOM || fDragX != fDragX0)) {
return;
}
} else {
@@ -3190,21 +3359,34 @@ public class TimeGraphControl extends TimeGraphBaseControl
return;
}
}
- Point p = toControl(e.x, e.y);
int idx = getItemIndexAtY(p.y);
if (idx >= 0 && idx < fItemData.fExpandedItems.length) {
+ e.doit = true;
Item item = fItemData.fExpandedItems[idx];
ITimeGraphEntry entry = item.fEntry;
+
+ /* Send menu event for the time graph entry */
+ e.doit = true;
+ e.data = entry;
+ fireMenuEventOnTimeGraphEntry(e);
+ Menu menu = getMenu();
+ if (e.doit && (menu != null)) {
+ menu.setVisible(true);
+ }
+
+ /* Send menu event for time event */
if (entry.hasTimeEvents()) {
ITimeEvent event = Utils.findEvent(entry, getTimeAtX(p.x), 2);
if (event != null) {
+ e.doit = true;
e.data = event;
fireMenuEventOnTimeEvent(e);
- return;
+ menu = getMenu();
+ if (e.doit && (menu != null)) {
+ menu.setVisible(true);
+ }
}
}
- e.data = entry;
- fireMenuEventOnTimeGraphEntry(e);
}
}